From Jeremy Moles, import of the osgWidget NodeKit, sourced from the original http://osgwidget.googlecode.com/svn/trunk

Notes from Robert Osfield, I've merged osgWidget trunk, and added/changed CMakeLists.txt file to make it suitable for inclusion in the core OSG, and moved imagery/scripts/shaders out into OpenSceneGraph-Data
This commit is contained in:
Robert Osfield
2008-07-15 17:21:25 +00:00
parent 0c3d119cea
commit c2b77aa08e
77 changed files with 9643 additions and 15 deletions

39
include/osgWidget/Box Normal file
View File

@@ -0,0 +1,39 @@
// -*-c++-*- osgWidget - Code by: Jeremy Moles (cubicool) 2007-2008
// $Id: Box 46 2008-04-30 16:11:51Z cubicool $
#ifndef OSGWIDGET_BOX
#define OSGWIDGET_BOX
#include <osgWidget/Window>
namespace osgWidget {
class OSGWIDGET_EXPORT Box: public Window {
public:
enum BOX_TYPE {
VERTICAL,
HORIZONTAL
};
private:
BOX_TYPE _boxType;
bool _uniform;
unsigned int _lastAdd;
protected:
virtual void _resizeImplementation(point_type, point_type);
virtual Sizes _getWidthImplementation () const;
virtual Sizes _getHeightImplementation () const;
public:
META_Object (osgWidget, Box);
META_UIObject (Box);
Box (const std::string& = "", BOX_TYPE = HORIZONTAL, bool = false);
Box (const Box&, const osg::CopyOp&);
};
}
#endif

28
include/osgWidget/Canvas Normal file
View File

@@ -0,0 +1,28 @@
// -*-c++-*- osgWidget - Code by: Jeremy Moles (cubicool) 2007-2008
// $Id: Canvas 66 2008-07-14 21:54:09Z cubicool $
#ifndef OSGWIDGET_CANVAS
#define OSGWIDGET_CANVAS
#include <osgWidget/Window>
namespace osgWidget {
class OSGWIDGET_EXPORT Canvas: public Window {
protected:
virtual void _resizeImplementation(point_type, point_type);
public:
META_Object (osgWidget, Canvas);
META_UIObject (Canvas);
Canvas (const std::string& = "");
Canvas (const Canvas&, const osg::CopyOp&);
// This would conflict with the normal addWidget if there were default values. :(
virtual bool addWidget(Widget*, point_type, point_type);
};
}
#endif

View File

@@ -0,0 +1,376 @@
// -*-c++-*- osgWidget - Code by: Jeremy Moles (cubicool) 2007-2008
// $Id: EventInterface 64 2008-06-30 21:32:00Z cubicool $
#ifndef OSGWIDGET_EVENT_INTERFACE
#define OSGWIDGET_EVENT_INTERFACE
#include <list>
#include <osg/ref_ptr>
#include <osg/Referenced>
#include <osgWidget/Export>
namespace osgWidget {
class WindowManager;
class Window;
class Widget;
enum EVENT_TYPE {
EVENT_NONE = 0x0000,
EVENT_FOCUS = 0x0001,
EVENT_UNFOCUS = 0x0002,
EVENT_MOUSE_ENTER = 0x0004,
EVENT_MOUSE_OVER = 0x0008,
EVENT_MOUSE_LEAVE = 0x0010,
EVENT_MOUSE_DRAG = 0x0020,
EVENT_MOUSE_PUSH = 0x0040,
EVENT_MOUSE_RELEASE = 0x0080,
EVENT_MOUSE_SCROLL = 0x0100,
EVENT_KEY_DOWN = 0x0200,
EVENT_KEY_UP = 0x0400,
EVENT_ALL = 0xFFFF
};
// Helpful wrapper around using the raw types, since it often doesn't make sense to
// use some without the others.
enum EVENT_MASK {
EVENT_MASK_FOCUS = EVENT_FOCUS | EVENT_UNFOCUS,
EVENT_MASK_MOUSE_MOVE = EVENT_MOUSE_ENTER | EVENT_MOUSE_OVER | EVENT_MOUSE_LEAVE,
EVENT_MASK_MOUSE_CLICK = EVENT_MOUSE_PUSH | EVENT_MOUSE_RELEASE,
EVENT_MASK_MOUSE_DRAG = EVENT_MASK_MOUSE_MOVE | EVENT_MASK_MOUSE_CLICK | EVENT_MOUSE_DRAG,
EVENT_MASK_KEY = EVENT_KEY_UP | EVENT_KEY_DOWN
};
class OSGWIDGET_EXPORT Event {
friend class WindowManager;
friend class Window;
WindowManager* _wm;
Window* _window;
Widget* _widget;
void* _data;
public:
EVENT_TYPE type;
double x;
double y;
int key;
int keyMask;
Event(WindowManager* wm, EVENT_TYPE _type = EVENT_NONE):
_wm (wm),
_window (0),
_widget (0),
_data (0),
type (_type),
x (0.0f),
y (0.0f),
key (-1),
keyMask (-1) {
}
Event& makeType(EVENT_TYPE _type) {
if(_type != EVENT_NONE) type = _type;
return *this;
}
Event& makeMouse(double _x, double _y, EVENT_TYPE _type = EVENT_NONE) {
x = _x;
y = _y;
if(_type != EVENT_NONE) type = _type;
return *this;
}
Event& makeKey(int _key, int _keyMask, EVENT_TYPE _type = EVENT_NONE) {
key = _key;
keyMask = _keyMask;
if(_type != EVENT_NONE) type = _type;
return *this;
}
WindowManager* getWindowManager() {
return _wm;
}
const WindowManager* getWindowManager() const {
return _wm;
}
Window* getWindow() {
return _window;
}
const Window* getWindow() const {
return _window;
}
Widget* getWidget() {
return _widget;
}
const Widget* getWidget() const {
return _widget;
}
void* getData() {
return _data;
}
const void* getData() const {
return _data;
}
void setData(void* data) {
_data = data;
}
};
// The Callback interface was inspired by the CEGUI project:
//
// http://www.cegui.org.uk/wiki/index.php/Main_Page
//
// It's a great little way to cleanly implement callbacks for events, although
// I did change the names a bit to make them more appropriate for OSG. MANY THANKS
// to the CEGUI project!
// The CallbackInterface, which the highest-level functor keeps a pointer to.
struct CallbackInterface: public osg::Referenced {
virtual ~CallbackInterface() {
}
virtual bool operator()(Event&) = 0;
};
// The object that facilitates a class method as a callback.
template<typename T>
class ObjectCallback: public CallbackInterface {
public:
typedef bool (T::*ObjectCallbackType)(Event&);
private:
ObjectCallbackType _callback;
T* _object;
public:
ObjectCallback(ObjectCallbackType callback, T* obj):
_callback (callback),
_object (obj) {
}
virtual bool operator()(Event& ev) {
return (_object->*_callback)(ev);
}
};
// The object that facilitates general functions as callbacks.
template<typename T>
class FunctionCallback: public CallbackInterface {
T* _callback;
public:
FunctionCallback(T* callback):
_callback(callback) {
}
virtual bool operator()(Event& ev) {
return (*_callback)(ev);
}
};
// The highlevel functor.
class OSGWIDGET_EXPORT Callback {
EVENT_TYPE _type;
void* _data;
// We use a ref_ptr here so that we don't have to worry about memory.
osg::ref_ptr<CallbackInterface> _callback;
public:
// Creates a Callback that is bound to a member function.
template<typename T>
Callback(bool (T::*function)(Event&), T* obj, EVENT_TYPE type, void* data=0):
_type (type),
_data (data),
_callback (new ObjectCallback<T>(function, obj)) {
}
// Creates a Callback that is bound to a functor pointer.
template<typename T>
Callback(T* functor, EVENT_TYPE type, void* data=0):
_type (type),
_data (data),
_callback (new FunctionCallback<T>(functor)) {
}
bool operator()(Event& ev) {
return (*_callback)(ev);
}
EVENT_TYPE getType() const {
return _type;
}
void* getData() {
return _data;
}
const void* getData() const {
return _data;
}
};
class OSGWIDGET_EXPORT EventInterface {
private:
typedef std::list<Callback> CallbackList;
unsigned int _eventMask;
CallbackList _callbacks;
public:
EventInterface():
_eventMask(EVENT_NONE) {
}
EventInterface(const EventInterface& ei):
_eventMask (ei._eventMask),
_callbacks (ei._callbacks) {
}
virtual ~EventInterface() {
}
// These functions take as their final argument the WindowManager which issued the
// request. This is sometimes useful to get information about key state, etc.
// Notify the EventInterface object that is has been focused or unfocused; since
// this isn't always bound to a mouse event (i.e., if you want to be able to use
// the TAB key to focus), we need seperate events here.
virtual bool focus (WindowManager*) { return false; }
virtual bool unfocus (WindowManager*) { return false; }
// Mouse events, pretty self-explanatory.
virtual bool mouseEnter (double, double, WindowManager*) { return false; }
virtual bool mouseOver (double, double, WindowManager*) { return false; }
virtual bool mouseLeave (double, double, WindowManager*) { return false; }
virtual bool mouseDrag (double, double, WindowManager*) { return false; }
virtual bool mousePush (double, double, WindowManager*) { return false; }
virtual bool mouseRelease (double, double, WindowManager*) { return false; }
virtual bool mouseScroll (double, double, WindowManager*) { return false; }
// These functions pass the osgGA::GUIEventAdapter::KeySymbol and KeyModMask and,
// as above, the WindowManager.
virtual bool keyDown (int, int, WindowManager*) { return false; }
virtual bool keyUp (int, int, WindowManager*) { return false; }
void setEventMask(unsigned int mask) {
_eventMask = mask;
}
void addEventMask(unsigned int mask) {
_eventMask |= mask;
}
void removeEventMask(unsigned int mask) {
_eventMask ^= mask;
}
unsigned int getEventMask() const {
return _eventMask;
}
void addCallback(const Callback& cb) {
_callbacks.push_back(cb);
}
bool callCallbacks(Event& ev) {
if(ev.type == EVENT_NONE || !(_eventMask & ev.type)) return false;
for(CallbackList::iterator i = _callbacks.begin(); i != _callbacks.end(); i++) {
// This is the OLD method; testing a new method below.
// if(i->getType() == ev.type && (*i)(ev)) return true;
if(i->getType() == ev.type) {
ev.setData(i->getData());
if((*i)(ev)) return true;
}
}
return false;
}
bool callMethodAndCallbacks(Event& ev) {
if(ev.type == EVENT_NONE || !(_eventMask & ev.type)) return false;
bool handled = false;
if(ev.type == EVENT_FOCUS) handled = focus(ev.getWindowManager());
else if(ev.type == EVENT_UNFOCUS) handled = unfocus(ev.getWindowManager());
else if(ev.type == EVENT_MOUSE_ENTER)
handled = mouseEnter(ev.x, ev.y, ev.getWindowManager())
;
else if(ev.type == EVENT_MOUSE_OVER)
handled = mouseOver(ev.x, ev.y, ev.getWindowManager())
;
else if(ev.type == EVENT_MOUSE_LEAVE)
handled = mouseLeave(ev.x, ev.y, ev.getWindowManager())
;
else if(ev.type == EVENT_MOUSE_DRAG)
handled = mouseDrag(ev.x, ev.y, ev.getWindowManager())
;
else if(ev.type == EVENT_MOUSE_PUSH)
handled = mousePush(ev.x, ev.y, ev.getWindowManager())
;
else if(ev.type == EVENT_MOUSE_RELEASE)
handled = mouseRelease(ev.x, ev.y, ev.getWindowManager())
;
else if(ev.type == EVENT_MOUSE_SCROLL)
handled = mouseScroll(ev.x, ev.y, ev.getWindowManager())
;
else if(ev.type == EVENT_KEY_DOWN)
handled = keyDown(ev.key, ev.keyMask, ev.getWindowManager())
;
else if(ev.type == EVENT_KEY_UP)
handled = keyUp(ev.key, ev.keyMask, ev.getWindowManager())
;
else return false;
return callCallbacks(ev) || handled;
}
bool canFocus () const { return (_eventMask & EVENT_FOCUS) != 0; }
bool canUnfocus () const { return (_eventMask & EVENT_UNFOCUS) != 0; }
bool canMouseEnter () const { return (_eventMask & EVENT_MOUSE_ENTER) != 0; }
bool canMouseOver () const { return (_eventMask & EVENT_MOUSE_OVER) != 0; }
bool canMouseLeave () const { return (_eventMask & EVENT_MOUSE_LEAVE) != 0; }
bool canMouseDrag () const { return (_eventMask & EVENT_MOUSE_DRAG) != 0; }
bool canMousePush () const { return (_eventMask & EVENT_MOUSE_PUSH) != 0; }
bool canMouseRelease () const { return (_eventMask & EVENT_MOUSE_RELEASE) != 0; }
bool canMouseScroll () const { return (_eventMask & EVENT_MOUSE_SCROLL) != 0; }
bool canKeyDown () const { return (_eventMask & EVENT_KEY_DOWN) != 0; }
bool canKeyUp () const { return (_eventMask & EVENT_KEY_UP) != 0; }
};
}
#endif

