super early draft of Panda2d

This commit is contained in:
Cary Sandvig 2000-10-31 21:02:44 +00:00
parent 92a7d4d162
commit 0c3195ffb8
20 changed files with 868 additions and 19 deletions

View File

@ -0,0 +1,31 @@
#define OTHER_LIBS dtool
#begin lib_target
#define TARGET gui
#define LOCAL_LIBS \
putil display tform device pandabase dgraph sgattrib light gobj text
#define SOURCES \
config_gui.h config_gui.cxx \
guiManager.h guiManager.I guiManager.cxx \
guiRegion.h guiRegion.I guiRegion.cxx \
guiLabel.h guiLabel.I guiLabel.cxx \
guiRollover.h guiRollover.I guiRollover.cxx \
guiButton.h guiButton.I guiButton.cxx
#define INSTALL_HEADERS \
guiManager.h guiManager.I \
guiRegion.h guiRegion.I \
guiLabel.h guiLabel.I \
guiRollover.h guiRollover.I \
guiButton.h guiButton.I
#define IGATESCAN \
guiManager.h guiManager.I \
guiRegion.h guiRegion.I \
guiLabel.h guiLabel.I \
guiRollover.h guiRollover.I \
guiButton.h guiButton.I
#end lib_target

View File

@ -0,0 +1,14 @@
// Filename: config_gui.cxx
// Created by: cary (26Oct00)
//
////////////////////////////////////////////////////////////////////
#include "config_gui.h"
#include <dconfig.h>
Configure(config_gui);
NotifyCategoryDef(gui, "");
ConfigureFn(config_gui) {
}

View File

@ -2,3 +2,13 @@
// Created by: cary (26Oct00)
//
////////////////////////////////////////////////////////////////////
#ifndef __CONFIG_GUI_H__
#define __CONFIG_GUI_H__
#include <pandabase.h>
#include <notifyCategoryProxy.h>
NotifyCategoryDecl(gui, EXPCL_PANDA, EXPTP_PANDA);
#endif /* __CONFIG_GUI_H__ */

View File

@ -2,3 +2,158 @@
// Created by: cary (30Oct00)
//
////////////////////////////////////////////////////////////////////
INLINE GuiButton::GuiButton(void) {
}
INLINE void GuiButton::enter(void) {
switch (_state) {
case UP:
switch_state(UP_ROLLOVER);
break;
case DOWN:
switch_state(DOWN_ROLLOVER);
break;
case INACTIVE:
switch_state(INACTIVE_ROLLOVER);
break;
default:
break;
}
}
INLINE void GuiButton::exit(void) {
switch (_state) {
case UP_ROLLOVER:
switch_state(UP);
break;
case DOWN_ROLLOVER:
switch_state(DOWN);
break;
case INACTIVE_ROLLOVER:
switch_state(INACTIVE);
break;
default:
break;
}
}
INLINE void GuiButton::up(void) {
switch (_state) {
case DOWN:
switch_state(UP);
break;
case DOWN_ROLLOVER:
switch_state(UP_ROLLOVER);
break;
default:
gui_cat->warning() << "got up from invalid state (" << _state << ")"
<< endl;
}
}
INLINE void GuiButton::down(void) {
switch (_state) {
case UP:
switch_state(DOWN);
break;
case UP_ROLLOVER:
switch_state(DOWN_ROLLOVER);
break;
default:
gui_cat->warning() << "got down from invalid state (" << _state << ")"
<< endl;
}
}
INLINE void GuiButton::inactive(void) {
switch (_state) {
case UP:
case DOWN:
switch_state(INACTIVE);
break;
case UP_ROLLOVER:
case DOWN_ROLLOVER:
switch_state(INACTIVE_ROLLOVER);
break;
default:
gui_cat->warning() << "got inactive from invalid state (" << _state << ")"
<< endl;
}
}
INLINE void GuiButton::click(void) {
switch (_state) {
case UP:
case UP_ROLLOVER:
down();
break;
case DOWN:
case DOWN_ROLLOVER:
up();
break;
case INACTIVE:
break;
default:
gui_cat->warning() << "got click from invalid state (" << _state << ")"
<< endl;
}
}
INLINE bool GuiButton::is_up(void) const {
if ((_state == UP) || (_state == UP_ROLLOVER))
return true;
return false;
}
INLINE bool GuiButton::is_over(void) const {
if ((_state == UP_ROLLOVER) || (_state == DOWN_ROLLOVER))
return true;
return false;
}
INLINE bool GuiButton::is_active(void) const {
if ((_state == INACTIVE) || (_state == NONE))
return false;
return true;
}
INLINE void GuiButton::set_up_event(const string& s) {
_up_event = s;
}
INLINE void GuiButton::set_up_rollover_event(const string& s) {
_up_rollover_event = s;
}
INLINE void GuiButton::set_down_event(const string& s) {
_down_event = s;
}
INLINE void GuiButton::set_down_rollover_event(const string& s) {
_down_rollover_event = s;
}
INLINE void GuiButton::set_inactive_event(const string& s) {
_inactive_event = s;
}
INLINE const string& GuiButton::get_up_event(void) const {
return _up_event;
}
INLINE const string& GuiButton::get_up_rollover_event(void) const {
return _up_rollover_event;
}
INLINE const string& GuiButton::get_down_event(void) const {
return _down_event;
}
INLINE const string& GuiButton::get_down_rollover_event(void) const {
return _down_rollover_event;
}
INLINE const string& GuiButton::get_inactive_event(void) const {
return _inactive_event;
}

