Hi,

this patch adds an option to what used to be the Ring view palette for
choosing the layout to use in the favorites view.

Thanks,

Tomeu
From 97a1ef00389bbc2a9724070889164b78527a6f55 Mon Sep 17 00:00:00 2001
From: Tomeu Vizoso <[EMAIL PROTECTED](none)>
Date: Thu, 19 Jun 2008 20:52:09 +0200
Subject: [PATCH] Add an option for choosing the layout in the favorites view.

---
 src/view/home/HomeBox.py         |   81 ++++++++++++++++++++++++++++------
 src/view/home/MeshBox.py         |    5 +-
 src/view/home/favoriteslayout.py |   25 +++++++----
 src/view/home/favoritesview.py   |   90 ++++++++++++++++++++++++--------------
 4 files changed, 143 insertions(+), 58 deletions(-)

diff --git a/src/view/home/HomeBox.py b/src/view/home/HomeBox.py
index 14c0911..61ceee9 100644
--- a/src/view/home/HomeBox.py
+++ b/src/view/home/HomeBox.py
@@ -21,9 +21,11 @@ import gtk
 
 from sugar.graphics import style
 from sugar.graphics import iconentry
+from sugar.graphics.palette import Palette
+from sugar.graphics.menuitem import MenuItem
 from sugar.graphics.radiotoolbutton import RadioToolButton
 
-from view.home.favoritesview import FavoritesView
+from view.home import favoritesview
 from view.home.activitieslist import ActivitiesList
 
 _FAVORITES_VIEW = 0
@@ -37,7 +39,7 @@ class HomeBox(gtk.VBox):
     def __init__(self):
         gobject.GObject.__init__(self)
 
-        self._favorites_view = FavoritesView()
+        self._favorites_view = favoritesview.FavoritesView()
         self._list_view = ActivitiesList()
         self._enable_xo_palette = False
 
@@ -47,7 +49,7 @@ class HomeBox(gtk.VBox):
         self.pack_start(self._toolbar, expand=False)
         self._toolbar.show()
 
-        self._set_view(_FAVORITES_VIEW)
+        self._set_view(_FAVORITES_VIEW, favoritesview.RANDOM_LAYOUT)
 
     def __toolbar_query_changed_cb(self, toolbar, query):
         if self._list_view is None:
@@ -55,19 +57,22 @@ class HomeBox(gtk.VBox):
         query = query.lower()
         self._list_view.set_filter(query)
 
-    def __toolbar_view_changed_cb(self, toolbar, view):
-        self._set_view(view)
+    def __toolbar_view_changed_cb(self, toolbar, view, layout):
+        self._set_view(view, layout)
 
-    def _set_view(self, view):
+    def _set_view(self, view, layout):
         if view == _FAVORITES_VIEW:
             if self._list_view in self.get_children():
                 self.remove(self._list_view)
 
+            self._favorites_view.layout = layout
+
             if self._enable_xo_palette:
                 self._favorites_view.enable_xo_palette()
 
-            self.add(self._favorites_view)
-            self._favorites_view.show()
+            if self._favorites_view not in self.get_children():
+                self.add(self._favorites_view)
+                self._favorites_view.show()
         elif view == _LIST_VIEW:
             if self._favorites_view in self.get_children():
                 self.remove(self._favorites_view)
@@ -104,7 +109,7 @@ class HomeToolbar(gtk.Toolbar):
                           ([str])),
         'view-changed':  (gobject.SIGNAL_RUN_FIRST,
                           gobject.TYPE_NONE,
-                          ([int]))
+                          ([object, object]))
     }
 
     def __init__(self):
@@ -131,9 +136,7 @@ class HomeToolbar(gtk.Toolbar):
 
         self._add_separator(expand=True)
 
