Browse Source

support the new gui event world order

Cary Sandvig 25 years ago
parent
commit
d1c1b0b7a1

+ 10 - 1
direct/src/gui/Button.py

@@ -21,7 +21,8 @@ class Button(DirectObject):
                  upStyle = Label.ButtonUp,
                  upStyle = Label.ButtonUp,
                  litStyle = Label.ButtonLit,
                  litStyle = Label.ButtonLit,
                  downStyle = Label.ButtonDown,
                  downStyle = Label.ButtonDown,
-                 inactiveStyle = Label.ButtonInactive):
+                 inactiveStyle = Label.ButtonInactive,
+                 event = None):
         self.name = name
         self.name = name
         self.width = width
         self.width = width
 
 
@@ -96,6 +97,10 @@ class Button(DirectObject):
                                           self.lDown, self.lDown, self.lInactive)
                                           self.lDown, self.lDown, self.lInactive)
         self.button.setDrawOrder(drawOrder)
         self.button.setDrawOrder(drawOrder)
 
 
+        if (event != None):
+            self.button.setBehaviorEvent(event)
+        self.event = event
+
         if align == TMALIGNLEFT:
         if align == TMALIGNLEFT:
             self.xoffset = width / 2.0 * scale
             self.xoffset = width / 2.0 * scale
         elif align == TMALIGNRIGHT:
         elif align == TMALIGNRIGHT:
@@ -157,6 +162,9 @@ class Button(DirectObject):
             else:
             else:
                 self.button.manage(guiMgr, base.eventMgr.eventHandler)
                 self.button.manage(guiMgr, base.eventMgr.eventHandler)
 
 
+            if (self.event != None):
+                self.button.startBehavior()
+
             if self.inactive:
             if self.inactive:
                 self.button.exit()
                 self.button.exit()
                 self.button.inactive()
                 self.button.inactive()
@@ -184,6 +192,7 @@ class Button(DirectObject):
 
 
     def setBehaviorEvent(self, eventName):
     def setBehaviorEvent(self, eventName):
         self.button.setBehaviorEvent(eventName)
         self.button.setBehaviorEvent(eventName)
+        self.event = eventName
 
 
     def setBehaviorEventParameter(self, param):
     def setBehaviorEventParameter(self, param):
         self.button.setBehaviorEventParameter(param)
         self.button.setBehaviorEventParameter(param)

+ 13 - 10
direct/src/gui/DialogBox.py

@@ -9,7 +9,7 @@ import Button
 import StateData
 import StateData
 import OnscreenPanel
 import OnscreenPanel
 
 
-# No buttons at aall
+# No buttons at all
 NoButtons = 0
 NoButtons = 0
 
 
 # just an OK button
 # just an OK button
@@ -83,12 +83,13 @@ class DialogBox(OnscreenPanel.OnscreenPanel):
         if (self.style == TwoChoice):
         if (self.style == TwoChoice):
             # create OK and CANCEL buttons
             # create OK and CANCEL buttons
             self.makeButton("OK", pos = (-0.325, -0.25),
             self.makeButton("OK", pos = (-0.325, -0.25),
-                            func = self.handleOk)
+                            func = self.handleOk, event = "ok")
             self.makeButton("Cancel", pos = (0.2, -0.25),
             self.makeButton("Cancel", pos = (0.2, -0.25),
-                            func = self.handleCancel)
+                            func = self.handleCancel, event = "cancel")
         elif (self.style == Acknowledge):
         elif (self.style == Acknowledge):
             # create a centered OK  button
             # create a centered OK  button
-            self.makeButton("OK", pos = (0.0, -0.25), func = self.handleOk)
+            self.makeButton("OK", pos = (0.0, -0.25), func = self.handleOk,
+                            event = "ok")
         elif (self.style == NoButtons):
         elif (self.style == NoButtons):
             # No buttons at all
             # No buttons at all
             pass
             pass
@@ -114,15 +115,17 @@ class DialogBox(OnscreenPanel.OnscreenPanel):
     def handleRollover(self):
     def handleRollover(self):
 	return None
 	return None
 
 
-    def handleOk(self):
+    def handleOk(self, okButton, item):
         assert(self.style != NoButtons)
         assert(self.style != NoButtons)
