Mercurial > fife-parpg
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 |