mirror of
https://github.com/panda3d/panda3d.git
synced 2026-04-21 05:59:27 -05:00
initial pgui stuff
This commit is contained in:
@@ -16,7 +16,7 @@
|
||||
parametrics pnm \
|
||||
pnmimagetypes pnmimage sgattrib sgmanip sgraph sgraphutil \
|
||||
switchnode text tform tiff lerp loader putil effects \
|
||||
audio gui pandabase
|
||||
audio gui pgui pandabase
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -48,8 +48,8 @@
|
||||
|
||||
#define INCLUDED_SOURCES \
|
||||
allAttributesWrapper.cxx allTransitionsWrapper.cxx \
|
||||
arcChain.cxxbitMask32Transition.cxx \
|
||||
boundedObject.cxxconfig_graph.cxx graphReducer.cxx \
|
||||
arcChain.cxx bitMask32Transition.cxx \
|
||||
boundedObject.cxx config_graph.cxx graphReducer.cxx \
|
||||
immediateAttribute.cxx immediateTransition.cxx \
|
||||
lmatrix4fTransition.cxx multiNodeAttribute.cxx \
|
||||
multiNodeTransition.cxx namedNode.cxx node.cxx \
|
||||
@@ -58,7 +58,7 @@
|
||||
nodeTransition.cxx nodeTransitionCache.cxx \
|
||||
nodeTransitionCacheEntry.cxx nodeTransitionWrapper.cxx \
|
||||
nodeTransitions.cxx \
|
||||
nullAttributeWrapper.cxxnullLevelState.cxx \
|
||||
nullAttributeWrapper.cxx nullLevelState.cxx \
|
||||
nullTransitionWrapper.cxx onAttribute.cxx onOffAttribute.cxx \
|
||||
onOffTransition.cxx onTransition.cxx pt_NamedNode.cxx \
|
||||
pt_Node.cxx pt_NodeRelation.cxx vector_PT_Node.cxx \
|
||||
|
||||
@@ -301,27 +301,82 @@ operator = (const ArcChain ©) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ArcChain::has_node
|
||||
// Function: ArcChain::is_empty
|
||||
// Access: Public
|
||||
// Description: Returns true if there is at least a top node in the
|
||||
// chain, or false otherwise.
|
||||
// Description: Returns true if the ArcChain contains no nodes and no
|
||||
// arcs.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE_GRAPH bool ArcChain::
|
||||
has_node() const {
|
||||
return (_head != (ArcComponent *)NULL);
|
||||
is_empty() const {
|
||||
return (_head == (ArcComponent *)NULL);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ArcChain::is_singleton
|
||||
// Access: Public
|
||||
// Description: Returns true if the ArcChain contains exactly one
|
||||
// node, and no arcs.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE_GRAPH bool ArcChain::
|
||||
is_singleton() const {
|
||||
return (_head != (ArcComponent *)NULL && _head->is_top_node());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ArcChain::has_arcs
|
||||
// Access: Public
|
||||
// Description: Returns true if there are any arcs in the chain, or
|
||||
// false otherwise.
|
||||
// Description: Returns true if the ArcChain contains at least one
|
||||
// arc, and therefore at least two nodes. This is the
|
||||
// same thing as asking get_num_arcs() > 0, but is
|
||||
// easier to compute.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE_GRAPH bool ArcChain::
|
||||
has_arcs() const {
|
||||
return (_head != (ArcComponent *)NULL && !_head->is_top_node());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ArcChain::get_num_arcs
|
||||
// Access: Public
|
||||
// Description: Returns the number of arcs in the path.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE_GRAPH int ArcChain::
|
||||
get_num_arcs() const {
|
||||
if (!has_arcs()) {
|
||||
return 0;
|
||||
}
|
||||
return get_num_nodes() - 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ArcChain::node
|
||||
// Access: Public
|
||||
// Description: Returns the bottom node of the path, or NULL if the
|
||||
// path is empty.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE_GRAPH Node *ArcChain::
|
||||
node() const {
|
||||
if (is_empty()) {
|
||||
return (Node *)NULL;
|
||||
}
|
||||
return _head->get_node();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ArcChain::arc
|
||||
// Access: Public
|
||||
// Description: Returns the bottom arc of the path, or NULL if the
|
||||
// path is empty or is a singleton.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE_GRAPH NodeRelation *ArcChain::
|
||||
arc() const {
|
||||
if (!has_arcs()) {
|
||||
// A singleton or empty list.
|
||||
return (NodeRelation *)NULL;
|
||||
}
|
||||
return _head->get_arc();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ArcChain::begin
|
||||
// Access: Public
|
||||
|
||||
@@ -60,6 +60,95 @@ operator = (const ArcComponent ©) {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ArcChain::get_num_nodes
|
||||
// Access: Public
|
||||
// Description: Returns the number of nodes in the path. This is
|
||||
// always one more than the number of arcs (except for
|
||||
// a completely empty path).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int ArcChain::
|
||||
get_num_nodes() const {
|
||||
int num = 0;
|
||||
ArcComponent *comp = _head;
|
||||
while (comp != (ArcComponent *)NULL) {
|
||||
num++;
|
||||
comp = comp->get_next();
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ArcChain::get_node
|
||||
// Access: Public
|
||||
// Description: Returns the nth node of the path, where 0 is the
|
||||
// bottom node and get_num_nodes() - 1 is the top node.
|
||||
// This requires iterating through the path.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
Node *ArcChain::
|
||||
get_node(int index) const {
|
||||
nassertr(index >= 0 && index < get_num_nodes(), NULL);
|
||||
|
||||
ArcComponent *comp = _head;
|
||||
while (index > 0) {
|
||||
// If this assertion fails, the index was out of range.
|
||||
nassertr(comp != (ArcComponent *)NULL, NULL);
|
||||
comp = comp->get_next();
|
||||
index--;
|
||||
}
|
||||
|
||||
// If this assertion fails, the index was out of range.
|
||||
nassertr(comp != (ArcComponent *)NULL, NULL);
|
||||
return comp->get_node();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ArcChain::get_arc
|
||||
// Access: Public
|
||||
// Description: Returns the nth arc of the path, where 0 is the arc
|
||||
// above the bottom node node and get_num_arcs() - 1 is
|
||||
// the arc below the top node. This requires iterating
|
||||
// through the path.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
NodeRelation *ArcChain::
|
||||
get_arc(int index) const {
|
||||
nassertr(index >= 0 && index < get_num_arcs(), NULL);
|
||||
|
||||
ArcComponent *comp = _head;
|
||||
while (index > 0) {
|
||||
// If this assertion fails, the index was out of range.
|
||||
nassertr(comp != (ArcComponent *)NULL, NULL);
|
||||
comp = comp->get_next();
|
||||
index--;
|
||||
}
|
||||
|
||||
// If either assertion fails, the index was out of range.
|
||||
nassertr(comp != (ArcComponent *)NULL, NULL);
|
||||
nassertr(comp->has_arc(), NULL);
|
||||
return comp->get_arc();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ArcChain::get_top_node
|
||||
// Access: Public
|
||||
// Description: Returns the top node of the path, or NULL if the path
|
||||
// is empty. This requires iterating through the path.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
Node *ArcChain::
|
||||
get_top_node() const {
|
||||
if (is_empty()) {
|
||||
return (Node *)NULL;
|
||||
}
|
||||
|
||||
ArcComponent *comp = _head;
|
||||
while (!comp->is_top_node()) {
|
||||
comp = comp->get_next();
|
||||
nassertr(comp != (ArcComponent *)NULL, NULL);
|
||||
}
|
||||
|
||||
return comp->get_node();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ArcChain::r_output
|
||||
// Access: Private
|
||||
|
||||
@@ -141,8 +141,23 @@ public:
|
||||
INLINE_GRAPH ArcChain(const ArcChain ©);
|
||||
INLINE_GRAPH void operator = (const ArcChain ©);
|
||||
|
||||
INLINE_GRAPH bool has_node() const;
|
||||
// Methods to query an ArcChain's contents.
|
||||
PUBLISHED:
|
||||
INLINE_GRAPH bool is_empty() const;
|
||||
INLINE_GRAPH bool is_singleton() const;
|
||||
INLINE_GRAPH bool has_arcs() const;
|
||||
int get_num_nodes() const;
|
||||
Node *get_node(int index) const;
|
||||
|
||||
INLINE_GRAPH int get_num_arcs() const;
|
||||
NodeRelation *get_arc(int index) const;
|
||||
|
||||
Node *get_top_node() const;
|
||||
INLINE_GRAPH Node *node() const;
|
||||
INLINE_GRAPH NodeRelation *arc() const;
|
||||
|
||||
public:
|
||||
// Methods to make an ArcChain behave like an STL container.
|
||||
|
||||
INLINE_GRAPH const_iterator begin() const;
|
||||
INLINE_GRAPH const_iterator end() const;
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
#define OTHER_LIBS interrogatedb:c dconfig:c dtoolconfig:m \
|
||||
dtoolutil:c dtoolbase:c dtool:m
|
||||
|
||||
#begin lib_target
|
||||
#define TARGET pgui
|
||||
#define LOCAL_LIBS \
|
||||
text tform graph linmath event putil gobj \
|
||||
mathutil sgraph sgraphutil
|
||||
|
||||
// #define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx
|
||||
|
||||
#define SOURCES \
|
||||
config_pgui.h \
|
||||
pgButton.I pgButton.h \
|
||||
pgFrameStyle.I pgFrameStyle.h \
|
||||
pgItem.I pgItem.h \
|
||||
pgMouseWatcherRegion.I pgMouseWatcherRegion.h \
|
||||
pgTop.I pgTop.h
|
||||
|
||||
// #define INCLUDED_SOURCES \
|
||||
#define SOURCES $[SOURCES] \
|
||||
config_pgui.cxx \
|
||||
pgButton.cxx \
|
||||
pgFrameStyle.cxx \
|
||||
pgItem.cxx \
|
||||
pgMouseWatcherRegion.cxx \
|
||||
pgTop.cxx
|
||||
|
||||
#define INSTALL_HEADERS \
|
||||
pgButton.I pgButton.h \
|
||||
pgFrameStyle.I pgFrameStyle.h \
|
||||
pgItem.I pgItem.h \
|
||||
pgMouseWatcherRegion.I pgMouseWatcherRegion.h \
|
||||
pgTop.I pgTop.h
|
||||
|
||||
|
||||
#define IGATESCAN all
|
||||
|
||||
#end lib_target
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
// Filename: config_pgui.cxx
|
||||
// Created by: drose (02Jul01)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "config_pgui.h"
|
||||
#include "pgButton.h"
|
||||
#include "pgItem.h"
|
||||
#include "pgMouseWatcherRegion.h"
|
||||
#include "pgTop.h"
|
||||
|
||||
#include "dconfig.h"
|
||||
|
||||
Configure(config_pgui);
|
||||
NotifyCategoryDef(pgui, "");
|
||||
|
||||
ConfigureFn(config_pgui) {
|
||||
PGButton::init_type();
|
||||
PGItem::init_type();
|
||||
PGMouseWatcherRegion::init_type();
|
||||
PGTop::init_type();
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
// Filename: config_pgui.h
|
||||
// Created by: drose (02Jul01)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 CONFIG_PGUI_H
|
||||
#define CONFIG_PGUI_H
|
||||
|
||||
#include <pandabase.h>
|
||||
#include <notifyCategoryProxy.h>
|
||||
|
||||
NotifyCategoryDecl(pgui, EXPCL_PANDA, EXPTP_PANDA);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,78 @@
|
||||
// Filename: pgButton.I
|
||||
// Created by: drose (03Jul01)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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: PGButton::setup
|
||||
// Access: Published
|
||||
// Description: Sets up the button using the indicated NodePath as
|
||||
// arbitrary geometry.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void PGButton::
|
||||
setup(const ArcChain &ready) {
|
||||
setup(ready, ready, ready, ready);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGButton::setup
|
||||
// Access: Published
|
||||
// Description: Sets up the button using the indicated NodePath as
|
||||
// arbitrary geometry.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void PGButton::
|
||||
setup(const ArcChain &ready, const ArcChain &depressed) {
|
||||
setup(ready, depressed, ready, ready);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGButton::setup
|
||||
// Access: Published
|
||||
// Description: Sets up the button using the indicated NodePath as
|
||||
// arbitrary geometry.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void PGButton::
|
||||
setup(const ArcChain &ready, const ArcChain &depressed,
|
||||
const ArcChain &rollover) {
|
||||
setup(ready, depressed, rollover, ready);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGButton::set_active
|
||||
// Access: Public
|
||||
// Description: Toggles the active/inactive state of the button. In
|
||||
// the case of a PGButton, this also changes its visual
|
||||
// appearance.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void PGButton::
|
||||
set_active(bool active) {
|
||||
if (active != get_active()) {
|
||||
set_state(active ? S_ready : S_inactive);
|
||||
PGItem::set_active(active);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGButton::get_click_event
|
||||
// Access: Published
|
||||
// Description: Returns the event name that will be thrown when the
|
||||
// button is clicked normally.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE string PGButton::
|
||||
get_click_event() const {
|
||||
return "click-" + get_id();
|
||||
}
|
||||
@@ -0,0 +1,212 @@
|
||||
// Filename: pgButton.cxx
|
||||
// Created by: drose (03Jul01)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "pgButton.h"
|
||||
#include "throw_event.h"
|
||||
#include "renderRelation.h"
|
||||
#include "colorTransition.h"
|
||||
|
||||
TypeHandle PGButton::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGButton::Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PGButton::
|
||||
PGButton(const string &name) : PGItem(name)
|
||||
{
|
||||
_button_down = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGButton::Destructor
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PGButton::
|
||||
~PGButton() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGButton::Copy Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PGButton::
|
||||
PGButton(const PGButton ©) :
|
||||
PGItem(copy)
|
||||
{
|
||||
_button_down = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGButton::Copy Assignment Operator
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PGButton::
|
||||
operator = (const PGButton ©) {
|
||||
PGItem::operator = (copy);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGButton::make_copy
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns a newly-allocated Node that is a shallow copy
|
||||
// of this one. It will be a different Node pointer,
|
||||
// but its internal data may or may not be shared with
|
||||
// that of the original Node.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
Node *PGButton::
|
||||
make_copy() const {
|
||||
return new PGButton(*this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGButton::enter
|
||||
// Access: Public, Virtual
|
||||
// Description: This is a callback hook function, called whenever the
|
||||
// mouse enters the region.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PGButton::
|
||||
enter() {
|
||||
if (get_active()) {
|
||||
set_state(_button_down ? S_depressed : S_rollover);
|
||||
}
|
||||
PGItem::enter();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGButton::exit
|
||||
// Access: Public, Virtual
|
||||
// Description: This is a callback hook function, called whenever the
|
||||
// mouse exits the region.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PGButton::
|
||||
exit() {
|
||||
if (get_active()) {
|
||||
set_state(S_ready);
|
||||
}
|
||||
PGItem::exit();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGButton::button_down
|
||||
// Access: Public, Virtual
|
||||
// Description: This is a callback hook function, called whenever a
|
||||
// mouse or keyboard button is depressed while the mouse
|
||||
// is within the region.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PGButton::
|
||||
button_down(ButtonHandle button) {
|
||||
if (get_active()) {
|
||||
_button_down = true;
|
||||
set_state(S_depressed);
|
||||
}
|
||||
PGItem::button_down(button);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGButton::button_up
|
||||
// Access: Public, Virtual
|
||||
// Description: This is a callback hook function, called whenever a
|
||||
// mouse or keyboard button previously depressed with
|
||||
// button_down() is release. The bool is_within flag is
|
||||
// true if the button was released while the mouse was
|
||||
// still within the region, or false if it was released
|
||||
// outside the region.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PGButton::
|
||||
button_up(ButtonHandle button, bool is_within) {
|
||||
_button_down = false;
|
||||
if (get_active()) {
|
||||
if (is_within) {
|
||||
set_state(S_rollover);
|
||||
click();
|
||||
} else {
|
||||
set_state(S_ready);
|
||||
}
|
||||
}
|
||||
PGItem::button_up(button, is_within);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGButton::click
|
||||
// Access: Public, Virtual
|
||||
// Description: This is a callback hook function, called whenever the
|
||||
// button is clicked normally.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PGButton::
|
||||
click() {
|
||||
throw_event(get_click_event());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGButton::setup
|
||||
// Access: Published
|
||||
// Description: Sets up the button as a default text button using the
|
||||
// indicated label string. The TextNode defined by
|
||||
// PGItem::get_text_node() will be used to create the
|
||||
// label geometry. This automatically sets up the frame
|
||||
// according to the size of the text.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PGButton::
|
||||
setup(const string &label) {
|
||||
TextNode *text_node = get_text_node();
|
||||
text_node->set_text(label);
|
||||
PT_Node geom = text_node->generate();
|
||||
|
||||
new RenderRelation(get_state_def(S_ready), geom);
|
||||
NodeRelation *dep = new RenderRelation(get_state_def(S_depressed), geom);
|
||||
new RenderRelation(get_state_def(S_rollover), geom);
|
||||
new RenderRelation(get_state_def(S_inactive), geom);
|
||||
|
||||
PGFrameStyle style;
|
||||
style.set_type(PGFrameStyle::T_flat);
|
||||
style.set_color(1.0, 1.0, 1.0, 1.0);
|
||||
set_frame_style(S_ready, style);
|
||||
|
||||
style.set_color(0.0, 0.0, 0.0, 1.0);
|
||||
set_frame_style(S_depressed, style);
|
||||
ColorTransition *col_trans = new ColorTransition(Colorf(0.0, 1.0, 1.0, 1.0));
|
||||
dep->set_transition(col_trans);
|
||||
|
||||
style.set_color(1.0, 1.0, 0.0, 1.0);
|
||||
set_frame_style(S_rollover, style);
|
||||
|
||||
style.set_color(0.6, 0.6, 0.6, 1.0);
|
||||
set_frame_style(S_inactive, style);
|
||||
|
||||
set_frame(text_node->get_card_actual());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGButton::setup
|
||||
// Access: Published
|
||||
// Description: Sets up the button using the indicated NodePath as
|
||||
// arbitrary geometry.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PGButton::
|
||||
setup(const ArcChain &ready, const ArcChain &depressed,
|
||||
const ArcChain &rollover, const ArcChain &inactive) {
|
||||
instance_to_state_def(S_ready, ready);
|
||||
instance_to_state_def(S_depressed, depressed);
|
||||
instance_to_state_def(S_rollover, rollover);
|
||||
instance_to_state_def(S_inactive, inactive);
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
// Filename: pgButton.h
|
||||
// Created by: drose (03Jul01)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 PGBUTTON_H
|
||||
#define PGBUTTON_H
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "pgItem.h"
|
||||
#include "arcChain.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : PGButton
|
||||
// Description : This is a particular kind of PGItem that is
|
||||
// specialized to behave like a normal button object.
|
||||
// It keeps track of its own state, and handles mouse
|
||||
// events sensibly.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA PGButton : public PGItem {
|
||||
PUBLISHED:
|
||||
PGButton(const string &name = "");
|
||||
virtual ~PGButton();
|
||||
|
||||
public:
|
||||
PGButton(const PGButton ©);
|
||||
void operator = (const PGButton ©);
|
||||
|
||||
virtual Node *make_copy() const;
|
||||
|
||||
virtual void enter();
|
||||
virtual void exit();
|
||||
virtual void button_down(ButtonHandle button);
|
||||
virtual void button_up(ButtonHandle button, bool is_within);
|
||||
|
||||
virtual void click();
|
||||
|
||||
PUBLISHED:
|
||||
enum State {
|
||||
S_ready = 0,
|
||||
S_depressed,
|
||||
S_rollover,
|
||||
S_inactive
|
||||
};
|
||||
|
||||
void setup(const string &label);
|
||||
INLINE void setup(const ArcChain &ready);
|
||||
INLINE void setup(const ArcChain &ready, const ArcChain &depressed);
|
||||
INLINE void setup(const ArcChain &ready, const ArcChain &depressed,
|
||||
const ArcChain &rollover);
|
||||
void setup(const ArcChain &ready, const ArcChain &depressed,
|
||||
const ArcChain &rollover, const ArcChain &inactive);
|
||||
|
||||
INLINE void set_active(bool active);
|
||||
|
||||
INLINE string get_click_event() const;
|
||||
|
||||
private:
|
||||
bool _button_down;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
PGItem::init_type();
|
||||
register_type(_type_handle, "PGButton",
|
||||
PGItem::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 "pgButton.I"
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,150 @@
|
||||
// Filename: pgFrameStyle.I
|
||||
// Created by: drose (03Jul01)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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: PGFrameStyle::Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PGFrameStyle::
|
||||
PGFrameStyle() {
|
||||
_type = T_none;
|
||||
_color.set(1.0, 1.0, 1.0, 1.0);
|
||||
_width = 0.01;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGFrameStyle::Copy Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PGFrameStyle::
|
||||
PGFrameStyle(const PGFrameStyle ©) :
|
||||
_type(copy._type),
|
||||
_color(copy._color),
|
||||
_width(copy._width)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGFrameStyle::Copy Assignment Operator
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void PGFrameStyle::
|
||||
operator = (const PGFrameStyle ©) {
|
||||
_type = copy._type;
|
||||
_color = copy._color;
|
||||
_width = copy._width;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGFrameStyle::Destructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PGFrameStyle::
|
||||
~PGFrameStyle() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGFrameStyle::set_type
|
||||
// Access: Published
|
||||
// Description: Sets the basic type of frame.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void PGFrameStyle::
|
||||
set_type(PGFrameStyle::Type type) {
|
||||
_type = type;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGFrameStyle::get_type
|
||||
// Access: Published
|
||||
// Description: Returns the basic type of frame.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PGFrameStyle::Type PGFrameStyle::
|
||||
get_type() const {
|
||||
return _type;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGFrameStyle::set_color
|
||||
// Access: Published
|
||||
// Description: Sets the dominant color of the frame.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void PGFrameStyle::
|
||||
set_color(float r, float g, float b, float a) {
|
||||
set_color(Colorf(r, g, b, a));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGFrameStyle::set_color
|
||||
// Access: Published
|
||||
// Description: Sets the dominant color of the frame.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void PGFrameStyle::
|
||||
set_color(const Colorf &color) {
|
||||
_color = color;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGFrameStyle::set_color
|
||||
// Access: Published
|
||||
// Description: Returns the dominant color of the frame.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const Colorf &PGFrameStyle::
|
||||
get_color() const {
|
||||
return _color;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGFrameStyle::set_width
|
||||
// Access: Published
|
||||
// Description: Sets the width parameter, which has meaning only for
|
||||
// certain frame types. For instance, this is the width
|
||||
// of the bevel for T_bevel_in or T_bevel_out. The
|
||||
// units are in screen units.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void PGFrameStyle::
|
||||
set_width(float width) {
|
||||
_width = width;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGFrameStyle::get_width
|
||||
// Access: Published
|
||||
// Description: Returns the width parameter, which has meaning only
|
||||
// for certain frame types. For instance, this is the
|
||||
// width of the bevel for T_bevel_in or T_bevel_out.
|
||||
// The units are in screen units.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE float PGFrameStyle::
|
||||
get_width() const {
|
||||
return _width;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGFrameStyle ostream output
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE ostream &
|
||||
operator << (ostream &out, const PGFrameStyle &pfs) {
|
||||
pfs.output(out);
|
||||
return out;
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
// Filename: pgFrameStyle.cxx
|
||||
// Created by: drose (03Jul01)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "pgFrameStyle.h"
|
||||
#include "geomTristrip.h"
|
||||
#include "geomNode.h"
|
||||
#include "transparencyProperty.h"
|
||||
#include "transparencyTransition.h"
|
||||
#include "renderRelation.h"
|
||||
|
||||
ostream &
|
||||
operator << (ostream &out, PGFrameStyle::Type type) {
|
||||
switch (type) {
|
||||
case PGFrameStyle::T_none:
|
||||
return out << "none";
|
||||
|
||||
case PGFrameStyle::T_flat:
|
||||
return out << "flat";
|
||||
|
||||
case PGFrameStyle::T_bevel_out:
|
||||
return out << "bevel_out";
|
||||
|
||||
case PGFrameStyle::T_bevel_in:
|
||||
return out << "bevel_in";
|
||||
}
|
||||
|
||||
return out << "**unknown(" << (int)type << ")**";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGFrameStyle::output
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PGFrameStyle::
|
||||
output(ostream &out) const {
|
||||
out << _type << " color = " << _color << " width = " << _width;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGFrameStyle::generate_into
|
||||
// Access: Public
|
||||
// Description: Generates geometry representing a frame of the
|
||||
// indicated size, and parents it to the indicated node,
|
||||
// with a scene graph sort order of -1.
|
||||
//
|
||||
// The return value is the generated arc, if any, or
|
||||
// NULL if nothing is generated.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
NodeRelation *PGFrameStyle::
|
||||
generate_into(Node *node, const LVecBase4f &frame) {
|
||||
NodeRelation *arc = (NodeRelation *)NULL;
|
||||
PT(Geom) geom;
|
||||
|
||||
switch (_type) {
|
||||
case T_none:
|
||||
return (NodeRelation *)NULL;
|
||||
|
||||
case T_flat:
|
||||
geom = generate_flat_geom(frame);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (geom != (Geom *)NULL) {
|
||||
// We've got a basic Geom; create a GeomNode for it.
|
||||
PT(GeomNode) gnode = new GeomNode("frame");
|
||||
gnode->add_geom(geom);
|
||||
arc = new RenderRelation(node, gnode, -1);
|
||||
}
|
||||
|
||||
if (arc != (NodeRelation *)NULL && _color[3] != 1.0) {
|
||||
// We've got some alpha on the color; we need transparency.
|
||||
TransparencyProperty::Mode mode = TransparencyProperty::M_alpha;
|
||||
TransparencyTransition *tt = new TransparencyTransition(mode);
|
||||
arc->set_transition(tt);
|
||||
}
|
||||
|
||||
return arc;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGFrameStyle::generate_flat_geom
|
||||
// Access: Public
|
||||
// Description: Generates the Geom object appropriate to a T_flat
|
||||
// frame.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(Geom) PGFrameStyle::
|
||||
generate_flat_geom(const LVecBase4f &frame) {
|
||||
PT(Geom) geom = new GeomTristrip;
|
||||
|
||||
float left = frame[0];
|
||||
float right = frame[1];
|
||||
float bottom = frame[2];
|
||||
float top = frame[3];
|
||||
|
||||
PTA_int lengths(0);
|
||||
lengths.push_back(4);
|
||||
|
||||
PTA_Vertexf verts;
|
||||
verts.push_back(Vertexf(left, 0.0, top));
|
||||
verts.push_back(Vertexf(left, 0.0, bottom));
|
||||
verts.push_back(Vertexf(right, 0.0, top));
|
||||
verts.push_back(Vertexf(right, 0.0, bottom));
|
||||
|
||||
geom->set_num_prims(1);
|
||||
geom->set_lengths(lengths);
|
||||
|
||||
geom->set_coords(verts, G_PER_VERTEX);
|
||||
|
||||
PTA_Colorf colors;
|
||||
colors.push_back(_color);
|
||||
geom->set_colors(colors, G_OVERALL);
|
||||
|
||||
return geom;
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
// Filename: pgFrameStyle.h
|
||||
// Created by: drose (03Jul01)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 PGFRAMESTYLE_H
|
||||
#define PGFRAMESTYLE_H
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "luse.h"
|
||||
#include "geom.h"
|
||||
#include "pointerTo.h"
|
||||
|
||||
class NodeRelation;
|
||||
class Node;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : PGFrameStyle
|
||||
// Description :
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA PGFrameStyle {
|
||||
PUBLISHED:
|
||||
INLINE PGFrameStyle();
|
||||
INLINE PGFrameStyle(const PGFrameStyle ©);
|
||||
INLINE void operator = (const PGFrameStyle ©);
|
||||
|
||||
INLINE ~PGFrameStyle();
|
||||
|
||||
enum Type {
|
||||
T_none,
|
||||
T_flat,
|
||||
T_bevel_out,
|
||||
T_bevel_in
|
||||
};
|
||||
|
||||
INLINE void set_type(Type type);
|
||||
INLINE Type get_type() const;
|
||||
|
||||
INLINE void set_color(float r, float g, float b, float a);
|
||||
INLINE void set_color(const Colorf &color);
|
||||
INLINE const Colorf &get_color() const;
|
||||
|
||||
INLINE void set_width(float width);
|
||||
INLINE float get_width() const;
|
||||
|
||||
void output(ostream &out) const;
|
||||
|
||||
public:
|
||||
NodeRelation *generate_into(Node *node, const LVecBase4f &frame);
|
||||
|
||||
private:
|
||||
PT(Geom) generate_flat_geom(const LVecBase4f &frame);
|
||||
|
||||
private:
|
||||
Type _type;
|
||||
Colorf _color;
|
||||
float _width;
|
||||
};
|
||||
|
||||
INLINE ostream &operator << (ostream &out, const PGFrameStyle &pfs);
|
||||
ostream &operator << (ostream &out, PGFrameStyle::Type type);
|
||||
|
||||
#include "pgFrameStyle.I"
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,233 @@
|
||||
// Filename: pgItem.I
|
||||
// Created by: drose (02Jul01)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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: PGItem::get_region
|
||||
// Access: Public
|
||||
// Description: Returns the MouseWatcherRegion associated with this
|
||||
// item. Every PGItem has a MouseWatcherRegion
|
||||
// associated with it, that is created when the PGItem
|
||||
// is created; it does not change during the lifetime of
|
||||
// the PGItem. Even items that do not have a frame have
|
||||
// an associated MouseWatcherRegion, although it will
|
||||
// not be used in this case.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PGMouseWatcherRegion *PGItem::
|
||||
get_region() const {
|
||||
return _region;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGItem::set_frame
|
||||
// Access: Published
|
||||
// Description: Sets the bounding rectangle of the item, in local
|
||||
// coordinates. This is the region on screen within
|
||||
// which the mouse will be considered to be within the
|
||||
// item. Normally, it should correspond to the bounding
|
||||
// rectangle of the visible geometry of the item.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void PGItem::
|
||||
set_frame(float left, float right, float bottom, float top) {
|
||||
set_frame(LVecBase4f(left, right, bottom, top));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGItem::set_frame
|
||||
// Access: Published
|
||||
// Description: Sets the bounding rectangle of the item, in local
|
||||
// coordinates. This is the region on screen within
|
||||
// which the mouse will be considered to be within the
|
||||
// item. Normally, it should correspond to the bounding
|
||||
// rectangle of the visible geometry of the item.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void PGItem::
|
||||
set_frame(const LVecBase4f &frame) {
|
||||
_has_frame = true;
|
||||
_frame = frame;
|
||||
mark_frames_stale();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGItem::get_frame
|
||||
// Access: Published
|
||||
// Description: Returns the bounding rectangle of the item. See
|
||||
// set_frame(). It is an error to call this if
|
||||
// has_frame() returns false.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const LVecBase4f &PGItem::
|
||||
get_frame() const {
|
||||
nassertr(has_frame(), _frame);
|
||||
return _frame;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGItem::has_frame
|
||||
// Access: Published
|
||||
// Description: Returns true if the item has a bounding rectangle;
|
||||
// see set_frame().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool PGItem::
|
||||
has_frame() const {
|
||||
return _has_frame;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGItem::clear_frame
|
||||
// Access: Published
|
||||
// Description: Removes the bounding rectangle from the item. It
|
||||
// will no longer be possible to position the mouse
|
||||
// within the item; see set_frame().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void PGItem::
|
||||
clear_frame() {
|
||||
_has_frame = false;
|
||||
mark_frames_stale();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGItem::set_state
|
||||
// Access: Published
|
||||
// Description: Sets the "state" of this particular PGItem.
|
||||
//
|
||||
// The PGItem node will render as if it were the
|
||||
// subgraph assigned to the corresponding index via
|
||||
// set_state_def().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void PGItem::
|
||||
set_state(int state) {
|
||||
_state = state;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGItem::get_state
|
||||
// Access: Published
|
||||
// Description: Returns the "state" of this particular PGItem. See
|
||||
// set_state().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int PGItem::
|
||||
get_state() const {
|
||||
return _state;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGItem::set_active
|
||||
// Access: Published
|
||||
// Description: Sets whether the PGItem is active for mouse watching.
|
||||
// This is not necessarily related to the
|
||||
// active/inactive appearance of the item, which is
|
||||
// controlled by set_state(), but it does affect whether
|
||||
// it responds to mouse events.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void PGItem::
|
||||
set_active(bool active) {
|
||||
_active = active;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGItem::get_active
|
||||
// Access: Published
|
||||
// Description: Returns whether the PGItem is currently active for
|
||||
// mouse events. See set_active().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool PGItem::
|
||||
get_active() const {
|
||||
return _active;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGItem::get_id
|
||||
// Access: Published
|
||||
// Description: Returns the unique ID assigned to this PGItem. This
|
||||
// will be assigned to the region created with the
|
||||
// MouseWatcher, and will thus be used to generate event
|
||||
// names.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const string &PGItem::
|
||||
get_id() const {
|
||||
return _region->get_name();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGItem::get_enter_event
|
||||
// Access: Published
|
||||
// Description: Returns the event name that will be thrown when the
|
||||
// item is active and the mouse enters its frame.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE string PGItem::
|
||||
get_enter_event() const {
|
||||
return "enter-" + get_id();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGItem::get_exit_event
|
||||
// Access: Published
|
||||
// Description: Returns the event name that will be thrown when the
|
||||
// item is active and the mouse exits its frame.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE string PGItem::
|
||||
get_exit_event() const {
|
||||
return "exit-" + get_id();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGItem::get_button_down_event
|
||||
// Access: Published
|
||||
// Description: Returns the event name that will be thrown when the
|
||||
// item is active and a mouse or keyboard button is
|
||||
// depressed while the mouse is within the frame.
|
||||
//
|
||||
// This event will be thrown with one parameter, which
|
||||
// will be the name of the button that generated the
|
||||
// event.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE string PGItem::
|
||||
get_button_down_event() const {
|
||||
return "bdown-" + get_id();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGItem::get_button_up_event
|
||||
// Access: Published
|
||||
// Description: Returns the event name that will be thrown when the
|
||||
// item is active and a mouse or keyboard button,
|
||||
// formerly clicked down is within the frame, is
|
||||
// released.
|
||||
//
|
||||
// This event will be thrown with two parameters, the
|
||||
// first of which will be the name of the button that
|
||||
// generated the event, and the second of which will be
|
||||
// a boolean flag indicating true if the mouse was
|
||||
// within the frame while the button was released.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE string PGItem::
|
||||
get_button_up_event() const {
|
||||
return "bup-" + get_id();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGItem::set_text_node
|
||||
// Access: Published, Static
|
||||
// Description: Changes the TextNode object that will be used by all
|
||||
// PGItems to generate default labels given a string.
|
||||
// This can be loaded with the default font, etc.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void PGItem::
|
||||
set_text_node(TextNode *node) {
|
||||
_text_node = node;
|
||||
}
|
||||
@@ -0,0 +1,396 @@
|
||||
// Filename: pgItem.cxx
|
||||
// Created by: drose (02Jul01)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "pgItem.h"
|
||||
|
||||
#include "namedNode.h"
|
||||
#include "throw_event.h"
|
||||
#include "string_utils.h"
|
||||
#include "arcChain.h"
|
||||
|
||||
TypeHandle PGItem::_type_handle;
|
||||
PT(TextNode) PGItem::_text_node;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGItem::Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PGItem::
|
||||
PGItem(const string &name) : NamedNode(name)
|
||||
{
|
||||
_has_frame = false;
|
||||
_frame.set(0, 0, 0, 0);
|
||||
_region = new PGMouseWatcherRegion(this);
|
||||
_state = 0;
|
||||
_active = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGItem::Destructor
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PGItem::
|
||||
~PGItem() {
|
||||
nassertv(_region->_item == this);
|
||||
_region->_item = (PGItem *)NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGItem::Copy Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PGItem::
|
||||
PGItem(const PGItem ©) :
|
||||
NamedNode(copy),
|
||||
_has_frame(copy._has_frame),
|
||||
_frame(copy._frame),
|
||||
_state(copy._state),
|
||||
_active(copy._active)
|
||||
{
|
||||
_region = new PGMouseWatcherRegion(this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGItem::Copy Assignment Operator
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PGItem::
|
||||
operator = (const PGItem ©) {
|
||||
NamedNode::operator = (copy);
|
||||
_has_frame = copy._has_frame;
|
||||
_frame = copy._frame;
|
||||
_state = copy._state;
|
||||
_active = copy._active;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGItem::make_copy
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns a newly-allocated Node that is a shallow copy
|
||||
// of this one. It will be a different Node pointer,
|
||||
// but its internal data may or may not be shared with
|
||||
// that of the original Node.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
Node *PGItem::
|
||||
make_copy() const {
|
||||
return new PGItem(*this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGItem::activate_region
|
||||
// Access: Public, Virtual
|
||||
// Description: Applies the indicated scene graph transform and order
|
||||
// as determined by the traversal from PGTop.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PGItem::
|
||||
activate_region(const LMatrix4f &transform, int sort) {
|
||||
LPoint3f ll(_frame[0], 0.0, _frame[2]);
|
||||
LPoint3f ur(_frame[1], 0.0, _frame[3]);
|
||||
ll = ll * transform;
|
||||
ur = ur * transform;
|
||||
_region->set_frame(ll[0], ur[0], ll[2], ur[2]);
|
||||
_region->set_sort(sort);
|
||||
_region->set_active(true);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGItem::enter
|
||||
// Access: Public, Virtual
|
||||
// Description: This is a callback hook function, called whenever the
|
||||
// mouse enters the region.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PGItem::
|
||||
enter() {
|
||||
throw_event(get_enter_event());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGItem::exit
|
||||
// Access: Public, Virtual
|
||||
// Description: This is a callback hook function, called whenever the
|
||||
// mouse exits the region.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PGItem::
|
||||
exit() {
|
||||
throw_event(get_exit_event());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGItem::button_down
|
||||
// Access: Public, Virtual
|
||||
// Description: This is a callback hook function, called whenever a
|
||||
// mouse or keyboard button is depressed while the mouse
|
||||
// is within the region.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PGItem::
|
||||
button_down(ButtonHandle button) {
|
||||
throw_event(get_button_down_event(), button.get_name());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGItem::button_up
|
||||
// Access: Public, Virtual
|
||||
// Description: This is a callback hook function, called whenever a
|
||||
// mouse or keyboard button previously depressed with
|
||||
// button_down() is release. The bool is_within flag is
|
||||
// true if the button was released while the mouse was
|
||||
// still within the region, or false if it was released
|
||||
// outside the region.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PGItem::
|
||||
button_up(ButtonHandle button, bool is_within) {
|
||||
throw_event(get_button_up_event(),
|
||||
EventParameter(button.get_name()),
|
||||
EventParameter(is_within));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGItem::get_num_state_defs
|
||||
// Access: Published
|
||||
// Description: Returns one more than the highest-numbered state def
|
||||
// that was ever assigned to the PGItem. The complete
|
||||
// set of state defs assigned may then be retrieved by
|
||||
// indexing from 0 to (get_num_state_defs() - 1).
|
||||
//
|
||||
// This is only an upper limit on the actual number of
|
||||
// state defs, since there may be holes in the list.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int PGItem::
|
||||
get_num_state_defs() const {
|
||||
return _state_defs.size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGItem::has_state_def
|
||||
// Access: Published
|
||||
// Description: Returns true if get_state_def() has ever been called
|
||||
// for the indicated state (thus defining a render
|
||||
// subgraph for this state index), false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool PGItem::
|
||||
has_state_def(int state) const {
|
||||
if (state < 0 || state >= (int)_state_defs.size()) {
|
||||
return false;
|
||||
}
|
||||
return (_state_defs[state]._node != (Node *)NULL);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGItem::clear_state_def
|
||||
// Access: Published
|
||||
// Description: Resets the NodePath assigned to the indicated state
|
||||
// to its initial default, with only a frame
|
||||
// representation if appropriate.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PGItem::
|
||||
clear_state_def(int state) {
|
||||
if (state < 0 || state >= (int)_state_defs.size()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Node *def = _state_defs[state]._node;
|
||||
if (def != (Node *)NULL) {
|
||||
// Remove all the children from this node.
|
||||
int num_children = def->get_num_children(RenderRelation::get_class_type());
|
||||
while (num_children > 0) {
|
||||
nassertv(num_children == def->get_num_children(RenderRelation::get_class_type()));
|
||||
NodeRelation *arc =
|
||||
def->get_child(RenderRelation::get_class_type(), num_children - 1);
|
||||
remove_arc(arc);
|
||||
num_children--;
|
||||
}
|
||||
}
|
||||
|
||||
_state_defs[state]._frame_arc = (NodeRelation *)NULL;
|
||||
_state_defs[state]._frame_stale = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGItem::get_state_def
|
||||
// Access: Published
|
||||
// Description: Returns the Node that is the root of the subgraph
|
||||
// that will be drawn when the PGItem is in the
|
||||
// indicated state. The first time this is called for a
|
||||
// particular state index, it may create the Node.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
Node *PGItem::
|
||||
get_state_def(int state) {
|
||||
nassertr(state < 1000, (Node *)NULL); // Sanity check.
|
||||
slot_state_def(state);
|
||||
|
||||
if (_state_defs[state]._node == (Node *)NULL) {
|
||||
// Create a new node.
|
||||
_state_defs[state]._node = new NamedNode("state_" + format_string(state));
|
||||
_state_defs[state]._frame_stale = true;
|
||||
}
|
||||
|
||||
if (_state_defs[state]._frame_stale) {
|
||||
update_frame(state);
|
||||
}
|
||||
|
||||
return _state_defs[state]._node;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGItem::instance_to_state_def
|
||||
// Access: Published
|
||||
// Description: Parents an instance of the bottom node of the
|
||||
// indicated ArcChain (normally a NodePath) to the
|
||||
// indicated state index.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PGItem::
|
||||
instance_to_state_def(int state, const ArcChain &chain) {
|
||||
if (chain.empty()) {
|
||||
// If the chain is empty, quietly do nothing.
|
||||
return;
|
||||
}
|
||||
|
||||
NodeRelation *new_arc =
|
||||
new RenderRelation(get_state_def(state), chain.node());
|
||||
|
||||
if (chain.has_arcs()) {
|
||||
// If the chain has an arc, copy the transitions from it.
|
||||
new_arc->copy_transitions_from(chain.arc());
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGItem::get_frame_style
|
||||
// Access: Published
|
||||
// Description: Returns the kind of frame that will be drawn behind
|
||||
// the item when it is in the indicated state.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PGFrameStyle PGItem::
|
||||
get_frame_style(int state) {
|
||||
if (state < 0 || state >= (int)_state_defs.size()) {
|
||||
return PGFrameStyle();
|
||||
}
|
||||
return _state_defs[state]._frame_style;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGItem::set_frame_style
|
||||
// Access: Published
|
||||
// Description: Changes the kind of frame that will be drawn behind
|
||||
// the item when it is in the indicated state.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PGItem::
|
||||
set_frame_style(int state, const PGFrameStyle &style) {
|
||||
// Get the state def node, mainly to ensure that this state is
|
||||
// slotted and listed as having been defined.
|
||||
Node *def = get_state_def(state);
|
||||
nassertv(def != (Node *)NULL);
|
||||
|
||||
_state_defs[state]._frame_style = style;
|
||||
_state_defs[state]._frame_stale = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGItem::get_text_node
|
||||
// Access: Published, Static
|
||||
// Description: Returns the TextNode object that will be used by all
|
||||
// PGItems to generate default labels given a string.
|
||||
// This can be loaded with the default font, etc.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
TextNode *PGItem::
|
||||
get_text_node() {
|
||||
if (_text_node == (TextNode *)NULL) {
|
||||
_text_node = new TextNode("pguiText");
|
||||
_text_node->freeze();
|
||||
_text_node->set_text_color(0.0, 0.0, 0.0, 1.0);
|
||||
_text_node->set_align(TM_ALIGN_CENTER);
|
||||
}
|
||||
return _text_node;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGItem::slot_state_def
|
||||
// Access: Private
|
||||
// Description: Ensures there is a slot in the array for the given
|
||||
// state definition.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PGItem::
|
||||
slot_state_def(int state) {
|
||||
while (state >= (int)_state_defs.size()) {
|
||||
StateDef def;
|
||||
def._frame_stale = true;
|
||||
_state_defs.push_back(def);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGItem::update_frame
|
||||
// Access: Private
|
||||
// Description: Generates a new instance of the frame geometry for
|
||||
// the indicated state.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PGItem::
|
||||
update_frame(int state) {
|
||||
// First, remove the old frame geometry, if any.
|
||||
if (state >= 0 && state < (int)_state_defs.size()) {
|
||||
NodeRelation *old_arc = _state_defs[state]._frame_arc;
|
||||
if (old_arc != (NodeRelation *)NULL) {
|
||||
if (old_arc->is_attached()) {
|
||||
remove_arc(old_arc);
|
||||
_state_defs[state]._frame_arc = (NodeRelation *)NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We must turn off the stale flag first, before we call
|
||||
// get_state_def(), to prevent get_state_def() from being a
|
||||
// recursive call.
|
||||
_state_defs[state]._frame_stale = false;
|
||||
|
||||
// Now create new frame geometry.
|
||||
if (has_frame()) {
|
||||
Node *node = get_state_def(state);
|
||||
nassertv(node != (Node *)NULL);
|
||||
|
||||
_state_defs[state]._frame_arc =
|
||||
_state_defs[state]._frame_style.generate_into(node, _frame);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGItem::mark_frames_stale
|
||||
// Access: Private
|
||||
// Description: Marks all the frames in all states stale, so that
|
||||
// they will be regenerated the next time each state is
|
||||
// requested.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PGItem::
|
||||
mark_frames_stale() {
|
||||
StateDefs::iterator di;
|
||||
for (di = _state_defs.begin(); di != _state_defs.end(); ++di) {
|
||||
// Remove the old frame, if any.
|
||||
NodeRelation *old_arc = (*di)._frame_arc;
|
||||
if (old_arc != (NodeRelation *)NULL) {
|
||||
if (old_arc->is_attached()) {
|
||||
remove_arc(old_arc);
|
||||
(*di)._frame_arc = (NodeRelation *)NULL;
|
||||
}
|
||||
}
|
||||
|
||||
(*di)._frame_stale = true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
// Filename: pgItem.h
|
||||
// Created by: drose (02Jul01)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 PGITEM_H
|
||||
#define PGITEM_H
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "pgMouseWatcherRegion.h"
|
||||
#include "pgFrameStyle.h"
|
||||
|
||||
#include "namedNode.h"
|
||||
#include "nodeRelation.h"
|
||||
#include "luse.h"
|
||||
#include "pointerTo.h"
|
||||
#include "pt_Node.h"
|
||||
#include "pt_NodeRelation.h"
|
||||
#include "textNode.h"
|
||||
|
||||
class ArcChain;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : PGItem
|
||||
// Description : This is the base class for all the various kinds of
|
||||
// gui widget objects.
|
||||
//
|
||||
// It is a Node which corresponds to a rectangular
|
||||
// region on the screen, and it may have any number of
|
||||
// "state" subgraphs, one of which is rendered at any
|
||||
// given time according to its current state.
|
||||
//
|
||||
// The PGItem node must be parented to the scene graph
|
||||
// somewhere beneath a PGTop node in order for this
|
||||
// behavior to work.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA PGItem : public NamedNode {
|
||||
PUBLISHED:
|
||||
PGItem(const string &name = "");
|
||||
virtual ~PGItem();
|
||||
|
||||
public:
|
||||
PGItem(const PGItem ©);
|
||||
void operator = (const PGItem ©);
|
||||
|
||||
virtual Node *make_copy() const;
|
||||
|
||||
void activate_region(const LMatrix4f &transform, int sort);
|
||||
INLINE PGMouseWatcherRegion *get_region() const;
|
||||
|
||||
virtual void enter();
|
||||
virtual void exit();
|
||||
virtual void button_down(ButtonHandle button);
|
||||
virtual void button_up(ButtonHandle button, bool is_within);
|
||||
|
||||
PUBLISHED:
|
||||
INLINE void set_frame(float left, float right, float bottom, float top);
|
||||
INLINE void set_frame(const LVecBase4f &frame);
|
||||
INLINE const LVecBase4f &get_frame() const;
|
||||
INLINE bool has_frame() const;
|
||||
INLINE void clear_frame();
|
||||
|
||||
INLINE void set_state(int state);
|
||||
INLINE int get_state() const;
|
||||
|
||||
INLINE void set_active(bool active);
|
||||
INLINE bool get_active() const;
|
||||
|
||||
int get_num_state_defs() const;
|
||||
void clear_state_def(int state);
|
||||
bool has_state_def(int state) const;
|
||||
Node *get_state_def(int state);
|
||||
void instance_to_state_def(int state, const ArcChain &chain);
|
||||
|
||||
PGFrameStyle get_frame_style(int state);
|
||||
void set_frame_style(int state, const PGFrameStyle &style);
|
||||
|
||||
INLINE const string &get_id() const;
|
||||
INLINE string get_enter_event() const;
|
||||
INLINE string get_exit_event() const;
|
||||
INLINE string get_button_down_event() const;
|
||||
INLINE string get_button_up_event() const;
|
||||
|
||||
static TextNode *get_text_node();
|
||||
INLINE static void set_text_node(TextNode *node);
|
||||
|
||||
private:
|
||||
void slot_state_def(int state);
|
||||
void update_frame(int state);
|
||||
void mark_frames_stale();
|
||||
|
||||
bool _has_frame;
|
||||
LVecBase4f _frame;
|
||||
int _state;
|
||||
bool _active;
|
||||
|
||||
PT(PGMouseWatcherRegion) _region;
|
||||
|
||||
class StateDef {
|
||||
public:
|
||||
PT_Node _node;
|
||||
PGFrameStyle _frame_style;
|
||||
PT_NodeRelation _frame_arc;
|
||||
bool _frame_stale;
|
||||
};
|
||||
typedef pvector<StateDef> StateDefs;
|
||||
StateDefs _state_defs;
|
||||
|
||||
static PT(TextNode) _text_node;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
NamedNode::init_type();
|
||||
register_type(_type_handle, "PGItem",
|
||||
NamedNode::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 "pgItem.I"
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,18 @@
|
||||
// Filename: pgMouseWatcherRegion.I
|
||||
// Created by: drose (02Jul01)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
// Filename: pgMouseWatcherRegion.cxx
|
||||
// Created by: drose (02Jul01)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "pgMouseWatcherRegion.h"
|
||||
#include "pgItem.h"
|
||||
|
||||
#include "string_utils.h"
|
||||
|
||||
TypeHandle PGMouseWatcherRegion::_type_handle;
|
||||
int PGMouseWatcherRegion::_next_index = 0;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGMouseWatcherRegion::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PGMouseWatcherRegion::
|
||||
PGMouseWatcherRegion(PGItem *item) :
|
||||
#ifndef CPPPARSER
|
||||
MouseWatcherRegion("pg" + format_string(_next_index++), 0, 0, 0, 0),
|
||||
#endif
|
||||
_item(item)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGMouseWatcherRegion::Destructor
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PGMouseWatcherRegion::
|
||||
~PGMouseWatcherRegion() {
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGMouseWatcherRegion::enter
|
||||
// Access: Public, Virtual
|
||||
// Description: This is a callback hook function, called whenever the
|
||||
// mouse enters the region.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PGMouseWatcherRegion::
|
||||
enter() {
|
||||
if (_item != (PGItem *)NULL) {
|
||||
_item->enter();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGMouseWatcherRegion::exit
|
||||
// Access: Public, Virtual
|
||||
// Description: This is a callback hook function, called whenever the
|
||||
// mouse exits the region.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PGMouseWatcherRegion::
|
||||
exit() {
|
||||
if (_item != (PGItem *)NULL) {
|
||||
_item->exit();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGMouseWatcherRegion::button_down
|
||||
// Access: Public, Virtual
|
||||
// Description: This is a callback hook function, called whenever a
|
||||
// mouse or keyboard button is depressed while the mouse
|
||||
// is within the region.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PGMouseWatcherRegion::
|
||||
button_down(ButtonHandle button) {
|
||||
if (_item != (PGItem *)NULL) {
|
||||
_item->button_down(button);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGMouseWatcherRegion::button_up
|
||||
// Access: Public, Virtual
|
||||
// Description: This is a callback hook function, called whenever a
|
||||
// mouse or keyboard button previously depressed with
|
||||
// button_down() is release. The bool is_within flag is
|
||||
// true if the button was released while the mouse was
|
||||
// still within the region, or false if it was released
|
||||
// outside the region.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PGMouseWatcherRegion::
|
||||
button_up(ButtonHandle button, bool is_within) {
|
||||
if (_item != (PGItem *)NULL) {
|
||||
_item->button_up(button, is_within);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
// Filename: pgMouseWatcherRegion.h
|
||||
// Created by: drose (02Jul01)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 PGMOUSEWATCHERREGION_H
|
||||
#define PGMOUSEWATCHERREGION_H
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "mouseWatcherRegion.h"
|
||||
|
||||
class PGItem;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : PGMouseWatcherRegion
|
||||
// Description : This is a specialization on MouseWatcherRegion, to
|
||||
// add a bit more fields that are relevant to the PG
|
||||
// system. Each PGItem corresponds to exactly one
|
||||
// PGMouseWatcherRegion.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA PGMouseWatcherRegion : public MouseWatcherRegion {
|
||||
public:
|
||||
PGMouseWatcherRegion(PGItem *item);
|
||||
virtual ~PGMouseWatcherRegion();
|
||||
|
||||
virtual void enter();
|
||||
virtual void exit();
|
||||
virtual void button_down(ButtonHandle button);
|
||||
virtual void button_up(ButtonHandle button, bool is_within);
|
||||
|
||||
private:
|
||||
PGItem *_item;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
MouseWatcherRegion::init_type();
|
||||
register_type(_type_handle, "PGMouseWatcherRegion",
|
||||
MouseWatcherRegion::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;
|
||||
static int _next_index;
|
||||
|
||||
friend class PGItem;
|
||||
};
|
||||
|
||||
#include "pgMouseWatcherRegion.I"
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,56 @@
|
||||
// Filename: pgTop.I
|
||||
// Created by: drose (02Jul01)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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: PGTop::Copy Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PGTop::
|
||||
PGTop(const PGTop ©) :
|
||||
NamedNode(copy),
|
||||
_watcher(copy._watcher)
|
||||
{
|
||||
_gsg = (GraphicsStateGuardian *)NULL;
|
||||
_trav = (RenderTraverser *)NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGTop::Copy Assignment Operator
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void PGTop::
|
||||
operator = (const PGTop ©) {
|
||||
NamedNode::operator = (copy);
|
||||
_watcher = copy._watcher;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGTop::get_mouse_watcher
|
||||
// Access: Published
|
||||
// Description: Returns the MouseWatcher pointer that the PGTop object
|
||||
// registers its PG items with, or NULL if the
|
||||
// MouseWatcher has not yet been set.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE MouseWatcher *PGTop::
|
||||
get_mouse_watcher() const {
|
||||
return _watcher;
|
||||
}
|
||||
@@ -0,0 +1,256 @@
|
||||
// Filename: pgTop.cxx
|
||||
// Created by: drose (02Jul01)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "pgTop.h"
|
||||
#include "pgItem.h"
|
||||
|
||||
#include "arcChain.h"
|
||||
#include "graphicsStateGuardian.h"
|
||||
#include "config_sgraphutil.h"
|
||||
#include "renderRelation.h"
|
||||
#include "geomNode.h"
|
||||
#include "allTransitionsWrapper.h"
|
||||
#include "allAttributesWrapper.h"
|
||||
#include "wrt.h"
|
||||
#include "switchNode.h"
|
||||
#include "transformTransition.h"
|
||||
#include "nodeTransitionWrapper.h"
|
||||
#include "directRenderTraverser.h"
|
||||
#include "omniBoundingVolume.h"
|
||||
#include "pruneTransition.h"
|
||||
|
||||
TypeHandle PGTop::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGTop::Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PGTop::
|
||||
PGTop(const string &name) : NamedNode(name)
|
||||
{
|
||||
_gsg = (GraphicsStateGuardian *)NULL;
|
||||
_trav = (RenderTraverser *)NULL;
|
||||
|
||||
// A PGTop node normally has an infinite bounding volume. Screw
|
||||
// culling.
|
||||
set_bound(OmniBoundingVolume());
|
||||
set_final(true);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGTop::Destructor
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PGTop::
|
||||
~PGTop() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGTop::make_copy
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns a newly-allocated Node that is a shallow copy
|
||||
// of this one. It will be a different Node pointer,
|
||||
// but its internal data may or may not be shared with
|
||||
// that of the original Node.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
Node *PGTop::
|
||||
make_copy() const {
|
||||
return new PGTop(*this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGTop::sub_render
|
||||
// Access: Public, Virtual
|
||||
// Description: Gets called during the draw traversal to render this
|
||||
// node and all nodes below it. In the case of the
|
||||
// PGTop node, this uses a depth-first left-to-right
|
||||
// traversal to render all of the GeomNodes and PGItems
|
||||
// in the scene graph order.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool PGTop::
|
||||
sub_render(const AllAttributesWrapper &attrib, AllTransitionsWrapper &,
|
||||
RenderTraverser *trav) {
|
||||
_attrib = attrib;
|
||||
_gsg = trav->get_gsg();
|
||||
const ArcChain &chain = trav->get_arc_chain();
|
||||
|
||||
// Empty our set of regions in preparation for re-adding whichever
|
||||
// ones we encounter in the traversal that are current.
|
||||
clear_regions();
|
||||
_sort_index = 0;
|
||||
|
||||
// Start the traversal below the current node.
|
||||
const DownRelationPointers &drp =
|
||||
find_connection(RenderRelation::get_class_type()).get_down();
|
||||
|
||||
DownRelationPointers::const_iterator drpi;
|
||||
for (drpi = drp.begin(); drpi != drp.end(); ++drpi) {
|
||||
NodeRelation *arc = (*drpi);
|
||||
if (!arc->has_transition(PruneTransition::get_class_type())) {
|
||||
ArcChain next_chain(chain);
|
||||
next_chain.push_back(arc);
|
||||
r_traverse(arc->get_child(), next_chain);
|
||||
}
|
||||
}
|
||||
|
||||
// We don't need the normal render traverser to do anything else;
|
||||
// we've done it all.
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGTop::has_sub_render
|
||||
// Access: Public, Virtual
|
||||
// Description: Should be redefined to return true if the function
|
||||
// sub_render(), above, expects to be called during
|
||||
// traversal.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool PGTop::
|
||||
has_sub_render() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGTop::set_mouse_watcher
|
||||
// Access: Published
|
||||
// Description: Sets the MouseWatcher pointer that the PGTop object
|
||||
// registers its PG items with. This must be set before
|
||||
// the PG items are active.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PGTop::
|
||||
set_mouse_watcher(MouseWatcher *watcher) {
|
||||
if (_watcher != (MouseWatcher *)NULL) {
|
||||
_watcher->remove_group(this);
|
||||
}
|
||||
_watcher = watcher;
|
||||
if (_watcher != (MouseWatcher *)NULL) {
|
||||
_watcher->add_group(this);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PGTop::r_traverse
|
||||
// Access: Private
|
||||
// Description: Handles the main recursive traversal of the scene
|
||||
// graph for nodes below the PGTop node. This
|
||||
// implements a depth-first traversal.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PGTop::
|
||||
r_traverse(Node *node, const ArcChain &chain) {
|
||||
if (implicit_app_traversal) {
|
||||
node->app_traverse();
|
||||
}
|
||||
node->draw_traverse();
|
||||
_gsg->_nodes_pcollector.add_level(1);
|
||||
|
||||
|
||||
if (node->is_of_type(PGItem::get_class_type())) {
|
||||
PGItem *pgi = DCAST(PGItem, node);
|
||||
|
||||
if (pgi->has_frame() && pgi->get_active()) {
|
||||
// The item has a frame, so we want to generate a region for it
|
||||
// and update the MouseWatcher.
|
||||
|
||||
// Get the complete net transform to the PGItem from the top.
|
||||
LMatrix4f mat;
|
||||
|
||||
NodeTransitionWrapper ntw(TransformTransition::get_class_type());
|
||||
wrt(pgi, chain.begin(), chain.end(), (Node *)NULL,
|
||||
ntw, RenderRelation::get_class_type());
|
||||
const TransformTransition *tt;
|
||||
if (!get_transition_into(tt, ntw)) {
|
||||
// No relative transform.
|
||||
mat = LMatrix4f::ident_mat();
|
||||
return;
|
||||
}
|
||||
|
||||
mat = tt->get_matrix();
|
||||
|
||||
// Now apply this transform to the item's frame.
|
||||
pgi->activate_region(mat, _sort_index);
|
||||
_sort_index++;
|
||||
|
||||
add_region(pgi->get_region());
|
||||
}
|
||||
|
||||
if (pgi->has_state_def(pgi->get_state())) {
|
||||
// This item has a current state definition that we should use
|
||||
// to render the item.
|
||||
Node *def = pgi->get_state_def(pgi->get_state());
|
||||
|
||||
// Get the net transitions to the PGItem.
|
||||
AllTransitionsWrapper complete_trans;
|
||||
wrt(pgi, chain.begin(), chain.end(), this,
|
||||
complete_trans, RenderRelation::get_class_type());
|
||||
|
||||
// We'll use a normal DirectRenderTraverser to do the rendering
|
||||
// of the subgraph.
|
||||
DirectRenderTraverser drt(_gsg, RenderRelation::get_class_type());
|
||||
drt.traverse(def, _attrib, complete_trans);
|
||||
}
|
||||
|
||||
} else if (node->is_of_type(GeomNode::get_class_type())) {
|
||||
_gsg->_geom_nodes_pcollector.add_level(1);
|
||||
GeomNode *geom = DCAST(GeomNode, node);
|
||||
|
||||
// Get the complete state of the GeomNode.
|
||||
AllTransitionsWrapper complete_trans;
|
||||
wrt(geom, chain.begin(), chain.end(), this,
|
||||
complete_trans, RenderRelation::get_class_type());
|
||||
AllAttributesWrapper complete_state;
|
||||
complete_state.apply_from(_attrib, complete_trans);
|
||||
_gsg->set_state(complete_state.get_attributes(), true);
|
||||
|
||||
// Finally, draw the Geom.
|
||||
_gsg->prepare_display_region();
|
||||
geom->draw(_gsg);
|
||||
}
|
||||
|
||||
|
||||
// Continue the traversal.
|
||||
const DownRelationPointers &drp =
|
||||
node->find_connection(RenderRelation::get_class_type()).get_down();
|
||||
|
||||
if (node->is_of_type(SwitchNode::get_class_type())) {
|
||||
SwitchNode *swnode = DCAST(SwitchNode, node);
|
||||
swnode->compute_switch(_trav);
|
||||
size_t i = 0;
|
||||
for (i = 0; i < drp.size(); i++) {
|
||||
if (swnode->is_child_visible(RenderRelation::get_class_type(), i)) {
|
||||
NodeRelation *arc = drp[i];
|
||||
if (!arc->has_transition(PruneTransition::get_class_type())) {
|
||||
ArcChain next_chain(chain);
|
||||
next_chain.push_back(arc);
|
||||
r_traverse(arc->get_child(), next_chain);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
DownRelationPointers::const_iterator drpi;
|
||||
for (drpi = drp.begin(); drpi != drp.end(); ++drpi) {
|
||||
NodeRelation *arc = (*drpi);
|
||||
if (!arc->has_transition(PruneTransition::get_class_type())) {
|
||||
ArcChain next_chain(chain);
|
||||
next_chain.push_back(arc);
|
||||
r_traverse(arc->get_child(), next_chain);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
// Filename: pgTop.h
|
||||
// Created by: drose (02Jul01)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 PGTOP_H
|
||||
#define PGTOP_H
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "namedNode.h"
|
||||
#include "mouseWatcherGroup.h"
|
||||
#include "mouseWatcher.h"
|
||||
#include "pointerTo.h"
|
||||
#include "allAttributesWrapper.h"
|
||||
|
||||
class GraphicsStateGuardian;
|
||||
class RenderTraverser;
|
||||
class ArcChain;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : PGTop
|
||||
// Description : The "top" node of the new Panda GUI system. This
|
||||
// node must be parented to the 2-d scene graph, and all
|
||||
// PG objects should be parented to this node or
|
||||
// somewhere below it. PG objects not parented within
|
||||
// this hierarchy will not even be visible.
|
||||
//
|
||||
// This node begins the special traversal of the PG
|
||||
// objects that registers each node within the
|
||||
// MouseWatcher and forces everything to render in a
|
||||
// depth-first, left-to-right order, appropriate for 2-d
|
||||
// objects.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA PGTop : public NamedNode, public MouseWatcherGroup {
|
||||
PUBLISHED:
|
||||
PGTop(const string &name = "");
|
||||
virtual ~PGTop();
|
||||
|
||||
public:
|
||||
INLINE PGTop(const PGTop ©);
|
||||
INLINE void operator = (const PGTop ©);
|
||||
|
||||
virtual Node *make_copy() const;
|
||||
|
||||
virtual bool sub_render(const AllAttributesWrapper &attrib,
|
||||
AllTransitionsWrapper &trans,
|
||||
RenderTraverser *trav);
|
||||
virtual bool has_sub_render() const;
|
||||
|
||||
PUBLISHED:
|
||||
void set_mouse_watcher(MouseWatcher *watcher);
|
||||
INLINE MouseWatcher *get_mouse_watcher() const;
|
||||
|
||||
private:
|
||||
void r_traverse(Node *node, const ArcChain &chain);
|
||||
|
||||
PT(MouseWatcher) _watcher;
|
||||
GraphicsStateGuardian *_gsg;
|
||||
RenderTraverser *_trav;
|
||||
AllAttributesWrapper _attrib;
|
||||
int _sort_index;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
NamedNode::init_type();
|
||||
MouseWatcherGroup::init_type();
|
||||
register_type(_type_handle, "PGTop",
|
||||
NamedNode::get_class_type(),
|
||||
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 "pgTop.I"
|
||||
|
||||
#endif
|
||||
@@ -51,6 +51,26 @@ NodePath(Node *top_node, TypeHandle graph_type) :
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::Constructor
|
||||
// Access: Public
|
||||
// Description: Creates a NodePath that contains one arc, and the two
|
||||
// Nodes connected to that arc.
|
||||
//
|
||||
// If the NodeRelation pointer is NULL, this quietly
|
||||
// creates an empty NodePath.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE NodePath::
|
||||
NodePath(NodeRelation *arc) :
|
||||
_graph_type(RenderRelation::get_class_type()),
|
||||
_error_type(ET_ok)
|
||||
{
|
||||
if (arc != (NodeRelation *)NULL) {
|
||||
_graph_type = arc->get_type();
|
||||
extend_by(arc);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::Constructor
|
||||
// Access: Public
|
||||
@@ -183,12 +203,9 @@ compare_to(const NodePath &other) const {
|
||||
// Access: Public
|
||||
// Description: Changes the type of graph that the NodePath will
|
||||
// search for. By default, this is RenderRelation.
|
||||
// This may only be called when the NodePath contains no
|
||||
// arcs (e.g. is_empty() || is_singleton()).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void NodePath::
|
||||
set_graph_type(TypeHandle graph_type) {
|
||||
nassertv(_head == (ArcComponent *)NULL);
|
||||
_graph_type = graph_type;
|
||||
}
|
||||
|
||||
@@ -242,17 +259,6 @@ get_max_search_depth() {
|
||||
return _max_search_depth;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::is_empty
|
||||
// Access: Public
|
||||
// Description: Returns true if the NodePath contains no nodes and no
|
||||
// arcs.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool NodePath::
|
||||
is_empty() const {
|
||||
return !ArcChain::has_node();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::get_error_type
|
||||
// Access: Public
|
||||
@@ -264,74 +270,6 @@ get_error_type() const {
|
||||
return _error_type;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::is_singleton
|
||||
// Access: Public
|
||||
// Description: Returns true if the NodePath contains exactly one
|
||||
// node, and no arcs.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool NodePath::
|
||||
is_singleton() const {
|
||||
return ArcChain::has_node() && !ArcChain::has_arcs();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::has_arcs
|
||||
// Access: Public
|
||||
// Description: Returns true if the NodePath contains at least one
|
||||
// arc, and therefore at least two nodes. This is the
|
||||
// same thing as asking get_num_arcs() > 0, but is
|
||||
// easier to compute.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool NodePath::
|
||||
has_arcs() const {
|
||||
return ArcChain::has_arcs();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::get_num_arcs
|
||||
// Access: Public
|
||||
// Description: Returns the number of arcs in the path.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int NodePath::
|
||||
get_num_arcs() const {
|
||||
if (!has_arcs()) {
|
||||
return 0;
|
||||
}
|
||||
return get_num_nodes() - 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::node
|
||||
// Access: Public
|
||||
// Description: Returns the bottom node of the path, or NULL if the
|
||||
// path is empty.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE Node *NodePath::
|
||||
node() const {
|
||||
nassertr(_error_type == ET_ok, (Node *)NULL);
|
||||
if (is_empty()) {
|
||||
return (Node *)NULL;
|
||||
}
|
||||
return _head->get_node();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::arc
|
||||
// Access: Public
|
||||
// Description: Returns the bottom arc of the path, or NULL if the
|
||||
// path is empty or is a singleton.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE NodeRelation *NodePath::
|
||||
arc() const {
|
||||
nassertr(_error_type == ET_ok, (NodeRelation *)NULL);
|
||||
if (!has_arcs()) {
|
||||
// A singleton or empty list.
|
||||
return (NodeRelation *)NULL;
|
||||
}
|
||||
return _head->get_arc();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::get_num_children
|
||||
// Access: Public
|
||||
@@ -449,7 +387,11 @@ attach_new_node(const string &name, int sort) const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void NodePath::
|
||||
output(ostream &out) const {
|
||||
out << as_string(0);
|
||||
if (_error_type == ET_ok && is_empty()) {
|
||||
out << "**empty**";
|
||||
} else {
|
||||
out << as_string(0);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -150,16 +150,6 @@ extend_by(NodeRelation *darc) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (darc->get_type() != get_graph_type() &&
|
||||
darc->get_type() != NodeRelation::get_stashed_type()) {
|
||||
if (sgmanip_cat.is_debug()) {
|
||||
sgmanip_cat.debug()
|
||||
<< "Cannot extend " << *this << " by arc " << *darc
|
||||
<< "; wrong graph type.\n";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
_head = new ArcComponent(darc, _head);
|
||||
|
||||
return true;
|
||||
@@ -418,95 +408,6 @@ find_singular_transform() const {
|
||||
return NodePath::not_found();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::get_node
|
||||
// Access: Public
|
||||
// Description: Returns the nth node of the path, where 0 is the
|
||||
// bottom node and get_num_nodes() - 1 is the top node.
|
||||
// This requires iterating through the path.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
Node *NodePath::
|
||||
get_node(int index) const {
|
||||
nassertr(index >= 0 && index < get_num_nodes(), NULL);
|
||||
|
||||
ArcComponent *comp = _head;
|
||||
while (index > 0) {
|
||||
// If this assertion fails, the index was out of range.
|
||||
nassertr(comp != (ArcComponent *)NULL, NULL);
|
||||
comp = comp->get_next();
|
||||
index--;
|
||||
}
|
||||
|
||||
// If this assertion fails, the index was out of range.
|
||||
nassertr(comp != (ArcComponent *)NULL, NULL);
|
||||
return comp->get_node();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::get_num_nodes
|
||||
// Access: Public
|
||||
// Description: Returns the number of nodes in the path. This is
|
||||
// always one more than the number of arcs (except for
|
||||
// a completely empty path).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int NodePath::
|
||||
get_num_nodes() const {
|
||||
int num = 0;
|
||||
ArcComponent *comp = _head;
|
||||
while (comp != (ArcComponent *)NULL) {
|
||||
num++;
|
||||
comp = comp->get_next();
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::get_arc
|
||||
// Access: Public
|
||||
// Description: Returns the nth arc of the path, where 0 is the arc
|
||||
// above the bottom node node and get_num_arcs() - 1 is
|
||||
// the arc below the top node. This requires iterating
|
||||
// through the path.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
NodeRelation *NodePath::
|
||||
get_arc(int index) const {
|
||||
nassertr(index >= 0 && index < get_num_arcs(), NULL);
|
||||
|
||||
ArcComponent *comp = _head;
|
||||
while (index > 0) {
|
||||
// If this assertion fails, the index was out of range.
|
||||
nassertr(comp != (ArcComponent *)NULL, NULL);
|
||||
comp = comp->get_next();
|
||||
index--;
|
||||
}
|
||||
|
||||
// If either assertion fails, the index was out of range.
|
||||
nassertr(comp != (ArcComponent *)NULL, NULL);
|
||||
nassertr(comp->has_arc(), NULL);
|
||||
return comp->get_arc();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::get_top_node
|
||||
// Access: Public
|
||||
// Description: Returns the top node of the path, or NULL if the path
|
||||
// is empty. This requires iterating through the path.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
Node *NodePath::
|
||||
get_top_node() const {
|
||||
if (is_empty()) {
|
||||
return (Node *)NULL;
|
||||
}
|
||||
|
||||
ArcComponent *comp = _head;
|
||||
while (!comp->is_top_node()) {
|
||||
comp = comp->get_next();
|
||||
nassertr(comp != (ArcComponent *)NULL, NULL);
|
||||
}
|
||||
|
||||
return comp->get_node();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::share_with
|
||||
// Access: Public
|
||||
|
||||
@@ -148,6 +148,7 @@ PUBLISHED:
|
||||
|
||||
INLINE NodePath(TypeHandle graph_type = RenderRelation::get_class_type());
|
||||
INLINE NodePath(Node *top_node, TypeHandle graph_type = RenderRelation::get_class_type());
|
||||
INLINE NodePath(NodeRelation *arc);
|
||||
INLINE NodePath(const ArcChain &chain, TypeHandle graph_type);
|
||||
|
||||
INLINE NodePath(const NodePath ©);
|
||||
@@ -183,19 +184,9 @@ PUBLISHED:
|
||||
|
||||
// Methods to query a NodePath's contents.
|
||||
|
||||
INLINE bool is_empty() const;
|
||||
INLINE ErrorType get_error_type() const;
|
||||
INLINE bool is_singleton() const;
|
||||
INLINE bool has_arcs() const;
|
||||
int get_num_nodes() const;
|
||||
Node *get_node(int index) const;
|
||||
|
||||
INLINE int get_num_arcs() const;
|
||||
NodeRelation *get_arc(int index) const;
|
||||
|
||||
Node *get_top_node() const;
|
||||
INLINE Node *node() const;
|
||||
INLINE NodeRelation *arc() const;
|
||||
// Most of these methods are inherited from ArcChain.
|
||||
|
||||
|
||||
// Methods to manage the disconnected NodePaths that can result if
|
||||
|
||||
@@ -74,7 +74,7 @@ FrustumCullTraverser(ArcChain &arc_chain, Node *root,
|
||||
}
|
||||
}
|
||||
|
||||
bool needs_top_node = !_arc_chain.has_node();
|
||||
bool needs_top_node = _arc_chain.is_empty();
|
||||
if (needs_top_node) {
|
||||
// If the ArcChain supplied in is initially empty, put the root
|
||||
// node in it.
|
||||
|
||||
@@ -10,15 +10,17 @@
|
||||
#define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx
|
||||
|
||||
#define SOURCES \
|
||||
buttonThrower.h config_tform.h dataValve.I dataValve.h \
|
||||
driveInterface.I driveInterface.h mouseWatcher.I \
|
||||
mouseWatcher.h mouseWatcherRegion.I mouseWatcherRegion.h \
|
||||
planarSlider.h trackball.h transform2sg.h
|
||||
buttonThrower.h config_tform.h dataValve.I dataValve.h \
|
||||
driveInterface.I driveInterface.h mouseWatcher.I \
|
||||
mouseWatcher.h mouseWatcherGroup.h \
|
||||
mouseWatcherRegion.I mouseWatcherRegion.h \
|
||||
planarSlider.h trackball.h transform2sg.h
|
||||
|
||||
#define INCLUDED_SOURCES \
|
||||
buttonThrower.cxx config_tform.cxx dataValve.cxx \
|
||||
driveInterface.cxx mouseWatcher.cxx mouseWatcherRegion.cxx \
|
||||
planarSlider.cxx trackball.cxx transform2sg.cxx
|
||||
buttonThrower.cxx config_tform.cxx dataValve.cxx \
|
||||
driveInterface.cxx mouseWatcher.cxx mouseWatcherGroup.cxx \
|
||||
mouseWatcherRegion.cxx \
|
||||
planarSlider.cxx trackball.cxx transform2sg.cxx
|
||||
|
||||
#define INSTALL_HEADERS \
|
||||
buttonThrower.h dataValve.I dataValve.h \
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "driveInterface.h"
|
||||
#include "buttonThrower.h"
|
||||
#include "mouseWatcher.h"
|
||||
#include "mouseWatcherGroup.h"
|
||||
#include "mouseWatcherRegion.h"
|
||||
#include "planarSlider.h"
|
||||
#include "trackball.h"
|
||||
@@ -49,6 +50,7 @@ ConfigureFn(config_tform) {
|
||||
DriveInterface::init_type();
|
||||
ButtonThrower::init_type();
|
||||
MouseWatcher::init_type();
|
||||
MouseWatcherGroup::init_type();
|
||||
MouseWatcherRegion::init_type();
|
||||
PlanarSlider::init_type();
|
||||
Trackball::init_type();
|
||||
|
||||
@@ -296,7 +296,7 @@ set_extra_handler(EventHandler *eh) {
|
||||
// can be registered with a mouseWatcher so that events
|
||||
// can be dealt with much sooner.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE EventHandler* MouseWatcher::
|
||||
INLINE EventHandler *MouseWatcher::
|
||||
get_extra_handler(void) const {
|
||||
return _eh;
|
||||
}
|
||||
|
||||
@@ -59,34 +59,10 @@ MouseWatcher::
|
||||
~MouseWatcher() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MouseWatcher::add_region
|
||||
// Access: Published
|
||||
// Description: Adds the indicated region to the set of regions that
|
||||
// are to be watched. Returns true if it was
|
||||
// successfully added, or false if it was already on the
|
||||
// list.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool MouseWatcher::
|
||||
add_region(MouseWatcherRegion *region) {
|
||||
return _regions.insert(region).second;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MouseWatcher::has_region
|
||||
// Access: Published
|
||||
// Description: Returns true if the indicated region has already been
|
||||
// added to the MouseWatcher, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool MouseWatcher::
|
||||
has_region(MouseWatcherRegion *region) const {
|
||||
return _regions.count(region) != 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MouseWatcher::remove_region
|
||||
// Access: Published
|
||||
// Description: Removes the indicated region from the Watcher.
|
||||
// Description: Removes the indicated region from the group.
|
||||
// Returns true if it was successfully removed, or false
|
||||
// if it wasn't there in the first place.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@@ -98,27 +74,7 @@ remove_region(MouseWatcherRegion *region) {
|
||||
if (region == _button_down_region) {
|
||||
_button_down_region = (MouseWatcherRegion *)NULL;
|
||||
}
|
||||
return _regions.erase(region) != 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MouseWatcher::find_region
|
||||
// Access: Published
|
||||
// Description: Returns a pointer to the first region found with the
|
||||
// indicated name. If multiple regions share the same
|
||||
// name, the one that is returned is indeterminate.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
MouseWatcherRegion *MouseWatcher::
|
||||
find_region(const string &name) const {
|
||||
Regions::const_iterator ri;
|
||||
for (ri = _regions.begin(); ri != _regions.end(); ++ri) {
|
||||
MouseWatcherRegion *region = (*ri);
|
||||
if (region->get_name() == name) {
|
||||
return region;
|
||||
}
|
||||
}
|
||||
|
||||
return (MouseWatcherRegion *)NULL;
|
||||
return MouseWatcherGroup::remove_region(region);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@@ -151,6 +107,27 @@ get_over_region(const LPoint2f &pos) const {
|
||||
}
|
||||
}
|
||||
|
||||
// Also check all of our sub-groups.
|
||||
Groups::const_iterator gi;
|
||||
for (gi = _groups.begin(); gi != _groups.end(); ++gi) {
|
||||
MouseWatcherGroup *group = (*gi);
|
||||
for (ri = group->_regions.begin(); ri != group->_regions.end(); ++ri) {
|
||||
MouseWatcherRegion *region = (*ri);
|
||||
const LVecBase4f &frame = region->get_frame();
|
||||
|
||||
if (region->get_active() &&
|
||||
pos[0] >= frame[0] && pos[0] <= frame[1] &&
|
||||
pos[1] >= frame[2] && pos[1] <= frame[3]) {
|
||||
|
||||
// We're over this region. Is it preferred to the other one?
|
||||
if (over_region == (MouseWatcherRegion *)NULL ||
|
||||
*region < *over_region) {
|
||||
over_region = region;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return over_region;
|
||||
}
|
||||
|
||||
@@ -180,6 +157,59 @@ write(ostream &out, int indent_level) const {
|
||||
MouseWatcherRegion *region = (*ri);
|
||||
region->write(out, indent_level + 2);
|
||||
}
|
||||
|
||||
if (!_groups.empty()) {
|
||||
Groups::const_iterator gi;
|
||||
for (gi = _groups.begin(); gi != _groups.end(); ++gi) {
|
||||
MouseWatcherGroup *group = (*gi);
|
||||
indent(out, indent_level + 2)
|
||||
<< "Subgroup:\n";
|
||||
for (ri = group->_regions.begin(); ri != group->_regions.end(); ++ri) {
|
||||
MouseWatcherRegion *region = (*ri);
|
||||
region->write(out, indent_level + 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MouseWatcher::add_group
|
||||
// Access: Public
|
||||
// Description: Adds the indicated group of regions to the set of
|
||||
// regions the MouseWatcher will monitor each frame.
|
||||
//
|
||||
// Since the MouseWatcher itself inherits from
|
||||
// MouseWatcherGroup, this operation is normally not
|
||||
// necessary--you can simply add the Regions you care
|
||||
// about one at a time. Adding a complete group is
|
||||
// useful when you may want to explicitly remove the
|
||||
// regions as a group later.
|
||||
//
|
||||
// Returns true if the group was successfully added, or
|
||||
// false if it was already on the list.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool MouseWatcher::
|
||||
add_group(MouseWatcherGroup *group) {
|
||||
return _groups.insert(group).second;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MouseWatcher::remove_group
|
||||
// Access: Public
|
||||
// Description: Removes the indicated group from the set of extra
|
||||
// groups associated with the MouseWatcher. Returns
|
||||
// true if successful, or false if the group was already
|
||||
// removed or was never added via add_group().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool MouseWatcher::
|
||||
remove_group(MouseWatcherGroup *group) {
|
||||
if (group->has_region(_current_region)) {
|
||||
_current_region = (MouseWatcherRegion *)NULL;
|
||||
}
|
||||
if (group->has_region(_button_down_region)) {
|
||||
_button_down_region = (MouseWatcherRegion *)NULL;
|
||||
}
|
||||
return _groups.erase(group) != 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@@ -198,10 +228,12 @@ set_current_region(MouseWatcherRegion *region) {
|
||||
#endif
|
||||
if (region != _current_region) {
|
||||
if (_current_region != (MouseWatcherRegion *)NULL) {
|
||||
_current_region->exit();
|
||||
throw_event_pattern(_leave_pattern, _current_region);
|
||||
}
|
||||
_current_region = region;
|
||||
if (_current_region != (MouseWatcherRegion *)NULL) {
|
||||
_current_region->enter();
|
||||
throw_event_pattern(_enter_pattern, _current_region);
|
||||
}
|
||||
}
|
||||
@@ -219,9 +251,11 @@ throw_event_pattern(const string &pattern, const MouseWatcherRegion *region,
|
||||
if (pattern.empty()) {
|
||||
return;
|
||||
}
|
||||
#ifndef NDEBUG
|
||||
if (region != (MouseWatcherRegion *)NULL) {
|
||||
region->test_ref_count_integrity();
|
||||
}
|
||||
#endif
|
||||
|
||||
string event;
|
||||
for (size_t p = 0; p < pattern.size(); ++p) {
|
||||
@@ -323,13 +357,9 @@ transmit_data(NodeAttributes &data) {
|
||||
// There is some danger of losing button-up events here. If
|
||||
// more than one button goes down together, we won't detect
|
||||
// both of the button-up events properly.
|
||||
|
||||
// We should probably throw a different button_up event based
|
||||
// on whether the _current_region is NULL or not, so the
|
||||
// calling code can differentiate between button_up within the
|
||||
// starting region, and button_up outside the region.
|
||||
// Presently, changing this will break the GUI code.
|
||||
if (_button_down_region != (MouseWatcherRegion *)NULL) {
|
||||
bool is_within = (_current_region == _button_down_region);
|
||||
_button_down_region->button_up(be._button, is_within);
|
||||
throw_event_pattern(_button_up_pattern, _button_down_region,
|
||||
be._button.get_name());
|
||||
}
|
||||
@@ -343,6 +373,7 @@ transmit_data(NodeAttributes &data) {
|
||||
}
|
||||
_button_down = true;
|
||||
if (_button_down_region != (MouseWatcherRegion *)NULL) {
|
||||
_button_down_region->button_down(be._button);
|
||||
throw_event_pattern(_button_down_pattern, _button_down_region,
|
||||
be._button.get_name());
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <pandabase.h>
|
||||
|
||||
#include "mouseWatcherRegion.h"
|
||||
#include "mouseWatcherGroup.h"
|
||||
|
||||
#include <dataNode.h>
|
||||
#include <vec3DataTransition.h>
|
||||
@@ -52,15 +53,12 @@
|
||||
// scene graph. It will move the geometry around
|
||||
// according to the mouse's known position.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA MouseWatcher : public DataNode {
|
||||
class EXPCL_PANDA MouseWatcher : public DataNode, public MouseWatcherGroup {
|
||||
PUBLISHED:
|
||||
MouseWatcher(const string &name = "");
|
||||
~MouseWatcher();
|
||||
|
||||
bool add_region(MouseWatcherRegion *region);
|
||||
bool has_region(MouseWatcherRegion *region) const;
|
||||
bool remove_region(MouseWatcherRegion *region);
|
||||
MouseWatcherRegion *find_region(const string &name) const;
|
||||
|
||||
INLINE bool has_mouse() const;
|
||||
INLINE const LPoint2f &get_mouse() const;
|
||||
@@ -93,26 +91,29 @@ PUBLISHED:
|
||||
INLINE void clear_geometry();
|
||||
|
||||
INLINE void set_extra_handler(EventHandler *eh);
|
||||
INLINE EventHandler* get_extra_handler(void) const;
|
||||
INLINE EventHandler *get_extra_handler(void) const;
|
||||
|
||||
public:
|
||||
virtual void output(ostream &out) const;
|
||||
virtual void write(ostream &out, int indent_level = 0) const;
|
||||
|
||||
bool add_group(MouseWatcherGroup *group);
|
||||
bool remove_group(MouseWatcherGroup *group);
|
||||
|
||||
private:
|
||||
void set_current_region(MouseWatcherRegion *region);
|
||||
void throw_event_pattern(const string &pattern,
|
||||
const MouseWatcherRegion *region,
|
||||
const string &button_name = string());
|
||||
|
||||
typedef pset< PT(MouseWatcherRegion) > Regions;
|
||||
Regions _regions;
|
||||
typedef pset< PT(MouseWatcherGroup) > Groups;
|
||||
Groups _groups;
|
||||
|
||||
bool _has_mouse;
|
||||
LPoint2f _mouse;
|
||||
|
||||
MouseWatcherRegion *_current_region;
|
||||
MouseWatcherRegion *_button_down_region;
|
||||
PT(MouseWatcherRegion) _current_region;
|
||||
PT(MouseWatcherRegion) _button_down_region;
|
||||
bool _button_down;
|
||||
|
||||
string _button_down_pattern;
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
// Filename: mouseWatcherGroup.cxx
|
||||
// Created by: drose (02Jul01)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "mouseWatcherGroup.h"
|
||||
|
||||
|
||||
TypeHandle MouseWatcherGroup::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MouseWatcherGroup::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.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool MouseWatcherGroup::
|
||||
add_region(MouseWatcherRegion *region) {
|
||||
return _regions.insert(region).second;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MouseWatcherGroup::has_region
|
||||
// Access: Published
|
||||
// Description: Returns true if the indicated region has already been
|
||||
// added to the MouseWatcherGroup, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool MouseWatcherGroup::
|
||||
has_region(MouseWatcherRegion *region) const {
|
||||
return _regions.count(region) != 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MouseWatcherGroup::remove_region
|
||||
// Access: Published
|
||||
// Description: Removes the indicated region from the group.
|
||||
// Returns true if it was successfully removed, or false
|
||||
// if it wasn't there in the first place.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool MouseWatcherGroup::
|
||||
remove_region(MouseWatcherRegion *region) {
|
||||
return _regions.erase(region) != 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MouseWatcherGroup::find_region
|
||||
// Access: Published
|
||||
// Description: Returns a pointer to the first region found with the
|
||||
// indicated name. If multiple regions share the same
|
||||
// name, the one that is returned is indeterminate.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
MouseWatcherRegion *MouseWatcherGroup::
|
||||
find_region(const string &name) const {
|
||||
Regions::const_iterator ri;
|
||||
for (ri = _regions.begin(); ri != _regions.end(); ++ri) {
|
||||
MouseWatcherRegion *region = (*ri);
|
||||
if (region->get_name() == name) {
|
||||
return region;
|
||||
}
|
||||
}
|
||||
|
||||
return (MouseWatcherRegion *)NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MouseWatcherGroup::clear_regions
|
||||
// Access: Published
|
||||
// Description: Removes all the regions from the group.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void MouseWatcherGroup::
|
||||
clear_regions() {
|
||||
_regions.clear();
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
// Filename: mouseWatcherGroup.h
|
||||
// Created by: drose (02Jul01)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 MOUSEWATCHERGROUP_H
|
||||
#define MOUSEWATCHERGROUP_H
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "mouseWatcherRegion.h"
|
||||
|
||||
#include "pointerTo.h"
|
||||
#include "referenceCount.h"
|
||||
#include "pset.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : MouseWatcherGroup
|
||||
// Description : This represents a collection of MouseWatcherRegions
|
||||
// that may be managed as a group.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA MouseWatcherGroup : virtual public ReferenceCount {
|
||||
PUBLISHED:
|
||||
bool add_region(MouseWatcherRegion *region);
|
||||
bool has_region(MouseWatcherRegion *region) const;
|
||||
bool remove_region(MouseWatcherRegion *region);
|
||||
MouseWatcherRegion *find_region(const string &name) const;
|
||||
void clear_regions();
|
||||
|
||||
protected:
|
||||
typedef pset< PT(MouseWatcherRegion) > Regions;
|
||||
Regions _regions;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
register_type(_type_handle, "MouseWatcherGroup");
|
||||
}
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
|
||||
friend class MouseWatcher;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -43,3 +43,47 @@ write(ostream &out, int indent_level) const {
|
||||
indent(out, indent_level) << get_name() << " lrbt = " << _frame << "\n";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MouseWatcherRegion::enter
|
||||
// Access: Public, Virtual
|
||||
// Description: This is a callback hook function, called whenever the
|
||||
// mouse enters the region.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void MouseWatcherRegion::
|
||||
enter() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MouseWatcherRegion::exit
|
||||
// Access: Public, Virtual
|
||||
// Description: This is a callback hook function, called whenever the
|
||||
// mouse exits the region.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void MouseWatcherRegion::
|
||||
exit() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MouseWatcherRegion::button_down
|
||||
// Access: Public, Virtual
|
||||
// Description: This is a callback hook function, called whenever a
|
||||
// mouse or keyboard button is depressed while the mouse
|
||||
// is within the region.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void MouseWatcherRegion::
|
||||
button_down(ButtonHandle) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MouseWatcherRegion::button_up
|
||||
// Access: Public, Virtual
|
||||
// Description: This is a callback hook function, called whenever a
|
||||
// mouse or keyboard button previously depressed with
|
||||
// button_down() is release. The bool is_within flag is
|
||||
// true if the button was released while the mouse was
|
||||
// still within the region, or false if it was released
|
||||
// outside the region.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void MouseWatcherRegion::
|
||||
button_up(ButtonHandle, bool) {
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <namable.h>
|
||||
#include <typedReferenceCount.h>
|
||||
#include <luse.h>
|
||||
#include <buttonHandle.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : MouseWatcherRegion
|
||||
@@ -56,6 +57,11 @@ PUBLISHED:
|
||||
public:
|
||||
INLINE bool operator < (const MouseWatcherRegion &other) const;
|
||||
|
||||
virtual void enter();
|
||||
virtual void exit();
|
||||
virtual void button_down(ButtonHandle button);
|
||||
virtual void button_up(ButtonHandle button, bool is_within);
|
||||
|
||||
private:
|
||||
LVecBase4f _frame;
|
||||
float _area;
|
||||
|
||||
@@ -3,4 +3,5 @@
|
||||
#include "config_tform.cxx"
|
||||
#include "dataValve.cxx"
|
||||
#include "driveInterface.cxx"
|
||||
#include "planarSlider.cxx"
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
#include "mouseWatcher.cxx"
|
||||
#include "mouseWatcherGroup.cxx"
|
||||
#include "mouseWatcherRegion.cxx"
|
||||
#include "planarSlider.cxx"
|
||||
#include "trackball.cxx"
|
||||
#include "transform2sg.cxx"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user