comparison orpg/mapper/map.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 5df1340bda13
comparison
equal deleted inserted replaced
-1:000000000000 0:4385a7d0efd1
1 # Copyright (C) 2000-2001 The OpenRPG Project
2 #
3 # openrpg-dev@lists.sourceforge.net
4 #
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2 of the License, or
8 # (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 # --
19 #
20 # File: mapper/map.py
21 # Author: OpenRPG
22 # Maintainer:
23 # Version:
24 # $Id: map.py,v 1.73 2007/12/07 20:39:49 digitalxero Exp $
25 #
26 # Description:
27 #
28 __version__ = "$Id: map.py,v 1.73 2007/12/07 20:39:49 digitalxero Exp $"
29
30 from map_version import MAP_VERSION
31 from map_msg import *
32 from min_dialogs import *
33 from map_prop_dialog import *
34 import orpg.dirpath
35 import random
36 import os
37 import thread
38 import gc
39 import traceback
40 from miniatures_handler import *
41 from whiteboard_handler import *
42 from background_handler import *
43 from fog_handler import *
44 from images import ImageHandler
45 from grid_handler import *
46 from map_handler import *
47 from orpg.orpgCore import open_rpg
48
49 # Various marker modes for player tools on the map
50 MARKER_MODE_NONE = 0
51 MARKER_MODE_MEASURE = 1
52 MARKER_MODE_TARGET = 2
53 MARKER_MODE_AREA_TARGET = 3
54
55 class MapCanvas(wx.ScrolledWindow):
56 def __init__(self, parent, ID, isEditor=0):
57 self.parent = parent
58 self.log = open_rpg.get_component("log")
59 self.log.log("Enter MapCanvas", ORPG_DEBUG)
60 self.settings = open_rpg.get_component("settings")
61 self.session = open_rpg.get_component("session")
62 wx.ScrolledWindow.__init__(self, parent, ID, style=wx.HSCROLL | wx.VSCROLL | wx.FULL_REPAINT_ON_RESIZE | wx.SUNKEN_BORDER )
63 self.frame = parent
64 self.MAP_MODE = 1 #Mode 1 = MINI, 2 = DRAW, 3 = TAPE MEASURE
65 self.layers = {}
66 self.layers['bg'] = layer_back_ground(self)
67 self.layers['grid'] = grid_layer(self)
68 self.layers['whiteboard'] = whiteboard_layer(self)
69 self.layers['miniatures'] = miniature_layer(self)
70 self.layers['fog'] = fog_layer(self)
71 self.Bind(wx.EVT_ERASE_BACKGROUND, self.on_erase_background)
72 self.Bind(wx.EVT_PAINT, self.on_paint)
73 self.Bind(wx.EVT_LEFT_DOWN, self.on_left_down)
74 self.Bind(wx.EVT_LEFT_DCLICK, self.on_left_dclick)
75 self.Bind(wx.EVT_LEFT_UP, self.on_left_up)
76 self.Bind(wx.EVT_RIGHT_DOWN, self.on_right_down)
77 self.Bind(wx.EVT_MOTION, self.on_motion)
78 self.Bind(wx.EVT_SCROLLWIN, self.on_scroll)
79 self.Bind(wx.EVT_CHAR, self.on_char)
80 self.Bind(wx.EVT_SIZE, self.on_resize)
81 self.set_size((1000,1000))
82 self.root_dir = os.getcwd()
83 self.size_change = 0
84 self.isEditor = isEditor
85 self.map_version = MAP_VERSION
86 self.cacheSize = 32
87 # Create the marker mode attributes for the map
88 self.markerMode = MARKER_MODE_NONE
89 self.markerStart = wx.Point( -1, -1 )
90 self.markerStop = wx.Point( -1, -1 )
91 self.markerMidpoint = wx.Point( -1, -1 )
92 self.markerAngle = 0.0
93 # Optimization of map refreshing during busy map load
94 self.lastRefreshValue = 0
95 self.requireRefresh = 0
96 self.lastRefreshTime = 0
97 self.zoom_display_timer = wx.Timer(self, wx.NewId())
98 self.Bind(wx.EVT_TIMER, self.better_refresh, self.zoom_display_timer)
99 random.seed( time.time() )
100 self.image_timer = wx.Timer(self, wx.NewId())
101 self.Bind(wx.EVT_TIMER, self.processImages, self.image_timer)
102 self.image_timer.Start(100)
103 # Used to check if we've used the user cache size value
104 self.cacheSizeSet = False
105 self.inside = 0
106 # miniatures drag
107 self.drag = None
108 self.log.log("Exit MapCanvas", ORPG_DEBUG)
109
110 def better_refresh(self, event=None):
111 self.log.log("Enter MapCanvas->better_refresh(self)", ORPG_DEBUG)
112 self.Refresh(True)
113 self.log.log("Eexit MapCanvas->better_refresh(self)", ORPG_DEBUG)
114
115 def pre_destory_cleanup(self):
116 self.log.log("Enter MapCanvas->pre_destory_cleanup(self)", ORPG_DEBUG)
117 self.layers["miniatures"].del_all_miniatures()
118 self.log.log("Exit MapCanvas->pre_destory_cleanup(self)", ORPG_DEBUG)
119
120 def processImages(self, evt=None):
121 self.log.log("Enter MapCanvas->processImages(self)", ORPG_DEBUG)
122 self.session = open_rpg.get_component("session")
123 if self.session.my_role() == self.session.ROLE_LURKER or (str(self.session.group_id) == '0' and str(self.session.status) == '1'):
124 cidx = self.parent.get_tab_index("Background")
125 self.parent.layer_tabs.EnableTab(cidx, False)
126 cidx = self.parent.get_tab_index("Grid")
127 self.parent.layer_tabs.EnableTab(cidx, False)
128 cidx = self.parent.get_tab_index("Miniatures")
129 self.parent.layer_tabs.EnableTab(cidx, False)
130 cidx = self.parent.get_tab_index("Whiteboard")
131 self.parent.layer_tabs.EnableTab(cidx, False)
132 cidx = self.parent.get_tab_index("Fog")
133 self.parent.layer_tabs.EnableTab(cidx, False)
134 cidx = self.parent.get_tab_index("General")
135 self.parent.layer_tabs.EnableTab(cidx, False)
136 else:
137 cidx = self.parent.get_tab_index("Background")
138 if not self.parent.layer_tabs.GetEnabled(cidx):
139 cidx = self.parent.get_tab_index("Miniatures")
140 self.parent.layer_tabs.EnableTab(cidx, True)
141 cidx = self.parent.get_tab_index("Whiteboard")
142 self.parent.layer_tabs.EnableTab(cidx, True)
143 cidx = self.parent.get_tab_index("Background")
144 self.parent.layer_tabs.EnableTab(cidx, False)
145 cidx = self.parent.get_tab_index("Grid")
146 self.parent.layer_tabs.EnableTab(cidx, False)
147 cidx = self.parent.get_tab_index("Fog")
148 self.parent.layer_tabs.EnableTab(cidx, False)
149 cidx = self.parent.get_tab_index("General")
150 self.parent.layer_tabs.EnableTab(cidx, False)
151 if self.session.my_role() == self.session.ROLE_GM:
152 cidx = self.parent.get_tab_index("Background")
153 self.parent.layer_tabs.EnableTab(cidx, True)
154 cidx = self.parent.get_tab_index("Grid")
155 self.parent.layer_tabs.EnableTab(cidx, True)
156 cidx = self.parent.get_tab_index("Fog")
157 self.parent.layer_tabs.EnableTab(cidx, True)
158 cidx = self.parent.get_tab_index("General")
159 self.parent.layer_tabs.EnableTab(cidx, True)
160 if not self.cacheSizeSet:
161 self.cacheSizeSet = True
162 cacheSize = self.settings.get_setting("ImageCacheSize")
163 if len(cacheSize):
164 self.cacheSize = int(cacheSize)
165 else:
166 self.log.log("Default cache size being used.", ORPG_GENERAL)
167 self.log.log("Current image cache size is set at " + str(self.cacheSize) + " images, using random purge.", ORPG_GENERAL)
168 if not ImageHandler.Queue.empty():
169 (path, image_type, imageId) = ImageHandler.Queue.get()
170 img = wx.ImageFromMime(path[1], path[2]).ConvertToBitmap()
171 try:
172 # Now, apply the image to the proper object
173 if image_type == "miniature":
174 min = self.layers['miniatures'].get_miniature_by_id(imageId)
175 min.set_bmp(img)
176 elif image_type == "background" or image_type == "texture":
177 self.layers['bg'].bg_bmp = img
178 if image_type == "background":
179 self.set_size([img.GetWidth(), img.GetHeight()])
180 except:
181 pass
182 # Flag that we now need to refresh!
183 self.requireRefresh += 1
184
185 # Randomly purge an item from the cache, while this is lamo, it does
186 # keep the cache from growing without bounds, which is pretty important!
187 if len(ImageHandler.Cache) >= self.cacheSize:
188 ImageHandler.cleanCache()
189 else:
190 # Now, make sure not only that we require a refresh, but that enough time has
191 # gone by since our last refresh. This keeps back to back refreshing occuring during
192 # large map loads. Of course, we are now trying to pack as many image refreshes as
193 # we can into a single cycle.
194 if self.requireRefresh and (self.requireRefresh == self.lastRefreshValue):
195 if (self.lastRefreshTime) < time.time():
196 self.requireRefresh = 0
197 self.lastRefreshValue = 0
198 self.lastRefreshTime = time.time()
199 self.Refresh(True)
200 else:
201 self.lastRefreshValue = self.requireRefresh
202 self.log.log("Exit MapCanvas->processImages(self)", ORPG_DEBUG)
203
204 def on_scroll(self, evt):
205 self.log.log("Enter MapCanvas->on_scroll(self, evt)", ORPG_DEBUG)
206 if self.drag:
207 self.drag.Hide()
208 if self.settings.get_setting("AlwaysShowMapScale") == "1":
209 self.printscale()
210 evt.Skip()
211 self.log.log("Exit MapCanvas->on_scroll(self, evt)", ORPG_DEBUG)
212
213 def on_char(self, evt):
214 self.log.log("Enter MapCanvas->on_char(self, evt)", ORPG_DEBUG)
215 if self.settings.get_setting("AlwaysShowMapScale") == "1":
216 self.printscale()
217 evt.Skip()
218 self.log.log("Exit MapCanvas->on_char(self, evt)", ORPG_DEBUG)
219
220 def printscale(self):
221 self.log.log("Enter MapCanvas->printscale(self)", ORPG_DEBUG)
222 wx.BeginBusyCursor()
223 dc = wx.ClientDC(self)
224 self.PrepareDC(dc)
225 self.showmapscale(dc)
226 self.Refresh(True)
227 wx.EndBusyCursor()
228 self.log.log("Exit MapCanvas->printscale(self)", ORPG_DEBUG)
229
230 def send_map_data(self, action="update"):
231 self.log.log("Enter MapCanvas->send_map_data(self, " + action +")", ORPG_DEBUG)
232 wx.BeginBusyCursor()
233 send_text = self.toxml(action)
234 if send_text:
235 if not self.isEditor:
236 self.frame.session.send(send_text)
237 wx.EndBusyCursor()
238 self.log.log("Exit MapCanvas->send_map_data(self, " + action +")", ORPG_DEBUG)
239
240 def get_size(self):
241 self.log.log("Enter MapCanvas->get_size(self)", ORPG_DEBUG)
242 self.log.log("Exit MapCanvas->get_size(self) return " + str(self.size), ORPG_DEBUG)
243 return self.size
244
245 def set_size(self, size):
246 self.log.log("Enter MapCanvas->set_size(self, size)", ORPG_DEBUG)
247 if size[0] < 300:
248 size = (300, size[1])
249 if size[1] < 300:
250 size = (size[0], 300)
251 self.size_changed = 1
252 self.size = size
253 self.fix_scroll()
254 self.layers['fog'].resize(size)
255 self.log.log("Exit MapCanvas->set_size(self, size)", ORPG_DEBUG)
256
257 def fix_scroll(self):
258 self.log.log("Enter MapCanvas->fix_scroll(self)", ORPG_DEBUG)
259 scale = self.layers['grid'].mapscale
260 pos = self.GetViewStart()
261 unit = self.GetScrollPixelsPerUnit()
262 pos = [pos[0]*unit[0],pos[1]*unit[1]]
263 size = self.GetClientSize()
264 unit = [10*scale,10*scale]
265 if (unit[0] == 0 or unit[1] == 0):
266 self.log.log("Exit MapCanvas->fix_scroll(self)", ORPG_DEBUG)
267 return
268 pos[0] /= unit[0]
269 pos[1] /= unit[1]
270 mx = [int(self.size[0]*scale/unit[0])+1, int(self.size[1]*scale/unit[1]+1)]
271 self.SetScrollbars(unit[0], unit[1], mx[0], mx[1], pos[0], pos[1])
272 self.log.log("Exit MapCanvas->fix_scroll(self)", ORPG_DEBUG)
273
274 def on_resize(self, evt):
275 self.log.log("Enter MapCanvas->on_resize(self, evt)", ORPG_DEBUG)
276 self.fix_scroll()
277 wx.CallAfter(self.Refresh, True)
278 evt.Skip()
279 self.log.log("Exit MapCanvas->on_resize(self, evt)", ORPG_DEBUG)
280
281 def on_erase_background(self, evt):
282 self.log.log("Enter MapCanvas->on_erase_background(self, evt)", ORPG_DEBUG)
283 evt.Skip()
284 self.log.log("Exit MapCanvas->on_erase_background(self, evt)", ORPG_DEBUG)
285
286 def on_paint(self, evt):
287 self.log.log("Enter MapCanvas->on_paint(self, evt)", ORPG_DEBUG)
288 scale = self.layers['grid'].mapscale
289 scrollsize = self.GetScrollPixelsPerUnit()
290 clientsize = self.GetClientSize()
291 topleft1 = self.GetViewStart()
292 topleft = [topleft1[0]*scrollsize[0], topleft1[1]*scrollsize[1]]
293 if (clientsize[0] > 1) and (clientsize[1] > 1):
294 dc = wx.MemoryDC()
295 bmp = wx.EmptyBitmap(clientsize[0]+1, clientsize[1]+1)
296 dc.SelectObject(bmp)
297 dc.SetPen(wx.TRANSPARENT_PEN)
298 dc.SetBrush(wx.Brush(self.GetBackgroundColour(), wx.SOLID))
299 dc.DrawRectangle(0,0,clientsize[0]+1,clientsize[1]+1)
300 dc.SetDeviceOrigin(-topleft[0], -topleft[1])
301 dc.SetUserScale(scale, scale)
302 self.layers['bg'].layerDraw(dc, scale, topleft, clientsize)
303 self.layers['grid'].layerDraw(dc, [topleft[0]/scale, topleft[1]/scale], [clientsize[0]/scale, clientsize[1]/scale])
304 self.layers['miniatures'].layerDraw(dc, [topleft[0]/scale, topleft[1]/scale], [clientsize[0]/scale, clientsize[1]/scale])
305 self.layers['whiteboard'].layerDraw(dc)
306 self.layers['fog'].layerDraw(dc, topleft, clientsize)
307 dc.SetPen(wx.NullPen)
308 dc.SetBrush(wx.NullBrush)
309 dc.SelectObject(wx.NullBitmap)
310 del dc
311 wdc = self.preppaint()
312 wdc.DrawBitmap(bmp, topleft[0], topleft[1])
313 if self.frame.settings.get_setting("AlwaysShowMapScale") == "1":
314 self.showmapscale(wdc)
315 try:
316 evt.Skip()
317 except:
318 pass
319 self.log.log("Exit MapCanvas->on_paint(self, evt)", ORPG_DEBUG)
320
321 def preppaint(self):
322 self.log.log("Enter MapCanvas->preppaint(self)", ORPG_DEBUG)
323 dc = wx.PaintDC(self)
324 self.PrepareDC(dc)
325 self.log.log("Exit MapCanvas->preppaint(self)", ORPG_DEBUG)
326 return (dc)
327
328 def showmapscale(self, dc):
329 self.log.log("Enter MapCanvas->showmapscale(self, dc)", ORPG_DEBUG)
330 scalestring = "Scale x" + `self.layers['grid'].mapscale`[:3]
331 (textWidth, textHeight) = dc.GetTextExtent(scalestring)
332 dc.SetUserScale(1, 1)
333 dc.SetPen(wx.LIGHT_GREY_PEN)
334 dc.SetBrush(wx.LIGHT_GREY_BRUSH)
335 x = dc.DeviceToLogicalX(0)
336 y = dc.DeviceToLogicalY(0)
337 dc.DrawRectangle(x, y, textWidth+2, textHeight+2)
338 dc.SetPen(wx.RED_PEN)
339 dc.DrawText(scalestring, x+1, y+1)
340 dc.SetPen(wx.NullPen)
341 dc.SetBrush(wx.NullBrush)
342 self.log.log("Exit MapCanvas->showmapscale(self, dc)", ORPG_DEBUG)
343
344 def snapMarker(self, snapPoint):
345 """Based on the position and unit size, figure out where we need to snap to. As is, on
346 a square grid, there are four possible places to snap. On a hex gid, there are 6 or 12 snap
347 points."""
348 self.log.log("Enter MapCanvas->snapMarker(self, snapPoint)", ORPG_DEBUG)
349
350 # If snap to grid is disabled, simply return snapPoint unmodified
351 if self.layers['grid'].snap:
352 # This means we need to determine where to snap our line. We will support
353 # snapping to four different snapPoints per square for now.
354 # TODO!!!
355 if self.layers['grid'].mode == GRID_HEXAGON:
356 size = self.layers['grid'].unit_size_y
357 else:
358 size = int(self.layers['grid'].unit_size)
359 # Find the uppper left hand corner of the grid we are to snap to
360 offsetX = (snapPoint.x / size) * size
361 offsetY = (snapPoint.y / size) * size
362 # Calculate the delta value between where we clicked and the square it is near
363 deltaX = snapPoint.x - offsetX
364 deltaY = snapPoint.y - offsetY
365 # Now, figure our what quadrant (x, y) we need to snap to
366 snapSize = size / 2
367 # Figure out the X snap placement
368 if deltaX <= snapSize:
369 quadXPos = offsetX
370 else:
371 quadXPos = offsetX + size
372 # Now, figure out the Y snap placement
373 if deltaY <= snapSize:
374 quadYPos = offsetY
375 else:
376 quadYPos = offsetY + size
377 # Create our snap snapPoint and return it
378 snapPoint = wx.Point( quadXPos, quadYPos )
379 self.log.log("Exit MapCanvas->snapMarker(self, snapPoint)", ORPG_DEBUG)
380 return snapPoint
381
382 # Bunch of math stuff for marking and measuring
383 def calcSlope(self, start, stop):
384 """Calculates the slop of a line and returns it."""
385 self.log.log("Enter MapCanvas->calcSlope(self, start, stop)", ORPG_DEBUG)
386 if start.x == stop.x:
387 s = 0.0001
388 else:
389 s = float((stop.y - start.y)) / float((stop.x - start.x))
390 self.log.log("Exit MapCanvas->calcSlope(self, start, stop)", ORPG_DEBUG)
391 return s
392
393 def calcSlopeToAngle(self, slope):
394 """Based on the input slope, the angle (in degrees) will be returned."""
395 self.log.log("Enter MapCanvas->calcSlopeToAngle(self, slope)", ORPG_DEBUG)
396 # See if the slope is neg or positive
397 if slope == abs(slope):
398 # Slope is positive, so make sure it's not zero
399 if slope == 0:
400 a = 0
401 else:
402 # We are positive and NOT zero
403 a = 360 - atan(slope) * (180.0/pi)
404 else:
405 # Slope is negative so work on the abs of it
406 a = atan(abs(slope)) * (180.0/pi)
407 self.log.log("Exit MapCanvas->calcSlopeToAngle(self, slope)", ORPG_DEBUG)
408 return a
409
410 def calcLineAngle(self, start, stop):
411 """Based on two points that are on a line, return the angle of that line."""
412 self.log.log("Enter MapCanvas->calcLineAngle(self, start, stop)", ORPG_DEBUG)
413 a = self.calcSlopeToAngle( self.calcSlope( start, stop ) )
414 self.log.log("Exit MapCanvas->calcLineAngle(self, start, stop)", ORPG_DEBUG)
415 return a
416
417 def calcPixelDistance(self, start, stop):
418 """Calculate the distance between two pixels and returns it. The calculated
419 distance is the Euclidean Distance, which is:
420 d = sqrt( (x2 - x1)**2 + (y2 - y1)**2 )"""
421 self.log.log("Enter MapCanvas->calcPixelDistance(self, start, stop)", ORPG_DEBUG)
422 d = sqrt( abs((stop.x - start.x)**2 - (stop.y - start.y)**2) )
423 self.log.log("Exit MapCanvas->calcPixelDistance(self, start, stop)", ORPG_DEBUG)
424 return d
425
426 def calcUnitDistance(self, start, stop, lineAngle):
427 self.log.log("Enter MapCanvas->calcUnitDistance(self, start, stop, lineAngle)", ORPG_DEBUG)
428 distance = self.calcPixelDistance( start, stop )
429 ln = "%0.2f" % lineAngle
430 if self.layers['grid'].mode == GRID_HEXAGON:
431 if ln == "0.00" or ln == "359.99":
432 ud = distance / self.layers['grid'].unit_size_y
433 else:
434 ud = (sqrt(abs((stop.x - start.x)**2 + (stop.y - start.y)**2))) / self.layers['grid'].unit_size_y
435 else:
436 if ln == "0.00" or ln == "359.99":
437 ud = distance / self.layers['grid'].unit_size
438 else:
439 ud = (sqrt(abs((stop.x - start.x)**2 + (stop.y - start.y)**2))) / self.layers['grid'].unit_size
440 #ud = sqrt( abs((stop.x - start.x)**2 - (stop.y - start.y)**2) )
441 self.log.log("Exit MapCanvas->calcUnitDistance(self, start, stop, lineAngle)", ORPG_DEBUG)
442 return ud
443
444 def on_tape_motion(self, evt):
445 """Track mouse motion so we can update the marker visual every time it's moved"""
446 self.log.log("Enter MapCanvas->on_tape_motion(self, evt)", ORPG_DEBUG)
447 # Make sure we have a mode to do anything, otherwise, we ignore this
448 if self.markerMode:
449 # Grap the current DC for all of the marker modes
450 dc = wx.ClientDC( self )
451 self.PrepareDC( dc )
452 dc.SetUserScale(self.layers['grid'].mapscale,self.layers['grid'].mapscale)
453 # Grab the current map position
454 pos = self.snapMarker( evt.GetLogicalPosition( dc ) )
455 # Enable brush optimizations
456 #dc.SetOptimization( True )
457 # Set up the pen used for drawing our marker
458 dc.SetPen( wx.Pen(wx.RED, 1, wx.LONG_DASH) )
459 # Now, based on the marker mode, draw the right thing
460 if self.markerMode == MARKER_MODE_MEASURE:
461 if self.markerStop.x != -1 and self.markerStop.y != -1:
462 # Set the DC function that we need
463 dc.SetLogicalFunction(wx.INVERT)
464 # Erase old and Draw new marker line
465 dc.BeginDrawing()
466 dc.DrawLine( self.markerStart.x, self.markerStart.y, self.markerStop.x, self.markerStop.y )
467 dc.DrawLine( self.markerStart.x, self.markerStart.y, pos.x, pos.y )
468 dc.EndDrawing()
469 # Restore the default DC function
470 dc.SetLogicalFunction(wx.COPY)
471 # As long as we are in marker mode, we ned to update the stop point
472 self.markerStop = pos
473 dc.SetPen(wx.NullPen)
474 # Disable brush optimizations
475 #dc.SetOptimization( False )
476 del dc
477 self.log.log("Exit MapCanvas->on_tape_motion(self, evt)", ORPG_DEBUG)
478
479 def on_tape_down(self, evt):
480 """Greg's experimental tape measure code. Hopefully, when this is done, it will all be
481 modal based on a toolbar."""
482 self.log.log("Enter MapCanvas->on_tape_down(self, evt)", ORPG_DEBUG)
483 dc = wx.ClientDC( self )
484 self.PrepareDC( dc )
485 dc.SetUserScale(self.layers['grid'].mapscale,self.layers['grid'].mapscale)
486 pos = evt.GetLogicalPosition( dc )
487 # If grid snap is enabled, then snap the tool to a proper position
488 pos = self.snapMarker( evt.GetLogicalPosition( dc ) )
489 # Maker mode should really be set by a toolbar
490 self.markerMode = MARKER_MODE_MEASURE
491 # Erase the old line if her have one
492 if self.markerStart.x != -1 and self.markerStart.y != -1:
493 # Enable brush optimizations
494 #dc.SetOptimization( True )
495 # Set up the pen used for drawing our marker
496 dc.SetPen( wx.Pen(wx.RED, 1, wx.LONG_DASH) )
497 # Set the DC function that we need
498 dc.SetLogicalFunction(wx.INVERT)
499 # Draw the marker line
500 dc.BeginDrawing()
501 dc.DrawLine( self.markerStart.x, self.markerStart.y, self.markerStop.x, self.markerStop.y )
502 dc.EndDrawing()
503 # Restore the default DC function and pen
504 dc.SetLogicalFunction(wx.COPY)
505 dc.SetPen(wx.NullPen)
506 # Disable brush optimizations
507 #dc.SetOptimization( False )
508 # Save our current start and reset the stop value
509 self.markerStart = pos
510 self.markerStop = pos
511 del dc
512 self.log.log("Exit MapCanvas->on_tape_down(self, evt)", ORPG_DEBUG)
513
514 def on_tape_up(self, evt):
515 """When we release the middle button, disable any marking updates that we have been doing."""
516 self.log.log("Enter MapCanvas->on_tape_up(self, evt)", ORPG_DEBUG)
517 # If we are in measure mode, draw the actual UNIT distance
518 if self.markerMode == MARKER_MODE_MEASURE:
519 dc = wx.ClientDC( self )
520 self.PrepareDC( dc )
521 dc.SetUserScale(self.layers['grid'].mapscale,self.layers['grid'].mapscale)
522 # Draw the measured distance on the DC. Since we want
523 # the text to match the line angle, calculate the angle
524 # of the line.
525 lineAngle = self.calcLineAngle( self.markerStart, self.markerStop )
526 distance = self.calcUnitDistance( self.markerStart, self.markerStop, lineAngle )
527 midPoint = (self.markerStart + self.markerStop)
528 midPoint.x /= 2
529 midPoint.y /= 2
530 # Adjust out font to be bigger & scaled
531 font = dc.GetFont()
532 # Set the DC function that we need
533 dc.SetLogicalFunction(wx.INVERT)
534 # Set the pen we want to use
535 dc.SetPen(wx.BLACK_PEN)
536 # Now, draw the text at the proper angle on the canvas
537 self.markerMidpoint = midPoint
538 self.markerAngle = lineAngle
539 dText = "%0.2f Units" % (distance)
540 dc.BeginDrawing()
541 dc.DrawRotatedText( dText, midPoint.x, midPoint.y, lineAngle )
542 dc.EndDrawing()
543 # Restore the default font and DC
544 dc.SetFont(wx.NullFont)
545 dc.SetLogicalFunction(wx.COPY)
546 del font
547 del dc
548 self.markerMode = MARKER_MODE_NONE
549 self.log.log("Exit MapCanvas->on_tape_up(self, evt)", ORPG_DEBUG)
550
551 # MODE 1 = MOVE, MODE 2 = whiteboard, MODE 3 = Tape measure
552 def on_left_down(self, evt):
553 self.log.log("Enter MapCanvas->on_left_down(self, evt)", ORPG_DEBUG)
554 if evt.ShiftDown():
555 self.on_tape_down (evt)
556 else:
557 self.frame.on_left_down(evt)
558 self.log.log("Exit MapCanvas->on_left_down(self, evt)", ORPG_DEBUG)
559
560 def on_right_down(self, evt):
561 self.log.log("Enter MapCanvas->on_right_down(self, evt)", ORPG_DEBUG)
562 if evt.ShiftDown():
563 pass
564 else:
565 self.frame.on_right_down(evt)
566 self.log.log("Exit MapCanvas->on_right_down(self, evt)", ORPG_DEBUG)
567
568 def on_left_dclick(self, evt):
569 self.log.log("Enter MapCanvas->on_left_dclick(self, evt)", ORPG_DEBUG)
570 if evt.ShiftDown():
571 pass
572 else:
573 self.frame.on_left_dclick(evt)
574 self.log.log("Exit MapCanvas->on_left_dclick(self, evt)", ORPG_DEBUG)
575
576 def on_left_up(self, evt):
577 self.log.log("Enter MapCanvas->on_left_up(self, evt)", ORPG_DEBUG)
578 if evt.ShiftDown():
579 self.on_tape_up(evt)
580 elif open_rpg.get_component("tree").dragging:
581 tree = open_rpg.get_component("tree")
582 if tree.drag_obj.map_aware():
583 tree.drag_obj.on_send_to_map(evt)
584 tree.dragging = False
585 tree.drag_obj = None
586 else:
587 self.frame.on_left_up(evt)
588 self.log.log("Exit MapCanvas->on_left_up(self, evt)", ORPG_DEBUG)
589
590 def on_motion(self, evt):
591 self.log.log("Enter MapCanvas->on_motion(self, evt)", ORPG_DEBUG)
592 if evt.ShiftDown():
593 self.on_tape_motion(evt)
594 elif evt.LeftIsDown() and open_rpg.get_component("tree").dragging:
595 pass
596 else:
597 self.frame.on_motion(evt)
598 self.log.log("Exit MapCanvas->on_motion(self, evt)", ORPG_DEBUG)
599
600 def on_zoom_out(self, evt):
601 self.log.log("Enter MapCanvas->on_zoom_out(self, evt)", ORPG_DEBUG)
602 if self.layers['grid'].mapscale > 0.2:
603 # attempt to keep same logical point at center of screen
604 scale = self.layers['grid'].mapscale
605 scrollsize = self.GetScrollPixelsPerUnit()
606 clientsize = self.GetClientSize()
607 topleft1 = self.GetViewStart()
608 topleft = [topleft1[0]*scrollsize[0], topleft1[1]*scrollsize[1]]
609 scroll_x = (((topleft[0]+clientsize[0]/2)*(scale-.1)/scale)-clientsize[0]/2)/scrollsize[0]
610 scroll_y = (((topleft[1]+clientsize[1]/2)*(scale-.1)/scale)-clientsize[1]/2)/scrollsize[1]
611 self.Scroll(scroll_x, scroll_y)
612 self.layers['grid'].mapscale -= .1
613 scalestring = "x" + `self.layers['grid'].mapscale`[:3]
614 self.frame.get_current_layer_handler().zoom_out_button.SetToolTip(wx.ToolTip("Zoom out from " + scalestring) )
615 self.frame.get_current_layer_handler().zoom_in_button.SetToolTip(wx.ToolTip("Zoom in from " + scalestring) )
616 self.set_size(self.size)
617 dc = wx.ClientDC(self)
618 dc.BeginDrawing()
619 scalestring = "Scale x" + `self.layers['grid'].mapscale`[:3]
620 (textWidth,textHeight) = dc.GetTextExtent(scalestring)
621 dc.SetPen(wx.LIGHT_GREY_PEN)
622 dc.SetBrush(wx.LIGHT_GREY_BRUSH)
623 dc.DrawRectangle(dc.DeviceToLogicalX(0),dc.DeviceToLogicalY(0),textWidth,textHeight)
624 dc.SetPen(wx.RED_PEN)
625 dc.DrawText(scalestring,dc.DeviceToLogicalX(0),dc.DeviceToLogicalY(0))
626 dc.SetPen(wx.NullPen)
627 dc.SetBrush(wx.NullBrush)
628 dc.EndDrawing()
629 del dc
630 self.zoom_display_timer.Start(500,1)
631 self.log.log("Exit MapCanvas->on_zoom_out(self, evt)", ORPG_DEBUG)
632
633 def on_zoom_in(self, evt):
634 self.log.log("Enter MapCanvas->on_zoom_in(self, evt)", ORPG_DEBUG)
635 # attempt to keep same logical point at center of screen
636 scale = self.layers['grid'].mapscale
637 scrollsize = self.GetScrollPixelsPerUnit()
638 clientsize = self.GetClientSize()
639 topleft1 = self.GetViewStart()
640 topleft = [topleft1[0]*scrollsize[0], topleft1[1]*scrollsize[1]]
641 scroll_x = (((topleft[0]+clientsize[0]/2)*(scale+.1)/scale)-clientsize[0]/2)/scrollsize[0]
642 scroll_y = (((topleft[1]+clientsize[1]/2)*(scale+.1)/scale)-clientsize[1]/2)/scrollsize[1]
643 self.Scroll(scroll_x, scroll_y)
644 self.layers['grid'].mapscale += .1
645 scalestring = "x" + `self.layers['grid'].mapscale`[:3]
646 self.frame.get_current_layer_handler().zoom_out_button.SetToolTip(wx.ToolTip("Zoom out from " + scalestring) )
647 self.frame.get_current_layer_handler().zoom_in_button.SetToolTip(wx.ToolTip("Zoom in from " + scalestring) )
648 self.set_size(self.size)
649 dc = wx.ClientDC(self)
650 dc.BeginDrawing()
651 scalestring = "Scale x" + `self.layers['grid'].mapscale`[:3]
652 (textWidth,textHeight) = dc.GetTextExtent(scalestring)
653 dc.SetPen(wx.LIGHT_GREY_PEN)
654 dc.SetBrush(wx.LIGHT_GREY_BRUSH)
655 dc.DrawRectangle(dc.DeviceToLogicalX(0), dc.DeviceToLogicalY(0), textWidth,textHeight)
656 dc.SetPen(wx.RED_PEN)
657 dc.DrawText(scalestring, dc.DeviceToLogicalX(0), dc.DeviceToLogicalY(0))
658 dc.SetPen(wx.NullPen)
659 dc.SetBrush(wx.NullBrush)
660 dc.EndDrawing()
661 del dc
662 self.zoom_display_timer.Start(500, 1)
663 self.log.log("Exit MapCanvas->on_zoom_in(self, evt)", ORPG_DEBUG)
664
665 def on_prop(self, evt):
666 self.log.log("Enter MapCanvas->on_prop(self, evt)", ORPG_DEBUG)
667 self.session = open_rpg.get_component("session")
668 self.chat = open_rpg.get_component("chat")
669 if (self.session.my_role() != self.session.ROLE_GM):
670 self.chat.InfoPost("You must be a GM to use this feature")
671 self.log.log("Exit MapCanvas->on_prop(self, evt)", ORPG_DEBUG)
672 return
673 dlg = general_map_prop_dialog(self.frame.GetParent(),self.size,self.layers['bg'],self.layers['grid'])
674 if dlg.ShowModal() == wx.ID_OK:
675 self.set_size(dlg.size)
676 self.send_map_data()
677 self.Refresh(False)
678 dlg.Destroy()
679 os.chdir(self.root_dir)
680 self.log.log("Exit MapCanvas->on_prop(self, evt)", ORPG_DEBUG)
681
682 def add_miniature(self, min_url, min_label='', min_unique=-1):
683 self.log.log("Enter MapCanvas->add_miniature(self, min_url, min_label, min_unique)", ORPG_DEBUG)
684 if min_unique == -1:
685 min_unique = not self.use_serial
686 if min_url == "" or min_url == "http://":
687 return
688 if min_url[:7] != "http://" :
689 min_url = "http://" + min_url
690 # make label
691 wx.BeginBusyCursor()
692 if self.auto_label:
693 if min_label == '':
694 min_label = self.get_label_from_url( min_url )
695 if not min_unique and self.use_serial:
696 min_label = '%s %d' % ( min_label, self.layers['miniatures'].next_serial() )
697 else:
698 min_label = ""
699 if self.frame.min_url.FindString(min_url) == -1:
700 self.frame.min_url.Append(min_url)
701 try:
702 id = 'mini-' + self.frame.session.get_next_id()
703 self.layers['miniatures'].add_miniature(id, min_url, label=min_label)
704 except Exception, e:
705 self.log.log(traceback.format_exc(), ORPG_GENERAL)
706 self.log.log("Unable to load/resolve URL: " + min_url + " on resource ' + min_label + ' !!!", ORPG_GENERAL)
707 self.layers['miniatures'].rollback_serial()
708 wx.EndBusyCursor()
709 self.send_map_data()
710 self.Refresh(False)
711 self.log.log("Exit MapCanvas->add_miniature(self, min_url, min_label, min_unique)", ORPG_DEBUG)
712
713 def get_label_from_url(self, url=''):
714 self.log.log("Enter MapCanvas->get_label_from_url(self, url)", ORPG_DEBUG)
715 if url == '':
716 self.log.log("Exit MapCanvas->get_label_from_url(self, url)", ORPG_DEBUG)
717 return ''
718 start = url.rfind("/")+1
719 label = url[start:len(url)-4]
720 self.log.log("Exit MapCanvas->get_label_from_url(self, url)", ORPG_DEBUG)
721 return label
722
723 def toxml(self, action="update"):
724 self.log.log("Enter MapCanvas->toxml(self, " + action + ")", ORPG_DEBUG)
725 if action == "new":
726 self.size_changed = 1
727 xml_str = "<map version='" + self.map_version + "'"
728 changed = self.size_changed
729 if self.size_changed:
730 xml_str += " sizex='" + str(self.size[0]) + "'"
731 xml_str += " sizey='" + str(self.size[1]) + "'"
732 s = ""
733 keys = self.layers.keys()
734 for k in keys:
735 if (k != "fog" or action != "update"):
736 s += self.layers[k].layerToXML(action)
737 self.size_changed = 0
738 if s:
739 self.log.log("Exit MapCanvas->toxml(self, " + action + ")", ORPG_DEBUG)
740 return xml_str + " action='" + action + "'>" + s + "</map>"
741 else:
742 if changed:
743 self.log.log("Exit MapCanvas->toxml(self, " + action + ")", ORPG_DEBUG)
744 return xml_str + " action='" + action + "'/>"
745 else:
746 self.log.log("Exit MapCanvas->toxml(self, " + action + ")", ORPG_DEBUG)
747 return ""
748
749 def takexml(self, xml):
750 #
751 # Added Process Dialog to display during long map parsings
752 # as well as a try block with an exception traceback to try
753 # and isolate some of the map related problems users have been
754 # experiencing --Snowdog 5/15/03
755 #
756 # Apparently Process Dialog causes problems with linux.. commenting it out. sheez.
757 # --Snowdog 5/27/03
758 self.log.log("Enter MapCanvas->takexml(self, xml)", ORPG_DEBUG)
759 try:
760 #parse the map DOM
761 xml_dom = parseXml(xml)
762 if xml_dom == None:
763 self.log.log("xml_dom == None\n" + xml, ORPG_INFO)
764 self.log.log("Exit MapCanvas->takexml(self, xml)", ORPG_DEBUG)
765 return
766 node_list = xml_dom.getElementsByTagName("map")
767 if len(node_list) < 1:
768 self.log.log("Invalid XML format for mapper", ORPG_INFO)
769 else:
770 # set map version to incoming data so layers can convert
771 self.map_version = node_list[0].getAttribute("version")
772 action = node_list[0].getAttribute("action")
773 if action == "new":
774 self.layers = {}
775 try:
776 self.layers['bg'] = layer_back_ground(self)
777 except:
778 pass
779 try:
780 self.layers['grid'] = grid_layer(self)
781 except:
782 pass
783 try:
784 self.layers['miniatures'] = miniature_layer(self)
785 except:
786 pass
787 try:
788 self.layers['whiteboard'] = whiteboard_layer(self)
789 except:
790 pass
791 try:
792 self.layers['fog'] = fog_layer(self)
793 except:
794 pass
795 sizex = node_list[0].getAttribute("sizex")
796 if sizex != "":
797 sizex = int(float(sizex))
798 sizey = self.size[1]
799 self.set_size((sizex,sizey))
800 self.size_changed = 0
801 sizey = node_list[0].getAttribute("sizey")
802 if sizey != "":
803 sizey = int(float(sizey))
804 sizex = self.size[0]
805 self.set_size((sizex,sizey))
806 self.size_changed = 0
807 children = node_list[0]._get_childNodes()
808 #fog layer must be computed first, so that no data is inadvertently revealed
809 for c in children:
810 name = c._get_nodeName()
811 if name == "fog":
812 self.layers[name].layerTakeDOM(c)
813 for c in children:
814 name = c._get_nodeName()
815 if name != "fog":
816 self.layers[name].layerTakeDOM(c)
817 # all map data should be converted, set map version to current version
818 self.map_version = MAP_VERSION
819 self.Refresh(False)
820 xml_dom.unlink() # eliminate circular refs
821 except:
822 self.log.log(traceback.format_exc(), ORPG_GENERAL)
823 self.log.log("EXCEPTION: Critical Error Loading Map!!!", ORPG_GENERAL)
824 self.log.log("Exit MapCanvas->takexml(self, xml)", ORPG_DEBUG)
825
826 def re_ids_in_xml(self, xml):
827 self.log.log("Enter MapCanvas->re_ids_in_xml(self, xml)", ORPG_DEBUG)
828 new_xml = ""
829 tmp_map = map_msg()
830 xml_dom = parseXml(str(xml))
831 node_list = xml_dom.getElementsByTagName("map")
832 if len(node_list) < 1:
833 self.log.log("Invalid XML format for mapper", ORPG_INFO)
834 else:
835 tmp_map.init_from_dom(node_list[0])
836 if tmp_map.children.has_key("miniatures"):
837 miniatures_layer = tmp_map.children["miniatures"]
838 if miniatures_layer:
839 minis = miniatures_layer.get_children().keys()
840 if minis:
841 for mini in minis:
842 m = miniatures_layer.children[mini]
843 id = 'mini-' + self.frame.session.get_next_id()
844 m.init_prop("id", id)
845 # This allows for backward compatibility with older maps which do not
846 # have a whiteboard node. As such, if it's not there, we'll just happily
847 # move on and process as always.
848 if tmp_map.children.has_key("whiteboard"):
849 whiteboard_layer = tmp_map.children["whiteboard"]
850 if whiteboard_layer:
851 lines = whiteboard_layer.get_children().keys()
852 if lines:
853 for line in lines:
854 l = whiteboard_layer.children[line]
855 if l.tagname == 'line':
856 id = 'line-' + self.frame.session.get_next_id()
857 elif l.tagname == 'text':
858 id = 'text-' + self.frame.session.get_next_id()
859 elif l.tagname == 'circle':
860 id = 'circle-' + self.frame.session.get_next_id()
861 l.init_prop("id", id)
862 new_xml = tmp_map.get_all_xml()
863 if xml_dom:
864 xml_dom.unlink()
865 self.log.log("Exit MapCanvas->re_ids_in_xml(self, xml)", ORPG_DEBUG)
866 return str(new_xml)
867
868 class map_wnd(wx.Panel):
869 def __init__(self, parent, id):
870 self.log = open_rpg.get_component('log')
871 self.log.log("Enter map_wnd", ORPG_DEBUG)
872 wx.Panel.__init__(self, parent, id)
873 self.canvas = MapCanvas(self, -1)
874 self.session = open_rpg.get_component('session')
875 self.settings = open_rpg.get_component('settings')
876 self.chat = open_rpg.get_component('chat')
877 self.top_frame = open_rpg.get_component('frame')
878 self.root_dir = os.getcwd()
879 self.current_layer = 2
880 self.layer_tabs = orpgTabberWnd(self, style=FNB.FNB_NO_X_BUTTON|FNB.FNB_BOTTOM|FNB.FNB_NO_NAV_BUTTONS)
881 self.layer_handlers = []
882 self.layer_handlers.append(background_handler(self.layer_tabs,-1,self.canvas))
883 self.layer_tabs.AddPage(self.layer_handlers[0],"Background")
884 self.layer_handlers.append(grid_handler(self.layer_tabs,-1,self.canvas))
885 self.layer_tabs.AddPage(self.layer_handlers[1],"Grid")
886 self.layer_handlers.append(miniatures_handler(self.layer_tabs,-1,self.canvas))
887 self.layer_tabs.AddPage(self.layer_handlers[2],"Miniatures", True)
888 self.layer_handlers.append(whiteboard_handler(self.layer_tabs,-1,self.canvas))
889 self.layer_tabs.AddPage(self.layer_handlers[3],"Whiteboard")
890 self.layer_handlers.append(fog_handler(self.layer_tabs,-1,self.canvas))
891 self.layer_tabs.AddPage(self.layer_handlers[4],"Fog")
892 self.layer_handlers.append(map_handler(self.layer_tabs,-1,self.canvas))
893 self.layer_tabs.AddPage(self.layer_handlers[5],"General")
894 self.layer_tabs.SetSelection(2)
895 self.Bind(FNB.EVT_FLATNOTEBOOK_PAGE_CHANGED, self.on_layer_change)
896 self.Bind(wx.EVT_SIZE, self.on_size)
897 self.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeave)
898 self.load_default()
899 # size of tabs is diffrent on windows and linux :(
900 if wx.Platform == '__WXMSW__':
901 self.toolbar_height = 50
902 else:
903 self.toolbar_height = 55
904 self.log.log("Exit map_wnd", ORPG_DEBUG)
905
906 def OnLeave(self, evt):
907 if "__WXGTK__" in wx.PlatformInfo:
908 wx.SetCursor(wx.StockCursor(wx.CURSOR_ARROW))
909
910 def load_default(self):
911 self.log.log("Enter map_wnd->load_default(self)", ORPG_DEBUG)
912 if self.session.is_connected() and (self.session.my_role() != self.session.ROLE_GM) and (self.session.use_roles()):
913 self.chat.InfoPost("You must be a GM to use this feature")
914 self.log.log("Exit map_wnd->load_default(self)", ORPG_DEBUG)
915 return
916 f = open(orpg.dirpath.dir_struct["template"] + "default_map.xml")
917 self.new_data(f.read())
918 f.close()
919 self.canvas.send_map_data("new")
920 if not self.session.is_connected() and (self.session.my_role() != self.session.ROLE_GM):
921 self.session.update_role("GM")
922 self.log.log("Exit map_wnd->load_default(self)", ORPG_DEBUG)
923
924 def new_data(self, data):
925 self.log.log("Enter map_wnd->new_data(self, data)", ORPG_DEBUG)
926 self.canvas.takexml(data)
927 self.update_tools()
928 self.log.log("Exit map_wnd->new_data(self, data)", ORPG_DEBUG)
929
930 def on_save(self,evt):
931 self.log.log("Enter map_wnd->new_data(self, data)", ORPG_DEBUG)
932 if (self.session.my_role() != self.session.ROLE_GM):
933 self.chat.InfoPost("You must be a GM to use this feature")
934 self.log.log("Exit map_wnd->new_data(self, data)", ORPG_DEBUG)
935 return
936 d = wx.FileDialog(self.GetParent(), "Save map data", orpg.dirpath.dir_struct["user"], "", "*.xml", wx.SAVE)
937 if d.ShowModal() == wx.ID_OK:
938 f = open(d.GetPath(), "w")
939 data = '<nodehandler class="min_map" icon="compass" module="core" name="miniature Map">'
940 data += self.canvas.toxml("new")
941 data += "</nodehandler>"
942 data = data.replace(">",">\n")
943 f.write(data)
944 f.close()
945 d.Destroy()
946 os.chdir(self.root_dir)
947 self.log.log("Exit map_wnd->new_data(self, data)", ORPG_DEBUG)
948
949 def on_open(self, evt):
950 self.log.log("Enter map_wnd->on_open(self, evt)", ORPG_DEBUG)
951 if self.session.is_connected() and (self.session.my_role() != self.session.ROLE_GM) and (self.session.use_roles()):
952 self.chat.InfoPost("You must be a GM to use this feature")
953 self.log.log("Exit map_wnd->on_open(self, evt)", ORPG_DEBUG)
954 return
955 d = wx.FileDialog(self.GetParent(), "Select a file", orpg.dirpath.dir_struct["user"], "", "*.xml", wx.OPEN)
956 if d.ShowModal() == wx.ID_OK:
957 f = open(d.GetPath())
958 map_string = f.read()
959 new_xml = self.canvas.re_ids_in_xml(map_string)
960 if new_xml:
961 self.canvas.takexml(new_xml)
962 self.canvas.send_map_data("new")
963 self.update_tools()
964 if not self.session.is_connected() and (self.session.my_role() != self.session.ROLE_GM):
965 self.session.update_role("GM")
966 d.Destroy()
967 os.chdir(self.root_dir)
968 self.log.log("Exit map_wnd->on_open(self, evt)", ORPG_DEBUG)
969
970 def get_current_layer_handler(self):
971 self.log.log("Enter map_wnd->get_current_layer_handler(self)", ORPG_DEBUG)
972 self.log.log("Exit map_wnd->get_current_layer_handler(self)", ORPG_DEBUG)
973 return self.layer_handlers[self.current_layer]
974
975 def get_tab_index(self, layer):
976 """Return the index of a chatpanel in the wxNotebook."""
977 self.log.log("Enter map_wnd->get_tab_index(self, layer)", ORPG_DEBUG)
978 for i in xrange(self.layer_tabs.GetPageCount()):
979 if (self.layer_tabs.GetPageText(i) == layer):
980 self.log.log("Exit map_wnd->get_tab_index(self, layer) return " + str(i), ORPG_DEBUG)
981 return i
982 self.log.log("Exit map_wnd->get_tab_index(self, layer) return 0", ORPG_DEBUG)
983 return 0
984
985 def on_layer_change(self, evt):
986 self.log.log("Enter map_wnd->on_layer_change(self, evt)", ORPG_DEBUG)
987 layer = self.layer_tabs.GetPage(evt.GetSelection())
988 for i in xrange(0, len(self.layer_handlers)):
989 if layer == self.layer_handlers[i]:
990 self.current_layer = i
991 if self.current_layer == 0:
992 bg = self.layer_handlers[0]
993 if (self.session.my_role() != self.session.ROLE_GM):
994 bg.url_path.Show(False)
995 else:
996 bg.url_path.Show(True)
997 self.canvas.Refresh(False)
998 evt.Skip()
999 self.log.log("Exit map_wnd->on_layer_change(self, evt)", ORPG_DEBUG)
1000
1001 def on_left_down(self, evt):
1002 self.log.log("Enter map_wnd->on_left_down(self, evt)", ORPG_DEBUG)
1003 self.log.log("Exit map_wnd->on_left_down(self, evt)", ORPG_DEBUG)
1004 self.layer_handlers[self.current_layer].on_left_down(evt)
1005
1006 #double click handler added by Snowdog 5/03
1007 def on_left_dclick(self, evt):
1008 self.log.log("Enter map_wnd->on_left_dclick(self, evt)", ORPG_DEBUG)
1009 self.log.log("Exit map_wnd->on_left_dclick(self, evt)", ORPG_DEBUG)
1010 self.layer_handlers[self.current_layer].on_left_dclick(evt)
1011
1012 def on_right_down(self, evt):
1013 self.log.log("Enter map_wnd->on_right_down(self, evt)", ORPG_DEBUG)
1014 self.log.log("Exit map_wnd->on_right_down(self, evt)", ORPG_DEBUG)
1015 self.layer_handlers[self.current_layer].on_right_down(evt)
1016
1017 def on_left_up(self, evt):
1018 self.log.log("Enter map_wnd->on_left_up(self, evt)", ORPG_DEBUG)
1019 self.log.log("Exit map_wnd->on_left_up(self, evt)", ORPG_DEBUG)
1020 self.layer_handlers[self.current_layer].on_left_up(evt)
1021
1022 def on_motion(self, evt):
1023 self.log.log("Enter map_wnd->on_motion(self, evt)", ORPG_DEBUG)
1024 self.log.log("Exit map_wnd->on_motion(self, evt)", ORPG_DEBUG)
1025 self.layer_handlers[self.current_layer].on_motion(evt)
1026
1027 def MapBar(self, id, data):
1028 self.log.log("Enter map_wnd->MapBar(self, id, data)", ORPG_DEBUG)
1029 self.canvas.MAP_MODE = data
1030 if id == 1:
1031 self.canvas.MAP_MODE = data
1032 self.log.log("Exit map_wnd->MapBar(self, id, data)", ORPG_DEBUG)
1033
1034 def set_map_focus(self, evt):
1035 self.log.log("Enter map_wnd->set_map_focus(self, evt)", ORPG_DEBUG)
1036 self.canvas.SetFocus()
1037 self.log.log("Exit map_wnd->set_map_focus(self, evt)", ORPG_DEBUG)
1038
1039 def pre_exit_cleanup(self):
1040 self.log.log("Enter map_wnd->pre_exit_cleanup(self)", ORPG_DEBUG)
1041 # do some pre exit clean up for bitmaps or other objects
1042 try:
1043 ImageHandler.flushCache()
1044 self.canvas.pre_destory_cleanup()
1045 except Exception, e:
1046 self.log.log(traceback.format_exc(), ORPG_CRITICAL)
1047 self.log.log("EXCEPTION: " + str(e), ORPG_CRITICAL)
1048 self.log.log("Exit map_wnd->pre_exit_cleanup(self)", ORPG_DEBUG)
1049
1050 def update_tools(self):
1051 self.log.log("Enter map_wnd->update_tools(self)", ORPG_DEBUG)
1052 for h in self.layer_handlers:
1053 h.update_info()
1054 self.log.log("Exit map_wnd->update_tools(self)", ORPG_DEBUG)
1055
1056 def on_hk_map_layer(self, evt):
1057 self.log.log("Enter map_wnd->on_hk_map_layer(self, evt)", ORPG_DEBUG)
1058 id = self.top_frame.mainmenu.GetHelpString(evt.GetId())
1059 #print evt.GetMenu().GetTitle()
1060 if id == "Background Layer":
1061 self.current_layer = self.get_tab_index("Background")
1062 if id == "Grid Layer":
1063 self.current_layer = self.get_tab_index("Grid")
1064 if id == "Miniature Layer":
1065 self.current_layer = self.get_tab_index("Miniatures")
1066 elif id == "Whiteboard Layer":
1067 self.current_layer = self.get_tab_index("Whiteboard")
1068 elif id == "Fog Layer":
1069 self.current_layer = self.get_tab_index("Fog")
1070 elif id == "General Properties":
1071 self.current_layer = self.get_tab_index("General")
1072 self.layer_tabs.SetSelection(self.current_layer)
1073 self.log.log("Exit map_wnd->on_hk_map_layer(self, evt)", ORPG_DEBUG)
1074
1075 def on_flush_cache(self, evt):
1076 self.log.log("Enter map_wnd->on_flush_cache(self, evt)", ORPG_DEBUG)
1077 ImageHandler.flushCache()
1078 self.log.log("Exit map_wnd->on_flush_cache(self, evt)", ORPG_DEBUG)
1079
1080 def build_menu(self):
1081 self.log.log("Enter map_wnd->build_menu(self)", ORPG_DEBUG)
1082 # temp menu
1083 menu = wx.Menu()
1084 item = wx.MenuItem(menu, wx.ID_ANY, "&Load Map", "Load Map")
1085 self.top_frame.Bind(wx.EVT_MENU, self.on_open, item)
1086 menu.AppendItem(item)
1087 item = wx.MenuItem(menu, wx.ID_ANY, "&Save Map", "Save Map")
1088 self.top_frame.Bind(wx.EVT_MENU, self.on_save, item)
1089 menu.AppendItem(item)
1090 menu.AppendSeparator()
1091 item = wx.MenuItem(menu, wx.ID_ANY, "Background Layer\tCtrl+1", "Background Layer")
1092 self.top_frame.Bind(wx.EVT_MENU, self.on_hk_map_layer, item)
1093 menu.AppendItem(item)
1094 item = wx.MenuItem(menu, wx.ID_ANY, "Grid Layer\tCtrl+2", "Grid Layer")
1095 self.top_frame.Bind(wx.EVT_MENU, self.on_hk_map_layer, item)
1096 menu.AppendItem(item)
1097 item = wx.MenuItem(menu, wx.ID_ANY, "Miniature Layer\tCtrl+3", "Miniature Layer")
1098 self.top_frame.Bind(wx.EVT_MENU, self.on_hk_map_layer, item)
1099 menu.AppendItem(item)
1100 item = wx.MenuItem(menu, wx.ID_ANY, "Whiteboard Layer\tCtrl+4", "Whiteboard Layer")
1101 self.top_frame.Bind(wx.EVT_MENU, self.on_hk_map_layer, item)
1102 menu.AppendItem(item)
1103 item = wx.MenuItem(menu, wx.ID_ANY, "Fog Layer\tCtrl+5", "Fog Layer")
1104 self.top_frame.Bind(wx.EVT_MENU, self.on_hk_map_layer, item)
1105 menu.AppendItem(item)
1106 item = wx.MenuItem(menu, wx.ID_ANY, "General Properties\tCtrl+6", "General Properties")
1107 self.top_frame.Bind(wx.EVT_MENU, self.on_hk_map_layer, item)
1108 menu.AppendItem(item)
1109 menu.AppendSeparator()
1110 item = wx.MenuItem(menu, wx.ID_ANY, "&Flush Image Cache\tCtrl+F", "Flush Image Cache")
1111 self.top_frame.Bind(wx.EVT_MENU, self.on_flush_cache, item)
1112 menu.AppendItem(item)
1113 menu.AppendSeparator()
1114 item = wx.MenuItem(menu, wx.ID_ANY, "&Properties", "Properties")
1115 self.top_frame.Bind(wx.EVT_MENU, self.canvas.on_prop, item)
1116 menu.AppendItem(item)
1117 self.top_frame.mainmenu.Insert(2, menu, '&Map')
1118 self.log.log("Exit map_wnd->build_menu(self)", ORPG_DEBUG)
1119
1120 def get_hot_keys(self):
1121 self.log.log("Enter map_wnd->get_hot_keys(self)", ORPG_DEBUG)
1122 self.build_menu()
1123 self.log.log("Exit map_wnd->get_hot_keys(self)", ORPG_DEBUG)
1124 return []
1125
1126 def on_size(self, evt):
1127 self.log.log("Enter map_wnd->on_size(self, evt)", ORPG_DEBUG)
1128 s = self.GetClientSizeTuple()
1129 self.canvas.SetDimensions(0,0,s[0],s[1]-self.toolbar_height)
1130 self.layer_tabs.SetDimensions(0,s[1]-self.toolbar_height,s[0],self.toolbar_height)
1131 self.log.log("Exit map_wnd->on_size(self, evt)", ORPG_DEBUG)