-	self.doneStatus = "ok"	
-	messenger.send(self.doneEvent)
+        if (okButton == item):
+            self.doneStatus = "ok"	
+            messenger.send(self.doneEvent)
 
 
-    def handleCancel(self):
+    def handleCancel(self, cancelButton, item):
         assert(self.style == TwoChoice)
         assert(self.style == TwoChoice)
-        self.doneStatus = "cancel"
-	messenger.send(self.doneEvent)
+        if (cancelButton == item):
+            self.doneStatus = "cancel"
+            messenger.send(self.doneEvent)
 
 
     def setMessage(self, message):
     def setMessage(self, message):
         """setMessage(self, string)
         """setMessage(self, string)

+ 17 - 7
direct/src/gui/ListBox.py

@@ -49,12 +49,19 @@ class ListBox(DirectObject):
 
 
 	return None
 	return None
 
 
-    def addItem(self, item, label):
-        button = Button.Button(item, label,
-                               scale = self.scale,
-                               width = self.width,
-                               drawOrder = self.drawOrder,
-                               font = self.font)
+    def addItem(self, item, label, event = None, param = None):
+        if event:
+            button = Button.Button(item, label, scale = self.scale,
+                                   width = self.width,
+                                   drawOrder = self.drawOrder,
+                                   font = self.font, event = event)
+            button.button.setBehaviorEventParameter(param)
+        else:
+            button = Button.Button(item, label,
+                                   scale = self.scale,
+                                   width = self.width,
+                                   drawOrder = self.drawOrder,
+                                   font = self.font)
         
         
         self.items.append((item, button))
         self.items.append((item, button))
         self.listBox.addItem(button.button)
         self.listBox.addItem(button.button)
@@ -64,7 +71,10 @@ class ListBox(DirectObject):
             if isinstance(i, types.StringType):
             if isinstance(i, types.StringType):
                 self.addItem(i, i)
                 self.addItem(i, i)
             else:
             else:
-                self.addItem(i[0], i[1])
+                if (len(i) == 3):
+                    self.addItem(i[0], i[1])
+                else:
+                    self.addItem(i[0], i[1], i[3], i[4])
 
 
     def cleanup(self):
     def cleanup(self):
         if (self.managed):
         if (self.managed):

+ 15 - 5
direct/src/gui/OnscreenPanel.py

@@ -203,10 +203,15 @@ class OnscreenPanel(PandaObject.PandaObject, NodePath):
 
 
         # show the buttons that are meant to be shown
         # show the buttons that are meant to be shown
         for button in self.panelButtons:
         for button in self.panelButtons:
-            if button.func != None:
-                self.accept(button.getName() + '-down-rollover', button.func)
             if button.panelManage:
             if button.panelManage:
                 button.manage(self)
                 button.manage(self)
+            if button.func != None:
+                if (button.event != None):
+                    self.accept(button.event, button.func, [button.button])
+                else:
+                    self.accept(button.button.getDownRolloverEvent(),
+                                button.func, [button.button])
+                button.startBehavior()
                 
                 
         base.mouseWatcher.node().addRegion(self.panelRegion)
         base.mouseWatcher.node().addRegion(self.panelRegion)
         
         
@@ -221,7 +226,10 @@ class OnscreenPanel(PandaObject.PandaObject, NodePath):
 
 
         # hide the shown buttons and remove all hooks
         # hide the shown buttons and remove all hooks
         for button in self.panelButtons:        
         for button in self.panelButtons:        
-            self.ignore(button.getName() + '-down-rollover')
+            if (button.event != None):
+                self.ignore(button.event)
+            else:
+                self.ignore(button.button.getDownRolloverEvent())
             if button.panelManage:
             if button.panelManage:
                 button.unmanage()
                 button.unmanage()
                 
                 
@@ -243,7 +251,8 @@ class OnscreenPanel(PandaObject.PandaObject, NodePath):
                    upStyle = Label.ButtonUp,
                    upStyle = Label.ButtonUp,
                    litStyle = Label.ButtonLit,
                    litStyle = Label.ButtonLit,
                    downStyle = Label.ButtonDown,
                    downStyle = Label.ButtonDown,
