Browse Source

*** empty log message ***

David Rose 25 years ago
parent
commit
7785f82e1b

+ 2 - 0
direct/src/gui/Frame.py

@@ -72,6 +72,7 @@ class Frame:
         for itemNum in range(1, len(self.items)):
         for itemNum in range(1, len(self.items)):
             self.packItem(itemNum, GuiFrame.GuiFrame.UNDER, itemNum - 1)
             self.packItem(itemNum, GuiFrame.GuiFrame.UNDER, itemNum - 1)
             self.packItem(itemNum, GuiFrame.GuiFrame.ALIGNLEFT, itemNum - 1)
             self.packItem(itemNum, GuiFrame.GuiFrame.ALIGNLEFT, itemNum - 1)
+        self.frame.recompute()
             
             
     def makeHorizontal(self):
     def makeHorizontal(self):
         # remove any previous packing
         # remove any previous packing
@@ -80,6 +81,7 @@ class Frame:
         for itemNum in range(1, len(self.items)):
         for itemNum in range(1, len(self.items)):
             self.packItem(itemNum, GuiFrame.GuiFrame.RIGHT, itemNum - 1)
             self.packItem(itemNum, GuiFrame.GuiFrame.RIGHT, itemNum - 1)
             self.packItem(itemNum, GuiFrame.GuiFrame.ALIGNABOVE, itemNum - 1)
             self.packItem(itemNum, GuiFrame.GuiFrame.ALIGNABOVE, itemNum - 1)
+        self.frame.recompute()
             
             
     def makeWideAsWidest(self):
     def makeWideAsWidest(self):
         # make all the buttons as wide as the widest button in
         # make all the buttons as wide as the widest button in

+ 48 - 3
panda/src/gui/guiButton.cxx

@@ -15,6 +15,17 @@ static ButtonMap buttons;
 
 
 TypeHandle GuiButton::_type_handle;
 TypeHandle GuiButton::_type_handle;
 
 
