comparison tools/editor/scripts/gui/toolbar.py @ 378:64738befdf3b

bringing in the changes from the build_system_rework branch in preparation for the 0.3.0 release. This commit will require the Jan2010 devkit. Clients will also need to be modified to the new way to import fife.
author vtchill@33b003aa-7bff-0310-803a-e67f0ece8222
date Mon, 11 Jan 2010 23:34:52 +0000
parents
children
comparison
equal deleted inserted replaced
377:fe6fb0e0ed23 378:64738befdf3b
1 # -*- coding: utf-8 -*-
2
3 # ####################################################################
4 # Copyright (C) 2005-2009 by the FIFE team
5 # http://www.fifengine.de
6 # This file is part of FIFE.
7 #
8 # FIFE is free software; you can redistribute it and/or
9 # modify it under the terms of the GNU Lesser General Public
10 # License as published by the Free Software Foundation; either
11 # version 2.1 of the License, or (at your option) any later version.
12 #
13 # This library is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 # Lesser General Public License for more details.
17 #
18 # You should have received a copy of the GNU Lesser General Public
19 # License along with this library; if not, write to the
20 # Free Software Foundation, Inc.,
21 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 # ####################################################################
23
24 from fife.extensions import pychan
25 from fife.extensions.pychan import widgets
26
27 import scripts.events
28 import action
29 import scripts.editor
30 from action import Action, ActionGroup
31 from fife.fife import Color
32 from panel import Panel
33 from resizablebase import ResizableBase
34
35 class ToolBar(Panel):
36 ORIENTATION = {
37 "Horizontal" : 0,
38 "Vertical" : 1
39 }
40
41 BUTTON_STYLE = {
42 "IconOnly" : 0,
43 "TextOnly" : 1,
44 "TextUnderIcon" : 2,
45 "TextBesideIcon" : 3
46 }
47
48 def __init__(self, button_style=0, panel_size=27, orientation=0, *args, **kwargs):
49 super(ToolBar, self).__init__(resizable=False, *args, **kwargs)
50
51 self._actions = []
52 self._actionbuttons = []
53 self._button_style = 0
54 self._panel_size = panel_size
55 self.gui = None
56
57 self._orientation = orientation
58 self._button_style = button_style
59
60 self._updateToolbar()
61
62 self.capture(self.mouseReleased, "mouseReleased", "toolbar")
63 self.capture(self.mouseClicked, "mouseClicked", "toolbar")
64
65 def addSeparator(self, separator=None):
66 self.insertSeparator(separator, len(self._actions))
67
68 def addAction(self, action):
69 self.insertAction(action, len(self._actions))
70
71 def removeAction(self, action):
72 self._actions.remove(action)
73
74 actions = [action]
75 if isinstance(action, ActionGroup):
76 actions = action.getActions()
77 scripts.gui.action.changed.disconnect(self._updateActionGroup, sender=action)
78
79 for a in actions:
80 for b in self._actionbuttons[:]:
81 if a == b.action:
82 self.gui.removeChild(b)
83 self._actionbuttons.remove(b)
84
85 self.adaptLayout(False)
86
87 def hasAction(self, action):
88 for a in self._actions:
89 if a == action: return True
90 return False
91
92 def insertAction(self, action, position=0, before=None):
93 if self.hasAction(action):
94 print "Action already added to toolbar"
95 return
96
97 if before is not None:
98 position = self._actions.index(before)
99
100 self._actions.insert(position, action)
101 self._insertButton(action, position)
102
103 def _updateActionGroup(self, sender):
104 if isinstance(sender, ActionGroup):
105 # Toolbar didn't properly handle events where
106 # an action in actiongroup was removed
107 self._updateToolbar()
108 else:
109 position = self._actions.index(sender)
110 self.removeAction(sender)
111 self.insertAction(sender, position)
112 self.adaptLayout()
113
114
115 def _insertButton(self, action, position):
116 actions = [action]
117 if isinstance(action, ActionGroup):
118 actions = action.getActions()
119 scripts.gui.action.changed.connect(self._updateActionGroup, sender=action)
120
121 if position >= 0:
122 actions = reversed(actions)
123
124 # Action groups are counted as one action, add the hidde number of actions to position
125 for i in range(position):
126 if isinstance(self._actions[i], ActionGroup):
127 position += len(self._actions[i].getActions()) - 1
128
129 for a in actions:
130 button = ToolbarButton(a, button_style=self._button_style, name=a.text)
131 self.gui.insertChild(button, position)
132 self._actionbuttons.insert(position, button)
133
134 def insertSeparator(self, separator=None, position=0, before=None):
135 if separator==None:
136 separator = Action(separator=True)
137 self.insertAction(separator, position, before)
138
139 def clear(self):
140 self.removeAllChildren()
141 self._actions = []
142
143 for i in reversed(range(len(self._actionbuttons))):
144 self._actionbuttons[i].removeEvents()
145 self._actionbuttons = []
146
147 def setButtonStyle(self, button_style):
148 self._button_style = ToolBar.BUTTON_STYLE['IconOnly']
149 for key, val in ToolBar.BUTTON_STYLE.iteritems():
150 if val == button_style:
151 self._button_style = button_style
152 break
153
154 self._updateToolbar()
155
156 def getButtonStyle(self):
157 return self._button_style
158 button_style = property(getButtonStyle, setButtonStyle)
159
160 def _updateToolbar(self):
161 actions = self._actions
162
163 self.clear()
164
165 if self._orientation == ToolBar.ORIENTATION['Vertical']:
166 self.gui = widgets.VBox(min_size=(self._panel_size, self._panel_size))
167 else:
168 self.gui = widgets.HBox(min_size=(self._panel_size, self._panel_size))
169 self.addChild(self.gui)
170
171 for action in actions:
172 self.addAction(action)
173
174 self.adaptLayout()
175
176 def setOrientation(self, orientation):
177 if orientation == ToolBar.ORIENTATION['Vertical']:
178 self._orientation = ToolBar.ORIENTATION['Vertical']
179 self._max_size = (self._panel_size, 5000)
180 else:
181 self._orientation = ToolBar.ORIENTATION['Horizontal']
182 self._max_size = (5000, self._panel_size)
183 self._orientation = orientation
184
185 self._updateToolbar()
186
187 def getOrientation(self):
188 return self._orientation
189 orientation = property(getOrientation, setOrientation)
190
191 def setPanelSize(self, panel_size):
192 self._panel_size = panel_size
193 self.min_size = self.gui.min_size = (self._panel_size, self._panel_size)
194 self.setOrientation(self._orientation)
195
196 def getPanelSize(self):
197 return self._panel_size
198 panel_size = property(getPanelSize, setPanelSize)
199
200 def mouseClicked(self, event):
201 if event.getButton() == 2: # Right click
202 if self.isDocked():
203 self.setDocked(False)
204 event.consume()
205
206 def mouseDragged(self, event):
207 if self._resize is False and self.isDocked() is False:
208 mouseX = self.x+event.getX()
209 mouseY = self.y+event.getY()
210 self._editor.getToolbarAreaAt(mouseX, mouseY, True)
211 else:
212 ResizableBase.mouseDragged(self, event)
213
214 def mouseReleased(self, event):
215 # Resize/move done
216 self.real_widget.setMovable(self._movable)
217
218 if self._resize:
219 ResizableBase.mouseReleased(self, event)
220 elif self._movable:
221 mouseX = self.x+event.getX()
222 mouseY = self.y+event.getY()
223
224 dockArea = self._editor.getToolbarAreaAt(mouseX, mouseY)
225 if dockArea is not None:
226 self._editor.dockWidgetTo(self, dockArea, mouseX, mouseY)
227
228 class ToolbarButton(widgets.VBox):
229 def __init__(self, action, button_style=0, **kwargs):
230 self._action = action
231 self._widget = None
232
233 super(ToolbarButton, self).__init__(**kwargs)
234
235 self.setButtonStyle(button_style)
236 self.update()
237
238 self.initEvents()
239
240 def initEvents(self):
241 # Register eventlisteners
242 self.capture(self._showTooltip, "mouseEntered")
243 self.capture(self._hideTooltip, "mouseExited")
244
245 scripts.gui.action.changed.connect(self._actionChanged, sender=self._action)
246
247 def removeEvents(self):
248 # Remove eventlisteners
249 self.capture(None, "mouseEntered")
250 self.capture(None, "mouseExited")
251
252 scripts.gui.action.changed.disconnect(self.update, sender=self._action)
253
254 def setAction(self, action):
255 self.removeEvents()
256
257 self._action = action
258 self.update()
259 self.adaptLayout(False)
260
261 self.initEvents()
262
263 def getAction(self):
264 return self._action
265 action = property(getAction, setAction)
266
267 def setButtonStyle(self, button_style):
268 self._button_style = ToolBar.BUTTON_STYLE['IconOnly']
269 for key, val in ToolBar.BUTTON_STYLE.iteritems():
270 if val == button_style:
271 self._button_style = button_style
272 break
273
274 def getButtonStyle(self):
275 return self._button_style
276 button_style = property(getButtonStyle, setButtonStyle)
277
278 def _showTooltip(self):
279 if self._action is not None and self._action.helptext != "":
280 scripts.editor.getEditor().getStatusBar().showTooltip(self._action.helptext)
281
282 def _hideTooltip(self):
283 scripts.editor.getEditor().getStatusBar().hideTooltip()
284
285 def _actionChanged(self):
286 self.update()
287 self.adaptLayout(False)
288
289 def update(self):
290 """ Sets up the button widget """
291 if self._widget != None:
292 self.removeChild(self._widget)
293 self._widget = None
294
295 if self._action is None:
296 return
297
298 widget = None
299 icon = None
300 text = None
301
302 if self._action.isSeparator():
303 widget = widgets.VBox()
304 widget.base_color += Color(8, 8, 8)
305 widget.min_size = (2, 2)
306 else:
307 if self._button_style != ToolBar.BUTTON_STYLE['TextOnly'] and len(self._action.icon) > 0:
308 if self._action.isCheckable():
309 icon = widgets.ToggleButton(hexpand=0, up_image=self._action.icon,down_image=self._action.icon,hover_image=self._action.icon,offset=(1,1))
310 icon.toggled = self._action.isChecked()
311 else:
312 icon = widgets.ImageButton(hexpand=0, up_image=self._action.icon,down_image=self._action.icon,hover_image=self._action.icon,offset=(1,1))
313 icon.capture(self._action.activate)
314
315 if self._button_style != ToolBar.BUTTON_STYLE['IconOnly'] or len(self._action.icon) <= 0:
316 if self._action.isCheckable():
317 text = widgets.ToggleButton(hexpand=0, text=self._action.text,offset=(1,1))
318 text.toggled = self._action.isChecked()
319 else:
320 text = widgets.Button(text=self._action.text)
321 text.capture(self._action.activate)
322
323 if self._button_style == ToolBar.BUTTON_STYLE['TextOnly'] or len(self._action.icon) <= 0:
324 widget = text
325
326 elif self._button_style == ToolBar.BUTTON_STYLE['TextUnderIcon']:
327 widget = widgets.VBox()
328 icon.position_technique = "center:top"
329 text.position_technique = "center:bottom"
330 widget.addChild(icon)
331 widget.addChild(text)
332
333 elif self._button_style == ToolBar.BUTTON_STYLE['TextBesideIcon']:
334 widget = widgets.HBox()
335 widget.addChild(icon)
336 widget.addChild(text)
337
338 else:
339 widget = icon
340
341 widget.position_technique = "left:center"
342 widget.hexpand = 0
343
344 self._widget = widget
345 self.addChild(self._widget)
346