Mercurial > traipse_dev
view orpg/map/_canvas.py @ 158:cc1ae9386f87 beta
Traipse Beta 'OpenRPG' {091125-03}
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)
Added Bookmarks
Fix to Remote Admin Commands
Minor fix to text based Server
Fix to Pretty Print, from Core
Fix to Splitter Nodes not being created
Fix to massive amounts of images loading, from Core
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
default_manifest.xml renamed to default_upmana.xml
Cleaner clode for saved repositories
New TrueDebug Class in orpg_log (See documentation for usage)
Mercurial's hgweb folder is ported to upmana
Pretty important update that can help remove thousands of dead children from your
gametree.
Children, <forms />, <group_atts />, <horizontal />, <cols />, <rows />, <height
/>, etc... are all tags now. Check your gametree and look for dead children!!
New Gametree Recursion method, mapping, and context sensitivity. !Infinite Loops
return error instead of freezing the software!
New Syntax added for custom PC sheets
Tip of the Day added, from Core and community
Fixed Whiteboard ID to prevent random line or text deleting. Modified ID's to
prevent non updated clients from ruining the fix.
author | sirebral |
---|---|
date | Wed, 25 Nov 2009 14:25:25 -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()