diff 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 97265586402b
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/orpg/gametree/nodehandlers/rpg_grid.py	Tue Jul 14 16:41:58 2009 -0500
@@ -0,0 +1,498 @@
+# Copyright (C) 2000-2001 The OpenRPG Project
+#
+#        openrpg-dev@lists.sourceforge.net
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+# --
+#
+# File: rpg_grid.py
+# Author: Chris Davis
+# Maintainer:
+# Version:
+#   $Id: rpg_grid.py,v 1.20 2006/11/15 12:11:24 digitalxero Exp $
+#
+# Description: The file contains code for the grid nodehanlers
+#
+
+__version__ = "$Id: rpg_grid.py,v 1.20 2006/11/15 12:11:24 digitalxero Exp $"
+
+from core import *
+from forms import *
+
+class rpg_grid_handler(node_handler):
+    """ Node handler for rpg grid tool
+<nodehandler module='rpg_grid' class='rpg_grid_handler' name='sample'>
+  <grid border='' autosize='1' >
+    <row>
+      <cell size='?'></cell>
+      <cell></cell>
+    </row>
+    <row>
+      <cell></cell>
+      <cell></cell>
+    </row>
+  </grid>
+  <macros>
+    <macro name=''/>
+  </macros>
+</nodehandler>
+    """
+    def __init__(self,xml_dom,tree_node):
+        node_handler.__init__(self,xml_dom,tree_node)
+        self.grid = self.master_dom.getElementsByTagName('grid')[0]
+        if self.grid.getAttribute("border") == "":
+            self.grid.setAttribute("border","1")
+        if self.grid.getAttribute("autosize") == "":
+            self.grid.setAttribute("autosize","1")
+        self.macros = self.master_dom.getElementsByTagName('macros')[0]
+        self.myeditor = None
+        self.refresh_rows()
+
+    def refresh_die_macros(self):
+        pass
+
+    def refresh_rows(self):
+        self.rows = {}
+        tree = self.tree
+        icons = self.tree.icons
+        tree.CollapseAndReset(self.mytree_node)
+        node_list = self.master_dom.getElementsByTagName('row')
+        for n in node_list:
+            cells = n.getElementsByTagName('cell')
+            t_node = cells[0]._get_firstChild()
+            if t_node == None:
+                name = "Row"
+            else:
+                name = t_node._get_nodeValue()
+            if name == "":
+                name = "Row"
+            new_tree_node = tree.AppendItem(self.mytree_node,name,icons['gear'],icons['gear'])
+            handler = grid_row_handler(n,new_tree_node,self)
+            tree.SetPyData(new_tree_node,handler)
+
+
+    def tohtml(self):
+        border = self.grid.getAttribute("border")
+        name = self.master_dom.getAttribute('name')
+        rows = self.grid.getElementsByTagName('row')
+        colspan = str(len(rows[0].getElementsByTagName('cell')))
+        html_str = "<table border=\""+border+"\" align=center><tr bgcolor=\""+TH_BG+"\" ><th colspan="+colspan+">"+name+"</th></tr>"
+        for r in rows:
+            cells = r.getElementsByTagName('cell')
+            html_str += "<tr>"
+            for c in cells:
+                #html_str += "<td width='"+c.getAttribute('size')+"' >" bug here
+                html_str += "<td >"
+                t_node = c._get_firstChild()
+                if t_node == None:
+                    html_str += "<br /></td>"
+                else:
+                    html_str += t_node._get_nodeValue() + "</td>"
+            html_str += "</tr>"
+        html_str += "</table>"
+        return html_str
+
+    def get_design_panel(self,parent):
+        return rpg_grid_edit_panel(parent,self)
+
+    def get_use_panel(self,parent):
+        return rpg_grid_panel(parent,self)
+
+    def get_size_constraint(self):
+        return 1
+
+    def is_autosized(self):
+        return self.grid.getAttribute("autosize")
+
+    def set_autosize(self,autosize=1):
+        self.grid.setAttribute("autosize",str(autosize))
+
+class grid_row_handler(node_handler):
+    """ Node Handler grid row.
+    """
+    def __init__(self,xml_dom,tree_node,parent):
+        node_handler.__init__(self,xml_dom,tree_node)
+        self.drag = False
+
+    def on_drop(self,evt):
+        pass
+
+    def can_clone(self):
+        return 0;
+
+    def tohtml(self):
+        cells = self.master_dom.getElementsByTagName('cell')
+        html_str = "<table border=1 align=center><tr >"
+        for c in cells:
+            html_str += "<td >"
+            t_node = c._get_firstChild()
+            if t_node == None:
+                html_str += "<br /></td>"
+            else:
+                html_str += t_node._get_nodeValue() + "</td>"
+            html_str += "</tr>"
+        html_str += "</table>"
+        return html_str
+
+class MyCellEditor(wx.grid.PyGridCellEditor):
+    """
+    This is a sample GridCellEditor that shows you how to make your own custom
+    grid editors.  All the methods that can be overridden are show here.  The
+    ones that must be overridden are marked with "*Must Override*" in the
+    docstring.
+
+    Notice that in order to call the base class version of these special
+    methods we use the method name preceded by "base_".  This is because these
+    methods are "virtual" in C++ so if we try to call wxGridCellEditor.Create
+    for example, then when the wxPython extension module tries to call
+    ptr->Create(...) then it actually calls the derived class version which
+    looks up the method in this class and calls it, causing a recursion loop.
+    If you don't understand any of this, don't worry, just call the "base_"
+    version instead.
+
+    ----------------------------------------------------------------------------
+    This class is copied from the wxPython examples directory and was written by
+    Robin Dunn.
+
+    I have pasted it directly in and removed all references to "log"
+
+    -- Andrew
+
+    """
+    def __init__(self):
+        wx.grid.PyGridCellEditor.__init__(self)
+
+
+    def Create(self, parent, id, evtHandler):
+        """
+        Called to create the control, which must derive from wxControl.
+        *Must Override*
+        """
+        self._tc = wx.TextCtrl(parent, id, "", style=wx.TE_PROCESS_ENTER | wx.TE_PROCESS_TAB)
+        self._tc.SetInsertionPoint(0)
+        self.SetControl(self._tc)
+        if evtHandler:
+            self._tc.PushEventHandler(evtHandler)
+
+
+    def SetSize(self, rect):
+        """
+        Called to position/size the edit control within the cell rectangle.
+        If you don't fill the cell (the rect) then be sure to override
+        PaintBackground and do something meaningful there.
+        """
+        self._tc.SetDimensions(rect.x+1, rect.y+1, rect.width+2, rect.height+2)
+
+
+    def Show(self, show, attr):
+        """
+        Show or hide the edit control.  You can use the attr (if not None)
+        to set colours or fonts for the control.
+        """
+        self.base_Show(show, attr)
+
+
+    def BeginEdit(self, row, col, grid):
+        """
+        Fetch the value from the table and prepare the edit control
+        to begin editing.  Set the focus to the edit control.
+        *Must Override*
+        """
+        self.startValue = grid.GetTable().GetValue(row, col)
+        self._tc.SetValue(self.startValue)
+        self._tc.SetInsertionPointEnd()
+        self._tc.SetFocus()
+
+        # For this example, select the text
+        self._tc.SetSelection(0, self._tc.GetLastPosition())
+
+
+    def EndEdit(self, row, col, grid):
+        """
+        Complete the editing of the current cell. Returns True if the value
+        has changed.  If necessary, the control may be destroyed.
+        *Must Override*
+        """
+        changed = False
+
+        val = self._tc.GetValue()
+        if val != self.startValue:
+            changed = True
+            grid.GetTable().SetValue(row, col, val) # update the table
+
+        self.startValue = ''
+        self._tc.SetValue('')
+        return changed
+
+
+    def Reset(self):
+        """
+        Reset the value in the control back to its starting value.
+        *Must Override*
+        """
+        self._tc.SetValue(self.startValue)
+        self._tc.SetInsertionPointEnd()
+
+
+    def IsAcceptedKey(self, evt):
+        """
+        Return True to allow the given key to start editing: the base class
+        version only checks that the event has no modifiers.  F2 is special
+        and will always start the editor.
+        """
+
+        ## Oops, there's a bug here, we'll have to do it ourself..
+        ##return self.base_IsAcceptedKey(evt)
+
+        return (not (evt.ControlDown() or evt.AltDown()) and
+                evt.GetKeyCode() != wx.WXK_SHIFT)
+
+
+    def StartingKey(self, evt):
+        """
+        If the editor is enabled by pressing keys on the grid, this will be
+        called to let the editor do something about that first key if desired.
+        """
+        key = evt.GetKeyCode()
+        ch = None
+        if key in [wx.WXK_NUMPAD0, wx.WXK_NUMPAD1, wx.WXK_NUMPAD2, wx.WXK_NUMPAD3, wx.WXK_NUMPAD4,
+                   wx.WXK_NUMPAD5, wx.WXK_NUMPAD6, wx.WXK_NUMPAD7, wx.WXK_NUMPAD8, wx.WXK_NUMPAD9]:
+            ch = ch = chr(ord('0') + key - wx.WXK_NUMPAD0)
+
+        elif key < 256 and key >= 0 and chr(key) in string.printable:
+            ch = chr(key)
+            if not evt.ShiftDown():
+                ch = string.lower(ch)
+
+        if ch is not None:
+            # For this example, replace the text.  Normally we would append it.
+            self._tc.AppendText(ch)
+        else:
+            evt.Skip()
+
+
+
+    def Destroy(self):
+        """final cleanup"""
+        self.base_Destroy()
+
+
+    def Clone(self):
+        """
+        Create a new object which is the copy of this one
+        *Must Override*
+        """
+        return MyCellEditor()
+
+
+
+class rpg_grid(wx.grid.Grid):
+    """grid for attacks"""
+    def __init__(self, parent, handler):
+        wx.grid.Grid.__init__(self, parent, -1, style=wx.SUNKEN_BORDER | wx.WANTS_CHARS)
+        self.parent = parent
+        self.handler = handler
+
+        #  Registers a "custom" cell editor (really the example from Robin Dunn with minor mods
+        self.RegisterDataType(wx.grid.GRID_VALUE_STRING, wx.grid.GridCellStringRenderer(),MyCellEditor())
+
+        self.rows = handler.grid.getElementsByTagName('row')
+        rows = len(self.rows)
+        cols = len(self.rows[0].getElementsByTagName('cell'))
+        self.CreateGrid(rows,cols)
+        self.SetRowLabelSize(0)
+        self.SetColLabelSize(0)
+        self.set_col_widths()
+
+        for i in range(0,len(self.rows)):
+            self.refresh_row(i)
+
+        self.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.on_cell_change)
+        self.Bind(wx.grid.EVT_GRID_COL_SIZE, self.on_col_size)
+        self.Bind(wx.grid.EVT_GRID_CELL_LEFT_DCLICK, self.on_leftdclick)
+
+
+    def on_leftdclick(self,evt):
+        if self.CanEnableCellControl():
+            self.EnableCellEditControl()
+
+    def on_col_size(self, evt):
+        col = evt.GetRowOrCol()
+        cells = self.rows[0].getElementsByTagName('cell')
+        size = self.GetColSize(col)
+        cells[col].setAttribute('size',str(size))
+        evt.Skip()
+
+    def on_cell_change(self,evt):
+        row = evt.GetRow()
+        col = evt.GetCol()
+        value = self.GetCellValue(row,col)
+        cells = self.rows[row].getElementsByTagName('cell')
+        t_node = cells[col]._get_firstChild()
+        print t_node
+        t_node._set_nodeValue(value)
+        if col == 0:
+            self.handler.refresh_rows()
+
+    def set_col_widths(self):
+        cells = self.rows[0].getElementsByTagName('cell')
+        for i in range(0,len(cells)):
+            try:
+                size = int(cells[i].getAttribute('size'))
+                self.SetColSize(i,size)
+            except:
+                continue
+
+    def refresh_row(self,rowi):
+        cells = self.rows[rowi].getElementsByTagName('cell')
+        for i in range(0,len(cells)):
+            t_node = cells[i]._get_firstChild()
+            if t_node == None:
+                #doc = cells[i].ownerDocument
+                #t_node = doc.createTextNode("")
+                t_node = minidom.Text("")
+                t_node = cells[i].appendChild(t_node)
+            self.SetCellValue(rowi,i,t_node._get_nodeValue())
+
+    def add_row(self,evt=None):
+        cols = self.GetNumberCols()
+        #doc = self.handler.grid.ownerDocument
+        #row = doc.createElement('row')
+        row = minidom.Element('row')
+        for i in range(0,cols):
+            #cell = doc.createElement('cell')
+            cell = minidom.Element('cell')
+            #t_node = doc.createTextNode("")
+            t_node = minidom.Text("")
+            t_node = cell.appendChild(t_node)
+            row.appendChild(cell)
+        self.handler.grid.appendChild(row)
+        self.AppendRows(1)
+        self.rows = self.handler.grid.getElementsByTagName('row')
+        self.handler.refresh_rows()
+
+    def add_col(self,evt=None):
+        #doc = self.handler.grid.ownerDocument
+        for r in self.rows:
+            #cell = doc.createElement('cell')
+            cell = minidom.Element('cell')
+            #t_node = doc.createTextNode("")
+            t_node = minidom.Text("")
+            t_node = cell.appendChild(t_node)
+            r.appendChild(cell)
+        self.AppendCols(1)
+        self.fit_cols()
+
+
+    def del_row(self,evt=None):
+        num = self.GetNumberRows()
+        row = self.rows[num-1]
+        self.handler.grid.removeChild(row)
+        self.DeleteRows(num-1,1)
+        self.rows = self.handler.grid.getElementsByTagName('row')
+        self.handler.refresh_rows()
+
+    def del_col(self,evt=None):
+        num = self.GetNumberCols()
+        for r in self.rows:
+            cells = r.getElementsByTagName('cell')
+            r.removeChild(cells[num-1])
+        self.DeleteCols(num-1,1)
+        self.fit_cols()
+
+
+G_TITLE = wx.NewId()
+GRID_BOR = wx.NewId()
+class rpg_grid_panel(wx.Panel):
+    def __init__(self, parent, handler):
+        wx.Panel.__init__(self, parent, -1)
+        self.handler = handler
+        self.grid = rpg_grid(self,handler)
+        label = handler.master_dom.getAttribute('name')
+        self.main_sizer = wx.BoxSizer(wx.VERTICAL)
+        self.main_sizer.Add(wx.StaticText(self, -1, label+": "), 0, wx.EXPAND)
+        self.main_sizer.Add(self.grid,1,wx.EXPAND)
+        self.SetSizer(self.main_sizer)
+        self.SetAutoLayout(True)
+        self.Fit()
+        parent.SetSize(self.GetBestSize())
+
+
+G_AUTO_SIZE = wx.NewId()
+G_ADD_ROW = wx.NewId()
+G_ADD_COL = wx.NewId()
+G_DEL_ROW = wx.NewId()
+G_DEL_COL = wx.NewId()
+
+class rpg_grid_edit_panel(wx.Panel):
+    def __init__(self, parent, handler):
+        wx.Panel.__init__(self, parent, -1)
+        self.handler = handler
+        self.grid = rpg_grid(self,handler)
+        self.title = wx.TextCtrl(self, G_TITLE, handler.master_dom.getAttribute('name'))
+
+        radio_b = wx.RadioBox(self, GRID_BOR, "Border (HTML)", choices=["no","yes"])
+        border = handler.grid.getAttribute("border")
+        radio_b.SetSelection(int(border))
+
+        self.auto_size = wx.CheckBox(self, G_AUTO_SIZE, " Auto Size")
+        if handler.is_autosized() == '1':
+            self.auto_size.SetValue(True)
+        else:
+            self.auto_size.SetValue(False)
+
+        sizer = wx.BoxSizer(wx.HORIZONTAL)
+        sizer.Add(wx.Button(self, G_ADD_ROW, "Add Row"), 1, wx.EXPAND)
+        sizer.Add(wx.Size(10,10))
+        sizer.Add(wx.Button(self, G_DEL_ROW, "Remove Row"), 1, wx.EXPAND)
+        sizer.Add(wx.Size(10,10))
+        sizer.Add(wx.Button(self, G_ADD_COL, "Add Column"), 1, wx.EXPAND)
+        sizer.Add(wx.Size(10,10))
+        sizer.Add(wx.Button(self, G_DEL_COL, "Remove Column"), 1, wx.EXPAND)
+
+        self.main_sizer = wx.StaticBoxSizer(wx.StaticBox(self,-1,"Grid"), wx.VERTICAL)
+        self.main_sizer.Add(wx.StaticText(self, -1, "Title:"), 0, wx.EXPAND)
+        self.main_sizer.Add(self.title, 0, wx.EXPAND)
+        self.main_sizer.Add(radio_b, 0, 0)
+        self.main_sizer.Add(self.auto_size, 0, 0)
+        self.main_sizer.Add(self.grid,1,wx.EXPAND)
+        self.main_sizer.Add(sizer,0,wx.EXPAND)
+
+        self.SetSizer(self.main_sizer)
+        self.SetAutoLayout(True)
+        self.Fit()
+
+        self.Bind(wx.EVT_TEXT, self.on_text, id=G_TITLE)
+        self.Bind(wx.EVT_BUTTON, self.grid.add_row, id=G_ADD_ROW)
+        self.Bind(wx.EVT_BUTTON, self.grid.del_row, id=G_DEL_ROW)
+        self.Bind(wx.EVT_BUTTON, self.grid.add_col, id=G_ADD_COL)
+        self.Bind(wx.EVT_BUTTON, self.grid.del_col, id=G_DEL_COL)
+        self.Bind(wx.EVT_RADIOBOX, self.on_radio_box, id=GRID_BOR)
+        self.Bind(wx.EVT_CHECKBOX, self.on_auto_size, id=G_AUTO_SIZE)
+
+    def on_auto_size(self,evt):
+        self.handler.set_autosize(bool2int(evt.Checked()))
+
+    def on_radio_box(self,evt):
+        id = evt.GetId()
+        index = evt.GetInt()
+        if id == GRID_BOR:
+            self.handler.grid.setAttribute("border",str(index))
+
+    def on_text(self,evt):
+        txt = self.title.GetValue()
+        if txt != "":
+            self.handler.master_dom.setAttribute('name',txt)
+            self.handler.rename(txt)