Drag&Drop DirectGui [SOLVED]

Hi,

I’ve got a relatively easy task at mind - drag an icon from one container to another.

To get into more details - I’ve got two DirectFrame objects (one represents a chest of loot the other a players inventory) they are both parented to base.a2dLeftCenter(could be aspect2d, not that important, they just have the same parent), one of them has a button parented to it(it’s just an icon, it could well be just a DirectFrame as well). Now I’d want to use the mouse pointer to move that button/icon from one of the frames to the other, so that when it’s done the icon will be parented to the frame it was dragged to.

So I have a task watching the mouse pointer and translating its position into the aspect2d(or a2dLeftCenter) coordinates also an event for when the button/icon gets clicked on (to start/stop moving that icon to where the mouse pointer is). That I can do (but I can’t get the icon to stay on top of both frames).

How should I determine what’s under the icon that’s moving with the mouse pointer? DGG.ENTER and DGG.EXIT events for the frames do not detect the pointer when my icon is on top of the frame (and I want it to be on top).

Any ideas, tricks, tips?

Use DGG.WITHIN and DGG.WITHOUT.

David

Thanks, that did it!

…but I still need some help. It sort of works until I move one of the frames - after that the icon ‘jumps away’, not sure why. Here’s my code:

from panda3d.core import *
from direct.showbase.DirectObject import DirectObject
import direct.directbase.DirectStart
from direct.gui.DirectGui import *


class MyGui(DirectObject):
 
    def __init__(self):
        self.green = DirectFrame(frameColor=(0, 1, 0, 1),
                                    frameSize=(0, 1, -0.6, 0.9),
                                    state=DGG.NORMAL)
        self.green.reparentTo(base.a2dLeftCenter)  
        self.green.setBin('fixed', 10)
        
        self.red = DirectFrame(frameColor=(1, 0, 0, 1),
                                    frameSize=(1, 1.5, -0.6, 0.9),
                                    state=DGG.NORMAL)
        self.red.reparentTo(base.a2dLeftCenter) 
        self.red.setBin('fixed', 10)
        
        self.blue = DirectFrame(frameColor=(0, 0, 1, 1),
                                    frameSize=(-0.1, 0.1, -0.1, 0.1),
                                    pos=(0.5, 0, 0),
                                    state=DGG.NORMAL)
        self.blue.reparentTo(self.green)  
        self.blue.setBin('fixed', 100)   
        
        self.button = DirectButton(text = ("Move Red"), command=self.moveRed, scale=0.2, pos=(0,0,-0.8))      
        
        
        self.green.bind(DGG.WITHIN, self.myOnEnter, [self.green]) 
        self.green.bind(DGG.WITHOUT, self.myOnExit,[self.green]) 
        
        self.red.bind(DGG.WITHIN, self.myOnEnter, [self.red]) 
        self.red.bind(DGG.WITHOUT, self.myOnExit, [self.red]) 
        
        self.blue.bind(DGG.B1PRESS, self.myOnClick,[self.blue]) 
        
        self.moveMe=0
        self.tempParent=None
        self.LastPos=Point3(0,0,0)
        taskMgr.add(self.move,"moveTask")
    
    def moveRed(self):
        if self.red.getPos()==Point3(0,0,0):
            self.red.setPos(0.5,0, 0)
        else:    
            self.red.setPos(0,0, 0)
            
    def myOnEnter(self, color, mouse):
        self.tempParent=color
        
    def myOnExit(self, color, mouse):
        self.tempParent=None
        
    def myOnClick(self, color, mouse):        
        if self.moveMe==1: #drag
            self.moveMe=0 
            if  self.tempParent != None:
                    color.reparentTo(self.tempParent)
            else:
                color.setPos(self.LastPos)
        else: #drop
            self.moveMe=1
            self.LastPos=color.getPos()
    
    def move(self, task):
        if self.moveMe==1:
            if base.mouseWatcherNode.hasMouse():
                newPos=Point3(base.mouseWatcherNode.getMouseX() ,0, base.mouseWatcherNode.getMouseY())
                self.blue.setPos(base.a2dLeftCenter.getRelativePoint(render2d, newPos))
        return task.cont    
            
world = MyGui()
run()    

Ok, got it fixed by using wrtReparentTo() and moving my icon relative to its parent.