Discussion:
[fc] Remove object
Werner F. Bruhin
2013-02-18 18:30:37 UTC
Permalink
Hi,

When I need to delete an object I do:

if self._selectedObject:
runit =
self.ds.query(db.Wineracku).get(self._selectedObject.rackUnitId)
self.doListItemDelete(runit)
self.canvas.RemoveObject(self._selectedObject)
self._rackModulesCount -= 1
self._rackModules.remove(self._selectedObject)
self._selectedObject = None
self.canvas.ZoomToBB()
self.canvas.Draw(True)

After above code the related database items are gone (doListItemDelete)
but the _selectedObject is still shown on the canvas, I have to close
and reload to see the change.

What step am I missing in the delete? BTW, the _selectedObject is an
"fc.Group" type object. Do I have to remove the objects which are
grouped by this selected object individually?

Werner
Chris Barker - NOAA Federal
2013-02-19 05:31:43 UTC
Permalink
Hi Werner,

On Mon, Feb 18, 2013 at 10:30 AM, Werner F. Bruhin
Post by Werner F. Bruhin
runit =
self.ds.query(db.Wineracku).get(self._selectedObject.rackUnitId)
self.doListItemDelete(runit)
self.canvas.RemoveObject(self._selectedObject)
self._rackModulesCount -= 1
self._rackModules.remove(self._selectedObject)
self._selectedObject = None
self.canvas.ZoomToBB()
self.canvas.Draw(True)
After above code the related database items are gone (doListItemDelete)
but the _selectedObject is still shown on the canvas, I have to close
and reload to see the change.
What step am I missing in the delete?
That sure should do it.
BTW, the _selectedObject is an
"fc.Group" type object. Do I have to remove the objects which are
grouped by this selected object individually?
Not unless you added the sub-objects directly to the canvas...

I've enclosed a demo app that puts a couple groups on the canvas, and
removes then when you click the "remove" button -- it works fine for
me (wxPython2.8, on a Mac).

Do note that if you click the "ReplaceA" (or B) button more than once,
it will put multiple references to the object on the canvas, so you
have to click "RemoveA" multiple times as well. Is there a chance that
in your code, you've added the group in question more than once?

-Chris
--
Christopher Barker, Ph.D.
Oceanographer

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

Chris.Barker-***@public.gmane.org
Werner F. Bruhin
2013-02-19 07:16:21 UTC
Permalink
Hi Chris,

On 19/02/2013 06:31, Chris Barker - NOAA Federal wrote:

...
Post by Chris Barker - NOAA Federal
Not unless you added the sub-objects directly to the canvas...
That was my problem, didn't only add directly to the canvas but also to
the group, so no wonder delete didn't work.

Thanks for the quick reply.

Werner
Werner F. Bruhin
2013-02-19 11:31:45 UTC
Permalink
Hi Chris,
Post by Werner F. Bruhin
Hi Chris,
...
Post by Chris Barker - NOAA Federal
Not unless you added the sub-objects directly to the canvas...
That was my problem, didn't only add directly to the canvas but also to
the group, so no wonder delete didn't work.
Hhm, a bit to quick, I have it fixed in the "designer" which has hittest
on the group object, but in the "viewer" which has hittest on the member
of the group object I get this exception:

