]>
Commit | Line | Data |
---|---|---|
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 |
7 | from xxx import * # xxx imports globals and params |
8 | from tree import ID_NEW | |
1fded56b | 9 | |
d14a1e28 RD |
10 | # Icons |
11 | import images | |
12 | ||
13 | # Groups of controls | |
14 | GROUPNUM = 4 | |
15 | GROUP_WINDOWS, GROUP_MENUS, GROUP_SIZERS, GROUP_CONTROLS = range(GROUPNUM) | |
16 | ||
17 | # States depending on current selection and Control/Shift keys | |
18 | STATE_ROOT, STATE_MENUBAR, STATE_TOOLBAR, STATE_MENU, STATE_ELSE = range(5) | |
19 | ||
20 | # Left toolbar for GUI elements | |
21 | class Tools(wxPanel): | |
22 | TOOL_SIZE = (30, 30) | |
23 | def __init__(self, parent): | |
24 | if wxPlatform == '__WXGTK__': | |
25 | wxPanel.__init__(self, parent, -1, | |
26 | style=wxRAISED_BORDER|wxWANTS_CHARS) | |
27 | else: | |
28 | wxPanel.__init__(self, parent, -1, style=wxWANTS_CHARS) | |
29 | # Create sizer for groups | |
30 | self.sizer = wxBoxSizer(wxVERTICAL) | |
31 | # Data to create buttons | |
32 | pullDownMenu = g.pullDownMenu | |
33 | self.groups = [] | |
34 | self.ctrl = self.shift = False | |
35 | # Current state (what to enable/disable) | |
36 | self.state = None | |
37 | groups = [ | |
38 | ["Windows", | |
39 | (ID_NEW.FRAME, images.getToolFrameBitmap()), | |
40 | (ID_NEW.DIALOG, images.getToolDialogBitmap()), | |
41 | (ID_NEW.PANEL, images.getToolPanelBitmap())], | |
42 | ["Menus", | |
43 | (ID_NEW.TOOL_BAR, images.getToolToolBarBitmap()), | |
44 | (ID_NEW.MENU_BAR, images.getToolMenuBarBitmap()), | |
45 | (ID_NEW.MENU, images.getToolMenuBitmap()), | |
46 | (ID_NEW.TOOL, images.getToolToolBitmap()), | |
47 | (ID_NEW.MENU_ITEM, images.getToolMenuItemBitmap()), | |
48 | (ID_NEW.SEPARATOR, images.getToolSeparatorBitmap())], | |
49 | ["Sizers", | |
50 | (ID_NEW.BOX_SIZER, images.getToolBoxSizerBitmap()), | |
51 | (ID_NEW.STATIC_BOX_SIZER, images.getToolStaticBoxSizerBitmap()), | |
52 | (ID_NEW.GRID_SIZER, images.getToolGridSizerBitmap()), | |
53 | (ID_NEW.FLEX_GRID_SIZER, images.getToolFlexGridSizerBitmap()), | |
a4c013b2 | 54 | (ID_NEW.GRID_BAG_SIZER, images.getToolGridBagSizerBitmap()), |
d14a1e28 RD |
55 | (ID_NEW.SPACER, images.getToolSpacerBitmap())], |
56 | ["Controls", | |
57 | (ID_NEW.STATIC_TEXT, images.getToolStaticTextBitmap()), | |
58 | (ID_NEW.STATIC_BITMAP, images.getToolStaticBitmapBitmap()), | |
59 | (ID_NEW.STATIC_LINE, images.getToolStaticLineBitmap()), | |
60 | ||
61 | (ID_NEW.BUTTON, images.getToolButtonBitmap()), | |
62 | (ID_NEW.BITMAP_BUTTON, images.getToolBitmapButtonBitmap()), | |
63 | (ID_NEW.STATIC_BOX, images.getToolStaticBoxBitmap()), | |
64 | ||
65 | (ID_NEW.TEXT_CTRL, images.getToolTextCtrlBitmap()), | |
66 | (ID_NEW.COMBO_BOX, images.getToolComboBoxBitmap()), | |
67 | (ID_NEW.CHOICE, images.getToolChoiceBitmap()), | |
68 | ||
69 | (ID_NEW.RADIO_BUTTON, images.getToolRadioButtonBitmap()), | |
70 | (ID_NEW.CHECK_BOX, images.getToolCheckBoxBitmap()), | |
71 | (ID_NEW.RADIO_BOX, images.getToolRadioBoxBitmap()), | |
72 | ||
73 | (ID_NEW.SPIN_CTRL, images.getToolSpinCtrlBitmap()), | |
74 | (ID_NEW.SPIN_BUTTON, images.getToolSpinButtonBitmap()), | |
75 | (ID_NEW.SCROLL_BAR, images.getToolScrollBarBitmap()), | |
76 | ||
77 | (ID_NEW.SLIDER, images.getToolSliderBitmap()), | |
78 | (ID_NEW.GAUGE, images.getToolGaugeBitmap()), | |
79 | (ID_NEW.TREE_CTRL, images.getToolTreeCtrlBitmap()), | |
80 | ||
81 | (ID_NEW.LIST_BOX, images.getToolListBoxBitmap()), | |
82 | (ID_NEW.CHECK_LIST, images.getToolCheckListBitmap()), | |
83 | (ID_NEW.LIST_CTRL, images.getToolListCtrlBitmap()), | |
84 | ||
85 | (ID_NEW.NOTEBOOK, images.getToolNotebookBitmap()), | |
68ae5821 | 86 | (ID_NEW.SPLITTER_WINDOW, images.getToolSplitterWindowBitmap()), |
d14a1e28 RD |
87 | |
88 | (ID_NEW.UNKNOWN, images.getToolUnknownBitmap())] | |
89 | ] | |
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]]) | |
94 | self.SetAutoLayout(True) | |
95 | self.SetSizerAndFit(self.sizer) | |
96 | # Allow to be resized in vertical direction only | |
97 | self.SetSizeHints(self.GetSize()[0], -1) | |
98 | # Events | |
99 | EVT_COMMAND_RANGE(self, ID_NEW.PANEL, ID_NEW.LAST, | |
100 | wxEVT_COMMAND_BUTTON_CLICKED, g.frame.OnCreate) | |
101 | EVT_KEY_DOWN(self, self.OnKeyDown) | |
102 | EVT_KEY_UP(self, self.OnKeyUp) | |
103 | ||
104 | def AddButton(self, id, image, text): | |
5e8b10e9 RD |
105 | from wxPython.lib import buttons |
106 | button = buttons.wxGenBitmapButton(self, id, image, size=self.TOOL_SIZE, | |
107 | style=wxNO_BORDER|wxWANTS_CHARS) | |
108 | button.SetBezelWidth(0) | |
d14a1e28 RD |
109 | EVT_KEY_DOWN(button, self.OnKeyDown) |
110 | EVT_KEY_UP(button, self.OnKeyUp) | |
111 | button.SetToolTipString(text) | |
112 | self.curSizer.Add(button) | |
113 | self.groups[-1][1][id] = button | |
114 | ||
115 | def AddGroup(self, name): | |
116 | # Each group is inside box | |
117 | box = wxStaticBox(self, -1, name, style=wxWANTS_CHARS) | |
289128a4 | 118 | box.SetFont(g.smallerFont()) |
d14a1e28 RD |
119 | boxSizer = wxStaticBoxSizer(box, wxVERTICAL) |
120 | boxSizer.Add((0, 4)) | |
121 | self.curSizer = wxGridSizer(0, 3) | |
122 | boxSizer.Add(self.curSizer) | |
123 | self.sizer.Add(boxSizer, 0, wxTOP | wxLEFT | wxRIGHT, 4) | |
124 | self.groups.append((box,{})) | |
125 | ||
126 | # Enable/disable group | |
127 | def EnableGroup(self, gnum, enable = True): | |
128 | grp = self.groups[gnum] | |
129 | grp[0].Enable(enable) | |
130 | for b in grp[1].values(): b.Enable(enable) | |
131 | ||
132 | # Enable/disable group item | |
133 | def EnableGroupItem(self, gnum, id, enable = True): | |
134 | grp = self.groups[gnum] | |
135 | grp[1][id].Enable(enable) | |
136 | ||
137 | # Enable/disable group items | |
138 | def EnableGroupItems(self, gnum, ids, enable = True): | |
139 | grp = self.groups[gnum] | |
140 | for id in ids: | |
141 | grp[1][id].Enable(enable) | |
142 | ||
143 | # Process key events | |
144 | def OnKeyDown(self, evt): | |
145 | if evt.GetKeyCode() == WXK_CONTROL: | |
146 | g.tree.ctrl = True | |
147 | elif evt.GetKeyCode() == WXK_SHIFT: | |
148 | g.tree.shift = True | |
149 | self.UpdateIfNeeded() | |
150 | evt.Skip() | |
151 | ||
152 | def OnKeyUp(self, evt): | |
153 | if evt.GetKeyCode() == WXK_CONTROL: | |
154 | g.tree.ctrl = False | |
155 | elif evt.GetKeyCode() == WXK_SHIFT: | |
156 | g.tree.shift = False | |
157 | self.UpdateIfNeeded() | |
158 | evt.Skip() | |
159 | ||
160 | def OnMouse(self, evt): | |
161 | # Update control and shift states | |
162 | g.tree.ctrl = evt.ControlDown() | |
163 | g.tree.shift = evt.ShiftDown() | |
164 | self.UpdateIfNeeded() | |
165 | evt.Skip() | |
166 | ||
167 | # Update UI after key presses, if necessary | |
168 | def UpdateIfNeeded(self): | |
169 | tree = g.tree | |
170 | if self.ctrl != tree.ctrl or self.shift != tree.shift: | |
171 | # Enabling is needed only for ctrl | |
172 | if self.ctrl != tree.ctrl: self.UpdateUI() | |
173 | self.ctrl = tree.ctrl | |
174 | self.shift = tree.shift | |
175 | if tree.ctrl: | |
176 | status = 'SBL' | |
177 | elif tree.shift: | |
178 | status = 'INS' | |
179 | else: | |
180 | status = '' | |
181 | g.frame.SetStatusText(status, 1) | |
182 | ||
183 | # Update interface | |
184 | def UpdateUI(self): | |
185 | if not self.IsShown(): return | |
186 | # Update status bar | |
187 | pullDownMenu = g.pullDownMenu | |
188 | tree = g.tree | |
189 | item = tree.selection | |
190 | # If nothing selected, disable everything and return | |
191 | if not item: | |
192 | # Disable everything | |
193 | for grp in range(GROUPNUM): | |
194 | self.EnableGroup(grp, False) | |
195 | self.state = None | |
196 | return | |
197 | if tree.ctrl: needInsert = True | |
198 | else: needInsert = tree.NeedInsert(item) | |
199 | # Enable depending on selection | |
200 | if item == tree.root or needInsert and tree.GetItemParent(item) == tree.root: | |
201 | state = STATE_ROOT | |
202 | else: | |
203 | xxx = tree.GetPyData(item).treeObject() | |
204 | # Check parent for possible child nodes if inserting sibling | |
205 | if needInsert: xxx = xxx.parent | |
206 | if xxx.__class__ == xxxMenuBar: | |
207 | state = STATE_MENUBAR | |
208 | elif xxx.__class__ in [xxxToolBar, xxxTool] or \ | |
209 | xxx.__class__ == xxxSeparator and xxx.parent.__class__ == xxxToolBar: | |
210 | state = STATE_TOOLBAR | |
211 | elif xxx.__class__ in [xxxMenu, xxxMenuItem]: | |
212 | state = STATE_MENU | |
213 | else: | |
214 | state = STATE_ELSE | |
215 | ||
216 | # Enable depending on selection | |
217 | if state != self.state: | |
218 | # Disable everything | |
219 | for grp in range(GROUPNUM): | |
220 | self.EnableGroup(grp, False) | |
221 | # Enable some | |
222 | if state == STATE_ROOT: | |
223 | self.EnableGroup(GROUP_WINDOWS, True) | |
224 | self.EnableGroup(GROUP_MENUS, True) | |
225 | # But disable items | |
226 | self.EnableGroupItems(GROUP_MENUS, | |
227 | [ ID_NEW.TOOL, | |
228 | ID_NEW.MENU_ITEM, | |
229 | ID_NEW.SEPARATOR ], | |
230 | False) | |
231 | elif state == STATE_MENUBAR: | |
232 | self.EnableGroup(GROUP_MENUS) | |
233 | self.EnableGroupItems(GROUP_MENUS, | |
234 | [ ID_NEW.TOOL_BAR, | |
235 | ID_NEW.MENU_BAR, | |
236 | ID_NEW.TOOL ], | |
237 | False) | |
238 | elif state == STATE_TOOLBAR: | |
239 | self.EnableGroup(GROUP_MENUS) | |
240 | self.EnableGroupItems(GROUP_MENUS, | |
241 | [ ID_NEW.TOOL_BAR, | |
242 | ID_NEW.MENU, | |
243 | ID_NEW.MENU_BAR, | |
244 | ID_NEW.MENU_ITEM ], | |
245 | False) | |
246 | self.EnableGroup(GROUP_CONTROLS) | |
247 | self.EnableGroupItems(GROUP_CONTROLS, | |
248 | [ ID_NEW.TREE_CTRL, | |
68ae5821 RD |
249 | ID_NEW.NOTEBOOK, |
250 | ID_NEW.SPLITTER_WINDOW ], | |
d14a1e28 RD |
251 | False) |
252 | elif state == STATE_MENU: | |
253 | self.EnableGroup(GROUP_MENUS) | |
254 | self.EnableGroupItems(GROUP_MENUS, | |
255 | [ ID_NEW.TOOL_BAR, | |
256 | ID_NEW.MENU_BAR, | |
257 | ID_NEW.TOOL ], | |
258 | False) | |
259 | else: | |
260 | self.EnableGroup(GROUP_WINDOWS) | |
261 | self.EnableGroupItems(GROUP_WINDOWS, | |
262 | [ ID_NEW.FRAME, | |
263 | ID_NEW.DIALOG ], | |
264 | False) | |
265 | self.EnableGroup(GROUP_MENUS) | |
266 | self.EnableGroupItems(GROUP_MENUS, | |
267 | [ ID_NEW.MENU_BAR, | |
268 | ID_NEW.MENU_BAR, | |
269 | ID_NEW.MENU, | |
270 | ID_NEW.MENU_ITEM, | |
271 | ID_NEW.TOOL, | |
272 | ID_NEW.SEPARATOR ], | |
273 | False) | |
274 | self.EnableGroup(GROUP_SIZERS) | |
275 | self.EnableGroup(GROUP_CONTROLS) | |
276 | # Special case for notebook (always executed) | |
277 | if state == STATE_ELSE: | |
278 | if xxx.__class__ == xxxNotebook: | |
279 | self.EnableGroup(GROUP_SIZERS, False) | |
280 | else: | |
281 | self.EnableGroup(GROUP_SIZERS) | |
282 | if not (xxx.isSizer or xxx.parent and xxx.parent.isSizer): | |
283 | self.EnableGroupItem(GROUP_SIZERS, ID_NEW.SPACER, False) | |
284 | # Save state | |
285 | self.state = state |