View File

@ -2,3 +2,201 @@
// Created by: cary (30Oct00)
//
////////////////////////////////////////////////////////////////////
#include "guiButton.h"
#include "config_gui.h"
#include <throw_event.h>
#include <map>
typedef map<string, GuiButton*> ButtonMap;
static ButtonMap buttons;
inline void GetExtents(GuiLabel* v, GuiLabel* w, GuiLabel* x, GuiLabel* y,
GuiLabel* z, float& l, float& r, float& b, float& t) {
float l1, l2, r1, r2, b1, b2, t1, t2;
v->get_extents(l1, r1, b1, t1);
w->get_extents(l2, r2, b2, t2);
l1 = (l1<l2)?l1:l2;
r1 = (r1<r2)?r2:r1;
b1 = (b1<b2)?b1:b2;
t1 = (t1<t2)?t2:t1;
if (x != (GuiLabel*)0L) {
x->get_extents(l2, r2, b2, t2);
l1 = (l1<l2)?l1:l2;
r1 = (r1<r2)?r2:r1;
b1 = (b1<b2)?b1:b2;
t1 = (t1<t2)?t2:t1;
}
if (y != (GuiLabel*)0L) {
y->get_extents(l2, r2, b2, t2);
l1 = (l1<l2)?l1:l2;
r1 = (r1<r2)?r2:r1;
b1 = (b1<b2)?b1:b2;
t1 = (t1<t2)?t2:t1;
}
if (z != (GuiLabel*)0L) {
z->get_extents(l2, r2, b2, t2);
l = (l1<l2)?l1:l2;
r = (r1<r2)?r2:r1;
b = (b1<b2)?b1:b2;
t = (t1<t2)?t2:t1;
}
}
static void enter_button(CPT_Event e) {
GuiButton* val = buttons[e->get_name()];
val->enter();
}
static void exit_button(CPT_Event e) {
GuiButton* val = buttons[e->get_name()];
val->exit();
}
static void click_button(CPT_Event e) {
GuiButton* val = buttons[e->get_name()];
val->click();
}
void GuiButton::switch_state(GuiButton::States nstate) {
// cleanup old state
switch (_state) {
case NONE:
break;
case UP:
_mgr->remove_label(_up);
break;
case UP_ROLLOVER:
_mgr->remove_label(_up_rollover);
break;
case DOWN:
_mgr->remove_label(_down);
break;
case DOWN_ROLLOVER:
_mgr->remove_label(_down_rollover);
break;
case INACTIVE:
if (_inactive != (GuiLabel*)0L)
_mgr->remove_label(_inactive);
break;
case INACTIVE_ROLLOVER:
if (_inactive != (GuiLabel*)0L)
_mgr->remove_label(_inactive);
break;
default:
gui_cat->warning() << "switching away from invalid state (" << _state
<< ")" << endl;
}
_state = nstate;
// deal with new state
switch (_state) {
case NONE:
_rgn->trap_clicks(false);
break;
case UP:
_mgr->add_label(_up);
if (!_up_event.empty())
throw_event(_up_event);
_rgn->trap_clicks(true);
break;
case UP_ROLLOVER:
if (_up_rollover != (GuiLabel*)0L) {
_mgr->add_label(_up_rollover);
if (!_up_rollover_event.empty())
throw_event(_up_rollover_event);
} else {
_mgr->add_label(_up);
if (!_up_event.empty())
throw_event(_up_event);
_state = UP;
}
_rgn->trap_clicks(true);
break;
case DOWN:
_mgr->add_label(_down);
if (!_down_event.empty())
throw_event(_down_event);
_rgn->trap_clicks(true);
break;
case DOWN_ROLLOVER:
if (_down_rollover != (GuiLabel*)0L) {
_mgr->add_label(_down_rollover);
if (!_down_rollover_event.empty())
throw_event(_down_rollover_event);
} else {
_mgr->add_label(_down);
if (!_down_event.empty())
throw_event(_down_event);
_state = DOWN;
}
_rgn->trap_clicks(true);
break;
case INACTIVE:
if (_inactive != (GuiLabel*)0L) {
_mgr->add_label(_inactive);
if (!_inactive_event.empty())
throw_event(_inactive_event);
}
_rgn->trap_clicks(false);
break;
case INACTIVE_ROLLOVER:
if (_inactive != (GuiLabel*)0L) {
_mgr->add_label(_inactive);
if (!_inactive_event.empty())
throw_event(_inactive_event);
}
_rgn->trap_clicks(false);
break;
default:
gui_cat->warning() << "switched to invalid state (" << _state << ")"
<< endl;
}
}
GuiButton::GuiButton(const string& name, GuiLabel* up, GuiLabel* up_roll,
GuiLabel* down, GuiLabel* down_roll, GuiLabel* inactive)
: Namable(name), _up(up), _up_rollover(up_roll), _down(down),
_down_rollover(down_roll), _inactive(inactive), _state(GuiButton::NONE),
_added_hooks(false), _mgr((GuiManager*)0L), _up_event(name + "-up"),
_up_rollover_event(name + "-up-rollover"), _down_event(name +"-down"),
_down_rollover_event(name + "-down-rollover"),
_inactive_event(name + "-inactive") {
float left, right, bottom, top;
GetExtents(up, down, up_roll, down_roll, inactive, left, right, bottom, top);
_rgn = new GuiRegion("button-" + name, left, right, bottom, top, true);
buttons["gui-in-button-" + name] = this;
buttons["gui-out-button-" + name] = this;
buttons["gui-button-" + name + "-mouse1"] = this;
buttons["gui-button-" + name + "-mouse2"] = this;
buttons["gui-button-" + name + "-mouse3"] = this;
}
GuiButton::~GuiButton(void) {
}
void GuiButton::manage(GuiManager* mgr, EventHandler& eh) {
if (!_added_hooks) {
eh.add_hook("gui-in-button-" + get_name(), enter_button);
eh.add_hook("gui-out-button-" + get_name(), exit_button);
eh.add_hook("gui-button-" + get_name() + "-mouse1", click_button);
eh.add_hook("gui-button-" + get_name() + "-mouse2", click_button);
eh.add_hook("gui-button-" + get_name() + "-mouse3", click_button);
_added_hooks = true;
}
if (_mgr == (GuiManager*)0L) {
mgr->add_region(_rgn);
_mgr = mgr;
switch_state(UP);
} else
gui_cat->warning() << "tried to manage button (0x" << (void*)this
<< ") that is already managed" << endl;
}
void GuiButton::unmanage(void) {
_mgr->remove_region(_rgn);
switch_state(NONE);
_mgr = (GuiManager*)0L;
}