-        favorites_button = RadioToolButton(named_icon='view-radial', group=None)
-        favorites_button.props.tooltip = _('Favorites view')
-        favorites_button.props.accelerator = _('<Ctrl>R')
+        favorites_button = FavoritesButton()
         favorites_button.connect('toggled', self.__view_button_toggled_cb,
                                  _FAVORITES_VIEW)
         self.insert(favorites_button, -1)
@@ -152,8 +155,11 @@ class HomeToolbar(gtk.Toolbar):
 
     def __view_button_toggled_cb(self, button, view):
         if button.props.active:
-            self.emit('view-changed', view)
-
+            if view == _FAVORITES_VIEW:
+                self.emit('view-changed', view, button.layout)
+            else:
+                self.emit('view-changed', view, None)
+            
     def _add_separator(self, expand=False):
         separator = gtk.SeparatorToolItem()
         separator.props.draw = False
@@ -188,3 +194,50 @@ class HomeToolbar(gtk.Toolbar):
         self._search_entry.activate()
         return False
 
+class FavoritesButton(RadioToolButton):
+    __gtype_name__ = 'SugarFavoritesButton'
+    
+    def __init__(self):
+        RadioToolButton.__init__(self)
+
+        self.props.named_icon = 'view-radial'
+        self.props.tooltip = _('Favorites view')
+        self.props.accelerator = _('<Ctrl>R')
+        self.props.group = None
+
+        self._layout = favoritesview.RANDOM_LAYOUT
+
+        # TRANS: label for the free layout in the favorites view
+        menu_item = MenuItem(_('Free'), 'activity-start')
+        menu_item.connect('activate', self.__layout_activate_cb,
+                          favoritesview.RANDOM_LAYOUT)
+        self.props.palette.menu.append(menu_item)
+        menu_item.show()
+
+        # TRANS: label for the ring layout in the favorites view
+        menu_item = MenuItem(_('Ring'), 'view-radial')
+        menu_item.connect('activate', self.__layout_activate_cb,
+                          favoritesview.RING_LAYOUT)
+        self.props.palette.menu.append(menu_item)
+        menu_item.show()
+
+    def __layout_activate_cb(self, menu_item, layout):
+        if self._layout == layout and self.props.active:
+            return
+        elif self._layout != layout:
+            if layout == favoritesview.RANDOM_LAYOUT:
+                self.props.named_icon = 'activity-start'
+            elif layout == favoritesview.RING_LAYOUT:
+                self.props.named_icon = 'view-radial'
+            else:
+                raise ValueError('Invalid layout: %r' % layout)
+            self._layout = layout
+        if not self.props.active:
+            self.props.active = True
+        else:
+            self.emit('toggled')
+
+    def _get_layout(self):
+        return self._layout
+    layout = property(_get_layout, None)
+
diff --git a/src/view/home/MeshBox.py b/src/view/home/MeshBox.py
index 1dff8cb..5e05623 100644
--- a/src/view/home/MeshBox.py
+++ b/src/view/home/MeshBox.py
@@ -446,8 +446,9 @@ class MeshBox(gtk.VBox):
             
         self._toolbar = MeshToolbar()
         self._toolbar.connect('query-changed', self._toolbar_query_changed_cb)
-        self.add(self._toolbar)
-        
+        self.pack_start(self._toolbar, expand=False)
+        self._toolbar.show()
+
         canvas = hippo.Canvas()
         self.add(canvas)
         canvas.show()
diff --git a/src/view/home/favoriteslayout.py b/src/view/home/favoriteslayout.py
index 54cccb1..0400350 100644
--- a/src/view/home/favoriteslayout.py
+++ b/src/view/home/favoriteslayout.py
@@ -52,7 +52,7 @@ class FavoritesLayout(gobject.GObject, hippo.CanvasLayout):
     def compare_activities(self, icon_a, icon_b):
         return 0
 
-    def append(self, icon):
+    def append(self, icon, locked=False):
         self.box.insert_sorted(icon, 0, self.compare_activities)
         if hasattr(icon, 'fixed_position'):
             relative_x, relative_y = icon.fixed_position