AttributeError: 'NoneType' object has no attribute 'UseHitTest'
File "c:\dev\twcbv4\twcbsrc\controllers\fwinerackview.py", line 589, in
<module>
app.MainLoop()
File "c:\Python27\Lib\site-packages\wx-2.9.5-msw\wx\_core.py", line
8660, in MainLoop
wx.PyApp.MainLoop(self)
File "c:\Python27\Lib\site-packages\wx-2.9.5-msw\wx\_core.py", line
7952, in MainLoop
return _core_.PyApp_MainLoop(*args, **kwargs)
File "c:\dev\twcbv4\twcbsrc\libui\cpopupctrl.py", line 77, in onLeftUp
self.notify()
File "c:\dev\twcbv4\twcbsrc\libui\cpopupctrl.py", line 54, in notify
self.GetEventHandler().ProcessEvent(evt)
File "c:\Python27\Lib\site-packages\wx-2.9.5-msw\wx\_core.py", line
4154, in ProcessEvent
return _core_.EvtHandler_ProcessEvent(*args, **kwargs)
File "c:\dev\twcbv4\twcbsrc\libui\cpopupctrl.py", line 282, in onButton
self.doPop()
File "c:\dev\twcbv4\twcbsrc\libui\cpopupctrl.py", line 294, in doPop
self.pop.display()
File "c:\dev\twcbv4\twcbsrc\libui\cpopupctrl.py", line 203, in display
self.ShowModal()
File "c:\Python27\Lib\site-packages\wx-2.9.5-msw\wx\_windows.py", line
805, in ShowModal
return _windows_.Dialog_ShowModal(*args, **kwargs)
File "c:\dev\twcbv4\twcbsrc\libui\searchctrl.py", line 417, in
onOLVItemSelected
self.doSetDbItem(selObj)
File "c:\dev\twcbv4\twcbsrc\libui\searchctrl.py", line 506, in doSetDbItem
self.doSetDbItemBase(item)
File "c:\dev\twcbv4\twcbsrc\libui\searchctrl.py", line 489, in
doSetDbItemBase
self.GetEventHandler().ProcessEvent(evt)
File "c:\Python27\Lib\site-packages\wx-2.9.5-msw\wx\_core.py", line
4154, in ProcessEvent
return _core_.EvtHandler_ProcessEvent(*args, **kwargs)
File "c:\dev\twcbv4\twcbsrc\controllers\fwinerackview.py", line 176, in
onWinerack
self.viewRack(dbItem)
File "c:\dev\twcbv4\twcbsrc\controllers\fwinerackview.py", line 436, in
viewRack
self.loadRack()
File "c:\dev\twcbv4\twcbsrc\controllers\fwinerackview.py", line 448, in
loadRack
self.loadMovingGroup(mg)
File "c:\dev\twcbv4\twcbsrc\controllers\fwinerackview.py", line 495, in
loadMovingGroup
bot.Bind(fc.EVT_FC_LEFT_DOWN, self.objectHit)
File
"c:\Python27\Lib\site-packages\wx-2.9.5-msw\wx\lib\floatcanvas\FloatCanvas.py",
line 247, in Bind
self._Canvas.UseHitTest = True

Line 495 in fwinerackview.py is the last line in the following snippet:
bot = rutils.MovingCircle((x, y), dia,
LineColor=lineColour,
LineWidth=lineWidth,
FillColor=fillColor,
FillStyle=fillStyle)
bot.rackItemId = cir.rackitemid

#self.canvas.AddObject(bot)

rackUnit.AddObject(bot)
print bot
bot.Bind(fc.EVT_FC_LEFT_DOWN, self.objectHit)

and the print in the above is:
<twcbsrc.tools.rack_utils.MovingCircle instance at 0x076AC620>

which is:
class MovingCircle(fc.Circle, MovingObjectMixin, PersistMovingCircleMixin):
"""
Circle Object that can be moved
"""
## All we need to do is is inherit from:
## Circle, MovingObjectMixin
def __init__(self, *args, **kwargs):
fc.Circle.__init__(self, *args, **kwargs)
PersistMovingCircleMixin.__init__(self)

Any idea?

Werner
Post by Werner F. Bruhin
Thanks for the quick reply.
Werner
_______________________________________________
FloatCanvas mailing list
http://paulmcnett.com/cgi-bin/mailman/listinfo/floatcanvas
Chris Barker - NOAA Federal
2013-02-19 18:00:13 UTC
Permalink
Werner ,

Hard to help much now--only have iPhone-- but:

It looks like the draw object didn't get it's self._Canvas attribute
set-- that should happen when it is added to the canvas. If it's part
of a group, then the group would have had it set, but not the
sub-object.

Group is not all that well tested, I suspect an object needs to be
either in group or on its own, but can't be half and half.

Chris



