diff --git a/examples/radiopalette.py b/examples/radiopalette.py new file mode 100644 index 00000000..eb868313 --- /dev/null +++ b/examples/radiopalette.py @@ -0,0 +1,57 @@ +import gtk + +from sugar.graphics.radiopalette import RadioPalette, RadioMenuButton, \ + RadioToolsButton +from sugar.graphics.toolbutton import ToolButton +from sugar.graphics import style + +window = gtk.Window() + +box = gtk.VBox() +window.add(box) + +toolbar = gtk.Toolbar() +box.pack_start(toolbar, False) + +text_view = gtk.TextView() +box.pack_start(text_view) + +def echo(text): + text_view.props.buffer.props.text += "\n" + text + +palette = RadioPalette() +palette.append( + icon_name='document-open', + tooltip='menu.document-open', + toggled_cb=lambda: echo('menu.document-open')) +palette.append( + icon_name='document-save', + tooltip='menu.document-save', + toggled_cb=lambda: echo('menu.document-save')) +palette.append( + icon_name='document-send', + tooltip='menu.document-send', + toggled_cb=lambda: echo('menu.document-send')) + +button = RadioMenuButton(palette=palette) +toolbar.insert(button, -1) + +palette = RadioPalette() +palette.append( + icon_name='document-open', + tooltip='tools.document-open', + toggled_cb=lambda: echo('tools.document-open')) +palette.append( + icon_name='document-save', + tooltip='tools.document-save', + toggled_cb=lambda: echo('tools.document-save')) +palette.append( + icon_name='document-send', + tooltip='tools.document-send', + toggled_cb=lambda: echo('tools.document-send')) + +button = RadioToolsButton(palette=palette) +toolbar.insert(button, -1) + +window.show_all() +gtk.main() diff --git a/src/sugar/graphics/radiopalette.py b/src/sugar/graphics/radiopalette.py new file mode 100644 index 00000000..2adaa0e8 --- /dev/null +++ b/src/sugar/graphics/radiopalette.py @@ -0,0 +1,128 @@ +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the +# Free Software Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +import gtk +import gobject +import logging +from gobject import SIGNAL_RUN_FIRST, TYPE_NONE + +from sugar.graphics import style +from sugar.graphics.toolbutton import ToolButton +from sugar.graphics.palette import Palette +from sugar.graphics.radiotoolbutton import RadioToolButton + +class RadioPaletteButton(ToolButton): + def __init__(self, **kwargs): + ToolButton.__init__(self, **kwargs) + + self._button_cb = None + + if self.props.palette: + self.__palette_cb(None, None) + + self.connect('notify::palette', self.__palette_cb) + + def __palette_cb(self, widget, pspec): + if not isinstance(self.props.palette, RadioPalette): + return + self.props.palette.update_button() + + def _set_current_button(self, button): + self.set_icon(button.rp_icon_name) + self._button_cb = button.rp_toggled_cb + +class RadioMenuButton(RadioPaletteButton): + def __init__(self, **kwargs): + RadioPaletteButton.__init__(self, **kwargs) + + def do_clicked(self): + if not self.palette: + return + if self.palette.is_up() and \ + self.palette.palette_state == Palette.SECONDARY: + self.palette.popdown(immediate=True) + else: + self.palette.popup(immediate=True, state=Palette.SECONDARY) + + def do_expose_event(self, event): + ToolButton.do_expose_event(self, event) + if not self.palette: + return + + if self.palette.is_up(): + type = gtk.ARROW_DOWN + else: + type = gtk.ARROW_UP + + a = self.allocation + self.get_style().paint_arrow(event.window, + gtk.STATE_NORMAL, gtk.SHADOW_IN, event.area, self, + None, type, True, + a.x + a.width/2 - style.TOOLBAR_ARROW_SIZE/2, + a.y + a.height - style.TOOLBAR_ARROW_SIZE - \ + style._FOCUS_LINE_WIDTH, + style.TOOLBAR_ARROW_SIZE, style.TOOLBAR_ARROW_SIZE) + +class RadioToolsButton(RadioPaletteButton): + def __init__(self, **kwargs): + RadioPaletteButton.__init__(self, **kwargs) + + def do_clicked(self): + if not self._button_cb: + return + self._button_cb() + +class RadioPalette(Palette): + def __init__(self, **kwargs): + Palette.__init__(self, **kwargs) + + self.top = gtk.HBox() + self.top.show() + self.set_content(self.top) + + def append(self, icon_name, tooltip=None, toggled_cb=None): + children = self.top.get_children() + button = RadioToolButton(icon_name=icon_name, + group=children and children[0] or None) + button.show() + button.connect('toggled', self.__toggled_cb) + self.top.pack_start(button, fill=False) + + button.rp_icon_name = icon_name + button.rp_tooltip = tooltip + button.rp_toggled_cb = toggled_cb + + if not children: + self.__toggled_cb(button, True) + + def update_button(self): + for i in self.top.get_children(): + self.__toggled_cb(i, True) + + def __toggled_cb(self, button, quiet=False): + if not button.get_active(): + return + + self.set_primary_text(button.rp_tooltip) + if not quiet: + if button.rp_toggled_cb: + button.rp_toggled_cb() + self.popdown(immediate=True) + + if not self.invoker or \ + not isinstance(self.invoker.parent, RadioPaletteButton): + return + + self.invoker.parent._set_current_button(button) diff --git a/src/sugar/graphics/toolbutton.py b/src/sugar/graphics/toolbutton.py index 6205b8a4..047df067 100644 --- a/src/sugar/graphics/toolbutton.py +++ b/src/sugar/graphics/toolbutton.py @@ -68,7 +68,6 @@ class ToolButton(gtk.ToolButton): if icon_name: self.set_icon(icon_name) - self.connect('clicked', self.__button_clicked_cb) self.get_child().connect('can-activate-accel', self.__button_can_activate_accel_cb) @@ -151,8 +150,7 @@ class ToolButton(gtk.ToolButton): allocation.width, allocation.height) gtk.ToolButton.do_expose_event(self, event) - - def __button_clicked_cb(self, widget): + + def do_clicked(self): if self.palette: self.palette.popdown(True) -