]> git.saurik.com Git - wxWidgets.git/blame - wxPython/wx/tools/XRCed/tools.py
use wxFormatString in wxV[f]printf()
[wxWidgets.git] / wxPython / wx / tools / XRCed / tools.py
CommitLineData
d14a1e28
RD
1# Name: tools.py
2# Purpose: XRC editor, toolbar
3# Author: Roman Rolinsky <rolinsky@mema.ucl.ac.be>
4# Created: 19.03.2003
5# RCS-ID: $Id$
1fded56b 6
d14a1e28
RD
7from xxx import * # xxx imports globals and params
8from tree import ID_NEW
1fded56b 9
d14a1e28
RD
10# Icons
11import images
12
13# Groups of controls
14GROUPNUM = 4
15GROUP_WINDOWS, GROUP_MENUS, GROUP_SIZERS, GROUP_CONTROLS = range(GROUPNUM)
16
17# States depending on current selection and Control/Shift keys
c032d94e 18STATE_ROOT, STATE_MENUBAR, STATE_TOOLBAR, STATE_MENU, STATE_STDDLGBTN, STATE_ELSE = range(6)
d14a1e28 19# Left toolbar for GUI elements
29a41103 20class Tools(wx.Panel):
d14a1e28
RD
21 TOOL_SIZE = (30, 30)
22 def __init__(self, parent):
29a41103
RD
23 if wx.Platform == '__WXGTK__':
24 wx.Panel.__init__(self, parent, -1,
25 style=wx.RAISED_BORDER|wx.WANTS_CHARS)
d14a1e28 26 else:
29a41103 27 wx.Panel.__init__(self, parent, -1, style=wx.WANTS_CHARS)
d14a1e28 28 # Create sizer for groups
29a41103 29 self.sizer = wx.BoxSizer(wx.VERTICAL)
d14a1e28
RD
30 # Data to create buttons
31 pullDownMenu = g.pullDownMenu
32 self.groups = []
33 self.ctrl = self.shift = False
34 # Current state (what to enable/disable)
35 self.state = None
36 groups = [
37 ["Windows",
38 (ID_NEW.FRAME, images.getToolFrameBitmap()),
39 (ID_NEW.DIALOG, images.getToolDialogBitmap()),
40 (ID_NEW.PANEL, images.getToolPanelBitmap())],
41 ["Menus",
42 (ID_NEW.TOOL_BAR, images.getToolToolBarBitmap()),
43 (ID_NEW.MENU_BAR, images.getToolMenuBarBitmap()),
44 (ID_NEW.MENU, images.getToolMenuBitmap()),
45 (ID_NEW.TOOL, images.getToolToolBitmap()),
46 (ID_NEW.MENU_ITEM, images.getToolMenuItemBitmap()),
47 (ID_NEW.SEPARATOR, images.getToolSeparatorBitmap())],
48 ["Sizers",
49 (ID_NEW.BOX_SIZER, images.getToolBoxSizerBitmap()),
50 (ID_NEW.STATIC_BOX_SIZER, images.getToolStaticBoxSizerBitmap()),
51 (ID_NEW.GRID_SIZER, images.getToolGridSizerBitmap()),
52 (ID_NEW.FLEX_GRID_SIZER, images.getToolFlexGridSizerBitmap()),
a4c013b2 53 (ID_NEW.GRID_BAG_SIZER, images.getToolGridBagSizerBitmap()),
d14a1e28
RD
54 (ID_NEW.SPACER, images.getToolSpacerBitmap())],
55 ["Controls",
56 (ID_NEW.STATIC_TEXT, images.getToolStaticTextBitmap()),
57 (ID_NEW.STATIC_BITMAP, images.getToolStaticBitmapBitmap()),
58 (ID_NEW.STATIC_LINE, images.getToolStaticLineBitmap()),
59
60 (ID_NEW.BUTTON, images.getToolButtonBitmap()),
61 (ID_NEW.BITMAP_BUTTON, images.getToolBitmapButtonBitmap()),
62 (ID_NEW.STATIC_BOX, images.getToolStaticBoxBitmap()),
63
64 (ID_NEW.TEXT_CTRL, images.getToolTextCtrlBitmap()),
65 (ID_NEW.COMBO_BOX, images.getToolComboBoxBitmap()),
66 (ID_NEW.CHOICE, images.getToolChoiceBitmap()),
67
68 (ID_NEW.RADIO_BUTTON, images.getToolRadioButtonBitmap()),
69 (ID_NEW.CHECK_BOX, images.getToolCheckBoxBitmap()),
70 (ID_NEW.RADIO_BOX, images.getToolRadioBoxBitmap()),
71
72 (ID_NEW.SPIN_CTRL, images.getToolSpinCtrlBitmap()),
73 (ID_NEW.SPIN_BUTTON, images.getToolSpinButtonBitmap()),
74 (ID_NEW.SCROLL_BAR, images.getToolScrollBarBitmap()),
75
76 (ID_NEW.SLIDER, images.getToolSliderBitmap()),
77 (ID_NEW.GAUGE, images.getToolGaugeBitmap()),
78 (ID_NEW.TREE_CTRL, images.getToolTreeCtrlBitmap()),
79
80 (ID_NEW.LIST_BOX, images.getToolListBoxBitmap()),
81 (ID_NEW.CHECK_LIST, images.getToolCheckListBitmap()),
82 (ID_NEW.LIST_CTRL, images.getToolListCtrlBitmap()),
83
84 (ID_NEW.NOTEBOOK, images.getToolNotebookBitmap()),
68ae5821 85 (ID_NEW.SPLITTER_WINDOW, images.getToolSplitterWindowBitmap()),
d14a1e28
RD
86
87 (ID_NEW.UNKNOWN, images.getToolUnknownBitmap())]
88 ]
552240ce 89 self.boxes = {}
d14a1e28
RD
90 for grp in groups:
91 self.AddGroup(grp[0])
92 for b in grp[1:]:
93 self.AddButton(b[0], b[1], g.pullDownMenu.createMap[b[0]])
d14a1e28
RD
94 self.SetSizerAndFit(self.sizer)
95 # Allow to be resized in vertical direction only
96 self.SetSizeHints(self.GetSize()[0], -1)
97 # Events
29a41103 98 wx.EVT_COMMAND_RANGE(self, ID_NEW.PANEL, ID_NEW.LAST,
5c82ed90 99 wx.wxEVT_COMMAND_BUTTON_CLICKED, g.frame.OnCreate)
29a41103
RD
100 wx.EVT_KEY_DOWN(self, self.OnKeyDown)
101 wx.EVT_KEY_UP(self, self.OnKeyUp)
9e20825c 102 self.Bind(wx.EVT_LEFT_DOWN, self.OnClickBox)
d14a1e28 103
ed650677
RR
104 self.drag = None
105
d14a1e28 106 def AddButton(self, id, image, text):
29a41103
RD
107 from wx.lib import buttons
108 button = buttons.GenBitmapButton(self, id, image, size=self.TOOL_SIZE,
5c82ed90 109 style=wx.NO_BORDER|wx.WANTS_CHARS)
5e8b10e9 110 button.SetBezelWidth(0)
29a41103
RD
111 wx.EVT_KEY_DOWN(button, self.OnKeyDown)
112 wx.EVT_KEY_UP(button, self.OnKeyUp)
ed650677
RR
113 wx.EVT_LEFT_DOWN(button, self.OnLeftDownOnButton)
114 wx.EVT_MOTION(button, self.OnMotionOnButton)
d14a1e28
RD
115 button.SetToolTipString(text)
116 self.curSizer.Add(button)
117 self.groups[-1][1][id] = button
118
119 def AddGroup(self, name):
120 # Each group is inside box
552240ce
RR
121 id = wx.NewId()
122 box = wx.StaticBox(self, id, '[+] '+name, style=wx.WANTS_CHARS)
9e20825c
RR
123 box.SetForegroundColour(wx.Colour(64, 64, 64))
124# box.SetFont(g.smallerFont())
552240ce
RR
125 box.show = True
126 box.name = name
127 box.gnum = len(self.groups)
552240ce 128 box.Bind(wx.EVT_LEFT_DOWN, self.OnClickBox)
29a41103 129 boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
d14a1e28 130 boxSizer.Add((0, 4))
552240ce 131 self.boxes[id] = box
29a41103 132 self.curSizer = wx.GridSizer(0, 3)
d14a1e28 133 boxSizer.Add(self.curSizer)
552240ce 134 self.sizer.Add(boxSizer, 0, wx.TOP | wx.LEFT | wx.RIGHT | wx.EXPAND, 4)
d14a1e28
RD
135 self.groups.append((box,{}))
136
137 # Enable/disable group
138 def EnableGroup(self, gnum, enable = True):
139 grp = self.groups[gnum]
9e20825c 140 #grp[0].Enable(enable)
d14a1e28
RD
141 for b in grp[1].values(): b.Enable(enable)
142
552240ce
RR
143 # Show/hide group
144 def ShowGroup(self, gnum, show = True):
145 grp = self.groups[gnum]
146 grp[0].show = show
147 for b in grp[1].values(): b.Show(show)
148
d14a1e28
RD
149 # Enable/disable group item
150 def EnableGroupItem(self, gnum, id, enable = True):
151 grp = self.groups[gnum]
152 grp[1][id].Enable(enable)
153
154 # Enable/disable group items
155 def EnableGroupItems(self, gnum, ids, enable = True):
156 grp = self.groups[gnum]
157 for id in ids:
158 grp[1][id].Enable(enable)
159
552240ce 160 def OnClickBox(self, evt):
9e20825c
RR
161 if wx.Platform == '__WXMSW__':
162 box = None
163 for id,b in self.boxes.items():
164 # Detect click on label
165 if b.GetRect().Inside(evt.GetPosition()):
166 box = b
167 break
168 if not box: return
169 else:
170 box = self.boxes[evt.GetId()]
552240ce
RR
171 # Collapse/restore static box, change label
172 self.ShowGroup(box.gnum, not box.show)
173 if box.show: box.SetLabel('[+] ' + box.name)
174 else: box.SetLabel('[-] ' + box.name)
175 self.Layout()
9e20825c
RR
176 self.Refresh()
177 #for b in self.boxes.items():
552240ce 178
ed650677
RR
179 # DaD
180 def OnLeftDownOnButton(self, evt):
181 self.posDown = evt.GetPosition()
182 self.idDown = evt.GetId()
183 self.btnDown = evt.GetEventObject()
184 evt.Skip()
185
186 def OnMotionOnButton(self, evt):
187 # Detect dragging
188 if evt.Dragging() and evt.LeftIsDown():
189 d = evt.GetPosition() - self.posDown
190 if max(abs(d[0]), abs(d[1])) >= 5:
191 if self.btnDown.HasCapture():
192 # Generate up event to release mouse
193 evt = wx.MouseEvent(wx.EVT_LEFT_UP.typeId)
194 evt.SetId(self.idDown)
195 # Set flag to prevent normal button operation this time
196 self.drag = True
197 self.btnDown.ProcessEvent(evt)
198 self.StartDrag()
199 evt.Skip()
200
201 def StartDrag(self):
5c82ed90 202 do = MyDataObject()
ed650677
RR
203 do.SetData(str(self.idDown))
204 bm = self.btnDown.GetBitmapLabel()
a7d8ec1e
RR
205 # wxGTK requires wxIcon cursor, wxWIN and wxMAC require wxCursor
206 if wx.Platform == '__WXGTK__':
5c82ed90
RR
207 icon = wx.EmptyIcon()
208 icon.CopyFromBitmap(bm)
209 dragSource = wx.DropSource(self, icon)
a7d8ec1e 210 else:
5c82ed90
RR
211 curs = wx.CursorFromImage(wx.ImageFromBitmap(bm))
212 dragSource = wx.DropSource(self, curs)
213 dragSource.SetData(do)
214 g.frame.SetStatusText('Release the mouse button over the test window')
215 dragSource.DoDragDrop()
216
d14a1e28
RD
217 # Process key events
218 def OnKeyDown(self, evt):
29a41103 219 if evt.GetKeyCode() == wx.WXK_CONTROL:
d14a1e28 220 g.tree.ctrl = True
29a41103 221 elif evt.GetKeyCode() == wx.WXK_SHIFT:
d14a1e28
RD
222 g.tree.shift = True
223 self.UpdateIfNeeded()
224 evt.Skip()
225
226 def OnKeyUp(self, evt):
29a41103 227 if evt.GetKeyCode() == wx.WXK_CONTROL:
d14a1e28 228 g.tree.ctrl = False
29a41103 229 elif evt.GetKeyCode() == wx.WXK_SHIFT:
d14a1e28
RD
230 g.tree.shift = False
231 self.UpdateIfNeeded()
232 evt.Skip()
233
234 def OnMouse(self, evt):
235 # Update control and shift states
236 g.tree.ctrl = evt.ControlDown()
237 g.tree.shift = evt.ShiftDown()
238 self.UpdateIfNeeded()
239 evt.Skip()
240
241 # Update UI after key presses, if necessary
242 def UpdateIfNeeded(self):
243 tree = g.tree
244 if self.ctrl != tree.ctrl or self.shift != tree.shift:
245 # Enabling is needed only for ctrl
246 if self.ctrl != tree.ctrl: self.UpdateUI()
247 self.ctrl = tree.ctrl
248 self.shift = tree.shift
249 if tree.ctrl:
250 status = 'SBL'
251 elif tree.shift:
252 status = 'INS'
253 else:
254 status = ''
255 g.frame.SetStatusText(status, 1)
256
257 # Update interface
258 def UpdateUI(self):
259 if not self.IsShown(): return
260 # Update status bar
261 pullDownMenu = g.pullDownMenu
262 tree = g.tree
263 item = tree.selection
264 # If nothing selected, disable everything and return
265 if not item:
266 # Disable everything
267 for grp in range(GROUPNUM):
268 self.EnableGroup(grp, False)
269 self.state = None
270 return
271 if tree.ctrl: needInsert = True
272 else: needInsert = tree.NeedInsert(item)
273 # Enable depending on selection
274 if item == tree.root or needInsert and tree.GetItemParent(item) == tree.root:
275 state = STATE_ROOT
276 else:
277 xxx = tree.GetPyData(item).treeObject()
278 # Check parent for possible child nodes if inserting sibling
279 if needInsert: xxx = xxx.parent
280 if xxx.__class__ == xxxMenuBar:
281 state = STATE_MENUBAR
282 elif xxx.__class__ in [xxxToolBar, xxxTool] or \
283 xxx.__class__ == xxxSeparator and xxx.parent.__class__ == xxxToolBar:
284 state = STATE_TOOLBAR
285 elif xxx.__class__ in [xxxMenu, xxxMenuItem]:
286 state = STATE_MENU
c032d94e
RR
287 elif xxx.__class__ == xxxStdDialogButtonSizer:
288 state = STATE_STDDLGBTN
d14a1e28
RD
289 else:
290 state = STATE_ELSE
291
292 # Enable depending on selection
293 if state != self.state:
294 # Disable everything
295 for grp in range(GROUPNUM):
296 self.EnableGroup(grp, False)
297 # Enable some
298 if state == STATE_ROOT:
299 self.EnableGroup(GROUP_WINDOWS, True)
300 self.EnableGroup(GROUP_MENUS, True)
301 # But disable items
302 self.EnableGroupItems(GROUP_MENUS,
303 [ ID_NEW.TOOL,
304 ID_NEW.MENU_ITEM,
305 ID_NEW.SEPARATOR ],
306 False)
306b6fe9 307 elif state == STATE_STDDLGBTN:
c032d94e 308 pass # nothing can be added from toolbar
d14a1e28
RD
309 elif state == STATE_MENUBAR:
310 self.EnableGroup(GROUP_MENUS)
311 self.EnableGroupItems(GROUP_MENUS,
312 [ ID_NEW.TOOL_BAR,
313 ID_NEW.MENU_BAR,
314 ID_NEW.TOOL ],
315 False)
316 elif state == STATE_TOOLBAR:
317 self.EnableGroup(GROUP_MENUS)
318 self.EnableGroupItems(GROUP_MENUS,
319 [ ID_NEW.TOOL_BAR,
320 ID_NEW.MENU,
321 ID_NEW.MENU_BAR,
322 ID_NEW.MENU_ITEM ],
323 False)
324 self.EnableGroup(GROUP_CONTROLS)
325 self.EnableGroupItems(GROUP_CONTROLS,
326 [ ID_NEW.TREE_CTRL,
68ae5821
RD
327 ID_NEW.NOTEBOOK,
328 ID_NEW.SPLITTER_WINDOW ],
d14a1e28
RD
329 False)
330 elif state == STATE_MENU:
331 self.EnableGroup(GROUP_MENUS)
332 self.EnableGroupItems(GROUP_MENUS,
333 [ ID_NEW.TOOL_BAR,
334 ID_NEW.MENU_BAR,
335 ID_NEW.TOOL ],
336 False)
337 else:
338 self.EnableGroup(GROUP_WINDOWS)
339 self.EnableGroupItems(GROUP_WINDOWS,
340 [ ID_NEW.FRAME,
341 ID_NEW.DIALOG ],
342 False)
343 self.EnableGroup(GROUP_MENUS)
344 self.EnableGroupItems(GROUP_MENUS,
345 [ ID_NEW.MENU_BAR,
346 ID_NEW.MENU_BAR,
347 ID_NEW.MENU,
348 ID_NEW.MENU_ITEM,
349 ID_NEW.TOOL,
350 ID_NEW.SEPARATOR ],
351 False)
352 self.EnableGroup(GROUP_SIZERS)
353 self.EnableGroup(GROUP_CONTROLS)
306b6fe9 354 # Special case for *book (always executed)
d14a1e28 355 if state == STATE_ELSE:
306b6fe9 356 if xxx.__class__ in [xxxNotebook, xxxChoicebook, xxxListbook]:
d14a1e28
RD
357 self.EnableGroup(GROUP_SIZERS, False)
358 else:
359 self.EnableGroup(GROUP_SIZERS)
360 if not (xxx.isSizer or xxx.parent and xxx.parent.isSizer):
361 self.EnableGroupItem(GROUP_SIZERS, ID_NEW.SPACER, False)
f65bb0f8
RD
362 if xxx.__class__ == xxxFrame:
363 self.EnableGroupItem(GROUP_MENUS, ID_NEW.MENU_BAR)
d14a1e28
RD
364 # Save state
365 self.state = state