may be None at that point- did the code that assigns it get called?
Post by Werner F. Bruhin
Hi Chris,
Post by Werner F. Bruhin
Hi Chris,
...
Post by Chris Barker - NOAA Federal
Not unless you added the sub-objects directly to the canvas...
That was my problem, didn't only add directly to the canvas but also to
the group, so no wonder delete didn't work.
Hhm, a bit to quick, I have it fixed in the "designer" which has hittest
on the group object, but in the "viewer" which has hittest on the member
AttributeError: 'NoneType' object has no attribute 'UseHitTest'
File "c:\dev\twcbv4\twcbsrc\controllers\fwinerackview.py", line 589, in
<module>
app.MainLoop()
File "c:\Python27\Lib\site-packages\wx-2.9.5-msw\wx\_core.py", line
8660, in MainLoop
wx.PyApp.MainLoop(self)
File "c:\Python27\Lib\site-packages\wx-2.9.5-msw\wx\_core.py", line
7952, in MainLoop
return _core_.PyApp_MainLoop(*args, **kwargs)
File "c:\dev\twcbv4\twcbsrc\libui\cpopupctrl.py", line 77, in onLeftUp
self.notify()
File "c:\dev\twcbv4\twcbsrc\libui\cpopupctrl.py", line 54, in notify
self.GetEventHandler().ProcessEvent(evt)
File "c:\Python27\Lib\site-packages\wx-2.9.5-msw\wx\_core.py", line
4154, in ProcessEvent
return _core_.EvtHandler_ProcessEvent(*args, **kwargs)
File "c:\dev\twcbv4\twcbsrc\libui\cpopupctrl.py", line 282, in onButton
self.doPop()
File "c:\dev\twcbv4\twcbsrc\libui\cpopupctrl.py", line 294, in doPop
self.pop.display()
File "c:\dev\twcbv4\twcbsrc\libui\cpopupctrl.py", line 203, in display
self.ShowModal()
File "c:\Python27\Lib\site-packages\wx-2.9.5-msw\wx\_windows.py", line
805, in ShowModal
return _windows_.Dialog_ShowModal(*args, **kwargs)
File "c:\dev\twcbv4\twcbsrc\libui\searchctrl.py", line 417, in
onOLVItemSelected
self.doSetDbItem(selObj)
File "c:\dev\twcbv4\twcbsrc\libui\searchctrl.py", line 506, in doSetDbItem
self.doSetDbItemBase(item)
File "c:\dev\twcbv4\twcbsrc\libui\searchctrl.py", line 489, in
doSetDbItemBase
self.GetEventHandler().ProcessEvent(evt)
File "c:\Python27\Lib\site-packages\wx-2.9.5-msw\wx\_core.py", line
4154, in ProcessEvent
return _core_.EvtHandler_ProcessEvent(*args, **kwargs)
File "c:\dev\twcbv4\twcbsrc\controllers\fwinerackview.py", line 176, in
onWinerack
self.viewRack(dbItem)
File "c:\dev\twcbv4\twcbsrc\controllers\fwinerackview.py", line 436, in
viewRack
self.loadRack()
File "c:\dev\twcbv4\twcbsrc\controllers\fwinerackview.py", line 448, in
loadRack
self.loadMovingGroup(mg)
File "c:\dev\twcbv4\twcbsrc\controllers\fwinerackview.py", line 495, in
loadMovingGroup
bot.Bind(fc.EVT_FC_LEFT_DOWN, self.objectHit)
File
"c:\Python27\Lib\site-packages\wx-2.9.5-msw\wx\lib\floatcanvas\FloatCanvas.py",
line 247, in Bind
self._Canvas.UseHitTest = True
bot = rutils.MovingCircle((x, y), dia,
LineColor=lineColour,
LineWidth=lineWidth,
FillColor=fillColor,
FillStyle=fillStyle)
bot.rackItemId = cir.rackitemid
#self.canvas.AddObject(bot)
rackUnit.AddObject(bot)
print bot
bot.Bind(fc.EVT_FC_LEFT_DOWN, self.objectHit)
<twcbsrc.tools.rack_utils.MovingCircle instance at 0x076AC620>
"""
Circle Object that can be moved
"""
## Circle, MovingObjectMixin
fc.Circle.__init__(self, *args, **kwargs)
PersistMovingCircleMixin.__init__(self)
Any idea?
Werner
Post by Werner F. Bruhin
Thanks for the quick reply.
Werner
_______________________________________________
FloatCanvas mailing list
http://paulmcnett.com/cgi-bin/mailman/listinfo/floatcanvas
_______________________________________________
FloatCanvas mailing list
http://paulmcnett.com/cgi-bin/mailman/listinfo/floatcanvas
Werner F. Bruhin
2013-02-19 19:02:30 UTC
Permalink
Hi Chris,
Post by Chris Barker - NOAA Federal
Werner ,
Nothing urgent.
Post by Chris Barker - NOAA Federal
It looks like the draw object didn't get it's self._Canvas attribute
set-- that should happen when it is added to the canvas. If it's part
of a group, then the group would have had it set, but not the
sub-object.
Group is not all that well tested, I suspect an object needs to be
either in group or on its own, but can't be half and half.
It is in the group, but then I can't bind a "fc.EVT_FC_LEFT_DOWN".

