On Thu, May 8, 2014 at 11:01 PM, Farrukh <[email protected]> wrote:

>  Thanks for gracious comments sir here is my code when i draw a rectangle
> and upon zoomin or zoomout everything on canvas disappears and please add
> code for how to undo last drawn shape.
>

I was on travel, and didn't get a chance to check this out till now.

My comments:

0) NEVER use tabs to indent! really! trust me on this.

1) as is, it doesn't display right at first. and odd rectangle at th upper
left.
  but making the FloatCanvas background color red make  it show up clearly,
and it was there -- though not the scrollbars...


2) I recommend against nested design like this -- hard to debug and not
very flexible. i.e keep the panels as separate claees, and everyting
related to each panel it it's class -- then put them together on the Frame.
See:

http://wiki.wxpython.org/wxPython%20Style%20Guide

for some more ideas and discussion.

3) You are mingling your own drawing and FloatCanvas drawing -- that could
get tricky -- I"d try to work with FloatCAvanas and much as possible -- if
you need to add features, make a subclass and add them (and maybe I"ll want
to integrate them into the main code at some point, but let the FloatCanvas
manage the DCs, etc for you.

4) specifics:

* NC = FloatCanvas.FloatCanvas(self.cpanel)

FloatCanvas IS a panel, so no need to put it on another panel, unless there
is other stuff on that panel.

However, cpanel is a scrolledPanel, this is likley to get ugly --
FloatCanvas is designed to do handle zooming and panning itself, putting it
on a Scrolled Panel might get weird...

I never got a chance to implement it, but the "right" thing to do is to
make a version of FloatCanvas that uses scroll bars, if you want them,
instead of the Panning. You would do that by creating scroll bars and
calling the FloatCanvas.Move method when the user scrolled.

*   if USE_BUFFERED_DC:

you probably don't want to mess with BUFFERED_DC -- FloatCanvas is
buffering on ints own already.

*  self.dc = wx.ClientDC(self.canvas)

keeping DCs around is not a great idea in general, and Client DC, certanly
not. create it when (if) you need it.


*        self.toppanel.zoomout = wx.Button(self.toppanel, label='-',
pos=(240, 2), size=(40, 25))
        self.toppanel.Bind(wx.EVT_BUTTON, self.ZoomOut,
self.toppanel.zoomout)

cleaner syntax for binding:

self.toppanel.zoomout.Bind(wx.EVT_BUTTON, self.ZoomOut)

* you want to use the FloatCanvas events' GetCoords() method to get the
"world coordinates of the event -- so you can put stuff on the canvas in
the right coordinates.

*

> <[email protected]> wrote:
>
>> 1- I am using  "FloatCanvas.FloatCanvas(self.panel)"  and when i
>> "self.canvas.Zoom(1.1)" or "self.canvas.Zoom(0.9)" all of my drawn shapes
>> disappear.
>
>
I"m not getting any drawing now -- but also the only code I see that adds
anyting to the canvas is NewREct -- but I dont see that gtting called
anywhere.

If you draw anything on top of the Canvas with a ClientDC -- it will
disapear when the canvas re-draws -- you'll need to add an object to the
canvaqs to get anything new on there.

But ideally you don't need to do a lot of hand-drawing on the canvas with a
ClientDC. YOu can put objects on the canvas on the "forecground" layer, and
they will be rendered quickly without needing to re-render the entire
canvas.

After drawing they can be removed from the foreground.

You'll then need to manage the added objects somehow, if you want to be
able edit them, or delete them, or????

I've hacked up your sample to show this in action. There is still an odd
rendering bug on OS-X, and I recommend some re-factoring, but you can draw
stuff and zoom in and out and it all renders well.

HTH,
  -Chris


-- 

Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R            (206) 526-6959   voice
7600 Sand Point Way NE   (206) 526-6329   fax
Seattle, WA  98115       (206) 526-6317   main reception

[email protected]
#!/usr/bin/env python

import numpy as np

import wx, os, sys, os.path, math
from wx.lib.floatcanvas import NavCanvas, FloatCanvas, Resources, Utilities, GUIMode
from wx.lib.floatcanvas.Utilities import GUI
import wx.lib.scrolledpanel as scrolled