47
include/osgWidget/Export Normal file
View File

@@ -0,0 +1,47 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
#ifndef OSGWIDGET_EXPORT_
#define OSGWIDGET_EXPORT_ 1
#if defined(_MSC_VER)
#pragma warning( disable : 4244 )
#pragma warning( disable : 4251 )
#pragma warning( disable : 4267 )
#pragma warning( disable : 4275 )
#pragma warning( disable : 4290 )
#pragma warning( disable : 4786 )
#pragma warning( disable : 4305 )
#pragma warning( disable : 4996 )
#endif
#if defined(_MSC_VER) || defined(__CYGWIN__) || defined(__MINGW32__) || defined( __BCPLUSPLUS__)
# if defined( OSG_LIBRARY_STATIC )
# define OSGWIDGET_EXPORT
# elif defined( OSGWIDGET_LIBRARY )
# define OSGWIDGET_EXPORT __declspec(dllexport)
# else
# define OSGWIDGET_EXPORT __declspec(dllimport)
# endif
#else
# define OSGWIDGET_EXPORT
#endif
/**
\namespace osgWidet
The osgWidget is a NodeKit library that extends the core scene graph to support 3D widget set.
*/
#endif

161
include/osgWidget/Frame Normal file
View File

@@ -0,0 +1,161 @@
// -*-c++-*- osgWidget - Code by: Jeremy Moles (cubicool) 2007-2008
// $Id: Frame 59 2008-05-15 20:55:31Z cubicool $
#ifndef OSGWIDGET_FRAME
#define OSGWIDGET_FRAME
#include <osgWidget/Table>
namespace osgWidget {
class OSGWIDGET_EXPORT Frame: public Table {
public:
enum CORNER {
CORNER_LOWER_LEFT,
CORNER_LOWER_RIGHT,
CORNER_UPPER_LEFT,
CORNER_UPPER_RIGHT
};
enum BORDER {
BORDER_LEFT,
BORDER_RIGHT,
BORDER_TOP,
BORDER_BOTTOM
};
protected:
Widget* _getCorner (CORNER) const;
Widget* _getBorder (BORDER) const;
public:
static std::string cornerToString (CORNER);
static std::string borderToString (BORDER);
class OSGWIDGET_EXPORT Corner: public Widget {
CORNER _corner;
public:
META_Object (osgWidget, Corner);
META_UIObject (Corner);
Corner (CORNER = CORNER_LOWER_LEFT, point_type = 0.0f, point_type = 0.0f);
Corner (const Corner&, const osg::CopyOp&);
bool mouseDrag(double, double, WindowManager*);
CORNER getCorner() const {
return _corner;
}
void setCorner(CORNER corner) {
_corner = corner;
}
void setCornerAndName(CORNER corner) {
_corner = corner;
_name = cornerToString(corner);
}
};
class OSGWIDGET_EXPORT Border: public Widget {
BORDER _border;
public:
META_Object (osgWidget, Border);
META_UIObject (Border);
Border (BORDER = BORDER_LEFT, point_type = 0.0f, point_type = 0.0f);
Border (const Border&, const osg::CopyOp&);
bool mouseDrag(double, double, WindowManager*);
BORDER getBorder() const {
return _border;
}
void setBorder(BORDER border) {
_border = border;
}
void setBorderAndName(BORDER border) {
_border = border;
_name = borderToString(border);
}
};
META_Object (osgWidget, Frame);
META_UIObject (Frame);
Frame (const std::string& = "");
Frame (const Frame&, const osg::CopyOp&);
virtual void managed(WindowManager*);
static Frame* createSimpleFrame(
const std::string&,
point_type,
point_type,
point_type,
point_type,
Frame* = 0
);
static Frame* createSimpleFrameWithSingleTexture(
const std::string&,
const std::string&,
point_type,
point_type,
point_type,
point_type,
point_type,
point_type,
Frame* = 0
);
void createSimpleFrame(point_type cw, point_type ch, point_type w, point_type h) {
createSimpleFrame(_name, cw, ch, w, h, this);
}
void createSimpleFrameWithSingleTexture(
const std::string& tex,
point_type tw,
point_type th,
point_type cw,
point_type ch,
point_type w,
point_type h
) {
createSimpleFrameWithSingleTexture(_name, tex, tw, th, cw, ch, w, h, this);
}
bool setWindow(Window*);
EmbeddedWindow* getEmbeddedWindow() {
return dynamic_cast<EmbeddedWindow*>(getByRowCol(1, 1));
}
const EmbeddedWindow* getEmbeddedWindow() const {
return dynamic_cast<const EmbeddedWindow*>(getByRowCol(1, 1));
}
Corner* getCorner(CORNER c) {
return dynamic_cast<Corner*>(_getCorner(c));
}
const Corner* getCorner(CORNER c) const {
return dynamic_cast<const Corner*>(_getCorner(c));
}
Border* getBorder(BORDER b) {
return dynamic_cast<Border*>(_getBorder(b));
}
const Border* getBorder(BORDER b) const {
return dynamic_cast<const Border*>(_getBorder(b));
}
};
}
#endif

77
include/osgWidget/Input Normal file
View File

@@ -0,0 +1,77 @@
// -*-c++-*- osgWidget - Code by: Jeremy Moles (cubicool) 2007-2008
// $Id: Input 45 2008-04-23 16:46:11Z cubicool $
#ifndef OSGWIDGET_INPUT
#define OSGWIDGET_INPUT
#include <osgWidget/Label>
namespace osgWidget {
class OSGWIDGET_EXPORT Input: public Label {
point_type _xoff;
point_type _yoff;
unsigned int _index;
unsigned int _size;
unsigned int _cursorIndex;
unsigned int _maxSize;
std::vector<point_type> _offsets;
osg::ref_ptr<Widget> _cursor;
protected:
virtual void _calculateSize(const XYCoord&);
void _calculateCursorOffsets();
public:
Input(const std::string& = "", const std::string& = "", unsigned int = 20);
virtual void parented (Window*);
virtual void positioned ();
virtual bool focus (WindowManager*);
virtual bool unfocus (WindowManager*);
virtual bool keyUp (int, int, WindowManager*);
virtual bool keyDown (int, int, WindowManager*);
void setCursor(Widget*);
void setXOffset(point_type xo) {
_xoff = xo;
}
void setYOffset(point_type yo) {
_yoff = yo;
}
void setXYOffset(point_type xo, point_type yo) {
_xoff = xo;
_yoff = yo;
}
osg::Drawable* getCursor() {
return _cursor.get();
}
const osg::Drawable* getCursor() const {
return _cursor.get();
}
point_type getXOffset() const {
return _xoff;
}
point_type getYOffset() const {
return _yoff;
}
XYCoord getXYOffset() const {
return XYCoord(_xoff, _yoff);
}
};
}
#endif

59
include/osgWidget/Label Normal file
View File

