Cary Sandvig преди 25 години
родител
ревизия
e4fda87212

+ 5 - 3
panda/src/audio/Sources.pp

@@ -8,7 +8,7 @@
   #define USE_MIKMOD yes
   #define USE_MIKMOD yes
 
 
   #define TARGET audio
   #define TARGET audio
-  #define LOCAL_LIBS putil ipc
+  #define LOCAL_LIBS putil ipc gui
 
 
   #define SOURCES \
   #define SOURCES \
     audio_manager.I audio_manager.cxx audio_manager.h audio_midi.cxx \
     audio_manager.I audio_manager.cxx audio_manager.h audio_midi.cxx \
@@ -18,14 +18,16 @@
     audio_mikmod_traits.h audio_win_traits.I audio_win_traits.cxx \
     audio_mikmod_traits.h audio_win_traits.I audio_win_traits.cxx \
     audio_win_traits.h audio_null_traits.I audio_null_traits.cxx \
     audio_win_traits.h audio_null_traits.I audio_null_traits.cxx \
     audio_null_traits.h audio_linux_traits.I audio_linux_traits.cxx \
     audio_null_traits.h audio_linux_traits.I audio_linux_traits.cxx \
-    audio_linux_traits.h audio_sound.h audio_sound.I audio_sound.cxx
+    audio_linux_traits.h audio_sound.h audio_sound.I audio_sound.cxx \
+    audio_gui_functor.h audio_gui_functor.cxx
 
 
   #define INSTALL_HEADERS \
   #define INSTALL_HEADERS \
     audio.h audio_manager.h audio_pool.I audio_pool.h \
     audio.h audio_manager.h audio_pool.I audio_pool.h \
     audio_trait.h audio_mikmod_traits.h \
     audio_trait.h audio_mikmod_traits.h \
     audio_win_traits.I audio_win_traits.h audio_null_traits.I \
     audio_win_traits.I audio_win_traits.h audio_null_traits.I \
     audio_null_traits.h audio_linux_traits.I audio_linux_traits.h \
     audio_null_traits.h audio_linux_traits.I audio_linux_traits.h \
-    config_audio.h audio_manager.I audio_sound.h audio_sound.I
+    config_audio.h audio_manager.I audio_sound.h audio_sound.I \
+    audio_gui_functor.h
 
 
   #define IGATESCAN audio.h
   #define IGATESCAN audio.h
 
 

+ 1 - 0
panda/src/audio/audio.h

@@ -10,5 +10,6 @@
 #include "audio_sound.h"
 #include "audio_sound.h"
 #include "audio_manager.h"
 #include "audio_manager.h"
 #include "audio_pool.h"
 #include "audio_pool.h"
+#include "audio_gui_functor.h"
 
 
 #endif /* __AUDIO_H__ */
 #endif /* __AUDIO_H__ */

+ 11 - 0
panda/src/audio/audio_gui_functor.cxx

@@ -10,4 +10,15 @@ AudioGuiFunctor::AudioGuiFunctor(AudioSound* sound,
   : _prev(prev), _sound(sound) {}
   : _prev(prev), _sound(sound) {}
 
 
 AudioGuiFunctor::~AudioGuiFunctor(void) {
 AudioGuiFunctor::~AudioGuiFunctor(void) {
+  if (_prev != (GuiBehavior::BehaviorFunctor*)0L)
+    delete _prev;
+}
+
+#include "audio_manager.h"
+
+void AudioGuiFunctor::doit(GuiBehavior* b) {
+  if (_sound != (AudioSound*)0L)
+    AudioManager::play(_sound);
+  if (_prev != (GuiBehavior::BehaviorFunctor*)0L)
+    _prev->doit(b);
 }
 }

+ 69 - 5
panda/src/gui/guiButton.cxx

@@ -105,6 +105,7 @@ void GuiButton::switch_state(GuiButton::States nstate) {
   }
   }
 
 
   test_ref_count_integrity();
   test_ref_count_integrity();