try:
    from agw import pybusyinfo as PBI
except ImportError: # if it's not there locally, try the wxPython lib.
    import wx.lib.agw.pybusyinfo as PBI
    
#USE_BUFFERED_DC = False
USE_BUFFERED_DC = False
           
class Example(wx.Frame):
    def __init__(self, parent, title, size):
        style=( wx.MINIMIZE_BOX | wx.MAXIMIZE_BOX | wx.SYSTEM_MENU | wx.CLOSE_BOX | wx.CAPTION | wx.CLIP_CHILDREN )
        wx.Frame.__init__(self, parent, title=title, size=size, style = style)  # pos is not working in this statement. 
        self.Centre()
        self.toppanel = wx.Panel(self)
        self.cpanel = wx.ScrolledWindow(self)
        
        self.maxVirtualWidth  = 1000
        self.maxVirtualHeight = 1000
        self.cpanel.SetVirtualSize((self.maxVirtualWidth, self.maxVirtualHeight))
        self.cpanel.SetScrollRate(20,20)
     
        self.penclr = wx.Colour(0, 255, 255, 128)
        self.brushclr  = wx.Colour(3, 2, 255, 240)
        self.detailpenclr = wx.Colour(255, 0, 0, 128)
        self.detailbrushclr  = wx.Colour(252, 253, 0, 240)
        self.r = 255
        self.g = 0
        self.b = 0
        self.thickness = 2
        self.linetype = wx.SHORT_DASH
        self.Tol = 2
        self.Drawing = False
        self.RBRect = None
        self.Rects = []
        
        self.toppanel.SetBackgroundColour( ( 223, 235, 247 ) )
        # LIGHT GRAY, LIGHT STEEL BLUE, WHEAT
        
        w, h = self.cpanel.GetSize()
        #self.Bind(wx.EVT_PAINT, self.OnPaint)
        #NC = NavCanvas.NavCanvas(self.cpanel, size=(-1,-1), ProjectionFun = None, Debug = 0)
        #self.cpanel.tb = NC.ToolBar
        #self.cpanel.tb.AddSeparator()
        #self.cpanel.tb.Realize()
        

        NC = FloatCanvas.FloatCanvas(self.cpanel,
                                     BackgroundColor = "White",
                                     )
        self.canvas = NC
        
        if USE_BUFFERED_DC:
            self.buffer = wx.EmptyBitmap(w, h)
            self.dc = wx.BufferedPaintDC(None, self.buffer, style=wx.BUFFER_VIRTUAL_AREA)
        
        elif False:
            self.buffer = wx.EmptyBitmap(w, h)
            self.dc = wx.BufferedDC(None, self.buffer)
        
        elif False:
            self.cdc = wx.ClientDC(self.canvas)
            bmp = wx.EmptyBitmap(w, h)
            memDC = wx.MemoryDC()
            memDC.SelectObject(bmp)
            memDC.Blit( 0, 0, w, h, self.cdc, 0, 0  )
            memDC.SelectObject(wx.NullBitmap)
            
            self.dc = memDC
        
        else:
            self.dc = wx.ClientDC(self.canvas)
    
        self.canvas.MinScale = 0.2
        self.canvas.MaxScale = 2.4
        
        self.canvas.Bind(FloatCanvas.EVT_MOTION, self.OnMove)
        self.canvas.Bind(FloatCanvas.EVT_LEFT_DOWN, self.OnDown)
        self.canvas.Bind(FloatCanvas.EVT_LEFT_UP, self.OnUp)
        self.timer = wx.Timer(self)
        
        self.toppanel.zoomin = wx.Button(self.toppanel, label='+', pos=(190, 2), size=(40, 25))
        self.toppanel.Bind(wx.EVT_BUTTON, self.ZoomIn, self.toppanel.zoomin)
        
        self.toppanel.zoomout = wx.Button(self.toppanel, label='-', pos=(240, 2), size=(40, 25))
        self.toppanel.Bind(wx.EVT_BUTTON, self.ZoomOut, self.toppanel.zoomout)

        canvas_sizer = wx.BoxSizer(wx.HORIZONTAL)
        canvas_sizer.Add(self.canvas, 1, wx.EXPAND | wx.ALIGN_CENTRE | wx.ALL, border=0)
        self.cpanel.SetSizer(canvas_sizer)
                
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.toppanel, 1, wx.EXPAND | wx.ALIGN_TOP)
        sizer.Add(self.cpanel, 19, wx.EXPAND | wx.ALIGN_CENTRE | wx.ALL, border=25)
        #self.SetAutoLayout(True)
        self.SetSizer(sizer)
        
        self.statusbar = self.CreateStatusBar(2, wx.ST_SIZEGRIP) 
        self.statusbar.SetStatusWidths([-4, -1])
        self.statusbar.SetStatusText('Ready', 0)
        self.statusbar.SetStatusText('Float Canvas', 1)
                    
        self.AddedLines = []

    def NewRect(self, rect):
        self.Rects.append(self.canvas.AddRectangle(*rect, LineWidth=2))
        self.canvas.Draw(True)

    # def OnMove(self, e):
    #     upx, upy = e.GetPosition()
    #     self.statusbar.SetStatusText('x:'+str(upx)+'  y:'+str(upy),1)
        
    #     if self.Drawing:
    #         x, y = self.StartPoint
    #         Cornerx, Cornery = e.GetPosition()
    #         w, h = ( Cornerx - x, Cornery - y)
    #         self.pt1x = x
    #         self.pt1y = y
    #         self.statusbar.SetStatusText('Left_Down x:'+str(self.pt1x)+'  y:'+str(self.pt1y)+ ' -- Left_Down x:'+str(Cornerx)+'  y:'+str(Cornery),0)
    #         if abs(w) > self.Tol and abs(h) > self.Tol:
    #             # draw the RB box
    #             self.dc.SetPen(wx.Pen(self.penclr, self.thickness, self.linetype))
    #             self.dc.SetBrush(wx.Brush(self.brushclr))
    #             self.dc.SetLogicalFunction(wx.XOR)
    #             if self.RBRect:
    #                 self.dc.DrawRectanglePointSize(*self.RBRect)
    #             self.RBRect = ( (self.pt1x,self.pt1y), (w, h) )
    #             self.dc.DrawRectanglePointSize(*self.RBRect)

    def OnMove(self, e):
        x, y = e.GetCoords()
        self.statusbar.SetStatusText('x:'+str(x)+'  y:'+str(y), 1)
        
        if self.Drawing:
            x, y = e.GetCoords()
            self.CurrentLine.Points = np.r_[self.CurrentLine.Points, ((x,y),)]
            self.canvas.Draw()
    
                    
    def OnDown(self, e):
        print "OnDown"
        self.canvas.SetCursor(wx.StockCursor(wx.CURSOR_PENCIL)) # change default + cursor to pencil
        # Start drawing
        self.Drawing = True
        self.StartPoint = x, y = e.GetCoords()
        self.CurrentLine = self.canvas.AddLine([self.StartPoint,],
                                               LineColor = "Blue",
                                               LineStyle = "Solid",
                                               LineWidth    = 4,
                                               InForeground = True)

        #e.Skip()
        
    def OnUp(self, e):
        self.canvas.SetCursor(wx.StockCursor(wx.CURSOR_ARROW)) # change default + cursor to pencil
        # Stop Drawing
        if self.Drawing:
            self.Drawing = False
            self.CurrentLine.PutInBackground()
            self.AddedLines.append(self.CurrentLine)
            self.CurrentLine = None

        self.RBRect = None
    
    def ZoomIn(self, e):
        self.canvas.Zoom(1.5)
        self.canvas.Draw(True)
        e.Skip()

    def ZoomOut(self, e):
        self.canvas.Zoom(0.666666666666666)   
        self.canvas.Draw(True)
        e.Skip()
                
if __name__ == '__main__':
    app = wx.App()
    Example(None, 'Float Canvas', size=(800, 660)).Show()

    #import wx.lib.inspection
    #wx.lib.inspection.InspectionTool().Show()

    app.MainLoop()

_______________________________________________
FloatCanvas mailing list
[email protected]
http://mailman.paulmcnett.com/cgi-bin/mailman/listinfo/floatcanvas

Reply via email to