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)
|
138
|
163 self.handler = handler
|
|
164 self.outline = wx.StaticBoxSizer(wx.StaticBox(self, -1, "Group"), wx.VERTICAL)
|
|
165
|
131
|
166 sizer = wx.BoxSizer(wx.VERTICAL)
|
138
|
167 self.text = {P_TITLE : wx.TextCtrl(self, P_TITLE, handler.xml.get('name')) }
|
131
|
168 sizer.Add(wx.StaticText(self, -1, "Title:"), 0, wx.EXPAND)
|
|
169 sizer.Add(self.text[P_TITLE], 0, wx.EXPAND)
|
|
170 sizer.Add(wx.Size(10,10))
|
|
171
|
|
172 radio_c = wx.RadioBox(self, GROUP_COLS, "Columns", choices=["1","2","3","4"])
|
|
173 cols = handler.xml.get("cols")
|
|
174 if cols != "":
|
|
175 radio_c.SetSelection(int(cols)-1)
|
|
176
|
|
177 radio_b = wx.RadioBox(self, GROUP_BOR, "Border", choices=["no","yes"])
|
|
178 border = handler.xml.get("border")
|
|
179 if border != "":
|
|
180 radio_b.SetSelection(int(border))
|
|
181
|
|
182 sizer.Add(radio_c, 0, wx.EXPAND)
|
|
183 sizer.Add(wx.Size(10,10))
|
138
|
184 sizer.Add(radio_b, 0, wx.EXPAND)
|
|
185
|
|
186 self.outline.Add(sizer, 0)
|
|
187 self.sizer = self.outline
|
131
|
188 self.SetSizer(self.sizer)
|
|
189 self.SetAutoLayout(True)
|
|
190 self.Fit()
|
|
191 parent.SetSize(self.GetBestSize())
|
|
192 self.Bind(wx.EVT_TEXT, self.on_text, id=P_TITLE)
|
|
193 self.Bind(wx.EVT_RADIOBOX, self.on_radio_box, id=GROUP_BOR)
|
|
194 self.Bind(wx.EVT_RADIOBOX, self.on_radio_box, id=GROUP_COLS)
|
|
195
|
|
196 def on_radio_box(self,evt):
|
|
197 id = evt.GetId()
|
|
198 index = evt.GetInt()
|
|
199 if id == GROUP_COLS:
|
|
200 self.handler.xml.set("cols",str(index+1))
|
|
201 elif id == GROUP_BOR:
|
|
202 self.handler.xml.set("border",str(index))
|
|
203
|
|
204 def on_text(self,evt):
|
|
205 id = evt.GetId()
|
|
206 if id == P_TITLE:
|
|
207 txt = self.text[id].GetValue()
|
|
208 if txt != "":
|
|
209 self.handler.xml.set('name',txt)
|
|
210 self.handler.rename(txt)
|
|
211
|
|
212
|
|
213
|
|
214 ##########################
|
|
215 ## tabber node handler
|
|
216 ##########################
|
|
217 class tabber_handler(container_handler):
|
|
218 """ <nodehandler name='?' module='containers' class='tabber_handler' />"""
|
|
219
|
|
220 def __init__(self, xml, tree_node):
|
|
221 container_handler.__init__(self, xml, tree_node)
|
|
222
|
|
223 def get_design_panel(self,parent):
|
138
|
224 return tabbed_edit_panel(parent, self)
|
131
|
225
|
|
226 def get_use_panel(self,parent):
|
138
|
227 return tabbed_panel(parent, self, 1)
|
131
|
228
|
|
229
|
|
230 class tabbed_panel(orpgTabberWnd):
|
|
231 def __init__(self, parent, handler, mode):
|
|
232 orpgTabberWnd.__init__(self, parent, style=FNB.FNB_NO_X_BUTTON)
|
|
233 self.handler = handler
|
|
234 self.parent = parent
|
|
235 handler.tree.traverse(handler.mytree_node, self.pick_panel, mode, False)
|
|
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")
|
138
|
243 if panel: self.AddPage(panel, name, False)
|
|
244
|
|
245 class tabbed_edit_panel(orpgTabberWnd):
|
|
246 def __init__(self, parent, handler):
|
|
247 orpgTabberWnd.__init__(self, parent, style=FNB.FNB_NO_X_BUTTON)
|
|
248 self.handler = handler
|
|
249 self.parent = parent
|
|
250 main_sizer = wx.StaticBoxSizer(wx.StaticBox(self, -1, "Tabber"), wx.VERTICAL)
|
|
251 self.title = wx.TextCtrl(self, 1, handler.xml.get('name'))
|
|
252 main_sizer.Add(wx.StaticText(self, -1, "Title:"), 0, wx.EXPAND)
|
|
253 main_sizer.Add(self.title, 0, wx.EXPAND)
|
|
254 self.SetSizer(main_sizer)
|
|
255 self.SetAutoLayout(True)
|
|
256 self.Fit()
|
|
257 self.Bind(wx.EVT_TEXT, self.on_text, id=1)
|
|
258
|
|
259 def on_text(self,evt):
|
|
260 txt = self.title.GetValue()
|
|
261 if txt != "":
|
|
262 self.handler.xml.set('name',txt)
|
|
263 self.handler.rename(txt)
|
|
264
|
131
|
265
|
|
266 #################################
|
|
267 ## Splitter container
|
|
268 #################################
|
|
269
|
|
270 class splitter_handler(container_handler):
|
|
271 """ <nodehandler name='?' module='containers' class='splitter_handler' />"""
|
|
272
|
|
273 def __init__(self,xml,tree_node):
|
|
274 container_handler.__init__(self,xml,tree_node)
|
|
275
|
|
276 def load_children(self):
|
|
277 self.atts = None
|
|
278 for child_xml in self.xml:
|
|
279 if child_xml.tag == "splitter_atts": self.xml.remove(child_xml) #Same here!
|
|
280 elif child_xml: self.tree.load_xml(child_xml,self.mytree_node)
|
|
281 if not self.xml.get('horizontal'): self.xml.set('horizontal', '0')
|
|
282
|
|
283 def get_design_panel(self,parent):
|
|
284 return self.build_splitter_wnd(parent, 1)
|
|
285
|
|
286 def get_use_panel(self,parent):
|
|
287 return self.build_splitter_wnd(parent, 2)
|
|
288
|
|
289 def on_drop(self,evt):
|
|
290 drag_obj = self.tree.drag_obj
|
|
291 container_handler.on_drop(self,evt)
|
|
292
|
|
293 def build_splitter_wnd(self, parent, mode):
|
|
294 self.split = self.xml.get("horizontal")
|
|
295 self.pane = splitter_panel(parent, self)
|
138
|
296 self.splitter = MultiSplitterWindow(self.pane, -1,
|
|
297 style=wx.SP_LIVE_UPDATE|wx.SP_3DSASH|wx.SP_NO_XP_THEME)
|
|
298 if self.split == '1': self.splitter.SetOrientation(wx.VERTICAL)
|
|
299 else: self.splitter.SetOrientation(wx.HORIZONTAL)
|
131
|
300 self.bestSizex = -1
|
|
301 self.bestSizey = -1
|
|
302 self.tree.traverse(self.mytree_node, self.doSplit, mode, False)
|
|
303 self.pane.sizer.Add(self.splitter, 1, wx.EXPAND)
|
138
|
304 if mode != 1: self.pane.hozCheck.Hide()
|
131
|
305 self.pane.SetSize((self.bestSizex, self.bestSizey))
|
|
306 self.pane.Layout()
|
|
307 parent.SetSize(self.pane.GetSize())
|
|
308 return self.pane
|
|
309
|
|
310 def doSplit(self, treenode, mode):
|
|
311 node = self.tree.GetPyData(treenode)
|
|
312 if mode == 1: tmp = node.get_design_panel(self.splitter)
|
|
313 else: tmp = node.get_use_panel(self.splitter)
|
|
314 if self.split == '1':
|
|
315 sash = tmp.GetBestSize()[1]+1
|
|
316 self.bestSizey += sash+11
|
|
317 if self.bestSizex < tmp.GetBestSize()[0]:
|
|
318 self.bestSizex = tmp.GetBestSize()[0]+10
|
|
319 else:
|
|
320 sash = tmp.GetBestSize()[0]+1
|
|
321 self.bestSizex += sash
|
|
322 if self.bestSizey < tmp.GetBestSize()[1]:
|
|
323 self.bestSizey = tmp.GetBestSize()[1]+31
|
|
324 self.splitter.AppendWindow(tmp, sash)
|
|
325 def get_size_constraint(self):
|
|
326 return 1
|
|
327
|
|
328 class splitter_panel(wx.Panel):
|
|
329 def __init__(self, parent, handler):
|
|
330 wx.Panel.__init__(self, parent, -1)
|
|
331 self.handler = handler
|
|
332 sizer = wx.BoxSizer(wx.VERTICAL)
|
138
|
333 self.title = wx.TextCtrl(self, 1, handler.xml.get('name'))
|
131
|
334
|
|
335 self.hozCheck = wx.CheckBox(self, -1, "Horizontal Split")
|
|
336 hoz = self.handler.xml.get("horizontal")
|
|
337
|
138
|
338 if hoz == '1': self.hozCheck.SetValue(True)
|
|
339 else: self.hozCheck.SetValue(False)
|
|
340
|
|
341 sizer.Add(wx.StaticText(self, -1, "Title:"), 0, wx.EXPAND)
|
|
342 sizer.Add(self.title, 0)
|
131
|
343 sizer.Add(self.hozCheck, 0, wx.EXPAND)
|
|
344 sizer.Add(wx.Size(10,0))
|
|
345 #sizer.Add(self.splitsize, 1, wx.EXPAND)
|
|
346
|
|
347 self.sizer = sizer
|
|
348 self.SetSizer(self.sizer)
|
|
349 self.SetAutoLayout(True)
|
138
|
350 self.Bind(wx.EVT_TEXT, self.on_text, id=1)
|
131
|
351 self.Bind(wx.EVT_CHECKBOX, self.on_check_box, id=self.hozCheck.GetId())
|
|
352
|
|
353 def on_check_box(self,evt):
|
|
354 state = self.hozCheck.GetValue()
|
138
|
355 if state: self.handler.xml.set("horizontal", "1")
|
|
356 else: self.handler.xml.set("horizontal", "0")
|
|
357
|
|
358 def on_text(self,evt):
|
|
359 txt = self.title.GetValue()
|
|
360 if txt != "":
|
|
361 self.handler.xml.set('name',txt)
|
|
362 self.handler.rename(txt)
|
|
363
|