If I do canvas.AddObject and groupObj.AddObject in the viewer then I can
do the bind, as if the groupObj.AddObject does not add "self._Canvas" to
the object one adds to the group object.

No big deal as doing "my" dual add in the "viewer" works for me, and
doesn't seem to have any undesired side effects.

In the designer I only add to the group and there it works too, but in
the designer I only need to select the group and not the item within a
group.

Have a nice day
Werner
Chris Barker - NOAA Federal
2013-02-21 15:50:54 UTC
Permalink
Werner,

I looked a bit more into your issue if binding to objects within a Group:

Putting the object both in the group and by itself is fine -- it will
result in it being drawn twice, but no big deal. It also will change
the draw order, which may not be ideal in some instances.

However, to do it right:

First, a kludge: the issue is that when added to the canvas as part of
a Group, an individual object doesn't get a reference to the canvas --
but you can add one by hand:

TheObject._Canvas = TheCanvas

or

TheObject._Canvas = TheGroup._Canvas # after the group has been added
to the canvas.

But I've also fixed the issue, but adding a bit of code to the Group
code. So you could grab the latest version from SVN:

http://svn.wxwidgets.org/svn/wx/wxPython/3rdParty/FloatCanvas/

and binding to a sub-object should "just work".

-Chris





On Tue, Feb 19, 2013 at 11:02 AM, Werner F. Bruhin
Post by Werner F. Bruhin
Hi Chris,
Post by Chris Barker - NOAA Federal
Werner ,
Nothing urgent.
Post by Chris Barker - NOAA Federal
It looks like the draw object didn't get it's self._Canvas attribute
set-- that should happen when it is added to the canvas. If it's part
of a group, then the group would have had it set, but not the
sub-object.
Group is not all that well tested, I suspect an object needs to be
either in group or on its own, but can't be half and half.
It is in the group, but then I can't bind a "fc.EVT_FC_LEFT_DOWN".
If I do canvas.AddObject and groupObj.AddObject in the viewer then I can
do the bind, as if the groupObj.AddObject does not add "self._Canvas" to
the object one adds to the group object.
No big deal as doing "my" dual add in the "viewer" works for me, and
doesn't seem to have any undesired side effects.
In the designer I only add to the group and there it works too, but in
the designer I only need to select the group and not the item within a
group.
Have a nice day
Werner
_______________________________________________
FloatCanvas mailing list
http://paulmcnett.com/cgi-bin/mailman/listinfo/floatcanvas
--
Christopher Barker, Ph.D.
Oceanographer

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

Chris.Barker-***@public.gmane.org
Werner F. Bruhin
2013-02-21 16:30:42 UTC
Permalink
Chris,

Thanks for having looked into this and for the fix. Will give the SVN
code a go and let you know how it is going.

