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

Reply via email to