+  States ostate = _state;
   // cleanup old state
   // cleanup old state
   switch (_state) {
   switch (_state) {
   case NONE:
   case NONE:
@@ -158,12 +159,17 @@ void GuiButton::switch_state(GuiButton::States nstate) {
 	_mgr->add_label(_up, _alt_root);
 	_mgr->add_label(_up, _alt_root);
     }
     }
     if (!_up_event.empty()) {
     if (!_up_event.empty()) {
+#ifdef _DEBUG
       if (gui_cat->is_debug())
       if (gui_cat->is_debug())
 	gui_cat->debug() << "throwing _up_event '" << _up_event << "'" << endl;
 	gui_cat->debug() << "throwing _up_event '" << _up_event << "'" << endl;
+#endif /* _DEBUG */
       throw_event(_up_event, EventParameter(this));
       throw_event(_up_event, EventParameter(this));
-    } else
-      if (gui_cat->is_debug())
+#ifdef _DEBUG
+    } else if (gui_cat->is_debug())
 	gui_cat->debug() << "_up_event is empty!" << endl;
 	gui_cat->debug() << "_up_event is empty!" << endl;
+#else /* _DEBUG */
+    }
+#endif /* _DEBUG */
     _rgn->set_suppress_below(true);
     _rgn->set_suppress_below(true);
     break;
     break;
   case UP_ROLLOVER:
   case UP_ROLLOVER:
@@ -178,12 +184,18 @@ void GuiButton::switch_state(GuiButton::States nstate) {
 	  _mgr->add_label(_up_rollover, _alt_root);
 	  _mgr->add_label(_up_rollover, _alt_root);
       }
       }
       if (!_up_rollover_event.empty()) {
       if (!_up_rollover_event.empty()) {
+#ifdef _DEBUG
 	if (gui_cat->is_debug())
 	if (gui_cat->is_debug())
 	  gui_cat->debug() << "throwing _up_rollover_event '"
 	  gui_cat->debug() << "throwing _up_rollover_event '"
 			   << _up_rollover_event << "'" << endl;
 			   << _up_rollover_event << "'" << endl;
+#endif /* _DEBUG */
 	throw_event(_up_rollover_event, EventParameter(this));
 	throw_event(_up_rollover_event, EventParameter(this));
+#ifdef _DEBUG
       } else if (gui_cat->is_debug())
       } else if (gui_cat->is_debug())
 	  gui_cat->debug() << "_up_rollover_event is empty!" << endl;
 	  gui_cat->debug() << "_up_rollover_event is empty!" << endl;
+#else /* _DEBUG */
+      }
+#endif /* _DEBUG */
     } else {
     } else {
       if (_alt_root.is_null()) {
       if (_alt_root.is_null()) {
 	if (!(_mgr->has_label(_up)))
 	if (!(_mgr->has_label(_up)))
@@ -193,15 +205,24 @@ void GuiButton::switch_state(GuiButton::States nstate) {
 	  _mgr->add_label(_up, _alt_root);
 	  _mgr->add_label(_up, _alt_root);
       }
       }
       if (!_up_event.empty()) {
       if (!_up_event.empty()) {
+#ifdef _DEBUG
 	if (gui_cat->is_debug())
 	if (gui_cat->is_debug())
 	  gui_cat->debug() << "throwing _up_event '" << _up_event << "'"
 	  gui_cat->debug() << "throwing _up_event '" << _up_event << "'"
 			   << endl;
 			   << endl;
+#endif /* _DEBUG */
 	throw_event(_up_event, EventParameter(this));
 	throw_event(_up_event, EventParameter(this));
+#ifdef _DEBUG
       } else if (gui_cat->is_debug())
       } else if (gui_cat->is_debug())
 	gui_cat->debug() << "_up_event is empty!" << endl;
 	gui_cat->debug() << "_up_event is empty!" << endl;
+#else /* _DEBUG */
+      }
+#endif /* _DEBUG */
       _state = UP;
       _state = UP;
     }
     }
     _rgn->set_suppress_below(true);
     _rgn->set_suppress_below(true);
+    if ((ostate == UP) &&
+	(_rollover_functor != (GuiBehavior::BehaviorFunctor*)0L))
+      _rollover_functor->doit(this);
     break;
     break;
   case DOWN:
   case DOWN:
     if (!(_mgr->has_region(_rgn)))
     if (!(_mgr->has_region(_rgn)))
@@ -214,12 +235,18 @@ void GuiButton::switch_state(GuiButton::States nstate) {
 	_mgr->add_label(_down, _alt_root);
 	_mgr->add_label(_down, _alt_root);
     }
     }
     if (!_down_event.empty()) {
     if (!_down_event.empty()) {
+#ifdef _DEBUG
       if (gui_cat->is_debug())
       if (gui_cat->is_debug())
 	gui_cat->debug() << "throwing _down_event '" << _down_event << "'"
 	gui_cat->debug() << "throwing _down_event '" << _down_event << "'"
 			 << endl;
 			 << endl;
+#endif /* _DEBUG */
       throw_event(_down_event, EventParameter(this));
       throw_event(_down_event, EventParameter(this));
+#ifdef _DEBUG
     } else if (gui_cat->is_debug())
     } else if (gui_cat->is_debug())
       gui_cat->debug() << "_down_event is empty!" << endl;
       gui_cat->debug() << "_down_event is empty!" << endl;
+#else /* _DEBUG */
+    }
+#endif /* _DEBUG */
     _rgn->set_suppress_below(true);
     _rgn->set_suppress_below(true);
     break;
     break;
   case DOWN_ROLLOVER:
   case DOWN_ROLLOVER:
@@ -234,12 +261,18 @@ void GuiButton::switch_state(GuiButton::States nstate) {
 	  _mgr->add_label(_down_rollover, _alt_root);
 	  _mgr->add_label(_down_rollover, _alt_root);
       }
       }
       if (!_down_rollover_event.empty()) {
       if (!_down_rollover_event.empty()) {
+#ifdef _DEBUG
 	if (gui_cat->is_debug())
 	if (gui_cat->is_debug())
 	  gui_cat->debug() << "throwing _down_rollover_event '"
 	  gui_cat->debug() << "throwing _down_rollover_event '"
 			   << _down_rollover_event << "'" << endl;
 			   << _down_rollover_event << "'" << endl;
+#endif /* _DEBUG */
 	throw_event(_down_rollover_event, EventParameter(this));
 	throw_event(_down_rollover_event, EventParameter(this));
+#ifdef _DEBUG
       } else if (gui_cat->is_debug())
       } else if (gui_cat->is_debug())
 	gui_cat->debug() << "_down_rollover_event is empty!" << endl;
 	gui_cat->debug() << "_down_rollover_event is empty!" << endl;
+#else /* _DEBUG */
+      }
+#endif /* _DEBUG */
     } else {
     } else {
       if (_alt_root.is_null()) {
       if (_alt_root.is_null()) {
 	if (!(_mgr->has_label(_down)))
 	if (!(_mgr->has_label(_down)))
@@ -249,12 +282,18 @@ void GuiButton::switch_state(GuiButton::States nstate) {
 	  _mgr->add_label(_down, _alt_root);
 	  _mgr->add_label(_down, _alt_root);
       }
       }
       if (!_down_event.empty()) {
       if (!_down_event.empty()) {
+#ifdef _DEBUG
 	if (gui_cat->is_debug())
 	if (gui_cat->is_debug())
 	  gui_cat->debug() << "throwing _down_event '" << _down_event << "'"
 	  gui_cat->debug() << "throwing _down_event '" << _down_event << "'"
 			   << endl;
 			   << endl;
+#endif /* _DEBUG */
 	throw_event(_down_event, EventParameter(this));
 	throw_event(_down_event, EventParameter(this));
+#ifdef _DEBUG
       } else if (gui_cat->is_debug())
       } else if (gui_cat->is_debug())
 	gui_cat->debug() << "_down_event is empty!" << endl;
 	gui_cat->debug() << "_down_event is empty!" << endl;
+#else /* _DEBUG */
+      }
+#endif /* _DEBUG */
       _state = DOWN;
       _state = DOWN;
     }
     }
     _rgn->set_suppress_below(true);
     _rgn->set_suppress_below(true);
@@ -271,9 +310,11 @@ void GuiButton::switch_state(GuiButton::States nstate) {
 	  _mgr->add_label(_inactive, _alt_root);
 	  _mgr->add_label(_inactive, _alt_root);
       }
       }
       if (!_inactive_event.empty()) {
       if (!_inactive_event.empty()) {
+#ifdef _DEBUG
 	if (gui_cat->is_debug())
 	if (gui_cat->is_debug())
 	  gui_cat->debug() << "throwing _inactive_event '" << _inactive_event
 	  gui_cat->debug() << "throwing _inactive_event '" << _inactive_event
 			   << "'" << endl;
 			   << "'" << endl;
+#endif /* _DEBUG */
 	throw_event(_inactive_event, EventParameter(this));
 	throw_event(_inactive_event, EventParameter(this));
       }
       }
     }
     }