@@ -62,12 +62,10 @@ class FavoritesLayout(gobject.GObject, hippo.CanvasLayout):
                 self.fixed_positions[icon] = \
                         (int(relative_x * _BASE_SCALE / float(width)),
                          int(relative_y * _BASE_SCALE / float(height)))
-            self.update_icon_sizes()
 
     def remove(self, icon):
         del self.fixed_positions[icon]
         self.box.remove(icon)
-        self.update_icon_sizes()
 
     def move_icon(self, icon, x, y, locked=False):
         if icon not in self.box.get_children():
@@ -83,9 +81,6 @@ class FavoritesLayout(gobject.GObject, hippo.CanvasLayout):
                     y * height / float(_BASE_SCALE))
             self.fixed_positions[icon] = (x, y)
 
-    def update_icon_sizes(self):
-        pass
-
     def do_allocate(self, x, y, width, height, req_width, req_height,
                     origin_changed):
         raise NotImplementedError()
@@ -108,8 +103,8 @@ class RandomLayout(FavoritesLayout):
     def __grid_child_changed_cb(self, grid, child):
         child.emit_request_changed()
 
-    def append(self, icon):
-        FavoritesLayout.append(self, icon)
+    def append(self, icon, locked=False):
+        FavoritesLayout.append(self, icon, locked)
 
         min_width_, child_width = icon.get_width_request()
         min_height_, child_height = icon.get_height_request(child_width)
@@ -173,6 +168,18 @@ class RingLayout(FavoritesLayout):
         FavoritesLayout.__init__(self)
         self._locked_children = {}
 
+    def append(self, icon, locked=False):
+        FavoritesLayout.append(self, icon, locked)
+        if locked:
+            child = self.box.find_box_child(icon)
+            self._locked_children[child] = (0, 0)
+
+    def remove(self, icon):
+        child = self.box.find_box_child(icon)
+        if child in self._locked_children:
+            del self._locked_children[child]
+        FavoritesLayout.remove(self, icon)
+
     def move_icon(self, icon, x, y, locked=False):
         FavoritesLayout.move_icon(self, icon, x, y, locked)
         if locked:
@@ -219,7 +226,7 @@ class RingLayout(FavoritesLayout):
                 if child not in self._locked_children]
         return children_in_ring
 
-    def update_icon_sizes(self):
+    def _update_icon_sizes(self):
         children_in_ring = self._get_children_in_ring()
         radius_, icon_size = \
                 self._calculate_radius_and_icon_size(len(children_in_ring))
diff --git a/src/view/home/favoritesview.py b/src/view/home/favoritesview.py
index 81364c2..a6e2268 100644
--- a/src/view/home/favoritesview.py
+++ b/src/view/home/favoritesview.py
@@ -34,7 +34,7 @@ import view.Shell
 from view.palettes import JournalPalette
 from view.palettes import CurrentActivityPalette, ActivityPalette
 from view.home.MyIcon import MyIcon
-from view.home.favoriteslayout import RandomLayout
+from view.home import favoriteslayout
 from model import shellmodel
 from model.shellmodel import ShellModel
 from hardware import schoolserver
@@ -45,52 +45,50 @@ _logger = logging.getLogger('FavoritesView')
 
 _ICON_DND_TARGET = ('activity-icon', gtk.TARGET_SAME_WIDGET, 0)
 
+RING_LAYOUT = 0
+RANDOM_LAYOUT = 1
+
+_LAYOUT_MAP = {RING_LAYOUT: favoriteslayout.RingLayout,
+               RANDOM_LAYOUT: favoriteslayout.RandomLayout}
+
 class FavoritesView(hippo.Canvas):
     __gtype_name__ = 'SugarFavoritesView'
 
     def __init__(self, **kwargs):
         gobject.GObject.__init__(self, **kwargs)
 