@@ -0,0 +1,59 @@
// -*-c++-*- osgWidget - Code by: Jeremy Moles (cubicool) 2007-2008
// $Id: Label 59 2008-05-15 20:55:31Z cubicool $
#ifndef OSGWIDGET_LABEL
#define OSGWIDGET_LABEL
#include <osgText/Text>
#include <osgWidget/Widget>
#include <osgWidget/Window>
namespace osgWidget {
class OSGWIDGET_EXPORT Label: public Widget {
unsigned int _textIndex;
protected:
osg::ref_ptr<osgText::Text> _text;
virtual void _calculateSize(const XYCoord&);
public:
META_Object (osgWidget, Label);
META_UIObject (Label);
Label (const std::string& = "", const std::string& = "");
Label (const Label&, const osg::CopyOp&);
virtual void parented (Window*);
virtual void unparented (Window*);
virtual void managed (WindowManager*);
virtual void positioned ();
void update ();
void setLabel (const std::string&);
void setFont (const std::string&);
void setFontSize (unsigned int);
void setFontColor (const Color&);
void setShadow (point_type);
XYCoord getTextSize() const;
std::string getLabel() const {
return _text->getText().createUTF8EncodedString();
}
void setFontColor(point_type r, point_type g, point_type b, point_type a) {
setFontColor(Color(r, g, b, a));
}
// For now you only get a const pointer, because we have a highly specific
// interface with the osgText library.
const osgText::Text* getText() const {
return _text.get();
}
};
}
#endif

31
include/osgWidget/Lua Normal file
View File

@@ -0,0 +1,31 @@
// -*-c++-*- osgWidget - Code by: Jeremy Moles (cubicool) 2007-2008
// $Id: Lua 2 2008-01-24 16:11:26Z cubicool $
#ifndef OSGWIDGET_LUA
#define OSGWIDGET_LUA
#include <osgWidget/WindowManager>
namespace osgWidget {
// Externally defined; does this work in Windows?
struct LuaEngineData;
// The actual Engine itself. Every attempt is made to export the implemenation into the
// source file, rather than having it here.
class OSGWIDGET_EXPORT LuaEngine: public ScriptEngine {
LuaEngineData* _data;
WindowManager* _wm;
public:
LuaEngine(WindowManager* = 0);
bool initialize ();
bool close ();
bool eval (const std::string&);
bool runFile (const std::string&);
};
}
#endif

28
include/osgWidget/Python Normal file
View File

@@ -0,0 +1,28 @@
// -*-c++-*- osgWidget - Code by: Jeremy Moles (cubicool) 2007-2008
// $Id: Python 2 2008-01-24 16:11:26Z cubicool $
#ifndef OSGWIDGET_PYTHON
#define OSGWIDGET_PYTHON
#include <osgWidget/WindowManager>
namespace osgWidget {
struct PythonEngineData;
class OSGWIDGET_EXPORT PythonEngine: public ScriptEngine {
PythonEngineData* _data;
WindowManager* _wm;
public:
PythonEngine(WindowManager* = 0);
bool initialize ();
bool close ();
bool eval (const std::string&);
bool runFile (const std::string&);
};
}
#endif

View File

@@ -0,0 +1,29 @@
// -*-c++-*- osgWidget - Code by: Jeremy Moles (cubicool) 2007-2008
// $Id: ScriptEngine 2 2008-01-24 16:11:26Z cubicool $
#ifndef OSGWIDGET_SCRIPT_ENGINE
#define OSGWIDGET_SCRIPT_ENGINE
#include <osg/Referenced>
namespace osgWidget {
// An interface for our scripting API so that we can have a unified way to talk to both
// Lua and Python; perhaps even more! Furthermore, this will allow us to put the
// entire implementation into a source file...
class ScriptEngine: public osg::Referenced {
protected:
std::string _err;
public:
virtual bool initialize () { return false; }
virtual bool close () { return false; }
virtual bool eval (const std::string&) { return false; }
virtual bool runFile (const std::string&) { return false; }
virtual const std::string& getLastErrorText() const { return _err; }
};
}
#endif

View File

@@ -0,0 +1,39 @@
// -*-c++-*- osgWidget - Code by: Jeremy Moles (cubicool) 2007-2008
// $Id: StyleInterface 63 2008-06-30 19:18:37Z cubicool $
#ifndef OSGWIDGET_STYLE_INTERFACE
#define OSGWIDGET_STYLE_INTERFACE
namespace osgWidget {
#include <osgWidget/Export>
class OSGWIDGET_EXPORT StyleInterface {
private:
std::string _style;
public:
StyleInterface():
_style("") {
}
StyleInterface(const StyleInterface& si):
_style(si._style) {
}
void setStyle(const std::string& style) {
_style = style;
}
std::string& getStyle() {
return _style;
}
const std::string& getStyle() const {
return _style;
}
};
}
#endif

View File

@@ -0,0 +1,175 @@
// -*-c++-*- osgWidget - Code by: Jeremy Moles (cubicool) 2007-2008
// $Id: StyleManager 61 2008-06-24 20:24:26Z cubicool $
#ifndef OSGWIDGET_STYLE_MANAGER
#define OSGWIDGET_STYLE_MANAGER
#include <map>
#include <osgDB/FieldReaderIterator>
#include <osgWidget/Box>
#include <osgWidget/Frame>
#include <osgWidget/Input>
namespace osgWidget {
typedef osgDB::FieldReaderIterator& Reader;
class OSGWIDGET_EXPORT Style: public osg::Object {
std::string _style;
bool _match(const char* seq, Reader r) {
if(r.matchSequence(seq)) {
++r;
return true;
}
return false;
}
public:
META_Object(osgWidget, Style);
// Class and contents...
Style (const std::string& = "", const std::string& = "");
Style (const Style&, const osg::CopyOp&);
virtual bool applyStyle (Widget*, Reader);
virtual bool applyStyle (Label*, Reader);
virtual bool applyStyle (Input*, Reader);
virtual bool applyStyle (Window*, Reader);
virtual bool applyStyle (Window::EmbeddedWindow*, Reader);
virtual bool applyStyle (Box*, Reader);
virtual bool applyStyle (Frame::Corner*, Reader);
virtual bool applyStyle (Frame::Border*, Reader);
void setStyle(const std::string& style) {
_style = style;
}
std::string& getStyle() {
return _style;
}
const std::string& getStyle() const {
return _style;
}
static Widget::LAYER strToLayer (const std::string&);
static Widget::VERTICAL_ALIGNMENT strToVAlign (const std::string&);
static Widget::HORIZONTAL_ALIGNMENT strToHAlign (const std::string&);
static Widget::COORDINATE_MODE strToCoordMode (const std::string&);
static bool strToFill (const std::string&);
};
class OSGWIDGET_EXPORT StyleManager: public osg::Object {
public:
typedef std::map<std::string, osg::ref_ptr<Style> > Styles;
typedef Styles::iterator Iterator;
typedef Styles::const_iterator ConstIterator;
private:
Styles _styles;
template<typename T>
bool _applySpecificStyle(T* t, const std::string& style) {
osgDB::FieldReaderIterator r;
std::istringstream input(_styles[style]->getStyle());
r.attach(&input);
bool inc = false;
while(!r.eof()) if(_styles[style]->applyStyle(t, r)) inc = true;
return inc;
}
template<typename T>
bool _coerceAndApply(
osg::Object* obj,
const std::string& style,
const std::string& className
) {
T* t = dynamic_cast<T*>(obj);
if(!t) {
warn()
<< "An attempt was made to coerce Object [" << obj->getName()
<< "] into a " << className << " but failed." << std::endl
;
return 0;
}
return _applySpecificStyle(t, style);
}
bool _applyStyleToObject(osg::Object*, const std::string&);
// 1. Check and see if the explicit FULL path is available.
// 2. Check and see if each component working backward--minus the last--is available.
// 3. Check to see if just the className() is available.
template<typename T>
bool _applyStyles(T* t) {
if(!t) {
warn()
<< "Cannot call StyleManager::applyStyle with a NULL object."
<< std::endl
;
return false;
}
osg::Object* obj = dynamic_cast<osg::Object*>(t);
if(!obj) {
warn()
<< "Cannot coerce object into osg::Object in StyleManager:::applyStyle"
<< std::endl
;
return false;
}
std::string c = obj->className();
// Case 3; there's no explicit Style set, so see if there's one for the class.
if(t->getStyle().empty()) {
// Couldn't find the className, so we exit.
if(_styles.find(c) == _styles.end()) return false;
return _applyStyleToObject(obj, c);
}
// Case 1...
if(_styles.find(t->getStyle()) != _styles.end()) return _applyStyleToObject(
obj,
t->getStyle()
);
return false;
}
public:
META_Object(osgWidget, StyleManager);
StyleManager ();
StyleManager (const StyleManager&, const osg::CopyOp&);
bool addStyle(Style*);
bool applyStyles(Widget* widget) {
return _applyStyles(widget);
}
bool applyStyles(Window* window) {
return _applyStyles(window);
}
};
}
#endif

63
include/osgWidget/Table Normal file
View File

@@ -0,0 +1,63 @@
// -*-c++-*- osgWidget - Code by: Jeremy Moles (cubicool) 2007-2008
// $Id: Table 48 2008-05-05 14:13:20Z cubicool $
#ifndef OSGWIDGET_TABLE
#define OSGWIDGET_TABLE
#include <osgWidget/Window>
namespace osgWidget {
class OSGWIDGET_EXPORT Table: public Window {
unsigned int _rows;
unsigned int _cols;
unsigned int _lastRowAdd;
unsigned int _lastColAdd;
public:
typedef std::vector<point_type> CellSizes;
protected:
unsigned int _calculateIndex(unsigned int, unsigned int) const;
void _getRows (CellSizes&, Getter) const;
void _getColumns (CellSizes&, Getter) const;
virtual void _resizeImplementation(point_type, point_type);
virtual Sizes _getWidthImplementation () const;
virtual Sizes _getHeightImplementation () const;
public:
META_Object (osgWidget, Table);
META_UIObject (Table);
Table (const std::string& = "", unsigned int = 0, unsigned int = 0);
Table (const Table&, const osg::CopyOp&);
virtual bool addWidget (Widget*);
virtual bool addWidget (Widget*, unsigned int, unsigned int);
void getRowHeights (CellSizes&) const;
void getRowMinHeights (CellSizes&) const;
void getColumnWidths (CellSizes&) const;
void getColumnMinWidths (CellSizes&) const;
void addHeightToRow (unsigned int, point_type);
void addWidthToColumn (unsigned int, point_type);
bool isRowVerticallyFillable (unsigned int) const;
bool isColumnHorizontallyFillable (unsigned int) const;
Widget* getByRowCol(unsigned int row, unsigned int col) {
return getObjects()[_calculateIndex(row, col)].get();
}
const Widget* getByRowCol(unsigned int row, unsigned int col) const {
return getObjects()[_calculateIndex(row, col)].get();
}
};
}
#endif

31
include/osgWidget/Types Normal file
View File

