mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 10:54:24 -04:00
167 lines
5.5 KiB
Python
167 lines
5.5 KiB
Python
from DirectFrame import *
|
|
from DirectButton import *
|
|
import Task
|
|
|
|
class DirectScrolledList(DirectFrame):
|
|
def __init__(self, parent = aspect2d, **kw):
|
|
|
|
self.index = 0
|
|
|
|
# Inherits from DirectFrame
|
|
optiondefs = (
|
|
# Define type of DirectGuiWidget
|
|
('items', [], None),
|
|
('command', None, None),
|
|
('extraArgs', [], None),
|
|
('numItemsVisible', 1, self.setNumItemsVisible),
|
|
('scrollSpeed', 8, self.setScrollSpeed),
|
|
)
|
|
# Merge keyword options with default options
|
|
self.defineoptions(kw, optiondefs)
|
|
|
|
# Initialize superclasses
|
|
DirectFrame.__init__(self, parent)
|
|
|
|
self.incButton = self.createcomponent("incButton", (), None,
|
|
DirectButton, (self,),
|
|
)
|
|
self.incButton.bind(B1PRESS, self.__incButtonDown)
|
|
self.incButton.bind(B1RELEASE, self.__buttonUp)
|
|
self.decButton = self.createcomponent("decButton", (), None,
|
|
DirectButton, (self,),
|
|
)
|
|
self.decButton.bind(B1PRESS, self.__decButtonDown)
|
|
self.decButton.bind(B1RELEASE, self.__buttonUp)
|
|
self.itemFrame = self.createcomponent("itemFrame", (), None,
|
|
DirectFrame, (self,),
|
|
)
|
|
for item in self["items"]:
|
|
item.reparentTo(self.itemFrame)
|
|
|
|
self.initialiseoptions(DirectScrolledList)
|
|
self.recordMaxHeight()
|
|
#if len(self["items"]) > 0:
|
|
# self.scrollTo(0)
|
|
self.scrollTo(0)
|
|
|
|
|
|
def recordMaxHeight(self):
|
|
self.maxHeight = 0.0
|
|
for item in self["items"]:
|
|
self.maxHeight = max(self.maxHeight, item.getHeight())
|
|
|
|
def setScrollSpeed(self):
|
|
# Items per second to move
|
|
self.scrollSpeed = self["scrollSpeed"]
|
|
if self.scrollSpeed <= 0:
|
|
self.scrollSpeed = 1
|
|
|
|
def setNumItemsVisible(self):
|
|
# Items per second to move
|
|
self.numItemsVisible = self["numItemsVisible"]
|
|
|
|
def destroy(self):
|
|
taskMgr.remove(self.taskName("scroll"))
|
|
DirectFrame.destroy(self)
|
|
|
|
def scrollBy(self, delta):
|
|
return self.scrollTo(self.index + delta)
|
|
|
|
def scrollTo(self, index):
|
|
self.index = index
|
|
|
|
# Not enough items to even worry about scrolling,
|
|
# just disable the buttons and do nothing
|
|
if (len(self["items"]) <= self["numItemsVisible"]):
|
|
self.incButton['state'] = DISABLED
|
|
self.decButton['state'] = DISABLED
|
|
# Hmm.. just reset self.index to 0 and bail out
|
|
self.index = 0
|
|
ret = 0
|
|
else:
|
|
if (self.index <= 0):
|
|
self.index = 0
|
|
self.decButton['state'] = DISABLED
|
|
self.incButton['state'] = NORMAL
|
|
ret = 0
|
|
elif (self.index >= ( len(self["items"]) - self["numItemsVisible"])):
|
|
self.index = len(self["items"]) - self["numItemsVisible"]
|
|
self.incButton['state'] = DISABLED
|
|
self.decButton['state'] = NORMAL
|
|
ret = 0
|
|
else:
|
|
self.incButton['state'] = NORMAL
|
|
self.decButton['state'] = NORMAL
|
|
ret = 1
|
|
|
|
# Hide them all
|
|
for item in self["items"]:
|
|
item.hide()
|
|
# Then show the ones in range, and stack their positions
|
|
upperRange = min(len(self["items"]), self["numItemsVisible"])
|
|
for i in range(self.index, self.index + upperRange):
|
|
item = self["items"][i]
|
|
item.show()
|
|
item.setPos(0,0, - (i - self.index) * self.maxHeight)
|
|
return ret
|
|
|
|
def __scrollByTask(self, task):
|
|
if ((task.time - task.prevTime) < task.delayTime):
|
|
return Task.cont
|
|
else:
|
|
ret = self.scrollBy(task.delta)
|
|
task.prevTime = task.time
|
|
if ret:
|
|
return Task.cont
|
|
else:
|
|
return Task.done
|
|
|
|
def __incButtonDown(self, event):
|
|
task = Task.Task(self.__scrollByTask)
|
|
task.delayTime = (1.0 / self.scrollSpeed)
|
|
task.prevTime = 0.0
|
|
task.delta = 1
|
|
self.scrollBy(task.delta)
|
|
taskMgr.add(task, self.taskName("scroll"))
|
|
|
|
def __decButtonDown(self, event):
|
|
task = Task.Task(self.__scrollByTask)
|
|
task.delayTime = (1.0 / self.scrollSpeed)
|
|
task.prevTime = 0.0
|
|
task.delta = -1
|
|
self.scrollBy(task.delta)
|
|
taskMgr.add(task, self.taskName("scroll"))
|
|
|
|
def __buttonUp(self, event):
|
|
taskMgr.remove(self.taskName("scroll"))
|
|
|
|
def addItem(self, item):
|
|
"""
|
|
Add this string and extraArg to the list
|
|
"""
|
|
self['items'].append(item)
|
|
item.reparentTo(self.itemFrame)
|
|
self.refresh()
|
|
|
|
|
|
def removeItem(self, item):
|
|
"""
|
|
Remove this item from the panel
|
|
"""
|
|
if item in self["items"]:
|
|
self["items"].remove(item)
|
|
item.reparentTo(hidden)
|
|
self.refresh()
|
|
return 1
|
|
else:
|
|
return 0
|
|
|
|
def refresh(self):
|
|
"""
|
|
Update the list - useful when adding or deleting items
|
|
or changing properties that would effect the scrolling
|
|
"""
|
|
self.recordMaxHeight()
|
|
self.scrollTo(self.index)
|
|
|