comparison clients/editor/scripts/gui/toolbar.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 import pychan
2 from pychan import widgets
3
4 import scripts.events
5 import action
6 import scripts.editor
7 from action import Action, ActionGroup
8 from fife import Color
9 from panel import Panel
10 from resizablebase import ResizableBase
11
12 class ToolBar(Panel):
13 ORIENTATION = {
14 "Horizontal" : 0,
15 "Vertical" : 1
16 }
17
18 BUTTON_STYLE = {
19 "IconOnly" : 0,
20 "TextOnly" : 1,
21 "TextUnderIcon" : 2,
22 "TextBesideIcon" : 3
23 }
24
25 def __init__(self, button_style=0, panel_size=27, orientation=0, *args, **kwargs):
26 super(ToolBar, self).__init__(resizable=False, *args, **kwargs)
27
28 self._actions = []
29 self._actionbuttons = []
30 self._button_style = 0
31 self._panel_size = panel_size
32 self.gui = None
33
34 self._orientation = orientation
35 self._button_style = button_style
36
37 self._updateToolbar()
38
39 self.capture(self.mouseReleased, "mouseReleased", "toolbar")
40 self.capture(self.mouseClicked, "mouseClicked", "toolbar")
41
42 def addSeparator(self, separator=None):
43 self.insertSeparator(separator, len(self._actions))
44
45 def addAction(self, action):
46 self.insertAction(action, len(self._actions))
47
48 def removeAction(self, action):
49 self._actions.remove(action)
50
51 actions = [action]
52 if isinstance(action, ActionGroup):
53 actions = action.getActions()
54 scripts.gui.action.changed.disconnect(self._updateActionGroup, sender=action)
55
56 for a in actions:
57 for b in self._actionbuttons[:]:
58 if a == b.action:
59 self.gui.removeChild(b)
60 self._actionbuttons.remove(b)
61
62 self.adaptLayout()
63
64 def hasAction(self, action):
65 for a in self._actions:
66 if a == action: return True
67 return False
68
69 def insertAction(self, action, position=0, before=None):
70 if self.hasAction(action):
71 print "Action already added to toolbar"
72 return
73
74 if before is not None:
75 position = self._actions.index(before)
76
77 self._actions.insert(position, action)
78 self._insertButton(action, position)
79
80 def _updateActionGroup(self, sender):
81 position = self._actions.index(sender)
82 self.removeAction(sender)
83 self.insertAction(sender, position)
84 self.adaptLayout()
85
86 def _insertButton(self, action, position):
87 actions = [action]
88 if isinstance(action, ActionGroup):
89 actions = action.getActions()
90 scripts.gui.action.changed.connect(self._updateActionGroup, sender=action)
91
92 if position >= 0:
93 actions = reversed(actions)
94
95 # Action groups are counted as one action, add the hidde number of actions to position
96 for i in range(position):
97 if isinstance(self._actions[i], ActionGroup):
98 position += len(self._actions[i].getActions()) - 1
99
100 for a in actions:
101 button = ToolbarButton(a, button_style=self._button_style, name=a.text)
102 self.gui.insertChild(button, position)
103 self._actionbuttons.insert(position, button)
104
105 def insertSeparator(self, separator=None, position=0, before=None):
106 if separator==None:
107 separator = Action(separator=True)
108 self.insertAction(separator, position, before)
109
110 def clear(self):
111 self.removeAllChildren()
112 self._actions = []
113
114 for i in reversed(range(len(self._actionbuttons))):
115 self._actionbuttons[i].removeEvents()
116 self._actionbuttons = []
117
118 def setButtonStyle(self, button_style):
119 self._button_style = ToolBar.BUTTON_STYLE['IconOnly']
120 for key, val in ToolBar.BUTTON_STYLE.iteritems():
121 if val == button_style:
122 self._button_style = button_style
123 break
124
125 self._updateToolbar()
126
127 def getButtonStyle(self):
128 return self._button_style
129 button_style = property(getButtonStyle, setButtonStyle)
130
131 def _updateToolbar(self):
132 actions = self._actions
133
134 self.clear()
135
136 if self._orientation == ToolBar.ORIENTATION['Vertical']:
137 self.gui = widgets.VBox(min_size=(self._panel_size, self._panel_size))
138 else:
139 self.gui = widgets.HBox(min_size=(self._panel_size, self._panel_size))
140 self.addChild(self.gui)
141
142 for action in actions:
143 self.addAction(action)
144
145 self.adaptLayout()
146
147 def setOrientation(self, orientation):
148 if orientation == ToolBar.ORIENTATION['Vertical']:
149 self._orientation = ToolBar.ORIENTATION['Vertical']
150 self._max_size = (self._panel_size, 5000)
151 else:
152 self._orientation = ToolBar.ORIENTATION['Horizontal']
153 self._max_size = (5000, self._panel_size)
154 self._orientation = orientation
155
156 self._updateToolbar()
157
158 def getOrientation(self):
159 return self._orientation
160 orientation = property(getOrientation, setOrientation)
161
162 def setPanelSize(self, panel_size):
163 self._panel_size = panel_size
164 self.min_size = self.gui.min_size = (self._panel_size, self._panel_size)
165 self.setOrientation(self._orientation)
166
167 def getPanelSize(self):
168 return self._panel_size
169 panel_size = property(getPanelSize, setPanelSize)
170
171 def mouseClicked(self, event):
172 if event.getButton() == 2: # Right click
173 if self.isDocked():
174 self.setDocked(False)
175 event.consume()
176
177 def mouseDragged(self, event):
178 if self._resize is False and self.isDocked() is False:
179 mouseX = self.x+event.getX()
180 mouseY = self.y+event.getY()
181 self._editor.getToolbarAreaAt(mouseX, mouseY, True)
182 else:
183 ResizableBase.mouseDragged(self, event)
184
185 def mouseReleased(self, event):
186 # Resize/move done
187 self.real_widget.setMovable(self._movable)
188
189 if self._resize:
190 ResizableBase.mouseReleased(self, event)
191 elif self._movable:
192 mouseX = self.x+event.getX()
193 mouseY = self.y+event.getY()
194
195 dockArea = self._editor.getToolbarAreaAt(mouseX, mouseY)
196 if dockArea is not None:
197 self._editor.dockWidgetTo(self, dockArea, mouseX, mouseY)
198
199 class ToolbarButton(widgets.VBox):
200 def __init__(self, action, button_style=0, **kwargs):
201 self._action = action
202 self._widget = None
203
204 super(ToolbarButton, self).__init__(**kwargs)
205
206 self.setButtonStyle(button_style)
207 self.update()
208
209 self.initEvents()
210
211 def initEvents(self):
212 # Register eventlisteners
213 self.capture(self._showTooltip, "mouseEntered")
214 self.capture(self._hideTooltip, "mouseExited")
215
216 scripts.gui.action.changed.connect(self._actionChanged, sender=self._action)
217
218 def removeEvents(self):
219 # Remove eventlisteners
220 self.capture(None, "mouseEntered")
221 self.capture(None, "mouseExited")
222
223 scripts.gui.action.changed.disconnect(self.update, sender=self._action)
224
225 def setAction(self, action):
226 self.removeEvents()
227
228 self._action = action
229 self.update()
230 self.adaptLayout()
231
232 self.initEvents()
233
234 def getAction(self):
235 return self._action
236 action = property(getAction, setAction)
237
238 def setButtonStyle(self, button_style):
239 self._button_style = ToolBar.BUTTON_STYLE['IconOnly']
240 for key, val in ToolBar.BUTTON_STYLE.iteritems():
241 if val == button_style:
242 self._button_style = button_style
243 break
244
245 def getButtonStyle(self):
246 return self._button_style
247 button_style = property(getButtonStyle, setButtonStyle)
248
249 def _showTooltip(self):
250 if self._action is not None and self._action.helptext != "":
251 scripts.editor.getEditor().getStatusBar().showTooltip(self._action.helptext)
252
253 def _hideTooltip(self):
254 scripts.editor.getEditor().getStatusBar().hideTooltip()
255
256 def _actionChanged(self):
257 self.update()
258 self.adaptLayout()
259
260 def update(self):
261 """ Sets up the button widget """
262 if self._widget != None:
263 self.removeChild(self._widget)
264 self._widget = None
265
266 if self._action is None:
267 return
268
269 widget = None
270 icon = None
271 text = None
272
273 if self._action.isSeparator():
274 widget = widgets.VBox()
275 widget.base_color += Color(8, 8, 8)
276 widget.min_size = (2, 2)
277 else:
278 if self._button_style != ToolBar.BUTTON_STYLE['TextOnly'] and len(self._action.icon) > 0:
279 if self._action.isCheckable():
280 icon = widgets.ToggleButton(hexpand=0, up_image=self._action.icon,down_image=self._action.icon,hover_image=self._action.icon,offset=(1,1))
281 icon.toggled = self._action.isChecked()
282 else:
283 icon = widgets.ImageButton(hexpand=0, up_image=self._action.icon,down_image=self._action.icon,hover_image=self._action.icon,offset=(1,1))
284 icon.capture(self._action.activate)
285
286 if self._button_style != ToolBar.BUTTON_STYLE['IconOnly'] or len(self._action.icon) <= 0:
287 if self._action.isCheckable():
288 text = widgets.ToggleButton(hexpand=0, text=self._action.text,offset=(1,1))
289 text.toggled = self._action.isChecked()
290 else:
291 text = widgets.Button(text=self._action.text)
292 text.capture(self._action.activate)
293
294 if self._button_style == ToolBar.BUTTON_STYLE['TextOnly'] or len(self._action.icon) <= 0:
295 widget = text
296
297 elif self._button_style == ToolBar.BUTTON_STYLE['TextUnderIcon']:
298 widget = widgets.VBox()
299 icon.position_technique = "center:top"
300 text.position_technique = "center:bottom"
301 widget.addChild(icon)
302 widget.addChild(text)
303
304 elif self._button_style == ToolBar.BUTTON_STYLE['TextBesideIcon']:
305 widget = widgets.HBox()
306 widget.addChild(icon)
307 widget.addChild(text)
308
309 else:
310 widget = icon
311
312 widget.position_technique = "left:center"
313 widget.hexpand = 0
314
315 self._widget = widget
316 self.addChild(self._widget)
317