Mercurial > traipse_dev
diff orpg/mapper/miniatures.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 | 2b9e766f9dee |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/orpg/mapper/miniatures.py Tue Jul 14 16:41:58 2009 -0500 @@ -0,0 +1,741 @@ +# 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/miniatures.py +# Author: Chris Davis +# Maintainer: +# Version: +# $Id: miniatures.py,v 1.46 2007/12/07 20:39:50 digitalxero Exp $ +# +# Description: This file contains some of the basic definitions for the chat +# utilities in the orpg project. +# +__version__ = "$Id: miniatures.py,v 1.46 2007/12/07 20:39:50 digitalxero Exp $" + +from base import * +import thread +import time +import urllib +import os.path + +MIN_STICKY_BACK = -0XFFFFFF +MIN_STICKY_FRONT = 0xFFFFFF + +##---------------------------------------- +## miniature object +##---------------------------------------- + +FACE_NONE = 0 +FACE_NORTH = 1 +FACE_NORTHEAST = 2 +FACE_EAST = 3 +FACE_SOUTHEAST = 4 +FACE_SOUTH = 5 +FACE_SOUTHWEST = 6 +FACE_WEST = 7 +FACE_NORTHWEST = 8 +SNAPTO_ALIGN_CENTER = 0 +SNAPTO_ALIGN_TL = 1 + +def cmp_zorder(first,second): + f = first.zorder + s = second.zorder + if f == None: + f = 0 + if s == None: + s = 0 + if f == s: + value = 0 + elif f < s: + value = -1 + else: + value = 1 + return value + +class BmpMiniature: + def __init__(self, id,path, bmp, pos=cmpPoint(0,0), heading=FACE_NONE, face=FACE_NONE, label="", locked=False, hide=False, snap_to_align=SNAPTO_ALIGN_CENTER, zorder=0, width=0, height=0, log=None, local=False, localPath='', localTime=-1): + self.log = log + self.log.log("Enter BmpMiniature", ORPG_DEBUG) + self.heading = heading + self.face = face + self.label = label + self.path = path + self.bmp = bmp + self.pos = pos + self.selected = False + self.locked = locked + self.snap_to_align = snap_to_align + self.hide = hide + self.id = id + self.zorder = zorder + self.left = 0 + self.local = local + self.localPath = localPath + self.localTime = localTime + if not width: + self.width = 0 + else: + self.width = width + if not height: + self.height = 0 + else: + self.height = height + self.right = bmp.GetWidth() + self.top = 0 + self.bottom = bmp.GetHeight() + self.isUpdated = False + self.gray = False + self.log.log("Exit BmpMiniature", ORPG_DEBUG) + + def __del__(self): + self.log.log("Enter BmpMiniature->__del__(self)", ORPG_DEBUG) + del self.bmp + self.bmp = None + self.log.log("Exit BmpMiniature->__del__(self)", ORPG_DEBUG) + + def set_bmp(self, bmp): + self.log.log("Enter BmpMiniature->set_bmp(self, bmp)", ORPG_DEBUG) + self.bmp = bmp + self.log.log("Exit BmpMiniature->set_bmp(self, bmp)", ORPG_DEBUG) + + def set_min_props(self, heading=FACE_NONE, face=FACE_NONE, label="", locked=False, hide=False, width=0, height=0): + self.log.log("Enter BmpMiniature->set_min_props(self, heading, face, label, locked, hide, width, height)", ORPG_DEBUG) + self.heading = heading + self.face = face + self.label = label + if locked: + self.locked = True + else: + self.locked = False + if hide: + self.hide = True + else: + self.hide = False + self.width = int(width) + self.height = int(height) + self.isUpdated = True + self.log.log("Exit BmpMiniature->set_min_props(self, heading, face, label, locked, hide, width, height)", ORPG_DEBUG) + + def hit_test(self, pt): + self.log.log("Enter BmpMiniature->hit_test(self, pt)", ORPG_DEBUG) + rect = self.get_rect() + result = None + result = rect.InsideXY(pt.x, pt.y) + self.log.log("Exit BmpMiniature->hit_test(self, pt)", ORPG_DEBUG) + return result + + def get_rect(self): + self.log.log("Enter BmpMiniature->get_rect(self)", ORPG_DEBUG) + ret = wx.Rect(self.pos.x, self.pos.y, self.bmp.GetWidth(), self.bmp.GetHeight()) + self.log.log("Exit BmpMiniature->get_rect(self)", ORPG_DEBUG) + return ret + + def draw(self, dc, mini_layer, op=wx.COPY): + self.log.log("Enter BmpMiniature->draw(self, dc, mini_layer, op)", ORPG_DEBUG) + if isinstance(self.bmp, tuple): + self.log.log("bmp is a tuple, it shouldnt be!", ORPG_INFO) + self.bmp = wx.ImageFromMime(self.bmp[1], self.bmp[2]).ConvertToBitmap() + if self.bmp != None and self.bmp.Ok(): + # check if hidden and GM: we outline the mini in grey (little bit smaller than the actual size) + # and write the label in the center of the mini + if self.hide and mini_layer.canvas.frame.session.my_role() == mini_layer.canvas.frame.session.ROLE_GM: + self.log.log("Enter BmpMiniature->draw->Draw Hidden", ORPG_DEBUG) + # set the width and height of the image + if self.width and self.height: + tmp_image = self.bmp.ConvertToImage() + tmp_image.Rescale(int(self.width), int(self.height)) + tmp_image.ConvertAlphaToMask() + self.bmp = tmp_image.ConvertToBitmap() + mask = wx.Mask(self.bmp, wx.Colour(tmp_image.GetMaskRed(), tmp_image.GetMaskGreen(), tmp_image.GetMaskBlue())) + self.bmp.SetMask(mask) + del tmp_image + del mask + self.left = 0 + self.right = self.bmp.GetWidth() + self.top = 0 + self.bottom = self.bmp.GetHeight() + # grey outline + graypen = wx.Pen("gray", 1, wx.DOT) + dc.SetPen(graypen) + dc.SetBrush(wx.TRANSPARENT_BRUSH) + #if width or height < 20 then offset = 1 + if self.bmp.GetWidth() <= 20: + xoffset = 1 + else: + xoffset = 5 + if self.bmp.GetHeight() <= 20: + yoffset = 1 + else: + yoffset = 5 + dc.DrawRectangle(self.pos.x + xoffset, self.pos.y + yoffset, self.bmp.GetWidth() - (xoffset * 2), self.bmp.GetHeight() - (yoffset * 2)) + dc.SetBrush(wx.NullBrush) + dc.SetPen(wx.NullPen) + ## draw label in the center of the mini + label = mini_layer.get_mini_label(self) + if len(label): + dc.SetTextForeground(wx.RED) + (textWidth,textHeight) = dc.GetTextExtent(label) + x = self.pos.x +((self.bmp.GetWidth() - textWidth) /2) - 1 + y = self.pos.y + (self.bmp.GetHeight() / 2) + dc.SetPen(wx.GREY_PEN) + dc.SetBrush(wx.LIGHT_GREY_BRUSH) + dc.DrawRectangle(x, y, textWidth+2, textHeight+2) + if (textWidth+2 > self.right): + self.right += int((textWidth+2-self.right)/2)+1 + self.left -= int((textWidth+2-self.right)/2)+1 + self.bottom = y+textHeight+2-self.pos.y + dc.SetPen(wx.NullPen) + dc.SetBrush(wx.NullBrush) + dc.DrawText(label, x+1, y+1) + + #selected outline + if self.selected: + dc.SetPen(wx.RED_PEN) + dc.SetBrush(wx.TRANSPARENT_BRUSH) + dc.DrawRectangle(self.pos.x, self.pos.y, self.bmp.GetWidth(), self.bmp.GetHeight()) + dc.SetBrush(wx.NullBrush) + dc.SetPen(wx.NullPen) + self.log.log("Exit BmpMiniature->draw->Draw Hidden", ORPG_DEBUG) + return True + elif self.hide: + self.log.log("Enter/Exit BmpMiniature->draw->Skip Hidden", ORPG_DEBUG) + return True + + else: + self.log.log("Enter BmpMiniature->draw->Not Hidden", ORPG_DEBUG) + # set the width and height of the image + bmp = self.bmp + if self.width and self.height: + tmp_image = self.bmp.ConvertToImage() + tmp_image.Rescale(int(self.width), int(self.height)) + tmp_image.ConvertAlphaToMask() + self.bmp = tmp_image.ConvertToBitmap() + mask = wx.Mask(self.bmp, wx.Colour(tmp_image.GetMaskRed(), tmp_image.GetMaskGreen(), tmp_image.GetMaskBlue())) + self.bmp.SetMask(mask) + if self.gray: + tmp_image = tmp_image.ConvertToGreyscale() + bmp = tmp_image.ConvertToBitmap() + else: + bmp = self.bmp + dc.DrawBitmap(bmp, self.pos.x, self.pos.y, True) + self.left = 0 + self.right = self.bmp.GetWidth() + self.top = 0 + self.bottom = self.bmp.GetHeight() + + # Draw the facing marker if needed + if self.face != 0: + x_mid = self.pos.x + (self.bmp.GetWidth()/2) + x_right = self.pos.x + self.bmp.GetWidth() + y_mid = self.pos.y + (self.bmp.GetHeight()/2) + y_bottom = self.pos.y + self.bmp.GetHeight() + dc.SetPen(wx.WHITE_PEN) + dc.SetBrush(wx.RED_BRUSH) + triangle = [] + + # Figure out which direction to draw the marker!! + if self.face == FACE_WEST: + triangle.append(cmpPoint(self.pos.x,self.pos.y)) + triangle.append(cmpPoint(self.pos.x - 5, y_mid)) + triangle.append(cmpPoint(self.pos.x, y_bottom)) + elif self.face == FACE_EAST: + triangle.append(cmpPoint(x_right, self.pos.y)) + triangle.append(cmpPoint(x_right + 5, y_mid)) + triangle.append(cmpPoint(x_right, y_bottom)) + elif self.face == FACE_SOUTH: + triangle.append(cmpPoint(self.pos.x, y_bottom)) + triangle.append(cmpPoint(x_mid, y_bottom + 5)) + triangle.append(cmpPoint(x_right, y_bottom)) + elif self.face == FACE_NORTH: + triangle.append(cmpPoint(self.pos.x, self.pos.y)) + triangle.append(cmpPoint(x_mid, self.pos.y - 5)) + triangle.append(cmpPoint(x_right, self.pos.y)) + elif self.face == FACE_NORTHEAST: + triangle.append(cmpPoint(x_mid, self.pos.y)) + triangle.append(cmpPoint(x_right + 5, self.pos.y - 5)) + triangle.append(cmpPoint(x_right, y_mid)) + triangle.append(cmpPoint(x_right, self.pos.y)) + elif self.face == FACE_SOUTHEAST: + triangle.append(cmpPoint(x_right, y_mid)) + triangle.append(cmpPoint(x_right + 5, y_bottom + 5)) + triangle.append(cmpPoint(x_mid, y_bottom)) + triangle.append(cmpPoint(x_right, y_bottom)) + elif self.face == FACE_SOUTHWEST: + triangle.append(cmpPoint(x_mid, y_bottom)) + triangle.append(cmpPoint(self.pos.x - 5, y_bottom + 5)) + triangle.append(cmpPoint(self.pos.x, y_mid)) + triangle.append(cmpPoint(self.pos.x, y_bottom)) + elif self.face == FACE_NORTHWEST: + triangle.append(cmpPoint(self.pos.x, y_mid)) + triangle.append(cmpPoint(self.pos.x - 5, self.pos.y - 5)) + triangle.append(cmpPoint(x_mid, self.pos.y)) + triangle.append(cmpPoint(self.pos.x, self.pos.y)) + dc.DrawPolygon(triangle) + dc.SetBrush(wx.NullBrush) + dc.SetPen(wx.NullPen) + + # Draw the heading if needed + if self.heading: + x_adjust = 0 + y_adjust = 4 + x_half = self.bmp.GetWidth()/2 + y_half = self.bmp.GetHeight()/2 + x_quarter = self.bmp.GetWidth()/4 + y_quarter = self.bmp.GetHeight()/4 + x_3quarter = x_quarter*3 + y_3quarter = y_quarter*3 + x_full = self.bmp.GetWidth() + y_full = self.bmp.GetHeight() + x_center = self.pos.x + x_half + y_center = self.pos.y + y_half + # Remember, the pen/brush must be a different color than the + # facing marker!!!! We'll use black/cyan for starters. + # Also notice that we will draw the heading on top of the + # larger facing marker. + dc.SetPen(wx.BLACK_PEN) + dc.SetBrush(wx.CYAN_BRUSH) + triangle = [] + + # Figure out which direction to draw the marker!! + if self.heading == FACE_NORTH: + triangle.append(cmpPoint(x_center - x_quarter, y_center - y_half )) + triangle.append(cmpPoint(x_center, y_center - y_3quarter )) + triangle.append(cmpPoint(x_center + x_quarter, y_center - y_half )) + elif self.heading == FACE_SOUTH: + triangle.append(cmpPoint(x_center - x_quarter, y_center + y_half )) + triangle.append(cmpPoint(x_center, y_center + y_3quarter )) + triangle.append(cmpPoint(x_center + x_quarter, y_center + y_half )) + elif self.heading == FACE_NORTHEAST: + triangle.append(cmpPoint(x_center + x_quarter, y_center - y_half )) + triangle.append(cmpPoint(x_center + x_3quarter, y_center - y_3quarter )) + triangle.append(cmpPoint(x_center + x_half, y_center - y_quarter )) + elif self.heading == FACE_EAST: + triangle.append(cmpPoint(x_center + x_half, y_center - y_quarter )) + triangle.append(cmpPoint(x_center + x_3quarter, y_center )) + triangle.append(cmpPoint(x_center + x_half, y_center + y_quarter )) + elif self.heading == FACE_SOUTHEAST: + triangle.append(cmpPoint(x_center + x_half, y_center + y_quarter )) + triangle.append(cmpPoint(x_center + x_3quarter, y_center + y_3quarter )) + triangle.append(cmpPoint(x_center + x_quarter, y_center + y_half )) + elif self.heading == FACE_SOUTHWEST: + triangle.append(cmpPoint(x_center - x_quarter, y_center + y_half )) + triangle.append(cmpPoint(x_center - x_3quarter, y_center + y_3quarter )) + triangle.append(cmpPoint(x_center - x_half, y_center + y_quarter )) + elif self.heading == FACE_WEST: + triangle.append(cmpPoint(x_center - x_half, y_center + y_quarter )) + triangle.append(cmpPoint(x_center - x_3quarter, y_center )) + triangle.append(cmpPoint(x_center - x_half, y_center - y_quarter )) + elif self.heading == FACE_NORTHWEST: + triangle.append(cmpPoint(x_center - x_half, y_center - y_quarter )) + triangle.append(cmpPoint(x_center - x_3quarter, y_center - y_3quarter )) + triangle.append(cmpPoint(x_center - x_quarter, y_center - y_half )) + dc.DrawPolygon(triangle) + dc.SetBrush(wx.NullBrush) + dc.SetPen(wx.NullPen) + #selected outline + if self.selected: + dc.SetPen(wx.RED_PEN) + dc.SetBrush(wx.TRANSPARENT_BRUSH) + dc.DrawRectangle(self.pos.x, self.pos.y, self.bmp.GetWidth(), self.bmp.GetHeight()) + dc.SetBrush(wx.NullBrush) + dc.SetPen(wx.NullPen) + # draw label + label = mini_layer.get_mini_label(self) + if len(label): + dc.SetTextForeground(wx.RED) + (textWidth,textHeight) = dc.GetTextExtent(label) + x = self.pos.x +((self.bmp.GetWidth() - textWidth) /2) - 1 + y = self.pos.y + self.bmp.GetHeight() + 6 + dc.SetPen(wx.WHITE_PEN) + dc.SetBrush(wx.WHITE_BRUSH) + dc.DrawRectangle(x,y,textWidth+2,textHeight+2) + if (textWidth+2 > self.right): + self.right += int((textWidth+2-self.right)/2)+1 + self.left -= int((textWidth+2-self.right)/2)+1 + self.bottom = y+textHeight+2-self.pos.y + dc.SetPen(wx.NullPen) + dc.SetBrush(wx.NullBrush) + dc.DrawText(label,x+1,y+1) + self.top-=5 + self.bottom+=5 + self.left-=5 + self.right+=5 + self.log.log("Exit BmpMiniature->draw->Not Hidden", ORPG_DEBUG) + return True + else: + self.log.log("Exit BmpMiniature->draw(self, dc, mini_layer, op) return False", ORPG_DEBUG) + return False + self.log.log("Exit BmpMiniature->draw(self, dc, mini_layer, op)", ORPG_DEBUG) + + def toxml(self, action="update"): + self.log.log("Enter BmpMiniature->toxml(self, " + action + ")", ORPG_DEBUG) + if action == "del": + xml_str = "<miniature action='del' id='" + self.id + "'/>" + self.log.log(xml_str, ORPG_DEBUG) + self.log.log("Exit BmpMiniature->toxml(self, " + action + ")", ORPG_DEBUG) + return xml_str + xml_str = "<miniature" + xml_str += " action='" + action + "'" + xml_str += " label='" + self.label + "'" + xml_str+= " id='" + self.id + "'" + if self.pos != None: + xml_str += " posx='" + str(self.pos.x) + "'" + xml_str += " posy='" + str(self.pos.y) + "'" + if self.heading != None: + xml_str += " heading='" + str(self.heading) + "'" + if self.face != None: + xml_str += " face='" + str(self.face) + "'" + if self.path != None: + xml_str += " path='" + urllib.quote(self.path).replace('%3A', ':') + "'" + if self.locked: + xml_str += " locked='1'" + else: + xml_str += " locked='0'" + if self.hide: + xml_str += " hide='1'" + else: + xml_str += " hide='0'" + if self.snap_to_align != None: + xml_str += " align='" + str(self.snap_to_align) + "'" + if self.id != None: + xml_str += " zorder='" + str(self.zorder) + "'" + if self.width != None: + xml_str += " width='" + str(self.width) + "'" + if self.height != None: + xml_str += " height='" + str(self.height) + "'" + if self.local: + xml_str += ' local="' + str(self.local) + '"' + xml_str += ' localPath="' + str(urllib.quote(self.localPath).replace('%3A', ':')) + '"' + xml_str += ' localTime="' + str(self.localTime) + '"' + xml_str += " />" + self.log.log(xml_str, ORPG_DEBUG) + self.log.log("Exit BmpMiniature->toxml(self, " + action + ")", ORPG_DEBUG) + if (action == "update" and self.isUpdated) or action == "new": + self.isUpdated = False + return xml_str + else: + return '' + + def takedom(self, xml_dom): + self.log.log("Enter BmpMiniature->takedom(self, xml_dom)", ORPG_DEBUG) + self.id = xml_dom.getAttribute("id") + self.log.log("self.id=" + str(self.id), ORPG_DEBUG) + if xml_dom.hasAttribute("posx"): + self.pos.x = int(xml_dom.getAttribute("posx")) + self.log.log("self.pos.x=" + str(self.pos.x), ORPG_DEBUG) + if xml_dom.hasAttribute("posy"): + self.pos.y = int(xml_dom.getAttribute("posy")) + self.log.log("self.pos.y=" + str(self.pos.y), ORPG_DEBUG) + if xml_dom.hasAttribute("heading"): + self.heading = int(xml_dom.getAttribute("heading")) + self.log.log("self.heading=" + str(self.heading), ORPG_DEBUG) + if xml_dom.hasAttribute("face"): + self.face = int(xml_dom.getAttribute("face")) + self.log.log("self.face=" + str(self.face), ORPG_DEBUG) + if xml_dom.hasAttribute("path"): + self.path = urllib.unquote(xml_dom.getAttribute("path")) + self.set_bmp(ImageHandler.load(self.path, 'miniature', self.id)) + self.log.log("self.path=" + self.path, ORPG_DEBUG) + if xml_dom.hasAttribute("locked"): + if xml_dom.getAttribute("locked") == '1' or xml_dom.getAttribute("locked") == 'True': + self.locked = True + else: + self.locked = False + self.log.log("self.locked=" + str(self.locked), ORPG_DEBUG) + if xml_dom.hasAttribute("hide"): + if xml_dom.getAttribute("hide") == '1' or xml_dom.getAttribute("hide") == 'True': + self.hide = True + else: + self.hide = False + self.log.log("self.hide=" + str(self.hide), ORPG_DEBUG) + if xml_dom.hasAttribute("label"): + self.label = xml_dom.getAttribute("label") + self.log.log("self.label=" + self.label, ORPG_DEBUG) + if xml_dom.hasAttribute("zorder"): + self.zorder = int(xml_dom.getAttribute("zorder")) + self.log.log("self.zorder=" + str(self.zorder), ORPG_DEBUG) + if xml_dom.hasAttribute("align"): + if xml_dom.getAttribute("align") == '1' or xml_dom.getAttribute("align") == 'True': + self.snap_to_align = 1 + else: + self.snap_to_align = 0 + self.log.log("self.snap_to_align=" + str(self.snap_to_align), ORPG_DEBUG) + if xml_dom.hasAttribute("width"): + self.width = int(xml_dom.getAttribute("width")) + self.log.log("self.width=" + str(self.width), ORPG_DEBUG) + if xml_dom.hasAttribute("height"): + self.height = int(xml_dom.getAttribute("height")) + self.log.log("self.height=" + str(self.height), ORPG_DEBUG) + self.log.log("Exit BmpMiniature->takedom(self, xml_dom)", ORPG_DEBUG) + +##----------------------------- +## miniature layer +##----------------------------- +class miniature_layer(layer_base): + def __init__(self, canvas): + self.canvas = canvas + self.log = self.canvas.log + self.log.log("Enter miniature_layer", ORPG_DEBUG) + self.settings = self.canvas.settings + layer_base.__init__(self) + self.miniatures = [] + self.serial_number = 0 + self.log.log("Exit miniature_layer", ORPG_DEBUG) + + def next_serial(self): + self.log.log("Enter miniature_layer->next_serial(self)", ORPG_DEBUG) + self.serial_number += 1 + self.log.log("Exit miniature_layer->next_serial(self)", ORPG_DEBUG) + return self.serial_number + + def get_next_highest_z(self): + self.log.log("Enter miniature_layer->get_next_highest_z(self)", ORPG_DEBUG) + z = len(self.miniatures)+1 + self.log.log("Exit miniature_layer->get_next_highest_z(self)", ORPG_DEBUG) + return z + + def cleanly_collapse_zorder(self): + self.log.log("Enter miniature_layer->cleanly_collapse_zorder(self)", ORPG_DEBUG) + # lock the zorder stuff + sorted_miniatures = self.miniatures[:] + sorted_miniatures.sort(cmp_zorder) + i = 0 + for mini in sorted_miniatures: + mini.zorder = i + i = i + 1 + self.log.log("Exit miniature_layer->cleanly_collapse_zorder(self)", ORPG_DEBUG) + # unlock the zorder stuff + + def collapse_zorder(self): + self.log.log("Enter miniature_layer->collapse_zorder(self)", ORPG_DEBUG) + # lock the zorder stuff + sorted_miniatures = self.miniatures[:] + sorted_miniatures.sort(cmp_zorder) + i = 0 + for mini in sorted_miniatures: + if (mini.zorder != MIN_STICKY_BACK) and (mini.zorder != MIN_STICKY_FRONT): + mini.zorder = i + else: + pass + i = i + 1 + self.log.log("Exit miniature_layer->collapse_zorder(self)", ORPG_DEBUG) + # unlock the zorder stuff + + def rollback_serial(self): + self.log.log("Enter miniature_layer->rollback_serial(self)", ORPG_DEBUG) + self.serial_number -= 1 + self.log.log("Exit miniature_layer->rollback_serial(self)", ORPG_DEBUG) + + def add_miniature(self, id, path, pos=cmpPoint(0,0), label="", heading=FACE_NONE, face=FACE_NONE, width=0, height=0, local=False, localPath='', localTime=-1): + self.log.log("Enter miniature_layer->add_miniature(self, id, path, pos, label, heading, face, width, height)", ORPG_DEBUG) + self.log.log("Before mini creation: " + str(self.get_next_highest_z()), ORPG_DEBUG) + bmp = ImageHandler.load(path, 'miniature', id) + if bmp: + mini = BmpMiniature(id, path, bmp, pos, heading, face, label, zorder=self. get_next_highest_z(), width=width, height=height, log=self.log, local=local, localPath=localPath, localTime=localTime) + self.log.log("After mini creation:" + str(self.get_next_highest_z()), ORPG_DEBUG) + self.miniatures.append(mini) + self.log.log("After mini addition:" + str(self.get_next_highest_z()), ORPG_DEBUG) + xml_str = "<map><miniatures>" + xml_str += mini.toxml("new") + xml_str += "</miniatures></map>" + self.canvas.frame.session.send(xml_str) + else: + self.log.log("Invalid image " + path + " has been ignored!", ORPG_DEBUG) + self.log.log("Exit miniature_layer->add_miniature(self, id, path, pos, label, heading, face, width, height)", ORPG_DEBUG) + + def get_miniature_by_id(self, id): + self.log.log("Enter miniature_layer->get_miniature_by_id(self, id)", ORPG_DEBUG) + for mini in self.miniatures: + if str(mini.id) == str(id): + self.log.log("Exit miniature_layer->get_miniature_by_id(self, id) return miniID: " + str(id), ORPG_DEBUG) + return mini + self.log.log("Exit miniature_layer->get_miniature_by_id(self, id) return None", ORPG_DEBUG) + return None + + def del_miniature(self, min): + self.log.log("Enter miniature_layer->del_miniature(self, min)", ORPG_DEBUG) + xml_str = "<map><miniatures>" + xml_str += min.toxml("del") + xml_str += "</miniatures></map>" + self.canvas.frame.session.send(xml_str) + self.miniatures.remove(min) + del min + self.collapse_zorder() + self.log.log("Exit miniature_layer->del_miniature(self, min)", ORPG_DEBUG) + + def del_all_miniatures(self): + self.log.log("Enter miniature_layer->del_all_miniatures(self)", ORPG_DEBUG) + while len(self.miniatures): + min = self.miniatures.pop() + del min + self.collapse_zorder() + self.log.log("Exit miniature_layer->del_all_miniatures(self)", ORPG_DEBUG) + + def layerDraw(self, dc, topleft, size): + self.log.log("Enter miniature_layer->layerDraw(self, dc, topleft, size)", ORPG_DEBUG) + sorted_miniatures = self.miniatures[:] + sorted_miniatures.sort(cmp_zorder) + for m in sorted_miniatures: + if (m.pos.x>topleft[0]-m.right and + m.pos.y>topleft[1]-m.bottom and + m.pos.x<topleft[0]+size[0]-m.left and + m.pos.y<topleft[1]+size[1]-m.top): + m.draw(dc, self) + self.log.log("Exit miniature_layer->layerDraw(self, dc, topleft, size)", ORPG_DEBUG) + + def find_miniature(self, pt, only_unlocked=False): + self.log.log("Enter miniature_layer->find_miniature(self, pt, only_unlocked)", ORPG_DEBUG) + min_list = [] + for m in self.miniatures: + if m.hit_test(pt): + if m.hide and self.canvas.frame.session.my_role() != self.canvas.frame.session.ROLE_GM: + continue + if only_unlocked and not m.locked: + min_list.append(m) + elif not only_unlocked and m.locked: + min_list.append(m) + else: + continue + if len(min_list) > 0: + self.log.log("Exit miniature_layer->find_miniature(self, pt, only_unlocked)", ORPG_DEBUG) + return min_list + else: + self.log.log("Exit miniature_layer->find_miniature(self, pt, only_unlocked)", ORPG_DEBUG) + return None + + def layerToXML(self, action="update"): + """ format """ + self.log.log("Enter miniature_layer->layerToXML(self, " + action + ")", ORPG_DEBUG) + minis_string = "" + if self.miniatures: + for m in self.miniatures: + minis_string += m.toxml(action) + if minis_string != '': + s = "<miniatures" + s += " serial='" + str(self.serial_number) + "'" + s += ">" + s += minis_string + s += "</miniatures>" + self.log.log("Exit miniature_layer->layerToXML(self, " + action + ")", ORPG_DEBUG) + return s + else: + self.log.log("Exit miniature_layer->layerToXML(self, " + action + ") return None", ORPG_DEBUG) + return "" + + def layerTakeDOM(self, xml_dom): + self.log.log("Enter miniature_layer->layerTakeDOM(self, xml_dom)", ORPG_DEBUG) + if xml_dom.hasAttribute('serial'): + self.serial_number = int(xml_dom.getAttribute('serial')) + children = xml_dom._get_childNodes() + for c in children: + action = c.getAttribute("action") + id = c.getAttribute('id') + if action == "del": + mini = self.get_miniature_by_id(id) + if mini: + self.miniatures.remove(mini) + del mini + else: + self.log.log("Map Synchronization Error :: Update of unknown mini attempted", ORPG_DEBUG) + #wx.MessageBox("Deletion of unknown mini attempted","Map Synchronization Error") + elif action == "new": + pos = cmpPoint(int(c.getAttribute('posx')),int(c.getAttribute('posy'))) + path = urllib.unquote(c.getAttribute('path')) + label = c.getAttribute('label') + height = width = heading = face = snap_to_align = zorder = 0 + locked = hide = False + if c.hasAttribute('height'): + height = int(c.getAttribute('height')) + if c.hasAttribute('width'): + width = int(c.getAttribute('width')) + if c.getAttribute('locked') == 'True' or c.getAttribute('locked') == '1': + locked = True + if c.getAttribute('hide') == 'True' or c.getAttribute('hide') == '1': + hide = True + if c.getAttribute('heading'): + heading = int(c.getAttribute('heading')) + if c.hasAttribute('face'): + face = int(c.getAttribute('face')) + if c.hasAttribute('align'): + snap_to_align = int(c.getAttribute('align')) + if c.getAttribute('zorder'): + zorder = int(c.getAttribute('zorder')) + min = BmpMiniature(id, path, ImageHandler.load(path, 'miniature', id), pos, heading, face, label, locked, hide, snap_to_align, zorder, width, height, self.log) + self.miniatures.append(min) + if c.hasAttribute('local') and c.getAttribute('local') == 'True' and os.path.exists(urllib.unquote(c.getAttribute('localPath'))): + localPath = urllib.unquote(c.getAttribute('localPath')) + local = True + localTime = float(c.getAttribute('localTime')) + if localTime-time.time() <= 144000: + file = open(localPath, "rb") + imgdata = file.read() + file.close() + filename = os.path.split(localPath) + (imgtype,j) = mimetypes.guess_type(filename[1]) + postdata = urllib.urlencode({'filename':filename[1], 'imgdata':imgdata, 'imgtype':imgtype}) + thread.start_new_thread(self.upload, (postdata, localPath, True)) + # collapse the zorder. If the client behaved well, then nothing should change. + # Otherwise, this will ensure that there's some kind of z-order + self.collapse_zorder() + else: + mini = self.get_miniature_by_id(id) + if mini: + mini.takedom(c) + else: + self.log.log("Map Synchronization Error :: Update of unknown mini attempted", ORPG_DEBUG) + #wx.MessageBox("Update of unknown mini attempted","Map Synchronization Error") + self.log.log("Exit miniature_layer->layerTakeDOM(self, xml_dom)", ORPG_DEBUG) + + def upload(self, postdata, filename, modify=False, pos=cmpPoint(0,0)): + 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 not modify: + start = path.rfind("/") + 1 + if self.canvas.parent.layer_handlers[2].auto_label: + min_label = path[start:len(path)-4] + else: + min_label = "" + id = 'mini-' + self.canvas.frame.session.get_next_id() + self.add_miniature(id, path, pos=pos, label=min_label, local=True, localPath=filename, localTime=time.time()) + else: + self.miniatures[len(self.miniatures)-1].local = True + self.miniatures[len(self.miniatures)-1].localPath = filename + self.miniatures[len(self.miniatures)-1].localTime = time.time() + self.miniatures[len(self.miniatures)-1].path = path + else: + print xml_dom.getAttribute('msg') + except Exception, e: + print e + print recvdata + urllib.urlcleanup() + self.lock.release() +#################################################################### + ## helper function + + def get_mini_label(self, mini): + # override this to change the label displayed under each mini (and the label on hidden minis) + return mini.label