15 |
|
|
16 |
from wxPython.wx import wxWindow,\ |
from wxPython.wx import wxWindow,\ |
17 |
wxPaintDC, wxColour, wxClientDC, wxINVERT, wxTRANSPARENT_BRUSH, wxFont,\ |
wxPaintDC, wxColour, wxClientDC, wxINVERT, wxTRANSPARENT_BRUSH, wxFont,\ |
18 |
EVT_PAINT, EVT_LEFT_DOWN, EVT_LEFT_UP, EVT_MOTION |
EVT_PAINT, EVT_LEFT_DOWN, EVT_LEFT_UP, EVT_MOTION, EVT_LEAVE_WINDOW |
19 |
|
|
20 |
|
|
21 |
from wxPython import wx |
from wxPython import wx |
29 |
SHAPETYPE_POINT |
SHAPETYPE_POINT |
30 |
from Thuban.Model.label import ALIGN_CENTER, ALIGN_TOP, ALIGN_BOTTOM, \ |
from Thuban.Model.label import ALIGN_CENTER, ALIGN_TOP, ALIGN_BOTTOM, \ |
31 |
ALIGN_LEFT, ALIGN_RIGHT |
ALIGN_LEFT, ALIGN_RIGHT |
32 |
|
from Thuban.Lib.connector import Publisher |
33 |
|
|
34 |
from renderer import ScreenRenderer, PrinterRender |
from renderer import ScreenRenderer, PrinterRender |
35 |
|
|
36 |
import labeldialog |
import labeldialog |
37 |
|
|
38 |
from messages import SELECTED_SHAPE |
from messages import SELECTED_SHAPE, VIEW_POSITION |
39 |
|
|
40 |
|
|
41 |
# |
# |
240 |
return wx.true |
return wx.true |
241 |
|
|
242 |
|
|
243 |
class MapCanvas(wxWindow): |
class MapCanvas(wxWindow, Publisher): |
244 |
|
|
245 |
"""A widget that displays a map and offers some interaction""" |
"""A widget that displays a map and offers some interaction""" |
246 |
|
|
253 |
self.dragging = 0 |
self.dragging = 0 |
254 |
self.tool = None |
self.tool = None |
255 |
self.redraw_on_idle = 0 |
self.redraw_on_idle = 0 |
256 |
|
self.current_position = None |
257 |
EVT_PAINT(self, self.OnPaint) |
EVT_PAINT(self, self.OnPaint) |
258 |
EVT_LEFT_DOWN(self, self.OnLeftDown) |
EVT_LEFT_DOWN(self, self.OnLeftDown) |
259 |
EVT_LEFT_UP(self, self.OnLeftUp) |
EVT_LEFT_UP(self, self.OnLeftUp) |
260 |
EVT_MOTION(self, self.OnMotion) |
EVT_MOTION(self, self.OnMotion) |
261 |
|
EVT_LEAVE_WINDOW(self, self.OnLeaveWindow) |
262 |
wx.EVT_IDLE(self, self.OnIdle) |
wx.EVT_IDLE(self, self.OnIdle) |
263 |
self.interactor = interactor |
self.interactor = interactor |
264 |
self.interactor.Subscribe(SELECTED_SHAPE, self.shape_selected) |
self.interactor.Subscribe(SELECTED_SHAPE, self.shape_selected) |
265 |
|
|
266 |
|
def __del__(self): |
267 |
|
wxWindow.__del__(self) |
268 |
|
Publisher.__del__(self) |
269 |
|
|
270 |
def OnPaint(self, event): |
def OnPaint(self, event): |
271 |
dc = wxPaintDC(self) |
dc = wxPaintDC(self) |
272 |
if self.map is not None and self.map.HasLayers(): |
if self.map is not None and self.map.HasLayers(): |
452 |
def CurrentTool(self): |
def CurrentTool(self): |
453 |
return self.tool and self.tool.Name() or None |
return self.tool and self.tool.Name() or None |
454 |
|
|
455 |
|
def CurrentPosition(self): |
456 |
|
"""Return current position of the mouse in projected coordinates. |
457 |
|
|
458 |
|
The result is a 2-tuple of floats with the coordinates. If the |
459 |
|
mouse is not in the window, the result is None. |
460 |
|
""" |
461 |
|
if self.current_position is not None: |
462 |
|
x, y = self.current_position |
463 |
|
return self.win_to_proj(x, y) |
464 |
|
else: |
465 |
|
return None |
466 |
|
|
467 |
|
def set_current_position(self, event): |
468 |
|
"""Set the current position from event |
469 |
|
|
470 |
|
Should be called by all events that contain mouse positions |
471 |
|
especially EVT_MOTION. The event paramete may be None to |
472 |
|
indicate the the pointer left the window. |
473 |
|
""" |
474 |
|
if event is not None: |
475 |
|
self.current_position = (event.m_x, event.m_y) |
476 |
|
else: |
477 |
|
self.current_position = None |
478 |
|
self.issue(VIEW_POSITION) |
479 |
|
|
480 |
def OnLeftDown(self, event): |
def OnLeftDown(self, event): |
481 |
|
self.set_current_position(event) |
482 |
if self.tool is not None: |
if self.tool is not None: |
483 |
self.drag_dc = wxClientDC(self) |
self.drag_dc = wxClientDC(self) |
484 |
self.drag_dc.SetLogicalFunction(wxINVERT) |
self.drag_dc.SetLogicalFunction(wxINVERT) |
490 |
|
|
491 |
def OnLeftUp(self, event): |
def OnLeftUp(self, event): |
492 |
self.ReleaseMouse() |
self.ReleaseMouse() |
493 |
|
self.set_current_position(event) |
494 |
if self.dragging: |
if self.dragging: |
495 |
self.tool.Hide(self.drag_dc) |
self.tool.Hide(self.drag_dc) |
496 |
self.tool.MouseUp(event) |
self.tool.MouseUp(event) |
498 |
self.dragging = 0 |
self.dragging = 0 |
499 |
|
|
500 |
def OnMotion(self, event): |
def OnMotion(self, event): |
501 |
|
self.set_current_position(event) |
502 |
if self.dragging: |
if self.dragging: |
503 |
self.tool.Hide(self.drag_dc) |
self.tool.Hide(self.drag_dc) |
504 |
self.tool.MouseMove(event) |
self.tool.MouseMove(event) |
505 |
self.tool.Show(self.drag_dc) |
self.tool.Show(self.drag_dc) |
506 |
|
|
507 |
|
def OnLeaveWindow(self, event): |
508 |
|
self.set_current_position(None) |
509 |
|
|
510 |
def OnIdle(self, event): |
def OnIdle(self, event): |
511 |
if self.redraw_on_idle: |
if self.redraw_on_idle: |
512 |
self.do_redraw() |
self.do_redraw() |