diff --git a/panda/src/gui/guiBackground.cxx b/panda/src/gui/guiBackground.cxx index 7f9fdecb25..307e17ee3b 100644 --- a/panda/src/gui/guiBackground.cxx +++ b/panda/src/gui/guiBackground.cxx @@ -129,6 +129,12 @@ void GuiBackground::set_priority(GuiItem* it, const GuiItem::Priority p) { GuiItem::set_priority(it, p); } +int GuiBackground::set_draw_order(int v) { + int o = _bg->set_draw_order(v); + o = _item->set_draw_order(o); + return GuiItem::set_draw_order(o); +} + 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 67b7efae31..c34c8fd280 100644 --- a/panda/src/gui/guiBackground.h +++ b/panda/src/gui/guiBackground.h @@ -39,6 +39,8 @@ PUBLISHED: INLINE void set_color(const Colorf&); INLINE Colorf get_color(void) const; + virtual int set_draw_order(int); + virtual void output(ostream&) const; INLINE void reassert(void); diff --git a/panda/src/gui/guiButton.cxx b/panda/src/gui/guiButton.cxx index c6f4537da2..69b9671676 100644 --- a/panda/src/gui/guiButton.cxx +++ b/panda/src/gui/guiButton.cxx @@ -277,47 +277,29 @@ void GuiButton::recompute_frame(void) { _down_rollover->recompute(); if (_inactive != (GuiLabel*)0L) _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); + this->adjust_region(); } void GuiButton::adjust_region(void) { GetExtents(_up, _down, _up_rollover, _down_rollover, _inactive, _left, _right, _bottom, _top); + gui_cat->debug() << "in adjust_region, base values (" << _left << ", " + << _right << ", " << _bottom << ", " << _top << ")" << endl; 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; + LMatrix4f m; + this->get_graph_mat(m); + LVector3f ul = LVector3f::rfu(_left, 0., _top); + LVector3f lr = LVector3f::rfu(_right, 0., _bottom); + ul = m * ul; + lr = m * lr; + _left = ul.dot(LVector3f::rfu(1., 0., 0.)); + _top = ul.dot(LVector3f::rfu(0., 0., 1.)); + _right = lr.dot(LVector3f::rfu(1., 0., 0.)); + _bottom = lr.dot(LVector3f::rfu(0., 0., 1.)); + gui_cat->debug() << "childed to non-default node, current values (" + << _left << ", " << _right << ", " << _bottom << ", " + << _top << ")" << endl; } _rgn->set_region(_left, _right, _bottom, _top); } @@ -645,6 +627,18 @@ void GuiButton::set_priority(GuiItem* i, const GuiItem::Priority p) { GuiBehavior::set_priority(i, p); } +int GuiButton::set_draw_order(int v) { + int o = _up->set_draw_order(v); + o = _down->set_draw_order(o); + if (_up_rollover != (GuiLabel*)0L) + o = _up_rollover->set_draw_order(o); + if (_down_rollover != (GuiLabel*)0L) + o = _down_rollover->set_draw_order(o); + if (_inactive != (GuiLabel*)0L) + o = _inactive->set_draw_order(o); + return GuiBehavior::set_draw_order(o); +} + 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 9c59bc4859..09063d93e9 100644 --- a/panda/src/gui/guiButton.h +++ b/panda/src/gui/guiButton.h @@ -101,6 +101,8 @@ PUBLISHED: virtual void stop_behavior(void); virtual void reset_behavior(void); + virtual int set_draw_order(int); + virtual void output(ostream&) const; public: diff --git a/panda/src/gui/guiChooser.cxx b/panda/src/gui/guiChooser.cxx index 368facd4e9..3a182a5ee4 100644 --- a/panda/src/gui/guiChooser.cxx +++ b/panda/src/gui/guiChooser.cxx @@ -316,6 +316,14 @@ void GuiChooser::set_priority(GuiItem* it, const GuiItem::Priority p) { _next_button->set_priority(it, p); } +int GuiChooser::set_draw_order(int v) { + int o = _prev_button->set_draw_order(v); + o = _next_button->set_draw_order(o); + for (ItemVector::iterator i=_items.begin(); i!=_items.end(); ++i) + o = (*i)->set_draw_order(o); + return GuiBehavior::set_draw_order(o); +} + 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 13df24a942..6f9c9b4194 100644 --- a/panda/src/gui/guiChooser.h +++ b/panda/src/gui/guiChooser.h @@ -68,6 +68,8 @@ PUBLISHED: virtual void stop_behavior(void); virtual void reset_behavior(void); + virtual int set_draw_order(int); + virtual void output(ostream&) const; INLINE void set_loop(bool); diff --git a/panda/src/gui/guiCollection.cxx b/panda/src/gui/guiCollection.cxx index a9fc9485c8..79198b0516 100644 --- a/panda/src/gui/guiCollection.cxx +++ b/panda/src/gui/guiCollection.cxx @@ -131,6 +131,18 @@ void GuiCollection::set_priority(GuiItem* it, const GuiItem::Priority p) { (*i)->set_priority(it, p); } +int GuiCollection::set_draw_order(int v) { + bool first = true; + int o; + for (Items::iterator i=_items.begin(); i!=_items.end(); ++i) + if (first) { + first = false; + o = (*i)->set_draw_order(v); + } else + o = (*i)->set_draw_order(o); + return GuiItem::set_draw_order(o); +} + void GuiCollection::output(ostream& os) const { GuiItem::output(os); os << " Collection data:" << endl; diff --git a/panda/src/gui/guiCollection.h b/panda/src/gui/guiCollection.h index 360b1519ff..fd4f7d8ac6 100644 --- a/panda/src/gui/guiCollection.h +++ b/panda/src/gui/guiCollection.h @@ -38,6 +38,8 @@ PUBLISHED: virtual void set_priority(GuiLabel*, const Priority); virtual void set_priority(GuiItem*, const Priority); + virtual int set_draw_order(int); + virtual void output(ostream&) const; public: // type interface diff --git a/panda/src/gui/guiFrame.cxx b/panda/src/gui/guiFrame.cxx index 1f0f16bc38..177916b6dc 100644 --- a/panda/src/gui/guiFrame.cxx +++ b/panda/src/gui/guiFrame.cxx @@ -382,6 +382,18 @@ void GuiFrame::set_priority(GuiItem* it, const GuiItem::Priority p) { } } +int GuiFrame::set_draw_order(int v) { + int o; + bool first = true; + for (Boxes::iterator i=_items.begin(); i!=_items.end(); ++i) + if (first) { + first = false; + o = (*i).get_item()->set_draw_order(v); + } else + o = (*i).get_item()->set_draw_order(o); + return GuiItem::set_draw_order(o); +} + 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 4b975f0d9b..2385448a7b 100644 --- a/panda/src/gui/guiFrame.h +++ b/panda/src/gui/guiFrame.h @@ -124,6 +124,8 @@ PUBLISHED: virtual void set_priority(GuiLabel*, const Priority); virtual void set_priority(GuiItem*, const Priority); + virtual int set_draw_order(int); + virtual void output(ostream&) const; public: // type interface diff --git a/panda/src/gui/guiItem.I b/panda/src/gui/guiItem.I index f48e4fcae1..bfb09e38f8 100644 --- a/panda/src/gui/guiItem.I +++ b/panda/src/gui/guiItem.I @@ -10,18 +10,13 @@ INLINE GuiItem::GuiItem(void) : Namable("fubar"), _scale(1.), _scale_x(1.), #include -INLINE LVector3f GuiItem::get_graph_scale(void) { - if (_alt_root.is_null()) - return LVector3f(1., 1., 1.); +INLINE void GuiItem::get_graph_mat(LMatrix4f& m) { + if (_alt_root.is_null()) { + m = LMatrix4f::ident_mat(); + return; + } // 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); + get_rel_mat(_alt_root, (Node*)0L, m); } INLINE float GuiItem::get_scale(void) const { diff --git a/panda/src/gui/guiItem.cxx b/panda/src/gui/guiItem.cxx index 9f5ee90241..78d66439a8 100644 --- a/panda/src/gui/guiItem.cxx +++ b/panda/src/gui/guiItem.cxx @@ -78,6 +78,10 @@ void GuiItem::set_priority(GuiItem* i, const GuiItem::Priority p) { _mgr->recompute_priorities(); } +int GuiItem::set_draw_order(int v) { + return v; +} + 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 8d27c5434d..6a03597d3f 100644 --- a/panda/src/gui/guiItem.h +++ b/panda/src/gui/guiItem.h @@ -26,8 +26,7 @@ protected: virtual void recompute_frame(void) = 0; virtual void adjust_region(void); - INLINE LVector3f get_graph_scale(void); - INLINE LPoint3f get_graph_pos(void); + INLINE void get_graph_mat(LMatrix4f&); PUBLISHED: GuiItem(const string&); @@ -62,6 +61,8 @@ PUBLISHED: INLINE void recompute(void); + virtual int set_draw_order(int) = 0; + virtual void output(ostream&) const = 0; public: // type interface diff --git a/panda/src/gui/guiLabel.I b/panda/src/gui/guiLabel.I index dead3ea4b2..0f2237cfc1 100644 --- a/panda/src/gui/guiLabel.I +++ b/panda/src/gui/guiLabel.I @@ -18,7 +18,7 @@ INLINE GuiLabel::GuiLabel(void) : _type(GuiLabel::NONE), _have_height(false), _height(0.), _mirror_x(false), _mirror_y(false), _hard_pri(0), _highest_pri(false), - _lowest_pri(false) { + _lowest_pri(false), _has_hard_pri(false) { } INLINE Node* GuiLabel::get_geometry(void) const { @@ -39,7 +39,7 @@ INLINE void GuiLabel::set_width(float f) { _width = 0.; } else { if (_type == MODEL) - _width = f / this->get_width(); + _width = f / this->_model_width; else _width = f; _have_width = true; @@ -53,7 +53,7 @@ INLINE void GuiLabel::set_height(float f) { _height = 0.; } else { if (_type == MODEL) - _height = f / this->get_height(); + _height = f / this->_model_height; else _height = f; _have_height = true; @@ -140,3 +140,7 @@ INLINE void GuiLabel::set_priority(GuiLabel* l, const PriorityType t) { else this->_priorities[l] = t; } + +INLINE bool GuiLabel::has_hard_draw_order(void) const { + return _has_hard_pri; +} diff --git a/panda/src/gui/guiLabel.cxx b/panda/src/gui/guiLabel.cxx index 8a068f840d..8ddb78e707 100644 --- a/panda/src/gui/guiLabel.cxx +++ b/panda/src/gui/guiLabel.cxx @@ -625,6 +625,35 @@ bool GuiLabel::operator<(const GuiLabel& c) const { int GuiLabel::set_draw_order(int order) { int ret = order+1; this->freeze(); + _has_hard_pri = true; + _hard_pri = order; + switch (_type) { + case SIMPLE_TEXT: + { + TextNode* n = DCAST(TextNode, _geom); + n->set_bin("fixed"); + n->set_draw_order(order); + ret += 2; + } + break; + case SIMPLE_TEXTURE: + case SIMPLE_CARD: + case L_NULL: + case MODEL: + _arc->set_transition(new GeomBinTransition("fixed", order)); + break; + default: + gui_cat->warning() << "trying to set draw order on an unknown label type (" + << (int)_type << ")" << endl; + } + this->thaw(); + return ret; +} + +int GuiLabel::soft_set_draw_order(int order) { + int ret = order+1; + this->freeze(); + _has_hard_pri = false; _hard_pri = order; switch (_type) { case SIMPLE_TEXT: diff --git a/panda/src/gui/guiLabel.h b/panda/src/gui/guiLabel.h index 46ac560b6b..bc4b760bc6 100644 --- a/panda/src/gui/guiLabel.h +++ b/panda/src/gui/guiLabel.h @@ -52,6 +52,7 @@ private: int _hard_pri; bool _highest_pri; bool _lowest_pri; + bool _has_hard_pri; INLINE Node* get_geometry(void) const; INLINE void set_arc(RenderRelation*); @@ -114,7 +115,9 @@ PUBLISHED: // used for the priority system bool operator<(const GuiLabel&) const; INLINE void set_priority(GuiLabel*, const PriorityType); + int soft_set_draw_order(int); int set_draw_order(int); + INLINE bool has_hard_draw_order(void) const; void write(ostream&) const; diff --git a/panda/src/gui/guiManager.I b/panda/src/gui/guiManager.I index c91142ea97..cadac2213b 100644 --- a/panda/src/gui/guiManager.I +++ b/panda/src/gui/guiManager.I @@ -3,7 +3,8 @@ // //////////////////////////////////////////////////////////////////// -INLINE GuiManager::GuiManager(MouseWatcher* w, Node* n) : _next_draw_order(0), +INLINE GuiManager::GuiManager(MouseWatcher* w, Node* n) : _start_draw_order(0), + _next_draw_order(0), _root(n), _watcher(w) { } @@ -21,3 +22,11 @@ INLINE void GuiManager::set_next_draw_order(int v) { #endif /* NDEBUG */ this->_next_draw_order = v; } + +INLINE int GuiManager::get_start_draw_order(void) const { + return _start_draw_order; +} + +INLINE void GuiManager::set_start_draw_order(int v) { + this->_start_draw_order = v; +} diff --git a/panda/src/gui/guiManager.cxx b/panda/src/gui/guiManager.cxx index 77547cd2f8..9021277455 100644 --- a/panda/src/gui/guiManager.cxx +++ b/panda/src/gui/guiManager.cxx @@ -194,9 +194,10 @@ void GuiManager::recompute_priorities(void) { _sorts.clear(); for (LabelSet::iterator i=_labels.begin(); i!=_labels.end(); ++i) _sorts.insert(*i); - int p=0; + int p=this->_start_draw_order; for (SortSet::iterator j=_sorts.begin(); j!=_sorts.end(); ++j) { - p = (*j)->set_draw_order(p); + if (!((*j)->has_hard_draw_order())) + p = (*j)->soft_set_draw_order(p); } _next_draw_order = p; } diff --git a/panda/src/gui/guiManager.h b/panda/src/gui/guiManager.h index d19efe6ab0..47d9d9bbf7 100644 --- a/panda/src/gui/guiManager.h +++ b/panda/src/gui/guiManager.h @@ -34,6 +34,7 @@ private: typedef set SortSet; SortSet _sorts; + int _start_draw_order; int _next_draw_order; Node* _root; @@ -54,6 +55,8 @@ PUBLISHED: INLINE int get_next_draw_order(void) const; INLINE void set_next_draw_order(int); + INLINE int get_start_draw_order(void) const; + INLINE void set_start_draw_order(int); }; #include "guiManager.I" diff --git a/panda/src/gui/guiRollover.cxx b/panda/src/gui/guiRollover.cxx index 3859a16eba..71ca337e48 100644 --- a/panda/src/gui/guiRollover.cxx +++ b/panda/src/gui/guiRollover.cxx @@ -63,45 +63,28 @@ void GuiRollover::recompute_frame(void) { GuiItem::recompute_frame(); _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); + this->adjust_region(); } void GuiRollover::adjust_region(void) { GetExtents(_off, _on, _left, _right, _bottom, _top); + gui_cat->debug() << "in adjust_region, base values (" << _left << ", " + << _right << ", " << _bottom << ", " << _top << ")" << endl; 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; + LMatrix4f m; + this->get_graph_mat(m); + LVector3f ul = LVector3f::rfu(_left, 0., _top); + LVector3f lr = LVector3f::rfu(_right, 0., _bottom); + ul = m * ul; + lr = m * lr; + _left = ul.dot(LVector3f::rfu(1., 0., 0.)); + _top = ul.dot(LVector3f::rfu(0., 0., 1.)); + _right = lr.dot(LVector3f::rfu(1., 0., 0.)); + _bottom = lr.dot(LVector3f::rfu(0., 0., 1.)); + gui_cat->debug() << "childed to non-default node, current values (" + << _left << ", " << _right << ", " << _bottom << ", " + << _top << ")" << endl; } _rgn->set_region(_left, _right, _bottom, _top); } @@ -220,6 +203,12 @@ void GuiRollover::set_priority(GuiItem* i, const GuiItem::Priority p) { GuiItem::set_priority(i, p); } +int GuiRollover::set_draw_order(int v) { + int o = _off->set_draw_order(v); + o = _on->set_draw_order(o); + return GuiItem::set_draw_order(o); +} + 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 fc6df536d7..f119060f5b 100644 --- a/panda/src/gui/guiRollover.h +++ b/panda/src/gui/guiRollover.h @@ -48,6 +48,8 @@ PUBLISHED: virtual void set_priority(GuiLabel*, const Priority); virtual void set_priority(GuiItem*, const Priority); + virtual int set_draw_order(int); + virtual void output(ostream&) const; public: diff --git a/panda/src/gui/guiSign.cxx b/panda/src/gui/guiSign.cxx index 8ad4947f7a..7e4e7430b9 100644 --- a/panda/src/gui/guiSign.cxx +++ b/panda/src/gui/guiSign.cxx @@ -94,6 +94,11 @@ void GuiSign::set_priority(GuiItem* i, const GuiItem::Priority p) { GuiItem::set_priority(i, p); } +int GuiSign::set_draw_order(int v) { + int o = _sign->set_draw_order(v); + return GuiItem::set_draw_order(o); +} + 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 e7fddff31a..af9fc70e17 100644 --- a/panda/src/gui/guiSign.h +++ b/panda/src/gui/guiSign.h @@ -35,6 +35,8 @@ PUBLISHED: virtual void set_priority(GuiLabel*, const Priority); virtual void set_priority(GuiItem*, const Priority); + virtual int set_draw_order(int); + virtual void output(ostream&) const; public: