diff --git a/panda/src/gui/guiBackground.cxx b/panda/src/gui/guiBackground.cxx index 393a6a20d9..06be76f78a 100644 --- a/panda/src/gui/guiBackground.cxx +++ b/panda/src/gui/guiBackground.cxx @@ -14,6 +14,10 @@ void GuiBackground::recompute_frame(void) { GuiItem::recompute_frame(); } +void GuiBackground::set_priority(GuiLabel* l, const GuiItem::Priority p) { + _bg->set_priority(l, ((p==P_Low)?GuiLabel::P_LOWER:GuiLabel::P_HIGHER)); +} + GuiBackground::GuiBackground(const string& name, GuiItem* item) : GuiItem(name), _item(item) { _bg = GuiLabel::make_simple_card_label(); @@ -72,6 +76,12 @@ void GuiBackground::set_pos(const LVector3f& p) { recompute_frame(); } +void GuiBackground::set_priority(GuiItem* it, const GuiItem::Priority p) { + _item->set_priority(it, p); + it->set_priority(_bg, ((p==P_Low)?P_High:P_Low)); + GuiItem::set_priority(it, p); +} + void GuiBackground::output(ostream& os) const { GuiItem::output(os); os << " Background data:" << endl; diff --git a/panda/src/gui/guiBackground.h b/panda/src/gui/guiBackground.h index fd73727b12..980cb97fc7 100644 --- a/panda/src/gui/guiBackground.h +++ b/panda/src/gui/guiBackground.h @@ -29,6 +29,8 @@ PUBLISHED: virtual void set_scale(float); virtual void set_pos(const LVector3f&); + virtual void set_priority(GuiLabel*, const Priority); + virtual void set_priority(GuiItem*, const Priority); virtual void output(ostream&) const; diff --git a/panda/src/gui/guiButton.cxx b/panda/src/gui/guiButton.cxx index 991166e02e..fa114d43a4 100644 --- a/panda/src/gui/guiButton.cxx +++ b/panda/src/gui/guiButton.cxx @@ -237,6 +237,21 @@ void GuiButton::recompute_frame(void) { _rgn->set_region(_left, _right, _bottom, _top); } +void GuiButton::set_priority(GuiLabel* l, GuiItem::Priority p) { + _up->set_priority(l, ((p==P_Low)?GuiLabel::P_LOWER:GuiLabel::P_HIGHER)); + _down->set_priority(l, ((p==P_Low)?GuiLabel::P_LOWER:GuiLabel::P_HIGHER)); + if (_up_rollover != (GuiLabel*)0L) + _up_rollover->set_priority(l, ((p==P_Low)?GuiLabel::P_LOWER: + GuiLabel::P_HIGHER)); + if (_down_rollover != (GuiLabel*)0L) + _down_rollover->set_priority(l, ((p==P_Low)?GuiLabel::P_LOWER: + GuiLabel::P_HIGHER)); + if (_inactive != (GuiLabel*)0L) + _inactive->set_priority(l, ((p==P_Low)?GuiLabel::P_LOWER: + GuiLabel::P_HIGHER)); + GuiItem::set_priority(l, p); +} + void GuiButton::behavior_up(CPT_Event, void* data) { GuiButton* button = (GuiButton*)data; gui_cat->debug() << "behavior_up (0x" << data << ")" << endl; @@ -477,6 +492,18 @@ void GuiButton::reset_behavior(void) { _eh->remove_hook(_up_rollover_event, GuiButton::behavior_up, (void*)this); } +void GuiButton::set_priority(GuiItem* i, const GuiItem::Priority p) { + i->set_priority(_up, ((p==P_Low)?P_High:P_Low)); + i->set_priority(_down, ((p==P_Low)?P_High:P_Low)); + if (_up_rollover != (GuiLabel*)0L) + i->set_priority(_up_rollover, ((p==P_Low)?P_High:P_Low)); + if (_down_rollover != (GuiLabel*)0L) + i->set_priority(_down_rollover, ((p==P_Low)?P_High:P_Low)); + if (_inactive != (GuiLabel*)0L) + i->set_priority(_inactive, ((p==P_Low)?P_High:P_Low)); + GuiBehavior::set_priority(i, p); +} + void GuiButton::output(ostream& os) const { GuiBehavior::output(os); os << " Button data:" << endl; diff --git a/panda/src/gui/guiButton.h b/panda/src/gui/guiButton.h index e70496a8ef..be6889b6b1 100644 --- a/panda/src/gui/guiButton.h +++ b/panda/src/gui/guiButton.h @@ -91,6 +91,8 @@ PUBLISHED: virtual void set_scale(float); virtual void set_pos(const LVector3f&); + virtual void set_priority(GuiLabel*, const Priority); + virtual void set_priority(GuiItem*, const Priority); virtual void start_behavior(void); virtual void stop_behavior(void); diff --git a/panda/src/gui/guiChooser.cxx b/panda/src/gui/guiChooser.cxx index 2828f3f0e5..0373e3fbfa 100644 --- a/panda/src/gui/guiChooser.cxx +++ b/panda/src/gui/guiChooser.cxx @@ -25,6 +25,9 @@ void GuiChooser::ChooseFunctor::doit(GuiBehavior* b) { void GuiChooser::recompute_frame(void) { } +void GuiChooser::set_priority(GuiLabel*, GuiItem::Priority) { +} + GuiChooser::GuiChooser(const string& name, GuiButton* prev, GuiButton* next) : GuiBehavior(name), _curr(-1), _loop(false), _prev_button(prev), _next_button(next), _prev_functor((GuiChooser::ChooseFunctor*)0L), @@ -225,6 +228,13 @@ void GuiChooser::reset_behavior(void) { _next_button->reset_behavior(); } +void GuiChooser::set_priority(GuiItem* it, const GuiItem::Priority p) { + for (ItemVector::iterator i=_items.begin(); i!=_items.end(); ++i) + (*i)->set_priority(it, p); + _prev_button->set_priority(it, p); + _next_button->set_priority(it, p); +} + void GuiChooser::output(ostream& os) const { GuiBehavior::output(os); os << " Chooser data:" << endl; diff --git a/panda/src/gui/guiChooser.h b/panda/src/gui/guiChooser.h index 553c82f456..1e19953824 100644 --- a/panda/src/gui/guiChooser.h +++ b/panda/src/gui/guiChooser.h @@ -57,6 +57,8 @@ PUBLISHED: virtual void set_scale(float); virtual void set_pos(const LVector3f&); + virtual void set_priority(GuiLabel*, const Priority); + virtual void set_priority(GuiItem*, const Priority); virtual void start_behavior(void); virtual void stop_behavior(void); diff --git a/panda/src/gui/guiFrame.cxx b/panda/src/gui/guiFrame.cxx index 717c944644..4f787810a9 100644 --- a/panda/src/gui/guiFrame.cxx +++ b/panda/src/gui/guiFrame.cxx @@ -210,6 +210,9 @@ void GuiFrame::recompute_frame(void) { thaw(); } +void GuiFrame::set_priority(GuiLabel*, const GuiItem::Priority) { +} + GuiFrame::GuiFrame(const string& name) : GuiItem(name), _align_to_left(false), _align_to_right(false), _align_to_top(false), @@ -343,6 +346,15 @@ void GuiFrame::set_pos(const LVector3f& p) { // this->recompute_frame(); } +void GuiFrame::set_priority(GuiItem* it, const GuiItem::Priority p) { + Boxes::iterator i; + + for (i=_items.begin(); i!=_items.end(); ++i) { + GuiItem* here = (*i).get_item(); + here->set_priority(it, p); + } +} + void GuiFrame::output(ostream& os) const { GuiItem::output(os); os << " Frame data:" << endl; diff --git a/panda/src/gui/guiFrame.h b/panda/src/gui/guiFrame.h index 0ee70f404a..321f16a3cb 100644 --- a/panda/src/gui/guiFrame.h +++ b/panda/src/gui/guiFrame.h @@ -119,6 +119,8 @@ PUBLISHED: virtual void set_scale(float); virtual void set_pos(const LVector3f&); + virtual void set_priority(GuiLabel*, const Priority); + virtual void set_priority(GuiItem*, const Priority); virtual void output(ostream&) const; public: diff --git a/panda/src/gui/guiItem.I b/panda/src/gui/guiItem.I index 215b7b6ede..82a819f360 100644 --- a/panda/src/gui/guiItem.I +++ b/panda/src/gui/guiItem.I @@ -6,23 +6,6 @@ INLINE GuiItem::GuiItem(void) : Namable("fubar"), _left(-1.), _right(1.), _bottom(-1.), _top(1.), _pri(P_Normal) {} -INLINE void GuiItem::set_priority(const GuiItem::Priority p) { - _pri = p; - float r = _pos.dot(LVector3f::rfu(1., 0., 0.)); - float u = _pos.dot(LVector3f::rfu(0., 0., 1.)); - switch (_pri) { - case P_Low: - this->set_pos(LVector3f::rfu(r, 0.5, u)); - break; - case P_Normal: - this->set_pos(LVector3f::rfu(r, 0., u)); - break; - case P_High: - this->set_pos(LVector3f::rfu(r, -0.5, u)); - break; - } -} - INLINE float GuiItem::get_scale(void) const { return _scale; } diff --git a/panda/src/gui/guiItem.cxx b/panda/src/gui/guiItem.cxx index 4f01c0f40e..0b71cbbda2 100644 --- a/panda/src/gui/guiItem.cxx +++ b/panda/src/gui/guiItem.cxx @@ -11,6 +11,9 @@ void GuiItem::recompute_frame(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.), _bottom(-1.), _top(1.), @@ -51,6 +54,11 @@ void GuiItem::set_pos(const LVector3f& p) { _pos = p; } +void GuiItem::set_priority(GuiItem* i, const GuiItem::Priority p) { + if (_mgr != (GuiManager*)0L) + _mgr->recompute_priorities(); +} + void GuiItem::output(ostream& os) const { os << "GuiItem (0x" << (void*)this << ")" << endl; os << " name - '" << get_name() << "'" << endl; diff --git a/panda/src/gui/guiItem.h b/panda/src/gui/guiItem.h index 13fd7c8339..db6f622f65 100644 --- a/panda/src/gui/guiItem.h +++ b/panda/src/gui/guiItem.h @@ -36,7 +36,8 @@ PUBLISHED: virtual void set_scale(float) = 0; virtual void set_pos(const LVector3f&) = 0; - INLINE void set_priority(const Priority); + virtual void set_priority(GuiLabel*, const Priority) = 0; + virtual void set_priority(GuiItem*, const Priority) = 0; INLINE float get_scale(void) const; INLINE LVector3f get_pos(void) const; diff --git a/panda/src/gui/guiLabel.I b/panda/src/gui/guiLabel.I index 5f0dd97204..1a32038e6f 100644 --- a/panda/src/gui/guiLabel.I +++ b/panda/src/gui/guiLabel.I @@ -14,7 +14,7 @@ INLINE GuiLabel::GuiLabel(void) : _type(GuiLabel::NONE), _background(0., 0., 0., 0.), _have_width(false), _width(0.), _have_height(false), _height(0.), - _depth(0.) { + _depth(0.), _hard_pri(0) { } INLINE Node* GuiLabel::get_geometry(void) const { @@ -106,3 +106,7 @@ INLINE Colorf GuiLabel::get_background_color(void) const { INLINE void GuiLabel::recompute(void) { this->recompute_transform(); } + +INLINE void GuiLabel::set_priority(GuiLabel* l, const PriorityType t) { + this->_priorities[l] = t; +} diff --git a/panda/src/gui/guiLabel.cxx b/panda/src/gui/guiLabel.cxx index f4948d0527..38d3978028 100644 --- a/panda/src/gui/guiLabel.cxx +++ b/panda/src/gui/guiLabel.cxx @@ -372,3 +372,15 @@ void GuiLabel::set_text(const string& val) { } recompute(); } + +bool GuiLabel::operator<(const GuiLabel& c) const { + PriorityMap::const_iterator pi; + pi = _priorities.find((GuiLabel*)(&c)); + if (pi != _priorities.end()) { + if ((*pi).second == P_LOWER) + return true; + else + return false; + } + return ((void*)this) < ((void*)&c); +} diff --git a/panda/src/gui/guiLabel.h b/panda/src/gui/guiLabel.h index a6a2186608..d54eceeafb 100644 --- a/panda/src/gui/guiLabel.h +++ b/panda/src/gui/guiLabel.h @@ -21,8 +21,12 @@ class GuiManager; class EXPCL_PANDA GuiLabel : public TypedReferenceCount { +PUBLISHED: + enum PriorityType { P_NONE, P_LOWER, P_HIGHER }; private: + typedef map PriorityMap; enum LabelType { NONE, SIMPLE_TEXTURE, SIMPLE_TEXT, SIMPLE_CARD }; + LabelType _type; PT_Node _geom; RenderRelation* _arc; @@ -41,6 +45,9 @@ private: float _height; float _depth; + PriorityMap _priorities; + int _hard_pri; + INLINE Node* get_geometry(void) const; INLINE void set_arc(RenderRelation*); INLINE RenderRelation* get_arc(void) const; @@ -90,6 +97,10 @@ PUBLISHED: INLINE void recompute(void); + // used for the priority system + bool operator<(const GuiLabel&) const; + INLINE void set_priority(GuiLabel*, const PriorityType); + public: // type interface static TypeHandle get_class_type(void) { diff --git a/panda/src/gui/guiListBox.cxx b/panda/src/gui/guiListBox.cxx index 839c278f3a..ed58bdd1ff 100644 --- a/panda/src/gui/guiListBox.cxx +++ b/panda/src/gui/guiListBox.cxx @@ -125,6 +125,9 @@ void GuiListBox::visible_patching(void) { this->reset_behavior(); } +void GuiListBox::set_priority(GuiLabel* l, const GuiItem::Priority p) { +} + GuiListBox::GuiListBox(const string& name, int N, GuiItem* up, GuiItem* down) : GuiBehavior(name), _arrow_top(false), _arrow_bottom(false), _up_arrow(up), _down_arrow(down), _n_visible(N), @@ -430,6 +433,35 @@ void GuiListBox::reset_behavior(void) { } } +void GuiListBox::set_priority(GuiItem* it, const GuiItem::Priority p) { + ItemVector::iterator i; + ItemDeque::iterator j; + + for (i=_top_stack.begin(); i!=_top_stack.end(); ++i) { + if (*i == _up_arrow) + continue; + if (*i == _down_arrow) + continue; + (*i)->set_priority(it, p); + } + for (i=_visible.begin(); i!=_visible.end(); ++i) { + if (*i == _up_arrow) + continue; + if (*i == _down_arrow) + continue; + (*i)->set_priority(it, p); + } + for (j=_bottom_stack.begin(); j!=_bottom_stack.end(); ++j) { + if (*j == _up_arrow) + continue; + if (*j == _down_arrow) + continue; + (*j)->set_priority(it, p); + } + _up_arrow->set_priority(it, p); + _down_arrow->set_priority(it, p); +} + void GuiListBox::output(ostream& os) const { GuiBehavior::output(os); os << " Listbox data:" << endl; diff --git a/panda/src/gui/guiListBox.h b/panda/src/gui/guiListBox.h index 9694343754..e6e8aa6711 100644 --- a/panda/src/gui/guiListBox.h +++ b/panda/src/gui/guiListBox.h @@ -60,6 +60,8 @@ PUBLISHED: virtual void set_scale(float); virtual void set_pos(const LVector3f&); + virtual void set_priority(GuiLabel*, const Priority); + virtual void set_priority(GuiItem*, const Priority); virtual void start_behavior(void); virtual void stop_behavior(void); diff --git a/panda/src/gui/guiManager.cxx b/panda/src/gui/guiManager.cxx index 7010c83e7f..30373fee38 100644 --- a/panda/src/gui/guiManager.cxx +++ b/panda/src/gui/guiManager.cxx @@ -176,3 +176,16 @@ void GuiManager::remove_label(GuiLabel* label) { _labels.erase(li); } } + +#include + +void GuiManager::recompute_priorities(void) { + _sorts.clear(); + for (LabelSet::iterator i=_labels.begin(); i!=_labels.end(); ++i) + _sorts.insert(*i); + int p=0; + for (SortSet::iterator j=_sorts.begin(); j!=_sorts.end(); ++j, ++p) { + (*j)->_hard_pri = p; + (*j)->get_arc()->set_transition(new GeomBinTransition("fixed", p)); + } +} diff --git a/panda/src/gui/guiManager.h b/panda/src/gui/guiManager.h index 005b46bfd6..fa68b10035 100644 --- a/panda/src/gui/guiManager.h +++ b/panda/src/gui/guiManager.h @@ -25,12 +25,19 @@ private: RegionSet _regions; typedef set LabelSet; LabelSet _labels; + class SortComp { + public: + inline bool operator()(GuiLabel* a, GuiLabel* b) const { + return (*a) < (*b); + } + }; + typedef set SortSet; + SortSet _sorts; Node* _root; MouseWatcher* _watcher; INLINE GuiManager(MouseWatcher*, Node*); - PUBLISHED: static GuiManager* get_ptr(GraphicsWindow*, MouseAndKeyboard*, Node *root2d); @@ -39,6 +46,8 @@ PUBLISHED: void remove_region(GuiRegion*); void remove_label(GuiLabel*); + + void recompute_priorities(void); }; #include "guiManager.I" diff --git a/panda/src/gui/guiRollover.cxx b/panda/src/gui/guiRollover.cxx index be04a733d8..b5bbd6fcfd 100644 --- a/panda/src/gui/guiRollover.cxx +++ b/panda/src/gui/guiRollover.cxx @@ -67,6 +67,12 @@ void GuiRollover::recompute_frame(void) { _rgn->set_region(_left, _right, _bottom, _top); } +void GuiRollover::set_priority(GuiLabel* l, const GuiItem::Priority p) { + _off->set_priority(l, ((p==P_Low)?GuiLabel::P_LOWER:GuiLabel::P_HIGHER)); + _on->set_priority(l, ((p==P_Low)?GuiLabel::P_LOWER:GuiLabel::P_HIGHER)); + GuiItem::set_priority(l, p); +} + GuiRollover::GuiRollover(const string& name, GuiLabel* off, GuiLabel* on) : GuiItem(name), _off(off), _on(on), _off_scale(off->get_scale()), _on_scale(on->get_scale()), _state(false) { @@ -138,6 +144,12 @@ void GuiRollover::set_pos(const LVector3f& p) { recompute_frame(); } +void GuiRollover::set_priority(GuiItem* i, const GuiItem::Priority p) { + i->set_priority(_off, ((p==P_Low)?P_High:P_Low)); + i->set_priority(_on, ((p==P_Low)?P_High:P_Low)); + GuiItem::set_priority(i, p); +} + void GuiRollover::output(ostream& os) const { GuiItem::output(os); os << " Rollover data:" << endl; diff --git a/panda/src/gui/guiRollover.h b/panda/src/gui/guiRollover.h index 152dc41d70..80ff72cefe 100644 --- a/panda/src/gui/guiRollover.h +++ b/panda/src/gui/guiRollover.h @@ -42,6 +42,8 @@ PUBLISHED: virtual void set_scale(float); virtual void set_pos(const LVector3f&); + virtual void set_priority(GuiLabel*, const Priority); + virtual void set_priority(GuiItem*, const Priority); virtual void output(ostream&) const; diff --git a/panda/src/gui/guiSign.cxx b/panda/src/gui/guiSign.cxx index 655f5020a5..8d907344ba 100644 --- a/panda/src/gui/guiSign.cxx +++ b/panda/src/gui/guiSign.cxx @@ -14,6 +14,11 @@ void GuiSign::recompute_frame(void) { _sign->get_extents(_left, _right, _bottom, _top); } +void GuiSign::set_priority(GuiLabel* l, const GuiItem::Priority p) { + _sign->set_priority(l, ((p==P_Low)?GuiLabel::P_LOWER:GuiLabel::P_HIGHER)); + GuiItem::set_priority(l, p); +} + GuiSign::GuiSign(const string& name, GuiLabel* sign) : GuiItem(name), _sign(sign), _sign_scale(sign->get_scale()) { _sign->get_extents(_left, _right, _bottom, _top); @@ -62,6 +67,11 @@ void GuiSign::set_pos(const LVector3f& p) { recompute_frame(); } +void GuiSign::set_priority(GuiItem* i, const GuiItem::Priority p) { + i->set_priority(_sign, ((p==P_Low)?P_High:P_Low)); + GuiItem::set_priority(i, p); +} + void GuiSign::output(ostream& os) const { GuiItem::output(os); os << " Sign data:" << endl; diff --git a/panda/src/gui/guiSign.h b/panda/src/gui/guiSign.h index 347badbf79..b98714803c 100644 --- a/panda/src/gui/guiSign.h +++ b/panda/src/gui/guiSign.h @@ -30,6 +30,8 @@ PUBLISHED: virtual void set_scale(float); virtual void set_pos(const LVector3f&); + virtual void set_priority(GuiLabel*, const Priority); + virtual void set_priority(GuiItem*, const Priority); virtual void output(ostream&) const;