Werner
Post by Chris Barker - NOAA Federal
Werner,
Putting the object both in the group and by itself is fine -- it will
result in it being drawn twice, but no big deal. It also will change
the draw order, which may not be ideal in some instances.
First, a kludge: the issue is that when added to the canvas as part of
a Group, an individual object doesn't get a reference to the canvas --
TheObject._Canvas = TheCanvas
or
TheObject._Canvas = TheGroup._Canvas # after the group has been added
to the canvas.
But I've also fixed the issue, but adding a bit of code to the Group
http://svn.wxwidgets.org/svn/wx/wxPython/3rdParty/FloatCanvas/
and binding to a sub-object should "just work".
-Chris
On Tue, Feb 19, 2013 at 11:02 AM, Werner F. Bruhin
Post by Werner F. Bruhin
Hi Chris,
Post by Chris Barker - NOAA Federal
Werner ,
Nothing urgent.
Post by Chris Barker - NOAA Federal
It looks like the draw object didn't get it's self._Canvas attribute
set-- that should happen when it is added to the canvas. If it's part
of a group, then the group would have had it set, but not the
sub-object.
Group is not all that well tested, I suspect an object needs to be
either in group or on its own, but can't be half and half.
It is in the group, but then I can't bind a "fc.EVT_FC_LEFT_DOWN".
If I do canvas.AddObject and groupObj.AddObject in the viewer then I can
do the bind, as if the groupObj.AddObject does not add "self._Canvas" to
the object one adds to the group object.
No big deal as doing "my" dual add in the "viewer" works for me, and
doesn't seem to have any undesired side effects.
In the designer I only add to the group and there it works too, but in
the designer I only need to select the group and not the item within a
group.
Have a nice day
Werner
_______________________________________________
FloatCanvas mailing list
http://paulmcnett.com/cgi-bin/mailman/listinfo/floatcanvas
Werner F. Bruhin
2013-02-22 08:53:33 UTC
Permalink
Hi Chris,

The Bind issue is resolved, while testing this I noted another issue
with Groups and I wonder if that could be fixed too.

e.g. I do this:

startPos = self.getStartPos() + 2

rackFrame = rutils.MovingRectangle((startPos, 0), (100, 100))

# add it to canvas too, otherwise next object will overlap
this one
self.canvas.AddObject(rackFrame)
rackUnit.AddObject(rackFrame)
rackUnit.Bind(fc.EVT_FC_LEFT_DOWN, self.objectHit)

If I don't add the rackFrame to the canvas directly then the getStartPos
does not get the right position, i.e. the next object I add will be
drawn on top of the previous one. Note that the rackUnit in this case
is a "class MovingGroup(fc.Group, MovingObjectMixin,
RackUnitPersistanceMixin):"

def getStartPos(self):
if self.canvas.BoundingBoxDirty:
self.canvas._ResetBoundingBox()

bBox = self.canvas.BoundingBox[1]
if bBox.IsNull():
startPos = 0
else:
startPos = bBox[0]

return startPos

Is above enough information for you, or do I need to debug it further?

Werner
Chris Barker - NOAA Federal
2013-02-22 19:45:59 UTC
Permalink
On Fri, Feb 22, 2013 at 12:53 AM, Werner F. Bruhin
Post by Werner F. Bruhin
The Bind issue is resolved, while testing this I noted another issue
with Groups and I wonder if that could be fixed too.
startPos = self.getStartPos() + 2
rackFrame = rutils.MovingRectangle((startPos, 0), (100, 100))
# add it to canvas too, otherwise next object will overlap
this one
self.canvas.AddObject(rackFrame)
rackUnit.AddObject(rackFrame)
rackUnit.Bind(fc.EVT_FC_LEFT_DOWN, self.objectHit)
If I don't add the rackFrame to the canvas directly then the getStartPos
does not get the right position, i.e. the next object I add will be
drawn on top of the previous one.
Werner,

I"m not really surprised that having a MovingObject inside a
MovingObjectGroup doesn't work quite right.

I suspect that some extra code will need to be added when making a
MovingGroup. i.e. something that adjust the positions of all the
sub-objects at the end of the move.
Post by Werner F. Bruhin
Note that the rackUnit in this case
is a "class MovingGroup(fc.Group, MovingObjectMixin,
RackUnitPersistanceMixin):"
self.canvas._ResetBoundingBox()
bBox = self.canvas.BoundingBox[1]
startPos = 0
startPos = bBox[0]
return startPos
Is above enough information for you, or do I need to debug it further?
I"m still a bit confused about how this is all nested. If you could
make a stand alone sample with a couple MovingObjects in a
MovingObjectGroup, that may clarify it, and help one of us figure out
where the issue is.

-CHB
--
Christopher Barker, Ph.D.
Oceanographer

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

