From 3f695fa481dfb44f4f6ff1dc173a13fc95515692 Mon Sep 17 00:00:00 2001
From: Aleksey Lim <alsroot@member.fsf.org>
Date: Tue, 15 Sep 2009 20:51:11 +0000
Subject: Exposed secondary toolbar causes intermittent Activity lockup #1334
---
src/sugar/graphics/toolbarbox.py | 100 +++++++++++++++++++++++---------------
1 files changed, 61 insertions(+), 39 deletions(-)
diff --git a/src/sugar/graphics/toolbarbox.py b/src/sugar/graphics/toolbarbox.py
index 430ff67..1a12b2f 100644
a
|
b
|
|
17 | 17 | |
18 | 18 | import gtk |
19 | 19 | import gobject |
20 | | import logging |
21 | 20 | |
22 | 21 | from sugar.graphics import style |
23 | 22 | from sugar.graphics.palette import PaletteWindow, ToolInvoker |
… |
… |
class ToolbarButton(ToolButton): |
38 | 37 | lambda widget: self.set_expanded(not self.is_expanded())) |
39 | 38 | |
40 | 39 | def get_toolbar_box(self): |
41 | | if not hasattr(self.parent, 'owner'): |
42 | | return None |
43 | | return self.parent.owner |
| 40 | return _get_page_parent(self.parent) |
44 | 41 | |
45 | 42 | toolbar_box = property(get_toolbar_box) |
46 | 43 | |
… |
… |
class ToolbarButton(ToolButton): |
55 | 52 | return |
56 | 53 | self.page_widget = _embody_page(_Box, page) |
57 | 54 | self.page_widget.set_size_request(-1, style.GRID_CELL_SIZE) |
58 | | self.page_widget.toolbar_button = self |
59 | 55 | page.show() |
60 | 56 | if self.props.palette is None: |
61 | 57 | self.props.palette = _ToolbarPalette(invoker=ToolInvoker(self)) |
62 | | self.props.palette.toolbar_button = self |
63 | 58 | self._move_page_to_palette() |
64 | 59 | |
65 | 60 | page = gobject.property(type=object, getter=get_page, setter=set_page) |
66 | 61 | |
67 | 62 | def _move_page_to_palette(self): |
68 | | if self.page_widget is None: |
| 63 | if self.page_widget is None or \ |
| 64 | self.page_widget.parent == self.props.palette: |
69 | 65 | return |
70 | 66 | |
71 | | if self.toolbar_box is not None and \ |
72 | | self.page_widget in self.toolbar_box.get_children(): |
73 | | self.toolbar_box.remove(self.page_widget) |
| 67 | if self.page_widget.parent is not None: |
| 68 | self.page_widget.parent.remove(self.page_widget) |
74 | 69 | |
75 | 70 | if isinstance(self.props.palette, _ToolbarPalette): |
76 | 71 | self.props.palette.add(self.page_widget) |
77 | 72 | |
78 | 73 | def is_expanded(self): |
79 | | return self.toolbar_box is not None and self.page_widget is not None \ |
80 | | and self.toolbar_box.expanded_button == self |
| 74 | return self.page_widget is not None and \ |
| 75 | self.page_widget.parent is not None and \ |
| 76 | self.page_widget.parent != self.props.palette |
81 | 77 | |
82 | 78 | def popdown(self): |
83 | 79 | if self.props.palette is not None: |
… |
… |
class ToolbarButton(ToolButton): |
86 | 82 | def set_expanded(self, expanded): |
87 | 83 | self.popdown() |
88 | 84 | |
89 | | box = self.toolbar_box |
90 | | |
91 | | if box is None or self.page_widget is None or \ |
92 | | self.is_expanded() == expanded: |
| 85 | if self.page_widget is None or self.is_expanded() == expanded: |
93 | 86 | return |
94 | 87 | |
95 | 88 | if not expanded: |
96 | | box.remove(self.page_widget) |
97 | | box.expanded_button = None |
98 | 89 | self._move_page_to_palette() |
99 | 90 | return |
100 | 91 | |
| 92 | box = self.toolbar_box |
| 93 | |
101 | 94 | if box.expanded_button is not None: |
102 | | # need to redraw it to erase arrow |
103 | | expanded_toolitem = box.expanded_button.page_widget.toolbar_button |
104 | | if expanded_toolitem.window is not None: |
105 | | expanded_toolitem.window.invalidate_rect(None, True) |
| 95 | if box.expanded_button.window is not None: |
| 96 | # need to redraw it to erase arrow |
| 97 | box.expanded_button.window.invalidate_rect(None, True) |
106 | 98 | box.expanded_button.set_expanded(False) |
| 99 | box.expanded_button = self |
107 | 100 | |
108 | 101 | if self.page_widget.parent is not None: |
109 | 102 | self.props.palette.remove(self.page_widget) |
… |
… |
class ToolbarButton(ToolButton): |
111 | 104 | self.modify_bg(gtk.STATE_NORMAL, box.background) |
112 | 105 | _setup_page(self.page_widget, box.background, box.props.padding) |
113 | 106 | box.pack_start(self.page_widget) |
114 | | box.expanded_button = self |
115 | 107 | |
116 | 108 | def do_expose_event(self, event): |
117 | 109 | if not self.is_expanded() or self.props.palette is not None and \ |
… |
… |
class ToolbarBox(gtk.VBox): |
141 | 133 | |
142 | 134 | def __init__(self, padding=style.TOOLBOX_HORIZONTAL_PADDING): |
143 | 135 | gtk.VBox.__init__(self) |
144 | | self.expanded_button = None |
| 136 | self._expanded_button_index = -1 |
145 | 137 | self.background = None |
146 | 138 | |
147 | 139 | self._toolbar = gtk.Toolbar() |
148 | | self._toolbar.owner = self |
149 | 140 | self._toolbar.connect('remove', self.__remove_cb) |
150 | 141 | |
151 | 142 | top_widget = _embody_page(gtk.EventBox, self._toolbar) |
… |
… |
class ToolbarBox(gtk.VBox): |
155 | 146 | self.modify_bg(gtk.STATE_NORMAL, |
156 | 147 | style.COLOR_TOOLBAR_GREY.get_gdk_color()) |
157 | 148 | |
| 149 | def get_expanded_button(self): |
| 150 | if self._expanded_button_index == -1: |
| 151 | return None |
| 152 | return self._toolbar.get_nth_item(self._expanded_button_index) |
| 153 | |
| 154 | def set_expanded_button(self, button): |
| 155 | if not button in self._toolbar: |
| 156 | self._expanded_button_index = -1 |
| 157 | return |
| 158 | self._expanded_button_index = self._toolbar.get_item_index(button) |
| 159 | |
| 160 | expanded_button = property(get_expanded_button, set_expanded_button) |
| 161 | |
158 | 162 | def __remove_cb(self, sender, button): |
159 | 163 | if not isinstance(button, ToolbarButton): |
160 | 164 | return |
161 | 165 | button.popdown() |
162 | | if self.expanded_button == button: |
| 166 | if button == self.expanded_button: |
163 | 167 | self.remove(button.page_widget) |
164 | | self.expanded_button = None |
| 168 | self._expanded_button_index = -1 |
165 | 169 | |
166 | 170 | def get_toolbar(self): |
167 | 171 | return self._toolbar |
… |
… |
class _ToolbarPalette(PaletteWindow): |
188 | 192 | |
189 | 193 | def __init__(self, **kwargs): |
190 | 194 | PaletteWindow.__init__(self, **kwargs) |
191 | | self.toolbar_box = None |
192 | 195 | self.set_border_width(0) |
193 | 196 | self._has_focus = False |
194 | 197 | |
195 | 198 | group = palettegroup.get_group('default') |
196 | 199 | group.connect('popdown', self.__group_popdown_cb) |
197 | | self.set_group_id('toolbar_box') |
| 200 | self.set_group_id('toolbarbox') |
| 201 | |
| 202 | def get_expanded_button(self): |
| 203 | return self.invoker.parent |
| 204 | |
| 205 | expanded_button = property(get_expanded_button) |
198 | 206 | |
199 | 207 | def on_invoker_enter(self): |
200 | 208 | PaletteWindow.on_invoker_enter(self) |
… |
… |
class _ToolbarPalette(PaletteWindow): |
225 | 233 | gtk.gdk.screen_width()) |
226 | 234 | |
227 | 235 | def popup(self, immediate=False): |
228 | | button = self.toolbar_button |
| 236 | button = self.expanded_button |
229 | 237 | if button.is_expanded(): |
230 | 238 | return |
231 | 239 | box = button.toolbar_box |
… |
… |
class _Box(gtk.EventBox): |
246 | 254 | self.set_app_paintable(True) |
247 | 255 | |
248 | 256 | def do_expose_event(self, widget, event): |
249 | | alloc = self.toolbar_button.allocation |
| 257 | if self.parent.expanded_button is None: |
| 258 | return |
| 259 | alloc = self.parent.expanded_button.allocation |
250 | 260 | self.get_style().paint_box(event.window, |
251 | 261 | gtk.STATE_NORMAL, gtk.SHADOW_IN, event.area, self, |
252 | 262 | 'palette-invoker', -style.FOCUS_LINE_WIDTH, 0, |
… |
… |
def _setup_page(page_widget, color, hpad): |
273 | 283 | page_widget.modify_bg(gtk.STATE_PRELIGHT, color) |
274 | 284 | |
275 | 285 | |
276 | | def _embody_page(box_class, widget): |
277 | | widget.show() |
| 286 | def _embody_page(box_class, page): |
| 287 | page.show() |
| 288 | |
278 | 289 | alignment = gtk.Alignment(0.0, 0.0, 1.0, 1.0) |
279 | | alignment.add(widget) |
| 290 | alignment.add(page) |
280 | 291 | alignment.show() |
281 | | box = box_class() |
282 | | box.modify_bg(gtk.STATE_ACTIVE, style.COLOR_BUTTON_GREY.get_gdk_color()) |
283 | | box.add(alignment) |
284 | | box.show() |
285 | | return box |
| 292 | |
| 293 | page_widget = box_class() |
| 294 | page_widget.modify_bg(gtk.STATE_ACTIVE, |
| 295 | style.COLOR_BUTTON_GREY.get_gdk_color()) |
| 296 | page_widget.add(alignment) |
| 297 | page_widget.show() |
| 298 | |
| 299 | return page_widget |
| 300 | |
| 301 | |
| 302 | def _get_page_parent(page): |
| 303 | if page is None or page.parent is None or \ |
| 304 | page.parent.parent is None or \ |
| 305 | page.parent.parent.parent is None: |
| 306 | return None |
| 307 | return page.parent.parent.parent |
286 | 308 | |
287 | 309 | |
288 | 310 | def _paint_arrow(widget, event, arrow_type): |