mirror of
https://github.com/wxWidgets/Phoenix.git
synced 2026-01-04 11:00:07 +01:00
Add the FloatCanvas demo modules
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxPython/Phoenix/trunk@73860 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
304
samples/floatcanvas/Animation.py
Executable file
304
samples/floatcanvas/Animation.py
Executable file
@@ -0,0 +1,304 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
A test of some simple animation
|
||||||
|
|
||||||
|
this is very old-style code: don't imitate it!
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
from time import clock
|
||||||
|
import wx
|
||||||
|
from numpy import *
|
||||||
|
|
||||||
|
## import local version:
|
||||||
|
import sys
|
||||||
|
|
||||||
|
#ver = 'local'
|
||||||
|
ver = 'installed'
|
||||||
|
|
||||||
|
if ver == 'installed': ## import the installed version
|
||||||
|
from wx.lib.floatcanvas import NavCanvas
|
||||||
|
from wx.lib.floatcanvas import FloatCanvas
|
||||||
|
print "using installed version:", wx.lib.floatcanvas.__version__
|
||||||
|
elif ver == 'local':
|
||||||
|
## import a local version
|
||||||
|
import sys
|
||||||
|
sys.path.append("..")
|
||||||
|
from floatcanvas import NavCanvas
|
||||||
|
from floatcanvas import FloatCanvas
|
||||||
|
|
||||||
|
ID_DRAW_BUTTON = 100
|
||||||
|
ID_QUIT_BUTTON = 101
|
||||||
|
ID_CLEAR_BUTTON = 103
|
||||||
|
ID_ZOOM_IN_BUTTON = 104
|
||||||
|
ID_ZOOM_OUT_BUTTON = 105
|
||||||
|
ID_ZOOM_TO_FIT_BUTTON = 110
|
||||||
|
ID_MOVE_MODE_BUTTON = 111
|
||||||
|
ID_TEST_BUTTON = 112
|
||||||
|
|
||||||
|
ID_ABOUT_MENU = 200
|
||||||
|
ID_EXIT_MENU = 201
|
||||||
|
ID_ZOOM_IN_MENU = 202
|
||||||
|
ID_ZOOM_OUT_MENU = 203
|
||||||
|
ID_ZOOM_TO_FIT_MENU = 204
|
||||||
|
ID_DRAWTEST_MENU = 205
|
||||||
|
ID_DRAWMAP_MENU = 206
|
||||||
|
ID_CLEAR_MENU = 207
|
||||||
|
|
||||||
|
|
||||||
|
ID_TEST = 500
|
||||||
|
|
||||||
|
|
||||||
|
class DrawFrame(wx.Frame):
|
||||||
|
def __init__(self,parent, id,title,position,size):
|
||||||
|
wx.Frame.__init__(self,parent, id,title,position, size)
|
||||||
|
|
||||||
|
## Set up the MenuBar
|
||||||
|
|
||||||
|
MenuBar = wx.MenuBar()
|
||||||
|
|
||||||
|
file_menu = wx.Menu()
|
||||||
|
file_menu.Append(ID_EXIT_MENU, "E&xit","Terminate the program")
|
||||||
|
wx.EVT_MENU(self, ID_EXIT_MENU, self.OnQuit)
|
||||||
|
MenuBar.Append(file_menu, "&File")
|
||||||
|
|
||||||
|
draw_menu = wx.Menu()
|
||||||
|
draw_menu.Append(ID_DRAWTEST_MENU, "&Draw Test","Run a test of drawing random components")
|
||||||
|
wx.EVT_MENU(self, ID_DRAWTEST_MENU,self.DrawTest)
|
||||||
|
draw_menu.Append(ID_DRAWMAP_MENU, "Draw &Movie","Run a test of drawing a map")
|
||||||
|
wx.EVT_MENU(self, ID_DRAWMAP_MENU,self.RunMovie)
|
||||||
|
draw_menu.Append(ID_CLEAR_MENU, "&Clear","Clear the Canvas")
|
||||||
|
wx.EVT_MENU(self, ID_CLEAR_MENU,self.Clear)
|
||||||
|
MenuBar.Append(draw_menu, "&Draw")
|
||||||
|
|
||||||
|
|
||||||
|
view_menu = wx.Menu()
|
||||||
|
view_menu.Append(ID_ZOOM_TO_FIT_MENU, "Zoom to &Fit","Zoom to fit the window")
|
||||||
|
wx.EVT_MENU(self, ID_ZOOM_TO_FIT_MENU,self.ZoomToFit)
|
||||||
|
MenuBar.Append(view_menu, "&View")
|
||||||
|
|
||||||
|
help_menu = wx.Menu()
|
||||||
|
help_menu.Append(ID_ABOUT_MENU, "&About",
|
||||||
|
"More information About this program")
|
||||||
|
wx.EVT_MENU(self, ID_ABOUT_MENU, self.OnAbout)
|
||||||
|
MenuBar.Append(help_menu, "&Help")
|
||||||
|
|
||||||
|
self.SetMenuBar(MenuBar)
|
||||||
|
|
||||||
|
self.CreateStatusBar()
|
||||||
|
self.SetStatusText("")
|
||||||
|
|
||||||
|
wx.EVT_CLOSE(self, self.OnCloseWindow)
|
||||||
|
|
||||||
|
# Other event handlers:
|
||||||
|
wx.EVT_RIGHT_DOWN(self, self.RightButtonEvent)
|
||||||
|
|
||||||
|
# Add the Canvas
|
||||||
|
self.Canvas = NavCanvas.NavCanvas(self,-1,(500,500),
|
||||||
|
Debug = False,
|
||||||
|
BackgroundColor = "WHITE").Canvas
|
||||||
|
self.Canvas.NumBetweenBlits = 1000
|
||||||
|
self.Show(True)
|
||||||
|
|
||||||
|
self.DrawTest(None)
|
||||||
|
return None
|
||||||
|
|
||||||
|
def RightButtonEvent(self,event):
|
||||||
|
print "Right Button has been clicked in DrawFrame"
|
||||||
|
print "coords are: %i, %i"%(event.GetX(),event.GetY())
|
||||||
|
event.Skip()
|
||||||
|
|
||||||
|
def OnAbout(self, event):
|
||||||
|
dlg = wx.MessageDialog(self, "This is a small program to demonstrate\n"
|
||||||
|
"the use of the FloatCanvas\n",
|
||||||
|
"About Me", wx.OK | wx.ICON_INFORMATION)
|
||||||
|
dlg.ShowModal()
|
||||||
|
dlg.Destroy()
|
||||||
|
|
||||||
|
def ZoomToFit(self,event):
|
||||||
|
self.Canvas.ZoomToBB()
|
||||||
|
|
||||||
|
def Clear(self,event = None):
|
||||||
|
self.Canvas.ClearAll()
|
||||||
|
self.Canvas.Draw()
|
||||||
|
|
||||||
|
def OnQuit(self,event):
|
||||||
|
self.Close(True)
|
||||||
|
|
||||||
|
def OnCloseWindow(self, event):
|
||||||
|
self.Destroy()
|
||||||
|
|
||||||
|
def DrawTest(self,event = None):
|
||||||
|
import random
|
||||||
|
import numpy.random as RandomArray
|
||||||
|
|
||||||
|
Range = (-10,10)
|
||||||
|
|
||||||
|
colors = ["AQUAMARINE", "BLACK", "BLUE", "BLUE VIOLET", "BROWN",
|
||||||
|
"CADET BLUE", "CORAL", "CORNFLOWER BLUE", "CYAN", "DARK GREY",
|
||||||
|
"DARK GREEN", "DARK OLIVE GREEN", "DARK ORCHID", "DARK SLATE BLUE",
|
||||||
|
"DARK SLATE GREY", "DARK TURQUOISE", "DIM GREY",
|
||||||
|
"FIREBRICK", "FOREST GREEN", "GOLD", "GOLDENROD", "GREY",
|
||||||
|
"GREEN", "GREEN YELLOW", "INDIAN RED", "KHAKI", "LIGHT BLUE",
|
||||||
|
"LIGHT GREY", "LIGHT STEEL BLUE", "LIME GREEN", "MAGENTA",
|
||||||
|
"MAROON", "MEDIUM AQUAMARINE", "MEDIUM BLUE", "MEDIUM FOREST GREEN",
|
||||||
|
"MEDIUM GOLDENROD", "MEDIUM ORCHID", "MEDIUM SEA GREEN",
|
||||||
|
"MEDIUM SLATE BLUE", "MEDIUM SPRING GREEN", "MEDIUM TURQUOISE",
|
||||||
|
"MEDIUM VIOLET RED", "MIDNIGHT BLUE", "NAVY", "ORANGE", "ORANGE RED",
|
||||||
|
"ORCHID", "PALE GREEN", "PINK", "PLUM", "PURPLE", "RED",
|
||||||
|
"SALMON", "SEA GREEN", "SIENNA", "SKY BLUE", "SLATE BLUE",
|
||||||
|
"SPRING GREEN", "STEEL BLUE", "TAN", "THISTLE", "TURQUOISE",
|
||||||
|
"VIOLET", "VIOLET RED", "WHEAT", "WHITE", "YELLOW", "YELLOW GREEN"]
|
||||||
|
Canvas = self.Canvas
|
||||||
|
|
||||||
|
# Some Polygons in the background:
|
||||||
|
# for i in range(500):
|
||||||
|
# points = RandomArray.uniform(-100,100,(10,2))
|
||||||
|
for i in range(500):
|
||||||
|
# for i in range(1):
|
||||||
|
points = RandomArray.uniform(-100,100,(10,2))
|
||||||
|
lw = random.randint(1,6)
|
||||||
|
cf = random.randint(0,len(colors)-1)
|
||||||
|
cl = random.randint(0,len(colors)-1)
|
||||||
|
self.Canvas.AddPolygon(points,
|
||||||
|
LineWidth = lw,
|
||||||
|
LineColor = colors[cl],
|
||||||
|
FillColor = colors[cf],
|
||||||
|
FillStyle = 'Solid',
|
||||||
|
InForeground = False)
|
||||||
|
|
||||||
|
## Pointset
|
||||||
|
print "Adding Points to Foreground"
|
||||||
|
for i in range(1):
|
||||||
|
points = RandomArray.uniform(-100,100,(1000,2))
|
||||||
|
D = 2
|
||||||
|
self.LEs = self.Canvas.AddPointSet(points, Color = "Black", Diameter = D, InForeground = True)
|
||||||
|
|
||||||
|
self.Canvas.AddRectangle((-200,-200), (400,400))
|
||||||
|
Canvas.ZoomToBB()
|
||||||
|
|
||||||
|
def RunMovie(self,event = None):
|
||||||
|
import numpy.random as RandomArray
|
||||||
|
start = clock()
|
||||||
|
#shift = RandomArray.randint(0,0,(2,))
|
||||||
|
for i in range(100):
|
||||||
|
points = self.LEs.Points
|
||||||
|
shift = RandomArray.randint(-5,6,(2,))
|
||||||
|
points += shift
|
||||||
|
self.LEs.SetPoints(points)
|
||||||
|
self.Canvas.Draw()
|
||||||
|
wx.GetApp().Yield(True)
|
||||||
|
print "running the movie took %f seconds"%(clock() - start)
|
||||||
|
|
||||||
|
class DemoApp(wx.App):
|
||||||
|
"""
|
||||||
|
How the demo works:
|
||||||
|
|
||||||
|
Under the Draw menu, there are three options:
|
||||||
|
|
||||||
|
*Draw Test: will put up a picture of a bunch of randomly generated
|
||||||
|
objects, of each kind supported.
|
||||||
|
|
||||||
|
*Draw Map: will draw a map of the world. Be patient, it is a big map,
|
||||||
|
with a lot of data, and will take a while to load and draw (about 10 sec
|
||||||
|
on my 450Mhz PIII). Redraws take about 2 sec. This demonstrates how the
|
||||||
|
performance is not very good for large drawings.
|
||||||
|
|
||||||
|
*Clear: Clears the Canvas.
|
||||||
|
|
||||||
|
Once you have a picture drawn, you can zoom in and out and move about
|
||||||
|
the picture. There is a tool bar with three tools that can be
|
||||||
|
selected.
|
||||||
|
|
||||||
|
The magnifying glass with the plus is the zoom in tool. Once selected,
|
||||||
|
if you click the image, it will zoom in, centered on where you
|
||||||
|
clicked. If you click and drag the mouse, you will get a rubber band
|
||||||
|
box, and the image will zoom to fit that box when you release it.
|
||||||
|
|
||||||
|
The magnifying glass with the minus is the zoom out tool. Once selected,
|
||||||
|
if you click the image, it will zoom out, centered on where you
|
||||||
|
clicked. (note that this takes a while when you are looking at the map,
|
||||||
|
as it has a LOT of lines to be drawn. The image is double buffered, so
|
||||||
|
you don't see the drawing in progress)
|
||||||
|
|
||||||
|
The hand is the move tool. Once selected, if you click and drag on the
|
||||||
|
image, it will move so that the part you clicked on ends up where you
|
||||||
|
release the mouse. Nothing is changed while you are dragging. The
|
||||||
|
drawing is too slow for that.
|
||||||
|
|
||||||
|
I'd like the cursor to change as you change tools, but the stock
|
||||||
|
wx.Cursors didn't include anything I liked, so I stuck with the
|
||||||
|
pointer. Pleae let me know if you have any nice cursor images for me to
|
||||||
|
use.
|
||||||
|
|
||||||
|
|
||||||
|
Any bugs, comments, feedback, questions, and especially code are welcome:
|
||||||
|
|
||||||
|
-Chris Barker
|
||||||
|
|
||||||
|
ChrisHBarker@home.net
|
||||||
|
http://members.home.net/barkerlohmann
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def OnInit(self):
|
||||||
|
wx.InitAllImageHandlers()
|
||||||
|
frame = DrawFrame(None, -1, "Simple Drawing Window",wx.DefaultPosition, (700,700) )
|
||||||
|
|
||||||
|
self.SetTopWindow(frame)
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
def Read_MapGen(filename,stats = False):
|
||||||
|
"""
|
||||||
|
This function reads a MapGen Format file, and
|
||||||
|
returns a list of NumPy arrays with the line segments in them.
|
||||||
|
|
||||||
|
Each NumPy array in the list is an NX2 array of Python Floats.
|
||||||
|
|
||||||
|
The demo should have come with a file, "world.dat" that is the
|
||||||
|
shorelines of the whole worls, in MapGen format.
|
||||||
|
|
||||||
|
"""
|
||||||
|
import string
|
||||||
|
from numpy import array
|
||||||
|
file = open(filename,'rt')
|
||||||
|
data = file.readlines()
|
||||||
|
data = map(string.strip,data)
|
||||||
|
|
||||||
|
Shorelines = []
|
||||||
|
segment = []
|
||||||
|
for line in data:
|
||||||
|
if line == "# -b": #New segment begining
|
||||||
|
if segment: Shorelines.append(array(segment))
|
||||||
|
segment = []
|
||||||
|
else:
|
||||||
|
segment.append(map(float,string.split(line)))
|
||||||
|
if segment: Shorelines.append(array(segment))
|
||||||
|
|
||||||
|
if stats:
|
||||||
|
NumSegments = len(Shorelines)
|
||||||
|
NumPoints = False
|
||||||
|
for segment in Shorelines:
|
||||||
|
NumPoints = NumPoints + len(segment)
|
||||||
|
AvgPoints = NumPoints / NumSegments
|
||||||
|
print "Number of Segments: ", NumSegments
|
||||||
|
print "Average Number of Points per segment: ",AvgPoints
|
||||||
|
|
||||||
|
return Shorelines
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
|
||||||
|
app = DemoApp(0)
|
||||||
|
app.MainLoop()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
133
samples/floatcanvas/BB_HitTest.py
Executable file
133
samples/floatcanvas/BB_HitTest.py
Executable file
@@ -0,0 +1,133 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
"""
|
||||||
|
Test of an alternaive hit test methoid that used the bounding boxes of teh objects instead.
|
||||||
|
|
||||||
|
Poorly tested!
|
||||||
|
|
||||||
|
Edited from code contributed by Benjamin Jessup on the mailing list
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
import wx
|
||||||
|
|
||||||
|
## import the installed version
|
||||||
|
from wx.lib.floatcanvas import NavCanvas, FloatCanvas
|
||||||
|
|
||||||
|
## import a local version
|
||||||
|
#import sys
|
||||||
|
#sys.path.append("../")
|
||||||
|
#from floatcanvas import NavCanvas, FloatCanvas
|
||||||
|
FC = FloatCanvas
|
||||||
|
|
||||||
|
def BB_HitTest(self, event, HitEvent):
|
||||||
|
""" Hit Test Function for BoundingBox Based HitMap System"""
|
||||||
|
if self.HitDict and self.HitDict[HitEvent]:
|
||||||
|
# loop though the objects associated with this event
|
||||||
|
objects = [] #Create object list for holding multiple objects
|
||||||
|
object_index_list = [] #Create list for holding the indexes
|
||||||
|
xy_p = event.GetPosition()
|
||||||
|
xy = self.PixelToWorld( xy_p ) #Convert to the correct coords
|
||||||
|
for key2 in self.HitDict[HitEvent].keys():
|
||||||
|
#Get Mouse Event Position
|
||||||
|
bb = self.HitDict[HitEvent][key2].BoundingBox
|
||||||
|
if bb.PointInside(xy):
|
||||||
|
Object = self.HitDict[HitEvent][key2]
|
||||||
|
objects.append(Object)
|
||||||
|
try:
|
||||||
|
#First try the foreground index and add the length of the background index
|
||||||
|
#to account for the two 'layers' that already exist in the code
|
||||||
|
index = self._ForeDrawList.index(Object) + len(self._DrawList)
|
||||||
|
except ValueError:
|
||||||
|
index = self._DrawList.index(Object) #Now check background if not found in foreground
|
||||||
|
object_index_list.append(index) #append the index found
|
||||||
|
else:
|
||||||
|
Object = self.HitDict[HitEvent][key2]
|
||||||
|
if len(objects) > 0: #If no objects then do nothing
|
||||||
|
#Get the highest index object
|
||||||
|
highest_object = objects[object_index_list.index(max(object_index_list))]
|
||||||
|
highest_object.HitCoords = xy
|
||||||
|
highest_object.HitCoordsPixel = xy_p
|
||||||
|
highest_object.CallBackFuncs[HitEvent](highest_object)
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
return False
|
||||||
|
|
||||||
|
FC.FloatCanvas.HitTest = BB_HitTest
|
||||||
|
|
||||||
|
class DrawFrame(wx.Frame):
|
||||||
|
|
||||||
|
"""
|
||||||
|
A frame used for the FloatCanvas Demo
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
wx.Frame.__init__(self, *args, **kwargs)
|
||||||
|
|
||||||
|
self.CreateStatusBar()
|
||||||
|
|
||||||
|
# Add the Canvas
|
||||||
|
Canvas = NavCanvas.NavCanvas(self,-1,
|
||||||
|
size = (500,500),
|
||||||
|
ProjectionFun = None,
|
||||||
|
Debug = 0,
|
||||||
|
BackgroundColor = "DARK SLATE BLUE",
|
||||||
|
).Canvas
|
||||||
|
|
||||||
|
self.Canvas = Canvas
|
||||||
|
|
||||||
|
FloatCanvas.EVT_MOTION(self.Canvas, self.OnMove )
|
||||||
|
|
||||||
|
Point = (45,40)
|
||||||
|
Text = Canvas.AddScaledText("A String",
|
||||||
|
Point,
|
||||||
|
20,
|
||||||
|
Color = "Black",
|
||||||
|
BackgroundColor = None,
|
||||||
|
Family = wx.ROMAN,
|
||||||
|
Style = wx.NORMAL,
|
||||||
|
Weight = wx.NORMAL,
|
||||||
|
Underlined = False,
|
||||||
|
Position = 'bl',
|
||||||
|
InForeground = False)
|
||||||
|
Text.MinFontSize = 4 # the default is 1
|
||||||
|
Text.DisappearWhenSmall = False #the default is True
|
||||||
|
|
||||||
|
Rect1 = Canvas.AddRectangle((50, 20), (40,15), FillColor="Red", LineStyle = None)
|
||||||
|
Rect1.Bind(FC.EVT_FC_LEFT_DOWN, self.OnLeft)
|
||||||
|
Rect1.Name = "red"
|
||||||
|
|
||||||
|
Rect2 = Canvas.AddRectangle((70, 30), (40,15), FillColor="Blue", LineStyle = None)
|
||||||
|
Rect2.Bind(FC.EVT_FC_LEFT_DOWN, self.OnLeft)
|
||||||
|
Rect2.Name = 'blue'
|
||||||
|
|
||||||
|
self.Show()
|
||||||
|
Canvas.ZoomToBB()
|
||||||
|
|
||||||
|
def OnLeft(self, object):
|
||||||
|
print "Rect %s got hit"%object.Name
|
||||||
|
|
||||||
|
def OnMove(self, event):
|
||||||
|
"""
|
||||||
|
Updates the status bar with the world coordinates
|
||||||
|
|
||||||
|
"""
|
||||||
|
self.SetStatusText("%.2f, %.2f"%tuple(event.Coords))
|
||||||
|
|
||||||
|
app = wx.App(False)
|
||||||
|
F = DrawFrame(None, title="FloatCanvas Demo App", size=(700,700) )
|
||||||
|
app.MainLoop()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
353
samples/floatcanvas/BNAEditor.py
Executable file
353
samples/floatcanvas/BNAEditor.py
Executable file
@@ -0,0 +1,353 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
BNA-Editor: a simple app for editing polygons in BNA files
|
||||||
|
|
||||||
|
BNA is a simple text format for storing polygons in lat-long coordinates.
|
||||||
|
|
||||||
|
"""
|
||||||
|
import os, sys
|
||||||
|
import sets
|
||||||
|
|
||||||
|
import numpy as N
|
||||||
|
|
||||||
|
#### import local version:
|
||||||
|
#sys.path.append("..")
|
||||||
|
#from floatcanvas import NavCanvas, FloatCanvas
|
||||||
|
|
||||||
|
## import the installed version
|
||||||
|
from wx.lib.floatcanvas import NavCanvas, FloatCanvas
|
||||||
|
|
||||||
|
import wx
|
||||||
|
import sys
|
||||||
|
|
||||||
|
if len(sys.argv) > 1:
|
||||||
|
StartFileName = sys.argv[1]
|
||||||
|
else:
|
||||||
|
StartFileName = None
|
||||||
|
|
||||||
|
### These utilities are required to load and save BNA data.
|
||||||
|
class BNAData:
|
||||||
|
"""
|
||||||
|
Class to store the full set of data in a BNA file
|
||||||
|
|
||||||
|
"""
|
||||||
|
def __init__(self, Filename = None):
|
||||||
|
self.Filename = Filename
|
||||||
|
self.PointsData = None
|
||||||
|
self.Filename = None
|
||||||
|
self.Names = None
|
||||||
|
self.Types = None
|
||||||
|
if Filename is not None:
|
||||||
|
self.Load(Filename)
|
||||||
|
|
||||||
|
def __getitem__(self,index):
|
||||||
|
return (self.PointsData[index], self.Names[index])
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
return len(self.PointsData)
|
||||||
|
|
||||||
|
def Save(self, filename = None):
|
||||||
|
if not filename:
|
||||||
|
filename = self.filename
|
||||||
|
file = open(filename, 'w')
|
||||||
|
for i, points in enumerate(self.PointsData):
|
||||||
|
file.write('"%s","%s", %i\n'%(self.Names[i],self.Types[i],len(points) ) )
|
||||||
|
for p in points:
|
||||||
|
file.write("%.12f,%.12f\n"%(tuple(p)))
|
||||||
|
|
||||||
|
def Load(self, filename):
|
||||||
|
#print "Loading:", filename
|
||||||
|
file = open(filename,'rU')
|
||||||
|
|
||||||
|
self.Filename = filename
|
||||||
|
self.PointsData = []
|
||||||
|
self.Names = []
|
||||||
|
self.Types = []
|
||||||
|
while 1:
|
||||||
|
line = file.readline()
|
||||||
|
if not line:
|
||||||
|
break
|
||||||
|
line = line.strip()
|
||||||
|
Name, line = line.split('","')
|
||||||
|
Name = Name[1:]
|
||||||
|
Type,line = line.split('",')
|
||||||
|
num_points = int(line)
|
||||||
|
self.Types.append(Type)
|
||||||
|
self.Names.append(Name)
|
||||||
|
polygon = N.zeros((num_points,2),N.float)
|
||||||
|
for i in range(num_points):
|
||||||
|
polygon[i,:] = map(float, file.readline().split(','))
|
||||||
|
self.PointsData.append(polygon)
|
||||||
|
|
||||||
|
file.close()
|
||||||
|
return None
|
||||||
|
|
||||||
|
class DrawFrame(wx.Frame):
|
||||||
|
"""
|
||||||
|
A frame used for the BNA Editor
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self,parent, id,title,position,size):
|
||||||
|
wx.Frame.__init__(self,parent, id,title,position, size)
|
||||||
|
|
||||||
|
## Set up the MenuBar
|
||||||
|
MenuBar = wx.MenuBar()
|
||||||
|
|
||||||
|
FileMenu = wx.Menu()
|
||||||
|
|
||||||
|
OpenMenu = FileMenu.Append(wx.ID_ANY, "&Open","Open BNA")
|
||||||
|
self.Bind(wx.EVT_MENU, self.OpenBNA, OpenMenu)
|
||||||
|
|
||||||
|
SaveMenu = FileMenu.Append(wx.ID_ANY, "&Save","Save BNA")
|
||||||
|
self.Bind(wx.EVT_MENU, self.SaveBNA, SaveMenu)
|
||||||
|
|
||||||
|
CloseMenu = FileMenu.Append(wx.ID_ANY, "&Close","Close Application")
|
||||||
|
self.Bind(wx.EVT_MENU, self.OnQuit, CloseMenu)
|
||||||
|
|
||||||
|
MenuBar.Append(FileMenu, "&File")
|
||||||
|
|
||||||
|
view_menu = wx.Menu()
|
||||||
|
ZoomMenu = view_menu.Append(wx.ID_ANY, "Zoom to &Fit","Zoom to fit the window")
|
||||||
|
self.Bind(wx.EVT_MENU, self.ZoomToFit, ZoomMenu)
|
||||||
|
MenuBar.Append(view_menu, "&View")
|
||||||
|
|
||||||
|
help_menu = wx.Menu()
|
||||||
|
AboutMenu = help_menu.Append(wx.ID_ANY, "&About",
|
||||||
|
"More information About this program")
|
||||||
|
self.Bind(wx.EVT_MENU, self.OnAbout, AboutMenu)
|
||||||
|
MenuBar.Append(help_menu, "&Help")
|
||||||
|
|
||||||
|
self.SetMenuBar(MenuBar)
|
||||||
|
|
||||||
|
self.CreateStatusBar()
|
||||||
|
# Add the Canvas
|
||||||
|
self.Canvas = NavCanvas.NavCanvas(self,-1,(500,500),
|
||||||
|
Debug = 0,
|
||||||
|
BackgroundColor = "DARK SLATE BLUE"
|
||||||
|
).Canvas
|
||||||
|
|
||||||
|
wx.EVT_CLOSE(self, self.OnCloseWindow)
|
||||||
|
|
||||||
|
FloatCanvas.EVT_MOTION(self.Canvas, self.OnMove )
|
||||||
|
FloatCanvas.EVT_LEFT_UP(self.Canvas, self.OnLeftUp )
|
||||||
|
FloatCanvas.EVT_LEFT_DOWN(self.Canvas, self.OnLeftDown)
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.FileDialog = wx.FileDialog(self, "Pick a BNA file",".","","*", wx.OPEN)
|
||||||
|
except wx._core.PyAssertionError:
|
||||||
|
self.FileDialog = None
|
||||||
|
|
||||||
|
self.ResetSelections()
|
||||||
|
return None
|
||||||
|
|
||||||
|
def ResetSelections(self):
|
||||||
|
self.SelectedPoly = None
|
||||||
|
self.SelectedPolyOrig = None
|
||||||
|
self.SelectedPoints = None
|
||||||
|
self.PointSelected = False
|
||||||
|
self.SelectedPointNeighbors = None
|
||||||
|
|
||||||
|
def OnLeftDown(self,event):
|
||||||
|
if self.SelectedPoly:
|
||||||
|
self.DeSelectPoly()
|
||||||
|
self.Canvas.Draw()
|
||||||
|
|
||||||
|
def OnAbout(self, event):
|
||||||
|
dlg = wx.MessageDialog(self, "This is a small program to demonstrate\n"
|
||||||
|
"the use of the FloatCanvas\n",
|
||||||
|
"About Me", wx.OK | wx.ICON_INFORMATION)
|
||||||
|
dlg.ShowModal()
|
||||||
|
dlg.Destroy()
|
||||||
|
|
||||||
|
def ZoomToFit(self,event):
|
||||||
|
self.Canvas.ZoomToBB()
|
||||||
|
|
||||||
|
def OpenBNA(self, event):
|
||||||
|
if self.FileDialog is None:
|
||||||
|
self.FileDialog = wx.FileDialog(self, "Pick a BNA file",style= wx.OPEN)
|
||||||
|
dlg = self.FileDialog
|
||||||
|
dlg.SetMessage("Pick a BNA file")
|
||||||
|
if dlg.ShowModal() == wx.ID_OK:
|
||||||
|
filename = dlg.GetPath()
|
||||||
|
self.LoadBNA(filename)
|
||||||
|
|
||||||
|
def SaveBNA(self, event):
|
||||||
|
for i in self.ChangedPolys:
|
||||||
|
self.BNAFile.PointsData[i] = self.AllPolys[i].Points
|
||||||
|
dlg = wx.FileDialog(self,
|
||||||
|
message="Pick a BNA file",
|
||||||
|
style=wx.SAVE)
|
||||||
|
if dlg.ShowModal() == wx.ID_OK:
|
||||||
|
filename = dlg.GetPath()
|
||||||
|
self.BNAFile.Save(filename)
|
||||||
|
|
||||||
|
def Clear(self,event = None):
|
||||||
|
self.Canvas.ClearAll()
|
||||||
|
self.Canvas.Draw(True)
|
||||||
|
|
||||||
|
def OnQuit(self,event):
|
||||||
|
self.Close(True)
|
||||||
|
|
||||||
|
def OnCloseWindow(self, event):
|
||||||
|
self.Destroy()
|
||||||
|
|
||||||
|
def OnMove(self, event):
|
||||||
|
"""
|
||||||
|
Updates the status bar with the world coordinates
|
||||||
|
And moves a point if there is one
|
||||||
|
|
||||||
|
"""
|
||||||
|
self.SetStatusText("%.4f, %.4f"%tuple(event.Coords))
|
||||||
|
|
||||||
|
if self.PointSelected:
|
||||||
|
PolyPoints = self.SelectedPoly.Points
|
||||||
|
Index = self.SelectedPoints.Index
|
||||||
|
dc = wx.ClientDC(self.Canvas)
|
||||||
|
PixelCoords = event.GetPosition()
|
||||||
|
dc.SetPen(wx.Pen('WHITE', 2, wx.SHORT_DASH))
|
||||||
|
dc.SetLogicalFunction(wx.XOR)
|
||||||
|
if self.SelectedPointNeighbors is None:
|
||||||
|
self.SelectedPointNeighbors = N.zeros((3,2), N.float)
|
||||||
|
#fixme: This feels very inelegant!
|
||||||
|
if Index == 0:
|
||||||
|
self.SelectedPointNeighbors[0] = self.SelectedPoly.Points[-1]
|
||||||
|
self.SelectedPointNeighbors[1:3] = self.SelectedPoly.Points[:2]
|
||||||
|
elif Index == len(self.SelectedPoly.Points)-1:
|
||||||
|
self.SelectedPointNeighbors[0:2] = self.SelectedPoly.Points[-2:]
|
||||||
|
self.SelectedPointNeighbors[2] = self.SelectedPoly.Points[0]
|
||||||
|
else:
|
||||||
|
self.SelectedPointNeighbors = self.SelectedPoly.Points[Index-1:Index+2]
|
||||||
|
self.SelectedPointNeighbors = self.Canvas.WorldToPixel(self.SelectedPointNeighbors)
|
||||||
|
else:
|
||||||
|
dc.DrawLines(self.SelectedPointNeighbors)
|
||||||
|
self.SelectedPointNeighbors[1] = PixelCoords
|
||||||
|
dc.DrawLines(self.SelectedPointNeighbors)
|
||||||
|
|
||||||
|
def OnLeftUp(self, event):
|
||||||
|
if self.PointSelected:
|
||||||
|
self.SelectedPoly.Points[self.SelectedPoints.Index] = event.GetCoords()
|
||||||
|
self.SelectedPoly.SetPoints(self.SelectedPoly.Points, copy = False)
|
||||||
|
self.SelectedPoints.SetPoints(self.SelectedPoly.Points, copy = False)
|
||||||
|
self.PointSelected = False
|
||||||
|
self.SelectedPointNeighbors = None
|
||||||
|
self.SelectedPoly.HasChanged = True
|
||||||
|
self.Canvas.Draw()
|
||||||
|
|
||||||
|
def DeSelectPoly(self):
|
||||||
|
Canvas = self.Canvas
|
||||||
|
if self.SelectedPoly.HasChanged:
|
||||||
|
self.ChangedPolys.add(self.SelectedPolyOrig.BNAIndex)
|
||||||
|
self.SelectedPolyOrig.SetPoints(self.SelectedPoly.Points, copy = False)
|
||||||
|
self.Canvas.Draw(Force = True)
|
||||||
|
Canvas.RemoveObject(self.SelectedPoly)
|
||||||
|
Canvas.RemoveObject(self.SelectedPoints)
|
||||||
|
self.ResetSelections()
|
||||||
|
|
||||||
|
def SelectPoly(self, Object):
|
||||||
|
Canvas = self.Canvas
|
||||||
|
if Object is self.SelectedPolyOrig:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
if self.SelectedPoly is not None:
|
||||||
|
self.DeSelectPoly()
|
||||||
|
self.SelectedPolyOrig = Object
|
||||||
|
self.SelectedPoly = Canvas.AddPolygon(Object.Points,
|
||||||
|
LineWidth = 1,
|
||||||
|
LineColor = "Red",
|
||||||
|
FillColor = None,
|
||||||
|
InForeground = True)
|
||||||
|
self.SelectedPoly.HasChanged = False
|
||||||
|
# Draw points on the Vertices of the Selected Poly:
|
||||||
|
self.SelectedPoints = Canvas.AddPointSet(Object.Points,
|
||||||
|
Diameter = 4,
|
||||||
|
Color = "Red",
|
||||||
|
InForeground = True)
|
||||||
|
self.SelectedPoints.HitLineWidth = 8 # make it a bit easier to hit
|
||||||
|
self.SelectedPoints.Bind(FloatCanvas.EVT_FC_LEFT_DOWN, self.SelectPointHit)
|
||||||
|
Canvas.Draw()
|
||||||
|
|
||||||
|
def SelectPointHit(self, PointSet):
|
||||||
|
PointSet.Index = PointSet.FindClosestPoint(PointSet.HitCoords)
|
||||||
|
self.PointSelected = True
|
||||||
|
|
||||||
|
def LoadBNA(self, filename):
|
||||||
|
self.ResetSelections()
|
||||||
|
self.Canvas.ClearAll()
|
||||||
|
self.Canvas.SetProjectionFun('FlatEarth')
|
||||||
|
try:
|
||||||
|
AllPolys = []
|
||||||
|
self.BNAFile = BNAData(filename)
|
||||||
|
print "loaded BNAFile:", self.BNAFile.Filename
|
||||||
|
for i, shoreline in enumerate(self.BNAFile.PointsData):
|
||||||
|
Poly = self.Canvas.AddPolygon(shoreline,
|
||||||
|
LineWidth = 1,
|
||||||
|
LineColor = "Black",
|
||||||
|
FillColor = "Brown",
|
||||||
|
FillStyle = 'Solid')
|
||||||
|
Poly.Bind(FloatCanvas.EVT_FC_LEFT_DOWN, self.SelectPoly)
|
||||||
|
Poly.BNAIndex = i
|
||||||
|
AllPolys.append(Poly)
|
||||||
|
self.Canvas.ZoomToBB()
|
||||||
|
self.ChangedPolys = sets.Set()
|
||||||
|
self.AllPolys = AllPolys
|
||||||
|
except:
|
||||||
|
#raise
|
||||||
|
dlg = wx.MessageDialog(None,
|
||||||
|
'There was something wrong with the selected bna file',
|
||||||
|
'File Loading Error',
|
||||||
|
wx.OK | wx.ICON_ERROR)
|
||||||
|
dlg.ShowModal()
|
||||||
|
dlg.Destroy()
|
||||||
|
|
||||||
|
|
||||||
|
class BNAEditor(wx.App):
|
||||||
|
"""
|
||||||
|
Once you have a picture drawn, you can zoom in and out and move about
|
||||||
|
the picture. There is a tool bar with three tools that can be
|
||||||
|
selected.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
wx.App.__init__(self, *args, **kwargs)
|
||||||
|
|
||||||
|
def OnInit(self):
|
||||||
|
frame = DrawFrame(None, -1, "BNA Editor",wx.DefaultPosition,(700,700))
|
||||||
|
|
||||||
|
self.SetTopWindow(frame)
|
||||||
|
frame.Show()
|
||||||
|
|
||||||
|
if StartFileName:
|
||||||
|
frame.LoadBNA(StartFileName)
|
||||||
|
else:
|
||||||
|
##frame.LoadBNA("Tests/Small.bna")
|
||||||
|
frame.LoadBNA("Tiny.bna")
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
app = BNAEditor(False)# put in True if you want output to go to it's own window.
|
||||||
|
app.MainLoop()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
149
samples/floatcanvas/BarPlot.py
Executable file
149
samples/floatcanvas/BarPlot.py
Executable file
@@ -0,0 +1,149 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import wx
|
||||||
|
## import the installed version
|
||||||
|
from wx.lib.floatcanvas import NavCanvas, FloatCanvas
|
||||||
|
|
||||||
|
## import a local version
|
||||||
|
#import sys
|
||||||
|
#sys.path.append("../")
|
||||||
|
#from floatcanvas import NavCanvas, FloatCanvas
|
||||||
|
|
||||||
|
import numpy as N
|
||||||
|
from numpy import random as random
|
||||||
|
|
||||||
|
NumChannels = 200
|
||||||
|
MaxValue = 2000
|
||||||
|
#MaxValue = 2**24
|
||||||
|
|
||||||
|
|
||||||
|
def YScaleFun(center):
|
||||||
|
"""
|
||||||
|
Function that returns a scaling vector to scale y data to same range as x data
|
||||||
|
|
||||||
|
This is used by FloatCanvas as a "projection function", so that you can have
|
||||||
|
a different scale for X and Y. With the default projection, X and Y are the same scale.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
# center gets ignored in this case
|
||||||
|
return N.array((1, float(NumChannels)/MaxValue), N.float)
|
||||||
|
|
||||||
|
def ScaleWorldToPixel(self, Lengths):
|
||||||
|
"""
|
||||||
|
This is a new version of a function that will get passed to the
|
||||||
|
drawing functions of the objects, to Change a length from world to
|
||||||
|
pixel coordinates.
|
||||||
|
|
||||||
|
This version uses the "ceil" function, so that fractional pixel get
|
||||||
|
rounded up, rather than down.
|
||||||
|
|
||||||
|
Lengths should be a NX2 array of (x,y) coordinates, or
|
||||||
|
a 2-tuple, or sequence of 2-tuples.
|
||||||
|
"""
|
||||||
|
return N.ceil(( (N.asarray(Lengths, N.float)*self.TransformVector) )).astype('i')
|
||||||
|
|
||||||
|
|
||||||
|
class DrawFrame(wx.Frame):
|
||||||
|
|
||||||
|
"""
|
||||||
|
A frame used for the FloatCanvas Demo
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
wx.Frame.__init__(self, *args, **kwargs)
|
||||||
|
|
||||||
|
self.CreateStatusBar()
|
||||||
|
|
||||||
|
# Add the Canvas
|
||||||
|
FloatCanvas.FloatCanvas.ScaleWorldToPixel = ScaleWorldToPixel
|
||||||
|
NC = NavCanvas.NavCanvas(self,-1,
|
||||||
|
size = (500,500),
|
||||||
|
BackgroundColor = "DARK SLATE BLUE",
|
||||||
|
ProjectionFun = YScaleFun,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.Canvas = Canvas = NC.Canvas
|
||||||
|
#self.Canvas.ScaleWorldToPixel = ScaleWorldToPixel
|
||||||
|
|
||||||
|
FloatCanvas.EVT_MOTION(self.Canvas, self.OnMove )
|
||||||
|
|
||||||
|
self.Values = random.randint(0, MaxValue, (NumChannels,))
|
||||||
|
|
||||||
|
self.Bars = []
|
||||||
|
self.BarWidth = 0.75
|
||||||
|
# add an X axis
|
||||||
|
Canvas.AddLine(((0,0), (NumChannels, 0 )),)
|
||||||
|
for x in N.linspace(1, NumChannels, 11):
|
||||||
|
Canvas.AddText("%i"%x, (x-1+self.BarWidth/2,0), Position="tc")
|
||||||
|
|
||||||
|
for i, Value in enumerate(self.Values):
|
||||||
|
bar = Canvas.AddRectangle(XY=(i, 0),
|
||||||
|
WH=(self.BarWidth, Value),
|
||||||
|
LineColor = None,
|
||||||
|
LineStyle = "Solid",
|
||||||
|
LineWidth = 1,
|
||||||
|
FillColor = "Red",
|
||||||
|
FillStyle = "Solid",
|
||||||
|
)
|
||||||
|
self.Bars.append(bar)
|
||||||
|
|
||||||
|
# Add a couple a button the Toolbar
|
||||||
|
|
||||||
|
tb = NC.ToolBar
|
||||||
|
tb.AddSeparator()
|
||||||
|
|
||||||
|
ResetButton = wx.Button(tb, label="Reset")
|
||||||
|
tb.AddControl(ResetButton)
|
||||||
|
ResetButton.Bind(wx.EVT_BUTTON, self.ResetData)
|
||||||
|
|
||||||
|
# PlayButton = wx.Button(tb, wx.ID_ANY, "Run")
|
||||||
|
# tb.AddControl(PlayButton)
|
||||||
|
# PlayButton.Bind(wx.EVT_BUTTON, self.RunTest)
|
||||||
|
tb.Realize()
|
||||||
|
|
||||||
|
self.Show()
|
||||||
|
Canvas.ZoomToBB()
|
||||||
|
Canvas.Draw(True)
|
||||||
|
|
||||||
|
|
||||||
|
def OnMove(self, event):
|
||||||
|
"""
|
||||||
|
Updates the status bar with the world coordinates
|
||||||
|
|
||||||
|
"""
|
||||||
|
channel, value = event.Coords
|
||||||
|
if 0 < channel < NumChannels :
|
||||||
|
channel = "%i,"%(channel+1)
|
||||||
|
else:
|
||||||
|
channel = ""
|
||||||
|
|
||||||
|
if value >=0:
|
||||||
|
value = "%3g"%value
|
||||||
|
else:
|
||||||
|
value = ""
|
||||||
|
self.SetStatusText("Channel: %s Value: %s"%(channel, value))
|
||||||
|
|
||||||
|
def ResetData(self, event):
|
||||||
|
self.Values = random.randint(0, MaxValue, (NumChannels,))
|
||||||
|
for i, bar in enumerate(self.Bars):
|
||||||
|
bar.SetShape(bar.XY, (self.BarWidth, self.Values[i]))
|
||||||
|
self.Canvas.Draw(Force=True)
|
||||||
|
|
||||||
|
app = wx.App(False)
|
||||||
|
F = DrawFrame(None, title="FloatCanvas Demo App", size=(700,700) )
|
||||||
|
app.MainLoop()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
212
samples/floatcanvas/BouncingBall.py
Executable file
212
samples/floatcanvas/BouncingBall.py
Executable file
@@ -0,0 +1,212 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
A test of some simple animation
|
||||||
|
|
||||||
|
this is very old-style code: don't imitate it!
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
import wx
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
## import local version:
|
||||||
|
import sys
|
||||||
|
|
||||||
|
#ver = 'local'
|
||||||
|
ver = 'installed'
|
||||||
|
|
||||||
|
if ver == 'installed': ## import the installed version
|
||||||
|
from wx.lib.floatcanvas import NavCanvas
|
||||||
|
from wx.lib.floatcanvas import FloatCanvas
|
||||||
|
print "using installed version:", wx.lib.floatcanvas.__version__
|
||||||
|
elif ver == 'local':
|
||||||
|
## import a local version
|
||||||
|
import sys
|
||||||
|
sys.path.append("..")
|
||||||
|
from floatcanvas import NavCanvas
|
||||||
|
from floatcanvas import FloatCanvas
|
||||||
|
|
||||||
|
FC = FloatCanvas
|
||||||
|
|
||||||
|
class MovingObjectMixin: # Borrowed from MovingElements.py
|
||||||
|
"""
|
||||||
|
Methods required for a Moving object
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def GetOutlinePoints(self):
|
||||||
|
BB = self.BoundingBox
|
||||||
|
OutlinePoints = np.array( ( (BB[0,0], BB[0,1]),
|
||||||
|
(BB[0,0], BB[1,1]),
|
||||||
|
(BB[1,0], BB[1,1]),
|
||||||
|
(BB[1,0], BB[0,1]),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
return OutlinePoints
|
||||||
|
|
||||||
|
|
||||||
|
class Ball(MovingObjectMixin, FloatCanvas.Circle):
|
||||||
|
def __init__(self, XY, Velocity, Radius=2.0, **kwargs):
|
||||||
|
self.Velocity = np.asarray(Velocity, np.float).reshape((2,))
|
||||||
|
self.Radius = Radius
|
||||||
|
self.Moving = False
|
||||||
|
FloatCanvas.Circle.__init__(self, XY, Diameter=Radius*2, FillColor="red", **kwargs)
|
||||||
|
|
||||||
|
class DrawFrame(wx.Frame):
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
wx.Frame.__init__(self, *args, **kwargs)
|
||||||
|
|
||||||
|
## Set up the MenuBar
|
||||||
|
|
||||||
|
MenuBar = wx.MenuBar()
|
||||||
|
|
||||||
|
file_menu = wx.Menu()
|
||||||
|
item = file_menu.Append(wx.ID_ANY, "E&xit","Terminate the program")
|
||||||
|
self.Bind(wx.EVT_MENU, self.OnQuit, item)
|
||||||
|
MenuBar.Append(file_menu, "&File")
|
||||||
|
|
||||||
|
|
||||||
|
self.SetMenuBar(MenuBar)
|
||||||
|
|
||||||
|
self.CreateStatusBar()
|
||||||
|
self.SetStatusText("")
|
||||||
|
|
||||||
|
wx.EVT_CLOSE(self, self.OnCloseWindow)
|
||||||
|
|
||||||
|
# Add the buttons
|
||||||
|
ResetButton = wx.Button(self, label="Reset")
|
||||||
|
ResetButton.Bind(wx.EVT_BUTTON, self.OnReset)
|
||||||
|
|
||||||
|
StartButton = wx.Button(self, label="Start")
|
||||||
|
StartButton.Bind(wx.EVT_BUTTON, self.OnStart)
|
||||||
|
|
||||||
|
StopButton = wx.Button(self, label="Stop")
|
||||||
|
StopButton.Bind(wx.EVT_BUTTON, self.OnStop)
|
||||||
|
|
||||||
|
butSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
|
butSizer.Add(StartButton, 0, wx.RIGHT, 5 )
|
||||||
|
butSizer.Add(ResetButton, 0, wx.RIGHT, 5)
|
||||||
|
butSizer.Add(StopButton, 0, )
|
||||||
|
# Add the Canvas
|
||||||
|
NC = NavCanvas.NavCanvas(self, -1, (500,500),
|
||||||
|
Debug = False,
|
||||||
|
BackgroundColor = "BLUE")
|
||||||
|
|
||||||
|
self.Canvas = NC.Canvas
|
||||||
|
self.Initialize(None)
|
||||||
|
|
||||||
|
# lay it out:
|
||||||
|
S = wx.BoxSizer(wx.VERTICAL)
|
||||||
|
S.Add(butSizer, 0, wx.ALIGN_CENTER | wx.ALL, 5)
|
||||||
|
S.Add(NC, 1, wx.EXPAND)
|
||||||
|
self.SetSizer(S)
|
||||||
|
|
||||||
|
self.timer = wx.Timer(self)
|
||||||
|
self.Bind(wx.EVT_TIMER, self.MoveBall, self.timer)
|
||||||
|
|
||||||
|
self.Show(True)
|
||||||
|
|
||||||
|
def OnQuit(self,event):
|
||||||
|
self.Close(True)
|
||||||
|
|
||||||
|
def OnCloseWindow(self, event):
|
||||||
|
self.Destroy()
|
||||||
|
|
||||||
|
def Initialize(self, event=None):
|
||||||
|
Canvas = self.Canvas
|
||||||
|
|
||||||
|
#Add the floor
|
||||||
|
Canvas.AddLine(( (0, 0), (100, 0) ), LineWidth=4, LineColor="Black")
|
||||||
|
# add the wall:
|
||||||
|
Canvas.AddRectangle( (0,0), (10,50), FillColor='green')
|
||||||
|
|
||||||
|
# add the ball:
|
||||||
|
self.Ball = Ball( (5, 52), (2, 0), InForeground=True )
|
||||||
|
Canvas.AddObject( self.Ball )
|
||||||
|
# to capture the mouse to move the ball
|
||||||
|
self.Ball.Bind(FC.EVT_FC_LEFT_DOWN, self.BallHit)
|
||||||
|
Canvas.Bind(FC.EVT_MOTION, self.OnMove )
|
||||||
|
Canvas.Bind(FC.EVT_LEFT_UP, self.OnLeftUp )
|
||||||
|
|
||||||
|
wx.CallAfter(Canvas.ZoomToBB)
|
||||||
|
|
||||||
|
def BallHit(self, object):
|
||||||
|
print "the ball was clicked"
|
||||||
|
self.Ball.Moving = True
|
||||||
|
|
||||||
|
def OnMove(self, event):
|
||||||
|
"""
|
||||||
|
Updates the status bar with the world coordinates
|
||||||
|
and moves the object it is clicked on
|
||||||
|
|
||||||
|
"""
|
||||||
|
self.SetStatusText("%.4f, %.4f"%tuple(event.Coords))
|
||||||
|
if self.Ball.Moving:
|
||||||
|
self.Ball.SetPoint(event.Coords)
|
||||||
|
self.Canvas.Draw(True)
|
||||||
|
|
||||||
|
def OnLeftUp(self, event):
|
||||||
|
self.Ball.Moving = False
|
||||||
|
|
||||||
|
def OnReset(self, event=None):
|
||||||
|
self.Ball.SetPoint( (5, 52) )
|
||||||
|
self.Ball.Velocity = np.array((1.5, 0.0))
|
||||||
|
self.Canvas.Draw(True)
|
||||||
|
|
||||||
|
def OnStart(self, event=None):
|
||||||
|
self.timer.Start(20)
|
||||||
|
|
||||||
|
def OnStop(self, event=None):
|
||||||
|
self.timer.Stop()
|
||||||
|
|
||||||
|
def MoveBall(self, event=None):
|
||||||
|
ball = self.Ball
|
||||||
|
|
||||||
|
dt = .1
|
||||||
|
g = 9.806
|
||||||
|
m = 1
|
||||||
|
A = np.pi*(ball.Radius/100)**2 # radius in cm
|
||||||
|
Cd = 0.47
|
||||||
|
rho = 1.3
|
||||||
|
|
||||||
|
if not ball.Moving: # don't do this if the user is moving it
|
||||||
|
vel = ball.Velocity
|
||||||
|
pos = ball.XY
|
||||||
|
|
||||||
|
# apply drag
|
||||||
|
vel -= np.sign(vel) * ((0.5 * Cd * rho * A * vel**2) / m * dt)
|
||||||
|
# apply gravity
|
||||||
|
vel[1] -= g * dt
|
||||||
|
# move the ball
|
||||||
|
pos += dt * vel
|
||||||
|
# check if it's on the wall
|
||||||
|
if pos[1] <= 52. and pos[0] <= 10.:
|
||||||
|
#reverse velocity
|
||||||
|
vel[1] *= -1.0
|
||||||
|
pos[1] = 52.
|
||||||
|
# check if it's hit the floor
|
||||||
|
elif pos[1] <= ball.Radius:
|
||||||
|
#reverse velocity
|
||||||
|
vel[1] *= -1.0
|
||||||
|
pos[1] = ball.Radius
|
||||||
|
|
||||||
|
self.Ball.SetPoint( pos )
|
||||||
|
self.Canvas.Draw(True)
|
||||||
|
wx.GetApp().Yield(onlyIfNeeded=True)
|
||||||
|
|
||||||
|
class DemoApp(wx.App):
|
||||||
|
def OnInit(self):
|
||||||
|
frame = DrawFrame(None, -1, "Simple Drawing Window",wx.DefaultPosition, (700,700) )
|
||||||
|
|
||||||
|
self.SetTopWindow(frame)
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
|
||||||
|
app = DemoApp(0)
|
||||||
|
app.MainLoop()
|
||||||
|
|
||||||
|
|
||||||
126
samples/floatcanvas/Chart.py
Executable file
126
samples/floatcanvas/Chart.py
Executable file
@@ -0,0 +1,126 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import wx
|
||||||
|
|
||||||
|
## import the installed version
|
||||||
|
from wx.lib.floatcanvas import NavCanvas, FloatCanvas
|
||||||
|
|
||||||
|
## import a local version
|
||||||
|
#import sys
|
||||||
|
#sys.path.append("../")
|
||||||
|
#from floatcanvas import NavCanvas, FloatCanvas
|
||||||
|
|
||||||
|
|
||||||
|
class DrawFrame(wx.Frame):
|
||||||
|
|
||||||
|
"""
|
||||||
|
A frame used for the FloatCanvas Demo
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
wx.Frame.__init__(self, *args, **kwargs)
|
||||||
|
|
||||||
|
self.CreateStatusBar()
|
||||||
|
|
||||||
|
# Add the Canvas
|
||||||
|
Canvas = NavCanvas.NavCanvas(self,-1,
|
||||||
|
size = (500,500),
|
||||||
|
ProjectionFun = None,
|
||||||
|
Debug = 0,
|
||||||
|
BackgroundColor = "White",
|
||||||
|
).Canvas
|
||||||
|
# Canvas = FloatCanvas.FloatCanvas(self,-1,
|
||||||
|
# size = (500,500),
|
||||||
|
# ProjectionFun = None,
|
||||||
|
# Debug = 0,
|
||||||
|
# BackgroundColor = "White",
|
||||||
|
# )
|
||||||
|
|
||||||
|
self.Canvas = Canvas
|
||||||
|
|
||||||
|
FloatCanvas.EVT_MOTION(self.Canvas, self.OnMove )
|
||||||
|
FloatCanvas.EVT_LEFT_DOWN(self.Canvas, self.OnLeft)
|
||||||
|
|
||||||
|
|
||||||
|
# Some default sizes:
|
||||||
|
self.LineHeight = 1
|
||||||
|
self.TextWidth = 8
|
||||||
|
self.SpaceWidth = 1
|
||||||
|
self.Labels = ["SW Tasks", "Set RX Rf"] + ["A Row Label"]*16
|
||||||
|
self.NumRows = len(self.Labels)
|
||||||
|
|
||||||
|
self.BuildChartBackground()
|
||||||
|
self.AddLabels()
|
||||||
|
self.Show()
|
||||||
|
Canvas.MinScale=28
|
||||||
|
Canvas.MaxScale=28
|
||||||
|
Canvas.ZoomToBB()
|
||||||
|
|
||||||
|
def BuildChartBackground(self):
|
||||||
|
Canvas = self.Canvas
|
||||||
|
top = 0
|
||||||
|
bottom = -(self.LineHeight * self.NumRows)
|
||||||
|
width = self.SpaceWidth * 16 + self.TextWidth
|
||||||
|
# put in the rows:
|
||||||
|
for i in range(1, self.NumRows+1, 2):
|
||||||
|
Canvas.AddRectangle((0-self.TextWidth, -i*self.LineHeight),
|
||||||
|
(width, self.LineHeight),
|
||||||
|
LineColor = None,
|
||||||
|
FillColor = "LightGrey",
|
||||||
|
FillStyle = "Solid",)
|
||||||
|
|
||||||
|
# put a dashed line in every 1 unit:
|
||||||
|
for i in range(16):
|
||||||
|
Canvas.AddLine(((i*self.SpaceWidth,bottom),(i*self.SpaceWidth,top)),
|
||||||
|
LineColor = "Black",
|
||||||
|
LineStyle = "Dot",
|
||||||
|
# or "Dot", "ShortDash", "LongDash","ShortDash", "DotDash"
|
||||||
|
LineWidth = 1,)
|
||||||
|
def AddLabels(self):
|
||||||
|
Canvas = self.Canvas
|
||||||
|
|
||||||
|
for i, label in enumerate(self.Labels):
|
||||||
|
Canvas.AddScaledText(label,
|
||||||
|
( -self.TextWidth, -(i+0.2)*self.LineHeight ),
|
||||||
|
Size = 0.6 * self.LineHeight,
|
||||||
|
Color = "Black",
|
||||||
|
BackgroundColor = None,
|
||||||
|
Family = wx.MODERN,
|
||||||
|
Style = wx.NORMAL,
|
||||||
|
Weight = wx.NORMAL,
|
||||||
|
Underlined = False,
|
||||||
|
Position = 'tl',
|
||||||
|
)
|
||||||
|
|
||||||
|
def OnMove(self, event):
|
||||||
|
"""
|
||||||
|
Updates the status bar with the world coordinates
|
||||||
|
|
||||||
|
"""
|
||||||
|
self.SetStatusText("%.2f, %.2f"%tuple(event.Coords))
|
||||||
|
|
||||||
|
def OnLeft(self, event):
|
||||||
|
"""
|
||||||
|
Prints various info about the state of the canvas to stdout
|
||||||
|
|
||||||
|
"""
|
||||||
|
print "Scale is:", self.Canvas.Scale
|
||||||
|
|
||||||
|
|
||||||
|
app = wx.App(False)
|
||||||
|
F = DrawFrame(None, title="FloatCanvas Demo App", size=(700,700) )
|
||||||
|
app.MainLoop()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
119
samples/floatcanvas/ClickableBoxes.py
Executable file
119
samples/floatcanvas/ClickableBoxes.py
Executable file
@@ -0,0 +1,119 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
This is a little demo of how to make clickable (and changeable) objects with
|
||||||
|
FloatCanvas
|
||||||
|
|
||||||
|
Also an example of constant size, rather than the usual zooming and panning
|
||||||
|
|
||||||
|
Developed as an answer to a question on the wxPYhton mailing lilst:
|
||||||
|
"get panel id while dragging across several panels'
|
||||||
|
April 5, 2012
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
import random
|
||||||
|
import wx
|
||||||
|
|
||||||
|
## import the installed version
|
||||||
|
from wx.lib.floatcanvas import NavCanvas, FloatCanvas
|
||||||
|
|
||||||
|
## import a local version
|
||||||
|
#import sys
|
||||||
|
#sys.path.append("../")
|
||||||
|
#from floatcanvas import FloatCanvas as FC
|
||||||
|
|
||||||
|
|
||||||
|
colors = [ (255, 0 , 0 ),
|
||||||
|
(0 , 255, 0 ),
|
||||||
|
(0 , 0, 255),
|
||||||
|
(255, 255, 0 ),
|
||||||
|
(255, 0, 255),
|
||||||
|
(0 , 255, 255),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class DrawFrame(wx.Frame):
|
||||||
|
|
||||||
|
"""
|
||||||
|
A frame used for the Demo
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
wx.Frame.__init__(self, *args, **kwargs)
|
||||||
|
# Add the Canvas
|
||||||
|
Canvas = FC.FloatCanvas(self,
|
||||||
|
size = (500,500),
|
||||||
|
ProjectionFun = None,
|
||||||
|
Debug = 0,
|
||||||
|
BackgroundColor = "Black",
|
||||||
|
)
|
||||||
|
|
||||||
|
self.Canvas = Canvas
|
||||||
|
|
||||||
|
self.Canvas.Bind(wx.EVT_SIZE, self.OnSize)
|
||||||
|
|
||||||
|
# build the squares:
|
||||||
|
w = 10
|
||||||
|
dx = 14
|
||||||
|
for i in range(9):
|
||||||
|
for j in range(9):
|
||||||
|
Rect = Canvas.AddRectangle((i*dx, j*dx), (w, w), FillColor="White", LineStyle = None)
|
||||||
|
Outline = Canvas.AddRectangle((i*dx, j*dx), (w, w),
|
||||||
|
FillColor=None,
|
||||||
|
LineWidth=4,
|
||||||
|
LineColor='Red',
|
||||||
|
LineStyle=None)
|
||||||
|
Rect.indexes = (i,j)
|
||||||
|
Rect.outline = Outline
|
||||||
|
Rect.Bind(FC.EVT_FC_LEFT_DOWN, self.SquareHitLeft)
|
||||||
|
Rect.Bind(FC.EVT_FC_ENTER_OBJECT, self.SquareEnter)
|
||||||
|
Rect.Bind(FC.EVT_FC_LEAVE_OBJECT, self.SquareLeave)
|
||||||
|
|
||||||
|
self.Show()
|
||||||
|
Canvas.ZoomToBB()
|
||||||
|
|
||||||
|
def SquareHitLeft(self, square):
|
||||||
|
print "square hit:", square.indexes
|
||||||
|
# set a random color
|
||||||
|
c = random.sample(colors, 1)[0]
|
||||||
|
square.SetFillColor( c )
|
||||||
|
self.Canvas.Draw(True)
|
||||||
|
|
||||||
|
def SquareEnter(self, square):
|
||||||
|
print "entering square:", square.indexes
|
||||||
|
square.outline.SetLineStyle("Solid")
|
||||||
|
self.Canvas.Draw(True)
|
||||||
|
|
||||||
|
def SquareLeave(self, square):
|
||||||
|
print "leaving square:", square.indexes
|
||||||
|
square.outline.SetLineStyle(None)
|
||||||
|
self.Canvas.Draw(True)
|
||||||
|
|
||||||
|
|
||||||
|
def OnSize(self, event):
|
||||||
|
"""
|
||||||
|
re-zooms the canvas to fit the window
|
||||||
|
|
||||||
|
"""
|
||||||
|
print "in OnSize"
|
||||||
|
self.Canvas.ZoomToBB()
|
||||||
|
event.Skip()
|
||||||
|
|
||||||
|
app = wx.App(False)
|
||||||
|
F = DrawFrame(None, title="FloatCanvas Demo App", size=(700,700) )
|
||||||
|
app.MainLoop()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
72
samples/floatcanvas/DrawBot.py
Executable file
72
samples/floatcanvas/DrawBot.py
Executable file
@@ -0,0 +1,72 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
DrawBot.py
|
||||||
|
|
||||||
|
This a a demo of how one can use the FloatCanvas to do a drawing similar to one of the "DrawBot" demos:
|
||||||
|
|
||||||
|
|
||||||
|
http://just.letterror.com/ltrwiki/DrawBot
|
||||||
|
|
||||||
|
I think it's easier with FloatCavnas, and you get zoomign and scrolling to boot!
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
import wx
|
||||||
|
from math import *
|
||||||
|
|
||||||
|
try: # see if there is a local FloatCanvas to use
|
||||||
|
import sys
|
||||||
|
sys.path.append("../")
|
||||||
|
from floatcanvas import NavCanvas, FloatCanvas
|
||||||
|
print "Using local FloatCanvas"
|
||||||
|
except ImportError: # Use the wxPython lib one
|
||||||
|
from wx.lib.floatcanvas import NavCanvas, FloatCanvas
|
||||||
|
print "Using installed FloatCanvas"
|
||||||
|
|
||||||
|
|
||||||
|
class DrawFrame(wx.Frame):
|
||||||
|
|
||||||
|
"""
|
||||||
|
A frame used for the FloatCanvas Demo
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self,parent, id,title,position,size):
|
||||||
|
wx.Frame.__init__(self,parent, id,title,position, size)
|
||||||
|
|
||||||
|
# Add the Canvas
|
||||||
|
self.Canvas = NavCanvas.NavCanvas(self,-1,(500,500),
|
||||||
|
ProjectionFun = None,
|
||||||
|
Debug = 0,
|
||||||
|
BackgroundColor = "White",
|
||||||
|
).Canvas
|
||||||
|
|
||||||
|
|
||||||
|
self.Show(True)
|
||||||
|
self.MakePic()
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
def MakePic(self):
|
||||||
|
Canvas = self.Canvas
|
||||||
|
phi = (sqrt(5) + 1)/2 - 1
|
||||||
|
oradius = 10.0
|
||||||
|
for i in xrange(720):
|
||||||
|
radius = 1.5 * oradius * sin(i * pi/720)
|
||||||
|
Color = (255*(i / 720.), 255*( i / 720.), 255 * 0.25)
|
||||||
|
x = oradius + 0.25*i*cos(phi*i*2*pi)
|
||||||
|
y = oradius + 0.25*i*sin(phi*i*2*pi)
|
||||||
|
Canvas.AddCircle((x,y),
|
||||||
|
radius,
|
||||||
|
LineColor = "Black",
|
||||||
|
LineWidth = 2,
|
||||||
|
FillColor = Color,
|
||||||
|
)
|
||||||
|
self.Canvas.ZoomToBB()
|
||||||
|
|
||||||
|
app = wx.PySimpleApp()
|
||||||
|
DrawFrame(None, -1, "FloatCanvas Demo App", wx.DefaultPosition, (700,700) )
|
||||||
|
app.MainLoop()
|
||||||
|
|
||||||
117
samples/floatcanvas/DrawRect.py
Executable file
117
samples/floatcanvas/DrawRect.py
Executable file
@@ -0,0 +1,117 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
A simple demo that shows how to use FloatCanvas to draw rectangles on the screen
|
||||||
|
|
||||||
|
Note: this is now broken -- the events are not getting to the Rubber Band Box object.
|
||||||
|
It should be re-factored to use GUIMode
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
import wx
|
||||||
|
|
||||||
|
## import a local version
|
||||||
|
#import sys
|
||||||
|
#sys.path.append("..")
|
||||||
|
#from floatcanvas import NavCanvas, FloatCanvas, Resources, Utilities, GUIMode
|
||||||
|
#from floatcanvas.Utilities import GUI
|
||||||
|
|
||||||
|
## import the installed version
|
||||||
|
from wx.lib.floatcanvas import NavCanvas, FloatCanvas
|
||||||
|
from wx.lib.floatcanvas.Utilities import GUI
|
||||||
|
|
||||||
|
import numpy as N
|
||||||
|
|
||||||
|
class DrawFrame(wx.Frame):
|
||||||
|
|
||||||
|
"""
|
||||||
|
A frame used for the FloatCanvas Demo
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self,parent, id,title,position,size):
|
||||||
|
wx.Frame.__init__(self,parent, id,title,position, size)
|
||||||
|
|
||||||
|
self.CreateStatusBar()
|
||||||
|
# Add the Canvas
|
||||||
|
NC = NavCanvas.NavCanvas(self,
|
||||||
|
size= (500,500),
|
||||||
|
ProjectionFun = None,
|
||||||
|
Debug = 0,
|
||||||
|
BackgroundColor = "DARK SLATE BLUE",
|
||||||
|
)
|
||||||
|
|
||||||
|
self.Canvas = NC.Canvas
|
||||||
|
|
||||||
|
FloatCanvas.EVT_MOTION(self.Canvas, self.OnMove )
|
||||||
|
|
||||||
|
# Add some buttons to the Toolbar
|
||||||
|
tb = NC.ToolBar
|
||||||
|
tb.AddSeparator()
|
||||||
|
|
||||||
|
ClearButton = wx.Button(tb, wx.ID_ANY, "Clear")
|
||||||
|
tb.AddControl(ClearButton)
|
||||||
|
ClearButton.Bind(wx.EVT_BUTTON, self.Clear)
|
||||||
|
|
||||||
|
DrawButton = wx.Button(tb, wx.ID_ANY, "StopDrawing")
|
||||||
|
tb.AddControl(DrawButton)
|
||||||
|
DrawButton.Bind(wx.EVT_BUTTON, self.SetDraw)
|
||||||
|
self.DrawButton = DrawButton
|
||||||
|
|
||||||
|
tb.Realize()
|
||||||
|
|
||||||
|
# Initialize a few values
|
||||||
|
self.Rects = []
|
||||||
|
|
||||||
|
self.RBBoxMode = GUI.RubberBandBox(self.NewRect)
|
||||||
|
self.Canvas.SetMode(self.RBBoxMode)
|
||||||
|
|
||||||
|
self.Canvas.ZoomToBB()
|
||||||
|
|
||||||
|
self.Show(True)
|
||||||
|
return None
|
||||||
|
|
||||||
|
def Clear(self, event=None):
|
||||||
|
self.Rects = []
|
||||||
|
self.Canvas.ClearAll()
|
||||||
|
self.Canvas.Draw()
|
||||||
|
|
||||||
|
def SetDraw(self, event=None):
|
||||||
|
label = self.DrawButton.GetLabel()
|
||||||
|
if label == "Draw":
|
||||||
|
self.DrawButton.SetLabel("StopDrawing")
|
||||||
|
self.Canvas.SetMode(self.RBBoxMode)
|
||||||
|
elif label == "StopDrawing":
|
||||||
|
self.DrawButton.SetLabel("Draw")
|
||||||
|
self.Canvas.SetMode(GUIMode.GUIMouse())
|
||||||
|
else: # huh?
|
||||||
|
pass
|
||||||
|
|
||||||
|
def NewRect(self, rect):
|
||||||
|
self.Rects.append(self.Canvas.AddRectangle(*rect, LineWidth=4))
|
||||||
|
self.Canvas.Draw(True)
|
||||||
|
|
||||||
|
def OnMove(self, event):
|
||||||
|
"""
|
||||||
|
Updates the status bar with the world coordinates
|
||||||
|
|
||||||
|
"""
|
||||||
|
self.SetStatusText("%.4f, %.4f"%tuple(event.Coords))
|
||||||
|
event.Skip()
|
||||||
|
|
||||||
|
app = wx.PySimpleApp()
|
||||||
|
DrawFrame(None, -1, "FloatCanvas Rectangle Drawer", wx.DefaultPosition, (700,700) )
|
||||||
|
app.MainLoop()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
84
samples/floatcanvas/GridDemo.py
Executable file
84
samples/floatcanvas/GridDemo.py
Executable file
@@ -0,0 +1,84 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
A simple demo to show how to do grids
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
import wx
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
# See if there is a local copy
|
||||||
|
import sys
|
||||||
|
sys.path.append("../")
|
||||||
|
from floatcanvas import NavCanvas, FloatCanvas
|
||||||
|
except ImportError:
|
||||||
|
from wx.lib.floatcanvas import NavCanvas, FloatCanvas
|
||||||
|
|
||||||
|
class DrawFrame(wx.Frame):
|
||||||
|
|
||||||
|
"""
|
||||||
|
A frame used for the FloatCanvas Demo
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
wx.Frame.__init__(self, *args, **kwargs)
|
||||||
|
|
||||||
|
self.CreateStatusBar()
|
||||||
|
|
||||||
|
# Add the Canvas
|
||||||
|
Canvas = NavCanvas.NavCanvas(self,-1,
|
||||||
|
size = (500,500),
|
||||||
|
ProjectionFun = None,
|
||||||
|
Debug = 0,
|
||||||
|
BackgroundColor = "DARK SLATE BLUE",
|
||||||
|
).Canvas
|
||||||
|
|
||||||
|
|
||||||
|
Point = (45,40)
|
||||||
|
Box = Canvas.AddCircle(Point,
|
||||||
|
Diameter = 10,
|
||||||
|
FillColor = "Black",
|
||||||
|
LineColor = "Red",
|
||||||
|
LineWidth = 6)
|
||||||
|
|
||||||
|
# Crosses:
|
||||||
|
Grid = FloatCanvas.DotGrid( Spacing=(1, .5), Size=2, Color="Cyan", Cross=True, CrossThickness=2)
|
||||||
|
#Dots:
|
||||||
|
#Grid = FloatCanvas.DotGrid( (0.5, 1), Size=3, Color="Red")
|
||||||
|
|
||||||
|
Canvas.GridUnder = Grid
|
||||||
|
#Canvas.GridOver = Grid
|
||||||
|
|
||||||
|
FloatCanvas.EVT_MOTION(Canvas, self.OnMove )
|
||||||
|
|
||||||
|
self.Show()
|
||||||
|
Canvas.ZoomToBB()
|
||||||
|
|
||||||
|
def OnMove(self, event):
|
||||||
|
"""
|
||||||
|
Updates the status bar with the world coordinates
|
||||||
|
|
||||||
|
"""
|
||||||
|
self.SetStatusText("%.2f, %.2f"%tuple(event.Coords))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
app = wx.App(False) # true to get its own output window.
|
||||||
|
F = DrawFrame(None, title="FloatCanvas Demo App", size=(700,700) )
|
||||||
|
app.MainLoop()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
121
samples/floatcanvas/GroupDeleteDemo.py
Normal file
121
samples/floatcanvas/GroupDeleteDemo.py
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
A small demo of how to use Groups of Objects
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
import wx
|
||||||
|
|
||||||
|
## import the installed version
|
||||||
|
from wx.lib.floatcanvas import NavCanvas, FloatCanvas
|
||||||
|
|
||||||
|
## import a local version
|
||||||
|
#import sys
|
||||||
|
#sys.path.append("..")
|
||||||
|
#from floatcanvas import NavCanvas, FloatCanvas
|
||||||
|
|
||||||
|
class DrawFrame(wx.Frame):
|
||||||
|
|
||||||
|
"""
|
||||||
|
A frame used for the FloatCanvas Demo
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
wx.Frame.__init__(self, *args, **kwargs)
|
||||||
|
|
||||||
|
self.CreateStatusBar()
|
||||||
|
|
||||||
|
# Add the Canvas
|
||||||
|
NC = NavCanvas.NavCanvas(self,-1,
|
||||||
|
size = (500,500),
|
||||||
|
ProjectionFun = None,
|
||||||
|
Debug = 0,
|
||||||
|
BackgroundColor = "DARK SLATE BLUE",
|
||||||
|
)
|
||||||
|
Canvas = NC.Canvas
|
||||||
|
self.Canvas = Canvas
|
||||||
|
|
||||||
|
FloatCanvas.EVT_MOTION(self.Canvas, self.OnMove )
|
||||||
|
|
||||||
|
Point = (45,40)
|
||||||
|
|
||||||
|
## create a few Objects:
|
||||||
|
C = FloatCanvas.Circle((0, 0), 10, FillColor="Red")
|
||||||
|
R = FloatCanvas.Rectangle((5, 5),(15, 8), FillColor="Blue")
|
||||||
|
E = FloatCanvas.Ellipse((1.5, 1.5), (12, 8), FillColor="Purple")
|
||||||
|
C2 = FloatCanvas.Circle((0, 5), 10, FillColor="cyan")
|
||||||
|
T = FloatCanvas.Text("Group A", (5.5, 5.5), Position="cc", Size = 16, Weight=wx.BOLD, Family=wx.SWISS)
|
||||||
|
|
||||||
|
self.GroupA = FloatCanvas.Group((R,C,E))
|
||||||
|
self.GroupA.AddObjects((C2,T))
|
||||||
|
Canvas.AddObject(self.GroupA)
|
||||||
|
|
||||||
|
|
||||||
|
## create another Groups of objects
|
||||||
|
|
||||||
|
R = FloatCanvas.Rectangle((15, 15),(10, 18), FillColor="orange")
|
||||||
|
E = FloatCanvas.Ellipse((22, 28), (12, 8), FillColor="yellow")
|
||||||
|
C = FloatCanvas.Circle((25, 20), 15, FillColor="Green")
|
||||||
|
C2 = FloatCanvas.Circle((12, 22), 10, FillColor="cyan")
|
||||||
|
T = FloatCanvas.Text("Group B", (19, 24), Position="cc", Size = 16, Weight=wx.BOLD, Family=wx.SWISS)
|
||||||
|
|
||||||
|
self.GroupB = FloatCanvas.Group((R,E,C,C2,T))
|
||||||
|
Canvas.AddObject(self.GroupB)
|
||||||
|
|
||||||
|
self.Groups = {"A":self.GroupA, "B":self.GroupB}
|
||||||
|
|
||||||
|
# Add a couple of tools to the Canvas Toolbar
|
||||||
|
|
||||||
|
tb = NC.ToolBar
|
||||||
|
# tb.AddSeparator()
|
||||||
|
|
||||||
|
for Group in self.Groups.keys():
|
||||||
|
Button = wx.Button(tb, wx.ID_ANY, "Remove %s"%Group)
|
||||||
|
tb.AddControl(Button)
|
||||||
|
Button.Bind(wx.EVT_BUTTON, lambda evt, group=Group: self.RemoveGroup(evt, group))
|
||||||
|
Button = wx.Button(tb, wx.ID_ANY, "Replace%s"%Group)
|
||||||
|
tb.AddControl(Button)
|
||||||
|
Button.Bind(wx.EVT_BUTTON, lambda evt, group=Group: self.ReplaceGroup(evt, group))
|
||||||
|
tb.Realize()
|
||||||
|
|
||||||
|
self.Show()
|
||||||
|
Canvas.ZoomToBB()
|
||||||
|
|
||||||
|
def OnMove(self, event):
|
||||||
|
"""
|
||||||
|
Updates the status bar with the world coordinates of the mouse position
|
||||||
|
|
||||||
|
"""
|
||||||
|
self.SetStatusText("%.2f, %.2f"%tuple(event.Coords))
|
||||||
|
|
||||||
|
def RemoveGroup(self, evt, group=""):
|
||||||
|
print "removing group:", group
|
||||||
|
G = self.Groups[group]
|
||||||
|
self.Canvas.RemoveObject(G)
|
||||||
|
self.Canvas.Draw(Force=True)
|
||||||
|
|
||||||
|
def ReplaceGroup(self, evt, group=""):
|
||||||
|
print "replacing group:", group
|
||||||
|
G = self.Groups[group]
|
||||||
|
self.Canvas.AddObject(G)
|
||||||
|
self.Canvas.Draw(Force=True)
|
||||||
|
|
||||||
|
|
||||||
|
app = wx.App(False)
|
||||||
|
F = DrawFrame(None, title="FloatCanvas Demo App", size=(700,700) )
|
||||||
|
app.MainLoop()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
111
samples/floatcanvas/GroupDemo.py
Normal file
111
samples/floatcanvas/GroupDemo.py
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
A small demo of how to use Groups of Objects
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
import wx
|
||||||
|
|
||||||
|
## import the installed version
|
||||||
|
from wx.lib.floatcanvas import NavCanvas, FloatCanvas
|
||||||
|
|
||||||
|
## import a local version
|
||||||
|
#import sys
|
||||||
|
#sys.path.append("..")
|
||||||
|
#from floatcanvas import NavCanvas, FloatCanvas
|
||||||
|
|
||||||
|
class DrawFrame(wx.Frame):
|
||||||
|
|
||||||
|
"""
|
||||||
|
A frame used for the FloatCanvas Demo
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
wx.Frame.__init__(self, *args, **kwargs)
|
||||||
|
|
||||||
|
self.CreateStatusBar()
|
||||||
|
|
||||||
|
# Add the Canvas
|
||||||
|
NC = NavCanvas.NavCanvas(self,-1,
|
||||||
|
size = (500,500),
|
||||||
|
ProjectionFun = None,
|
||||||
|
Debug = 0,
|
||||||
|
BackgroundColor = "DARK SLATE BLUE",
|
||||||
|
)
|
||||||
|
Canvas = NC.Canvas
|
||||||
|
self.Canvas = Canvas
|
||||||
|
|
||||||
|
FloatCanvas.EVT_MOTION(self.Canvas, self.OnMove )
|
||||||
|
|
||||||
|
Point = (45,40)
|
||||||
|
|
||||||
|
## create a few Objects:
|
||||||
|
C = FloatCanvas.Circle((0, 0), 10, FillColor="Red")
|
||||||
|
R = FloatCanvas.Rectangle((5, 5),(15, 8), FillColor="Blue")
|
||||||
|
E = FloatCanvas.Ellipse((1.5, 1.5), (12, 8), FillColor="Purple")
|
||||||
|
C2 = FloatCanvas.Circle((0, 5), 10, FillColor="cyan")
|
||||||
|
T = FloatCanvas.Text("Group A", (5.5, 5.5), Position="cc", Size = 16, Weight=wx.BOLD, Family=wx.SWISS)
|
||||||
|
|
||||||
|
self.GroupA = FloatCanvas.Group((R,C,E))
|
||||||
|
self.GroupA.AddObjects((C2,T))
|
||||||
|
Canvas.AddObject(self.GroupA)
|
||||||
|
|
||||||
|
|
||||||
|
## create another Groups of objects
|
||||||
|
|
||||||
|
R = FloatCanvas.Rectangle((15, 15),(10, 18), FillColor="orange")
|
||||||
|
E = FloatCanvas.Ellipse((22, 28), (12, 8), FillColor="yellow")
|
||||||
|
C = FloatCanvas.Circle((25, 20), 15, FillColor="Green")
|
||||||
|
C2 = FloatCanvas.Circle((12, 22), 10, FillColor="cyan")
|
||||||
|
T = FloatCanvas.Text("Group B", (19, 24), Position="cc", Size = 16, Weight=wx.BOLD, Family=wx.SWISS)
|
||||||
|
|
||||||
|
self.GroupB = FloatCanvas.Group((R,E,C,C2,T))
|
||||||
|
Canvas.AddObject(self.GroupB)
|
||||||
|
|
||||||
|
self.Groups = {"A":self.GroupA, "B":self.GroupB}
|
||||||
|
|
||||||
|
# Add a couple of tools to the Canvas Toolbar
|
||||||
|
|
||||||
|
tb = NC.ToolBar
|
||||||
|
# tb.AddSeparator()
|
||||||
|
|
||||||
|
for Group in self.Groups.keys():
|
||||||
|
Button = wx.Button(tb, wx.ID_ANY, "Hide/Show%s"%Group)
|
||||||
|
tb.AddControl(Button)
|
||||||
|
print Group
|
||||||
|
Button.Bind(wx.EVT_BUTTON, lambda evt, group=Group: self.HideGroup(evt, group))
|
||||||
|
tb.Realize()
|
||||||
|
|
||||||
|
self.Show()
|
||||||
|
Canvas.ZoomToBB()
|
||||||
|
|
||||||
|
def OnMove(self, event):
|
||||||
|
"""
|
||||||
|
Updates the status bar with the world coordinates of the mouse position
|
||||||
|
|
||||||
|
"""
|
||||||
|
self.SetStatusText("%.2f, %.2f"%tuple(event.Coords))
|
||||||
|
|
||||||
|
def HideGroup(self, evt, group=""):
|
||||||
|
G = self.Groups[group]
|
||||||
|
G.Visible = not G.Visible
|
||||||
|
self.Canvas.Draw(Force=True)
|
||||||
|
|
||||||
|
app = wx.App(False)
|
||||||
|
F = DrawFrame(None, title="FloatCanvas Demo App", size=(700,700) )
|
||||||
|
app.MainLoop()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
102
samples/floatcanvas/Hexagons.py
Executable file
102
samples/floatcanvas/Hexagons.py
Executable file
@@ -0,0 +1,102 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
A simple demo to display a lot of hexagons
|
||||||
|
|
||||||
|
This was an example someone had on the wxPython-users list
|
||||||
|
|
||||||
|
"""
|
||||||
|
import wx
|
||||||
|
import wx.lib.colourdb
|
||||||
|
|
||||||
|
## import local version:
|
||||||
|
#import sys
|
||||||
|
#sys.path.append("..")
|
||||||
|
#from floatcanvas import NavCanvas, FloatCanvas
|
||||||
|
|
||||||
|
## import installed version
|
||||||
|
from wx.lib.floatcanvas import NavCanvas, FloatCanvas
|
||||||
|
|
||||||
|
NumHexagons = 1000
|
||||||
|
|
||||||
|
import numpy as N
|
||||||
|
from numpy.random import uniform
|
||||||
|
|
||||||
|
import random
|
||||||
|
import time
|
||||||
|
|
||||||
|
class DrawFrame(wx.Frame):
|
||||||
|
"""
|
||||||
|
A frame used for the FloatCanvas Demo
|
||||||
|
|
||||||
|
"""
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
wx.Frame.__init__(self, *args, **kwargs)
|
||||||
|
|
||||||
|
# Add the Canvas
|
||||||
|
self.Canvas = NavCanvas.NavCanvas(self,-1,(500,500),
|
||||||
|
ProjectionFun = None,
|
||||||
|
Debug = 1,
|
||||||
|
BackgroundColor = "DARK SLATE BLUE",
|
||||||
|
).Canvas
|
||||||
|
self.MakeHexagons()
|
||||||
|
|
||||||
|
self.Show(True)
|
||||||
|
print "Drawing the Hexagons"
|
||||||
|
self.Canvas.ZoomToBB()
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
def MakeHexagons(self):
|
||||||
|
print "Building %i Hexagons"%NumHexagons
|
||||||
|
# get a list of colors for random colors
|
||||||
|
|
||||||
|
wx.lib.colourdb.updateColourDB()
|
||||||
|
self.colors = wx.lib.colourdb.getColourList()
|
||||||
|
print "Max colors:", len(self.colors)
|
||||||
|
Canvas = self.Canvas
|
||||||
|
D = 1.0
|
||||||
|
h = D *N.sqrt(3)/2
|
||||||
|
Hex = N.array(((D , 0),
|
||||||
|
(D/2 , -h),
|
||||||
|
(-D/2, -h),
|
||||||
|
(-D , 0),
|
||||||
|
(-D/2, h),
|
||||||
|
(D/2 , h),
|
||||||
|
))
|
||||||
|
Centers = uniform(-100, 100, (NumHexagons, 2))
|
||||||
|
for center in Centers:
|
||||||
|
# scale the hexagon
|
||||||
|
Points = Hex * uniform(5,20)
|
||||||
|
#print Points
|
||||||
|
# shift the hexagon
|
||||||
|
Points = Points + center
|
||||||
|
#print Points
|
||||||
|
cf = random.randint(0,len(self.colors)-1)
|
||||||
|
#cf = 55
|
||||||
|
H = Canvas.AddPolygon(Points, LineColor = None, FillColor = self.colors[cf])
|
||||||
|
#print "BrushList is: %i long"%len(H.BrushList)
|
||||||
|
H.Bind(FloatCanvas.EVT_FC_LEFT_DOWN, self.HexHit)
|
||||||
|
print "BrushList is: %i long"%len(H.BrushList)
|
||||||
|
|
||||||
|
def HexHit(self, Hex):
|
||||||
|
print "A %s Hex was hit, obj ID: %i"%(Hex.FillColor, id(Hex))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
app = wx.App(False)
|
||||||
|
DrawFrame(None, -1, "FloatCanvas Demo App", wx.DefaultPosition, (700,700) )
|
||||||
|
app.MainLoop()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
77
samples/floatcanvas/Map.py
Executable file
77
samples/floatcanvas/Map.py
Executable file
@@ -0,0 +1,77 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
|
||||||
|
TestFileName = "../data/TestMap.png"
|
||||||
|
|
||||||
|
|
||||||
|
import wx
|
||||||
|
|
||||||
|
from wx.lib.floatcanvas import NavCanvas, FloatCanvas
|
||||||
|
|
||||||
|
#import sys
|
||||||
|
#sys.path.append("..")
|
||||||
|
#from floatcanvas import NavCanvas, FloatCanvas
|
||||||
|
|
||||||
|
|
||||||
|
class DrawFrame(wx.Frame):
|
||||||
|
|
||||||
|
"""
|
||||||
|
A frame used for the FloatCanvas Demo
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
wx.Frame.__init__(self, *args, **kwargs)
|
||||||
|
|
||||||
|
self.CreateStatusBar()
|
||||||
|
|
||||||
|
# Add the Canvas
|
||||||
|
NC = NavCanvas.NavCanvas(self,-1,
|
||||||
|
size = (500,500),
|
||||||
|
ProjectionFun = None,
|
||||||
|
Debug = 0,
|
||||||
|
BackgroundColor = "White",
|
||||||
|
)
|
||||||
|
self.Canvas = NC.Canvas
|
||||||
|
|
||||||
|
self.LoadMap(TestFileName)
|
||||||
|
|
||||||
|
FloatCanvas.EVT_MOTION(self.Canvas, self.OnMove )
|
||||||
|
|
||||||
|
self.Show()
|
||||||
|
self.Canvas.ZoomToBB()
|
||||||
|
|
||||||
|
def LoadMap(self, filename):
|
||||||
|
Image = wx.Image(filename)
|
||||||
|
self.Canvas.AddScaledBitmap(Image, (0,0), Height = Image.GetSize()[1], Position = "tl")
|
||||||
|
|
||||||
|
self.Canvas.AddPoint((0,0), Diameter=3)
|
||||||
|
self.Canvas.AddText("(0,0)", (0,0), Position="cl")
|
||||||
|
p = (Image.GetSize()[0],-Image.GetSize()[1])
|
||||||
|
self.Canvas.AddPoint(p, Diameter=3)
|
||||||
|
self.Canvas.AddText("(%i,%i)"%p, p, Position="cl")
|
||||||
|
|
||||||
|
self.Canvas.MinScale = 0.15
|
||||||
|
self.Canvas.MaxScale = 1.0
|
||||||
|
|
||||||
|
def Binding(self, event):
|
||||||
|
print "Writing a png file:"
|
||||||
|
self.Canvas.SaveAsImage("junk.png")
|
||||||
|
print "Writing a jpeg file:"
|
||||||
|
self.Canvas.SaveAsImage("junk.jpg",wx.BITMAP_TYPE_JPEG)
|
||||||
|
|
||||||
|
def OnMove(self, event):
|
||||||
|
"""
|
||||||
|
Updates the status bar with the world coordinates
|
||||||
|
|
||||||
|
And moves a point if there is one selected
|
||||||
|
|
||||||
|
"""
|
||||||
|
self.SetStatusText("%.2f, %.2f"%tuple(event.Coords))
|
||||||
|
|
||||||
|
|
||||||
|
app = wx.App(False)
|
||||||
|
F = DrawFrame(None, title="FloatCanvas Demo App", size=(700,700) )
|
||||||
|
app.MainLoop()
|
||||||
|
|
||||||
|
|
||||||
83
samples/floatcanvas/MicroDemo.py
Executable file
83
samples/floatcanvas/MicroDemo.py
Executable file
@@ -0,0 +1,83 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import wx
|
||||||
|
|
||||||
|
## import the installed version
|
||||||
|
from wx.lib.floatcanvas import NavCanvas, FloatCanvas
|
||||||
|
|
||||||
|
## import a local version
|
||||||
|
#import sys
|
||||||
|
#sys.path.append("../")
|
||||||
|
#from floatcanvas import NavCanvas, FloatCanvas
|
||||||
|
|
||||||
|
|
||||||
|
class DrawFrame(wx.Frame):
|
||||||
|
|
||||||
|
"""
|
||||||
|
A frame used for the FloatCanvas Demo
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
wx.Frame.__init__(self, *args, **kwargs)
|
||||||
|
|
||||||
|
self.CreateStatusBar()
|
||||||
|
|
||||||
|
# Add the Canvas
|
||||||
|
Canvas = NavCanvas.NavCanvas(self,-1,
|
||||||
|
size = (500,500),
|
||||||
|
ProjectionFun = None,
|
||||||
|
Debug = 0,
|
||||||
|
BackgroundColor = "DARK SLATE BLUE",
|
||||||
|
).Canvas
|
||||||
|
|
||||||
|
self.Canvas = Canvas
|
||||||
|
|
||||||
|
FloatCanvas.EVT_MOTION(self.Canvas, self.OnMove )
|
||||||
|
|
||||||
|
Point = (45,40)
|
||||||
|
Text = Canvas.AddScaledText("A String",
|
||||||
|
Point,
|
||||||
|
20,
|
||||||
|
Color = "Black",
|
||||||
|
BackgroundColor = None,
|
||||||
|
Family = wx.ROMAN,
|
||||||
|
Style = wx.NORMAL,
|
||||||
|
Weight = wx.NORMAL,
|
||||||
|
Underlined = False,
|
||||||
|
Position = 'bl',
|
||||||
|
InForeground = False)
|
||||||
|
Text.MinFontSize = 4 # the default is 1
|
||||||
|
Text.DisappearWhenSmall = False #the default is True
|
||||||
|
|
||||||
|
Rect = Canvas.AddRectangle((50, 20), (40,10), FillColor="Red", LineStyle = None)
|
||||||
|
Rect.MinSize = 4 # default is 1
|
||||||
|
Rect.DisappearWhenSmall = False # defualt is True
|
||||||
|
|
||||||
|
self.Show()
|
||||||
|
Canvas.ZoomToBB()
|
||||||
|
|
||||||
|
|
||||||
|
def OnMove(self, event):
|
||||||
|
"""
|
||||||
|
Updates the status bar with the world coordinates
|
||||||
|
|
||||||
|
"""
|
||||||
|
self.SetStatusText("%.2f, %.2f"%tuple(event.Coords))
|
||||||
|
|
||||||
|
app = wx.App(False)
|
||||||
|
F = DrawFrame(None, title="FloatCanvas Demo App", size=(700,700) )
|
||||||
|
app.MainLoop()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
381
samples/floatcanvas/MiniDemo.py
Executable file
381
samples/floatcanvas/MiniDemo.py
Executable file
@@ -0,0 +1,381 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import wx
|
||||||
|
|
||||||
|
## import local version:
|
||||||
|
#import sys
|
||||||
|
#sys.path.append("../")
|
||||||
|
#from floatcanvas import NavCanvas, FloatCanvas
|
||||||
|
|
||||||
|
## import installed version
|
||||||
|
from wx.lib.floatcanvas import NavCanvas, FloatCanvas
|
||||||
|
|
||||||
|
import wx.lib.colourdb
|
||||||
|
|
||||||
|
class DrawFrame(wx.Frame):
|
||||||
|
|
||||||
|
"""
|
||||||
|
A frame used for the FloatCanvas Demo
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
wx.Frame.__init__(self, *args, **kwargs)
|
||||||
|
|
||||||
|
## Set up the MenuBar
|
||||||
|
|
||||||
|
MenuBar = wx.MenuBar()
|
||||||
|
|
||||||
|
file_menu = wx.Menu()
|
||||||
|
item = file_menu.Append(wx.ID_ANY, "&Close","Close this frame")
|
||||||
|
self.Bind(wx.EVT_MENU, self.OnQuit, item)
|
||||||
|
MenuBar.Append(file_menu, "&File")
|
||||||
|
|
||||||
|
draw_menu = wx.Menu()
|
||||||
|
|
||||||
|
item = draw_menu.Append(wx.ID_ANY, "&Draw Test","Run a test of drawing random components")
|
||||||
|
self.Bind(wx.EVT_MENU,self.DrawTest, item)
|
||||||
|
|
||||||
|
item = draw_menu.Append(wx.ID_ANY, "&Move Test","Run a test of moving stuff in the background")
|
||||||
|
self.Bind(wx.EVT_MENU, self.MoveTest, item)
|
||||||
|
|
||||||
|
item = draw_menu.Append(wx.ID_ANY, "&Clear","Clear the Canvas")
|
||||||
|
self.Bind(wx.EVT_MENU,self.Clear, item)
|
||||||
|
|
||||||
|
MenuBar.Append(draw_menu, "&Draw")
|
||||||
|
|
||||||
|
view_menu = wx.Menu()
|
||||||
|
item = view_menu.Append(wx.ID_ANY, "Zoom to &Fit","Zoom to fit the window")
|
||||||
|
self.Bind(wx.EVT_MENU,self.ZoomToFit, item)
|
||||||
|
MenuBar.Append(view_menu, "&View")
|
||||||
|
|
||||||
|
help_menu = wx.Menu()
|
||||||
|
item = help_menu.Append(wx.ID_ANY, "&About",
|
||||||
|
"More information About this program")
|
||||||
|
self.Bind(wx.EVT_MENU, self.OnAbout, item)
|
||||||
|
MenuBar.Append(help_menu, "&Help")
|
||||||
|
|
||||||
|
self.SetMenuBar(MenuBar)
|
||||||
|
|
||||||
|
self.CreateStatusBar()
|
||||||
|
self.SetStatusText("")
|
||||||
|
|
||||||
|
wx.EVT_CLOSE(self, self.OnCloseWindow)
|
||||||
|
|
||||||
|
# Add the Canvas
|
||||||
|
self.Canvas = NavCanvas.NavCanvas(self,
|
||||||
|
ProjectionFun = None,
|
||||||
|
Debug = 0,
|
||||||
|
BackgroundColor = "DARK SLATE BLUE",
|
||||||
|
).Canvas
|
||||||
|
|
||||||
|
|
||||||
|
self.Show(True)
|
||||||
|
|
||||||
|
|
||||||
|
# get a list of colors for random colors
|
||||||
|
wx.lib.colourdb.updateColourDB()
|
||||||
|
self.colors = wx.lib.colourdb.getColourList()
|
||||||
|
|
||||||
|
self.LineStyles = FloatCanvas.DrawObject.LineStyleList.keys()
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
def OnAbout(self, event):
|
||||||
|
dlg = wx.MessageDialog(self, "This is a small program to demonstrate\n"
|
||||||
|
"the use of the FloatCanvas\n",
|
||||||
|
"About Me", wx.OK | wx.ICON_INFORMATION)
|
||||||
|
dlg.ShowModal()
|
||||||
|
dlg.Destroy()
|
||||||
|
|
||||||
|
def ZoomToFit(self,event):
|
||||||
|
self.Canvas.ZoomToBB()
|
||||||
|
|
||||||
|
def Clear(self,event = None):
|
||||||
|
self.Canvas.ClearAll()
|
||||||
|
self.Canvas.Draw()
|
||||||
|
|
||||||
|
def OnQuit(self,event):
|
||||||
|
self.Close(True)
|
||||||
|
|
||||||
|
def OnCloseWindow(self, event):
|
||||||
|
self.Destroy()
|
||||||
|
|
||||||
|
def DrawTest(self,event):
|
||||||
|
wx.GetApp().Yield()
|
||||||
|
import random
|
||||||
|
import numpy.random as RandomArray
|
||||||
|
Range = (-10,10)
|
||||||
|
|
||||||
|
Canvas = self.Canvas
|
||||||
|
Canvas.ClearAll()
|
||||||
|
|
||||||
|
# Set some zoom limits:
|
||||||
|
self.Canvas.MinScale = 15.0
|
||||||
|
self.Canvas.MaxScale = 500.0
|
||||||
|
|
||||||
|
#### Draw a few Random Objects ####
|
||||||
|
|
||||||
|
# Rectangles
|
||||||
|
for i in range(5):
|
||||||
|
xy = (random.uniform(Range[0],Range[1]),random.uniform(Range[0],Range[1]))
|
||||||
|
lw = random.randint(1,5)
|
||||||
|
cf = random.randint(0,len(self.colors)-1)
|
||||||
|
h = random.randint(1,5)
|
||||||
|
w = random.randint(1,5)
|
||||||
|
Canvas.AddRectangle(xy, (h,w),
|
||||||
|
LineWidth = lw,
|
||||||
|
FillColor = self.colors[cf])
|
||||||
|
|
||||||
|
# Ellipses
|
||||||
|
for i in range(5):
|
||||||
|
xy = (random.uniform(Range[0],Range[1]),random.uniform(Range[0],Range[1]))
|
||||||
|
lw = random.randint(1,5)
|
||||||
|
cf = random.randint(0,len(self.colors)-1)
|
||||||
|
h = random.randint(1,5)
|
||||||
|
w = random.randint(1,5)
|
||||||
|
Canvas.AddEllipse(xy, (h,w),
|
||||||
|
LineWidth = lw,
|
||||||
|
FillColor = self.colors[cf])
|
||||||
|
|
||||||
|
# Circles
|
||||||
|
for i in range(5):
|
||||||
|
point = (random.uniform(Range[0],Range[1]),random.uniform(Range[0],Range[1]))
|
||||||
|
D = random.randint(1,5)
|
||||||
|
lw = random.randint(1,5)
|
||||||
|
cf = random.randint(0,len(self.colors)-1)
|
||||||
|
cl = random.randint(0,len(self.colors)-1)
|
||||||
|
Canvas.AddCircle(point, D,
|
||||||
|
LineWidth = lw,
|
||||||
|
LineColor = self.colors[cl],
|
||||||
|
FillColor = self.colors[cf])
|
||||||
|
Canvas.AddText("Circle # %i"%(i),
|
||||||
|
point,
|
||||||
|
Size = 12,
|
||||||
|
Position = "cc")
|
||||||
|
|
||||||
|
# Lines
|
||||||
|
for i in range(5):
|
||||||
|
points = []
|
||||||
|
for j in range(random.randint(2,10)):
|
||||||
|
point = (random.randint(Range[0],Range[1]),random.randint(Range[0],Range[1]))
|
||||||
|
points.append(point)
|
||||||
|
lw = random.randint(1,10)
|
||||||
|
cf = random.randint(0,len(self.colors)-1)
|
||||||
|
cl = random.randint(0,len(self.colors)-1)
|
||||||
|
Canvas.AddLine(points, LineWidth = lw, LineColor = self.colors[cl])
|
||||||
|
|
||||||
|
# Polygons
|
||||||
|
for i in range(3):
|
||||||
|
points = []
|
||||||
|
for j in range(random.randint(2,6)):
|
||||||
|
point = (random.uniform(Range[0],Range[1]),random.uniform(Range[0],Range[1]))
|
||||||
|
points.append(point)
|
||||||
|
lw = random.randint(1,6)
|
||||||
|
cf = random.randint(0,len(self.colors)-1)
|
||||||
|
cl = random.randint(0,len(self.colors)-1)
|
||||||
|
Canvas.AddPolygon(points,
|
||||||
|
LineWidth = lw,
|
||||||
|
LineColor = self.colors[cl],
|
||||||
|
FillColor = self.colors[cf],
|
||||||
|
FillStyle = 'Solid')
|
||||||
|
|
||||||
|
self.Canvas.ZoomToBB()
|
||||||
|
|
||||||
|
def MoveTest(self,event=None):
|
||||||
|
print "Running: TestHitTestForeground"
|
||||||
|
wx.GetApp().Yield()
|
||||||
|
|
||||||
|
self.UnBindAllMouseEvents()
|
||||||
|
Canvas = self.Canvas
|
||||||
|
|
||||||
|
Canvas.ClearAll()
|
||||||
|
# Clear the zoom limits:
|
||||||
|
self.Canvas.MinScale = None
|
||||||
|
self.Canvas.MaxScale = None
|
||||||
|
|
||||||
|
Canvas.SetProjectionFun(None)
|
||||||
|
|
||||||
|
#Add a Hitable rectangle
|
||||||
|
w,h = 60, 20
|
||||||
|
|
||||||
|
dx = 80
|
||||||
|
dy = 40
|
||||||
|
x,y = 20, 20
|
||||||
|
|
||||||
|
color = "Red"
|
||||||
|
R = Canvas.AddRectangle((x,y), (w,h),
|
||||||
|
LineWidth = 2,
|
||||||
|
FillColor = color
|
||||||
|
)
|
||||||
|
|
||||||
|
R.Name = color + "Rectangle"
|
||||||
|
Canvas.AddText(R.Name, (x, y+h), Position = "tl")
|
||||||
|
|
||||||
|
## A set of Rectangles that move together
|
||||||
|
|
||||||
|
## NOTE: In a real app, it might be better to create a new
|
||||||
|
## custom FloatCanvas DrawObject
|
||||||
|
|
||||||
|
self.MovingRects = []
|
||||||
|
x += dx
|
||||||
|
color = "LightBlue"
|
||||||
|
R = Canvas.AddRectangle((x,y), (w/2, h/2),
|
||||||
|
LineWidth = 2,
|
||||||
|
FillColor = color)
|
||||||
|
|
||||||
|
R.HitFill = True
|
||||||
|
R.Bind(FloatCanvas.EVT_FC_LEFT_DOWN, self.RectMoveLeft)
|
||||||
|
L = Canvas.AddText("Left", (x + w/4, y + h/4),
|
||||||
|
Position = "cc")
|
||||||
|
self.MovingRects.extend( (R,L) )
|
||||||
|
|
||||||
|
x += w/2
|
||||||
|
R = Canvas.AddRectangle((x, y), (w/2, h/2),
|
||||||
|
LineWidth = 2,
|
||||||
|
FillColor = color)
|
||||||
|
|
||||||
|
R.HitFill = True
|
||||||
|
R.Bind(FloatCanvas.EVT_FC_LEFT_DOWN, self.RectMoveRight)
|
||||||
|
L = Canvas.AddText("Right", (x + w/4, y + h/4),
|
||||||
|
Position = "cc")
|
||||||
|
self.MovingRects.extend( (R,L) )
|
||||||
|
|
||||||
|
x -= w/2
|
||||||
|
y += h/2
|
||||||
|
R = Canvas.AddRectangle((x, y), (w/2, h/2),
|
||||||
|
LineWidth = 2,
|
||||||
|
FillColor = color)
|
||||||
|
R.HitFill = True
|
||||||
|
R.Bind(FloatCanvas.EVT_FC_LEFT_DOWN, self.RectMoveUp)
|
||||||
|
L = Canvas.AddText("Up", (x + w/4, y + h/4),
|
||||||
|
Position = "cc")
|
||||||
|
self.MovingRects.extend( (R,L) )
|
||||||
|
|
||||||
|
|
||||||
|
x += w/2
|
||||||
|
R = Canvas.AddRectangle((x, y), (w/2, h/2),
|
||||||
|
LineWidth = 2,
|
||||||
|
FillColor = color)
|
||||||
|
R.HitFill = True
|
||||||
|
R.Bind(FloatCanvas.EVT_FC_LEFT_DOWN, self.RectMoveDown)
|
||||||
|
L = Canvas.AddText("Down", (x + w/4, y + h/4),
|
||||||
|
Position = "cc")
|
||||||
|
self.MovingRects.extend( (R,L) )
|
||||||
|
|
||||||
|
self.Canvas.ZoomToBB()
|
||||||
|
|
||||||
|
def RectMoveLeft(self,Object):
|
||||||
|
self.MoveRects("left")
|
||||||
|
|
||||||
|
def RectMoveRight(self,Object):
|
||||||
|
self.MoveRects("right")
|
||||||
|
|
||||||
|
def RectMoveUp(self,Object):
|
||||||
|
self.MoveRects("up")
|
||||||
|
|
||||||
|
def RectMoveDown(self,Object):
|
||||||
|
self.MoveRects("down")
|
||||||
|
|
||||||
|
def MoveRects(self, Dir):
|
||||||
|
for Object in self.MovingRects:
|
||||||
|
X,Y = Object.XY
|
||||||
|
if Dir == "left": X -= 10
|
||||||
|
elif Dir == "right": X += 10
|
||||||
|
elif Dir == "up": Y += 10
|
||||||
|
elif Dir == "down": Y -= 10
|
||||||
|
Object.SetPoint((X,Y))
|
||||||
|
self.Canvas.Draw(True)
|
||||||
|
|
||||||
|
def UnBindAllMouseEvents(self):
|
||||||
|
## Here is how you catch FloatCanvas mouse events
|
||||||
|
FloatCanvas.EVT_LEFT_DOWN(self.Canvas, None )
|
||||||
|
FloatCanvas.EVT_LEFT_UP(self.Canvas, None )
|
||||||
|
FloatCanvas.EVT_LEFT_DCLICK(self.Canvas, None)
|
||||||
|
|
||||||
|
FloatCanvas.EVT_MIDDLE_DOWN(self.Canvas, None )
|
||||||
|
FloatCanvas.EVT_MIDDLE_UP(self.Canvas, None )
|
||||||
|
FloatCanvas.EVT_MIDDLE_DCLICK(self.Canvas, None )
|
||||||
|
|
||||||
|
FloatCanvas.EVT_RIGHT_DOWN(self.Canvas, None )
|
||||||
|
FloatCanvas.EVT_RIGHT_UP(self.Canvas, None )
|
||||||
|
FloatCanvas.EVT_RIGHT_DCLICK(self.Canvas, None )
|
||||||
|
|
||||||
|
FloatCanvas.EVT_MOUSEWHEEL(self.Canvas, None )
|
||||||
|
|
||||||
|
self.EventsAreBound = False
|
||||||
|
|
||||||
|
class DemoApp(wx.App):
|
||||||
|
"""
|
||||||
|
How the demo works:
|
||||||
|
|
||||||
|
Under the Draw menu, there are three options:
|
||||||
|
|
||||||
|
*Draw Test: will put up a picture of a bunch of randomly generated
|
||||||
|
objects, of each kind supported.
|
||||||
|
|
||||||
|
*Draw Map: will draw a map of the world. Be patient, it is a big map,
|
||||||
|
with a lot of data, and will take a while to load and draw (about 10 sec
|
||||||
|
on my 450Mhz PIII). Redraws take about 2 sec. This demonstrates how the
|
||||||
|
performance is not very good for large drawings.
|
||||||
|
|
||||||
|
*Clear: Clears the Canvas.
|
||||||
|
|
||||||
|
Once you have a picture drawn, you can zoom in and out and move about
|
||||||
|
the picture. There is a tool bar with three tools that can be
|
||||||
|
selected.
|
||||||
|
|
||||||
|
The magnifying glass with the plus is the zoom in tool. Once selected,
|
||||||
|
if you click the image, it will zoom in, centered on where you
|
||||||
|
clicked. If you click and drag the mouse, you will get a rubber band
|
||||||
|
box, and the image will zoom to fit that box when you release it.
|
||||||
|
|
||||||
|
The magnifying glass with the minus is the zoom out tool. Once selected,
|
||||||
|
if you click the image, it will zoom out, centered on where you
|
||||||
|
clicked. (note that this takes a while when you are looking at the map,
|
||||||
|
as it has a LOT of lines to be drawn. The image is double buffered, so
|
||||||
|
you don't see the drawing in progress)
|
||||||
|
|
||||||
|
The hand is the move tool. Once selected, if you click and drag on the
|
||||||
|
image, it will move so that the part you clicked on ends up where you
|
||||||
|
release the mouse. Nothing is changed while you are dragging. The
|
||||||
|
drawing is too slow for that.
|
||||||
|
|
||||||
|
I'd like the cursor to change as you change tools, but the stock
|
||||||
|
wx.Cursors didn't include anything I liked, so I stuck with the
|
||||||
|
pointer. Please let me know if you have any nice cursor images for me to
|
||||||
|
use.
|
||||||
|
|
||||||
|
|
||||||
|
Any bugs, comments, feedback, questions, and especially code are welcome:
|
||||||
|
|
||||||
|
-Chris Barker
|
||||||
|
|
||||||
|
Chris.Barker@noaa.gov
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def OnInit(self):
|
||||||
|
frame = DrawFrame(None, wx.ID_ANY,
|
||||||
|
title = "FloatCanvas Demo App",
|
||||||
|
size = (700,700) )
|
||||||
|
|
||||||
|
self.SetTopWindow(frame)
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
app = DemoApp(False)
|
||||||
|
app.MainLoop()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
48
samples/floatcanvas/MouseTest.py
Executable file
48
samples/floatcanvas/MouseTest.py
Executable file
@@ -0,0 +1,48 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
Small demo of catching Mouse events using just FloatCanvas, rather than
|
||||||
|
NavCanvas
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
import wx
|
||||||
|
|
||||||
|
app = wx.App(0)
|
||||||
|
|
||||||
|
try:
|
||||||
|
# See if there is a local copy
|
||||||
|
import sys
|
||||||
|
sys.path.append("../")
|
||||||
|
from floatcanvas import NavCanvas, FloatCanvas, GUIMode
|
||||||
|
except ImportError:
|
||||||
|
from wx.lib.floatcanvas import NavCanvas, FloatCanvas, GUIMode
|
||||||
|
|
||||||
|
class TestFrame(wx.Frame):
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
|
||||||
|
wx.Frame.__init__(self, *args, **kwargs)
|
||||||
|
self.canvas =FloatCanvas.FloatCanvas(self, BackgroundColor = "DARK SLATE BLUE")
|
||||||
|
|
||||||
|
# Layout
|
||||||
|
MainSizer = wx.BoxSizer(wx.VERTICAL)
|
||||||
|
MainSizer.Add(self.canvas, 4, wx.EXPAND)
|
||||||
|
self.SetSizer(MainSizer)
|
||||||
|
|
||||||
|
self.canvas.Bind(FloatCanvas.EVT_LEFT_DOWN, self.OnLeftDown)
|
||||||
|
|
||||||
|
self.canvas.AddRectangle((10,10), (100, 20), FillColor="red")
|
||||||
|
|
||||||
|
self.canvas.SetMode(GUIMode.GUIMouse(self.canvas))
|
||||||
|
|
||||||
|
wx.CallAfter(self.canvas.ZoomToBB)
|
||||||
|
|
||||||
|
def OnLeftDown(self, event):
|
||||||
|
print 'Left Button clicked at:', event.Coords
|
||||||
|
|
||||||
|
frame = TestFrame(None, title="Mouse Event Tester")
|
||||||
|
#self.SetTopWindow(frame)
|
||||||
|
frame.Show(True)
|
||||||
|
app.MainLoop()
|
||||||
|
|
||||||
281
samples/floatcanvas/MovingElements.py
Executable file
281
samples/floatcanvas/MovingElements.py
Executable file
@@ -0,0 +1,281 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
"""
|
||||||
|
|
||||||
|
This is a small demo, showing how to make an object that can be moved around.
|
||||||
|
|
||||||
|
It also contains a simple prototype for a "Connector" object
|
||||||
|
-- a line connecting two other objects
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
import wx
|
||||||
|
|
||||||
|
#ver = 'local'
|
||||||
|
ver = 'installed'
|
||||||
|
|
||||||
|
if ver == 'installed': ## import the installed version
|
||||||
|
from wx.lib.floatcanvas import NavCanvas, Resources
|
||||||
|
from wx.lib.floatcanvas import FloatCanvas as FC
|
||||||
|
print "using installed version:", wx.lib.floatcanvas.__version__
|
||||||
|
elif ver == 'local':
|
||||||
|
## import a local version
|
||||||
|
import sys
|
||||||
|
sys.path.append("..")
|
||||||
|
from floatcanvas import NavCanvas, Resources
|
||||||
|
from floatcanvas import FloatCanvas as FC
|
||||||
|
from floatcanvas.Utilities import BBox
|
||||||
|
|
||||||
|
import numpy as N
|
||||||
|
|
||||||
|
## here we create some new mixins:
|
||||||
|
|
||||||
|
class MovingObjectMixin:
|
||||||
|
"""
|
||||||
|
Methods required for a Moving object
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def GetOutlinePoints(self):
|
||||||
|
BB = self.BoundingBox
|
||||||
|
OutlinePoints = N.array( ( (BB[0,0], BB[0,1]),
|
||||||
|
(BB[0,0], BB[1,1]),
|
||||||
|
(BB[1,0], BB[1,1]),
|
||||||
|
(BB[1,0], BB[0,1]),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
return OutlinePoints
|
||||||
|
|
||||||
|
|
||||||
|
class ConnectorObjectMixin:
|
||||||
|
"""
|
||||||
|
Mixin class for DrawObjects that can be connected with lines
|
||||||
|
|
||||||
|
NOte that this versionony works for Objects that have an "XY" attribute:
|
||||||
|
that is, one that is derived from XHObjectMixin.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def GetConnectPoint(self):
|
||||||
|
return self.XY
|
||||||
|
|
||||||
|
class MovingBitmap(FC.ScaledBitmap, MovingObjectMixin, ConnectorObjectMixin):
|
||||||
|
"""
|
||||||
|
ScaledBitmap Object that can be moved
|
||||||
|
"""
|
||||||
|
## All we need to do is is inherit from:
|
||||||
|
## ScaledBitmap, MovingObjectMixin and ConnectorObjectMixin
|
||||||
|
pass
|
||||||
|
|
||||||
|
class MovingCircle(FC.Circle, MovingObjectMixin, ConnectorObjectMixin):
|
||||||
|
"""
|
||||||
|
ScaledBitmap Object that can be moved
|
||||||
|
"""
|
||||||
|
## All we need to do is is inherit from:
|
||||||
|
## ScaledBitmap, MovingObjectMixin and ConnectorObjectMixin
|
||||||
|
pass
|
||||||
|
|
||||||
|
class MovingArc(FC.Arc, MovingObjectMixin, ConnectorObjectMixin):
|
||||||
|
"""
|
||||||
|
ScaledBitmap Object that can be moved
|
||||||
|
"""
|
||||||
|
## All we need to do is is inherit from:
|
||||||
|
## ScaledBitmap, MovingObjectMixin and ConnectorObjectMixin
|
||||||
|
pass
|
||||||
|
|
||||||
|
class ConnectorLine(FC.LineOnlyMixin, FC.DrawObject,):
|
||||||
|
"""
|
||||||
|
|
||||||
|
A Line that connects two objects -- it uses the objects to get its coordinates
|
||||||
|
|
||||||
|
"""
|
||||||
|
##fixme: this should be added to the Main FloatCanvas Objects some day.
|
||||||
|
def __init__(self,
|
||||||
|
Object1,
|
||||||
|
Object2,
|
||||||
|
LineColor = "Black",
|
||||||
|
LineStyle = "Solid",
|
||||||
|
LineWidth = 1,
|
||||||
|
InForeground = False):
|
||||||
|
FC.DrawObject.__init__(self, InForeground)
|
||||||
|
|
||||||
|
self.Object1 = Object1
|
||||||
|
self.Object2 = Object2
|
||||||
|
self.LineColor = LineColor
|
||||||
|
self.LineStyle = LineStyle
|
||||||
|
self.LineWidth = LineWidth
|
||||||
|
|
||||||
|
self.CalcBoundingBox()
|
||||||
|
self.SetPen(LineColor,LineStyle,LineWidth)
|
||||||
|
|
||||||
|
self.HitLineWidth = max(LineWidth,self.MinHitLineWidth)
|
||||||
|
|
||||||
|
def CalcBoundingBox(self):
|
||||||
|
self.BoundingBox = BBox.fromPoints((self.Object1.GetConnectPoint(),
|
||||||
|
self.Object2.GetConnectPoint()) )
|
||||||
|
if self._Canvas:
|
||||||
|
self._Canvas.BoundingBoxDirty = True
|
||||||
|
|
||||||
|
|
||||||
|
def _Draw(self, dc , WorldToPixel, ScaleWorldToPixel, HTdc=None):
|
||||||
|
Points = N.array( (self.Object1.GetConnectPoint(),
|
||||||
|
self.Object2.GetConnectPoint()) )
|
||||||
|
Points = WorldToPixel(Points)
|
||||||
|
dc.SetPen(self.Pen)
|
||||||
|
dc.DrawLines(Points)
|
||||||
|
if HTdc and self.HitAble:
|
||||||
|
HTdc.SetPen(self.HitPen)
|
||||||
|
HTdc.DrawLines(Points)
|
||||||
|
|
||||||
|
|
||||||
|
class TriangleShape1(FC.Polygon, MovingObjectMixin):
|
||||||
|
|
||||||
|
def __init__(self, XY, L):
|
||||||
|
|
||||||
|
"""
|
||||||
|
An equilateral triangle object
|
||||||
|
XY is the middle of the triangle
|
||||||
|
L is the length of one side of the Triangle
|
||||||
|
"""
|
||||||
|
|
||||||
|
XY = N.asarray(XY)
|
||||||
|
XY.shape = (2,)
|
||||||
|
|
||||||
|
Points = self.CompPoints(XY, L)
|
||||||
|
|
||||||
|
FC.Polygon.__init__(self, Points,
|
||||||
|
LineColor = "Black",
|
||||||
|
LineStyle = "Solid",
|
||||||
|
LineWidth = 2,
|
||||||
|
FillColor = "Red",
|
||||||
|
FillStyle = "Solid")
|
||||||
|
## Override the default OutlinePoints
|
||||||
|
def GetOutlinePoints(self):
|
||||||
|
return self.Points
|
||||||
|
|
||||||
|
def CompPoints(self, XY, L):
|
||||||
|
c = L/ N.sqrt(3)
|
||||||
|
|
||||||
|
Points = N.array(((0, c),
|
||||||
|
( L/2.0, -c/2.0),
|
||||||
|
(-L/2.0, -c/2.0)),
|
||||||
|
N.float_)
|
||||||
|
|
||||||
|
Points += XY
|
||||||
|
return Points
|
||||||
|
|
||||||
|
|
||||||
|
class DrawFrame(wx.Frame):
|
||||||
|
|
||||||
|
"""
|
||||||
|
A simple frame used for the Demo
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
wx.Frame.__init__(self, *args, **kwargs)
|
||||||
|
|
||||||
|
self.CreateStatusBar()
|
||||||
|
# Add the Canvas
|
||||||
|
Canvas = NavCanvas.NavCanvas(self,-1,(500,500),
|
||||||
|
ProjectionFun = None,
|
||||||
|
Debug = 0,
|
||||||
|
BackgroundColor = "DARK SLATE BLUE",
|
||||||
|
).Canvas
|
||||||
|
|
||||||
|
self.Canvas = Canvas
|
||||||
|
|
||||||
|
Canvas.Bind(FC.EVT_MOTION, self.OnMove )
|
||||||
|
Canvas.Bind(FC.EVT_LEFT_UP, self.OnLeftUp )
|
||||||
|
|
||||||
|
Points = N.array(((0,0),
|
||||||
|
(1,0),
|
||||||
|
(0.5, 1)),
|
||||||
|
N.float)
|
||||||
|
|
||||||
|
data = (( (0,0), 1),
|
||||||
|
( (3,3), 2),
|
||||||
|
( (-2,3), 2.5 ),
|
||||||
|
)
|
||||||
|
|
||||||
|
for p, L in data:
|
||||||
|
Tri = TriangleShape1(p, 1)
|
||||||
|
Canvas.AddObject(Tri)
|
||||||
|
Tri.Bind(FC.EVT_FC_LEFT_DOWN, self.ObjectHit)
|
||||||
|
|
||||||
|
Circle = MovingCircle( (1, 3), 2, FillColor="Blue")
|
||||||
|
Canvas.AddObject(Circle)
|
||||||
|
Circle.Bind(FC.EVT_FC_LEFT_DOWN, self.ObjectHit)
|
||||||
|
|
||||||
|
Bitmaps = []
|
||||||
|
## create the bitmaps first
|
||||||
|
for Point in ((1,1), (-4,3)):
|
||||||
|
Bitmaps.append(MovingBitmap(Resources.getMondrianImage(),
|
||||||
|
Point,
|
||||||
|
Height=1,
|
||||||
|
Position='cc')
|
||||||
|
)
|
||||||
|
Line = ConnectorLine(Bitmaps[0], Bitmaps[1], LineWidth=3, LineColor="Red")
|
||||||
|
Canvas.AddObject(Line)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## then add them to the Canvas, so they are on top of the line
|
||||||
|
for bmp in Bitmaps:
|
||||||
|
Canvas.AddObject(bmp)
|
||||||
|
bmp.Bind(FC.EVT_FC_LEFT_DOWN, self.ObjectHit)
|
||||||
|
|
||||||
|
A = MovingArc((-5, 0),(-2, 2),(-5, 2), LineColor="Red", LineWidth=2)
|
||||||
|
self.Canvas.AddObject(A)
|
||||||
|
A.Bind(FC.EVT_FC_LEFT_DOWN, self.ObjectHit)
|
||||||
|
|
||||||
|
self.Show(True)
|
||||||
|
self.Canvas.ZoomToBB()
|
||||||
|
|
||||||
|
self.MoveObject = None
|
||||||
|
self.Moving = False
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
def ObjectHit(self, object):
|
||||||
|
if not self.Moving:
|
||||||
|
self.Moving = True
|
||||||
|
self.StartPoint = object.HitCoordsPixel
|
||||||
|
self.StartObject = self.Canvas.WorldToPixel(object.GetOutlinePoints())
|
||||||
|
self.MoveObject = None
|
||||||
|
self.MovingObject = object
|
||||||
|
|
||||||
|
def OnMove(self, event):
|
||||||
|
"""
|
||||||
|
Updates the status bar with the world coordinates
|
||||||
|
and moves the object it is clicked on
|
||||||
|
|
||||||
|
"""
|
||||||
|
self.SetStatusText("%.4f, %.4f"%tuple(event.Coords))
|
||||||
|
|
||||||
|
if self.Moving:
|
||||||
|
dxy = event.GetPosition() - self.StartPoint
|
||||||
|
# Draw the Moving Object:
|
||||||
|
dc = wx.ClientDC(self.Canvas)
|
||||||
|
dc.SetPen(wx.Pen('WHITE', 2, wx.SHORT_DASH))
|
||||||
|
dc.SetBrush(wx.TRANSPARENT_BRUSH)
|
||||||
|
dc.SetLogicalFunction(wx.XOR)
|
||||||
|
if self.MoveObject is not None:
|
||||||
|
dc.DrawPolygon(self.MoveObject)
|
||||||
|
self.MoveObject = self.StartObject + dxy
|
||||||
|
dc.DrawPolygon(self.MoveObject)
|
||||||
|
|
||||||
|
def OnLeftUp(self, event):
|
||||||
|
if self.Moving:
|
||||||
|
self.Moving = False
|
||||||
|
if self.MoveObject is not None:
|
||||||
|
dxy = event.GetPosition() - self.StartPoint
|
||||||
|
dxy = self.Canvas.ScalePixelToWorld(dxy)
|
||||||
|
self.MovingObject.Move(dxy)
|
||||||
|
self.MoveTri = None
|
||||||
|
self.Canvas.Draw(True)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
app = wx.PySimpleApp(0)
|
||||||
|
DrawFrame(None, -1, "FloatCanvas Moving Object App", wx.DefaultPosition, (700,700) )
|
||||||
|
app.MainLoop()
|
||||||
238
samples/floatcanvas/MovingPlot.py
Executable file
238
samples/floatcanvas/MovingPlot.py
Executable file
@@ -0,0 +1,238 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
"""
|
||||||
|
|
||||||
|
A small test app that uses FloatCanvas to draw a plot, and have an
|
||||||
|
efficient moving line on it.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
import wx
|
||||||
|
import numpy as N
|
||||||
|
|
||||||
|
## import the installed version
|
||||||
|
from wx.lib.floatcanvas import NavCanvas, FloatCanvas
|
||||||
|
|
||||||
|
## import a local version
|
||||||
|
#import sys
|
||||||
|
#sys.path.append("../")
|
||||||
|
#from floatcanvas import NavCanvas, FloatCanvas
|
||||||
|
|
||||||
|
|
||||||
|
class DrawFrame(wx.Frame):
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
wx.Frame.__init__(self, *args, **kwargs)
|
||||||
|
|
||||||
|
## Set up the MenuBar
|
||||||
|
|
||||||
|
MenuBar = wx.MenuBar()
|
||||||
|
|
||||||
|
file_menu = wx.Menu()
|
||||||
|
item = file_menu.Append(wx.ID_ANY, "E&xit","Terminate the program")
|
||||||
|
self.Bind(wx.EVT_MENU, self.OnQuit, item)
|
||||||
|
MenuBar.Append(file_menu, "&File")
|
||||||
|
|
||||||
|
draw_menu = wx.Menu()
|
||||||
|
item = draw_menu.Append(wx.ID_ANY, "&Run","Run the test")
|
||||||
|
self.Bind(wx.EVT_MENU, self.RunTest, item)
|
||||||
|
item = draw_menu.Append(wx.ID_ANY, "&Stop","Stop the test")
|
||||||
|
self.Bind(wx.EVT_MENU, self.Stop, item)
|
||||||
|
MenuBar.Append(draw_menu, "&Plot")
|
||||||
|
|
||||||
|
|
||||||
|
help_menu = wx.Menu()
|
||||||
|
item = help_menu.Append(wx.ID_ANY, "&About",
|
||||||
|
"More information About this program")
|
||||||
|
self.Bind(wx.EVT_MENU, self.OnAbout, item)
|
||||||
|
MenuBar.Append(help_menu, "&Help")
|
||||||
|
|
||||||
|
self.SetMenuBar(MenuBar)
|
||||||
|
|
||||||
|
|
||||||
|
self.CreateStatusBar()
|
||||||
|
self.SetStatusText("")
|
||||||
|
|
||||||
|
wx.EVT_CLOSE(self, self.OnCloseWindow)
|
||||||
|
|
||||||
|
# Add the Canvas
|
||||||
|
NC = NavCanvas.NavCanvas(self ,wx.ID_ANY ,(500,300),
|
||||||
|
ProjectionFun = None,
|
||||||
|
Debug = 0,
|
||||||
|
BackgroundColor = "WHITE"
|
||||||
|
)
|
||||||
|
self.Canvas = NC.Canvas
|
||||||
|
|
||||||
|
self.Canvas.NumBetweenBlits = 1000
|
||||||
|
|
||||||
|
# Add a couple of tools to the Canvas Toolbar
|
||||||
|
|
||||||
|
tb = NC.ToolBar
|
||||||
|
tb.AddSeparator()
|
||||||
|
|
||||||
|
StopButton = wx.Button(tb, wx.ID_ANY, "Stop")
|
||||||
|
tb.AddControl(StopButton)
|
||||||
|
StopButton.Bind(wx.EVT_BUTTON, self.Stop)
|
||||||
|
|
||||||
|
PlayButton = wx.Button(tb, wx.ID_ANY, "Run")
|
||||||
|
tb.AddControl(PlayButton)
|
||||||
|
PlayButton.Bind(wx.EVT_BUTTON, self.RunTest)
|
||||||
|
|
||||||
|
tb.Realize()
|
||||||
|
|
||||||
|
self.Show(True)
|
||||||
|
|
||||||
|
self.timer = None
|
||||||
|
|
||||||
|
self.DrawAxis()
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def OnAbout(self, event):
|
||||||
|
dlg = wx.MessageDialog(self, "This is a small program to demonstrate\n"
|
||||||
|
"the use of the FloatCanvas\n"
|
||||||
|
"for simple plotting",
|
||||||
|
"About Me", wx.OK | wx.ICON_INFORMATION)
|
||||||
|
dlg.ShowModal()
|
||||||
|
dlg.Destroy()
|
||||||
|
|
||||||
|
def ZoomToFit(self,event):
|
||||||
|
self.Canvas.ZoomToBB()
|
||||||
|
|
||||||
|
def OnQuit(self,event):
|
||||||
|
self.Close(True)
|
||||||
|
|
||||||
|
def OnCloseWindow(self, event):
|
||||||
|
self.Destroy()
|
||||||
|
|
||||||
|
def DrawAxis(self):
|
||||||
|
Canvas = self.Canvas
|
||||||
|
|
||||||
|
# Draw the Axis
|
||||||
|
|
||||||
|
# Note: the AddRectangle Parameters all have sensible
|
||||||
|
# defaults. I've put them all here explicitly, so you can see
|
||||||
|
# what the options are.
|
||||||
|
|
||||||
|
self.Canvas.AddRectangle((0, -1.1),
|
||||||
|
(2*N.pi, 2.2),
|
||||||
|
LineColor = "Black",
|
||||||
|
LineStyle = "Solid",
|
||||||
|
LineWidth = 1,
|
||||||
|
FillColor = None,
|
||||||
|
FillStyle = "Solid",
|
||||||
|
InForeground = 0)
|
||||||
|
for tic in N.arange(7):
|
||||||
|
self.Canvas.AddText("%1.1f"%tic,
|
||||||
|
(tic,-1.1),
|
||||||
|
Position = 'tc')
|
||||||
|
|
||||||
|
for tic in N.arange(-1, 1.1, 0.5):
|
||||||
|
self.Canvas.AddText("%1.1f"%tic,
|
||||||
|
(0,tic),
|
||||||
|
Position = 'cr')
|
||||||
|
|
||||||
|
# Add a phantom rectangle to get the bounding box right
|
||||||
|
# (the bounding box doesn't get unscaled text right)
|
||||||
|
self.Canvas.AddRectangle((-0.7, -1.5), (7, 3), LineColor = None)
|
||||||
|
|
||||||
|
Canvas.ZoomToBB()
|
||||||
|
Canvas.Draw()
|
||||||
|
|
||||||
|
def Stop(self,event):
|
||||||
|
if self.timer:
|
||||||
|
self.timer.Stop()
|
||||||
|
|
||||||
|
|
||||||
|
def OnTimer(self,event):
|
||||||
|
self.count += .1
|
||||||
|
self.data1[:,1] = N.sin(self.time+self.count) #fake move
|
||||||
|
|
||||||
|
self.line.SetPoints(self.data1)
|
||||||
|
|
||||||
|
self.Canvas.Draw()
|
||||||
|
|
||||||
|
def RunTest(self,event = None):
|
||||||
|
self.n = 100
|
||||||
|
self.dT = 0.05
|
||||||
|
|
||||||
|
self.time = 2.0*N.pi*N.arange(100)/100.0
|
||||||
|
|
||||||
|
self.data1 = 1.0*N.ones((100,2))
|
||||||
|
self.data1[:,0] = self.time
|
||||||
|
self.data1[:,1] = N.sin(self.time)
|
||||||
|
Canvas = self.Canvas
|
||||||
|
self.Canvas.ClearAll()
|
||||||
|
self.DrawAxis()
|
||||||
|
self.line = Canvas.AddLine(self.data1,
|
||||||
|
LineColor = "Red",
|
||||||
|
LineStyle = "Solid",
|
||||||
|
LineWidth = 2,
|
||||||
|
InForeground = 1)
|
||||||
|
self.Canvas.Draw()
|
||||||
|
|
||||||
|
self.timerID = wx.NewId()
|
||||||
|
self.timer = wx.Timer(self,self.timerID)
|
||||||
|
|
||||||
|
wx.EVT_TIMER(self,self.timerID,self.OnTimer)
|
||||||
|
|
||||||
|
self.count = 0
|
||||||
|
self.timer.Start(int(self.dT*1000))
|
||||||
|
|
||||||
|
class DemoApp(wx.App):
|
||||||
|
"""
|
||||||
|
How the demo works:
|
||||||
|
|
||||||
|
Either under the Draw menu, or on the toolbar, you can push Run and Stop
|
||||||
|
|
||||||
|
"Run" start an oscilloscope like display of a moving sine curve
|
||||||
|
"Stop" stops it.
|
||||||
|
|
||||||
|
While the plot os running (or not) you can zoom in and out and move
|
||||||
|
about the picture. There is a tool bar with three tools that can be
|
||||||
|
selected.
|
||||||
|
|
||||||
|
The magnifying glass with the plus is the zoom in tool. Once selected,
|
||||||
|
if you click the image, it will zoom in, centered on where you
|
||||||
|
clicked. If you click and drag the mouse, you will get a rubber band
|
||||||
|
box, and the image will zoom to fit that box when you release it.
|
||||||
|
|
||||||
|
The magnifying glass with the minus is the zoom out tool. Once selected,
|
||||||
|
if you click the image, it will zoom out, centered on where you
|
||||||
|
clicked.
|
||||||
|
|
||||||
|
The hand is the move tool. Once selected, if you click and drag on
|
||||||
|
the image, it will move so that the part you clicked on ends up
|
||||||
|
where you release the mouse. Nothing is changed while you are
|
||||||
|
dragging, but you can see the outline of the former picture.
|
||||||
|
|
||||||
|
I'd like the cursor to change as you change tools, but the stock
|
||||||
|
wx.Cursors didn't include anything I liked, so I stuck with the
|
||||||
|
pointer. Please let me know if you have any nice cursor images for me to
|
||||||
|
use.
|
||||||
|
|
||||||
|
|
||||||
|
Any bugs, comments, feedback, questions, and especially code are welcome:
|
||||||
|
|
||||||
|
-Chris Barker
|
||||||
|
|
||||||
|
Chris.Barker@noaa.gov
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def OnInit(self):
|
||||||
|
wx.InitAllImageHandlers()
|
||||||
|
frame = DrawFrame(None, wx.ID_ANY,
|
||||||
|
title = "Plotting Test",
|
||||||
|
size = (700,400) )
|
||||||
|
|
||||||
|
self.SetTopWindow(frame)
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
|
||||||
|
app = DemoApp(0)
|
||||||
|
app.MainLoop()
|
||||||
|
|
||||||
|
|
||||||
189
samples/floatcanvas/MovingTriangle.py
Executable file
189
samples/floatcanvas/MovingTriangle.py
Executable file
@@ -0,0 +1,189 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
"""
|
||||||
|
|
||||||
|
This is a small demo, showing how to make an object that can be moved around.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
import wx
|
||||||
|
|
||||||
|
#ver = 'local'
|
||||||
|
ver = 'installed'
|
||||||
|
|
||||||
|
if ver == 'installed': ## import the installed version
|
||||||
|
from wx.lib.floatcanvas import NavCanvas, Resources
|
||||||
|
from wx.lib.floatcanvas import FloatCanvas as FC
|
||||||
|
print "using installed version:", wx.lib.floatcanvas.__version__
|
||||||
|
elif ver == 'local':
|
||||||
|
## import a local version
|
||||||
|
import sys
|
||||||
|
sys.path.append("..")
|
||||||
|
from floatcanvas import NavCanvas, Resources
|
||||||
|
from floatcanvas import FloatCanvas as FC
|
||||||
|
|
||||||
|
import numpy as N
|
||||||
|
|
||||||
|
## here we create a new DrawObject:
|
||||||
|
## code borrowed and adapted from Werner Bruhin
|
||||||
|
|
||||||
|
class ShapeMixin:
|
||||||
|
"""
|
||||||
|
just here for added features later
|
||||||
|
"""
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class TriangleShape1(FC.Polygon, ShapeMixin):
|
||||||
|
|
||||||
|
def __init__(self, XY, L):
|
||||||
|
|
||||||
|
"""
|
||||||
|
An equilateral triangle object
|
||||||
|
|
||||||
|
XY is the middle of the triangle
|
||||||
|
|
||||||
|
L is the length of one side of the Triangle
|
||||||
|
"""
|
||||||
|
|
||||||
|
XY = N.asarray(XY)
|
||||||
|
XY.shape = (2,)
|
||||||
|
|
||||||
|
Points = self.CompPoints(XY, L)
|
||||||
|
|
||||||
|
FC.Polygon.__init__(self, Points,
|
||||||
|
LineColor = "Black",
|
||||||
|
LineStyle = "Solid",
|
||||||
|
LineWidth = 2,
|
||||||
|
FillColor = "Red",
|
||||||
|
FillStyle = "Solid")
|
||||||
|
ShapeMixin.__init__(self)
|
||||||
|
|
||||||
|
def CompPoints(self, XY, L):
|
||||||
|
c = L/ N.sqrt(3)
|
||||||
|
|
||||||
|
Points = N.array(((0, c),
|
||||||
|
( L/2.0, -c/2.0),
|
||||||
|
(-L/2.0, -c/2.0)),
|
||||||
|
N.float_)
|
||||||
|
|
||||||
|
Points += XY
|
||||||
|
return Points
|
||||||
|
|
||||||
|
|
||||||
|
class DrawFrame(wx.Frame):
|
||||||
|
|
||||||
|
"""
|
||||||
|
A frame used for the FloatCanvas Demo
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self,parent, id,title,position,size):
|
||||||
|
wx.Frame.__init__(self,parent, id,title,position, size)
|
||||||
|
|
||||||
|
self.CreateStatusBar()
|
||||||
|
# Add the Canvas
|
||||||
|
Canvas = NavCanvas.NavCanvas(self,-1,(500,500),
|
||||||
|
ProjectionFun = None,
|
||||||
|
Debug = 0,
|
||||||
|
BackgroundColor = "DARK SLATE BLUE",
|
||||||
|
).Canvas
|
||||||
|
|
||||||
|
self.Canvas = Canvas
|
||||||
|
|
||||||
|
Canvas.Bind(FC.EVT_MOTION, self.OnMove )
|
||||||
|
Canvas.Bind(FC.EVT_LEFT_UP, self.OnLeftUp )
|
||||||
|
|
||||||
|
Canvas.AddRectangle((-5,-5),
|
||||||
|
(10,10),
|
||||||
|
LineColor = "Red",
|
||||||
|
LineStyle = "Solid",
|
||||||
|
LineWidth = 2,
|
||||||
|
FillColor = "CYAN",
|
||||||
|
FillStyle = "Solid")
|
||||||
|
|
||||||
|
Points = N.array(((0,0),
|
||||||
|
(1,0),
|
||||||
|
(0.5, 1)),
|
||||||
|
N.float_)
|
||||||
|
|
||||||
|
data = (( (0,0), 1),
|
||||||
|
( (3,3), 2),
|
||||||
|
( (-2,3), 2.5 ),
|
||||||
|
)
|
||||||
|
|
||||||
|
for p, L in data:
|
||||||
|
Tri = TriangleShape1(p, 1)
|
||||||
|
Canvas.AddObject(Tri)
|
||||||
|
Tri.Bind(FC.EVT_FC_LEFT_DOWN, self.TriHit)
|
||||||
|
|
||||||
|
|
||||||
|
self.MoveTri = None
|
||||||
|
|
||||||
|
self.Show(True)
|
||||||
|
self.Canvas.ZoomToBB()
|
||||||
|
|
||||||
|
self.Moving = False
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
def TriHit(self, object):
|
||||||
|
print "In TriHit"
|
||||||
|
if not self.Moving:
|
||||||
|
self.Moving = True
|
||||||
|
self.StartPoint = object.HitCoordsPixel
|
||||||
|
self.StartTri = self.Canvas.WorldToPixel(object.Points)
|
||||||
|
self.MoveTri = None
|
||||||
|
self.MovingTri = object
|
||||||
|
|
||||||
|
def OnMove(self, event):
|
||||||
|
"""
|
||||||
|
Updates the status bar with the world coordinates
|
||||||
|
|
||||||
|
And moves the triangle it it is clicked on
|
||||||
|
|
||||||
|
"""
|
||||||
|
self.SetStatusText("%.4f, %.4f"%tuple(event.Coords))
|
||||||
|
|
||||||
|
if self.Moving:
|
||||||
|
dxy = event.GetPosition() - self.StartPoint
|
||||||
|
# Draw the Moving Triangle:
|
||||||
|
dc = wx.ClientDC(self.Canvas)
|
||||||
|
dc.SetPen(wx.Pen('WHITE', 2, wx.SHORT_DASH))
|
||||||
|
dc.SetBrush(wx.TRANSPARENT_BRUSH)
|
||||||
|
dc.SetLogicalFunction(wx.XOR)
|
||||||
|
if self.MoveTri is not None:
|
||||||
|
dc.DrawPolygon(self.MoveTri)
|
||||||
|
self.MoveTri = self.StartTri + dxy
|
||||||
|
dc.DrawPolygon(self.MoveTri)
|
||||||
|
|
||||||
|
def OnLeftUp(self, event):
|
||||||
|
if self.Moving:
|
||||||
|
self.Moving = False
|
||||||
|
if self.MoveTri is not None:
|
||||||
|
dxy = event.GetPosition() - self.StartPoint
|
||||||
|
dxy = self.Canvas.ScalePixelToWorld(dxy)
|
||||||
|
self.MovingTri.Move(dxy) ## The Move function has jsut been added
|
||||||
|
## to the FloatCanvas PointsObject
|
||||||
|
## It does the next three lines for you.
|
||||||
|
#self.Tri.Points += dxy
|
||||||
|
#self.Tri.BoundingBox += dxy
|
||||||
|
#self.Canvas.BoundingBoxDirty = True
|
||||||
|
self.MoveTri = None
|
||||||
|
self.Canvas.Draw(True)
|
||||||
|
|
||||||
|
app = wx.PySimpleApp(0)
|
||||||
|
DrawFrame(None, -1, "FloatCanvas TextBox Test App", wx.DefaultPosition, (700,700) )
|
||||||
|
app.MainLoop()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
BIN
samples/floatcanvas/NOAA.png
Normal file
BIN
samples/floatcanvas/NOAA.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.4 KiB |
93
samples/floatcanvas/NoToolbar.py
Executable file
93
samples/floatcanvas/NoToolbar.py
Executable file
@@ -0,0 +1,93 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
A simple example of how to use FloatCanvas by itself, without the NavCanvas toolbar
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
import wx
|
||||||
|
|
||||||
|
## import the installed version
|
||||||
|
from wx.lib.floatcanvas import NavCanvas, FloatCanvas
|
||||||
|
|
||||||
|
## import a local version
|
||||||
|
#import sys
|
||||||
|
#sys.path.append("../")
|
||||||
|
#from floatcanvas import NavCanvas, FloatCanvas
|
||||||
|
|
||||||
|
|
||||||
|
class DrawFrame(wx.Frame):
|
||||||
|
|
||||||
|
"""
|
||||||
|
A frame used for the FloatCanvas Demo
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
wx.Frame.__init__(self, *args, **kwargs)
|
||||||
|
|
||||||
|
self.CreateStatusBar()
|
||||||
|
|
||||||
|
# Add the Canvas
|
||||||
|
Canvas = FloatCanvas.FloatCanvas(self,
|
||||||
|
size = (500,500),
|
||||||
|
BackgroundColor = "DARK SLATE BLUE",
|
||||||
|
)
|
||||||
|
|
||||||
|
self.Canvas = Canvas
|
||||||
|
|
||||||
|
FloatCanvas.EVT_MOTION(self.Canvas, self.OnMove )
|
||||||
|
|
||||||
|
Point = (45,40)
|
||||||
|
Box = Canvas.AddScaledTextBox("A Two Line\nString",
|
||||||
|
Point,
|
||||||
|
2,
|
||||||
|
Color = "Black",
|
||||||
|
BackgroundColor = None,
|
||||||
|
LineColor = "Red",
|
||||||
|
LineStyle = "Solid",
|
||||||
|
LineWidth = 1,
|
||||||
|
Width = None,
|
||||||
|
PadSize = 5,
|
||||||
|
Family = wx.ROMAN,
|
||||||
|
Style = wx.NORMAL,
|
||||||
|
Weight = wx.NORMAL,
|
||||||
|
Underlined = False,
|
||||||
|
Position = 'br',
|
||||||
|
Alignment = "left",
|
||||||
|
InForeground = False)
|
||||||
|
|
||||||
|
Box.Bind(FloatCanvas.EVT_FC_LEFT_DOWN, self.Binding)
|
||||||
|
self.Show()
|
||||||
|
Canvas.ZoomToBB()
|
||||||
|
|
||||||
|
def OnMove(self, event):
|
||||||
|
"""
|
||||||
|
Updates the status bar with the world coordinates
|
||||||
|
|
||||||
|
"""
|
||||||
|
self.SetStatusText("%.2f, %.2f"%tuple(event.Coords))
|
||||||
|
|
||||||
|
def Binding(self, event):
|
||||||
|
print "Writing a png file:"
|
||||||
|
self.Canvas.SaveAsImage("junk.png")
|
||||||
|
print "Writing a jpeg file:"
|
||||||
|
self.Canvas.SaveAsImage("junk.jpg",wx.BITMAP_TYPE_JPEG)
|
||||||
|
|
||||||
|
|
||||||
|
app = wx.App(False)
|
||||||
|
F = DrawFrame(None, title="FloatCanvas Demo App", size=(700,700) )
|
||||||
|
app.MainLoop()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
43
samples/floatcanvas/NonGUI.py
Executable file
43
samples/floatcanvas/NonGUI.py
Executable file
@@ -0,0 +1,43 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
Demo of a FloatCanvas App that will create an image, without
|
||||||
|
actually showing anything on screen. It seems to work, but you do need
|
||||||
|
to have an X-server running on *nix for this to work.
|
||||||
|
|
||||||
|
Note: you need to specify the size in the FloatCanvas Constructor.
|
||||||
|
|
||||||
|
hmm -- I wonder if you'd even need the frame?
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
import wx
|
||||||
|
|
||||||
|
## import the installed version
|
||||||
|
from wx.lib.floatcanvas import FloatCanvas
|
||||||
|
|
||||||
|
## import a local version
|
||||||
|
#import sys
|
||||||
|
#sys.path.append("../")
|
||||||
|
#from floatcanvas import NavCanvas, FloatCanvas
|
||||||
|
|
||||||
|
app = wx.PySimpleApp()
|
||||||
|
|
||||||
|
f = wx.Frame(None)
|
||||||
|
Canvas = FloatCanvas.FloatCanvas(f,
|
||||||
|
BackgroundColor = "Cyan",
|
||||||
|
size=(500,500)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
Canvas.AddRectangle((0,0), (16,20))
|
||||||
|
Canvas.AddRectangle((1,1), (6,8.5))
|
||||||
|
Canvas.AddRectangle((9,1), (6,8.5))
|
||||||
|
Canvas.AddRectangle((9,10.5), (6,8.5))
|
||||||
|
Canvas.AddRectangle((1,10.5), (6,8.5))
|
||||||
|
Canvas.ZoomToBB()
|
||||||
|
|
||||||
|
|
||||||
|
print "Saving the image:", "junk.png"
|
||||||
|
Canvas.SaveAsImage("junk.png")
|
||||||
|
|
||||||
142
samples/floatcanvas/OverlayDemo.py
Executable file
142
samples/floatcanvas/OverlayDemo.py
Executable file
@@ -0,0 +1,142 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
A simple demo to show how to "Overlays": i.e. drawing something
|
||||||
|
on top of eveything else on the Canvas, relative to window coords,
|
||||||
|
rather than screen coords.
|
||||||
|
|
||||||
|
This method uses the "GridOver" object in the FloatCanvas
|
||||||
|
- it was orginally dsigend for girds, graticule,s etc. that
|
||||||
|
are always drawn regardless of zoom, pan, etc, but it works
|
||||||
|
for overlays too.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
import wx
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
# See if there is a local copy
|
||||||
|
import sys
|
||||||
|
sys.path.append("../")
|
||||||
|
from floatcanvas import NavCanvas, FloatCanvas
|
||||||
|
except ImportError:
|
||||||
|
from wx.lib.floatcanvas import NavCanvas, FloatCanvas
|
||||||
|
|
||||||
|
class TextOverlay(FloatCanvas.Text):
|
||||||
|
"""
|
||||||
|
An example of an Overlay object:
|
||||||
|
|
||||||
|
all it needs is a new _Draw method.
|
||||||
|
|
||||||
|
NOTE: you may want to get fancier with this,
|
||||||
|
deriving from ScaledTextBox
|
||||||
|
|
||||||
|
"""
|
||||||
|
def __init__(self,
|
||||||
|
String,
|
||||||
|
xy,
|
||||||
|
Size = 24,
|
||||||
|
Color = "Black",
|
||||||
|
BackgroundColor = None,
|
||||||
|
Family = wx.MODERN,
|
||||||
|
Style = wx.NORMAL,
|
||||||
|
Weight = wx.NORMAL,
|
||||||
|
Underlined = False,
|
||||||
|
Font = None):
|
||||||
|
FloatCanvas.Text.__init__(self,
|
||||||
|
String,
|
||||||
|
xy,
|
||||||
|
Size = Size,
|
||||||
|
Color = Color,
|
||||||
|
BackgroundColor = BackgroundColor,
|
||||||
|
Family = Family,
|
||||||
|
Style = Style,
|
||||||
|
Weight = Weight,
|
||||||
|
Underlined = Underlined,
|
||||||
|
Font = Font)
|
||||||
|
|
||||||
|
def _Draw(self, dc, Canvas):
|
||||||
|
"""
|
||||||
|
_Draw method for Overlay
|
||||||
|
note: this is a differeent signarture than the DrawObject Draw
|
||||||
|
"""
|
||||||
|
dc.SetFont(self.Font)
|
||||||
|
dc.SetTextForeground(self.Color)
|
||||||
|
if self.BackgroundColor:
|
||||||
|
dc.SetBackgroundMode(wx.SOLID)
|
||||||
|
dc.SetTextBackground(self.BackgroundColor)
|
||||||
|
else:
|
||||||
|
dc.SetBackgroundMode(wx.TRANSPARENT)
|
||||||
|
## maybe inpliment this...
|
||||||
|
#if self.TextWidth is None or self.TextHeight is None:
|
||||||
|
# (self.TextWidth, self.TextHeight) = dc.GetTextExtent(self.String)
|
||||||
|
#XY = self.ShiftFun(XY[0], XY[1], self.TextWidth, self.TextHeight)
|
||||||
|
dc.DrawTextPoint(self.String, self.XY)
|
||||||
|
|
||||||
|
|
||||||
|
class DrawFrame(wx.Frame):
|
||||||
|
|
||||||
|
"""
|
||||||
|
A frame used for the FloatCanvas Demo
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
wx.Frame.__init__(self, *args, **kwargs)
|
||||||
|
|
||||||
|
self.CreateStatusBar()
|
||||||
|
|
||||||
|
# Add the Canvas
|
||||||
|
Canvas = NavCanvas.NavCanvas(self,-1,
|
||||||
|
size = (500,500),
|
||||||
|
ProjectionFun = None,
|
||||||
|
Debug = 0,
|
||||||
|
BackgroundColor = "DARK SLATE BLUE",
|
||||||
|
).Canvas
|
||||||
|
|
||||||
|
|
||||||
|
Point = (45,40)
|
||||||
|
Box = Canvas.AddCircle(Point,
|
||||||
|
Diameter = 10,
|
||||||
|
FillColor = "Cyan",
|
||||||
|
LineColor = "Red",
|
||||||
|
LineWidth = 6)
|
||||||
|
|
||||||
|
Canvas.GridOver = TextOverlay("Some Text",
|
||||||
|
(20,20),
|
||||||
|
Size = 48,
|
||||||
|
Color = "Black",
|
||||||
|
BackgroundColor = 'Pink',
|
||||||
|
)
|
||||||
|
|
||||||
|
FloatCanvas.EVT_MOTION(Canvas, self.OnMove )
|
||||||
|
|
||||||
|
self.Show()
|
||||||
|
Canvas.ZoomToBB()
|
||||||
|
|
||||||
|
def OnMove(self, event):
|
||||||
|
"""
|
||||||
|
Updates the status bar with the world coordinates
|
||||||
|
|
||||||
|
"""
|
||||||
|
self.SetStatusText("%.2f, %.2f"%tuple(event.Coords))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
app = wx.App(False) # true to get its own output window.
|
||||||
|
F = DrawFrame(None, title="FloatCanvas Demo App", size=(700,700) )
|
||||||
|
app.MainLoop()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
91
samples/floatcanvas/PieChart.py
Executable file
91
samples/floatcanvas/PieChart.py
Executable file
@@ -0,0 +1,91 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
|
||||||
|
import wx
|
||||||
|
|
||||||
|
## import the installed version
|
||||||
|
from wx.lib.floatcanvas import NavCanvas, FloatCanvas
|
||||||
|
from wx.lib.floatcanvas.SpecialObjects import PieChart
|
||||||
|
|
||||||
|
## import a local version
|
||||||
|
#import sys
|
||||||
|
#sys.path.append("..")
|
||||||
|
#from floatcanvas import NavCanvas, FloatCanvas
|
||||||
|
#from floatcanvas.SpecialObjects import PieChart
|
||||||
|
|
||||||
|
|
||||||
|
import numpy as N
|
||||||
|
|
||||||
|
class DrawFrame(wx.Frame):
|
||||||
|
|
||||||
|
"""
|
||||||
|
A frame used for the FloatCanvas Demo
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
wx.Frame.__init__(self, *args, **kwargs)
|
||||||
|
|
||||||
|
self.CreateStatusBar()
|
||||||
|
|
||||||
|
# Add the Canvas
|
||||||
|
Canvas = NavCanvas.NavCanvas(self,-1,
|
||||||
|
size = (500,500),
|
||||||
|
Debug = 0,
|
||||||
|
BackgroundColor = "DARK SLATE BLUE",
|
||||||
|
).Canvas
|
||||||
|
|
||||||
|
self.Canvas = Canvas
|
||||||
|
|
||||||
|
Values = (10,10,10)
|
||||||
|
Colors = ('Red', 'Blue', 'Green')
|
||||||
|
Pie1 = PieChart(N.array((0, 0)), 10, Values, Colors, Scaled=False)
|
||||||
|
Canvas.AddObject(Pie1)
|
||||||
|
|
||||||
|
Values = (10, 5, 5)
|
||||||
|
Pie2 = PieChart(N.array((40, 0)), 10, Values, Colors)
|
||||||
|
Canvas.AddObject(Pie2)
|
||||||
|
|
||||||
|
# test default colors
|
||||||
|
Values = (10, 15, 12, 24, 6, 10, 13, 11, 9, 13, 15, 12)
|
||||||
|
Pie3 = PieChart(N.array((20, 20)), 10, Values, LineColor="Black")
|
||||||
|
Canvas.AddObject(Pie3)
|
||||||
|
|
||||||
|
# missng slice!
|
||||||
|
Values = (10, 15, 12, 24)
|
||||||
|
Colors = ('Red', 'Blue', 'Green', None)
|
||||||
|
Pie4 = PieChart(N.array((0, -15)), 10, Values, Colors, LineColor="Black")
|
||||||
|
Canvas.AddObject(Pie4)
|
||||||
|
|
||||||
|
|
||||||
|
# Test the styles
|
||||||
|
Values = (10, 12, 14)
|
||||||
|
Styles = ("Solid", "CrossDiagHatch","CrossHatch")
|
||||||
|
Colors = ('Red', 'Blue', 'Green')
|
||||||
|
Pie4 = PieChart(N.array((20, -20)), 10, Values, Colors, Styles)
|
||||||
|
Canvas.AddObject(Pie2)
|
||||||
|
|
||||||
|
Pie1.Bind(FloatCanvas.EVT_FC_LEFT_DOWN, self.Pie1Hit)
|
||||||
|
Pie2.Bind(FloatCanvas.EVT_FC_LEFT_DOWN, self.Pie2Hit)
|
||||||
|
|
||||||
|
FloatCanvas.EVT_MOTION(self.Canvas, self.OnMove )
|
||||||
|
|
||||||
|
self.Show()
|
||||||
|
Canvas.ZoomToBB()
|
||||||
|
|
||||||
|
def Pie1Hit(self, obj):
|
||||||
|
print "Pie1 hit!"
|
||||||
|
|
||||||
|
def Pie2Hit(self, obj):
|
||||||
|
print "Pie2 hit!"
|
||||||
|
|
||||||
|
def OnMove(self, event):
|
||||||
|
"""
|
||||||
|
Updates the status bar with the world coordinates
|
||||||
|
"""
|
||||||
|
self.SetStatusText("%.2g, %.2g"%tuple(event.Coords))
|
||||||
|
|
||||||
|
|
||||||
|
app = wx.App(False)
|
||||||
|
F = DrawFrame(None, title="FloatCanvas Demo App", size=(700,700) )
|
||||||
|
app.MainLoop()
|
||||||
150
samples/floatcanvas/PixelBitmap.py
Executable file
150
samples/floatcanvas/PixelBitmap.py
Executable file
@@ -0,0 +1,150 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
A simple demo to show how to drw a bitmap on top of the Canvas at given pixel coords.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
import wx
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
try:
|
||||||
|
# See if there is a local copy
|
||||||
|
import sys
|
||||||
|
sys.path.append("../")
|
||||||
|
from floatcanvas import NavCanvas, FloatCanvas
|
||||||
|
except ImportError:
|
||||||
|
from wx.lib.floatcanvas import NavCanvas, FloatCanvas
|
||||||
|
FC = FloatCanvas
|
||||||
|
|
||||||
|
class PixelBitmap:
|
||||||
|
"""
|
||||||
|
An unscaled bitmap that can be put on top of the canvas using:
|
||||||
|
|
||||||
|
Canvas.GridOver = MyPixelBitmap
|
||||||
|
|
||||||
|
It will always be drawn on top of everything else, and be positioned
|
||||||
|
according to pixel coordinates on teh screen, regardless of zoom and
|
||||||
|
pan position.
|
||||||
|
|
||||||
|
"""
|
||||||
|
def __init__(self, Bitmap, XY, Position = 'tl'):
|
||||||
|
"""
|
||||||
|
PixelBitmap (Bitmap, XY, Position='tl')
|
||||||
|
|
||||||
|
Bitmap is a wx.Bitmap or wx.Image
|
||||||
|
|
||||||
|
XY is the (x,y) location to place the bitmap, in pixel coordinates
|
||||||
|
|
||||||
|
Position indicates from where in the window the position is relative to:
|
||||||
|
'tl' indicated the position from the top left the the window (the detault)
|
||||||
|
'br' the bottom right
|
||||||
|
'cr the center right, etc.
|
||||||
|
|
||||||
|
"""
|
||||||
|
if type(Bitmap) == wx._gdi.Bitmap:
|
||||||
|
self.Bitmap = Bitmap
|
||||||
|
elif type(Bitmap) == wx._core.Image:
|
||||||
|
self.Bitmap = wx.BitmapFromImage(Bitmap)
|
||||||
|
else:
|
||||||
|
raise FC.FloatCanvasError("PixelBitmap takes only a wx.Bitmap or a wx.Image as input")
|
||||||
|
|
||||||
|
self.XY = np.asarray(XY, dtype=np.int).reshape((2,))
|
||||||
|
self.Position = Position
|
||||||
|
|
||||||
|
(self.Width, self.Height) = self.Bitmap.GetWidth(), self.Bitmap.GetHeight()
|
||||||
|
self.ShiftFun = FC.TextObjectMixin.ShiftFunDict[Position]
|
||||||
|
|
||||||
|
def _Draw(self, dc, Canvas):
|
||||||
|
w, h = Canvas.Size
|
||||||
|
XY = self.XY
|
||||||
|
if self.Position[0] == 'b':
|
||||||
|
XY = (XY[0], h - XY[1] - self.Height)
|
||||||
|
elif self.Position[0] == 'c':
|
||||||
|
XY = (XY[0], XY[1] + (h - self.Height)/2)
|
||||||
|
|
||||||
|
if self.Position[1] == 'r':
|
||||||
|
XY = (w - XY[0] - self.Width, XY[1])
|
||||||
|
elif self.Position[1] == 'c':
|
||||||
|
XY = (XY[0] + (w - self.Width)/2, XY[1])
|
||||||
|
|
||||||
|
dc.DrawBitmapPoint(self.Bitmap, XY, True)
|
||||||
|
|
||||||
|
class GridGroup:
|
||||||
|
def __init__(self, grids=[]):
|
||||||
|
self.Grids = grids
|
||||||
|
|
||||||
|
def _Draw(self, *args):
|
||||||
|
for grid in self.Grids:
|
||||||
|
grid._Draw(*args)
|
||||||
|
|
||||||
|
class DrawFrame(wx.Frame):
|
||||||
|
|
||||||
|
"""
|
||||||
|
A frame used for the FloatCanvas Demo
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
wx.Frame.__init__(self, *args, **kwargs)
|
||||||
|
|
||||||
|
self.CreateStatusBar()
|
||||||
|
|
||||||
|
# Add the Canvas
|
||||||
|
Canvas = NavCanvas.NavCanvas(self,-1,
|
||||||
|
size = (500,500),
|
||||||
|
ProjectionFun = None,
|
||||||
|
Debug = 0,
|
||||||
|
BackgroundColor = "DARK SLATE BLUE",
|
||||||
|
).Canvas
|
||||||
|
|
||||||
|
|
||||||
|
Point = (45,40)
|
||||||
|
Box = Canvas.AddCircle(Point,
|
||||||
|
Diameter = 10,
|
||||||
|
FillColor = "Black",
|
||||||
|
LineColor = "Red",
|
||||||
|
LineWidth = 6)
|
||||||
|
bmp = wx.Bitmap('NOAA.png')
|
||||||
|
grids = GridGroup([PixelBitmap(bmp, (10, 10), Position='tl'),
|
||||||
|
PixelBitmap(bmp, (10, 10), Position='br'),
|
||||||
|
PixelBitmap(bmp, (10, 10), Position='tr'),
|
||||||
|
PixelBitmap(bmp, (10, 10), Position='bl'),
|
||||||
|
PixelBitmap(bmp, (10, 10), Position='cl'),
|
||||||
|
PixelBitmap(bmp, (10, 10), Position='cr'),
|
||||||
|
PixelBitmap(bmp, (10, 10), Position='cc'),
|
||||||
|
PixelBitmap(bmp, (10, 10), Position='tc'),
|
||||||
|
PixelBitmap(bmp, (10, 10), Position='bc'),
|
||||||
|
])
|
||||||
|
Canvas.GridOver = grids
|
||||||
|
|
||||||
|
FloatCanvas.EVT_MOTION(Canvas, self.OnMove )
|
||||||
|
|
||||||
|
self.Show()
|
||||||
|
Canvas.ZoomToBB()
|
||||||
|
|
||||||
|
def OnMove(self, event):
|
||||||
|
"""
|
||||||
|
Updates the status bar with the world coordinates
|
||||||
|
|
||||||
|
"""
|
||||||
|
self.SetStatusText("%.2f, %.2f"%tuple(event.Coords))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
app = wx.App(False) # true to get its own output window.
|
||||||
|
F = DrawFrame(None, title="FloatCanvas Demo App", size=(700,700) )
|
||||||
|
app.MainLoop()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
81
samples/floatcanvas/PointsHitDemo.py
Executable file
81
samples/floatcanvas/PointsHitDemo.py
Executable file
@@ -0,0 +1,81 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import wx
|
||||||
|
|
||||||
|
## import the installed version
|
||||||
|
from wx.lib.floatcanvas import NavCanvas, FloatCanvas
|
||||||
|
|
||||||
|
## import a local version
|
||||||
|
#import sys
|
||||||
|
#sys.path.append("../")
|
||||||
|
#from floatcanvas import NavCanvas, FloatCanvas
|
||||||
|
|
||||||
|
|
||||||
|
class DrawFrame(wx.Frame):
|
||||||
|
|
||||||
|
"""
|
||||||
|
A frame used for the FloatCanvas Demo
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
wx.Frame.__init__(self, *args, **kwargs)
|
||||||
|
|
||||||
|
self.CreateStatusBar()
|
||||||
|
|
||||||
|
# Add the Canvas
|
||||||
|
Canvas = NavCanvas.NavCanvas(self,-1,
|
||||||
|
size = (500,500),
|
||||||
|
ProjectionFun = None,
|
||||||
|
Debug = 0,
|
||||||
|
BackgroundColor = "DARK SLATE BLUE",
|
||||||
|
).Canvas
|
||||||
|
|
||||||
|
self.Canvas = Canvas
|
||||||
|
|
||||||
|
FloatCanvas.EVT_MOTION(self.Canvas, self.OnMove )
|
||||||
|
|
||||||
|
Pts = ((45,40), (20, 15), (10, 40), (30,30))
|
||||||
|
|
||||||
|
Points = Canvas.AddPointSet(Pts, Diameter=3, Color="Red")
|
||||||
|
Points.HitLineWidth = 10
|
||||||
|
|
||||||
|
Points.Bind(FloatCanvas.EVT_FC_ENTER_OBJECT, self.OnOverPoints)
|
||||||
|
Points.Bind(FloatCanvas.EVT_FC_LEAVE_OBJECT, self.OnLeavePoints)
|
||||||
|
Points.Bind(FloatCanvas.EVT_FC_LEFT_DOWN, self.OnLeftDown)
|
||||||
|
|
||||||
|
self.Show()
|
||||||
|
Canvas.ZoomToBB()
|
||||||
|
|
||||||
|
def OnOverPoints(self, obj):
|
||||||
|
print "Mouse over point: ", obj.FindClosestPoint(obj.HitCoords)
|
||||||
|
|
||||||
|
def OnLeavePoints(self, obj):
|
||||||
|
print "Mouse left point: ", obj.FindClosestPoint(obj.HitCoords)
|
||||||
|
|
||||||
|
def OnLeftDown(self, obj):
|
||||||
|
print "Mouse left down on point: ", obj.FindClosestPoint(obj.HitCoords)
|
||||||
|
|
||||||
|
def OnMove(self, event):
|
||||||
|
"""
|
||||||
|
Updates the status bar with the world coordinates
|
||||||
|
|
||||||
|
"""
|
||||||
|
self.SetStatusText("%.2f, %.2f"%tuple(event.Coords))
|
||||||
|
|
||||||
|
app = wx.App(False)
|
||||||
|
F = DrawFrame(None, title="FloatCanvas Demo App", size=(700,700) )
|
||||||
|
app.MainLoop()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
255
samples/floatcanvas/PolyEditor.py
Executable file
255
samples/floatcanvas/PolyEditor.py
Executable file
@@ -0,0 +1,255 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
PolyEditor: a simple app for editing polygons
|
||||||
|
|
||||||
|
Used as a demo for FloatCanvas
|
||||||
|
"""
|
||||||
|
import numpy as N
|
||||||
|
import random
|
||||||
|
import numpy.random as RandomArray
|
||||||
|
|
||||||
|
from wx.lib.floatcanvas import NavCanvas, FloatCanvas
|
||||||
|
|
||||||
|
# import a local copy:
|
||||||
|
#import sys
|
||||||
|
#sys.path.append("..")
|
||||||
|
#from floatcanvas import NavCanvas, FloatCanvas
|
||||||
|
|
||||||
|
import wx
|
||||||
|
|
||||||
|
ID_ABOUT_MENU = wx.ID_ABOUT
|
||||||
|
ID_ZOOM_TO_FIT_MENU = wx.NewId()
|
||||||
|
|
||||||
|
class DrawFrame(wx.Frame):
|
||||||
|
|
||||||
|
"""
|
||||||
|
A frame used for the FloatCanvas Demo
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self,parent, id,title,position,size):
|
||||||
|
wx.Frame.__init__(self,parent, id,title,position, size)
|
||||||
|
|
||||||
|
## Set up the MenuBar
|
||||||
|
MenuBar = wx.MenuBar()
|
||||||
|
|
||||||
|
FileMenu = wx.Menu()
|
||||||
|
FileMenu.Append(wx.NewId(), "&Close","Close Application")
|
||||||
|
wx.EVT_MENU(self, FileMenu.FindItem("Close"), self.OnQuit)
|
||||||
|
|
||||||
|
MenuBar.Append(FileMenu, "&File")
|
||||||
|
|
||||||
|
view_menu = wx.Menu()
|
||||||
|
view_menu.Append(wx.NewId(), "Zoom to &Fit","Zoom to fit the window")
|
||||||
|
wx.EVT_MENU(self, view_menu.FindItem("Zoom to &Fit"), self.ZoomToFit)
|
||||||
|
MenuBar.Append(view_menu, "&View")
|
||||||
|
|
||||||
|
help_menu = wx.Menu()
|
||||||
|
help_menu.Append(ID_ABOUT_MENU, "&About",
|
||||||
|
"More information About this program")
|
||||||
|
wx.EVT_MENU(self, ID_ABOUT_MENU, self.OnAbout)
|
||||||
|
MenuBar.Append(help_menu, "&Help")
|
||||||
|
|
||||||
|
self.SetMenuBar(MenuBar)
|
||||||
|
|
||||||
|
self.CreateStatusBar()
|
||||||
|
# Add the Canvas
|
||||||
|
self.Canvas = NavCanvas.NavCanvas(self,-1,(500,500),
|
||||||
|
Debug = 0,
|
||||||
|
BackgroundColor = "DARK SLATE BLUE"
|
||||||
|
).Canvas
|
||||||
|
|
||||||
|
wx.EVT_CLOSE(self, self.OnCloseWindow)
|
||||||
|
|
||||||
|
FloatCanvas.EVT_MOTION(self.Canvas, self.OnMove )
|
||||||
|
FloatCanvas.EVT_LEFT_UP(self.Canvas, self.OnLeftUp )
|
||||||
|
FloatCanvas.EVT_LEFT_DOWN(self.Canvas, self.OnLeftClick )
|
||||||
|
|
||||||
|
self.ResetSelections()
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
def ResetSelections(self):
|
||||||
|
self.SelectedPoly = None
|
||||||
|
self.SelectedPolyOrig = None
|
||||||
|
self.SelectedPoints = None
|
||||||
|
self.PointSelected = False
|
||||||
|
self.SelectedPointNeighbors = None
|
||||||
|
|
||||||
|
def OnAbout(self, event):
|
||||||
|
dlg = wx.MessageDialog(self, "This is a small program to demonstrate\n"
|
||||||
|
"the use of the FloatCanvas\n",
|
||||||
|
"About Me", wx.OK | wx.ICON_INFORMATION)
|
||||||
|
dlg.ShowModal()
|
||||||
|
dlg.Destroy()
|
||||||
|
|
||||||
|
def ZoomToFit(self,event):
|
||||||
|
self.Canvas.ZoomToBB()
|
||||||
|
|
||||||
|
def Clear(self,event = None):
|
||||||
|
self.Canvas.ClearAll()
|
||||||
|
self.Canvas.SetProjectionFun(None)
|
||||||
|
self.Canvas.Draw()
|
||||||
|
|
||||||
|
def OnQuit(self,event):
|
||||||
|
self.Close(True)
|
||||||
|
|
||||||
|
def OnCloseWindow(self, event):
|
||||||
|
self.Destroy()
|
||||||
|
|
||||||
|
def OnMove(self, event):
|
||||||
|
"""
|
||||||
|
Updates the status bar with the world coordinates
|
||||||
|
|
||||||
|
And moves a point if there is one selected
|
||||||
|
|
||||||
|
"""
|
||||||
|
self.SetStatusText("%.2f, %.2f"%tuple(event.Coords))
|
||||||
|
|
||||||
|
if self.PointSelected:
|
||||||
|
PolyPoints = self.SelectedPoly.Points
|
||||||
|
Index = self.SelectedPoints.Index
|
||||||
|
dc = wx.ClientDC(self.Canvas)
|
||||||
|
PixelCoords = event.GetPosition()
|
||||||
|
dc.SetPen(wx.Pen('WHITE', 2, wx.SHORT_DASH))
|
||||||
|
dc.SetLogicalFunction(wx.XOR)
|
||||||
|
if self.SelectedPointNeighbors is None:
|
||||||
|
self.SelectedPointNeighbors = N.zeros((3,2), N.float_)
|
||||||
|
#fixme: This feels very inelegant!
|
||||||
|
if Index == 0:
|
||||||
|
self.SelectedPointNeighbors[0] = self.SelectedPoly.Points[-1]
|
||||||
|
self.SelectedPointNeighbors[1:3] = self.SelectedPoly.Points[:2]
|
||||||
|
elif Index == len(self.SelectedPoly.Points)-1:
|
||||||
|
self.SelectedPointNeighbors[0:2] = self.SelectedPoly.Points[-2:]
|
||||||
|
self.SelectedPointNeighbors[2] = self.SelectedPoly.Points[0]
|
||||||
|
else:
|
||||||
|
self.SelectedPointNeighbors = self.SelectedPoly.Points[Index-1:Index+2]
|
||||||
|
self.SelectedPointNeighbors = self.Canvas.WorldToPixel(self.SelectedPointNeighbors)
|
||||||
|
else:
|
||||||
|
dc.DrawLines(self.SelectedPointNeighbors)
|
||||||
|
self.SelectedPointNeighbors[1] = PixelCoords
|
||||||
|
dc.DrawLines(self.SelectedPointNeighbors)
|
||||||
|
|
||||||
|
|
||||||
|
def OnLeftUp(self, event):
|
||||||
|
## if a point was selected, it's not anymore
|
||||||
|
if self.PointSelected:
|
||||||
|
self.SelectedPoly.Points[self.SelectedPoints.Index] = event.GetCoords()
|
||||||
|
self.SelectedPoly.SetPoints(self.SelectedPoly.Points, copy = False)
|
||||||
|
self.SelectedPoints.SetPoints(self.SelectedPoly.Points, copy = False)
|
||||||
|
self.PointSelected = False
|
||||||
|
self.SelectedPointNeighbors = None
|
||||||
|
self.Canvas.Draw()
|
||||||
|
|
||||||
|
def OnLeftClick(self,event):
|
||||||
|
## If a click happens outside the polygon, it's no longer selected
|
||||||
|
self.DeSelectPoly()
|
||||||
|
self.Canvas.Draw()
|
||||||
|
|
||||||
|
def Setup(self, event = None):
|
||||||
|
"Seting up with some random polygons"
|
||||||
|
wx.GetApp().Yield()
|
||||||
|
self.ResetSelections()
|
||||||
|
self.Canvas.ClearAll()
|
||||||
|
|
||||||
|
Range = (-10,10)
|
||||||
|
|
||||||
|
# Create a couple of random Polygons
|
||||||
|
for i, color in enumerate(("LightBlue", "Green", "Purple","Yellow")):
|
||||||
|
points = RandomArray.uniform(Range[0],Range[1],(6,2))
|
||||||
|
Poly = self.Canvas.AddPolygon(points,
|
||||||
|
LineWidth = 2,
|
||||||
|
LineColor = "Black",
|
||||||
|
FillColor = color,
|
||||||
|
FillStyle = 'Solid')
|
||||||
|
|
||||||
|
Poly.Bind(FloatCanvas.EVT_FC_LEFT_DOWN, self.SelectPoly)
|
||||||
|
self.Canvas.ZoomToBB()
|
||||||
|
|
||||||
|
|
||||||
|
def SelectPoly(self, Object):
|
||||||
|
Canvas = self.Canvas
|
||||||
|
if Object is self.SelectedPolyOrig:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
if self.SelectedPoly:
|
||||||
|
self.DeSelectPoly()
|
||||||
|
self.SelectedPolyOrig = Object
|
||||||
|
self.SelectedPoly = Canvas.AddPolygon(Object.Points,
|
||||||
|
LineWidth = 2,
|
||||||
|
LineColor = "Red",
|
||||||
|
FillColor = "Red",
|
||||||
|
FillStyle = "CrossHatch",
|
||||||
|
InForeground = True)
|
||||||
|
# Draw points on the Vertices of the Selected Poly:
|
||||||
|
self.SelectedPoints = Canvas.AddPointSet(Object.Points,
|
||||||
|
Diameter = 6,
|
||||||
|
Color = "Red",
|
||||||
|
InForeground = True)
|
||||||
|
self.SelectedPoints.Bind(FloatCanvas.EVT_FC_LEFT_DOWN, self.SelectPointHit)
|
||||||
|
Canvas.Draw()
|
||||||
|
|
||||||
|
def DeSelectPoly(self):
|
||||||
|
Canvas = self.Canvas
|
||||||
|
if self.SelectedPolyOrig is not None:
|
||||||
|
self.SelectedPolyOrig.SetPoints(self.SelectedPoly.Points, copy = False)
|
||||||
|
self.Canvas.Draw(Force = True)
|
||||||
|
Canvas.RemoveObject(self.SelectedPoly)
|
||||||
|
Canvas.RemoveObject(self.SelectedPoints)
|
||||||
|
self.ResetSelections()
|
||||||
|
|
||||||
|
def SelectPointHit(self, PointSet):
|
||||||
|
PointSet.Index = PointSet.FindClosestPoint(PointSet.HitCoords)
|
||||||
|
print "point #%i hit"%PointSet.Index
|
||||||
|
#Index = PointSet.Index
|
||||||
|
self.PointSelected = True
|
||||||
|
|
||||||
|
class PolyEditor(wx.App):
|
||||||
|
"""
|
||||||
|
|
||||||
|
A simple example of making editable shapes with FloatCanvas
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def OnInit(self):
|
||||||
|
wx.InitAllImageHandlers()
|
||||||
|
frame = DrawFrame(None,
|
||||||
|
-1,
|
||||||
|
"FloatCanvas Demo App",
|
||||||
|
wx.DefaultPosition,
|
||||||
|
(700,700),
|
||||||
|
)
|
||||||
|
|
||||||
|
self.SetTopWindow(frame)
|
||||||
|
frame.Show()
|
||||||
|
|
||||||
|
frame.Setup()
|
||||||
|
return True
|
||||||
|
|
||||||
|
PolyEditor(0).MainLoop()# put in True if you want output to go to it's own window.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
379
samples/floatcanvas/ProcessDiagram.py
Normal file
379
samples/floatcanvas/ProcessDiagram.py
Normal file
@@ -0,0 +1,379 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
"""
|
||||||
|
|
||||||
|
This is a demo, showing how to work with a "tree" structure
|
||||||
|
|
||||||
|
It demonstrates moving objects around, etc, etc.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
import wx
|
||||||
|
|
||||||
|
#ver = 'local'
|
||||||
|
ver = 'installed'
|
||||||
|
|
||||||
|
if ver == 'installed': ## import the installed version
|
||||||
|
from wx.lib.floatcanvas import NavCanvas, Resources
|
||||||
|
from wx.lib.floatcanvas import FloatCanvas as FC
|
||||||
|
from wx.lib.floatcanvas.Utilities import BBox
|
||||||
|
print "using installed version:", wx.lib.floatcanvas.__version__
|
||||||
|
elif ver == 'local':
|
||||||
|
## import a local version
|
||||||
|
import sys
|
||||||
|
sys.path.append("..")
|
||||||
|
from floatcanvas import NavCanvas, Resources
|
||||||
|
from floatcanvas import FloatCanvas as FC
|
||||||
|
from floatcanvas.Utilities import BBox
|
||||||
|
|
||||||
|
import numpy as N
|
||||||
|
|
||||||
|
## here we create some new mixins:
|
||||||
|
## fixme: These really belong in floatcanvas package -- but I kind of want to clean it up some first
|
||||||
|
|
||||||
|
class MovingObjectMixin:
|
||||||
|
"""
|
||||||
|
Methods required for a Moving object
|
||||||
|
|
||||||
|
"""
|
||||||
|
def GetOutlinePoints(self):
|
||||||
|
"""
|
||||||
|
Returns a set of points with which to draw the outline when moving the
|
||||||
|
object.
|
||||||
|
|
||||||
|
Points are a NX2 array of (x,y) points in World coordinates.
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
BB = self.BoundingBox
|
||||||
|
OutlinePoints = N.array( ( (BB[0,0], BB[0,1]),
|
||||||
|
(BB[0,0], BB[1,1]),
|
||||||
|
(BB[1,0], BB[1,1]),
|
||||||
|
(BB[1,0], BB[0,1]),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
return OutlinePoints
|
||||||
|
|
||||||
|
class ConnectorObjectMixin:
|
||||||
|
"""
|
||||||
|
Mixin class for DrawObjects that can be connected with lines
|
||||||
|
|
||||||
|
Note that this version only works for Objects that have an "XY" attribute:
|
||||||
|
that is, one that is derived from XHObjectMixin.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def GetConnectPoint(self):
|
||||||
|
return self.XY
|
||||||
|
|
||||||
|
class MovingBitmap(FC.ScaledBitmap, MovingObjectMixin, ConnectorObjectMixin):
|
||||||
|
"""
|
||||||
|
ScaledBitmap Object that can be moved
|
||||||
|
"""
|
||||||
|
## All we need to do is is inherit from:
|
||||||
|
## ScaledBitmap, MovingObjectMixin and ConnectorObjectMixin
|
||||||
|
pass
|
||||||
|
|
||||||
|
class MovingCircle(FC.Circle, MovingObjectMixin, ConnectorObjectMixin):
|
||||||
|
"""
|
||||||
|
ScaledBitmap Object that can be moved
|
||||||
|
"""
|
||||||
|
## All we need to do is is inherit from:
|
||||||
|
## Circle MovingObjectMixin and ConnectorObjectMixin
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class MovingGroup(FC.Group, MovingObjectMixin, ConnectorObjectMixin):
|
||||||
|
|
||||||
|
def GetConnectPoint(self):
|
||||||
|
return self.BoundingBox.Center
|
||||||
|
|
||||||
|
class NodeObject(FC.Group, MovingObjectMixin, ConnectorObjectMixin):
|
||||||
|
"""
|
||||||
|
A version of the moving group for nodes -- an ellipse with text on it.
|
||||||
|
"""
|
||||||
|
def __init__(self,
|
||||||
|
Label,
|
||||||
|
XY,
|
||||||
|
WH,
|
||||||
|
BackgroundColor = "Yellow",
|
||||||
|
TextColor = "Black",
|
||||||
|
InForeground = False,
|
||||||
|
IsVisible = True):
|
||||||
|
XY = N.asarray(XY, N.float).reshape(2,)
|
||||||
|
WH = N.asarray(WH, N.float).reshape(2,)
|
||||||
|
Label = FC.ScaledText(Label,
|
||||||
|
XY,
|
||||||
|
Size = WH[1] / 2.0,
|
||||||
|
Color = TextColor,
|
||||||
|
Position = 'cc',
|
||||||
|
)
|
||||||
|
self.Ellipse = FC.Ellipse( (XY - WH/2.0),
|
||||||
|
WH,
|
||||||
|
FillColor = BackgroundColor,
|
||||||
|
LineStyle = None,
|
||||||
|
)
|
||||||
|
FC.Group.__init__(self, [self.Ellipse, Label], InForeground, IsVisible)
|
||||||
|
|
||||||
|
def GetConnectPoint(self):
|
||||||
|
return self.BoundingBox.Center
|
||||||
|
|
||||||
|
|
||||||
|
class MovingText(FC.ScaledText, MovingObjectMixin, ConnectorObjectMixin):
|
||||||
|
"""
|
||||||
|
ScaledBitmap Object that can be moved
|
||||||
|
"""
|
||||||
|
## All we need to do is is inherit from:
|
||||||
|
## ScaledBitmap, MovingObjectMixin and ConnectorObjectMixin
|
||||||
|
pass
|
||||||
|
|
||||||
|
class MovingTextBox(FC.ScaledTextBox, MovingObjectMixin, ConnectorObjectMixin):
|
||||||
|
"""
|
||||||
|
ScaledBitmap Object that can be moved
|
||||||
|
"""
|
||||||
|
## All we need to do is is inherit from:
|
||||||
|
## ScaledBitmap, MovingObjectMixin and ConnectorObjectMixin
|
||||||
|
pass
|
||||||
|
|
||||||
|
class ConnectorLine(FC.LineOnlyMixin, FC.DrawObject,):
|
||||||
|
"""
|
||||||
|
|
||||||
|
A Line that connects two objects -- it uses the objects to get its coordinates
|
||||||
|
The objects must have a GetConnectPoint() method.
|
||||||
|
|
||||||
|
"""
|
||||||
|
##fixme: this should be added to the Main FloatCanvas Objects some day.
|
||||||
|
def __init__(self,
|
||||||
|
Object1,
|
||||||
|
Object2,
|
||||||
|
LineColor = "Black",
|
||||||
|
LineStyle = "Solid",
|
||||||
|
LineWidth = 1,
|
||||||
|
InForeground = False):
|
||||||
|
FC.DrawObject.__init__(self, InForeground)
|
||||||
|
|
||||||
|
self.Object1 = Object1
|
||||||
|
self.Object2 = Object2
|
||||||
|
self.LineColor = LineColor
|
||||||
|
self.LineStyle = LineStyle
|
||||||
|
self.LineWidth = LineWidth
|
||||||
|
|
||||||
|
self.CalcBoundingBox()
|
||||||
|
self.SetPen(LineColor,LineStyle,LineWidth)
|
||||||
|
|
||||||
|
self.HitLineWidth = max(LineWidth,self.MinHitLineWidth)
|
||||||
|
|
||||||
|
def CalcBoundingBox(self):
|
||||||
|
self.BoundingBox = BBox.fromPoints((self.Object1.GetConnectPoint(),
|
||||||
|
self.Object2.GetConnectPoint()) )
|
||||||
|
if self._Canvas:
|
||||||
|
self._Canvas.BoundingBoxDirty = True
|
||||||
|
|
||||||
|
|
||||||
|
def _Draw(self, dc , WorldToPixel, ScaleWorldToPixel, HTdc=None):
|
||||||
|
Points = N.array( (self.Object1.GetConnectPoint(),
|
||||||
|
self.Object2.GetConnectPoint()) )
|
||||||
|
Points = WorldToPixel(Points)
|
||||||
|
dc.SetPen(self.Pen)
|
||||||
|
dc.DrawLines(Points)
|
||||||
|
if HTdc and self.HitAble:
|
||||||
|
HTdc.SetPen(self.HitPen)
|
||||||
|
HTdc.DrawLines(Points)
|
||||||
|
|
||||||
|
|
||||||
|
class TriangleShape1(FC.Polygon, MovingObjectMixin):
|
||||||
|
|
||||||
|
def __init__(self, XY, L):
|
||||||
|
|
||||||
|
"""
|
||||||
|
An equilateral triangle object
|
||||||
|
XY is the middle of the triangle
|
||||||
|
L is the length of one side of the Triangle
|
||||||
|
"""
|
||||||
|
|
||||||
|
XY = N.asarray(XY)
|
||||||
|
XY.shape = (2,)
|
||||||
|
|
||||||
|
Points = self.CompPoints(XY, L)
|
||||||
|
|
||||||
|
FC.Polygon.__init__(self, Points,
|
||||||
|
LineColor = "Black",
|
||||||
|
LineStyle = "Solid",
|
||||||
|
LineWidth = 2,
|
||||||
|
FillColor = "Red",
|
||||||
|
FillStyle = "Solid")
|
||||||
|
## Override the default OutlinePoints
|
||||||
|
def GetOutlinePoints(self):
|
||||||
|
return self.Points
|
||||||
|
|
||||||
|
def CompPoints(self, XY, L):
|
||||||
|
c = L/ N.sqrt(3)
|
||||||
|
|
||||||
|
Points = N.array(((0, c),
|
||||||
|
( L/2.0, -c/2.0),
|
||||||
|
(-L/2.0, -c/2.0)),
|
||||||
|
N.float_)
|
||||||
|
|
||||||
|
Points += XY
|
||||||
|
return Points
|
||||||
|
|
||||||
|
### Tree Utilities
|
||||||
|
### And some hard coded data...
|
||||||
|
|
||||||
|
class TreeNode:
|
||||||
|
dx = 15
|
||||||
|
dy = 4
|
||||||
|
def __init__(self, name, Children = []):
|
||||||
|
self.Name = name
|
||||||
|
#self.parent = None -- Is this needed?
|
||||||
|
self.Children = Children
|
||||||
|
self.Point = None # The coords of the node.
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return "TreeNode: %s"%self.Name
|
||||||
|
__repr__ = __str__
|
||||||
|
|
||||||
|
|
||||||
|
## Build Tree:
|
||||||
|
leaves = [TreeNode(name) for name in ["Assistant VP 1","Assistant VP 2","Assistant VP 3"] ]
|
||||||
|
VP1 = TreeNode("VP1", Children = leaves)
|
||||||
|
VP2 = TreeNode("VP2")
|
||||||
|
|
||||||
|
CEO = TreeNode("CEO", [VP1, VP2])
|
||||||
|
Father = TreeNode("Father", [TreeNode("Daughter"), TreeNode("Son")])
|
||||||
|
elements = TreeNode("Root", [CEO, Father])
|
||||||
|
|
||||||
|
def LayoutTree(root, x, y, level):
|
||||||
|
NumNodes = len(root.Children)
|
||||||
|
root.Point = (x,y)
|
||||||
|
x += root.dx
|
||||||
|
y += (root.dy * level * (NumNodes-1) / 2.0)
|
||||||
|
for node in root.Children:
|
||||||
|
LayoutTree(node, x, y, level-1)
|
||||||
|
y -= root.dy * level
|
||||||
|
|
||||||
|
def TraverseTree(root, func):
|
||||||
|
func(root)
|
||||||
|
for child in (root.Children):
|
||||||
|
TraverseTree(child, func)
|
||||||
|
|
||||||
|
class DrawFrame(wx.Frame):
|
||||||
|
|
||||||
|
"""
|
||||||
|
A simple frame used for the Demo
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
wx.Frame.__init__(self, *args, **kwargs)
|
||||||
|
|
||||||
|
self.CreateStatusBar()
|
||||||
|
# Add the Canvas
|
||||||
|
Canvas = NavCanvas.NavCanvas(self,-1,(500,500),
|
||||||
|
ProjectionFun = None,
|
||||||
|
Debug = 0,
|
||||||
|
BackgroundColor = "White",
|
||||||
|
).Canvas
|
||||||
|
|
||||||
|
self.Canvas = Canvas
|
||||||
|
|
||||||
|
|
||||||
|
Canvas.Bind(FC.EVT_MOTION, self.OnMove )
|
||||||
|
Canvas.Bind(FC.EVT_LEFT_UP, self.OnLeftUp )
|
||||||
|
|
||||||
|
self.elements = elements
|
||||||
|
LayoutTree(self.elements, 0, 0, 3)
|
||||||
|
self.AddTree(self.elements)
|
||||||
|
|
||||||
|
|
||||||
|
self.Show(True)
|
||||||
|
self.Canvas.ZoomToBB()
|
||||||
|
|
||||||
|
self.MoveObject = None
|
||||||
|
self.Moving = False
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
def AddTree(self, root):
|
||||||
|
Nodes = []
|
||||||
|
Connectors = []
|
||||||
|
EllipseW = 15
|
||||||
|
EllipseH = 4
|
||||||
|
def CreateObject(node):
|
||||||
|
if node.Children:
|
||||||
|
object = NodeObject(node.Name,
|
||||||
|
node.Point,
|
||||||
|
(15, 4),
|
||||||
|
BackgroundColor = "Yellow",
|
||||||
|
TextColor = "Black",
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
object = MovingTextBox(node.Name,
|
||||||
|
node.Point,
|
||||||
|
2.0,
|
||||||
|
BackgroundColor = "White",
|
||||||
|
Color = "Black",
|
||||||
|
Position = "cl",
|
||||||
|
PadSize = 1
|
||||||
|
)
|
||||||
|
node.DrawObject = object
|
||||||
|
Nodes.append(object)
|
||||||
|
def AddConnectors(node):
|
||||||
|
for child in node.Children:
|
||||||
|
Connector = ConnectorLine(node.DrawObject, child.DrawObject, LineWidth=3, LineColor="Red")
|
||||||
|
Connectors.append(Connector)
|
||||||
|
## create the Objects
|
||||||
|
TraverseTree(root, CreateObject)
|
||||||
|
## create the Connectors
|
||||||
|
TraverseTree(root, AddConnectors)
|
||||||
|
## Add the conenctos to the Canvas first, so they are undernieth the nodes
|
||||||
|
self.Canvas.AddObjects(Connectors)
|
||||||
|
## now add the nodes
|
||||||
|
self.Canvas.AddObjects(Nodes)
|
||||||
|
# Now bind the Nodes -- DrawObjects must be Added to a Canvas before they can be bound.
|
||||||
|
for node in Nodes:
|
||||||
|
#pass
|
||||||
|
node.Bind(FC.EVT_FC_LEFT_DOWN, self.ObjectHit)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def ObjectHit(self, object):
|
||||||
|
if not self.Moving:
|
||||||
|
self.Moving = True
|
||||||
|
self.StartPoint = object.HitCoordsPixel
|
||||||
|
self.StartObject = self.Canvas.WorldToPixel(object.GetOutlinePoints())
|
||||||
|
self.MoveObject = None
|
||||||
|
self.MovingObject = object
|
||||||
|
|
||||||
|
def OnMove(self, event):
|
||||||
|
"""
|
||||||
|
Updates the status bar with the world coordinates
|
||||||
|
and moves the object it is clicked on
|
||||||
|
|
||||||
|
"""
|
||||||
|
self.SetStatusText("%.4f, %.4f"%tuple(event.Coords))
|
||||||
|
|
||||||
|
if self.Moving:
|
||||||
|
dxy = event.GetPosition() - self.StartPoint
|
||||||
|
# Draw the Moving Object:
|
||||||
|
dc = wx.ClientDC(self.Canvas)
|
||||||
|
dc.SetPen(wx.Pen('WHITE', 2, wx.SHORT_DASH))
|
||||||
|
dc.SetBrush(wx.TRANSPARENT_BRUSH)
|
||||||
|
dc.SetLogicalFunction(wx.XOR)
|
||||||
|
if self.MoveObject is not None:
|
||||||
|
dc.DrawPolygon(self.MoveObject)
|
||||||
|
self.MoveObject = self.StartObject + dxy
|
||||||
|
dc.DrawPolygon(self.MoveObject)
|
||||||
|
|
||||||
|
def OnLeftUp(self, event):
|
||||||
|
if self.Moving:
|
||||||
|
self.Moving = False
|
||||||
|
if self.MoveObject is not None:
|
||||||
|
dxy = event.GetPosition() - self.StartPoint
|
||||||
|
dxy = self.Canvas.ScalePixelToWorld(dxy)
|
||||||
|
self.MovingObject.Move(dxy)
|
||||||
|
self.Canvas.Draw(True)
|
||||||
|
|
||||||
|
app = wx.PySimpleApp(0)
|
||||||
|
DrawFrame(None, -1, "FloatCanvas Tree Demo App", wx.DefaultPosition, (700,700) )
|
||||||
|
app.MainLoop()
|
||||||
100
samples/floatcanvas/ScaleDemo.py
Normal file
100
samples/floatcanvas/ScaleDemo.py
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
This demonstrates how to use FloatCanvas with a coordinate system where
|
||||||
|
X and Y have different scales. In the example, a user had:
|
||||||
|
|
||||||
|
X data in the range: 50e-6 to 2000e-6
|
||||||
|
Y data in the range: 0 to 50000
|
||||||
|
|
||||||
|
-chb
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
import wx
|
||||||
|
|
||||||
|
## import the installed version
|
||||||
|
from wx.lib.floatcanvas import NavCanvas, FloatCanvas
|
||||||
|
|
||||||
|
## import a local version
|
||||||
|
#import sys
|
||||||
|
#sys.path.append("..")
|
||||||
|
#from floatcanvas import NavCanvas, FloatCanvas
|
||||||
|
|
||||||
|
|
||||||
|
import numpy as N
|
||||||
|
|
||||||
|
def YScaleFun(center):
|
||||||
|
"""
|
||||||
|
function that returns a scaling vector to scale y data to same range as x data
|
||||||
|
|
||||||
|
"""
|
||||||
|
# center gets ignored in this case
|
||||||
|
return N.array((5e7, 1), N.float)
|
||||||
|
|
||||||
|
class DrawFrame(wx.Frame):
|
||||||
|
|
||||||
|
"""
|
||||||
|
A frame used for the FloatCanvas Demo
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
wx.Frame.__init__(self, *args, **kwargs)
|
||||||
|
|
||||||
|
self.CreateStatusBar()
|
||||||
|
|
||||||
|
# Add the Canvas
|
||||||
|
Canvas = NavCanvas.NavCanvas(self,-1,
|
||||||
|
size = (500,500),
|
||||||
|
ProjectionFun = YScaleFun,
|
||||||
|
Debug = 0,
|
||||||
|
BackgroundColor = "DARK SLATE BLUE",
|
||||||
|
).Canvas
|
||||||
|
|
||||||
|
self.Canvas = Canvas
|
||||||
|
|
||||||
|
Point = N.array((50e-6, 0))
|
||||||
|
Size = N.array(( (2000e-6 - 5e-6), 50000))
|
||||||
|
Box = Canvas.AddRectangle(Point,
|
||||||
|
Size,
|
||||||
|
FillColor = "blue"
|
||||||
|
)
|
||||||
|
|
||||||
|
Canvas.AddText("%s"%(Point,), Point, Position="cr")
|
||||||
|
Canvas.AddPoint(Point, Diameter=3, Color = "red")
|
||||||
|
|
||||||
|
|
||||||
|
Point = Point + Size
|
||||||
|
Canvas.AddText("%s"%(Point,), Point, Position="cl")
|
||||||
|
Canvas.AddPoint(Point, Diameter=3, Color = "red")
|
||||||
|
|
||||||
|
FloatCanvas.EVT_MOTION(self.Canvas, self.OnMove )
|
||||||
|
|
||||||
|
|
||||||
|
self.Show()
|
||||||
|
Canvas.ZoomToBB()
|
||||||
|
|
||||||
|
def OnMove(self, event):
|
||||||
|
"""
|
||||||
|
Updates the status bar with the world coordinates
|
||||||
|
"""
|
||||||
|
self.SetStatusText("%.2g, %.2g"%tuple(event.Coords))
|
||||||
|
|
||||||
|
|
||||||
|
app = wx.App(False)
|
||||||
|
F = DrawFrame(None, title="FloatCanvas Demo App", size=(700,700) )
|
||||||
|
app.MainLoop()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
83
samples/floatcanvas/ScaledBitmap2Demo.py
Executable file
83
samples/floatcanvas/ScaledBitmap2Demo.py
Executable file
@@ -0,0 +1,83 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
This demo shows how to use a ScaledBitmap2 (which is like a scaled bitmap,
|
||||||
|
but uses memory more efficiently for large images and high zoom levels.)
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
## Set a path to an Image file here:
|
||||||
|
ImageFile = "white_tank.jpg"
|
||||||
|
|
||||||
|
|
||||||
|
import wx
|
||||||
|
import random
|
||||||
|
|
||||||
|
## import the installed version
|
||||||
|
from wx.lib.floatcanvas import NavCanvas, FloatCanvas
|
||||||
|
|
||||||
|
## import a local version
|
||||||
|
#import sys
|
||||||
|
#sys.path.append("../")
|
||||||
|
#from floatcanvas import NavCanvas, FloatCanvas
|
||||||
|
|
||||||
|
class DrawFrame(wx.Frame):
|
||||||
|
|
||||||
|
"""
|
||||||
|
A frame used for the FloatCanvas Demo
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
wx.Frame.__init__(self, *args, **kwargs)
|
||||||
|
self.CreateStatusBar()
|
||||||
|
|
||||||
|
# Add the Canvas
|
||||||
|
Canvas = NavCanvas.NavCanvas(self,
|
||||||
|
ProjectionFun = None,
|
||||||
|
BackgroundColor = "DARK SLATE BLUE",
|
||||||
|
).Canvas
|
||||||
|
Canvas.MaxScale=20 # sets the maximum zoom level
|
||||||
|
self.Canvas = Canvas
|
||||||
|
|
||||||
|
FloatCanvas.EVT_MOTION(self.Canvas, self.OnMove )
|
||||||
|
|
||||||
|
|
||||||
|
# create the image:
|
||||||
|
image = wx.Image(ImageFile)
|
||||||
|
self.width, self.height = image.GetSize()
|
||||||
|
img = FloatCanvas.ScaledBitmap2( image,
|
||||||
|
(0,0),
|
||||||
|
Height=image.GetHeight(),
|
||||||
|
Position = 'tl',
|
||||||
|
)
|
||||||
|
Canvas.AddObject(img)
|
||||||
|
|
||||||
|
self.Show()
|
||||||
|
Canvas.ZoomToBB()
|
||||||
|
|
||||||
|
def OnMove(self, event):
|
||||||
|
"""
|
||||||
|
Updates the status bar with the world coordinates
|
||||||
|
|
||||||
|
"""
|
||||||
|
self.SetStatusText("%i, %i"%tuple(event.Coords))
|
||||||
|
|
||||||
|
|
||||||
|
app = wx.App(False)
|
||||||
|
F = DrawFrame(None, title="FloatCanvas Demo App", size=(700,700) )
|
||||||
|
app.MainLoop()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
72
samples/floatcanvas/SplitterWindow.py
Normal file
72
samples/floatcanvas/SplitterWindow.py
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import wx
|
||||||
|
|
||||||
|
## import the installed version
|
||||||
|
from wx.lib.floatcanvas import NavCanvas, FloatCanvas
|
||||||
|
|
||||||
|
## import a local version
|
||||||
|
#import sys
|
||||||
|
#sys.path.append("../")
|
||||||
|
#from floatcanvas import NavCanvas, FloatCanvas
|
||||||
|
|
||||||
|
class MyFrame(wx.Frame):
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
wx.Frame.__init__(self, *args, **kwargs)
|
||||||
|
|
||||||
|
#Adding the SplitterWindow
|
||||||
|
splitter = wx.SplitterWindow(self, style=wx.SP_LIVE_UPDATE|wx.SP_3D, size = (800,400))
|
||||||
|
|
||||||
|
# add the left Panel
|
||||||
|
panel1 = wx.Panel(splitter)
|
||||||
|
panel1.SetBackgroundColour(wx.RED)
|
||||||
|
|
||||||
|
# add the Canvas
|
||||||
|
panel2 = NavCanvas.NavCanvas(splitter,
|
||||||
|
ProjectionFun = None,
|
||||||
|
Debug = 0,
|
||||||
|
BackgroundColor = "DARK SLATE BLUE",
|
||||||
|
)
|
||||||
|
Canvas = panel2.Canvas
|
||||||
|
|
||||||
|
# put something on the Canvas
|
||||||
|
Point = (15,10)
|
||||||
|
Canvas.AddScaledTextBox("A Two Line\nString",
|
||||||
|
Point,
|
||||||
|
2,
|
||||||
|
Color = "Black",
|
||||||
|
BackgroundColor = None,
|
||||||
|
LineColor = "Red",
|
||||||
|
LineStyle = "Solid",
|
||||||
|
LineWidth = 1,
|
||||||
|
Width = None,
|
||||||
|
PadSize = 5,
|
||||||
|
Family = wx.ROMAN,
|
||||||
|
Style = wx.NORMAL,
|
||||||
|
Weight = wx.NORMAL,
|
||||||
|
Underlined = False,
|
||||||
|
Position = 'br',
|
||||||
|
Alignment = "left",
|
||||||
|
InForeground = False)
|
||||||
|
|
||||||
|
wx.CallAfter(Canvas.ZoomToBB)
|
||||||
|
|
||||||
|
# set up the Splitter
|
||||||
|
sash_Position = 300
|
||||||
|
splitter.SplitVertically(panel1, panel2, sash_Position)
|
||||||
|
splitter.SetSashSize(10)
|
||||||
|
min_Pan_size = 40
|
||||||
|
splitter.SetMinimumPaneSize(min_Pan_size)
|
||||||
|
|
||||||
|
self.Fit()
|
||||||
|
|
||||||
|
|
||||||
|
class MyApp(wx.App):
|
||||||
|
def OnInit(self):
|
||||||
|
frame = MyFrame(None, title='splitter test')
|
||||||
|
frame.Show(True)
|
||||||
|
self.SetTopWindow(frame)
|
||||||
|
return True
|
||||||
|
|
||||||
|
app = MyApp(0)
|
||||||
|
app.MainLoop()
|
||||||
67
samples/floatcanvas/SubClassNavCanvas.py
Executable file
67
samples/floatcanvas/SubClassNavCanvas.py
Executable file
@@ -0,0 +1,67 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
A simple example of sub-classing the Navcanvas
|
||||||
|
|
||||||
|
-- an alternative to simply putting a NavCanvas on your yoru oen panle or whatever
|
||||||
|
"""
|
||||||
|
|
||||||
|
import wx
|
||||||
|
|
||||||
|
## import the installed version
|
||||||
|
from wx.lib.floatcanvas import NavCanvas, FloatCanvas
|
||||||
|
|
||||||
|
## import a local version
|
||||||
|
#import sys
|
||||||
|
#sys.path.append("../")
|
||||||
|
#from floatcanvas import NavCanvas, FloatCanvas
|
||||||
|
|
||||||
|
class DrawFrame(wx.Frame):
|
||||||
|
|
||||||
|
"""
|
||||||
|
A frame used for the Demo
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
wx.Frame.__init__(self, *args, **kwargs)
|
||||||
|
self.CreateStatusBar()
|
||||||
|
|
||||||
|
panel = NavPanel(self)
|
||||||
|
|
||||||
|
self.Show()
|
||||||
|
|
||||||
|
class NavPanel(NavCanvas.NavCanvas):
|
||||||
|
"""
|
||||||
|
a subclass of NavCAnvas -- with some specific drawing code
|
||||||
|
"""
|
||||||
|
def __init__(self, parent):
|
||||||
|
NavCanvas.NavCanvas.__init__(self,
|
||||||
|
parent,
|
||||||
|
ProjectionFun = None,
|
||||||
|
BackgroundColor = "DARK SLATE BLUE",
|
||||||
|
)
|
||||||
|
|
||||||
|
self.parent_frame = parent
|
||||||
|
FloatCanvas.EVT_MOTION(self.Canvas, self.OnMove )
|
||||||
|
|
||||||
|
# create the image:
|
||||||
|
self.Canvas.AddPolygon( ( (2,3),
|
||||||
|
(5,6),
|
||||||
|
(7,1), ),
|
||||||
|
FillColor = "red",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
wx.CallAfter(self.Canvas.ZoomToBB) # so it will get called after everything is created and sized
|
||||||
|
|
||||||
|
def OnMove(self, event):
|
||||||
|
"""
|
||||||
|
Updates the status bar with the world coordinates
|
||||||
|
|
||||||
|
"""
|
||||||
|
self.parent_frame.SetStatusText("%f, %f"%tuple(event.Coords))
|
||||||
|
pass
|
||||||
|
|
||||||
|
app = wx.App(False)
|
||||||
|
F = DrawFrame(None, title="FloatCanvas Demo App", size=(700,700) )
|
||||||
|
app.MainLoop()
|
||||||
185
samples/floatcanvas/TestSpline.py
Executable file
185
samples/floatcanvas/TestSpline.py
Executable file
@@ -0,0 +1,185 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
This is a very small app using the FloatCanvas
|
||||||
|
|
||||||
|
It tests the Spline object, including how you can put points together to
|
||||||
|
create an object with curves and square corners.
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
import wx
|
||||||
|
|
||||||
|
#### import local version:
|
||||||
|
#import sys
|
||||||
|
#sys.path.append("../")
|
||||||
|
#from floatcanvas import NavCanvas
|
||||||
|
#from floatcanvas import FloatCanvas as FC
|
||||||
|
|
||||||
|
from wx.lib.floatcanvas import FloatCanvas as FC
|
||||||
|
from wx.lib.floatcanvas import NavCanvas
|
||||||
|
|
||||||
|
class Spline(FC.Line):
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
FC.Line.__init__(self, *args, **kwargs)
|
||||||
|
|
||||||
|
def _Draw(self, dc , WorldToPixel, ScaleWorldToPixel, HTdc=None):
|
||||||
|
Points = WorldToPixel(self.Points)
|
||||||
|
dc.SetPen(self.Pen)
|
||||||
|
dc.DrawSpline(Points)
|
||||||
|
if HTdc and self.HitAble:
|
||||||
|
HTdc.SetPen(self.HitPen)
|
||||||
|
HTdc.DrawSpline(Points)
|
||||||
|
|
||||||
|
class DrawFrame(wx.Frame):
|
||||||
|
|
||||||
|
"""
|
||||||
|
A frame used for the FloatCanvas
|
||||||
|
|
||||||
|
"""
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
wx.Frame.__init__(self, *args, **kwargs)
|
||||||
|
|
||||||
|
## Set up the MenuBar
|
||||||
|
MenuBar = wx.MenuBar()
|
||||||
|
|
||||||
|
file_menu = wx.Menu()
|
||||||
|
item = file_menu.Append(-1, "&Close","Close this frame")
|
||||||
|
self.Bind(wx.EVT_MENU, self.OnQuit, item)
|
||||||
|
MenuBar.Append(file_menu, "&File")
|
||||||
|
|
||||||
|
help_menu = wx.Menu()
|
||||||
|
item = help_menu.Append(-1, "&About",
|
||||||
|
"More information About this program")
|
||||||
|
self.Bind(wx.EVT_MENU, self.OnAbout, item)
|
||||||
|
MenuBar.Append(help_menu, "&Help")
|
||||||
|
|
||||||
|
self.SetMenuBar(MenuBar)
|
||||||
|
self.CreateStatusBar()
|
||||||
|
|
||||||
|
# Add the Canvas
|
||||||
|
self.Canvas = NavCanvas.NavCanvas(self,
|
||||||
|
BackgroundColor = "White",
|
||||||
|
).Canvas
|
||||||
|
|
||||||
|
self.Canvas.Bind(FC.EVT_MOTION, self.OnMove)
|
||||||
|
|
||||||
|
wx.EVT_CLOSE(self, self.OnCloseWindow)
|
||||||
|
|
||||||
|
self.DrawTest()
|
||||||
|
self.Show()
|
||||||
|
self.Canvas.ZoomToBB()
|
||||||
|
|
||||||
|
def OnAbout(self, event):
|
||||||
|
print "OnAbout called"
|
||||||
|
|
||||||
|
dlg = wx.MessageDialog(self, "This is a small program to demonstrate\n"
|
||||||
|
"the use of the FloatCanvas\n",
|
||||||
|
"About Me", wx.OK | wx.ICON_INFORMATION)
|
||||||
|
dlg.ShowModal()
|
||||||
|
dlg.Destroy()
|
||||||
|
|
||||||
|
def OnMove(self, event):
|
||||||
|
"""
|
||||||
|
Updates the status bar with the world coordinates
|
||||||
|
"""
|
||||||
|
self.SetStatusText("%.2f, %.2f"%tuple(event.Coords))
|
||||||
|
|
||||||
|
def OnQuit(self,event):
|
||||||
|
self.Close(True)
|
||||||
|
|
||||||
|
def OnCloseWindow(self, event):
|
||||||
|
self.Destroy()
|
||||||
|
|
||||||
|
def DrawTest(self,event=None):
|
||||||
|
wx.GetApp().Yield()
|
||||||
|
|
||||||
|
Canvas = self.Canvas
|
||||||
|
|
||||||
|
Points = [(0, 0),
|
||||||
|
(200,0),
|
||||||
|
(200,0),
|
||||||
|
(200,0),
|
||||||
|
(200,15),
|
||||||
|
(185,15),
|
||||||
|
(119,15),
|
||||||
|
(104,15),
|
||||||
|
(104,30),
|
||||||
|
(104,265),
|
||||||
|
(104,280),
|
||||||
|
(119,280),
|
||||||
|
(185,280),
|
||||||
|
(200,280),
|
||||||
|
(200,295),
|
||||||
|
(200,295),
|
||||||
|
(200,295),
|
||||||
|
(0, 295),
|
||||||
|
(0, 295),
|
||||||
|
(0, 295),
|
||||||
|
(0, 280),
|
||||||
|
(15, 280),
|
||||||
|
(81, 280),
|
||||||
|
(96, 280),
|
||||||
|
(96, 265),
|
||||||
|
(96, 30),
|
||||||
|
(96, 15),
|
||||||
|
(81, 15),
|
||||||
|
(15, 15),
|
||||||
|
(0, 15),
|
||||||
|
(0, 0),
|
||||||
|
]
|
||||||
|
|
||||||
|
Canvas.ClearAll()
|
||||||
|
|
||||||
|
MyLine = FC.Spline(Points,
|
||||||
|
LineWidth = 3,
|
||||||
|
LineColor = "Blue")
|
||||||
|
|
||||||
|
Canvas.AddObject(MyLine)
|
||||||
|
Canvas.AddPointSet(Points,
|
||||||
|
Color = "Red",
|
||||||
|
Diameter = 4,
|
||||||
|
)
|
||||||
|
|
||||||
|
## A regular old spline:
|
||||||
|
Points = [(-30, 260),
|
||||||
|
(-10, 130),
|
||||||
|
(70, 185),
|
||||||
|
(160,60),
|
||||||
|
]
|
||||||
|
|
||||||
|
Canvas.AddSpline(Points,
|
||||||
|
LineWidth = 5,
|
||||||
|
LineColor = "Purple")
|
||||||
|
|
||||||
|
class DemoApp(wx.App):
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
wx.App.__init__(self, *args, **kwargs)
|
||||||
|
|
||||||
|
def OnInit(self):
|
||||||
|
frame = DrawFrame(None, title="FloatCanvas Spline Demo", size = (700,700))
|
||||||
|
|
||||||
|
self.SetTopWindow(frame)
|
||||||
|
return True
|
||||||
|
|
||||||
|
app = DemoApp(False)# put in True if you want output to go to it's own window.
|
||||||
|
app.MainLoop()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
302
samples/floatcanvas/TextBox.py
Executable file
302
samples/floatcanvas/TextBox.py
Executable file
@@ -0,0 +1,302 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
"""
|
||||||
|
|
||||||
|
A test and demo of the features of the ScaledTextBox
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
import wx
|
||||||
|
|
||||||
|
## import the installed version
|
||||||
|
from wx.lib.floatcanvas import NavCanvas, FloatCanvas
|
||||||
|
|
||||||
|
## import the local version
|
||||||
|
#import sys
|
||||||
|
#sys.path.append("..")
|
||||||
|
#from floatcanvas import NavCanvas, FloatCanvas
|
||||||
|
|
||||||
|
import numpy as N
|
||||||
|
|
||||||
|
class DrawFrame(wx.Frame):
|
||||||
|
|
||||||
|
"""
|
||||||
|
A frame used for the FloatCanvas Demo
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self,parent, id,title,position,size):
|
||||||
|
wx.Frame.__init__(self,parent, id,title,position, size)
|
||||||
|
|
||||||
|
# Add the Canvas
|
||||||
|
self.CreateStatusBar()
|
||||||
|
Canvas = NavCanvas.NavCanvas(self,-1,(500,500),
|
||||||
|
ProjectionFun = None,
|
||||||
|
Debug = 0,
|
||||||
|
BackgroundColor = "DARK SLATE BLUE",
|
||||||
|
).Canvas
|
||||||
|
|
||||||
|
self.Canvas = Canvas
|
||||||
|
FloatCanvas.EVT_MOTION(self.Canvas, self.OnMove )
|
||||||
|
|
||||||
|
Point = (45,40)
|
||||||
|
Box = Canvas.AddScaledTextBox("A Two Line\nString",
|
||||||
|
Point,
|
||||||
|
2,
|
||||||
|
Color = "Black",
|
||||||
|
BackgroundColor = None,
|
||||||
|
LineColor = "Red",
|
||||||
|
LineStyle = "Solid",
|
||||||
|
LineWidth = 1,
|
||||||
|
Width = None,
|
||||||
|
PadSize = 5,
|
||||||
|
Family = wx.ROMAN,
|
||||||
|
Style = wx.NORMAL,
|
||||||
|
Weight = wx.NORMAL,
|
||||||
|
Underlined = False,
|
||||||
|
Position = 'br',
|
||||||
|
Alignment = "left",
|
||||||
|
InForeground = False)
|
||||||
|
|
||||||
|
# All defaults
|
||||||
|
Box = Canvas.AddScaledTextBox("A Two Line\nString",
|
||||||
|
Point,
|
||||||
|
2)
|
||||||
|
|
||||||
|
Box = Canvas.AddScaledTextBox("A Two Line\nString",
|
||||||
|
Point,
|
||||||
|
2,
|
||||||
|
BackgroundColor = "Yellow",
|
||||||
|
LineColor = "Red",
|
||||||
|
LineStyle = "Solid",
|
||||||
|
PadSize = 5,
|
||||||
|
Family = wx.TELETYPE,
|
||||||
|
Position = 'bl')
|
||||||
|
|
||||||
|
Box = Canvas.AddScaledTextBox("A Two Line\nString",
|
||||||
|
Point,
|
||||||
|
2,
|
||||||
|
BackgroundColor = "Yellow",
|
||||||
|
LineColor = "Red",
|
||||||
|
LineStyle = "Solid",
|
||||||
|
PadSize = 5,
|
||||||
|
Family = wx.TELETYPE,
|
||||||
|
Position = 'tr')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Box.Bind(FloatCanvas.EVT_FC_LEFT_DOWN, self.binding2)
|
||||||
|
|
||||||
|
Canvas.AddPoint(Point, Diameter = 4)
|
||||||
|
|
||||||
|
Point = (45,15)
|
||||||
|
Box = Canvas.AddScaledTextBox("A Two Line\nString",
|
||||||
|
Point,
|
||||||
|
2,
|
||||||
|
Color = "Black",
|
||||||
|
BackgroundColor = 'Red',
|
||||||
|
LineColor = "Blue",
|
||||||
|
LineStyle = "LongDash",
|
||||||
|
LineWidth = 2,
|
||||||
|
Width = None,
|
||||||
|
PadSize = 5,
|
||||||
|
Family = wx.TELETYPE,
|
||||||
|
Style = wx.NORMAL,
|
||||||
|
Weight = wx.NORMAL,
|
||||||
|
Underlined = False,
|
||||||
|
Position = 'cr',
|
||||||
|
Alignment = "left",
|
||||||
|
InForeground = False)
|
||||||
|
|
||||||
|
Box = Canvas.AddScaledTextBox("A Two Line\nString",
|
||||||
|
Point,
|
||||||
|
1.5,
|
||||||
|
Color = "Black",
|
||||||
|
BackgroundColor = 'Red',
|
||||||
|
LineColor = "Blue",
|
||||||
|
LineStyle = "LongDash",
|
||||||
|
LineWidth = 2,
|
||||||
|
Width = None,
|
||||||
|
PadSize = 5,
|
||||||
|
Family = wx.TELETYPE,
|
||||||
|
Style = wx.NORMAL,
|
||||||
|
Weight = wx.NORMAL,
|
||||||
|
Underlined = False,
|
||||||
|
Position = 'cl',
|
||||||
|
Alignment = "left",
|
||||||
|
InForeground = False)
|
||||||
|
|
||||||
|
Canvas.AddPoint(Point, Diameter = 4)
|
||||||
|
|
||||||
|
Point = (45,-10)
|
||||||
|
Box = Canvas.AddScaledTextBox("A Two Line\nString",
|
||||||
|
Point,
|
||||||
|
2,
|
||||||
|
Color = "Black",
|
||||||
|
BackgroundColor = 'Red',
|
||||||
|
LineColor = "Blue",
|
||||||
|
LineStyle = "LongDash",
|
||||||
|
LineWidth = 2,
|
||||||
|
Width = None,
|
||||||
|
PadSize = 3,
|
||||||
|
Family = wx.TELETYPE,
|
||||||
|
Style = wx.NORMAL,
|
||||||
|
Weight = wx.NORMAL,
|
||||||
|
Underlined = False,
|
||||||
|
Position = 'tc',
|
||||||
|
Alignment = "left",
|
||||||
|
InForeground = False)
|
||||||
|
|
||||||
|
Box = Canvas.AddScaledTextBox("A three\nLine\nString",
|
||||||
|
Point,
|
||||||
|
1.5,
|
||||||
|
Color = "Black",
|
||||||
|
BackgroundColor = 'Red',
|
||||||
|
LineColor = "Blue",
|
||||||
|
LineStyle = "LongDash",
|
||||||
|
LineWidth = 2,
|
||||||
|
Width = None,
|
||||||
|
PadSize = 0.5,
|
||||||
|
Family = wx.TELETYPE,
|
||||||
|
Style = wx.NORMAL,
|
||||||
|
Weight = wx.NORMAL,
|
||||||
|
Underlined = False,
|
||||||
|
Position = 'bc',
|
||||||
|
Alignment = "left",
|
||||||
|
InForeground = False)
|
||||||
|
|
||||||
|
|
||||||
|
Canvas.AddPoint(Point, Diameter = 4)
|
||||||
|
|
||||||
|
Box = Canvas.AddScaledTextBox("Some Auto Wrapped Text. There is enough to do.",
|
||||||
|
(80,40),
|
||||||
|
2,
|
||||||
|
BackgroundColor = 'White',
|
||||||
|
LineWidth = 2,
|
||||||
|
Width = 20,
|
||||||
|
PadSize = 0.5,
|
||||||
|
Family = wx.TELETYPE,
|
||||||
|
)
|
||||||
|
|
||||||
|
Box = Canvas.AddScaledTextBox("Some more auto wrapped text. Wrapped to a different width and right aligned.\n\nThis is another paragraph.",
|
||||||
|
(80,20),
|
||||||
|
2,
|
||||||
|
BackgroundColor = 'White',
|
||||||
|
LineWidth = 2,
|
||||||
|
Width = 40,
|
||||||
|
PadSize = 0.5,
|
||||||
|
Family = wx.ROMAN,
|
||||||
|
Alignment = "right"
|
||||||
|
)
|
||||||
|
Point = N.array((100, -20), N.float_)
|
||||||
|
Box = Canvas.AddScaledTextBox("Here is even more auto wrapped text. This time the line spacing is set to 0.8. \n\nThe Padding is set to 0.",
|
||||||
|
Point,
|
||||||
|
Size = 3,
|
||||||
|
BackgroundColor = 'White',
|
||||||
|
LineWidth = 1,
|
||||||
|
Width = 40,
|
||||||
|
PadSize = 0.0,
|
||||||
|
Family = wx.ROMAN,
|
||||||
|
Position = "cc",
|
||||||
|
LineSpacing = 0.8
|
||||||
|
)
|
||||||
|
Canvas.AddPoint(Point, "Red", 2)
|
||||||
|
|
||||||
|
Point = N.array((0, -40), N.float_)
|
||||||
|
# Point = N.array((0, 0), N.float_)
|
||||||
|
for Position in ["tl", "bl", "tr", "br"]:
|
||||||
|
# for Position in ["br"]:
|
||||||
|
Box = Canvas.AddScaledTextBox("Here is a\nfour liner\nanother line\nPosition=%s"%Position,
|
||||||
|
Point,
|
||||||
|
Size = 4,
|
||||||
|
Color = "Red",
|
||||||
|
BackgroundColor = None,#'LightBlue',
|
||||||
|
LineWidth = 1,
|
||||||
|
LineColor = "White",
|
||||||
|
Width = None,
|
||||||
|
PadSize = 2,
|
||||||
|
Family = wx.ROMAN,
|
||||||
|
Position = Position,
|
||||||
|
LineSpacing = 0.8
|
||||||
|
)
|
||||||
|
Canvas.AddPoint(Point, "Red", 4)
|
||||||
|
|
||||||
|
Point = N.array((-20, 60), N.float_)
|
||||||
|
Box = Canvas.AddScaledTextBox("Here is some\ncentered\ntext",
|
||||||
|
Point,
|
||||||
|
Size = 4,
|
||||||
|
Color = "Red",
|
||||||
|
BackgroundColor = 'LightBlue',
|
||||||
|
LineWidth = 1,
|
||||||
|
LineColor = "White",
|
||||||
|
Width = None,
|
||||||
|
PadSize = 2,
|
||||||
|
Family = wx.ROMAN,
|
||||||
|
Position = "tl",
|
||||||
|
Alignment = "center",
|
||||||
|
LineSpacing = 0.8
|
||||||
|
)
|
||||||
|
|
||||||
|
Point = N.array((-20, 20), N.float_)
|
||||||
|
Box = Canvas.AddScaledTextBox("Here is some\nright aligned\ntext",
|
||||||
|
Point,
|
||||||
|
Size = 4,
|
||||||
|
Color = "Red",
|
||||||
|
BackgroundColor = 'LightBlue',
|
||||||
|
LineColor = None,
|
||||||
|
Width = None,
|
||||||
|
PadSize = 2,
|
||||||
|
Family = wx.ROMAN,
|
||||||
|
Position = "tl",
|
||||||
|
Alignment = "right",
|
||||||
|
LineSpacing = 0.8
|
||||||
|
)
|
||||||
|
|
||||||
|
Point = N.array((100, -60), N.float_)
|
||||||
|
Box = Canvas.AddScaledTextBox("Here is some auto wrapped text. This time it is centered, rather than right aligned.\n\nThe Padding is set to 2.",
|
||||||
|
Point,
|
||||||
|
Size = 3,
|
||||||
|
BackgroundColor = 'White',
|
||||||
|
LineWidth = 1,
|
||||||
|
Width = 40,
|
||||||
|
PadSize = 2.0,
|
||||||
|
Family = wx.ROMAN,
|
||||||
|
Position = "cc",
|
||||||
|
LineSpacing = 0.8,
|
||||||
|
Alignment = 'center',
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
self.Show(True)
|
||||||
|
self.Canvas.ZoomToBB()
|
||||||
|
|
||||||
|
return None
|
||||||
|
def OnMove(self, event):
|
||||||
|
"""
|
||||||
|
Updates the status bar with the world coordinates
|
||||||
|
"""
|
||||||
|
self.SetStatusText("%.2f, %.2f"%tuple(event.Coords))
|
||||||
|
|
||||||
|
|
||||||
|
def binding(self, event):
|
||||||
|
print "I'm the Rectangle"
|
||||||
|
|
||||||
|
def binding2(self, event):
|
||||||
|
print "I'm the TextBox"
|
||||||
|
|
||||||
|
app = wx.PySimpleApp()
|
||||||
|
DrawFrame(None, -1, "FloatCanvas Demo App", wx.DefaultPosition, (700,700) )
|
||||||
|
app.MainLoop()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
228
samples/floatcanvas/TextBox2.py
Executable file
228
samples/floatcanvas/TextBox2.py
Executable file
@@ -0,0 +1,228 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
A test and demo of the ScaledTextbox.
|
||||||
|
|
||||||
|
It also shows how one can use the Mouse to interact and change objects on a Canvas.
|
||||||
|
|
||||||
|
this really needs to be re-done with GUI-Modes.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
import wx
|
||||||
|
|
||||||
|
|
||||||
|
## import the installed version
|
||||||
|
from wx.lib.floatcanvas import NavCanvas, FloatCanvas
|
||||||
|
|
||||||
|
## import a local version
|
||||||
|
#import sys
|
||||||
|
#sys.path.append("../")
|
||||||
|
#from floatcanvas import NavCanvas, FloatCanvas, Resources
|
||||||
|
|
||||||
|
|
||||||
|
import numpy as N
|
||||||
|
|
||||||
|
LongString = (
|
||||||
|
"""This is a long string. It is a bunch of text. I am using it to test how the nifty wrapping text box works when you want to re-size.
|
||||||
|
|
||||||
|
This is another paragraph. I am trying to make it long enough to wrap a reasonable amount. Let's see how it works.
|
||||||
|
|
||||||
|
|
||||||
|
This is a way to start a paragraph with indenting
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
##LongString = (
|
||||||
|
##""" This is a not so long string
|
||||||
|
##Another line""")
|
||||||
|
|
||||||
|
class DrawFrame(wx.Frame):
|
||||||
|
|
||||||
|
"""
|
||||||
|
A frame used for the FloatCanvas Demo
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self,parent, id,title,position,size):
|
||||||
|
wx.Frame.__init__(self,parent, id,title,position, size)
|
||||||
|
|
||||||
|
self.CreateStatusBar()
|
||||||
|
# Add the Canvas
|
||||||
|
Canvas = NavCanvas.NavCanvas(self,-1,(500,500),
|
||||||
|
ProjectionFun = None,
|
||||||
|
Debug = 0,
|
||||||
|
BackgroundColor = "DARK SLATE BLUE",
|
||||||
|
).Canvas
|
||||||
|
|
||||||
|
self.Canvas = Canvas
|
||||||
|
|
||||||
|
FloatCanvas.EVT_MOTION(self.Canvas, self.OnMove )
|
||||||
|
FloatCanvas.EVT_LEFT_UP(self.Canvas, self.OnLeftUp )
|
||||||
|
FloatCanvas.EVT_LEFT_DOWN(self.Canvas, self.OnLeftDown)
|
||||||
|
|
||||||
|
Point = N.array((0,0), N.float)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Canvas.AddCircle(Point,
|
||||||
|
|
||||||
|
Diameter=40,
|
||||||
|
|
||||||
|
FillColor="Red",
|
||||||
|
|
||||||
|
LineStyle=None,
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
Width = 300
|
||||||
|
self.Box = Canvas.AddScaledTextBox(LongString,
|
||||||
|
Point,
|
||||||
|
10,
|
||||||
|
Color = "Black",
|
||||||
|
BackgroundColor = 'White',
|
||||||
|
LineStyle = "Solid",
|
||||||
|
LineWidth = 2,
|
||||||
|
Width = Width,
|
||||||
|
PadSize = 10.0,
|
||||||
|
Family = wx.ROMAN,
|
||||||
|
#Family = wx.TELETYPE,
|
||||||
|
Style = wx.NORMAL,
|
||||||
|
Weight = wx.NORMAL,
|
||||||
|
Underlined = False,
|
||||||
|
Position = 'tl',
|
||||||
|
LineSpacing = 0.8,
|
||||||
|
Alignment = "left",
|
||||||
|
#Alignment = "center",
|
||||||
|
#Alignment = "right",
|
||||||
|
InForeground = False)
|
||||||
|
|
||||||
|
|
||||||
|
self.Handle1 = Canvas.AddBitmap(Resources.getMoveCursorBitmap(), Point, Position='cc')
|
||||||
|
self.Handle2a = Canvas.AddBitmap(Resources.getMoveRLCursorBitmap(), Point, Position='cc')
|
||||||
|
self.Handle2b = Canvas.AddBitmap(Resources.getMoveRLCursorBitmap(), Point, Position='cc')
|
||||||
|
|
||||||
|
self.SetHandles()
|
||||||
|
|
||||||
|
self.Handle1.Bind(FloatCanvas.EVT_FC_LEFT_DOWN, self.Handle1Hit)
|
||||||
|
self.Handle2a.Bind(FloatCanvas.EVT_FC_LEFT_DOWN, self.Handle2Hit)
|
||||||
|
self.Handle2b.Bind(FloatCanvas.EVT_FC_LEFT_DOWN, self.Handle2Hit)
|
||||||
|
|
||||||
|
|
||||||
|
self.Show(True)
|
||||||
|
self.Canvas.ZoomToBB()
|
||||||
|
|
||||||
|
self.Resizing = False
|
||||||
|
self.ResizeRect = None
|
||||||
|
self.Moving = False
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
def Handle1Hit(self, object):
|
||||||
|
if not self.Moving:
|
||||||
|
self.Moving = True
|
||||||
|
self.StartPoint = object.HitCoordsPixel
|
||||||
|
|
||||||
|
def Handle2Hit(self,event=None):
|
||||||
|
if not self.Resizing:
|
||||||
|
self.Resizing = True
|
||||||
|
|
||||||
|
def OnMove(self, event):
|
||||||
|
"""
|
||||||
|
Updates the status bar with the world coordinates
|
||||||
|
|
||||||
|
And moves a point if there is one
|
||||||
|
|
||||||
|
"""
|
||||||
|
self.SetStatusText("%.4f, %.4f"%tuple(event.Coords))
|
||||||
|
|
||||||
|
if self.Resizing:
|
||||||
|
((xy),(wh)) = self.Box.GetBoxRect()
|
||||||
|
(xp, yp) = self.Canvas.WorldToPixel(xy)
|
||||||
|
(wp, hp) = self.Canvas.ScaleWorldToPixel(wh)
|
||||||
|
hp = -hp
|
||||||
|
Corner = event.GetPosition()
|
||||||
|
if self.Box.Position[1] in 'lc':
|
||||||
|
wp = max(20, Corner[0]-xp) # don't allow the box to get narrower than 20 pixels
|
||||||
|
elif self.Box.Position[1] in 'r':
|
||||||
|
DeltaX = Corner[0]-xp
|
||||||
|
xp += DeltaX
|
||||||
|
wp -= DeltaX
|
||||||
|
# draw the RB box
|
||||||
|
dc = wx.ClientDC(self.Canvas)
|
||||||
|
dc.SetPen(wx.Pen('WHITE', 2, wx.SHORT_DASH))
|
||||||
|
dc.SetBrush(wx.TRANSPARENT_BRUSH)
|
||||||
|
dc.SetLogicalFunction(wx.XOR)
|
||||||
|
if self.ResizeRect:
|
||||||
|
dc.DrawRectangle(*self.ResizeRect)
|
||||||
|
self.ResizeRect = (xp,yp,wp,hp)
|
||||||
|
dc.DrawRectangle(*self.ResizeRect)
|
||||||
|
elif self.Moving:
|
||||||
|
dxy = event.GetPosition() - self.StartPoint
|
||||||
|
((xy),(wh)) = self.Box.GetBoxRect()
|
||||||
|
xp, yp = self.Canvas.WorldToPixel(xy) + dxy
|
||||||
|
(wp, hp) = self.Canvas.ScaleWorldToPixel(wh)
|
||||||
|
hp = -hp
|
||||||
|
# draw the RB box
|
||||||
|
dc = wx.ClientDC(self.Canvas)
|
||||||
|
dc.SetPen(wx.Pen('WHITE', 2, wx.SHORT_DASH))
|
||||||
|
dc.SetBrush(wx.TRANSPARENT_BRUSH)
|
||||||
|
dc.SetLogicalFunction(wx.XOR)
|
||||||
|
if self.ResizeRect:
|
||||||
|
dc.DrawRectangle(*self.ResizeRect)
|
||||||
|
self.ResizeRect = (xp,yp,wp,hp)
|
||||||
|
dc.DrawRectangle(*self.ResizeRect)
|
||||||
|
|
||||||
|
def OnLeftDown(self, event):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def OnLeftUp(self, event):
|
||||||
|
if self.Resizing:
|
||||||
|
self.Resizing = False
|
||||||
|
if self.ResizeRect:
|
||||||
|
Point = self.Canvas.PixelToWorld(self.ResizeRect[:2])
|
||||||
|
W, H = self.Canvas.ScalePixelToWorld(self.ResizeRect[2:4])
|
||||||
|
self.ResizeRect = None
|
||||||
|
self.Box.ReWrap(W)
|
||||||
|
self.SetHandles()
|
||||||
|
elif self.Moving:
|
||||||
|
self.Moving = False
|
||||||
|
if self.ResizeRect:
|
||||||
|
dxy = event.GetPosition() - self.StartPoint
|
||||||
|
dxy = self.Canvas.ScalePixelToWorld(dxy)
|
||||||
|
self.Box.Move(dxy)
|
||||||
|
self.ResizeRect = None
|
||||||
|
# self.Box.SetPoint(Point1)
|
||||||
|
self.SetHandles()
|
||||||
|
|
||||||
|
self.Canvas.Draw(True)
|
||||||
|
|
||||||
|
def SetHandles(self):
|
||||||
|
((x,y),(w,h)) = self.Box.GetBoxRect()
|
||||||
|
if self.Box.Position[1] in "lc":
|
||||||
|
x += w
|
||||||
|
y -= h/3
|
||||||
|
self.Handle2a.SetPoint((x,y))
|
||||||
|
y -= h/3
|
||||||
|
self.Handle2b.SetPoint((x,y))
|
||||||
|
self.Handle1.SetPoint(self.Box.XY)
|
||||||
|
|
||||||
|
|
||||||
|
app = wx.PySimpleApp()
|
||||||
|
DrawFrame(None, -1, "FloatCanvas TextBox Test App", wx.DefaultPosition, (700,700) )
|
||||||
|
app.MainLoop()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
38
samples/floatcanvas/Tiny.bna
Normal file
38
samples/floatcanvas/Tiny.bna
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
"Another Name","Another Type", 19
|
||||||
|
-81.531753540039,31.134635925293
|
||||||
|
-81.531150817871,31.134529113769
|
||||||
|
-81.530662536621,31.134353637695
|
||||||
|
-81.530502319336,31.134126663208
|
||||||
|
-81.530685424805,31.133970260620
|
||||||
|
-81.531112670898,31.134040832519
|
||||||
|
-81.532104492188,31.134008407593
|
||||||
|
-81.532485961914,31.134220123291
|
||||||
|
-81.533134460449,31.134204864502
|
||||||
|
-81.534004211426,31.134277343750
|
||||||
|
-81.534667968750,31.134349822998
|
||||||
|
-81.534912109375,31.134525299072
|
||||||
|
-81.534667968750,31.134855270386
|
||||||
|
-81.534248352051,31.134975433350
|
||||||
|
-81.533943176270,31.135166168213
|
||||||
|
-81.533760070801,31.135200500488
|
||||||
|
-81.532928466797,31.135110855102
|
||||||
|
-81.532447814941,31.134794235229
|
||||||
|
-81.532341003418,31.134586334229
|
||||||
|
"A third 'name'","6", 7
|
||||||
|
-81.522369384766,31.122062683106
|
||||||
|
-81.522109985352,31.121908187866
|
||||||
|
-81.522010803223,31.121685028076
|
||||||
|
-81.522254943848,31.121658325195
|
||||||
|
-81.522483825684,31.121797561646
|
||||||
|
-81.522514343262,31.122062683106
|
||||||
|
-81.522369384766,31.122062683106
|
||||||
|
"8223","1", 9
|
||||||
|
-81.523277282715,31.122261047363
|
||||||
|
-81.522987365723,31.121982574463
|
||||||
|
-81.523200988770,31.121547698975
|
||||||
|
-81.523361206055,31.121408462524
|
||||||
|
-81.523818969727,31.121549606323
|
||||||
|
-81.524078369141,31.121662139893
|
||||||
|
-81.524009704590,31.121944427490
|
||||||
|
-81.523925781250,31.122068405151
|
||||||
|
-81.523277282715,31.122261047363
|
||||||
371
samples/floatcanvas/Tree.py
Executable file
371
samples/floatcanvas/Tree.py
Executable file
@@ -0,0 +1,371 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
"""
|
||||||
|
|
||||||
|
This is a demo, showing how to work with a "tree" structure
|
||||||
|
|
||||||
|
It demonstrates moving objects around, etc, etc.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
import wx
|
||||||
|
|
||||||
|
#ver = 'local'
|
||||||
|
2ver = 'installed'
|
||||||
|
|
||||||
|
if ver == 'installed': ## import the installed version
|
||||||
|
from wx.lib.floatcanvas import NavCanvas, Resources
|
||||||
|
from wx.lib.floatcanvas import FloatCanvas as FC
|
||||||
|
from wx.lib.floatcanvas.Utilities import BBox
|
||||||
|
print "using installed version:", wx.lib.floatcanvas.__version__
|
||||||
|
elif ver == 'local':
|
||||||
|
## import a local version
|
||||||
|
import sys
|
||||||
|
sys.path.append("..")
|
||||||
|
from floatcanvas import NavCanvas, Resources
|
||||||
|
from floatcanvas import FloatCanvas as FC
|
||||||
|
from floatcanvas.Utilities import BBox
|
||||||
|
|
||||||
|
import numpy as N
|
||||||
|
|
||||||
|
## here we create some new mixins:
|
||||||
|
## fixme: These really belong in floatcanvas package -- but I kind of want to clean it up some first
|
||||||
|
|
||||||
|
class MovingObjectMixin:
|
||||||
|
"""
|
||||||
|
Methods required for a Moving object
|
||||||
|
|
||||||
|
"""
|
||||||
|
def GetOutlinePoints(self):
|
||||||
|
"""
|
||||||
|
Returns a set of points with which to draw the outline when moving the
|
||||||
|
object.
|
||||||
|
|
||||||
|
Points are a NX2 array of (x,y) points in World coordinates.
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
BB = self.BoundingBox
|
||||||
|
OutlinePoints = N.array( ( (BB[0,0], BB[0,1]),
|
||||||
|
(BB[0,0], BB[1,1]),
|
||||||
|
(BB[1,0], BB[1,1]),
|
||||||
|
(BB[1,0], BB[0,1]),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
return OutlinePoints
|
||||||
|
|
||||||
|
class ConnectorObjectMixin:
|
||||||
|
"""
|
||||||
|
Mixin class for DrawObjects that can be connected with lines
|
||||||
|
|
||||||
|
Note that this version only works for Objects that have an "XY" attribute:
|
||||||
|
that is, one that is derived from XHObjectMixin.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def GetConnectPoint(self):
|
||||||
|
return self.XY
|
||||||
|
|
||||||
|
class MovingBitmap(FC.ScaledBitmap, MovingObjectMixin, ConnectorObjectMixin):
|
||||||
|
"""
|
||||||
|
ScaledBitmap Object that can be moved
|
||||||
|
"""
|
||||||
|
## All we need to do is is inherit from:
|
||||||
|
## ScaledBitmap, MovingObjectMixin and ConnectorObjectMixin
|
||||||
|
pass
|
||||||
|
|
||||||
|
class MovingCircle(FC.Circle, MovingObjectMixin, ConnectorObjectMixin):
|
||||||
|
"""
|
||||||
|
ScaledBitmap Object that can be moved
|
||||||
|
"""
|
||||||
|
## All we need to do is is inherit from:
|
||||||
|
## Circle MovingObjectMixin and ConnectorObjectMixin
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class MovingGroup(FC.Group, MovingObjectMixin, ConnectorObjectMixin):
|
||||||
|
|
||||||
|
def GetConnectPoint(self):
|
||||||
|
return self.BoundingBox.Center
|
||||||
|
|
||||||
|
class NodeObject(FC.Group, MovingObjectMixin, ConnectorObjectMixin):
|
||||||
|
"""
|
||||||
|
A version of the moving group for nodes -- an ellipse with text on it.
|
||||||
|
"""
|
||||||
|
def __init__(self,
|
||||||
|
Label,
|
||||||
|
XY,
|
||||||
|
WH,
|
||||||
|
BackgroundColor = "Yellow",
|
||||||
|
TextColor = "Black",
|
||||||
|
InForeground = False,
|
||||||
|
IsVisible = True):
|
||||||
|
XY = N.asarray(XY, N.float).reshape(2,)
|
||||||
|
WH = N.asarray(WH, N.float).reshape(2,)
|
||||||
|
Label = FC.ScaledText(Label,
|
||||||
|
XY,
|
||||||
|
Size = WH[1] / 2.0,
|
||||||
|
Color = TextColor,
|
||||||
|
Position = 'cc',
|
||||||
|
)
|
||||||
|
self.Ellipse = FC.Ellipse( (XY - WH/2.0),
|
||||||
|
WH,
|
||||||
|
FillColor = BackgroundColor,
|
||||||
|
LineStyle = None,
|
||||||
|
)
|
||||||
|
FC.Group.__init__(self, [self.Ellipse, Label], InForeground, IsVisible)
|
||||||
|
|
||||||
|
def GetConnectPoint(self):
|
||||||
|
return self.BoundingBox.Center
|
||||||
|
|
||||||
|
|
||||||
|
class MovingText(FC.ScaledText, MovingObjectMixin, ConnectorObjectMixin):
|
||||||
|
"""
|
||||||
|
ScaledBitmap Object that can be moved
|
||||||
|
"""
|
||||||
|
## All we need to do is is inherit from:
|
||||||
|
## ScaledBitmap, MovingObjectMixin and ConnectorObjectMixin
|
||||||
|
pass
|
||||||
|
|
||||||
|
class ConnectorLine(FC.LineOnlyMixin, FC.DrawObject,):
|
||||||
|
"""
|
||||||
|
|
||||||
|
A Line that connects two objects -- it uses the objects to get its coordinates
|
||||||
|
The objects must have a GetConnectPoint() method.
|
||||||
|
|
||||||
|
"""
|
||||||
|
##fixme: this should be added to the Main FloatCanvas Objects some day.
|
||||||
|
def __init__(self,
|
||||||
|
Object1,
|
||||||
|
Object2,
|
||||||
|
LineColor = "Black",
|
||||||
|
LineStyle = "Solid",
|
||||||
|
LineWidth = 1,
|
||||||
|
InForeground = False):
|
||||||
|
FC.DrawObject.__init__(self, InForeground)
|
||||||
|
|
||||||
|
self.Object1 = Object1
|
||||||
|
self.Object2 = Object2
|
||||||
|
self.LineColor = LineColor
|
||||||
|
self.LineStyle = LineStyle
|
||||||
|
self.LineWidth = LineWidth
|
||||||
|
|
||||||
|
self.CalcBoundingBox()
|
||||||
|
self.SetPen(LineColor,LineStyle,LineWidth)
|
||||||
|
|
||||||
|
self.HitLineWidth = max(LineWidth,self.MinHitLineWidth)
|
||||||
|
|
||||||
|
def CalcBoundingBox(self):
|
||||||
|
self.BoundingBox = BBox.fromPoints((self.Object1.GetConnectPoint(),
|
||||||
|
self.Object2.GetConnectPoint()) )
|
||||||
|
if self._Canvas:
|
||||||
|
self._Canvas.BoundingBoxDirty = True
|
||||||
|
|
||||||
|
|
||||||
|
def _Draw(self, dc , WorldToPixel, ScaleWorldToPixel, HTdc=None):
|
||||||
|
Points = N.array( (self.Object1.GetConnectPoint(),
|
||||||
|
self.Object2.GetConnectPoint()) )
|
||||||
|
Points = WorldToPixel(Points)
|
||||||
|
dc.SetPen(self.Pen)
|
||||||
|
dc.DrawLines(Points)
|
||||||
|
if HTdc and self.HitAble:
|
||||||
|
HTdc.SetPen(self.HitPen)
|
||||||
|
HTdc.DrawLines(Points)
|
||||||
|
|
||||||
|
|
||||||
|
class TriangleShape1(FC.Polygon, MovingObjectMixin):
|
||||||
|
|
||||||
|
def __init__(self, XY, L):
|
||||||
|
|
||||||
|
"""
|
||||||
|
An equilateral triangle object
|
||||||
|
XY is the middle of the triangle
|
||||||
|
L is the length of one side of the Triangle
|
||||||
|
"""
|
||||||
|
|
||||||
|
XY = N.asarray(XY)
|
||||||
|
XY.shape = (2,)
|
||||||
|
|
||||||
|
Points = self.CompPoints(XY, L)
|
||||||
|
|
||||||
|
FC.Polygon.__init__(self, Points,
|
||||||
|
LineColor = "Black",
|
||||||
|
LineStyle = "Solid",
|
||||||
|
LineWidth = 2,
|
||||||
|
FillColor = "Red",
|
||||||
|
FillStyle = "Solid")
|
||||||
|
## Override the default OutlinePoints
|
||||||
|
def GetOutlinePoints(self):
|
||||||
|
return self.Points
|
||||||
|
|
||||||
|
def CompPoints(self, XY, L):
|
||||||
|
c = L/ N.sqrt(3)
|
||||||
|
|
||||||
|
Points = N.array(((0, c),
|
||||||
|
( L/2.0, -c/2.0),
|
||||||
|
(-L/2.0, -c/2.0)),
|
||||||
|
N.float_)
|
||||||
|
|
||||||
|
Points += XY
|
||||||
|
return Points
|
||||||
|
|
||||||
|
### Tree Utilities
|
||||||
|
### And some hard coded data...
|
||||||
|
|
||||||
|
class TreeNode:
|
||||||
|
dx = 15
|
||||||
|
dy = 4
|
||||||
|
def __init__(self, name, Children = []):
|
||||||
|
self.Name = name
|
||||||
|
#self.parent = None -- Is this needed?
|
||||||
|
self.Children = Children
|
||||||
|
self.Point = None # The coords of the node.
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return "TreeNode: %s"%self.Name
|
||||||
|
__repr__ = __str__
|
||||||
|
|
||||||
|
|
||||||
|
## Build Tree:
|
||||||
|
leaves = [TreeNode(name) for name in ["Assistant VP 1","Assistant VP 2","Assistant VP 3"] ]
|
||||||
|
VP1 = TreeNode("VP1", Children = leaves)
|
||||||
|
VP2 = TreeNode("VP2")
|
||||||
|
|
||||||
|
CEO = TreeNode("CEO", [VP1, VP2])
|
||||||
|
Father = TreeNode("Father", [TreeNode("Daughter"), TreeNode("Son")])
|
||||||
|
elements = TreeNode("Root", [CEO, Father])
|
||||||
|
|
||||||
|
def LayoutTree(root, x, y, level):
|
||||||
|
NumNodes = len(root.Children)
|
||||||
|
root.Point = (x,y)
|
||||||
|
x += root.dx
|
||||||
|
y += (root.dy * level * (NumNodes-1) / 2.0)
|
||||||
|
for node in root.Children:
|
||||||
|
LayoutTree(node, x, y, level-1)
|
||||||
|
y -= root.dy * level
|
||||||
|
|
||||||
|
def TraverseTree(root, func):
|
||||||
|
func(root)
|
||||||
|
for child in (root.Children):
|
||||||
|
TraverseTree(child, func)
|
||||||
|
|
||||||
|
class DrawFrame(wx.Frame):
|
||||||
|
|
||||||
|
"""
|
||||||
|
A simple frame used for the Demo
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
wx.Frame.__init__(self, *args, **kwargs)
|
||||||
|
|
||||||
|
self.CreateStatusBar()
|
||||||
|
# Add the Canvas
|
||||||
|
Canvas = NavCanvas.NavCanvas(self,-1,(500,500),
|
||||||
|
ProjectionFun = None,
|
||||||
|
Debug = 0,
|
||||||
|
BackgroundColor = "White",
|
||||||
|
).Canvas
|
||||||
|
|
||||||
|
self.Canvas = Canvas
|
||||||
|
|
||||||
|
|
||||||
|
Canvas.Bind(FC.EVT_MOTION, self.OnMove )
|
||||||
|
Canvas.Bind(FC.EVT_LEFT_UP, self.OnLeftUp )
|
||||||
|
|
||||||
|
self.elements = elements
|
||||||
|
LayoutTree(self.elements, 0, 0, 3)
|
||||||
|
self.AddTree(self.elements)
|
||||||
|
|
||||||
|
|
||||||
|
self.Show(True)
|
||||||
|
self.Canvas.ZoomToBB()
|
||||||
|
|
||||||
|
self.MoveObject = None
|
||||||
|
self.Moving = False
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
def AddTree(self, root):
|
||||||
|
Nodes = []
|
||||||
|
Connectors = []
|
||||||
|
EllipseW = 15
|
||||||
|
EllipseH = 4
|
||||||
|
def CreateObject(node):
|
||||||
|
if node.Children:
|
||||||
|
object = NodeObject(node.Name,
|
||||||
|
node.Point,
|
||||||
|
(15, 4),
|
||||||
|
BackgroundColor = "Yellow",
|
||||||
|
TextColor = "Black",
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
object = MovingText(node.Name,
|
||||||
|
node.Point,
|
||||||
|
2.0,
|
||||||
|
BackgroundColor = "Yellow",
|
||||||
|
Color = "Red",
|
||||||
|
Position = "cl",
|
||||||
|
)
|
||||||
|
node.DrawObject = object
|
||||||
|
Nodes.append(object)
|
||||||
|
def AddConnectors(node):
|
||||||
|
for child in node.Children:
|
||||||
|
Connector = ConnectorLine(node.DrawObject, child.DrawObject, LineWidth=3, LineColor="Red")
|
||||||
|
Connectors.append(Connector)
|
||||||
|
## create the Objects
|
||||||
|
TraverseTree(root, CreateObject)
|
||||||
|
## create the Connectors
|
||||||
|
TraverseTree(root, AddConnectors)
|
||||||
|
## Add the conenctos to the Canvas first, so they are undernieth the nodes
|
||||||
|
self.Canvas.AddObjects(Connectors)
|
||||||
|
## now add the nodes
|
||||||
|
self.Canvas.AddObjects(Nodes)
|
||||||
|
# Now bind the Nodes -- DrawObjects must be Added to a Canvas before they can be bound.
|
||||||
|
for node in Nodes:
|
||||||
|
#pass
|
||||||
|
node.Bind(FC.EVT_FC_LEFT_DOWN, self.ObjectHit)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def ObjectHit(self, object):
|
||||||
|
if not self.Moving:
|
||||||
|
self.Moving = True
|
||||||
|
self.StartPoint = object.HitCoordsPixel
|
||||||
|
self.StartObject = self.Canvas.WorldToPixel(object.GetOutlinePoints())
|
||||||
|
self.MoveObject = None
|
||||||
|
self.MovingObject = object
|
||||||
|
|
||||||
|
def OnMove(self, event):
|
||||||
|
"""
|
||||||
|
Updates the status bar with the world coordinates
|
||||||
|
and moves the object it is clicked on
|
||||||
|
|
||||||
|
"""
|
||||||
|
self.SetStatusText("%.4f, %.4f"%tuple(event.Coords))
|
||||||
|
|
||||||
|
if self.Moving:
|
||||||
|
dxy = event.GetPosition() - self.StartPoint
|
||||||
|
# Draw the Moving Object:
|
||||||
|
dc = wx.ClientDC(self.Canvas)
|
||||||
|
dc.SetPen(wx.Pen('WHITE', 2, wx.SHORT_DASH))
|
||||||
|
dc.SetBrush(wx.TRANSPARENT_BRUSH)
|
||||||
|
dc.SetLogicalFunction(wx.XOR)
|
||||||
|
if self.MoveObject is not None:
|
||||||
|
dc.DrawPolygon(self.MoveObject)
|
||||||
|
self.MoveObject = self.StartObject + dxy
|
||||||
|
dc.DrawPolygon(self.MoveObject)
|
||||||
|
|
||||||
|
def OnLeftUp(self, event):
|
||||||
|
if self.Moving:
|
||||||
|
self.Moving = False
|
||||||
|
if self.MoveObject is not None:
|
||||||
|
dxy = event.GetPosition() - self.StartPoint
|
||||||
|
dxy = self.Canvas.ScalePixelToWorld(dxy)
|
||||||
|
self.MovingObject.Move(dxy)
|
||||||
|
self.MoveTri = None
|
||||||
|
self.Canvas.Draw(True)
|
||||||
|
|
||||||
|
app = wx.PySimpleApp(0)
|
||||||
|
DrawFrame(None, -1, "FloatCanvas Tree Demo App", wx.DefaultPosition, (700,700) )
|
||||||
|
app.MainLoop()
|
||||||
203
samples/floatcanvas/VectPlot.py
Executable file
203
samples/floatcanvas/VectPlot.py
Executable file
@@ -0,0 +1,203 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
"""
|
||||||
|
|
||||||
|
A small test app that uses FloatCanvas to draw a vector plot.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
import wx
|
||||||
|
import numpy as N
|
||||||
|
import random
|
||||||
|
|
||||||
|
## import the installed version
|
||||||
|
from wx.lib.floatcanvas import NavCanvas, FloatCanvas
|
||||||
|
|
||||||
|
## import a local version
|
||||||
|
#import sys
|
||||||
|
#sys.path.append("../")
|
||||||
|
#from floatcanvas import NavCanvas, FloatCanvas
|
||||||
|
|
||||||
|
|
||||||
|
class DrawFrame(wx.Frame):
|
||||||
|
def __init__(self,parent, id,title,position,size):
|
||||||
|
wx.Frame.__init__(self,parent, id,title,position, size)
|
||||||
|
|
||||||
|
## Set up the MenuBar
|
||||||
|
|
||||||
|
MenuBar = wx.MenuBar()
|
||||||
|
|
||||||
|
file_menu = wx.Menu()
|
||||||
|
item = file_menu.Append(wx.ID_ANY, "E&xit","Terminate the program")
|
||||||
|
self.Bind(wx.EVT_MENU, self.OnQuit, item)
|
||||||
|
MenuBar.Append(file_menu, "&File")
|
||||||
|
|
||||||
|
draw_menu = wx.Menu()
|
||||||
|
item = draw_menu.Append(wx.ID_ANY, "&Plot","Re-do Plot")
|
||||||
|
self.Bind(wx.EVT_MENU, self.Plot, item)
|
||||||
|
MenuBar.Append(draw_menu, "&Plot")
|
||||||
|
|
||||||
|
|
||||||
|
help_menu = wx.Menu()
|
||||||
|
item = help_menu.Append(wx.ID_ANY, "&About",
|
||||||
|
"More information About this program")
|
||||||
|
self.Bind(wx.EVT_MENU, self.OnAbout, item)
|
||||||
|
MenuBar.Append(help_menu, "&Help")
|
||||||
|
|
||||||
|
self.SetMenuBar(MenuBar)
|
||||||
|
|
||||||
|
|
||||||
|
self.CreateStatusBar()
|
||||||
|
self.SetStatusText("")
|
||||||
|
|
||||||
|
wx.EVT_CLOSE(self, self.OnCloseWindow)
|
||||||
|
|
||||||
|
# Add the Canvas
|
||||||
|
self.Canvas = NavCanvas.NavCanvas(self ,wx.ID_ANY ,(500,300),
|
||||||
|
ProjectionFun = None,
|
||||||
|
Debug = 0,
|
||||||
|
BackgroundColor = "WHITE"
|
||||||
|
).Canvas
|
||||||
|
|
||||||
|
self.Canvas.NumBetweenBlits = 1000
|
||||||
|
|
||||||
|
|
||||||
|
self.Show(True)
|
||||||
|
|
||||||
|
self.Plot()
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def OnAbout(self, event):
|
||||||
|
dlg = wx.MessageDialog(self, "This is a small program to demonstrate\n"
|
||||||
|
"the use of the FloatCanvas\n"
|
||||||
|
"for vector plotting",
|
||||||
|
"About Me", wx.OK | wx.ICON_INFORMATION)
|
||||||
|
dlg.ShowModal()
|
||||||
|
dlg.Destroy()
|
||||||
|
|
||||||
|
def ZoomToFit(self,event):
|
||||||
|
self.Canvas.ZoomToBB()
|
||||||
|
|
||||||
|
def OnQuit(self,event):
|
||||||
|
self.Close(True)
|
||||||
|
|
||||||
|
def OnCloseWindow(self, event):
|
||||||
|
self.Destroy()
|
||||||
|
|
||||||
|
|
||||||
|
def DrawAxis(self):
|
||||||
|
Canvas = self.Canvas
|
||||||
|
|
||||||
|
# Draw the Axis
|
||||||
|
|
||||||
|
# Note: the AddRectangle Parameters all have sensible
|
||||||
|
# defaults. I've put them all here explicitly, so you can see
|
||||||
|
# what the options are.
|
||||||
|
|
||||||
|
self.Canvas.AddRectangle((0, -1.1),
|
||||||
|
(2*N.pi, 2.2),
|
||||||
|
LineColor = "Black",
|
||||||
|
LineStyle = "Solid",
|
||||||
|
LineWidth = 1,
|
||||||
|
FillColor = None,
|
||||||
|
FillStyle = "Solid",
|
||||||
|
InForeground = 0)
|
||||||
|
for tic in N.arange(7):
|
||||||
|
self.Canvas.AddText("%1.1f"%tic,
|
||||||
|
(tic, -1.1),
|
||||||
|
Position = 'tc')
|
||||||
|
|
||||||
|
for tic in N.arange(-1,1.1,0.5):
|
||||||
|
self.Canvas.AddText("%1.1f"%tic,
|
||||||
|
(0,tic),
|
||||||
|
Position = 'cr')
|
||||||
|
|
||||||
|
# Add a phantom rectangle to get the bounding box right
|
||||||
|
# (the bounding box doesn't get unscaled text right)
|
||||||
|
self.Canvas.AddRectangle((-0.7, -1.5),
|
||||||
|
(7, 3),
|
||||||
|
LineColor = None)
|
||||||
|
|
||||||
|
#Canvas.ZoomToBB()
|
||||||
|
#Canvas.Draw()
|
||||||
|
|
||||||
|
def Plot(self, event = None):
|
||||||
|
x = N.arange(0, 2*N.pi, 0.1)
|
||||||
|
x.shape = (-1,1)
|
||||||
|
y = N.sin(x)
|
||||||
|
data = N.concatenate((x, y),1)
|
||||||
|
|
||||||
|
Canvas = self.Canvas
|
||||||
|
self.Canvas.ClearAll()
|
||||||
|
self.DrawAxis()
|
||||||
|
for p in data:
|
||||||
|
Canvas.AddPoint(p,
|
||||||
|
Diameter = 4,
|
||||||
|
Color = "Red",
|
||||||
|
InForeground = 1)
|
||||||
|
theta = random.uniform(0, 360)
|
||||||
|
Canvas.AddArrow(p,
|
||||||
|
Length = 20,
|
||||||
|
Direction = p[1]*360,
|
||||||
|
LineColor = "Red",
|
||||||
|
)
|
||||||
|
self.Canvas.ZoomToBB()
|
||||||
|
self.Canvas.Draw()
|
||||||
|
self.Canvas.SaveAsImage("junk.png")
|
||||||
|
|
||||||
|
|
||||||
|
class DemoApp(wx.App):
|
||||||
|
"""
|
||||||
|
How the demo works:
|
||||||
|
|
||||||
|
Either under the Draw menu, or on the toolbar, you can push Run and Stop
|
||||||
|
|
||||||
|
"Run" start an oscilloscope like display of a moving sine curve
|
||||||
|
"Stop" stops it.
|
||||||
|
|
||||||
|
While the plot os running (or not) you can zoom in and out and move
|
||||||
|
about the picture. There is a tool bar with three tools that can be
|
||||||
|
selected.
|
||||||
|
|
||||||
|
The magnifying glass with the plus is the zoom in tool. Once selected,
|
||||||
|
if you click the image, it will zoom in, centered on where you
|
||||||
|
clicked. If you click and drag the mouse, you will get a rubber band
|
||||||
|
box, and the image will zoom to fit that box when you release it.
|
||||||
|
|
||||||
|
The magnifying glass with the minus is the zoom out tool. Once selected,
|
||||||
|
if you click the image, it will zoom out, centered on where you
|
||||||
|
clicked.
|
||||||
|
|
||||||
|
The hand is the move tool. Once selected, if you click and drag on
|
||||||
|
the image, it will move so that the part you clicked on ends up
|
||||||
|
where you release the mouse. Nothing is changed while you are
|
||||||
|
dragging, but you can see the outline of the former picture.
|
||||||
|
|
||||||
|
I'd like the cursor to change as you change tools, but the stock
|
||||||
|
wx.Cursors didn't include anything I liked, so I stuck with the
|
||||||
|
pointer. Please let me know if you have any nice cursor images for me to
|
||||||
|
use.
|
||||||
|
|
||||||
|
|
||||||
|
Any bugs, comments, feedback, questions, and especially code are welcome:
|
||||||
|
|
||||||
|
-Chris Barker
|
||||||
|
|
||||||
|
Chris.Barker@noaa.gov
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def OnInit(self):
|
||||||
|
frame = DrawFrame(None, wx.ID_ANY, "Plotting Test",wx.DefaultPosition,wx.Size(700,400))
|
||||||
|
|
||||||
|
self.SetTopWindow(frame)
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
|
||||||
|
app = DemoApp(0)
|
||||||
|
app.MainLoop()
|
||||||
|
|
||||||
|
|
||||||
95
samples/floatcanvas/YDownDemo.py
Executable file
95
samples/floatcanvas/YDownDemo.py
Executable file
@@ -0,0 +1,95 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
This demonstrates how to use FloatCanvas with a coordinate system where
|
||||||
|
Y is increased down, instead of up. This is a standard system for
|
||||||
|
images, for instance.
|
||||||
|
|
||||||
|
Note that there are some problems with doing this for bitmaps and text: things that require positioning.
|
||||||
|
|
||||||
|
I'm sure it can be fixed, but I don't have a need for it, so I haven't taken the time yet.
|
||||||
|
-chb
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
import wx
|
||||||
|
|
||||||
|
## import the installed version
|
||||||
|
from wx.lib.floatcanvas import NavCanvas, FloatCanvas
|
||||||
|
|
||||||
|
## import a local version
|
||||||
|
#import sys
|
||||||
|
#sys.path.append("..")
|
||||||
|
#from floatcanvas import NavCanvas, FloatCanvas
|
||||||
|
|
||||||
|
|
||||||
|
import numpy as N
|
||||||
|
|
||||||
|
def YDownProjection(CenterPoint):
|
||||||
|
return N.array((1,-1))
|
||||||
|
|
||||||
|
class DrawFrame(wx.Frame):
|
||||||
|
|
||||||
|
"""
|
||||||
|
A frame used for the FloatCanvas Demo
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
wx.Frame.__init__(self, *args, **kwargs)
|
||||||
|
|
||||||
|
self.CreateStatusBar()
|
||||||
|
|
||||||
|
# Add the Canvas
|
||||||
|
Canvas = NavCanvas.NavCanvas(self,-1,
|
||||||
|
size = (500,500),
|
||||||
|
ProjectionFun = YDownProjection,
|
||||||
|
Debug = 0,
|
||||||
|
BackgroundColor = "DARK SLATE BLUE",
|
||||||
|
).Canvas
|
||||||
|
|
||||||
|
self.Canvas = Canvas
|
||||||
|
|
||||||
|
Point = (0,0)
|
||||||
|
Box = Canvas.AddRectangle(Point,
|
||||||
|
(80,100),
|
||||||
|
FillColor = "blue"
|
||||||
|
)
|
||||||
|
|
||||||
|
Canvas.AddText("%s"%(Point,), Point, Position="cr")
|
||||||
|
Canvas.AddPoint(Point, Diameter=3, Color = "red")
|
||||||
|
|
||||||
|
|
||||||
|
Point = (0,100)
|
||||||
|
Canvas.AddText("%s"%(Point,), Point, Position="cr")
|
||||||
|
Canvas.AddPoint(Point, Diameter=3, Color = "red")
|
||||||
|
|
||||||
|
FloatCanvas.EVT_MOTION(self.Canvas, self.OnMove )
|
||||||
|
|
||||||
|
|
||||||
|
self.Show()
|
||||||
|
Canvas.ZoomToBB()
|
||||||
|
|
||||||
|
def OnMove(self, event):
|
||||||
|
"""
|
||||||
|
Updates the status bar with the world coordinates
|
||||||
|
"""
|
||||||
|
self.SetStatusText("%.2f, %.2f"%tuple(event.Coords))
|
||||||
|
|
||||||
|
|
||||||
|
app = wx.App(False)
|
||||||
|
F = DrawFrame(None, title="FloatCanvas Demo App", size=(700,700) )
|
||||||
|
app.MainLoop()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
BIN
samples/floatcanvas/white_tank.jpg
Normal file
BIN
samples/floatcanvas/white_tank.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 162 KiB |
Reference in New Issue
Block a user