Chris.Barker-***@public.gmane.org
Werner F. Bruhin
2013-02-22 21:43:50 UTC
Permalink
Hi Chris,
Post by Chris Barker - NOAA Federal
I"m still a bit confused about how this is all nested. If you could
make a stand alone sample with a couple MovingObjects in a
MovingObjectGroup, that may clarify it, and help one of us figure out
where the issue is.
Just adding the object twice in my "designer" makes it work.

Will try and come up with some stand alone code to demonstrate the problem.

I also want to re-factor stuff to have better reuse of code, so all this
might take a bit.

Werner
Chris Barker - NOAA Federal
2013-02-22 21:44:14 UTC
Permalink
Post by Werner F. Bruhin
Post by Chris Barker - NOAA Federal
I"m still a bit confused about how this is all nested. If you could
make a stand alone sample with a couple MovingObjects in a
MovingObjectGroup, that may clarify it, and help one of us figure out
where the issue is.
Just adding the object twice in my "designer" makes it work.
Will try and come up with some stand alone code to demonstrate the problem.
I also want to re-factor stuff to have better reuse of code, so all this
might take a bit.
I'm in no hurry!

-CHB
--
Christopher Barker, Ph.D.
Oceanographer

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

Chris.Barker-***@public.gmane.org
Werner F. Bruhin
2013-02-23 12:32:54 UTC
Permalink
Hi Chris,

I finally managed to recreate my problem with a changed version of the
GroupDemo.py which I attach.

Un-comment line 205 to have the yellow rectangle show to the right of
the circles/box created by "doUnitSingleBottle".

Can you see with this what I am doing wrong/missing or .....

Have a nice weekend
Werner
Chris Barker - NOAA Federal
2013-02-23 20:10:45 UTC
Permalink
Werner,

I think I see the issue now:

first: I'm not sure I'd leverage the Canvas boudnign box to figure out
where to put stuff, but rather, keep track of the coordinates of you
objects yourself, so you can place things relative to other objects
regardless of what else is on the canvas.

however, what you did should work.

The issue is that you've created a group object, then added it to the
Canvas, then added sub-objects to it. Apparently, the boudning box of
the canvas doesn't get properly updated when you do things in that
order.

I moved the line:

self.Canvas.AddObject(rackUnit)


to after adding all the sub-objects (line 204 in my version), and I
think it works like you expect.

But it would be better if the canvas boundign box was properly updated
when objects were added to a group. I'll try to take a look at that
now.

-Chris
--
Christopher Barker, Ph.D.
Oceanographer

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

Chris.Barker-***@public.gmane.org
Chris Barker - NOAA Federal
2013-02-24 06:47:00 UTC
Permalink
Post by Chris Barker - NOAA Federal
first: I'm not sure I'd leverage the Canvas boudnign box to figure out
where to put stuff, but rather, keep track of the coordinates of you
objects yourself, so you can place things relative to other objects
regardless of what else is on the canvas.
I still think it's best to think of the Canvas Bounding Box as
something for internal use. However, in this case, you are tryhing to
place somethign relative to a Group, so whay not use the Group
boudnign box?

self.doUnitSingleBottle()
BB = self.rackUnit.BoundingBox
pr = FloatCanvas.Rectangle((BB.Right,BB.Bottom),
(10, 18),
FillColor="yellow")
Canvas.AddObject(pr)

See my latest version of the code (enclosed)

-Chris
--
Christopher Barker, Ph.D.
Oceanographer

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

Chris.Barker-***@public.gmane.org
Werner F. Bruhin
2013-02-24 07:24:09 UTC
Permalink
Good morning Chris,

Thanks a lot for looking into this.

I basically want to ensure that nothing overlaps or is hidden when new
stuff is added. The user will then move things to where it should be.

The group.BoundingBox will actually come in handy for an rack unit type
I haven't done yet, multiple shelves where each has one of the units I
currently support.

Thanks again and have a nice weekend
Werner

Benjamin Jessup
2013-02-22 15:24:42 UTC
Permalink
Post by Werner F. Bruhin
Post by Chris Barker - NOAA Federal
Group is not all that well tested, I suspect an object needs to be
either in group or on its own, but can't be half and half.
It is in the group, but then I can't bind a "fc.EVT_FC_LEFT_DOWN".
I know this is semi off-topic, and probably a repeat of old news, but I
want to remind everyone that if the objects are similar to make use of
the "list" drawing routines (in my original copy of FC - Chris put a
note about this; which I ran with). They increase speed dramatically
when objects are the same. A snippit from my modified
FloatCanvas._DrawObjects routine:

