Przeglądaj źródła

I'm really just hoping this works right now

Cary Sandvig 25 lat temu
rodzic
commit
f08c6862f3

+ 19 - 0
panda/src/gui/guiBackground.cxx

@@ -67,6 +67,18 @@ void GuiBackground::manage(GuiManager* mgr, EventHandler& eh) {
 		       << ") thta is already managed" << endl;
 		       << ") thta is already managed" << endl;
 }
 }
 
 
+void GuiBackground::manage(GuiManager* mgr, EventHandler& eh, Node* n) {
+  if (!_added_hooks)
+    _added_hooks = true;
+  if (_mgr == (GuiManager*)0L) {
+    mgr->add_label(_bg, n);
+    _item->manage(mgr, eh, n);
+    GuiItem::manage(mgr, eh, n);
+  } else
+    gui_cat->warning() << "tried to manage background (0x" << (void*)this
+		       << ") thta is already managed" << endl;
+}
+
 void GuiBackground::unmanage(void) {
 void GuiBackground::unmanage(void) {
   if (_mgr != (GuiManager*)0L) {
   if (_mgr != (GuiManager*)0L) {
     _mgr->remove_label(_bg);
     _mgr->remove_label(_bg);
@@ -92,6 +104,13 @@ void GuiBackground::set_scale(float f) {
   recompute_frame();
   recompute_frame();
 }
 }
 
 
+void GuiBackground::set_scale(float x, float y, float z) {
+  _bg->set_scale(x, y, z);
+  _item->set_scale(x, y, z);
+  GuiItem::set_scale(x, y, z);
+  recompute_frame();
+}
+
 void GuiBackground::set_pos(const LVector3f& p) {
 void GuiBackground::set_pos(const LVector3f& p) {
   _bg->set_pos(p);
   _bg->set_pos(p);
   _item->set_pos(p);
   _item->set_pos(p);

+ 2 - 0
panda/src/gui/guiBackground.h

@@ -23,12 +23,14 @@ PUBLISHED:
   ~GuiBackground(void);
   ~GuiBackground(void);
 
 
   virtual void manage(GuiManager*, EventHandler&);
   virtual void manage(GuiManager*, EventHandler&);
+  virtual void manage(GuiManager*, EventHandler&, Node*);
   virtual void unmanage(void);
   virtual void unmanage(void);
 
 
   virtual int freeze(void);
   virtual int freeze(void);
   virtual int thaw(void);
   virtual int thaw(void);
 
 
   virtual void set_scale(float);
   virtual void set_scale(float);
+  virtual void set_scale(float, float, float);
   virtual void set_pos(const LVector3f&);
   virtual void set_pos(const LVector3f&);
   virtual void set_priority(GuiLabel*, const Priority);
   virtual void set_priority(GuiLabel*, const Priority);
   virtual void set_priority(GuiItem*, const Priority);
   virtual void set_priority(GuiItem*, const Priority);

+ 5 - 0
panda/src/gui/guiBehavior.cxx

@@ -29,6 +29,11 @@ void GuiBehavior::manage(GuiManager* mgr, EventHandler& eh) {
   GuiItem::manage(mgr, eh);
   GuiItem::manage(mgr, eh);
 }
 }
 
 
+void GuiBehavior::manage(GuiManager* mgr, EventHandler& eh, Node* n) {
+  _eh = &eh;
+  GuiItem::manage(mgr, eh, n);
+}
+
 void GuiBehavior::unmanage(void) {
 void GuiBehavior::unmanage(void) {
   if (_behavior_running)
   if (_behavior_running)
     this->stop_behavior();
     this->stop_behavior();

+ 1 - 0
panda/src/gui/guiBehavior.h

@@ -26,6 +26,7 @@ PUBLISHED:
   virtual ~GuiBehavior(void);
   virtual ~GuiBehavior(void);
 
 
   virtual void manage(GuiManager*, EventHandler&) = 0;
   virtual void manage(GuiManager*, EventHandler&) = 0;
+  virtual void manage(GuiManager*, EventHandler&, Node*) = 0;
   virtual void unmanage(void) = 0;
   virtual void unmanage(void) = 0;
 
 
   virtual void start_behavior(void) = 0;
   virtual void start_behavior(void) = 0;

+ 110 - 10
panda/src/gui/guiButton.cxx

@@ -155,7 +155,10 @@ void GuiButton::switch_state(GuiButton::States nstate) {
     _rgn->trap_clicks(false);
     _rgn->trap_clicks(false);
     break;
     break;
   case UP:
   case UP:
-    _mgr->add_label(_up);
+    if (_alt_root.is_null())
+      _mgr->add_label(_up);
+    else
+      _mgr->add_label(_up, _alt_root);
     if (!_up_event.empty()) {
     if (!_up_event.empty()) {
       gui_cat->debug() << "throwing _up_event '" << _up_event << "'" << endl;
       gui_cat->debug() << "throwing _up_event '" << _up_event << "'" << endl;
       throw_event(_up_event);
       throw_event(_up_event);
@@ -167,15 +170,21 @@ void GuiButton::switch_state(GuiButton::States nstate) {
     break;
     break;
   case UP_ROLLOVER:
   case UP_ROLLOVER:
     if (_up_rollover != (GuiLabel*)0L) {
     if (_up_rollover != (GuiLabel*)0L) {
-      _mgr->add_label(_up_rollover);
+      if (_alt_root.is_null())
+	_mgr->add_label(_up_rollover);
+      else
+	_mgr->add_label(_up_rollover, _alt_root);
       if (!_up_rollover_event.empty()) {
       if (!_up_rollover_event.empty()) {
-	gui_cat->debug() << "throwing _up_rollover_event '" << _up_rollover_event << "'"
-	     << endl;
+	gui_cat->debug() << "throwing _up_rollover_event '"
+			 << _up_rollover_event << "'" << endl;
 	throw_event(_up_rollover_event);
 	throw_event(_up_rollover_event);
       } else
       } else
 	gui_cat->debug() << "_up_rollover_event is empty!" << endl;
 	gui_cat->debug() << "_up_rollover_event is empty!" << endl;
     } else {
     } else {
-      _mgr->add_label(_up);
+      if (_alt_root.is_null())
+	_mgr->add_label(_up);
+      else
+	_mgr->add_label(_up, _alt_root);
       if (!_up_event.empty()) {
       if (!_up_event.empty()) {
 	gui_cat->debug() << "throwing _up_event '" << _up_event << "'" << endl;
 	gui_cat->debug() << "throwing _up_event '" << _up_event << "'" << endl;
 	throw_event(_up_event);
 	throw_event(_up_event);
@@ -188,7 +197,10 @@ void GuiButton::switch_state(GuiButton::States nstate) {
       _mgr->add_region(_rgn);
       _mgr->add_region(_rgn);
     break;
     break;
   case DOWN:
   case DOWN:
-    _mgr->add_label(_down);
+    if (_alt_root.is_null())
+      _mgr->add_label(_down);
+    else
+      _mgr->add_label(_down, _alt_root);
     if (!_down_event.empty())
     if (!_down_event.empty())
       throw_event(_down_event);
       throw_event(_down_event);
     else
     else
@@ -199,13 +211,19 @@ void GuiButton::switch_state(GuiButton::States nstate) {
     break;
     break;
   case DOWN_ROLLOVER:
   case DOWN_ROLLOVER:
     if (_down_rollover != (GuiLabel*)0L) {
     if (_down_rollover != (GuiLabel*)0L) {
-      _mgr->add_label(_down_rollover);
+      if (_alt_root.is_null())
+	_mgr->add_label(_down_rollover);
+      else
+	_mgr->add_label(_down_rollover, _alt_root);
       if (!_down_rollover_event.empty())
       if (!_down_rollover_event.empty())
 	throw_event(_down_rollover_event);
 	throw_event(_down_rollover_event);
       else
       else
 	gui_cat->debug() << "_down_rollover_event is empty!" << endl;
 	gui_cat->debug() << "_down_rollover_event is empty!" << endl;
     } else {
     } else {
-      _mgr->add_label(_down);
+      if (_alt_root.is_null())
+	_mgr->add_label(_down);
+      else
+	_mgr->add_label(_down, _alt_root);
       if (!_down_event.empty())
       if (!_down_event.empty())
 	throw_event(_down_event);
 	throw_event(_down_event);
       else
       else
@@ -218,7 +236,10 @@ void GuiButton::switch_state(GuiButton::States nstate) {
     break;
     break;
   case INACTIVE:
   case INACTIVE:
     if (_inactive != (GuiLabel*)0L) {
     if (_inactive != (GuiLabel*)0L) {
-      _mgr->add_label(_inactive);
+      if (_alt_root.is_null())
+	_mgr->add_label(_inactive);
+      else
+	_mgr->add_label(_inactive, _alt_root);
       if (!_inactive_event.empty())
       if (!_inactive_event.empty())
 	throw_event(_inactive_event);
 	throw_event(_inactive_event);
     }
     }
@@ -228,7 +249,10 @@ void GuiButton::switch_state(GuiButton::States nstate) {
     break;
     break;
   case INACTIVE_ROLLOVER:
   case INACTIVE_ROLLOVER:
     if (_inactive != (GuiLabel*)0L) {
     if (_inactive != (GuiLabel*)0L) {
-      _mgr->add_label(_inactive);
+      if (_alt_root.is_null())
+	_mgr->add_label(_inactive);
+      else
+	_mgr->add_label(_inactive, _alt_root);
       if (!_inactive_event.empty())
       if (!_inactive_event.empty())
 	throw_event(_inactive_event);
 	throw_event(_inactive_event);
     }
     }
@@ -255,6 +279,46 @@ void GuiButton::recompute_frame(void) {
     _inactive->recompute();
     _inactive->recompute();
   GetExtents(_up, _down, _up_rollover, _down_rollover, _inactive, _left,
   GetExtents(_up, _down, _up_rollover, _down_rollover, _inactive, _left,
 	     _right, _bottom, _top);
 	     _right, _bottom, _top);
+  if (_alt_root.is_null()) {
+    // adjust for graph transform
+    LVector3f sc = this->get_graph_scale();
+    LPoint3f p = this->get_graph_pos();
+    float x = sc.dot(LVector3f::rfu(1., 0., 0.));
+    _left *= x;
+    _right *= x;
+    float y = sc.dot(LVector3f::rfu(0., 0., 1.));
+    _bottom *= y;
+    _top *= y;
+    x = p.dot(LVector3f::rfu(1., 0., 0.));
+    _left += x;
+    _right += y;
+    y = p.dot(LVector3f::rfu(0., 0., 1.));
+    _bottom += y;
+    _top += y;
+  }
+  _rgn->set_region(_left, _right, _bottom, _top);
+}
+
+void GuiButton::adjust_region(void) {
+  GetExtents(_up, _down, _up_rollover, _down_rollover, _inactive, _left,
+	     _right, _bottom, _top);
+  if (_alt_root.is_null()) {
+    // adjust for graph transform
+    LVector3f sc = this->get_graph_scale();
+    LPoint3f p = this->get_graph_pos();
+    float x = sc.dot(LVector3f::rfu(1., 0., 0.));
+    _left *= x;
+    _right *= x;
+    float y = sc.dot(LVector3f::rfu(0., 0., 1.));
+    _bottom *= y;
+    _top *= y;
+    x = p.dot(LVector3f::rfu(1., 0., 0.));
+    _left += x;
+    _right += y;
+    y = p.dot(LVector3f::rfu(0., 0., 1.));
+    _bottom += y;
+    _top += y;
+  }
   _rgn->set_region(_left, _right, _bottom, _top);
   _rgn->set_region(_left, _right, _bottom, _top);
 }
 }
 
 
@@ -421,6 +485,29 @@ void GuiButton::manage(GuiManager* mgr, EventHandler& eh) {
 		       << ") that is already managed" << endl;
 		       << ") that is already managed" << endl;
 }
 }
 
 
+void GuiButton::manage(GuiManager* mgr, EventHandler& eh, Node* n) {
+  if (!_added_hooks) {
+    eh.add_hook("gui-in-button-" + get_name(), enter_button);
+    eh.add_hook("gui-out-button-" + get_name(), exit_button);
+    eh.add_hook("gui-button-" + get_name() + "-mouse1", click_button_down);
+    eh.add_hook("gui-button-" + get_name() + "-mouse2", click_button_down);
+    eh.add_hook("gui-button-" + get_name() + "-mouse3", click_button_down);
+    eh.add_hook("gui-button-" + get_name() + "-mouse1-up", click_button_up);
+    eh.add_hook("gui-button-" + get_name() + "-mouse2-up", click_button_up);
+    eh.add_hook("gui-button-" + get_name() + "-mouse3-up", click_button_up);
+    _added_hooks = true;
+  }
+  if (_mgr == (GuiManager*)0L) {
+    mgr->add_region(_rgn);
+    GuiBehavior::manage(mgr, eh, n);
+    if (_behavior_running)
+      this->start_behavior();
+    switch_state(UP);
+  } else
+    gui_cat->warning() << "tried to manage button (0x" << (void*)this
+		       << ") that is already managed" << endl;
+}
+
 void GuiButton::unmanage(void) {
 void GuiButton::unmanage(void) {
   if (_mgr != (GuiManager*)0L)
   if (_mgr != (GuiManager*)0L)
     _mgr->remove_region(_rgn);
     _mgr->remove_region(_rgn);
@@ -469,6 +556,19 @@ void GuiButton::set_scale(float f) {
   this->recompute_frame();
   this->recompute_frame();
 }
 }
 
 
+void GuiButton::set_scale(float x, float y, float z) {
+  _up->set_scale(x, y, z);
+  _down->set_scale(x, y, z);
+  if (_up_rollover != (GuiLabel*)0L)
+    _up_rollover->set_scale(x, y, z);
+  if (_down_rollover != (GuiLabel*)0L)
+    _down_rollover->set_scale(x, y, z);
+  if (_inactive != (GuiLabel*)0L)
+    _inactive->set_scale(x, y, z);
+  GuiBehavior::set_scale(x, y, z);
+  this->recompute_frame();
+}
+
 void GuiButton::set_pos(const LVector3f& p) {
 void GuiButton::set_pos(const LVector3f& p) {
   _up->set_pos(p);
   _up->set_pos(p);
   _down->set_pos(p);
   _down->set_pos(p);

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

@@ -38,6 +38,7 @@ private:
   INLINE GuiButton(void);
   INLINE GuiButton(void);
   void switch_state(States);
   void switch_state(States);
   virtual void recompute_frame(void);
   virtual void recompute_frame(void);
+  virtual void adjust_region(void);
 
 
   static void behavior_up(CPT_Event, void*);
   static void behavior_up(CPT_Event, void*);
   static void behavior_down(CPT_Event, void*);
   static void behavior_down(CPT_Event, void*);
@@ -52,6 +53,7 @@ PUBLISHED:
 
 
 public:
 public:
   virtual void manage(GuiManager*, EventHandler&);
   virtual void manage(GuiManager*, EventHandler&);
+  virtual void manage(GuiManager*, EventHandler&, Node*);
   virtual void unmanage(void);
   virtual void unmanage(void);
 
 
 PUBLISHED:
 PUBLISHED:
@@ -90,6 +92,7 @@ PUBLISHED:
   INLINE GuiBehavior::BehaviorFunctor* get_behavior_functor(void) const;
   INLINE GuiBehavior::BehaviorFunctor* get_behavior_functor(void) const;
 
 
   virtual void set_scale(float);
   virtual void set_scale(float);
+  virtual void set_scale(float, float, float);
   virtual void set_pos(const LVector3f&);
   virtual void set_pos(const LVector3f&);
   virtual void set_priority(GuiLabel*, const Priority);
   virtual void set_priority(GuiLabel*, const Priority);
   virtual void set_priority(GuiItem*, const Priority);
   virtual void set_priority(GuiItem*, const Priority);

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

@@ -91,7 +91,10 @@ void GuiChooser::move_prev(void) {
   }
   }
   if (_mgr != (GuiManager*)0L) {
   if (_mgr != (GuiManager*)0L) {
     _items[_curr]->unmanage();
     _items[_curr]->unmanage();
-    _items[tmp]->manage(_mgr, *_eh);
+    if (_alt_root.is_null())
+      _items[tmp]->manage(_mgr, *_eh);
+    else
+      _items[tmp]->manage(_mgr, *_eh, _alt_root);
     if (tmp == 0) {
     if (tmp == 0) {
       _prev_button->exit();
       _prev_button->exit();
       _prev_button->inactive();
       _prev_button->inactive();
@@ -132,7 +135,10 @@ void GuiChooser::move_next(void) {
   }
   }
   if (_mgr != (GuiManager*)0L) {
   if (_mgr != (GuiManager*)0L) {
     _items[_curr]->unmanage();
     _items[_curr]->unmanage();
-    _items[tmp]->manage(_mgr, *_eh);
+    if (_alt_root.is_null())
+      _items[tmp]->manage(_mgr, *_eh);
+    else
+      _items[tmp]->manage(_mgr, *_eh, _alt_root);
     if (tmp == 0) {
     if (tmp == 0) {
       _prev_button->exit();
       _prev_button->exit();
       _prev_button->inactive();
       _prev_button->inactive();
@@ -212,6 +218,27 @@ void GuiChooser::manage(GuiManager* mgr, EventHandler& eh) {
 		       << ") that is already managed" << endl;
 		       << ") that is already managed" << endl;
 }
 }
 
 
+void GuiChooser::manage(GuiManager* mgr, EventHandler& eh, Node* n) {
+  if (_mgr == (GuiManager*)0L) {
+    _prev_button->manage(mgr, eh, n);
+    _next_button->manage(mgr, eh, n);
+    if (_curr != -1) {
+      _items[_curr]->manage(mgr, eh, n);
+      if (_curr == 0)
+	_prev_button->inactive();
+      int foo = _items.size() - 1;
+      if (_curr == foo)
+	_next_button->inactive();
+    } else {
+      _prev_button->inactive();
+      _next_button->inactive();
+    }
+    GuiBehavior::manage(mgr, eh, n);
+  } else
+    gui_cat->warning() << "tried to manage chooser (0x" << (void*)this
+		       << ") that is already managed" << endl;
+}
+
 void GuiChooser::unmanage(void) {
 void GuiChooser::unmanage(void) {
   _prev_button->unmanage();
   _prev_button->unmanage();
   _next_button->unmanage();
   _next_button->unmanage();
@@ -224,6 +251,10 @@ void GuiChooser::set_scale(float f) {
   GuiBehavior::set_scale(f);
   GuiBehavior::set_scale(f);
 }
 }
 
 
+void GuiChooser::set_scale(float x, float y, float z) {
+  GuiBehavior::set_scale(x, y, z);
+}
+
 void GuiChooser::set_pos(const LVector3f& p) {
 void GuiChooser::set_pos(const LVector3f& p) {
   GuiBehavior::set_pos(p);
   GuiBehavior::set_pos(p);
 }
 }

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

@@ -55,9 +55,11 @@ PUBLISHED:
   virtual int thaw(void);
   virtual int thaw(void);
 
 
   virtual void manage(GuiManager*, EventHandler&);
   virtual void manage(GuiManager*, EventHandler&);
+  virtual void manage(GuiManager*, EventHandler&, Node*);
   virtual void unmanage(void);
   virtual void unmanage(void);
 
 
   virtual void set_scale(float);
   virtual void set_scale(float);
+  virtual void set_scale(float, float, float);
   virtual void set_pos(const LVector3f&);
   virtual void set_pos(const LVector3f&);
   virtual void set_priority(GuiLabel*, const Priority);
   virtual void set_priority(GuiLabel*, const Priority);
   virtual void set_priority(GuiItem*, const Priority);
   virtual void set_priority(GuiItem*, const Priority);

+ 21 - 0
panda/src/gui/guiCollection.cxx

@@ -84,6 +84,18 @@ void GuiCollection::manage(GuiManager* mgr, EventHandler& eh) {
 		       << ") that is already managed" << endl;
 		       << ") that is already managed" << endl;
 }
 }
 
 
+void GuiCollection::manage(GuiManager* mgr, EventHandler& eh, Node* n) {
+  if (!_added_hooks)
+    _added_hooks = true;
+  if (_mgr == (GuiManager*)0L) {
+    for (Items::iterator i=_items.begin(); i!=_items.end(); ++i)
+      (*i)->manage(mgr, eh, n);
+    GuiItem::manage(mgr, eh, n);
+  } else
+    gui_cat->warning() << "tried to manage collection (0x" << (void*)this
+		       << ") that is already managed" << endl;
+}
+
 void GuiCollection::unmanage(void) {
 void GuiCollection::unmanage(void) {
   for (Items::iterator i=_items.begin(); i!=_items.end(); ++i)
   for (Items::iterator i=_items.begin(); i!=_items.end(); ++i)
     (*i)->unmanage();
     (*i)->unmanage();
@@ -97,6 +109,15 @@ void GuiCollection::set_scale(float f) {
   this->recompute_frame();
   this->recompute_frame();
 }
 }
 
 
+void GuiCollection::set_scale(float x, float y, float z) {
+  for (Items::iterator i=_items.begin(); i!=_items.end(); ++i)
+    (*i)->set_scale(x * (*i)->get_scale_x(),
+		    y * (*i)->get_scale_y(),
+		    z * (*i)->get_scale_z());
+  GuiItem::set_scale(x, y, z);
+  this->recompute_frame();
+}
+
 void GuiCollection::set_pos(const LVector3f& p) {
 void GuiCollection::set_pos(const LVector3f& p) {
   LVector3f delta = p - this->get_pos();
   LVector3f delta = p - this->get_pos();
   for (Items::iterator i=_items.begin(); i!=_items.end(); ++i)
   for (Items::iterator i=_items.begin(); i!=_items.end(); ++i)

+ 2 - 0
panda/src/gui/guiCollection.h

@@ -29,9 +29,11 @@ PUBLISHED:
   void remove_item(GuiItem*);
   void remove_item(GuiItem*);
 
 
   virtual void manage(GuiManager*, EventHandler&);
   virtual void manage(GuiManager*, EventHandler&);
+  virtual void manage(GuiManager*, EventHandler&, Node*);
   virtual void unmanage(void);
   virtual void unmanage(void);
 
 
   virtual void set_scale(float);
   virtual void set_scale(float);
+  virtual void set_scale(float, float, float);
   virtual void set_pos(const LVector3f&);
   virtual void set_pos(const LVector3f&);
   virtual void set_priority(GuiLabel*, const Priority);
   virtual void set_priority(GuiLabel*, const Priority);
   virtual void set_priority(GuiItem*, const Priority);
   virtual void set_priority(GuiItem*, const Priority);

+ 21 - 0
panda/src/gui/guiFrame.cxx

@@ -332,6 +332,19 @@ void GuiFrame::manage(GuiManager* mgr, EventHandler& eh) {
 		       << ") that is already managed" << endl;
 		       << ") that is already managed" << endl;
 }
 }
 
 
+void GuiFrame::manage(GuiManager* mgr, EventHandler& eh, Node* n) {
+  if (!_added_hooks) {
+    _added_hooks = true;
+  }
+  if (_mgr == (GuiManager*)0L) {
+    for (Boxes::iterator i=_items.begin(); i!=_items.end(); ++i)
+      (*i).get_item()->manage(mgr, eh, n);
+    GuiItem::manage(mgr, eh, n);
+  } else
+    gui_cat->warning() << "tried to manage frame (0x" << (void*)this
+		       << ") that is already managed" << endl;
+}
+
 void GuiFrame::unmanage(void) {
 void GuiFrame::unmanage(void) {
   for (Boxes::iterator i=_items.begin(); i!=_items.end(); ++i)
   for (Boxes::iterator i=_items.begin(); i!=_items.end(); ++i)
     (*i).get_item()->unmanage();
     (*i).get_item()->unmanage();
@@ -345,6 +358,14 @@ void GuiFrame::set_scale(float f) {
   //  this->recompute_frame();
   //  this->recompute_frame();
 }
 }
 
 
+void GuiFrame::set_scale(float x, float y, float z) {
+  for (Boxes::iterator i=_items.begin(); i!=_items.end(); ++i)
+    (*i).get_item()->set_scale(x * (*i).get_item()->get_scale_x(),
+			       y * (*i).get_item()->get_scale_y(),
+			       z * (*i).get_item()->get_scale_z());
+  GuiItem::set_scale(x, y, z);
+}
+
 void GuiFrame::set_pos(const LVector3f& p) {
 void GuiFrame::set_pos(const LVector3f& p) {
   for (Boxes::iterator i=_items.begin(); i!=_items.end(); ++i)
   for (Boxes::iterator i=_items.begin(); i!=_items.end(); ++i)
     (*i).get_item()->set_pos(p);
     (*i).get_item()->set_pos(p);

+ 2 - 0
panda/src/gui/guiFrame.h

@@ -115,9 +115,11 @@ PUBLISHED:
   INLINE void align_to_bottom(float = 0.);
   INLINE void align_to_bottom(float = 0.);
 
 
   virtual void manage(GuiManager*, EventHandler&);
   virtual void manage(GuiManager*, EventHandler&);
+  virtual void manage(GuiManager*, EventHandler&, Node*);
   virtual void unmanage(void);
   virtual void unmanage(void);
 
 
   virtual void set_scale(float);
   virtual void set_scale(float);
+  virtual void set_scale(float, float, float);
   virtual void set_pos(const LVector3f&);
   virtual void set_pos(const LVector3f&);
   virtual void set_priority(GuiLabel*, const Priority);
   virtual void set_priority(GuiLabel*, const Priority);
   virtual void set_priority(GuiItem*, const Priority);
   virtual void set_priority(GuiItem*, const Priority);

+ 32 - 2
panda/src/gui/guiItem.I

@@ -3,13 +3,43 @@
 // 
 // 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 
 
-INLINE GuiItem::GuiItem(void) : Namable("fubar"), _left(-1.), _right(1.),
-				_bottom(-1.), _top(1.), _pri(P_Normal) {}
+INLINE GuiItem::GuiItem(void) : Namable("fubar"), _scale(1.), _scale_x(1.),
+				_scale_y(1.), _scale_z(1.), _left(-1.),
+				_right(1.), _bottom(-1.), _top(1.),
+				_pri(P_Normal) {}
+
+#include <get_rel_pos.h>
+
+INLINE LVector3f GuiItem::get_graph_scale(void) {
+  if (_alt_root.is_null())
+    return LVector3f(1., 1., 1.);
+  // pass NULL for the 'to' to go to root
+  return get_rel_scale(_alt_root, (Node*)0L);
+}
+
+INLINE LPoint3f GuiItem::get_graph_pos(void) {
+  if (_alt_root.is_null())
+    return LPoint3f(0., 0., 0.);
+  // pass NULL for the 'to' to go to root
+  return get_rel_pos(_alt_root, (Node*)0L);
+}
 
 
 INLINE float GuiItem::get_scale(void) const {
 INLINE float GuiItem::get_scale(void) const {
   return _scale;
   return _scale;
 }
 }
 
 
+INLINE float GuiItem::get_scale_x(void) const {
+  return _scale_x;
+}
+
+INLINE float GuiItem::get_scale_y(void) const {
+  return _scale_y;
+}
+
+INLINE float GuiItem::get_scale_z(void) const {
+  return _scale_z;
+}
+
 INLINE LVector3f GuiItem::get_pos(void) const {
 INLINE LVector3f GuiItem::get_pos(void) const {
   return _pos;
   return _pos;
 }
 }

+ 20 - 1
panda/src/gui/guiItem.cxx

@@ -11,11 +11,16 @@ void GuiItem::recompute_frame(void) {
   test_ref_count_integrity();
   test_ref_count_integrity();
 }
 }
 
 
+void GuiItem::adjust_region(void) {
+  test_ref_count_integrity();
+}
+
 void GuiItem::set_priority(GuiLabel*, const GuiItem::Priority) {
 void GuiItem::set_priority(GuiLabel*, const GuiItem::Priority) {
 }
 }
 
 
 GuiItem::GuiItem(const string& name) : Namable(name), _added_hooks(false),
 GuiItem::GuiItem(const string& name) : Namable(name), _added_hooks(false),
-				       _scale(1.), _left(-1.), _right(1.),
+				       _scale(1.), _scale_x(1.), _scale_y(1.),
+				       _scale_z(1.), _left(-1.), _right(1.),
 				       _bottom(-1.), _top(1.),
 				       _bottom(-1.), _top(1.),
 				       _pos(0., 0., 0.),
 				       _pos(0., 0., 0.),
 				       _mgr((GuiManager*)0L), _pri(P_Normal) {
 				       _mgr((GuiManager*)0L), _pri(P_Normal) {
@@ -39,6 +44,14 @@ int GuiItem::thaw() {
 void GuiItem::manage(GuiManager* mgr, EventHandler&) {
 void GuiItem::manage(GuiManager* mgr, EventHandler&) {
   test_ref_count_integrity();
   test_ref_count_integrity();
   _mgr = mgr;
   _mgr = mgr;
+  _alt_root.clear();
+}
+
+void GuiItem::manage(GuiManager* mgr, EventHandler&, Node* n) {
+  test_ref_count_integrity();
+  _mgr = mgr;
+  _alt_root = n;
+  this->adjust_region();
 }
 }
 
 
 void GuiItem::unmanage(void) {
 void GuiItem::unmanage(void) {
@@ -50,6 +63,12 @@ void GuiItem::set_scale(float f) {
   _scale = f;
   _scale = f;
 }
 }
 
 
+void GuiItem::set_scale(float x, float y, float z) {
+  _scale_x = x;
+  _scale_y = y;
+  _scale_z = z;
+}
+
 void GuiItem::set_pos(const LVector3f& p) {
 void GuiItem::set_pos(const LVector3f& p) {
   _pos = p;
   _pos = p;
 }
 }

+ 11 - 1
panda/src/gui/guiItem.h

@@ -16,30 +16,40 @@ PUBLISHED:
 
 
 protected:
 protected:
   bool _added_hooks;
   bool _added_hooks;
-  float _scale, _left, _right, _bottom, _top;
+  float _scale, _scale_x, _scale_y, _scale_z, _left, _right, _bottom, _top;
   LVector3f _pos;
   LVector3f _pos;
   GuiManager* _mgr;
   GuiManager* _mgr;
   Priority _pri;
   Priority _pri;
+  PT_Node _alt_root;
 
 
   INLINE GuiItem(void);
   INLINE GuiItem(void);
   virtual void recompute_frame(void) = 0;
   virtual void recompute_frame(void) = 0;
+  virtual void adjust_region(void);
+
+  INLINE LVector3f get_graph_scale(void);
+  INLINE LPoint3f get_graph_pos(void);
 
 
 PUBLISHED:
 PUBLISHED:
   GuiItem(const string&);
   GuiItem(const string&);
   virtual ~GuiItem(void);
   virtual ~GuiItem(void);
 
 
   virtual void manage(GuiManager*, EventHandler&) = 0;
   virtual void manage(GuiManager*, EventHandler&) = 0;
+  virtual void manage(GuiManager*, EventHandler&, Node*) = 0;
   virtual void unmanage(void) = 0;
   virtual void unmanage(void) = 0;
 
 
   virtual int freeze();
   virtual int freeze();
   virtual int thaw();
   virtual int thaw();
 
 
   virtual void set_scale(float) = 0;
   virtual void set_scale(float) = 0;
+  virtual void set_scale(float, float, float) = 0;
   virtual void set_pos(const LVector3f&) = 0;
   virtual void set_pos(const LVector3f&) = 0;
   virtual void set_priority(GuiLabel*, const Priority) = 0;
   virtual void set_priority(GuiLabel*, const Priority) = 0;
   virtual void set_priority(GuiItem*, const Priority) = 0;
   virtual void set_priority(GuiItem*, const Priority) = 0;
 
 
   INLINE float get_scale(void) const;
   INLINE float get_scale(void) const;
+  INLINE float get_scale_x(void) const;
+  INLINE float get_scale_y(void) const;
+  INLINE float get_scale_z(void) const;
   INLINE LVector3f get_pos(void) const;
   INLINE LVector3f get_pos(void) const;
   INLINE float get_left(void) const;
   INLINE float get_left(void) const;
   INLINE float get_right(void) const;
   INLINE float get_right(void) const;

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

@@ -9,6 +9,7 @@ INLINE GuiLabel::GuiLabel(void) : _type(GuiLabel::NONE),
 				  _internal((RenderRelation*)0L),
 				  _internal((RenderRelation*)0L),
 				  _gset((Geom*)0L), _model_width(1.),
 				  _gset((Geom*)0L), _model_width(1.),
 				  _model_height(1.), _scale(1.),
 				  _model_height(1.), _scale(1.),
+				  _scale_x(1.), _scale_y(1.), _scale_z(1.),
 				  _pos(0., 0., 0.),
 				  _pos(0., 0., 0.),
 				  _foreground(1., 1., 1., 1.),
 				  _foreground(1., 1., 1., 1.),
 				  _have_background(false),
 				  _have_background(false),
@@ -65,6 +66,13 @@ INLINE void GuiLabel::set_scale(float f) {
   recompute_transform();
   recompute_transform();
 }
 }
 
 
+INLINE void GuiLabel::set_scale(float x, float y, float z) {
+  _scale_x = x;
+  _scale_y = y;
+  _scale_z = z;
+  recompute_transform();
+}
+
 INLINE void GuiLabel::set_mirror_x(bool b) {
 INLINE void GuiLabel::set_mirror_x(bool b) {
   _mirror_x = b;
   _mirror_x = b;
 }
 }

+ 12 - 4
panda/src/gui/guiLabel.cxx

@@ -15,7 +15,9 @@ void GuiLabel::recompute_transform(void) {
   switch (_type) {
   switch (_type) {
   case SIMPLE_TEXT:
   case SIMPLE_TEXT:
     {
     {
-      LMatrix4f mat = LMatrix4f::scale_mat(_scale) *
+      LMatrix4f mat = LMatrix4f::scale_mat(LVector3f::rfu(_scale_x, _scale_y,
+							  _scale_z)) *
+	LMatrix4f::scale_mat(_scale) *
 	LMatrix4f::scale_mat(LVector3f::rfu((_mirror_x?-1.:1.), 1.,
 	LMatrix4f::scale_mat(LVector3f::rfu((_mirror_x?-1.:1.), 1.,
 					    (_mirror_y?-1.:1.))) *
 					    (_mirror_y?-1.:1.))) *
 	LMatrix4f::translate_mat(_pos);
 	LMatrix4f::translate_mat(_pos);
@@ -27,7 +29,9 @@ void GuiLabel::recompute_transform(void) {
   case SIMPLE_CARD:
   case SIMPLE_CARD:
   case L_NULL:
   case L_NULL:
     {
     {
-      LMatrix4f mat = LMatrix4f::scale_mat(_scale) *
+      LMatrix4f mat = LMatrix4f::scale_mat(LVector3f::rfu(_scale_x, _scale_y,
+							  _scale_z)) *
+	LMatrix4f::scale_mat(_scale) *
 	LMatrix4f::scale_mat(LVector3f::rfu((_mirror_x?-1.:1.), 1.,
 	LMatrix4f::scale_mat(LVector3f::rfu((_mirror_x?-1.:1.), 1.,
 					    (_mirror_y?-1.:1.))) *
 					    (_mirror_y?-1.:1.))) *
 	LMatrix4f::translate_mat(_pos);
 	LMatrix4f::translate_mat(_pos);
@@ -38,7 +42,9 @@ void GuiLabel::recompute_transform(void) {
     {
     {
       float w=_have_width?_scale*_width:_scale;
       float w=_have_width?_scale*_width:_scale;
       float h=_have_height?_scale*_height:_scale;
       float h=_have_height?_scale*_height:_scale;
-      LMatrix4f mat = LMatrix4f::scale_mat(LVector3f::rfu(w, 1., h)) *
+      LMatrix4f mat = LMatrix4f::scale_mat(LVector3f::rfu(_scale_x, _scale_y,
+							  _scale_z)) *
+	LMatrix4f::scale_mat(LVector3f::rfu(w, 1., h)) *
 	LMatrix4f::scale_mat(LVector3f::rfu((_mirror_x?-1.:1.), 1.,
 	LMatrix4f::scale_mat(LVector3f::rfu((_mirror_x?-1.:1.), 1.,
 					    (_mirror_y?-1.:1.))) *
 					    (_mirror_y?-1.:1.))) *
 	LMatrix4f::translate_mat(_pos);
 	LMatrix4f::translate_mat(_pos);
@@ -334,7 +340,9 @@ void GuiLabel::get_extents(float& l, float& r, float& b, float& t) {
 	ul = LVector3f::rfu(-ratio, 0., 0.5);
 	ul = LVector3f::rfu(-ratio, 0., 0.5);
 	lr = LVector3f::rfu(ratio, 0., -0.5);
 	lr = LVector3f::rfu(ratio, 0., -0.5);
       }
       }
-      LMatrix4f mat = LMatrix4f::scale_mat(_scale) *
+      LMatrix4f mat = LMatrix4f::scale_mat(LVector3f::rfu(_scale_x, _scale_y,
+							  _scale_z)) *
+	LMatrix4f::scale_mat(_scale) *
 	LMatrix4f::translate_mat(_pos);
 	LMatrix4f::translate_mat(_pos);
       ul = mat * ul;
       ul = mat * ul;
       lr = mat * lr;
       lr = mat * lr;

+ 2 - 0
panda/src/gui/guiLabel.h

@@ -36,6 +36,7 @@ private:
   float _model_width, _model_height;
   float _model_width, _model_height;
 
 
   float _scale;
   float _scale;
+  float _scale_x, _scale_y, _scale_z;
   LVector3f _pos;
   LVector3f _pos;
   Colorf _foreground;
   Colorf _foreground;
   bool _have_background;
   bool _have_background;
@@ -83,6 +84,7 @@ PUBLISHED:
   INLINE void set_height(float);
   INLINE void set_height(float);
 
 
   INLINE void set_scale(float);
   INLINE void set_scale(float);
+  INLINE void set_scale(float, float, float);
   INLINE void set_mirror_x(bool);
   INLINE void set_mirror_x(bool);
   INLINE void set_mirror_y(bool);
   INLINE void set_mirror_y(bool);
   INLINE void set_pos(float, float, float);
   INLINE void set_pos(float, float, float);

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

@@ -325,6 +325,17 @@ void GuiListBox::manage(GuiManager* mgr, EventHandler& eh) {
 		       << ") that is already managed" << endl;
 		       << ") that is already managed" << endl;
 }
 }
 
 
+void GuiListBox::manage(GuiManager* mgr, EventHandler& eh, Node* n) {
+  if (_mgr == (GuiManager*)0L) {
+    this->recompute_frame();
+    for (ItemVector::iterator i=_visible.begin(); i!=_visible.end(); ++i)
+      (*i)->manage(mgr, eh, n);
+    GuiBehavior::manage(mgr, eh, n);
+  } else
+    gui_cat->warning() << "tried to manage listbox (0x" << (void*)this
+		       << ") that is already managed" << endl;
+}
+
 void GuiListBox::unmanage(void) {
 void GuiListBox::unmanage(void) {
   for (ItemVector::iterator i=_visible.begin(); i!=_visible.end(); ++i)
   for (ItemVector::iterator i=_visible.begin(); i!=_visible.end(); ++i)
     (*i)->unmanage();
     (*i)->unmanage();
@@ -343,6 +354,18 @@ void GuiListBox::set_scale(float f) {
   GuiBehavior::set_scale(f);
   GuiBehavior::set_scale(f);
 }
 }
 
 
+void GuiListBox::set_scale(float x, float y, float z) {
+  ItemVector::iterator i;
+  for (i=_top_stack.begin(); i!=_top_stack.end(); ++i)
+    (*i)->set_scale(x, y, z);
+  for (i=_visible.begin(); i!=_visible.end(); ++i)
+    (*i)->set_scale(x, y, z);
+  for (ItemDeque::iterator j=_bottom_stack.begin(); j!=_bottom_stack.end();
+       ++j)
+    (*j)->set_scale(x, y, z);
+  GuiBehavior::set_scale(x, y, z);
+}
+
 void GuiListBox::set_pos(const LVector3f& p) {
 void GuiListBox::set_pos(const LVector3f& p) {
   ItemVector::iterator i;
   ItemVector::iterator i;
   for (i=_top_stack.begin(); i!=_top_stack.end(); ++i)
   for (i=_top_stack.begin(); i!=_top_stack.end(); ++i)

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

@@ -56,9 +56,11 @@ PUBLISHED:
   virtual int thaw(void);
   virtual int thaw(void);
 
 
   virtual void manage(GuiManager*, EventHandler&);
   virtual void manage(GuiManager*, EventHandler&);
+  virtual void manage(GuiManager*, EventHandler&, Node*);
   virtual void unmanage(void);
   virtual void unmanage(void);
 
 
   virtual void set_scale(float);
   virtual void set_scale(float);
+  virtual void set_scale(float, float, float);
   virtual void set_pos(const LVector3f&);
   virtual void set_pos(const LVector3f&);
   virtual void set_priority(GuiLabel*, const Priority);
   virtual void set_priority(GuiLabel*, const Priority);
   virtual void set_priority(GuiItem*, const Priority);
   virtual void set_priority(GuiItem*, const Priority);

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

@@ -149,6 +149,19 @@ void GuiManager::add_label(GuiLabel* label) {
 		       << ") more then once" << endl;
 		       << ") more then once" << endl;
 }
 }
 
 
+void GuiManager::add_label(GuiLabel* label, Node* parent) {
+  label->test_ref_count_integrity();
+  LabelSet::const_iterator li;
+  li = _labels.find(label);
+  if (li == _labels.end()) {
+    // add it to the scenegraph
+    label->set_arc(new RenderRelation(parent, label->get_geometry()));
+    _labels.insert(label);
+  } else
+    gui_cat->warning() << "tried adding label (0x" << (void*)label
+		       << ") more then once" << endl;
+}
+
 void GuiManager::remove_region(GuiRegion* region) {
 void GuiManager::remove_region(GuiRegion* region) {
   region->test_ref_count_integrity();
   region->test_ref_count_integrity();
   RegionSet::iterator ri;
   RegionSet::iterator ri;

+ 1 - 0
panda/src/gui/guiManager.h

@@ -45,6 +45,7 @@ PUBLISHED:
 
 
   void add_region(GuiRegion*);
   void add_region(GuiRegion*);
   void add_label(GuiLabel*);
   void add_label(GuiLabel*);
+  void add_label(GuiLabel*, Node*);
 
 
   void remove_region(GuiRegion*);
   void remove_region(GuiRegion*);
   void remove_label(GuiLabel*);
   void remove_label(GuiLabel*);

+ 8 - 2
panda/src/gui/guiRollover.I

@@ -13,7 +13,10 @@ INLINE void GuiRollover::enter(void) {
 		       << "' more then once without exit" << endl;
 		       << "' more then once without exit" << endl;
   } else if (_mgr != (GuiManager*)0L) {
   } else if (_mgr != (GuiManager*)0L) {
     _mgr->remove_label(_off);
     _mgr->remove_label(_off);
-    _mgr->add_label(_on);
+    if (_alt_root.is_null())
+      _mgr->add_label(_on);
+    else
+      _mgr->add_label(_on, _alt_root);
     _state = true;
     _state = true;
   }
   }
 }
 }
@@ -25,7 +28,10 @@ INLINE void GuiRollover::exit(void) {
 		       << "' more then once without enter" << endl;
 		       << "' more then once without enter" << endl;
   } else if (_mgr != (GuiManager*)0L) {
   } else if (_mgr != (GuiManager*)0L) {
     _mgr->remove_label(_on);
     _mgr->remove_label(_on);
-    _mgr->add_label(_off);
+    if (_alt_root.is_null())
+      _mgr->add_label(_off);
+    else
+      _mgr->add_label(_off, _alt_root);
     _state = false;
     _state = false;
   }
   }
 }
 }

+ 62 - 0
panda/src/gui/guiRollover.cxx

@@ -64,6 +64,45 @@ void GuiRollover::recompute_frame(void) {
   _off->recompute();
   _off->recompute();
   _on->recompute();
   _on->recompute();
   GetExtents(_off, _on, _left, _right, _bottom, _top);
   GetExtents(_off, _on, _left, _right, _bottom, _top);
+  if (_alt_root.is_null()) {
+    // adjust for graph transform
+    LVector3f sc = this->get_graph_scale();
+    LPoint3f p = this->get_graph_pos();
+    float x = sc.dot(LVector3f::rfu(1., 0., 0.));
+    _left *= x;
+    _right *= x;
+    float y = sc.dot(LVector3f::rfu(0., 0., 1.));
+    _bottom *= y;
+    _top *= y;
+    x = p.dot(LVector3f::rfu(1., 0., 0.));
+    _left += x;
+    _right += y;
+    y = p.dot(LVector3f::rfu(0., 0., 1.));
+    _bottom += y;
+    _top += y;
+  }
+  _rgn->set_region(_left, _right, _bottom, _top);
+}
+
+void GuiRollover::adjust_region(void) {
+  GetExtents(_off, _on, _left, _right, _bottom, _top);
+  if (_alt_root.is_null()) {
+    // adjust for graph transform
+    LVector3f sc = this->get_graph_scale();
+    LPoint3f p = this->get_graph_pos();
+    float x = sc.dot(LVector3f::rfu(1., 0., 0.));
+    _left *= x;
+    _right *= x;
+    float y = sc.dot(LVector3f::rfu(0., 0., 1.));
+    _bottom *= y;
+    _top *= y;
+    x = p.dot(LVector3f::rfu(1., 0., 0.));
+    _left += x;
+    _right += y;
+    y = p.dot(LVector3f::rfu(0., 0., 1.));
+    _bottom += y;
+    _top += y;
+  }
   _rgn->set_region(_left, _right, _bottom, _top);
   _rgn->set_region(_left, _right, _bottom, _top);
 }
 }
 
 
@@ -109,6 +148,22 @@ void GuiRollover::manage(GuiManager* mgr, EventHandler& eh) {
 		       << ") that is already managed" << endl;
 		       << ") that is already managed" << endl;
 }
 }
 
 
+void GuiRollover::manage(GuiManager* mgr, EventHandler& eh, Node* n) {
+  if (!_added_hooks) {
+    eh.add_hook("gui-in-rollover-" + get_name(), enter_rollover);
+    eh.add_hook("gui-out-rollover-" + get_name(), exit_rollover);
+    _added_hooks = true;
+  }
+  if (_mgr == (GuiManager*)0L) {
+    mgr->add_region(_rgn);
+    _state = false;
+    mgr->add_label(_off, n);
+    GuiItem::manage(mgr, eh, n);
+  } else
+    gui_cat->warning() << "tried to manage rollover (0x" << (void*)this
+		       << ") that is already managed" << endl;
+}
+
 void GuiRollover::unmanage(void) {
 void GuiRollover::unmanage(void) {
   if (_mgr != (GuiManager*)0L) {
   if (_mgr != (GuiManager*)0L) {
     _mgr->remove_region(_rgn);
     _mgr->remove_region(_rgn);
@@ -137,6 +192,13 @@ void GuiRollover::set_scale(float f) {
   recompute_frame();
   recompute_frame();
 }
 }
 
 
+void GuiRollover::set_scale(float x, float y, float z) {
+  _on->set_scale(x, y, z);
+  _off->set_scale(x, y, z);
+  GuiItem::set_scale(x, y, z);
+  recompute_frame();
+}
+
 void GuiRollover::set_pos(const LVector3f& p) {
 void GuiRollover::set_pos(const LVector3f& p) {
   _on->set_pos(p);
   _on->set_pos(p);
   _off->set_pos(p);
   _off->set_pos(p);

+ 3 - 0
panda/src/gui/guiRollover.h

@@ -24,12 +24,14 @@ private:
 
 
   INLINE GuiRollover(void);
   INLINE GuiRollover(void);
   virtual void recompute_frame(void);
   virtual void recompute_frame(void);
+  virtual void adjust_region(void);
 
 
 PUBLISHED:
 PUBLISHED:
   GuiRollover(const string&, GuiLabel*, GuiLabel*);
   GuiRollover(const string&, GuiLabel*, GuiLabel*);
   virtual ~GuiRollover(void);
   virtual ~GuiRollover(void);
 
 
   virtual void manage(GuiManager*, EventHandler&);
   virtual void manage(GuiManager*, EventHandler&);
+  virtual void manage(GuiManager*, EventHandler&, Node*);
   virtual void unmanage(void);
   virtual void unmanage(void);
 
 
   virtual int freeze(void);
   virtual int freeze(void);
@@ -41,6 +43,7 @@ PUBLISHED:
   INLINE bool is_over(void) const;
   INLINE bool is_over(void) const;
 
 
   virtual void set_scale(float);
   virtual void set_scale(float);
+  virtual void set_scale(float, float, float);
   virtual void set_pos(const LVector3f&);
   virtual void set_pos(const LVector3f&);
   virtual void set_priority(GuiLabel*, const Priority);
   virtual void set_priority(GuiLabel*, const Priority);
   virtual void set_priority(GuiItem*, const Priority);
   virtual void set_priority(GuiItem*, const Priority);

+ 17 - 0
panda/src/gui/guiSign.cxx

@@ -39,6 +39,17 @@ void GuiSign::manage(GuiManager* mgr, EventHandler& eh) {
 		       << ") that is already managed" << endl;
 		       << ") that is already managed" << endl;
 }
 }
 
 
+void GuiSign::manage(GuiManager* mgr, EventHandler& eh, Node* n) {
+  if (!_added_hooks)
+    _added_hooks = true;
+  if (_mgr == (GuiManager*)0L) {
+    mgr->add_label(_sign, n);
+    GuiItem::manage(mgr, eh, n);
+  } else
+    gui_cat->warning() << "tried to manage sign (0x" << (void*)this
+		       << ") that is already managed" << endl;
+}
+
 void GuiSign::unmanage(void) {
 void GuiSign::unmanage(void) {
   if (_mgr != (GuiManager*)0L)
   if (_mgr != (GuiManager*)0L)
     _mgr->remove_label(_sign);
     _mgr->remove_label(_sign);
@@ -61,6 +72,12 @@ void GuiSign::set_scale(float f) {
   recompute_frame();
   recompute_frame();
 }
 }
 
 
+void GuiSign::set_scale(float x, float y, float z) {
+  _sign->set_scale(x, y, z);
+  GuiItem::set_scale(x, y, z);
+  recompute_frame();
+}
+
 void GuiSign::set_pos(const LVector3f& p) {
 void GuiSign::set_pos(const LVector3f& p) {
   _sign->set_pos(p);
   _sign->set_pos(p);
   GuiItem::set_pos(p);
   GuiItem::set_pos(p);

+ 2 - 0
panda/src/gui/guiSign.h

@@ -23,12 +23,14 @@ PUBLISHED:
   ~GuiSign(void);
   ~GuiSign(void);
 
 
   virtual void manage(GuiManager*, EventHandler&);
   virtual void manage(GuiManager*, EventHandler&);
+  virtual void manage(GuiManager*, EventHandler&, Node*);
   virtual void unmanage(void);
   virtual void unmanage(void);
 
 
   virtual int freeze();
   virtual int freeze();
   virtual int thaw();
   virtual int thaw();
 
 
   virtual void set_scale(float);
   virtual void set_scale(float);
+  virtual void set_scale(float, float, float);
   virtual void set_pos(const LVector3f&);
   virtual void set_pos(const LVector3f&);
   virtual void set_priority(GuiLabel*, const Priority);
   virtual void set_priority(GuiLabel*, const Priority);
   virtual void set_priority(GuiItem*, const Priority);
   virtual void set_priority(GuiItem*, const Priority);