131
|
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: containers.py
|
|
21 # Author: Chris Davis
|
|
22 # Maintainer:
|
|
23 # Version:
|
|
24 # $Id: containers.py,v 1.43 2007/08/08 19:17:17 digitalxero Exp $
|
|
25 #
|
|
26 # Description: The file contains code for the container nodehandlers
|
|
27 #
|
|
28
|
|
29
|
|
30 from core import *
|
|
31 from wx.lib.splitter import MultiSplitterWindow
|
|
32
|
|
33
|
|
34 ##########################
|
|
35 ## base contiainer
|
|
36 ##########################
|
|
37
|
|
38 class container_handler(node_handler):
|
|
39 """ should not be used! only a base class!
|
|
40 <nodehandler name='?' module='core' class='container_handler' />
|
|
41 """
|
|
42 def __init__(self, xml, tree_node):
|
|
43 node_handler.__init__(self, xml, tree_node)
|
|
44 self.load_children()
|
|
45
|
|
46 def load_children(self):
|
|
47 for child_xml in self.xml:
|
|
48 self.tree.load_xml(child_xml,self.mytree_node)
|
|
49
|
|
50 def check_map_aware(self, treenode, evt):
|
|
51 node = self.tree.GetPyData(treenode)
|
|
52 if hasattr(node,"map_aware") and node.map_aware():
|
|
53 node.on_send_to_map(evt)
|
|
54
|
|
55 def on_send_to_map(self, evt):
|
|
56 self.tree.traverse(self.mytree_node, self.check_map_aware, evt)
|
|
57
|
|
58 def checkChildToMap(self, treenode, evt):
|
|
59 node = self.tree.GetPyData(treenode)
|
|
60 if hasattr(node,"map_aware") and node.map_aware():
|
|
61 self.mapcheck = True
|
|
62
|
|
63 def checkToMapMenu(self):
|
|
64 self.mapcheck = False
|
|
65 self.tree.traverse(self.mytree_node, self.checkChildToMap)
|
|
66 return self.mapcheck
|
|
67
|
|
68 def on_drop(self,evt):
|
|
69 drag_obj = self.tree.drag_obj
|
|
70 if drag_obj == self or self.tree.is_parent_node(self.mytree_node,drag_obj.mytree_node):
|
|
71 return
|
|
72 opt = wx.MessageBox("Add node as child?","Container Node",wx.YES_NO|wx.CANCEL)
|
|
73 if opt == wx.YES:
|
|
74 drop_xml = self.tree.drag_obj.delete()
|
|
75 self.xml.insert(0, drop_xml)
|
|
76 self.tree.load_xml(drop_xml, self.mytree_node)
|
|
77 self.tree.Expand(self.mytree_node)
|
|
78 elif opt == wx.NO:
|
|
79 node_handler.on_drop(self,evt)
|
|
80
|
|
81 def gen_html(self, treenode, evt):
|
|
82 node = self.tree.GetPyData(treenode)
|
|
83 self.html_str += "<p>" + node.tohtml()
|
|
84
|
|
85 def tohtml(self):
|
|
86 self.html_str = "<table border=\"1\" ><tr><td>"
|
|
87 self.html_str += "<b>"+self.xml.get("name") + "</b>"
|
|
88 self.html_str += "</td></tr>\n"
|
|
89 self.html_str += "<tr><td>"
|
|
90
|
|
91 self.tree.traverse(self.mytree_node, self.gen_html, recurse=False)
|
|
92
|
|
93 self.html_str += "</td></tr></table>"
|
|
94 return self.html_str
|
|
95
|
|
96 def get_size_constraint(self):
|
|
97 return 2
|
|
98
|
|
99
|
|
100 ##########################
|
|
101 ## group node handler
|
|
102 ##########################
|
|
103 class group_handler(container_handler):
|
|
104 """ group nodehandler to be used as a placeholder for other nodehandlers.
|
|
105 This handler will continue parsing child xml data.
|
|
106 <nodehandler name='?' module='core' class='group_handler' />
|
|
107 """
|
|
108 def __init__(self, xml, tree_node):
|
|
109 container_handler.__init__(self, xml, tree_node)
|
|
110
|
|
111 def load_children(self):
|
|
112 self.atts = None
|
|
113 for child_xml in self.xml:
|
|
114 if child_xml.get == "group_atts": #having the group attributes as a child is bad!
|
|
115 self.xml.remove(child_xml)
|
|
116 elif child_xml:
|
|
117 self.tree.load_xml(child_xml, self.mytree_node)
|
|
118 if not self.xml.get('cols'): self.xml.set('cols', '1')
|
|
119 if not self.xml.get('border'): self.xml.set('border', '1')
|
|
120 """
|
|
121 if not self.atts:
|
|
122 self.atts = Element('group_atts')
|
|
123 self.atts.set("cols","1")
|
|
124 self.atts.set("border","1")
|
|
125 self.xml.append(self.atts)"""
|
|
126
|
|
127 def get_design_panel(self,parent):
|
|
128 return group_edit_panel(parent,self)
|
|
129
|
|
130 def on_use(self,evt):
|
|
131 return
|
|
132
|
|
133 def gen_html(self, treenode, evt):
|
|
134 node = self.tree.GetPyData(treenode)
|
|
135 if self.i not in self.tdatas:
|
|
136 self.tdatas[self.i] = ''
|
|
137 self.tdatas[self.i] += "<P>" + node.tohtml()
|
|
138 self.i += 1
|
|
139 if self.i >= self.cols:
|
|
140 self.i = 0
|
|
141
|
|
142 def tohtml(self):
|
|
143 cols = self.xml.get("cols")
|
|
144 border = self.xml.get("border")
|
|
145 self.html_str = "<table border=\""+border+"\" ><tr><td colspan=\""+cols+"\">"
|
|
146 self.html_str += "<font size=4>"+self.xml.get("name") + "</font>"
|
|
147 self.html_str += "</td></tr>\n<tr>"
|
|
148 self.cols = int(cols)
|
|
149 self.i = 0
|
|
150 self.tdatas = {}
|
|
151 self.tree.traverse(self.mytree_node, self.gen_html, recurse=False)
|
|
152 for td in self.tdatas:
|
|
153 self.html_str += "<td valign=\"top\" >" + self.tdatas[td] + "</td>\n";
|
|
154 self.html_str += "</tr></table>"
|
|
155 return self.html_str
|
|
156
|
|
157 GROUP_COLS = wx.NewId()
|
|
158 GROUP_BOR = wx.NewId()
|
|
159
|
|
160 class group_edit_panel(wx.Panel):
|
|
161 def __init__(self, parent, handler):
|
|
162 wx.Panel.__init__(self, parent, -1)
|
|
163 self.handler = handler
|
|
164 sizer = wx.BoxSizer(wx.VERTICAL)
|
|
165 self.text = { P_TITLE : wx.TextCtrl(self, P_TITLE, handler.xml.get('name'))
|
|
166 }
|
|
167 sizer.Add(wx.StaticText(self, -1, "Title:"), 0, wx.EXPAND)
|
|
168 sizer.Add(self.text[P_TITLE], 0, wx.EXPAND)
|
|
169 sizer.Add(wx.Size(10,10))
|
|
170
|
|
171 radio_c = wx.RadioBox(self, GROUP_COLS, "Columns", choices=["1","2","3","4"])
|
|
172 cols = handler.xml.get("cols")
|
|
173 if cols != "":
|
|
174 radio_c.SetSelection(int(cols)-1)
|
|
175
|
|
176 radio_b = wx.RadioBox(self, GROUP_BOR, "Border", choices=["no","yes"])
|
|
177 border = handler.xml.get("border")
|
|
178 if border != "":
|
|
179 radio_b.SetSelection(int(border))
|
|
180
|
|
181 sizer.Add(radio_c, 0, wx.EXPAND)
|
|
182 sizer.Add(wx.Size(10,10))
|
|
183 sizer.Add(radio_b, 0, wx.EXPAND)
|
|
184
|
|
185 self.sizer = sizer
|
|
186 self.outline = wx.StaticBox(self,-1,"Group")
|
|
187 self.SetSizer(self.sizer)
|
|
188 self.SetAutoLayout(True)
|
|
189 self.Fit()
|
|
190 parent.SetSize(self.GetBestSize())
|
|
191 self.Bind(wx.EVT_TEXT, self.on_text, id=P_TITLE)
|
|
192 self.Bind(wx.EVT_RADIOBOX, self.on_radio_box, id=GROUP_BOR)
|
|
193 self.Bind(wx.EVT_RADIOBOX, self.on_radio_box, id=GROUP_COLS)
|
|
194
|
|
195 def on_radio_box(self,evt):
|
|
196 id = evt.GetId()
|
|
197 index = evt.GetInt()
|
|
198 if id == GROUP_COLS:
|
|
199 self.handler.xml.set("cols",str(index+1))
|
|
200 elif id == GROUP_BOR:
|
|
201 self.handler.xml.set("border",str(index))
|
|
202
|
|
203 def on_text(self,evt):
|
|
204 id = evt.GetId()
|
|
205 if id == P_TITLE:
|
|
206 txt = self.text[id].GetValue()
|
|
207 if txt != "":
|
|
208 self.handler.xml.set('name',txt)
|
|
209 self.handler.rename(txt)
|
|
210
|
|
211
|
|
212
|
|
213 ##########################
|
|
214 ## tabber node handler
|
|
215 ##########################
|
|
216 class tabber_handler(container_handler):
|
|
217 """ <nodehandler name='?' module='containers' class='tabber_handler' />"""
|
|
218
|
|
219 def __init__(self, xml, tree_node):
|
|
220 container_handler.__init__(self, xml, tree_node)
|
|
221
|
|
222 def get_design_panel(self,parent):
|
|
223 return tabbed_panel(parent,self,1)
|
|
224
|
|
225 def get_use_panel(self,parent):
|
|
226 return tabbed_panel(parent,self,2)
|
|
227
|
|
228
|
|
229 class tabbed_panel(orpgTabberWnd):
|
|
230 def __init__(self, parent, handler, mode):
|
|
231 orpgTabberWnd.__init__(self, parent, style=FNB.FNB_NO_X_BUTTON)
|
|
232 self.handler = handler
|
|
233 self.parent = parent
|
|
234 handler.tree.traverse(handler.mytree_node, self.pick_panel, mode, False)
|
|
235
|
|
236 parent.SetSize(self.GetBestSize())
|
|
237
|
|
238 def pick_panel(self, treenode, mode):
|
|
239 node = self.handler.tree.GetPyData(treenode)
|
|
240 if mode == 1: panel = node.get_design_panel(self)
|
|
241 else: panel = node.get_use_panel(self)
|
|
242 name = node.xml.get("name")
|
|
243 if panel: self.AddPage(panel, name, False)
|
|
244
|
|
245 #################################
|
|
246 ## Splitter container
|
|
247 #################################
|
|
248
|
|
249 class splitter_handler(container_handler):
|
|
250 """ <nodehandler name='?' module='containers' class='splitter_handler' />"""
|
|
251
|
|
252 def __init__(self,xml,tree_node):
|
|
253 container_handler.__init__(self,xml,tree_node)
|
|
254
|
|
255 def load_children(self):
|
|
256 self.atts = None
|
|
257 for child_xml in self.xml:
|
|
258 if child_xml.tag == "splitter_atts": self.xml.remove(child_xml) #Same here!
|
|
259 elif child_xml: self.tree.load_xml(child_xml,self.mytree_node)
|
|
260 if not self.xml.get('horizontal'): self.xml.set('horizontal', '0')
|
|
261 """if not self.atts:
|
|
262 self.atts = Element('splitter_atts')
|
|
263 self.atts.set("horizontal","0")
|
|
264 self.xml.append(self.atts)"""
|
|
265
|
|
266 def get_design_panel(self,parent):
|
|
267 return self.build_splitter_wnd(parent, 1)
|
|
268
|
|
269 def get_use_panel(self,parent):
|
|
270 return self.build_splitter_wnd(parent, 2)
|
|
271
|
|
272 def on_drop(self,evt):
|
|
273 drag_obj = self.tree.drag_obj
|
|
274 container_handler.on_drop(self,evt)
|
|
275
|
|
276 def build_splitter_wnd(self, parent, mode):
|
|
277 self.split = self.xml.get("horizontal")
|
|
278
|
|
279 self.pane = splitter_panel(parent, self)
|
|
280
|
|
281 self.splitter = MultiSplitterWindow(self.pane, -1, style=wx.SP_LIVE_UPDATE|wx.SP_3DSASH|wx.SP_NO_XP_THEME)
|
|
282
|
|
283 if self.split == '1':
|
|
284 self.splitter.SetOrientation(wx.VERTICAL)
|
|
285 else:
|
|
286 self.splitter.SetOrientation(wx.HORIZONTAL)
|
|
287
|
|
288 self.bestSizex = -1
|
|
289 self.bestSizey = -1
|
|
290
|
|
291 self.tree.traverse(self.mytree_node, self.doSplit, mode, False)
|
|
292
|
|
293 self.pane.sizer.Add(self.splitter, 1, wx.EXPAND)
|
|
294
|
|
295
|
|
296 if mode != 1:
|
|
297 self.pane.hozCheck.Hide()
|
|
298
|
|
299 self.pane.SetSize((self.bestSizex, self.bestSizey))
|
|
300 self.pane.Layout()
|
|
301 parent.SetSize(self.pane.GetSize())
|
|
302 return self.pane
|
|
303
|
|
304 def doSplit(self, treenode, mode):
|
|
305 node = self.tree.GetPyData(treenode)
|
|
306 if mode == 1: tmp = node.get_design_panel(self.splitter)
|
|
307 else: tmp = node.get_use_panel(self.splitter)
|
|
308
|
|
309 if self.split == '1':
|
|
310 sash = tmp.GetBestSize()[1]+1
|
|
311 self.bestSizey += sash+11
|
|
312 if self.bestSizex < tmp.GetBestSize()[0]:
|
|
313 self.bestSizex = tmp.GetBestSize()[0]+10
|
|
314 else:
|
|
315 sash = tmp.GetBestSize()[0]+1
|
|
316 self.bestSizex += sash
|
|
317 if self.bestSizey < tmp.GetBestSize()[1]:
|
|
318 self.bestSizey = tmp.GetBestSize()[1]+31
|
|
319
|
|
320 self.splitter.AppendWindow(tmp, sash)
|
|
321
|
|
322 def get_size_constraint(self):
|
|
323 return 1
|
|
324
|
|
325 class splitter_panel(wx.Panel):
|
|
326 def __init__(self, parent, handler):
|
|
327 wx.Panel.__init__(self, parent, -1)
|
|
328 self.handler = handler
|
|
329 sizer = wx.BoxSizer(wx.VERTICAL)
|
|
330
|
|
331 self.hozCheck = wx.CheckBox(self, -1, "Horizontal Split")
|
|
332 hoz = self.handler.xml.get("horizontal")
|
|
333
|
|
334 if hoz == '1':
|
|
335 self.hozCheck.SetValue(True)
|
|
336 #self.splitsize = wx.BoxSizer(wx.HORIZONTAL)
|
|
337 else:
|
|
338 self.hozCheck.SetValue(False)
|
|
339 #self.splitsize = wx.BoxSizer(wx.VERTICAL)
|
|
340
|
|
341 sizer.Add(self.hozCheck, 0, wx.EXPAND)
|
|
342 sizer.Add(wx.Size(10,0))
|
|
343 #sizer.Add(self.splitsize, 1, wx.EXPAND)
|
|
344
|
|
345 self.sizer = sizer
|
|
346 self.SetSizer(self.sizer)
|
|
347 self.SetAutoLayout(True)
|
|
348
|
|
349 self.Bind(wx.EVT_CHECKBOX, self.on_check_box, id=self.hozCheck.GetId())
|
|
350
|
|
351 def on_check_box(self,evt):
|
|
352 state = self.hozCheck.GetValue()
|
|
353 if state:
|
|
354 self.handler.xml.set("horizontal", "1")
|
|
355 else:
|
|
356 self.handler.xml.set("horizontal", "0")
|