-                   inactiveStyle = Label.ButtonInactive):
+                   inactiveStyle = Label.ButtonInactive,
+                   event = None):
         """makeButton(self, ...)
         """makeButton(self, ...)
 
 
         Creates a button on the panel.  The return value is the button
         Creates a button on the panel.  The return value is the button
@@ -284,7 +293,8 @@ class OnscreenPanel(PandaObject.PandaObject, NodePath):
                                upStyle = upStyle,
                                upStyle = upStyle,
                                litStyle = litStyle,
                                litStyle = litStyle,
                                downStyle = downStyle,
                                downStyle = downStyle,
-                               inactiveStyle = inactiveStyle)
+                               inactiveStyle = inactiveStyle,
+                               event = event)
 
 
         self.panelButtons.append(button)
         self.panelButtons.append(button)
         
         

+ 51 - 57
direct/src/gui/PickList.py

@@ -32,6 +32,12 @@ class PickList(PandaObject.PandaObject):
 	self.isClean = 0
 	self.isClean = 0
 	return None
 	return None
 
 
+    def owns(self, item):
+        for x in self.choiceList:
+            if (x.button == item):
+                return 1
+        return None
+
     def cleanup(self):
     def cleanup(self):
 	"""cleanup(self)
 	"""cleanup(self)
 	"""
 	"""
@@ -75,16 +81,15 @@ class PickList(PandaObject.PandaObject):
         for choice in choiceList:
         for choice in choiceList:
             # create a button for each choice
             # create a button for each choice
             button = Button.Button(choice, scale = scale, width = width,
             button = Button.Button(choice, scale = scale, width = width,
-                                   drawOrder = drawOrder, font = font)
+                                   drawOrder = drawOrder, font = font,
+                                   event = "choose")
             choiceIndex = choiceList.index(choice)
             choiceIndex = choiceList.index(choice)
+            button.setBehaviorEventParameter(choiceIndex)
             # set the rollover-up event
             # set the rollover-up event
-            eventName = self.name + "-up-" + str(choiceIndex)
+            eventName = self.name + "-up"
             button.button.setUpRolloverEvent(eventName)
             button.button.setUpRolloverEvent(eventName)
-            # set the rollover-down event
-            eventName = self.name + "-down-" + str(choiceIndex)
-            button.button.setDownRolloverEvent(eventName)
             # set exit event
             # set exit event
-            eventName = self.name + "-exit-" + str(choiceIndex)
+            eventName = self.name + "-exit"
             button.button.setUpEvent(eventName)
             button.button.setUpEvent(eventName)
             # keep a list of the choice buttons
             # keep a list of the choice buttons
             self.frame.addItem(button)
             self.frame.addItem(button)
@@ -98,6 +103,8 @@ class PickList(PandaObject.PandaObject):
     def manage(self):
     def manage(self):
         self.enable()
         self.enable()
         self.frame.manage()
         self.frame.manage()
+        for x in self.choiceList:
+            x.startBehavior()
 	return None
 	return None
 
 
     def unmanage(self):
     def unmanage(self):
@@ -112,21 +119,10 @@ class PickList(PandaObject.PandaObject):
         # listen for keyboard events
         # listen for keyboard events
         self.accept("up-up", self.__decrementChoice)
         self.accept("up-up", self.__decrementChoice)
         self.accept("down-up", self.__incrementChoice)
         self.accept("down-up", self.__incrementChoice)
-        self.accept("enter-up", self.__makeChoice, [1])
-
-        for choice in self.choiceList:
-            choiceIndex = self.choiceList.index(choice)
-            # set the rollover-up event
-            eventName = self.name + "-up-" + str(choiceIndex)
-            self.accept(eventName, self.__updateButtonChoice, [choiceIndex])
-            # set the rollover-down event
-            eventName = self.name + "-down-" + str(choiceIndex)
-            self.accept(eventName, self.__makeChoice)
-            # set exit event
-            eventName = self.name + "-exit-" + str(choiceIndex)
-            self.accept(eventName, self.__exitChoice)
-
-            
+        self.accept("enter-up", self.__makeChoice, [1, None, None])
+        self.accept(self.name + "-up", self.__updateButtonChoice)
+        self.accept(self.name + "-exit", self.__exitChoice)
+        self.accept("choose", self.__makeChoice, [0])
 
 
     def disable(self, button=None):
     def disable(self, button=None):
         # turn the buttons off
         # turn the buttons off
