comparison orpg/mapper/whiteboard_handler.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 78407d627cba
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: mapper/whiteboard_hander.py
21 # Author: OpenRPG Team
22 # Maintainer:
23 # Version:
24 # $Id: whiteboard_handler.py,v 1.37 2007/03/09 14:11:56 digitalxero Exp $
25 #
26 # Description: Whiteboard layer handler
27 #
28 __version__ = "$Id: whiteboard_handler.py,v 1.37 2007/03/09 14:11:56 digitalxero Exp $"
29
30 from base_handler import *
31 from math import floor
32 from math import sqrt
33
34 class whiteboard_handler(base_layer_handler):
35 def __init__(self, parent, id, canvas):
36 self.drawing_mode = 'Freeform'
37 self.line_string = "0,0;"
38 self.drawing = False
39 self.upperleft = wx.Point(0,0)
40 self.lowerright = wx.Point(0,0)
41 #polyline drawing vars
42 self.polypoints = 0
43 self.lastpoint = None
44 self.selected = None
45 #text drawing vars
46 self.style = str(wx.NORMAL)
47 self.weight = str(wx.NORMAL)
48 self.pointsize = str(12)
49 self.text_selected_item = None
50 #self.r_h = RGBHex()
51 base_layer_handler.__init__(self, parent, id, canvas)
52 self.build_text_properties_menu()
53 self.wb = self.canvas.layers['whiteboard']
54 self.temp_circle = None
55 self.cone_start = None
56 self.temp_edge1 = None
57 self.temp_edge2 = None
58
59 def build_ctrls(self):
60 base_layer_handler.build_ctrls(self)
61 self.color_button = wx.Button(self, wx.ID_ANY, "Pen Color", style=wx.BU_EXACTFIT)
62 self.color_button.SetBackgroundColour(wx.BLACK)
63 self.color_button.SetForegroundColour(wx.WHITE)
64 self.drawmode_ctrl = wx.Choice(self, wx.ID_ANY, choices = ["Freeform", "Polyline","Text", "Cone", "Circle"])
65 self.drawmode_ctrl.SetSelection(0) #always start showing "Freeform"
66 self.radius = wx.TextCtrl(self, wx.ID_ANY, size=(32,-1) )
67 self.radius.SetValue("15")
68 self.live_refresh = wx.CheckBox(self, wx.ID_ANY, " Live Refresh")
69 self.live_refresh.SetValue(True)
70 self.widthList= wx.Choice(self, wx.ID_ANY, size= wx.Size(40, 20), choices=['1','2','3','4','5','6','7','8','9','10'])
71 self.widthList.SetSelection(0) #always start showing "1"
72 self.sizer.Add(wx.StaticText(self, wx.ID_ANY, "Line Width: "),0,wx.ALIGN_CENTER)
73 self.sizer.Add(self.widthList, 0, wx.EXPAND)
74 self.sizer.Add(wx.Size(10,25))
75 self.sizer.Add(wx.StaticText(self, wx.ID_ANY, "Drawing Mode: "),0,wx.ALIGN_CENTER)
76 self.sizer.Add(self.drawmode_ctrl, 0, wx.EXPAND)
77 self.sizer.Add(wx.StaticText(self, -1, " Radius: "), 0, wx.ALIGN_CENTER|wx.ALL, 3)
78 self.sizer.Add(self.radius, 0, wx.EXPAND|wx.ALL, 2)
79 self.sizer.Add(wx.Size(10,25))
80 self.sizer.Add(self.live_refresh, 0, wx.EXPAND)
81 self.sizer.Add(wx.Size(20,25))
82 self.sizer.Add(self.color_button, 0, wx.EXPAND)
83 self.sizer.Add(wx.Size(20,25))
84 self.Bind(wx.EVT_MOTION, self.on_motion)
85 self.Bind(wx.EVT_CHOICE, self.check_draw_mode, self.drawmode_ctrl)
86 self.Bind(wx.EVT_BUTTON, self.on_pen_color, self.color_button)
87 self.Bind(wx.EVT_CHOICE, self.on_pen_width, self.widthList)
88
89 def build_text_properties_menu(self, label="Text Properties"):
90 self.text_properties_dialog = wx.Dialog(self, -1, "Text Properties", name = "Text Properties")
91 self.text_props_sizer = wx.BoxSizer(wx.VERTICAL)
92 okay_boxer = wx.BoxSizer(wx.HORIZONTAL)
93 okay_button = wx.Button(self.text_properties_dialog, wx.ID_OK, "APPLY")
94 cancel_button = wx.Button(self.text_properties_dialog, wx.ID_CANCEL,"CANCEL")
95 okay_boxer.Add(okay_button, 1, wx.ALIGN_LEFT)
96 okay_boxer.Add(wx.Size(10,10))
97 okay_boxer.Add(cancel_button, 1, wx.ALIGN_RIGHT)
98 self.txt_boxer = wx.BoxSizer(wx.HORIZONTAL)
99 self.txt_static = wx.StaticText(self.text_properties_dialog, -1, "Text: ")
100 self.text_control = wx.TextCtrl(self.text_properties_dialog, wx.ID_ANY, "", name = "Text: ")
101 self.txt_boxer.Add(self.txt_static,0,wx.EXPAND)
102 self.txt_boxer.Add(wx.Size(10,10))
103 self.txt_boxer.Add(self.text_control,1,wx.EXPAND)
104 self.point_boxer = wx.BoxSizer(wx.HORIZONTAL)
105 self.point_static = wx.StaticText(self.text_properties_dialog, -1, "Text Size: ")
106 self.point_control = wx.SpinCtrl(self.text_properties_dialog, wx.ID_ANY, value = "12",min = 1, initial = 12, name = "Font Size: ")
107 self.point_boxer.Add(self.point_static,1,wx.EXPAND)
108 self.point_boxer.Add(wx.Size(10,10))
109 self.point_boxer.Add(self.point_control,0,wx.EXPAND)
110 self.text_color_control = wx.Button(self.text_properties_dialog, wx.ID_ANY, "TEXT COLOR",style=wx.BU_EXACTFIT)
111 self.weight_control = wx.RadioBox(self.text_properties_dialog, wx.ID_ANY, "Weight", choices = ["Normal","Bold"])
112 self.style_control = wx.RadioBox(self.text_properties_dialog, wx.ID_ANY, "Style", choices = ["Normal", "Italic"])
113 self.text_props_sizer.Add(self.txt_boxer,0,wx.EXPAND)
114 self.text_props_sizer.Add(self.point_boxer,0, wx.EXPAND)
115 self.text_props_sizer.Add(self.weight_control,0, wx.EXPAND)
116 self.text_props_sizer.Add(self.style_control,0, wx.EXPAND)
117 self.text_props_sizer.Add(self.text_color_control, 0, wx.EXPAND)
118 self.text_props_sizer.Add(wx.Size(10,10))
119 self.text_props_sizer.Add(okay_boxer,0, wx.EXPAND)
120 self.text_props_sizer.Fit(self)
121 self.text_properties_dialog.SetSizer(self.text_props_sizer)
122 self.text_properties_dialog.Fit()
123 self.text_properties_dialog.Bind(wx.EVT_BUTTON, self.on_text_color, self.text_color_control)
124 self.text_properties_dialog.Bind(wx.EVT_BUTTON, self.on_text_properties, okay_button)
125 #self.text_properties_dialog.Destroy()
126
127 def build_menu(self, label = "Whiteboard"):
128 base_layer_handler.build_menu(self,label)
129 self.main_menu.AppendSeparator()
130 item = wx.MenuItem(self.main_menu, wx.ID_ANY, "&Change Pen Color", "Change Pen Color")
131 self.canvas.Bind(wx.EVT_MENU, self.on_pen_color, item)
132 self.main_menu.AppendItem(item)
133 item = wx.MenuItem(self.main_menu, wx.ID_ANY, "Delete &All Lines", "Delete All Lines")
134 self.canvas.Bind(wx.EVT_MENU, self.delete_all_lines, item)
135 self.main_menu.AppendItem(item)
136 item = wx.MenuItem(self.main_menu, wx.ID_ANY, "&Undo Last Deleted Line", "Undo Last Deleted Line")
137 self.canvas.Bind(wx.EVT_MENU, self.undo_line, item)
138 self.main_menu.AppendItem(item)
139 self.line_menu = wx.Menu("Whiteboard Line")
140 self.line_menu.SetTitle("Whiteboard Line")
141 item = wx.MenuItem(self.line_menu, wx.ID_ANY, "&Remove", "Remove")
142 self.canvas.Bind(wx.EVT_MENU, self.on_line_menu_item, item)
143 self.line_menu.AppendItem(item)
144 self.text_menu = wx.Menu("Whiteboard Text")
145 self.text_menu.SetTitle("Whiteboard Text")
146 item = wx.MenuItem(self.text_menu, wx.ID_ANY, "&Properties", "Properties")
147 self.canvas.Bind(wx.EVT_MENU, self.get_text_properties, item)
148 self.text_menu.AppendItem(item)
149 item = wx.MenuItem(self.text_menu, wx.ID_ANY, "&Remove", "Remove")
150 self.canvas.Bind(wx.EVT_MENU, self.on_text_menu_item, item)
151 self.text_menu.AppendItem(item)
152
153 def do_line_menu(self,pos):
154 self.canvas.PopupMenu(self.line_menu, pos)
155
156 def item_selected(self,evt):
157 item = evt.GetId()
158 self.item_selection = self.selection_list[item]
159
160 def on_text_properties(self,evt):
161 text_string = self.text_control.GetValue()
162 if self.style_control.GetStringSelection() == 'Normal':
163 style = wx.NORMAL
164 else:
165 style = wx.ITALIC
166 if self.weight_control.GetStringSelection() == 'Normal':
167 weight = wx.NORMAL
168 else:
169 weight = wx.BOLD
170 point = str(self.point_control.GetValue())
171 c = self.text_color_control.GetForegroundColour()
172 color = self.canvas.layers['whiteboard'].r_h.hexstring(c.Red(), c.Green(), c.Blue())
173 self.text_selected_item.set_text_props(text_string, style, point, weight, color)
174 self.text_to_xml()
175 self.text_properties_dialog.Show(False)
176 self.text_selected_item.selected = False
177 self.text_selected_item.isUpdated = True
178 self.text_selected_item = None
179
180 def on_text_color(self,evt):
181 dlg = wx.ColourDialog(self)
182 if dlg.ShowModal() == wx.ID_OK:
183 c = dlg.GetColourData()
184 self.text_color_control.SetForegroundColour(c.GetColour())
185 dlg.Destroy()
186
187 def text_to_xml(self):
188 xml_str = "<map><whiteboard>"
189 xml_str += self.text_selected_item.toxml('update')
190 xml_str += "</whiteboard></map>"
191 self.canvas.frame.session.send(xml_str)
192 self.canvas.Refresh(False)
193
194 def get_text_properties(self, event=None):
195 self.text_color_control.SetForegroundColour(self.text_selected_item.textcolor)
196 self.text_control.SetValue(self.text_selected_item.text_string)
197 self.point_control.SetValue(int(self.text_selected_item.pointsize))
198 if int(self.text_selected_item.weight) == wx.NORMAL:
199 self.weight_control.SetSelection(0)
200 else:
201 self.weight_control.SetSelection(1)
202
203 if int(self.text_selected_item.style) == wx.NORMAL:
204 self.style_control.SetSelection(0)
205 else:
206 self.style_control.SetSelection(1)
207 self.text_properties_dialog.Center()
208 self.text_properties_dialog.Show(True)
209
210 def do_text_menu(self, pos, items=None):
211 if items == None:
212 self.canvas.PopupMenu(self.text_menu)
213 else:
214 menu = wx.Menu()
215 self.ItemList = items
216 self.tmpPos = pos
217 for i in xrange(len(items)):
218 menu.Append(i+1, items[i].text_string)
219 self.canvas.Bind(wx.EVT_MENU, self.onItemSelect, id=i+1)
220 self.canvas.PopupMenu(menu)
221 return
222
223 def onItemSelect(self, evt):
224 id = evt.GetId()-1
225 self.text_selected_item = self.ItemList[id]
226 self.text_selected_item.selected = True
227 if self.tmpPos == 'right':
228 self.canvas.PopupMenu(self.text_menu)
229 self.ItemList = None
230 self.tmpPos = None
231
232 def on_right_down(self,evt):
233 line = 0
234 scale = self.canvas.layers['grid'].mapscale
235 dc = wx.ClientDC(self.canvas)
236 self.canvas.PrepareDC(dc)
237 dc.SetUserScale(scale,scale)
238 pos = evt.GetLogicalPosition(dc)
239 if self.drawing_mode == 'Text':
240 self.on_text_right_down(evt, dc)
241 elif self.drawing and ((self.drawing_mode == 'Circle') or (self.drawing_mode == 'Cone')):
242 self.check_draw_mode()
243 self.drawing = False
244 elif (self.drawing_mode == 'Freeform') or (self.drawing_mode == 'Polyline') or (self.drawing_mode == 'Circle') or (self.drawing_mode == 'Cone'):
245 line_list = self.canvas.layers['whiteboard'].find_line(pos)
246 if line_list:
247 self.sel_rline = self.canvas.layers['whiteboard'].get_line_by_id(line_list.id)
248 if self.sel_rline:
249 self.do_line_menu(evt.GetPosition())
250 self.canvas.Refresh(False)
251 else:
252 base_layer_handler.on_right_down(self,evt)
253 else:
254 base_layer_handler.on_right_down(self,evt)
255 del dc
256
257 def on_pen_color(self,evt):
258 data = wx.ColourData()
259 data.SetChooseFull(True)
260 dlg = wx.ColourDialog(self.canvas, data)
261 if dlg.ShowModal() == wx.ID_OK:
262 data = dlg.GetColourData()
263 color = data.GetColour()
264 self.canvas.layers['whiteboard'].setcolor(color)
265 self.color_button.SetBackgroundColour(color)
266 dlg.Destroy()
267
268 def on_pen_width(self,evt):
269 width = int(self.widthList.GetStringSelection())
270 self.canvas.layers['whiteboard'].setwidth(width)
271
272 def undo_line(self,evt):
273 session = self.canvas.frame.session
274 if (session.my_role() != session.ROLE_GM) and (session.use_roles()):
275 self.top_frame.openrpg.get_component("chat").InfoPost("You must be a GM to use this feature")
276 return
277 self.canvas.layers['whiteboard'].undo_line()
278 dc = self.create_dc()
279 self.un_highlight(dc)
280 self.selected = None
281 del dc
282
283 def delete_all_lines(self,evt):
284 session = self.canvas.frame.session
285 if (session.my_role() != session.ROLE_GM) and (session.use_roles()):
286 open_rpg.get_component("chat").InfoPost("You must be a GM to use this feature")
287 return
288 dlg = wx.MessageDialog(self, "Are you sure you want to delete all lines?","Delete All Lines",wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION)
289 if dlg.ShowModal() != wx.ID_YES:
290 return
291 self.canvas.layers['whiteboard'].del_all_lines()
292 dc = self.create_dc()
293 self.un_highlight(dc)
294 self.selected = None
295 del dc
296
297 def on_line_menu_item(self, evt):
298 dc = self.create_dc()
299 self.un_highlight(dc)
300 self.canvas.layers['whiteboard'].del_line(self.sel_rline)
301 self.selected = None
302 del dc
303
304 def on_text_menu_item(self, evt):
305 dc = self.create_dc()
306 self.un_highlight(dc)
307 self.canvas.layers['whiteboard'].del_text(self.selected)
308 self.selected = None
309 del dc
310
311 # Check Draw Mode
312 # Queries the GUI to see what mode to draw in
313 # 05-09-2003 Snowdog
314
315 def check_draw_mode(self, evt=None):
316 self.drawing_mode = self.drawmode_ctrl.GetStringSelection()
317
318 #because mode can be changed while a polyline is being created
319 #clear the current linestring and reset the polyline data
320 self.upperleft.x = self.upperleft.y = 0
321 self.lowerright.x = self.lowerright.y = 0
322 self.lastpoint = None #because the end check function is not called we must force its lastpoint var to None again
323 self.polypoints = 0
324 self.line_string = "0,0;"
325 if self.temp_circle:
326 self.canvas.layers['whiteboard'].del_temp_line(self.temp_circle)
327 if self.selected == self.temp_circle:
328 self.selected = None
329 self.canvas.Refresh(True)
330 self.temp_circle = None
331 self.cone_start = None
332
333 # Altered on_left_up to toggle between
334 # drawing modes freeform vs polyline
335 # 05-09-2003 Snowdog
336 def on_left_down(self,evt):
337 if not self.drawing:
338 self.check_draw_mode()
339 if self.drawing_mode == 'Freeform':
340 #Freeform mode ignores the inital down click
341 pass
342 elif self.drawing_mode == 'Polyline':
343 self.polyline_add_point( evt )
344 elif self.drawing_mode == 'Text':
345 self.on_text_left_down(evt)
346 elif self.drawing_mode == 'Cone':
347 if self.cone_start == None:
348 self.on_start_cone(evt)
349 else:
350 self.draw_temporary_cone(evt)
351 elif self.drawing_mode == 'Circle':
352 self.draw_temporary_circle(evt)
353
354 # Added handling for double clicks within the map
355 # 05-09-2003 Snowdog
356 def on_left_dclick(self, evt):
357 if self.drawing_mode == 'Freeform':
358 #Freeform mode ignores the double click
359 pass
360 elif self.drawing_mode == 'Polyline':
361 self.polyline_last_point( evt )
362 elif self.drawing_mode == 'Text':
363 pass
364 elif self.drawing_mode == 'Circle' or self.drawing_mode == 'Cone':
365 self.canvas.layers['whiteboard'].del_temp_line(self.temp_circle)
366 #pointArray = self.temp_circle.line_string.split(";")
367 self.canvas.layers['whiteboard'].add_line(self.temp_circle.line_string)
368 self.temp_circle = None
369 self.cone_start = None
370 self.drawing = False
371
372 # Altered on_left_up to toggle between
373 # drawing modes freeform vs polyline
374 # 05-09-2003 Snowdog
375 def on_left_up(self,evt):
376 if self.drawing_mode == 'Freeform':
377 self.on_freeform_left_up(evt)
378 elif self.drawing_mode == 'Polyline':
379 #Polyline mode relies on the down click
380 #not the mouse button release
381 pass
382 elif self.drawing_mode == 'Text':
383 pass
384
385 # Altered on_left_up to toggle between
386 # drawing modes freeform vs polyline
387 # 05-09-2003 Snowdog
388 def on_motion(self,evt):
389 session = self.canvas.frame.session
390 if (session.my_role() != session.ROLE_GM) \
391 and (session.my_role()!=session.ROLE_PLAYER) \
392 and (session.use_roles()):
393 return
394 if self.drawing_mode == 'Freeform':
395 if evt.m_leftDown:
396 self.freeform_motion(evt)
397 elif self.drawing_mode == 'Polyline':
398 if self.drawing:
399 self.polyline_preview( evt )
400 dc = self.create_dc()
401 pos = evt.GetLogicalPosition(dc)
402 hit = self.canvas.layers['whiteboard'].hit_test_lines(pos,dc)
403 if hit:
404 self.highlight(hit,dc)
405 else:
406 self.un_highlight(dc)
407 hit = self.canvas.layers['whiteboard'].hit_test_text(pos,dc)
408 if hit:
409 self.highlight(hit,dc)
410 else:
411 self.un_highlight(dc)
412 del dc
413
414 def create_dc(self):
415 scale = self.canvas.layers['grid'].mapscale
416 dc = wx.ClientDC( self.canvas )
417 self.canvas.PrepareDC( dc )
418 dc.SetUserScale(scale,scale)
419 return dc
420
421 def highlight(self,hit,dc):
422 if self.selected:
423 self.selected.highlight(False)
424 self.selected.draw(self.wb,dc)
425 self.selected = hit[0]
426 self.selected.highlight()
427 self.selected.draw(self.wb,dc)
428
429 def un_highlight(self,dc):
430 if self.selected:
431 self.selected.highlight(False)
432 self.selected.draw(self.wb,dc)
433
434 # Polyline Add Point
435 # adds a new point to the polyline
436 # 05-09-2003 Snowdog
437 def polyline_add_point(self, evt):
438 scale = self.canvas.layers['grid'].mapscale
439 dc = wx.ClientDC( self.canvas )
440 self.canvas.PrepareDC( dc )
441 dc.SetUserScale(scale,scale)
442 pos = evt.GetLogicalPosition(dc)
443 #reset the bounding points
444 if pos.x < self.upperleft.x:
445 self.upperleft.x = pos.x
446 elif pos.x > self.lowerright.x:
447 self.lowerright.x = pos.x
448 if pos.y < self.upperleft.y:
449 self.upperleft.y = pos.y
450 elif pos.y > self.lowerright.y:
451 self.lowerright.y = pos.y
452
453 #if this point doens't end the line
454 #add a new point into the line string
455 if not self.polyline_end_check( pos ):
456 if self.drawing == True:
457 self.polypoints += 1 #add one to the point counter.
458 self.line_string += `pos.x` + "," + `pos.y` + ";"
459 self.canvas.layers['whiteboard'].draw_working_line(dc,self.line_string)
460 else: #start of line...
461 self.polypoints += 1 #add one to the point counter.
462 self.line_string = `pos.x` + "," + `pos.y` + ";"
463 self.upperleft.x = pos.x
464 self.upperleft.y = pos.y
465 self.lowerright.x = pos.x
466 self.lowerright.y = pos.y
467 self.drawing = True
468 else: #end of line. Send and reset vars for next line
469 self.drawing = False
470 if self.polypoints < 2:
471 #not enough points to form a line. Ignore line
472 pass
473 else:
474 #have enough points to create valid line
475 #check to role to make sure user can draw at all....
476 session = self.canvas.frame.session
477 if (session.my_role() != session.ROLE_GM) and (session.my_role()!=session.ROLE_PLAYER) and (session.use_roles()):
478 open_rpg.get_component("chat").InfoPost("You must be either a player or GM to use this feature")
479 self.canvas.Refresh(False)
480 else:
481 #user allowed to draw on whiteboard.. send polyline
482 line = self.canvas.layers['whiteboard'].add_line(self.line_string,self.upperleft,self.lowerright)
483 #resetting variables for next line
484 self.upperleft.x = self.upperleft.y = 0
485 self.lowerright.x = self.lowerright.y = 0
486 self.polypoints = 0
487 self.line_string = "0,0;"
488
489 # Polyline Last Point
490 # adds a final point to the polyline and ends it
491 # 05-09-2003 Snowdog
492 def polyline_last_point(self, evt):
493 #if we haven't started a line already. Ignore the click
494 if self.drawing != True:
495 return
496 scale = self.canvas.layers['grid'].mapscale
497 dc = wx.ClientDC( self.canvas )
498 self.canvas.PrepareDC( dc )
499 dc.SetUserScale(scale,scale)
500 pos = evt.GetLogicalPosition(dc)
501 #reset the bounding points
502 if pos.x < self.upperleft.x:
503 self.upperleft.x = pos.x
504 elif pos.x > self.lowerright.x:
505 self.lowerright.x = pos.x
506 if pos.y < self.upperleft.y:
507 self.upperleft.y = pos.y
508 elif pos.y > self.lowerright.y:
509 self.lowerright.y = pos.y
510 self.polypoints += 1 #add one to the point counter.
511 self.line_string += `pos.x` + "," + `pos.y` + ";"
512 self.canvas.layers['whiteboard'].draw_working_line(dc,self.line_string)
513 #end of line. Send and reset vars for next line
514 self.drawing = False
515 if self.polypoints < 2:
516 #not enough points to form a line. Ignore line
517 pass
518 else:
519 #have enough points to create valid line
520 #check to role to make sure user can draw at all....
521 session = self.canvas.frame.session
522 if (session.my_role() != session.ROLE_GM) and (session.my_role()!=session.ROLE_PLAYER) and (session.use_roles()):
523 open_rpg.get_component("chat").InfoPost("You must be either a player or GM to use this feature")
524 self.canvas.Refresh(False)
525 else:
526 #user allowed to draw on whiteboard.. send polyline
527 line = self.canvas.layers['whiteboard'].add_line(self.line_string,self.upperleft,self.lowerright)
528 #resetting variables for next line
529 self.upperleft.x = self.upperleft.y = 0
530 self.lowerright.x = self.lowerright.y = 0
531 self.lastpoint = None #becuase the end check function is not called we must force its lastpoint var to None again
532 self.polypoints = 0
533 self.line_string = "0,0;"
534
535 # Polyline End Check
536 # checks to see if a double click has occured
537 # a second click on the LAST polyline point
538 # (or very close proximity) should cause the
539 # polyline even to complete and send
540 # 05-09-2003 Snowdog
541 def polyline_end_check(self, pos):
542 # check to see if the position of the give point is within POLYLINE_END_TOLERANCE
543 # if it is then the line has been completed and should be sent to the map just like
544 # the original freeform version is. A line with fewer than 2 points should be ignored
545 x_in = y_in = 0
546 tol = 5
547
548 #first point check
549 if type(self.lastpoint) == type(None):
550 self.lastpoint = wx.Point(pos.x,pos.y)
551 return 0 #not end of line
552 if ((self.lastpoint.x -tol) <= pos.x <= (self.lastpoint.x)):
553 x_in = 1
554 if ((self.lastpoint.y -tol) <= pos.y <= (self.lastpoint.y)):
555 y_in = 1
556 if x_in and y_in:
557 #point within tolerance. End line
558 self.lastpoint = None
559 return 1
560 #if we've reached here the point is NOT a terminal point. Reset the lastpoint and return False
561 self.lastpoint.x = pos.x
562 self.lastpoint.y = pos.y
563 return 0
564
565 # Polyline Preview
566 # display a temporary/momentary line to the user
567 # from the last point to mouse position
568 # 05-09-2003 Snowdog
569 def polyline_preview(self, evt):
570 if self.drawing != True:
571 #not enough points to form a line. Ignore line
572 return
573 if self.live_refresh.GetValue() == 0:
574 #not using live redraw
575 return
576 scale = self.canvas.layers['grid'].mapscale
577 dc = wx.ClientDC( self.canvas )
578 self.canvas.PrepareDC( dc )
579 dc.SetUserScale(scale,scale)
580 pos = evt.GetLogicalPosition(dc)
581
582 #reset the bounding points
583 if pos.x < self.upperleft.x:
584 self.upperleft.x = pos.x
585 elif pos.x > self.lowerright.x:
586 self.lowerright.x = pos.x
587 if pos.y < self.upperleft.y:
588 self.upperleft.y = pos.y
589 elif pos.y > self.lowerright.y:
590 self.lowerright.y = pos.y
591
592 #redraw the line with a line connected to the cursor
593 temp_string = self.line_string
594 temp_string += `pos.x` + "," + `pos.y` + ";"
595 self.canvas.layers['whiteboard'].draw_working_line(dc,temp_string)
596 self.canvas.Refresh(True)
597
598 # moved original on_motion to this function
599 # to allow alternate drawing method to be used
600 # 05-09-2003 Snowdog
601 def freeform_motion(self, evt):
602 # if not self.drawing:
603 # return
604 scale = self.canvas.layers['grid'].mapscale
605 dc = wx.ClientDC( self.canvas )
606 self.canvas.PrepareDC( dc )
607 dc.SetUserScale(scale,scale)
608 pos = evt.GetLogicalPosition(dc)
609 if pos.x < self.upperleft.x:
610 self.upperleft.x = pos.x
611 elif pos.x > self.lowerright.x:
612 self.lowerright.x = pos.x
613 if pos.y < self.upperleft.y:
614 self.upperleft.y = pos.y
615 elif pos.y > self.lowerright.y:
616 self.lowerright.y = pos.y
617 if evt.m_leftDown:
618 if self.drawing == True:
619 self.line_string += `pos.x` + "," + `pos.y` + ";"
620 self.canvas.layers['whiteboard'].draw_working_line(dc,self.line_string)
621 else:
622 self.line_string = `pos.x` + "," + `pos.y` + ";"
623 self.upperleft.x = pos.x
624 self.upperleft.y = pos.y
625 self.lowerright.x = pos.x
626 self.lowerright.y = pos.y
627 self.drawing = True
628 del dc
629
630 # moved original on_left_up to this function
631 # to allow alternate drawing method to be used
632 # 05-09-2003 Snowdog
633 def on_freeform_left_up(self,evt):
634 if self.drawing == True:
635 self.drawing = False
636 session = self.canvas.frame.session
637 if (session.my_role() != session.ROLE_GM) and (session.my_role()!=session.ROLE_PLAYER) and (session.use_roles()):
638 open_rpg.get_component("chat").InfoPost("You must be either a player or GM to use this feature")
639 self.canvas.Refresh(False)
640 return
641 #self.id +=1
642 line = self.canvas.layers['whiteboard'].add_line(self.line_string,self.upperleft,self.lowerright)
643 dc = self.create_dc()
644 for m in range(30):
645 line.highlight()
646 line.draw(self.wb,dc)
647 line.highlight(False)
648 line.draw(self.wb,dc)
649 del dc
650 self.upperleft.x = self.upperleft.y = 0
651 self.lowerright.x = self.lowerright.y = 0
652
653 def on_text_left_down(self, evt):
654 session = self.canvas.frame.session
655 if (session.my_role() != session.ROLE_GM) and (session.my_role()!=session.ROLE_PLAYER) and (session.use_roles()):
656 open_rpg.get_component("chat").InfoPost("You must be either a player or GM to use this feature")
657 self.canvas.Refresh(False)
658 return
659 scale = self.canvas.layers['grid'].mapscale
660 dc = wx.ClientDC( self.canvas )
661 self.canvas.PrepareDC( dc )
662 dc.SetUserScale(scale,scale)
663 pos = evt.GetLogicalPosition(dc)
664 test_text = self.canvas.layers['whiteboard'].hit_test_text(pos,dc)
665 if len(test_text) > 0:
666 if len(test_text) > 1:
667 self.do_text_menu('left', test_text)
668 else:
669 self.text_selected_item = test_text[0]
670 self.text_selected_item.selected = True
671 self.canvas.Refresh(True)
672 else:
673 if self.text_selected_item == None:
674 dlg = wx.TextEntryDialog(self,"Text to add to whiteboard", caption="Enter text",defaultValue=" ")
675 if dlg.ShowModal() == wx.ID_OK:
676 text_string = dlg.GetValue()
677 self.canvas.layers['whiteboard'].add_text(text_string,pos, self.style, self.pointsize, self.weight, self.canvas.layers['whiteboard'].color)
678 else:
679 self.text_selected_item.posx = pos.x
680 self.text_selected_item.posy = pos.y
681 self.text_selected_item.isUpdated = True
682 self.text_to_xml()
683 self.text_selected_item.selected = False
684 self.text_selected_item = None
685 del dc
686
687 def on_text_right_down(self, evt, dc):
688 session = self.canvas.frame.session
689 if (session.my_role() != session.ROLE_GM) and (session.my_role()!=session.ROLE_PLAYER) and (session.use_roles()):
690 open_rpg.get_component("chat").InfoPost("You must be either a player or GM to use this feature")
691 self.canvas.Refresh(False)
692 return
693 pos = evt.GetLogicalPosition(dc)
694 test_text = self.canvas.layers['whiteboard'].hit_test_text(pos, dc)
695 if len(test_text) > 0:
696 if len(test_text) > 1:
697 self.do_text_menu('right', test_text)
698 else:
699 self.text_selected_item = test_text[0]
700 self.do_text_menu('right')
701
702 def on_start_cone(self, evt):
703 session = self.canvas.frame.session
704 if (session.my_role() != session.ROLE_GM) and (session.my_role()!=session.ROLE_PLAYER) and (session.use_roles()):
705 open_rpg.get_component("chat").InfoPost("You must be either a player or GM to use this feature")
706 self.canvas.Refresh(False)
707 return
708 self.cone_start = self.get_snapped_to_logical_pos(evt)
709 self.drawing = True
710
711 def get_snapped_to_logical_pos(self, evt):
712 scale = self.canvas.layers['grid'].mapscale
713 dc = wx.ClientDC( self.canvas )
714 self.canvas.PrepareDC( dc )
715 dc.SetUserScale(scale,scale)
716 pos = evt.GetLogicalPosition(dc)
717 if self.canvas.layers['grid'].snap:
718 size = self.canvas.layers['grid'].unit_size
719 pos.x = int((pos.x+size/2)/size)*size
720 pos.y = int((pos.y+size/2)/size)*size
721 return pos
722
723 def draw_temporary_cone(self, evt):
724 scale = self.canvas.layers['grid'].mapscale
725 dc = wx.ClientDC( self.canvas )
726 self.canvas.PrepareDC( dc )
727 dc.SetUserScale(scale,scale)
728 pos = evt.GetLogicalPosition(dc)
729 pos2 = self.get_snapped_to_logical_pos(evt)
730 size = self.canvas.layers['grid'].unit_size #60
731 if abs(pos.x-pos2.x)<=size/10 and abs(pos.y-pos2.y)<=size/10:
732 pos = pos2
733 radius = int(int(self.radius.GetValue())/5)
734 curve = self.calculate_circle(self.cone_start, radius, size)
735 edge1 = []
736 edge2 = []
737 horizontal_inc = wx.Point(size,0)
738 if pos.x <= self.cone_start.x:
739 horizontal_inc = wx.Point(-size,0)
740 vertical_inc = wx.Point(0,size)
741 if pos.y <= self.cone_start.y:
742 vertical_inc = wx.Point(0,-size)
743 x_diff = float(pos.x - self.cone_start.x)
744 y_diff = float(pos.y - self.cone_start.y)
745 ratio = float(1)
746 if abs(x_diff) <= abs(y_diff):
747 ratio = x_diff / y_diff
748 elif abs(y_diff) < abs(x_diff):
749 ratio = -(y_diff / x_diff)
750 horizontal_inc,vertical_inc = vertical_inc,horizontal_inc #swap
751 horizontal_rotated = wx.Point(-horizontal_inc.y, horizontal_inc.x)
752 vertical_rotated = wx.Point(-vertical_inc.y, vertical_inc.x)
753 on_diagonal = True
754 for v in range(radius):
755 x = int(floor((v+1)*ratio)) - int(floor(v*ratio))
756 if x < 0 and on_diagonal:
757 edge1 += [vertical_inc]
758 edge1 += [horizontal_inc]
759 elif x != 0:
760 edge1 += [horizontal_inc]
761 edge1 += [vertical_inc]
762 else:
763 edge1 += [vertical_inc]
764 on_diagonal = False
765 on_diagonal = True
766 for v in range(radius):
767 x = int(floor((v+1)*(-ratio))) - int(floor(v*(-ratio)))
768 if x < 0 and on_diagonal:
769 edge2 += [vertical_rotated]
770 edge2 += [horizontal_rotated]
771 elif x != 0:
772 edge2 += [horizontal_rotated]
773 edge2 += [vertical_rotated]
774 else:
775 edge2 += [vertical_rotated]
776 on_diagonal = False
777 p = wx.Point(0,0)
778 string1 = self.point_to_string(p, [self.cone_start])
779 string1 += self.point_to_string(p, edge1)
780 p = wx.Point(0,0)
781 string2 = self.point_to_string(p, [self.cone_start])
782 string2 += self.point_to_string(p, edge2)
783
784 # truncate the edges where they meet the curve
785 pointArray = string1.split(";")
786 string1 = ""
787 for p in pointArray:
788 p += ";"
789 index = (";"+curve).find(";"+p)
790 if index >= 0:
791 # found intersection, start circle at intersection
792 curve = curve[index:]+curve[:index]
793 break
794 string1 += p
795
796 # truncate the edges where they meet the curve
797 pointArray = string2.split(";")
798 string2 = ""
799 for p in pointArray:
800 p += ";"
801 string2 = p + string2 #backwards
802 index = (";"+curve).find(";"+p)
803 if index >= 0:
804 # found intersection, end circle at intersection
805 curve = curve[:index]
806 break
807 curve = string1 + curve + string2
808
809 # add the lines that define the real cone edges
810 sz = sqrt(x_diff*x_diff + y_diff*y_diff)
811 x_diff = radius*size*x_diff/sz
812 y_diff = radius*size*y_diff/sz
813 pos = wx.Point(self.cone_start.x+x_diff, self.cone_start.y+y_diff)
814 qos = wx.Point(self.cone_start.x-y_diff, self.cone_start.y+x_diff)# 90 degree rotation
815 curve = `pos.x`+","+`pos.y`+";" + curve + `qos.x`+","+`qos.y`+";"
816 if(self.temp_circle):
817 self.canvas.layers['whiteboard'].del_temp_line(self.temp_circle)
818 if self.selected == self.temp_circle:
819 self.selected = None
820 self.temp_circle = self.canvas.layers['whiteboard'].add_temp_line(curve)
821 self.canvas.Refresh(True)
822
823 def draw_temporary_circle(self, evt):
824 session = self.canvas.frame.session
825 if (session.my_role() != session.ROLE_GM) and (session.my_role()!=session.ROLE_PLAYER) and (session.use_roles()):
826 open_rpg.get_component("chat").InfoPost("You must be either a player or GM to use this feature")
827 self.canvas.Refresh(False)
828 return
829 pos = self.get_snapped_to_logical_pos(evt)
830 size = self.canvas.layers['grid'].unit_size #60
831 radius = int(int(self.radius.GetValue())/5)
832 center = wx.Point(pos.x, pos.y+size*radius)
833 curve = self.calculate_circle(center, radius, size)
834 if(self.temp_circle):
835 self.canvas.layers['whiteboard'].del_temp_line(self.temp_circle)
836 self.selected = None
837 self.temp_circle = self.canvas.layers['whiteboard'].add_temp_line(curve)
838 self.drawing = True
839 self.canvas.Refresh(True)
840
841 def calculate_circle(self, center, radius, size):
842 pos = wx.Point(center.x, center.y-size*radius)
843 r = int(radius+2/3)
844 right = wx.Point(size,0)
845 left = wx.Point(-size,0)
846 up = wx.Point(0,-size)
847 down = wx.Point(0,size)
848 v1 = ([right, down, right]*r)[:radius]
849 v2 = ([down, right, down]*r)[r*3-radius:]
850 v3 = ([down, left, down]*r)[:radius]
851 v4 = ([left, down, left]*r)[r*3-radius:]
852 v5 = ([left, up, left]*r)[:radius]
853 v6 = ([up, left, up]*r)[r*3-radius:]
854 v7 = ([up, right, up]*r)[:radius]
855 v8 = ([right, up, right]*r)[r*3-radius:]
856 p = wx.Point(0,0)
857 temp_string = self.point_to_string(p, [pos])
858 temp_string += self.point_to_string(p, v1+v2+v3+v4+v5+v6+v7+v8)
859 return temp_string
860
861 def point_to_string(self, pos, vec):
862 str = ""
863 for i in range(len(vec)):
864 pos.x = pos.x + vec[i].x
865 pos.y = pos.y + vec[i].y
866 str += `pos.x` + "," + `pos.y` + ";"
867 return str
868