class TrayIcon(Gtk.ToolItem): __gtype_name__ = 'SugarTrayIcon' def __init__(self, icon_name=None, xo_color=None): Gtk.ToolItem.__init__(self) self._icon_widget = _IconWidget(icon_name, xo_color) self.add(self._icon_widget) self._icon_widget.show() self._palette_invoker = ToolInvoker(self) self.set_size_request(style.GRID_CELL_SIZE, style.GRID_CELL_SIZE) self.connect('destroy', self.__destroy_cb) def __destroy_cb(self, icon): if self._palette_invoker is not None: self._palette_invoker.detach() def create_palette(self): return None def get_palette(self): return self._palette_invoker.palette def set_palette(self, palette): self._palette_invoker.palette = palette palette = GObject.property(type=object, setter=set_palette, getter=get_palette) def get_palette_invoker(self): return self._palette_invoker def set_palette_invoker(self, palette_invoker): self._palette_invoker.detach() self._palette_invoker = palette_invoker palette_invoker = GObject.property(type=object, setter=set_palette_invoker, getter=get_palette_invoker) def get_icon(self): return self._icon_widget.get_icon() icon = property(get_icon, None)
class TrayIcon(Gtk.ToolItem): __gtype_name__ = 'SugarTrayIcon' def __init__(self, icon_name=None, xo_color=None): Gtk.ToolItem.__init__(self) self._icon_widget = _IconWidget(icon_name, xo_color) self.add(self._icon_widget) self._icon_widget.show() self._palette_invoker = ToolInvoker(self) self.set_size_request(style.GRID_CELL_SIZE, style.GRID_CELL_SIZE) self.connect('destroy', self.__destroy_cb) def __destroy_cb(self, icon): if self._palette_invoker is not None: self._palette_invoker.detach() def create_palette(self): return None def get_palette(self): return self._palette_invoker.palette def set_palette(self, palette): self._palette_invoker.palette = palette palette = GObject.property( type=object, setter=set_palette, getter=get_palette) def get_palette_invoker(self): return self._palette_invoker def set_palette_invoker(self, palette_invoker): self._palette_invoker.detach() self._palette_invoker = palette_invoker palette_invoker = GObject.property( type=object, setter=set_palette_invoker, getter=get_palette_invoker) def get_icon(self): return self._icon_widget.get_icon() icon = property(get_icon, None)
class ColorToolButton(Gtk.ToolItem): # This not ideal. It would be better to subclass Gtk.ToolButton, however # the python bindings do not seem to be powerfull enough for that. # (As we need to change a variable in the class structure.) __gtype_name__ = 'SugarColorToolButton' __gsignals__ = {'color-set': (GObject.SignalFlags.RUN_FIRST, None, tuple())} def __init__(self, icon_name='color-preview', **kwargs): self._accelerator = None self._tooltip = None self._palette_invoker = ToolInvoker() self._palette = None GObject.GObject.__init__(self, **kwargs) # The Gtk.ToolButton has already added a normal button. # Replace it with a ColorButton color_button = _ColorButton(icon_name=icon_name, has_invoker=False) self.add(color_button) color_button.show() # The following is so that the behaviour on the toolbar is correct. color_button.set_relief(Gtk.ReliefStyle.NONE) color_button.icon_size = style.STANDARD_ICON_SIZE self._palette_invoker.attach_tool(self) self._palette_invoker.props.toggle_palette = True self._palette_invoker.props.lock_palette = True # This widget just proxies the following properties to the colorbutton color_button.connect('notify::color', self.__notify_change) color_button.connect('notify::icon-name', self.__notify_change) color_button.connect('notify::icon-size', self.__notify_change) color_button.connect('notify::title', self.__notify_change) color_button.connect('color-set', self.__color_set_cb) color_button.connect('can-activate-accel', self.__button_can_activate_accel_cb) def __button_can_activate_accel_cb(self, button, signal_id): # Accept activation via accelerators regardless of this widget's state return True def set_accelerator(self, accelerator): ''' Sets keyboard shortcut that activates this button. Args: accelerator(string): accelerator to be set. Should be in form <modifier>Letter Find about format here : https://developer.gnome.org/gtk3/stable/gtk3-Keyboard-Accelerators.html#gtk-accelerator-parse Example: set_accelerator(self, 'accel') ''' self._accelerator = accelerator setup_accelerator(self) def get_accelerator(self): ''' Returns the above accelerator string. ''' return self._accelerator accelerator = GObject.Property(type=str, setter=set_accelerator, getter=get_accelerator) def create_palette(self): ''' The create_palette function is called when the palette needs to be invoked. For example, when the user has right clicked the icon or the user has hovered over the icon for a long time. The create_palette will only be called once or zero times. The palette returned will be stored and re-used if the user invokes the palette multiple times. Your create_palette implementation does not need to :any:`Gtk.Widget.show` the palette, as this will be done by the invoker. However, you still need to show the menu items, etc that you place in the palette. Returns: sugar3.graphics.palette.Palette, or None to indicate that you do not want a palette shown The default implementation returns None, to indicate no palette should be shown. ''' self._palette = self.get_child().create_palette() return self._palette def get_palette_invoker(self): return self._palette_invoker def set_palette_invoker(self, palette_invoker): self._palette_invoker.detach() self._palette_invoker = palette_invoker palette_invoker = GObject.Property( type=object, setter=set_palette_invoker, getter=get_palette_invoker) def set_expanded(self, expanded): box = self.toolbar_box if not box: return if not expanded: self._palette_invoker.notify_popdown() return if box.expanded_button is not None: box.expanded_button.queue_draw() if box.expanded_button != self: box.expanded_button.set_expanded(False) box.expanded_button = self def get_toolbar_box(self): parent = self.get_parent() if not hasattr(parent, 'owner'): return None return parent.owner toolbar_box = property(get_toolbar_box) def set_color(self, color): ''' Sets the color of the colorbutton ''' self.get_child().props.color = color def get_color(self): ''' Gets the above set color string. ''' return self.get_child().props.color color = GObject.Property(type=object, getter=get_color, setter=set_color) def set_icon_name(self, icon_name): ''' Sets the icon for the tool button from a named themed icon. If it is none then no icon will be shown. Args: icon_name(string): The name for a themed icon. It can be set as 'None' too. Example: set_icon_name('view-radial') ''' self.get_child().props.icon_name = icon_name def get_icon_name(self): ''' The get_icon_name() method returns the value of the icon_name property that contains the name of a themed icon or None. ''' return self.get_child().props.icon_name icon_name = GObject.Property(type=str, getter=get_icon_name, setter=set_icon_name) def set_icon_size(self, icon_size): ''' Sets the size of icons in the colorbutton. ''' self.get_child().props.icon_size = icon_size def get_icon_size(self): ''' Gets the size of icons in the colorbutton. ''' return self.get_child().props.icon_size icon_size = GObject.Property(type=int, getter=get_icon_size, setter=set_icon_size) def set_title(self, title): ''' The set_title() method sets the "title" property to the value of title. The "title" property contains the string that is used to set the colorbutton title. ''' self.get_child().props.title = title def get_title(self): ''' Return the above title string. ''' return self.get_child().props.title title = GObject.Property(type=str, getter=get_title, setter=set_title) def do_draw(self, cr): if self._palette and self._palette.is_up(): allocation = self.get_allocation() # draw a black background, has been done by the engine before cr.set_source_rgb(0, 0, 0) cr.rectangle(0, 0, allocation.width, allocation.height) cr.paint() Gtk.ToolItem.do_draw(self, cr) if self._palette and self._palette.is_up(): invoker = self._palette.props.invoker invoker.draw_rectangle(cr, self._palette) return False def __notify_change(self, widget, pspec): self.notify(pspec.name) def __color_set_cb(self, widget): self.emit('color-set')
class FilterToolItem(Gtk.ToolButton): _LABEL_MAX_WIDTH = 18 _MAXIMUM_PALETTE_COLUMNS = 4 __gsignals__ = { 'changed': (GObject.SignalFlags.RUN_LAST, None, ([str])), } def __init__(self, default_icon, default_value, options, palette_title): self._palette_invoker = ToolInvoker() self._options = options self._palette_title = palette_title Gtk.ToolButton.__init__(self) self._value = default_value self._label = self._options[default_value] self.set_is_important(True) self.set_size_request(style.GRID_CELL_SIZE, -1) self._label_widget = Gtk.Label() self._label_widget.set_alignment(0.0, 0.5) self._label_widget.set_ellipsize(Pango.EllipsizeMode.MIDDLE) self._label_widget.set_max_width_chars(self._LABEL_MAX_WIDTH) self._label_widget.set_use_markup(True) self._label_widget.set_markup(self._label) self.set_label_widget(self._label_widget) self._label_widget.show() self.set_widget_icon(icon_name=default_icon) self._hide_tooltip_on_click = True self._palette_invoker.attach_tool(self) self._palette_invoker.props.toggle_palette = True self._palette_invoker.props.lock_palette = True self.palette = Palette(self._palette_title) self.palette.set_invoker(self._palette_invoker) self.props.palette.set_content(self.set_palette_list(options)) def set_options(self, options): self._options = options self.palette = Palette(self._palette_title) self.palette.set_invoker(self._palette_invoker) self.props.palette.set_content(self.set_palette_list(options)) if self._value not in list(self._options.keys()): new_value = list(self._options.keys())[0] self._value = new_value self._set_widget_label(self._options[new_value]) self.emit('changed', new_value) def set_widget_icon(self, icon_name=None): icon = Icon(icon_name=icon_name, pixel_size=style.SMALL_ICON_SIZE) self.set_icon_widget(icon) icon.show() def _set_widget_label(self, label=None): # FIXME: Ellipsis is not working on these labels. if label is None: label = self._label if len(label) > self._LABEL_MAX_WIDTH: label = label[0:7] + '...' + label[-7:] self._label_widget.set_markup(label) self._label = label def __destroy_cb(self, icon): if self._palette_invoker is not None: self._palette_invoker.detach() def create_palette(self): return None def get_palette(self): return self._palette_invoker.palette def set_palette(self, palette): self._palette_invoker.palette = palette palette = GObject.property(type=object, setter=set_palette, getter=get_palette) def get_palette_invoker(self): return self._palette_invoker def set_palette_invoker(self, palette_invoker): self._palette_invoker.detach() self._palette_invoker = palette_invoker palette_invoker = GObject.property(type=object, setter=set_palette_invoker, getter=get_palette_invoker) def do_draw(self, cr): if self.palette and self.palette.is_up(): allocation = self.get_allocation() # draw a black background, has been done by the engine before cr.set_source_rgb(0, 0, 0) cr.rectangle(0, 0, allocation.width, allocation.height) cr.paint() Gtk.ToolButton.do_draw(self, cr) if self.palette and self.palette.is_up(): invoker = self.palette.props.invoker invoker.draw_rectangle(cr, self.palette) return False def set_palette_list(self, options): _menu_item = PaletteMenuItem( text_label=options[list(options.keys())[0]]) req2 = _menu_item.get_preferred_size()[1] menuitem_width = req2.width menuitem_height = req2.height palette_width = Gdk.Screen.width() - style.GRID_CELL_SIZE palette_height = Gdk.Screen.height() - style.GRID_CELL_SIZE * 3 nx = min(self._MAXIMUM_PALETTE_COLUMNS, int(palette_width / menuitem_width)) ny = min(int(palette_height / menuitem_height), len(options) + 1) if ny >= len(options): nx = 1 ny = len(options) grid = Gtk.Grid() grid.set_row_spacing(style.DEFAULT_PADDING) grid.set_column_spacing(0) grid.set_border_width(0) grid.show() x = 0 y = 0 for key in sorted(options): menu_item = PaletteMenuItem() menu_item.set_label(options[key]) menu_item.set_size_request(style.GRID_CELL_SIZE * 3, -1) menu_item.connect('button-release-event', self._option_selected, key) grid.attach(menu_item, x, y, 1, 1) x += 1 if x == nx: x = 0 y += 1 menu_item.show() if palette_height < (y * menuitem_height + style.GRID_CELL_SIZE): # if the grid is bigger than the palette, put in a scrolledwindow scrolled_window = Gtk.ScrolledWindow() scrolled_window.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) scrolled_window.set_size_request(nx * menuitem_width, (ny + 1) * menuitem_height) scrolled_window.add_with_viewport(grid) return scrolled_window else: return grid def _option_selected(self, menu_item, event, key): self._set_widget_label(self._options[key]) self._value = key self.emit('changed', key)
class ToolButton(Gtk.ToolButton): __gtype_name__ = 'SugarToolButton' def __init__(self, icon_name=None, **kwargs): self._accelerator = None self._tooltip = None self._palette_invoker = ToolInvoker() GObject.GObject.__init__(self, **kwargs) self._hide_tooltip_on_click = True self._palette_invoker.attach_tool(self) if icon_name: self.set_icon_name(icon_name) self.get_child().connect('can-activate-accel', self.__button_can_activate_accel_cb) self.connect('destroy', self.__destroy_cb) def __destroy_cb(self, icon): if self._palette_invoker is not None: self._palette_invoker.detach() def __button_can_activate_accel_cb(self, button, signal_id): # Accept activation via accelerators regardless of this widget's state return True def set_tooltip(self, tooltip): """ Set a simple palette with just a single label. """ if self.palette is None or self._tooltip is None: self.palette = Palette(tooltip) elif self.palette is not None: self.palette.set_primary_text(tooltip) self._tooltip = tooltip # Set label, shows up when toolbar overflows Gtk.ToolButton.set_label(self, tooltip) def get_tooltip(self): return self._tooltip tooltip = GObject.property(type=str, setter=set_tooltip, getter=get_tooltip) def get_hide_tooltip_on_click(self): return self._hide_tooltip_on_click def set_hide_tooltip_on_click(self, hide_tooltip_on_click): if self._hide_tooltip_on_click != hide_tooltip_on_click: self._hide_tooltip_on_click = hide_tooltip_on_click hide_tooltip_on_click = GObject.property( type=bool, default=True, getter=get_hide_tooltip_on_click, setter=set_hide_tooltip_on_click) def set_accelerator(self, accelerator): self._accelerator = accelerator setup_accelerator(self) def get_accelerator(self): return self._accelerator accelerator = GObject.property(type=str, setter=set_accelerator, getter=get_accelerator) def set_icon_name(self, icon_name): icon = Icon(icon_name=icon_name) self.set_icon_widget(icon) icon.show() def get_icon_name(self): if self.props.icon_widget is not None: return self.props.icon_widget.props.icon_name else: return None icon_name = GObject.property(type=str, setter=set_icon_name, getter=get_icon_name) def create_palette(self): return None def get_palette(self): return self._palette_invoker.palette def set_palette(self, palette): self._palette_invoker.palette = palette palette = GObject.property( type=object, setter=set_palette, getter=get_palette) def get_palette_invoker(self): return self._palette_invoker def set_palette_invoker(self, palette_invoker): self._palette_invoker.detach() self._palette_invoker = palette_invoker palette_invoker = GObject.property( type=object, setter=set_palette_invoker, getter=get_palette_invoker) def do_draw(self, cr): child = self.get_child() if self.palette and self.palette.is_up(): allocation = self.get_allocation() # draw a black background, has been done by the engine before cr.set_source_rgb(0, 0, 0) cr.rectangle(0, 0, allocation.width, allocation.height) cr.paint() Gtk.ToolButton.do_draw(self, cr) if self.palette and self.palette.is_up(): invoker = self.palette.props.invoker invoker.draw_rectangle(cr, self.palette) return False def do_clicked(self): if self._hide_tooltip_on_click and self.palette: self.palette.popdown(True)
class FilterToolItem(Gtk.ToolButton): __gsignals__ = { 'changed': (GObject.SignalFlags.RUN_LAST, None, ([])), } def __init__(self, tagline, default_icon, default_label, palette_content): self._palette_invoker = ToolInvoker() Gtk.ToolButton.__init__(self) self._label = default_label self.set_is_important(False) self.set_size_request(style.GRID_CELL_SIZE, -1) self._label_widget = Gtk.Label() self._label_widget.set_alignment(0.0, 0.5) self._label_widget.set_ellipsize(Pango.EllipsizeMode.MIDDLE) self._label_widget.set_max_width_chars(10) self._label_widget.set_use_markup(True) self._label_widget.set_markup(default_label) self.set_label_widget(self._label_widget) self._label_widget.show() self.set_widget_icon(icon_name=default_icon) self._hide_tooltip_on_click = True self._palette_invoker.attach_tool(self) self._palette_invoker.props.toggle_palette = True self._palette_invoker.props.lock_palette = True self.palette = Palette(tagline) self.palette.set_invoker(self._palette_invoker) self.props.palette.set_content(palette_content) def set_widget_icon(self, icon_name=None, file_name=None): if file_name is not None: icon = Icon(file=file_name, pixel_size=style.SMALL_ICON_SIZE, xo_color=XoColor('white')) else: icon = Icon(icon_name=icon_name, pixel_size=style.SMALL_ICON_SIZE, xo_color=XoColor('white')) self.set_icon_widget(icon) icon.show() def set_widget_label(self, label=None): # FIXME: Ellipsis is not working on these labels. if label is None: label = self._label """ if len(label) > 10: label = label[0:7] + '...' + label[-7:] """ self._label_widget.set_markup(label) self._label = label def __destroy_cb(self, icon): if self._palette_invoker is not None: self._palette_invoker.detach() def create_palette(self): return None def get_palette(self): return self._palette_invoker.palette def set_palette(self, palette): self._palette_invoker.palette = palette palette = GObject.Property(type=object, setter=set_palette, getter=get_palette) def get_palette_invoker(self): return self._palette_invoker def set_palette_invoker(self, palette_invoker): self._palette_invoker.detach() self._palette_invoker = palette_invoker palette_invoker = GObject.Property(type=object, setter=set_palette_invoker, getter=get_palette_invoker) def do_draw(self, cr): if self.palette and self.palette.is_up(): allocation = self.get_allocation() # draw a black background, has been done by the engine before cr.set_source_rgb(0, 0, 0) cr.rectangle(0, 0, allocation.width, allocation.height) cr.paint() Gtk.ToolButton.do_draw(self, cr) if self.palette and self.palette.is_up(): invoker = self.palette.props.invoker invoker.draw_rectangle(cr, self.palette) return False
class FilterToolItem(Gtk.ToolButton): _LABEL_MAX_WIDTH = 18 _MAXIMUM_PALETTE_COLUMNS = 4 __gsignals__ = { 'changed': (GObject.SignalFlags.RUN_LAST, None, ([str])), } def __init__(self, default_icon, default_value, options): self._palette_invoker = ToolInvoker() self._options = options Gtk.ToolButton.__init__(self) logging.debug('filter options %s', options) self._value = default_value self._label = self._options[default_value] self.set_is_important(True) self.set_size_request(style.GRID_CELL_SIZE, -1) self._label_widget = Gtk.Label() self._label_widget.set_alignment(0.0, 0.5) self._label_widget.set_ellipsize(Pango.EllipsizeMode.MIDDLE) self._label_widget.set_max_width_chars(self._LABEL_MAX_WIDTH) self._label_widget.set_use_markup(True) self._label_widget.set_markup(self._label) self.set_label_widget(self._label_widget) self._label_widget.show() self.set_widget_icon(icon_name=default_icon) self._hide_tooltip_on_click = True self._palette_invoker.attach_tool(self) self._palette_invoker.props.toggle_palette = True self._palette_invoker.props.lock_palette = True self.palette = Palette(_('Select language')) self.palette.set_invoker(self._palette_invoker) self.props.palette.set_content(self.set_palette_list(options)) def set_options(self, options): self._options = options self.palette = Palette(_('Select language')) self.palette.set_invoker(self._palette_invoker) self.props.palette.set_content(self.set_palette_list(options)) if self._value not in self._options.keys(): new_value = self._options.keys()[0] self._value = new_value self._set_widget_label(self._options[new_value]) self.emit('changed', new_value) def set_widget_icon(self, icon_name=None): icon = Icon(icon_name=icon_name, pixel_size=style.SMALL_ICON_SIZE) self.set_icon_widget(icon) icon.show() def _set_widget_label(self, label=None): # FIXME: Ellipsis is not working on these labels. if label is None: label = self._label if len(label) > self._LABEL_MAX_WIDTH: label = label[0:7] + '...' + label[-7:] self._label_widget.set_markup(label) self._label = label def __destroy_cb(self, icon): if self._palette_invoker is not None: self._palette_invoker.detach() def create_palette(self): return None def get_palette(self): return self._palette_invoker.palette def set_palette(self, palette): self._palette_invoker.palette = palette palette = GObject.property( type=object, setter=set_palette, getter=get_palette) def get_palette_invoker(self): return self._palette_invoker def set_palette_invoker(self, palette_invoker): self._palette_invoker.detach() self._palette_invoker = palette_invoker palette_invoker = GObject.property( type=object, setter=set_palette_invoker, getter=get_palette_invoker) def do_draw(self, cr): if self.palette and self.palette.is_up(): allocation = self.get_allocation() # draw a black background, has been done by the engine before cr.set_source_rgb(0, 0, 0) cr.rectangle(0, 0, allocation.width, allocation.height) cr.paint() Gtk.ToolButton.do_draw(self, cr) if self.palette and self.palette.is_up(): invoker = self.palette.props.invoker invoker.draw_rectangle(cr, self.palette) return False def set_palette_list(self, options): _menu_item = PaletteMenuItem(text_label=options[options.keys()[0]]) req2 = _menu_item.get_preferred_size()[1] menuitem_width = req2.width menuitem_height = req2.height palette_width = Gdk.Screen.width() - style.GRID_CELL_SIZE palette_height = Gdk.Screen.height() - style.GRID_CELL_SIZE * 3 nx = min(self._MAXIMUM_PALETTE_COLUMNS, int(palette_width / menuitem_width)) ny = min(int(palette_height / menuitem_height), len(options) + 1) if ny >= len(options): nx = 1 ny = len(options) grid = Gtk.Grid() grid.set_row_spacing(style.DEFAULT_PADDING) grid.set_column_spacing(0) grid.set_border_width(0) grid.show() x = 0 y = 0 for key in options.keys(): menu_item = PaletteMenuItem() menu_item.set_label(options[key]) menu_item.set_size_request(style.GRID_CELL_SIZE * 3, -1) menu_item.connect('button-release-event', self._option_selected, key) grid.attach(menu_item, x, y, 1, 1) x += 1 if x == nx: x = 0 y += 1 menu_item.show() if palette_height < (y * menuitem_height + style.GRID_CELL_SIZE): # if the grid is bigger than the palette, put in a scrolledwindow scrolled_window = Gtk.ScrolledWindow() scrolled_window.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) scrolled_window.set_size_request(nx * menuitem_width, (ny + 1) * menuitem_height) scrolled_window.add_with_viewport(grid) return scrolled_window else: return grid def _option_selected(self, menu_item, event, key): self._set_widget_label(self._options[key]) self._value = key self.emit('changed', key)
class IntensitySelector(Gtk.ToolItem): __gsignals__ = { 'changed': (GObject.SignalFlags.RUN_LAST, None, ([])), } def __init__(self, value_range, default_value, default_image): Gtk.ToolItem.__init__(self) self._palette_invoker = ToolInvoker() self.palette = None self._values = value_range self._palette_invoker.attach_tool(self) # theme the buttons, can be removed if add the style to the sugar css # these are the same values used in gtk-widgets.css.em if style.zoom(100) == 100: subcell_size = 15 default_padding = 6 else: subcell_size = 11 default_padding = 4 hbox = Gtk.HBox() vbox = Gtk.VBox() self.add(vbox) # add a vbox to set the padding up and down vbox.pack_start(hbox, True, True, default_padding) self._size_down = ToolButton('go-previous-paired') self._palette_invoker.attach_tool(self._size_down) self._size_down.set_can_focus(False) self._size_down.connect('clicked', self.__value_changed_cb, False) hbox.pack_start(self._size_down, False, False, 5) # TODO: default? self._default_value = default_value self._value = self._default_value self.image_wrapper = Gtk.EventBox() self._intensityImage = Gtk.Image() self.image_wrapper.add(self._intensityImage) self.image_wrapper.show() self._intensityImage.set_from_file(default_image) self._intensityImage.show() self._palette_invoker.attach_widget(self.image_wrapper) hbox.pack_start(self.image_wrapper, False, False, 10) self._size_up = ToolButton('go-next-paired') self._palette_invoker.attach_tool(self._size_up) self._size_up.set_can_focus(False) self._size_up.connect('clicked', self.__value_changed_cb, True) hbox.pack_start(self._size_up, False, False, 5) radius = 2 * subcell_size theme_up = "GtkButton {border-radius:0px %dpx %dpx 0px;}" % (radius, radius) css_provider_up = Gtk.CssProvider() css_provider_up.load_from_data(theme_up) style_context = self._size_up.get_style_context() style_context.add_provider(css_provider_up, Gtk.STYLE_PROVIDER_PRIORITY_USER) theme_down = "GtkButton {border-radius: %dpx 0px 0px %dpx;}" % (radius, radius) css_provider_down = Gtk.CssProvider() css_provider_down.load_from_data(theme_down) style_context = self._size_down.get_style_context() style_context.add_provider(css_provider_down, Gtk.STYLE_PROVIDER_PRIORITY_USER) self.show_all() def __destroy_cb(self, **args): if self._palette_invoker is not None: self._palette_invoker.detach() def __value_changed_cb(self, button, increase): if self._value in self._values: i = self._values.index(self._value) if increase: if i < len(self._values) - 1: i += 1 else: if i > 0: i -= 1 else: i = self._values.index(self._default_value) self._value = self._values[i] self._size_down.set_sensitive(i != 0) self._size_up.set_sensitive(i < len(self._values) - 1) self.emit('changed') def set_value(self, val): if val not in self._values: # assure the val assigned is in the range # if not, assign one close. for v in self._values: if v > val: val = v break if val > self._values[-1]: size = self._values[-1] self._value = size self._size_label.set_text(str(self._value)) # update the buttons states i = self._values.index(self._value) self._size_down.set_sensitive(i != 0) self._size_up.set_sensitive(i < len(self._value) - 1) self.emit('changed') def set_tooltip(self, tooltip): """ Set a simple palette with just a single label. """ if self.palette is None or self._tooltip is None: self.palette = Palette(tooltip) elif self.palette is not None: self.palette.set_primary_text(tooltip) self._tooltip = tooltip def get_hide_tooltip_on_click(self): return self._hide_tooltip_on_click def set_hide_tooltip_on_click(self, hide_tooltip_on_click): if self._hide_tooltip_on_click != hide_tooltip_on_click: self._hide_tooltip_on_click = hide_tooltip_on_click hide_tooltip_on_click = GObject.Property( type=bool, default=True, getter=get_hide_tooltip_on_click, setter=set_hide_tooltip_on_click) def get_tooltip(self): return self._tooltip def create_palette(self): return None def get_palette(self): return self._palette_invoker.palette def set_palette(self, palette): self._palette_invoker.palette = palette palette = GObject.Property( type=object, setter=set_palette, getter=get_palette) def get_palette_invoker(self): return self._palette_invoker def set_palette_invoker(self, palette_invoker): self._palette_invoker.detach() self._palette_invoker = palette_invoker palette_invoker = GObject.Property( type=object, setter=set_palette_invoker, getter=get_palette_invoker) def do_draw(self, cr): Gtk.ToolButton.do_draw(self, cr) if self.palette and self.palette.is_up(): invoker = self.palette.props.invoker invoker.draw_rectangle(cr, self.palette) return False def do_clicked(self): if self._hide_tooltip_on_click and self.palette: self.palette.popdown(True) def set_image(self, image): self._intensityImage.set_from_file(image) def get_value(self): return self._value
class PaletteBox(Gtk.ToolItem): __gsignals__ = { 'changed': (GObject.SignalFlags.RUN_LAST, None, ([])), } def __init__(self, default, options): self._palette_invoker = ToolInvoker() Gtk.ToolItem.__init__(self) self._label = Gtk.Label() bt = Gtk.Button('') bt.set_can_focus(False) bt.remove(bt.get_children()[0]) self._box = Gtk.HBox() bt.add(self._box) self._icon = Icon(icon_name='') self._box.pack_start(self._icon, False, False, 5) self._box.pack_end(self._label, False, False, 5) self.add(bt) self.show_all() # theme the button, can be removed if add the style to the sugar css if style.zoom(100) == 100: subcell_size = 15 else: subcell_size = 11 radius = 2 * subcell_size theme = "GtkButton {border-radius: %dpx;}" % radius css_provider = Gtk.CssProvider() css_provider.load_from_data(theme) style_context = bt.get_style_context() style_context.add_provider(css_provider, Gtk.STYLE_PROVIDER_PRIORITY_USER) # init palette self._hide_tooltip_on_click = True self._palette_invoker.attach_tool(self) self._palette_invoker.props.toggle_palette = True self.palette = Palette(_('Select option')) self.palette.set_invoker(self._palette_invoker) # load the fonts in the palette menu self._menu_box = PaletteMenuBox() self.props.palette.set_content(self._menu_box) self._menu_box.show() for option in options: if option.__class__ is str: self._add_menu(option, activate_cb=self.__option_selected_cb) else: self._add_menu(option[0], icon=option[1], activate_cb=self.__option_selected_cb) self.set_value(default) def _set_icon(self, icon_name): self._box.remove(self._box.get_children()[0]) self._icon = Icon(icon_name=icon_name, pixel_size=style.STANDARD_ICON_SIZE) self._icon.show() self._box.pack_start(self._icon, False, False, 5) def __option_selected_cb(self, menu, option): self.set_value(option) self.emit('changed') def _add_menu(self, option, icon=None, activate_cb=None): if icon is not None: menu_item = PaletteMenuItem(icon_name=icon) if activate_cb is not None: menu_item.connect('activate', activate_cb, [option, icon]) else: menu_item = PaletteMenuItem() if activate_cb is not None: menu_item.connect('activate', activate_cb, option) menu_item.set_label(option) self._menu_box.append_item(menu_item) menu_item.show() def __destroy_cb(self, icon): if self._palette_invoker is not None: self._palette_invoker.detach() def create_palette(self): return None def get_palette(self): return self._palette_invoker.palette def set_palette(self, palette): self._palette_invoker.palette = palette palette = GObject.property( type=object, setter=set_palette, getter=get_palette) def get_palette_invoker(self): return self._palette_invoker def set_palette_invoker(self, palette_invoker): self._palette_invoker.detach() self._palette_invoker = palette_invoker palette_invoker = GObject.property( type=object, setter=set_palette_invoker, getter=get_palette_invoker) def set_value(self, value): self._value = value if value.__class__ is str: self._label.set_text(value) else: self._label.set_text(value[0]) self._set_icon(value[1]) def get_value(self): return self._value
class ToggleToolButton(Gtk.ToggleToolButton): __gtype_name__ = 'SugarToggleToolButton' def __init__(self, icon_name=None): GObject.GObject.__init__(self) self._palette_invoker = ToolInvoker(self) if icon_name: self.set_icon_name(icon_name) self.connect('destroy', self.__destroy_cb) def __destroy_cb(self, icon): if self._palette_invoker is not None: self._palette_invoker.detach() def set_icon_name(self, icon_name): icon = Icon(icon_name=icon_name) self.set_icon_widget(icon) icon.show() def get_icon_name(self): if self.props.icon_widget is not None: return self.props.icon_widget.props.icon_name else: return None icon_name = GObject.property(type=str, setter=set_icon_name, getter=get_icon_name) def create_palette(self): return None def get_palette(self): return self._palette_invoker.palette def set_palette(self, palette): self._palette_invoker.palette = palette palette = GObject.property( type=object, setter=set_palette, getter=get_palette) def get_palette_invoker(self): return self._palette_invoker def set_palette_invoker(self, palette_invoker): self._palette_invoker.detach() self._palette_invoker = palette_invoker palette_invoker = GObject.property( type=object, setter=set_palette_invoker, getter=get_palette_invoker) def set_tooltip(self, text): self.set_palette(Palette(text)) def set_accelerator(self, accelerator): self._accelerator = accelerator setup_accelerator(self) def get_accelerator(self): return self._accelerator accelerator = GObject.property(type=str, setter=set_accelerator, getter=get_accelerator) def do_draw(self, cr): allocation = self.get_allocation() child = self.get_child() if self.palette and self.palette.is_up(): invoker = self.palette.props.invoker invoker.draw_rectangle(cr, self.palette) allocation = self.get_allocation() # draw a black background, has been done by the engine before cr.set_source_rgb(0, 0, 0) cr.rectangle(0, 0, allocation.width, allocation.height) cr.paint() Gtk.ToggleToolButton.do_draw(self, cr) palette = property(get_palette, set_palette)
class ToggleToolButton(Gtk.ToggleToolButton): ''' UI for toggletoolbutton. A ToggleToolButton is a ToolItem that contains a toggle button, having an icon, a tooltip palette, and an accelerator. Use ToggleToolButton.new() to create a new ToggleToolButton. Args: accelerator (string): keyboard shortcut to be used to activate this button. Find about format here : https://developer.gnome.org/gtk3/stable/gtk3-Keyboard-Accelerators.html#gtk-accelerator-parse tooltip (string): tooltip to be displayed when user hovers over toggle button. Keyword Args: icon_name(string): name of themed icon which is to be used. ''' __gtype_name__ = 'SugarToggleToolButton' def __init__(self, icon_name=None): GObject.GObject.__init__(self) self._palette_invoker = ToolInvoker(self) if icon_name: self.set_icon_name(icon_name) self.connect('destroy', self.__destroy_cb) def __destroy_cb(self, icon): if self._palette_invoker is not None: self._palette_invoker.detach() def set_icon_name(self, icon_name): ''' Sets the icon for the tool button from a named themed icon. If it is none then no icon will be shown. Args: icon_name(string): The name for a themed icon. It can be set as 'None' too. Example: set_icon_name('view-radial') ''' icon = Icon(icon_name=icon_name) self.set_icon_widget(icon) icon.show() def get_icon_name(self): ''' The get_icon_name() method returns the value of the icon_name property that contains the name of a themed icon or None. ''' if self.props.icon_widget is not None: return self.props.icon_widget.props.icon_name else: return None icon_name = GObject.property(type=str, setter=set_icon_name, getter=get_icon_name) def create_palette(self): return None def get_palette(self): return self._palette_invoker.palette def set_palette(self, palette): self._palette_invoker.palette = palette palette = GObject.property(type=object, setter=set_palette, getter=get_palette) def get_palette_invoker(self): return self._palette_invoker def set_palette_invoker(self, palette_invoker): self._palette_invoker.detach() self._palette_invoker = palette_invoker palette_invoker = GObject.property(type=object, setter=set_palette_invoker, getter=get_palette_invoker) def set_tooltip(self, text): ''' Sets the tooltip of the toogle tool button. Displays when user hovers over the button with cursor. Args: tooltip (string): tooltip to be added to the button ''' self.set_palette(Palette(text)) def set_accelerator(self, accelerator): ''' Sets keyboard shortcut that activates this button. Args: accelerator(string): accelerator to be set. Should be in form <modifier>Letter Find about format here : https://developer.gnome.org/gtk3/stable/gtk3-Keyboard-Accelerators.html#gtk-accelerator-parse Example: set_accelerator(self, 'accel') ''' self._accelerator = accelerator setup_accelerator(self) def get_accelerator(self): ''' Returns above accelerator string. ''' return self._accelerator accelerator = GObject.property(type=str, setter=set_accelerator, getter=get_accelerator) def do_draw(self, cr): ''' Implementation method for drawing the toogle tool button ''' if self.palette and self.palette.is_up(): allocation = self.get_allocation() # draw a black background, has been done by the engine before cr.set_source_rgb(0, 0, 0) cr.rectangle(0, 0, allocation.width, allocation.height) cr.paint() Gtk.ToggleToolButton.do_draw(self, cr) if self.palette and self.palette.is_up(): invoker = self.palette.props.invoker invoker.draw_rectangle(cr, self.palette) return False def do_clicked(self): ''' Implementation method for hiding the tooltip when the toggle button is clicked ''' if self.palette: self.palette.popdown(True) palette = property(get_palette, set_palette)
class ColorToolButton(Gtk.ToolItem): # This not ideal. It would be better to subclass Gtk.ToolButton, however # the python bindings do not seem to be powerfull enough for that. # (As we need to change a variable in the class structure.) __gtype_name__ = 'SugarColorToolButton' __gsignals__ = {'color-set': (GObject.SignalFlags.RUN_FIRST, None, tuple())} def __init__(self, icon_name='color-preview', **kwargs): self._accelerator = None self._tooltip = None self._palette_invoker = ToolInvoker() self._palette = None GObject.GObject.__init__(self, **kwargs) # The Gtk.ToolButton has already added a normal button. # Replace it with a ColorButton color_button = _ColorButton(icon_name=icon_name, has_invoker=False) self.add(color_button) color_button.show() # The following is so that the behaviour on the toolbar is correct. color_button.set_relief(Gtk.ReliefStyle.NONE) color_button.icon_size = Gtk.IconSize.LARGE_TOOLBAR self._palette_invoker.attach_tool(self) self._palette_invoker.props.toggle_palette = True self._palette_invoker.props.lock_palette = True # This widget just proxies the following properties to the colorbutton color_button.connect('notify::color', self.__notify_change) color_button.connect('notify::icon-name', self.__notify_change) color_button.connect('notify::icon-size', self.__notify_change) color_button.connect('notify::title', self.__notify_change) color_button.connect('color-set', self.__color_set_cb) color_button.connect('can-activate-accel', self.__button_can_activate_accel_cb) def __button_can_activate_accel_cb(self, button, signal_id): # Accept activation via accelerators regardless of this widget's state return True def set_accelerator(self, accelerator): ''' Sets keyboard shortcut that activates this button. Args: accelerator(string): accelerator to be set. Should be in form <modifier>Letter Find about format here : https://developer.gnome.org/gtk3/stable/gtk3-Keyboard-Accelerators.html#gtk-accelerator-parse Example: set_accelerator(self, 'accel') ''' self._accelerator = accelerator setup_accelerator(self) def get_accelerator(self): ''' Returns the above accelerator string. ''' return self._accelerator accelerator = GObject.Property(type=str, setter=set_accelerator, getter=get_accelerator) def create_palette(self): ''' The create_palette function is called when the palette needs to be invoked. For example, when the user has right clicked the icon or the user has hovered over the icon for a long time. The create_palette will only be called once or zero times. The palette returned will be stored and re-used if the user invokes the palette multiple times. Your create_palette implementation does not need to :any:`Gtk.Widget.show` the palette, as this will be done by the invoker. However, you still need to show the menu items, etc that you place in the palette. Returns: sugar3.graphics.palette.Palette, or None to indicate that you do not want a palette shown The default implementation returns None, to indicate no palette should be shown. ''' self._palette = self.get_child().create_palette() return self._palette def get_palette_invoker(self): return self._palette_invoker def set_palette_invoker(self, palette_invoker): self._palette_invoker.detach() self._palette_invoker = palette_invoker palette_invoker = GObject.Property( type=object, setter=set_palette_invoker, getter=get_palette_invoker) def set_expanded(self, expanded): box = self.toolbar_box if not box: return if not expanded: self._palette_invoker.notify_popdown() return if box.expanded_button is not None: box.expanded_button.queue_draw() if box.expanded_button != self: box.expanded_button.set_expanded(False) box.expanded_button = self def get_toolbar_box(self): parent = self.get_parent() if not hasattr(parent, 'owner'): return None return parent.owner toolbar_box = property(get_toolbar_box) def set_color(self, color): ''' Sets the color of the colorbutton ''' self.get_child().props.color = color def get_color(self): ''' Gets the above set color string. ''' return self.get_child().props.color color = GObject.Property(type=object, getter=get_color, setter=set_color) def set_icon_name(self, icon_name): ''' Sets the icon for the tool button from a named themed icon. If it is none then no icon will be shown. Args: icon_name(string): The name for a themed icon. It can be set as 'None' too. Example: set_icon_name('view-radial') ''' self.get_child().props.icon_name = icon_name def get_icon_name(self): ''' The get_icon_name() method returns the value of the icon_name property that contains the name of a themed icon or None. ''' return self.get_child().props.icon_name icon_name = GObject.Property(type=str, getter=get_icon_name, setter=set_icon_name) def set_icon_size(self, icon_size): ''' Sets the size of icons in the colorbutton. ''' self.get_child().props.icon_size = icon_size def get_icon_size(self): ''' Gets the size of icons in the colorbutton. ''' return self.get_child().props.icon_size icon_size = GObject.Property(type=int, getter=get_icon_size, setter=set_icon_size) def set_title(self, title): ''' The set_title() method sets the "title" property to the value of title. The "title" property contains the string that is used to set the colorbutton title. ''' self.get_child().props.title = title def get_title(self): ''' Return the above title string. ''' return self.get_child().props.title title = GObject.Property(type=str, getter=get_title, setter=set_title) def do_draw(self, cr): if self._palette and self._palette.is_up(): allocation = self.get_allocation() # draw a black background, has been done by the engine before cr.set_source_rgb(0, 0, 0) cr.rectangle(0, 0, allocation.width, allocation.height) cr.paint() Gtk.ToolItem.do_draw(self, cr) if self._palette and self._palette.is_up(): invoker = self._palette.props.invoker invoker.draw_rectangle(cr, self._palette) return False def __notify_change(self, widget, pspec): self.notify(pspec.name) def __color_set_cb(self, widget): self.emit('color-set')
class ToggleToolButton(Gtk.ToggleToolButton): __gtype_name__ = 'SugarToggleToolButton' def __init__(self, icon_name=None): GObject.GObject.__init__(self) self._palette_invoker = ToolInvoker(self) if icon_name: self.set_icon_name(icon_name) self.connect('destroy', self.__destroy_cb) def __destroy_cb(self, icon): if self._palette_invoker is not None: self._palette_invoker.detach() def set_icon_name(self, icon_name): icon = Icon(icon_name=icon_name) self.set_icon_widget(icon) icon.show() def get_icon_name(self): if self.props.icon_widget is not None: return self.props.icon_widget.props.icon_name else: return None icon_name = GObject.property(type=str, setter=set_icon_name, getter=get_icon_name) def create_palette(self): return None def get_palette(self): return self._palette_invoker.palette def set_palette(self, palette): self._palette_invoker.palette = palette palette = GObject.property( type=object, setter=set_palette, getter=get_palette) def get_palette_invoker(self): return self._palette_invoker def set_palette_invoker(self, palette_invoker): self._palette_invoker.detach() self._palette_invoker = palette_invoker palette_invoker = GObject.property( type=object, setter=set_palette_invoker, getter=get_palette_invoker) def set_tooltip(self, text): self.set_palette(Palette(text)) def set_accelerator(self, accelerator): self._accelerator = accelerator setup_accelerator(self) def get_accelerator(self): return self._accelerator accelerator = GObject.property(type=str, setter=set_accelerator, getter=get_accelerator) def do_draw(self, cr): if self.palette and self.palette.is_up(): allocation = self.get_allocation() # draw a black background, has been done by the engine before cr.set_source_rgb(0, 0, 0) cr.rectangle(0, 0, allocation.width, allocation.height) cr.paint() Gtk.ToggleToolButton.do_draw(self, cr) if self.palette and self.palette.is_up(): invoker = self.palette.props.invoker invoker.draw_rectangle(cr, self.palette) return False def do_clicked(self): if self.palette: self.palette.popdown(True) palette = property(get_palette, set_palette)
class ToolButton(Gtk.ToolButton): __gtype_name__ = 'SugarToolButton' def __init__(self, icon_name=None, **kwargs): self._accelerator = None self._tooltip = None self._palette_invoker = ToolInvoker() GObject.GObject.__init__(self, **kwargs) self._hide_tooltip_on_click = True self._palette_invoker.attach_tool(self) if icon_name: self.set_icon_name(icon_name) self.get_child().connect('can-activate-accel', self.__button_can_activate_accel_cb) self.connect('destroy', self.__destroy_cb) def __destroy_cb(self, icon): if self._palette_invoker is not None: self._palette_invoker.detach() def __button_can_activate_accel_cb(self, button, signal_id): # Accept activation via accelerators regardless of this widget's state return True def set_tooltip(self, tooltip): """ Set a simple palette with just a single label. """ if self.palette is None or self._tooltip is None: self.palette = Palette(tooltip) elif self.palette is not None: self.palette.set_primary_text(tooltip) self._tooltip = tooltip # Set label, shows up when toolbar overflows Gtk.ToolButton.set_label(self, tooltip) def get_tooltip(self): return self._tooltip tooltip = GObject.property(type=str, setter=set_tooltip, getter=get_tooltip) def get_hide_tooltip_on_click(self): return self._hide_tooltip_on_click def set_hide_tooltip_on_click(self, hide_tooltip_on_click): if self._hide_tooltip_on_click != hide_tooltip_on_click: self._hide_tooltip_on_click = hide_tooltip_on_click hide_tooltip_on_click = GObject.property(type=bool, default=True, getter=get_hide_tooltip_on_click, setter=set_hide_tooltip_on_click) def set_accelerator(self, accelerator): self._accelerator = accelerator setup_accelerator(self) def get_accelerator(self): return self._accelerator accelerator = GObject.property(type=str, setter=set_accelerator, getter=get_accelerator) def set_icon_name(self, icon_name): icon = Icon(icon_name=icon_name) self.set_icon_widget(icon) icon.show() def get_icon_name(self): if self.props.icon_widget is not None: return self.props.icon_widget.props.icon_name else: return None icon_name = GObject.property(type=str, setter=set_icon_name, getter=get_icon_name) def create_palette(self): return None def get_palette(self): return self._palette_invoker.palette def set_palette(self, palette): self._palette_invoker.palette = palette palette = GObject.property(type=object, setter=set_palette, getter=get_palette) def get_palette_invoker(self): return self._palette_invoker def set_palette_invoker(self, palette_invoker): self._palette_invoker.detach() self._palette_invoker = palette_invoker palette_invoker = GObject.property(type=object, setter=set_palette_invoker, getter=get_palette_invoker) def do_draw(self, cr): if self.palette and self.palette.is_up(): allocation = self.get_allocation() # draw a black background, has been done by the engine before cr.set_source_rgb(0, 0, 0) cr.rectangle(0, 0, allocation.width, allocation.height) cr.paint() Gtk.ToolButton.do_draw(self, cr) if self.palette and self.palette.is_up(): invoker = self.palette.props.invoker invoker.draw_rectangle(cr, self.palette) return False def do_clicked(self): if self._hide_tooltip_on_click and self.palette: self.palette.popdown(True)
class FontComboBox(Gtk.ToolItem): __gsignals__ = { 'changed': (GObject.SignalFlags.RUN_LAST, None, ([])), } def __init__(self): self._palette_invoker = ToolInvoker() Gtk.ToolItem.__init__(self) self._font_label = FontLabel() bt = Gtk.Button('') bt.set_can_focus(False) bt.remove(bt.get_children()[0]) box = Gtk.HBox() bt.add(box) icon = Icon(icon_name='font-text') box.pack_start(icon, False, False, 10) box.pack_start(self._font_label, False, False, 10) self.add(bt) self.show_all() self._font_name = 'Sans' # theme the button, can be removed if add the style to the sugar css if style.zoom(100) == 100: subcell_size = 15 else: subcell_size = 11 radius = 2 * subcell_size theme = b"GtkButton {border-radius: %dpx;}" % radius css_provider = Gtk.CssProvider() css_provider.load_from_data(theme) style_context = bt.get_style_context() style_context.add_provider(css_provider, Gtk.STYLE_PROVIDER_PRIORITY_USER) # init palette self._hide_tooltip_on_click = True self._palette_invoker.attach_tool(self) self._palette_invoker.props.toggle_palette = True self.palette = Palette(_('Select font')) self.palette.set_invoker(self._palette_invoker) # load the fonts in the palette menu self._menu_box = PaletteMenuBox() self.props.palette.set_content(self._menu_box) self._menu_box.show() context = self.get_pango_context() self._init_font_list() tmp_list = [] for family in context.list_families(): name = family.get_name() if name in self._font_white_list: tmp_list.append(name) for name in sorted(tmp_list): self._add_menu(name, self.__font_selected_cb) self._font_label.set_font(self._font_name) def _init_font_list(self): self._font_white_list = [] self._font_white_list.extend(DEFAULT_FONTS) # check if there are a user configuration file if not os.path.exists(USER_FONTS_FILE_PATH): # verify if exists a file in /etc if os.path.exists(GLOBAL_FONTS_FILE_PATH): shutil.copy(GLOBAL_FONTS_FILE_PATH, USER_FONTS_FILE_PATH) if os.path.exists(USER_FONTS_FILE_PATH): # get the font names in the file to the white list fonts_file = open(USER_FONTS_FILE_PATH) # get the font names in the file to the white list for line in fonts_file: self._font_white_list.append(line.strip()) # monitor changes in the file gio_fonts_file = Gio.File.new_for_path(USER_FONTS_FILE_PATH) self.monitor = gio_fonts_file.monitor_file( Gio.FileMonitorFlags.NONE, None) self.monitor.set_rate_limit(5000) self.monitor.connect('changed', self._reload_fonts) def _reload_fonts(self, monitor, gio_file, other_file, event): if event != Gio.FileMonitorEvent.CHANGES_DONE_HINT: return self._font_white_list = [] self._font_white_list.extend(DEFAULT_FONTS) fonts_file = open(USER_FONTS_FILE_PATH) for line in fonts_file: self._font_white_list.append(line.strip()) # update the menu for child in self._menu_box.get_children(): self._menu_box.remove(child) child = None context = self.get_pango_context() tmp_list = [] for family in context.list_families(): name = family.get_name() if name in self._font_white_list: tmp_list.append(name) for name in sorted(tmp_list): self._add_menu(name, self.__font_selected_cb) return False def __font_selected_cb(self, menu, font_name): self._font_name = font_name self._font_label.set_font(font_name) self.emit('changed') def _add_menu(self, font_name, activate_cb): label = '<span font="%s">%s</span>' % (font_name, font_name) menu_item = PaletteMenuItem() menu_item.set_label(label) menu_item.connect('activate', activate_cb, font_name) self._menu_box.append_item(menu_item) menu_item.show() def __destroy_cb(self, icon): if self._palette_invoker is not None: self._palette_invoker.detach() def create_palette(self): return None def get_palette(self): return self._palette_invoker.palette def set_palette(self, palette): self._palette_invoker.palette = palette palette = GObject.Property(type=object, setter=set_palette, getter=get_palette) def get_palette_invoker(self): return self._palette_invoker def set_palette_invoker(self, palette_invoker): self._palette_invoker.detach() self._palette_invoker = palette_invoker palette_invoker = GObject.Property(type=object, setter=set_palette_invoker, getter=get_palette_invoker) def set_font_name(self, font_name): self._font_label.set_font(font_name) def get_font_name(self): return self._font_name
class RadioToolButton(Gtk.RadioToolButton): ''' The RadioToolButton class manages a Gtk.RadioToolButton styled for Sugar. Args: icon_name (string): name of icon to be used. Keyword Args: accelerator (string): keyboard shortcut to be used to activate this button. tooltip (string): tooltip to be displayed when user hovers over button. xo_color (sugar3.graphics.xocolor.XoColor): XoColor of button. hide_tooltip_on_click (bool): Whether or not the tooltip is hidden when user clicks on button. ''' __gtype_name__ = 'SugarRadioToolButton' def __init__(self, icon_name=None, **kwargs): self._accelerator = None self._tooltip = None self._xo_color = None self._hide_tooltip_on_click = True self._palette_invoker = ToolInvoker() GObject.GObject.__init__(self, **kwargs) self._palette_invoker.attach_tool(self) if icon_name: self.set_icon_name(icon_name) # HACK: stop Gtk from adding a label and expanding the size of # the button. This happen when set_icon_widget is called # if label_widget is None self.props.label_widget = Gtk.Box() self.connect('destroy', self.__destroy_cb) def __destroy_cb(self, icon): if self._palette_invoker is not None: self._palette_invoker.detach() def set_tooltip(self, tooltip): ''' Set the tooltip. Args: tooltip (string): tooltip to be set. ''' if self.palette is None or self._tooltip is None: self.palette = Palette(tooltip) elif self.palette is not None: self.palette.set_primary_text(tooltip) self._tooltip = tooltip # Set label, shows up when toolbar overflows Gtk.RadioToolButton.set_label(self, tooltip) def get_tooltip(self): ''' Return the tooltip. ''' return self._tooltip tooltip = GObject.Property(type=str, setter=set_tooltip, getter=get_tooltip) def set_accelerator(self, accelerator): ''' Set keyboard shortcut that activates this button. Args: accelerator (string): accelerator to be set. Should be in form <modifier>Letter. ''' self._accelerator = accelerator toolbutton.setup_accelerator(self) def get_accelerator(self): ''' Return accelerator string. ''' return self._accelerator accelerator = GObject.Property(type=str, setter=set_accelerator, getter=get_accelerator) def set_icon_name(self, icon_name): ''' Set name of icon. Args: icon_name (string): name of icon ''' icon = Icon(icon_name=icon_name, xo_color=self._xo_color) self.set_icon_widget(icon) icon.show() def get_icon_name(self): ''' Return icon name, or None if there is no icon name. ''' if self.props.icon_widget is not None: return self.props.icon_widget.props.icon_name else: return None icon_name = GObject.Property(type=str, setter=set_icon_name, getter=get_icon_name) def set_xo_color(self, xo_color): ''' Set XoColor of button icon. Args: xo_color (sugar3.graphics.xocolor.XoColor): xocolor to be set. ''' if self._xo_color != xo_color: self._xo_color = xo_color if self.props.icon_widget is not None: self.props.icon_widget.props.xo_color = xo_color def get_xo_color(self): ''' Return xocolor. ''' return self._xo_color xo_color = GObject.Property(type=object, setter=set_xo_color, getter=get_xo_color) def create_palette(self): return None def get_palette(self): return self._palette_invoker.palette def set_palette(self, palette): self._palette_invoker.palette = palette palette = GObject.Property( type=object, setter=set_palette, getter=get_palette) def get_palette_invoker(self): return self._palette_invoker def set_palette_invoker(self, palette_invoker): self._palette_invoker.detach() self._palette_invoker = palette_invoker palette_invoker = GObject.Property( type=object, setter=set_palette_invoker, getter=get_palette_invoker) def do_draw(self, cr): ''' Implementation method for drawing the button. ''' if self.palette and self.palette.is_up(): allocation = self.get_allocation() # draw a black background, has been done by the engine before cr.set_source_rgb(0, 0, 0) cr.rectangle(0, 0, allocation.width, allocation.height) cr.paint() Gtk.RadioToolButton.do_draw(self, cr) if self.palette and self.palette.is_up(): invoker = self.palette.props.invoker invoker.draw_rectangle(cr, self.palette) return False def get_hide_tooltip_on_click(self): ''' Return True if the tooltip is hidden when a user clicks on the button, otherwise return False. ''' return self._hide_tooltip_on_click def set_hide_tooltip_on_click(self, hide_tooltip_on_click): ''' Set whether or not the tooltip is hidden when a user clicks on the button. Args: hide_tooltip_on_click (bool): True if the tooltip is hidden on click, and False otherwise. ''' if self._hide_tooltip_on_click != hide_tooltip_on_click: self._hide_tooltip_on_click = hide_tooltip_on_click hide_tooltip_on_click = GObject.Property( type=bool, default=True, getter=get_hide_tooltip_on_click, setter=set_hide_tooltip_on_click) def do_clicked(self): ''' Implementation method for hiding the tooltip when the button is clicked. ''' if self._hide_tooltip_on_click and self.palette: self.palette.popdown(True)
class FilterToolItem(Gtk.ToolButton): __gsignals__ = { 'changed': (GObject.SignalFlags.RUN_LAST, None, ([])), } def __init__(self, tagline, default_icon, default_label, palette_content): self._palette_invoker = ToolInvoker() Gtk.ToolButton.__init__(self) self._label = default_label self.set_is_important(False) self.set_size_request(style.GRID_CELL_SIZE, -1) self._label_widget = Gtk.Label() self._label_widget.set_alignment(0.0, 0.5) self._label_widget.set_ellipsize(Pango.EllipsizeMode.MIDDLE) self._label_widget.set_max_width_chars(10) self._label_widget.set_use_markup(True) self._label_widget.set_markup(default_label) self.set_label_widget(self._label_widget) self._label_widget.show() self.set_widget_icon(icon_name=default_icon) self._hide_tooltip_on_click = True self._palette_invoker.attach_tool(self) self._palette_invoker.props.toggle_palette = True self._palette_invoker.props.lock_palette = True self.palette = Palette(tagline) self.palette.set_invoker(self._palette_invoker) self.props.palette.set_content(palette_content) def set_widget_icon(self, icon_name=None, file_name=None): if file_name is not None: icon = Icon(file=file_name, pixel_size=style.SMALL_ICON_SIZE, xo_color=XoColor('white')) else: icon = Icon(icon_name=icon_name, pixel_size=style.SMALL_ICON_SIZE, xo_color=XoColor('white')) self.set_icon_widget(icon) icon.show() def set_widget_label(self, label=None): # FIXME: Ellipsis is not working on these labels. if label is None: label = self._label """ if len(label) > 10: label = label[0:7] + '...' + label[-7:] """ self._label_widget.set_markup(label) self._label = label def __destroy_cb(self, icon): if self._palette_invoker is not None: self._palette_invoker.detach() def create_palette(self): return None def get_palette(self): return self._palette_invoker.palette def set_palette(self, palette): self._palette_invoker.palette = palette palette = GObject.Property( type=object, setter=set_palette, getter=get_palette) def get_palette_invoker(self): return self._palette_invoker def set_palette_invoker(self, palette_invoker): self._palette_invoker.detach() self._palette_invoker = palette_invoker palette_invoker = GObject.Property( type=object, setter=set_palette_invoker, getter=get_palette_invoker) def do_draw(self, cr): if self.palette and self.palette.is_up(): allocation = self.get_allocation() # draw a black background, has been done by the engine before cr.set_source_rgb(0, 0, 0) cr.rectangle(0, 0, allocation.width, allocation.height) cr.paint() Gtk.ToolButton.do_draw(self, cr) if self.palette and self.palette.is_up(): invoker = self.palette.props.invoker invoker.draw_rectangle(cr, self.palette) return False
class RadioToolButton(Gtk.RadioToolButton): ''' The RadioToolButton class manages a Gtk.RadioToolButton styled for Sugar. Args: icon_name (string): name of icon to be used. Keyword Args: accelerator (string): keyboard shortcut to be used to activate this button. tooltip (string): tooltip to be displayed when user hovers over button. xo_color (sugar3.graphics.xocolor.XoColor): XoColor of button. hide_tooltip_on_click (bool): Whether or not the tooltip is hidden when user clicks on button. ''' __gtype_name__ = 'SugarRadioToolButton' def __init__(self, icon_name=None, **kwargs): self._accelerator = None self._tooltip = None self._xo_color = None self._hide_tooltip_on_click = True self._palette_invoker = ToolInvoker() GObject.GObject.__init__(self, **kwargs) self._palette_invoker.attach_tool(self) if icon_name: self.set_icon_name(icon_name) # HACK: stop Gtk from adding a label and expanding the size of # the button. This happen when set_icon_widget is called # if label_widget is None self.props.label_widget = Gtk.Box() self.connect('destroy', self.__destroy_cb) def __destroy_cb(self, icon): if self._palette_invoker is not None: self._palette_invoker.detach() def set_tooltip(self, tooltip): ''' Set the tooltip. Args: tooltip (string): tooltip to be set. ''' if self.palette is None or self._tooltip is None: self.palette = Palette(tooltip) elif self.palette is not None: self.palette.set_primary_text(tooltip) self._tooltip = tooltip # Set label, shows up when toolbar overflows Gtk.RadioToolButton.set_label(self, tooltip) def get_tooltip(self): ''' Return the tooltip. ''' return self._tooltip tooltip = GObject.Property(type=str, setter=set_tooltip, getter=get_tooltip) def set_accelerator(self, accelerator): ''' Set keyboard shortcut that activates this button. Args: accelerator (string): accelerator to be set. Should be in form <modifier>Letter. ''' self._accelerator = accelerator toolbutton.setup_accelerator(self) def get_accelerator(self): ''' Return accelerator string. ''' return self._accelerator accelerator = GObject.Property(type=str, setter=set_accelerator, getter=get_accelerator) def set_icon_name(self, icon_name): ''' Set name of icon. Args: icon_name (string): name of icon ''' icon = Icon(icon_name=icon_name, xo_color=self._xo_color) self.set_icon_widget(icon) icon.show() def get_icon_name(self): ''' Return icon name, or None if there is no icon name. ''' if self.props.icon_widget is not None: return self.props.icon_widget.props.icon_name else: return None icon_name = GObject.Property(type=str, setter=set_icon_name, getter=get_icon_name) def set_xo_color(self, xo_color): ''' Set XoColor of button icon. Args: xo_color (sugar3.graphics.xocolor.XoColor): xocolor to be set. ''' if self._xo_color != xo_color: self._xo_color = xo_color if self.props.icon_widget is not None: self.props.icon_widget.props.xo_color = xo_color def get_xo_color(self): ''' Return xocolor. ''' return self._xo_color xo_color = GObject.Property(type=object, setter=set_xo_color, getter=get_xo_color) def create_palette(self): return None def get_palette(self): return self._palette_invoker.palette def set_palette(self, palette): self._palette_invoker.palette = palette palette = GObject.Property(type=object, setter=set_palette, getter=get_palette) def get_palette_invoker(self): return self._palette_invoker def set_palette_invoker(self, palette_invoker): self._palette_invoker.detach() self._palette_invoker = palette_invoker palette_invoker = GObject.Property(type=object, setter=set_palette_invoker, getter=get_palette_invoker) def do_draw(self, cr): ''' Implementation method for drawing the button. ''' if self.palette and self.palette.is_up(): allocation = self.get_allocation() # draw a black background, has been done by the engine before cr.set_source_rgb(0, 0, 0) cr.rectangle(0, 0, allocation.width, allocation.height) cr.paint() Gtk.RadioToolButton.do_draw(self, cr) if self.palette and self.palette.is_up(): invoker = self.palette.props.invoker invoker.draw_rectangle(cr, self.palette) return False def get_hide_tooltip_on_click(self): ''' Return True if the tooltip is hidden when a user clicks on the button, otherwise return False. ''' return self._hide_tooltip_on_click def set_hide_tooltip_on_click(self, hide_tooltip_on_click): ''' Set whether or not the tooltip is hidden when a user clicks on the button. Args: hide_tooltip_on_click (bool): True if the tooltip is hidden on click, and False otherwise. ''' if self._hide_tooltip_on_click != hide_tooltip_on_click: self._hide_tooltip_on_click = hide_tooltip_on_click hide_tooltip_on_click = GObject.Property(type=bool, default=True, getter=get_hide_tooltip_on_click, setter=set_hide_tooltip_on_click) def do_clicked(self): ''' Implementation method for hiding the tooltip when the button is clicked. ''' if self._hide_tooltip_on_click and self.palette: self.palette.popdown(True)
class ColorToolButton(Gtk.ToolItem): # This not ideal. It would be better to subclass Gtk.ToolButton, however # the python bindings do not seem to be powerfull enough for that. # (As we need to change a variable in the class structure.) __gtype_name__ = 'SugarColorToolButton' __gsignals__ = { 'color-set': (GObject.SignalFlags.RUN_FIRST, None, tuple()) } def __init__(self, icon_name='color-preview', **kwargs): self._accelerator = None self._tooltip = None self._palette_invoker = ToolInvoker() self._palette = None GObject.GObject.__init__(self, **kwargs) # The Gtk.ToolButton has already added a normal button. # Replace it with a ColorButton color_button = _ColorButton(icon_name=icon_name, has_invoker=False) self.add(color_button) color_button.show() # The following is so that the behaviour on the toolbar is correct. color_button.set_relief(Gtk.ReliefStyle.NONE) color_button.icon_size = Gtk.IconSize.LARGE_TOOLBAR self._palette_invoker.attach_tool(self) self._palette_invoker.props.toggle_palette = True self._palette_invoker.props.lock_palette = True # This widget just proxies the following properties to the colorbutton color_button.connect('notify::color', self.__notify_change) color_button.connect('notify::icon-name', self.__notify_change) color_button.connect('notify::icon-size', self.__notify_change) color_button.connect('notify::title', self.__notify_change) color_button.connect('color-set', self.__color_set_cb) color_button.connect('can-activate-accel', self.__button_can_activate_accel_cb) def __button_can_activate_accel_cb(self, button, signal_id): # Accept activation via accelerators regardless of this widget's state return True def set_accelerator(self, accelerator): self._accelerator = accelerator setup_accelerator(self) def get_accelerator(self): return self._accelerator accelerator = GObject.property(type=str, setter=set_accelerator, getter=get_accelerator) def create_palette(self): self._palette = self.get_child().create_palette() return self._palette def get_palette_invoker(self): return self._palette_invoker def set_palette_invoker(self, palette_invoker): self._palette_invoker.detach() self._palette_invoker = palette_invoker palette_invoker = GObject.property(type=object, setter=set_palette_invoker, getter=get_palette_invoker) def set_expanded(self, expanded): box = self.toolbar_box if not box: return if not expanded: self._palette_invoker.notify_popdown() return if box.expanded_button is not None: box.expanded_button.queue_draw() if box.expanded_button != self: box.expanded_button.set_expanded(False) box.expanded_button = self def get_toolbar_box(self): parent = self.get_parent() if not hasattr(parent, 'owner'): return None return parent.owner toolbar_box = property(get_toolbar_box) def set_color(self, color): self.get_child().props.color = color def get_color(self): return self.get_child().props.color color = GObject.property(type=object, getter=get_color, setter=set_color) def set_icon_name(self, icon_name): self.get_child().props.icon_name = icon_name def get_icon_name(self): return self.get_child().props.icon_name icon_name = GObject.property(type=str, getter=get_icon_name, setter=set_icon_name) def set_icon_size(self, icon_size): self.get_child().props.icon_size = icon_size def get_icon_size(self): return self.get_child().props.icon_size icon_size = GObject.property(type=int, getter=get_icon_size, setter=set_icon_size) def set_title(self, title): self.get_child().props.title = title def get_title(self): return self.get_child().props.title title = GObject.property(type=str, getter=get_title, setter=set_title) def do_draw(self, cr): if self._palette and self._palette.is_up(): allocation = self.get_allocation() # draw a black background, has been done by the engine before cr.set_source_rgb(0, 0, 0) cr.rectangle(0, 0, allocation.width, allocation.height) cr.paint() Gtk.ToolItem.do_draw(self, cr) if self._palette and self._palette.is_up(): invoker = self._palette.props.invoker invoker.draw_rectangle(cr, self._palette) return False def __notify_change(self, widget, pspec): self.notify(pspec.name) def __color_set_cb(self, widget): self.emit('color-set')
class ToolButton(Gtk.ToolButton): ''' The ToolButton class manages a Gtk.ToolButton styled for Sugar. Keyword Args: icon_name(string): name of themed icon. accelerator (string): keyboard shortcut to be used to activate this button. tooltip (string): tooltip to be displayed when user hovers over button. hide_tooltip_on_click (bool): Whether or not the tooltip is hidden when user clicks on button. ''' __gtype_name__ = 'SugarToolButton' def __init__(self, icon_name=None, **kwargs): self._accelerator = None self._tooltip = None self._palette_invoker = ToolInvoker() GObject.GObject.__init__(self, **kwargs) self._hide_tooltip_on_click = True self._palette_invoker.attach_tool(self) if icon_name: self.set_icon_name(icon_name) self.get_child().connect('can-activate-accel', self.__button_can_activate_accel_cb) self.connect('destroy', self.__destroy_cb) def __destroy_cb(self, icon): if self._palette_invoker is not None: self._palette_invoker.detach() def __button_can_activate_accel_cb(self, button, signal_id): # Accept activation via accelerators regardless of this widget's state return True def set_tooltip(self, tooltip): ''' Set the tooltip. Args: tooltip (string): tooltip to be set. ''' if self.palette is None or self._tooltip is None: self.palette = Palette(tooltip) elif self.palette is not None: self.palette.set_primary_text(tooltip) self._tooltip = tooltip # Set label, shows up when toolbar overflows Gtk.ToolButton.set_label(self, tooltip) def get_tooltip(self): ''' Return the tooltip. ''' return self._tooltip tooltip = GObject.property(type=str, setter=set_tooltip, getter=get_tooltip) def get_hide_tooltip_on_click(self): ''' Return True if the tooltip is hidden when a user clicks on the button, otherwise return False. ''' return self._hide_tooltip_on_click def set_hide_tooltip_on_click(self, hide_tooltip_on_click): ''' Set whether or not the tooltip is hidden when a user clicks on the button. Args: hide_tooltip_on_click (bool): True if the tooltip is hidden on click, and False otherwise. ''' if self._hide_tooltip_on_click != hide_tooltip_on_click: self._hide_tooltip_on_click = hide_tooltip_on_click hide_tooltip_on_click = GObject.property( type=bool, default=True, getter=get_hide_tooltip_on_click, setter=set_hide_tooltip_on_click) def set_accelerator(self, accelerator): ''' Set accelerator that activates the button. Args: accelerator(string): accelerator to be set. ''' self._accelerator = accelerator setup_accelerator(self) def get_accelerator(self): ''' Return accelerator that activates the button. ''' return self._accelerator accelerator = GObject.property(type=str, setter=set_accelerator, getter=get_accelerator) def set_icon_name(self, icon_name): ''' Set name of icon. Args: icon_name (string): name of icon ''' icon = Icon(icon_name=icon_name) self.set_icon_widget(icon) icon.show() def get_icon_name(self): ''' Return icon name, or None if there is no icon name. ''' if self.props.icon_widget is not None: return self.props.icon_widget.props.icon_name else: return None icon_name = GObject.property(type=str, setter=set_icon_name, getter=get_icon_name) def create_palette(self): return None def get_palette(self): return self._palette_invoker.palette def set_palette(self, palette): self._palette_invoker.palette = palette palette = GObject.property( type=object, setter=set_palette, getter=get_palette) def get_palette_invoker(self): return self._palette_invoker def set_palette_invoker(self, palette_invoker): self._palette_invoker.detach() self._palette_invoker = palette_invoker palette_invoker = GObject.property( type=object, setter=set_palette_invoker, getter=get_palette_invoker) def do_draw(self, cr): ''' Implementation method for drawing the button. ''' if self.palette and self.palette.is_up(): allocation = self.get_allocation() # draw a black background, has been done by the engine before cr.set_source_rgb(0, 0, 0) cr.rectangle(0, 0, allocation.width, allocation.height) cr.paint() Gtk.ToolButton.do_draw(self, cr) if self.palette and self.palette.is_up(): invoker = self.palette.props.invoker invoker.draw_rectangle(cr, self.palette) return False def do_clicked(self): ''' Implementation method for hiding the tooltip when the button is clicked. ''' if self._hide_tooltip_on_click and self.palette: self.palette.popdown(True)
class ToolButton(Gtk.ToolButton): ''' The ToolButton class manages a Gtk.ToolButton styled for Sugar. Keyword Args: icon_name(string): name of themed icon. accelerator (string): keyboard shortcut to be used to activate this button. tooltip (string): tooltip to be displayed when user hovers over button. hide_tooltip_on_click (bool): Whether or not the tooltip is hidden when user clicks on button. ''' __gtype_name__ = 'SugarToolButton' def __init__(self, icon_name=None, **kwargs): self._accelerator = None self._tooltip = None self._palette_invoker = ToolInvoker() GObject.GObject.__init__(self, **kwargs) self._hide_tooltip_on_click = True self._palette_invoker.attach_tool(self) if icon_name: self.set_icon_name(icon_name) self.get_child().connect('can-activate-accel', self.__button_can_activate_accel_cb) self.connect('destroy', self.__destroy_cb) def __destroy_cb(self, icon): if self._palette_invoker is not None: self._palette_invoker.detach() def __button_can_activate_accel_cb(self, button, signal_id): # Accept activation via accelerators regardless of this widget's state return True def set_tooltip(self, tooltip): ''' Set the tooltip. Args: tooltip (string): tooltip to be set. ''' if self.palette is None or self._tooltip is None: self.palette = Palette(tooltip) elif self.palette is not None: self.palette.set_primary_text(tooltip) self._tooltip = tooltip # Set label, shows up when toolbar overflows Gtk.ToolButton.set_label(self, tooltip) def get_tooltip(self): ''' Return the tooltip. ''' return self._tooltip tooltip = GObject.property(type=str, setter=set_tooltip, getter=get_tooltip) def get_hide_tooltip_on_click(self): ''' Return True if the tooltip is hidden when a user clicks on the button, otherwise return False. ''' return self._hide_tooltip_on_click def set_hide_tooltip_on_click(self, hide_tooltip_on_click): ''' Set whether or not the tooltip is hidden when a user clicks on the button. Args: hide_tooltip_on_click (bool): True if the tooltip is hidden on click, and False otherwise. ''' if self._hide_tooltip_on_click != hide_tooltip_on_click: self._hide_tooltip_on_click = hide_tooltip_on_click hide_tooltip_on_click = GObject.property(type=bool, default=True, getter=get_hide_tooltip_on_click, setter=set_hide_tooltip_on_click) def set_accelerator(self, accelerator): ''' Set accelerator that activates the button. Args: accelerator(string): accelerator to be set. ''' self._accelerator = accelerator setup_accelerator(self) def get_accelerator(self): ''' Return accelerator that activates the button. ''' return self._accelerator accelerator = GObject.property(type=str, setter=set_accelerator, getter=get_accelerator) def set_icon_name(self, icon_name): ''' Set name of icon. Args: icon_name (string): name of icon ''' icon = Icon(icon_name=icon_name) self.set_icon_widget(icon) icon.show() def get_icon_name(self): ''' Return icon name, or None if there is no icon name. ''' if self.props.icon_widget is not None: return self.props.icon_widget.props.icon_name else: return None icon_name = GObject.property(type=str, setter=set_icon_name, getter=get_icon_name) def create_palette(self): return None def get_palette(self): return self._palette_invoker.palette def set_palette(self, palette): self._palette_invoker.palette = palette palette = GObject.property(type=object, setter=set_palette, getter=get_palette) def get_palette_invoker(self): return self._palette_invoker def set_palette_invoker(self, palette_invoker): self._palette_invoker.detach() self._palette_invoker = palette_invoker palette_invoker = GObject.property(type=object, setter=set_palette_invoker, getter=get_palette_invoker) def do_draw(self, cr): ''' Implementation method for drawing the button. ''' if self.palette and self.palette.is_up(): allocation = self.get_allocation() # draw a black background, has been done by the engine before cr.set_source_rgb(0, 0, 0) cr.rectangle(0, 0, allocation.width, allocation.height) cr.paint() Gtk.ToolButton.do_draw(self, cr) if self.palette and self.palette.is_up(): invoker = self.palette.props.invoker invoker.draw_rectangle(cr, self.palette) return False def do_clicked(self): ''' Implementation method for hiding the tooltip when the button is clicked. ''' if self._hide_tooltip_on_click and self.palette: self.palette.popdown(True)
class PaletteBox(Gtk.ToolItem): __gsignals__ = { 'changed': (GObject.SignalFlags.RUN_LAST, None, ([])), } def __init__(self, default, options): self._palette_invoker = ToolInvoker() Gtk.ToolItem.__init__(self) self._label = Gtk.Label() bt = Gtk.Button('') bt.set_can_focus(False) bt.remove(bt.get_children()[0]) self._box = Gtk.HBox() bt.add(self._box) self._icon = Icon(icon_name='') self._box.pack_start(self._icon, False, False, 5) self._box.pack_end(self._label, False, False, 5) self.add(bt) self.show_all() # theme the button, can be removed if add the style to the sugar css if style.zoom(100) == 100: subcell_size = 15 else: subcell_size = 11 radius = 2 * subcell_size theme = "GtkButton {border-radius: %dpx;}" % radius css_provider = Gtk.CssProvider() css_provider.load_from_data(theme) style_context = bt.get_style_context() style_context.add_provider(css_provider, Gtk.STYLE_PROVIDER_PRIORITY_USER) # init palette self._hide_tooltip_on_click = True self._palette_invoker.attach_tool(self) self._palette_invoker.props.toggle_palette = True self.palette = Palette(_('Select option')) self.palette.set_invoker(self._palette_invoker) # load the fonts in the palette menu self._menu_box = PaletteMenuBox() self.props.palette.set_content(self._menu_box) self._menu_box.show() for option in options: if option.__class__ is str: self._add_menu(option, activate_cb=self.__option_selected_cb) else: self._add_menu(option[0], icon=option[1], activate_cb=self.__option_selected_cb) self.set_value(default) def _set_icon(self, icon_name): self._box.remove(self._box.get_children()[0]) self._icon = Icon(icon_name=icon_name, pixel_size=style.STANDARD_ICON_SIZE) self._icon.show() self._box.pack_start(self._icon, False, False, 5) def __option_selected_cb(self, menu, option): self.set_value(option) self.emit('changed') def _add_menu(self, option, icon=None, activate_cb=None): if icon is not None: menu_item = PaletteMenuItem(icon_name=icon) if activate_cb is not None: menu_item.connect('activate', activate_cb, [option, icon]) else: menu_item = PaletteMenuItem() if activate_cb is not None: menu_item.connect('activate', activate_cb, option) menu_item.set_label(option) self._menu_box.append_item(menu_item) menu_item.show() def __destroy_cb(self, icon): if self._palette_invoker is not None: self._palette_invoker.detach() def create_palette(self): return None def get_palette(self): return self._palette_invoker.palette def set_palette(self, palette): self._palette_invoker.palette = palette palette = GObject.property(type=object, setter=set_palette, getter=get_palette) def get_palette_invoker(self): return self._palette_invoker def set_palette_invoker(self, palette_invoker): self._palette_invoker.detach() self._palette_invoker = palette_invoker palette_invoker = GObject.property(type=object, setter=set_palette_invoker, getter=get_palette_invoker) def set_value(self, value): self._value = value if value.__class__ is str: self._label.set_text(value) else: self._label.set_text(value[0]) self._set_icon(value[1]) def get_value(self): return self._value
class IntensitySelector(Gtk.ToolItem): __gsignals__ = { 'changed': (GObject.SignalFlags.RUN_LAST, None, ([])), } def __init__(self, value_range, default_value, default_image): Gtk.ToolItem.__init__(self) self._palette_invoker = ToolInvoker() self.palette = None self._values = value_range self._palette_invoker.attach_tool(self) # theme the buttons, can be removed if add the style to the sugar css # these are the same values used in gtk-widgets.css.em if style.zoom(100) == 100: subcell_size = 15 default_padding = 6 else: subcell_size = 11 default_padding = 4 hbox = Gtk.HBox() vbox = Gtk.VBox() self.add(vbox) # add a vbox to set the padding up and down vbox.pack_start(hbox, True, True, default_padding) self._size_down = ToolButton('go-previous-paired') self._palette_invoker.attach_tool(self._size_down) self._size_down.set_can_focus(False) self._size_down.connect('clicked', self.__value_changed_cb, False) hbox.pack_start(self._size_down, False, False, 5) # TODO: default? self._default_value = default_value self._value = self._default_value self.image_wrapper = Gtk.EventBox() self._intensityImage = Gtk.Image() self.image_wrapper.add(self._intensityImage) self.image_wrapper.show() self._intensityImage.set_from_file(default_image) self._intensityImage.show() self._palette_invoker.attach_widget(self.image_wrapper) hbox.pack_start(self.image_wrapper, False, False, 10) self._size_up = ToolButton('go-next-paired') self._palette_invoker.attach_tool(self._size_up) self._size_up.set_can_focus(False) self._size_up.connect('clicked', self.__value_changed_cb, True) hbox.pack_start(self._size_up, False, False, 5) radius = 2 * subcell_size theme_up = "GtkButton {border-radius:0px %dpx %dpx 0px;}" % (radius, radius) css_provider_up = Gtk.CssProvider() css_provider_up.load_from_data(theme_up) style_context = self._size_up.get_style_context() style_context.add_provider(css_provider_up, Gtk.STYLE_PROVIDER_PRIORITY_USER) theme_down = "GtkButton {border-radius: %dpx 0px 0px %dpx;}" % (radius, radius) css_provider_down = Gtk.CssProvider() css_provider_down.load_from_data(theme_down) style_context = self._size_down.get_style_context() style_context.add_provider(css_provider_down, Gtk.STYLE_PROVIDER_PRIORITY_USER) self.show_all() def __destroy_cb(self, **args): if self._palette_invoker is not None: self._palette_invoker.detach() def __value_changed_cb(self, button, increase): if self._value in self._values: i = self._values.index(self._value) if increase: if i < len(self._values) - 1: i += 1 else: if i > 0: i -= 1 else: i = self._values.index(self._default_value) self._value = self._values[i] self._size_down.set_sensitive(i != 0) self._size_up.set_sensitive(i < len(self._values) - 1) self.emit('changed') def set_value(self, val): if val not in self._values: # assure the val assigned is in the range # if not, assign one close. for v in self._values: if v > val: val = v break if val > self._values[-1]: size = self._values[-1] self._value = size self._size_label.set_text(str(self._value)) # update the buttons states i = self._values.index(self._value) self._size_down.set_sensitive(i != 0) self._size_up.set_sensitive(i < len(self._value) - 1) self.emit('changed') def set_tooltip(self, tooltip): """ Set a simple palette with just a single label. """ if self.palette is None or self._tooltip is None: self.palette = Palette(tooltip) elif self.palette is not None: self.palette.set_primary_text(tooltip) self._tooltip = tooltip def get_hide_tooltip_on_click(self): return self._hide_tooltip_on_click def set_hide_tooltip_on_click(self, hide_tooltip_on_click): if self._hide_tooltip_on_click != hide_tooltip_on_click: self._hide_tooltip_on_click = hide_tooltip_on_click hide_tooltip_on_click = GObject.Property(type=bool, default=True, getter=get_hide_tooltip_on_click, setter=set_hide_tooltip_on_click) def get_tooltip(self): return self._tooltip def create_palette(self): return None def get_palette(self): return self._palette_invoker.palette def set_palette(self, palette): self._palette_invoker.palette = palette palette = GObject.Property(type=object, setter=set_palette, getter=get_palette) def get_palette_invoker(self): return self._palette_invoker def set_palette_invoker(self, palette_invoker): self._palette_invoker.detach() self._palette_invoker = palette_invoker palette_invoker = GObject.Property(type=object, setter=set_palette_invoker, getter=get_palette_invoker) def do_draw(self, cr): Gtk.ToolButton.do_draw(self, cr) if self.palette and self.palette.is_up(): invoker = self.palette.props.invoker invoker.draw_rectangle(cr, self.palette) return False def do_clicked(self): if self._hide_tooltip_on_click and self.palette: self.palette.popdown(True) def set_image(self, image): self._intensityImage.set_from_file(image) def get_value(self): return self._value
class ColorToolButton(Gtk.ToolItem): # This not ideal. It would be better to subclass Gtk.ToolButton, however # the python bindings do not seem to be powerfull enough for that. # (As we need to change a variable in the class structure.) __gtype_name__ = 'SugarColorToolButton' __gsignals__ = {'color-set': (GObject.SignalFlags.RUN_FIRST, None, tuple())} def __init__(self, icon_name='color-preview', **kwargs): self._accelerator = None self._tooltip = None self._palette_invoker = ToolInvoker() self._palette = None GObject.GObject.__init__(self, **kwargs) # The Gtk.ToolButton has already added a normal button. # Replace it with a ColorButton color_button = _ColorButton(icon_name=icon_name, has_invoker=False) self.add(color_button) color_button.show() # The following is so that the behaviour on the toolbar is correct. color_button.set_relief(Gtk.ReliefStyle.NONE) color_button.icon_size = Gtk.IconSize.LARGE_TOOLBAR self._palette_invoker.attach_tool(self) self._palette_invoker.props.toggle_palette = True self._palette_invoker.props.lock_palette = True # This widget just proxies the following properties to the colorbutton color_button.connect('notify::color', self.__notify_change) color_button.connect('notify::icon-name', self.__notify_change) color_button.connect('notify::icon-size', self.__notify_change) color_button.connect('notify::title', self.__notify_change) color_button.connect('color-set', self.__color_set_cb) color_button.connect('can-activate-accel', self.__button_can_activate_accel_cb) def __button_can_activate_accel_cb(self, button, signal_id): # Accept activation via accelerators regardless of this widget's state return True def set_accelerator(self, accelerator): self._accelerator = accelerator setup_accelerator(self) def get_accelerator(self): return self._accelerator accelerator = GObject.property(type=str, setter=set_accelerator, getter=get_accelerator) def create_palette(self): self._palette = self.get_child().create_palette() return self._palette def get_palette_invoker(self): return self._palette_invoker def set_palette_invoker(self, palette_invoker): self._palette_invoker.detach() self._palette_invoker = palette_invoker palette_invoker = GObject.property( type=object, setter=set_palette_invoker, getter=get_palette_invoker) def set_expanded(self, expanded): box = self.toolbar_box if not box: return if not expanded: self._palette_invoker.notify_popdown() return if box.expanded_button is not None: box.expanded_button.queue_draw() if box.expanded_button != self: box.expanded_button.set_expanded(False) box.expanded_button = self def get_toolbar_box(self): parent = self.get_parent() if not hasattr(parent, 'owner'): return None return parent.owner toolbar_box = property(get_toolbar_box) def set_color(self, color): self.get_child().props.color = color def get_color(self): return self.get_child().props.color color = GObject.property(type=object, getter=get_color, setter=set_color) def set_icon_name(self, icon_name): self.get_child().props.icon_name = icon_name def get_icon_name(self): return self.get_child().props.icon_name icon_name = GObject.property(type=str, getter=get_icon_name, setter=set_icon_name) def set_icon_size(self, icon_size): self.get_child().props.icon_size = icon_size def get_icon_size(self): return self.get_child().props.icon_size icon_size = GObject.property(type=int, getter=get_icon_size, setter=set_icon_size) def set_title(self, title): self.get_child().props.title = title def get_title(self): return self.get_child().props.title title = GObject.property(type=str, getter=get_title, setter=set_title) def do_draw(self, cr): if self._palette and self._palette.is_up(): allocation = self.get_allocation() # draw a black background, has been done by the engine before cr.set_source_rgb(0, 0, 0) cr.rectangle(0, 0, allocation.width, allocation.height) cr.paint() Gtk.ToolItem.do_draw(self, cr) if self._palette and self._palette.is_up(): invoker = self._palette.props.invoker invoker.draw_rectangle(cr, self._palette) return False def __notify_change(self, widget, pspec): self.notify(pspec.name) def __color_set_cb(self, widget): self.emit('color-set')
class FontComboBox(Gtk.ToolItem): __gsignals__ = { 'changed': (GObject.SignalFlags.RUN_LAST, None, ([])), } def __init__(self): self._palette_invoker = ToolInvoker() Gtk.ToolItem.__init__(self) self._font_label = FontLabel() bt = Gtk.Button('') bt.set_can_focus(False) bt.remove(bt.get_children()[0]) box = Gtk.HBox() bt.add(box) icon = Icon(icon_name='font-text') box.pack_start(icon, False, False, 10) box.pack_start(self._font_label, False, False, 10) self.add(bt) self.show_all() self._font_name = 'Sans' # theme the button, can be removed if add the style to the sugar css if style.zoom(100) == 100: subcell_size = 15 else: subcell_size = 11 radius = 2 * subcell_size theme = "GtkButton {border-radius: %dpx;}" % radius css_provider = Gtk.CssProvider() css_provider.load_from_data(theme) style_context = bt.get_style_context() style_context.add_provider(css_provider, Gtk.STYLE_PROVIDER_PRIORITY_USER) # init palette self._hide_tooltip_on_click = True self._palette_invoker.attach_tool(self) self._palette_invoker.props.toggle_palette = True self.palette = Palette(_('Select font')) self.palette.set_invoker(self._palette_invoker) # load the fonts in the palette menu self._menu_box = PaletteMenuBox() self.props.palette.set_content(self._menu_box) self._menu_box.show() context = self.get_pango_context() self._init_font_list() tmp_list = [] for family in context.list_families(): name = family.get_name() if name in self._font_white_list: tmp_list.append(name) for name in sorted(tmp_list): self._add_menu(name, self.__font_selected_cb) self._font_label.set_font(self._font_name) def _init_font_list(self): self._font_white_list = [] self._font_white_list.extend(DEFAULT_FONTS) # check if there are a user configuration file if not os.path.exists(USER_FONTS_FILE_PATH): # verify if exists a file in /etc if os.path.exists(GLOBAL_FONTS_FILE_PATH): shutil.copy(GLOBAL_FONTS_FILE_PATH, USER_FONTS_FILE_PATH) if os.path.exists(USER_FONTS_FILE_PATH): # get the font names in the file to the white list fonts_file = open(USER_FONTS_FILE_PATH) # get the font names in the file to the white list for line in fonts_file: self._font_white_list.append(line.strip()) # monitor changes in the file gio_fonts_file = Gio.File.new_for_path(USER_FONTS_FILE_PATH) self.monitor = gio_fonts_file.monitor_file( Gio.FileMonitorFlags.NONE, None) self.monitor.set_rate_limit(5000) self.monitor.connect('changed', self._reload_fonts) def _reload_fonts(self, monitor, gio_file, other_file, event): if event != Gio.FileMonitorEvent.CHANGES_DONE_HINT: return self._font_white_list = [] self._font_white_list.extend(DEFAULT_FONTS) fonts_file = open(USER_FONTS_FILE_PATH) for line in fonts_file: self._font_white_list.append(line.strip()) # update the menu for child in self._menu_box.get_children(): self._menu_box.remove(child) child = None context = self.get_pango_context() tmp_list = [] for family in context.list_families(): name = family.get_name() if name in self._font_white_list: tmp_list.append(name) for name in sorted(tmp_list): self._add_menu(name, self.__font_selected_cb) return False def __font_selected_cb(self, menu, font_name): self._font_name = font_name self._font_label.set_font(font_name) self.emit('changed') def _add_menu(self, font_name, activate_cb): label = '<span font="%s">%s</span>' % (font_name, font_name) menu_item = PaletteMenuItem() menu_item.set_label(label) menu_item.connect('activate', activate_cb, font_name) self._menu_box.append_item(menu_item) menu_item.show() def __destroy_cb(self, icon): if self._palette_invoker is not None: self._palette_invoker.detach() def create_palette(self): return None def get_palette(self): return self._palette_invoker.palette def set_palette(self, palette): self._palette_invoker.palette = palette palette = GObject.property( type=object, setter=set_palette, getter=get_palette) def get_palette_invoker(self): return self._palette_invoker def set_palette_invoker(self, palette_invoker): self._palette_invoker.detach() self._palette_invoker = palette_invoker palette_invoker = GObject.property( type=object, setter=set_palette_invoker, getter=get_palette_invoker) def set_font_name(self, font_name): self._font_label.set_font(font_name) def get_font_name(self): return self._font_name
class ButtonStrokeColor(Gtk.ToolItem): """Class to manage the Stroke Color of a Button""" __gtype_name__ = 'BrushColorToolButton' __gsignals__ = {'color-set': (GObject.SignalFlags.RUN_FIRST, None, tuple())} def __init__(self, activity, **kwargs): self._activity = activity self.properties = self._activity.area.tool self._accelerator = None self._tooltip = None self._palette_invoker = ToolInvoker() self._palette = None self._selected_tool = None GObject.GObject.__init__(self, **kwargs) # The Gtk.ToolButton has already added a normal button. # Replace it with a ColorButton self.color_button = BrushButton(has_invoker=False) self.add(self.color_button) self.color_button.set_brush_size(self.properties['line size']) self.color_button.set_brush_shape(self.properties['line shape']) self.color_button.set_stamp_size(20) # The following is so that the behaviour on the toolbar is correct. self.color_button.set_relief(Gtk.ReliefStyle.NONE) self._palette_invoker.attach_tool(self) self._palette_invoker.props.toggle_palette = True self._palette_invoker.props.lock_palette = True # This widget just proxies the following properties to the colorbutton self.color_button.connect('notify::color', self.__notify_change) self.color_button.connect('notify::icon-name', self.__notify_change) self.color_button.connect('notify::icon-size', self.__notify_change) self.color_button.connect('notify::title', self.__notify_change) self.color_button.connect('can-activate-accel', self.__button_can_activate_accel_cb) self.create_palette() def __button_can_activate_accel_cb(self, button, signal_id): # Accept activation via accelerators regardless of this widget's state return True def __notify_change(self, widget, pspec): self.color_button.set_color(self.get_color()) self.notify(pspec.name) def _color_button_cb(self, widget, pspec): color = self.get_color() self.set_stroke_color(color) def create_palette(self): self._palette = self.get_child().create_palette() color_palette_hbox = self._palette._picker_hbox self.custom_box = Gtk.VBox() self.vbox_brush_options = Gtk.VBox() # This is where we set restrictions for size: # Initial value, minimum value, maximum value, step adj = Gtk.Adjustment(self.properties['line size'], 1.0, 100.0, 1.0) self.size_scale = Gtk.HScale() self.size_scale.set_adjustment(adj) self.size_scale.set_draw_value(False) self.size_scale.set_size_request(style.zoom(200), -1) self.size_label = Gtk.Label(label=_('Size')) self.size_label.props.halign = Gtk.Align.START self.vbox_brush_options.pack_start(self.size_label, True, True, 0) self.vbox_brush_options.pack_start(self.size_scale, True, True, 0) self.size_scale.connect('value-changed', self._on_value_changed) # Control alpha alpha = self.properties['alpha'] * 100 adj_alpha = Gtk.Adjustment(alpha, 10.0, 100.0, 1.0) self.alpha_scale = Gtk.HScale() self.alpha_scale.set_adjustment(adj_alpha) self.alpha_scale.set_draw_value(False) self.alpha_scale.set_size_request(style.zoom(200), -1) self.alpha_label = Gtk.Label(label=_('Opacity')) self.alpha_label.props.halign = Gtk.Align.START self.vbox_brush_options.pack_start(self.alpha_label, True, True, 0) self.vbox_brush_options.pack_start(self.alpha_scale, True, True, 0) self.alpha_scale.connect('value-changed', self._on_alpha_changed) # User is able to choose Shapes for 'Brush' and 'Eraser' self.shape_box = Gtk.HBox() self.custom_box.pack_start(self.vbox_brush_options, True, True, 0) item1 = RadioToolButton() item1.set_icon_name('tool-shape-ellipse') item2 = RadioToolButton() item2.set_icon_name('tool-shape-rectangle') item2.props.group = item1 if self.properties['line shape'] == 'circle': item1.set_active(True) else: item2.set_active(True) item1.connect('toggled', self._on_toggled, self.properties, 'circle') item2.connect('toggled', self._on_toggled, self.properties, 'square') self.shape_box.pack_start(Gtk.Label(_('Shape')), True, True, 0) self.shape_box.pack_start(item1, True, True, 0) self.shape_box.pack_start(item2, True, True, 0) self.vbox_brush_options.pack_start(self.shape_box, True, True, 0) self.keep_aspect_checkbutton = Gtk.CheckButton(_('Keep aspect')) ratio = self._activity.area.keep_aspect_ratio self.keep_aspect_checkbutton.set_active(ratio) self.keep_aspect_checkbutton.connect( 'toggled', self._keep_aspect_checkbutton_toggled) self.vbox_brush_options.pack_start(self.keep_aspect_checkbutton, True, True, 0) self.custom_separator = Gtk.VSeparator() color_palette_hbox.pack_start(self.custom_separator, True, True, padding=style.DEFAULT_SPACING) color_palette_hbox.pack_start(self.custom_box, True, True, padding=style.DEFAULT_SPACING) color_palette_hbox.show_all() self._update_palette() return self._palette def _keep_aspect_checkbutton_toggled(self, checkbutton): self._activity.area.keep_aspect_ratio = checkbutton.get_active() def _update_palette(self): tool_name = self._selected_tool show_controls = () show_colors = False if tool_name == 'brush' or tool_name is None: title = _('Brush properties') show_colors = True show_controls = (self.size_label, self.size_scale, self.shape_box, self.alpha_label, self.alpha_scale) elif tool_name == 'stamp': show_controls = (self.size_label, self.size_scale) title = _('Stamp properties') elif tool_name == 'eraser': show_controls = (self.size_label, self.size_scale, self.shape_box) title = _('Eraser properties') elif tool_name == 'bucket': show_colors = True title = _('Bucket properties') elif tool_name == 'picker': title = _('Picker properties') elif tool_name == 'marquee-rectangular': title = _('Select Area') show_controls = (self.keep_aspect_checkbutton,) else: title = '' self._palette._picker_hbox.show_all() # Hide palette color widgets except size: if not show_colors: palette_children = self._palette._picker_hbox.get_children() for ch in palette_children: if ch != self.custom_box: ch.hide() elif not show_controls: self.custom_separator.hide() self.vbox_brush_options.show_all() controls = self.vbox_brush_options.get_children() for control in controls: if control not in show_controls: control.hide() # Change title: self.set_title(title) self._palette._picker_hbox.resize_children() self._palette._picker_hbox.queue_draw() def update_stamping(self): if self.color_button.is_stamping(): self.size_scale.set_value(self.color_button.stamp_size) else: self.size_scale.set_value(self.color_button.brush_size) self._update_palette() def _on_alpha_changed(self, scale): alpha = scale.get_value() / 100.0 self._activity.area.set_alpha(alpha) self.color_button.set_alpha(alpha) def _on_value_changed(self, scale): size = int(scale.get_value()) if self.color_button.is_stamping(): # avoid stamps too small if size > 5: self.properties['stamp size'] = size resized_stamp = self._activity.area.resize_stamp(size) self.color_button.set_resized_stamp(resized_stamp) self.color_button.set_stamp_size(self.properties['stamp size']) else: self.properties['line size'] = size self.color_button.set_brush_size(self.properties['line size']) self._activity.area.set_tool(self.properties) def _on_toggled(self, radiobutton, tool, shape): if radiobutton.get_active(): self.properties['line shape'] = shape self.color_button.set_brush_shape(shape) self.color_button.set_brush_size(self.properties['line size']) def get_palette_invoker(self): return self._palette_invoker def set_palette_invoker(self, palette_invoker): self._palette_invoker.detach() self._palette_invoker = palette_invoker palette_invoker = GObject.property( type=object, setter=set_palette_invoker, getter=get_palette_invoker) def set_expanded(self, expanded): box = self.toolbar_box if not box: return if not expanded: self._palette_invoker.notify_popdown() return if box.expanded_button is not None: box.expanded_button.queue_draw() if box.expanded_button != self: box.expanded_button.set_expanded(False) box.expanded_button = self def get_toolbar_box(self): parent = self.get_parent() if not hasattr(parent, 'owner'): return None return parent.owner toolbar_box = property(get_toolbar_box) def set_color(self, color): self.color_button.set_color(color) def get_color(self): return self.get_child().props.color color = GObject.property(type=object, getter=get_color, setter=set_color) def set_title(self, title): self.get_child().props.title = title def get_title(self): return self.get_child().props.title title = GObject.property(type=str, getter=get_title, setter=set_title) def get_selected_tool(self): return self._selected_tool def set_selected_tool(self, tool_name): self._selected_tool = tool_name def do_draw(self, cr): if self._palette and self._palette.is_up(): allocation = self.get_allocation() # draw a black background, has been done by the engine before cr.set_source_rgb(0, 0, 0) cr.rectangle(0, 0, allocation.width, allocation.height) cr.paint() Gtk.ToolItem.do_draw(self, cr) if self._palette and self._palette.is_up(): invoker = self._palette.props.invoker invoker.draw_rectangle(cr, self._palette) return False
class ToggleToolButton(Gtk.ToggleToolButton): ''' UI for toggletoolbutton. A ToggleToolButton is a ToolItem that contains a toggle button, having an icon, a tooltip palette, and an accelerator. Use ToggleToolButton.new() to create a new ToggleToolButton. Args: accelerator (string): keyboard shortcut to be used to activate this button. Find about format here : https://developer.gnome.org/gtk3/stable/gtk3-Keyboard-Accelerators.html#gtk-accelerator-parse tooltip (string): tooltip to be displayed when user hovers over toggle button. Keyword Args: icon_name(string): name of themed icon which is to be used. ''' __gtype_name__ = 'SugarToggleToolButton' def __init__(self, icon_name=None): GObject.GObject.__init__(self) self._palette_invoker = ToolInvoker(self) if icon_name: self.set_icon_name(icon_name) self.connect('destroy', self.__destroy_cb) def __destroy_cb(self, icon): if self._palette_invoker is not None: self._palette_invoker.detach() def set_icon_name(self, icon_name): ''' Sets the icon for the tool button from a named themed icon. If it is none then no icon will be shown. Args: icon_name(string): The name for a themed icon. It can be set as 'None' too. Example: set_icon_name('view-radial') ''' icon = Icon(icon_name=icon_name) self.set_icon_widget(icon) icon.show() def get_icon_name(self): ''' The get_icon_name() method returns the value of the icon_name property that contains the name of a themed icon or None. ''' if self.props.icon_widget is not None: return self.props.icon_widget.props.icon_name else: return None icon_name = GObject.property(type=str, setter=set_icon_name, getter=get_icon_name) def create_palette(self): return None def get_palette(self): return self._palette_invoker.palette def set_palette(self, palette): self._palette_invoker.palette = palette palette = GObject.property( type=object, setter=set_palette, getter=get_palette) def get_palette_invoker(self): return self._palette_invoker def set_palette_invoker(self, palette_invoker): self._palette_invoker.detach() self._palette_invoker = palette_invoker palette_invoker = GObject.property( type=object, setter=set_palette_invoker, getter=get_palette_invoker) def set_tooltip(self, text): ''' Sets the tooltip of the toogle tool button. Displays when user hovers over the button with cursor. Args: tooltip (string): tooltip to be added to the button ''' self.set_palette(Palette(text)) def set_accelerator(self, accelerator): ''' Sets keyboard shortcut that activates this button. Args: accelerator(string): accelerator to be set. Should be in form <modifier>Letter Find about format here : https://developer.gnome.org/gtk3/stable/gtk3-Keyboard-Accelerators.html#gtk-accelerator-parse Example: set_accelerator(self, 'accel') ''' self._accelerator = accelerator setup_accelerator(self) def get_accelerator(self): ''' Returns above accelerator string. ''' return self._accelerator accelerator = GObject.property(type=str, setter=set_accelerator, getter=get_accelerator) def do_draw(self, cr): ''' Implementation method for drawing the toogle tool button ''' if self.palette and self.palette.is_up(): allocation = self.get_allocation() # draw a black background, has been done by the engine before cr.set_source_rgb(0, 0, 0) cr.rectangle(0, 0, allocation.width, allocation.height) cr.paint() Gtk.ToggleToolButton.do_draw(self, cr) if self.palette and self.palette.is_up(): invoker = self.palette.props.invoker invoker.draw_rectangle(cr, self.palette) return False def do_clicked(self): ''' Implementation method for hiding the tooltip when the toggle button is clicked ''' if self.palette: self.palette.popdown(True) palette = property(get_palette, set_palette)
class ButtonStrokeColor(Gtk.ToolItem): """Class to manage the Stroke Color of a Button""" __gtype_name__ = 'BrushColorToolButton' __gsignals__ = { 'color-set': (GObject.SignalFlags.RUN_FIRST, None, tuple()) } def __init__(self, activity, **kwargs): Gtk.ToolItem.__init__(self, **kwargs) self._activity = activity self.properties = self._activity.area.tool self._accelerator = None self._tooltip = None self._palette_invoker = ToolInvoker() self._palette = None self._selected_tool = None # The Gtk.ToolButton has already added a normal button. # Replace it with a ColorButton self.color_button = BrushButton(has_invoker=False) self.add(self.color_button) self.color_button.set_brush_size(self.properties['line size']) self.color_button.set_brush_shape(self.properties['line shape']) self.color_button.set_stamp_size(20) # The following is so that the behaviour on the toolbar is correct. self.color_button.set_relief(Gtk.ReliefStyle.NONE) self._palette_invoker.attach_tool(self) self._palette_invoker.props.toggle_palette = True self._palette_invoker.props.lock_palette = True # This widget just proxies the following properties to the colorbutton self.color_button.connect('notify::color', self.__notify_change) self.color_button.connect('notify::icon-name', self.__notify_change) self.color_button.connect('notify::icon-size', self.__notify_change) self.color_button.connect('notify::title', self.__notify_change) self.color_button.connect('can-activate-accel', self.__button_can_activate_accel_cb) self.create_palette() def __button_can_activate_accel_cb(self, button, signal_id): # Accept activation via accelerators regardless of this widget's state return True def __notify_change(self, widget, pspec): self.color_button.set_color(self.get_color()) self.notify(pspec.name) def _color_button_cb(self, widget, pspec): color = self.get_color() self.set_stroke_color(color) def create_palette(self): self._palette = self.get_child().create_palette() color_palette_hbox = self._palette._picker_hbox self.custom_box = Gtk.VBox() self.vbox_brush_options = Gtk.VBox() # This is where we set restrictions for size: # Initial value, minimum value, maximum value, step adj = Gtk.Adjustment(self.properties['line size'], 1.0, 100.0, 1.0) self.size_scale = Gtk.HScale() self.size_scale.set_adjustment(adj) self.size_scale.set_draw_value(False) self.size_scale.set_size_request(style.zoom(200), -1) self.size_label = Gtk.Label(label=_('Size')) self.size_label.props.halign = Gtk.Align.START self.vbox_brush_options.pack_start(self.size_label, True, True, 0) self.vbox_brush_options.pack_start(self.size_scale, True, True, 0) self.size_scale.connect('value-changed', self._on_value_changed) # Control alpha alpha = self.properties['alpha'] * 100 adj_alpha = Gtk.Adjustment(alpha, 10.0, 100.0, 1.0) self.alpha_scale = Gtk.HScale() self.alpha_scale.set_adjustment(adj_alpha) self.alpha_scale.set_draw_value(False) self.alpha_scale.set_size_request(style.zoom(200), -1) self.alpha_label = Gtk.Label(label=_('Opacity')) self.alpha_label.props.halign = Gtk.Align.START self.vbox_brush_options.pack_start(self.alpha_label, True, True, 0) self.vbox_brush_options.pack_start(self.alpha_scale, True, True, 0) self.alpha_scale.connect('value-changed', self._on_alpha_changed) # User is able to choose Shapes for 'Brush' and 'Eraser' self.shape_box = Gtk.HBox() self.custom_box.pack_start(self.vbox_brush_options, True, True, 0) item1 = RadioToolButton() item1.set_icon_name('tool-shape-ellipse') item2 = RadioToolButton() item2.set_icon_name('tool-shape-rectangle') item2.props.group = item1 if self.properties['line shape'] == 'circle': item1.set_active(True) else: item2.set_active(True) item1.connect('toggled', self._on_toggled, self.properties, 'circle') item2.connect('toggled', self._on_toggled, self.properties, 'square') self.shape_box.pack_start(Gtk.Label(_('Shape')), True, True, 0) self.shape_box.pack_start(item1, True, True, 0) self.shape_box.pack_start(item2, True, True, 0) self.vbox_brush_options.pack_start(self.shape_box, True, True, 0) self.keep_aspect_checkbutton = Gtk.CheckButton(_('Keep aspect')) ratio = self._activity.area.keep_aspect_ratio self.keep_aspect_checkbutton.set_active(ratio) self.keep_aspect_checkbutton.connect( 'toggled', self._keep_aspect_checkbutton_toggled) self.vbox_brush_options.pack_start(self.keep_aspect_checkbutton, True, True, 0) self.custom_separator = Gtk.VSeparator() color_palette_hbox.pack_start(self.custom_separator, True, True, padding=style.DEFAULT_SPACING) color_palette_hbox.pack_start(self.custom_box, True, True, padding=style.DEFAULT_SPACING) color_palette_hbox.show_all() self._update_palette() return self._palette def _keep_aspect_checkbutton_toggled(self, checkbutton): self._activity.area.keep_aspect_ratio = checkbutton.get_active() def _update_palette(self): tool_name = self._selected_tool show_controls = () show_colors = False if tool_name == 'brush' or tool_name is None: title = _('Brush properties') show_colors = True show_controls = (self.size_label, self.size_scale, self.shape_box, self.alpha_label, self.alpha_scale) elif tool_name in ('stamp', 'load-stamp'): show_controls = (self.size_label, self.size_scale) title = _('Stamp properties') elif tool_name == 'eraser': show_controls = (self.size_label, self.size_scale, self.shape_box) title = _('Eraser properties') elif tool_name == 'bucket': show_colors = True title = _('Bucket properties') elif tool_name == 'picker': title = _('Picker properties') elif tool_name == 'marquee-rectangular': title = _('Select Area') show_controls = (self.keep_aspect_checkbutton, ) else: title = '' self._palette._picker_hbox.show_all() # Hide palette color widgets except size: if not show_colors: palette_children = self._palette._picker_hbox.get_children() for ch in palette_children: if ch != self.custom_box: ch.hide() elif not show_controls: self.custom_separator.hide() self.vbox_brush_options.show_all() controls = self.vbox_brush_options.get_children() for control in controls: if control not in show_controls: control.hide() # Change title: self.set_title(title) self._palette._picker_hbox.resize_children() self._palette._picker_hbox.queue_draw() def update_stamping(self): if self.color_button.is_stamping(): self.size_scale.set_value(self.color_button.stamp_size) else: self.size_scale.set_value(self.color_button.brush_size) self.size_scale.queue_draw() self._update_palette() def _on_alpha_changed(self, scale): alpha = scale.get_value() / 100.0 self._activity.area.set_alpha(alpha) self.color_button.set_alpha(alpha) def _on_value_changed(self, scale): size = int(scale.get_value()) if self.color_button.is_stamping(): # avoid stamps too small if size > 5: self.properties['stamp size'] = size resized_stamp = self._activity.area.resize_stamp(size) self.color_button.set_resized_stamp(resized_stamp) self.color_button.set_stamp_size(self.properties['stamp size']) else: self.properties['line size'] = size self.color_button.set_brush_size(self.properties['line size']) self._activity.area.set_tool(self.properties) def _on_toggled(self, radiobutton, tool, shape): if radiobutton.get_active(): self.properties['line shape'] = shape self.color_button.set_brush_shape(shape) self.color_button.set_brush_size(self.properties['line size']) def get_palette_invoker(self): return self._palette_invoker def set_palette_invoker(self, palette_invoker): self._palette_invoker.detach() self._palette_invoker = palette_invoker palette_invoker = GObject.Property(type=object, setter=set_palette_invoker, getter=get_palette_invoker) def set_expanded(self, expanded): box = self.toolbar_box if not box: return if not expanded: self._palette_invoker.notify_popdown() return if box.expanded_button is not None: box.expanded_button.queue_draw() if box.expanded_button != self: box.expanded_button.set_expanded(False) box.expanded_button = self def get_toolbar_box(self): parent = self.get_parent() if not hasattr(parent, 'owner'): return None return parent.owner toolbar_box = property(get_toolbar_box) def set_color(self, color): self.color_button.set_color(color) def get_color(self): return self.get_child().props.color color = GObject.Property(type=object, getter=get_color, setter=set_color) def set_title(self, title): self.get_child().props.title = title def get_title(self): return self.get_child().props.title title = GObject.Property(type=str, getter=get_title, setter=set_title) def get_selected_tool(self): return self._selected_tool def set_selected_tool(self, tool_name): self._selected_tool = tool_name def do_draw(self, cr): if self._palette and self._palette.is_up(): allocation = self.get_allocation() # draw a black background, has been done by the engine before cr.set_source_rgb(0, 0, 0) cr.rectangle(0, 0, allocation.width, allocation.height) cr.paint() Gtk.ToolItem.do_draw(self, cr) if self._palette and self._palette.is_up(): invoker = self._palette.props.invoker invoker.draw_rectangle(cr, self._palette) return False
class FontComboBox(Gtk.ToolItem): __gsignals__ = { "changed": (GObject.SignalFlags.RUN_LAST, None, [str]), } def __init__(self, font_name): Gtk.ToolItem.__init__(self) self._palette_invoker = ToolInvoker() self._font_label = FontLabel(font_name) self._font_name = font_name bt = Gtk.Button("") bt.set_can_focus(False) bt.set_valign(Gtk.Align.CENTER) bt.remove(bt.get_children()[0]) box = Gtk.HBox() icon = Icon(icon_name="font-text") box.pack_start(icon, False, False, 10) box.pack_start(self._font_label, False, False, 10) bt.add(box) self.add(bt) self.show_all() if style.zoom(100) == 100: subcell_size = 15 else: subcell_size = 11 radius = 2 * subcell_size theme = "GtkButton { border-radius: %dpx; }" % radius css_provider = Gtk.CssProvider() css_provider.load_from_data(theme) style_context = bt.get_style_context() style_context.add_provider(css_provider, Gtk.STYLE_PROVIDER_PRIORITY_USER) self._hide_tooltip_on_click = True self._palette_invoker.attach_tool(self) self._palette_invoker.props.toggle_palette = True self.palette = Palette(_("Select font")) self.palette.set_invoker(self._palette_invoker) self._menu_box = PaletteMenuBox() self.props.palette.set_content(self._menu_box) self._menu_box.show() context = self.get_pango_context() self._init_font_list() tmp_list = [] for family in context.list_families(): name = family.get_name() if name in self._font_white_list: tmp_list.append(name) for name in sorted(tmp_list): self._add_menu(name, self.__font_selected_cb) self._font_label.set_font(self._font_name) def _init_font_list(self): self._font_white_list = [] self._font_white_list.extend(G.DEFAULT_FONTS) if not os.path.exists(G.USER_FONTS_FILE_PATH): if os.path.exists(G.GLOBAL_FONTS_FILE_PATH): shutil.copy(G.GLOBAL_FONTS_FILE_PATH, G.USER_FONTS_FILE_PATH) if os.path.exists(G.USER_FONTS_FILE_PATH): fonts_file = open(G.USER_FONTS_FILE_PATH) for line in fonts_file: self._font_white_list.append(line.strip()) gio_fonts_file = Gio.File.new_for_path(G.USER_FONTS_FILE_PATH) self.monitor = gio_fonts_file.monitor_file( Gio.FileMonitorFlags.NONE, None) self.monitor.set_rate_limit(5000) self.monitor.connect("changed", self._reload_fonts) def _reload_fonts(self, monitor, gio_file, other_file, event): if event != Gio.FileMonitorEvent.CHANGES_DONE_HINT: return self._font_white_list = [] self._font_white_list.extend(G.DEFAULT_FONTS) fonts_file = open(G.USER_FONTS_FILE_PATH) for line in fonts_file: self._font_white_list.append(line.strip()) for child in self._menu_box.get_children(): self._menu_box.remove(child) child = None context = self.get_pango_context() tmp_list = [] for family in context.list_families(): name = family.get_name() if name in self._font_white_list: tmp_list.append(name) for name in sorted(tmp_list): self._add_menu(name, self.__font_selected_cb) return False def __font_selected_cb(self, menu, font_name): self._font_name = font_name self._font_label.set_font(font_name) self.emit("changed", self._font_name) def _add_menu(self, font_name, activate_cb): label = '<span font="%s">%s</span>' % (font_name, font_name) menu_item = PaletteMenuItem() menu_item.set_label(label) menu_item.connect("activate", activate_cb, font_name) self._menu_box.append_item(menu_item) menu_item.show() def __destroy_cb(self, icon): if self._palette_invoker is not None: self._palette_invoker.detach() def create_palette(self): return None def get_palette(self): return self._palette_invoker.palette def set_palette(self, palette): self._palette_invoker.palette = palette palette = GObject.property(type=object, setter=set_palette, getter=get_palette) def get_palette_invoker(self): return self._palette_invoker def set_palette_invoker(self, palette_invoker): self._palette_invoker.detach() self._palette_invoker = palette_invoker palette_invoker = GObject.property(type=object, setter=set_palette_invoker, getter=get_palette_invoker) def set_font_name(self, font_name): self._font_label.set_font(font_name) def get_font_name(self): return self._font_name
class ProgressToolButton(Gtk.ToolButton): """Display the progress filling the ToolButton icon. Call update(progress) with the new progress to update the ToolButton icon. The direction defaults to 'vertical', in which case the icon is filled from bottom to top. If direction is set to 'horizontal', it will be filled from right to left or from left to right, depending on the system's language RTL setting. """ __gtype_name__ = 'SugarProgressToolButton' def __init__(self, icon_name=None, pixel_size=None, direction='vertical', **kwargs): self._accelerator = None self._tooltip = None self._palette_invoker = ToolInvoker() self._progress = 0.0 self._icon_name = icon_name self._pixel_size = pixel_size self._direction = direction GObject.GObject.__init__(self, **kwargs) self._hide_tooltip_on_click = True self._palette_invoker.attach_tool(self) self._stroke = get_surface( icon_name=self._icon_name, width=self._pixel_size, height=self._pixel_size, stroke_color=style.COLOR_BUTTON_GREY.get_svg(), #stroke_color=style.COLOR_WHITE.get_svg(), fill_color=style.COLOR_TRANSPARENT.get_svg()) self._fill = get_surface( icon_name=self._icon_name, width=self._pixel_size, height=self._pixel_size, stroke_color=style.COLOR_TRANSPARENT.get_svg(), fill_color=style.COLOR_WHITE.get_svg()) self.get_child().connect('can-activate-accel', self.__button_can_activate_accel_cb) self.connect('destroy', self.__destroy_cb) def __destroy_cb(self, icon): if self._palette_invoker is not None: self._palette_invoker.detach() def __button_can_activate_accel_cb(self, button, signal_id): # Accept activation via accelerators regardless of this widget's state return True def set_tooltip(self, tooltip): """ Set a simple palette with just a single label. """ if self.palette is None or self._tooltip is None: self.palette = Palette(tooltip) elif self.palette is not None: self.palette.set_primary_text(tooltip) self._tooltip = tooltip # Set label, shows up when toolbar overflows Gtk.ToolButton.set_label(self, tooltip) def get_tooltip(self): return self._tooltip tooltip = GObject.property(type=str, setter=set_tooltip, getter=get_tooltip) def get_hide_tooltip_on_click(self): return self._hide_tooltip_on_click def set_hide_tooltip_on_click(self, hide_tooltip_on_click): if self._hide_tooltip_on_click != hide_tooltip_on_click: self._hide_tooltip_on_click = hide_tooltip_on_click hide_tooltip_on_click = GObject.property(type=bool, default=True, getter=get_hide_tooltip_on_click, setter=set_hide_tooltip_on_click) def set_accelerator(self, accelerator): self._accelerator = accelerator setup_accelerator(self) def get_accelerator(self): return self._accelerator accelerator = GObject.property(type=str, setter=set_accelerator, getter=get_accelerator) def set_icon_name(self, icon_name): icon = Icon(icon_name=icon_name) self.set_icon_widget(icon) icon.show() def get_icon_name(self): if self.props.icon_widget is not None: return self.props.icon_widget.props.icon_name else: return None icon_name = GObject.property(type=str, setter=set_icon_name, getter=get_icon_name) def create_palette(self): return None def get_palette(self): return self._palette_invoker.palette def set_palette(self, palette): self._palette_invoker.palette = palette palette = GObject.property(type=object, setter=set_palette, getter=get_palette) def get_palette_invoker(self): return self._palette_invoker def set_palette_invoker(self, palette_invoker): self._palette_invoker.detach() self._palette_invoker = palette_invoker palette_invoker = GObject.property(type=object, setter=set_palette_invoker, getter=get_palette_invoker) def do_draw(self, cr): if self._progress > 0: self._stroke = get_surface( icon_name=self._icon_name, width=self._pixel_size, height=self._pixel_size, stroke_color=style.COLOR_WHITE.get_svg(), fill_color=style.COLOR_TRANSPARENT.get_svg()) else: self._stroke = get_surface( icon_name=self._icon_name, width=self._pixel_size, height=self._pixel_size, stroke_color=style.COLOR_BUTTON_GREY.get_svg(), fill_color=style.COLOR_TRANSPARENT.get_svg()) allocation = self.get_allocation() # Center the graphic in the allocated space. margin_x = (allocation.width - self._stroke.get_width()) / 2 margin_y = (allocation.height - self._stroke.get_height()) / 2 cr.translate(margin_x, margin_y) # Paint the fill, clipping it by the progress. x_, y_ = 0, 0 width, height = self._stroke.get_width(), self._stroke.get_height() if self._direction == 'vertical': # vertical direction, bottom to top y_ = self._stroke.get_height() height *= self._progress * -1 else: rtl_direction = \ Gtk.Widget.get_default_direction() == Gtk.TextDirection.RTL if rtl_direction: # horizontal direction, right to left x_ = self._stroke.get_width() width *= self._progress * -1 else: # horizontal direction, left to right width *= self._progress cr.rectangle(x_, y_, width, height) cr.clip() cr.set_source_surface(self._fill, 0, 0) cr.paint() # Paint the stroke over the fill. cr.reset_clip() cr.set_source_surface(self._stroke, 0, 0) cr.paint() return False def do_clicked(self): if self._hide_tooltip_on_click and self.palette: self.palette.popdown(True) def update(self, progress): self._progress = progress self.queue_draw()
class RadioToolButton(Gtk.RadioToolButton): """An implementation of a "push" button.""" __gtype_name__ = "SugarRadioToolButton" def __init__(self, icon_name=None, **kwargs): self._accelerator = None self._tooltip = None self._xo_color = None self._hide_tooltip_on_click = True self._palette_invoker = ToolInvoker() GObject.GObject.__init__(self, **kwargs) self._palette_invoker.attach_tool(self) if icon_name: self.set_icon_name(icon_name) self.connect("destroy", self.__destroy_cb) def __destroy_cb(self, icon): if self._palette_invoker is not None: self._palette_invoker.detach() def set_tooltip(self, tooltip): if self.palette is None or self._tooltip is None: self.palette = Palette(tooltip) elif self.palette is not None: self.palette.set_primary_text(tooltip) self._tooltip = tooltip # Set label, shows up when toolbar overflows Gtk.RadioToolButton.set_label(self, tooltip) def get_tooltip(self): return self._tooltip tooltip = GObject.property(type=str, setter=set_tooltip, getter=get_tooltip) def set_accelerator(self, accelerator): self._accelerator = accelerator toolbutton.setup_accelerator(self) def get_accelerator(self): return self._accelerator accelerator = GObject.property(type=str, setter=set_accelerator, getter=get_accelerator) def set_icon_name(self, icon_name): icon = Icon(icon_name=icon_name, xo_color=self._xo_color) self.set_icon_widget(icon) icon.show() def get_icon_name(self): if self.props.icon_widget is not None: return self.props.icon_widget.props.icon_name else: return None icon_name = GObject.property(type=str, setter=set_icon_name, getter=get_icon_name) def set_xo_color(self, xo_color): if self._xo_color != xo_color: self._xo_color = xo_color if self.props.icon_widget is not None: self.props.icon_widget.props.xo_color = xo_color def get_xo_color(self): return self._xo_color xo_color = GObject.property(type=object, setter=set_xo_color, getter=get_xo_color) def create_palette(self): return None def get_palette(self): return self._palette_invoker.palette def set_palette(self, palette): self._palette_invoker.palette = palette palette = GObject.property(type=object, setter=set_palette, getter=get_palette) def get_palette_invoker(self): return self._palette_invoker def set_palette_invoker(self, palette_invoker): self._palette_invoker.detach() self._palette_invoker = palette_invoker palette_invoker = GObject.property(type=object, setter=set_palette_invoker, getter=get_palette_invoker) def do_draw(self, cr): if self.palette and self.palette.is_up(): allocation = self.get_allocation() # draw a black background, has been done by the engine before cr.set_source_rgb(0, 0, 0) cr.rectangle(0, 0, allocation.width, allocation.height) cr.paint() Gtk.RadioToolButton.do_draw(self, cr) if self.palette and self.palette.is_up(): invoker = self.palette.props.invoker invoker.draw_rectangle(cr, self.palette) return False def get_hide_tooltip_on_click(self): return self._hide_tooltip_on_click def set_hide_tooltip_on_click(self, hide_tooltip_on_click): if self._hide_tooltip_on_click != hide_tooltip_on_click: self._hide_tooltip_on_click = hide_tooltip_on_click hide_tooltip_on_click = GObject.property( type=bool, default=True, getter=get_hide_tooltip_on_click, setter=set_hide_tooltip_on_click ) def do_clicked(self): if self._hide_tooltip_on_click and self.palette: self.palette.popdown(True)
class RadioToolButton(Gtk.RadioToolButton): """An implementation of a "push" button.""" __gtype_name__ = 'SugarRadioToolButton' def __init__(self, icon_name=None, **kwargs): self._accelerator = None self._tooltip = None self._xo_color = None self._hide_tooltip_on_click = True self._palette_invoker = ToolInvoker() GObject.GObject.__init__(self, **kwargs) self._palette_invoker.attach_tool(self) if icon_name: self.set_icon_name(icon_name) self.connect('destroy', self.__destroy_cb) def __destroy_cb(self, icon): if self._palette_invoker is not None: self._palette_invoker.detach() def set_tooltip(self, tooltip): if self.palette is None or self._tooltip is None: self.palette = Palette(tooltip) elif self.palette is not None: self.palette.set_primary_text(tooltip) self._tooltip = tooltip # Set label, shows up when toolbar overflows Gtk.RadioToolButton.set_label(self, tooltip) def get_tooltip(self): return self._tooltip tooltip = GObject.property(type=str, setter=set_tooltip, getter=get_tooltip) def set_accelerator(self, accelerator): self._accelerator = accelerator toolbutton.setup_accelerator(self) def get_accelerator(self): return self._accelerator accelerator = GObject.property(type=str, setter=set_accelerator, getter=get_accelerator) def set_icon_name(self, icon_name): icon = Icon(icon_name=icon_name, xo_color=self._xo_color) self.set_icon_widget(icon) icon.show() def get_icon_name(self): if self.props.icon_widget is not None: return self.props.icon_widget.props.icon_name else: return None icon_name = GObject.property(type=str, setter=set_icon_name, getter=get_icon_name) def set_xo_color(self, xo_color): if self._xo_color != xo_color: self._xo_color = xo_color if self.props.icon_widget is not None: self.props.icon_widget.props.xo_color = xo_color def get_xo_color(self): return self._xo_color xo_color = GObject.property(type=object, setter=set_xo_color, getter=get_xo_color) def create_palette(self): return None def get_palette(self): return self._palette_invoker.palette def set_palette(self, palette): self._palette_invoker.palette = palette palette = GObject.property(type=object, setter=set_palette, getter=get_palette) def get_palette_invoker(self): return self._palette_invoker def set_palette_invoker(self, palette_invoker): self._palette_invoker.detach() self._palette_invoker = palette_invoker palette_invoker = GObject.property(type=object, setter=set_palette_invoker, getter=get_palette_invoker) def do_draw(self, cr): if self.palette and self.palette.is_up(): allocation = self.get_allocation() # draw a black background, has been done by the engine before cr.set_source_rgb(0, 0, 0) cr.rectangle(0, 0, allocation.width, allocation.height) cr.paint() Gtk.RadioToolButton.do_draw(self, cr) if self.palette and self.palette.is_up(): invoker = self.palette.props.invoker invoker.draw_rectangle(cr, self.palette) return False def get_hide_tooltip_on_click(self): return self._hide_tooltip_on_click def set_hide_tooltip_on_click(self, hide_tooltip_on_click): if self._hide_tooltip_on_click != hide_tooltip_on_click: self._hide_tooltip_on_click = hide_tooltip_on_click hide_tooltip_on_click = GObject.property(type=bool, default=True, getter=get_hide_tooltip_on_click, setter=set_hide_tooltip_on_click) def do_clicked(self): if self._hide_tooltip_on_click and self.palette: self.palette.popdown(True)