@@ -136,12 +132,9 @@ class PickList(PandaObject.PandaObject):
         self.ignore("up-up")
         self.ignore("up-up")
         self.ignore("down-up")
         self.ignore("down-up")
         self.ignore("enter-up")
         self.ignore("enter-up")
-
-        # ignore all the buttons
-        for item in self.frame.getItems():
-       	    self.ignore(item.getGuiItem().getUpEvent())
-    	    self.ignore(item.getGuiItem().getUpRolloverEvent())
-       	    self.ignore(item.getGuiItem().getDownRolloverEvent())
+        self.ignore(self.name + "-up")
+        self.ignore(self.name + "-exit")
+        self.ignore("choose")
 
 
     def activate(self):
     def activate(self):
         # make sure items are active
         # make sure items are active
@@ -168,41 +161,41 @@ class PickList(PandaObject.PandaObject):
     # event handlers
     # event handlers
     def __incrementChoice(self):
     def __incrementChoice(self):
         # handle the up arrow
         # handle the up arrow
-        if (self.choice >= 0):
-            # exit lest choice, if it exists
-            self.choiceList[self.choice].getGuiItem().exit()
-        self.choice = self.choice + 1
-        if (self.choice > len(self.choiceList) - 1):
-            self.choice = 0
+        choice = self.choice + 1
+        if (choice > len(self.choiceList) - 1):
+            choice = 0
         # enter the new choice
         # enter the new choice
-        self.choiceList[self.choice].getGuiItem().enter()
-
+        self.choiceList[choice].getGuiItem().enter()
     
     
     def __decrementChoice(self):
     def __decrementChoice(self):
         # handle the down arrow
         # handle the down arrow
-        if (self.choice >= 0):
-            self.choiceList[self.choice].getGuiItem().exit()        
-        self.choice = self.choice - 1
-        if (self.choice < 0):
-            self.choice = len(self.choiceList) - 1
+        choice = self.choice - 1
+        if (choice < 0):
+            choice = len(self.choiceList) - 1
         # enter this choice
         # enter this choice
-        self.choiceList[self.choice].getGuiItem().enter()
+        self.choiceList[choice].getGuiItem().enter()
 
 
-    def __updateButtonChoice(self, newChoice, *args):
+    def __updateButtonChoice(self, item):
         # handle the mouse rollovers
         # handle the mouse rollovers
-        self.choice = newChoice
-        # make sure all the other buttons have exited
-        for choice in self.choiceList:
-            if not (self.choiceList.index(choice) == self.choice):
-                choice.getGuiItem().exit()
-	# throw event
-	messenger.send(self.name + "-rollover")
-
-    def __exitChoice(self, *args):
+        if self.owns(item):
+            if (self.choice == -1):
+                self.choice = item.getBehaviorEventParameter()
+            if (self.choice != item.getBehaviorEventParameter()):
+                self.choice = item.getBehaviorEventParameter()
+                # make sure all the other buttons have exited
+                for choice in self.choiceList:
+                    if (choice.button != item):
+                        choice.getGuiItem().exit()
+                # throw event
+                messenger.send(self.name + "-rollover")
+            
+    def __exitChoice(self, item):
         # reset choice when mouse exits a button
         # reset choice when mouse exits a button
-        self.choice = -1
+        if self.owns(item):
+            if (self.choice == item.getBehaviorEventParameter()):
+                self.choice = -1
         
         
-    def __makeChoice(self, button=0, *args):
+    def __makeChoice(self, button, item, whichOne):
         # handle the enter key
         # handle the enter key
         if (self.choice == -1):
         if (self.choice == -1):
             # nothing selected yet
             # nothing selected yet
@@ -216,13 +209,14 @@ class PickList(PandaObject.PandaObject):
                     return Task.done
                     return Task.done
                 task = Task.Task(buttonUp)
                 task = Task.Task(buttonUp)
                 task.choice = self.choiceList[self.choice]
                 task.choice = self.choiceList[self.choice]
