Package dtk :: Package ui :: Module button

Source Code for Module dtk.ui.button

  1  #! /usr/bin/env python 
  2  # -*- coding: utf-8 -*- 
  3   
  4  # Copyright (C) 2011 ~ 2012 Deepin, Inc. 
  5  #               2011 ~ 2012 Wang Yong 
  6  #  
  7  # Author:     Wang Yong <lazycat.manatee@gmail.com> 
  8  # Maintainer: Wang Yong <lazycat.manatee@gmail.com> 
  9  #  
 10  # This program is free software: you can redistribute it and/or modify 
 11  # it under the terms of the GNU General Public License as published by 
 12  # the Free Software Foundation, either version 3 of the License, or 
 13  # any later version. 
 14  #  
 15  # This program is distributed in the hope that it will be useful, 
 16  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 17  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 18  # GNU General Public License for more details. 
 19  #  
 20  # You should have received a copy of the GNU General Public License 
 21  # along with this program.  If not, see <http://www.gnu.org/licenses/>. 
 22   
 23  from cache_pixbuf import CachePixbuf 
 24  from constant import DEFAULT_FONT_SIZE 
 25  from draw import draw_vlinear, draw_pixbuf, draw_line, draw_text 
 26  from keymap import get_keyevent_name 
 27  from label import Label 
 28  from theme import ui_theme 
 29  import gobject 
 30  import gtk 
 31  import pango 
 32  from utils import (get_content_size, color_hex_to_cairo, propagate_expose, set_clickable_cursor, 
 33                     window_is_max, get_same_level_widgets, widget_fix_cycle_destroy_bug, run_command) 
 34   
 35  __all__ = ["Button", "ImageButton", "ThemeButton", 
 36             "MenuButton", "MinButton", "CloseButton", 
 37             "MaxButton", "ToggleButton", "ActionButton", 
 38             "CheckButton", "RadioButton", "DisableButton", 
 39             "LinkButton"] 
 40   
