Mercurial > traipse_dev
view orpg/mapper/whiteboard_handler.py @ 174:ff6cbd2b7620 alpha
Traipse Alpha 'OpenRPG' {100112-00}
Traipse is a distribution of OpenRPG that is designed to be easy to
setup and go. Traipse also makes it easy for developers to work on code
without fear of sacrifice. 'Ornery-Orc' continues the trend of 'Grumpy'
and adds fixes to the code. 'Ornery-Orc's main goal is to offer more
advanced features and enhance the productivity of the user.
Update Summary (Keeping up with Beta)
New Features:
Added Bookmarks
Added 'boot' command to remote admin
Added confirmation window for sent nodes
Minor changes to allow for portability to an OpenSUSE linux OS
Miniatures Layer pop up box allows users to turn off Mini labels, from
FlexiRPG
Zoom Mouse plugin added
Images added to Plugin UI
Switching to Element Tree
Map efficiency, from FlexiRPG
Added Status Bar to Update Manager
New TrueDebug Class in orpg_log (See documentation for usage)
Portable Mercurial
Tip of the Day added, from Core and community
New Reference Syntax added for custom PC sheets
New Child Reference for gametree
New Parent Reference for gametree
New Gametree Recursion method, mapping, context sensitivity, and
effeciency..
New Features node with bonus nodes and Node Referencing help added
Dieroller structure from Core
Added 7th Sea die roller method; ie [7k3] =
[7d10.takeHighest(3).open(10)]
New 'Mythos' System die roller added
Added new vs. die roller method for WoD; ie [3v3] = [3d10.vs(3)].
Includes support for Mythos roller
New EZ_Tree Reference system. Push a button, Traipse the tree, get a
reference (Alpha!!)
Fixes:
Fix to Text based Server
Fix to Remote Admin Commands
Fix to Pretty Print, from Core
Fix to Splitter Nodes not being created
Fix to massive amounts of images loading, from Core
Fix to Map from gametree not showing to all clients
Fix to gametree about menus
Fix to Password Manager check on startup
Fix to PC Sheets from tool nodes. They now use the tabber_panel
Fixed Whiteboard ID to prevent random line or text deleting.
Modified ID's to prevent non updated clients from ruining the fix.
default_manifest.xml renamed to default_upmana.xml
Fix to Update Manager; cleaner clode for saved repositories
Fixes made to Settings Panel and no reactive settings when Ok is pressed
Fixes to Alternity roller's attack roll. Uses a simple Tuple instead of
a Splice
Fix to Use panel of Forms and Tabbers. Now longer enters design mode
author | sirebral |
---|---|
date | Tue, 12 Jan 2010 19:38:11 -0600 |
parents | 06f10429eedc |
children | b633f4c64aae 81d0bfd5e800 |
line wrap: on
line source
# 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: mapper/whiteboard_hander.py # Author: OpenRPG Team # Maintainer: # Version: # $Id: whiteboard_handler.py,v 1.37 2007/03/09 14:11:56 digitalxero Exp $ # # Description: Whiteboard layer handler # __version__ = "$Id: whiteboard_handler.py,v 1.37 2007/03/09 14:11:56 digitalxero Exp $" from base_handler import * from math import floor, sqrt class whiteboard_handler(base_layer_handler): def __init__(self, parent, id, canvas): self.drawing_mode = 'Freeform' self.line_string = "0,0;" self.drawing = False self.upperleft = wx.Point(0,0) self.lowerright = wx.Point(0,0) #polyline drawing vars self.polypoints = 0 self.lastpoint = None self.selected = None #text drawing vars self.style = str(wx.NORMAL) self.weight = str(wx.NORMAL) self.pointsize = str(12) self.text_selected_item = None #self.r_h = RGBHex() base_layer_handler.__init__(self, parent, id, canvas) self.build_text_properties_menu() self.wb = self.canvas.layers['whiteboard'] self.temp_circle = None self.cone_start = None self.temp_edge1 = None self.temp_edge2 = None def build_ctrls(self): base_layer_handler.build_ctrls(self) self.color_button = wx.Button(self, wx.ID_ANY, "Pen Color", style=wx.BU_EXACTFIT) self.color_button.SetBackgroundColour(wx.BLACK) self.color_button.SetForegroundColour(wx.WHITE) self.drawmode_ctrl = wx.Choice(self, wx.ID_ANY, choices = ["Freeform", "Polyline","Text", "Cone", "Circle"]) self.drawmode_ctrl.SetSelection(0) #always start showing "Freeform" self.radius = wx.TextCtrl(self, wx.ID_ANY, size=(32,-1) ) self.radius.SetValue("15") self.live_refresh = wx.CheckBox(self, wx.ID_ANY, " Live Refresh") self.live_refresh.SetValue(True) self.widthList= wx.Choice(self, wx.ID_ANY, size= wx.Size(40, 20), choices=['1','2','3','4','5','6','7','8','9','10']) self.widthList.SetSelection(0) self.sizer.Add(wx.StaticText(self, wx.ID_ANY, "Line Width: "),0,wx.ALIGN_CENTER) self.sizer.Add(self.widthList, 0, wx.EXPAND) self.sizer.Add(wx.Size(10,25)) self.sizer.Add(wx.StaticText(self, wx.ID_ANY, "Drawing Mode: "),0,wx.ALIGN_CENTER) self.sizer.Add(self.drawmode_ctrl, 0, wx.EXPAND) self.sizer.Add(wx.StaticText(self, -1, " Radius: "), 0, wx.ALIGN_CENTER|wx.ALL, 3) self.sizer.Add(self.radius, 0, wx.EXPAND|wx.ALL, 2) self.sizer.Add(wx.Size(10,25)) self.sizer.Add(self.live_refresh, 0, wx.EXPAND) self.sizer.Add(wx.Size(20,25)) self.sizer.Add(self.color_button, 0, wx.EXPAND) self.sizer.Add(wx.Size(20,25)) self.Bind(wx.EVT_MOTION, self.on_motion) self.Bind(wx.EVT_CHOICE, self.check_draw_mode, self.drawmode_ctrl) self.Bind(wx.EVT_BUTTON, self.on_pen_color, self.color_button) self.Bind(wx.EVT_CHOICE, self.on_pen_width, self.widthList) def build_text_properties_menu(self, label="Text Properties"): self.text_properties_dialog = wx.Dialog(self, -1, "Text Properties", name = "Text Properties") self.text_props_sizer = wx.BoxSizer(wx.VERTICAL) okay_boxer = wx.BoxSizer(wx.HORIZONTAL) okay_button = wx.Button(self.text_properties_dialog, wx.ID_OK, "APPLY") cancel_button = wx.Button(self.text_properties_dialog, wx.ID_CANCEL,"CANCEL") okay_boxer.Add(okay_button, 1, wx.ALIGN_LEFT) okay_boxer.Add(wx.Size(10,10)) okay_boxer.Add(cancel_button, 1, wx.ALIGN_RIGHT) self.txt_boxer = wx.BoxSizer(wx.HORIZONTAL) self.txt_static = wx.StaticText(self.text_properties_dialog, -1, "Text: ") self.text_control = wx.TextCtrl(self.text_properties_dialog, wx.ID_ANY, "", name = "Text: ") self.txt_boxer.Add(self.txt_static,0,wx.EXPAND) self.txt_boxer.Add(wx.Size(10,10)) self.txt_boxer.Add(self.text_control,1,wx.EXPAND) self.point_boxer = wx.BoxSizer(wx.HORIZONTAL) self.point_static = wx.StaticText(self.text_properties_dialog, -1, "Text Size: ") self.point_control = wx.SpinCtrl(self.text_properties_dialog, wx.ID_ANY, value = "12", min = 1, initial = 12, name = "Font Size: ") self.point_boxer.Add(self.point_static,1,wx.EXPAND) self.point_boxer.Add(wx.Size(10,10)) self.point_boxer.Add(self.point_control,0,wx.EXPAND) self.text_color_control = wx.Button(self.text_properties_dialog, wx.ID_ANY, "TEXT COLOR",style=wx.BU_EXACTFIT) self.weight_control = wx.RadioBox(self.text_properties_dialog, wx.ID_ANY, "Weight", choices = ["Normal","Bold"]) self.style_control = wx.RadioBox(self.text_properties_dialog, wx.ID_ANY, "Style", choices = ["Normal", "Italic"]) self.text_props_sizer.Add(self.txt_boxer,0,wx.EXPAND) self.text_props_sizer.Add(self.point_boxer,0, wx.EXPAND) self.text_props_sizer.Add(self.weight_control,0, wx.EXPAND) self.text_props_sizer.Add(self.style_control,0, wx.EXPAND) self.text_props_sizer.Add(self.text_color_control, 0, wx.EXPAND) self.text_props_sizer.Add(wx.Size(10,10)) self.text_props_sizer.Add(okay_boxer,0, wx.EXPAND) self.text_props_sizer.Fit(self) self.text_properties_dialog.SetSizer(self.text_props_sizer) self.text_properties_dialog.Fit() self.text_properties_dialog.Bind(wx.EVT_BUTTON, self.on_text_color, self.text_color_control) self.text_properties_dialog.Bind(wx.EVT_BUTTON, self.on_text_properties, okay_button) #self.text_properties_dialog.Destroy() def build_menu(self, label = "Whiteboard"): base_layer_handler.build_menu(self,label) self.main_menu.AppendSeparator() item = wx.MenuItem(self.main_menu, wx.ID_ANY, "&Change Pen Color", "Change Pen Color") self.canvas.Bind(wx.EVT_MENU, self.on_pen_color, item) self.main_menu.AppendItem(item) item = wx.MenuItem(self.main_menu, wx.ID_ANY, "Delete &All Lines", "Delete All Lines") self.canvas.Bind(wx.EVT_MENU, self.delete_all_lines, item) self.main_menu.AppendItem(item) item = wx.MenuItem(self.main_menu, wx.ID_ANY, "&Undo Last Deleted Line", "Undo Last Deleted Line") self.canvas.Bind(wx.EVT_MENU, self.undo_line, item) self.main_menu.AppendItem(item) self.line_menu = wx.Menu("Whiteboard Line") self.line_menu.SetTitle("Whiteboard Line") item = wx.MenuItem(self.line_menu, wx.ID_ANY, "&Remove", "Remove") self.canvas.Bind(wx.EVT_MENU, self.on_line_menu_item, item) self.line_menu.AppendItem(item) self.text_menu = wx.Menu("Whiteboard Text") self.text_menu.SetTitle("Whiteboard Text") item = wx.MenuItem(self.text_menu, wx.ID_ANY, "&Properties", "Properties") self.canvas.Bind(wx.EVT_MENU, self.get_text_properties, item) self.text_menu.AppendItem(item) item = wx.MenuItem(self.text_menu, wx.ID_ANY, "&Remove", "Remove") self.canvas.Bind(wx.EVT_MENU, self.on_text_menu_item, item) self.text_menu.AppendItem(item) def do_line_menu(self,pos): self.canvas.PopupMenu(self.line_menu, pos) def item_selected(self,evt): item = evt.GetId() self.item_selection = self.selection_list[item] def on_text_properties(self,evt): text_string = self.text_control.GetValue() if self.style_control.GetStringSelection() == 'Normal': style = wx.NORMAL else: style = wx.ITALIC if self.weight_control.GetStringSelection() == 'Normal': weight = wx.NORMAL else: weight = wx.BOLD point = str(self.point_control.GetValue()) c = self.text_color_control.GetForegroundColour() color = self.canvas.layers['whiteboard'].r_h.hexstring(c.Red(), c.Green(), c.Blue()) self.text_selected_item.set_text_props(text_string, style, point, weight, color) self.text_to_xml() self.text_properties_dialog.Show(False) self.text_selected_item.selected = False self.text_selected_item.isUpdated = True self.text_selected_item = None def on_text_color(self,evt): dlg = wx.ColourDialog(self) if dlg.ShowModal() == wx.ID_OK: c = dlg.GetColourData() self.text_color_control.SetForegroundColour(c.GetColour()) dlg.Destroy() def text_to_xml(self): xml_str = "<map><whiteboard>" xml_str += self.text_selected_item.toxml('update') xml_str += "</whiteboard></map>" self.canvas.frame.session.send(xml_str) self.canvas.Refresh(False) def get_text_properties(self, event=None): self.text_color_control.SetForegroundColour(self.text_selected_item.textcolor) self.text_control.SetValue(self.text_selected_item.text_string) self.point_control.SetValue(int(self.text_selected_item.pointsize)) if int(self.text_selected_item.weight) == wx.NORMAL: self.weight_control.SetSelection(0) else: self.weight_control.SetSelection(1) if int(self.text_selected_item.style) == wx.NORMAL: self.style_control.SetSelection(0) else: self.style_control.SetSelection(1) self.text_properties_dialog.Center() self.text_properties_dialog.Show(True) def do_text_menu(self, pos, items=None): if items == None: self.canvas.PopupMenu(self.text_menu) else: menu = wx.Menu() self.ItemList = items self.tmpPos = pos for i in xrange(len(items)): menu.Append(i+1, items[i].text_string) self.canvas.Bind(wx.EVT_MENU, self.onItemSelect, id=i+1) self.canvas.PopupMenu(menu) return def onItemSelect(self, evt): id = evt.GetId()-1 self.text_selected_item = self.ItemList[id] self.text_selected_item.selected = True if self.tmpPos == 'right': self.canvas.PopupMenu(self.text_menu) self.ItemList = None self.tmpPos = None def on_right_down(self,evt): line = 0 scale = self.canvas.layers['grid'].mapscale dc = wx.ClientDC(self.canvas) self.canvas.PrepareDC(dc) dc.SetUserScale(scale,scale) pos = evt.GetLogicalPosition(dc) if self.drawing_mode == 'Text': self.on_text_right_down(evt, dc) elif self.drawing and ((self.drawing_mode == 'Circle') or (self.drawing_mode == 'Cone')): self.check_draw_mode() self.drawing = False elif (self.drawing_mode == 'Freeform') or (self.drawing_mode == 'Polyline') or (self.drawing_mode == 'Circle') or (self.drawing_mode == 'Cone'): line_list = self.canvas.layers['whiteboard'].find_line(pos) if line_list: self.sel_rline = self.canvas.layers['whiteboard'].get_line_by_id(line_list.id) if self.sel_rline: self.do_line_menu(evt.GetPosition()) self.canvas.Refresh(False) else: base_layer_handler.on_right_down(self,evt) else: base_layer_handler.on_right_down(self,evt) del dc def on_pen_color(self,evt): data = wx.ColourData() data.SetChooseFull(True) dlg = wx.ColourDialog(self.canvas, data) if dlg.ShowModal() == wx.ID_OK: data = dlg.GetColourData() color = data.GetColour() self.canvas.layers['whiteboard'].setcolor(color) self.color_button.SetBackgroundColour(color) dlg.Destroy() def on_pen_width(self,evt): width = int(self.widthList.GetStringSelection()) self.canvas.layers['whiteboard'].setwidth(width) def undo_line(self,evt): session = self.canvas.frame.session if (session.my_role() != session.ROLE_GM) and (session.use_roles()): self.top_frame.openrpg.get("chat").InfoPost("You must be a GM to use this feature") return self.canvas.layers['whiteboard'].undo_line() dc = self.create_dc() self.un_highlight(dc) self.selected = None del dc def delete_all_lines(self,evt): session = self.canvas.frame.session if (session.my_role() != session.ROLE_GM) and (session.use_roles()): component.get("chat").InfoPost("You must be a GM to use this feature") return 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) if dlg.ShowModal() != wx.ID_YES: return self.canvas.layers['whiteboard'].del_all_lines() dc = self.create_dc() self.un_highlight(dc) self.selected = None del dc def on_line_menu_item(self, evt): dc = self.create_dc() self.un_highlight(dc) self.canvas.layers['whiteboard'].del_line(self.sel_rline) self.selected = None del dc def on_text_menu_item(self, evt): dc = self.create_dc() self.un_highlight(dc) self.canvas.layers['whiteboard'].del_text(self.selected) self.selected = None del dc # Check Draw Mode # Queries the GUI to see what mode to draw in # 05-09-2003 Snowdog def check_draw_mode(self, evt=None): self.drawing_mode = self.drawmode_ctrl.GetStringSelection() #because mode can be changed while a polyline is being created #clear the current linestring and reset the polyline data self.upperleft.x = self.upperleft.y = 0 self.lowerright.x = self.lowerright.y = 0 self.lastpoint = None #because the end check function is not called we must force its lastpoint var to None again self.polypoints = 0 self.line_string = "0,0;" if self.temp_circle: self.canvas.layers['whiteboard'].del_temp_line(self.temp_circle) if self.selected == self.temp_circle: self.selected = None self.canvas.Refresh(True) self.temp_circle = None self.cone_start = None # Altered on_left_up to toggle between # drawing modes freeform vs polyline # 05-09-2003 Snowdog def on_left_down(self,evt): if not self.drawing: self.check_draw_mode() if self.drawing_mode == 'Freeform': pass elif self.drawing_mode == 'Polyline': self.polyline_add_point( evt ) elif self.drawing_mode == 'Text': self.on_text_left_down(evt) elif self.drawing_mode == 'Cone': if self.cone_start == None: self.on_start_cone(evt) else: self.draw_temporary_cone(evt) elif self.drawing_mode == 'Circle': self.draw_temporary_circle(evt) # Added handling for double clicks within the map # 05-09-2003 Snowdog def on_left_dclick(self, evt): if self.drawing_mode == 'Freeform': pass #Freeform mode ignores the double click elif self.drawing_mode == 'Polyline': self.polyline_last_point( evt ) elif self.drawing_mode == 'Text': pass elif self.drawing_mode == 'Circle' or self.drawing_mode == 'Cone': self.canvas.layers['whiteboard'].del_temp_line(self.temp_circle) #pointArray = self.temp_circle.line_string.split(";") self.canvas.layers['whiteboard'].add_line(self.temp_circle.line_string) self.temp_circle = None self.cone_start = None self.drawing = False # Altered on_left_up to toggle between # drawing modes freeform vs polyline # 05-09-2003 Snowdog def on_left_up(self,evt): if self.drawing_mode == 'Freeform': self.on_freeform_left_up(evt) elif self.drawing_mode == 'Polyline': pass elif self.drawing_mode == 'Text': pass # Altered on_left_up to toggle between # drawing modes freeform vs polyline # 05-09-2003 Snowdog def on_motion(self,evt): session = self.canvas.frame.session if (session.my_role() != session.ROLE_GM) \ and (session.my_role()!=session.ROLE_PLAYER) \ and (session.use_roles()): return if self.drawing_mode == 'Freeform': if evt.m_leftDown: self.freeform_motion(evt) elif self.drawing_mode == 'Polyline': if self.drawing: self.polyline_preview( evt ) dc = self.create_dc() pos = evt.GetLogicalPosition(dc) hit = self.canvas.layers['whiteboard'].hit_test_lines(pos,dc) if hit: self.highlight(hit,dc) else: self.un_highlight(dc) hit = self.canvas.layers['whiteboard'].hit_test_text(pos,dc) if hit: self.highlight(hit,dc) else: self.un_highlight(dc) del dc def create_dc(self): scale = self.canvas.layers['grid'].mapscale dc = wx.ClientDC( self.canvas ) self.canvas.PrepareDC( dc ) dc.SetUserScale(scale,scale) return dc def highlight(self,hit,dc): if self.selected: self.selected.highlight(False) self.selected.draw(self.wb,dc) self.selected = hit[0] self.selected.highlight() self.selected.draw(self.wb,dc) def un_highlight(self,dc): if self.selected: self.selected.highlight(False) self.selected.draw(self.wb,dc) # Polyline Add Point # adds a new point to the polyline # 05-09-2003 Snowdog def polyline_add_point(self, evt): scale = self.canvas.layers['grid'].mapscale dc = wx.ClientDC( self.canvas ) self.canvas.PrepareDC( dc ) dc.SetUserScale(scale,scale) pos = evt.GetLogicalPosition(dc) #reset the bounding points if pos.x < self.upperleft.x: self.upperleft.x = pos.x elif pos.x > self.lowerright.x: self.lowerright.x = pos.x if pos.y < self.upperleft.y: self.upperleft.y = pos.y elif pos.y > self.lowerright.y: self.lowerright.y = pos.y #if this point doens't end the line #add a new point into the line string if not self.polyline_end_check( pos ): if self.drawing == True: self.polypoints += 1 #add one to the point counter. self.line_string += `pos.x` + "," + `pos.y` + ";" self.canvas.layers['whiteboard'].draw_working_line(dc,self.line_string) else: #start of line... self.polypoints += 1 #add one to the point counter. self.line_string = `pos.x` + "," + `pos.y` + ";" self.upperleft.x = pos.x self.upperleft.y = pos.y self.lowerright.x = pos.x self.lowerright.y = pos.y self.drawing = True else: #end of line. Send and reset vars for next line self.drawing = False if self.polypoints < 2: pass else: #have enough points to create valid line #check to role to make sure user can draw at all.... session = self.canvas.frame.session if (session.my_role() != session.ROLE_GM) and (session.my_role()!=session.ROLE_PLAYER) and (session.use_roles()): component.get("chat").InfoPost("You must be either a player or GM to use this feature") self.canvas.Refresh(False) else: line = self.canvas.layers['whiteboard'].add_line(self.line_string,self.upperleft,self.lowerright) #resetting variables for next line self.upperleft.x = self.upperleft.y = 0 self.lowerright.x = self.lowerright.y = 0 self.polypoints = 0 self.line_string = "0,0;" # Polyline Last Point # adds a final point to the polyline and ends it # 05-09-2003 Snowdog def polyline_last_point(self, evt): #if we haven't started a line already. Ignore the click if self.drawing != True: return scale = self.canvas.layers['grid'].mapscale dc = wx.ClientDC( self.canvas ) self.canvas.PrepareDC( dc ) dc.SetUserScale(scale,scale) pos = evt.GetLogicalPosition(dc) #reset the bounding points if pos.x < self.upperleft.x: self.upperleft.x = pos.x elif pos.x > self.lowerright.x: self.lowerright.x = pos.x if pos.y < self.upperleft.y: self.upperleft.y = pos.y elif pos.y > self.lowerright.y: self.lowerright.y = pos.y self.polypoints += 1 #add one to the point counter. self.line_string += `pos.x` + "," + `pos.y` + ";" self.canvas.layers['whiteboard'].draw_working_line(dc,self.line_string) #end of line. Send and reset vars for next line self.drawing = False if self.polypoints < 2: pass else: #have enough points to create valid line #check to role to make sure user can draw at all.... session = self.canvas.frame.session if (session.my_role() != session.ROLE_GM) and (session.my_role()!=session.ROLE_PLAYER) and (session.use_roles()): component.get("chat").InfoPost("You must be either a player or GM to use this feature") self.canvas.Refresh(False) else: line = self.canvas.layers['whiteboard'].add_line(self.line_string,self.upperleft,self.lowerright) #resetting variables for next line self.upperleft.x = self.upperleft.y = 0 self.lowerright.x = self.lowerright.y = 0 self.lastpoint = None #becuase the end check function is not called we must force its lastpoint var to None again self.polypoints = 0 self.line_string = "0,0;" # Polyline End Check # checks to see if a double click has occured # a second click on the LAST polyline point # (or very close proximity) should cause the # polyline even to complete and send # 05-09-2003 Snowdog def polyline_end_check(self, pos): # check to see if the position of the give point is within POLYLINE_END_TOLERANCE # if it is then the line has been completed and should be sent to the map just like # the original freeform version is. A line with fewer than 2 points should be ignored x_in = y_in = 0 tol = 5 #first point check if type(self.lastpoint) == type(None): self.lastpoint = wx.Point(pos.x,pos.y); return 0 #not end of line if ((self.lastpoint.x -tol) <= pos.x <= (self.lastpoint.x)): x_in = 1 if ((self.lastpoint.y -tol) <= pos.y <= (self.lastpoint.y)): y_in = 1 if x_in and y_in: self.lastpoint = None; return 1 #if we've reached here the point is NOT a terminal point. Reset the lastpoint and return False self.lastpoint.x = pos.x self.lastpoint.y = pos.y return 0 # Polyline Preview # display a temporary/momentary line to the user # from the last point to mouse position # 05-09-2003 Snowdog def polyline_preview(self, evt): if self.drawing != True: return if self.live_refresh.GetValue() == 0: return scale = self.canvas.layers['grid'].mapscale dc = wx.ClientDC( self.canvas ) self.canvas.PrepareDC( dc ) dc.SetUserScale(scale,scale) pos = evt.GetLogicalPosition(dc) #reset the bounding points if pos.x < self.upperleft.x: self.upperleft.x = pos.x elif pos.x > self.lowerright.x: self.lowerright.x = pos.x if pos.y < self.upperleft.y: self.upperleft.y = pos.y elif pos.y > self.lowerright.y: self.lowerright.y = pos.y #redraw the line with a line connected to the cursor temp_string = self.line_string temp_string += `pos.x` + "," + `pos.y` + ";" self.canvas.layers['whiteboard'].draw_working_line(dc,temp_string) self.canvas.Refresh(True) # moved original on_motion to this function # to allow alternate drawing method to be used # 05-09-2003 Snowdog def freeform_motion(self, evt): #if not self.drawing: # return scale = self.canvas.layers['grid'].mapscale dc = wx.ClientDC( self.canvas ) self.canvas.PrepareDC( dc ) dc.SetUserScale(scale,scale) pos = evt.GetLogicalPosition(dc) if pos.x < self.upperleft.x: self.upperleft.x = pos.x elif pos.x > self.lowerright.x: self.lowerright.x = pos.x if pos.y < self.upperleft.y: self.upperleft.y = pos.y elif pos.y > self.lowerright.y: self.lowerright.y = pos.y if evt.m_leftDown: if self.drawing == True: self.line_string += `pos.x` + "," + `pos.y` + ";" self.canvas.layers['whiteboard'].draw_working_line(dc,self.line_string) else: self.line_string = `pos.x` + "," + `pos.y` + ";" self.upperleft.x = pos.x self.upperleft.y = pos.y self.lowerright.x = pos.x self.lowerright.y = pos.y self.drawing = True del dc # moved original on_left_up to this function # to allow alternate drawing method to be used # 05-09-2003 Snowdog def on_freeform_left_up(self,evt): if self.drawing == True: self.drawing = False session = self.canvas.frame.session if (session.my_role() != session.ROLE_GM) and (session.my_role()!=session.ROLE_PLAYER) and (session.use_roles()): component.get("chat").InfoPost("You must be either a player or GM to use this feature") self.canvas.Refresh(False) return line = self.canvas.layers['whiteboard'].add_line(self.line_string,self.upperleft,self.lowerright) dc = self.create_dc() for m in range(30): line.highlight() line.draw(self.wb,dc) line.highlight(False) line.draw(self.wb,dc) del dc self.upperleft.x = self.upperleft.y = 0 self.lowerright.x = self.lowerright.y = 0 def on_text_left_down(self, evt): session = self.canvas.frame.session if (session.my_role() != session.ROLE_GM) and (session.my_role()!=session.ROLE_PLAYER) and (session.use_roles()): component.get("chat").InfoPost("You must be either a player or GM to use this feature") self.canvas.Refresh(False) return scale = self.canvas.layers['grid'].mapscale dc = wx.ClientDC( self.canvas ) self.canvas.PrepareDC( dc ) dc.SetUserScale(scale,scale) pos = evt.GetLogicalPosition(dc) test_text = self.canvas.layers['whiteboard'].hit_test_text(pos,dc) if len(test_text) > 0: if len(test_text) > 1: self.do_text_menu('left', test_text) else: self.text_selected_item = test_text[0] self.text_selected_item.selected = True self.canvas.Refresh(True) else: if self.text_selected_item == None: dlg = wx.TextEntryDialog(self,"Text to add to whiteboard", caption="Enter text",defaultValue=" ") if dlg.ShowModal() == wx.ID_OK: text_string = dlg.GetValue() self.canvas.layers['whiteboard'].add_text(text_string,pos, self.style, self.pointsize, self.weight, self.canvas.layers['whiteboard'].color) else: self.text_selected_item.posx = pos.x self.text_selected_item.posy = pos.y self.text_selected_item.isUpdated = True self.text_to_xml() self.text_selected_item.selected = False self.text_selected_item = None del dc def on_text_right_down(self, evt, dc): session = self.canvas.frame.session if (session.my_role() != session.ROLE_GM) and (session.my_role()!=session.ROLE_PLAYER) and (session.use_roles()): component.get("chat").InfoPost("You must be either a player or GM to use this feature") self.canvas.Refresh(False) return pos = evt.GetLogicalPosition(dc) test_text = self.canvas.layers['whiteboard'].hit_test_text(pos, dc) if len(test_text) > 0: if len(test_text) > 1: self.do_text_menu('right', test_text) else: self.text_selected_item = test_text[0] self.do_text_menu('right') def on_start_cone(self, evt): session = self.canvas.frame.session if (session.my_role() != session.ROLE_GM) and (session.my_role()!=session.ROLE_PLAYER) and (session.use_roles()): component.get("chat").InfoPost("You must be either a player or GM to use this feature") self.canvas.Refresh(False) return self.cone_start = self.get_snapped_to_logical_pos(evt) self.drawing = True def get_snapped_to_logical_pos(self, evt): scale = self.canvas.layers['grid'].mapscale dc = wx.ClientDC( self.canvas ) self.canvas.PrepareDC( dc ) dc.SetUserScale(scale,scale) pos = evt.GetLogicalPosition(dc) if self.canvas.layers['grid'].snap: size = self.canvas.layers['grid'].unit_size pos.x = int((pos.x+size/2)/size)*size pos.y = int((pos.y+size/2)/size)*size return pos def draw_temporary_cone(self, evt): scale = self.canvas.layers['grid'].mapscale dc = wx.ClientDC( self.canvas ) self.canvas.PrepareDC( dc ) dc.SetUserScale(scale,scale) pos = evt.GetLogicalPosition(dc) pos2 = self.get_snapped_to_logical_pos(evt) size = self.canvas.layers['grid'].unit_size #60 if abs(pos.x-pos2.x)<=size/10 and abs(pos.y-pos2.y)<=size/10: pos = pos2 radius = int(int(self.radius.GetValue())/5) curve = self.calculate_circle(self.cone_start, radius, size) edge1 = [] edge2 = [] horizontal_inc = wx.Point(size,0) if pos.x <= self.cone_start.x: horizontal_inc = wx.Point(-size,0) vertical_inc = wx.Point(0,size) if pos.y <= self.cone_start.y: vertical_inc = wx.Point(0,-size) x_diff = float(pos.x - self.cone_start.x) y_diff = float(pos.y - self.cone_start.y) ratio = float(1) if abs(x_diff) <= abs(y_diff): ratio = x_diff / y_diff elif abs(y_diff) < abs(x_diff): ratio = -(y_diff / x_diff) horizontal_inc,vertical_inc = vertical_inc,horizontal_inc #swap horizontal_rotated = wx.Point(-horizontal_inc.y, horizontal_inc.x) vertical_rotated = wx.Point(-vertical_inc.y, vertical_inc.x) on_diagonal = True for v in range(radius): x = int(floor((v+1)*ratio)) - int(floor(v*ratio)) if x < 0 and on_diagonal: edge1 += [vertical_inc] edge1 += [horizontal_inc] elif x != 0: edge1 += [horizontal_inc] edge1 += [vertical_inc] else: edge1 += [vertical_inc] on_diagonal = False on_diagonal = True for v in range(radius): x = int(floor((v+1)*(-ratio))) - int(floor(v*(-ratio))) if x < 0 and on_diagonal: edge2 += [vertical_rotated] edge2 += [horizontal_rotated] elif x != 0: edge2 += [horizontal_rotated] edge2 += [vertical_rotated] else: edge2 += [vertical_rotated] on_diagonal = False p = wx.Point(0,0) string1 = self.point_to_string(p, [self.cone_start]) string1 += self.point_to_string(p, edge1) p = wx.Point(0,0) string2 = self.point_to_string(p, [self.cone_start]) string2 += self.point_to_string(p, edge2) # truncate the edges where they meet the curve pointArray = string1.split(";") string1 = "" for p in pointArray: p += ";" index = (";"+curve).find(";"+p) if index >= 0: # found intersection, start circle at intersection curve = curve[index:]+curve[:index] break string1 += p # truncate the edges where they meet the curve pointArray = string2.split(";") string2 = "" for p in pointArray: p += ";" string2 = p + string2 #backwards index = (";"+curve).find(";"+p) if index >= 0: # found intersection, end circle at intersection curve = curve[:index] break curve = string1 + curve + string2 # add the lines that define the real cone edges sz = sqrt(x_diff*x_diff + y_diff*y_diff) x_diff = radius*size*x_diff/sz y_diff = radius*size*y_diff/sz pos = wx.Point(self.cone_start.x+x_diff, self.cone_start.y+y_diff) qos = wx.Point(self.cone_start.x-y_diff, self.cone_start.y+x_diff)# 90 degree rotation curve = `pos.x`+","+`pos.y`+";" + curve + `qos.x`+","+`qos.y`+";" if(self.temp_circle): self.canvas.layers['whiteboard'].del_temp_line(self.temp_circle) if self.selected == self.temp_circle: self.selected = None self.temp_circle = self.canvas.layers['whiteboard'].add_temp_line(curve) self.canvas.Refresh(True) def draw_temporary_circle(self, evt): session = self.canvas.frame.session if (session.my_role() != session.ROLE_GM) and (session.my_role()!=session.ROLE_PLAYER) and (session.use_roles()): component.get("chat").InfoPost("You must be either a player or GM to use this feature") self.canvas.Refresh(False) return pos = self.get_snapped_to_logical_pos(evt) size = self.canvas.layers['grid'].unit_size #60 radius = int(int(self.radius.GetValue())/5) center = wx.Point(pos.x, pos.y+size*radius) curve = self.calculate_circle(center, radius, size) if(self.temp_circle): self.canvas.layers['whiteboard'].del_temp_line(self.temp_circle) self.selected = None self.temp_circle = self.canvas.layers['whiteboard'].add_temp_line(curve) self.drawing = True self.canvas.Refresh(True) def calculate_circle(self, center, radius, size): pos = wx.Point(center.x, center.y-size*radius) r = int(radius+2/3) right = wx.Point(size,0) left = wx.Point(-size,0) up = wx.Point(0,-size) down = wx.Point(0,size) v1 = ([right, down, right]*r)[:radius] v2 = ([down, right, down]*r)[r*3-radius:] v3 = ([down, left, down]*r)[:radius] v4 = ([left, down, left]*r)[r*3-radius:] v5 = ([left, up, left]*r)[:radius] v6 = ([up, left, up]*r)[r*3-radius:] v7 = ([up, right, up]*r)[:radius] v8 = ([right, up, right]*r)[r*3-radius:] p = wx.Point(0,0) temp_string = self.point_to_string(p, [pos]) temp_string += self.point_to_string(p, v1+v2+v3+v4+v5+v6+v7+v8) return temp_string def point_to_string(self, pos, vec): str = "" for i in range(len(vec)): pos.x = pos.x + vec[i].x pos.y = pos.y + vec[i].y str += `pos.x` + "," + `pos.y` + ";" return str