@@ -0,0 +1,31 @@
// -*-c++-*- osgWidget - Code by: Jeremy Moles (cubicool) 2007-2008
// $Id: Types 33 2008-04-04 19:03:12Z cubicool $
#ifndef OSGWIDGET_TYPES
#define OSGWIDGET_TYPES
#include <numeric>
#include <osg/Geometry>
namespace osgWidget {
typedef osg::Vec2Array TexCoordArray;
typedef osg::Vec3Array PointArray;
typedef osg::Vec4Array ColorArray;
typedef TexCoordArray::value_type TexCoord;
typedef PointArray::value_type Point;
typedef ColorArray::value_type Color;
typedef TexCoord::value_type texcoord_type;
typedef Point::value_type point_type;
typedef Color::value_type color_type;
typedef osg::Vec2 XYCoord;
typedef osg::Vec4 Quad;
typedef osg::Matrix::value_type matrix_type;
}
#endif

View File

@@ -0,0 +1,123 @@
// -*-c++-*- osgWidget - Code by: Jeremy Moles (cubicool) 2007-2008
// $Id: UIObjectParent 55 2008-05-12 19:14:42Z cubicool $
#ifndef OSGWIDGET_UI_OBJECT_PARENT
#define OSGWIDGET_UI_OBEJCT_PARENT
namespace osgWidget {
#define META_UIObject(name) \
name * cloneAs(\
const std::string& newName, \
const osg::CopyOp& co = osg::CopyOp::DEEP_COPY_ALL \
) const { \
name * obj = dynamic_cast<name *>(this->clone(co)); \
obj->setName(newName); \
return obj; \
}
template <typename T>
class UIObjectParent {
public:
typedef T object_type;
typedef osg::observer_ptr<object_type> ptr_type;
typedef std::vector<ptr_type> Vector;
typedef typename Vector::iterator Iterator;
typedef typename Vector::const_iterator ConstIterator;
protected:
Vector _objects;
public:
Iterator begin() {
return _objects.begin();
}
ConstIterator begin() const {
return _objects.begin();
}
Iterator end() {
return _objects.end();
}
ConstIterator end() const {
return _objects.end();
}
typename Vector::size_type size() const {
return _objects.size();
}
private:
// I had to add this to avoid ambiguity errors with MSVC. Garbage.
object_type* _getByName(const std::string& name) const {
for(ConstIterator i = begin(); i != end(); i++) {
if(i->valid() && i->get()->getName() == name) return i->get();
}
return 0;
}
object_type* _getByIndex(unsigned int index) const {
for(ConstIterator i = begin(); i != end(); i++) {
if(i->valid() && i->get()->getIndex() == index) return i->get();
}
return 0;
}
public:
object_type* getByName(const std::string& name) {
return _getByName(name);
}
const object_type* getByName(const std::string& name) const {
return _getByName(name);
}
object_type* getByIndex(unsigned int index) {
return _getByIndex(index);
}
const object_type* getByIndex(unsigned int index) const {
return _getByIndex(index);
}
unsigned int getNumObjects() const {
return _objects.size();
}
Vector& getObjects() {
return _objects;
}
const Vector& getObjects() const {
return _objects;
}
protected:
bool _remove(object_type* obj) {
Iterator i = std::find(begin(), end(), obj);
if(i == end()) return false;
_objects.erase(i);
return true;
}
bool _removeByName(const std::string& name) {
for(Iterator i = begin(); i != end(); i++) if(i->get()->getName() == name) {
_objects.erase(i);
return true;
}
return false;
}
};
}
#endif

79
include/osgWidget/Util Normal file
View File

@@ -0,0 +1,79 @@
// -*-c++-*- osgWidget - Code by: Jeremy Moles (cubicool) 2007-2008
// $Id: Util 59 2008-05-15 20:55:31Z cubicool $
#ifndef OSGWIDGET_UTIL
#define OSGWIDGET_UTIL
#include <cctype>
#include <algorithm>
#include <sstream>
#include <osg/Camera>
#include <osgViewer/Viewer>
#include <osgViewer/CompositeViewer>
#include <osgWidget/Export>
#include <osgWidget/Types>
namespace osgWidget {
// These are NOT OSGWIDGET_EXPORT'd; these are internal only!
inline std::ostream& _notify(osg::NotifySeverity ns = osg::INFO) {
std::ostream& n = osg::notify(ns);
return n << "osgWidget: ";
}
inline std::ostream& warn() {
return _notify(osg::WARN);
}
inline std::ostream& info() {
return _notify();
}
inline std::string lowerCase(const std::string& str) {
std::string s = str;
// TODO: Why can't I specify std::tolower?
std::transform(s.begin(), s.end(), s.begin(), ::tolower);
return s;
}
// TODO: Is this totally ghetto or what?
template <typename T>
inline bool hasDecimal(T v) {
return (v - static_cast<T>(static_cast<long>(v))) > 0.0f;
}
class WindowManager;
// These ARE OSGWIDGET_EXPORT'd for your convenience. :)
OSGWIDGET_EXPORT std::string getFilePath (const std::string&);
OSGWIDGET_EXPORT std::string generateRandomName (const std::string&);
OSGWIDGET_EXPORT osg::Matrix createInvertedYOrthoProjectionMatrix (matrix_type, matrix_type);
OSGWIDGET_EXPORT osg::Camera* createOrthoCamera (matrix_type, matrix_type);
OSGWIDGET_EXPORT osg::Camera* createInvertedYOrthoCamera (matrix_type, matrix_type);
// This function sets up our basic example framework, and optionally sets some root
// scene data.
OSGWIDGET_EXPORT int createExample(osgViewer::Viewer&, WindowManager*, osg::Node* = 0);
// This function works like the above routine, except creates an additional "outside"
// view for looking at your 2D scene.
// TODO: Fix this!
OSGWIDGET_EXPORT int createCompositeExample(
osgViewer::CompositeViewer&,
osgViewer::View*,
WindowManager*,
osg::Node* = 0
);
OSGWIDGET_EXPORT bool writeWindowManagerNode(WindowManager*);
}
#endif

23
include/osgWidget/Version Normal file
View File

@@ -0,0 +1,23 @@
// -*-c++-*- osgWidget - Code by: Jeremy Moles (cubicool) 2007-2008
// $Id: Version 64 2008-06-30 21:32:00Z cubicool $
#ifndef OSGWIDGET_VERSION
#define OSGWIDGET_VERSION
#include <osgWidget/Export>
extern "C" {
OSGWIDGET_EXPORT unsigned int osgWidgetGetMajorVersion ();
OSGWIDGET_EXPORT unsigned int osgWidgetGetMinorVersion ();
OSGWIDGET_EXPORT unsigned int osgWidgetGetPatchVersion ();
OSGWIDGET_EXPORT const char* osgWidgetGetExtraText ();
OSGWIDGET_EXPORT const char* osgWidgetGetVersion ();
OSGWIDGET_EXPORT const char* osgWidgetGetLibraryName ();
OSGWIDGET_EXPORT bool osgWidgetVersionMinimum (unsigned int, unsigned int, unsigned int);
OSGWIDGET_EXPORT bool osgWidgetVersionMaximum (unsigned int, unsigned int, unsigned int);
OSGWIDGET_EXPORT bool osgWidgetVersionRequired (unsigned int, unsigned int, unsigned int);
}
#endif

View File

@@ -0,0 +1,78 @@
// -*-c++-*- osgWidget - Code by: Jeremy Moles (cubicool) 2007-2008
// $Id: ViewerEventHandlers 31 2008-04-01 19:36:41Z cubicool $
#ifndef OSGWIDGET_VIEWER_EVENT_HANDLERS
#define OSGWIDGET_VIEWER_EVENT_HANDLERS
#include <osgGA/GUIEventAdapter>
#include <osgGA/GUIEventHandler>
#include <osgWidget/WindowManager>
// NOTE! These are all just examples of some default event handlers--they are not
// required. You are more than welcome to provide your own even handlers that
// communicate with a WindowManager using it's public API.
namespace osgWidget {
// This handles the pressing/moving of mouse buttons, etc.
class OSGWIDGET_EXPORT MouseHandler: public osgGA::GUIEventHandler {
osg::ref_ptr<WindowManager> _wm;
bool _handleMousePush (float, float, int);
bool _handleMouseRelease (float, float, int);
bool _handleMouseDoubleClick (float, float, int);
bool _handleMouseDrag (float, float, int);
bool _handleMouseMove (float, float, int);
bool _handleMouseScroll (float, float, int);
typedef bool (MouseHandler::*MouseAction)(float, float, int);
typedef bool (WindowManager::*MouseEvent)(float, float);
MouseAction _isMouseEvent (osgGA::GUIEventAdapter::EventType) const;
bool _doMouseEvent (float, float, MouseEvent);
public:
MouseHandler(WindowManager*);
virtual bool handle(
const osgGA::GUIEventAdapter&,
osgGA::GUIActionAdapter&,
osg::Object*,
osg::NodeVisitor*
);
};
// This handles the forwarding of keypress events.
class OSGWIDGET_EXPORT KeyboardHandler: public osgGA::GUIEventHandler {
osg::ref_ptr<WindowManager> _wm;
public:
KeyboardHandler(WindowManager*);
virtual bool handle(
const osgGA::GUIEventAdapter&,
osgGA::GUIActionAdapter&,
osg::Object*,
osg::NodeVisitor*
);
};
// This class offers a default kind of handling for resizing.
class OSGWIDGET_EXPORT ResizeHandler: public osgGA::GUIEventHandler {
osg::ref_ptr<WindowManager> _wm;
osg::ref_ptr<osg::Camera> _camera;
public:
ResizeHandler(WindowManager*, osg::Camera*);
virtual bool handle(
const osgGA::GUIEventAdapter&,
osgGA::GUIActionAdapter&,
osg::Object*,
osg::NodeVisitor*
);
};
}
#endif

626
include/osgWidget/Widget Normal file
View File

