Skip to content

Instantly share code, notes, and snippets.

@wezu
Last active May 11, 2018 10:15
Show Gist options
  • Save wezu/17c8021fe2bcbff3e0ef7d3a8460ab90 to your computer and use it in GitHub Desktop.
Save wezu/17c8021fe2bcbff3e0ef7d3a8460ab90 to your computer and use it in GitHub Desktop.
Panda3D Drag & Drop Demo
'''
Drag & Drop Demo
Use the mouse to drag and drop colored squares from moving frames or the background.
Use left mouse click to grab a square, release it to ...well, release it.
'''
from panda3d.core import *
from direct.gui.DirectGui import *
from direct.showbase import ShowBase
from direct.interval.LerpInterval import LerpPosInterval
from direct.interval.MetaInterval import Sequence
import random
#Helper functions
def _pos2d(x,y):
return Point3(x,0,-y)
def _rec2d(width, height):
return (width, 0, 0, -height)
class App:
def __init__(self):
#add a title/instructions
wp = WindowProperties.getDefault()
wp.set_title("Drag & Drop the colored squares")
WindowProperties.setDefault(wp)
#init showvase
base = ShowBase.ShowBase()
#make a frame
self.white_frame=DirectFrame(frameColor=(1,1,1,1.0),
frameSize=_rec2d(256, 256),
state=DGG.NORMAL,
parent=pixel2d)
self.white_frame.set_pos(_pos2d(32, 32))
#bind the events
self.white_frame.bind(DGG.WITHIN, self.hover_in, [self.white_frame])
self.white_frame.bind(DGG.WITHOUT, self.hover_out)
#make it move
Sequence(LerpPosInterval(self.white_frame, 5.0,_pos2d(32,256)),
LerpPosInterval(self.white_frame, 5.0,_pos2d(32,32)) ).loop()
#do the same as with the white_frame,
self.black_frame=DirectFrame(frameColor=(0,0,0,1.0),
frameSize=_rec2d(256, 256),
state=DGG.NORMAL,
parent=pixel2d)
self.black_frame.set_pos(_pos2d(base.win.get_x_size()-32-256, 32))
self.black_frame.bind(DGG.WITHIN, self.hover_in, [self.black_frame])
self.black_frame.bind(DGG.WITHOUT, self.hover_out)
Sequence(LerpPosInterval(self.black_frame, 3.0,_pos2d(base.win.get_x_size()-32-256,256)),
LerpPosInterval(self.black_frame, 3.0,_pos2d(base.win.get_x_size()-32-256, 32)) ).loop()
#make some squares to be drag/dropped
for x in range(8):
for y in range(8):
frame=DirectFrame(frameColor=(random.uniform(0, 1),random.uniform(0, 1),random.uniform(0, 1),1.0),
frameSize=_rec2d(30, 30),
state=DGG.NORMAL,
parent=self.black_frame)
#bind the events
frame.bind(DGG.B1PRESS, self.drag, [frame])
frame.bind(DGG.B1RELEASE, self.drop)
frame.set_pos(_pos2d(x*32,y*32))
self.current_dragged=None
self.last_hover_in=None
#run a task tracking the mouse cursor
taskMgr.add(self.update, "update", sort=-50)
def update(self, task=None):
'''Track the mouse pos and move self.current_dragged to where the cursor is '''
if self.current_dragged:
if base.mouseWatcherNode.has_mouse():
mpos = base.mouseWatcherNode.get_mouse()
self.current_dragged.set_pos(pixel2d.get_relative_point(render2d, Point3(mpos.get_x() ,0, mpos.get_y())))
if task:
return task.again
def drag(self, widget, mouse_pos=None):
'''Set the widget to be the currently dragged object'''
widget.reparent_to(pixel2d)
self.current_dragged=widget
self.update()
def drop(self, mouse_pos=None):
'''Drop the currently dragged object on the last object the cursor hovered over'''
if self.current_dragged:
if self.last_hover_in:
self.current_dragged.wrt_reparent_to(self.last_hover_in)
self.current_dragged=None
def hover_in(self, widget, mouse_pos=None):
'''Set the widget to be the target to drop objects onto'''
self.last_hover_in=widget
def hover_out(self, mouse_pos=None):
'''Clear the target to drop objects onto'''
self.last_hover_in=None
app=App()
base.run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment