Package dtk :: Package ui :: Module volume_button

Source Code for Module dtk.ui.volume_button

  1  #! /usr/bin/env python 
  2  # -*- coding: utf-8 -*- 
  3   
  4  # houshaohui:code->[str_size function, get size, type, mtime, combox].  
  5  # Copyright (C) 2012 Deepin, Inc. 
  6  #               2012 Hailong Qiu 
  7  # 
  8  # Author:     Hailong Qiu <356752238@qq.com> 
  9  # Maintainer: Hailong Qiu <356752238@qq.com> 
 10  # 
 11  # This program is free software: you can redistribute it and/or modify 
 12  # it under the terms of the GNU General Public License as published by 
 13  # the Free Software Foundation, either version 3 of the License, or 
 14  # any later version. 
 15  # 
 16  # This program is distributed in the hope that it will be useful, 
 17  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 18  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 19  # GNU General Public License for more details. 
 20  # 
 21  # You should have received a copy of the GNU General Public License 
 22  # along with this program.  If not, see <http://www.gnu.org/licenses/>. 
 23   
 24  from cache_pixbuf import CachePixbuf 
 25  from draw import draw_pixbuf 
 26  from theme import ui_theme 
 27  from utils import set_clickable_cursor 
 28  import gobject 
 29  import gtk 
 30   
 31  ''' 
 32  100 / 500 = 0.2 
 33  x = 100 -> 100 * 0.2 = 20 
 34  x = 500 -> 500 * 0.2 = 100 
 35  x = 100 -> 100 * 0.2 = 20  
 36  ''' 
 37   
 38  # volume state. 
 39  ZERO_STATE = 0 
 40  MIN_STATE = 1 
 41  MID_STATE = 2 
 42  MAX_STATE = 3 
 43  MUTE_STATE = -1 
 44  # mouse volume state. 
 45  MOUSE_VOLUME_STATE_PRESS  = 1 
 46  MOUSE_VOLUME_STATE_HOVER  = 2 
 47  MOUSE_VOLUME_STATE_NORMAL = -1 
 48  # volume type. 
 49  VOLUME_RIGHT = "right" 
 50  VOLUME_LEFT   = "left" 
