From ef25e2597d494a2ce833a3897cf0ee7eb67e810d Mon Sep 17 00:00:00 2001 From: David Rose Date: Mon, 9 Jul 2001 23:04:53 +0000 Subject: [PATCH] add groove, ridge; prevent circular ref counts --- panda/src/pgui/Sources.pp | 3 + panda/src/pgui/pgButton.I | 12 ++ panda/src/pgui/pgButton.h | 1 + panda/src/pgui/pgFrameStyle.cxx | 245 ++++++++++++++++++++++++ panda/src/pgui/pgFrameStyle.h | 5 +- panda/src/pgui/pgItem.I | 58 +++++- panda/src/pgui/pgItem.h | 5 + panda/src/pgui/pgMouseWatcherGroup.I | 40 ++++ panda/src/pgui/pgMouseWatcherGroup.cxx | 38 ++++ panda/src/pgui/pgMouseWatcherGroup.h | 67 +++++++ panda/src/pgui/pgMouseWatcherRegion.cxx | 2 +- panda/src/pgui/pgMouseWatcherRegion.h | 2 +- panda/src/pgui/pgTop.I | 28 +++ panda/src/pgui/pgTop.cxx | 20 +- panda/src/pgui/pgTop.h | 14 +- 15 files changed, 527 insertions(+), 13 deletions(-) create mode 100644 panda/src/pgui/pgMouseWatcherGroup.I create mode 100644 panda/src/pgui/pgMouseWatcherGroup.cxx create mode 100644 panda/src/pgui/pgMouseWatcherGroup.h diff --git a/panda/src/pgui/Sources.pp b/panda/src/pgui/Sources.pp index 909d63b565..5365d431f4 100644 --- a/panda/src/pgui/Sources.pp +++ b/panda/src/pgui/Sources.pp @@ -12,6 +12,7 @@ #define SOURCES \ config_pgui.h \ pgButton.I pgButton.h \ + pgMouseWatcherGroup.I pgMouseWatcherGroup.h \ pgMouseWatcherParameter.I pgMouseWatcherParameter.h \ pgFrameStyle.I pgFrameStyle.h \ pgItem.I pgItem.h \ @@ -22,6 +23,7 @@ #define SOURCES $[SOURCES] \ config_pgui.cxx \ pgButton.cxx \ + pgMouseWatcherGroup.cxx \ pgMouseWatcherParameter.cxx \ pgFrameStyle.cxx \ pgItem.cxx \ @@ -30,6 +32,7 @@ #define INSTALL_HEADERS \ pgButton.I pgButton.h \ + pgMouseWatcherGroup.I pgMouseWatcherGroup.h \ pgMouseWatcherParameter.I pgMouseWatcherParameter.h \ pgFrameStyle.I pgFrameStyle.h \ pgItem.I pgItem.h \ diff --git a/panda/src/pgui/pgButton.I b/panda/src/pgui/pgButton.I index 4349c9f93f..c32329de9b 100644 --- a/panda/src/pgui/pgButton.I +++ b/panda/src/pgui/pgButton.I @@ -66,6 +66,18 @@ set_active(bool active) { } } +//////////////////////////////////////////////////////////////////// +// Function: PGButton::get_click_prefix +// Access: Published, Static +// Description: Returns the prefix that is used to define the click +// event for all PGButtons. The click event is the +// concatenation of this string followed by get_id(). +//////////////////////////////////////////////////////////////////// +INLINE string PGButton:: +get_click_prefix() { + return "click-"; +} + //////////////////////////////////////////////////////////////////// // Function: PGButton::get_click_event // Access: Published diff --git a/panda/src/pgui/pgButton.h b/panda/src/pgui/pgButton.h index d820a958c1..c35b26b29b 100644 --- a/panda/src/pgui/pgButton.h +++ b/panda/src/pgui/pgButton.h @@ -72,6 +72,7 @@ PUBLISHED: bool remove_click_button(const ButtonHandle &button); bool has_click_button(const ButtonHandle &button); + INLINE static string get_click_prefix(); INLINE string get_click_event(const ButtonHandle &button) const; private: diff --git a/panda/src/pgui/pgFrameStyle.cxx b/panda/src/pgui/pgFrameStyle.cxx index 097f55287d..12a1ad0748 100644 --- a/panda/src/pgui/pgFrameStyle.cxx +++ b/panda/src/pgui/pgFrameStyle.cxx @@ -39,6 +39,12 @@ operator << (ostream &out, PGFrameStyle::Type type) { case PGFrameStyle::T_bevel_in: return out << "bevel_in"; + + case PGFrameStyle::T_groove: + return out << "groove"; + + case PGFrameStyle::T_ridge: + return out << "ridge"; } return out << "**unknown(" << (int)type << ")**"; @@ -84,6 +90,8 @@ xform(const LMatrix4f &mat) { case T_bevel_out: case T_bevel_in: + case T_groove: + case T_ridge: return true; } @@ -122,6 +130,14 @@ generate_into(Node *node, const LVecBase4f &frame) { gnode = generate_bevel_geom(frame, true); break; + case T_groove: + gnode = generate_groove_geom(frame, true); + break; + + case T_ridge: + gnode = generate_groove_geom(frame, false); + break; + default: break; } @@ -338,3 +354,232 @@ generate_bevel_geom(const LVecBase4f &frame, bool in) { return gnode.p(); } + +//////////////////////////////////////////////////////////////////// +// Function: PGFrameStyle::generate_groove_geom +// Access: Private +// Description: Generates the GeomNode appropriate to a T_groove or +// T_ridge frame. +//////////////////////////////////////////////////////////////////// +PT_Node PGFrameStyle:: +generate_groove_geom(const LVecBase4f &frame, bool in) { + // + // Colors: + // + // + // * * * * * * * * * * * * * * * * * * * * * * * * * * * + // * * * * + // * * ctop * * + // * * * * + // * * * * * * * * * * * * * * * * * * * * * + // * * * * * * + // * * * cbottom * * * + // * * * * * * + // * * * * * * * * * * * * * * * + // * * * * * * + // * * * * * * + // * cleft * cright* _color * cleft * cright* + // * * * * * * + // * * * * * * + // * * * * * * * * * * * * * * * + // * * * * * * + // * * * ctop * * * + // * * * * * * + // * * * * * * * * * * * * * * * * * * * * * + // * * * * + // * * cbottom * * + // * * * * + // * * * * * * * * * * * * * * * * * * * * * * * * * * * + // + // + // Vertices: + // + // tristrip 1: + // 4 * * * * * * * * * * * * * * * * * * * * * * * * * 6 + // * * * + // * * * + // * * * + // * 5 * * * * * * * * * * * * * * * * * 7 + // * * + // * * + // * * + // * * + // * * + // * * + // * * + // * * + // * * + // * * + // * * + // * * + // * * + // * 3 * * * * * * * * * * * * * * * * * 1 + // * * * + // * * * + // * * * + // 2 * * * * * * * * * * * * * * * * * * * * * * * * * 0 + // + // tristrip 2: + // 4 * * * * * * * * * * * * * * * * * 6 + // * * * + // * * * + // * * * + // * 5 * * * * * * * * * 7 + // * * + // * * + // * * + // * * + // * * + // * 3 * * * * * * * * * 1 + // * * * + // * * * + // * * * + // 2 * * * * * * * * * * * * * * * * * 0 + // + // tristrip 3: + // 1 + // * * + // * * + // * * + // 3 * + // * * * + // * * * + // * * * + // 7 * * * * * * * * * 5 * * + // * * * * + // * * * * + // * * * * + // * * * * + // * * * * + // 6 * * * * * * * * * 4 * * + // * * * + // * * * + // * * * + // 2 * + // * * + // * * + // * * + // 0 + + PT(GeomNode) gnode = new GeomNode("groove"); + + float left = frame[0]; + float right = frame[1]; + float bottom = frame[2]; + float top = frame[3]; + + float mid_left = left + 0.5 * _width[0]; + float mid_right = right - 0.5 * _width[0]; + float mid_bottom = bottom + 0.5 * _width[1]; + float mid_top = top - 0.5 * _width[1]; + + float inner_left = left + _width[0]; + float inner_right = right - _width[0]; + float inner_bottom = bottom + _width[1]; + float inner_top = top - _width[1]; + + float left_color_scale = 1.2; + float right_color_scale = 0.8; + float bottom_color_scale = 0.7; + float top_color_scale = 1.3; + + if (in) { + right_color_scale = 1.2; + left_color_scale = 0.8; + top_color_scale = 0.7; + bottom_color_scale = 1.3; + } + + // Clamp all colors at white, and don't scale the alpha. + Colorf cleft(min(_color[0] * left_color_scale, 1.0f), + min(_color[1] * left_color_scale, 1.0f), + min(_color[2] * left_color_scale, 1.0f), + _color[3]); + + Colorf cright(min(_color[0] * right_color_scale, 1.0f), + min(_color[1] * right_color_scale, 1.0f), + min(_color[2] * right_color_scale, 1.0f), + _color[3]); + + Colorf cbottom(min(_color[0] * bottom_color_scale, 1.0f), + min(_color[1] * bottom_color_scale, 1.0f), + min(_color[2] * bottom_color_scale, 1.0f), + _color[3]); + + Colorf ctop(min(_color[0] * top_color_scale, 1.0f), + min(_color[1] * top_color_scale, 1.0f), + min(_color[2] * top_color_scale, 1.0f), + _color[3]); + + // Now make the tristrips. + Geom *geom = new GeomTristrip; + gnode->add_geom(geom); + + PTA_int lengths; + PTA_Vertexf verts; + PTA_Colorf colors; + + // Tristrip 1. + lengths.push_back(8); + + verts.push_back(Vertexf(right, 0.0, bottom)); + verts.push_back(Vertexf(mid_right, 0.0, mid_bottom)); + verts.push_back(Vertexf(left, 0.0, bottom)); + verts.push_back(Vertexf(mid_left, 0.0, mid_bottom)); + verts.push_back(Vertexf(left, 0.0, top)); + verts.push_back(Vertexf(mid_left, 0.0, mid_top)); + verts.push_back(Vertexf(right, 0.0, top)); + verts.push_back(Vertexf(mid_right, 0.0, mid_top)); + + colors.push_back(cbottom); + colors.push_back(cbottom); + colors.push_back(cleft); + colors.push_back(cleft); + colors.push_back(ctop); + colors.push_back(ctop); + + // Tristrip 2. + lengths.push_back(8); + + verts.push_back(Vertexf(mid_right, 0.0, mid_bottom)); + verts.push_back(Vertexf(inner_right, 0.0, inner_bottom)); + verts.push_back(Vertexf(mid_left, 0.0, mid_bottom)); + verts.push_back(Vertexf(inner_left, 0.0, inner_bottom)); + verts.push_back(Vertexf(mid_left, 0.0, mid_top)); + verts.push_back(Vertexf(inner_left, 0.0, inner_top)); + verts.push_back(Vertexf(mid_right, 0.0, mid_top)); + verts.push_back(Vertexf(inner_right, 0.0, inner_top)); + + colors.push_back(ctop); + colors.push_back(ctop); + colors.push_back(cright); + colors.push_back(cright); + colors.push_back(cbottom); + colors.push_back(cbottom); + + // Tristrip 3. + lengths.push_back(8); + + verts.push_back(Vertexf(right, 0.0, bottom)); + verts.push_back(Vertexf(right, 0.0, top)); + verts.push_back(Vertexf(mid_right, 0.0, mid_bottom)); + verts.push_back(Vertexf(mid_right, 0.0, mid_top)); + verts.push_back(Vertexf(inner_right, 0.0, inner_bottom)); + verts.push_back(Vertexf(inner_right, 0.0, inner_top)); + verts.push_back(Vertexf(inner_left, 0.0, inner_bottom)); + verts.push_back(Vertexf(inner_left, 0.0, inner_top)); + + colors.push_back(cright); + colors.push_back(cright); + colors.push_back(cleft); + colors.push_back(cleft); + colors.push_back(_color); + colors.push_back(_color); + + geom->set_num_prims(3); + geom->set_lengths(lengths); + geom->set_coords(verts, G_PER_VERTEX); + geom->set_colors(colors, G_PER_COMPONENT); + + return gnode.p(); +} diff --git a/panda/src/pgui/pgFrameStyle.h b/panda/src/pgui/pgFrameStyle.h index f1876cce40..98768439b7 100644 --- a/panda/src/pgui/pgFrameStyle.h +++ b/panda/src/pgui/pgFrameStyle.h @@ -43,7 +43,9 @@ PUBLISHED: T_none, T_flat, T_bevel_out, - T_bevel_in + T_bevel_in, + T_groove, + T_ridge }; INLINE void set_type(Type type); @@ -66,6 +68,7 @@ public: private: PT_Node generate_flat_geom(const LVecBase4f &frame); PT_Node generate_bevel_geom(const LVecBase4f &frame, bool in); + PT_Node generate_groove_geom(const LVecBase4f &frame, bool in); private: Type _type; diff --git a/panda/src/pgui/pgItem.I b/panda/src/pgui/pgItem.I index 7561d2134e..42788f40d7 100644 --- a/panda/src/pgui/pgItem.I +++ b/panda/src/pgui/pgItem.I @@ -163,6 +163,56 @@ get_id() const { return _region->get_name(); } +//////////////////////////////////////////////////////////////////// +// Function: PGItem::get_enter_prefix +// Access: Published, Static +// Description: Returns the prefix that is used to define the enter +// event for all PGItems. The enter event is the +// concatenation of this string followed by get_id(). +//////////////////////////////////////////////////////////////////// +INLINE string PGItem:: +get_enter_prefix() { + return "enter-"; +} + +//////////////////////////////////////////////////////////////////// +// Function: PGItem::get_exit_prefix +// Access: Published, Static +// Description: Returns the prefix that is used to define the exit +// event for all PGItems. The exit event is the +// concatenation of this string followed by get_id(). +//////////////////////////////////////////////////////////////////// +INLINE string PGItem:: +get_exit_prefix() { + return "exit-"; +} + +//////////////////////////////////////////////////////////////////// +// Function: PGItem::get_press_prefix +// Access: Published, Static +// Description: Returns the prefix that is used to define the press +// event for all PGItems. The press event is the +// concatenation of this string followed by a button +// name, followed by a hyphen and get_id(). +//////////////////////////////////////////////////////////////////// +INLINE string PGItem:: +get_press_prefix() { + return "press-"; +} + +//////////////////////////////////////////////////////////////////// +// Function: PGItem::get_release_prefix +// Access: Published, Static +// Description: Returns the prefix that is used to define the release +// event for all PGItems. The release event is the +// concatenation of this string followed by a button +// name, followed by a hyphen and get_id(). +//////////////////////////////////////////////////////////////////// +INLINE string PGItem:: +get_release_prefix() { + return "release-"; +} + //////////////////////////////////////////////////////////////////// // Function: PGItem::get_enter_event // Access: Published @@ -171,7 +221,7 @@ get_id() const { //////////////////////////////////////////////////////////////////// INLINE string PGItem:: get_enter_event() const { - return "enter-" + get_id(); + return get_enter_prefix() + get_id(); } //////////////////////////////////////////////////////////////////// @@ -182,7 +232,7 @@ get_enter_event() const { //////////////////////////////////////////////////////////////////// INLINE string PGItem:: get_exit_event() const { - return "exit-" + get_id(); + return get_exit_prefix() + get_id(); } //////////////////////////////////////////////////////////////////// @@ -195,7 +245,7 @@ get_exit_event() const { //////////////////////////////////////////////////////////////////// INLINE string PGItem:: get_press_event(const ButtonHandle &button) const { - return "press-" + button.get_name() + "-" + get_id(); + return get_press_prefix() + button.get_name() + "-" + get_id(); } //////////////////////////////////////////////////////////////////// @@ -208,7 +258,7 @@ get_press_event(const ButtonHandle &button) const { //////////////////////////////////////////////////////////////////// INLINE string PGItem:: get_release_event(const ButtonHandle &button) const { - return "release-" + button.get_name() + "-" + get_id(); + return get_release_prefix() + button.get_name() + "-" + get_id(); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/pgui/pgItem.h b/panda/src/pgui/pgItem.h index 36a808d1f2..5685bd9ec7 100644 --- a/panda/src/pgui/pgItem.h +++ b/panda/src/pgui/pgItem.h @@ -92,6 +92,11 @@ PUBLISHED: void set_frame_style(int state, const PGFrameStyle &style); INLINE const string &get_id() const; + INLINE static string get_enter_prefix(); + INLINE static string get_exit_prefix(); + INLINE static string get_press_prefix(); + INLINE static string get_release_prefix(); + INLINE string get_enter_event() const; INLINE string get_exit_event() const; INLINE string get_press_event(const ButtonHandle &button) const; diff --git a/panda/src/pgui/pgMouseWatcherGroup.I b/panda/src/pgui/pgMouseWatcherGroup.I new file mode 100644 index 0000000000..42bfa71385 --- /dev/null +++ b/panda/src/pgui/pgMouseWatcherGroup.I @@ -0,0 +1,40 @@ +// Filename: pgMouseWatcherGroup.I +// Created by: drose (09Jul01) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://www.panda3d.org/license.txt . +// +// To contact the maintainers of this program write to +// panda3d@yahoogroups.com . +// +//////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////// +// Function: PGMouseWatcherGroup::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE PGMouseWatcherGroup:: +PGMouseWatcherGroup(PGTop *top) : _top(top) { +} + +//////////////////////////////////////////////////////////////////// +// Function: PGMouseWatcherGroup::clear_top +// Access: Public +// Description: Called by the PGTop object to indicate that it is no +// longer keeping the pointer to the PGMouseWatcherGroup +// object. +//////////////////////////////////////////////////////////////////// +INLINE void PGMouseWatcherGroup:: +clear_top(PGTop *top) { + nassertv(_top == top); + _top = (PGTop *)NULL; +} diff --git a/panda/src/pgui/pgMouseWatcherGroup.cxx b/panda/src/pgui/pgMouseWatcherGroup.cxx new file mode 100644 index 0000000000..c8d861fd7e --- /dev/null +++ b/panda/src/pgui/pgMouseWatcherGroup.cxx @@ -0,0 +1,38 @@ +// Filename: pgMouseWatcherGroup.cxx +// Created by: drose (09Jul01) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://www.panda3d.org/license.txt . +// +// To contact the maintainers of this program write to +// panda3d@yahoogroups.com . +// +//////////////////////////////////////////////////////////////////// + +#include "pgMouseWatcherGroup.h" +#include "pgTop.h" + +TypeHandle PGMouseWatcherGroup::_type_handle; + +//////////////////////////////////////////////////////////////////// +// Function: PGMouseWatcherGroup::Destructor +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +PGMouseWatcherGroup:: +~PGMouseWatcherGroup() { + cerr << "~PGMouseWatcherGroup()\n"; + // When the MouseWatcherGroup destructs for whatever reason, the + // PGTop object should lose its MouseWatcher. + if (_top != (PGTop *)NULL) { + _top->_watcher_group = (PGMouseWatcherGroup *)NULL; + _top->set_mouse_watcher((MouseWatcher *)NULL); + } +} diff --git a/panda/src/pgui/pgMouseWatcherGroup.h b/panda/src/pgui/pgMouseWatcherGroup.h new file mode 100644 index 0000000000..aab0e52e45 --- /dev/null +++ b/panda/src/pgui/pgMouseWatcherGroup.h @@ -0,0 +1,67 @@ +// Filename: pgMouseWatcherGroup.h +// Created by: drose (09Jul01) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://www.panda3d.org/license.txt . +// +// To contact the maintainers of this program write to +// panda3d@yahoogroups.com . +// +//////////////////////////////////////////////////////////////////// + +#ifndef PGMOUSEWATCHERGROUP_H +#define PGMOUSEWATCHERGROUP_H + +#include "pandabase.h" + +#include "mouseWatcherGroup.h" +#include "pointerTo.h" + +class PGTop; + +//////////////////////////////////////////////////////////////////// +// Class : PGMouseWatcherGroup +// Description : This is a specialization on MouseWatcherGroup, to +// associate it with a PGTop. Originally we had PGTop +// multiply inheriting from NamedNode and +// MouseWatcherGroup, but this causes problems with +// circular reference counts. +//////////////////////////////////////////////////////////////////// +class EXPCL_PANDA PGMouseWatcherGroup : public MouseWatcherGroup { +public: + INLINE PGMouseWatcherGroup(PGTop *top); + virtual ~PGMouseWatcherGroup(); + + INLINE void clear_top(PGTop *top); + +private: + PGTop *_top; + +public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + MouseWatcherGroup::init_type(); + register_type(_type_handle, "PGMouseWatcherGroup", + MouseWatcherGroup::get_class_type()); + } + virtual TypeHandle get_type() const { + return get_class_type(); + } + virtual TypeHandle force_init_type() {init_type(); return get_class_type();} + +private: + static TypeHandle _type_handle; +}; + +#include "pgMouseWatcherGroup.I" + +#endif diff --git a/panda/src/pgui/pgMouseWatcherRegion.cxx b/panda/src/pgui/pgMouseWatcherRegion.cxx index 8e956572ed..103104bd13 100644 --- a/panda/src/pgui/pgMouseWatcherRegion.cxx +++ b/panda/src/pgui/pgMouseWatcherRegion.cxx @@ -21,8 +21,8 @@ #include "string_utils.h" -TypeHandle PGMouseWatcherRegion::_type_handle; int PGMouseWatcherRegion::_next_index = 0; +TypeHandle PGMouseWatcherRegion::_type_handle; //////////////////////////////////////////////////////////////////// // Function: PGMouseWatcherRegion::Constructor diff --git a/panda/src/pgui/pgMouseWatcherRegion.h b/panda/src/pgui/pgMouseWatcherRegion.h index e43a45c016..eee2ca170b 100644 --- a/panda/src/pgui/pgMouseWatcherRegion.h +++ b/panda/src/pgui/pgMouseWatcherRegion.h @@ -44,6 +44,7 @@ public: private: PGItem *_item; + static int _next_index; public: static TypeHandle get_class_type() { @@ -61,7 +62,6 @@ public: private: static TypeHandle _type_handle; - static int _next_index; friend class PGItem; }; diff --git a/panda/src/pgui/pgTop.I b/panda/src/pgui/pgTop.I index b68ad8a918..bee626dad2 100644 --- a/panda/src/pgui/pgTop.I +++ b/panda/src/pgui/pgTop.I @@ -54,3 +54,31 @@ INLINE MouseWatcher *PGTop:: get_mouse_watcher() const { return _watcher; } + +//////////////////////////////////////////////////////////////////// +// Function: PGTop::add_region +// Access: Published +// Description: Adds the indicated region to the set of regions in +// the group. Returns true if it was successfully +// added, or false if it was already on the list. +//////////////////////////////////////////////////////////////////// +INLINE bool PGTop:: +add_region(MouseWatcherRegion *region) { + if (_watcher_group == (PGMouseWatcherGroup *)NULL) { + return false; + } + return _watcher_group->add_region(region); +} + +//////////////////////////////////////////////////////////////////// +// Function: PGTop::clear_regions +// Access: Published +// Description: Removes all the regions from the group. +//////////////////////////////////////////////////////////////////// +INLINE void PGTop:: +clear_regions() { + if (_watcher_group == (PGMouseWatcherGroup *)NULL) { + return; + } + _watcher_group->clear_regions(); +} diff --git a/panda/src/pgui/pgTop.cxx b/panda/src/pgui/pgTop.cxx index 54c100aee8..050f7a1eaf 100644 --- a/panda/src/pgui/pgTop.cxx +++ b/panda/src/pgui/pgTop.cxx @@ -18,6 +18,7 @@ #include "pgTop.h" #include "pgItem.h" +#include "pgMouseWatcherGroup.h" #include "arcChain.h" #include "graphicsStateGuardian.h" @@ -44,6 +45,7 @@ TypeHandle PGTop::_type_handle; PGTop:: PGTop(const string &name) : NamedNode(name) { + _watcher_group = (PGMouseWatcherGroup *)NULL; _gsg = (GraphicsStateGuardian *)NULL; _trav = (RenderTraverser *)NULL; @@ -60,6 +62,7 @@ PGTop(const string &name) : NamedNode(name) //////////////////////////////////////////////////////////////////// PGTop:: ~PGTop() { + set_mouse_watcher((MouseWatcher *)NULL); } //////////////////////////////////////////////////////////////////// @@ -136,12 +139,21 @@ has_sub_render() const { //////////////////////////////////////////////////////////////////// void PGTop:: set_mouse_watcher(MouseWatcher *watcher) { - if (_watcher != (MouseWatcher *)NULL) { - _watcher->remove_group(this); + if (_watcher_group != (PGMouseWatcherGroup *)NULL) { + _watcher_group->clear_top(this); } - _watcher = watcher; if (_watcher != (MouseWatcher *)NULL) { - _watcher->add_group(this); + _watcher->remove_group(_watcher_group); + } + + _watcher = watcher; + _watcher_group = (PGMouseWatcherGroup *)NULL; + + if (_watcher != (MouseWatcher *)NULL) { + // We create a new PGMouseWatcherGroup, but we don't own the + // reference count; the watcher will own this for us. + _watcher_group = new PGMouseWatcherGroup(this); + _watcher->add_group(_watcher_group); } } diff --git a/panda/src/pgui/pgTop.h b/panda/src/pgui/pgTop.h index eac01addf6..660c05057f 100644 --- a/panda/src/pgui/pgTop.h +++ b/panda/src/pgui/pgTop.h @@ -21,8 +21,9 @@ #include "pandabase.h" +#include "pgMouseWatcherGroup.h" + #include "namedNode.h" -#include "mouseWatcherGroup.h" #include "mouseWatcher.h" #include "pointerTo.h" #include "allAttributesWrapper.h" @@ -30,6 +31,7 @@ class GraphicsStateGuardian; class RenderTraverser; class ArcChain; +class PGMouseWatcherGroup; //////////////////////////////////////////////////////////////////// // Class : PGTop @@ -45,7 +47,7 @@ class ArcChain; // depth-first, left-to-right order, appropriate for 2-d // objects. //////////////////////////////////////////////////////////////////// -class EXPCL_PANDA PGTop : public NamedNode, public MouseWatcherGroup { +class EXPCL_PANDA PGTop : public NamedNode { PUBLISHED: PGTop(const string &name = ""); virtual ~PGTop(); @@ -65,10 +67,16 @@ PUBLISHED: void set_mouse_watcher(MouseWatcher *watcher); INLINE MouseWatcher *get_mouse_watcher() const; +private: + // These methods duplicate the functionality of MouseWatcherGroup. + INLINE bool add_region(MouseWatcherRegion *region); + INLINE void clear_regions(); + private: void r_traverse(Node *node, const ArcChain &chain); PT(MouseWatcher) _watcher; + PGMouseWatcherGroup *_watcher_group; GraphicsStateGuardian *_gsg; RenderTraverser *_trav; AllAttributesWrapper _attrib; @@ -92,6 +100,8 @@ public: private: static TypeHandle _type_handle; + + friend class PGMouseWatcherGroup; }; #include "pgTop.I"