get panel id while dragging across several panels

Hi all,

I am working on a little GUI to connect a Novation Launchpad to SooperLooper. I have a basic test app going. Basically a 9x9 grid of panels where you can select colours for each panel. You can select a panel by Ctrl/Cmd left clicking on it, right clicking brings up a context menu where you can select a colour. I am doing this by using PostEvent to forward the mouse events on to the parent panel which then deals with selecting and changing the colours of the right panel:

self.Bind(wx.EVT_RIGHT_DOWN, self.onMouse)

self.Bind(wx.EVT_LEFT_DOWN, self.onMouse)

self.Bind(wx.EVT_MOTION, self.onMouse)

def onMouse(self, event):

wx.PostEvent(self.parent, event)

event.Skip()

and in the parent panel:

self.Bind(wx.EVT_RIGHT_DOWN, self.onRightClick)

self.Bind(wx.EVT_LEFT_DOWN, self.onLeftClick)

self.Bind(wx.EVT_MOTION, self.onMotion)

def onMotion(self, event):

print event.GetId()

def onRightClick(self, event):

self.leds[event.GetId()].select(1)

menu = wx.Menu()

for index,item in enumerate(self.menu_list):

menu.Append(index,item[0])

wx.EVT_MENU(menu, index, self.menuSelection)

self.PopupMenu(menu, self.leds[event.GetId()].GetPosition()  + event.GetPosition())

for item in self.leds:

item.select(0)

menu.Destroy()

def onLeftClick(self, event):

if event.CmdDown():

self.leds[event.GetId()].select(3)

I would like to use the EVT_MOTION to select several panels while Ctrl is being pressed but the Id while dragging remains the same as the Id of the panel where dragging began. Is there any way to break free of this?

