comparison orpg/mapper/miniatures.py @ 28:ff154cf3350c ornery-orc

Traipse 'OpenRPG' {100203-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 (Stable) New Features: New Bookmarks Feature New 'boot' command to remote admin New confirmation window for sent nodes Miniatures Layer pop up box allows users to turn off Mini labels, from FlexiRPG New Zoom Mouse plugin added New Images added to Plugin UI Switching to Element Tree New Map efficiency, from FlexiRPG New Status Bar to Update Manager New TrueDebug Class in orpg_log (See documentation for usage) New Portable Mercurial New Tip of the Day, 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 New Dieroller structure from Core New DieRoller portability for odd Dice New 7th Sea die roller; ie [7k3] = [7d10.takeHighest(3).open(10)] New 'Mythos' System die roller 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!) New Grids act more like Spreadsheets in Use mode, with Auto Calc Fixes: Fix to allow for portability to an OpenSUSE linux OS Fix to mplay_client for Fedora and OpenSUSE 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 Fix to whiteboard ID's to prevent non updated clients from ruining the fix. default_manifest.xml renamed to default_upmana.xml
author sirebral
date Wed, 03 Feb 2010 22:16:49 -0600
parents 51428d30c59e
children d02e9197c066
comparison
equal deleted inserted replaced
27:51428d30c59e 28:ff154cf3350c
19 # 19 #
20 # File: mapper/miniatures.py 20 # File: mapper/miniatures.py
21 # Author: Chris Davis 21 # Author: Chris Davis
22 # Maintainer: 22 # Maintainer:
23 # Version: 23 # Version:
24 # $Id: miniatures.py,v 1.46 2007/12/07 20:39:50 digitalxero Exp $ 24 # $Id: miniatures.py,v Traipse 'Ornery-Orc' prof.ebral Exp $
25 # 25 #
26 # Description: This file contains some of the basic definitions for the chat 26 # Description: This file contains some of the basic definitions for the chat
27 # utilities in the orpg project. 27 # utilities in the orpg project.
28 # 28 #
29 __version__ = "$Id: miniatures.py,v 1.46 2007/12/07 20:39:50 digitalxero Exp $" 29 __version__ = "$Id: miniatures.py,v Traipse 'Ornery-Orc' prof.ebral Exp $"
30 30
31 from base import * 31 from base import *
32 import thread 32 import thread, time, urllib, os.path, mimetypes
33 import time
34 import urllib
35 import os.path
36 import mimetypes
37 33
38 import xml.dom.minidom as minidom 34 import xml.dom.minidom as minidom
39 from orpg.tools.orpg_settings import settings 35 from orpg.tools.orpg_settings import settings
36
37 from xml.etree.ElementTree import ElementTree, Element
38 from xml.etree.ElementTree import fromstring, tostring
40 39
41 MIN_STICKY_BACK = -0XFFFFFF 40 MIN_STICKY_BACK = -0XFFFFFF
42 MIN_STICKY_FRONT = 0xFFFFFF 41 MIN_STICKY_FRONT = 0xFFFFFF
43 42
44 ##---------------------------------------- 43 ##----------------------------------------
66 elif f < s: value = -1 65 elif f < s: value = -1
67 else: value = 1 66 else: value = 1
68 return value 67 return value
69 68
70 class BmpMiniature: 69 class BmpMiniature:
71 def __init__(self, id,path, bmp, pos=cmpPoint(0,0), 70 def __init__(self, id, path, bmp, pos=cmpPoint(0,0),
72 heading=FACE_NONE, face=FACE_NONE, label="", 71 heading=FACE_NONE, face=FACE_NONE, label="",
73 locked=False, hide=False, snap_to_align=SNAPTO_ALIGN_CENTER, 72 locked=False, hide=False, snap_to_align=SNAPTO_ALIGN_CENTER,
74 zorder=0, width=0, height=0, log=None, local=False, localPath='', localTime=-1): 73 zorder=0, width=0, height=0, log=None, local=False, localPath='', localTime=-1, func='none'):
75 self.heading = heading 74 self.heading = heading
76 self.face = face 75 self.face = face
77 self.label = label 76 self.label = label
78 self.path = path 77 self.path = path
79 self.bmp = bmp
80 self.pos = pos 78 self.pos = pos
81 self.selected = False 79 self.selected = False
82 self.locked = locked 80 self.locked = locked
83 self.snap_to_align = snap_to_align 81 self.snap_to_align = snap_to_align
84 self.hide = hide 82 self.hide = hide
95 self.right = bmp.GetWidth() 93 self.right = bmp.GetWidth()
96 self.top = 0 94 self.top = 0
97 self.bottom = bmp.GetHeight() 95 self.bottom = bmp.GetHeight()
98 self.isUpdated = False 96 self.isUpdated = False
99 self.gray = False 97 self.gray = False
98 self.set_bmp(bmp)
100 99
101 def __del__(self): 100 def __del__(self):
102 del self.bmp 101 del self.image
103 self.bmp = None 102 self.image = None
104 103
105 def set_bmp(self, bmp): 104 def set_bmp(self, bmp):
106 self.bmp = bmp 105 self.image = bmp
106 self.image.ConvertAlphaToMask()
107 self.generate_bmps()
108
109 def generate_bmps(self):
110 if self.width:
111 bmp = self.image.Copy()
112 bmp.Rescale(int(self.width), int(self.height))
113 else:
114 bmp = self.image
115 self.bmp = bmp.ConvertToBitmap()
116 self.bmp_gray = bmp.ConvertToGreyscale().ConvertToBitmap()
107 117
108 def set_min_props(self, heading=FACE_NONE, face=FACE_NONE, label="", locked=False, hide=False, width=0, height=0): 118 def set_min_props(self, heading=FACE_NONE, face=FACE_NONE, label="", locked=False, hide=False, width=0, height=0):
109 self.heading = heading 119 self.heading = heading
110 self.face = face 120 self.face = face
111 self.label = label 121 self.label = label
114 if hide: self.hide = True 124 if hide: self.hide = True
115 else: self.hide = False 125 else: self.hide = False
116 self.width = int(width) 126 self.width = int(width)
117 self.height = int(height) 127 self.height = int(height)
118 self.isUpdated = True 128 self.isUpdated = True
129 self.generate_bmps()
119 130
120 def hit_test(self, pt): 131 def hit_test(self, pt):
121 rect = self.get_rect() 132 rect = self.get_rect()
122 result = None 133 result = None
123 result = rect.InsideXY(pt.x, pt.y) 134 result = rect.InsideXY(pt.x, pt.y)
126 def get_rect(self): 137 def get_rect(self):
127 ret = wx.Rect(self.pos.x, self.pos.y, self.bmp.GetWidth(), self.bmp.GetHeight()) 138 ret = wx.Rect(self.pos.x, self.pos.y, self.bmp.GetWidth(), self.bmp.GetHeight())
128 return ret 139 return ret
129 140
130 def draw(self, dc, mini_layer, op=wx.COPY): 141 def draw(self, dc, mini_layer, op=wx.COPY):
131 if isinstance(self.bmp, tuple): 142 if self.hide and mini_layer.canvas.frame.session.my_role() == mini_layer.canvas.frame.session.ROLE_GM:
132 self.bmp = wx.ImageFromMime(self.bmp[1], self.bmp[2]).ConvertToBitmap() 143 # set the width and height of the image
133 if self.bmp != None and self.bmp.Ok(): 144 self.left = 0
134 # check if hidden and GM: we outline the mini in grey (little bit smaller than the actual size) 145 self.right = self.bmp.GetWidth()
135 # and write the label in the center of the mini 146 self.top = 0
136 if self.hide and mini_layer.canvas.frame.session.my_role() == mini_layer.canvas.frame.session.ROLE_GM: 147 self.bottom = self.bmp.GetHeight()
137 # set the width and height of the image 148 # grey outline
138 if self.width and self.height: 149 graypen = wx.Pen("gray", 1, wx.DOT)
139 tmp_image = self.bmp.ConvertToImage() 150 dc.SetPen(graypen)
140 tmp_image.Rescale(int(self.width), int(self.height)) 151 dc.SetBrush(wx.TRANSPARENT_BRUSH)
141 tmp_image.ConvertAlphaToMask() 152 #if width or height < 20 then offset = 1
142 self.bmp = tmp_image.ConvertToBitmap() 153 if self.bmp.GetWidth() <= 20: xoffset = 1
143 mask = wx.Mask(self.bmp, wx.Colour(tmp_image.GetMaskRed(), 154 else: xoffset = 5
144 tmp_image.GetMaskGreen(), tmp_image.GetMaskBlue())) 155 if self.bmp.GetHeight() <= 20: yoffset = 1
145 self.bmp.SetMask(mask) 156 else: yoffset = 5
146 del tmp_image 157 dc.DrawRectangle(self.pos.x + xoffset,
147 del mask 158 self.pos.y + yoffset, self.bmp.GetWidth(),
148 self.left = 0 159 self.bmp.GetHeight())
149 self.right = self.bmp.GetWidth() 160 dc.SetBrush(wx.NullBrush)
150 self.top = 0 161 dc.SetPen(wx.NullPen)
151 self.bottom = self.bmp.GetHeight() 162 if mini_layer.show_labels:
152 # grey outline
153 graypen = wx.Pen("gray", 1, wx.DOT)
154 dc.SetPen(graypen)
155 dc.SetBrush(wx.TRANSPARENT_BRUSH)
156 #if width or height < 20 then offset = 1
157 if self.bmp.GetWidth() <= 20: xoffset = 1
158 else: xoffset = 5
159 if self.bmp.GetHeight() <= 20: yoffset = 1
160 else: yoffset = 5
161 dc.DrawRectangle(self.pos.x + xoffset,
162 self.pos.y + yoffset, self.bmp.GetWidth() - (xoffset * 2),
163 self.bmp.GetHeight() - (yoffset * 2))
164 dc.SetBrush(wx.NullBrush)
165 dc.SetPen(wx.NullPen)
166 ## draw label in the center of the mini 163 ## draw label in the center of the mini
167 label = mini_layer.get_mini_label(self) 164 label = mini_layer.get_mini_label(self)
168 if len(label): 165 if len(label):
169 dc.SetTextForeground(wx.RED) 166 dc.SetTextForeground(wx.RED)
170 (textWidth,textHeight) = dc.GetTextExtent(label) 167 (textWidth,textHeight) = dc.GetTextExtent(label)
178 self.left -= int((textWidth+2-self.right)/2)+1 175 self.left -= int((textWidth+2-self.right)/2)+1
179 self.bottom = y+textHeight+2-self.pos.y 176 self.bottom = y+textHeight+2-self.pos.y
180 dc.SetPen(wx.NullPen) 177 dc.SetPen(wx.NullPen)
181 dc.SetBrush(wx.NullBrush) 178 dc.SetBrush(wx.NullBrush)
182 dc.DrawText(label, x+1, y+1) 179 dc.DrawText(label, x+1, y+1)
183 180
184 #selected outline 181 #selected outline
185 if self.selected: 182 if self.selected:
186 dc.SetPen(wx.RED_PEN) 183 dc.SetPen(wx.RED_PEN)
187 dc.SetBrush(wx.TRANSPARENT_BRUSH) 184 dc.SetBrush(wx.TRANSPARENT_BRUSH)
188 dc.DrawRectangle(self.pos.x, self.pos.y, self.bmp.GetWidth(), self.bmp.GetHeight()) 185 dc.DrawRectangle(self.pos.x, self.pos.y, self.bmp.GetWidth(), self.bmp.GetHeight())
189 dc.SetBrush(wx.NullBrush) 186 dc.SetBrush(wx.NullBrush)
190 dc.SetPen(wx.NullPen) 187 dc.SetPen(wx.NullPen)
191 return True 188 return True
192 elif self.hide: return True 189 elif self.hide: return True
193 190
194 else: 191 else:
195 # set the width and height of the image 192 bmp = self.bmp_gray if self.gray else self.bmp
196 bmp = self.bmp 193 try: dc.DrawBitmap(bmp, self.pos.x, self.pos.y, True)
197 if self.width and self.height: 194 except: print bmp
198 tmp_image = self.bmp.ConvertToImage() 195 self.left = 0
199 tmp_image.Rescale(int(self.width), int(self.height)) 196 self.right = self.bmp.GetWidth()
200 tmp_image.ConvertAlphaToMask() 197 self.top = 0
201 self.bmp = tmp_image.ConvertToBitmap() 198 self.bottom = self.bmp.GetHeight()
202 mask = wx.Mask(self.bmp, wx.Colour(tmp_image.GetMaskRed(), 199 # Draw the facing marker if needed
203 tmp_image.GetMaskGreen(), tmp_image.GetMaskBlue())) 200 if self.face != 0:
204 self.bmp.SetMask(mask) 201 x_mid = self.pos.x + (self.bmp.GetWidth()/2)
205 if self.gray: 202 x_right = self.pos.x + self.bmp.GetWidth()
206 tmp_image = tmp_image.ConvertToGreyscale() 203 y_mid = self.pos.y + (self.bmp.GetHeight()/2)
207 bmp = tmp_image.ConvertToBitmap() 204 y_bottom = self.pos.y + self.bmp.GetHeight()
208 else: bmp = self.bmp 205 dc.SetPen(wx.WHITE_PEN)
209 dc.DrawBitmap(bmp, self.pos.x, self.pos.y, True) 206 dc.SetBrush(wx.RED_BRUSH)
210 self.left = 0 207 triangle = []
211 self.right = self.bmp.GetWidth() 208 # Figure out which direction to draw the marker!!
212 self.top = 0 209 tri_list = {
213 self.bottom = self.bmp.GetHeight() 210 FACE_WEST: [cmpPoint(self.pos.x, self.pos.y), cmpPoint(self.pos.x-5, y_mid), cmpPoint(self.pos.x, y_bottom)],
214 211 FACE_EAST: [cmpPoint(x_right, self.pos.y), cmpPoint(x_right + 5, y_mid), cmpPoint(x_right, y_bottom)],
215 # Draw the facing marker if needed 212 FACE_SOUTH: [cmpPoint(self.pos.x, y_bottom), cmpPoint(x_mid, y_bottom + 5), cmpPoint(x_right, y_bottom)],
216 if self.face != 0: 213 FACE_NORTH: [cmpPoint(self.pos.x, self.pos.y), cmpPoint(x_mid, self.pos.y - 5), cmpPoint(x_right, self.pos.y)],
217 x_mid = self.pos.x + (self.bmp.GetWidth()/2) 214 FACE_NORTHEAST: [cmpPoint(x_mid, self.pos.y), cmpPoint(x_right + 5, self.pos.y - 5), cmpPoint(x_right, y_mid), cmpPoint(x_right, self.pos.y)],
218 x_right = self.pos.x + self.bmp.GetWidth() 215 FACE_SOUTHEAST: [cmpPoint(x_right, y_mid), cmpPoint(x_right + 5, y_bottom + 5), cmpPoint(x_mid, y_bottom), cmpPoint(x_right, y_bottom)],
219 y_mid = self.pos.y + (self.bmp.GetHeight()/2) 216 FACE_SOUTHWEST: [cmpPoint(x_mid, y_bottom), cmpPoint(self.pos.x - 5, y_bottom + 5),
220 y_bottom = self.pos.y + self.bmp.GetHeight() 217 cmpPoint(self.pos.x, y_mid), cmpPoint(self.pos.x, y_bottom)],
221 dc.SetPen(wx.WHITE_PEN) 218 FACE_NORTHWEST: [cmpPoint(self.pos.x, y_mid), cmpPoint(self.pos.x - 5, self.pos.y - 5), cmpPoint(x_mid, self.pos.y), cmpPoint(self.pos.x, self.pos.y)]
222 dc.SetBrush(wx.RED_BRUSH) 219 }
223 triangle = [] 220 for tri in tri_list[self.face]:
224 221 triangle.append(tri)
225 # Figure out which direction to draw the marker!! 222 del tri_list
226 if self.face == FACE_WEST: 223 dc.DrawPolygon(triangle)
227 triangle.append(cmpPoint(self.pos.x,self.pos.y)) 224 dc.SetBrush(wx.NullBrush)
228 triangle.append(cmpPoint(self.pos.x - 5, y_mid)) 225 dc.SetPen(wx.NullPen)
229 triangle.append(cmpPoint(self.pos.x, y_bottom)) 226 # Draw the heading if needed
230 elif self.face == FACE_EAST: 227 if self.heading:
231 triangle.append(cmpPoint(x_right, self.pos.y)) 228 x_adjust = 0
232 triangle.append(cmpPoint(x_right + 5, y_mid)) 229 y_adjust = 4
233 triangle.append(cmpPoint(x_right, y_bottom)) 230 x_half = self.bmp.GetWidth()/2
234 elif self.face == FACE_SOUTH: 231 y_half = self.bmp.GetHeight()/2
235 triangle.append(cmpPoint(self.pos.x, y_bottom)) 232 x_quarter = self.bmp.GetWidth()/4
236 triangle.append(cmpPoint(x_mid, y_bottom + 5)) 233 y_quarter = self.bmp.GetHeight()/4
237 triangle.append(cmpPoint(x_right, y_bottom)) 234 x_3quarter = x_quarter*3
238 elif self.face == FACE_NORTH: 235 y_3quarter = y_quarter*3
239 triangle.append(cmpPoint(self.pos.x, self.pos.y)) 236 x_full = self.bmp.GetWidth()
240 triangle.append(cmpPoint(x_mid, self.pos.y - 5)) 237 y_full = self.bmp.GetHeight()
241 triangle.append(cmpPoint(x_right, self.pos.y)) 238 x_center = self.pos.x + x_half
242 elif self.face == FACE_NORTHEAST: 239 y_center = self.pos.y + y_half
243 triangle.append(cmpPoint(x_mid, self.pos.y)) 240 # Remember, the pen/brush must be a different color than the
244 triangle.append(cmpPoint(x_right + 5, self.pos.y - 5)) 241 # facing marker!!!! We'll use black/cyan for starters.
245 triangle.append(cmpPoint(x_right, y_mid)) 242 # Also notice that we will draw the heading on top of the
246 triangle.append(cmpPoint(x_right, self.pos.y)) 243 # larger facing marker.
247 elif self.face == FACE_SOUTHEAST: 244 dc.SetPen(wx.BLACK_PEN)
248 triangle.append(cmpPoint(x_right, y_mid)) 245 dc.SetBrush(wx.CYAN_BRUSH)
249 triangle.append(cmpPoint(x_right + 5, y_bottom + 5)) 246 triangle = []
250 triangle.append(cmpPoint(x_mid, y_bottom)) 247 # Figure out which direction to draw the marker!!
251 triangle.append(cmpPoint(x_right, y_bottom)) 248 tri_list = {
252 elif self.face == FACE_SOUTHWEST: 249 FACE_NORTH: [cmpPoint(x_center - x_quarter, y_center - y_half ),
253 triangle.append(cmpPoint(x_mid, y_bottom)) 250 cmpPoint(x_center, y_center - y_3quarter ),
254 triangle.append(cmpPoint(self.pos.x - 5, y_bottom + 5)) 251 cmpPoint(x_center + x_quarter, y_center - y_half)],
255 triangle.append(cmpPoint(self.pos.x, y_mid)) 252 FACE_SOUTH: [cmpPoint(x_center - x_quarter, y_center + y_half ),
256 triangle.append(cmpPoint(self.pos.x, y_bottom)) 253 cmpPoint(x_center, y_center + y_3quarter ),
257 elif self.face == FACE_NORTHWEST: 254 cmpPoint(x_center + x_quarter, y_center + y_half )],
258 triangle.append(cmpPoint(self.pos.x, y_mid)) 255 FACE_NORTHEAST: [cmpPoint(x_center + x_quarter, y_center - y_half ),
259 triangle.append(cmpPoint(self.pos.x - 5, self.pos.y - 5)) 256 cmpPoint(x_center + x_3quarter, y_center - y_3quarter ),
260 triangle.append(cmpPoint(x_mid, self.pos.y)) 257 cmpPoint(x_center + x_half, y_center - y_quarter)],
261 triangle.append(cmpPoint(self.pos.x, self.pos.y)) 258 FACE_EAST: [cmpPoint(x_center + x_half, y_center - y_quarter ),
262 dc.DrawPolygon(triangle) 259 cmpPoint(x_center + x_3quarter, y_center ),
263 dc.SetBrush(wx.NullBrush) 260 cmpPoint(x_center + x_half, y_center + y_quarter )],
264 dc.SetPen(wx.NullPen) 261 FACE_SOUTHEAST: [cmpPoint(x_center + x_half, y_center + y_quarter ),
265 262 cmpPoint(x_center + x_3quarter, y_center + y_3quarter ),
266 # Draw the heading if needed 263 cmpPoint(x_center + x_quarter, y_center + y_half )],
267 if self.heading: 264 FACE_SOUTHWEST: [cmpPoint(x_center - x_quarter, y_center + y_half ),
268 x_adjust = 0 265 cmpPoint(x_center - x_3quarter, y_center + y_3quarter ),
269 y_adjust = 4 266 cmpPoint(x_center - x_half, y_center + y_quarter )],
270 x_half = self.bmp.GetWidth()/2 267 FACE_WEST: [cmpPoint(x_center - x_half, y_center + y_quarter ),
271 y_half = self.bmp.GetHeight()/2 268 cmpPoint(x_center - x_3quarter, y_center ),
272 x_quarter = self.bmp.GetWidth()/4 269 cmpPoint(x_center - x_half, y_center - y_quarter )],
273 y_quarter = self.bmp.GetHeight()/4 270 FACE_NORTHWEST: [cmpPoint(x_center - x_half, y_center - y_quarter ),
274 x_3quarter = x_quarter*3 271 cmpPoint(x_center - x_3quarter, y_center - y_3quarter ),
275 y_3quarter = y_quarter*3 272 cmpPoint(x_center - x_quarter, y_center - y_half )]}
276 x_full = self.bmp.GetWidth() 273 for tri in tri_list[self.heading]:
277 y_full = self.bmp.GetHeight() 274 triangle.append(tri)
278 x_center = self.pos.x + x_half 275 del tri_list
279 y_center = self.pos.y + y_half 276 dc.DrawPolygon(triangle)
280 # Remember, the pen/brush must be a different color than the 277 dc.SetBrush(wx.NullBrush)
281 # facing marker!!!! We'll use black/cyan for starters. 278 dc.SetPen(wx.NullPen)
282 # Also notice that we will draw the heading on top of the 279 #selected outline
283 # larger facing marker. 280 if self.selected:
284 dc.SetPen(wx.BLACK_PEN) 281 dc.SetPen(wx.RED_PEN)
285 dc.SetBrush(wx.CYAN_BRUSH) 282 dc.SetBrush(wx.TRANSPARENT_BRUSH)
286 triangle = [] 283 dc.DrawRectangle(self.pos.x, self.pos.y, self.bmp.GetWidth(), self.bmp.GetHeight())
287 284 dc.SetBrush(wx.NullBrush)
288 # Figure out which direction to draw the marker!! 285 dc.SetPen(wx.NullPen)
289 if self.heading == FACE_NORTH: 286 if mini_layer.show_labels:
290 triangle.append(cmpPoint(x_center - x_quarter, y_center - y_half ))
291 triangle.append(cmpPoint(x_center, y_center - y_3quarter ))
292 triangle.append(cmpPoint(x_center + x_quarter, y_center - y_half ))
293 elif self.heading == FACE_SOUTH:
294 triangle.append(cmpPoint(x_center - x_quarter, y_center + y_half ))
295 triangle.append(cmpPoint(x_center, y_center + y_3quarter ))
296 triangle.append(cmpPoint(x_center + x_quarter, y_center + y_half ))
297 elif self.heading == FACE_NORTHEAST:
298 triangle.append(cmpPoint(x_center + x_quarter, y_center - y_half ))
299 triangle.append(cmpPoint(x_center + x_3quarter, y_center - y_3quarter ))
300 triangle.append(cmpPoint(x_center + x_half, y_center - y_quarter ))
301 elif self.heading == FACE_EAST:
302 triangle.append(cmpPoint(x_center + x_half, y_center - y_quarter ))
303 triangle.append(cmpPoint(x_center + x_3quarter, y_center ))
304 triangle.append(cmpPoint(x_center + x_half, y_center + y_quarter ))
305 elif self.heading == FACE_SOUTHEAST:
306 triangle.append(cmpPoint(x_center + x_half, y_center + y_quarter ))
307 triangle.append(cmpPoint(x_center + x_3quarter, y_center + y_3quarter ))
308 triangle.append(cmpPoint(x_center + x_quarter, y_center + y_half ))
309 elif self.heading == FACE_SOUTHWEST:
310 triangle.append(cmpPoint(x_center - x_quarter, y_center + y_half ))
311 triangle.append(cmpPoint(x_center - x_3quarter, y_center + y_3quarter ))
312 triangle.append(cmpPoint(x_center - x_half, y_center + y_quarter ))
313 elif self.heading == FACE_WEST:
314 triangle.append(cmpPoint(x_center - x_half, y_center + y_quarter ))
315 triangle.append(cmpPoint(x_center - x_3quarter, y_center ))
316 triangle.append(cmpPoint(x_center - x_half, y_center - y_quarter ))
317 elif self.heading == FACE_NORTHWEST:
318 triangle.append(cmpPoint(x_center - x_half, y_center - y_quarter ))
319 triangle.append(cmpPoint(x_center - x_3quarter, y_center - y_3quarter ))
320 triangle.append(cmpPoint(x_center - x_quarter, y_center - y_half ))
321 dc.DrawPolygon(triangle)
322 dc.SetBrush(wx.NullBrush)
323 dc.SetPen(wx.NullPen)
324 #selected outline
325 if self.selected:
326 dc.SetPen(wx.RED_PEN)
327 dc.SetBrush(wx.TRANSPARENT_BRUSH)
328 dc.DrawRectangle(self.pos.x, self.pos.y, self.bmp.GetWidth(), self.bmp.GetHeight())
329 dc.SetBrush(wx.NullBrush)
330 dc.SetPen(wx.NullPen)
331 # draw label 287 # draw label
332 label = mini_layer.get_mini_label(self) 288 self.mini_label(mini_layer, dc)
333 if len(label): 289 self.top-=5
334 dc.SetTextForeground(wx.RED) 290 self.bottom+=5
335 (textWidth,textHeight) = dc.GetTextExtent(label) 291 self.left-=5
336 x = self.pos.x +((self.bmp.GetWidth() - textWidth) /2) - 1 292 self.right+=5
337 y = self.pos.y + self.bmp.GetHeight() + 6 293 return True
338 dc.SetPen(wx.WHITE_PEN) 294
339 dc.SetBrush(wx.WHITE_BRUSH) 295
340 dc.DrawRectangle(x,y,textWidth+2,textHeight+2) 296 def mini_label(self, mini_layer, dc):
341 if (textWidth+2 > self.right): 297 label = mini_layer.get_mini_label(self)
342 self.right += int((textWidth+2-self.right)/2)+1 298 if len(label):
343 self.left -= int((textWidth+2-self.right)/2)+1 299 dc.SetTextForeground(wx.RED)
344 self.bottom = y+textHeight+2-self.pos.y 300 (textWidth,textHeight) = dc.GetTextExtent(label)
345 dc.SetPen(wx.NullPen) 301 x = self.pos.x +((self.bmp.GetWidth() - textWidth) /2) - 1
346 dc.SetBrush(wx.NullBrush) 302 y = self.pos.y + self.bmp.GetHeight() + 6
347 dc.DrawText(label,x+1,y+1) 303 dc.SetPen(wx.WHITE_PEN)
348 self.top-=5 304 dc.SetBrush(wx.WHITE_BRUSH)
349 self.bottom+=5 305 dc.DrawRectangle(x,y,textWidth+2,textHeight+2)
350 self.left-=5 306 if (textWidth+2 > self.right):
351 self.right+=5 307 self.right += int((textWidth+2-self.right)/2)+1
352 return True 308 self.left -= int((textWidth+2-self.right)/2)+1
353 else: return False 309 self.bottom = y+textHeight+2-self.pos.y
310 dc.SetPen(wx.NullPen)
311 dc.SetBrush(wx.NullBrush)
312 dc.DrawText(label,x+1,y+1)
354 313
355 def toxml(self, action="update"): 314 def toxml(self, action="update"):
356 if action == "del": 315 if action == "del":
357 xml_str = "<miniature action='del' id='" + self.id + "'/>" 316 xml_str = "<miniature action='del' id='" + self.id + "'/>"
358 return xml_str 317 return xml_str
384 return xml_str 343 return xml_str
385 else: return '' 344 else: return ''
386 345
387 def takedom(self, xml_dom): 346 def takedom(self, xml_dom):
388 self.id = xml_dom.getAttribute("id") 347 self.id = xml_dom.getAttribute("id")
389 if xml_dom.hasAttribute("posx"): 348 if xml_dom.hasAttribute("posx"): self.pos.x = int(xml_dom.getAttribute("posx"))
390 self.pos.x = int(xml_dom.getAttribute("posx")) 349 if xml_dom.hasAttribute("posy"): self.pos.y = int(xml_dom.getAttribute("posy"))
391 if xml_dom.hasAttribute("posy"): 350 if xml_dom.hasAttribute("heading"): self.heading = int(xml_dom.getAttribute("heading"))
392 self.pos.y = int(xml_dom.getAttribute("posy")) 351 if xml_dom.hasAttribute("face"): self.face = int(xml_dom.getAttribute("face"))
393 if xml_dom.hasAttribute("heading"):
394 self.heading = int(xml_dom.getAttribute("heading"))
395 if xml_dom.hasAttribute("face"):
396 self.face = int(xml_dom.getAttribute("face"))
397 if xml_dom.hasAttribute("path"): 352 if xml_dom.hasAttribute("path"):
398 self.path = urllib.unquote(xml_dom.getAttribute("path")) 353 self.path = urllib.unquote(xml_dom.getAttribute("path"))
399 self.set_bmp(ImageHandler.load(self.path, 'miniature', self.id)) 354 self.set_bmp(ImageHandler.load(self.path, 'miniature', self.id))
400 if xml_dom.hasAttribute("locked"): 355 if xml_dom.hasAttribute("locked"):
401 if xml_dom.getAttribute("locked") == '1' or xml_dom.getAttribute("locked") == 'True': self.locked = True 356 if xml_dom.getAttribute("locked") == '1' or xml_dom.getAttribute("locked") == 'True': self.locked = True
402 else: self.locked = False 357 else: self.locked = False
403 if xml_dom.hasAttribute("hide"): 358 if xml_dom.hasAttribute("hide"):
404 if xml_dom.getAttribute("hide") == '1' or xml_dom.getAttribute("hide") == 'True': self.hide = True 359 if xml_dom.getAttribute("hide") == '1' or xml_dom.getAttribute("hide") == 'True': self.hide = True
405 else: self.hide = False 360 else: self.hide = False
406 if xml_dom.hasAttribute("label"): 361 if xml_dom.hasAttribute("label"): self.label = xml_dom.getAttribute("label")
407 self.label = xml_dom.getAttribute("label") 362 if xml_dom.hasAttribute("zorder"): self.zorder = int(xml_dom.getAttribute("zorder"))
408 if xml_dom.hasAttribute("zorder"):
409 self.zorder = int(xml_dom.getAttribute("zorder"))
410 if xml_dom.hasAttribute("align"): 363 if xml_dom.hasAttribute("align"):
411 if xml_dom.getAttribute("align") == '1' or xml_dom.getAttribute("align") == 'True': self.snap_to_align = 1 364 if xml_dom.getAttribute("align") == '1' or xml_dom.getAttribute("align") == 'True': self.snap_to_align = 1
412 else: self.snap_to_align = 0 365 else: self.snap_to_align = 0
413 if xml_dom.hasAttribute("width"): 366 if xml_dom.hasAttribute("width"): self.width = int(xml_dom.getAttribute("width"))
414 self.width = int(xml_dom.getAttribute("width")) 367 if xml_dom.hasAttribute("height"): self.height = int(xml_dom.getAttribute("height"))
415 if xml_dom.hasAttribute("height"):
416 self.height = int(xml_dom.getAttribute("height"))
417 368
418 ##----------------------------- 369 ##-----------------------------
419 ## miniature layer 370 ## miniature layer
420 ##----------------------------- 371 ##-----------------------------
421 class miniature_layer(layer_base): 372 class miniature_layer(layer_base):
422 def __init__(self, canvas): 373 def __init__(self, canvas):
423 self.canvas = canvas 374 self.canvas = canvas
424 layer_base.__init__(self) 375 layer_base.__init__(self)
425 self.id = -1 #added. 376 self.id = -1
426 self.miniatures = [] 377 self.miniatures = []
427 self.serial_number = 0 378 self.serial_number = 0
428 379 self.show_labels = True
429 # Set the font of the labels to be the same as the chat window 380 # Set the font of the labels to be the same as the chat window
430 # only smaller. 381 # only smaller.
431 font_size = int(settings.get_setting('defaultfontsize')) 382 font_size = int(settings.get_setting('defaultfontsize'))
432 if (font_size >= 10): font_size -= 2 383 if (font_size >= 10): font_size -= 2
433 self.label_font = wx.Font(font_size, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, 384 self.label_font = wx.Font(font_size,
385 wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL,
386 wx.FONTWEIGHT_NORMAL,
434 False, settings.get_setting('defaultfont')) 387 False, settings.get_setting('defaultfont'))
435 388
436 def next_serial(self): 389 def next_serial(self):
437 self.serial_number += 1 390 self.serial_number += 1
438 return self.serial_number 391 return self.serial_number
468 def add_miniature(self, id, path, pos=cmpPoint(0,0), label="", heading=FACE_NONE, 421 def add_miniature(self, id, path, pos=cmpPoint(0,0), label="", heading=FACE_NONE,
469 face=FACE_NONE, width=0, height=0, local=False, localPath='', localTime=-1): 422 face=FACE_NONE, width=0, height=0, local=False, localPath='', localTime=-1):
470 bmp = ImageHandler.load(path, 'miniature', id) 423 bmp = ImageHandler.load(path, 'miniature', id)
471 if bmp: 424 if bmp:
472 mini = BmpMiniature(id, path, bmp, pos, heading, face, label, 425 mini = BmpMiniature(id, path, bmp, pos, heading, face, label,
473 zorder=self. get_next_highest_z(), width=width, 426 zorder=self.get_next_highest_z(), width=width,
474 height=height, local=local, localPath=localPath, localTime=localTime) 427 height=height, local=local, localPath=localPath, localTime=localTime)
475 self.miniatures.append(mini) 428 self.miniatures.append(mini)
476 xml_str = "<map><miniatures>" 429 xml_str = "<map><miniatures>"
477 xml_str += mini.toxml("new") 430 xml_str += mini.toxml("new")
478 xml_str += "</miniatures></map>" 431 xml_str += "</miniatures></map>"
479 self.canvas.frame.session.send(xml_str) 432 self.canvas.frame.session.send(xml_str)
480 433
481 def get_miniature_by_id(self, id): 434 def get_miniature_by_id(self, id):
482 for mini in self.miniatures: 435 for mini in self.miniatures:
483 if str(mini.id) == str(id): 436 if str(mini.id) == str(id): return mini
484 return mini
485 return None 437 return None
486 438
487 def del_miniature(self, min): 439 def del_miniature(self, min):
488 xml_str = "<map><miniatures>" 440 xml_str = "<map><miniatures>"
489 xml_str += min.toxml("del") 441 xml_str += min.toxml("del")
543 for c in children: 495 for c in children:
544 action = c.getAttribute("action") 496 action = c.getAttribute("action")
545 id = c.getAttribute('id') 497 id = c.getAttribute('id')
546 if action == "del": 498 if action == "del":
547 mini = self.get_miniature_by_id(id) 499 mini = self.get_miniature_by_id(id)
548 if mini: 500 if mini: self.miniatures.remove(mini); del mini
549 self.miniatures.remove(mini)
550 del mini
551 elif action == "new": 501 elif action == "new":
552 pos = cmpPoint(int(c.getAttribute('posx')),int(c.getAttribute('posy'))) 502 pos = cmpPoint(int(c.getAttribute('posx')),int(c.getAttribute('posy')))
553 path = urllib.unquote(c.getAttribute('path')) 503 path = urllib.unquote(c.getAttribute('path'))
554 label = c.getAttribute('label') 504 label = c.getAttribute('label')
555 height = width = heading = face = snap_to_align = zorder = 0 505 height = width = heading = face = snap_to_align = zorder = 0
576 filename = os.path.split(localPath) 526 filename = os.path.split(localPath)
577 (imgtype,j) = mimetypes.guess_type(filename[1]) 527 (imgtype,j) = mimetypes.guess_type(filename[1])
578 postdata = urllib.urlencode({'filename':filename[1], 'imgdata':imgdata, 'imgtype':imgtype}) 528 postdata = urllib.urlencode({'filename':filename[1], 'imgdata':imgdata, 'imgtype':imgtype})
579 thread.start_new_thread(self.upload, (postdata, localPath, True)) 529 thread.start_new_thread(self.upload, (postdata, localPath, True))
580 # collapse the zorder. If the client behaved well, then nothing should change. 530 # collapse the zorder. If the client behaved well, then nothing should change.
581 # Otherwise, this will ensure that there's some kind of z-order 531 # Otherwise, this will ensure that there's some kind of z-order
582 self.collapse_zorder() 532 self.collapse_zorder()
583 else: 533 else:
584 mini = self.get_miniature_by_id(id) 534 mini = self.get_miniature_by_id(id)
585 if mini: mini.takedom(c) 535 if mini: mini.takedom(c)
586 536
589 url = settings.get_setting('ImageServerBaseURL') 539 url = settings.get_setting('ImageServerBaseURL')
590 file = urllib.urlopen(url, postdata) 540 file = urllib.urlopen(url, postdata)
591 recvdata = file.read() 541 recvdata = file.read()
592 file.close() 542 file.close()
593 try: 543 try:
594 xml_dom = minidom.parseString(recvdata)._get_documentElement() 544 xml_dom = fromstring(recvdata)
595 if xml_dom.nodeName == 'path': 545 if xml_dom.tag == 'path':
596 path = xml_dom.getAttribute('url') 546 path = xml_dom.get('url')
597 path = urllib.unquote(path) 547 path = urllib.unquote(path)
598 if not modify: 548 if not modify:
599 start = path.rfind("/") + 1 549 start = path.rfind("/") + 1
600 if self.canvas.parent.layer_handlers[2].auto_label: min_label = path[start:len(path)-4] 550 if self.canvas.parent.layer_handlers[2].auto_label: min_label = path[start:len(path)-4]
601 else: min_label = "" 551 else: min_label = ""
605 else: 555 else:
606 self.miniatures[len(self.miniatures)-1].local = True 556 self.miniatures[len(self.miniatures)-1].local = True
607 self.miniatures[len(self.miniatures)-1].localPath = filename 557 self.miniatures[len(self.miniatures)-1].localPath = filename
608 self.miniatures[len(self.miniatures)-1].localTime = time.time() 558 self.miniatures[len(self.miniatures)-1].localTime = time.time()
609 self.miniatures[len(self.miniatures)-1].path = path 559 self.miniatures[len(self.miniatures)-1].path = path
610 else: 560 else: print xml_dom.get('msg')
611 print xml_dom.getAttribute('msg')
612 except Exception, e: 561 except Exception, e:
613 print e 562 print e
614 print recvdata 563 print recvdata
615 finally: 564 finally:
616 urllib.urlcleanup() 565 urllib.urlcleanup()