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:
626
include/osgWidget/Widget
Normal file
626
include/osgWidget/Widget
Normal 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
|
||||
Reference in New Issue
Block a user