@@ -0,0 +1,626 @@
// -*-c++-*- osgWidget - Code by: Jeremy Moles (cubicool) 2007-2008
// $Id: Widget 64 2008-06-30 21:32:00Z cubicool $
#ifndef OSGWIDGET_WIDGET
#define OSGWIDGET_WIDGET
#include <osg/Texture2D>
#include <osgWidget/EventInterface>
#include <osgWidget/StyleInterface>
#include <osgWidget/UIObjectParent>
#include <osgWidget/Types>
namespace osgWidget {
class Window;
class WindowManager;
// A Widget is a rectangular region that recieves events about the state of various input
// devices such as the pointer and keyboard. It is aware of it's width, height, and origin but
// nothing else. It is the job of higher-level container objects to organize layouts and
// the like, and to contextualize the meaning of the widgets "origin" (whether it is absolute
// or relative).
class OSGWIDGET_EXPORT Widget: public osg::Geometry, public EventInterface, public StyleInterface {
public:
enum POINT {
LOWER_LEFT = 0,
LOWER_RIGHT = 1,
UPPER_RIGHT = 2,
UPPER_LEFT = 3,
LL = LOWER_LEFT,
LR = LOWER_RIGHT,
UR = UPPER_RIGHT,
UL = UPPER_LEFT,
ALL_POINTS = 4
};
enum LAYER {
LAYER_TOP = 20,
LAYER_HIGH = 15,
LAYER_MIDDLE = 10,
LAYER_LOW = 5,
LAYER_BG = 0
};
enum VERTICAL_ALIGNMENT {
VA_CENTER,
VA_TOP,
VA_BOTTOM
};
enum HORIZONTAL_ALIGNMENT {
HA_CENTER,
HA_LEFT,
HA_RIGHT
};
enum COORDINATE_MODE {
CM_ABSOLUTE,
CM_RELATIVE
};
private:
friend class Window;
// TODO: Because of the current class design, I don't think it's possible to
// have a ref_ptr here. :(
Window* _parent;
unsigned int _index;
unsigned int _layer;
// Padding is the value of pixels of space between whatever the widget is "contianed"
// in and the point at which it starts getting placed.
point_type _padLeft;
point_type _padRight;
point_type _padTop;
point_type _padBottom;
// The alignments are used in conjuction when the widget is NOT set to fill.
VERTICAL_ALIGNMENT _valign;
HORIZONTAL_ALIGNMENT _halign;
// This flag determines how sizing values are interpretted by setDimensions().
COORDINATE_MODE _coordMode;
// These are the relative values, which are not stored directly in our verts
// array but kept around for calculation later.
Quad _relCoords;
// This fill flag determines whether or not the widget will resize itself to fill
// all available space.
bool _canFill;
// Set this to false in an implementation to prevent copying.
bool _canClone;
// This variable is only used by the Window object to determine if it's necessary
// to call managed().
bool _isManaged;
// This variable is like _isManaged; it is used to store whether the Widget has
// been styled yet.
bool _isStyled;
// Set these variables to be the minimum size of a Widget so that it cannot be
// resized any smaller than this.
point_type _minWidth;
point_type _minHeight;
static osg::ref_ptr<PointArray> _norms;
WindowManager* _getWindowManager () const;
osg::Image* _getImage () const;
protected:
point_type _calculateZ(unsigned int) const;
PointArray* _verts() {
return dynamic_cast<PointArray*>(getVertexArray());
}
const PointArray* _verts() const {
return dynamic_cast<const PointArray*>(getVertexArray());
}
ColorArray* _cols() {
return dynamic_cast<ColorArray*>(getColorArray());
}
const ColorArray* _cols() const {
return dynamic_cast<const ColorArray*>(getColorArray());
}
TexCoordArray* _texs() {
return dynamic_cast<TexCoordArray*>(getTexCoordArray(0));
}
const TexCoordArray* _texs() const {
return dynamic_cast<const TexCoordArray*>(getTexCoordArray(0));
}
osg::Texture2D* _texture() {
return dynamic_cast<osg::Texture2D*>(
getStateSet()->getTextureAttribute(0, osg::StateAttribute::TEXTURE)
);
}
const osg::Texture2D* _texture() const {
return dynamic_cast<const osg::Texture2D*>(
getStateSet()->getTextureAttribute(0, osg::StateAttribute::TEXTURE)
);
}
osg::Image* _image() {
return _getImage();
}
const osg::Image* _image() const {
return _getImage();
}
public:
META_Object (osgWidget, Widget);
META_UIObject (Widget);
Widget (const std::string& = "", point_type = 0.0f, point_type = 0.0f);
Widget (const Widget&, const osg::CopyOp&);
virtual ~Widget() {
}
// This method is called when the widget is added to a Window; this is useful
// when the widget needs to do something advanced (like a Label). The parent
// is passed as the first argument, although _parent should already be set.
virtual void parented(Window*) {
}
virtual void unparented(Window*) {
}
// This method is called when the widget's parent Window is added to a
// WindowManager object. The base managed method (WHICH YOU MUST REMEMBER
// TO CALL IN YOUR DERIVED METHODS!) sets the TexMat properly depending
// on what coordinate system you're using.
virtual void managed(WindowManager*);
virtual void unmanaged(WindowManager*) {
}
// This method is called when the widget is resized or reallocated in any
// way. This is useful when the widget manages some internal Drawables that need
// to be modified in some way.
virtual void positioned() {
}
void setDimensions(
point_type = -1.0f,
point_type = -1.0f,
point_type = -1.0f,
point_type = -1.0f,
point_type = -1.0f
);
void setPadding (point_type);
void setColor (color_type, color_type, color_type, color_type, POINT = ALL_POINTS);
void addColor (color_type, color_type, color_type, color_type, POINT = ALL_POINTS);
void setTexCoord (texcoord_type, texcoord_type, POINT = ALL_POINTS);
// These are additional texture coordinate setting methods.
// This method will use a given origin as the LOWER_LEFT point and texture the
// remaining area based on some width and height values.
void setTexCoordRegion(point_type, point_type, point_type, point_type);
// These are convenience methods for setting up wrapping modes.
void setTexCoordWrapHorizontal ();
void setTexCoordWrapVertical ();
bool setImage (osg::Image*, bool=false);
bool setImage (const std::string&, bool=false);
void addX (point_type);
void addY (point_type);
void addWidth (point_type);
void addHeight (point_type);
void addOrigin (point_type, point_type);
void addSize (point_type, point_type);
point_type getWidth () const;
point_type getHeight () const;
point_type getX () const;
point_type getY () const;
point_type getZ () const;
point_type getPadHorizontal () const;
point_type getPadVertical () const;
const Point& getPoint (POINT = ALL_POINTS) const;
const Color& getColor (POINT = ALL_POINTS) const;
const TexCoord& getTexCoord (POINT = ALL_POINTS) const;
POINT convertPoint (POINT) const;
Color getImageColorAtXY (point_type x, point_type y) const;
XYCoord localXY (double, double) const;
bool isPaddingUniform() const;
bool isManaged() const {
return _isManaged;
}
bool isStyled() const {
return _isStyled;
}
void setDimensions(const Quad& q, point_type z = -1.0f) {
setDimensions(q[0], q[1], q[2], q[4], z);
}
void setX(point_type x) {
setDimensions(x);
}
void setY(point_type y) {
setDimensions(-1.0f, y);
}
// This method should be use with extreme caution.
void setZ(point_type z) {
setDimensions(-1.0f, -1.0f, -1.0f, -1.0f, z);
}
void setWidth(point_type w) {
setDimensions(-1.0f, -1.0f, w);
}
void setHeight(point_type h) {
setDimensions(-1.0f, -1.0f, -1.0f, h);
}
void setOrigin(point_type x, point_type y) {
setDimensions(x, y);
}
void setOrigin(const XYCoord& xy) {
setOrigin(xy.x(), xy.y());
}
void setSize(point_type w, point_type h) {
setDimensions(-1.0f, -1.0f, w, h);
}
void setSize(const XYCoord& xy) {
setSize(xy.x(), xy.y());
}
void setColor(const Color& col, POINT p = ALL_POINTS) {
setColor(col.r(), col.g(), col.b(), col.a(), p);
}
void setTexCoord(const XYCoord& xy, POINT p = ALL_POINTS) {
setTexCoord(xy.x(), xy.y(), p);
}
void setTexCoordRegion(const XYCoord& xy, point_type w, point_type h) {
setTexCoordRegion(xy.x(), xy.y(), w, h);
}
void addColor(const Color& col, POINT p = ALL_POINTS) {
addColor(col.r(), col.g(), col.b(), col.a(), p);
}
void addOrigin(const XYCoord& xy) {
addOrigin(xy.x(), xy.y());
}
void addSize(const XYCoord& xy) {
addSize(xy.x(), xy.y());
}
void setMinimumSize(point_type width, point_type height) {
_minWidth = width;
_minHeight = height;
}
void setMinimumSize(const XYCoord& xy) {
setMinimumSize(xy.x(), xy.y());
}
// TODO: Refine this...
void setLayer(LAYER l, unsigned int offset = 0) {
_layer = l + offset;
}
void setPadLeft(point_type p) {
_padLeft = p;
}
void setPadRight(point_type p) {
_padRight = p;
}
void setPadTop(point_type p) {
_padTop = p;
}
void setPadBottom(point_type p) {
_padBottom = p;
}
void setAlignHorizontal(HORIZONTAL_ALIGNMENT h) {
_halign = h;
}
void setAlignVertical(VERTICAL_ALIGNMENT v) {
_valign = v;
}
void setCoordinateMode(COORDINATE_MODE cm) {
_coordMode = cm;
}
void setCanFill(bool f) {
_canFill = f;
}
void setCanClone(bool c) {
_canClone = c;
}
WindowManager* getWindowManager() {
return _getWindowManager();
}
const WindowManager* getWindowManager() const {
return _getWindowManager();
}
Window* getParent() {
return _parent;
}
const Window* getParent() const {
return _parent;
}
unsigned int getIndex() const {
return _index;
}
XYCoord getOrigin() const {
return XYCoord(getX(), getY());
}
Color getImageColorAtXY(const XYCoord& xy) const {
return getImageColorAtXY(xy.x(), xy.y());
}
Color getImageColorAtPointerXY(double x, double y) const {
return getImageColorAtXY(localXY(x, y));
}
Point getPosition() const {
return Point(getX(), getY(), getZ());
}
XYCoord getSize() const {
return XYCoord(getWidth(), getHeight());
}
Quad getDimensions() const {
return Quad(getX(), getY(), getWidth(), getHeight());
}
point_type getPadLeft() const {
return _padLeft;
}
point_type getPadRight() const {
return _padRight;
}
point_type getPadTop() const {
return _padTop;
}
point_type getPadBottom() const {
return _padBottom;
}
HORIZONTAL_ALIGNMENT getAlignHorizontal() const {
return _halign;
}
VERTICAL_ALIGNMENT getAlignVertical() const {
return _valign;
}
COORDINATE_MODE getCoordinateMode() const {
return _coordMode;
}
bool canFill() const {
return _canFill;
}
bool canClone() const {
return _canClone;
}
// This casts the bool _fill variable to be used in iteratively in functions such
// as Window::_accumulate and whatnot.
point_type getFillAsNumeric() const {
return static_cast<point_type>(_canFill);
}
point_type getWidthTotal() const {
return getWidth() + getPadHorizontal();
}
point_type getHeightTotal() const {
return getHeight() + getPadVertical();
}
point_type getMinWidth() const {
return _minWidth;
}
point_type getMinHeight() const {
return _minHeight;
}
point_type getMinWidthTotal() const {
return _minWidth + getPadHorizontal();
}
point_type getMinHeightTotal() const {
return _minHeight + getPadVertical();
}
unsigned int getLayer() const {
return _layer;
}
};
typedef std::list<osg::observer_ptr<Widget> > WidgetList;
// A Widget subclass that prints stuff using osg::notify(). :)
struct NotifyWidget: public Widget {
META_Object(osgWidget, NotifyWidget);
NotifyWidget(const std::string& n = "", point_type w = 0.0f, point_type h = 0.0f):
Widget(n, w, h) {
setEventMask(EVENT_ALL);
}
NotifyWidget(const NotifyWidget& widget, const osg::CopyOp& co):
Widget(widget, co) {
}
bool focus(const WindowManager*) {
osg::notify(osg::NOTICE) << _name << " > focus called" << std::endl;
return false;
}
bool unfocus(const WindowManager*) {
osg::notify(osg::NOTICE) << _name << " > unfocus called" << std::endl;
return false;
}
bool mouseEnter(double, double, const WindowManager*) {
osg::notify(osg::NOTICE) << _name << " > mouseEnter called" << std::endl;
return false;
}
bool mouseOver(double, double, const WindowManager*) {
osg::notify(osg::NOTICE) << _name << " > mouseOver called" << std::endl;
return false;
}
bool mouseLeave(double, double, const WindowManager*) {
osg::notify(osg::NOTICE) << _name << " > mouseLeave called" << std::endl;
return false;
}
bool mouseDrag(double, double, const WindowManager*) {
osg::notify(osg::NOTICE) << _name << " > mouseDrag called" << std::endl;
return false;
}
bool mousePush(double, double, const WindowManager*) {
osg::notify(osg::NOTICE) << _name << " > mousePush called" << std::endl;
return false;
}
bool mouseRelease(double, double, const WindowManager*) {
osg::notify(osg::NOTICE) << _name << " > mouseRelease called" << std::endl;
return false;
}
bool mouseScroll(double, double, const WindowManager*) {
osg::notify(osg::NOTICE) << _name << " > mouseScroll called" << std::endl;
return false;
}
bool keyPress(int, int, const WindowManager*) {
osg::notify(osg::NOTICE) << _name << " > keyPress called" << std::endl;
return false;
}
bool keyRelease(int, int, const WindowManager*) {
osg::notify(osg::NOTICE) << _name << " > keyRelease called" << std::endl;
return false;
}
};
// A Widget that eats all events and returns true.
struct NullWidget: public Widget {
META_Object(osgWidget, NullWidget);
NullWidget(const std::string& n = "", point_type w = 0.0f, point_type h = 0.0f):
Widget(n, w, h) {
setEventMask(EVENT_ALL);
}
NullWidget(const NullWidget& widget, const osg::CopyOp& co):
Widget(widget, co) {
}
bool focus(const WindowManager*) {
return true;
}
bool unfocus(const WindowManager*) {
return true;
}
bool mouseEnter(double, double, const WindowManager*) {
return true;
}
bool mouseOver(double, double, const WindowManager*) {
return true;
}
bool mouseLeave(double, double, const WindowManager*) {
return true;
}
bool mouseDrag(double, double, const WindowManager*) {
return true;
}
bool mousePush(double, double, const WindowManager*) {
return true;
}
bool mouseRelease(double, double, const WindowManager*) {
return true;
}
bool mouseScroll(double, double, const WindowManager*) {
return true;
}
bool keyPress(int, int, const WindowManager*) {
return true;
}
bool keyRelease(int, int, const WindowManager*) {
return true;
}
};
}
#endif

