Mercurial > traipse_dev
comparison orpg/gametree/nodehandlers/rpg_grid.py @ 0:4385a7d0efd1 grumpy-goblin
Deleted and repushed it with the 'grumpy-goblin' branch. I forgot a y
author | sirebral |
---|---|
date | Tue, 14 Jul 2009 16:41:58 -0500 |
parents | |
children | 449a8900f9ac |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4385a7d0efd1 |
---|---|
1 # Copyright (C) 2000-2001 The OpenRPG Project | |
2 # | |
3 # openrpg-dev@lists.sourceforge.net | |
4 # | |
5 # This program is free software; you can redistribute it and/or modify | |
6 # it under the terms of the GNU General Public License as published by | |
7 # the Free Software Foundation; either version 2 of the License, or | |
8 # (at your option) any later version. | |
9 # | |
10 # This program is distributed in the hope that it will be useful, | |
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 # GNU General Public License for more details. | |
14 # | |
15 # You should have received a copy of the GNU General Public License | |
16 # along with this program; if not, write to the Free Software | |
17 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
18 # -- | |
19 # | |
20 # File: rpg_grid.py | |
21 # Author: Chris Davis | |
22 # Maintainer: | |
23 # Version: | |
24 # $Id: rpg_grid.py,v 1.20 2006/11/15 12:11:24 digitalxero Exp $ | |
25 # | |
26 # Description: The file contains code for the grid nodehanlers | |
27 # | |
28 | |
29 __version__ = "$Id: rpg_grid.py,v 1.20 2006/11/15 12:11:24 digitalxero Exp $" | |
30 | |
31 from core import * | |
32 from forms import * | |
33 | |
34 class rpg_grid_handler(node_handler): | |
35 """ Node handler for rpg grid tool | |
36 <nodehandler module='rpg_grid' class='rpg_grid_handler' name='sample'> | |
37 <grid border='' autosize='1' > | |
38 <row> | |
39 <cell size='?'></cell> | |
40 <cell></cell> | |
41 </row> | |
42 <row> | |
43 <cell></cell> | |
44 <cell></cell> | |
45 </row> | |
46 </grid> | |
47 <macros> | |
48 <macro name=''/> | |
49 </macros> | |
50 </nodehandler> | |
51 """ | |
52 def __init__(self,xml_dom,tree_node): | |
53 node_handler.__init__(self,xml_dom,tree_node) | |
54 self.grid = self.master_dom.getElementsByTagName('grid')[0] | |
55 if self.grid.getAttribute("border") == "": | |
56 self.grid.setAttribute("border","1") | |
57 if self.grid.getAttribute("autosize") == "": | |
58 self.grid.setAttribute("autosize","1") | |
59 self.macros = self.master_dom.getElementsByTagName('macros')[0] | |
60 self.myeditor = None | |
61 self.refresh_rows() | |
62 | |
63 def refresh_die_macros(self): | |
64 pass | |
65 | |
66 def refresh_rows(self): | |
67 self.rows = {} | |
68 tree = self.tree | |
69 icons = self.tree.icons | |
70 tree.CollapseAndReset(self.mytree_node) | |
71 node_list = self.master_dom.getElementsByTagName('row') | |
72 for n in node_list: | |
73 cells = n.getElementsByTagName('cell') | |
74 t_node = cells[0]._get_firstChild() | |
75 if t_node == None: | |
76 name = "Row" | |
77 else: | |
78 name = t_node._get_nodeValue() | |
79 if name == "": | |
80 name = "Row" | |
81 new_tree_node = tree.AppendItem(self.mytree_node,name,icons['gear'],icons['gear']) | |
82 handler = grid_row_handler(n,new_tree_node,self) | |
83 tree.SetPyData(new_tree_node,handler) | |
84 | |
85 | |
86 def tohtml(self): | |
87 border = self.grid.getAttribute("border") | |
88 name = self.master_dom.getAttribute('name') | |
89 rows = self.grid.getElementsByTagName('row') | |
90 colspan = str(len(rows[0].getElementsByTagName('cell'))) | |
91 html_str = "<table border=\""+border+"\" align=center><tr bgcolor=\""+TH_BG+"\" ><th colspan="+colspan+">"+name+"</th></tr>" | |
92 for r in rows: | |
93 cells = r.getElementsByTagName('cell') | |
94 html_str += "<tr>" | |
95 for c in cells: | |
96 #html_str += "<td width='"+c.getAttribute('size')+"' >" bug here | |
97 html_str += "<td >" | |
98 t_node = c._get_firstChild() | |
99 if t_node == None: | |
100 html_str += "<br /></td>" | |
101 else: | |
102 html_str += t_node._get_nodeValue() + "</td>" | |
103 html_str += "</tr>" | |
104 html_str += "</table>" | |
105 return html_str | |
106 | |
107 def get_design_panel(self,parent): | |
108 return rpg_grid_edit_panel(parent,self) | |
109 | |
110 def get_use_panel(self,parent): | |
111 return rpg_grid_panel(parent,self) | |
112 | |
113 def get_size_constraint(self): | |
114 return 1 | |
115 | |
116 def is_autosized(self): | |
117 return self.grid.getAttribute("autosize") | |
118 | |
119 def set_autosize(self,autosize=1): | |
120 self.grid.setAttribute("autosize",str(autosize)) | |
121 | |
122 class grid_row_handler(node_handler): | |
123 """ Node Handler grid row. | |
124 """ | |
125 def __init__(self,xml_dom,tree_node,parent): | |
126 node_handler.__init__(self,xml_dom,tree_node) | |
127 self.drag = False | |
128 | |
129 def on_drop(self,evt): | |
130 pass | |
131 | |
132 def can_clone(self): | |
133 return 0; | |
134 | |
135 def tohtml(self): | |
136 cells = self.master_dom.getElementsByTagName('cell') | |
137 html_str = "<table border=1 align=center><tr >" | |
138 for c in cells: | |
139 html_str += "<td >" | |
140 t_node = c._get_firstChild() | |
141 if t_node == None: | |
142 html_str += "<br /></td>" | |
143 else: | |
144 html_str += t_node._get_nodeValue() + "</td>" | |
145 html_str += "</tr>" | |
146 html_str += "</table>" | |
147 return html_str | |
148 | |
149 class MyCellEditor(wx.grid.PyGridCellEditor): | |
150 """ | |
151 This is a sample GridCellEditor that shows you how to make your own custom | |
152 grid editors. All the methods that can be overridden are show here. The | |
153 ones that must be overridden are marked with "*Must Override*" in the | |
154 docstring. | |
155 | |
156 Notice that in order to call the base class version of these special | |
157 methods we use the method name preceded by "base_". This is because these | |
158 methods are "virtual" in C++ so if we try to call wxGridCellEditor.Create | |
159 for example, then when the wxPython extension module tries to call | |
160 ptr->Create(...) then it actually calls the derived class version which | |
161 looks up the method in this class and calls it, causing a recursion loop. | |
162 If you don't understand any of this, don't worry, just call the "base_" | |
163 version instead. | |
164 | |
165 ---------------------------------------------------------------------------- | |
166 This class is copied from the wxPython examples directory and was written by | |
167 Robin Dunn. | |
168 | |
169 I have pasted it directly in and removed all references to "log" | |
170 | |
171 -- Andrew | |
172 | |
173 """ | |
174 def __init__(self): | |
175 wx.grid.PyGridCellEditor.__init__(self) | |
176 | |
177 | |
178 def Create(self, parent, id, evtHandler): | |
179 """ | |
180 Called to create the control, which must derive from wxControl. | |
181 *Must Override* | |
182 """ | |
183 self._tc = wx.TextCtrl(parent, id, "", style=wx.TE_PROCESS_ENTER | wx.TE_PROCESS_TAB) | |
184 self._tc.SetInsertionPoint(0) | |
185 self.SetControl(self._tc) | |
186 if evtHandler: | |
187 self._tc.PushEventHandler(evtHandler) | |
188 | |
189 | |
190 def SetSize(self, rect): | |
191 """ | |
192 Called to position/size the edit control within the cell rectangle. | |
193 If you don't fill the cell (the rect) then be sure to override | |
194 PaintBackground and do something meaningful there. | |
195 """ | |
196 self._tc.SetDimensions(rect.x+1, rect.y+1, rect.width+2, rect.height+2) | |
197 | |
198 | |
199 def Show(self, show, attr): | |
200 """ | |
201 Show or hide the edit control. You can use the attr (if not None) | |
202 to set colours or fonts for the control. | |
203 """ | |
204 self.base_Show(show, attr) | |
205 | |
206 | |
207 def BeginEdit(self, row, col, grid): | |
208 """ | |
209 Fetch the value from the table and prepare the edit control | |
210 to begin editing. Set the focus to the edit control. | |
211 *Must Override* | |
212 """ | |
213 self.startValue = grid.GetTable().GetValue(row, col) | |
214 self._tc.SetValue(self.startValue) | |
215 self._tc.SetInsertionPointEnd() | |
216 self._tc.SetFocus() | |
217 | |
218 # For this example, select the text | |
219 self._tc.SetSelection(0, self._tc.GetLastPosition()) | |
220 | |
221 | |
222 def EndEdit(self, row, col, grid): | |
223 """ | |
224 Complete the editing of the current cell. Returns True if the value | |
225 has changed. If necessary, the control may be destroyed. | |
226 *Must Override* | |
227 """ | |
228 changed = False | |
229 | |
230 val = self._tc.GetValue() | |
231 if val != self.startValue: | |
232 changed = True | |
233 grid.GetTable().SetValue(row, col, val) # update the table | |
234 | |
235 self.startValue = '' | |
236 self._tc.SetValue('') | |
237 return changed | |
238 | |
239 | |
240 def Reset(self): | |
241 """ | |
242 Reset the value in the control back to its starting value. | |
243 *Must Override* | |
244 """ | |
245 self._tc.SetValue(self.startValue) | |
246 self._tc.SetInsertionPointEnd() | |
247 | |
248 | |
249 def IsAcceptedKey(self, evt): | |
250 """ | |
251 Return True to allow the given key to start editing: the base class | |
252 version only checks that the event has no modifiers. F2 is special | |
253 and will always start the editor. | |
254 """ | |
255 | |
256 ## Oops, there's a bug here, we'll have to do it ourself.. | |
257 ##return self.base_IsAcceptedKey(evt) | |
258 | |
259 return (not (evt.ControlDown() or evt.AltDown()) and | |
260 evt.GetKeyCode() != wx.WXK_SHIFT) | |
261 | |
262 | |
263 def StartingKey(self, evt): | |
264 """ | |
265 If the editor is enabled by pressing keys on the grid, this will be | |
266 called to let the editor do something about that first key if desired. | |
267 """ | |
268 key = evt.GetKeyCode() | |
269 ch = None | |
270 if key in [wx.WXK_NUMPAD0, wx.WXK_NUMPAD1, wx.WXK_NUMPAD2, wx.WXK_NUMPAD3, wx.WXK_NUMPAD4, | |
271 wx.WXK_NUMPAD5, wx.WXK_NUMPAD6, wx.WXK_NUMPAD7, wx.WXK_NUMPAD8, wx.WXK_NUMPAD9]: | |
272 ch = ch = chr(ord('0') + key - wx.WXK_NUMPAD0) | |
273 | |
274 elif key < 256 and key >= 0 and chr(key) in string.printable: | |
275 ch = chr(key) | |
276 if not evt.ShiftDown(): | |
277 ch = string.lower(ch) | |
278 | |
279 if ch is not None: | |
280 # For this example, replace the text. Normally we would append it. | |
281 self._tc.AppendText(ch) | |
282 else: | |
283 evt.Skip() | |
284 | |
285 | |
286 | |
287 def Destroy(self): | |
288 """final cleanup""" | |
289 self.base_Destroy() | |
290 | |
291 | |
292 def Clone(self): | |
293 """ | |
294 Create a new object which is the copy of this one | |
295 *Must Override* | |
296 """ | |
297 return MyCellEditor() | |
298 | |
299 | |
300 | |
301 class rpg_grid(wx.grid.Grid): | |
302 """grid for attacks""" | |
303 def __init__(self, parent, handler): | |
304 wx.grid.Grid.__init__(self, parent, -1, style=wx.SUNKEN_BORDER | wx.WANTS_CHARS) | |
305 self.parent = parent | |
306 self.handler = handler | |
307 | |
308 # Registers a "custom" cell editor (really the example from Robin Dunn with minor mods | |
309 self.RegisterDataType(wx.grid.GRID_VALUE_STRING, wx.grid.GridCellStringRenderer(),MyCellEditor()) | |
310 | |
311 self.rows = handler.grid.getElementsByTagName('row') | |
312 rows = len(self.rows) | |
313 cols = len(self.rows[0].getElementsByTagName('cell')) | |
314 self.CreateGrid(rows,cols) | |
315 self.SetRowLabelSize(0) | |
316 self.SetColLabelSize(0) | |
317 self.set_col_widths() | |
318 | |
319 for i in range(0,len(self.rows)): | |
320 self.refresh_row(i) | |
321 | |
322 self.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.on_cell_change) | |
323 self.Bind(wx.grid.EVT_GRID_COL_SIZE, self.on_col_size) | |
324 self.Bind(wx.grid.EVT_GRID_CELL_LEFT_DCLICK, self.on_leftdclick) | |
325 | |
326 | |
327 def on_leftdclick(self,evt): | |
328 if self.CanEnableCellControl(): | |
329 self.EnableCellEditControl() | |
330 | |
331 def on_col_size(self, evt): | |
332 col = evt.GetRowOrCol() | |
333 cells = self.rows[0].getElementsByTagName('cell') | |
334 size = self.GetColSize(col) | |
335 cells[col].setAttribute('size',str(size)) | |
336 evt.Skip() | |
337 | |
338 def on_cell_change(self,evt): | |
339 row = evt.GetRow() | |
340 col = evt.GetCol() | |
341 value = self.GetCellValue(row,col) | |
342 cells = self.rows[row].getElementsByTagName('cell') | |
343 t_node = cells[col]._get_firstChild() | |
344 print t_node | |
345 t_node._set_nodeValue(value) | |
346 if col == 0: | |
347 self.handler.refresh_rows() | |
348 | |
349 def set_col_widths(self): | |
350 cells = self.rows[0].getElementsByTagName('cell') | |
351 for i in range(0,len(cells)): | |
352 try: | |
353 size = int(cells[i].getAttribute('size')) | |
354 self.SetColSize(i,size) | |
355 except: | |
356 continue | |
357 | |
358 def refresh_row(self,rowi): | |
359 cells = self.rows[rowi].getElementsByTagName('cell') | |
360 for i in range(0,len(cells)): | |
361 t_node = cells[i]._get_firstChild() | |
362 if t_node == None: | |
363 #doc = cells[i].ownerDocument | |
364 #t_node = doc.createTextNode("") | |
365 t_node = minidom.Text("") | |
366 t_node = cells[i].appendChild(t_node) | |
367 self.SetCellValue(rowi,i,t_node._get_nodeValue()) | |
368 | |
369 def add_row(self,evt=None): | |
370 cols = self.GetNumberCols() | |
371 #doc = self.handler.grid.ownerDocument | |
372 #row = doc.createElement('row') | |
373 row = minidom.Element('row') | |
374 for i in range(0,cols): | |
375 #cell = doc.createElement('cell') | |
376 cell = minidom.Element('cell') | |
377 #t_node = doc.createTextNode("") | |
378 t_node = minidom.Text("") | |
379 t_node = cell.appendChild(t_node) | |
380 row.appendChild(cell) | |
381 self.handler.grid.appendChild(row) | |
382 self.AppendRows(1) | |
383 self.rows = self.handler.grid.getElementsByTagName('row') | |
384 self.handler.refresh_rows() | |
385 | |
386 def add_col(self,evt=None): | |
387 #doc = self.handler.grid.ownerDocument | |
388 for r in self.rows: | |
389 #cell = doc.createElement('cell') | |
390 cell = minidom.Element('cell') | |
391 #t_node = doc.createTextNode("") | |
392 t_node = minidom.Text("") | |
393 t_node = cell.appendChild(t_node) | |
394 r.appendChild(cell) | |
395 self.AppendCols(1) | |
396 self.fit_cols() | |
397 | |
398 | |
399 def del_row(self,evt=None): | |
400 num = self.GetNumberRows() | |
401 row = self.rows[num-1] | |
402 self.handler.grid.removeChild(row) | |
403 self.DeleteRows(num-1,1) | |
404 self.rows = self.handler.grid.getElementsByTagName('row') | |
405 self.handler.refresh_rows() | |
406 | |
407 def del_col(self,evt=None): | |
408 num = self.GetNumberCols() | |
409 for r in self.rows: | |
410 cells = r.getElementsByTagName('cell') | |
411 r.removeChild(cells[num-1]) | |
412 self.DeleteCols(num-1,1) | |
413 self.fit_cols() | |
414 | |
415 | |
416 G_TITLE = wx.NewId() | |
417 GRID_BOR = wx.NewId() | |
418 class rpg_grid_panel(wx.Panel): | |
419 def __init__(self, parent, handler): | |
420 wx.Panel.__init__(self, parent, -1) | |
421 self.handler = handler | |
422 self.grid = rpg_grid(self,handler) | |
423 label = handler.master_dom.getAttribute('name') | |
424 self.main_sizer = wx.BoxSizer(wx.VERTICAL) | |
425 self.main_sizer.Add(wx.StaticText(self, -1, label+": "), 0, wx.EXPAND) | |
426 self.main_sizer.Add(self.grid,1,wx.EXPAND) | |
427 self.SetSizer(self.main_sizer) | |
428 self.SetAutoLayout(True) | |
429 self.Fit() | |
430 parent.SetSize(self.GetBestSize()) | |
431 | |
432 | |
433 G_AUTO_SIZE = wx.NewId() | |
434 G_ADD_ROW = wx.NewId() | |
435 G_ADD_COL = wx.NewId() | |
436 G_DEL_ROW = wx.NewId() | |
437 G_DEL_COL = wx.NewId() | |
438 | |
439 class rpg_grid_edit_panel(wx.Panel): | |
440 def __init__(self, parent, handler): | |
441 wx.Panel.__init__(self, parent, -1) | |
442 self.handler = handler | |
443 self.grid = rpg_grid(self,handler) | |
444 self.title = wx.TextCtrl(self, G_TITLE, handler.master_dom.getAttribute('name')) | |
445 | |
446 radio_b = wx.RadioBox(self, GRID_BOR, "Border (HTML)", choices=["no","yes"]) | |
447 border = handler.grid.getAttribute("border") | |
448 radio_b.SetSelection(int(border)) | |
449 | |
450 self.auto_size = wx.CheckBox(self, G_AUTO_SIZE, " Auto Size") | |
451 if handler.is_autosized() == '1': | |
452 self.auto_size.SetValue(True) | |
453 else: | |
454 self.auto_size.SetValue(False) | |
455 | |
456 sizer = wx.BoxSizer(wx.HORIZONTAL) | |
457 sizer.Add(wx.Button(self, G_ADD_ROW, "Add Row"), 1, wx.EXPAND) | |
458 sizer.Add(wx.Size(10,10)) | |
459 sizer.Add(wx.Button(self, G_DEL_ROW, "Remove Row"), 1, wx.EXPAND) | |
460 sizer.Add(wx.Size(10,10)) | |
461 sizer.Add(wx.Button(self, G_ADD_COL, "Add Column"), 1, wx.EXPAND) | |
462 sizer.Add(wx.Size(10,10)) | |
463 sizer.Add(wx.Button(self, G_DEL_COL, "Remove Column"), 1, wx.EXPAND) | |
464 | |
465 self.main_sizer = wx.StaticBoxSizer(wx.StaticBox(self,-1,"Grid"), wx.VERTICAL) | |
466 self.main_sizer.Add(wx.StaticText(self, -1, "Title:"), 0, wx.EXPAND) | |
467 self.main_sizer.Add(self.title, 0, wx.EXPAND) | |
468 self.main_sizer.Add(radio_b, 0, 0) | |
469 self.main_sizer.Add(self.auto_size, 0, 0) | |
470 self.main_sizer.Add(self.grid,1,wx.EXPAND) | |
471 self.main_sizer.Add(sizer,0,wx.EXPAND) | |
472 | |
473 self.SetSizer(self.main_sizer) | |
474 self.SetAutoLayout(True) | |
475 self.Fit() | |
476 | |
477 self.Bind(wx.EVT_TEXT, self.on_text, id=G_TITLE) | |
478 self.Bind(wx.EVT_BUTTON, self.grid.add_row, id=G_ADD_ROW) | |
479 self.Bind(wx.EVT_BUTTON, self.grid.del_row, id=G_DEL_ROW) | |
480 self.Bind(wx.EVT_BUTTON, self.grid.add_col, id=G_ADD_COL) | |
481 self.Bind(wx.EVT_BUTTON, self.grid.del_col, id=G_DEL_COL) | |
482 self.Bind(wx.EVT_RADIOBOX, self.on_radio_box, id=GRID_BOR) | |
483 self.Bind(wx.EVT_CHECKBOX, self.on_auto_size, id=G_AUTO_SIZE) | |
484 | |
485 def on_auto_size(self,evt): | |
486 self.handler.set_autosize(bool2int(evt.Checked())) | |
487 | |
488 def on_radio_box(self,evt): | |
489 id = evt.GetId() | |
490 index = evt.GetInt() | |
491 if id == GRID_BOR: | |
492 self.handler.grid.setAttribute("border",str(index)) | |
493 | |
494 def on_text(self,evt): | |
495 txt = self.title.GetValue() | |
496 if txt != "": | |
497 self.handler.master_dom.setAttribute('name',txt) | |
498 self.handler.rename(txt) |