View File

@ -2,3 +2,66 @@
// Created by: cary (30Oct00)
//
////////////////////////////////////////////////////////////////////
#ifndef __GUIBUTTON_H__
#define __GUIBUTTON_H__
#include "guiRegion.h"
#include "guiLabel.h"
#include "guiManager.h"
#include <eventHandler.h>
class GuiButton : public Namable {
private:
GuiLabel* _up;
GuiLabel* _up_rollover;
GuiLabel* _down;
GuiLabel* _down_rollover;
GuiLabel* _inactive;
string _up_event, _up_rollover_event, _down_event, _down_rollover_event;
string _inactive_event;
GuiRegion* _rgn;
enum States { NONE, UP, UP_ROLLOVER, DOWN, DOWN_ROLLOVER, INACTIVE,
INACTIVE_ROLLOVER };
States _state;
bool _added_hooks;
GuiManager* _mgr;
INLINE GuiButton(void);
void switch_state(States);
public:
GuiButton(const string&, GuiLabel*, GuiLabel*, GuiLabel*, GuiLabel*,
GuiLabel*);
~GuiButton(void);
void manage(GuiManager*, EventHandler&);
void unmanage(void);
INLINE void enter(void);
INLINE void exit(void);
INLINE void up(void);
INLINE void down(void);
INLINE void inactive(void);
INLINE void click(void);
INLINE bool is_up(void) const;
INLINE bool is_over(void) const;
INLINE bool is_active(void) const;
INLINE void set_up_event(const string&);
INLINE void set_up_rollover_event(const string&);
INLINE void set_down_event(const string&);
INLINE void set_down_rollover_event(const string&);
INLINE void set_inactive_event(const string&);
INLINE const string& get_up_event(void) const;
INLINE const string& get_up_rollover_event(void) const;
INLINE const string& get_down_event(void) const;
INLINE const string& get_down_rollover_event(void) const;
INLINE const string& get_inactive_event(void) const;
};
#include "guiButton.I"
#endif /* __GUIBUTTON_H__ */