<code>

#Some lists of fc draw objects
Branches = []
Nodes = []
Tees = []

#If we want to draw fast
if UseFastRoutine:
lw = 1

dc.DrawRectangleList([x._Draw(dc,WorldToPixel,ScaleWorldToPixel,HTdc,draw =
False) for x in Branches],
wx.Pen('BLACK',lw,wx.SOLID),
wx.Brush((255,255,255)))

dc.DrawEllipseList([x._Draw(dc,WorldToPixel,ScaleWorldToPixel,HTdc,draw
= False) for x in Nodes],
wx.Pen('BLACK',lw,wx.SOLID),
wx.Brush((255,255,255)))

dc.DrawRectangleList([x._Draw(dc,WorldToPixel,ScaleWorldToPixel,HTdc,draw =
False) for x in Tees],
wx.Pen('BLACK',lw,wx.SOLID),
wx.Brush((255,255,255)))
</code>

This is the best way I could find to make drawing times reasonable for
very large number of objects. The extra work pays off in the long run,
as the GUI is much much more responsive. I combine this with an
additional routine called FloatCanvas.Update which allows me to do the
fast drawing times while being able to update small pieces of the
workspace (so that when a user clicks on a single object, I can
highlight it, without having to re-draw everything. There are some
caveats with this when using different line widths .... ask me if you
want my solution). My Floatcanvas.Update function is attached for any
comments.

Werner - I don't think you have all that many objects but in case you
ever need to add more :-)

