Mercurial > traipse_dev
diff orpg/map/_canvas.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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/orpg/map/_canvas.py Tue Jul 14 16:41:58 2009 -0500 @@ -0,0 +1,994 @@ +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() \ No newline at end of file