View File

@ -3,5 +3,17 @@
//
////////////////////////////////////////////////////////////////////
INLINE GuiLabel::GuiLabel(void) {
INLINE GuiLabel::GuiLabel(void) : _type(GuiLabel::NONE) {
}
INLINE Node* GuiLabel::get_geometry(void) const {
return _geom;
}
INLINE void GuiLabel::set_arc(RenderRelation* r) {
_arc = r;
}
INLINE RenderRelation* GuiLabel::get_arc(void) const {
return _arc;
}

View File

@ -4,3 +4,50 @@
////////////////////////////////////////////////////////////////////
#include "guiLabel.h"
GuiLabel::~GuiLabel(void) {
}
GuiLabel* GuiLabel::make_simple_texture_label(void) {
return new GuiLabel();
}
#include <textNode.h>
GuiLabel* GuiLabel::make_simple_text_label(const string& text, Node* font) {
GuiLabel* ret = new GuiLabel();
ret->_type = SIMPLE_TEXT;
TextNode* n = new TextNode("GUI label");
ret->_geom = n;
LMatrix4f mat = LMatrix4f::scale_mat(0.1);
n->set_transform(mat);
n->set_font(font);
// n->set_card_color(1., 1., 1., 0.);
n->set_align(TM_ALIGN_CENTER);
n->set_text_color(1., 1., 1., 1.);
n->set_text(text);
return ret;
}
void GuiLabel::get_extents(float& l, float& r, float& b, float& t) {
switch (_type) {
case SIMPLE_TEXT:
{
TextNode* n = DCAST(TextNode, _geom);
LVector3f ul = n->get_upper_left_3d() - LPoint3f::origin();
LVector3f lr = n->get_lower_right_3d() - LPoint3f::origin();
LVector3f up = LVector3f::up();
LVector3f right = LVector3f::right();
l = ul.dot(right);
r = lr.dot(right);
b = lr.dot(up);
t = ul.dot(up);
}
break;
default:
gui_cat->warning()
<< "trying to get extents from something I don't know how to" << endl;
l = b = 0.;
r = t = 1.;
}
}

View File

@ -6,12 +6,39 @@
#ifndef __GUILABEL_H__
#define __GUILABEL_H__
#include "config_gui.h"
#include <pandabase.h>
#include <node.h>
#include <pt_Node.h>
#include <renderRelation.h>
// label-ish behavior for GUI objects (labels, buttons, rollovers)
class GuiManager;
class GuiLabel {
private:
enum LabelType { NONE, SIMPLE_TEXTURE, SIMPLE_TEXT };
LabelType _type;
PT_Node _geom;
RenderRelation* _arc;
INLINE Node* get_geometry(void) const;
INLINE void set_arc(RenderRelation*);
INLINE RenderRelation* get_arc(void) const;
friend GuiManager;
public:
INLINE GuiLabel(void);
virtual ~GuiLabel(void);
static GuiLabel* make_simple_texture_label(void);
static GuiLabel* make_simple_text_label(const string&, Node*);
void get_extents(float&, float&, float&, float&);
};
#include "guiLabel.I"
#endif /* __GUILABEL_H__ */

View File

@ -3,9 +3,6 @@
//
////////////////////////////////////////////////////////////////////
INLINE GuiManager* GuiManager::get_ptr(void) {
if (_singleton == (GuiManager*)0L) {
_singleton = new GuiManager;
}
return _singleton;
INLINE GuiManager::GuiManager(MouseWatcher* w, Node* n) : _root(n),
_watcher(w) {
}

View File

@ -4,6 +4,7 @@
////////////////////////////////////////////////////////////////////
#include "guiManager.h"
#include "config_gui.h"
#include <dataRelation.h>
#include <renderRelation.h>
@ -19,14 +20,22 @@ GuiManager::GuiMap* GuiManager::_map = (GuiManager::GuiMap*)0L;
GuiManager* GuiManager::get_ptr(GraphicsWindow* w, MouseAndKeyboard* mak) {
GuiManager* ret;
if (_map == (GuiMap*)0L)
if (_map == (GuiMap*)0L) {
if (gui_cat->is_debug())
gui_cat->debug() << "allocating a manager map" << endl;
_map = new GuiMap;
}
GuiMap::const_iterator gi;
gi = _map->find(w);
if (gi != _map->end())
if (gi != _map->end()) {
ret = (*gi).second;
else {
if (gui_cat->is_debug())
gui_cat->debug() << "a manager for this window already exists (0x"
<< (void*)ret << ")" << endl;
} else {
// going to allocate a new GuiManager for this window
if (gui_cat->is_debug())
gui_cat->debug() << "allocating a new manager for this window" << endl;
// first see if there is a mouseWatcher already under the MouseAndKeyboard
bool has_watcher = false;
TypeHandle dgt = DataRelation::get_class_type();
@ -40,6 +49,8 @@ GuiManager* GuiManager::get_ptr(GraphicsWindow* w, MouseAndKeyboard* mak) {
if (!has_watcher) {
// there isn't already a mousewatcher in the data graph, so we'll make
// one and re-parent everything to it.
if (gui_cat->is_debug())
gui_cat->debug() << "no MouseWatcher found, making one" << endl;
watcher = new MouseWatcher("GUI watcher");
DataRelation* tmp = new DataRelation(mak, watcher);
for (int j=0; j<mak->get_num_children(dgt); ++j) {
@ -48,7 +59,30 @@ GuiManager* GuiManager::get_ptr(GraphicsWindow* w, MouseAndKeyboard* mak) {
// it's not the node we just created, so reparent it to ours
rel->change_parent(watcher);
}
}
} else if (gui_cat->is_debug())
gui_cat->debug() << "found a MouseWatcher, don't have to make one"
<< endl;
// now setup event triggers for the watcher
if (has_watcher)
gui_cat->warning() << "overwriting existing button down pattern '"
<< watcher->get_button_down_pattern()
<< "' with 'gui-%r-%b'" << endl;
watcher->set_button_down_pattern("gui-%r-%b");
if (has_watcher)
gui_cat->warning() << "overwriting existing button up pattern '"
<< watcher->get_button_up_pattern()
<< "' with 'gui-%r-%b-up'" << endl;
watcher->set_button_up_pattern("gui-%r-%b");
if (has_watcher)
gui_cat->warning() << "overwriting existing enter pattern '"
<< watcher->get_enter_pattern()
<< "' with 'gui-in-%r'" << endl;
watcher->set_enter_pattern("gui-in-%r");
if (has_watcher)
gui_cat->warning() << "overwriting existing exit pattern '"
<< watcher->get_leave_pattern()
<< "' with 'gui-out-%r'" << endl;
watcher->set_leave_pattern("gui-out-%r");
// next, create a 2d layer for the GUI stuff to live in.
Node* root2d_top = new NamedNode("GUI_top");
Node* root2d = new NamedNode("GUI");
@ -71,9 +105,63 @@ GuiManager* GuiManager::get_ptr(GraphicsWindow* w, MouseAndKeyboard* mak) {
DisplayRegion *dr = layer->make_display_region();
nassertv(dr != (DisplayRegion*)0L);
dr->set_camera(cam);
if (gui_cat->is_debug())
gui_cat->debug() << "2D layer created" << endl;
// now make the manager for this window
ret = new GuiManager(watcher, root2d);
if (gui_cat->is_debug())
gui_cat->debug() << "new manager allocated (0x" << (void*)ret << ")"
<< endl;
(*_map)[w] = ret;
}
return ret;
}
void GuiManager::add_region(GuiRegion* region) {
RegionSet::const_iterator ri;
ri = _regions.find(region);
if (ri == _regions.end()) {
_watcher->add_region(region->get_region());
_regions.insert(region);
} else
gui_cat->warning() << "tried adding region ('" << *region
<< "') more then once" << endl;
}
void GuiManager::add_label(GuiLabel* label) {
LabelSet::const_iterator li;
li = _labels.find(label);
if (li == _labels.end()) {
// add it to the scenegraph
label->set_arc(new RenderRelation(_root, label->get_geometry()));
_labels.insert(label);
} else
gui_cat->warning() << "tried adding label (0x" << (void*)label
<< ") more then once" << endl;
}
void GuiManager::remove_region(GuiRegion* region) {
RegionSet::const_iterator ri;
ri = _regions.find(region);
if (ri == _regions.end())
gui_cat->warning() << "tried removing region ('" << *region
<< "') that isn't there" << endl;
else {
_watcher->remove_region(region->get_region());
_regions.erase(ri);
}
}
void GuiManager::remove_label(GuiLabel* label) {
LabelSet::const_iterator li;
li = _labels.find(label);
if (li == _labels.end())
gui_cat->warning() << "label (0x" << (void*)label
<< ") is not there to be removed" << endl;
else {
// remove it to the scenegraph
remove_arc(label->get_arc());
label->set_arc((RenderRelation*)0L);
_labels.erase(li);
}
}

View File

@ -6,11 +6,40 @@
#ifndef __GUIMANAGER_H__
#define __GUIMANAGER_H__
#include <pandabase.h>
#include <graphicsWindow.h>
#include <mouse.h>
#include <mouseWatcher.h>
#include <node.h>
#include <set>
#include "guiRegion.h"
#include "guiLabel.h"
#include "config_gui.h"
class GuiManager {
private:
static GuiManager* _singleton;
typedef map<GraphicsWindow*, GuiManager*> GuiMap;
static GuiMap* _map;
typedef set<GuiRegion*> RegionSet;
RegionSet _regions;
typedef set<GuiLabel*> LabelSet;
LabelSet _labels;
Node* _root;
MouseWatcher* _watcher;
INLINE GuiManager(MouseWatcher*, Node*);
public:
INLINE static GuiManager* get_ptr(void);
static GuiManager* get_ptr(GraphicsWindow*, MouseAndKeyboard*);
void add_region(GuiRegion*);
void add_label(GuiLabel*);
void remove_region(GuiRegion*);
void remove_label(GuiLabel*);
};
#include "guiManager.I"
#endif /* __GUIMANAGER_H__ */

View File

@ -3,8 +3,21 @@
//
////////////////////////////////////////////////////////////////////
INLINE GiuRegion::GuiRegion(void) {
INLINE GuiRegion::GuiRegion(void) {
}
INLINE GiuRegion::GuiRegion(float, float, float, float) {
INLINE GuiRegion::GuiRegion(const string& name, float l, float r, float b,
float t, bool buttons) : Namable(name), _left(l),
_right(r), _bottom(b),
_top(t) {
_region = new MouseWatcherRegion(name, l, r, b, t);
_region->set_suppress_below(buttons);
}
INLINE MouseWatcherRegion* GuiRegion::get_region(void) const {
return _region;
}
INLINE void GuiRegion::trap_clicks(bool t) {
_region->set_suppress_below(t);
}

View File

@ -4,3 +4,6 @@
////////////////////////////////////////////////////////////////////
#include "guiRegion.h"
GuiRegion::~GuiRegion(void) {
}

View File

@ -6,13 +6,29 @@
#ifndef __GUIREGION_H__
#define __GUIREGION_H__
#include <pandabase.h>
#include <mouseWatcherRegion.h>
#include <pointerTo.h>
// container for active regions of a GUI
class GuiRegion {
class GuiManager;
class GuiRegion : public Namable {
private:
float _left, _right, _bottom, _top;
PT(MouseWatcherRegion) _region;
INLINE GuiRegion(void);
INLINE MouseWatcherRegion* get_region(void) const;
friend GuiManager;
public:
INLINE GuiRegion(float, float, float, float);
INLINE GuiRegion(const string&, float, float, float, float, bool);
~GuiRegion(void);
INLINE void trap_clicks(bool);
};
#include "guiRegion.I"

View File

@ -3,5 +3,33 @@
//
////////////////////////////////////////////////////////////////////
INLINE GuiRollover::GuiRollover(float, float, float, float) {
INLINE GuiRollover::GuiRollover(void) {
}
INLINE void GuiRollover::enter(void) {
if (_state) {
if (gui_cat->is_debug())
gui_cat->debug() << "entered '" << *this
<< "' more then once without exit" << endl;
} else if (_mgr != (GuiManager*)0L) {
_mgr->remove_label(_off);
_mgr->add_label(_on);
_state = true;
}
}
INLINE void GuiRollover::exit(void) {
if (!_state) {
if (gui_cat->is_debug())
gui_cat->debug() << "exited '" << *this
<< "' more then once without enter" << endl;
} else if (_mgr != (GuiManager*)0L) {
_mgr->remove_label(_on);
_mgr->add_label(_off);
_state = false;
}
}
INLINE bool GuiRollover::is_over(void) const {
return _state;
}

View File

@ -4,3 +4,67 @@
////////////////////////////////////////////////////////////////////
#include "guiRollover.h"
#include "config_gui.h"
#include <map>
typedef map<string, GuiRollover*> RolloverMap;
static RolloverMap rollovers;
inline void GetExtents(GuiLabel* x, GuiLabel* y, float& l, float& r, float& b,
float& t) {
float l1, l2, r1, r2, b1, b2, t1, t2;
x->get_extents(l1, r1, b1, t1);
y->get_extents(l2, r2, b2, t2);
l = (l1<l2)?l1:l2;
r = (r1<r2)?r2:r1;
b = (b1<b2)?b1:b2;
t = (t1<t2)?t2:t1;
}
static void enter_rollover(CPT_Event e) {
GuiRollover* val = rollovers[e->get_name()];
val->enter();
}
static void exit_rollover(CPT_Event e) {
GuiRollover* val = rollovers[e->get_name()];
val->exit();
}
GuiRollover::GuiRollover(const string& name, GuiLabel* off, GuiLabel* on)
: Namable(name), _off(off), _on(on), _state(false), _added_hooks(false) {
float left, right, bottom, top;
GetExtents(off, on, left, right, bottom, top);
_rgn = new GuiRegion("rollover-" + name, left, right, bottom, top, false);
rollovers["gui-in-rollover-" + name] = this;
rollovers["gui-out-rollover-" + name] = this;
_mgr = (GuiManager*)0L;
}
GuiRollover::~GuiRollover(void) {
}
void GuiRollover::manage(GuiManager* mgr, EventHandler& eh) {
if (!_added_hooks) {
eh.add_hook("gui-in-rollover-" + get_name(), enter_rollover);
eh.add_hook("gui-out-rollover-" + get_name(), exit_rollover);
_added_hooks = true;
}
if (_mgr == (GuiManager*)0L) {
mgr->add_region(_rgn);
_state = false;
mgr->add_label(_off);
_mgr = mgr;
} else
gui_cat->warning() << "tried to manage rollover (0x" << (void*)this
<< ") that is already managed" << endl;
}
void GuiRollover::unmanage(void) {
_mgr->remove_region(_rgn);
_mgr->remove_label(_off);
_mgr->remove_label(_on);
_mgr = (GuiManager*)0L;
}

View File

@ -6,10 +6,35 @@
#ifndef __GUIROLLOVER_H__
#define __GUIROLLOVER_H__
class GuiRollover : public GuiBaseButton {
#include "guiRegion.h"
#include "guiLabel.h"
#include "guiManager.h"
#include <eventHandler.h>
class GuiRollover : public Namable {
private:
GuiLabel* _off;
GuiLabel* _on;
GuiRegion* _rgn;
bool _state;
bool _added_hooks;
GuiManager* _mgr;
INLINE GuiRollover(void);
public:
INLINE GuiRollover(float, float, float, float);
GuiRollover(const string&, GuiLabel*, GuiLabel*);
~GuiRollover(void);
void manage(GuiManager*, EventHandler&);
void unmanage(void);
INLINE void enter(void);
INLINE void exit(void);
INLINE bool is_over(void) const;
};
#include "guiRollover.I"
#endif /* __GUIROLLOVER_H__ */

View File

@ -131,3 +131,12 @@
#end test_bin_target
#begin test_bin_target
#define TARGET gui_demo
#define SOURCES \
gui_demo.cxx
#define LOCAL_LIBS $[LOCAL_LIBS] gui
#end test_bin_target

View File

@ -40,8 +40,11 @@
#include <pta_Colorf.h>
#include <pta_float.h>
#include <pt_Node.h>
#include <modelPool.h>
#include <guiManager.h>
#include <guiRollover.h>
#include <guiButton.h>
//From framework
extern PT(GeomNode) geomnode;
@ -49,6 +52,23 @@ extern RenderRelation* first_arc;
static void setup_gui(void) {
GuiManager* mgr = GuiManager::get_ptr(main_win, mak);
PT_Node font = ModelPool::load_model("ttf-comic");
// test 1
// mgr->add_region(new GuiRegion("test1", 0., 0.25, 0., 0.25));
// mgr->add_label(GuiLabel::make_simple_text_label("test2", font));
// test 2
// GuiLabel* l1 = GuiLabel::make_simple_text_label("off", font);
// GuiLabel* l2 = GuiLabel::make_simple_text_label("on", font);
// GuiRollover* r1 = new GuiRollover("test2", l1, l2);
// r1->manage(mgr, event_handler);
// test 3
GuiLabel* l1 = GuiLabel::make_simple_text_label("up", font);
GuiLabel* l2 = GuiLabel::make_simple_text_label("upr", font);
GuiLabel* l3 = GuiLabel::make_simple_text_label("down", font);
GuiLabel* l4 = GuiLabel::make_simple_text_label("downr", font);
GuiLabel* l5 = GuiLabel::make_simple_text_label("none", font);
GuiButton* b1 = new GuiButton("test3", l1, l2, l3, l4, l5);
b1->manage(mgr, event_handler);
}
static void event_2(CPT_Event) {