Annoying flickering with wxFileDropTarget methods OnLeave/OnLeave

Hi,

I want to be able to drag a file icon onto a folder icon. When I drag
the file icon onto the folder icon, I want the folder image to change,
and then change back when I drag back outside of the folder icon's
space. The problem I'm having is that the folder images are switched
with any mouse movement within the folder window, not just on entry
and exit. Hopefully the code below makes it clear what I mean:

···

_______________________________________________

import wx
from wx.lib.pubsub import Publisher

class MyApp(wx.App):
    def OnInit(self):
        self.frame = Example(None, title="Top frame")
        self.SetTopWindow(self.frame)
        self.frame.Show()

        return True

class FileDrop(wx.FileDropTarget):
    def __init__(self, window):
        wx.FileDropTarget.__init__(self)
        self.window = window

    def OnLeave(self):
        Publisher().sendMessage("dragChange", 'exit')

    def OnEnter(self, x, y, drag_result):
        Publisher().sendMessage("dragChange", 'enter')

class Example(wx.Frame):

    def __init__(self, parent, title, ):
        super(Example, self).__init__(parent, title=title,size=(300,
350))

        self.panelOne = MyPanel(self)

        self.frameSizer = wx.BoxSizer(wx.VERTICAL)
        self.frameSizer.Add(self.panelOne, 1, wx.EXPAND)

        self.SetSizer(self.frameSizer)
        self.frameSizer.Fit(self)

        self.Centre()
        self.Show()

class MyPanel(wx.Panel):

    def __init__(self, parent):
        super(MyPanel, self).__init__(parent)

        self.mainSizer = wx.BoxSizer(wx.VERTICAL)

        Publisher().subscribe(self.switchFolder, "dragChange")

        save = wx.ArtProvider.GetBitmap(wx.ART_FILE_SAVE,
size=(64,64))
        bookmark = wx.ArtProvider.GetBitmap(wx.ART_ADD_BOOKMARK,
size=(64,64))
        floppy = wx.ArtProvider.GetBitmap(wx.ART_FLOPPY, size=(64,64))

        self.sveIcn = wx.StaticBitmap(self, -1, bitmap=save)
        self.sveIcn.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)

        self.bmkIcn = wx.StaticBitmap(self, -1, bitmap=bookmark)
        self.flpIcn = wx.StaticBitmap(self, -1, bitmap=floppy)
        self.flpIcn.Hide()
        dt = FileDrop(self.bmkIcn)
        self.bmkIcn.SetDropTarget(dt)

        ### widgets here
        hSizer = wx.BoxSizer(wx.HORIZONTAL)
        hSizer.Add(self.sveIcn, 0, wx.ALL, 10)
        hSizer.AddSpacer((30,30))
        hSizer.Add(self.flpIcn, 0, wx.ALL|wx.ALIGN_CENTER, 10)
        hSizer.Add(self.bmkIcn, 0, wx.ALL|wx.ALIGN_CENTER, 10)

        self.mainSizer.Add(hSizer)

        # set optimum layout for mainsizer...
        self.SetSizer(self.mainSizer)
        # ...then fit main sizer to the panel.
        self.mainSizer.Fit(self)

    def OnLeftDown(self, event):
        data = wx.FileDataObject()
        data.AddFile('/Users/paulpatterson/Desktop/testPhotos/
DSC00008.JPG')
        dropSource = wx.DropSource(self)
        dropSource.SetData(data)
        result = dropSource.DoDragDrop(wx.Drag_CopyOnly)

    def switchFolder(self, msg):
        if msg.data == 'exit':
            self.flpIcn.Hide()
            self.bmkIcn.Show()
        if msg.data == 'enter':
            self.flpIcn.Show()
            self.bmkIcn.Hide()

        self.Layout()

if __name__ == '__main__':

    app = MyApp(False)
    app.MainLoop()
_______________________________________________

Has anyone else experienced this problem? If it is just something I'm
going to have to overcome with a work-around does anyone have any
ideas what I could do? I've tried to bind wxEVT_ENTER_WINDOW/
_LEAVE_WINDOW to self.window in my DropTarget class but this just
presents a different set of problems that I don't know how to solve.

Thanks.

Hi,

I want to be able to drag a file icon onto a folder icon. When I drag
the file icon onto the folder icon, I want the folder image to change,
and then change back when I drag back outside of the folder icon's
space. The problem I'm having is that the folder images are switched
with any mouse movement within the folder window, not just on entry
and exit. Hopefully the code below makes it clear what I mean:

_______________________________________________

import wx
from wx.lib.pubsub import Publisher

class MyApp(wx.App):
     def OnInit(self):
         self.frame = Example(None, title="Top frame")
         self.SetTopWindow(self.frame)
         self.frame.Show()

         return True

class FileDrop(wx.FileDropTarget):
     def __init__(self, window):
         wx.FileDropTarget.__init__(self)
         self.window = window

     def OnLeave(self):
         Publisher().sendMessage("dragChange", 'exit')

     def OnEnter(self, x, y, drag_result):
         Publisher().sendMessage("dragChange", 'enter')

You should return drag_result from OnEnter. Or modify it if you want to enforce different effects in different situations. Either way, you need to return a value.

     def switchFolder(self, msg):
         if msg.data == 'exit':
             self.flpIcn.Hide()
             self.bmkIcn.Show()
         if msg.data == 'enter':
             self.flpIcn.Show()
             self.bmkIcn.Hide()

         self.Layout()

But the real problem is here. By hiding the window that has the drop target while the cursor is in the bounds of that window, will cause the drop target to get an OnLeave callback, and then showing it again will cause it to get a OnEnter callback. Instead of hiding and showing try just creating one widget and changing the bitmap that it is displaying.

···

On 1/5/12 1:59 AM, Paul wrote:

--
Robin Dunn
Software Craftsman

Thanks for the explanation and solution. Funnily enough I'd used the
SetBitmap() approach
elsewhere in the program, it just didn't occur to me to apply it here.
Have now done so,
and it's working fine.