I am trying to implement an application with MDI windows and FloatCanvas2.
My application should have only one guimode toolbar (in the
MDIParentFrame) and a variable number of FC2 canvas (one in each
MDIChildFrame).
For the trivial FC2 functions/buttons that don't have to interact with
the canvas (e.g., zoom to fit, refresh, open, and save), something
like:
self.GetActiveChild().GetChildren()[0].canvas.zoomToExtents()
works as expected when I press the ZoomToFit button in my toolbar
The problem is that I don't have any clue on how to implement the more
complex toolbar functions, like ZoomIn and Move, which require
constant interaction with the canvas.
I couldn't figure out how to do that even after looking at NavCanvas
and GuiMode functions.
I tried simple things like just calling
floatcanvas.guiMode.GUIModeZoomIn() and binding the toolbar event with
this method but it doesn't work. I was thinking that I could directly
call the GuiMode function in a simple way, I also tried to modify the
NavCanvas function to work with MDI windows but there are some stuff
there I don't understand, but nothing worked
I'd appreciate any directions on how to do that.
In case you need, I attached a small application with MDI windows and FC2.
Two more questions:
How to automatically resize (zoom to fit) the canvas when the MDI
window is resized? (I am using
self.GetActiveChild().GetChildren()[0].canvas.zoomToExtents() but it
does not work well; you will see that if you try the attached code).
How to change the look of a FC2 object? The FC2 objects have many
attributes but .look does not work.
Best
Marcos
Here are two very minor 'misbehavior' in FC2:
In FC2, just for stability, when somebody tries to rotate a circle(!),
FC2 crashes (I did that with the rotate gui tool).
The problem is with line 61 of transform.py, because numpy.linalg.inv(
normalized ) returns an error of singular matrix.
To avoid this problem, you might capture the error and return the
identity matrix in this case.
If the user uses the functions Export Image or Export SVG, and then
press cancel on the Select File dialog, an error occurs on lines 169
or 173 of navcanvas.py.
Just add a test to see if the user did press save or if the filename
is not empty.
"""
Draw points with the left-button mouse clicks in MDI windows
"""
import wx
import floatcanvas
#from floatcanvas.resources import Resources, navCanvasIcons
#from floatcanvas.patterns.partial import partial
class Drawer(object):
def __init__(self, canvas):
self.canvas = canvas
self.npoint = 0
#Bind event handlers
self.canvas.subscribe( self.onLeftDown, 'raw_input.left_down' )
def onLeftDown(self, evt):
pos = evt.coords.world # evt.coords is an array
self.point = (pos[0], pos[1]) # list
self.npoint += 1
# Draw point:
look = floatcanvas.SolidColourLook( line_colour = 'red', fill_colour = (255,0,0,255) ) # one solid color
pt = self.canvas.create('Circle', 10, pos=self.point, name='Point # %d' % self.npoint, look=look, where='front')
class MDIFrame(wx.MDIParentFrame):
def __init__(self, parent):
self.size = (800, 600)
wx.MDIParentFrame.__init__(
self, None, -1, title="Xc", size=self.size,
style = wx.DEFAULT_FRAME_STYLE )
self.winCount = 0
self.win = []
#MenuBar
self.createMenuBar()
#Toolbar
self.createToolBar()
#Status bar
self.statusbar = self.CreateStatusBar()
#The 1st canvas
self.winCount = self.winCount + 1
child = wx.MDIChildFrame(self, -1, title = "Canvas %d" % self.winCount, size = (600,400) )
self.win.append(child)
self.panel = wx.Panel(self.win[self.winCount-1], -1, name = "Panel %d" % self.winCount, size = (600,400) )
self.panel.canvas = floatcanvas.FloatCanvas( self.panel, backgroundColor = 'white', name = "Canvas %d" % self.winCount )
self.drawer = Drawer(self.panel.canvas)
self.win[self.winCount-1].Show(True)
#Event handlers
self.panel.canvas.subscribe( self.onMotion, 'raw_input.move' )
self.panel.canvas.subscribe( self.onMotion, 'raw_input.left_down' )
self.win[-1].Bind(wx.EVT_SIZE, self.onSize)
def createMenuBar(self):
self.menuBar = wx.MenuBar()
menu_file = wx.Menu()
self.menuBar.Append(menu_file, "&File")
self.SetMenuBar(self.menuBar)
def createToolBar(self):
toolbar = self.CreateToolBar()
toolbar.SetToolBitmapSize((24,24))
for each in self.toolbarData():
self.createSimpleTool(toolbar, *each)
toolbar.AddSeparator()
toolbar.Realize()
def createSimpleTool(self, toolbar, label, filename, help, handler):
bmp = wx.Image(filename).ConvertToBitmap()
tool = toolbar.AddSimpleTool(-1, bmp, label, help)
self.Bind(wx.EVT_TOOL, handler, tool)
def toolbarData(self):
return (("New Window", "data/icons/thumbnail.png", "New window", self.onNewWindow),
("Zoom In", "data/icons/viewmag_plus.png", "Zoom in", self.onZoomIn),
("Zoom Out", "data/icons/viewmag_minus.png", "Zoom out", self.onZoomOut),
("Zoom Fit", "data/icons/view_nofullscreen.png", 'Zoom to fit', self.onZoomToFit),
("Zoom 100%", "data/icons/viewmag_one.png", "Zoom 100%", self.onZoom100))
def onNewWindow(self, event):
self.winCount = self.winCount + 1
if self.winCount == 1:
child = wx.MDIChildFrame(self, -1, title="Canvas %d" % self.winCount, pos=(0,0), size=(600,400) )
else:
child = wx.MDIChildFrame(self, -1, title="Canvas %d" % self.winCount, size=(600,400) )
self.win.append(child)
self.panel = wx.Panel(self.win[self.winCount-1], -1, name="Panel %d" % self.winCount, size=(600,400) )
self.panel.canvas = floatcanvas.FloatCanvas( self.panel, backgroundColor='white', name="Canvas %d" % self.winCount )
self.drawer = Drawer(self.panel.canvas)
self.win[self.winCount-1].Show(True)
self.panel.canvas.subscribe( self.onMotion, 'raw_input.move' )
self.panel.canvas.subscribe( self.onMotion, 'raw_input.right_down' )
self.panel.canvas.subscribe( self.onMotion, 'raw_input.left_down' )
self.win[-1].Bind(wx.EVT_SIZE, self.onSize)
def onZoomIn(self, event):
##THIS DOES NOT WORK
floatcanvas.guiMode.GUIModeZoomIn()
def onZoomOut(self, event):
##THIS DOES NOT WORK
self.Bind( wx.EVT_TOOL, floatcanvas.guiMode.GUIModeZoomOut() )
def onZoomToFit(self, event):
self.GetActiveChild().GetChildren()[0].canvas.zoomToExtents()
def onZoom100(self, event):
self.GetActiveChild().GetChildren()[0].canvas.camera.zoom = (1, 1)
def onRefresh(self, event):
self.GetActiveChild().GetChildren()[0].canvas.Render()
def onMotion(self, event):
coords = event.coords.world.round(1)
self.statusbar.SetStatusText("Coordinates: %s" % coords)
event.Skip()
def onSize(self, event):
##THIS DOES NOT WORK WELL: it works for increasing the sizing
## but not for decreasing it (the canvas objects do not resize)
self.GetActiveChild().GetChildren()[0].canvas.zoomToExtents()
event.Skip()
def onExit(self, event):
self.Close(True)
class App(wx.App):
"""Application class"""
def OnInit(self):
self.frame = MDIFrame(None)
self.frame.Show(True)
self.SetTopWindow(self.frame)
return True
def main():
app = App(redirect = False)
app.MainLoop()
if __name__ == '__main__':
main()
_______________________________________________
FloatCanvas mailing list
[email protected]
http://mail.mithis.com/cgi-bin/mailman/listinfo/floatcanvas