def create_simple_button(self, name, callback=None): ''' Internal function to create simple button. ''' button = DisableButton( (ui_theme.get_pixbuf("spin/spin_arrow_%s_normal.png" % name), ui_theme.get_pixbuf("spin/spin_arrow_%s_hover.png" % name), ui_theme.get_pixbuf("spin/spin_arrow_%s_press.png" % name), ui_theme.get_pixbuf("spin/spin_arrow_%s_disable.png" % name)), ) if callback: button.connect("button-press-event", callback) button.connect("button-release-event", self.handle_key_release) return button
def create_simple_button(self, name, callback=None): button = DisableButton( ( ui_theme.get_pixbuf("spin/spin_arrow_%s_normal.png" % name), ui_theme.get_pixbuf("spin/spin_arrow_%s_hover.png" % name), ui_theme.get_pixbuf("spin/spin_arrow_%s_press.png" % name), ui_theme.get_pixbuf("spin/spin_arrow_%s_disable.png" % name), ) ) if callback: button.connect("button-press-event", callback) button.connect("button-release-event", self.handle_key_release) return button
class ComboBox(gtk.VBox): ''' ComboBox class. @undocumented: set_size_request @undocumented: auto_set_size @undocumented: on_drop_button_press @undocumented: on_combo_single_click @undocumented: on_focus_in_combo @undocumented: on_focus_out_combo @undocumented: items @undocumented: on_expose_combo_frame ''' __gsignals__ = { "item-selected" : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (str, gobject.TYPE_PYOBJECT, int,)), "key-release" : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (str, gobject.TYPE_PYOBJECT, int,)), } def __init__(self, items=[], droplist_height=None, select_index=0, max_width=None, fixed_width=None, min_width = 120, min_height = 100, editable=False, ): ''' Initialize ComboBox class. @param items: Init item list, default is empty list. @param droplist_height: The height of droplist, default is None that droplist's height will calculate with items' height automatically. @param select_index: Init index of selected item, default is 0. @param max_width: Maximum width of combobox, default is None. @param fixed_width: Fixed width of combobox, after you set this value combobox won't care the width of droplist and items, default is None. @param min_width: Minimum width of combobox, default is 120 pixels. @param min_height: Minimum height of combobox, default is 100 pixels. @param editable: Set True to make combobox can edit, default is False. ''' gtk.VBox.__init__(self) self.set_can_focus(True) # Init variables. self.focus_flag = False self.select_index = select_index self.editable = editable if self.editable: self.padding_x = 0 else: self.padding_x = 5 self.combo_list = ComboList(min_width=min_width, max_width=max_width, fixed_width=fixed_width, min_height=min_height, max_height=droplist_height) self.drop_button = DisableButton( (ui_theme.get_pixbuf("combo/dropbutton_normal.png"), ui_theme.get_pixbuf("combo/dropbutton_hover.png"), ui_theme.get_pixbuf("combo/dropbutton_press.png"), ui_theme.get_pixbuf("combo/dropbutton_disable.png")), ) self.drop_button_width = ui_theme.get_pixbuf("combo/dropbutton_normal.png").get_pixbuf().get_width() self.panel_align = gtk.Alignment() self.panel_align.set(0.5, 0.5, 0.0, 0.0) if self.editable: self.label = Entry() else: self.label = Label("", enable_select=False, enable_double_click=False) self.label.connect("button-press-event", self.on_drop_button_press) self.panel_align.set_padding(0, 0, self.padding_x, 0) self.panel_align.add(self.label) # Init items. self.add_items(items) # set selected index if len(items) > 0: self.set_select_index(select_index) hbox = gtk.HBox() hbox.pack_start(self.panel_align, True, False) hbox.pack_start(self.drop_button, False, False) box_align = gtk.Alignment() box_align.set(0.5, 0.5, 0.0, 0.0) box_align.add(hbox) self.add(box_align) # Connect signals. box_align.connect("expose-event", self.on_expose_combo_frame) self.drop_button.connect("button-press-event", self.on_drop_button_press) self.connect("focus-in-event", self.on_focus_in_combo) self.connect("focus-out-event", self.on_focus_out_combo) self.combo_list.treeview.connect("button-press-item", self.on_combo_single_click) def set_size_request(self, width, height): pass def auto_set_size(self): valid_width = self.combo_list.get_adjust_width() remained_width = valid_width - self.drop_button_width - self.padding_x if self.editable: self.label.set_size_request(remained_width, -1) else: self.label.set_fixed_width(remained_width) self.combo_list.auto_set_size() def add_items(self, items, select_index=0, pos=None, clear_first=True, ): ''' Add items with given index. @param items: Item list that need add is combo box. @param select_index: The index of select item, default is 0. @param pos: Position to insert, except you specified index, items will insert at end by default. @param clear_first: Whether clear existing items before insert anymore, default is True. ''' # Init combo widgets. if clear_first: self.combo_list.treeview.clear() combo_items = [ComboTextItem(item[0], item[1]) for item in items] self.combo_list.treeview.add_items(combo_items, insert_pos=pos) self.auto_set_size() self.set_select_index(select_index) def on_drop_button_press(self, widget, event): self.combo_list.hover_select_item() height = self.allocation.height x, y = self.window.get_root_origin() if self.combo_list.get_visible(): self.combo_list.hide() else: wx, wy = int(event.x), int(event.y) (offset_x, offset_y) = widget.translate_coordinates(self, 0, 0) (_, px, py, modifier) = widget.get_display().get_pointer() droplist_x, droplist_y = px - wx - offset_x - 1, py - wy - offset_y + height - 1 self.combo_list.show((droplist_x, droplist_y), (0, -height)) def on_combo_single_click(self, widget, item, column, x, y): self.label.set_text(item.title) self.combo_list.reset_status() if item: index = self.combo_list.get_select_index() self.combo_list.hide_self() self.emit("item-selected", item.title, item.item_value, index) def on_focus_in_combo(self, widget, event): self.focus_flag = True self.queue_draw() def on_focus_out_combo(self, widget, event): self.focus_flag = False self.queue_draw() def set_select_index(self, item_index): ''' Set select item with given index. @param item_index: The index of selected item. ''' if 0 <= item_index < len(self.items): self.combo_list.set_select_index(item_index) self.label.set_text(self.items[item_index].title) @property def items(self): return self.combo_list.items def get_item_with_index(self, item_index): ''' Get item with given index. @param item_index: The index of item that you want get. @return: Return item with given index, return None if given index is invalid. ''' if 0 <= item_index < len(self.items): item = self.items[item_index] return (item.title, item.item_value) else: return None def get_current_item(self): ''' Get current selected item. @return: Return current selected item. ''' return self.get_item_with_index(self.get_select_index()) def get_select_index(self): ''' Get index of select item. @return: Return index of selected item. ''' return self.combo_list.get_select_index() def set_sensitive(self, sensitive): super(ComboBox, self).set_sensitive(sensitive) self.label.set_sensitive(sensitive) def on_expose_combo_frame(self, widget, event): # Init. cr = widget.window.cairo_create() rect = widget.allocation # Draw frame. with cairo_disable_antialias(cr): cr.set_line_width(1) if self.get_sensitive(): cr.set_source_rgb(*color_hex_to_cairo(ui_theme.get_color("combo_entry_frame").get_color())) else: cr.set_source_rgb(*color_hex_to_cairo(ui_theme.get_color("disable_frame").get_color())) cr.rectangle(rect.x, rect.y, rect.width, rect.height) cr.stroke() if self.focus_flag: color = (ui_theme.get_color("combo_entry_select_background").get_color(), 0.9) cr.set_source_rgba(*alpha_color_hex_to_cairo(color)) cr.rectangle(rect.x, rect.y, rect.width - 1 - self.drop_button_width, rect.height - 1) cr.fill() cr.set_source_rgba(*alpha_color_hex_to_cairo((ui_theme.get_color("combo_entry_background").get_color(), 0.9))) cr.rectangle(rect.x + rect.width - 1 - self.drop_button_width, rect.y, self.drop_button_width, rect.height - 1) cr.fill() else: cr.set_source_rgba(*alpha_color_hex_to_cairo((ui_theme.get_color("combo_entry_background").get_color(), 0.9))) cr.rectangle(rect.x, rect.y, rect.width - 1, rect.height - 1) cr.fill() # Propagate expose to children. propagate_expose(widget, event) return True
class ComboBox(gtk.VBox): '''Combo box.''' __gsignals__ = { "item-selected" : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (str, gobject.TYPE_PYOBJECT, int,)), "key-release" : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (str, gobject.TYPE_PYOBJECT, int,)), } def __init__(self, items, droplist_height=None, select_index=0, max_width=None): '''Init combo box.''' # Init. gtk.VBox.__init__(self) self.set_can_focus(True) self.items = items self.droplist_height = droplist_height self.select_index = select_index self.focus_flag = False self.droplist = Droplist(self.items, max_width=max_width) if self.droplist_height: self.droplist.set_size_request(-1, self.droplist_height) self.width = self.droplist.get_droplist_width() self.height = 22 self.label_padding_left = 6 self.box = gtk.HBox() self.dropbutton_width = ui_theme.get_pixbuf("combo/dropbutton_normal.png").get_pixbuf().get_width() self.label = Label(self.items[select_index][0], label_width=self.width - self.dropbutton_width - 1 - self.label_padding_left, enable_select=False, enable_double_click=False) self.label.text_color = ui_theme.get_color("menu_font") self.dropbutton = DisableButton( (ui_theme.get_pixbuf("combo/dropbutton_normal.png"), ui_theme.get_pixbuf("combo/dropbutton_hover.png"), ui_theme.get_pixbuf("combo/dropbutton_press.png"), ui_theme.get_pixbuf("combo/dropbutton_disable.png")), ) self.align = gtk.Alignment() self.align.set(0.5, 0.5, 0.0, 0.0) self.align.set_padding(1, 1, 1 + self.label_padding_left, 1) self.pack_start(self.align, False, False) self.align.add(self.box) self.box.pack_start(self.label, False, False) self.box.pack_start(self.dropbutton, False, False) self.align.connect("expose-event", self.expose_combobox_frame) self.label.connect("button-press-event", self.click_drop_button) self.dropbutton.connect("button-press-event", self.click_drop_button) self.droplist.connect("item-selected", self.update_select_content) self.droplist.connect("key-release", lambda dl, s, o, i: self.emit("key-release", s, o, i)) self.connect("key-press-event", self.key_press_combo) self.connect("key-release-event", self.key_release_combo) self.connect("focus-in-event", self.focus_in_combo) self.connect("focus-out-event", self.focus_out_combo) self.keymap = { "Home" : self.select_first_item, "End" : self.select_last_item, "Up" : self.select_prev_item, "Down" : self.select_next_item} def focus_in_combo(self, widget, event): '''Focus in combo.''' self.focus_flag = True self.label.text_color = ui_theme.get_color("menu_select_font") self.queue_draw() def focus_out_combo(self, widget, event): '''Focus out combo.''' self.focus_flag = False self.label.text_color = ui_theme.get_color("menu_font") self.queue_draw() def click_drop_button(self, *args): '''Click drop button.''' if self.droplist.get_visible(): self.droplist.hide() else: (align_x, align_y) = get_widget_root_coordinate(self.align, WIDGET_POS_BOTTOM_LEFT) self.droplist.show( (align_x - 1, align_y - 1), (0, -self.height + 1)) self.droplist.item_select_index = self.select_index self.droplist.active_item() self.droplist.scroll_page_to_select_item() self.queue_draw() def select_first_item(self): '''Select first item.''' if len(self.droplist.droplist_items) > 0: first_index = self.droplist.get_first_index() if first_index != None: self.droplist.item_select_index = first_index self.droplist.active_item() self.droplist.droplist_items[self.droplist.item_select_index].wrap_droplist_clicked_action() def select_last_item(self): '''Select last item.''' if len(self.droplist.droplist_items) > 0: last_index = self.droplist.get_last_index() if last_index != None: self.droplist.item_select_index = last_index self.droplist.active_item() self.droplist.droplist_items[self.droplist.item_select_index].wrap_droplist_clicked_action() def select_prev_item(self): '''Select preview item.''' if len(self.droplist.droplist_items) > 0: prev_index = self.droplist.get_prev_index() if prev_index != None: self.droplist.item_select_index = prev_index self.droplist.active_item() self.droplist.droplist_items[self.droplist.item_select_index].wrap_droplist_clicked_action() def select_next_item(self): '''Select next item.''' if len(self.droplist.droplist_items) > 0: next_index = self.droplist.get_next_index() if next_index != None: self.droplist.item_select_index = next_index self.droplist.active_item() self.droplist.droplist_items[self.droplist.item_select_index].wrap_droplist_clicked_action() def key_press_combo(self, widget, event): '''Key press combo.''' if not self.droplist.get_visible(): key_name = get_keyevent_name(event) if self.keymap.has_key(key_name): self.keymap[key_name]() return True def set_select_index(self, item_index): '''Set select index.''' if 0 <= item_index < len(self.items): item = self.items[item_index] if item: self.select_index = item_index self.label.set_text(item[0]) def get_item_with_index(self, item_index): '''Get item with index.''' if 0 <= item_index < len(self.items): return self.items[item_index] else: return None def get_current_item(self): '''Get current item.''' return self.get_item_with_index(self.select_index) def key_release_combo(self, widget, event): '''Handle key release.''' self.emit("key-release", self.items[self.select_index][0], self.items[self.select_index][1], self.select_index) def update_select_content(self, droplist, item_content, item_value, item_index): '''Update select content.''' self.select_index = item_index self.label.set_text(item_content) self.emit("item-selected", item_content, item_value, item_index) self.grab_focus() self.queue_draw() def set_sensitive(self, sensitive): super(ComboBox, self).set_sensitive(sensitive) self.label.set_sensitive(sensitive) self.dropbutton.set_sensitive(sensitive) def expose_combobox_frame(self, widget, event): '''Expose combo box frame.''' # Init. cr = widget.window.cairo_create() rect = widget.allocation # Draw frame. with cairo_disable_antialias(cr): cr.set_line_width(1) if self.get_sensitive(): cr.set_source_rgb(*color_hex_to_cairo(ui_theme.get_color("combo_entry_frame").get_color())) else: cr.set_source_rgb(*color_hex_to_cairo(ui_theme.get_color("disable_frame").get_color())) cr.rectangle(rect.x, rect.y, rect.width, rect.height) cr.stroke() if self.focus_flag: cr.set_source_rgba(*alpha_color_hex_to_cairo((ui_theme.get_color("combo_entry_select_background").get_color(), 0.9))) cr.rectangle(rect.x, rect.y, rect.width - 1 - self.dropbutton_width, rect.height - 1) cr.fill() cr.set_source_rgba(*alpha_color_hex_to_cairo((ui_theme.get_color("combo_entry_background").get_color(), 0.9))) cr.rectangle(rect.x + rect.width - 1 - self.dropbutton_width, rect.y, self.dropbutton_width, rect.height - 1) cr.fill() else: cr.set_source_rgba(*alpha_color_hex_to_cairo((ui_theme.get_color("combo_entry_background").get_color(), 0.9))) cr.rectangle(rect.x, rect.y, rect.width - 1, rect.height - 1) cr.fill() # Propagate expose to children. propagate_expose(widget, event) return True
class ComboBox(gtk.VBox): ''' ComboBox class. @undocumented: set_size_request @undocumented: auto_set_size @undocumented: on_drop_button_press @undocumented: on_combo_single_click @undocumented: on_focus_in_combo @undocumented: on_focus_out_combo @undocumented: items @undocumented: on_expose_combo_frame ''' __gsignals__ = { "item-selected": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ( str, gobject.TYPE_PYOBJECT, int, )), "key-release": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ( str, gobject.TYPE_PYOBJECT, int, )), } def __init__( self, items=[], droplist_height=None, select_index=0, max_width=None, fixed_width=None, min_width=120, min_height=100, editable=False, ): ''' Initialize ComboBox class. @param items: Init item list, default is empty list. @param droplist_height: The height of droplist, default is None that droplist's height will calculate with items' height automatically. @param select_index: Init index of selected item, default is 0. @param max_width: Maximum width of combobox, default is None. @param fixed_width: Fixed width of combobox, after you set this value combobox won't care the width of droplist and items, default is None. @param min_width: Minimum width of combobox, default is 120 pixels. @param min_height: Minimum height of combobox, default is 100 pixels. @param editable: Set True to make combobox can edit, default is False. ''' gtk.VBox.__init__(self) self.set_can_focus(True) # Init variables. self.focus_flag = False self.select_index = select_index self.editable = editable if self.editable: self.padding_x = 0 else: self.padding_x = 5 self.combo_list = ComboList(min_width=min_width, max_width=max_width, fixed_width=fixed_width, min_height=min_height, max_height=droplist_height) self.drop_button = DisableButton( (ui_theme.get_pixbuf("combo/dropbutton_normal.png"), ui_theme.get_pixbuf("combo/dropbutton_hover.png"), ui_theme.get_pixbuf("combo/dropbutton_press.png"), ui_theme.get_pixbuf("combo/dropbutton_disable.png")), ) self.drop_button_width = ui_theme.get_pixbuf( "combo/dropbutton_normal.png").get_pixbuf().get_width() self.panel_align = gtk.Alignment() self.panel_align.set(0.5, 0.5, 0.0, 0.0) if self.editable: self.label = Entry() else: self.label = Label("", enable_select=False, enable_double_click=False) self.label.connect("button-press-event", self.on_drop_button_press) self.panel_align.set_padding(0, 0, self.padding_x, 0) self.panel_align.add(self.label) # Init items. self.add_items(items) # set selected index if len(items) > 0: self.set_select_index(select_index) hbox = gtk.HBox() hbox.pack_start(self.panel_align, True, False) hbox.pack_start(self.drop_button, False, False) box_align = gtk.Alignment() box_align.set(0.5, 0.5, 0.0, 0.0) box_align.add(hbox) self.add(box_align) # Connect signals. box_align.connect("expose-event", self.on_expose_combo_frame) self.drop_button.connect("button-press-event", self.on_drop_button_press) self.connect("focus-in-event", self.on_focus_in_combo) self.connect("focus-out-event", self.on_focus_out_combo) self.combo_list.treeview.connect("button-press-item", self.on_combo_single_click) def set_size_request(self, width, height): pass def auto_set_size(self): valid_width = self.combo_list.get_adjust_width() remained_width = valid_width - self.drop_button_width - self.padding_x if self.editable: self.label.set_size_request(remained_width, -1) else: self.label.set_fixed_width(remained_width) self.combo_list.auto_set_size() def add_items( self, items, select_index=0, pos=None, clear_first=True, ): ''' Add items with given index. @param items: Item list that need add is combo box. @param select_index: The index of select item, default is 0. @param pos: Position to insert, except you specified index, items will insert at end by default. @param clear_first: Whether clear existing items before insert anymore, default is True. ''' # Init combo widgets. if clear_first: self.combo_list.treeview.clear() combo_items = [ComboTextItem(item[0], item[1]) for item in items] self.combo_list.treeview.add_items(combo_items, insert_pos=pos) self.auto_set_size() self.set_select_index(select_index) def on_drop_button_press(self, widget, event): self.combo_list.hover_select_item() height = self.allocation.height x, y = self.window.get_root_origin() if self.combo_list.get_visible(): self.combo_list.hide() else: wx, wy = int(event.x), int(event.y) (offset_x, offset_y) = widget.translate_coordinates(self, 0, 0) (_, px, py, modifier) = widget.get_display().get_pointer() droplist_x, droplist_y = px - wx - offset_x - 1, py - wy - offset_y + height - 1 self.combo_list.show((droplist_x, droplist_y), (0, -height)) def on_combo_single_click(self, widget, item, column, x, y): self.label.set_text(item.title) self.combo_list.reset_status() if item: index = self.combo_list.get_select_index() self.combo_list.hide_self() self.emit("item-selected", item.title, item.item_value, index) def on_focus_in_combo(self, widget, event): self.focus_flag = True self.queue_draw() def on_focus_out_combo(self, widget, event): self.focus_flag = False self.queue_draw() def set_select_index(self, item_index): ''' Set select item with given index. @param item_index: The index of selected item. ''' if 0 <= item_index < len(self.items): self.combo_list.set_select_index(item_index) self.label.set_text(self.items[item_index].title) @property def items(self): return self.combo_list.items def get_item_with_index(self, item_index): ''' Get item with given index. @param item_index: The index of item that you want get. @return: Return item with given index, return None if given index is invalid. ''' if 0 <= item_index < len(self.items): item = self.items[item_index] return (item.title, item.item_value) else: return None def get_current_item(self): ''' Get current selected item. @return: Return current selected item. ''' return self.get_item_with_index(self.get_select_index()) def get_select_index(self): ''' Get index of select item. @return: Return index of selected item. ''' return self.combo_list.get_select_index() def set_sensitive(self, sensitive): super(ComboBox, self).set_sensitive(sensitive) self.label.set_sensitive(sensitive) def on_expose_combo_frame(self, widget, event): # Init. cr = widget.window.cairo_create() rect = widget.allocation # Draw frame. with cairo_disable_antialias(cr): cr.set_line_width(1) if self.get_sensitive(): cr.set_source_rgb(*color_hex_to_cairo( ui_theme.get_color("combo_entry_frame").get_color())) else: cr.set_source_rgb(*color_hex_to_cairo( ui_theme.get_color("disable_frame").get_color())) cr.rectangle(rect.x, rect.y, rect.width, rect.height) cr.stroke() if self.focus_flag: color = (ui_theme.get_color( "combo_entry_select_background").get_color(), 0.9) cr.set_source_rgba(*alpha_color_hex_to_cairo(color)) cr.rectangle(rect.x, rect.y, rect.width - 1 - self.drop_button_width, rect.height - 1) cr.fill() cr.set_source_rgba(*alpha_color_hex_to_cairo(( ui_theme.get_color("combo_entry_background").get_color(), 0.9))) cr.rectangle(rect.x + rect.width - 1 - self.drop_button_width, rect.y, self.drop_button_width, rect.height - 1) cr.fill() else: cr.set_source_rgba(*alpha_color_hex_to_cairo(( ui_theme.get_color("combo_entry_background").get_color(), 0.9))) cr.rectangle(rect.x, rect.y, rect.width - 1, rect.height - 1) cr.fill() # Propagate expose to children. propagate_expose(widget, event) return True