636
include/osgWidget/Window Normal file
View File

@@ -0,0 +1,636 @@
// -*-c++-*- osgWidget - Code by: Jeremy Moles (cubicool) 2007-2008
// $Id: Window 66 2008-07-14 21:54:09Z cubicool $
#ifndef OSGWIDGET_WINDOW
#define OSGWIDGET_WINDOW
#include <osg/Scissor>
#include <osg/MatrixTransform>
#include <osg/Geode>
#include <osg/ClipNode>
#include <osgWidget/Types>
#include <osgWidget/Util>
#include <osgWidget/Widget>
namespace osgWidget {
// These are helper callbacks you can attach to Windows that will make them moveable,
// rotatable, and scalable respectively.
bool callbackWindowMove (Event&);
bool callbackWindowRotate (Event&);
bool callbackWindowScale (Event&);
// These are helper callbacks you can attach to Windows to that will make various
// keyboard events behave as you might imagine.
bool callbackWindowTabFocus(Event&);
class OSGWIDGET_EXPORT Window:
public osg::MatrixTransform,
public UIObjectParent<Widget>,
public EventInterface,
public StyleInterface
{
public:
typedef std::list<osg::observer_ptr<Window> > WindowList;
struct Sizes {
point_type cur;
point_type min;
Sizes(point_type c = -1.0f, point_type m = -1.0f):
cur(c),
min(m) {
}
};
// TODO: This is a class that puts (embeds) the Window inside of a Widget
// interface, to help assemble Windows with Windows, and what have you.
class OSGWIDGET_EXPORT EmbeddedWindow: public Widget {
osg::ref_ptr<Window> _window;
public:
META_Object (osgWidget::Window, EmbeddedWindow);
META_UIObject (EmbeddedWindow);
EmbeddedWindow (const std::string& = "", point_type = 0.0f, point_type = 0.0f);
EmbeddedWindow (const EmbeddedWindow&, const osg::CopyOp&);
virtual void parented (Window*);
virtual void unparented (Window*);
virtual void managed (WindowManager*);
virtual void unmanaged (WindowManager*);
virtual void positioned ();
bool setWindow(Window*);
Window* getWindow() {
return _window.get();
}
const Window* getWindow() const {
return _window.get();
}
};
// These correspond to special regions honored by the WindowManager. Most Windows
// will want to be NONE, unless they need to exist in the foreground or background
// for some reason.
enum STRATA {
STRATA_NONE,
STRATA_BACKGROUND,
STRATA_FOREGROUND
};
// If you only want to display a portion of a Window (such as when it is embedded),
// you will need to set the VISIBILITY_MODE to WM_PARTIAL. Otherwise, the entire
// Window is visible by default. The final enum, VM_ENTIRE, says that no Scissoring
// should take place at all, and is useful in cases where you want to properly
// scale or rotate Windows.
enum VISIBILITY_MODE {
VM_FULL,
VM_PARTIAL,
VM_ENTIRE
};
// Anchors are very similar in that they allow us to pre-apply transformations in the
// call to Window::update() that allow us to position a Window somewhere relative
// to the WindowManger's viewable area. However, unlike the ALIGNMENT enums, these
// are totally optional (whereas a Widget must always have some ALIGNMENT value set.
enum VERTICAL_ANCHOR {
VA_NONE,
VA_CENTER,
VA_TOP,
VA_BOTTOM
};
enum HORIZONTAL_ANCHOR {
HA_NONE,
HA_CENTER,
HA_LEFT,
HA_RIGHT
};
protected:
typedef point_type (Widget::*Getter)() const;
typedef std::less<point_type> Less;
typedef std::greater<point_type> Greater;
typedef std::plus<point_type> Plus;
private:
friend class WindowManager;
// The (optional) Window that this Window is parented inside.
Window* _parent;
// The WindowManger to which this window is attached.
WindowManager* _wm;
// The positional index this Node holds within it's parent WindowManager.
unsigned int _index;
// The X and Y values of the Window (origin).
matrix_type _x;
matrix_type _y;
// A pair of values representing the currently calculated Z value and the
// depth range for all children to be used during the call to update().
matrix_type _z;
matrix_type _zRange;
// This is a special value that can be used to "force" a Window not to be
// focusable and instead always exist in the foreground or background.
STRATA _strata;
// A flag determining whether our visible area is the full Window or rather
// a portion of the Window.
VISIBILITY_MODE _vis;
// A rotation value in degrees.
matrix_type _r;
// This will also need to adjust geom internally so that picking is correct.
matrix_type _s;
matrix_type _scaleDenom;
Sizes _width;
Sizes _height;
VERTICAL_ANCHOR _vAnchor;
HORIZONTAL_ANCHOR _hAnchor;
// Not all windows have widgets that can focus, but if they do this should
// be a pointer to it.
osg::observer_ptr<Widget> _focused;
// The "visible" area that will define both the glScissor bounds AND will
// be used to make sure our pick is valid. The values herein correspond to
// X, Y, W, and H--in that order.
Quad _visibleArea;
// This helper method is used by _compare<>() and _accumulate<>(), so ignore this
// function and go see the docs for those instead. This thing is huge and unwieldy
// and not to be triffled with! :)
template<typename T>
point_type _forEachAssignOrApply(
Getter get,
int begin,
int end,
int add,
bool assign
) const {
point_type val = 0.0f;
unsigned int c = begin;
ConstIterator e = end > 0 ? _objects.begin() + end : _objects.end() + end;
// I WARNED YOU! If you try and understand what this does your head will
// explode! But let me say a few things: in MSVC you can't add to an iterator
// such that the add will cause it to increment past the end of the container.
// This appears to be safe in GCC, where it will just return the last
// item therein, but causes an assertion error in other compilers. I'm not
// sure if there is a cleaner remedy for this, so what we do for now is keep a
// count variable called "c" that makes sure our iterator's opterator+()
// method is safe to call.
for(
ConstIterator i = _objects.begin() + begin;
i < e;
c += add
) {
point_type v = 0.0f;
if(i->valid()) v = (i->get()->*get)();
// If you want to assign to val, and NOT add a sequence of them...
if(assign) {
if(T()(v, val)) val = v;
}
// If you want to accumulate a value INTO val...
else val = T()(v, val);
// Make sure our iterator is safe to increment. Otherwise, set it to
// whatever end is.
// TODO: This isn't 100% accurate, as it does not YET take into account
// our requested end in any way other than implicitly. It should, however,
// work okay for now.
if((c + add) < _objects.size()) i += add;
else i = e;
}
return val;
}
void _setWidthAndHeightUnknownSizeError (const std::string&, point_type);
void _setWidthAndHeightNotPAError (const std::string&, point_type);
void _setWidthAndHeight ();
void _removeFromGeode (Widget*);
Widget* _getBackground() const;
Window* _getTopmostParent() const;
protected:
// This method will return the T'th value returned by applying the Getter member function
// pointer to each iterator in the range of iterators defined by offset and add. In
// plain language, this helper method will apply some standard Widget::get* function
// to a range of objects in the _objects Vector, and will return the T'th of that.
// The template T can be any functor accepting two point_type values that return
// a bool. For example, this is commonly used with std::less to find the smallest
// width in a range of Widgets.
template<typename T>
point_type _compare(
Getter get,
int begin = 0,
int end = 0,
int add = 1
) const {
return _forEachAssignOrApply<T>(get, begin, end, add, true);
}
// This method will return the T'th value accumulated by applying the Getter member
// function to each iterator in the range of iterators defined by offset and add (similar
// to above). For example, this method can be used to apply std::plus to every
// width in a range of Widgets, and return the total.
template<typename T>
point_type _accumulate(
Getter get,
int begin = 0,
int end = 0,
int add = 1
) const {
return _forEachAssignOrApply<T>(get, begin, end, add, false);
}
osg::Geode* _geode() {
return dynamic_cast<osg::Geode*>(getChild(0));
}
const osg::Geode* _geode() const {
return dynamic_cast<const osg::Geode*>(getChild(0));
}
Widget* _bg() {
return _getBackground();
}
const Widget* _bg() const {
return _getBackground();
}
osg::Scissor* _scissor() {
return dynamic_cast<osg::Scissor*>(
getStateSet()->getAttribute(osg::StateAttribute::SCISSOR)
);
}
bool _setWidget (Widget*, int = -1);
bool _setVisible (bool);
void _setFocused (Widget*);
void _setStyled (Widget*);
void _setParented (Widget*, bool=false);
void _setManaged (Widget*, bool=false);
void _positionWidget(Widget*, point_type, point_type);
// These return the smallest and largest width and height values for the given
// range of Widgets.
point_type _getMinWidgetWidth (int = 0, int = 0, int = 1) const;
point_type _getMinWidgetHeight (int = 0, int = 0, int = 1) const;
point_type _getMaxWidgetWidth (int = 0, int = 0, int = 1) const;
point_type _getMaxWidgetHeight (int = 0, int = 0, int = 1) const;
// These return the smallest and largest minWidth and minHeight values for
// the given range of Widgets.
point_type _getMinWidgetMinWidth (int = 0, int = 0, int = 1) const;
point_type _getMinWidgetMinHeight (int = 0, int = 0, int = 1) const;
point_type _getMaxWidgetMinWidth (int = 0, int = 0, int = 1) const;
point_type _getMaxWidgetMinHeight (int = 0, int = 0, int = 1) const;
// These return the smallest and largest width and height total (width + pad)
// values for the given range of Widgets.
point_type _getMinWidgetWidthTotal (int = 0, int = 0, int = 1) const;
point_type _getMinWidgetHeightTotal (int = 0, int = 0, int = 1) const;
point_type _getMaxWidgetWidthTotal (int = 0, int = 0, int = 1) const;
point_type _getMaxWidgetHeightTotal (int = 0, int = 0, int = 1) const;
// These return the smallest and largest minWidth and minHeight total
// (width + pad) values for the given range of Widgets.
point_type _getMinWidgetMinWidthTotal (int = 0, int = 0, int = 1) const;
point_type _getMinWidgetMinHeightTotal (int = 0, int = 0, int = 1) const;
point_type _getMaxWidgetMinWidthTotal (int = 0, int = 0, int = 1) const;
point_type _getMaxWidgetMinHeightTotal (int = 0, int = 0, int = 1) const;
// These return the smallest and largest horizontal and vertical padding
// values for the given range of Widgets.
point_type _getMinWidgetPadHorizontal (int = 0, int = 0, int = 1) const;
point_type _getMinWidgetPadVertical (int = 0, int = 0, int = 1) const;
point_type _getMaxWidgetPadHorizontal (int = 0, int = 0, int = 1) const;
point_type _getMaxWidgetPadVertical (int = 0, int = 0, int = 1) const;
point_type _getNumFill(int = 0, int = 0, int = 1) const;
// This method is passed the additional values by which width and height should be
// modified as calculed by the parent method, Window::resize. Keep in mind that these
// values can be negative (indicating a potential "shrink" request) or positive (which
// would indicate a "grow" reqeust).
virtual void _resizeImplementation(point_type, point_type) = 0;
// These are made into implementation functions since getting the width or height
// of a window can potentially be an expensive operation, and we'll want to cache
// results if possible (which is handled transparently by the actualy Window::resize
// method). They return a Sizes struct which contains two members: cur (for current)
// and min (minimum). It's important that the Window know it's minimum possible
// size so that it can ignore invaled requests to resize.
//
// Default versions using BoundingBox calculations are provided, but some Windows
// override this (Table, Box).
virtual Sizes _getWidthImplementation () const;
virtual Sizes _getHeightImplementation () const;
public:
META_UIObject(Window);
Window (const std::string& = "");
Window (const Window&, const osg::CopyOp&);
bool resize (point_type = 0.0f, point_type = 0.0f);
bool resizeAdd (point_type = 0.0f, point_type = 0.0f);
bool resizePercent (point_type = 0.0f, point_type = 0.0f);
virtual void update ();
virtual void managed (WindowManager*);
virtual void unmanaged (WindowManager*);
virtual bool addWidget (Widget*);
virtual bool insertWidget (Widget*, unsigned int);
virtual bool removeWidget (Widget*);
virtual bool replaceWidget (Widget*, Widget*);
// This method wraps our Geode's addDrawable() method and returns the index of
// the newly-added Drawable.
unsigned int addDrawableAndGetIndex(osg::Drawable*);
bool isVisible () const;
bool isXYWithinVisible (float, float) const;
void setVisibleArea (int = 0, int = 0, int = 0, int = 0);
void addVisibleArea (int = 0, int = 0, int = 0, int = 0);
bool setFocused (const Widget*);
bool setFocused (const std::string&);
bool setFirstFocusable ();
bool setNextFocusable ();
bool getFocusList (WidgetList&) const;
bool getEmbeddedList (WindowList&) const;
void getParentList (WindowList&) const;
XYCoord localXY (double, double) const;
XYCoord getAbsoluteOrigin () const;
// This method wraps the current Window in a EmbeddedWindow object and returns it.
EmbeddedWindow* embed();
Widget* getFocused() {
return _focused.get();
}
const Widget* getFocused() const {
return _focused.get();
}
bool show() {
return _setVisible(true);
}
bool hide() {
return _setVisible(false);
}
bool isPointerXYWithinVisible(float x, float y) const {
XYCoord xy = localXY(x, y);
return isXYWithinVisible(xy.x(), xy.y());
}
osg::Geode* getGeode() {
return _geode();
}
const osg::Geode* getGeode() const {
return _geode();
}
Widget* getBackground() {
return _bg();
}
const Widget* getBackground() const {
return _bg();
}
WindowManager* getWindowManager() {
return _wm;
}
const WindowManager* getWindowManager() const {
return _wm;
}
Window* getParent() {
return _parent;
}
const Window* getParent() const {
return _parent;
}
Window* getTopmostParent() {
return _getTopmostParent();
}
const Window* getTopmostParent() const {
return _getTopmostParent();
}
unsigned int getIndex() const {
return _index;
}
matrix_type getX() const {
return _x;
}
matrix_type getY() const {
return _y;
}
matrix_type getZ() const {
return _z;
}
point_type getWidth() const {
return _width.cur;
}
point_type getHeight() const {
return _height.cur;
}
point_type getMinWidth() const {
return _width.min;
}
point_type getMinHeight() const {
return _height.min;
}
VERTICAL_ANCHOR getAnchorVertical() const {
return _vAnchor;
}
HORIZONTAL_ANCHOR getAnchorHorizontal() const {
return _hAnchor;
}
XYCoord getOrigin() const {
return XYCoord(_x, _y);
}
XYCoord getSize() const {
return XYCoord(_width.cur, _height.cur);
}
XYCoord getMinSize() const {
return XYCoord(_width.min, _height.min);
}
matrix_type getZRange() const {
return _zRange;
}
STRATA getStrata() const {
return _strata;
}
const Quad& getVisibleArea() const {
return _visibleArea;
}
VISIBILITY_MODE getVisibilityMode() const {
return _vis;
}
Point getPosition() const {
return Point(_x, _y, _z);
}
matrix_type getRotate() const {
return _r;
}
matrix_type getScale() const {
return _s;
}
matrix_type getScaleDenominator() const {
return _scaleDenom;
}
void setX(matrix_type x) {
_x = x;
}
void setY(matrix_type y) {
_y = y;
}
void setPosition(matrix_type x, matrix_type y, matrix_type z) {
_x = x;
_y = y;
_z = z;
}
void setPosition(const Point& p) {
setPosition(p.x(), p.y(), p.z());
}
void setOrigin(matrix_type x, matrix_type y) {
_x = x;
_y = y;
}
void setRotate(matrix_type r) {
_r = r;
}
void setScale(matrix_type s) {
_s = s;
}
void setScaleDenominator(matrix_type sd) {
_scaleDenom = sd;
}
void setAnchorVertical(VERTICAL_ANCHOR va) {
_vAnchor = va;
}
void setAnchorHorizontal(HORIZONTAL_ANCHOR ha) {
_hAnchor = ha;
}
void setStrata(STRATA s) {
_strata = s;
}
void setVisibilityMode(VISIBILITY_MODE v) {
_vis = v;
}
void addX(matrix_type x) {
_x += x;
}
void addY(matrix_type y) {
_y += y;
}
void addZ(matrix_type z) {
_z += z;
}
void addRotate(matrix_type r) {
_r += r;
}
void addScale(matrix_type s) {
_s += s / (_scaleDenom != 0.0f ? _scaleDenom : 1.0f);
}
void addOrigin(matrix_type x, matrix_type y) {
_x += x;
_y += y;
}
void attachMoveCallback() {
addCallback(Callback(&callbackWindowMove, EVENT_MOUSE_DRAG));
}
void attachRotateCallback() {
addCallback(Callback(&callbackWindowRotate, EVENT_MOUSE_DRAG));
}
void attachScaleCallback() {
addCallback(Callback(&callbackWindowScale, EVENT_MOUSE_DRAG));
}
void attachTabFocusCallback() {
addCallback(Callback(&callbackWindowTabFocus, EVENT_KEY_DOWN));
}
};
typedef Window::WindowList WindowList;
}
#endif

