130
|
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 import wx.lib.splitter
|
|
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
|
|
102 ##########################
|
|
103 ## group node handler
|
|
104 ##########################
|
|
105 class group_handler(container_handler):
|
|
106 """ group nodehandler to be used as a placeholder for other nodehandlers.
|
|
107 This handler will continue parsing child xml data.
|
|
108 <nodehandler name='?' module='core' class='group_handler' />
|
|
109 """
|
|
110 def __init__(self,xml,tree_node):
|
|
111 container_handler.__init__(self,xml,tree_node)
|
|
112
|
|
113 def load_children(self):
|
|
114 self.atts = None
|
|
115 for child_xml in self.xml:
|
|
116 if child_xml.tag == "group_atts":
|
|
117 self.atts = child_xml
|
|
118 else:
|
|
119 self.tree.load_xml(child_xml,self.mytree_node)
|
|
120 if not self.atts:
|
|
121 self.atts = ET.Element('group_atts')
|
|
122 self.atts.set("cols","1")
|
|
123 self.atts.set("border","1")
|
|
124 self.xml.append(self.atts)
|
|
125
|
|
126 def get_design_panel(self,parent):
|
|
127 return group_edit_panel(parent,self)
|
|
128
|
|
129 def on_use(self,evt):
|
|
130 return
|
|
131
|
|
132 def gen_html(self, treenode, evt):
|
|
133 node = self.tree.GetPyData(treenode)
|
|
134 if self.i not in self.tdatas:
|
|
135 self.tdatas[self.i] = ''
|
|
136 self.tdatas[self.i] += "<P>" + node.tohtml()
|
|
137 self.i += 1
|
|
138 if self.i >= self.cols:
|
|
139 self.i = 0
|
|
140
|
|
141 def tohtml(self):
|
|
142 cols = self.atts.get("cols")
|
|
143 border = self.atts.get("border")
|
|
144 self.html_str = "<table border=\""+border+"\" ><tr><td colspan=\""+cols+"\">"
|
|
145 self.html_str += "<font size=4>"+self.xml.get("name") + "</font>"
|
|
146 self.html_str += "</td></tr>\n<tr>"
|
|
147
|
|
148 self.cols = int(cols)
|
|
149 self.i = 0
|
|
150 self.tdatas = {}
|
|
151
|
|
152 self.tree.traverse(self.mytree_node, self.gen_html, recurse=False)
|
|
153
|
|
154 for td in self.tdatas:
|
|
155 self.html_str += "<td valign=\"top\" >" + self.tdatas[td] + "</td>\n";
|
|
156 self.html_str += "</tr></table>"
|
|
157 return self.html_str
|
|
158
|
|
159 GROUP_COLS = wx.NewId()
|
|
160 GROUP_BOR = wx.NewId()
|
|
161
|
|
162 class group_edit_panel(wx.Panel):
|
|
163 def __init__(self, parent, handler):
|
|
164 wx.Panel.__init__(self, parent, -1)
|
|
165 self.handler = handler
|
|
166 sizer = wx.BoxSizer(wx.VERTICAL)
|
|
167 self.text = { P_TITLE : wx.TextCtrl(self, P_TITLE, handler.xml.get('name'))
|
|
168 }
|
|
169 sizer.Add(wx.StaticText(self, -1, "Title:"), 0, wx.EXPAND)
|
|
170 sizer.Add(self.text[P_TITLE], 0, wx.EXPAND)
|
|
171 sizer.Add(wx.Size(10,10))
|
|
172
|
|
173 radio_c = wx.RadioBox(self, GROUP_COLS, "Columns", choices=["1","2","3","4"])
|
|
174 cols = handler.atts.get("cols")
|
|
175 if cols != "":
|
|
176 radio_c.SetSelection(int(cols)-1)
|
|
177
|
|
178 radio_b = wx.RadioBox(self, GROUP_BOR, "Border", choices=["no","yes"])
|
|
179 border = handler.atts.get("border")
|
|
180 if border != "":
|
|
181 radio_b.SetSelection(int(border))
|
|
182
|
|
183 sizer.Add(radio_c, 0, wx.EXPAND)
|
|
184 sizer.Add(wx.Size(10,10))
|
|
185 sizer.Add(radio_b, 0, wx.EXPAND)
|
|
186
|
|
187 self.sizer = sizer
|
|
188 self.outline = wx.StaticBox(self,-1,"Group")
|
|
189 self.SetSizer(self.sizer)
|
|
190 self.SetAutoLayout(True)
|
|
191 self.Fit()
|
|
192 parent.SetSize(self.GetBestSize())
|
|
193 self.Bind(wx.EVT_TEXT, self.on_text, id=P_TITLE)
|
|
194 self.Bind(wx.EVT_RADIOBOX, self.on_radio_box, id=GROUP_BOR)
|
|
195 self.Bind(wx.EVT_RADIOBOX, self.on_radio_box, id=GROUP_COLS)
|
|
196
|
|
197 def on_radio_box(self,evt):
|
|
198 id = evt.GetId()
|
|
199 index = evt.GetInt()
|
|
200 if id == GROUP_COLS:
|
|
201 self.handler.atts.set("cols",str(index+1))
|
|
202 elif id == GROUP_BOR:
|
|
203 self.handler.atts.set("border",str(index))
|
|
204
|
|
205 def on_text(self,evt):
|
|
206 id = evt.GetId()
|
|
207 if id == P_TITLE:
|
|
208 txt = self.text[id].GetValue()
|
|
209 if txt != "":
|
|
210 self.handler.xml.set('name',txt)
|
|
211 self.handler.rename(txt)
|
|
212
|
|
213
|
|
214
|
|
215 ##########################
|
|
216 ## tabber node handler
|
|
217 ##########################
|
|
218 class tabber_handler(container_handler):
|
|
219 """ <nodehandler name='?' module='containers' class='tabber_handler' />"""
|
|
220
|
|
221 def __init__(self,xml,tree_node):
|
|
222 container_handler.__init__(self,xml,tree_node)
|
|
223
|
|
224 def get_design_panel(self,parent):
|
|
225 return tabbed_panel(parent,self,1)
|
|
226
|
|
227 def get_use_panel(self,parent):
|
|
228 return tabbed_panel(parent,self,2)
|
|
229
|
|
230
|
|
231 class tabbed_panel(orpgTabberWnd):
|
|
232 def __init__(self, parent, handler, mode):
|
|
233 orpgTabberWnd.__init__(self, parent, style=FNB.FNB_NO_X_BUTTON)
|
|
234 self.handler = handler
|
|
235 self.parent = parent
|
|
236 handler.tree.traverse(handler.mytree_node, self.pick_panel, mode, False)
|
|
237
|
|
238 parent.SetSize(self.GetBestSize())
|
|
239
|
|
240 def pick_panel(self, treenode, mode):
|
|
241 node = self.handler.tree.GetPyData(treenode)
|
|
242 if mode == 1:
|
|
243 panel = node.get_design_panel(self)
|
|
244 else:
|
|
245 panel = node.get_use_panel(self)
|
|
246
|
|
247 name = node.xml.get("name")
|
|
248
|
|
249 if panel:
|
|
250 self.AddPage(panel, name, False)
|
|
251
|
|
252 #################################
|
|
253 ## Splitter container
|
|
254 #################################
|
|
255
|
|
256 class splitter_handler(container_handler):
|
|
257 """ <nodehandler name='?' module='containers' class='splitter_handler' />"""
|
|
258
|
|
259 def __init__(self,xml,tree_node):
|
|
260 container_handler.__init__(self,xml,tree_node)
|
|
261
|
|
262 def load_children(self):
|
|
263 self.atts = None
|
|
264 for child_xml in self.xml:
|
|
265 if child_xml.tag == "splitter_atts":
|
|
266 self.atts = child_xml
|
|
267 else:
|
|
268 self.tree.load_xml(child_xml,self.mytree_node)
|
|
269 if not self.atts:
|
|
270 self.atts = ET.Element('splitter_atts')
|
|
271 self.atts.set("horizontal","0")
|
|
272 self.xml.append(self.atts)
|
|
273
|
|
274 def get_design_panel(self,parent):
|
|
275 return self.build_splitter_wnd(parent, 1)
|
|
276
|
|
277 def get_use_panel(self,parent):
|
|
278 return self.build_splitter_wnd(parent, 2)
|
|
279
|
|
280 def on_drop(self,evt):
|
|
281 drag_obj = self.tree.drag_obj
|
|
282 container_handler.on_drop(self,evt)
|
|
283
|
|
284 def build_splitter_wnd(self, parent, mode):
|
|
285 self.split = self.atts.get("horizontal")
|
|
286
|
|
287 self.pane = splitter_panel(parent, self)
|
|
288
|
|
289 self.splitter = wx.lib.splitter.MultiSplitterWindow(self.pane, -1, style=wx.SP_LIVE_UPDATE|wx.SP_3DSASH|wx.SP_NO_XP_THEME)
|
|
290
|
|
291 if self.split == '1':
|
|
292 self.splitter.SetOrientation(wx.VERTICAL)
|
|
293 else:
|
|
294 self.splitter.SetOrientation(wx.HORIZONTAL)
|
|
295
|
|
296 self.bestSizex = -1
|
|
297 self.bestSizey = -1
|
|
298
|
|
299 self.tree.traverse(self.mytree_node, self.doSplit, mode, False)
|
|
300
|
|
301 self.pane.sizer.Add(self.splitter, 1, wx.EXPAND)
|
|
302
|
|
303
|
|
304 if mode != 1:
|
|
305 self.pane.hozCheck.Hide()
|
|
306
|
|
307 self.pane.SetSize((self.bestSizex, self.bestSizey))
|
|
308 self.pane.Layout()
|
|
309 parent.SetSize(self.pane.GetSize())
|
|
310 return self.pane
|
|
311
|
|
312 def doSplit(self, treenode, mode):
|
|
313 node = self.tree.GetPyData(treenode)
|
|
314 if mode == 1:
|
|
315 tmp = node.get_design_panel(self.splitter)
|
|
316 else:
|
|
317 tmp = node.get_use_panel(self.splitter)
|
|
318
|
|
319 if self.split == '1':
|
|
320 sash = tmp.GetBestSize()[1]+1
|
|
321 self.bestSizey += sash+11
|
|
322 if self.bestSizex < tmp.GetBestSize()[0]:
|
|
323 self.bestSizex = tmp.GetBestSize()[0]+10
|
|
324 else:
|
|
325 sash = tmp.GetBestSize()[0]+1
|
|
326 self.bestSizex += sash
|
|
327 if self.bestSizey < tmp.GetBestSize()[1]:
|
|
328 self.bestSizey = tmp.GetBestSize()[1]+31
|
|
329
|
|
330 self.splitter.AppendWindow(tmp, sash)
|
|
331
|
|
332 def get_size_constraint(self):
|
|
333 return 1
|
|
334
|
|
335 class splitter_panel(wx.Panel):
|
|
336 def __init__(self, parent, handler):
|
|
337 wx.Panel.__init__(self, parent, -1)
|
|
338 self.handler = handler
|
|
339 sizer = wx.BoxSizer(wx.VERTICAL)
|
|
340
|
|
341 self.hozCheck = wx.CheckBox(self, -1, "Horizontal Split")
|
|
342 hoz = self.handler.atts.get("horizontal")
|
|
343
|
|
344 if hoz == '1':
|
|
345 self.hozCheck.SetValue(True)
|
|
346 #self.splitsize = wx.BoxSizer(wx.HORIZONTAL)
|
|
347 else:
|
|
348 self.hozCheck.SetValue(False)
|
|
349 #self.splitsize = wx.BoxSizer(wx.VERTICAL)
|
|
350
|
|
351 sizer.Add(self.hozCheck, 0, wx.EXPAND)
|
|
352 sizer.Add(wx.Size(10,0))
|
|
353 #sizer.Add(self.splitsize, 1, wx.EXPAND)
|
|
354
|
|
355 self.sizer = sizer
|
|
356 self.SetSizer(self.sizer)
|
|
357 self.SetAutoLayout(True)
|
|
358
|
|
359 self.Bind(wx.EVT_CHECKBOX, self.on_check_box, id=self.hozCheck.GetId())
|
|
360
|
|
361 def on_check_box(self,evt):
|
|
362 state = self.hozCheck.GetValue()
|
|
363 if state:
|
|
364 self.handler.atts.set("horizontal", "1")
|
|
365 else:
|
|
366 self.handler.atts.set("horizontal", "0")
|