add groove, ridge; prevent circular ref counts

This commit is contained in:
David Rose 2001-07-09 23:04:53 +00:00
parent cd10e23931
commit ef25e2597d
15 changed files with 527 additions and 13 deletions

View File

@ -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 \

View File

@ -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

View File

@ -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:

View File

@ -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();
}

View File

@ -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;

View File

@ -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();
}
////////////////////////////////////////////////////////////////////

View File

@ -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;

View File

@ -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;
}

View File

@ -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);
}
}

View File

@ -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

View File

@ -21,8 +21,8 @@
#include "string_utils.h"
TypeHandle PGMouseWatcherRegion::_type_handle;
int PGMouseWatcherRegion::_next_index = 0;
TypeHandle PGMouseWatcherRegion::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: PGMouseWatcherRegion::Constructor

View File

@ -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;
};

View File

@ -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();
}

View File

@ -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);
}
}

View File

@ -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"