diff --git a/panda/src/gui/guiBackground.cxx b/panda/src/gui/guiBackground.cxx index 7da8ae3538..b54f20cdfc 100644 --- a/panda/src/gui/guiBackground.cxx +++ b/panda/src/gui/guiBackground.cxx @@ -103,6 +103,8 @@ void GuiBackground::set_priority(GuiItem* it, const GuiItem::Priority p) { _item->set_priority(it, p); if (p == P_Highest) _bg->set_priority(_bg, GuiLabel::P_HIGHEST); + else if (p == P_Lowest) + _bg->set_priority(_bg, GuiLabel::P_LOWEST); else it->set_priority(_bg, ((p==P_Low)?P_High:P_Low)); GuiItem::set_priority(it, p); diff --git a/panda/src/gui/guiButton.cxx b/panda/src/gui/guiButton.cxx index d6dd47bf26..bd51450885 100644 --- a/panda/src/gui/guiButton.cxx +++ b/panda/src/gui/guiButton.cxx @@ -523,6 +523,15 @@ void GuiButton::set_priority(GuiItem* i, const GuiItem::Priority p) { _down_rollover->set_priority(_up, GuiLabel::P_HIGHEST); if (_inactive != (GuiLabel*)0L) _inactive->set_priority(_up, GuiLabel::P_HIGHEST); + } else if (p == P_Lowest) { + _up->set_priority(_up, GuiLabel::P_LOWEST); + _down->set_priority(_up, GuiLabel::P_LOWEST); + if (_up_rollover != (GuiLabel*)0L) + _up_rollover->set_priority(_up, GuiLabel::P_LOWEST); + if (_down_rollover != (GuiLabel*)0L) + _down_rollover->set_priority(_up, GuiLabel::P_LOWEST); + if (_inactive != (GuiLabel*)0L) + _inactive->set_priority(_up, GuiLabel::P_LOWEST); } else { i->set_priority(_up, ((p==P_Low)?P_High:P_Low)); i->set_priority(_down, ((p==P_Low)?P_High:P_Low)); diff --git a/panda/src/gui/guiChooser.I b/panda/src/gui/guiChooser.I index 5271e3d9a0..cf6843405b 100644 --- a/panda/src/gui/guiChooser.I +++ b/panda/src/gui/guiChooser.I @@ -5,6 +5,10 @@ INLINE GuiChooser::GuiChooser(void) {} +INLINE int GuiChooser::get_curr_item(void) const { + return _curr; +} + INLINE void GuiChooser::set_loop(bool b) { _loop = b; } diff --git a/panda/src/gui/guiChooser.cxx b/panda/src/gui/guiChooser.cxx index 9b8f8eab47..55beb31968 100644 --- a/panda/src/gui/guiChooser.cxx +++ b/panda/src/gui/guiChooser.cxx @@ -92,9 +92,10 @@ void GuiChooser::move_prev(void) { if (_mgr != (GuiManager*)0L) { _items[_curr]->unmanage(); _items[tmp]->manage(_mgr, *_eh); - if (tmp == 0) + if (tmp == 0) { + _prev_button->exit(); _prev_button->inactive(); - else { + } else { _prev_button->up(); if (_behavior_running) { _prev_button->start_behavior(); @@ -102,9 +103,10 @@ void GuiChooser::move_prev(void) { } } int foo = _items.size() - 1; - if (tmp == foo) + if (tmp == foo) { + _next_button->exit(); _next_button->inactive(); - else { + } else { _next_button->up(); if (_behavior_running) { _next_button->start_behavior(); @@ -131,9 +133,10 @@ void GuiChooser::move_next(void) { if (_mgr != (GuiManager*)0L) { _items[_curr]->unmanage(); _items[tmp]->manage(_mgr, *_eh); - if (tmp == 0) + if (tmp == 0) { + _prev_button->exit(); _prev_button->inactive(); - else { + } else { _prev_button->up(); if (_behavior_running) { _prev_button->start_behavior(); @@ -141,9 +144,10 @@ void GuiChooser::move_next(void) { } } int foo = _items.size() - 1; - if (tmp == foo) + if (tmp == foo) { + _next_button->exit(); _next_button->inactive(); - else { + } else { _next_button->up(); if (_behavior_running) { _next_button->start_behavior(); diff --git a/panda/src/gui/guiChooser.h b/panda/src/gui/guiChooser.h index 1e19953824..b0a1f3f7d5 100644 --- a/panda/src/gui/guiChooser.h +++ b/panda/src/gui/guiChooser.h @@ -49,6 +49,8 @@ PUBLISHED: void move_next(void); void add_item(GuiItem*); + INLINE int get_curr_item(void) const; + virtual int freeze(void); virtual int thaw(void); diff --git a/panda/src/gui/guiItem.h b/panda/src/gui/guiItem.h index 45700a5565..49cbf80955 100644 --- a/panda/src/gui/guiItem.h +++ b/panda/src/gui/guiItem.h @@ -12,7 +12,7 @@ class EXPCL_PANDA GuiItem : public TypedReferenceCount, public Namable { PUBLISHED: - enum Priority { P_Low, P_Normal, P_High, P_Highest }; + enum Priority { P_Lowest, P_Low, P_Normal, P_High, P_Highest }; protected: bool _added_hooks; diff --git a/panda/src/gui/guiLabel.I b/panda/src/gui/guiLabel.I index f9018d9409..e37ab142b6 100644 --- a/panda/src/gui/guiLabel.I +++ b/panda/src/gui/guiLabel.I @@ -16,7 +16,8 @@ INLINE GuiLabel::GuiLabel(void) : _type(GuiLabel::NONE), _have_width(false), _width(0.), _have_height(false), _height(0.), _mirror_x(false), _mirror_y(false), - _hard_pri(0), _highest_pri(false) { + _hard_pri(0), _highest_pri(false), + _lowest_pri(false) { } INLINE Node* GuiLabel::get_geometry(void) const { @@ -115,6 +116,10 @@ INLINE Colorf GuiLabel::get_background_color(void) const { return _background; } +INLINE void GuiLabel::set_shadow_color(float r, float g, float b, float a) { + this->set_shadow_color(Colorf(r, g, b, a)); +} + INLINE void GuiLabel::recompute(void) { this->recompute_transform(); } @@ -122,6 +127,8 @@ INLINE void GuiLabel::recompute(void) { INLINE void GuiLabel::set_priority(GuiLabel* l, const PriorityType t) { if (t == P_HIGHEST) _highest_pri = true; + else if (t == P_LOWEST) + _lowest_pri = true; else this->_priorities[l] = t; } diff --git a/panda/src/gui/guiLabel.cxx b/panda/src/gui/guiLabel.cxx index 6147b8a538..6b361c14bb 100644 --- a/panda/src/gui/guiLabel.cxx +++ b/panda/src/gui/guiLabel.cxx @@ -25,6 +25,7 @@ void GuiLabel::recompute_transform(void) { break; case SIMPLE_TEXTURE: case SIMPLE_CARD: + case L_NULL: { LMatrix4f mat = LMatrix4f::scale_mat(_scale) * LMatrix4f::scale_mat(LVector3f::rfu((_mirror_x?-1.:1.), 1., @@ -100,6 +101,7 @@ void GuiLabel::set_properties(void) { break; case SIMPLE_TEXTURE: case MODEL: + case L_NULL: _internal->set_transition(new ColorTransition(_foreground)); break; case SIMPLE_CARD: @@ -232,6 +234,17 @@ GuiLabel* GuiLabel::make_simple_card_label(void) { return ret; } +GuiLabel* GuiLabel::make_null_label(void) { + GuiLabel* ret = new GuiLabel(); + ret->_type = L_NULL; + ret->_geom = new NamedNode("GUI label"); + NamedNode* n2 = new NamedNode("dummy"); + ret->_internal = new RenderRelation(ret->_geom, n2); + ret->_internal->set_transition( + new ColorTransition(Colorf(ret->_foreground))); + return ret; +} + GuiLabel* GuiLabel::make_model_label(Node* geom, float w, float h) { GuiLabel* ret = new GuiLabel(); ret->_type = MODEL; @@ -345,6 +358,20 @@ void GuiLabel::get_extents(float& l, float& r, float& b, float& t) { t += y; } break; + case L_NULL: + { + float x = _pos.dot(LVector3f::rfu(1., 0., 0.)); + float y = _pos.dot(LVector3f::rfu(0., 0., 1.)); + l = _have_width?-(_width*0.5):-0.000005; + r = _have_width?(_width*0.5):0.000005; + l += x; + r += x; + b = _have_height?-(_height*0.5):-0.000005; + t = _have_height?(_height*0.5):0.000005; + b += y; + t += y; + } + break; case MODEL: { float x = _pos.dot(LVector3f::rfu(1., 0., 0.)); @@ -390,6 +417,9 @@ float GuiLabel::get_width(void) { case MODEL: w = _have_width?(_width*_model_width):_model_width; break; + case L_NULL: + w = _have_width?_width:0.00001; + break; default: gui_cat->warning() << "trying to get width from something I don't know how to" << endl; @@ -421,6 +451,9 @@ float GuiLabel::get_height(void) { case MODEL: h = _have_height?(_height*_model_height):_model_height; break; + case L_NULL: + h = _have_height?_height:0.00001; + break; default: gui_cat->warning() << "trying to get height from something I don't know how to" << endl; @@ -459,6 +492,9 @@ void GuiLabel::set_text(const string& val) { case MODEL: gui_cat->warning() << "tried to set text on a model label" << endl; break; + case L_NULL: + gui_cat->warning() << "tried to set text on a null label" << endl; + break; default: gui_cat->warning() << "trying to set text on an unknown label type (" << (int)_type << ")" << endl; @@ -466,11 +502,98 @@ void GuiLabel::set_text(const string& val) { recompute(); } +void GuiLabel::set_shadow_color(const Colorf& c) { + switch (_type) { + case SIMPLE_TEXT: + { + TextNode* n = DCAST(TextNode, _geom); + n->set_shadow_color(c); + } + break; + case SIMPLE_TEXTURE: + gui_cat->warning() << "tried to set shadow color on a texture label" + << endl; + break; + case SIMPLE_CARD: + gui_cat->warning() << "tried to set shadow color on a card label" << endl; + break; + case MODEL: + gui_cat->warning() << "tried to set shadow color on a model label" << endl; + break; + case L_NULL: + gui_cat->warning() << "tried to set shadow color on a null label" << endl; + break; + default: + gui_cat->warning() + << "trying to set shadow color on an unknown label type (" << (int)_type + << ")" << endl; + } + recompute(); +} + +void GuiLabel::set_shadow(float x, float y) { + switch (_type) { + case SIMPLE_TEXT: + { + TextNode* n = DCAST(TextNode, _geom); + n->set_shadow(x, y); + } + break; + case SIMPLE_TEXTURE: + gui_cat->warning() << "tried to set shadow on a texture label" << endl; + break; + case SIMPLE_CARD: + gui_cat->warning() << "tried to set shadow on a card label" << endl; + break; + case MODEL: + gui_cat->warning() << "tried to set shadow on a model label" << endl; + break; + case L_NULL: + gui_cat->warning() << "tried to set shadow on a null label" << endl; + break; + default: + gui_cat->warning() << "trying to set shadow on an unknown label type (" + << (int)_type << ")" << endl; + } + recompute(); +} + +void GuiLabel::set_align(int a) { + switch (_type) { + case SIMPLE_TEXT: + { + TextNode* n = DCAST(TextNode, _geom); + n->set_align(a); + } + break; + case SIMPLE_TEXTURE: + gui_cat->warning() << "tried to set align on a texture label" << endl; + break; + case SIMPLE_CARD: + gui_cat->warning() << "tried to set align on a card label" << endl; + break; + case MODEL: + gui_cat->warning() << "tried to set align on a model label" << endl; + break; + case L_NULL: + gui_cat->warning() << "tried to set align on a null label" << endl; + break; + default: + gui_cat->warning() << "trying to set align on an unknown label type (" + << (int)_type << ")" << endl; + } + recompute(); +} + bool GuiLabel::operator<(const GuiLabel& c) const { if (_highest_pri) return false; if (c._highest_pri) return true; + if (_lowest_pri) + return true; + if (c._lowest_pri) + return false; PriorityMap::const_iterator pi; pi = _priorities.find((GuiLabel*)(&c)); if (pi != _priorities.end()) { @@ -506,6 +629,7 @@ int GuiLabel::set_draw_order(int order) { break; case SIMPLE_TEXTURE: case SIMPLE_CARD: + case L_NULL: case MODEL: _arc->set_transition(new GeomBinTransition("fixed", order)); break; @@ -537,6 +661,9 @@ void GuiLabel::write(ostream& os) const { case MODEL: os << "MODEL"; break; + case L_NULL: + os << "NULL"; + break; default: os << "bad"; } diff --git a/panda/src/gui/guiLabel.h b/panda/src/gui/guiLabel.h index ed3b26bb75..53f621f7c0 100644 --- a/panda/src/gui/guiLabel.h +++ b/panda/src/gui/guiLabel.h @@ -22,10 +22,10 @@ class GuiManager; class EXPCL_PANDA GuiLabel : public TypedReferenceCount { PUBLISHED: - enum PriorityType { P_NONE, P_LOWER, P_HIGHER, P_HIGHEST }; + enum PriorityType { P_NONE, P_LOWEST, P_LOWER, P_HIGHER, P_HIGHEST }; private: typedef map PriorityMap; - enum LabelType { NONE, SIMPLE_TEXTURE, SIMPLE_TEXT, SIMPLE_CARD, MODEL }; + enum LabelType { NONE, L_NULL, SIMPLE_TEXTURE, SIMPLE_TEXT, SIMPLE_CARD, MODEL }; LabelType _type; PT_Node _geom; @@ -50,6 +50,7 @@ private: PriorityMap _priorities; int _hard_pri; bool _highest_pri; + bool _lowest_pri; INLINE Node* get_geometry(void) const; INLINE void set_arc(RenderRelation*); @@ -68,6 +69,7 @@ PUBLISHED: static GuiLabel* make_simple_text_label(const string&, Node*, Texture* = (Texture*)0L); static GuiLabel* make_simple_card_label(void); + static GuiLabel* make_null_label(void); static GuiLabel* make_model_label(Node*, float, float); int freeze(); @@ -100,6 +102,10 @@ PUBLISHED: INLINE Colorf get_background_color(void) const; void set_text(const string&); + INLINE void set_shadow_color(float, float, float, float); + void set_shadow_color(const Colorf&); + void set_shadow(float, float); + void set_align(int); INLINE void recompute(void); diff --git a/panda/src/gui/guiManager.I b/panda/src/gui/guiManager.I index 014009a94f..c91142ea97 100644 --- a/panda/src/gui/guiManager.I +++ b/panda/src/gui/guiManager.I @@ -3,6 +3,21 @@ // //////////////////////////////////////////////////////////////////// -INLINE GuiManager::GuiManager(MouseWatcher* w, Node* n) : _root(n), +INLINE GuiManager::GuiManager(MouseWatcher* w, Node* n) : _next_draw_order(0), + _root(n), _watcher(w) { } + +INLINE int GuiManager::get_next_draw_order(void) const { + return _next_draw_order; +} + +INLINE void GuiManager::set_next_draw_order(int v) { +#ifndef NDEBUG + if (v < _next_draw_order) + gui_cat->warning() << "GuiManager::set_next_draw_order(" << v + << ") is < existing (" << _next_draw_order << ")" + << endl; +#endif /* NDEBUG */ + this->_next_draw_order = v; +} diff --git a/panda/src/gui/guiManager.cxx b/panda/src/gui/guiManager.cxx index 3c952f9675..d71aaba0a1 100644 --- a/panda/src/gui/guiManager.cxx +++ b/panda/src/gui/guiManager.cxx @@ -185,4 +185,5 @@ void GuiManager::recompute_priorities(void) { for (SortSet::iterator j=_sorts.begin(); j!=_sorts.end(); ++j) { p = (*j)->set_draw_order(p); } + _next_draw_order = p; } diff --git a/panda/src/gui/guiManager.h b/panda/src/gui/guiManager.h index fa68b10035..70ca13915b 100644 --- a/panda/src/gui/guiManager.h +++ b/panda/src/gui/guiManager.h @@ -34,6 +34,8 @@ private: typedef set SortSet; SortSet _sorts; + int _next_draw_order; + Node* _root; MouseWatcher* _watcher; @@ -48,6 +50,9 @@ PUBLISHED: void remove_label(GuiLabel*); void recompute_priorities(void); + + INLINE int get_next_draw_order(void) const; + INLINE void set_next_draw_order(int); }; #include "guiManager.I" diff --git a/panda/src/gui/guiRollover.cxx b/panda/src/gui/guiRollover.cxx index 0976b74419..4bcb7bdc1a 100644 --- a/panda/src/gui/guiRollover.cxx +++ b/panda/src/gui/guiRollover.cxx @@ -148,6 +148,9 @@ void GuiRollover::set_priority(GuiItem* i, const GuiItem::Priority p) { if (p == P_Highest) { _off->set_priority(_off, GuiLabel::P_HIGHEST); _on->set_priority(_on, GuiLabel::P_HIGHEST); + } else if (p == P_Lowest) { + _off->set_priority(_off, GuiLabel::P_LOWEST); + _on->set_priority(_on, GuiLabel::P_LOWEST); } else { i->set_priority(_off, ((p==P_Low)?P_High:P_Low)); i->set_priority(_on, ((p==P_Low)?P_High:P_Low)); diff --git a/panda/src/gui/guiSign.cxx b/panda/src/gui/guiSign.cxx index 6c9c9b966d..d41719d15f 100644 --- a/panda/src/gui/guiSign.cxx +++ b/panda/src/gui/guiSign.cxx @@ -70,6 +70,8 @@ void GuiSign::set_pos(const LVector3f& p) { void GuiSign::set_priority(GuiItem* i, const GuiItem::Priority p) { if (p == P_Highest) _sign->set_priority(_sign, GuiLabel::P_HIGHEST); + else if (p == P_Lowest) + _sign->set_priority(_sign, GuiLabel::P_LOWEST); else i->set_priority(_sign, ((p==P_Low)?P_High:P_Low)); GuiItem::set_priority(i, p);