+        # DND stuff
+        self._pressed_button = None
+        self._press_start_x = None
+        self._press_start_y = None
+        self._last_clicked_icon = None
+
         self._box = hippo.CanvasBox()
         self._box.props.background_color = style.COLOR_WHITE.get_int()
         self.set_root(self._box)
 
-        shell_model = shellmodel.get_instance()
-        shell_model.connect('notify::state', self._shell_state_changed_cb)
-
-        self._layout = RandomLayout()
-        self._box.set_layout(self._layout)
-
-        self._my_icon = _MyIcon(style.XLARGE_ICON_SIZE)
-        self._layout.append(self._my_icon)
-
-        self._current_activity = CurrentActivityIcon()
-        self._layout.append(self._current_activity)
+        self._my_icon = None
+        self._current_activity = None
+        self._layout = None
+        self._set_layout(RANDOM_LAYOUT)
 
         registry = activity.get_registry()
-        registry.get_activities_async(reply_handler=self._get_activities_cb)
         registry.connect('activity-added', self.__activity_added_cb)
         registry.connect('activity-removed', self.__activity_removed_cb)
         registry.connect('activity-changed', self.__activity_changed_cb)
 
-        # DND stuff
-        self._pressed_button = None
-        self._press_start_x = None
-        self._press_start_y = None
-        self._last_clicked_icon = None
-
-        if self._layout.allow_dnd():
-            self.drag_source_set(0, [], 0)
-            self.add_events(gtk.gdk.BUTTON_PRESS_MASK |
-                            gtk.gdk.POINTER_MOTION_HINT_MASK)
-            self.connect('motion-notify-event', self.__motion_notify_event_cb)
-            self.connect('button-press-event', self.__button_press_event_cb)
-            self.connect('drag-begin', self.__drag_begin_cb)
+        shell_model = shellmodel.get_instance()
+        shell_model.connect('notify::state', self._shell_state_changed_cb)
 
-            self.drag_dest_set(0, [], 0)
-            self.connect('drag-motion', self.__drag_motion_cb)
-            self.connect('drag-drop', self.__drag_drop_cb)
-            self.connect('drag-data-received', self.__drag_data_received_cb)
+        # More DND stuff
+        self.add_events(gtk.gdk.BUTTON_PRESS_MASK |
+                        gtk.gdk.POINTER_MOTION_HINT_MASK)
+        self.connect('motion-notify-event', self.__motion_notify_event_cb)
+        self.connect('button-press-event', self.__button_press_event_cb)
+        self.connect('drag-begin', self.__drag_begin_cb)
+        self.connect('drag-motion', self.__drag_motion_cb)
+        self.connect('drag-drop', self.__drag_drop_cb)
+        self.connect('drag-data-received', self.__drag_data_received_cb)
 
     def _add_activity(self, activity_info):
         icon = ActivityIcon(activity_info)
@@ -121,7 +119,7 @@ class FavoritesView(hippo.Canvas):
             self._layout.remove(icon)
 
     def __activity_changed_cb(self, activity_registry, activity_info):
-        if activity_info.bundle_id == "org.laptop.JournalActivity":
+        if activity_info.bundle_id == 'org.laptop.JournalActivity':
             return
         icon = self._find_activity_icon(activity_info.bundle_id,
                 activity_info.version)
@@ -239,6 +237,33 @@ class FavoritesView(hippo.Canvas):
                                 info, time):
         context.drop_finish(success=True, time=time)
 
