i’ve been playing around with dgui for a while and thought i might post this, maybe someone has some improvement idea’s.
it’s far from being completed, i’d like to put that into a class to make windows instanceable. another problem is that the 0/0 point inside the window is still at the left bottom point (scrolling problem)
changed:
07.09.2008: updated the code (is not instanceable, having some problems with button textures)
from pandac.PandaModules import TextNode, Vec3
from direct.gui.DirectGui import DirectFrame,DirectButton,DirectScrolledFrame,DGG
import direct.directbase.DirectStart
# a task that keeps a node at the position of the mouse-cursor
def mouseNodeTask( task ):
if base.mouseWatcherNode.hasMouse():
x=base.mouseWatcherNode.getMouseX()
y=base.mouseWatcherNode.getMouseY()
# the mouse position is read relative to render2d, so set it accordingly
aspect2dMouseNode.setPos( render2d, x, 0, y )
return task.cont
# maybe we should check if aspect2d doesnt already contain the aspect2dMouseNode
aspect2dMouseNode = aspect2d.attachNewNode( 'aspect2dMouseNode', sort = 999999 )
taskMgr.add( mouseNodeTask, 'mouseNodeTask' )
#egg-texture-cards -o title.egg -p 240,240 title.png title.png title.png title.png
#from direct.showbase.Loader import Loader
#title_tex = Loader('a').loadTexture( 'Bild 3.png' )
#title = loader.loadTexture( 'title.png' )
#DEFAULT_TITLE_GEOM = ( title_tex, title_tex, title_tex, title_tex )
title = loader.loadModel('title.egg').find('**/title')
DEFAULT_TITLE_GEOM = ( title
, title
, title
, title )
#resize_tex = Loader('a').loadTexture( 'Bild 5.png' )
resize_tex = loader.loadTexture( 'resize.png' )
DEFAULT_RESIZE_GEOM = ( resize_tex, resize_tex, resize_tex, resize_tex )
class DirectWindow( DirectFrame ):
def __init__( self
, pos = ( -.5, .5)
, title = 'Title'
, backgroundColor = ( 1, 1, 1, 1 )
, buttonColor = ( .6, .6, .6, 1 )
, minSize = ( .5, .5 )
, maxSize = ( 1, 1 )
, titleGeom = None
, resizeGeom = None ):
# the main window we want to move around
self.windowPos = pos
self.window = DirectFrame(
parent = aspect2d,
pos = ( self.windowPos[0], 0, self.windowPos[1] ),
frameColor = ( 0, 0, 0, 1 ),
)
# the title part of the window, drag around to move the window
self.headerHeight = 0.1
h = -self.headerHeight
self.windowHeader = DirectButton(
parent = self.window,
geom = titleGeom,
frameSize = ( -.5, .5, -.5, .5 ),
borderWidth = ( 0, 0 ),
relief = DGG.FLAT,
#scale = (1,1,1),
frameColor = buttonColor,
)
text = TextNode('WindowTitleTextNode')
text.setText(title)
text.setAlign(TextNode.ACenter)
text.setTextColor( 1, 1, 1, 1)
text.setShadow(0.05, 0.05)
text.setShadowColor(0, 0, 0, 1)
#cmr12 = loader.loadFont('cmr12.egg')
#text.setFont(cmr12)
self.textNodePath = self.window.attachNewNode(text)
#textNodePath = self.windowHeader.attachNewNode(text)
#self.textNodePath.setPos( )
self.textNodePath.setScale(0.07)
self.windowHeader.bind(DGG.B1PRESS,self.startWindowDrag)
# this is not handled correctly, if a window is dragged which has been
# created before another it will not be released
# check the bugfixed startWindowDrag function
#self.windowHeader.bind(DGG.B1RELEASE,self.stopWindowDrag)
# the content part of the window, put stuff beneath
# contentWindow.getCanvas() to put it into it
self.maxVirtualSize = maxSize
self.minVirtualSize = minSize
self.contentWindow = DirectScrolledFrame(
parent = self.window,
pos = ( 0, 0, -self.headerHeight ),
canvasSize = ( 0, self.maxVirtualSize[0], 0, self.maxVirtualSize[1] ),
frameColor = buttonColor,
relief = DGG.RAISED,
borderWidth = (0,0)
)
# TODO: BUG THIS IS INVISIBLE
DirectFrame.__init__( self,
parent = self.contentWindow.getCanvas(),
pos = ( 0, 0, 0 ),
frameSize = ( 0, self.maxVirtualSize[0], 0, self.maxVirtualSize[1] ),
frameColor = backgroundColor,
relief = DGG.RIDGE,
borderWidth = ( .01, .01),
)
# BUGFIX FOR ABOVE
self.backgroundColor = DirectFrame(
parent = self,
frameSize = ( 0, self.maxVirtualSize[0], 0, self.maxVirtualSize[1] ),
frameColor = backgroundColor,
relief = DGG.FLAT,
borderWidth = ( .01, .01),
)
# the resize button of the window
resizeSize = 0.08
self.windowResize = DirectButton(
parent = self.window,
frameSize = ( -resizeSize, 0, resizeSize, 0),
frameColor = buttonColor,
borderWidth = ( .005, .005),
relief = DGG.FLAT,
)
self.windowResize.bind(DGG.B1PRESS,self.startResizeDrag)
self.windowResize.bind(DGG.B1RELEASE,self.stopResizeDrag)
# offset then clicking on the resize button from the mouse to the resizebutton
# position, required to calculate the position / scaling
self.offset = None
self.taskName = "resizeTask-%s" % str(hash(self))
# do sizing of the window (minimum)
self.resize( Vec3(0,0,0), Vec3(0,0,0) )
# maximum
#self.resize( Vec3(100,0,-100), Vec3(0,0,0) )
# dragging functions
def startWindowDrag( self, param ):
self.window.wrtReparentTo( aspect2dMouseNode )
self.window.ignoreAll()
self.window.accept( 'mouse1-up', self.stopWindowDrag )
def stopWindowDrag( self, param=None ):
# this is called 2 times (bug), so make sure it's not already parented to aspect2d
if self.window.getParent() != aspect2d:
self.window.wrtReparentTo( aspect2d )
# resize functions
def resize( self, mPos, offset ):
mXPos = max( min( mPos.getX(), self.maxVirtualSize[0] ), self.minVirtualSize[0])
mZPos = max( min( mPos.getZ(), -self.minVirtualSize[1] ), -self.maxVirtualSize[1]-self.headerHeight)
self.windowResize.setPos( mXPos, 0, mZPos ) #['pos'] = (mXPos, 0, mZPos)
self.window['frameSize'] = (0, mXPos, 0, mZPos)
#self.window.setScale( mXPos, 1, -mZPos )
self.windowHeader.setPos( mXPos/2., 0, -self.headerHeight/2. )
self.windowHeader.setScale( mXPos, 1, -self.headerHeight )
self.contentWindow['frameSize'] = ( 0, mXPos, mZPos+self.headerHeight, 0)
self.textNodePath.setPos( mXPos/2., 0, -self.headerHeight/3.*2. )
def resizeTask( self, task=None ):
mPos = aspect2dMouseNode.getPos( self.window )+self.offset
self.resize( mPos, self.offset )
return task.cont
def startResizeDrag( self, param ):
self.offset = self.windowResize.getPos( aspect2dMouseNode )
taskMgr.remove( self.taskName )
taskMgr.add( self.resizeTask, self.taskName )
def stopResizeDrag( self, param ):
taskMgr.remove( self.taskName )
if __name__ == '__main__':
bg1 = DirectButton(
parent = aspect2d,
pos = (.6,0,.6),
#frameSize = (0,0.2,0,0.2),
frameSize = (-.5,.5,-.5,.5),
relief = DGG.FLAT,
frameColor = (0,1,1,1),
geom = DEFAULT_TITLE_GEOM,
)
bg2 = DirectButton(
parent = bg1,
pos = (.6,0,.6),
#frameSize = (0,0.2,0,0.2),
frameSize = (-.5,.5,-.5,.5),
relief = DGG.FLAT,
frameColor = (0,1,1,1),
geom = DEFAULT_TITLE_GEOM,
)
# a first window
window1 = DirectWindow( title='window1', pos = ( -.8, .8) )
windowContent = DirectButton(
parent = window1,
pos = (.05,0,.05),
frameSize = (0,.9,0,.9),
relief = DGG.FLAT,
frameColor = (0,1,0,1),
)
# a second window
window2 = DirectWindow( title='window2', pos = ( -.4, .4), maxSize = (1.5,1.5) )
windowContent = DirectButton(
parent = window2,
pos = (.6,0,.6),
#frameSize = (0,0.2,0,0.2),
frameSize = (-.5,.5,-.5,.5),
relief = DGG.FLAT,
frameColor = (0,1,1,1),
geom = DEFAULT_TITLE_GEOM,
)
# a second window
window3 = DirectWindow( title='window2', pos = ( 0, 0) )
windowContent = DirectButton(
parent = window3,
pos = (.5,0,.5),
frameSize = (-.5,.5,-.5,.5),
relief = DGG.FLAT,
frameColor = (0,1,1,1),
#geom = DEFAULT_TITLE_GEOM,
scale = 0.5,
)
run()