51 52 -class VolumeButton(gtk.Button):
53 ''' 54 Volume button. 55 ''' 56 57 __gsignals__ = { 58 "volume-state-changed":(gobject.SIGNAL_RUN_LAST, 59 gobject.TYPE_NONE,(gobject.TYPE_INT,gobject.TYPE_INT,)) 60 } 61
62 - def __init__(self, 63 volume_max_value = 100, 64 volume_width = 52, 65 volume_x = 0, 66 volume_y = 15, 67 line_width = 3, 68 volume_left_right_padding_x = 5, 69 volume_left_show_value = [(1, 33),(34, 66),(67, 100)], 70 scroll_bool = False, 71 press_emit_bool = False, 72 #============================================================= 73 bg_pixbuf = ui_theme.get_pixbuf("volumebutton/bg.png"), 74 fg_pixbuf = ui_theme.get_pixbuf("volumebutton/fg.png"), 75 #============================================================= 76 zero_volume_normal_pixbuf = ui_theme.get_pixbuf("volumebutton/zero_normal.png"), 77 zero_volume_hover_pixbuf = ui_theme.get_pixbuf("volumebutton/zero_hover.png"), 78 zero_volume_press_pixbuf = ui_theme.get_pixbuf("volumebutton/zero_press.png"), 79 #============================================================= 80 min_volume_normal_pixbuf = ui_theme.get_pixbuf("volumebutton/lower_normal.png"), 81 min_volume_hover_pixbuf = ui_theme.get_pixbuf("volumebutton/lower_hover.png"), 82 min_volume_press_pixbuf = ui_theme.get_pixbuf("volumebutton/lower_press.png"), 83 #============================================================= 84 mid_volume_normal_pixbuf = ui_theme.get_pixbuf("volumebutton/middle_normal.png"), 85 mid_volume_hover_pixbuf = ui_theme.get_pixbuf("volumebutton/middle_hover.png"), 86 mid_volume_press_pixbuf = ui_theme.get_pixbuf("volumebutton/middle_press.png"), 87 #============================================================= 88 max_volume_normal_pixbuf = ui_theme.get_pixbuf("volumebutton/high_normal.png"), 89 max_volume_hover_pixbuf = ui_theme.get_pixbuf("volumebutton/high_hover.png"), 90 max_volume_press_pixbuf = ui_theme.get_pixbuf("volumebutton/high_press.png"), 91 #============================================================= 92 mute_volume_normal_pixbuf = ui_theme.get_pixbuf("volumebutton/mute_normal.png"), 93 mute_volume_hover_pixbuf = ui_theme.get_pixbuf("volumebutton/mute_hover.png"), 94 mute_volume_press_pixbuf = ui_theme.get_pixbuf("volumebutton/mute_press.png"), 95 #============================================================= 96 point_volume_pixbuf = ui_theme.get_pixbuf("volumebutton/point_normal.png"), 97 inc_value=5, 98 ):
99 gtk.Button.__init__(self) 100 ########################### 101 if volume_x < max_volume_normal_pixbuf.get_pixbuf().get_width(): 102 volume_x = max_volume_normal_pixbuf.get_pixbuf().get_width() 103 '''Init pixbuf.''' 104 self.__bg_pixbuf = bg_pixbuf 105 self.__fg_pixbuf = fg_pixbuf 106 self.__bg_cache_pixbuf = CachePixbuf() 107 self.__fg_cache_pixbuf = CachePixbuf() 108 # zero volume pixbuf. 109 self.__zero_volume_normal_pixbuf = zero_volume_normal_pixbuf 110 self.__zero_volume_hover_pixbuf = zero_volume_hover_pixbuf 111 self.__zero_volume_press_pixbuf = zero_volume_press_pixbuf 112 # min volume pixbuf. 113 self.__min_volume_normal_pixbuf = min_volume_normal_pixbuf 114 self.__min_volume_hover_pixbuf = min_volume_hover_pixbuf 115 self.__min_volume_press_pixbuf = min_volume_press_pixbuf 116 # mid volume pixbuf: 117 self.__mid_volume_normal_pixbuf = mid_volume_normal_pixbuf 118 self.__mid_volume_hover_pixbuf = mid_volume_hover_pixbuf 119 self.__mid_volume_press_pixbuf = mid_volume_press_pixbuf 120 # max volume pixbuf[normal, hover, press]. 121 self.__max_volume_normal_pixbuf = max_volume_normal_pixbuf 122 self.__max_volume_hover_pixbuf = max_volume_hover_pixbuf 123 self.__max_volume_press_pixbuf = max_volume_press_pixbuf 124 # mute volume pixbuf[normal, hover, press]. 125 self.__mute_volume_normal_pixbuf = mute_volume_normal_pixbuf 126 self.__mute_volume_hover_pixbuf = mute_volume_hover_pixbuf 127 self.__mute_volume_press_pixbuf = mute_volume_press_pixbuf 128 # point volume pixbuf. 129 self.__point_volume_pixbuf = point_volume_pixbuf 130 '''Init Set VolumeButton attr.''' 131 '''Init value.''' 132 self.__press_emit_bool = press_emit_bool 133 self.__line_width = line_width 134 self.__current_value = 0 135 self.__mute_bool = False 136 self.temp_mute_bool = False 137 self.__drag = False 138 self.__volume_max_value = volume_max_value 139 self.__volume_width = volume_width 140 141 self.__volume_left_x = volume_x - self.__max_volume_normal_pixbuf.get_pixbuf().get_width() - volume_left_right_padding_x 142 self.__volume_left_y = volume_y - self.__max_volume_normal_pixbuf.get_pixbuf().get_height()/2 + self.__point_volume_pixbuf.get_pixbuf().get_height()/2 143 self.__volume_right_x = volume_x 144 self.__volume_right_y = volume_y 145 '''Left''' 146 self.volume_left_show_value = volume_left_show_value 147 self.__volume_state = MIN_STATE 148 self.__mouse_state = MOUSE_VOLUME_STATE_NORMAL 149 '''Right''' 150 # bg value. 151 self.__bg_x = 0 152 self.__bg_y = self.__volume_right_y 153 self.__bg_padding_x = self.__volume_right_x 154 # fg value. 155 self.__fg_x = 0 156 self.__fg_y = self.__volume_right_y 157 self.__fg_padding_x = self.__volume_right_x 158 # point value. 159 self.__point_y = self.__volume_right_y 160 self.__point_padding_x = self.__volume_right_x 161 self.inc_value = inc_value 162 163 '''Init VolumeButton event.''' 164 self.add_events(gtk.gdk.ALL_EVENTS_MASK) 165 self.connect("expose-event", self.__expose_draw_volume) 166 self.connect("motion-notify-event", self.__motion_mouse_set_point) 167 self.connect("button-press-event", self.__press_mouse_set_point) 168 self.connect("button-release-event", self.__release_mouse_set_point) 169 '''Event value''' 170 self.press_bool = False 171 # scroll event. 172 if scroll_bool: 173 self.connect("scroll-event", self.__scroll_mouse_set_point) 174 175 self.set_size_request(volume_width + self.__volume_left_x + self.__volume_right_x + self.__mute_volume_normal_pixbuf.get_pixbuf().get_width(), 30) 176 177 set_clickable_cursor(self)
178
179 - def set_press_emit_bool(self, emit_bool):
180 self.__press_emit_bool = emit_bool
181
182 - def __set_point_padding_x(self, event):
183 self.__mute_bool = False 184 self.__point_padding_x = int(event.x) 185 self.queue_draw()
186
187 - def __press_mouse_set_point(self, widget, event):
188 temp_x = int(event.x) 189 190 temp_min_x = self.__bg_x + self.__bg_padding_x - self.__point_volume_pixbuf.get_pixbuf().get_width()/2 191 temp_max_x = self.__bg_x + self.__bg_padding_x + self.__volume_width + self.__point_volume_pixbuf.get_pixbuf().get_width()/2 192 self.queue_draw() 193 if temp_min_x < temp_x < temp_max_x: 194 self.__set_point_padding_x(event) 195 self.__drag = True 196 else: 197 if self.__volume_left_x <= temp_x <= temp_min_x: 198 # Set mouse state press. 199 self.__mouse_state = MOUSE_VOLUME_STATE_PRESS 200 self.temp_mute_bool = True 201 self.press_bool = True 202
203 - def __release_mouse_set_point(self, widget, event):
204 # Set mouse state normal. 205 self.__mouse_state = MOUSE_VOLUME_STATE_NORMAL 206 self.__drag = False 207 self.press_bool = False 208 209 temp_x = int(event.x) 210 temp_y = int(event.y) 211 212 temp_min_x = self.__bg_x + self.__bg_padding_x - self.__point_volume_pixbuf.get_pixbuf().get_width()/2 213 if self.__volume_left_x <= temp_x <= temp_min_x and ( self.__volume_left_y <=temp_y < (self.__volume_left_y + self.__mute_volume_hover_pixbuf.get_pixbuf().get_height())): 214 if self.temp_mute_bool and not self.__mute_bool: 215 # Set mute state. 216 self.__mute_bool = not self.__mute_bool 217 self.__volume_state = MUTE_STATE 218 self.temp_mute_bool = False 219 else: # modify state. 220 self.__mute_bool = False 221 self.temp_mute_bool = False 222 self.__set_volume_value_to_state(self.__current_value) 223 self.queue_draw() 224 225 if self.__press_emit_bool: 226 self.emit("volume-state-changed", self.__current_value, self.__volume_state) 227 228 self.queue_draw() 229
230 - def __motion_mouse_set_point(self, widget, event):
231 temp_x = int(event.x) 232 temp_y = int(event.y) 233 temp_min_x = self.__bg_x + self.__bg_padding_x - self.__point_volume_pixbuf.get_pixbuf().get_width()/2 234 235 if (self.__volume_left_x <= temp_x <= temp_min_x) and ( self.__volume_left_y <=temp_y < (self.__volume_left_y + self.__mute_volume_hover_pixbuf.get_pixbuf().get_height())): 236 self.__mouse_state = MOUSE_VOLUME_STATE_HOVER 237 else: 238 self.__mouse_state = MOUSE_VOLUME_STATE_NORMAL 239 if not self.press_bool: 240 self.queue_draw() 241 242 if self.__drag: 243 self.__set_point_padding_x(event)
244
245 - def __scroll_mouse_set_point(self, widget, event):
246 if event.direction == gtk.gdk.SCROLL_UP: 247 self.volume_other_set_value(VOLUME_RIGHT) 248 elif event.direction == gtk.gdk.SCROLL_DOWN: 249 self.volume_other_set_value(VOLUME_LEFT) 250
251 - def volume_other_set_value(self, volume_type):
252 point_width_average = self.__point_volume_pixbuf.get_pixbuf().get_width() / 2 253 temp_min = (self.__point_padding_x - point_width_average) 254 temp_max = (self.__point_padding_x + self.__volume_width - point_width_average) 255 256 self.__mute_bool = False 257 258 if volume_type == VOLUME_RIGHT: 259 if self.__point_padding_x >= temp_max: 260 self.__point_padding_x = temp_max 261 else: 262 self.__point_padding_x += self.inc_value 263 elif volume_type == VOLUME_LEFT: 264 if self.__point_padding_x <= temp_min: 265 self.__point_padding_x = temp_min 266 else: 267 self.__point_padding_x -= self.inc_value 268 269 self.queue_draw() 270
271 - def __expose_draw_volume(self, widget, event):
272 self.__draw_volume_right(widget, event) # 1: get current value. 273 self.__set_volume_value_to_state(self.__current_value) # 2: value to state. 274 self.__draw_volume_left(widget, event) # 3: draw state pixbuf. 275 276 if not self.__press_emit_bool: 277 self.emit("volume-state-changed", self.__current_value, self.__volume_state) 278 # propagate_expose(widget, event) 279 return True 280 281 282 '''Left function''' 283 @property
284 - def volume_state(self):
285 return self.__volume_state
286 287 @volume_state.setter
288 - def volume_state(self, state):
289 if state == MIN_STATE: 290 self.__volume_state = MIN_STATE 291 elif state == ZERO_STATE: 292 self.__volume_state = ZERO_STATE 293 elif state == MID_STATE: 294 self.__volume_state = MID_STATE 295 elif state == MAX_STATE: 296 self.__volume_state = MAX_STATE 297 elif state == MUTE_STATE: 298 self.__volume_state = MUTE_STATE
299 300 301 @volume_state.getter
302 - def volume_state(self):
303 return self.__volume_state
304 305 @volume_state.deleter
306 - def volume_state(self):
307 del self.__volume_state
308
309 - def set_volume_left_show_value(self, show_value):
310 try: 311 show_value[0][0] - show_value[0][1] 312 show_value[1][0] - show_value[1][1] 313 show_value[2][0] - show_value[2][1] 314 315 self.volume_left_show_value = show_value 316 except: 317 print "Error show value!!"
318
319 - def __set_volume_value_to_state(self, value):
320 if not self.__mute_bool: 321 temp_show_value = self.volume_left_show_value 322 if temp_show_value[0][0] <= value <= temp_show_value[0][1]: 323 self.__volume_state = MIN_STATE 324 elif temp_show_value[1][0] <= value <= temp_show_value[1][1]: 325 self.__volume_state = MID_STATE 326 elif temp_show_value[2][0] <= value <= temp_show_value[2][1]: 327 self.__volume_state = MAX_STATE 328 elif 0 == value: 329 self.__volume_state = ZERO_STATE 330 else: 331 self.__volume_state = MUTE_STATE
332
333 - def set_volume_mute(self, mute_flag=True):
334 if mute_flag: 335 self.temp_mute_bool = False 336 self.__mute_bool = True 337 self.__volume_state = MUTE_STATE 338 else: 339 self.temp_mute_bool = False 340 self.__mute_bool = False 341 self.__set_volume_value_to_state(self.value) 342 343 self.queue_draw()
344
345 - def __draw_volume_left(self, widget, event):
346 cr = widget.window.cairo_create() 347 x, y, w, h = widget.allocation 348 349 if self.__volume_state == MUTE_STATE: # mute state. 350 if self.__mouse_state == MOUSE_VOLUME_STATE_NORMAL: 351 pixbuf = self.__mute_volume_normal_pixbuf 352 elif self.__mouse_state == MOUSE_VOLUME_STATE_HOVER: 353 pixbuf = self.__mute_volume_hover_pixbuf 354 elif self.__mouse_state == MOUSE_VOLUME_STATE_PRESS: 355 pixbuf = self.__mute_volume_press_pixbuf 356 elif self.__volume_state == ZERO_STATE: # zero state. 357 if self.__mouse_state == MOUSE_VOLUME_STATE_NORMAL: 358 pixbuf = self.__zero_volume_normal_pixbuf 359 elif self.__mouse_state == MOUSE_VOLUME_STATE_HOVER: 360 pixbuf = self.__zero_volume_hover_pixbuf 361 elif self.__mouse_state == MOUSE_VOLUME_STATE_PRESS: 362 pixbuf = self.__zero_volume_press_pixbuf 363 elif self.__volume_state == MIN_STATE: # min state. 364 if self.__mouse_state == MOUSE_VOLUME_STATE_NORMAL: 365 pixbuf = self.__min_volume_normal_pixbuf 366 elif self.__mouse_state == MOUSE_VOLUME_STATE_HOVER: 367 pixbuf = self.__min_volume_hover_pixbuf 368 elif self.__mouse_state == MOUSE_VOLUME_STATE_PRESS: 369 pixbuf = self.__min_volume_press_pixbuf 370 elif self.__volume_state == MID_STATE: # mid state. 371 if self.__mouse_state == MOUSE_VOLUME_STATE_NORMAL: 372 pixbuf = self.__mid_volume_normal_pixbuf 373 elif self.__mouse_state == MOUSE_VOLUME_STATE_HOVER: 374 pixbuf = self.__mid_volume_hover_pixbuf 375 elif self.__mouse_state == MOUSE_VOLUME_STATE_PRESS: 376 pixbuf = self.__mid_volume_press_pixbuf 377 elif self.__volume_state == MAX_STATE: # max state. 378 if self.__mouse_state == MOUSE_VOLUME_STATE_NORMAL: 379 pixbuf = self.__max_volume_normal_pixbuf 380 elif self.__mouse_state == MOUSE_VOLUME_STATE_HOVER: 381 pixbuf = self.__max_volume_hover_pixbuf 382 elif self.__mouse_state == MOUSE_VOLUME_STATE_PRESS: 383 pixbuf = self.__max_volume_press_pixbuf 384 385 386 draw_pixbuf(cr, 387 pixbuf.get_pixbuf(), 388 x + self.__volume_left_x, 389 y + self.__volume_left_y, 390 )
391 392 '''Right function''' 393 @property
394 - def line_width(self):
395 return self.__line_width
396 397 @line_width.setter
398 - def line_width(self, width):
399 self.__line_width = width 400 self.queue_draw()
401 402 @line_width.getter
403 - def line_width(self):
404 return self.__line_width 405 406 @line_width.deleter
407 - def line_width(self):
408 del self.__line_width
409 410 @property
411 - def value(self):
412 return self.__current_value
413 414 @value.setter
415 - def value(self, value):
416 if 0 <= value <= self.__volume_max_value: 417 temp_padding = (float(self.__volume_max_value) / self.__volume_width) 418 temp_padding_x = float(value) / temp_padding 419 self.__point_padding_x = temp_padding_x + ((self.__fg_padding_x)) 420 self.queue_draw() 421 422 @value.getter
423 - def value(self):
424 return self.__current_value 425 426
427 - def set_volume_position(self, x, y):
428 self.__volume_right_x = x 429 self.__volume_right_y = y 430 # Set x. 431 self.__bg_padding_x = self.__volume_right_x 432 self.__fg_padding_x = self.__volume_right_x 433 self.__point_padding_x = self.__volume_right_x 434 # Set y. 435 self.__bg_y = self.__volume_right_y 436 self.__fg_y = self.__volume_right_y 437 self.__point_y = self.__volume_right_y 438 439 @property
440 - def max_value(self):
441 self.__volume_max_value 442 443 @max_value.setter
444 - def max_value(self, max_value):
445 self.__volume_max_value = max_value 446 447 @max_value.getter
448 - def max_value(self):
449 return self.__volume_max_value 450 451 @max_value.deleter
452 - def max_value(self):
453 del self.__volume_max_value
454
455 - def __draw_volume_right(self, widget, event):
456 cr = widget.window.cairo_create() 457 cr.set_line_width(self.__line_width) 458 x, y, w, h = widget.allocation 459 460 fg_height_average = (self.__point_volume_pixbuf.get_pixbuf().get_height() - self.__fg_pixbuf.get_pixbuf().get_height()) / 2 461 bg_height_average = (self.__point_volume_pixbuf.get_pixbuf().get_height() - self.__bg_pixbuf.get_pixbuf().get_height()) / 2 462 point_width_average = self.__point_volume_pixbuf.get_pixbuf().get_width() / 2 463 ################################################## 464 # Draw bg. 465 if self.__volume_width > 0: 466 self.__bg_cache_pixbuf.scale(self.__bg_pixbuf.get_pixbuf(), 467 self.__volume_width, 468 self.__bg_pixbuf.get_pixbuf().get_height(), 469 ) 470 draw_pixbuf( 471 cr, 472 self.__bg_cache_pixbuf.get_cache(), 473 x + self.__bg_x + self.__bg_padding_x, 474 y + self.__bg_y + bg_height_average) 475 476 temp_fg_padding_x = self.__point_padding_x - (self.__fg_x + self.__fg_padding_x) 477 478 if temp_fg_padding_x < 0: 479 temp_fg_padding_x = 0 480 if temp_fg_padding_x > self.__volume_width: 481 temp_fg_padding_x = self.__volume_width 482 # Get current value. 483 self.__current_value = temp_fg_padding_x * (float(self.__volume_max_value) / self.__volume_width) 484 485 # Draw fg. 486 if temp_fg_padding_x > 0: 487 self.__fg_cache_pixbuf.scale(self.__fg_pixbuf.get_pixbuf(), 488 int(temp_fg_padding_x), 489 self.__fg_pixbuf.get_pixbuf().get_height(), 490 ) 491 draw_pixbuf( 492 cr, 493 self.__fg_cache_pixbuf.get_cache(), 494 x + self.__fg_x + self.__fg_padding_x, 495 y + self.__fg_y + fg_height_average) 496 ################################################# 497 # Draw point. 498 temp_point_padding_x = (self.__point_padding_x - point_width_average) 499 500 temp_min = (self.__volume_right_x - point_width_average) 501 temp_max = (self.__volume_right_x + self.__volume_width - point_width_average) 502 if temp_point_padding_x < temp_min: 503 temp_point_padding_x = temp_min 504 if temp_point_padding_x > temp_max: 505 temp_point_padding_x = temp_max 506 507 draw_pixbuf(cr, 508 self.__point_volume_pixbuf.get_pixbuf(), 509 x + temp_point_padding_x, 510 y + self.__point_y)
511 512 gobject.type_register(VolumeButton) 513 514 if __name__ == "__main__": 515 import random 516 from dtk.ui.window import Window
517 - def set_time_position():
518 volume_button.value = (random.randint(0, 100)) 519 return True
520
521 - def get_volume_value(volume_button, value, volume_state):
522 print "[get_volume_value:]" 523 print "volume_button:%s" % volume_button 524 print "value:%s" % value 525 print "volume_state:%s" % volume_state 526
527 - def set_value_button_clicked(widget):
528 print volume_button.volume_state 529 volume_button.max_value = 200 530 volume_button.value = 100 531 volume_button.line_width = 4 # Set draw line width. 532 # volume_button.set_volume_left_show_value([(0,10),(11,80),(81,100)]) 533 534 win = gtk.Window(gtk.WINDOW_TOPLEVEL) 535 # win = Window() 536 win.set_size_request(200, 120) 537 win.set_title("测试音量按钮") 538 main_vbox = gtk.VBox() 539 volume_button = VolumeButton(100,220) 540 volume_button.value = 100 541 # volume_button = VolumeButton() 542 volume_button.connect("volume-state-changed", get_volume_value) 543 set_value_button = gtk.Button("设置音量的值") 544 set_value_button.connect("clicked", set_value_button_clicked) 545 main_vbox.pack_start(volume_button, True, True) 546 main_vbox.pack_start(set_value_button, True, True) 547 # win.add(volume_button) 548 win.add(main_vbox) 549 # win.window_frame.add(main_vbox) 550 # gtk.timeout_add(500, set_time_position) 551 win.show_all() 552 gtk.main() 553