Thanks,
Ben
Benjamin Jessup
2013-02-22 15:35:10 UTC
Permalink
One thing I could use some help with if anyone is bored.... I try to
draw a constant message overtop the FloatCanvas, which is always there
and always in the same position (top left corner). I did not want to use
a floatcanvas object for this as I (thought I?) would have to keep
moving it's position... so my solution is below. It works but I have a
very strange bug in my program where if you click a wx.Menubar then
click the FC (which calls FC.Draw), my message disappears until the next
draw... :(

The code is below... and is super-sloppy. I will work on trying to
create a small sample with the original FC module that recreates the
issue (it is probably 99% not a problem with FC). I investigated
FC.OnPaint but that never seems to get called. For the longest time I
thought that FC was a subclass of wx.Window ... and this issue made me
realize the sheer amount of work Chris put in. Chris - cannot thank you
enough for your effort!

(Code is not clean - ignore my self._options, that is my globals class
for getting drawing attributes)

<code>

def DrawMessage(self,dc):
#print "%s.DrawMessage: drawing message..." % (self)
ScreenDC = dc
Font = eval(self._options.Get(opt.OPT_WORKSPACE_FONT, dont_print = True))
Font.SetPointSize(12)
ScreenDC.SetFont(Font)
ScreenDC.SetBackgroundMode(wx.SOLID)
ScreenDC.SetBackground(self.BackgroundBrush)
selection = self._options(opt.OPT_DISPLAY_BRANCH_RESULTS)
if not selection: selection = self._options(opt.OPT_DISPLAY_NODE_RESULTS)
msg = self.GetShowingText(selection)
ScreenDC.DrawText(msg,5,5)
#Get text height
w,h = ScreenDC.GetTextExtent('X')
selection = self._options(opt.OPT_DISPLAY_BRANCH_RESULTS2)
if not selection: selection = self._options(opt.OPT_DISPLAY_NODE_RESULTS2)
msg = self.GetShowingText(selection)
if selection:
ScreenDC.DrawText(msg,5,5+h)
draw2 = True
else:
draw2 = False
selection = self._options(opt.OPT_DISPLAY_BRANCH_RESULTS3)
if not selection: selection = self._options(opt.OPT_DISPLAY_NODE_RESULTS3)
msg = self.GetShowingText(selection)
if selection:
if draw2: ScreenDC.DrawText(msg,5,5+h+h)
else: ScreenDC.DrawText(msg,5,5+h)

</code>

Thanks,
Ben
Chris Barker - NOAA Federal
2013-02-22 19:37:58 UTC
Permalink
Post by Benjamin Jessup
One thing I could use some help with if anyone is bored.... I try to
draw a constant message overtop the FloatCanvas, which is always there
and always in the same position (top left corner). I did not want to use
a floatcanvas object for this as I (thought I?) would have to keep
moving it's position...
yes, pretty much true, but it turns out there is a way to leverage
FloatCanvas objects...
Post by Benjamin Jessup
I investigated
FC.OnPaint but that never seems to get called. For the longest time I
thought that FC was a subclass of wx.Window ...
well, it it a subclas of wx.Panel (which subclasses wx.Window), but
there is a lot ni ther to control the drawing, so it's a bit hard to
hook int it the way you are doing it.

But, it turns out that I added a feature a whihle back to support
drawing grids (or graticules) on top of, or under, the rest of the
canvas -- essentially, you create an object that will get drawn after
or before eveything else, and it doesn't need to use all teh scaling,
etc that regular DrawObjects do.

So, to make one, all you need is an ojbect with a _Draw method with
this signature:

def _Draw(self, dc, Canvas)

for example, one that draws text on top of eveything else, at a
particular pixel positon relative to teh client area of the Window:

class TextOverlay(FloatCanvas.Text):
"""
An example of an Overlay object:

all it needs is a new _Draw method.

this subclasses the Text DrawObject, to get some of the fint
handling, etc code.

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)
dc.DrawTextPoint(self.String, self.XY)

That's it.

I've enclosed a working sample, that's also been added to the Demos in SVN.

-Chris
--
Christopher Barker, Ph.D.
Oceanographer

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

Chris.Barker-***@public.gmane.org
Chris Barker - NOAA Federal
2013-02-22 19:50:49 UTC
Permalink
Hey Ben,
I know this is semi off-topic, and probably a repeat of old news, but I want
to remind everyone that if the objects are similar to make use of the "list"
drawing routines (in my original copy of FC - Chris put a note about this;
which I ran with). They increase speed dramatically when objects are the
same.
Good idea -- when I first added the list drawing routines, they really
only helped a lot with really simple objects: points, line segments,
but maybe drawing code is faster now, so that Python overhead makes
more difference.

A snippit from my modified FloatCanvas._DrawObjects routine:

Hmm -- I probably would not have modified FloatCanvas._DrawObjects,
but rather created a custom DrawObject that contained your Branches,
Nodes, and Tees, and called the *List drawing routines in its _Draw
method. Kind of a fancier version of the PointSet DrawObject.

You also might want to look at the PieChart object for a kind of
compound object example.

-Chris
--
Christopher Barker, Ph.D.
Oceanographer

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

Chris.Barker-***@public.gmane.org
Benjamin Jessup
2013-02-22 21:52:57 UTC
Permalink
Post by Chris Barker - NOAA Federal
Hmm -- I probably would not have modified FloatCanvas._DrawObjects,
but rather created a custom DrawObject that contained your Branches,
Nodes, and Tees, and called the *List drawing routines in its _Draw
method. Kind of a fancier version of the PointSet DrawObject.
I certainly agree with you *now* and apologize for misleading anyone on
the proper way to do what I did, but I was a python newbie back when I
did that. I did not fully understand the best way to "mixin" or
sub-class other people's classes properly. I know I am now repeating
myself; but at some point I will pull out my own floatcanvas functions
into a proper sub-class and try to submit them to you.

Ben
Chris Barker - NOAA Federal
2013-02-22 21:57:34 UTC
Permalink
Post by Benjamin Jessup
I certainly agree with you *now* and apologize for misleading anyone on
the proper way to do what I did, but I was a python newbie back when I
did that. I did not fully understand the best way to "mixin" or
sub-class other people's classes properly.
Hey -- whatever works!

I really should get around to writing some better docs for FloatCanvas
-- a tutorial or two and an overview of the architecture would really
help!
Post by Benjamin Jessup
at some point I will pull out my own floatcanvas functions
into a proper sub-class and try to submit them to you.
That would be great.

-Chris
--
Christopher Barker, Ph.D.
Oceanographer

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

Chris.Barker-***@public.gmane.org
Loading...