Full code is here: [https://gist.github.com/2308241](https://gist.github.com/2308241)

Regards,

Kasapr

On Wed, Apr 4, 2012 at 10:54 PM, Kaspar Bumke

I would like to use the EVT_MOTION to select several panels while Ctrl is
being pressed but the Id while dragging remains the same as the Id of the
panel where dragging began.

interesting, I wouldn't have expected this unless you called
CaptureMouse() -- but it it what it is.

Also -- it does seem to work like you want on OS-X -- but that
probably doesn't help.

(also, and OS-X error:

  File "soopad.py", line 97, in onRightClick
    menu.Append(index,item[0])
  File "/usr/local/lib/wxPython-unicode-2.8.12.1/lib/python2.7/site-packages/wx-2.8-mac-unicode/wx/_core.py",
line 11061, in Append
    return _core_.Menu_Append(*args, **kwargs)
wx._core.PyAssertionError: C++ assertion "id != 0 || pSubMenu != NULL"
failed at /BUILD/wxPython-src-2.8.12.1/src/mac/carbon/menuitem.cpp(35)
in wxMenuItem(): A MenuItem ID of Zero does not work under Mac
)

But on to your problem:

I"d suggest that you don't really need panels for this -- you aren't
really making a 9X9 set of controls, but ratehr one big control that
contains a bunch of squares.

So you could make it one panel, and draw the squares yourself with a
DC. YOu would need to do a little math to keep track of which square
the mouse is on at any given moment, but for a simple grid like that,
that's not very difficult.

I've enclosed a little Suduko app that does something similar -- it
might provide you soem ideas.

Another option: particularly if you would like to be able to re-size
the window, you could use wx.lib.floatcanvas -- it provides a way to
put objects on the screen and bind events to them, etc. IOt's primary
goal is to provide zooming and panning, but even with a constant size,
it makes this sort of thing pretty easy.

HTH,

  -Chris

Is there any way to break free of this?

sudoku-chb.py (10.7 KB)

···

Full code is here: Soopad test · GitHub

Regards,

Kasapr

--
To unsubscribe, send email to wxPython-users+unsubscribe@googlegroups.com
or visit http://groups.google.com/group/wxPython-users?hl=en

--

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@noaa.gov

OK, since FloatCanvas is my baby, I whipped up a sample that should
get you started. It draws boxes, and when you click on them, then
change color. See enclosed.

Lots of other samples here:

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

and some more info here:

http://trac.paulmcnett.com/floatcanvas

NOTE: FC does not support alpha channel out of the box (I started
writing it before GC existed), but if you really need that (I'm not at
all sure you do in this case), you can patch it in for a given object
pretty easily:

http://trac.paulmcnett.com/floatcanvas/wiki/AlphaCircle

(I really need to update for full support of GC one of these days....)

-Chris

ClickableBoxes.py (2.26 KB)

···

On Thu, Apr 5, 2012 at 8:41 AM, Chris Barker <chris.barker@noaa.gov> wrote:

Another option: particularly if you would like to be able to re-size
the window, you could use wx.lib.floatcanvas -- it provides a way to
put objects on the screen and bind events to them, etc. IOt's primary
goal is to provide zooming and panning, but even with a constant size,
it makes this sort of thing pretty easy.

--

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@noaa.gov

Hi,

Thanks a lot for your answer.

Also – it does seem to work like you want on OS-X – but that

probably doesn’t help.

Well, that’s frustrating.

(also, and OS-X error:

OK, so I can’t have a 0 Id, I could fix that easily enough.

I"d suggest that you don’t really need panels for this – you aren’t

really making a 9X9 set of controls, but rather one big control that

contains a bunch of squares.

I liked the abstraction of having each of the squares track their own state and easily being able to modify the numbers of squares with the whole frame adjusting itself appropriately.

OK, since FloatCanvas is my baby, I whipped up a sample that should

get you started. It draws boxes, and when you click on them, then

change color. See enclosed.

WOW, thanks! It works fine, however I tried to bind an EVT_FC_MOTION:

            Rect.Bind(FC.EVT_FC_LEFT_DOWN, self.SquareHitLeft)

            Rect.Bind(FC.EVT_FC_MOTION, self.SquareMotion)

    self.Show()

    Canvas.ZoomToBB()

def SquareMotion(self, square):

    print "motion in:", square.indexes

and I get a KeyError:

File “ClickableBoxes.py”, line 89, in

F = DrawFrame(None, title="FloatCanvas Demo App", size=(700,700) )

File “ClickableBoxes.py”, line 66, in init

Rect.Bind(FC.EVT_FC_MOTION, self.SquareHitLeft)

File “/usr/lib/python2.7/site-packages/wx-2.8-gtk2-unicode/wx/lib/floatcanvas/FloatCanvas.py”, line 261, in Bind

self._Canvas.HitDict[Event][self.HitColor] = (self) # put the object in the hit dict, indexed by its color

KeyError: 10257

Not sure how to decipher this error.

NOTE: FC does not support alpha channel out of the box

That’s a bit of a shame. The alpha channel makes it easier to simulate the brightness of the LEDs in the actual device but there is probably another way to do it.

Cheers,

Kaspar

WOW, thanks! It works fine, however I tried to bind an EVT_FC_MOTION:

            Rect\.Bind\(FC\.EVT\_FC\_LEFT\_DOWN, self\.SquareHitLeft\)
            Rect\.Bind\(FC\.EVT\_FC\_MOTION, self\.SquareMotion\)

There is no EVT_MOTION for objects -- I wasn't sure there was a need,
and might get a bit tricky to impliment (for arbitrary objects).

But there is:

EVT_FC_ENTER_OBJECT and EVT_FC_LEAVE_OBJECT

which may be better for your use anyway.

I've enclosed an updated sampel that draws an outline of the box when
the mouse is in it -- not sure what visual effect you want.

-Chris

ClickableBoxes.py (2.99 KB)

···

On Thu, Apr 5, 2012 at 10:54 AM, Kaspar Bumke <kaspar.bumke@gmail.com> wrote:

    self\.Show\(\)
    Canvas\.ZoomToBB\(\)

def SquareMotion\(self, square\):
    print &quot;motion in:&quot;, square\.indexes

and I get a KeyError:

File "ClickableBoxes.py", line 89, in <module>
F = DrawFrame(None, title="FloatCanvas Demo App", size=(700,700) )
File "ClickableBoxes.py", line 66, in __init__
Rect.Bind(FC.EVT_FC_MOTION, self.SquareHitLeft)
File
"/usr/lib/python2.7/site-packages/wx-2.8-gtk2-unicode/wx/lib/floatcanvas/FloatCanvas.py",
line 261, in Bind
self._Canvas.HitDict[Event][self.HitColor] = (self) # put the object in
the hit dict, indexed by its color
KeyError: 10257

Not sure how to decipher this error.

NOTE: FC does not support alpha channel out of the box

That's a bit of a shame. The alpha channel makes it easier to simulate the
brightness of the LEDs in the actual device but there is probably another
way to do it.

Cheers,

Kaspar

--
To unsubscribe, send email to wxPython-users+unsubscribe@googlegroups.com
or visit http://groups.google.com/group/wxPython-users?hl=en

--

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@noaa.gov

Ah, awesome. Now I will see if I will use Floatcanvas and try to get around the no alpha issue or use a GC for the entire surface and track the mouse in a self defined way.

Thanks a lot for your help!

Ah, awesome. Now I will see if I will use Floatcanvas and try to get around
the no alpha issue

actually, adding alpha to FC could be pretty easy -- as long as you
only need to draw squares (or one or two other specific objects)

what you'd need to do is make a new DrawOBject type:

I'd derive from Rectangle, the override the _draw method. In your
case, you'd create a GC from the dc passed in, then draw with alpha.
YOu could still draw to the hit-test bitmap the same, so not too much
to do -- something like:

class AlphaRectangle(FC.Rectangle):

    def _Draw(self, dc ,
                WorldToPixel,
                ScaleWorldToPixel,
                HTdc=None):

        ( XY, WH ) = self.SetUpDraw(dc,
                                    WorldToPixel,
                                    ScaleWorldToPixel,
                                    HTdc)

        WH[N.abs(WH) < self.MinSize] = self.MinSize
        if not( self.DisappearWhenSmall and N.abs(WH).min() <=
self.MinSize) : # don't try to draw it too tiny

            if HTdc and self.HitAble:
                HTdc.DrawRectanglePointSize(XY, WH)
            # here is a bit of a trick
            # SetUpDraw sets up the pens, brushes, etc. for a regular DC.
            # for alpha, that needs to be a bit different:
            gcdc.SetPen( wx.Pen(self.LineAlphaColor, self.PenWidth,
self.LineStyle) )
            gcdc.SetBrush( wx.Brush(self.FillAlphaColor, self.FillStyle) )
            gcdc = GCDC(dc)
            gcdc.DrawRectanglePointSize(XY, WH)

(you'll need to do somethign with the __init__, to, to set the AlphaColors)

Now you can put this new DrawObject on the Canvas:

rect = AlphaRectangle(....)
Canvas.AddObject(rect)

or use a GC for the entire surface and track the mouse in
a self defined way.

you can do that, too.

I really need to bring FloatCanvas into the modern world...

-Chris

···

On Thu, Apr 5, 2012 at 1:21 PM, Kaspar Bumke <kaspar.bumke@gmail.com> wrote:

--

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@noaa.gov