Mercurial > fife-parpg
comparison clients/editor/scripts/gui/menubar.py @ 255:51cc05d862f2
Merged editor_rewrite branch to trunk.
This contains changes that may break compatibility against existing clients.
For a list of changes that may affect your client, see: http://wiki.fifengine.de/Changes_to_pychan_and_FIFE_in_editor_rewrite_branch
author | cheesesucker@33b003aa-7bff-0310-803a-e67f0ece8222 |
---|---|
date | Mon, 08 Jun 2009 16:00:02 +0000 |
parents | |
children | 6add14ebe9f5 |
comparison
equal
deleted
inserted
replaced
254:10b5f7f36dd4 | 255:51cc05d862f2 |
---|---|
1 from pychan import widgets | |
2 from pychan.tools import callbackWithArguments as cbwa | |
3 | |
4 import scripts.events | |
5 import scripts.gui.action | |
6 from action import Action, ActionGroup | |
7 from fife import Color | |
8 import fife_timer | |
9 | |
10 MENU_ICON_SIZE = 24 | |
11 | |
12 class MenuBar(widgets.HBox): | |
13 def __init__(self, *args, **kwargs): | |
14 super(MenuBar, self).__init__(*args, **kwargs) | |
15 | |
16 self.menulist = [] | |
17 self._buttonlist = [] | |
18 self.gui = None | |
19 self._buildGui() | |
20 | |
21 self._timer = fife_timer.Timer(500, self._autoHideMenu) | |
22 self._timer.start() | |
23 | |
24 def _buildGui(self): | |
25 if self.gui is not None: | |
26 self.removeChild(self.gui) | |
27 self._buttonlist = [] | |
28 | |
29 self.gui = widgets.HBox() | |
30 for i, menu in enumerate(self.menulist): | |
31 button = widgets.Button(name=menu.name, text=menu.name) | |
32 button.hexpand = 0 | |
33 button.capture(cbwa(self._showMenu, i)) | |
34 self._buttonlist.append(button) | |
35 self.gui.addChild(button) | |
36 | |
37 self.gui.addSpacer(widgets.Spacer()) | |
38 | |
39 self.addChild(self.gui) | |
40 | |
41 def _showMenu(self, i): | |
42 if self.menulist[i].isVisible(): | |
43 self.menulist[i].hide() | |
44 return | |
45 | |
46 # Hide all menus | |
47 for m in self.menulist: | |
48 m.hide() | |
49 | |
50 menu = self.menulist[i] | |
51 button = self._buttonlist[i] | |
52 | |
53 menu.x = 0 | |
54 menu.y = button.height | |
55 | |
56 # Get absolute position of button | |
57 parent = button | |
58 while parent is not None: | |
59 menu.x += parent.x | |
60 menu.y += parent.y | |
61 parent = parent.parent | |
62 | |
63 menu.show() | |
64 | |
65 def _autoHideMenu(self): | |
66 for i, m in enumerate(self.menulist): | |
67 if not m.isVisible(): continue | |
68 if self._buttonlist[i].real_widget.isFocused(): continue | |
69 if self._isMenuFocused(m) is False: | |
70 m.hide() | |
71 | |
72 def _isMenuFocused(self, widget): | |
73 if widget.real_widget.isFocused(): return True | |
74 if hasattr(widget, "children"): | |
75 for c in widget.children: | |
76 if self._isMenuFocused(c): | |
77 return True | |
78 return False | |
79 | |
80 def addMenu(self, menu): | |
81 if menu is not None and self.menulist.count(menu) <= 0: | |
82 self.menulist.append(menu) | |
83 self._buildGui() | |
84 | |
85 def insertMenu(self, menu, beforeMenu): | |
86 try: | |
87 i = self.menulist.index(beforeMenu) | |
88 self.menulist.insert(i, menu) | |
89 self._buildGui() | |
90 | |
91 except ValueError: | |
92 print "MenuBar::insertMenu:", "MenuBar does not contain specified menu." | |
93 return | |
94 | |
95 def insertMenuAt(self, menu, index): | |
96 self.menulist.insert(index, menu) | |
97 self._buildGui() | |
98 | |
99 def removeMenu(self, menu): | |
100 self.menulist.remove(menu) | |
101 self._buildGui() | |
102 | |
103 def clear(self): | |
104 self.menulist = [] | |
105 self._buildGui() | |
106 | |
107 class Menu(widgets.VBox): | |
108 def __init__(self, name=u"", icon=u"", min_width=100, min_height=15, margins=(2,2), *args, **kwargs): | |
109 super(Menu, self).__init__(*args, **kwargs) | |
110 self.min_width=min_width | |
111 self.min_height=min_height | |
112 self.margins=margins | |
113 | |
114 self.name = name | |
115 self.icon = icon | |
116 | |
117 self._actions = [] | |
118 self._actionbuttons = [] | |
119 | |
120 self._update() | |
121 | |
122 def addSeparator(self, separator=None): | |
123 self.insertSeparator(separator, len(self._actions)) | |
124 | |
125 def addAction(self, action): | |
126 self.insertAction(action, len(self._actions)) | |
127 | |
128 def removeAction(self, action): | |
129 self._actions.remove(action) | |
130 | |
131 actions = [action] | |
132 if isinstance(action, ActionGroup): | |
133 actions = action.getActions() | |
134 scripts.gui.action.changed.disconnect(self._updateActionGroup, sender=action) | |
135 | |
136 for a in actions: | |
137 for b in self._actionbuttons[:]: | |
138 if a == b.action: | |
139 self.removeChild(b) | |
140 self._actionbuttons.remove(b) | |
141 | |
142 self.adaptLayout() | |
143 | |
144 def hasAction(self, action): | |
145 for a in self._actions: | |
146 if a == action: return True | |
147 return False | |
148 | |
149 def insertAction(self, action, position=0, before=None): | |
150 if self.hasAction(action): | |
151 print "Action already added to toolbar" | |
152 return | |
153 | |
154 if before is not None: | |
155 position = self._actions.index(before) | |
156 | |
157 self._actions.insert(position, action) | |
158 self._insertButton(action, position) | |
159 | |
160 def _updateActionGroup(self, sender): | |
161 position = self._actions.index(sender) | |
162 self.removeAction(sender) | |
163 self.insertAction(sender, position) | |
164 self.adaptLayout() | |
165 | |
166 def _insertButton(self, action, position): | |
167 actions = [action] | |
168 if isinstance(action, ActionGroup): | |
169 actions = action.getActions() | |
170 scripts.gui.action.changed.connect(self._updateActionGroup, sender=action) | |
171 | |
172 if position >= 0: | |
173 actions = reversed(actions) | |
174 | |
175 # Action groups are counted as one action, add the hidde number of actions to position | |
176 for i in range(position): | |
177 if isinstance(self._actions[i], ActionGroup): | |
178 position += len(self._actions[i].getActions()) - 1 | |
179 | |
180 for a in actions: | |
181 button = MenuButton(a, name=a.text) | |
182 self.insertChild(button, position) | |
183 self._actionbuttons.insert(position, button) | |
184 | |
185 def insertSeparator(self, separator=None, position=0, before=None): | |
186 if separator==None: | |
187 separator = Action(separator=True) | |
188 self.insertAction(separator, position, before) | |
189 | |
190 def clear(self): | |
191 self.removeAllChildren() | |
192 self._actions = [] | |
193 | |
194 for i in reversed(range(len(self._actionbuttons))): | |
195 self._actionbuttons[i].removeEvents() | |
196 self._actionbuttons = [] | |
197 | |
198 def _update(self): | |
199 actions = self._actions | |
200 | |
201 self.clear() | |
202 | |
203 for action in actions: | |
204 self.addAction(action) | |
205 | |
206 self.adaptLayout() | |
207 | |
208 def show(self): | |
209 self._update() | |
210 super(Menu, self).show() | |
211 | |
212 class MenuButton(widgets.HBox): | |
213 def __init__(self, action, **kwargs): | |
214 self._action = action | |
215 self._widget = None | |
216 | |
217 super(MenuButton, self).__init__(**kwargs) | |
218 | |
219 self.update() | |
220 | |
221 self.initEvents() | |
222 | |
223 def initEvents(self): | |
224 # Register eventlisteners | |
225 self.capture(self._showTooltip, "mouseEntered") | |
226 self.capture(self._hideTooltip, "mouseExited") | |
227 | |
228 scripts.gui.action.changed.connect(self._actionChanged, sender=self._action) | |
229 | |
230 def removeEvents(self): | |
231 # Remove eventlisteners | |
232 self.capture(None, "mouseEntered") | |
233 self.capture(None, "mouseExited") | |
234 | |
235 scripts.gui.action.changed.disconnect(self.update, sender=self._action) | |
236 | |
237 def setAction(self, action): | |
238 self.removeEvents() | |
239 | |
240 self._action = action | |
241 self.update() | |
242 self.adaptLayout() | |
243 | |
244 self.initEvents() | |
245 | |
246 def getAction(self): | |
247 return self._action | |
248 action = property(getAction, setAction) | |
249 | |
250 def _showTooltip(self): | |
251 if self._action is not None and self._action.helptext != "": | |
252 scripts.editor.getEditor().getStatusBar().showTooltip(self._action.helptext) | |
253 | |
254 def _hideTooltip(self): | |
255 scripts.editor.getEditor().getStatusBar().hideTooltip() | |
256 | |
257 def _actionChanged(self): | |
258 self.update() | |
259 self.adaptLayout() | |
260 | |
261 def update(self): | |
262 """ Sets up the button widget """ | |
263 if self._widget != None: | |
264 self.removeChild(self._widget) | |
265 self._widget = None | |
266 | |
267 if self._action is None: | |
268 return | |
269 | |
270 widget = None | |
271 icon = None | |
272 text = None | |
273 | |
274 if self._action.isSeparator(): | |
275 widget = widgets.HBox() | |
276 widget.base_color += Color(8, 8, 8) | |
277 widget.min_size = (2, 2) | |
278 else: | |
279 hasIcon = len(self._action.icon) > 0 | |
280 | |
281 if self._action.isCheckable(): | |
282 text = widgets.ToggleButton(text=self._action.text) | |
283 text.toggled = self._action.isChecked() | |
284 text.hexpand = 1 | |
285 else: | |
286 text = widgets.Button(text=self._action.text) | |
287 text.min_size = (1, MENU_ICON_SIZE) | |
288 text.max_size = (1000, MENU_ICON_SIZE) | |
289 text.capture(self._action.activate) | |
290 | |
291 if hasIcon: | |
292 if self._action.isCheckable(): | |
293 icon = widgets.ToggleButton(hexpand=0, up_image=self._action.icon,down_image=self._action.icon,hover_image=self._action.icon,offset=(1,1)) | |
294 icon.toggled = self._action.isChecked() | |
295 else: | |
296 icon = widgets.ImageButton(hexpand=0, up_image=self._action.icon,down_image=self._action.icon,hover_image=self._action.icon,offset=(1,1)) | |
297 | |
298 else: | |
299 if self._action.isCheckable(): | |
300 icon = widgets.ToggleButton(hexpand=0, offset=(1,1)) | |
301 icon.toggled = self._action.isChecked() | |
302 else: | |
303 icon = widgets.Button(text=u"", hexpand=0, offset=(1,1)) | |
304 | |
305 icon.min_size = icon.max_size = (MENU_ICON_SIZE, MENU_ICON_SIZE) | |
306 icon.capture(self._action.activate) | |
307 | |
308 widget = widgets.HBox() | |
309 widget.addChild(icon) | |
310 widget.addChild(text) | |
311 | |
312 widget.position_technique = "left:center" | |
313 widget.hexpand = 1 | |
314 widget.vexpand = 0 | |
315 | |
316 self._widget = widget | |
317 self.addChild(self._widget) | |
318 |