diff --git a/panda/src/gui/config_gui.cxx b/panda/src/gui/config_gui.cxx index a1fa659b2b..e296173a01 100644 --- a/panda/src/gui/config_gui.cxx +++ b/panda/src/gui/config_gui.cxx @@ -4,6 +4,13 @@ //////////////////////////////////////////////////////////////////// #include "config_gui.h" +#include "guiLabel.h" +#include "guiRegion.h" +#include "guiItem.h" +#include "guiSign.h" +#include "guiRollover.h" +#include "guiButton.h" +#include "guiFrame.h" #include @@ -11,4 +18,11 @@ Configure(config_gui); NotifyCategoryDef(gui, ""); ConfigureFn(config_gui) { + GuiLabel::init_type(); + GuiRegion::init_type(); + GuiItem::init_type(); + GuiSign::init_type(); + GuiRollover::init_type(); + GuiButton::init_type(); + GuiFrame::init_type(); } diff --git a/panda/src/gui/guiButton.cxx b/panda/src/gui/guiButton.cxx index 999371d70f..dcd324c16c 100644 --- a/panda/src/gui/guiButton.cxx +++ b/panda/src/gui/guiButton.cxx @@ -13,6 +13,8 @@ typedef map ButtonMap; static ButtonMap buttons; +TypeHandle GuiButton::_type_handle; + inline void GetExtents(GuiLabel* v, GuiLabel* w, GuiLabel* x, GuiLabel* y, GuiLabel* z, float& l, float& r, float& b, float& t) { float l1, l2, r1, r2, b1, b2, t1, t2; @@ -167,7 +169,9 @@ GuiButton::GuiButton(const string& name, GuiLabel* up, GuiLabel* down) _down_rollover((GuiLabel*)0L), _inactive((GuiLabel*)0L), _up_event(name + "-up"), _up_rollover_event(""), _down_event(name +"-down"), _down_rollover_event(""), - _inactive_event(""), _state(GuiButton::NONE) { + _inactive_event(""), _up_scale(up->get_scale()), _upr_scale(1.), + _down_scale(down->get_scale()), _downr_scale(1.), _inactive_scale(1.), + _state(GuiButton::NONE) { GetExtents(up, down, _up_rollover, _down_rollover, _inactive, _left, _right, _bottom, _top); _rgn = new GuiRegion("button-" + name, _left, _right, _bottom, _top, true); @@ -184,7 +188,9 @@ GuiButton::GuiButton(const string& name, GuiLabel* up, GuiLabel* down, _down_rollover((GuiLabel*)0L), _inactive(inactive), _up_event(name + "-up"), _up_rollover_event(""), _down_event(name +"-down"), _down_rollover_event(""), - _inactive_event(name + "-inactive"), _state(GuiButton::NONE) { + _inactive_event(name + "-inactive"), _up_scale(up->get_scale()), + _upr_scale(1.), _down_scale(down->get_scale()), _downr_scale(1.), + _inactive_scale(inactive->get_scale()), _state(GuiButton::NONE) { GetExtents(up, down, _up_rollover, _down_rollover, inactive, _left, _right, _bottom, _top); _rgn = new GuiRegion("button-" + name, _left, _right, _bottom, _top, true); @@ -201,7 +207,10 @@ GuiButton::GuiButton(const string& name, GuiLabel* up, GuiLabel* up_roll, _down_rollover(down_roll), _inactive(inactive), _up_event(name + "-up"), _up_rollover_event(name + "-up-rollover"), _down_event(name +"-down"), _down_rollover_event(name + "-down-rollover"), - _inactive_event(name + "-inactive"), _state(GuiButton::NONE) { + _inactive_event(name + "-inactive"), _up_scale(up->get_scale()), + _upr_scale(up_roll->get_scale()), _down_scale(down->get_scale()), + _downr_scale(down_roll->get_scale()), + _inactive_scale(inactive->get_scale()), _state(GuiButton::NONE) { GetExtents(up, down, up_roll, down_roll, inactive, _left, _right, _bottom, _top); _rgn = new GuiRegion("button-" + name, _left, _right, _bottom, _top, true); @@ -235,20 +244,21 @@ void GuiButton::manage(GuiManager* mgr, EventHandler& eh) { } void GuiButton::unmanage(void) { - _mgr->remove_region(_rgn); + if (_mgr != (GuiManager*)0L) + _mgr->remove_region(_rgn); switch_state(NONE); GuiItem::unmanage(); } void GuiButton::set_scale(float f) { - _up->set_scale(f); - _down->set_scale(f); + _up->set_scale(f * _up_scale); + _down->set_scale(f * _down_scale); if (_up_rollover != (GuiLabel*)0L) - _up_rollover->set_scale(f); + _up_rollover->set_scale(f * _upr_scale); if (_down_rollover != (GuiLabel*)0L) - _down_rollover->set_scale(f); + _down_rollover->set_scale(f * _downr_scale); if (_inactive != (GuiLabel*)0L) - _inactive->set_scale(f); + _inactive->set_scale(f * _inactive_scale); GuiItem::set_scale(f); this->recompute_frame(); } diff --git a/panda/src/gui/guiButton.h b/panda/src/gui/guiButton.h index 380ea65295..762b466f2e 100644 --- a/panda/src/gui/guiButton.h +++ b/panda/src/gui/guiButton.h @@ -13,14 +13,20 @@ class EXPCL_PANDA GuiButton : public GuiItem { private: - GuiLabel* _up; - GuiLabel* _up_rollover; - GuiLabel* _down; - GuiLabel* _down_rollover; - GuiLabel* _inactive; + PT(GuiLabel) _up; + PT(GuiLabel) _up_rollover; + PT(GuiLabel) _down; + PT(GuiLabel) _down_rollover; + PT(GuiLabel) _inactive; string _up_event, _up_rollover_event, _down_event, _down_rollover_event; string _inactive_event; - GuiRegion* _rgn; + PT(GuiRegion) _rgn; + + float _up_scale; + float _upr_scale; + float _down_scale; + float _downr_scale; + float _inactive_scale; enum States { NONE, UP, UP_ROLLOVER, DOWN, DOWN_ROLLOVER, INACTIVE, INACTIVE_ROLLOVER }; @@ -65,6 +71,25 @@ public: virtual void set_pos(const LVector3f&); virtual void output(ostream&) const; +public: + // type interface + static TypeHandle get_class_type(void) { + return _type_handle; + } + static void init_type(void) { + GuiItem::init_type(); + register_type(_type_handle, "GuiButton", + GuiItem::get_class_type()); + } + virtual TypeHandle get_type(void) const { + return get_class_type(); + } + virtual TypeHandle force_init_type(void) { + init_type(); + return get_class_type(); + } +private: + static TypeHandle _type_handle; }; #include "guiButton.I" diff --git a/panda/src/gui/guiFrame.cxx b/panda/src/gui/guiFrame.cxx index 59bf70d12a..fcd925f51b 100644 --- a/panda/src/gui/guiFrame.cxx +++ b/panda/src/gui/guiFrame.cxx @@ -5,6 +5,8 @@ #include "guiFrame.h" +TypeHandle GuiFrame::_type_handle; + GuiFrame::Boxes::iterator GuiFrame::find_box(GuiItem* item) { bool found = false; Boxes::iterator ret = _items.end(); @@ -190,7 +192,7 @@ void GuiFrame::unmanage(void) { void GuiFrame::set_scale(float f) { for (Boxes::iterator i=_items.begin(); i!=_items.end(); ++i) - (*i).get_item()->set_scale(f); + (*i).get_item()->set_scale(f * (*i).get_scale()); GuiItem::set_scale(f); this->recompute_frame(); } diff --git a/panda/src/gui/guiFrame.h b/panda/src/gui/guiFrame.h index 1803b763ed..6b1ab2c32e 100644 --- a/panda/src/gui/guiFrame.h +++ b/panda/src/gui/guiFrame.h @@ -39,18 +39,22 @@ private: typedef vector Connections; class Box { private: - GuiItem* _thing; + PT(GuiItem) _thing; + float _scale; Connections _links; public: - inline Box(void) : _thing((GuiItem*)0L) {} - inline Box(GuiItem* i) : _thing(i) {} - inline Box(const Box& c) : _thing(c._thing), _links(c._links) {} + inline Box(void) : _thing((GuiItem*)0L), _scale(1.) {} + inline Box(GuiItem* i) : _thing(i), _scale(i->get_scale()) {} + inline Box(const Box& c) : _thing(c._thing), _scale(c._scale), + _links(c._links) {} ~Box(void) {} inline void set_item(GuiItem* i) { _thing = i; } + inline void set_scale(float f) { _scale = f; } inline void add_link(Connection c) { _links.push_back(c); } inline GuiItem* get_item(void) const { return _thing; } + inline float get_scale(void) const { return _scale; } inline int get_num_links(void) const { return _links.size(); } inline Packing get_nth_packing(int n) const { return _links[n].get_how(); } inline GuiItem* get_nth_to(int n) const { return _links[n].get_who(); } @@ -81,6 +85,25 @@ public: virtual void set_pos(const LVector3f&); virtual void output(ostream&) const; +public: + // type interface + static TypeHandle get_class_type(void) { + return _type_handle; + } + static void init_type(void) { + GuiItem::init_type(); + register_type(_type_handle, "GuiFrame", + GuiItem::get_class_type()); + } + virtual TypeHandle get_type(void) const { + return get_class_type(); + } + virtual TypeHandle force_init_type(void) { + init_type(); + return get_class_type(); + } +private: + static TypeHandle _type_handle; }; #include "guiFrame.I" diff --git a/panda/src/gui/guiItem.cxx b/panda/src/gui/guiItem.cxx index b84c262f5f..9b3ed7b13f 100644 --- a/panda/src/gui/guiItem.cxx +++ b/panda/src/gui/guiItem.cxx @@ -5,6 +5,8 @@ #include "guiItem.h" +TypeHandle GuiItem::_type_handle; + void GuiItem::recompute_frame(void) { } @@ -16,6 +18,8 @@ GuiItem::GuiItem(const string& name) : Namable(name), _added_hooks(false), } GuiItem::~GuiItem(void) { + if (gui_cat->is_debug()) + gui_cat->debug() << "deleting item '" << this->get_name() << "'" << endl; this->unmanage(); } diff --git a/panda/src/gui/guiItem.h b/panda/src/gui/guiItem.h index 1ed0ed1b5e..99e830418f 100644 --- a/panda/src/gui/guiItem.h +++ b/panda/src/gui/guiItem.h @@ -10,7 +10,7 @@ #include -class EXPCL_PANDA GuiItem : public Namable { +class EXPCL_PANDA GuiItem : public TypedReferenceCount, public Namable { protected: bool _added_hooks; float _scale, _left, _right, _bottom, _top; @@ -38,6 +38,25 @@ public: INLINE LVector4f get_frame(void) const; virtual void output(ostream&) const = 0; +public: + // type interface + static TypeHandle get_class_type(void) { + return _type_handle; + } + static void init_type(void) { + TypedReferenceCount::init_type(); + register_type(_type_handle, "GuiItem", + TypedReferenceCount::get_class_type()); + } + virtual TypeHandle get_type(void) const { + return get_class_type(); + } + virtual TypeHandle force_init_type(void) { + init_type(); + return get_class_type(); + } +private: + static TypeHandle _type_handle; }; #include "guiItem.I" diff --git a/panda/src/gui/guiLabel.cxx b/panda/src/gui/guiLabel.cxx index f05596b6dd..2091a49a0e 100644 --- a/panda/src/gui/guiLabel.cxx +++ b/panda/src/gui/guiLabel.cxx @@ -9,6 +9,8 @@ #include #include +TypeHandle GuiLabel::_type_handle; + void GuiLabel::recompute_transform(void) { switch (_type) { case SIMPLE_TEXT: @@ -92,6 +94,8 @@ void GuiLabel::set_properties(void) { } GuiLabel::~GuiLabel(void) { + if (gui_cat->is_debug()) + gui_cat->debug() << "deleting label (0x" << (void*)this << ")" << endl; } #include @@ -220,15 +224,27 @@ void GuiLabel::get_extents(float& l, float& r, float& b, float& t) { } float GuiLabel::get_width(void) { - float l, r, b, t; - this->get_extents(l, r, b, t); - return (r - l); + float w; + TextNode* n = DCAST(TextNode, _geom); + if (n->has_card()) { + LVecBase4f v = n->get_card_actual(); + w = v[1] - v[0]; + } else { + w = n->get_width(); + } + return w; } float GuiLabel::get_height(void) { - float l, r, b, t; - this->get_extents(l, r, b, t); - return (t - b); + float h; + TextNode* n = DCAST(TextNode, _geom); + if (n->has_card()) { + LVecBase4f v = n->get_card_actual(); + h = v[3] - v[2]; + } else { + h = n->get_width(); + } + return h; } void GuiLabel::set_foreground_color(const Colorf& color) { diff --git a/panda/src/gui/guiLabel.h b/panda/src/gui/guiLabel.h index 20aea75239..9d5ac7b6f0 100644 --- a/panda/src/gui/guiLabel.h +++ b/panda/src/gui/guiLabel.h @@ -13,18 +13,19 @@ #include #include #include +#include // label-ish behavior for GUI objects (labels, buttons, rollovers) class GuiManager; -class EXPCL_PANDA GuiLabel { +class EXPCL_PANDA GuiLabel : public TypedReferenceCount { private: enum LabelType { NONE, SIMPLE_TEXTURE, SIMPLE_TEXT }; LabelType _type; PT_Node _geom; RenderRelation* _arc; - Texture* _tex; + PT(Texture) _tex; RenderRelation* _internal; float _scale; @@ -73,6 +74,25 @@ public: INLINE Colorf get_foreground_color(void) const; INLINE Colorf get_background_color(void) const; +public: + // type interface + static TypeHandle get_class_type(void) { + return _type_handle; + } + static void init_type(void) { + TypedReferenceCount::init_type(); + register_type(_type_handle, "GuiLabel", + TypedReferenceCount::get_class_type()); + } + virtual TypeHandle get_type(void) const { + return get_class_type(); + } + virtual TypeHandle force_init_type(void) { + init_type(); + return get_class_type(); + } +private: + static TypeHandle _type_handle; }; #include "guiLabel.I" diff --git a/panda/src/gui/guiRegion.cxx b/panda/src/gui/guiRegion.cxx index 62738a877e..7c8849af4f 100644 --- a/panda/src/gui/guiRegion.cxx +++ b/panda/src/gui/guiRegion.cxx @@ -3,7 +3,12 @@ // //////////////////////////////////////////////////////////////////// +#include "config_gui.h" #include "guiRegion.h" +TypeHandle GuiRegion::_type_handle; + GuiRegion::~GuiRegion(void) { + if (gui_cat->is_debug()) + gui_cat->debug() << "deleting region '" << *this << "'" << endl; } diff --git a/panda/src/gui/guiRegion.h b/panda/src/gui/guiRegion.h index 2a02ba0be5..1102191c2c 100644 --- a/panda/src/gui/guiRegion.h +++ b/panda/src/gui/guiRegion.h @@ -9,12 +9,13 @@ #include #include #include +#include // container for active regions of a GUI class GuiManager; -class EXPCL_PANDA GuiRegion : public Namable { +class EXPCL_PANDA GuiRegion : public TypedReferenceCount, public Namable { private: float _left, _right, _bottom, _top; PT(MouseWatcherRegion) _region; @@ -32,6 +33,25 @@ public: INLINE void set_region(float, float, float, float); INLINE LVector4f get_frame(void) const; +public: + // type interface + static TypeHandle get_class_type(void) { + return _type_handle; + } + static void init_type(void) { + TypedReferenceCount::init_type(); + register_type(_type_handle, "GuiRegion", + TypedReferenceCount::get_class_type()); + } + virtual TypeHandle get_type(void) const { + return get_class_type(); + } + virtual TypeHandle force_init_type(void) { + init_type(); + return get_class_type(); + } +private: + static TypeHandle _type_handle; }; #include "guiRegion.I" diff --git a/panda/src/gui/guiRollover.cxx b/panda/src/gui/guiRollover.cxx index 51ffbc0712..571cfbad45 100644 --- a/panda/src/gui/guiRollover.cxx +++ b/panda/src/gui/guiRollover.cxx @@ -11,6 +11,8 @@ typedef map RolloverMap; static RolloverMap rollovers; +TypeHandle GuiRollover::_type_handle; + inline void GetExtents(GuiLabel* x, GuiLabel* y, float& l, float& r, float& b, float& t) { float l1, l2, r1, r2, b1, b2, t1, t2; @@ -39,7 +41,8 @@ void GuiRollover::recompute_frame(void) { } GuiRollover::GuiRollover(const string& name, GuiLabel* off, GuiLabel* on) - : GuiItem(name), _off(off), _on(on), _state(false) { + : GuiItem(name), _off(off), _on(on), _off_scale(off->get_scale()), + _on_scale(on->get_scale()), _state(false) { GetExtents(off, on, _left, _right, _bottom, _top); _rgn = new GuiRegion("rollover-" + name, _left, _right, _bottom, _top, false); @@ -68,15 +71,17 @@ void GuiRollover::manage(GuiManager* mgr, EventHandler& eh) { } void GuiRollover::unmanage(void) { - _mgr->remove_region(_rgn); - _mgr->remove_label(_off); - _mgr->remove_label(_on); + if (_mgr != (GuiManager*)0L) { + _mgr->remove_region(_rgn); + _mgr->remove_label(_off); + _mgr->remove_label(_on); + } GuiItem::unmanage(); } void GuiRollover::set_scale(float f) { - _on->set_scale(f); - _off->set_scale(f); + _on->set_scale(f * _on_scale); + _off->set_scale(f * _off_scale); GuiItem::set_scale(f); recompute_frame(); } diff --git a/panda/src/gui/guiRollover.h b/panda/src/gui/guiRollover.h index c1cc9306f3..08cda83e07 100644 --- a/panda/src/gui/guiRollover.h +++ b/panda/src/gui/guiRollover.h @@ -13,9 +13,12 @@ class EXPCL_PANDA GuiRollover : public GuiItem { private: - GuiLabel* _off; - GuiLabel* _on; - GuiRegion* _rgn; + PT(GuiLabel) _off; + PT(GuiLabel) _on; + PT(GuiRegion) _rgn; + + float _off_scale; + float _on_scale; bool _state; @@ -36,6 +39,25 @@ public: virtual void set_pos(const LVector3f&); virtual void output(ostream&) const; +public: + // type interface + static TypeHandle get_class_type(void) { + return _type_handle; + } + static void init_type(void) { + GuiItem::init_type(); + register_type(_type_handle, "GuiRollover", + GuiItem::get_class_type()); + } + virtual TypeHandle get_type(void) const { + return get_class_type(); + } + virtual TypeHandle force_init_type(void) { + init_type(); + return get_class_type(); + } +private: + static TypeHandle _type_handle; }; #include "guiRollover.I" diff --git a/panda/src/gui/guiSign.cxx b/panda/src/gui/guiSign.cxx index 8be833c97b..15bce427ac 100644 --- a/panda/src/gui/guiSign.cxx +++ b/panda/src/gui/guiSign.cxx @@ -6,13 +6,15 @@ #include "guiSign.h" #include "config_gui.h" +TypeHandle GuiSign::_type_handle; + void GuiSign::recompute_frame(void) { GuiItem::recompute_frame(); _sign->get_extents(_left, _right, _bottom, _top); } -GuiSign::GuiSign(const string& name, GuiLabel* sign) : GuiItem(name), - _sign(sign) { +GuiSign::GuiSign(const string& name, GuiLabel* sign) + : GuiItem(name), _sign(sign), _sign_scale(sign->get_scale()) { _sign->get_extents(_left, _right, _bottom, _top); } @@ -32,12 +34,13 @@ void GuiSign::manage(GuiManager* mgr, EventHandler& eh) { } void GuiSign::unmanage(void) { - _mgr->remove_label(_sign); + if (_mgr != (GuiManager*)0L) + _mgr->remove_label(_sign); GuiSign::unmanage(); } void GuiSign::set_scale(float f) { - _sign->set_scale(f); + _sign->set_scale(f * _sign_scale); GuiItem::set_scale(f); recompute_frame(); } diff --git a/panda/src/gui/guiSign.h b/panda/src/gui/guiSign.h index e36201494d..c27e3ec7ef 100644 --- a/panda/src/gui/guiSign.h +++ b/panda/src/gui/guiSign.h @@ -12,7 +12,8 @@ class EXPCL_PANDA GuiSign : public GuiItem { private: - GuiLabel* _sign; + PT(GuiLabel) _sign; + float _sign_scale; INLINE GuiSign(void); virtual void recompute_frame(void); @@ -27,6 +28,25 @@ public: virtual void set_pos(const LVector3f&); virtual void output(ostream&) const; +public: + // type interface + static TypeHandle get_class_type(void) { + return _type_handle; + } + static void init_type(void) { + GuiItem::init_type(); + register_type(_type_handle, "GuiSign", + GuiItem::get_class_type()); + } + virtual TypeHandle get_type(void) const { + return get_class_type(); + } + virtual TypeHandle force_init_type(void) { + init_type(); + return get_class_type(); + } +private: + static TypeHandle _type_handle; }; #include "guiSign.I" diff --git a/panda/src/testbed/gui_demo.cxx b/panda/src/testbed/gui_demo.cxx index 9b59935a5c..e8cb959cf8 100644 --- a/panda/src/testbed/gui_demo.cxx +++ b/panda/src/testbed/gui_demo.cxx @@ -51,7 +51,7 @@ extern PT(GeomNode) geomnode; extern RenderRelation* first_arc; -static GuiFrame* global_frame; +static PT(GuiFrame) global_frame; static void setup_gui(void) { GuiManager* mgr = GuiManager::get_ptr(main_win, mak); @@ -205,7 +205,7 @@ static void event_2(CPT_Event) { } static void event_3(CPT_Event) { - delete global_frame; + global_frame = (GuiFrame*)0L; } void demo_keys(EventHandler&) {