@@ -291,9 +332,11 @@ void GuiButton::switch_state(GuiButton::States nstate) {
 	  _mgr->add_label(_inactive, _alt_root);
 	  _mgr->add_label(_inactive, _alt_root);
       }
       }
       if (!_inactive_event.empty()) {
       if (!_inactive_event.empty()) {
+#ifdef _DEBUG
 	if (gui_cat->is_debug())
 	if (gui_cat->is_debug())
 	  gui_cat->debug() << "throwing _inactive_event '" << _inactive_event
 	  gui_cat->debug() << "throwing _inactive_event '" << _inactive_event
 			   << "'" << endl;
 			   << "'" << endl;
+#endif /* _DEBUG */
 	throw_event(_inactive_event, EventParameter(this));
 	throw_event(_inactive_event, EventParameter(this));
       }
       }
     }
     }
@@ -343,40 +386,52 @@ void GuiButton::set_priority(GuiLabel* l, GuiItem::Priority p) {
 
 
 void GuiButton::behavior_up(CPT_Event e) {
 void GuiButton::behavior_up(CPT_Event e) {
   const GuiButton* button = DCAST(GuiButton, e->get_parameter(0).get_ptr());
   const GuiButton* button = DCAST(GuiButton, e->get_parameter(0).get_ptr());
+#ifdef _DEBUG
   if (gui_cat->is_debug())
   if (gui_cat->is_debug())
     gui_cat->debug() << "behavior_up (0x" << (void*)button << ")" << endl;
     gui_cat->debug() << "behavior_up (0x" << (void*)button << ")" << endl;
+#endif /* _DEBUG */
   button->run_button_up();
   button->run_button_up();
 }
 }
 
 
 void GuiButton::behavior_down(CPT_Event e) {
 void GuiButton::behavior_down(CPT_Event e) {
   const GuiButton* button = DCAST(GuiButton, e->get_parameter(0).get_ptr());
   const GuiButton* button = DCAST(GuiButton, e->get_parameter(0).get_ptr());
+#ifdef _DEBUG
   if (gui_cat->is_debug())
   if (gui_cat->is_debug())
     gui_cat->debug() << "behavior_down (0x" << (void*)button << ")" << endl;
     gui_cat->debug() << "behavior_down (0x" << (void*)button << ")" << endl;
+#endif /* _DEBUG */
   button->run_button_down();
   button->run_button_down();
 }
 }
 
 
 void GuiButton::run_button_up(void) const {
 void GuiButton::run_button_up(void) const {
+#ifdef _DEBUG
   if (gui_cat->is_debug())
   if (gui_cat->is_debug())
     gui_cat->debug() << "run_button_up (0x" << (void*)this << " '"
     gui_cat->debug() << "run_button_up (0x" << (void*)this << " '"
 		     << this->get_name() << "')" << endl;
 		     << this->get_name() << "')" << endl;
+#endif /* _DEBUG */
   if ((_eh == (EventHandler*)0L) || (!(this->_behavior_running)))
   if ((_eh == (EventHandler*)0L) || (!(this->_behavior_running)))
     return;
     return;
+#ifdef _DEBUG
   if (gui_cat->is_debug())
   if (gui_cat->is_debug())
     gui_cat->debug() << "doing work" << endl;
     gui_cat->debug() << "doing work" << endl;
+#endif /* _DEBUG */
   _eh->remove_hook(_up_event, GuiButton::behavior_up);
   _eh->remove_hook(_up_event, GuiButton::behavior_up);
   _eh->remove_hook(_up_rollover_event, GuiButton::behavior_up);
   _eh->remove_hook(_up_rollover_event, GuiButton::behavior_up);
   if (!_behavior_event.empty()) {
   if (!_behavior_event.empty()) {
     if (_have_event_param) {
     if (_have_event_param) {
+#ifdef _DEBUG
       if (gui_cat->is_debug())
       if (gui_cat->is_debug())
 	gui_cat->debug() << "throwing behavior event '" << _behavior_event
 	gui_cat->debug() << "throwing behavior event '" << _behavior_event
 			 << "' with parameter (" << _event_param << ")"
 			 << "' with parameter (" << _event_param << ")"
 			 << endl;
 			 << endl;
+#endif /* _DEBUG */
       throw_event(_behavior_event, EventParameter(this),
       throw_event(_behavior_event, EventParameter(this),
 		  EventParameter(_event_param));
 		  EventParameter(_event_param));
     } else {
     } else {
+#ifdef _DEBUG
       if (gui_cat->is_debug())
       if (gui_cat->is_debug())
 	gui_cat->debug() << "throwing behavior event '" << _behavior_event
 	gui_cat->debug() << "throwing behavior event '" << _behavior_event
 			 << "'" << endl;
 			 << "'" << endl;
+#endif /* _DEBUG */
       throw_event(_behavior_event, EventParameter(this));
       throw_event(_behavior_event, EventParameter(this));
     }
     }
   }
   }
@@ -385,14 +440,18 @@ void GuiButton::run_button_up(void) const {
 }
 }
 
 
 void GuiButton::run_button_down(void) const {
 void GuiButton::run_button_down(void) const {
+#ifdef _DEBUG
   if (gui_cat->is_debug())
   if (gui_cat->is_debug())
     gui_cat->debug() << "run_button_down (0x" << (void*)this << " '"
     gui_cat->debug() << "run_button_down (0x" << (void*)this << " '"
 		     << this->get_name() << "')" << endl;
 		     << this->get_name() << "')" << endl;
+#endif /* _DEBUG */
   if ((_eh == (EventHandler*)0L) || (!(this->_behavior_running)))
   if ((_eh == (EventHandler*)0L) || (!(this->_behavior_running)))
     return;
     return;
+#ifdef _DEBUG
   if (gui_cat->is_debug())
   if (gui_cat->is_debug())
     gui_cat->debug() << "doing work, up_event is '" << _up_event << "' '"
     gui_cat->debug() << "doing work, up_event is '" << _up_event << "' '"
 		     << _up_rollover_event << "'" << endl;
 		     << _up_rollover_event << "'" << endl;
+#endif /* _DEBUG */
   _eh->add_hook(_up_event, GuiButton::behavior_up);
   _eh->add_hook(_up_event, GuiButton::behavior_up);
   _eh->add_hook(_up_rollover_event, GuiButton::behavior_up);
   _eh->add_hook(_up_rollover_event, GuiButton::behavior_up);
 }
 }
@@ -405,7 +464,8 @@ GuiButton::GuiButton(const string& name, GuiLabel* up, GuiLabel* down)
     _inactive_event(""), _up_scale(up->get_scale()), _upr_scale(1.),
     _inactive_event(""), _up_scale(up->get_scale()), _upr_scale(1.),
     _down_scale(down->get_scale()), _downr_scale(1.), _inactive_scale(1.),
     _down_scale(down->get_scale()), _downr_scale(1.), _inactive_scale(1.),
     _state(GuiButton::NONE), _have_event_param(false), _event_param(0),
     _state(GuiButton::NONE), _have_event_param(false), _event_param(0),
-    _behavior_functor((GuiBehavior::BehaviorFunctor*)0L) {
+    _behavior_functor((GuiBehavior::BehaviorFunctor*)0L),
+    _rollover_functor((GuiBehavior::BehaviorFunctor*)0L) {
   GetExtents(up, down, _up_rollover, _down_rollover, _inactive, _left, _right,
   GetExtents(up, down, _up_rollover, _down_rollover, _inactive, _left, _right,
 	     _bottom, _top);
 	     _bottom, _top);
   _rgn = new MouseWatcherRegion("button-" + name, _left, _right, _bottom,
   _rgn = new MouseWatcherRegion("button-" + name, _left, _right, _bottom,
@@ -424,7 +484,8 @@ GuiButton::GuiButton(const string& name, GuiLabel* up, GuiLabel* down,
     _upr_scale(1.), _down_scale(down->get_scale()), _downr_scale(1.),
     _upr_scale(1.), _down_scale(down->get_scale()), _downr_scale(1.),
     _inactive_scale(inactive->get_scale()), _state(GuiButton::NONE),
     _inactive_scale(inactive->get_scale()), _state(GuiButton::NONE),
     _have_event_param(false), _event_param(0),
     _have_event_param(false), _event_param(0),
-    _behavior_functor((GuiBehavior::BehaviorFunctor*)0L) {
+    _behavior_functor((GuiBehavior::BehaviorFunctor*)0L),
+    _rollover_functor((GuiBehavior::BehaviorFunctor*)0L) {
   GetExtents(up, down, _up_rollover, _down_rollover, inactive, _left, _right,
   GetExtents(up, down, _up_rollover, _down_rollover, inactive, _left, _right,
 	     _bottom, _top);
 	     _bottom, _top);
   _rgn = new MouseWatcherRegion("button-" + name, _left, _right, _bottom,
   _rgn = new MouseWatcherRegion("button-" + name, _left, _right, _bottom,
@@ -444,7 +505,8 @@ GuiButton::GuiButton(const string& name, GuiLabel* up, GuiLabel* up_roll,
     _downr_scale(down_roll->get_scale()),
     _downr_scale(down_roll->get_scale()),
     _inactive_scale(inactive->get_scale()), _state(GuiButton::NONE),
     _inactive_scale(inactive->get_scale()), _state(GuiButton::NONE),
     _have_event_param(false), _event_param(0),
     _have_event_param(false), _event_param(0),
-    _behavior_functor((GuiBehavior::BehaviorFunctor*)0L) {
+    _behavior_functor((GuiBehavior::BehaviorFunctor*)0L),
+    _rollover_functor((GuiBehavior::BehaviorFunctor*)0L) {
   GetExtents(up, down, up_roll, down_roll, inactive, _left, _right, _bottom,
   GetExtents(up, down, up_roll, down_roll, inactive, _left, _right, _bottom,
 	     _top);
 	     _top);
   _rgn = new MouseWatcherRegion("button-" + name, _left, _right, _bottom,
   _rgn = new MouseWatcherRegion("button-" + name, _left, _right, _bottom,
@@ -470,6 +532,8 @@ GuiButton::~GuiButton(void) {
 
 
   if (_behavior_functor != (GuiBehavior::BehaviorFunctor*)0L)
   if (_behavior_functor != (GuiBehavior::BehaviorFunctor*)0L)
     delete _behavior_functor;
     delete _behavior_functor;
+  if (_rollover_functor != (GuiBehavior::BehaviorFunctor*)0L)
+    delete _behavior_functor;
 }
 }
 
 
 void GuiButton::manage(GuiManager* mgr, EventHandler& eh) {
 void GuiButton::manage(GuiManager* mgr, EventHandler& eh) {

+ 4 - 0
panda/src/gui/guiButton.h

@@ -37,6 +37,7 @@ private:
   bool _have_event_param;
   bool _have_event_param;
   int _event_param;
   int _event_param;
   GuiBehavior::BehaviorFunctor* _behavior_functor;
   GuiBehavior::BehaviorFunctor* _behavior_functor;
+  GuiBehavior::BehaviorFunctor* _rollover_functor;
 
 
   INLINE GuiButton(void);
   INLINE GuiButton(void);
   void switch_state(States);
   void switch_state(States);
@@ -96,6 +97,9 @@ PUBLISHED:
   INLINE void set_behavior_functor(GuiBehavior::BehaviorFunctor*);
   INLINE void set_behavior_functor(GuiBehavior::BehaviorFunctor*);
   INLINE GuiBehavior::BehaviorFunctor* get_behavior_functor(void) const;
   INLINE GuiBehavior::BehaviorFunctor* get_behavior_functor(void) const;
 
 
+  INLINE void set_rollover_functor(GuiBehavior::BehaviorFunctor*);
+  INLINE GuiBehavior::BehaviorFunctor* get_rollover_functor(void) const;
+
   INLINE void set_behavior_event_parameter(int);
   INLINE void set_behavior_event_parameter(int);
   INLINE int get_behavior_event_parameter(void) const;
   INLINE int get_behavior_event_parameter(void) const;
 
 

+ 2 - 0
panda/src/gui/guiChooser.cxx

@@ -20,6 +20,8 @@ void GuiChooser::ChooseFunctor::doit(GuiBehavior* b) {
     this->_ch->move_prev();
     this->_ch->move_prev();
   if ((b == this->_ch->_next_button) && this->_ch->_next_button->is_active())
   if ((b == this->_ch->_next_button) && this->_ch->_next_button->is_active())
     this->_ch->move_next();
     this->_ch->move_next();
+  if (_prev != (GuiBehavior::BehaviorFunctor*)0L)
+    _prev->doit(b);
 }
 }
 
 
 void GuiChooser::recompute_frame(void) {
 void GuiChooser::recompute_frame(void) {

+ 2 - 0
panda/src/gui/guiListBox.cxx

@@ -20,6 +20,8 @@ void GuiListBox::ListFunctor::doit(GuiBehavior* b) {
     this->_lb->scroll_up();
     this->_lb->scroll_up();
   if ((b == this->_lb->_down_arrow) && this->_lb->_down_arrow->is_active())
   if ((b == this->_lb->_down_arrow) && this->_lb->_down_arrow->is_active())
     this->_lb->scroll_down();
     this->_lb->scroll_down();
+  if (_prev != (GuiBehavior::BehaviorFunctor*)0L)
+    _prev->doit(b);
 }
 }
 
 
 void GuiListBox::recompute_frame(void) {
 void GuiListBox::recompute_frame(void) {