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)