-                taskMgr.spawnTaskNamed(Task.doLater(.035, task,
+                taskMgr.spawnTaskNamed(Task.doLater(0.035, task,
                                                     "buttonUp-later"),
                                                     "buttonUp-later"),
-                                   "doLater-buttonUp-later")
+                                       "doLater-buttonUp-later")
             else:
             else:
                 # let everyone know a choice was made                
                 # let everyone know a choice was made                
-                messenger.send(self.eventName, [self.choice])
-                self.disable(self.choice)
+                if self.owns(item):
+                    messenger.send(self.eventName, [self.choice])
+                    self.disable(self.choice)
                 
                 
                 
                 
 
 

+ 28 - 26
direct/src/gui/ScrollingLabel.py

@@ -69,8 +69,7 @@ class ScrollingLabel(PandaObject.PandaObject):
                                         label = " < ",
                                         label = " < ",
                                         scale = scale,
                                         scale = scale,
                                         drawOrder = drawOrder,
                                         drawOrder = drawOrder,
-                                        font = font)
-        self.leftButton.getGuiItem().setDownRolloverEvent(self.eventName + "-left")
+                                        font = font, event = "left-button")
         self.leftButton.getGuiItem().setUpRolloverEvent(self.eventName + "-rollover")
         self.leftButton.getGuiItem().setUpRolloverEvent(self.eventName + "-rollover")
         self.frame.addItem(self.leftButton)
         self.frame.addItem(self.leftButton)
         self.frame.packItem(self.leftButton, GuiFrame.GuiFrame.UNDER,
         self.frame.packItem(self.leftButton, GuiFrame.GuiFrame.UNDER,
@@ -81,9 +80,7 @@ class ScrollingLabel(PandaObject.PandaObject):
                                          label = " > ",
                                          label = " > ",
                                          scale = scale,
                                          scale = scale,
                                          drawOrder = drawOrder,
                                          drawOrder = drawOrder,
-                                         font = font)
-        self.rightButton.getGuiItem().setDownRolloverEvent(self.eventName +
-                                                           "-right")    
+                                         font = font, event = "right-button")
         self.rightButton.getGuiItem().setUpRolloverEvent(self.eventName + "-rollover")
         self.rightButton.getGuiItem().setUpRolloverEvent(self.eventName + "-rollover")
         self.frame.addItem(self.rightButton)
         self.frame.addItem(self.rightButton)
         self.frame.packItem(self.rightButton, GuiFrame.GuiFrame.UNDER,
         self.frame.packItem(self.rightButton, GuiFrame.GuiFrame.UNDER,
@@ -102,8 +99,8 @@ class ScrollingLabel(PandaObject.PandaObject):
 	"""cleanup(self)
 	"""cleanup(self)
 	"""
 	"""
         # ignore events
         # ignore events
-        self.ignore(self.eventName + "-left")
-        self.ignore(self.eventName + "-right")
+        self.ignore("left-button")
+        self.ignore("right-button")
 	self.ignore(self.eventName + "-rollover")
 	self.ignore(self.eventName + "-rollover")
         self.setKeyFocus(0)
         self.setKeyFocus(0)
 
 
@@ -190,12 +187,15 @@ class ScrollingLabel(PandaObject.PandaObject):
         
         
     def manage(self):
     def manage(self):
         # listen for the scroll buttons
         # listen for the scroll buttons
-        self.accept(self.eventName + "-left", self.handleLeftButton)
-        self.accept(self.eventName + "-right", self.handleRightButton)
+        self.accept("left-button", self.handleLeftButton)
+        self.accept("right-button", self.handleRightButton)
 
 
         self.frame.manage()
         self.frame.manage()
         self.setKeyFocus(0)
         self.setKeyFocus(0)
 
 
+        self.leftButton.startBehavior()
+        self.rightButton.startBehavior()
+
 	return None
 	return None
 
 
     def unmanage(self):
     def unmanage(self):
@@ -204,8 +204,8 @@ class ScrollingLabel(PandaObject.PandaObject):
         self.ignore("right-up")            
         self.ignore("right-up")            
 
 
         # ignore events
         # ignore events
-        self.ignore(self.eventName + "-left")
-        self.ignore(self.eventName + "-right")
+        self.ignore("left-button")
+        self.ignore("right-button")
 	self.ignore(self.eventName + "-rollover")
 	self.ignore(self.eventName + "-rollover")
         self.setKeyFocus(0)
         self.setKeyFocus(0)
 
 
@@ -213,35 +213,37 @@ class ScrollingLabel(PandaObject.PandaObject):
 
 
 	return None
 	return None
         
         
-    def handleLeftButton(self):
+    def handleLeftButton(self, item):
         # update the current item and the scroll label
         # update the current item and the scroll label
-        self.item = self.item - 1
-        if (self.item < 0):
-            self.item = len(self.items) - 1
-        self.setItem(self.item)
-        messenger.send(self.eventName, [self.item])
-
-    def handleRightButton(self):
+        if (self.leftButton.button == item):
+            self.item = self.item - 1
+            if (self.item < 0):
+                self.item = len(self.items) - 1
+            self.setItem(self.item)
+            messenger.send(self.eventName, [self.item])
+
+    def handleRightButton(self, item):
         # update the current item and the scroll label
         # update the current item and the scroll label
-        self.item = self.item + 1
-        if (self.item >= len(self.items)):
-            self.item = 0
-        self.setItem(self.item)
-        messenger.send(self.eventName, [self.item])
+        if (self.rightButton.button == item):
+            self.item = self.item + 1
+            if (self.item >= len(self.items)):
+                self.item = 0
+            self.setItem(self.item)
+            messenger.send(self.eventName, [self.item])
 
 
     def handleLeftArrow(self):
     def handleLeftArrow(self):
         # make the button toggle
         # make the button toggle
         self.leftButton.getGuiItem().down()
         self.leftButton.getGuiItem().down()
         self.spawnButtonUpTask(self.leftButton)
         self.spawnButtonUpTask(self.leftButton)
         # then act like a mouse click
         # then act like a mouse click
-        self.handleLeftButton()
+        self.handleLeftButton(self.leftButton.button)
 
 
     def handleRightArrow(self):
     def handleRightArrow(self):
         # make the button toggle
         # make the button toggle
         self.rightButton.getGuiItem().down()
         self.rightButton.getGuiItem().down()
         self.spawnButtonUpTask(self.rightButton)
         self.spawnButtonUpTask(self.rightButton)
         # then act like a mouse click
         # then act like a mouse click
-        self.handleRightButton()
+        self.handleRightButton(self.rightButton.button)
 
 
     def spawnButtonUpTask(self, button):
     def spawnButtonUpTask(self, button):
         def buttonUp(state):
         def buttonUp(state):

+ 16 - 12
direct/src/showbase/Messenger.py

@@ -117,20 +117,24 @@ class Messenger:
         if self.dict.has_key(event):
         if self.dict.has_key(event):
             acceptorDict = self.dict[event]
             acceptorDict = self.dict[event]
             for object in acceptorDict.keys():
             for object in acceptorDict.keys():
-                method, extraArgs, persistent = acceptorDict[object]
-                apply(method, (extraArgs + sentArgs))
-                # If this object was only accepting this event once,
-                # remove it from the dictionary
-                if not persistent:
-                    # We need to check this because the apply above might
-                    # have done an ignore.
-                    if acceptorDict.has_key(object):
-                        del acceptorDict[object]
+                # We have to make this apparently redundant check, because
+                # it is possible that one object removes its own hooks
+                # in response to a handler called by a previous object.
+                if acceptorDict.has_key(object):
+                    method, extraArgs, persistent = acceptorDict[object]
+                    apply(method, (extraArgs + sentArgs))
+                    # If this object was only accepting this event once,
+                    # remove it from the dictionary
+                    if not persistent:
+                        # We need to check this because the apply above might
+                        # have done an ignore.
+                        if acceptorDict.has_key(object):
+                            del acceptorDict[object]
                         # If this dictionary is now empty, remove the event
                         # If this dictionary is now empty, remove the event
                         # entry from the Messenger alltogether
                         # entry from the Messenger alltogether
-                    if ((len(acceptorDict) == 0) and
-                        (self.dict.has_key(event))):
-                        del self.dict[event]
+                        if ((len(acceptorDict) == 0) and
+                            (self.dict.has_key(event))):
+                            del self.dict[event]
 
 
     def clear(self):
     def clear(self):
         """clear(self)
         """clear(self)