View File

@@ -0,0 +1,358 @@
// -*-c++-*- osgWidget - Code by: Jeremy Moles (cubicool) 2007-2008
// $Id: WindowManager 66 2008-07-14 21:54:09Z cubicool $
#ifndef OSGWIDGET_WINDOW_MANAGER
#define OSGWIDGET_WINDOW_MANAGER
#include <osg/Switch>
#include <osg/Uniform>
#include <osg/Drawable>
#include <osgGA/GUIEventAdapter>
#include <osgUtil/LineSegmentIntersector>
#include <osgViewer/View>
#include <osgWidget/ScriptEngine>
#include <osgWidget/StyleManager>
#include <osgWidget/Window>
namespace osgWidget {
// TODO: It should be possible to use something other than osgWidget/ViewerEventHandlers
// to handle all of these events. In fact, I need to create an SDL example showing this.
// A private typedef that we use for pickAtXY() below.
typedef osgUtil::LineSegmentIntersector::Intersections Intersections;
// A WindowManager performs pointer interaction with the topmost (highest Z) Widget,
// and performs keyboard input on the currently focused Window->Widget.
class OSGWIDGET_EXPORT WindowManager: public osg::Switch, public UIObjectParent<Window> {
public:
enum WM_FLAGS {
WM_USE_LUA = 0x00000001,
WM_USE_PYTHON = 0x00000002,
WM_PICK_DEBUG = 0x00000004,
WM_NO_INVERT_Y = 0x00000008,
WM_NO_BETA_WARN = 0x00000010
};
enum POINTER_DIRECTION {
PD_NONE = 0x00000000,
PD_LEFT = 0x00000001,
PD_RIGHT = 0x00000002,
PD_UP = 0x00000004,
PD_DOWN = 0x00000008
};
enum POINTER_FOCUS_MODE {
PFM_FOCUS = 0x00000000,
PFM_UNFOCUS = 0x00000001,
PFM_SLOPPY = 0x00000002
};
private:
// A functor used to sort the Windows by their Z component in descending order.
struct WindowZCompare: public std::binary_function<ptr_type, ptr_type, bool> {
bool operator()(const ptr_type& x, const ptr_type& y) {
return x.get()->getZ() > y.get()->getZ();
}
};
point_type _width;
point_type _height;
point_type _zNear;
point_type _zFar;
matrix_type _numForeground;
matrix_type _numBackground;
unsigned int _flags;
unsigned int _nodeMask;
osgViewer::View* _view;
float _lastX;
float _lastY;
EventInterface* _lastEvent;
EventInterface* _lastPush;
POINTER_DIRECTION _lastVertical;
POINTER_DIRECTION _lastHorizontal;
POINTER_FOCUS_MODE _focusMode;
bool _leftDown;
bool _middleDown;
bool _rightDown;
osgGA::GUIEventAdapter::ScrollingMotion _scrolling;
osg::ref_ptr<ScriptEngine> _lua;
osg::ref_ptr<ScriptEngine> _python;
osg::ref_ptr<StyleManager> _styleManager;
osg::observer_ptr<Widget> _widget;
osg::observer_ptr<Window> _focused;
osg::observer_ptr<Window> _pickWindow;
void childInserted (unsigned int);
void childRemoved (unsigned int, unsigned int);
bool _handleMousePushed (float, float, bool&);
bool _handleMouseReleased (float, float, bool&);
bool _haneldMouseScrolled (float, float, bool = false);
void _getPointerXYDiff (float&, float&);
void _updatePickWindow (const WidgetList*, point_type, point_type);
public:
META_Object(osgWidget, WindowManager);
WindowManager(
osgViewer::View* = 0,
point_type = 0.0f,
point_type = 0.0f,
unsigned int = 0,
unsigned int = 0
);
WindowManager(const WindowManager&, const osg::CopyOp&);
virtual ~WindowManager();
// A static method that will set both the _widget and _window data of an Event
// reference from a passed-in Interface.
static void setEventFromInterface(Event&, EventInterface*);
// A static template method that will iterate over a container and return a
// properly formed EventInterface*.
template<typename T>
static EventInterface* getFirstEventInterface(T&, Event&);
bool pickAtXY (float, float, WidgetList&);
bool setFocused (Window*);
void setPointerXY (float, float);
void setStyleManager (StyleManager*);
void resizeAllWindows (bool = true);
// Methods all called by the ViewerEventHandlers::MouseHandler object, or
// by some customer caller of your own. Examples of this to come...
bool pointerMove (float, float);
bool pointerDrag (float, float);
bool mouseScroll (float, float);
osg::Camera* createParentOrthoCamera();
unsigned int getNodeMask() const {
return _nodeMask;
}
point_type getWidth() const {
return _width;
}
point_type getHeight() const {
return _height;
}
bool isUsingLua() const {
return (_flags & WM_USE_LUA) != 0;
}
bool isUsingPython() const {
return (_flags & WM_USE_PYTHON) != 0;
}
bool isInvertedY() const {
return (_flags & WM_NO_INVERT_Y) == 0;
}
int getMouseKeysDown() const {
int flag = 0;
flag |= _leftDown ? osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON : 0;
flag |= _middleDown ? osgGA::GUIEventAdapter::MIDDLE_MOUSE_BUTTON: 0;
flag |= _rightDown ? osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON : 0;
return flag;
}
ScriptEngine* getLuaEngine() {
return _lua.get();
}
const ScriptEngine* getLuaEngine() const {
return _lua.get();
}
ScriptEngine* getPythonEngine() {
return _python.get();
}
const ScriptEngine* getPythonEngine() const {
return _python.get();
}
StyleManager* getStyleManager() {
return _styleManager.get();
}
const StyleManager* getStyleManager() const {
return _styleManager.get();
}
POINTER_DIRECTION getPointerVerticalDirection() const {
return _lastVertical;
}
POINTER_DIRECTION getPointerHorizontalDirection() const {
return _lastHorizontal;
}
POINTER_FOCUS_MODE getPointerFocusMode() const {
return _focusMode;
}
int getPointerDirectionVector() const {
return _lastVertical | _lastHorizontal;
}
bool isPointerMovingUp() const {
return _lastVertical == PD_UP;
}
bool isPointerMovingDown() const {
return _lastVertical == PD_DOWN;
}
bool isPointerMovingLeft() const {
return _lastHorizontal == PD_LEFT;
}
bool isPointerMovingRight() const {
return _lastHorizontal == PD_RIGHT;
}
bool isPointerMovingVertically() const {
return _lastVertical != PD_NONE;
}
bool isPointerMovingHorizontally() const {
return _lastHorizontal != PD_NONE;
}
bool isLeftMouseButtonDown() const {
return _leftDown;
}
bool isMiddleMouseButtonDown() const {
return _middleDown;
}
bool isRightMouseButtonDown() const {
return _rightDown;
}
bool isMouseScrollingUp() const {
return _scrolling == osgGA::GUIEventAdapter::SCROLL_UP;
}
bool isMouseScrollingDown() const {
return _scrolling == osgGA::GUIEventAdapter::SCROLL_DOWN;
}
bool setFocusedByName(const std::string& name) {
return setFocused(getByName(name));
}
void setScrollingMotion(osgGA::GUIEventAdapter::ScrollingMotion sm) {
_scrolling = sm;
}
void setPointerFocusMode(POINTER_FOCUS_MODE pfm) {
_focusMode = pfm;
}
void setWidth(point_type w) {
_width = w;
}
void setHeight(point_type h) {
_height = h;
}
void setSize(point_type w, point_type h) {
_width = w;
_height = h;
}
// Wrappers around the real calls. These only pertains to mouse buttons,
// particularly 3-button mice, although there are other more generic
// "pointer" API methods.
bool mousePushedLeft(float x, float y) {
return _handleMousePushed(x, y, _leftDown);
}
bool mousePushedMiddle(float x, float y) {
return _handleMousePushed(x, y, _middleDown);
}
bool mousePushedRight(float x, float y) {
return _handleMousePushed(x, y, _rightDown);
}
bool mouseReleasedLeft(float x, float y) {
return _handleMouseReleased(x, y, _leftDown);
}
bool mouseReleasedMiddle(float x, float y) {
return _handleMouseReleased(x, y, _middleDown);
}
bool mouseReleasedRight(float x, float y) {
return _handleMouseReleased(x, y, _rightDown);
}
// Keyboards wrappers, as above; takes the key and key's mask code, which
// can be compared to osgGA::GUIEventAdapter::{KeySymbol,KeyModMask}.
bool keyDown (int, int);
bool keyUp (int, int);
};
// We use a template here because the container could be a list or a vector; or something
// else that supports iteration!
template<typename T>
EventInterface* WindowManager::getFirstEventInterface(T& container, Event& ev) {
if(!container.size()) return 0;
// See if we can find a Widget that responds to this event...
for(typename T::iterator i = container.begin(); i != container.end(); i++) {
Widget* widget = i->get();
// If so, set the _widget/_window members and return it.
if(widget->getEventMask() & ev.type) {
ev._window = widget->getParent();
ev._widget = widget;
return widget;
}
}
// If we can't find a Widget that will accept this event, try and recurse all
// of the parent Windows and find one that can.
WindowList windowList;
Window* parent = container.back()->getParent();
if(parent) {
parent->getParentList(windowList);
// A WindowList from getParentList includes the Window the method was called
// on, and the entire tree of parentage.
for(WindowList::iterator i = windowList.begin(); i != windowList.end(); i++) {
Window* window = i->get();
if(window->getEventMask() & ev.type) {
ev._window = window;
return window;
}
}
}
return 0;
}
}
#endif