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