A copy of the floatcanvas folder should be in the directory. The attached "Test
App" file shows a bare framework. Click the bitmap button '+' to add rows /
tracks. The current problem is that when the splitter window is resized, the
lines on the canvas move. I think once that problem is solved, the next ideal
step would be to try to implement scrolling capability. However, I have no idea
how much digging this would take. Depending how much, it may take some non GUI
effort to cycle back to it.
-Philip
#!/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 WidgetsTest
from WidgetsTest import Widget
# previously DrawFrame
class TrackGrid(NavCanvas.NavCanvas):
"""
A frame used for the FloatCanvas Demo
"""
def __init__(self,
parent,
id = wx.ID_ANY,
size = wx.DefaultSize,
**kwargs):
NavCanvas.NavCanvas.__init__(self,
parent,
id = wx.ID_ANY,
size = wx.DefaultSize,
**kwargs)
# Canvas = FloatCanvas.FloatCanvas(self,-1,
# size = (500,500),
# ProjectionFun = None,
# Debug = 0,
# BackgroundColor = "White",
# )
# canvas should be a property initialized from NavCanvas
Canvas = self.Canvas
FloatCanvas.EVT_MOTION(self.Canvas, self.OnMove )
FloatCanvas.EVT_LEFT_DOWN(self.Canvas, self.OnLeft)
# Some default sizes:
self.LineHeight = 1.465
self.TextWidth = 0
self.SpaceWidth = 1
## self.Labels = ["SW Tasks", "Set RX Rf"] + ["A Row Label"]*1
## self.NumRows = len(self.Labels)
self.curRow = 1
# self.BuildChartBackground()
self.AddLines()
## self.AddLabels()
self.Show()
Canvas.MinScale=10.8
Canvas.MaxScale=10.8
Canvas.ZoomToBB()
def AddLines(self):
top = 0
bottom = -((self.LineHeight) * 16)
for i in range(16):
# the larger both multiplyer of i, the more spread out the lines will be in both directions x
self.Canvas.AddLine(((i*5.38,bottom),(i*5.38,top)),
LineColor = "Black",
# or "Dot", "ShortDash", "LongDash","ShortDash", "DotDash"
LineWidth = 1,)
self.Canvas.Draw()
# previously this was BuildChartBackground
def AddTrackRow(self):
"""
Add one track... called on click of new track
"""
Canvas = self.Canvas
## top = 0
## bottom = -((self.LineHeight) * self.curRow)
width = self.SpaceWidth * 16 + self.TextWidth
# width*2 generates the length of each row
# if second parameter is positive, the rectangles are built bottom up
# first parameter controls start point length wise
for i in range(self.curRow, self.curRow + 1):
Canvas.AddRectangle((0, -i*self.LineHeight*2.59),
(width*6, self.LineHeight*2.59),
LineColor = "Black",
FillColor = "Grey",
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,)
Canvas.Draw()
self.curRow += 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',
## )
## Canvas.Draw()
def OnMove(self, event):
"""
Updates the status bar with the world coordinates
utilize this data in coordination with snapping function when vertical
timelines are available.
"""
# 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
class Track(FloatCanvas.FloatCanvas):
def __init__(self, parent, id = -1,
size = wx.DefaultSize,
ProjectionFun = None,
BackgroundColor = "WHITE",
Debug = False,
**kwargs):
FloatCanvas.FloatCanvas.__init__(self, parent, id = -1,
size = wx.DefaultSize,
ProjectionFun = None,
BackgroundColor = "WHITE",
Debug = False,
**kwargs)
class TrackPanel(NavCanvas.NavCanvas):
def __init__(self,
parent,
id = wx.ID_ANY,
size = wx.DefaultSize,
**kwargs):
NavCanvas.NavCanvas.__init__(self,
parent,
id = wx.ID_ANY,
size = wx.DefaultSize,
**kwargs)
self.curLine = [230]
self.curTrack = [270]
Canvas = self.Canvas
# note: self.Show() is implemented within track grid along with a few others
def AddTrack(self):
track = wx.Panel(self.Canvas, -1)
track.SetMinSize((189, 40))
track.SetBackgroundColour(wx.Colour(119, 119, 119))
# create items to add to track
label = wx.StaticText(track, -1, "track")
label_2 = wx.StaticText(track, -1, "")
label_2.SetMinSize((10, 5))
on_off = wx.ToggleButton(track, -1, "on/off")
on_off.SetMinSize((50, 20))
# create track sizer and add items
track_sizer = wx.FlexGridSizer(1,3,0,0)
track_sizer.Add(label,0,0,0)
track_sizer.Add(label_2,0,0,0)
track_sizer.Add(on_off,0,0,0)
track.SetSizer(track_sizer)
self.Canvas.AddObject(Widget(track, (-92, self.curTrack[0]) ) )
self.Canvas.AddLine(((-92,self.curLine[0]), (94, self.curLine[0])))
self.Canvas.Draw()
self.curTrack = [self.curTrack[0] - 41]
self.curLine = [self.curLine[0] - 41]
app = wx.App(False)
# F = DrawFrame(None, title="FloatCanvas Demo App", size=(700,700) )
app.MainLoop()
#!/usr/bin/env python
"""
A simple test and demo for putting Widgets on a Canvas
"""
import wx
import wx.lib.colourdb
## import the installed version
#from wx.lib.floatcanvas import NavCanvas, FloatCanvas
## import a local version
import sys
sys.path.append("../")
from floatcanvas import NavCanvas
from floatcanvas import FloatCanvas as FC
from floatcanvas.Utilities import BBox
import random
class Widget(FC.TextObjectMixin, FC.DrawObject):
"""
This class holds an arbitrary wx Widget (Control).
It will be placed at the given location, XY = (x, y) The "Position"
argument is a two character string, indicating where in relation
to the coordinates the widget should be oriented.
The first letter is: t, c, or b, for top, center and bottom The
second letter is: l, c, or r, for left, center and right The
position refers to the position relative to the text itself. It
defaults to "tl" (top left).
The size is fixed, and does not scale with the drawing.
"""
def __init__(self, Widget,
XY,
Position = 'tl',
InForeground = False):
FC.DrawObject.__init__(self,InForeground)
self.Widget = Widget
# Note the BB is just the point, as the size in World coordinates is not fixed
self.BoundingBox = BBox.asBBox( (XY,XY) )
self.XY = XY
(self.Width, self.Height) = self.Widget.Size
self.ShiftFun = self.ShiftFunDict[Position]
def _Draw(self, dc , WorldToPixel, ScaleWorldToPixel, HTdc=None):
XY = WorldToPixel(self.XY)
XY = self.ShiftFun(XY[0], XY[1], self.Width, self.Height)
self.Widget.Position = XY
self.Widget.Refresh()
# note: Widgets are not hitable, as that should be taken care fo by wx
class DrawFrame(wx.Frame):
"""
A frame used for the FloatCanvas Demo
"""
def __init__(self, *args, **kwargs):
wx.Frame.__init__(self, *args, **kwargs)
self.CreateStatusBar()
## getting all the colors for random objects
wx.lib.colourdb.updateColourDB()
self.AllColors = wx.lib.colourdb.getColourList()
# Add the Canvas
Canvas = NavCanvas.NavCanvas(self,-1,
size = (500,500),
ProjectionFun = None,
Debug = 0,
BackgroundColor = "DARK SLATE BLUE",
).Canvas
self.Canvas = Canvas
FC.EVT_MOTION(self.Canvas, self.OnMove )
self.Rectangle = Canvas.AddRectangle((50, 20), (40,10), FillColor="Red", LineStyle = None)
MyButton = wx.Button(self.Canvas, label="A Button")
MyButton.Bind(wx.EVT_BUTTON, self.OnButtonPress)
Canvas.AddObject(Widget(MyButton, (70, 25) ) )
self.Show()
Canvas.ZoomToBB()
def OnButtonPress(self, evt=None):
print "The button was pressed"
# Make the Rectangle and random color:
self.Rectangle.SetFillColor( random.choice(self.AllColors) )
self.Canvas.Draw(Force=True)
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()
#!/usr/bin/env python
# -*- coding: us-ascii -*-
# generated by wxGlade 0.6.3 on Sun Jun 12 00:41:39 2011
import wx
# begin wxGlade: extracode
# end wxGlade
# unnecessary if from ghart import trackgrid exists?
import TestChart
from TestChart import TrackGrid, Track, TrackPanel
class TestApp(wx.Frame):
def __init__(self, *args, **kwds):
# begin wxGlade: TestApp.__init__
kwds["style"] = wx.DEFAULT_FRAME_STYLE
wx.Frame.__init__(self, *args, **kwds)
self.notebook_1 = wx.Notebook(self, -1, style=wx.NB_BOTTOM)
self.notebook_1_pane_2 = wx.Panel(self.notebook_1, -1)
self.window_1 = wx.SplitterWindow(self.notebook_1_pane_2, -1, style=wx.SP_3D|wx.SP_BORDER)
self.window_1_pane_1 = wx.Panel(self.window_1, -1)
self.panel_3 = wx.Panel(self.notebook_1_pane_2, -1)
self.notebook_1_pane_1 = wx.Panel(self.notebook_1, -1)
# Menu Bar
self.frame_1_menubar = wx.MenuBar()
wxglade_tmp_menu = wx.Menu()
wxglade_tmp_menu.Append(wx.NewId(), "New Template", "", wx.ITEM_NORMAL)
wxglade_tmp_menu.Append(wx.NewId(), "Open", "", wx.ITEM_NORMAL)
wxglade_tmp_menu.Append(wx.NewId(), "Save", "", wx.ITEM_NORMAL)
wxglade_tmp_menu.Append(wx.NewId(), "Save as...", "", wx.ITEM_NORMAL)
self.frame_1_menubar.Append(wxglade_tmp_menu, "File")
wxglade_tmp_menu = wx.Menu()
wxglade_tmp_menu.Append(wx.NewId(), "Undo", "", wx.ITEM_NORMAL)
wxglade_tmp_menu.Append(wx.NewId(), "Redo", "", wx.ITEM_NORMAL)
wxglade_tmp_menu.AppendSeparator()
wxglade_tmp_menu.Append(wx.NewId(), "Cut", "", wx.ITEM_NORMAL)
wxglade_tmp_menu.Append(wx.NewId(), "Copy", "", wx.ITEM_NORMAL)
wxglade_tmp_menu.Append(wx.NewId(), "Paste", "", wx.ITEM_NORMAL)
wxglade_tmp_menu.Append(wx.NewId(), "Delete", "", wx.ITEM_NORMAL)
self.frame_1_menubar.Append(wxglade_tmp_menu, "Edit")
self.SetMenuBar(self.frame_1_menubar)
# Menu Bar end
self.frame_1_statusbar = self.CreateStatusBar(1, 0)
self.label_6 = wx.StaticText(self.notebook_1_pane_1, -1, "")
self.label_16 = wx.StaticText(self.notebook_1_pane_1, -1, "")
self.label_7 = wx.StaticText(self.notebook_1_pane_1, -1, "")
self.label_17 = wx.StaticText(self.notebook_1_pane_1, -1, "")
self.label_8 = wx.StaticText(self.notebook_1_pane_1, -1, "")
self.label_5 = wx.StaticText(self.notebook_1_pane_1, -1, "")
self.label_1 = wx.StaticText(self.notebook_1_pane_1, -1, "")
self.label_10 = wx.StaticText(self.notebook_1_pane_1, -1, "")
self.label_2 = wx.StaticText(self.notebook_1_pane_1, -1, "")
self.label_9 = wx.StaticText(self.notebook_1_pane_1, -1, "")
self.label_4 = wx.StaticText(self.notebook_1_pane_1, -1, "")
self.label_11 = wx.StaticText(self.notebook_1_pane_1, -1, "")
self.label_3 = wx.StaticText(self.notebook_1_pane_1, -1, "")
self.label_19 = wx.StaticText(self.notebook_1_pane_1, -1, "")
self.button_1 = wx.Button(self.notebook_1_pane_1, -1, "click tab below")
self.button_2 = wx.Button(self.notebook_1_pane_1, -1, "")
self.label_15 = wx.StaticText(self.notebook_1_pane_1, -1, "")
self.button_3 = wx.Button(self.notebook_1_pane_1, -1, "")
self.button_4 = wx.Button(self.notebook_1_pane_1, -1, "")
self.button_5 = wx.Button(self.notebook_1_pane_1, -1, "")
self.label_18 = wx.StaticText(self.notebook_1_pane_1, -1, "")
self.label_13 = wx.StaticText(self.notebook_1_pane_1, -1, "")
self.label_20 = wx.StaticText(self.notebook_1_pane_1, -1, "")
self.label_12 = wx.StaticText(self.notebook_1_pane_1, -1, "")
self.label_21 = wx.StaticText(self.notebook_1_pane_1, -1, "")
self.label_14 = wx.StaticText(self.notebook_1_pane_1, -1, "")
self.label_31 = wx.StaticText(self.notebook_1_pane_2, -1, "")
self.label_32 = wx.StaticText(self.notebook_1_pane_2, -1, "")
self.panel_4 = wx.Panel(self.notebook_1_pane_2, -1)
self.label_34 = wx.StaticText(self.notebook_1_pane_2, -1, "")
self.label_35 = wx.StaticText(self.notebook_1_pane_2, -1, "")
self.label_30 = wx.StaticText(self.notebook_1_pane_2, -1, "")
self.label_22 = wx.StaticText(self.notebook_1_pane_2, -1, "")
self.new_track = wx.BitmapButton(self.panel_3, -1, wx.Bitmap("/Developer/Examples/Sync Services/People/plus-pressed.tiff", wx.BITMAP_TYPE_ANY))
self.label_36 = wx.StaticText(self.notebook_1_pane_2, -1, "")
self.label_37 = wx.StaticText(self.notebook_1_pane_2, -1, "")
self.label_28 = wx.StaticText(self.notebook_1_pane_2, -1, "")
self.panel_2 = wx.Panel(self.notebook_1_pane_2, -1)
self.track_panel = TrackPanel(self.window_1_pane_1, -1)
self.trackNavCanvas = TrackGrid(self.window_1_pane_1, -1, BackgroundColor = "Grey")
self.window_1_pane_2 = wx.Panel(self.window_1, -1)
self.panel_5 = wx.Panel(self.notebook_1_pane_2, -1)
self.label_29 = wx.StaticText(self.notebook_1_pane_2, -1, "")
self.label_41 = wx.StaticText(self.notebook_1_pane_2, -1, "")
self.label_40 = wx.StaticText(self.notebook_1_pane_2, -1, "")
self.label_27 = wx.StaticText(self.notebook_1_pane_2, -1, "")
self.label_39 = wx.StaticText(self.notebook_1_pane_2, -1, "")
self.label_38 = wx.StaticText(self.notebook_1_pane_2, -1, "")
self.label_23 = wx.StaticText(self.notebook_1_pane_2, -1, "")
self.label_24 = wx.StaticText(self.notebook_1_pane_2, -1, "")
self.panel_1 = wx.Panel(self.notebook_1_pane_2, -1)
self.label_25 = wx.StaticText(self.notebook_1_pane_2, -1, "")
self.label_26 = wx.StaticText(self.notebook_1_pane_2, -1, "")
self.__set_properties()
self.__do_layout()
# end wxGlade
def __set_properties(self):
# begin wxGlade: TestApp.__set_properties
self.SetTitle("Test App")
self.SetSize((1239, 778))
self.frame_1_statusbar.SetStatusWidths([-1])
# statusbar fields
frame_1_statusbar_fields = [""]
for i in range(len(frame_1_statusbar_fields)):
self.frame_1_statusbar.SetStatusText(frame_1_statusbar_fields[i], i)
self.panel_4.SetMinSize((832, 60))
self.panel_4.SetBackgroundColour(wx.Colour(118, 118, 118))
self.new_track.SetMinSize((20, 20))
self.panel_3.SetBackgroundColour(wx.Colour(171, 178, 175))
self.panel_2.SetMinSize((160, 595))
self.panel_2.SetBackgroundColour(wx.Colour(119, 119, 119))
self.track_panel.SetMinSize((190, 580))
self.trackNavCanvas.SetMinSize((873, 0))
self.panel_5.SetMinSize((20, 595))
self.panel_5.SetBackgroundColour(wx.Colour(131, 131, 131))
self.panel_1.SetMinSize((1232, 16))
self.panel_1.SetBackgroundColour(wx.Colour(76, 76, 76))
self.notebook_1_pane_2.SetMinSize((1234, 721))
self.notebook_1.SetMinSize((1234, 755))
# end wxGlade
def __do_layout(self):
# begin wxGlade: TestApp.__do_layout
sizer_1 = wx.BoxSizer(wx.HORIZONTAL)
grid_sizer_2 = wx.FlexGridSizer(5, 5, 0, 0)
grid_sizer_3 = wx.FlexGridSizer(1, 2, 0, 0)
sizer_8 = wx.BoxSizer(wx.VERTICAL)
grid_sizer_1 = wx.FlexGridSizer(5, 5, 0, 0)
sizer_2 = wx.BoxSizer(wx.HORIZONTAL)
sizer_3 = wx.BoxSizer(wx.HORIZONTAL)
grid_sizer_1.Add(self.label_6, 0, 0, 0)
grid_sizer_1.Add(self.label_16, 0, 0, 0)
grid_sizer_1.Add(self.label_7, 0, 0, 0)
grid_sizer_1.Add(self.label_17, 0, 0, 0)
grid_sizer_1.Add(self.label_8, 0, 0, 0)
grid_sizer_1.Add(self.label_5, 0, 0, 0)
grid_sizer_1.Add(self.label_1, 0, wx.LEFT|wx.ALIGN_CENTER_HORIZONTAL, 116)
grid_sizer_1.Add(self.label_10, 0, 0, 0)
grid_sizer_1.Add(self.label_2, 0, wx.LEFT|wx.ALIGN_CENTER_HORIZONTAL, 49)
grid_sizer_1.Add(self.label_9, 0, 0, 0)
grid_sizer_1.Add(self.label_4, 0, 0, 0)
grid_sizer_1.Add(self.label_11, 0, 0, 0)
grid_sizer_1.Add(self.label_3, 0, 0, 0)
grid_sizer_1.Add(self.label_19, 0, wx.LEFT, 27)
sizer_3.Add(self.button_1, 0, wx.LEFT, 115)
sizer_3.Add(self.button_2, 0, 0, 0)
grid_sizer_1.Add(sizer_3, 1, wx.EXPAND, 0)
grid_sizer_1.Add(self.label_15, 0, 0, 0)
sizer_2.Add(self.button_3, 0, wx.LEFT, 45)
sizer_2.Add(self.button_4, 0, 0, 0)
sizer_2.Add(self.button_5, 0, 0, 0)
grid_sizer_1.Add(sizer_2, 1, wx.ALIGN_CENTER_HORIZONTAL, 0)
grid_sizer_1.Add(self.label_18, 0, 0, 0)
grid_sizer_1.Add(self.label_13, 0, 0, 0)
grid_sizer_1.Add(self.label_20, 0, 0, 0)
grid_sizer_1.Add(self.label_12, 0, 0, 0)
grid_sizer_1.Add(self.label_21, 0, 0, 0)
grid_sizer_1.Add(self.label_14, 0, 0, 0)
self.notebook_1_pane_1.SetSizer(grid_sizer_1)
grid_sizer_2.Add(self.label_31, 0, 0, 0)
grid_sizer_2.Add(self.label_32, 0, 0, 0)
grid_sizer_2.Add(self.panel_4, 1, wx.EXPAND, 0)
grid_sizer_2.Add(self.label_34, 0, 0, 0)
grid_sizer_2.Add(self.label_35, 0, 0, 0)
grid_sizer_2.Add(self.label_30, 0, 0, 0)
grid_sizer_2.Add(self.label_22, 0, 0, 0)
sizer_8.Add(self.new_track, 0, wx.LEFT, 20)
self.panel_3.SetSizer(sizer_8)
grid_sizer_2.Add(self.panel_3, 1, wx.ALL|wx.EXPAND, 0)
grid_sizer_2.Add(self.label_36, 0, 0, 0)
grid_sizer_2.Add(self.label_37, 0, 0, 0)
grid_sizer_2.Add(self.label_28, 0, 0, 0)
grid_sizer_2.Add(self.panel_2, 1, wx.EXPAND, 0)
grid_sizer_3.Add(self.track_panel, 1, wx.EXPAND, 0)
grid_sizer_3.Add(self.trackNavCanvas, 1, wx.EXPAND, 0)
self.window_1_pane_1.SetSizer(grid_sizer_3)
self.window_1.SplitHorizontally(self.window_1_pane_1, self.window_1_pane_2)
grid_sizer_2.Add(self.window_1, 1, wx.EXPAND, 0)
grid_sizer_2.Add(self.panel_5, 1, wx.EXPAND, 0)
grid_sizer_2.Add(self.label_29, 0, 0, 0)
grid_sizer_2.Add(self.label_41, 0, 0, 0)
grid_sizer_2.Add(self.label_40, 0, 0, 0)
grid_sizer_2.Add(self.label_27, 0, 0, 0)
grid_sizer_2.Add(self.label_39, 0, 0, 0)
grid_sizer_2.Add(self.label_38, 0, 0, 0)
grid_sizer_2.Add(self.label_23, 0, 0, 0)
grid_sizer_2.Add(self.label_24, 0, 0, 0)
grid_sizer_2.Add(self.panel_1, 1, wx.EXPAND, 0)
grid_sizer_2.Add(self.label_25, 0, 0, 0)
grid_sizer_2.Add(self.label_26, 0, 0, 0)
self.notebook_1_pane_2.SetSizer(grid_sizer_2)
self.notebook_1.AddPage(self.notebook_1_pane_1, "")
self.notebook_1.AddPage(self.notebook_1_pane_2, "tab")
sizer_1.Add(self.notebook_1, 1, wx.EXPAND, 19)
self.SetSizer(sizer_1)
self.Layout()
# end wxGlade
self.new_track.Bind(wx.EVT_BUTTON, self.NewTrack)
def Allow(self, event): # wxGlade: TestApp.<event_handler>
print "Event handler `Allow' not implemented!"
event.Skip()
def NewTrack(self, event):
""" When 'new_track' bitmap button is clicked, add one row to TrackGrid (calls TrackGrid function)
Will also call AddTrack which will create and assemble the track
"""
self.trackNavCanvas.AddTrackRow()
self.trackNavCanvas.AddLines() # redraws grid lines so to be seen
self.track_panel.AddTrack()
# end of class TestApp
if __name__ == "__main__":
app = wx.PySimpleApp(0)
wx.InitAllImageHandlers()
frame_1 = TestApp(None, -1, "")
app.SetTopWindow(frame_1)
frame_1.Show()
app.MainLoop()
_______________________________________________
FloatCanvas mailing list
[email protected]
http://paulmcnett.com/cgi-bin/mailman/listinfo/floatcanvas