From 1b0b4e74d44ddd76a2b33b2fd8dde548d801155b Mon Sep 17 00:00:00 2001 From: Joe Shochet Date: Fri, 27 Jul 2001 22:19:25 +0000 Subject: [PATCH] *** empty log message *** --- direct/src/extensions/NodePath-extensions.py | 13 +- direct/src/gui/DirectGuiBase.py | 37 ++- direct/src/gui/DirectScrolledList.py | 228 +++++++++++++++---- direct/src/gui/OnscreenText.py | 3 + 4 files changed, 222 insertions(+), 59 deletions(-) diff --git a/direct/src/extensions/NodePath-extensions.py b/direct/src/extensions/NodePath-extensions.py index aad9954682..36355da0f1 100644 --- a/direct/src/extensions/NodePath-extensions.py +++ b/direct/src/extensions/NodePath-extensions.py @@ -35,11 +35,14 @@ # For iterating over children def getChildrenAsList(self): """Converts a node path's child NodePathCollection into a list""" - children = self.getChildren() - childrenList = [] - for childNum in range(self.getNumChildren()): - childrenList.append(children[childNum]) - return childrenList + if self.isEmpty(): + return [] + else: + children = self.getChildren() + childrenList = [] + for childNum in range(self.getNumChildren()): + childrenList.append(children[childNum]) + return childrenList def printChildren(self): """Prints out the children of the bottom node of a node path""" diff --git a/direct/src/gui/DirectGuiBase.py b/direct/src/gui/DirectGuiBase.py index 63f1767ba6..92b541cfaa 100644 --- a/direct/src/gui/DirectGuiBase.py +++ b/direct/src/gui/DirectGuiBase.py @@ -346,9 +346,12 @@ class DirectGuiBase(PandaObject.PandaObject): # This is one of the options of this gui item. # Check it is an initialisation option. if optionInfo[option][FUNCTION] is INITOPT: - raise KeyError, \ - 'Cannot configure initialisation option "' \ - + option + '" for ' + self.__class__.__name__ + print 'Cannot configure initialisation option "' \ + + option + '" for ' + self.__class__.__name__ + break + #raise KeyError, \ + # 'Cannot configure initialisation option "' \ + # + option + '" for ' + self.__class__.__name__ optionInfo[option][VALUE] = value directOptions.append(option) else: @@ -812,7 +815,7 @@ class DirectGuiWidget(DirectGuiBase, NodePath): def setFrameSize(self, fClearFrame = 0): if self['frameSize']: # Use user specified bounds - bounds = self['frameSize'] + self.bounds = self['frameSize'] else: # Use ready state to compute bounds frameType = self.frameStyle[0].getType() @@ -824,16 +827,22 @@ class DirectGuiWidget(DirectGuiBase, NodePath): # Clear out frame before computing bounds self.stateNodePath[0].calcTightBounds(self.ll, self.ur) # Scale bounds to give a pad around graphics - bounds = (self.ll[0] - self['pad'][0], - self.ur[0] + self['pad'][0], - self.ll[2] - self['pad'][1], - self.ur[2] + self['pad'][1]) + self.bounds = (self.ll[0] - self['pad'][0], + self.ur[0] + self['pad'][0], + self.ll[2] - self['pad'][1], + self.ur[2] + self['pad'][1]) # Restore frame style if necessary if (frameType != PGFrameStyle.TNone): self.frameStyle[0].setType(frameType) self.guiItem.setFrameStyle(0, self.frameStyle[0]) # Set frame to new dimensions - self.guiItem.setFrame(bounds[0], bounds[1],bounds[2], bounds[3]) + self.guiItem.setFrame(self.bounds[0], self.bounds[1],self.bounds[2], self.bounds[3]) + + def getWidth(self): + return self.bounds[1] - self.bounds[0] + + def getHeight(self): + return self.bounds[3] - self.bounds[2] def updateFrameStyle(self): if not self.fInit: @@ -896,5 +905,13 @@ class DirectGuiWidget(DirectGuiBase, NodePath): # Print out children info for child in self.getChildrenAsList(): messenger.send(PRINT + child.getName(), [indent + 2]) - + def copyOptions(self, other): + """ + Copy other's options into our self so we look and feel like other + """ + for key, value in other._optionInfo.items(): + self[key] = value[1] + + def taskName(self, idString): + return (idString + "-" + str(self.guiId)) diff --git a/direct/src/gui/DirectScrolledList.py b/direct/src/gui/DirectScrolledList.py index 759fe19d2b..f5e5ba3e8f 100644 --- a/direct/src/gui/DirectScrolledList.py +++ b/direct/src/gui/DirectScrolledList.py @@ -1,52 +1,83 @@ from DirectFrame import * from DirectButton import * import GuiGlobals - +import Task """ -def choseAvatar(name, avId): - print name, avId - +from DirectGui import * + +def choseAvatar(item): + print item + model = loader.loadModel("phase_4/models/gui/friendslist_gui") +names = ['Top', 'Flippy1', 'Joe', 'Shochet', 'Mother', 'Father', 'Brother', 'Sister', 'One', 'Two', 'Three', 'Flippy2', 'Ashy', 'Bob', 'Moe', 'Funk', 'Bottom'] + +buttons = [] +for name in names: + buttons.append(DirectButton( + text = name, + text_scale = 0.05, + relief = None, + text2_bg = Vec4(1,1,0,1), + text1_bg = Vec4(0.5,0.9,1,1), + command = choseAvatar, + extraArgs = [name], + )) + + s = DirectScrolledList( image = model.find("**/FriendsBox_Open"), relief = None, # inc and dec are DirectButtons - incButton_text = "inc", - incButton_text_scale = 0.1, - incButton_pos = (0,0,0.1), - decButton_text = "dec", - decButton_text_scale = 0.1, - decButton_pos = (0,0,-0.1), + incButton_image = (model.find("**/FndsLst_ScrollUp"), + model.find("**/FndsLst_ScrollDN"), + model.find("**/FndsLst_ScrollUp_Rllvr"), + ), + incButton_relief = None, + incButton_scale = (1,1,-1), + incButton_pos = (0,0,-0.316), + decButton_image = (model.find("**/FndsLst_ScrollUp"), + model.find("**/FndsLst_ScrollDN"), + model.find("**/FndsLst_ScrollUp_Rllvr"), + ), + decButton_relief = None, + decButton_scale = (1,1,1), + decButton_pos = (0,0,0.119), # itemFrame is a DirectFrame - itemFrame_pos = (0,0,0), - itemFrame_relief = FLAT, - itemFrame_frameColor = (1,1,1,1), + itemFrame_pos = (0,0,0.05), + itemFrame_scale = 0.9, + itemFrame_relief = None, # each item is a button with text on it - numItemsVisible = 3, - items = ('Top', 'Flippy', 'Joe', 'Flippy', 'Ashy', 'Bottom'), - items_text_scale = 0.1, - items_relief = FLAT, - command = choseAvatar, - extraArgs = ([1], [2], [3]), + numItemsVisible = 7, + items = buttons, ) -s.addItem(string, extraArg) +s.addItem(DirectButton( + text = "Added", + text_scale = 0.05, + relief = None, + text2_bg = Vec4(1,1,0,1), + text1_bg = Vec4(0.5,0.9,1,1), + command = choseAvatar, + extraArgs = ["Added"]) s.removeItem(index) s.setItems(stringList, extraArgList) """ - class DirectScrolledList(DirectFrame): def __init__(self, parent = guiTop, **kw): + + self.index = 0 + # Inherits from DirectFrame optiondefs = ( # Define type of DirectGuiWidget ('items', [], None), ('command', None, None), ('extraArgs', [], None), - ('numItemsVisible', 1, None), + ('numItemsVisible', 1, self.setNumItemsVisible), + ('scrollSpeed', 8, self.setScrollSpeed), ) # Merge keyword options with default options self.defineoptions(kw, optiondefs, dynamicGroups = ("items",)) @@ -54,28 +85,137 @@ class DirectScrolledList(DirectFrame): # Initialize superclasses DirectFrame.__init__(self, parent) - self.createcomponent("incButton", (), "incButton", - DirectButton, (), - parent = self, - ) - self.createcomponent("decButton", (), "decButton", - DirectButton, (), - parent = self, - ) - self.createcomponent("itemFrame", (), "itemFrame", - DirectFrame, (), - parent = self, - ) - - for i in range(len(self["items"])): - item = self["items"][i] - self.createcomponent("item"+str(i), (), "items", - DirectButton, (), - parent = self.component("itemFrame"), - text = item, - command = self["command"], - extraArgs = [item] + self["extraArgs"][i], - ) + self.incButton = self.createcomponent("incButton", (), "incButton", + DirectButton, (), + parent = self, + ) + self.incButton.bind(B1PRESS, self.__incButtonDown) + self.incButton.bind(B1RELEASE, self.__buttonUp) + self.decButton = self.createcomponent("decButton", (), "decButton", + DirectButton, (), + parent = self, + ) + self.decButton.bind(B1PRESS, self.__decButtonDown) + self.decButton.bind(B1RELEASE, self.__buttonUp) + self.itemFrame = self.createcomponent("itemFrame", (), "itemFrame", + DirectFrame, (), + parent = self, + ) + for item in self["items"]: + item.reparentTo(self.itemFrame) self.initialiseoptions(DirectScrolledList) + self.recordMaxHeight() + if len(self["items"]) > 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.removeTasksNamed(self.taskName("scroll")) + DirectFrame.destroy(self) + + def scrollBy(self, delta): + return self.scrollTo(self.index + delta) + + def scrollTo(self, index): + self.index = index + 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 + 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.spawnTaskNamed(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.spawnTaskNamed(task, self.taskName("scroll")) + + def __buttonUp(self, event): + taskMgr.removeTasksNamed(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) + diff --git a/direct/src/gui/OnscreenText.py b/direct/src/gui/OnscreenText.py index 3df124f6ef..e88f314b5e 100644 --- a/direct/src/gui/OnscreenText.py +++ b/direct/src/gui/OnscreenText.py @@ -356,6 +356,9 @@ class OnscreenText(PandaObject, NodePath): getter = eval('self.get' + string.upper(option[0]) + option[1:]) return getter() + def setAlign(self, align): + self.textNode.setAlign(align) + # Allow index style refererences __getitem__ = cget