class DroplistItem(object): '''Droplist item.''' def __init__(self, droplist, index, item, font_size, droplist_padding_x, droplist_padding_y, item_padding_left, item_padding_right, item_padding_y, max_width): '''Init droplist item.''' # Init. self.droplist = droplist self.index = index self.item = item self.font_size = font_size self.droplist_padding_x = droplist_padding_x self.droplist_padding_y = droplist_padding_y self.item_padding_left = item_padding_left self.item_padding_right = item_padding_right self.item_padding_y = item_padding_y self.subdroplist_active = False self.max_width = max_width self.arrow_padding_x = 5 # Create. if self.item: self.create_droplist_item() else: self.create_separator_item() def create_separator_item(self): '''Create separator item.''' self.item_box = HSeparator( ui_theme.get_shadow_color("h_separator").get_color_info(), self.item_padding_left, self.item_padding_y) self.item_box_height = self.item_padding_y * 2 + 1 def create_droplist_item(self): '''Create droplist item.''' # Get item information. (item_content, item_value) = self.item[0:2] # Create button. self.item_box = gtk.Button() # Expose button. self.item_box.connect( "expose-event", lambda w, e: self.expose_droplist_item( w, e, item_content)) # Wrap droplist aciton. self.item_box.connect("button-press-event", lambda w, e: self.wrap_droplist_clicked_action()) self.item_box.connect("realize", lambda w: self.realize_item_box(w, item_content)) def realize_item_box(self, widget, item_content): '''Realize item box.''' # Set button size. (width, height) = get_content_size(item_content, self.font_size) self.item_box_height = self.item_padding_y * 2 + int(height) self.item_box_width = self.item_padding_left + self.item_padding_right + int(width) if self.max_width != None: self.item_box_width = min(self.item_box_width, self.max_width) else: self.item_box_width = self.item_box_width self.item_box.set_size_request(self.item_box_width, self.item_box_height) def wrap_droplist_clicked_action(self): '''Wrap droplist action.''' # Emit item-selected signal. self.droplist.emit("item-selected", self.item[0], self.item[1], self.index) # Hide droplist. droplist_grab_window_focus_out() def expose_droplist_item(self, widget, event, item_content): '''Expose droplist item.''' # Init. cr = widget.window.cairo_create() rect = widget.allocation font_color = ui_theme.get_color("menu_font").get_color() # Draw select effect. if self.subdroplist_active or widget.state in [gtk.STATE_PRELIGHT, gtk.STATE_ACTIVE]: # Draw background. draw_vlinear(cr, rect.x, rect.y, rect.width, rect.height, ui_theme.get_shadow_color("menu_item_select").get_color_info()) # Set font color. font_color = ui_theme.get_color("menu_select_font").get_color() # Draw item content. draw_text(cr, item_content, rect.x + self.item_padding_left, rect.y, rect.width, rect.height, self.font_size, font_color, ) # Propagate expose to children. propagate_expose(widget, event) return True
class DroplistItem(object): ''' DroplistItem for L{ I{Droplist} <Droplist>}. @undocumented: create_separator_item @undocumented: create_droplist_item @undocumented: realize_item_box @undocumented: wrap_droplist_clicked_action @undocumented: expose_droplist_item ''' def __init__(self, droplist, index, item, font_size, droplist_padding_x, droplist_padding_y, item_padding_left, item_padding_right, item_padding_y, max_width, fixed_width): ''' Initialize DroplistItem class. @param droplist: Droplist. @param index: Drop item index. @param item: Drop item, format (item_content, item_value) @param font_size: Drop item font size. @param droplist_padding_x: Padding x of droplist. @param droplist_padding_y: Padding y of droplist. @param item_padding_left: Padding at left of item. @param item_padding_right: Padding at right of item. @param item_padding_y: Padding at top or bottom of item. @param max_width: Maximum width of droplist item. @param fixed_width: Fxied width of droplist item. ''' # Init. self.droplist = droplist self.index = index self.item = item self.font_size = font_size self.droplist_padding_x = droplist_padding_x self.droplist_padding_y = droplist_padding_y self.item_padding_left = item_padding_left self.item_padding_right = item_padding_right self.item_padding_y = item_padding_y self.subdroplist_active = False self.max_width = max_width self.fixed_width = fixed_width self.arrow_padding_x = 5 # Create. if self.item: self.create_droplist_item() else: self.create_separator_item() def create_separator_item(self): ''' Internal function, create separator item. ''' self.item_box = HSeparator( ui_theme.get_shadow_color("h_separator").get_color_info(), self.item_padding_left, self.item_padding_y) self.item_box_height = self.item_padding_y * 2 + 1 def create_droplist_item(self): ''' Internal function, create droplist item. ''' # Get item information. (item_content, item_value) = self.item[0:2] # Create button. self.item_box = gtk.Button() # Expose button. self.item_box.connect( "expose-event", lambda w, e: self.expose_droplist_item( w, e, item_content)) # Wrap droplist aciton. self.item_box.connect("button-press-event", lambda w, e: self.wrap_droplist_clicked_action()) self.item_box.connect("realize", lambda w: self.realize_item_box(w, item_content)) def realize_item_box(self, widget, item_content): ''' Internal function, realize item box. @param widget: DropItem widget. @param item_content: Item content. ''' # Set button size. (width, height) = get_content_size(item_content, self.font_size) self.item_box_height = self.item_padding_y * 2 + int(height) self.item_box_width = self.item_padding_left + self.item_padding_right + int(width) if self.fixed_width != None: self.item_box_width = self.fixed_width elif self.max_width != None: ''' when max_width > item_box_width, it might choosing the max one ''' self.item_box_width = max(self.item_box_width, self.max_width) else: self.item_box_width = self.item_box_width self.item_box.set_size_request(self.item_box_width, self.item_box_height) def wrap_droplist_clicked_action(self): ''' Internal function to wrap clicked action. ''' # Hide droplist. droplist_grab_window_focus_out() # Emit item-selected signal. self.droplist.emit("item-selected", self.item[0], self.item[1], self.index) def expose_droplist_item(self, widget, event, item_content): ''' Internal function to handle `expose-event` signal of item. @param widget: DropItem widget. @param event: Expose event. @param item_content: Item content. ''' # Init. cr = widget.window.cairo_create() rect = widget.allocation font_color = ui_theme.get_color("menu_font").get_color() # Draw select effect. if self.subdroplist_active or widget.state in [gtk.STATE_PRELIGHT, gtk.STATE_ACTIVE]: # Draw background. draw_vlinear(cr, rect.x, rect.y, rect.width, rect.height, ui_theme.get_shadow_color("menu_item_select").get_color_info()) # Set font color. font_color = ui_theme.get_color("menu_select_font").get_color() # Draw item content. draw_text(cr, item_content, rect.x + self.item_padding_left, rect.y, rect.width, rect.height, self.font_size, font_color, ) # Propagate expose to children. propagate_expose(widget, event) return True
class MenuItem(object): '''Menu item.''' def __init__(self, item, font_size, select_scale, show_submenu_callback, hide_submenu_callback, get_root_menu_callback, get_menu_items_callback, icon_width, icon_height, have_submenu, submenu_width, submenu_height, menu_padding_x, menu_padding_y, item_padding_x, item_padding_y, min_width): '''Init menu item.''' # Init. self.item = item self.font_size = font_size self.select_scale = select_scale self.menu_padding_x = menu_padding_x self.menu_padding_y = menu_padding_y self.item_padding_x = item_padding_x self.item_padding_y = item_padding_y self.show_submenu_callback = show_submenu_callback self.hide_submenu_callback = hide_submenu_callback self.get_root_menu_callback = get_root_menu_callback self.get_menu_items_callback = get_menu_items_callback self.icon_width = icon_width self.icon_height = icon_height self.have_submenu = have_submenu self.submenu_width = submenu_width self.submenu_height = submenu_height self.submenu_active = False self.min_width = min_width self.arrow_padding_x = 5 # Create. if self.item: self.create_menu_item() else: self.create_separator_item() def create_separator_item(self): '''Create separator item.''' self.item_box = HSeparator( ui_theme.get_shadow_color("h_separator").get_color_info(), self.item_padding_x, self.item_padding_y) self.item_box_height = self.item_padding_y * 2 + 1 def create_menu_item(self): '''Create menu item.''' # Get item information. (item_icons, item_content, item_node) = self.item[0:3] # Create button. self.item_box = gtk.Button() # Expose button. self.item_box.connect("expose-event", self.expose_menu_item) self.item_box.connect("enter-notify-event", lambda w, e: self.enter_notify_menu_item(w)) # Wrap menu aciton. self.item_box.connect("button-press-event", self.wrap_menu_clicked_action) self.item_box.connect("realize", lambda w: self.realize_item_box(w, item_content)) def realize_item_box(self, widget, item_content): '''Realize item box.''' # Set button size. (width, height) = get_content_size(item_content, self.font_size) self.item_box_height = self.item_padding_y * 2 + max(int(height), self.icon_height) if self.select_scale: self.item_box_width = widget.get_parent().get_parent().allocation.width else: self.item_box_width = self.item_padding_x * 3 + self.icon_width + int(width) if self.have_submenu: self.item_box_width += self.item_padding_x + self.submenu_width + self.arrow_padding_x * 2 self.item_box_width = max(self.item_box_width, self.min_width) self.item_box.set_size_request(self.item_box_width, self.item_box_height) def wrap_menu_clicked_action(self, button, event): '''Wrap menu action.''' item_node = self.item[2] if not isinstance(item_node, Menu): # Hide menu. menu_grab_window_focus_out() # Execute callback. if item_node: if len(self.item) > 3: item_node(*self.item[3:]) else: item_node() def expose_menu_item(self, widget, event): '''Expose menu item.''' # Init. cr = widget.window.cairo_create() rect = widget.allocation font_color = ui_theme.get_color("menu_font").get_color() (item_icons, item_content, item_node) = self.item[0:3] # Draw select effect. if self.submenu_active or widget.state in [gtk.STATE_PRELIGHT, gtk.STATE_ACTIVE]: # Draw background. draw_vlinear(cr, rect.x, rect.y, rect.width, rect.height, ui_theme.get_shadow_color("menu_item_select").get_color_info(), MENU_ITEM_RADIUS) # Set font color. font_color = ui_theme.get_color("menu_select_font").get_color() # Draw item icon. pixbuf = None pixbuf_width = 0 if item_icons: (item_normal_dpixbuf, item_hover_dpixbuf) = item_icons if self.submenu_active or widget.state in [gtk.STATE_PRELIGHT, gtk.STATE_ACTIVE]: if item_hover_dpixbuf == None: pixbuf = item_normal_dpixbuf.get_pixbuf() else: pixbuf = item_hover_dpixbuf.get_pixbuf() else: pixbuf = item_normal_dpixbuf.get_pixbuf() pixbuf_width += pixbuf.get_width() draw_pixbuf(cr, pixbuf, rect.x + self.item_padding_x, rect.y + (rect.height - pixbuf.get_height()) / 2) # Draw item content. draw_text(cr, item_content, rect.x + self.item_padding_x * 2 + self.icon_width, rect.y, rect.width, rect.height, self.font_size, font_color, ) # Draw submenu arrow. if isinstance(item_node, Menu): if self.submenu_active or widget.state in [gtk.STATE_PRELIGHT, gtk.STATE_ACTIVE]: submenu_pixbuf = ui_theme.get_pixbuf("menu/arrow_hover.png").get_pixbuf() else: submenu_pixbuf = ui_theme.get_pixbuf("menu/arrow_normal.png").get_pixbuf() draw_pixbuf(cr, submenu_pixbuf, rect.x + rect.width - self.item_padding_x - submenu_pixbuf.get_width() - self.arrow_padding_x, rect.y + (rect.height - submenu_pixbuf.get_height()) / 2) # Propagate expose to children. propagate_expose(widget, event) return True def enter_notify_menu_item(self, widget): '''Callback for `enter-notify-event` signal.''' # Reset all items in same menu. for menu_item in self.get_menu_items_callback(): if menu_item != self and menu_item.submenu_active: menu_item.submenu_active = False menu_item.item_box.queue_draw() (item_icons, item_content, item_node) = self.item[0:3] if isinstance(item_node, Menu): menu_window = self.item_box.get_toplevel() (menu_window_x, menu_window_y) = get_widget_root_coordinate(menu_window, WIDGET_POS_RIGHT_CENTER) (item_x, item_y) = get_widget_root_coordinate(self.item_box) self.show_submenu_callback( item_node, (menu_window_x - menu_window.shadow_radius, item_y - widget.get_allocation().height - menu_window.shadow_radius), self.item_box.allocation.height + menu_window.shadow_radius) self.submenu_active = True else: self.hide_submenu_callback()
class MenuItem(object): """ Menu item for L{ I{Menu} <Menu>}. @undocumented: create_separator_item @undocumented: create_menu_item @undocumented: realize_item_box @undocumented: wrap_menu_clicked_action @undocumented: expose_menu_item @undocumented: enter_notify_menu_item """ def __init__( self, item, font_size, select_scale, show_submenu_callback, hide_submenu_callback, get_root_menu_callback, get_menu_items_callback, icon_width, icon_height, have_submenu, submenu_width, submenu_height, menu_padding_x, menu_padding_y, item_padding_x, item_padding_y, min_width, menu_item_select_color=None, ): """ Initialize MenuItem class. @param item: item format: ((item_normal_dpixbuf, item_hover_dpixbuf, item_disable_dpixbuf), item_name, item_node). @param font_size: Menu font size. @param select_scale: Default is False, it will use parant's width if it set True. @param show_submenu_callback: Callback when show submenus. @param hide_submenu_callback: Callback when hide submenus. @param get_root_menu_callback: Callback to get root menu. @param get_menu_items_callback: Callback to get menu items. @param icon_width: Icon width. @param icon_height: Icon height. @param have_submenu: Whether have submenu. @param submenu_width: Width of submenu. @param submenu_height: Height of submenu. @param menu_padding_x: Horizontal padding of menu. @param menu_padding_y: Vertical padding of menu. @param item_padding_x: Horizontal padding of item. @param item_padding_y: Vertical padding of item. @param min_width: Minimum width. """ # Init. self.item = item self.font_size = font_size self.select_scale = select_scale self.menu_padding_x = menu_padding_x self.menu_padding_y = menu_padding_y self.item_padding_x = item_padding_x self.item_padding_y = item_padding_y self.show_submenu_callback = show_submenu_callback self.hide_submenu_callback = hide_submenu_callback self.get_root_menu_callback = get_root_menu_callback self.get_menu_items_callback = get_menu_items_callback self.icon_width = icon_width self.icon_height = icon_height self.have_submenu = have_submenu self.submenu_width = submenu_width self.submenu_height = submenu_height self.submenu_active = False self.min_width = min_width self.arrow_padding_x = 5 self.menu_item_select_color = menu_item_select_color # Create. if self.item: self.create_menu_item() else: self.create_separator_item() def set_item_icons(self, icons): # deepin media player modify icons. if self.item: (item_icons, item_content, item_node) = self.item[0:3] item_icons = icons if len(self.item) > 3: self.item = (item_icons, item_content, item_node, self.item[-1]) else: self.item = (item_icons, item_content, item_node) def create_separator_item(self): """ Internal function to create separator item. """ self.item_box = HSeparator( ui_theme.get_shadow_color("h_separator").get_color_info(), self.item_padding_x, self.item_padding_y ) self.item_box_height = self.item_padding_y * 2 + 1 def create_menu_item(self): """ Internal function to create menu item. """ # Get item information. (item_icons, item_content, item_node) = self.item[0:3] # Create button. self.item_box = gtk.Button() # Expose button. self.item_box.connect("expose-event", self.expose_menu_item) self.item_box.connect("enter-notify-event", lambda w, e: self.enter_notify_menu_item(w)) # Wrap menu aciton. self.item_box.connect("button-press-event", self.wrap_menu_clicked_action) self.item_box.connect("realize", lambda w: self.realize_item_box(w, item_content)) def realize_item_box(self, widget, item_content): """ Internal callback for `realize` signal. """ # Set button size. (width, height) = get_content_size(item_content, self.font_size) self.item_box_height = self.item_padding_y * 2 + max(int(height), self.icon_height) if self.select_scale: self.item_box_width = widget.get_parent().get_parent().allocation.width else: self.item_box_width = self.item_padding_x * 3 + self.icon_width + int(width) if self.have_submenu: self.item_box_width += self.item_padding_x + self.submenu_width + self.arrow_padding_x * 2 self.item_box_width = max(self.item_box_width, self.min_width) self.item_box.set_size_request(self.item_box_width, self.item_box_height) def wrap_menu_clicked_action(self, button, event): """ Internal function to wrap clicked menu action. """ item_node = self.item[2] if not isinstance(item_node, Menu): # Hide menu. menu_grab_window_focus_out() # Execute callback. if item_node: if len(self.item) > 3: item_node(*self.item[3:]) else: item_node() def expose_menu_item(self, widget, event): """ Internal callback for `expose` signal. """ # Init. cr = widget.window.cairo_create() rect = widget.allocation font_color = ui_theme.get_color("menu_font").get_color() (item_icons, item_content, item_node) = self.item[0:3] # Draw select effect. if widget.state == gtk.STATE_INSENSITIVE: # Set font color. font_color = ui_theme.get_color("menu_disable_font").get_color() elif self.submenu_active or widget.state in [gtk.STATE_PRELIGHT, gtk.STATE_ACTIVE]: # Draw background. if self.menu_item_select_color: item_select_color = self.menu_item_select_color else: item_select_color = ui_theme.get_shadow_color("menu_item_select").get_color_info() draw_vlinear(cr, rect.x, rect.y, rect.width, rect.height, item_select_color, MENU_ITEM_RADIUS) # Set font color. font_color = ui_theme.get_color("menu_select_font").get_color() # Draw item icon. pixbuf = None pixbuf_width = 0 if item_icons: (item_normal_dpixbuf, item_hover_dpixbuf, item_disable_dpixbuf) = item_icons if widget.state == gtk.STATE_INSENSITIVE: pixbuf = item_disable_dpixbuf.get_pixbuf() elif self.submenu_active or widget.state in [gtk.STATE_PRELIGHT, gtk.STATE_ACTIVE]: if item_hover_dpixbuf == None: pixbuf = item_normal_dpixbuf.get_pixbuf() else: pixbuf = item_hover_dpixbuf.get_pixbuf() else: pixbuf = item_normal_dpixbuf.get_pixbuf() pixbuf_width += pixbuf.get_width() draw_pixbuf(cr, pixbuf, rect.x + self.item_padding_x, rect.y + (rect.height - pixbuf.get_height()) / 2) # Draw item content. draw_text( cr, item_content, rect.x + self.item_padding_x * 2 + self.icon_width, rect.y, rect.width, rect.height, self.font_size, font_color, ) # Draw submenu arrow. if isinstance(item_node, Menu): if widget.state == gtk.STATE_INSENSITIVE: submenu_pixbuf = ui_theme.get_pixbuf("menu/arrow_disable.png").get_pixbuf() elif self.submenu_active or widget.state in [gtk.STATE_PRELIGHT, gtk.STATE_ACTIVE]: submenu_pixbuf = ui_theme.get_pixbuf("menu/arrow_hover.png").get_pixbuf() else: submenu_pixbuf = ui_theme.get_pixbuf("menu/arrow_normal.png").get_pixbuf() draw_pixbuf( cr, submenu_pixbuf, rect.x + rect.width - self.item_padding_x - submenu_pixbuf.get_width() - self.arrow_padding_x, rect.y + (rect.height - submenu_pixbuf.get_height()) / 2, ) # Propagate expose to children. propagate_expose(widget, event) return True def enter_notify_menu_item(self, widget): """ Internal callback for `enter-notify-event` signal. """ # Reset all items in same menu. for menu_item in self.get_menu_items_callback(): if menu_item != self and menu_item.submenu_active: menu_item.submenu_active = False menu_item.item_box.queue_draw() (item_icons, item_content, item_node) = self.item[0:3] if isinstance(item_node, Menu): if widget.state != gtk.STATE_INSENSITIVE: menu_window = self.item_box.get_toplevel() (menu_window_x, menu_window_y) = get_widget_root_coordinate(menu_window, WIDGET_POS_RIGHT_CENTER) (item_x, item_y) = get_widget_root_coordinate(self.item_box) self.show_submenu_callback( item_node, ( menu_window_x - menu_window.shadow_radius, item_y - widget.get_allocation().height - menu_window.shadow_radius, ), self.item_box.allocation.height + menu_window.shadow_radius, ) self.submenu_active = True else: self.hide_submenu_callback()
class MenuItem(object): ''' Menu item for L{ I{Menu} <Menu>}. @undocumented: create_separator_item @undocumented: create_menu_item @undocumented: realize_item_box @undocumented: wrap_menu_clicked_action @undocumented: expose_menu_item @undocumented: enter_notify_menu_item ''' def __init__(self, item, font_size, select_scale, show_submenu_callback, hide_submenu_callback, get_root_menu_callback, get_menu_items_callback, icon_width, icon_height, have_submenu, submenu_width, submenu_height, menu_padding_x, menu_padding_y, item_padding_x, item_padding_y, min_width, menu_item_select_color=None): ''' Initialize MenuItem class. @param item: item format: ((item_normal_dpixbuf, item_hover_dpixbuf, item_disable_dpixbuf), item_name, item_node). @param font_size: Menu font size. @param select_scale: Default is False, it will use parant's width if it set True. @param show_submenu_callback: Callback when show submenus. @param hide_submenu_callback: Callback when hide submenus. @param get_root_menu_callback: Callback to get root menu. @param get_menu_items_callback: Callback to get menu items. @param icon_width: Icon width. @param icon_height: Icon height. @param have_submenu: Whether have submenu. @param submenu_width: Width of submenu. @param submenu_height: Height of submenu. @param menu_padding_x: Horizontal padding of menu. @param menu_padding_y: Vertical padding of menu. @param item_padding_x: Horizontal padding of item. @param item_padding_y: Vertical padding of item. @param min_width: Minimum width. ''' # Init. self.item = item self.font_size = font_size self.select_scale = select_scale self.menu_padding_x = menu_padding_x self.menu_padding_y = menu_padding_y self.item_padding_x = item_padding_x self.item_padding_y = item_padding_y self.show_submenu_callback = show_submenu_callback self.hide_submenu_callback = hide_submenu_callback self.get_root_menu_callback = get_root_menu_callback self.get_menu_items_callback = get_menu_items_callback self.icon_width = icon_width self.icon_height = icon_height self.have_submenu = have_submenu self.submenu_width = submenu_width self.submenu_height = submenu_height self.submenu_active = False self.min_width = min_width self.arrow_padding_x = 5 self.menu_item_select_color = menu_item_select_color # Create. if self.item: self.create_menu_item() else: self.create_separator_item() def set_item_icons(self, icons): # deepin media player modify icons. if self.item: (item_icons, item_content, item_node) = self.item[0:3] item_icons = icons if len(self.item) > 3: self.item = (item_icons, item_content, item_node, self.item[-1]) else: self.item = (item_icons, item_content, item_node) def create_separator_item(self): ''' Internal function to create separator item. ''' self.item_box = HSeparator( ui_theme.get_shadow_color("h_separator").get_color_info(), self.item_padding_x, self.item_padding_y) self.item_box_height = self.item_padding_y * 2 + 1 def create_menu_item(self): ''' Internal function to create menu item. ''' # Get item information. (item_icons, item_content, item_node) = self.item[0:3] # Create button. self.item_box = gtk.Button() # Expose button. self.item_box.connect("expose-event", self.expose_menu_item) self.item_box.connect("enter-notify-event", lambda w, e: self.enter_notify_menu_item(w)) # Wrap menu aciton. self.item_box.connect("button-press-event", self.wrap_menu_clicked_action) self.item_box.connect("realize", lambda w: self.realize_item_box(w, item_content)) def realize_item_box(self, widget, item_content): ''' Internal callback for `realize` signal. ''' # Set button size. (width, height) = get_content_size(item_content, self.font_size) self.item_box_height = self.item_padding_y * 2 + max( int(height), self.icon_height) if self.select_scale: self.item_box_width = widget.get_parent().get_parent( ).allocation.width else: self.item_box_width = self.item_padding_x * 3 + self.icon_width + int( width) if self.have_submenu: self.item_box_width += self.item_padding_x + self.submenu_width + self.arrow_padding_x * 2 self.item_box_width = max(self.item_box_width, self.min_width) self.item_box.set_size_request(self.item_box_width, self.item_box_height) def wrap_menu_clicked_action(self, button, event): ''' Internal function to wrap clicked menu action. ''' item_node = self.item[2] if not isinstance(item_node, Menu): # Hide menu. menu_grab_window_focus_out() # Execute callback. if item_node: if len(self.item) > 3: item_node(*self.item[3:]) else: item_node() def expose_menu_item(self, widget, event): ''' Internal callback for `expose` signal. ''' # Init. cr = widget.window.cairo_create() rect = widget.allocation font_color = ui_theme.get_color("menu_font").get_color() (item_icons, item_content, item_node) = self.item[0:3] # Draw select effect. if widget.state == gtk.STATE_INSENSITIVE: # Set font color. font_color = ui_theme.get_color("menu_disable_font").get_color() elif self.submenu_active or widget.state in [ gtk.STATE_PRELIGHT, gtk.STATE_ACTIVE ]: # Draw background. if self.menu_item_select_color: item_select_color = self.menu_item_select_color else: item_select_color = ui_theme.get_shadow_color( "menu_item_select").get_color_info() draw_vlinear(cr, rect.x, rect.y, rect.width, rect.height, item_select_color, MENU_ITEM_RADIUS) # Set font color. font_color = ui_theme.get_color("menu_select_font").get_color() # Draw item icon. pixbuf = None pixbuf_width = 0 if item_icons: (item_normal_dpixbuf, item_hover_dpixbuf, item_disable_dpixbuf) = item_icons if widget.state == gtk.STATE_INSENSITIVE: pixbuf = item_disable_dpixbuf.get_pixbuf() elif self.submenu_active or widget.state in [ gtk.STATE_PRELIGHT, gtk.STATE_ACTIVE ]: if item_hover_dpixbuf == None: pixbuf = item_normal_dpixbuf.get_pixbuf() else: pixbuf = item_hover_dpixbuf.get_pixbuf() else: pixbuf = item_normal_dpixbuf.get_pixbuf() pixbuf_width += pixbuf.get_width() draw_pixbuf(cr, pixbuf, rect.x + self.item_padding_x, rect.y + (rect.height - pixbuf.get_height()) / 2) # Draw item content. draw_text( cr, item_content, rect.x + self.item_padding_x * 2 + self.icon_width, rect.y, rect.width, rect.height, self.font_size, font_color, ) # Draw submenu arrow. if isinstance(item_node, Menu): if widget.state == gtk.STATE_INSENSITIVE: submenu_pixbuf = ui_theme.get_pixbuf( "menu/arrow_disable.png").get_pixbuf() elif self.submenu_active or widget.state in [ gtk.STATE_PRELIGHT, gtk.STATE_ACTIVE ]: submenu_pixbuf = ui_theme.get_pixbuf( "menu/arrow_hover.png").get_pixbuf() else: submenu_pixbuf = ui_theme.get_pixbuf( "menu/arrow_normal.png").get_pixbuf() draw_pixbuf( cr, submenu_pixbuf, rect.x + rect.width - self.item_padding_x - submenu_pixbuf.get_width() - self.arrow_padding_x, rect.y + (rect.height - submenu_pixbuf.get_height()) / 2) # Propagate expose to children. propagate_expose(widget, event) return True def enter_notify_menu_item(self, widget): ''' Internal callback for `enter-notify-event` signal. ''' # Reset all items in same menu. for menu_item in self.get_menu_items_callback(): if menu_item != self and menu_item.submenu_active: menu_item.submenu_active = False menu_item.item_box.queue_draw() (item_icons, item_content, item_node) = self.item[0:3] if isinstance(item_node, Menu): if widget.state != gtk.STATE_INSENSITIVE: menu_window = self.item_box.get_toplevel() (menu_window_x, menu_window_y) = get_widget_root_coordinate( menu_window, WIDGET_POS_RIGHT_CENTER) (item_x, item_y) = get_widget_root_coordinate(self.item_box) self.show_submenu_callback( item_node, (menu_window_x - menu_window.shadow_radius, item_y - widget.get_allocation().height - menu_window.shadow_radius), self.item_box.allocation.height + menu_window.shadow_radius) self.submenu_active = True else: self.hide_submenu_callback()
class DroplistItem(object): ''' DroplistItem for L{ I{Droplist} <Droplist>}. @undocumented: create_separator_item @undocumented: create_droplist_item @undocumented: realize_item_box @undocumented: wrap_droplist_clicked_action @undocumented: expose_droplist_item ''' def __init__(self, droplist, index, item, font_size, droplist_padding_x, droplist_padding_y, item_padding_left, item_padding_right, item_padding_y, max_width, fixed_width): ''' Initialize DroplistItem class. @param droplist: Droplist. @param index: Drop item index. @param item: Drop item, format (item_content, item_value) @param font_size: Drop item font size. @param droplist_padding_x: Padding x of droplist. @param droplist_padding_y: Padding y of droplist. @param item_padding_left: Padding at left of item. @param item_padding_right: Padding at right of item. @param item_padding_y: Padding at top or bottom of item. @param max_width: Maximum width of droplist item. @param fixed_width: Fxied width of droplist item. ''' # Init. self.droplist = droplist self.index = index self.item = item self.font_size = font_size self.droplist_padding_x = droplist_padding_x self.droplist_padding_y = droplist_padding_y self.item_padding_left = item_padding_left self.item_padding_right = item_padding_right self.item_padding_y = item_padding_y self.subdroplist_active = False self.max_width = max_width self.fixed_width = fixed_width self.arrow_padding_x = 5 # Create. if self.item: self.create_droplist_item() else: self.create_separator_item() def create_separator_item(self): ''' Internal function, create separator item. ''' self.item_box = HSeparator( ui_theme.get_shadow_color("h_separator").get_color_info(), self.item_padding_left, self.item_padding_y) self.item_box_height = self.item_padding_y * 2 + 1 def create_droplist_item(self): ''' Internal function, create droplist item. ''' # Get item information. (item_content, item_value) = self.item[0:2] # Create button. self.item_box = gtk.Button() # Expose button. self.item_box.connect( "expose-event", lambda w, e: self.expose_droplist_item(w, e, item_content)) # Wrap droplist aciton. self.item_box.connect("button-press-event", lambda w, e: self.wrap_droplist_clicked_action()) self.item_box.connect("realize", lambda w: self.realize_item_box(w, item_content)) def realize_item_box(self, widget, item_content): ''' Internal function, realize item box. @param widget: DropItem widget. @param item_content: Item content. ''' # Set button size. (width, height) = get_content_size(item_content, self.font_size) self.item_box_height = self.item_padding_y * 2 + int(height) self.item_box_width = self.item_padding_left + self.item_padding_right + int( width) if self.fixed_width != None: self.item_box_width = self.fixed_width elif self.max_width != None: ''' when max_width > item_box_width, it might choosing the max one ''' self.item_box_width = max(self.item_box_width, self.max_width) else: self.item_box_width = self.item_box_width self.item_box.set_size_request(self.item_box_width, self.item_box_height) def wrap_droplist_clicked_action(self): ''' Internal function to wrap clicked action. ''' # Hide droplist. droplist_grab_window_focus_out() # Emit item-selected signal. self.droplist.emit("item-selected", self.item[0], self.item[1], self.index) def expose_droplist_item(self, widget, event, item_content): ''' Internal function to handle `expose-event` signal of item. @param widget: DropItem widget. @param event: Expose event. @param item_content: Item content. ''' # Init. cr = widget.window.cairo_create() rect = widget.allocation font_color = ui_theme.get_color("menu_font").get_color() # Draw select effect. if self.subdroplist_active or widget.state in [ gtk.STATE_PRELIGHT, gtk.STATE_ACTIVE ]: # Draw background. draw_vlinear( cr, rect.x, rect.y, rect.width, rect.height, ui_theme.get_shadow_color("menu_item_select").get_color_info()) # Set font color. font_color = ui_theme.get_color("menu_select_font").get_color() # Draw item content. draw_text( cr, item_content, rect.x + self.item_padding_left, rect.y, rect.width, rect.height, self.font_size, font_color, ) # Propagate expose to children. propagate_expose(widget, event) return True