+
+static GuiButton *
+find_in_buttons_map(const string &name) {
+  ButtonMap::const_iterator bi;
+  bi = buttons.find(name);
+  if (bi == buttons.end()) {
+    return (GuiButton *)NULL;
+  }
+  return (*bi).second;
+}
+
 inline void GetExtents(GuiLabel* v, GuiLabel* w, GuiLabel* x, GuiLabel* y,
 inline void GetExtents(GuiLabel* v, GuiLabel* w, GuiLabel* x, GuiLabel* y,
 		       GuiLabel* z, float& l, float& r, float& b, float& t) {
 		       GuiLabel* z, float& l, float& r, float& b, float& t) {
   float l1, l2, r1, r2, b1, b2, t1, t2;
   float l1, l2, r1, r2, b1, b2, t1, t2;
@@ -48,21 +59,46 @@ inline void GetExtents(GuiLabel* v, GuiLabel* w, GuiLabel* x, GuiLabel* y,
 }
 }
 
 
 static void enter_button(CPT_Event e) {
 static void enter_button(CPT_Event e) {
-  GuiButton* val = buttons[e->get_name()];
+  GuiButton* val = find_in_buttons_map(e->get_name());
+  if (val == (GuiButton *)NULL) {
+    if (gui_cat.is_debug()) {
+      gui_cat.debug()
+	<< "Ignoring event " << e->get_name() << " for deleted button\n";
+    }
+    return;
+  }
+  val->test_ref_count_integrity();
   val->enter();
   val->enter();
 }
 }
 
 
 static void exit_button(CPT_Event e) {
 static void exit_button(CPT_Event e) {
-  GuiButton* val = buttons[e->get_name()];
+  GuiButton* val = find_in_buttons_map(e->get_name());
+  if (val == (GuiButton *)NULL) {
+    if (gui_cat.is_debug()) {
+      gui_cat.debug()
+	<< "Ignoring event " << e->get_name() << " for deleted button\n";
+    }
+    return;
+  }
+  val->test_ref_count_integrity();
   val->exit();
   val->exit();
 }
 }
 
 
 static void click_button(CPT_Event e) {
 static void click_button(CPT_Event e) {
-  GuiButton* val = buttons[e->get_name()];
+  GuiButton* val = find_in_buttons_map(e->get_name());
+  if (val == (GuiButton *)NULL) {
+    if (gui_cat.is_debug()) {
+      gui_cat.debug()
+	<< "Ignoring event " << e->get_name() << " for deleted button\n";
+    }
+    return;
+  }
+  val->test_ref_count_integrity();
   val->click();
   val->click();
 }
 }
 
 
 void GuiButton::switch_state(GuiButton::States nstate) {
 void GuiButton::switch_state(GuiButton::States nstate) {
+  test_ref_count_integrity();
   // cleanup old state
   // cleanup old state
   switch (_state) {
   switch (_state) {
   case NONE:
   case NONE:
@@ -231,6 +267,15 @@ GuiButton::GuiButton(const string& name, GuiLabel* up, GuiLabel* up_roll,
 
 
 GuiButton::~GuiButton(void) {
 GuiButton::~GuiButton(void) {
   this->unmanage();
   this->unmanage();
+
+  // Remove the names from the buttons map, so we don't end up with
+  // an invalid pointer.
+  string name = get_name();
+  buttons.erase("gui-in-button-" + name);
+  buttons.erase("gui-out-button-" + name);
+  buttons.erase("gui-button-" + name + "-mouse1");
+  buttons.erase("gui-button-" + name + "-mouse2");
+  buttons.erase("gui-button-" + name + "-mouse3");
 }
 }
 
 
 void GuiButton::manage(GuiManager* mgr, EventHandler& eh) {
 void GuiButton::manage(GuiManager* mgr, EventHandler& eh) {

+ 3 - 0
panda/src/gui/guiItem.cxx

@@ -8,6 +8,7 @@
 TypeHandle GuiItem::_type_handle;
 TypeHandle GuiItem::_type_handle;
 
 
 void GuiItem::recompute_frame(void) {
 void GuiItem::recompute_frame(void) {
+  test_ref_count_integrity();
 }
 }
 
 
 GuiItem::GuiItem(const string& name) : Namable(name), _added_hooks(false),
 GuiItem::GuiItem(const string& name) : Namable(name), _added_hooks(false),
@@ -24,10 +25,12 @@ GuiItem::~GuiItem(void) {
 }
 }
 
 
 void GuiItem::manage(GuiManager* mgr, EventHandler&) {
 void GuiItem::manage(GuiManager* mgr, EventHandler&) {
+  test_ref_count_integrity();
   _mgr = mgr;
   _mgr = mgr;
 }
 }
 
 
 void GuiItem::unmanage(void) {
 void GuiItem::unmanage(void) {
+  test_ref_count_integrity();
   _mgr = (GuiManager*)0L;
   _mgr = (GuiManager*)0L;
 }
 }
 
 

+ 4 - 0
panda/src/gui/guiManager.cxx

@@ -118,6 +118,7 @@ GuiManager* GuiManager::get_ptr(GraphicsWindow* w, MouseAndKeyboard* mak) {
 }
 }
 
 
 void GuiManager::add_region(GuiRegion* region) {
 void GuiManager::add_region(GuiRegion* region) {
+  region->test_ref_count_integrity();
   RegionSet::const_iterator ri;
   RegionSet::const_iterator ri;
   ri = _regions.find(region);
   ri = _regions.find(region);
   if (ri == _regions.end()) {
   if (ri == _regions.end()) {
@@ -129,6 +130,7 @@ void GuiManager::add_region(GuiRegion* region) {
 }
 }
 
 
 void GuiManager::add_label(GuiLabel* label) {
 void GuiManager::add_label(GuiLabel* label) {
+  label->test_ref_count_integrity();
   LabelSet::const_iterator li;
   LabelSet::const_iterator li;
   li = _labels.find(label);
   li = _labels.find(label);
   if (li == _labels.end()) {
   if (li == _labels.end()) {
@@ -141,6 +143,7 @@ void GuiManager::add_label(GuiLabel* label) {
 }
 }
 
 
 void GuiManager::remove_region(GuiRegion* region) {
 void GuiManager::remove_region(GuiRegion* region) {
+  region->test_ref_count_integrity();
   RegionSet::iterator ri;
   RegionSet::iterator ri;
   ri = _regions.find(region);
   ri = _regions.find(region);
   if (ri == _regions.end())
   if (ri == _regions.end())
@@ -153,6 +156,7 @@ void GuiManager::remove_region(GuiRegion* region) {
 }
 }
 
 
 void GuiManager::remove_label(GuiLabel* label) {
 void GuiManager::remove_label(GuiLabel* label) {
+  label->test_ref_count_integrity();
   LabelSet::iterator li;
   LabelSet::iterator li;
   li = _labels.find(label);
   li = _labels.find(label);
   if (li == _labels.end())
   if (li == _labels.end())

+ 8 - 0
panda/src/gui/guiRegion.I

@@ -15,15 +15,21 @@ INLINE GuiRegion::GuiRegion(const string& name, float l, float r, float b,
 }
 }
 
 
 INLINE MouseWatcherRegion* GuiRegion::get_region(void) const {
 INLINE MouseWatcherRegion* GuiRegion::get_region(void) const {
+  test_ref_count_integrity();
+  _region->test_ref_count_integrity();
   return _region;
   return _region;
 }
 }
 
 
 INLINE void GuiRegion::trap_clicks(bool t) {
 INLINE void GuiRegion::trap_clicks(bool t) {
+  test_ref_count_integrity();
+  _region->test_ref_count_integrity();
   _region->set_suppress_below(t);
   _region->set_suppress_below(t);
 }
 }
 
 
 INLINE void GuiRegion::set_region(float left, float right, float bottom,
 INLINE void GuiRegion::set_region(float left, float right, float bottom,
 				  float top) {
 				  float top) {
+  test_ref_count_integrity();
+  _region->test_ref_count_integrity();
   _region->set_frame(left, right, bottom, top);
   _region->set_frame(left, right, bottom, top);
   _left = left;
   _left = left;
   _right = right;
   _right = right;
@@ -32,5 +38,7 @@ INLINE void GuiRegion::set_region(float left, float right, float bottom,
 }
 }
 
 
 INLINE LVector4f GuiRegion::get_frame(void) const {
 INLINE LVector4f GuiRegion::get_frame(void) const {
+  test_ref_count_integrity();
+  _region->test_ref_count_integrity();
   return LVector4f(_left, _right, _bottom, _top);
   return LVector4f(_left, _right, _bottom, _top);
 }
 }

+ 33 - 2
panda/src/gui/guiRollover.cxx

@@ -13,6 +13,17 @@ static RolloverMap rollovers;
 
 
 TypeHandle GuiRollover::_type_handle;
 TypeHandle GuiRollover::_type_handle;
 
 
+
+static GuiRollover *
+find_in_rollovers_map(const string &name) {
+  RolloverMap::const_iterator bi;
+  bi = rollovers.find(name);
+  if (bi == rollovers.end()) {
+    return (GuiRollover *)NULL;
+  }
+  return (*bi).second;
+}
+
 inline void GetExtents(GuiLabel* x, GuiLabel* y, float& l, float& r, float& b,
 inline void GetExtents(GuiLabel* x, GuiLabel* y, float& l, float& r, float& b,
 		       float& t) {
 		       float& t) {
   float l1, l2, r1, r2, b1, b2, t1, t2;
   float l1, l2, r1, r2, b1, b2, t1, t2;
@@ -25,12 +36,26 @@ inline void GetExtents(GuiLabel* x, GuiLabel* y, float& l, float& r, float& b,
 }
 }
 
 
 static void enter_rollover(CPT_Event e) {
 static void enter_rollover(CPT_Event e) {
-  GuiRollover* val = rollovers[e->get_name()];
+  GuiRollover* val = find_in_rollovers_map(e->get_name());
+  if (val == (GuiRollover *)NULL) {
+    if (gui_cat.is_debug()) {
+      gui_cat.debug()
+	<< "Ignoring event " << e->get_name() << " for deleted rollover\n";
+    }
+    return;
+  }
   val->enter();
   val->enter();
 }
 }
 
 
 static void exit_rollover(CPT_Event e) {
 static void exit_rollover(CPT_Event e) {
-  GuiRollover* val = rollovers[e->get_name()];
+  GuiRollover* val = find_in_rollovers_map(e->get_name());
+  if (val == (GuiRollover *)NULL) {
+    if (gui_cat.is_debug()) {
+      gui_cat.debug()
+	<< "Ignoring event " << e->get_name() << " for deleted rollover\n";
+    }
+    return;
+  }
   val->exit();
   val->exit();
 }
 }
 
 
@@ -54,6 +79,12 @@ GuiRollover::GuiRollover(const string& name, GuiLabel* off, GuiLabel* on)
 
 
 GuiRollover::~GuiRollover(void) {
 GuiRollover::~GuiRollover(void) {
   this->unmanage();
   this->unmanage();
+
+  // Remove the names from the rollovers map, so we don't end up with
+  // an invalid pointer.
+  string name = get_name();
+  rollovers.erase("gui-in-rollover-" + name);
+  rollovers.erase("gui-out-rollover-" + name);
 }
 }
 
 
 void GuiRollover::manage(GuiManager* mgr, EventHandler& eh) {
 void GuiRollover::manage(GuiManager* mgr, EventHandler& eh) {

+ 12 - 0
panda/src/tform/mouseWatcher.cxx

@@ -79,6 +79,12 @@ has_region(MouseWatcherRegion *region) const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 bool MouseWatcher::
 bool MouseWatcher::
 remove_region(MouseWatcherRegion *region) {
 remove_region(MouseWatcherRegion *region) {
+  if (region == _current_region) {
+    _current_region = (MouseWatcherRegion *)NULL;
+  }
+  if (region == _button_down_region) {
+    _button_down_region = (MouseWatcherRegion *)NULL;
+  }
   return _regions.erase(region) != 0;
   return _regions.erase(region) != 0;
 }
 }
 
 
@@ -151,6 +157,11 @@ write(ostream &out, int indent_level) const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void MouseWatcher::
 void MouseWatcher::
 set_current_region(MouseWatcherRegion *region) {
 set_current_region(MouseWatcherRegion *region) {
+#ifndef NDEBUG
+  if (region != (MouseWatcherRegion *)NULL) {
+    region->test_ref_count_integrity();
+  }
+#endif
   if (region != _current_region) {
   if (region != _current_region) {
     if (_current_region != (MouseWatcherRegion *)NULL) {
     if (_current_region != (MouseWatcherRegion *)NULL) {
       throw_event_pattern(_leave_pattern, _current_region);
       throw_event_pattern(_leave_pattern, _current_region);
@@ -171,6 +182,7 @@ set_current_region(MouseWatcherRegion *region) {
 void MouseWatcher::
 void MouseWatcher::
 throw_event_pattern(const string &pattern, const MouseWatcherRegion *region, 
 throw_event_pattern(const string &pattern, const MouseWatcherRegion *region, 
 		    const string &button_name) {
 		    const string &button_name) {
+  region->test_ref_count_integrity();
   if (pattern.empty()) {
   if (pattern.empty()) {
     return;
     return;
   }
   }