Mercurial > traipse_dev
view orpg/map/_canvas.py @ 183:0d9b746b5751 beta
Traipse Beta 'OpenRPG' {100115-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 (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
New DieRoller portability for odd Dice
Added 7th Sea die roller; 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)].
Included for Mythos roller also
New Warhammer FRPG Die Roller (Special thanks to Puu-san for the
support)
New EZ_Tree Reference system. Push a button, Traipse the tree, get a
reference (Beta!)
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
Fix to Whiteboard ID to prevent random line or text deleting.
Fixes to Server, Remote Server, and Server GUI
Fix to Update Manager; cleaner clode for saved repositories
Fixes made to Settings Panel and now 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
Fix made Image Fetching. New fetching image and new failed image
Modified ID's to prevent non updated clients from ruining the fix.
default_manifest.xml renamed to default_upmana.xml
author | sirebral |
---|---|
date | Fri, 15 Jan 2010 23:01:42 -0600 |
parents | 4385a7d0efd1 |
children |
line wrap: on
line source
from threading import Lock import mimetypes import xml.dom.minidom as minidom import wx import orpg.dirpath from orpg.orpgCore import * from orpg.tools.rgbhex import RGBHex from _object import * from _circles import MapCircle from _text import MapText from _lines import MapLine from _grid import GridLayer from _fog import FogLayer USE_BUFFER = True if "wxMAC" in wx.PlatformInfo: USE_BUFFER = False class MapCanvas(wx.ScrolledWindow): def __init__(self, parent, openrpg): wx.ScrolledWindow.__init__(self, parent, wx.ID_ANY, style=wx.HSCROLL | wx.VSCROLL | wx.NO_FULL_REPAINT_ON_RESIZE | wx.SUNKEN_BORDER) self.openrpg = openrpg self.log = self.openrpg.get_component("log") self.xml = self.openrpg.get_component("xml") self.dir_struct = self.openrpg.get_component("dir_struct") self.validate = self.openrpg.get_component("validate") self.settings = self.openrpg.get_component("settings") self.session = self.openrpg.get_component("session") self.chat = self.openrpg.get_component("chat") self.lock = Lock() self.RGBHex = RGBHex() self.toolWnd = parent self.shift = False self.ctrl = False self.selectedObjects = [] self.overObjects = [] self._objectId = 0 self.gridLayer = GridLayer(self) self.circleLayer = MapCircle(self) self.textLayer = MapText(self) self.lineLayer = MapLine(self) self.fogLayer = FogLayer(self) self.zOrder = {} self.zOrder['tiles'] = [] self.zOrder["back"] = [] self.zOrder["front"] = [] self.bgImage = None self.bgType = 'Image' self.bgPath = None self.backgroundColor = '#008040' self.gridType = 'Square' self.gridLines = wx.SOLID self.gridSnap = True self.gridSize = 60 self.gridColor = "#000000" self.whiteboardColor = "#000000" self.zoomScale = 1.0 self.lastZoomTime = time.time() self.lastZoomScale = 1.0 self.useFog = False self.fogRegion = [] self.fogColor = "#000000" self.zoomScale = 1.0 self.lastZoomTime = time.time() self.lastZoomScale = 1.0 self.zoomTimer = wx.Timer(self) self.Bind(wx.EVT_TIMER, self.OnZoomTimer, self.zoomTimer) #self.zoomTimer.Start(1000) self.imageCache = {} self._SetSize((1000,1000)) self.Bind(wx.EVT_PAINT, self.OnPaint) self.Bind(wx.EVT_SIZE, self.OnSize) self.Bind(wx.EVT_MOUSEWHEEL, self.OnZoom) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_LEFT_DCLICK, self.OnLeftDClick) self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp) self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) self.Bind(wx.EVT_MOTION, self.OnMotion) self.Bind(wx.EVT_SCROLLWIN, self.OnScroll) self.Bind(wx.EVT_CLOSE, self.OnClose) self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnBackground) self.Bind(wx.EVT_KEY_DOWN, self.OnKey) self.Bind(wx.EVT_KEY_UP, self.OnKey) self.Bind(EVT_ENTER_OBJECT, self.EnterObject) self.Bind(EVT_LEAVE_OBJECT, self.LeaveObject) self.Bind(EVT_SELECT_OBJECT, self.ObjectSelected) self.Bind(EVT_DESELECT_OBJECT, self.ObjectDeselected) self.roleTimer = wx.Timer(self) self.Bind(wx.EVT_TIMER, self.OnRoleTimer, self.roleTimer) wx.CallAfter(self.OnSize, None) #Public API def UpdateMap(self, send=True): cdc = wx.ClientDC(self) self.PrepareDC(cdc) cdc.SetBackgroundMode(wx.TRANSPARENT) if USE_BUFFER: bdc = wx.BufferedDC(cdc, self._buffer) bdc.Clear() dc = wx.GraphicsContext.Create(bdc) else: cdc.Clear() dc = wx.GraphicsContext.Create(cdc) dc.SetPen(wx.TRANSPARENT_PEN) dc.SetBrush(wx.TRANSPARENT_BRUSH) #Draw BG Color r,g,b = self.RGBHex.rgb_tuple(self.backgroundColor) brush = wx.Brush(wx.Color(r,g,b,255)) dc.SetBrush(brush) path = dc.CreatePath() dc.PushState() path.AddRectangle(0, 0, self.size[0]+2, self.size[1]+2) dc.DrawPath(path) dc.PopState() dc.SetBrush(wx.NullBrush) #Set the Zoom dc.Scale(self.zoomScale, self.zoomScale) #Draw BG Image if self.bgImage != None: if self.bgType == 'Image': dc.DrawBitmap(self.bgImage, self.offset[0], self.offset[1], self.bgImage.GetWidth(), self.bgImage.GetHeight()) else: bmpW = self.bgImage.GetWidth() bmpH = self.bgImage.GetHeight() pos = wx.Point(self.offset[0], self.offset[1]) while pos.x < self.size[0]: dc.DrawBitmap(self.bgImage, pos.x, pos.y, self.bgImage.GetWidth(), self.bgImage.GetHeight()) while pos.y < self.size[1]: pos.y += bmpH dc.DrawBitmap(self.bgImage, pos.x, pos.y, self.bgImage.GetWidth(), self.bgImage.GetHeight()) pos.y = 0 pos.x += bmpW #Draw Tiles for tile in self.zOrder['tiles']: tile.Draw(dc) #Draw Grid self.gridLayer.Draw(dc) #Draw Objects for object in self.zOrder['back']: object.Draw(dc) zl = self.zOrder.keys() zl.remove('back') zl.remove('front') zl.remove('tiles') zl.sort() for layer in zl: for object in self.zOrder[layer]: object.Draw(dc) for object in self.zOrder['front']: object.Draw(dc) #Draw Fog if self.useFog: self.fogLayer.Draw(dc) dc.SetBrush(wx.NullBrush) dc.Scale(1/self.zoomScale, 1/self.zoomScale) if self.zoomScale != 1.0: pos = self.GetViewStart() unit = self.GetScrollPixelsPerUnit() pos = [pos[0]*unit[0],pos[1]*unit[1]] font = wx.Font(8, wx.DEFAULT, wx.NORMAL, wx.NORMAL) dc.SetFont(font, wx.BLACK) dc.DrawText("Zoom Factor: " + str(self.zoomScale), pos[0], pos[1], dc.CreateBrush(wx.WHITE_BRUSH)) def Clear(self): self._SetSize((1000,1000)) self.selectedObjects = [] self.overObjects = [] self._objectId = 0 self.bgImage = None self.bgType = 'Image' self.bgPath = None self.backgroundColor = '#008040' r, g, b = self.RGBHex.rgb_tuple(self.backgroundColor) self.toolWnd._SetColorBtn(wx.Color(r, g, b, 255), self.toolWnd.BGColorBtn) self.gridType = 'Square' self.gridLines = wx.SOLID self.gridSnap = True self.gridSize = 60 self.gridColor = "#000000" self.whiteboardColor = "#000000" r, g, b = self.RGBHex.rgb_tuple(self.whiteboardColor) self.toolWnd._SetColorBtn(wx.Color(r, g, b, 255), self.toolWnd.ColorBtn) self.zoomScale = 1.0 self.lastZoomTime = time.time() self.lastZoomScale = 1.0 self.useFog = False self.fogRegion = [] self.fogColor = "#000000" self.OnRemoveAllObjects(None) self.toolWnd.Freeze() for btn in self.toolWnd.exclusiveToolList: self.toolWnd.exclusiveToolList[btn].SetToggled(False) self.toolWnd.FogBtn.SetToggled(False) self.toolWnd.SelectorBtn.SetToggled(True) self.toolWnd.Thaw() def GetNewObjectId(self): return str(self._objectId+1) #Map Events def OnBackground(self, event): #Dont do it pass def OnPaint(self, event): if USE_BUFFER: dc = wx.PaintDC(self) self.PrepareDC(dc) dc.DrawBitmap(self._buffer, 0, 0) else: event.Skip() def OnSize(self, event): self._buffer = wx.EmptyBitmap(self.size[0], self.size[1]) self._FixScroll() wx.CallAfter(self.UpdateMap) def OnZoom(self, event): if event.GetWheelRotation() < 0: self.zoomScale -= .1 if self.zoomScale < .5: self.zoomScale = .5 else: self.lastZoomTime = time.time() self._FixScroll() self.UpdateMap() else: self.zoomScale += .1 if self.zoomScale > 1.5: self.zoomScale = 1.5 else: self.lastZoomTime = time.time() self._FixScroll() self.UpdateMap() def OnKey(self, event): self.shift = False self.ctrl = False if event.ShiftDown(): self.shift = True elif event.ControlDown(): self.ctrl = True def EnterObject(self, event): obj = event.GetObject() self.overObjects.append(obj) obj.Highlight() def LeaveObject(self, event): obj = event.GetObject() try: self.overObjects.remove(obj) except: pass obj.UnHighlight() def ObjectSelected(self, event): obj = event.GetObject() self.selectedObjects.append(obj) try: self.overObjects.remove(obj) except: pass obj.UnHighlight() def ObjectDeselected(self, event): obj = event.GetObject() try: self.selectedObjects.remove(obj) except: pass obj.Update() def OnLeftDown(self, event): dc = wx.ClientDC(self) self.PrepareDC(dc) pos = event.GetLogicalPosition(dc) pos.x /= self.zoomScale pos.y /= self.zoomScale if self.toolWnd.AddShapeBtn.GetToggled() and self.toolWnd.currentShape == 'Circle': self.circleLayer.OnLeftDown(pos) elif self.toolWnd.AddTextBtn.GetToggled(): self.textLayer.OnLeftDown(pos) elif self.toolWnd.DrawBtn.GetToggled(): self.lineLayer.OnLeftDown(pos) elif self.toolWnd.SelectorBtn.GetToggled() and (self.selectedObjects == [] or self.ctrl or self.shift) and not (self.useFog and self.fogLayer.region.Contains(pos.x, pos.y) and not self.toolWnd.gmToolBar.IsShown()): self.initiatPos = pos self.lxd = 0 self.lyd = 0 if len(self.overObjects) == 0: return elif len(self.overObjects) == 1: self.overObjects[0].Select() else: if not self.shift: menu = wx.Menu("Object Selection") id = 0 for obj in self.overObjects: menu.Append(id, obj.GetName()) id += 1 def selectmenu(event): id = event.GetId() self.overObjects[id].Select() self.Unbind(wx.EVT_MENU) self.Bind(wx.EVT_MENU, selectmenu) self.PopupMenu(menu) else: for i in xrange(len(self.overObjects)): self.overObjects[0].Select() elif self.toolWnd.SelectorBtn.GetToggled() and not self.selectedObjects == []: xd = (self.initiatPos.x+pos.x)*(self.initiatPos.x+pos.x) yd = (self.initiatPos.y+pos.y)*(self.initiatPos.y+pos.y) for i in xrange(len(self.selectedObjects)): self.selectedObjects[0].Deselect() elif self.toolWnd.FogToolBtn.GetToggled(): self.fogLayer.OnLeftDown(pos) def OnLeftDClick(self, event): dc = wx.ClientDC(self) self.PrepareDC(dc) pos = event.GetLogicalPosition(dc) pos.x /= self.zoomScale pos.y /= self.zoomScale if self.toolWnd.DrawBtn.GetToggled(): self.lineLayer.OnLeftDClick(pos) def OnLeftUp(self, event): dc = wx.ClientDC(self) self.PrepareDC(dc) pos = event.GetLogicalPosition(dc) pos.x /= self.zoomScale pos.y /= self.zoomScale if self.toolWnd.AddShapeBtn.GetToggled() and self.toolWnd.currentShape == 'Circle': self.circleLayer.OnLeftUp(pos) elif self.toolWnd.FogToolBtn.GetToggled(): self.fogLayer.OnLeftUp(pos) elif self.toolWnd.DrawBtn.GetToggled(): self.lineLayer.OnLeftUp(pos) elif self.toolWnd.SelectorBtn.GetToggled() and self.selectedObjects == []: rgn = wx.Region(self.initiatPos.x, self.initiatPos.y, self.lxd, self.lyd) for object in self.zOrder['back']: if rgn.Contains(object.start.x, object.start.y): object.Select() zl = self.zOrder.keys() zl.remove('back') zl.remove('front') zl.remove('tiles') zl.sort() for layer in zl: for object in self.zOrder[layer]: if rgn.Contains(object.start.x, object.start.y): object.Select() for object in self.zOrder['front']: if rgn.Contains(object.start.x, object.start.y): object.Select() self.lxd = 0 self.lyd = 0 self.initiatPos = pos self.Refresh() def OnMotion(self, event): dc = wx.ClientDC(self) self.PrepareDC(dc) pos = event.GetLogicalPosition(dc) pos.x /= self.zoomScale pos.y /= self.zoomScale #HitTest for object in self.zOrder['back']: object.HitTest(pos) zl = self.zOrder.keys() zl.remove('back') zl.remove('front') zl.remove('tiles') zl.sort() for layer in zl: for object in self.zOrder[layer]: object.HitTest(pos) for object in self.zOrder['front']: object.HitTest(pos) if self.toolWnd.AddShapeBtn.GetToggled() and event.m_leftDown and self.toolWnd.currentShape == 'Circle': self.circleLayer.OnMotion(pos) elif self.toolWnd.DrawBtn.GetToggled() and self.lineLayer.start != wx.Point(0,0): self.lineLayer.OnMotion(pos) elif self.toolWnd.SelectorBtn.GetToggled() and self.selectedObjects != [] and not (self.ctrl or self.shift): xd = (pos.x-self.initiatPos.x) yd = (pos.y-self.initiatPos.y) for obj in self.selectedObjects: obj.start.x += xd obj.start.y += yd obj.Update() self.initiatPos = pos elif self.toolWnd.SelectorBtn.GetToggled() and self.selectedObjects == [] and event.m_leftDown: dc.SetBrush(wx.TRANSPARENT_BRUSH) pen = wx.Pen(wx.BLACK, 3, wx.DOT) dc.SetPen(pen) dc.SetLogicalFunction(wx.INVERT) xd = (pos.x-self.initiatPos.x) yd = (pos.y-self.initiatPos.y) if self.lxd != 0 and self.lyd != 0: r = wx.Rect(self.initiatPos.x, self.initiatPos.y, self.lxd, self.lyd) dc.DrawRectangleRect(r) self.lxd = xd self.lyd = yd r = wx.Rect(self.initiatPos.x, self.initiatPos.y, self.lxd, self.lyd) dc.DrawRectangleRect(r) elif (self.toolWnd.FogToolBtn.GetToggled()) and event.m_leftDown: self.fogLayer.OnMotion(pos) def OnRightDown(self, event): mapmenu = wx.Menu() item = wx.MenuItem(mapmenu, wx.ID_ANY, "Load Map", "Load Map") #self.Bind(wx.EVT_MENU, self.OnOpenBtn, item) mapmenu.AppendItem(item) item = wx.MenuItem(mapmenu, wx.ID_ANY, "Save Map", "Save Map") #self.Bind(wx.EVT_MENU, self.OnSaveBtn, item) mapmenu.AppendItem(item) item = wx.MenuItem(mapmenu, wx.ID_ANY, "Default Map", "Default Map") self.Bind(wx.EVT_MENU, self.OnDefaultBtn, item) mapmenu.AppendItem(item) item = wx.MenuItem(mapmenu, wx.ID_ANY, "Map Properties", "Map Properties") #self.Bind(wx.EVT_MENU, OnMapPropsBtn, item) mapmenu.AppendItem(item) bgmenu = wx.Menu() item = wx.MenuItem(bgmenu, wx.ID_ANY, "Change Background Image", "Change Background Image") self.Bind(wx.EVT_MENU, self.OnBGBtn, item) bgmenu.AppendItem(item) item = wx.MenuItem(bgmenu, wx.ID_ANY, "Change Background Color", "Change Background Color") self.Bind(wx.EVT_MENU, self.OnBGColorBtn, item) bgmenu.AppendItem(item) item = wx.MenuItem(bgmenu, wx.ID_ANY, "Grid Properties", "Grid Properties") #self.Bind(wx.EVT_MENU, self.OnGridBtn, item) bgmenu.AppendItem(item) fogmenu = wx.Menu() item = wx.MenuItem(fogmenu, wx.ID_ANY, "Toggle Fog", "Toggle Fog") self.Bind(wx.EVT_MENU, self.OnFogBtn, item) fogmenu.AppendItem(item) item = wx.MenuItem(fogmenu, wx.ID_ANY, "Fog Color", "Fog Color") self.Bind(wx.EVT_MENU, self.OnFogColorBtn, item) fogmenu.AppendItem(item) menu = wx.Menu() if self.toolWnd.gmToolBar.IsShown(): menu.AppendMenu(wx.ID_ANY, "Map", mapmenu) menu.AppendMenu(wx.ID_ANY, "Background", bgmenu) menu.AppendMenu(wx.ID_ANY, "Fog", fogmenu) menu.AppendSeparator() item = wx.MenuItem(menu, wx.ID_ANY, "Miniture Properties", "Miniture Properties") #self.Bind(wx.EVT_MENU, self.OnColorBtn, item) menu.AppendItem(item) menu.AppendSeparator() item = wx.MenuItem(menu, wx.ID_ANY, "Whiteboard Color", "Whiteboard Color") self.Bind(wx.EVT_MENU, self.OnColorBtn, item) menu.AppendItem(item) def ObjectMenu(event): id = event.GetId() objid = int(menu.GetHelpString(id)) menuname = menu.GetLabel(id) obj = self.overObjects[objid] if menuname == "Move To Back": self.MoveToBack(obj) elif menuname == "Move Back": self.MoveBack(obj) elif menuname == "Move Forward": self.MoveForward(obj) elif menuname == "Move To Front": self.MoveToFront(obj) elif menuname == "Remove": self.zOrder[obj.zOrder].remove(obj) obj.Update() self.Unbind(wx.EVT_MENU) self.overObjects.remove(obj) if len(self.overObjects): menu.AppendSeparator() id = 0 for obj in self.overObjects: if obj.IsShown() or self.toolWnd.gmToolBar.IsShown(): objmenu = wx.Menu() item = wx.MenuItem(objmenu, wx.ID_ANY, "Move To Back", str(id)) self.Bind(wx.EVT_MENU, ObjectMenu, item) objmenu.AppendItem(item) item = wx.MenuItem(objmenu, wx.ID_ANY, "Move Back", str(id)) self.Bind(wx.EVT_MENU, ObjectMenu, item) objmenu.AppendItem(item) item = wx.MenuItem(objmenu, wx.ID_ANY, "Move Forward", str(id)) self.Bind(wx.EVT_MENU, ObjectMenu, item) objmenu.AppendItem(item) item = wx.MenuItem(objmenu, wx.ID_ANY, "Move To Front", str(id)) self.Bind(wx.EVT_MENU, ObjectMenu, item) objmenu.AppendItem(item) objmenu.AppendSeparator() if obj.IsShown(): item = wx.MenuItem(objmenu, wx.ID_ANY, "Hide", str(id)) self.Bind(wx.EVT_MENU, obj.Hide, item) objmenu.AppendItem(item) objmenu.AppendSeparator() elif self.toolWnd.gmToolBar.IsShown(): item = wx.MenuItem(objmenu, wx.ID_ANY, "Show", str(id)) self.Bind(wx.EVT_MENU, obj.Show, item) objmenu.AppendItem(item) objmenu.AppendSeparator() item = wx.MenuItem(objmenu, wx.ID_ANY, "Remove", str(id)) self.Bind(wx.EVT_MENU, ObjectMenu, item) objmenu.AppendItem(item) item = wx.MenuItem(objmenu, wx.ID_ANY, "Properties", str(id)) self.Bind(wx.EVT_MENU, obj.ShowProperties, item) objmenu.AppendItem(item) menu.AppendMenu(wx.ID_ANY, obj.GetName(), objmenu) menu.AppendSeparator() item = wx.MenuItem(menu, wx.ID_ANY, "Remove All Objects", "Remove All Whiteboard Items") self.Bind(wx.EVT_MENU, self.OnRemoveAllObjects, item) menu.AppendItem(item) self.PopupMenu(menu) def OnRemoveAllObjects(self, event): for layer in self.zOrder: for i in xrange(len(self.zOrder[layer])): del self.zOrder[layer][0] self.zOrder = {} self.zOrder['tiles'] = [] self.zOrder["back"] = [] self.zOrder["front"] = [] if event != None: self.UpdateMap() def MoveToBack(self, object): self.zOrder[object.zOrder].remove(object) self.zOrder['back'].append(object) object.zOrder = 'back' self.UpdateMap() def MoveToFront(self, object): self.zOrder[object.zOrder].remove(object) self.zOrder['front'].append(object) object.zOrder = 'front' self.UpdateMap() def MoveBack(self, object): self.zOrder[object.zOrder].remove(object) zl = self.zOrder.keys() zl.remove('back') zl.remove('front') zl.remove('tiles') zl.sort() lzo = 1 if len(zl): lzo = zl.pop() if object.zOrder == 'back' or object.zOrder == 1: self.zOrder['back'].append(object) object.zOrder = 'back' elif object.zOrder == 'front': if not self.zOrder.has_key(lzo): self.zOrder[lzo] = [] self.zOrder[lzo].append(object) object.zOrder = lzo else: object.zOrder -= 1 if not self.zOrder.has_key(object.zOrder): self.zOrder[object.zOrder] = [] self.zOrder[object.zOrder].append(object) self.UpdateMap() def MoveForward(self, object): self.zOrder[object.zOrder].remove(object) zl = self.zOrder.keys() zl.remove('back') zl.remove('front') zl.remove('tiles') zl.sort() lzo = 1 if len(zl): lzo = zl.pop() if object.zOrder == 'back': if not self.zOrder.has_key(1): self.zOrder[1] = [] self.zOrder[1].append(object) object.zOrder = 1 elif z == 'front': self.zOrder['front'].append(object) object.zOrder = 'front' else: object.zOrder += 1 if not self.zOrder.has_key(object.zOrder): self.zOrder[object.zOrder] = [] self.zOrder[object.zOrder].append(object) self.UpdateMap() def OnScroll(self, event): event.Skip() self.Refresh() def OnZoomTimer(self, event): if (time.time() - self.lastZoomTime) >= 3 and self.lastZoomScale != self.zoomScale: #Send Zoome Notice to other clients self.lastZoomTime = time.time() self.lastZoomScale = self.zoomScale def OnRoleTimer(self, event): #Figure out the users role if self.session.my_role() == self.session.ROLE_GM: self.role = 'GM' elif self.session.my_role() == self.session.ROLE_PLAYER: self.role = 'Player' else: self.role = 'Lurker' if self.role == 'GM' and not self.toolWnd.gmToolBar.IsShown() and not (str(self.session.group_id) == '0' and str(self.session.status) == '1'): self.toolWnd.Freeze() self.toolWnd.gmToolBar.Show() self.toolWnd.Thaw() elif self.role == 'Player' and not (str(self.session.group_id) == '0' and str(self.session.status) == '1'): if self.toolWnd.gmToolBar.IsShown(): self.toolWnd.Freeze() self.toolWnd.gmToolBar.Hide() self.toolWnd.Thaw() if not self.toolWnd.playerToolBar.IsShown(): self.toolWnd.Freeze() self.toolWnd.playerToolBar.Show() self.toolWnd.Thaw() elif self.role == 'Lurker' or (str(self.session.group_id) == '0' and str(self.session.status) == '1'): if self.toolWnd.playerToolBar.IsShown(): self.toolWnd.Freeze() self.toolWnd.gmToolBar.Hide() self.toolWnd.playerToolBar.Hide() self.toolWnd.Thaw() try: self.toolWnd.Layout() except: pass def OnClose(self, event): self.zoomTimer.Stop() self.roleTimer.Stop() event.Skip() #Toolbar Events def OnDefaultBtn(self, event): self.Clear() wx.CallAfter(self.UpdateMap) def OnColorBtn(self, event): newcolor = self.RGBHex.do_hex_color_dlg(self.toolWnd) if newcolor == None: return self.whiteboardColor = newcolor r, g, b = self.RGBHex.rgb_tuple(self.whiteboardColor) self.toolWnd._SetColorBtn(wx.Color(r, g, b, 255), self.toolWnd.ColorBtn) def OnBGColorBtn(self, event): newcolor = self.RGBHex.do_hex_color_dlg(self.toolWnd) if newcolor == None: return self.backgroundColor = newcolor r, g, b = self.RGBHex.rgb_tuple(self.backgroundColor) self.toolWnd._SetColorBtn(wx.Color(r, g, b, 255), self.toolWnd.BGColorBtn) self.UpdateMap() def OnFogColorBtn(self, event): newcolor = self.RGBHex.do_hex_color_dlg(self.toolWnd) if newcolor == None: return self.fogColor = newcolor r, g, b = self.RGBHex.rgb_tuple(self.fogColor) self.toolWnd._SetColorBtn(wx.Color(r, g, b, 255), self.toolWnd.FogColorBtn) self.UpdateMap() def OnExlusiveBtn(self, event): id = event.GetId() #This is backwards because the Toggle Switch does not get set until AFTER The mouse gets released if not self.toolWnd.exclusiveToolList[id].GetToggled(): self.toolWnd.Freeze() #Disable all mutualy exclusive tools for btn in self.toolWnd.exclusiveToolList: if self.toolWnd.exclusiveToolList[btn].GetId() != id: self.toolWnd.exclusiveToolList[btn].SetToggled(False) self.toolWnd.Thaw() else: wx.CallAfter(self.toolWnd.SelectorBtn.SetToggled, True) def OnFogBtn(self, event): if not self.toolWnd.FogBtn.GetToggled(): self.useFog = True else: self.useFog = False self.toolWnd.Freeze() self.toolWnd.SelectorBtn.SetToggled(True) self.toolWnd.FogToolBtn.SetToggled(False) self.toolWnd.Thaw() self.fogRegion = [] self.UpdateMap() def OnBGBtn(self, event): dlg = wx.Dialog(self.toolWnd, wx.ID_ANY, title="Background Properties") sizer = wx.BoxSizer(wx.HORIZONTAL) filename = wx.TextCtrl(dlg, wx.ID_ANY) filename.Hide() bgpath = wx.TextCtrl(dlg, wx.ID_ANY) if self.bgPath != None: bgpath.SetValue(self.bgPath) bgtype = wx.Choice(dlg, wx.ID_ANY, choices=['Image', 'Texture']) bgtype.SetStringSelection(self.bgType) browsebtn = wx.Button(dlg, wx.ID_ANY, "Browse") okbtn = wx.Button(dlg, wx.ID_OK) cancelbtn = wx.Button(dlg, wx.ID_CANCEL) sizer.Add(wx.StaticText(dlg, wx.ID_ANY, "Image Path"), 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 2) sizer.Add(bgpath, 0, wx.EXPAND|wx.ALL, 3) sizer.Add(wx.StaticText(dlg, wx.ID_ANY, "Image Type"), 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 2) sizer.Add(bgtype, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 3) sizer.Add(browsebtn, 0, wx.EXPAND|wx.ALL, 2) sizer.Add(okbtn, 0, wx.EXPAND|wx.ALL, 3) sizer.Add(cancelbtn, 0, wx.EXPAND|wx.ALL, 2) dlg.SetSizer(sizer) dlg.SetAutoLayout(True) dlg.Fit() def OnBrowse(event): filedlg = wx.FileDialog(self, "Select an Image File", self.dir_struct["user"], wildcard="Image files (*.bmp, *.gif, *.jpg, *.png)|*.bmp;*.gif;*.jpg;*.png", style=wx.HIDE_READONLY|wx.OPEN) if filedlg.ShowModal() != wx.ID_OK: filedlg.Destroy() return bgpath.SetValue(filedlg.GetPath()) filename.SetValue(filedlg.GetFilename()) dlg.Bind(wx.EVT_BUTTON, OnBrowse, browsebtn) dlg.Show() if not dlg.ShowModal() == wx.ID_OK: dlg.Destroy() return self.bgType = bgtype.GetStringSelection() if bgpath.GetValue().lower().find('http:') == -1: file = open(bgpath.GetValue(), "rb") imgdata = file.read() file.close() (imgtype,j) = mimetypes.guess_type(filename.GetValue()) postdata = urllib.urlencode({'filename':filename.GetValue(), 'imgdata':imgdata, 'imgtype':imgtype}) thread.start_new_thread(self.__Upload, (postdata, bgpath.GetValue(), "Background")) else: self.bgImage = self._LoadImage(bgpath.GetValue()) self.UpdateMap() #Private Methods def _SetSize(self, size): if size[0] == -1: size[0] = self.size[0] if size[1] == -1: size[1] = self.size[1] if size[0] < 300: size = (300, size[1]) if size[1] < 300: size = (size[0], 300) size1 = self.GetClientSizeTuple() if size[0] < size1[0]: size = (size1[0], size[1]) if size[1] < size1[1]: size = (size[0], size1[1]) self.sizeChanged = 1 self.size = size self._FixScroll() def _FixScroll(self): scale = self.zoomScale pos = self.GetViewStart() unit = self.GetScrollPixelsPerUnit() pos = [pos[0]*unit[0],pos[1]*unit[1]] size = self.GetClientSize() unit = [10*scale,10*scale] if (unit[0] == 0 or unit[1] == 0): return pos[0] /= unit[0] pos[1] /= unit[1] mx = [int(self.size[0]*scale/unit[0])+1, int(self.size[1]*scale/unit[1]+1)] self.SetScrollbars(unit[0], unit[1], mx[0], mx[1], pos[0], pos[1]) def _LoadImage(self, path, miniId=None): if self.imageCache.has_key(path): return self.imageCache[path] while len(self.imageCache) > int(self.settings.get_setting("ImageCacheSize")): keys = self.imageCache.keys() del self.imageCache[keys[0]] thread.start_new_thread(self.__DownloadImage, (path, miniId)) return wx.Bitmap(orpg.dirpath.dir_struct["icon"] + "fetching.png", wx.BITMAP_TYPE_PNG) def _ClearCache(self): for key in self.imageCache: del self.imageCache[key] #Threads def __Upload(self, postdata, filename, type="Background"): self.lock.acquire() url = self.settings.get_setting('ImageServerBaseURL') file = urllib.urlopen(url, postdata) recvdata = file.read() file.close() try: xml_dom = minidom.parseString(recvdata)._get_documentElement() if xml_dom.nodeName == 'path': path = xml_dom.getAttribute('url') path = urllib.unquote(path) if type == 'Background': self.bgImage = self._LoadImage(path) self.bgPath = path else: self.minis.append(self.mapLayer.AddMiniture(path)) self.UpdateMap() else: self.chat.InfoPost(xml_dom.getAttribute('msg')) except Exception, e: print e print recvdata self.lock.release() def __DownloadImage(self, path, miniId): self.lock.acquire() uriPath = urllib.unquote(path) try: data = urllib.urlretrieve(uriPath) if data[0] and data[1].getmaintype() == "image": imageType = data[1].gettype() img = wx.ImageFromMime(data[0], imageType).ConvertToBitmap() self.imageCache[path] = img if miniId == None: self.bgImage = img if self.bgType == 'Image': self._SetSize((img.GetHeight(), img.GetWidth())) else: mini = self.GetMiniById(miniId) mini.image = img self.UpdateMap() except Exception, e: self.chat.InfoPost("Unable to resolve/open the specified URI; image was NOT laoded:" + path) urllib.urlcleanup() self.lock.release()