+    def _set_layout(self, layout):
+        if layout not in _LAYOUT_MAP:
+            raise ValueError('Unknown favorites layout: %r' % layout)
+        if type(self._layout) != _LAYOUT_MAP[layout]:
+            self._box.clear()
+            self._layout = _LAYOUT_MAP[layout]()
+            self._box.set_layout(self._layout)
+
+            self._my_icon = _MyIcon(style.XLARGE_ICON_SIZE)
+            self._my_icon.log = True
+            self._layout.append(self._my_icon, locked=True)
+
+            self._current_activity = CurrentActivityIcon()
+            self._layout.append(self._current_activity, locked=True)
+
+            registry = activity.get_registry()
+            registry.get_activities_async(reply_handler=self._get_activities_cb)
+
+            if self._layout.allow_dnd():
+                self.drag_source_set(0, [], 0)
+                self.drag_dest_set(0, [], 0)
+            else:
+                self.drag_source_unset()
+                self.drag_dest_unset()
+
+    layout = property(None, _set_layout)
+
 class ActivityIcon(CanvasIcon):
     def __init__(self, activity_info):
         CanvasIcon.__init__(self, cache=True, file_name=activity_info.icon)
@@ -295,12 +320,11 @@ class CurrentActivityIcon(CanvasIcon, hippo.CanvasItem):
         self._home_model.get_active_activity().get_window().activate(1)
 
     def _update(self, home_activity):
-        _logger.debug('CurrentActivityIcon._update')
         self.props.file_name = home_activity.get_icon_path()
         self.props.xo_color = home_activity.get_icon_color()
         self.props.size = style.STANDARD_ICON_SIZE
 
-        if home_activity.get_type() == "org.laptop.JournalActivity":
+        if home_activity.get_type() == 'org.laptop.JournalActivity':
             palette = JournalPalette(home_activity)
         else:
             palette = CurrentActivityPalette(home_activity)
-- 
1.5.4.3

From 79f1188c846e0dea720d665a0208dce65668fe13 Mon Sep 17 00:00:00 2001
From: Tomeu Vizoso <[EMAIL PROTECTED](none)>
Date: Thu, 19 Jun 2008 20:53:12 +0200
Subject: [PATCH] Make xo_color, named_icon and group properties instead of constructor args

---
 src/sugar/graphics/radiotoolbutton.py |   32 ++++++++++++++++++++++++--------
 1 files changed, 24 insertions(+), 8 deletions(-)

diff --git a/src/sugar/graphics/radiotoolbutton.py b/src/sugar/graphics/radiotoolbutton.py
index 1563e2a..001ed06 100644
--- a/src/sugar/graphics/radiotoolbutton.py
+++ b/src/sugar/graphics/radiotoolbutton.py
@@ -24,23 +24,18 @@ from sugar.graphics.palette import Palette, ToolInvoker
 from sugar.graphics import toolbutton
 
 class RadioToolButton(gtk.RadioToolButton):
-    __gtype_name__ = "SugarRadioToolButton"
+    __gtype_name__ = 'SugarRadioToolButton'
 
-    def __init__(self, named_icon=None, group=None, xo_color=None, **kwargs):
+    def __init__(self, **kwargs):
         self._accelerator = None
         self._tooltip = None
-        self._xo_color = xo_color
+        self._xo_color = None
         self._palette_invoker = ToolInvoker()
 
         gobject.GObject.__init__(self, **kwargs)
 
         self._palette_invoker.attach_tool(self)
 
-        if named_icon:
-            self.set_named_icon(named_icon)
-        if group:
-            self.props.group = group
-
     def set_tooltip(self, tooltip):
         """ Set a simple palette with just a single label.
         """
@@ -76,6 +71,27 @@ class RadioToolButton(gtk.RadioToolButton):
         self.set_icon_widget(icon)
         icon.show()
 
+    def get_named_icon(self):
+        if self.props.icon_widget is not None:
+            return self.props.icon_widget.props.icon_name
+        else:
+            return None
+
+    named_icon = gobject.property(type=str, setter=set_named_icon,
+                                  getter=get_named_icon)
+
+    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=str, setter=set_xo_color,
+                                getter=get_xo_color)
+
     def create_palette(self):
         return None
 
-- 
1.5.4.3

_______________________________________________
Sugar mailing list
[email protected]
http://lists.laptop.org/listinfo/sugar

Reply via email to