diff --git a/panda/src/gui/guiBackground.cxx b/panda/src/gui/guiBackground.cxx index b54f20cdfc..7f9fdecb25 100644 --- a/panda/src/gui/guiBackground.cxx +++ b/panda/src/gui/guiBackground.cxx @@ -67,6 +67,18 @@ void GuiBackground::manage(GuiManager* mgr, EventHandler& eh) { << ") 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) { if (_mgr != (GuiManager*)0L) { _mgr->remove_label(_bg); @@ -92,6 +104,13 @@ void GuiBackground::set_scale(float f) { 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) { _bg->set_pos(p); _item->set_pos(p); diff --git a/panda/src/gui/guiBackground.h b/panda/src/gui/guiBackground.h index b721481895..67b7efae31 100644 --- a/panda/src/gui/guiBackground.h +++ b/panda/src/gui/guiBackground.h @@ -23,12 +23,14 @@ PUBLISHED: ~GuiBackground(void); virtual void manage(GuiManager*, EventHandler&); + virtual void manage(GuiManager*, EventHandler&, Node*); virtual void unmanage(void); virtual int freeze(void); virtual int thaw(void); virtual void set_scale(float); + virtual void set_scale(float, float, float); virtual void set_pos(const LVector3f&); virtual void set_priority(GuiLabel*, const Priority); virtual void set_priority(GuiItem*, const Priority); diff --git a/panda/src/gui/guiBehavior.cxx b/panda/src/gui/guiBehavior.cxx index 9733d3832f..f52b6b7f2c 100644 --- a/panda/src/gui/guiBehavior.cxx +++ b/panda/src/gui/guiBehavior.cxx @@ -29,6 +29,11 @@ void GuiBehavior::manage(GuiManager* mgr, EventHandler& 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) { if (_behavior_running) this->stop_behavior(); diff --git a/panda/src/gui/guiBehavior.h b/panda/src/gui/guiBehavior.h index 10deb7e34b..605fafaad6 100644 --- a/panda/src/gui/guiBehavior.h +++ b/panda/src/gui/guiBehavior.h @@ -26,6 +26,7 @@ PUBLISHED: virtual ~GuiBehavior(void); virtual void manage(GuiManager*, EventHandler&) = 0; + virtual void manage(GuiManager*, EventHandler&, Node*) = 0; virtual void unmanage(void) = 0; virtual void start_behavior(void) = 0; diff --git a/panda/src/gui/guiButton.cxx b/panda/src/gui/guiButton.cxx index bd51450885..c6f4537da2 100644 --- a/panda/src/gui/guiButton.cxx +++ b/panda/src/gui/guiButton.cxx @@ -155,7 +155,10 @@ void GuiButton::switch_state(GuiButton::States nstate) { _rgn->trap_clicks(false); break; 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()) { gui_cat->debug() << "throwing _up_event '" << _up_event << "'" << endl; throw_event(_up_event); @@ -167,15 +170,21 @@ void GuiButton::switch_state(GuiButton::States nstate) { break; case UP_ROLLOVER: 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()) { - 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); } else gui_cat->debug() << "_up_rollover_event is empty!" << endl; } 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()) { gui_cat->debug() << "throwing _up_event '" << _up_event << "'" << endl; throw_event(_up_event); @@ -188,7 +197,10 @@ void GuiButton::switch_state(GuiButton::States nstate) { _mgr->add_region(_rgn); break; 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()) throw_event(_down_event); else @@ -199,13 +211,19 @@ void GuiButton::switch_state(GuiButton::States nstate) { break; case DOWN_ROLLOVER: 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()) throw_event(_down_rollover_event); else gui_cat->debug() << "_down_rollover_event is empty!" << endl; } 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()) throw_event(_down_event); else @@ -218,7 +236,10 @@ void GuiButton::switch_state(GuiButton::States nstate) { break; case INACTIVE: 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()) throw_event(_inactive_event); } @@ -228,7 +249,10 @@ void GuiButton::switch_state(GuiButton::States nstate) { break; case INACTIVE_ROLLOVER: 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()) throw_event(_inactive_event); } @@ -255,6 +279,46 @@ void GuiButton::recompute_frame(void) { _inactive->recompute(); 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); +} + +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); } @@ -421,6 +485,29 @@ void GuiButton::manage(GuiManager* mgr, EventHandler& eh) { << ") 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) { if (_mgr != (GuiManager*)0L) _mgr->remove_region(_rgn); @@ -469,6 +556,19 @@ void GuiButton::set_scale(float f) { 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) { _up->set_pos(p); _down->set_pos(p); diff --git a/panda/src/gui/guiButton.h b/panda/src/gui/guiButton.h index be6889b6b1..9c59bc4859 100644 --- a/panda/src/gui/guiButton.h +++ b/panda/src/gui/guiButton.h @@ -38,6 +38,7 @@ private: INLINE GuiButton(void); void switch_state(States); virtual void recompute_frame(void); + virtual void adjust_region(void); static void behavior_up(CPT_Event, void*); static void behavior_down(CPT_Event, void*); @@ -52,6 +53,7 @@ PUBLISHED: public: virtual void manage(GuiManager*, EventHandler&); + virtual void manage(GuiManager*, EventHandler&, Node*); virtual void unmanage(void); PUBLISHED: @@ -90,6 +92,7 @@ PUBLISHED: INLINE GuiBehavior::BehaviorFunctor* get_behavior_functor(void) const; virtual void set_scale(float); + virtual void set_scale(float, float, float); virtual void set_pos(const LVector3f&); virtual void set_priority(GuiLabel*, const Priority); virtual void set_priority(GuiItem*, const Priority); diff --git a/panda/src/gui/guiChooser.cxx b/panda/src/gui/guiChooser.cxx index 55beb31968..368facd4e9 100644 --- a/panda/src/gui/guiChooser.cxx +++ b/panda/src/gui/guiChooser.cxx @@ -91,7 +91,10 @@ void GuiChooser::move_prev(void) { } if (_mgr != (GuiManager*)0L) { _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) { _prev_button->exit(); _prev_button->inactive(); @@ -132,7 +135,10 @@ void GuiChooser::move_next(void) { } if (_mgr != (GuiManager*)0L) { _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) { _prev_button->exit(); _prev_button->inactive(); @@ -212,6 +218,27 @@ void GuiChooser::manage(GuiManager* mgr, EventHandler& eh) { << ") 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) { _prev_button->unmanage(); _next_button->unmanage(); @@ -224,6 +251,10 @@ void GuiChooser::set_scale(float 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) { GuiBehavior::set_pos(p); } diff --git a/panda/src/gui/guiChooser.h b/panda/src/gui/guiChooser.h index b0a1f3f7d5..13df24a942 100644 --- a/panda/src/gui/guiChooser.h +++ b/panda/src/gui/guiChooser.h @@ -55,9 +55,11 @@ PUBLISHED: virtual int thaw(void); virtual void manage(GuiManager*, EventHandler&); + virtual void manage(GuiManager*, EventHandler&, Node*); virtual void unmanage(void); virtual void set_scale(float); + virtual void set_scale(float, float, float); virtual void set_pos(const LVector3f&); virtual void set_priority(GuiLabel*, const Priority); virtual void set_priority(GuiItem*, const Priority); diff --git a/panda/src/gui/guiCollection.cxx b/panda/src/gui/guiCollection.cxx index 4c1f77daff..a9fc9485c8 100644 --- a/panda/src/gui/guiCollection.cxx +++ b/panda/src/gui/guiCollection.cxx @@ -84,6 +84,18 @@ void GuiCollection::manage(GuiManager* mgr, EventHandler& eh) { << ") 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) { for (Items::iterator i=_items.begin(); i!=_items.end(); ++i) (*i)->unmanage(); @@ -97,6 +109,15 @@ void GuiCollection::set_scale(float f) { 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) { LVector3f delta = p - this->get_pos(); for (Items::iterator i=_items.begin(); i!=_items.end(); ++i) diff --git a/panda/src/gui/guiCollection.h b/panda/src/gui/guiCollection.h index bf6d6c512f..360b1519ff 100644 --- a/panda/src/gui/guiCollection.h +++ b/panda/src/gui/guiCollection.h @@ -29,9 +29,11 @@ PUBLISHED: void remove_item(GuiItem*); virtual void manage(GuiManager*, EventHandler&); + virtual void manage(GuiManager*, EventHandler&, Node*); virtual void unmanage(void); virtual void set_scale(float); + virtual void set_scale(float, float, float); virtual void set_pos(const LVector3f&); virtual void set_priority(GuiLabel*, const Priority); virtual void set_priority(GuiItem*, const Priority); diff --git a/panda/src/gui/guiFrame.cxx b/panda/src/gui/guiFrame.cxx index 76f7424c08..1f0f16bc38 100644 --- a/panda/src/gui/guiFrame.cxx +++ b/panda/src/gui/guiFrame.cxx @@ -332,6 +332,19 @@ void GuiFrame::manage(GuiManager* mgr, EventHandler& eh) { << ") 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) { for (Boxes::iterator i=_items.begin(); i!=_items.end(); ++i) (*i).get_item()->unmanage(); @@ -345,6 +358,14 @@ void GuiFrame::set_scale(float f) { // 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) { for (Boxes::iterator i=_items.begin(); i!=_items.end(); ++i) (*i).get_item()->set_pos(p); diff --git a/panda/src/gui/guiFrame.h b/panda/src/gui/guiFrame.h index 321f16a3cb..4b975f0d9b 100644 --- a/panda/src/gui/guiFrame.h +++ b/panda/src/gui/guiFrame.h @@ -115,9 +115,11 @@ PUBLISHED: INLINE void align_to_bottom(float = 0.); virtual void manage(GuiManager*, EventHandler&); + virtual void manage(GuiManager*, EventHandler&, Node*); virtual void unmanage(void); virtual void set_scale(float); + virtual void set_scale(float, float, float); virtual void set_pos(const LVector3f&); virtual void set_priority(GuiLabel*, const Priority); virtual void set_priority(GuiItem*, const Priority); diff --git a/panda/src/gui/guiItem.I b/panda/src/gui/guiItem.I index 82a819f360..f48e4fcae1 100644 --- a/panda/src/gui/guiItem.I +++ b/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 + +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 { 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 { return _pos; } diff --git a/panda/src/gui/guiItem.cxx b/panda/src/gui/guiItem.cxx index 0b71cbbda2..9f5ee90241 100644 --- a/panda/src/gui/guiItem.cxx +++ b/panda/src/gui/guiItem.cxx @@ -11,11 +11,16 @@ void GuiItem::recompute_frame(void) { test_ref_count_integrity(); } +void GuiItem::adjust_region(void) { + test_ref_count_integrity(); +} + void GuiItem::set_priority(GuiLabel*, const GuiItem::Priority) { } 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.), _pos(0., 0., 0.), _mgr((GuiManager*)0L), _pri(P_Normal) { @@ -39,6 +44,14 @@ int GuiItem::thaw() { void GuiItem::manage(GuiManager* mgr, EventHandler&) { test_ref_count_integrity(); _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) { @@ -50,6 +63,12 @@ void GuiItem::set_scale(float 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) { _pos = p; } diff --git a/panda/src/gui/guiItem.h b/panda/src/gui/guiItem.h index 49cbf80955..8d27c5434d 100644 --- a/panda/src/gui/guiItem.h +++ b/panda/src/gui/guiItem.h @@ -16,30 +16,40 @@ PUBLISHED: protected: bool _added_hooks; - float _scale, _left, _right, _bottom, _top; + float _scale, _scale_x, _scale_y, _scale_z, _left, _right, _bottom, _top; LVector3f _pos; GuiManager* _mgr; Priority _pri; + PT_Node _alt_root; INLINE GuiItem(void); virtual void recompute_frame(void) = 0; + virtual void adjust_region(void); + + INLINE LVector3f get_graph_scale(void); + INLINE LPoint3f get_graph_pos(void); PUBLISHED: GuiItem(const string&); virtual ~GuiItem(void); virtual void manage(GuiManager*, EventHandler&) = 0; + virtual void manage(GuiManager*, EventHandler&, Node*) = 0; virtual void unmanage(void) = 0; virtual int freeze(); virtual int thaw(); virtual void set_scale(float) = 0; + virtual void set_scale(float, float, float) = 0; virtual void set_pos(const LVector3f&) = 0; virtual void set_priority(GuiLabel*, const Priority) = 0; virtual void set_priority(GuiItem*, const Priority) = 0; 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 float get_left(void) const; INLINE float get_right(void) const; diff --git a/panda/src/gui/guiLabel.I b/panda/src/gui/guiLabel.I index e37ab142b6..dead3ea4b2 100644 --- a/panda/src/gui/guiLabel.I +++ b/panda/src/gui/guiLabel.I @@ -9,6 +9,7 @@ INLINE GuiLabel::GuiLabel(void) : _type(GuiLabel::NONE), _internal((RenderRelation*)0L), _gset((Geom*)0L), _model_width(1.), _model_height(1.), _scale(1.), + _scale_x(1.), _scale_y(1.), _scale_z(1.), _pos(0., 0., 0.), _foreground(1., 1., 1., 1.), _have_background(false), @@ -65,6 +66,13 @@ INLINE void GuiLabel::set_scale(float f) { 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) { _mirror_x = b; } diff --git a/panda/src/gui/guiLabel.cxx b/panda/src/gui/guiLabel.cxx index 6b361c14bb..8a068f840d 100644 --- a/panda/src/gui/guiLabel.cxx +++ b/panda/src/gui/guiLabel.cxx @@ -15,7 +15,9 @@ void GuiLabel::recompute_transform(void) { switch (_type) { 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., (_mirror_y?-1.:1.))) * LMatrix4f::translate_mat(_pos); @@ -27,7 +29,9 @@ void GuiLabel::recompute_transform(void) { case SIMPLE_CARD: 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., (_mirror_y?-1.:1.))) * LMatrix4f::translate_mat(_pos); @@ -38,7 +42,9 @@ void GuiLabel::recompute_transform(void) { { float w=_have_width?_scale*_width:_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., (_mirror_y?-1.:1.))) * 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); 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); ul = mat * ul; lr = mat * lr; diff --git a/panda/src/gui/guiLabel.h b/panda/src/gui/guiLabel.h index 53f621f7c0..46ac560b6b 100644 --- a/panda/src/gui/guiLabel.h +++ b/panda/src/gui/guiLabel.h @@ -36,6 +36,7 @@ private: float _model_width, _model_height; float _scale; + float _scale_x, _scale_y, _scale_z; LVector3f _pos; Colorf _foreground; bool _have_background; @@ -83,6 +84,7 @@ PUBLISHED: INLINE void set_height(float); INLINE void set_scale(float); + INLINE void set_scale(float, float, float); INLINE void set_mirror_x(bool); INLINE void set_mirror_y(bool); INLINE void set_pos(float, float, float); diff --git a/panda/src/gui/guiListBox.cxx b/panda/src/gui/guiListBox.cxx index 663f7ba3c4..7d435e5583 100644 --- a/panda/src/gui/guiListBox.cxx +++ b/panda/src/gui/guiListBox.cxx @@ -325,6 +325,17 @@ void GuiListBox::manage(GuiManager* mgr, EventHandler& eh) { << ") 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) { for (ItemVector::iterator i=_visible.begin(); i!=_visible.end(); ++i) (*i)->unmanage(); @@ -343,6 +354,18 @@ void GuiListBox::set_scale(float 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) { ItemVector::iterator i; for (i=_top_stack.begin(); i!=_top_stack.end(); ++i) diff --git a/panda/src/gui/guiListBox.h b/panda/src/gui/guiListBox.h index e6e8aa6711..43b6e7f771 100644 --- a/panda/src/gui/guiListBox.h +++ b/panda/src/gui/guiListBox.h @@ -56,9 +56,11 @@ PUBLISHED: virtual int thaw(void); virtual void manage(GuiManager*, EventHandler&); + virtual void manage(GuiManager*, EventHandler&, Node*); virtual void unmanage(void); virtual void set_scale(float); + virtual void set_scale(float, float, float); virtual void set_pos(const LVector3f&); virtual void set_priority(GuiLabel*, const Priority); virtual void set_priority(GuiItem*, const Priority); diff --git a/panda/src/gui/guiManager.cxx b/panda/src/gui/guiManager.cxx index d71aaba0a1..77547cd2f8 100644 --- a/panda/src/gui/guiManager.cxx +++ b/panda/src/gui/guiManager.cxx @@ -149,6 +149,19 @@ void GuiManager::add_label(GuiLabel* label) { << ") 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) { region->test_ref_count_integrity(); RegionSet::iterator ri; diff --git a/panda/src/gui/guiManager.h b/panda/src/gui/guiManager.h index 70ca13915b..d19efe6ab0 100644 --- a/panda/src/gui/guiManager.h +++ b/panda/src/gui/guiManager.h @@ -45,6 +45,7 @@ PUBLISHED: void add_region(GuiRegion*); void add_label(GuiLabel*); + void add_label(GuiLabel*, Node*); void remove_region(GuiRegion*); void remove_label(GuiLabel*); diff --git a/panda/src/gui/guiRollover.I b/panda/src/gui/guiRollover.I index d4b9885e8e..091459e307 100644 --- a/panda/src/gui/guiRollover.I +++ b/panda/src/gui/guiRollover.I @@ -13,7 +13,10 @@ INLINE void GuiRollover::enter(void) { << "' more then once without exit" << endl; } else if (_mgr != (GuiManager*)0L) { _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; } } @@ -25,7 +28,10 @@ INLINE void GuiRollover::exit(void) { << "' more then once without enter" << endl; } else if (_mgr != (GuiManager*)0L) { _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; } } diff --git a/panda/src/gui/guiRollover.cxx b/panda/src/gui/guiRollover.cxx index 4bcb7bdc1a..3859a16eba 100644 --- a/panda/src/gui/guiRollover.cxx +++ b/panda/src/gui/guiRollover.cxx @@ -64,6 +64,45 @@ void GuiRollover::recompute_frame(void) { _off->recompute(); _on->recompute(); 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); } @@ -109,6 +148,22 @@ void GuiRollover::manage(GuiManager* mgr, EventHandler& eh) { << ") 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) { if (_mgr != (GuiManager*)0L) { _mgr->remove_region(_rgn); @@ -137,6 +192,13 @@ void GuiRollover::set_scale(float f) { 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) { _on->set_pos(p); _off->set_pos(p); diff --git a/panda/src/gui/guiRollover.h b/panda/src/gui/guiRollover.h index 80ff72cefe..fc6df536d7 100644 --- a/panda/src/gui/guiRollover.h +++ b/panda/src/gui/guiRollover.h @@ -24,12 +24,14 @@ private: INLINE GuiRollover(void); virtual void recompute_frame(void); + virtual void adjust_region(void); PUBLISHED: GuiRollover(const string&, GuiLabel*, GuiLabel*); virtual ~GuiRollover(void); virtual void manage(GuiManager*, EventHandler&); + virtual void manage(GuiManager*, EventHandler&, Node*); virtual void unmanage(void); virtual int freeze(void); @@ -41,6 +43,7 @@ PUBLISHED: INLINE bool is_over(void) const; virtual void set_scale(float); + virtual void set_scale(float, float, float); virtual void set_pos(const LVector3f&); virtual void set_priority(GuiLabel*, const Priority); virtual void set_priority(GuiItem*, const Priority); diff --git a/panda/src/gui/guiSign.cxx b/panda/src/gui/guiSign.cxx index d41719d15f..8ad4947f7a 100644 --- a/panda/src/gui/guiSign.cxx +++ b/panda/src/gui/guiSign.cxx @@ -39,6 +39,17 @@ void GuiSign::manage(GuiManager* mgr, EventHandler& eh) { << ") 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) { if (_mgr != (GuiManager*)0L) _mgr->remove_label(_sign); @@ -61,6 +72,12 @@ void GuiSign::set_scale(float f) { 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) { _sign->set_pos(p); GuiItem::set_pos(p); diff --git a/panda/src/gui/guiSign.h b/panda/src/gui/guiSign.h index b98714803c..e7fddff31a 100644 --- a/panda/src/gui/guiSign.h +++ b/panda/src/gui/guiSign.h @@ -23,12 +23,14 @@ PUBLISHED: ~GuiSign(void); virtual void manage(GuiManager*, EventHandler&); + virtual void manage(GuiManager*, EventHandler&, Node*); virtual void unmanage(void); virtual int freeze(); virtual int thaw(); virtual void set_scale(float); + virtual void set_scale(float, float, float); virtual void set_pos(const LVector3f&); virtual void set_priority(GuiLabel*, const Priority); virtual void set_priority(GuiItem*, const Priority);