41 -class Button(gtk.Button):
42 ''' 43 Button with Deepin UI style. 44 45 @undocumented: key_press_button 46 @undocumented: expose_button 47 ''' 48
49 - def __init__(self, label, font_size=DEFAULT_FONT_SIZE):
50 ''' 51 Initialize Button class. 52 53 @param label: Button label. 54 @param font_size: Button label font size. 55 ''' 56 gtk.Button.__init__(self) 57 self.font_size = font_size 58 self.min_width = 69 59 self.min_height = 22 60 self.padding_x = 15 61 self.padding_y = 3 62 63 self.set_label(label) 64 65 self.connect("expose-event", self.expose_button) 66 self.connect("key-press-event", self.key_press_button) 67 68 self.keymap = { 69 "Return" : self.clicked}
70
71 - def set_label(self, label, font_size=DEFAULT_FONT_SIZE):
72 ''' 73 Set label of Button. 74 75 @param label: Button label. 76 @param font_size: Button label font size. 77 ''' 78 self.label = label 79 (self.label_width, self.label_height) = get_content_size(label, self.font_size) 80 self.set_size_request(max(self.label_width + self.padding_x * 2, self.min_width), 81 max(self.label_height + self.padding_y * 2, self.min_height)) 82 83 self.queue_draw()
84
85 - def key_press_button(self, widget, event):
86 ''' 87 Callback for `button-press-event` signal. 88 89 @param widget: Button widget. 90 @param event: Button press event. 91 ''' 92 key_name = get_keyevent_name(event) 93 if self.keymap.has_key(key_name): 94 self.keymap[key_name]()
95
96 - def expose_button(self, widget, event):
97 ''' 98 Callback for `expose-event` signal. 99 100 @param widget: Button widget. 101 @param event: Button press event. 102 ''' 103 # Init. 104 cr = widget.window.cairo_create() 105 rect = widget.allocation 106 x, y, w, h = rect.x, rect.y, rect.width, rect.height 107 108 # Get color info. 109 if widget.state == gtk.STATE_NORMAL: 110 text_color = ui_theme.get_color("button_font").get_color() 111 border_color = ui_theme.get_color("button_border_normal").get_color() 112 background_color = ui_theme.get_shadow_color("button_background_normal").get_color_info() 113 elif widget.state == gtk.STATE_PRELIGHT: 114 text_color = ui_theme.get_color("button_font").get_color() 115 border_color = ui_theme.get_color("button_border_prelight").get_color() 116 background_color = ui_theme.get_shadow_color("button_background_prelight").get_color_info() 117 elif widget.state == gtk.STATE_ACTIVE: 118 text_color = ui_theme.get_color("button_font").get_color() 119 border_color = ui_theme.get_color("button_border_active").get_color() 120 background_color = ui_theme.get_shadow_color("button_background_active").get_color_info() 121 elif widget.state == gtk.STATE_INSENSITIVE: 122 text_color = ui_theme.get_color("disable_text").get_color() 123 border_color = ui_theme.get_color("disable_frame").get_color() 124 disable_background_color = ui_theme.get_color("disable_background").get_color() 125 background_color = [(0, (disable_background_color, 1.0)), 126 (1, (disable_background_color, 1.0))] 127 128 # Draw background. 129 draw_vlinear( 130 cr, 131 x + 1, y + 1, w - 2, h - 2, 132 background_color) 133 134 # Draw border. 135 cr.set_source_rgb(*color_hex_to_cairo(border_color)) 136 draw_line(cr, x + 2, y + 1, x + w - 2, y + 1) # top 137 draw_line(cr, x + 2, y + h, x + w - 2, y + h) # bottom 138 draw_line(cr, x + 1, y + 2, x + 1, y + h - 2) # left 139 draw_line(cr, x + w, y + 2, x + w, y + h - 2) # right 140 141 # Draw four point. 142 if widget.state == gtk.STATE_INSENSITIVE: 143 top_left_point = ui_theme.get_pixbuf("button/disable_corner.png").get_pixbuf() 144 else: 145 top_left_point = ui_theme.get_pixbuf("button/corner.png").get_pixbuf() 146 top_right_point = top_left_point.rotate_simple(270) 147 bottom_right_point = top_left_point.rotate_simple(180) 148 bottom_left_point = top_left_point.rotate_simple(90) 149 150 draw_pixbuf(cr, top_left_point, x, y) 151 draw_pixbuf(cr, top_right_point, x + w - top_left_point.get_width(), y) 152 draw_pixbuf(cr, bottom_left_point, x, y + h - top_left_point.get_height()) 153 draw_pixbuf(cr, bottom_right_point, x + w - top_left_point.get_width(), y + h - top_left_point.get_height()) 154 155 # Draw font. 156 draw_text(cr, self.label, x, y, w, h, self.font_size, text_color, 157 alignment=pango.ALIGN_CENTER) 158 159 return True
160 161 gobject.type_register(Button) 162
163 -class ImageButton(gtk.Button):
164 ''' 165 ImageButton class. 166 ''' 167
168 - def __init__(self, 169 normal_dpixbuf, 170 hover_dpixbuf, 171 press_dpixbuf, 172 scale_x=False, 173 content=None):
174 ''' 175 Initialize ImageButton class. 176 177 @param normal_dpixbuf: DynamicPixbuf for button normal status. 178 @param hover_dpixbuf: DynamicPixbuf for button hover status. 179 @param press_dpixbuf: DynamicPixbuf for button press status. 180 @param scale_x: Whether scale horticulturally, default is False. 181 @param content: Button label content. 182 ''' 183 gtk.Button.__init__(self) 184 self.cache_pixbuf = CachePixbuf() 185 draw_button(self, self.cache_pixbuf, normal_dpixbuf, hover_dpixbuf, press_dpixbuf, scale_x, content)
186 187 gobject.type_register(ImageButton) 188
189 -class ThemeButton(gtk.Button):
190 ''' 191 ThemeButton class. 192 ''' 193
194 - def __init__(self):
195 ''' 196 Initialize ThemeButton class. 197 ''' 198 gtk.Button.__init__(self) 199 self.cache_pixbuf = CachePixbuf() 200 draw_button( 201 self, 202 self.cache_pixbuf, 203 ui_theme.get_pixbuf("button/window_theme_normal.png"), 204 ui_theme.get_pixbuf("button/window_theme_hover.png"), 205 ui_theme.get_pixbuf("button/window_theme_press.png"))
206 207 gobject.type_register(ThemeButton) 208 226 227 gobject.type_register(MenuButton) 228
229 -class MinButton(gtk.Button):
230 ''' 231 MinButton. 232 ''' 233
234 - def __init__(self):
235 ''' 236 Initialize MinButton class. 237 ''' 238 gtk.Button.__init__(self) 239 self.cache_pixbuf = CachePixbuf() 240 draw_button( 241 self, 242 self.cache_pixbuf, 243 ui_theme.get_pixbuf("button/window_min_normal.png"), 244 ui_theme.get_pixbuf("button/window_min_hover.png"), 245 ui_theme.get_pixbuf("button/window_min_press.png"))
246 247 gobject.type_register(MinButton) 248
249 -class CloseButton(gtk.Button):
250 ''' 251 CloseButton class. 252 ''' 253
254 - def __init__(self):
255 ''' 256 Initialize CloseButton class. 257 ''' 258 gtk.Button.__init__(self) 259 self.cache_pixbuf = CachePixbuf() 260 draw_button( 261 self, 262 self.cache_pixbuf, 263 ui_theme.get_pixbuf("button/window_close_normal.png"), 264 ui_theme.get_pixbuf("button/window_close_hover.png"), 265 ui_theme.get_pixbuf("button/window_close_press.png"))
266 267 gobject.type_register(CloseButton) 268
269 -class MaxButton(gtk.Button):
270 ''' 271 MaxButton class. 272 ''' 273
274 - def __init__(self, 275 sub_dir="button", 276 max_path_prefix="window_max", 277 unmax_path_prefix="window_unmax"):
278 ''' 279 Initialize MaxButton class. 280 281 @param sub_dir: Subdirectory of button images. 282 @param max_path_prefix: Image path prefix for maximise status. 283 @param unmax_path_prefix: Image path prefix for un-maximise status. 284 ''' 285 gtk.Button.__init__(self) 286 self.cache_pixbuf = CachePixbuf() 287 draw_max_button(self, self.cache_pixbuf, sub_dir, max_path_prefix, unmax_path_prefix)
288 289 gobject.type_register(MaxButton) 290
291 -def draw_button(widget, cache_pixbuf, normal_dpixbuf, hover_dpixbuf, press_dpixbuf, 292 scale_x=False, button_label=None, font_size=DEFAULT_FONT_SIZE, 293 label_dcolor=ui_theme.get_color("button_default_font")):
294 ''' 295 Draw button. 296 297 @param widget: Gtk.Widget instance. 298 @param cache_pixbuf: CachePixbuf. 299 @param normal_dpixbuf: DynamicPixbuf of normal status. 300 @param hover_dpixbuf: DynamicPixbuf of hover status. 301 @param press_dpixbuf: DynamicPixbuf of press status. 302 @param scale_x: Whether button scale with content. 303 @param button_label: Button label, default is None. 304 @param font_size: Button label font size, default is DEFAULT_FONT_SIZE. 305 @param label_dcolor: Button label color. 306 ''' 307 # Init request size. 308 if scale_x: 309 request_width = get_content_size(button_label, font_size)[0] 310 else: 311 request_width = normal_dpixbuf.get_pixbuf().get_width() 312 request_height = normal_dpixbuf.get_pixbuf().get_height() 313 widget.set_size_request(request_width, request_height) 314 315 # Expose button. 316 widget.connect("expose-event", lambda w, e: expose_button( 317 w, e, 318 cache_pixbuf, 319 scale_x, False, 320 normal_dpixbuf, hover_dpixbuf, press_dpixbuf, 321 button_label, font_size, label_dcolor))
322
323 -def expose_button(widget, event, 324 cache_pixbuf, 325 scale_x, scale_y, 326 normal_dpixbuf, hover_dpixbuf, press_dpixbuf, 327 button_label, font_size, label_dcolor):
328 ''' 329 Expose callback for L{ I{draw_button} <draw_button>}. 330 331 @param widget: Gtk.Widget instance. 332 @param cache_pixbuf: CachePixbuf. 333 @param scale_x: Whether button scale width with content. 334 @param scale_y: Whether button scale height with content. 335 @param normal_dpixbuf: DynamicPixbuf of normal status. 336 @param hover_dpixbuf: DynamicPixbuf of hover status. 337 @param press_dpixbuf: DynamicPixbuf of press status. 338 @param button_label: Button label, default is None. 339 @param font_size: Button label font size, default is DEFAULT_FONT_SIZE. 340 @param label_dcolor: Button label color. 341 ''' 342 # Init. 343 rect = widget.allocation 344 345 # Get pixbuf along with button's sate. 346 if widget.state == gtk.STATE_NORMAL: 347 image = normal_dpixbuf.get_pixbuf() 348 elif widget.state == gtk.STATE_PRELIGHT: 349 image = hover_dpixbuf.get_pixbuf() 350 elif widget.state == gtk.STATE_ACTIVE: 351 image = press_dpixbuf.get_pixbuf() 352 353 # Init size. 354 if scale_x: 355 image_width = widget.allocation.width 356 else: 357 image_width = image.get_width() 358 359 if scale_y: 360 image_height = widget.allocation.height 361 else: 362 image_height = image.get_height() 363 364 # Draw button. 365 pixbuf = image 366 if pixbuf.get_width() != image_width or pixbuf.get_height() != image_height: 367 cache_pixbuf.scale(image, image_width, image_height) 368 pixbuf = cache_pixbuf.get_cache() 369 cr = widget.window.cairo_create() 370 draw_pixbuf(cr, pixbuf, widget.allocation.x, widget.allocation.y) 371 372 # Draw font. 373 if button_label: 374 draw_text(cr, button_label, 375 rect.x, rect.y, rect.width, rect.height, 376 font_size, 377 label_dcolor.get_color(), 378 alignment=pango.ALIGN_CENTER 379 ) 380 381 # Propagate expose to children. 382 propagate_expose(widget, event) 383 384 return True
385
386 -def draw_max_button(widget, cache_pixbuf, sub_dir, max_path_prefix, unmax_path_prefix):
387 ''' 388 Draw maximum button. 389 390 @param widget: Gtk.Widget instance. 391 @param cache_pixbuf: CachePixbuf to avoid unnecessary pixbuf new operation. 392 @param sub_dir: Subdirectory of button. 393 @param max_path_prefix: Prefix of maximum image path. 394 @param unmax_path_prefix: Prefix of un-maximum image path. 395 ''' 396 # Init request size. 397 pixbuf = ui_theme.get_pixbuf("%s/%s_normal.png" % (sub_dir, unmax_path_prefix)).get_pixbuf() 398 widget.set_size_request(pixbuf.get_width(), pixbuf.get_height()) 399 400 # Redraw. 401 widget.connect("expose-event", lambda w, e: 402 expose_max_button(w, e, 403 cache_pixbuf, 404 sub_dir, max_path_prefix, unmax_path_prefix))
405
406 -def expose_max_button(widget, event, cache_pixbuf, sub_dir, max_path_prefix, unmax_path_prefix):
407 ''' 408 Expose callback for L{ I{draw_max_button} <draw_max_button>}. 409 410 @param widget: Gtk.Widget instance. 411 @param event: Expose event. 412 @param cache_pixbuf: CachePixbuf to avoid unnecessary new pixbuf operation. 413 @param sub_dir: Subdirectory for image path. 414 @param max_path_prefix: Prefix of maximum image path. 415 @param unmax_path_prefix: Prefix of un-maximum image path. 416 ''' 417 # Get dynamic pixbuf. 418 if window_is_max(widget): 419 normal_dpixbuf = ui_theme.get_pixbuf("%s/%s_normal.png" % (sub_dir, unmax_path_prefix)) 420 hover_dpixbuf = ui_theme.get_pixbuf("%s/%s_hover.png" % (sub_dir, unmax_path_prefix)) 421 press_dpixbuf = ui_theme.get_pixbuf("%s/%s_press.png" % (sub_dir, unmax_path_prefix)) 422 else: 423 normal_dpixbuf = ui_theme.get_pixbuf("%s/%s_normal.png" % (sub_dir, max_path_prefix)) 424 hover_dpixbuf = ui_theme.get_pixbuf("%s/%s_hover.png" % (sub_dir, max_path_prefix)) 425 press_dpixbuf = ui_theme.get_pixbuf("%s/%s_press.png" % (sub_dir, max_path_prefix)) 426 427 # Get pixbuf along with button's sate. 428 if widget.state == gtk.STATE_NORMAL: 429 image = normal_dpixbuf.get_pixbuf() 430 elif widget.state == gtk.STATE_PRELIGHT: 431 image = hover_dpixbuf.get_pixbuf() 432 elif widget.state == gtk.STATE_ACTIVE: 433 image = press_dpixbuf.get_pixbuf() 434 435 # Init size. 436 image_width = image.get_width() 437 image_height = image.get_height() 438 439 # Draw button. 440 pixbuf = image 441 if pixbuf.get_width() != image_width or pixbuf.get_height() != image_height: 442 cache_pixbuf.scale(image, image_width, image_height) 443 pixbuf = cache_pixbuf.get_cache() 444 cr = widget.window.cairo_create() 445 draw_pixbuf(cr, pixbuf, widget.allocation.x, widget.allocation.y) 446 447 # Propagate expose to children. 448 propagate_expose(widget, event) 449 450 return True
451
452 -class ToggleButton(gtk.ToggleButton):
453 ''' 454 ToggleButton class. 455 456 @undocumented: press_toggle_button 457 @undocumented: release_toggle_button 458 @undocumented: expose_toggle_button 459 @undocumented: set_inactive_pixbuf_group 460 @undocumented: set_active_pixbuf_group 461 ''' 462
463 - def __init__(self, 464 inactive_normal_dpixbuf, 465 active_normal_dpixbuf, 466 inactive_hover_dpixbuf=None, 467 active_hover_dpixbuf=None, 468 inactive_press_dpixbuf=None, 469 active_press_dpixbuf=None, 470 inactive_disable_dpixbuf=None, 471 active_disable_dpixbuf=None, 472 button_label=None, 473 padding_x=0):
474 ''' 475 Initialize ToggleButton class. 476 477 @param inactive_normal_dpixbuf: DynamicPixbuf for inactive normal status. 478 @param active_normal_dpixbuf: DynamicPixbuf for active normal status. 479 @param inactive_hover_dpixbuf: DynamicPixbuf for inactive hover status, default is None. 480 @param active_hover_dpixbuf: DynamicPixbuf for active hover status, default is None. 481 @param inactive_press_dpixbuf: DynamicPixbuf for inactive press status, default is None. 482 @param active_press_dpixbuf: DynamicPixbuf for active press status, default is None. 483 @param inactive_disable_dpixbuf: DynamicPixbuf for inactive disable status, default is None. 484 @param active_disable_dpixbuf: DynamicPixbuf for active disable status, default is None. 485 @param button_label: Button label, default is None. 486 @param padding_x: Padding x, default is 0. 487 ''' 488 gtk.ToggleButton.__init__(self) 489 font_size = DEFAULT_FONT_SIZE 490 label_dcolor = ui_theme.get_color("button_default_font") 491 self.button_press_flag = False 492 493 self.inactive_pixbuf_group = (inactive_normal_dpixbuf, 494 inactive_hover_dpixbuf, 495 inactive_press_dpixbuf, 496 inactive_disable_dpixbuf) 497 498 self.active_pixbuf_group = (active_normal_dpixbuf, 499 active_hover_dpixbuf, 500 active_press_dpixbuf, 501 active_disable_dpixbuf) 502 503 # Init request size. 504 label_width = 0 505 button_width = inactive_normal_dpixbuf.get_pixbuf().get_width() 506 button_height = inactive_normal_dpixbuf.get_pixbuf().get_height() 507 if button_label: 508 label_width = get_content_size(button_label, font_size)[0] 509 self.set_size_request(button_width + label_width + padding_x * 2, 510 button_height) 511 512 self.connect("button-press-event", self.press_toggle_button) 513 self.connect("button-release-event", self.release_toggle_button) 514 515 # Expose button. 516 self.connect("expose-event", lambda w, e : self.expose_toggle_button( 517 w, e, 518 button_label, padding_x, font_size, label_dcolor))
519
520 - def press_toggle_button(self, widget, event):
521 ''' 522 Callback for `button-press-event` signal. 523 524 @param widget: ToggleButton widget. 525 @param event: Button press event. 526 ''' 527 self.button_press_flag = True 528 self.queue_draw()
529
530 - def release_toggle_button(self, widget, event):
531 ''' 532 Callback for `button-press-release` signal. 533 534 @param widget: ToggleButton widget. 535 @param event: Button release event. 536 ''' 537 self.button_press_flag = False 538 self.queue_draw() 539
540 - def expose_toggle_button(self, widget, event, 541 button_label, padding_x, font_size, label_dcolor):
542 ''' 543 Callback for `expose-event` signal. 544 545 @param widget: ToggleButton widget. 546 @param event: Expose event. 547 @param button_label: Button label string. 548 @param padding_x: horticultural padding value. 549 @param font_size: Font size. 550 @param label_dcolor: Label DynamicColor. 551 ''' 552 # Init. 553 inactive_normal_dpixbuf, inactive_hover_dpixbuf, inactive_press_dpixbuf, inactive_disable_dpixbuf = self.inactive_pixbuf_group 554 active_normal_dpixbuf, active_hover_dpixbuf, active_press_dpixbuf, active_disable_dpixbuf = self.active_pixbuf_group 555 rect = widget.allocation 556 image = inactive_normal_dpixbuf.get_pixbuf() 557 558 # Get pixbuf along with button's sate. 559 if widget.state == gtk.STATE_INSENSITIVE: 560 if widget.get_active(): 561 image = active_disable_dpixbuf.get_pixbuf() 562 else: 563 image = inactive_disable_dpixbuf.get_pixbuf() 564 elif widget.state == gtk.STATE_NORMAL: 565 image = inactive_normal_dpixbuf.get_pixbuf() 566 elif widget.state == gtk.STATE_PRELIGHT: 567 if not inactive_hover_dpixbuf and not active_hover_dpixbuf: 568 if widget.get_active(): 569 image = active_normal_dpixbuf.get_pixbuf() 570 else: 571 image = inactive_normal_dpixbuf.get_pixbuf() 572 else: 573 if inactive_hover_dpixbuf and active_hover_dpixbuf: 574 if widget.get_active(): 575 image = active_hover_dpixbuf.get_pixbuf() 576 else: 577 image = inactive_hover_dpixbuf.get_pixbuf() 578 elif inactive_hover_dpixbuf: 579 image = inactive_hover_dpixbuf.get_pixbuf() 580 elif active_hover_dpixbuf: 581 image = active_hover_dpixbuf.get_pixbuf() 582 elif widget.state == gtk.STATE_ACTIVE: 583 if inactive_press_dpixbuf and active_press_dpixbuf: 584 if self.button_press_flag: 585 if widget.get_active(): 586 image = active_press_dpixbuf.get_pixbuf() 587 else: 588 image = inactive_press_dpixbuf.get_pixbuf() 589 else: 590 image = active_normal_dpixbuf.get_pixbuf() 591 else: 592 image = active_normal_dpixbuf.get_pixbuf() 593 594 # Draw button. 595 cr = widget.window.cairo_create() 596 draw_pixbuf(cr, image, rect.x + padding_x, rect.y) 597 598 # Draw font. 599 if widget.state == gtk.STATE_INSENSITIVE: 600 label_color = ui_theme.get_color("disable_text").get_color() 601 else: 602 label_color = label_dcolor.get_color() 603 if button_label: 604 draw_text(cr, button_label, 605 rect.x + image.get_width() + padding_x * 2, 606 rect.y, 607 rect.width - image.get_width() - padding_x * 2, 608 rect.height, 609 font_size, 610 label_color, 611 alignment=pango.ALIGN_LEFT 612 ) 613 614 # Propagate expose to children. 615 propagate_expose(widget, event) 616 617 return True
618
619 - def set_inactive_pixbuf_group(self, new_group):
620 ''' 621 Set inactive pixbuf group. 622 623 @param new_group: Inactive pixbuf group. 624 ''' 625 self.inactive_pixbuf_group = new_group
626
627 - def set_active_pixbuf_group(self, new_group):
628 ''' 629 Set inactive pixbuf group. 630 631 @param new_group: Active pixbuf group. 632 ''' 633 self.active_pixbuf_group = new_group 634
635 -class ActionButton(gtk.Button):
636 ''' 637 ActionButton class. 638 639 @undocumented: expose_action_button 640 ''' 641
642 - def __init__(self, actions, index=0):
643 ''' 644 Initialize for ActionButton class. 645 646 @param actions: Actions for button. 647 @param index: Index default is 0. 648 ''' 649 gtk.Button.__init__(self) 650 self.actions = actions 651 self.index = index 652 653 pixbuf = self.actions[self.index][0][0].get_pixbuf() 654 self.set_size_request(pixbuf.get_width(), pixbuf.get_height()) 655 656 self.connect("expose-event", self.expose_action_button) 657 self.connect("clicked", lambda w: self.update_action_index(w))
658
659 - def update_action_index(self, widget):
660 ''' 661 Update action index of ActionButton. 662 663 @param widget: ActionButton widget. 664 ''' 665 # Call click callback. 666 self.actions[self.index][1](widget) 667 668 # Update index. 669 self.index += 1 670 if self.index >= len(self.actions): 671 self.index = 0 672 673 # Redraw. 674 self.queue_draw()
675
676 - def expose_action_button(self, widget, event):
677 ''' 678 Callback for `expose-event` signal. 679 680 @param widget: ActionButton widget. 681 @param event: Expose event. 682 @return: Always return True. 683 ''' 684 # Init. 685 cr = widget.window.cairo_create() 686 rect = widget.allocation 687 688 if widget.state == gtk.STATE_NORMAL: 689 pixbuf = self.actions[self.index][0][0].get_pixbuf() 690 elif widget.state == gtk.STATE_PRELIGHT: 691 pixbuf = self.actions[self.index][0][1].get_pixbuf() 692 elif widget.state == gtk.STATE_ACTIVE: 693 pixbuf = self.actions[self.index][0][2].get_pixbuf() 694 695 draw_pixbuf(cr, pixbuf, rect.x, rect.y) 696 697 # Propagate expose to children. 698 propagate_expose(widget, event) 699 700 return True
701 702 gobject.type_register(ActionButton) 703
704 -class CheckButton(ToggleButton):
705 ''' 706 CheckButton class. 707 ''' 708
709 - def __init__(self, label_text=None, padding_x=8):
710 ''' 711 Initialize CheckButton class. 712 713 @param label_text: Label text. 714 @param padding_x: Horticultural padding value, default is 8. 715 ''' 716 ToggleButton.__init__( 717 self, 718 ui_theme.get_pixbuf("button/check_button_inactive_normal.png"), 719 ui_theme.get_pixbuf("button/check_button_active_normal.png"), 720 ui_theme.get_pixbuf("button/check_button_inactive_hover.png"), 721 ui_theme.get_pixbuf("button/check_button_active_hover.png"), 722 ui_theme.get_pixbuf("button/check_button_inactive_press.png"), 723 ui_theme.get_pixbuf("button/check_button_active_press.png"), 724 ui_theme.get_pixbuf("button/check_button_inactive_disable.png"), 725 ui_theme.get_pixbuf("button/check_button_active_disable.png"), 726 label_text, padding_x 727 )
728 729 gobject.type_register(CheckButton) 730
731 -class RadioButton(ToggleButton):
732 ''' 733 RadioButton class. 734 735 @undocumented: click_radio_button 736 ''' 737
738 - def __init__(self, label_text=None, padding_x=8):
739 ''' 740 Initialize RadioButton class. 741 742 @param label_text: Label text. 743 @param padding_x: Horticultural padding value, default is 8. 744 ''' 745 ToggleButton.__init__( 746 self, 747 ui_theme.get_pixbuf("button/radio_button_inactive_normal.png"), 748 ui_theme.get_pixbuf("button/radio_button_active_normal.png"), 749 ui_theme.get_pixbuf("button/radio_button_inactive_hover.png"), 750 ui_theme.get_pixbuf("button/radio_button_active_hover.png"), 751 ui_theme.get_pixbuf("button/radio_button_inactive_press.png"), 752 ui_theme.get_pixbuf("button/radio_button_active_press.png"), 753 ui_theme.get_pixbuf("button/radio_button_inactive_disable.png"), 754 ui_theme.get_pixbuf("button/radio_button_active_disable.png"), 755 label_text, 756 padding_x 757 ) 758 759 self.switch_lock = False 760 self.connect("clicked", self.click_radio_button)
761
762 - def click_radio_button(self, widget):
763 ''' 764 Callback for `clicked` signal. 765 766 @param widget: RadioButton widget. 767 ''' 768 if not self.switch_lock: 769 for w in get_same_level_widgets(self): 770 w.switch_lock = True 771 w.set_active(w == self) 772 w.switch_lock = False
773 774 gobject.type_register(RadioButton) 775
776 -class DisableButton(gtk.Button):
777 ''' 778 DisableButton class. 779 780 @undocumented: expose_disable_button 781 ''' 782
783 - def __init__(self, dpixbufs):
784 ''' 785 Initialize DisableButton class. 786 787 @param dpixbufs: DyanmicPixbuf. 788 ''' 789 gtk.Button.__init__(self) 790 pixbuf = dpixbufs[0].get_pixbuf() 791 self.set_size_request(pixbuf.get_width(), pixbuf.get_height()) 792 793 widget_fix_cycle_destroy_bug(self) 794 self.connect("expose-event", lambda w, e: self.expose_disable_button(w, e, dpixbufs))
795
796 - def expose_disable_button(self, widget, event, dpixbufs):
797 ''' 798 Callback for `expose-event` signal. 799 800 @param widget: DisableButton widget. 801 @param event: Expose event. 802 @param dpixbufs: DynamicPixbufs. 803 ''' 804 # Init. 805 cr = widget.window.cairo_create() 806 rect = widget.allocation 807 (normal_dpixbuf, hover_dpixbuf, press_dpixbuf, disable_dpixbuf) = dpixbufs 808 809 # Draw. 810 if widget.state == gtk.STATE_INSENSITIVE: 811 pixbuf = disable_dpixbuf.get_pixbuf() 812 elif widget.state == gtk.STATE_NORMAL: 813 pixbuf = normal_dpixbuf.get_pixbuf() 814 elif widget.state == gtk.STATE_PRELIGHT: 815 pixbuf = hover_dpixbuf.get_pixbuf() 816 elif widget.state == gtk.STATE_ACTIVE: 817 pixbuf = press_dpixbuf.get_pixbuf() 818 819 draw_pixbuf(cr, pixbuf, rect.x, rect.y) 820 821 # Propagate expose to children. 822 propagate_expose(widget, event) 823 824 return True
825 826 gobject.type_register(DisableButton) 827
828 -class LinkButton(Label):
829 ''' 830 LinkButton click to open browser. 831 ''' 832
833 - def __init__(self, 834 text, 835 link, 836 enable_gaussian=True, 837 text_color=ui_theme.get_color("link_text")):
838 ''' 839 Initialize LinkButton class. 840 841 @param text: Link content. 842 @param link: Link address. 843 @param enable_gaussian: To enable gaussian effect on link, default is True. 844 @param text_color: Link color, just use when option enable_gaussian is False. 845 ''' 846 Label.__init__(self, text, text_color, enable_gaussian=enable_gaussian, text_size=9, 847 gaussian_radious=1, border_radious=0) 848 849 self.connect("button-press-event", lambda w, e: run_command("xdg-open %s" % link)) 850 851 set_clickable_cursor(self)
852 853 gobject.type_register(LinkButton) 854