From Jeremy Moles, updates to osgWidget
Merged my Robert Osfield from OpenSceneGraph-osgWidget-dev.
This commit is contained in:
parent
d3b2d9b074
commit
9748fdd605
@ -11,8 +11,7 @@
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
// -*-c++-*- osgWidget - Code by: Jeremy Moles (cubicool) 2007-2008
|
||||
// $Id: Box 46 2008-04-30 16:11:51Z cubicool $
|
||||
// Code by: Jeremy Moles (cubicool) 2007-2008
|
||||
|
||||
#ifndef OSGWIDGET_BOX
|
||||
#define OSGWIDGET_BOX
|
||||
@ -21,17 +20,26 @@
|
||||
|
||||
namespace osgWidget {
|
||||
|
||||
//! The Box object is a Window subclass that can be configured to uniformly (or
|
||||
//! non-uniformly) position it's children either vertically or horizontally. It
|
||||
//! is the most basic Window implementation, though there is some difficulty when
|
||||
//! positioning children such that each child object ends up pixel-aligned.
|
||||
class OSGWIDGET_EXPORT Box: public Window
|
||||
{
|
||||
public:
|
||||
enum BOX_TYPE {
|
||||
|
||||
//! An enum corresponding to the type of Box alignment.
|
||||
enum BoxType {
|
||||
VERTICAL,
|
||||
HORIZONTAL
|
||||
};
|
||||
|
||||
META_Object (osgWidget, Box);
|
||||
|
||||
Box (const std::string& = "", BOX_TYPE = HORIZONTAL, bool = false);
|
||||
META_Object(osgWidget, Box);
|
||||
|
||||
//! The main constructor; takes the string name, the BoxType orientation, and a
|
||||
//! boolean indicating whether or not all of the Box regions should be uniformly
|
||||
//! sized.
|
||||
Box (const std::string& = "", BoxType = HORIZONTAL, bool = false);
|
||||
Box (const Box&, const osg::CopyOp&);
|
||||
|
||||
protected:
|
||||
@ -43,10 +51,9 @@ class OSGWIDGET_EXPORT Box: public Window
|
||||
|
||||
private:
|
||||
|
||||
BOX_TYPE _boxType;
|
||||
BoxType _boxType;
|
||||
bool _uniform;
|
||||
unsigned int _lastAdd;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -11,8 +11,7 @@
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
// -*-c++-*- osgWidget - Code by: Jeremy Moles (cubicool) 2007-2008
|
||||
// $Id: Canvas 66 2008-07-14 21:54:09Z cubicool $
|
||||
// Code by: Jeremy Moles (cubicool) 2007-2008
|
||||
|
||||
#ifndef OSGWIDGET_CANVAS
|
||||
#define OSGWIDGET_CANVAS
|
||||
@ -24,12 +23,13 @@ namespace osgWidget {
|
||||
class OSGWIDGET_EXPORT Canvas: public Window
|
||||
{
|
||||
public:
|
||||
META_Object (osgWidget, Canvas);
|
||||
|
||||
META_Object(osgWidget, Canvas);
|
||||
|
||||
Canvas (const std::string& = "");
|
||||
Canvas (const Canvas&, const osg::CopyOp&);
|
||||
|
||||
// This would conflict with the normal addWidget if there were default values. :(
|
||||
//! Adds a Widget at the given XY coordinate.
|
||||
virtual bool addWidget(Widget*, point_type, point_type);
|
||||
|
||||
protected:
|
||||
|
@ -11,8 +11,7 @@
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
// -*-c++-*- osgWidget - Code by: Jeremy Moles (cubicool) 2007-2008
|
||||
// $Id: EventInterface 64 2008-06-30 21:32:00Z cubicool $
|
||||
// Code by: Jeremy Moles (cubicool) 2007-2008
|
||||
|
||||
#ifndef OSGWIDGET_EVENT_INTERFACE
|
||||
#define OSGWIDGET_EVENT_INTERFACE
|
||||
@ -67,15 +66,15 @@ class OSGWIDGET_EXPORT Event
|
||||
int keyMask;
|
||||
|
||||
Event(WindowManager* wm, EventType _type = EVENT_NONE):
|
||||
_wm (wm),
|
||||
_window (0),
|
||||
_widget (0),
|
||||
_data (0),
|
||||
type (_type),
|
||||
x (0.0f),
|
||||
y (0.0f),
|
||||
key (-1),
|
||||
keyMask (-1) {
|
||||
keyMask (-1),
|
||||
_wm (wm),
|
||||
_window (0),
|
||||
_widget (0),
|
||||
_data (0) {
|
||||
}
|
||||
|
||||
Event& makeType(EventType _type) {
|
||||
@ -203,13 +202,19 @@ class FunctionCallback: public CallbackInterface
|
||||
};
|
||||
|
||||
// The highlevel functor.
|
||||
class OSGWIDGET_EXPORT Callback
|
||||
class OSGWIDGET_EXPORT Callback: public osg::Referenced
|
||||
{
|
||||
public:
|
||||
|
||||
Callback():_type(EVENT_NONE),_data(0) {}
|
||||
Callback(const Callback& rhs):_type(rhs._type),_data(rhs._data),_callback(rhs._callback) {}
|
||||
|
||||
Callback(): _type(EVENT_NONE), _data(0), _callback(0) {}
|
||||
Callback(const Callback& rhs): osg::Referenced(rhs), _type(rhs._type), _data(rhs._data), _callback(rhs._callback) {}
|
||||
|
||||
// The more traditional style of OSG Callbacks.
|
||||
Callback(EventType type, void* data=0):
|
||||
_type (type),
|
||||
_data (data),
|
||||
_callback (0) {
|
||||
}
|
||||
|
||||
// Creates a Callback that is bound to a member function.
|
||||
template<typename T>
|
||||
Callback(bool (T::*function)(Event&), T* obj, EventType type, void* data=0):
|
||||
@ -226,7 +231,11 @@ class OSGWIDGET_EXPORT Callback
|
||||
_callback (new FunctionCallback<T>(functor)) {
|
||||
}
|
||||
|
||||
bool operator()(Event& ev) {
|
||||
virtual ~Callback() {}
|
||||
|
||||
virtual bool operator()(Event& ev) {
|
||||
if(!_callback) return false;
|
||||
|
||||
return (*_callback)(ev);
|
||||
}
|
||||
|
||||
@ -241,9 +250,10 @@ class OSGWIDGET_EXPORT Callback
|
||||
const void* getData() const {
|
||||
return _data;
|
||||
}
|
||||
|
||||
protected:
|
||||
EventType _type;
|
||||
void* _data;
|
||||
void* _data;
|
||||
|
||||
// We use a ref_ptr here so that we don't have to worry about memory.
|
||||
osg::ref_ptr<CallbackInterface> _callback;
|
||||
@ -301,7 +311,7 @@ class OSGWIDGET_EXPORT EventInterface
|
||||
return _eventMask;
|
||||
}
|
||||
|
||||
void addCallback(const Callback& cb) {
|
||||
void addCallback(Callback* cb) {
|
||||
_callbacks.push_back(cb);
|
||||
}
|
||||
|
||||
@ -312,10 +322,10 @@ class OSGWIDGET_EXPORT EventInterface
|
||||
// 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->get()->getType() & ev.type) {
|
||||
ev.setData(i->get()->getData());
|
||||
|
||||
if((*i)(ev)) return true;
|
||||
if((*i->get())(ev)) return true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -387,7 +397,7 @@ class OSGWIDGET_EXPORT EventInterface
|
||||
bool canKeyUp () const { return (_eventMask & EVENT_KEY_UP) != 0; }
|
||||
|
||||
private:
|
||||
typedef std::list<Callback> CallbackList;
|
||||
typedef std::list<osg::ref_ptr<Callback> > CallbackList;
|
||||
|
||||
unsigned int _eventMask;
|
||||
CallbackList _callbacks;
|
||||
|
@ -11,6 +11,8 @@
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
// Code by: Jeremy Moles (cubicool) 2007-2008
|
||||
|
||||
#ifndef OSGWIDGET_EXPORT_
|
||||
#define OSGWIDGET_EXPORT_ 1
|
||||
|
||||
@ -41,7 +43,7 @@
|
||||
|
||||
\namespace osgWidget
|
||||
|
||||
The osgWidget library is a NodeKit that extends the core scene graph to support 3D GUI widget set.
|
||||
The osgWidget library is a NodeKit that extends the core scene graph to support a 2D (and eventually 3D) GUI widget set.
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
@ -11,8 +11,7 @@
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
// -*-c++-*- osgWidget - Code by: Jeremy Moles (cubicool) 2007-2008
|
||||
// $Id: Frame 59 2008-05-15 20:55:31Z cubicool $
|
||||
// Code by: Jeremy Moles (cubicool) 2007-2008
|
||||
|
||||
#ifndef OSGWIDGET_FRAME
|
||||
#define OSGWIDGET_FRAME
|
||||
@ -21,11 +20,46 @@
|
||||
|
||||
namespace osgWidget {
|
||||
|
||||
/*
|
||||
Lets take a moment and explain how Frame texturing works. When you create a Frame, you use
|
||||
a specially designed texture that is "chopped" up horizontally by the Frame code into 8 equal
|
||||
regions. Each region is then textured to a corresponding portion of the Frame, in the
|
||||
following order:
|
||||
|
||||
+---+---+---+---+---+---+---+---+
|
||||
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
|
||||
+---+---+---+---+---+---+---+---+
|
||||
|
||||
1. Upper-Left corner.
|
||||
2. Top border (rotated 90 degrees CCW).
|
||||
3. Upper-Right corner.
|
||||
4. Left border.
|
||||
5. Right border.
|
||||
6. Bottom-Left corner.
|
||||
7. Bottom border (rotated 90 degrees CCW).
|
||||
8. Bottom-Right corner.
|
||||
|
||||
Now, these should be pretty self-explanatory if you visualize a frame as a 3x3 "table"
|
||||
(which is exactly what it is), but note how regions 2 and 7 are rotated counter-clockwise.
|
||||
We do this for a VERY important reason: we want to enable texture repeat on the border
|
||||
regions, so that when the frame is resized the borders cleanly paint the texture over
|
||||
the entire are (and don't stretch it). However, it is impossible in OpenGL to repeat a
|
||||
sub-region of a texture without including either the vertical or horizontal bounds, so the
|
||||
artist is required to rotate the region during their rendering so that our code can properly
|
||||
rotate it back internally and have it repeat in the desired way.
|
||||
|
||||
This method of texturing a Frame object is inspired by World of Warcraft "edge files", and it
|
||||
is both efficient and easy-to-use--once you understand the basics. If you're still confused,
|
||||
take a look at this URL, or any of the example themes:
|
||||
|
||||
http://www.wowwiki.com/EdgeFiles
|
||||
*/
|
||||
|
||||
class OSGWIDGET_EXPORT Frame: public Table
|
||||
{
|
||||
public:
|
||||
|
||||
enum CORNER
|
||||
enum CornerType
|
||||
{
|
||||
CORNER_LOWER_LEFT,
|
||||
CORNER_LOWER_RIGHT,
|
||||
@ -33,7 +67,7 @@ class OSGWIDGET_EXPORT Frame: public Table
|
||||
CORNER_UPPER_RIGHT
|
||||
};
|
||||
|
||||
enum BORDER
|
||||
enum BorderType
|
||||
{
|
||||
BORDER_LEFT,
|
||||
BORDER_RIGHT,
|
||||
@ -41,109 +75,127 @@ class OSGWIDGET_EXPORT Frame: public Table
|
||||
BORDER_BOTTOM
|
||||
};
|
||||
|
||||
static std::string cornerToString (CORNER);
|
||||
static std::string borderToString (BORDER);
|
||||
enum FrameOptions
|
||||
{
|
||||
FRAME_RESIZE = 1,
|
||||
FRAME_MOVE = 2,
|
||||
FRAME_TEXTURE = 4,
|
||||
FRAME_ALL = FRAME_RESIZE | FRAME_MOVE | FRAME_TEXTURE
|
||||
};
|
||||
|
||||
static std::string cornerTypeToString (CornerType);
|
||||
static std::string borderTypeToString (BorderType);
|
||||
|
||||
class OSGWIDGET_EXPORT Corner: public Widget
|
||||
{
|
||||
public:
|
||||
META_Object (osgWidget, Corner);
|
||||
META_Object(osgWidget, Corner);
|
||||
|
||||
Corner (CORNER = CORNER_LOWER_LEFT, point_type = 0.0f, point_type = 0.0f);
|
||||
Corner (CornerType = CORNER_LOWER_LEFT, point_type = 0.0f, point_type = 0.0f);
|
||||
Corner (const Corner&, const osg::CopyOp&);
|
||||
|
||||
bool mouseDrag(double, double, WindowManager*);
|
||||
virtual void parented (Window*);
|
||||
virtual bool mouseDrag (double, double, WindowManager*);
|
||||
|
||||
CORNER getCorner() const {
|
||||
CornerType getCornerType() const
|
||||
{
|
||||
return _corner;
|
||||
}
|
||||
|
||||
void setCorner(CORNER corner) {
|
||||
void setCornerType(CornerType corner)
|
||||
{
|
||||
_corner = corner;
|
||||
}
|
||||
|
||||
void setCornerAndName(CORNER corner) {
|
||||
void setCornerTypeAndName(CornerType corner)
|
||||
{
|
||||
_corner = corner;
|
||||
_name = cornerToString(corner);
|
||||
_name = cornerTypeToString(corner);
|
||||
}
|
||||
|
||||
protected:
|
||||
CORNER _corner;
|
||||
|
||||
CornerType _corner;
|
||||
};
|
||||
|
||||
class OSGWIDGET_EXPORT Border: public Widget
|
||||
{
|
||||
public:
|
||||
META_Object (osgWidget, Border);
|
||||
META_Object(osgWidget, Border);
|
||||
|
||||
Border (BORDER = BORDER_LEFT, point_type = 0.0f, point_type = 0.0f);
|
||||
Border (BorderType = BORDER_LEFT, point_type = 0.0f, point_type = 0.0f);
|
||||
Border (const Border&, const osg::CopyOp&);
|
||||
|
||||
bool mouseDrag(double, double, WindowManager*);
|
||||
virtual void parented (Window*);
|
||||
virtual void positioned ();
|
||||
virtual bool mouseDrag (double, double, WindowManager*);
|
||||
|
||||
BORDER getBorder() const {
|
||||
BorderType getBorderType() const
|
||||
{
|
||||
return _border;
|
||||
}
|
||||
|
||||
void setBorder(BORDER border) {
|
||||
void setBorderType(BorderType border)
|
||||
{
|
||||
_border = border;
|
||||
}
|
||||
|
||||
void setBorderAndName(BORDER border) {
|
||||
void setBorderTypeAndName(BorderType border)
|
||||
{
|
||||
_border = border;
|
||||
_name = borderToString(border);
|
||||
_name = borderTypeToString(border);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
BORDER _border;
|
||||
|
||||
BorderType _border;
|
||||
};
|
||||
|
||||
META_Object (osgWidget, Frame);
|
||||
META_Object(osgWidget, Frame);
|
||||
|
||||
Frame (const std::string& = "");
|
||||
Frame (const std::string& = "", unsigned int = 0);
|
||||
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
|
||||
unsigned int = 0,
|
||||
Frame* = 0
|
||||
);
|
||||
|
||||
static Frame* createSimpleFrameWithSingleTexture(
|
||||
const std::string&,
|
||||
osg::Image*,
|
||||
point_type,
|
||||
point_type,
|
||||
unsigned int = 0,
|
||||
Frame* = 0
|
||||
);
|
||||
|
||||
static Frame* createSimpleFrameFromTheme(
|
||||
const std::string&,
|
||||
osg::Image*,
|
||||
point_type,
|
||||
point_type,
|
||||
point_type,
|
||||
point_type,
|
||||
point_type,
|
||||
point_type,
|
||||
Frame* = 0
|
||||
unsigned int = 0,
|
||||
Frame* = 0
|
||||
);
|
||||
|
||||
void createSimpleFrame(point_type cw, point_type ch, point_type w, point_type h)
|
||||
{
|
||||
createSimpleFrame(_name, cw, ch, w, h, this);
|
||||
createSimpleFrame(_name, cw, ch, w, h, 0, 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
|
||||
osg::Image* image,
|
||||
point_type w,
|
||||
point_type h
|
||||
)
|
||||
{
|
||||
createSimpleFrameWithSingleTexture(_name, tex, tw, th, cw, ch, w, h, this);
|
||||
createSimpleFrameWithSingleTexture(_name, image, w, h, 0, this);
|
||||
}
|
||||
|
||||
bool setWindow(Window*);
|
||||
@ -152,19 +204,49 @@ class OSGWIDGET_EXPORT Frame: public Table
|
||||
|
||||
const EmbeddedWindow* getEmbeddedWindow() const { return dynamic_cast<const EmbeddedWindow*>(getByRowCol(1, 1)); }
|
||||
|
||||
Corner* getCorner(CORNER c) { return dynamic_cast<Corner*>(_getCorner(c)); }
|
||||
Corner* getCorner(CornerType c) { return dynamic_cast<Corner*>(_getCorner(c)); }
|
||||
|
||||
const Corner* getCorner(CORNER c) const { return dynamic_cast<const Corner*>(_getCorner(c)); }
|
||||
const Corner* getCorner(CornerType c) const { return dynamic_cast<const Corner*>(_getCorner(c)); }
|
||||
|
||||
Border* getBorder(BORDER b) { return dynamic_cast<Border*>(_getBorder(b)); }
|
||||
Border* getBorder(BorderType b) { return dynamic_cast<Border*>(_getBorder(b)); }
|
||||
|
||||
const Border* getBorder(BORDER b) const { return dynamic_cast<const Border*>(_getBorder(b)); }
|
||||
const Border* getBorder(BorderType b) const { return dynamic_cast<const Border*>(_getBorder(b)); }
|
||||
|
||||
// This method resizes the internal EmbeddedWindow object and then properly resizes
|
||||
// the reset of the Frame based on the sizes of the Corners, Borders, etc.
|
||||
bool resizeFrame(point_type, point_type);
|
||||
|
||||
unsigned int getFlags() const
|
||||
{
|
||||
return _flags;
|
||||
}
|
||||
|
||||
void setFlags(unsigned int flags)
|
||||
{
|
||||
_flags = flags;
|
||||
}
|
||||
|
||||
bool canResize() const
|
||||
{
|
||||
return (_flags & FRAME_RESIZE) != 0;
|
||||
}
|
||||
|
||||
bool canMove() const
|
||||
{
|
||||
return (_flags & FRAME_MOVE) != 0;
|
||||
}
|
||||
|
||||
bool canTexture() const
|
||||
{
|
||||
return (_flags & FRAME_TEXTURE) != 0;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
Widget* _getCorner (CORNER) const;
|
||||
Widget* _getBorder (BORDER) const;
|
||||
Widget* _getCorner (CornerType) const;
|
||||
Widget* _getBorder (BorderType) const;
|
||||
|
||||
unsigned int _flags;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -11,8 +11,7 @@
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
// -*-c++-*- osgWidget - Code by: Jeremy Moles (cubicool) 2007-2008
|
||||
// $Id: Input 45 2008-04-23 16:46:11Z cubicool $
|
||||
// Code by: Jeremy Moles (cubicool) 2007-2008
|
||||
|
||||
#ifndef OSGWIDGET_INPUT
|
||||
#define OSGWIDGET_INPUT
|
||||
@ -21,9 +20,15 @@
|
||||
|
||||
namespace osgWidget {
|
||||
|
||||
// This is a string of values we use to try and determine the best Y
|
||||
// descent value (yoffset); you're welcome to use what works best for
|
||||
// your font.
|
||||
const std::string DESCENT_STRING("qpl");
|
||||
|
||||
class OSGWIDGET_EXPORT Input: public Label
|
||||
{
|
||||
public:
|
||||
|
||||
Input(const std::string& = "", const std::string& = "", unsigned int = 20);
|
||||
|
||||
virtual void parented (Window*);
|
||||
@ -34,7 +39,8 @@ class OSGWIDGET_EXPORT Input: public Label
|
||||
virtual bool keyUp (int, int, WindowManager*);
|
||||
virtual bool keyDown (int, int, WindowManager*);
|
||||
|
||||
void setCursor(Widget*);
|
||||
void setCursor (Widget*);
|
||||
unsigned int calculateBestYOffset (const std::string& = "qgl");
|
||||
|
||||
void setXOffset(point_type xo) {
|
||||
_xoff = xo;
|
||||
|
@ -11,8 +11,7 @@
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
// -*-c++-*- osgWidget - Code by: Jeremy Moles (cubicool) 2007-2008
|
||||
// $Id: Label 59 2008-05-15 20:55:31Z cubicool $
|
||||
// Code by: Jeremy Moles (cubicool) 2007-2008
|
||||
|
||||
#ifndef OSGWIDGET_LABEL
|
||||
#define OSGWIDGET_LABEL
|
||||
@ -34,10 +33,8 @@ class OSGWIDGET_EXPORT Label: public Widget
|
||||
|
||||
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);
|
||||
|
@ -11,8 +11,7 @@
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
// -*-c++-*- osgWidget - Code by: Jeremy Moles (cubicool) 2007-2008
|
||||
// $Id: Lua 2 2008-01-24 16:11:26Z cubicool $
|
||||
// Code by: Jeremy Moles (cubicool) 2007-2008
|
||||
|
||||
#ifndef OSGWIDGET_LUA
|
||||
#define OSGWIDGET_LUA
|
||||
|
@ -11,8 +11,7 @@
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
// -*-c++-*- osgWidget - Code by: Jeremy Moles (cubicool) 2007-2008
|
||||
// $Id: Python 2 2008-01-24 16:11:26Z cubicool $
|
||||
// Code by: Jeremy Moles (cubicool) 2007-2008
|
||||
|
||||
#ifndef OSGWIDGET_PYTHON
|
||||
#define OSGWIDGET_PYTHON
|
||||
|
@ -11,8 +11,7 @@
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
// -*-c++-*- osgWidget - Code by: Jeremy Moles (cubicool) 2007-2008
|
||||
// $Id: ScriptEngine 2 2008-01-24 16:11:26Z cubicool $
|
||||
// Code by: Jeremy Moles (cubicool) 2007-2008
|
||||
|
||||
#ifndef OSGWIDGET_SCRIPT_ENGINE
|
||||
#define OSGWIDGET_SCRIPT_ENGINE
|
||||
|
@ -11,8 +11,7 @@
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
// -*-c++-*- osgWidget - Code by: Jeremy Moles (cubicool) 2007-2008
|
||||
// $Id: StyleInterface 63 2008-06-30 19:18:37Z cubicool $
|
||||
// Code by: Jeremy Moles (cubicool) 2007-2008
|
||||
|
||||
#ifndef OSGWIDGET_STYLE_INTERFACE
|
||||
#define OSGWIDGET_STYLE_INTERFACE
|
||||
|
@ -11,8 +11,7 @@
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
// -*-c++-*- osgWidget - Code by: Jeremy Moles (cubicool) 2007-2008
|
||||
// $Id: StyleManager 61 2008-06-24 20:24:26Z cubicool $
|
||||
// Code by: Jeremy Moles (cubicool) 2007-2008
|
||||
|
||||
#ifndef OSGWIDGET_STYLE_MANAGER
|
||||
#define OSGWIDGET_STYLE_MANAGER
|
||||
|
@ -11,8 +11,7 @@
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
// -*-c++-*- osgWidget - Code by: Jeremy Moles (cubicool) 2007-2008
|
||||
// $Id: Table 48 2008-05-05 14:13:20Z cubicool $
|
||||
// Code by: Jeremy Moles (cubicool) 2007-2008
|
||||
|
||||
#ifndef OSGWIDGET_TABLE
|
||||
#define OSGWIDGET_TABLE
|
||||
|
@ -11,8 +11,7 @@
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
// -*-c++-*- osgWidget - Code by: Jeremy Moles (cubicool) 2007-2008
|
||||
// $Id: Types 33 2008-04-04 19:03:12Z cubicool $
|
||||
// Code by: Jeremy Moles (cubicool) 2007-2008
|
||||
|
||||
#ifndef OSGWIDGET_TYPES
|
||||
#define OSGWIDGET_TYPES
|
||||
@ -39,6 +38,11 @@ typedef osg::Vec4 Quad;
|
||||
|
||||
typedef osg::Matrix::value_type matrix_type;
|
||||
|
||||
// This is multiplied by a normalized Z value [0.0f, -1.0f] to create a RenderBin number
|
||||
// to set the state of the Window/Widget with. Perhaps at some later time this should
|
||||
// be configurable.
|
||||
const int OSGWIDGET_RENDERBIN_MOD = 5000;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -11,8 +11,7 @@
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
// -*-c++-*- osgWidget - Code by: Jeremy Moles (cubicool) 2007-2008
|
||||
// $Id: UIObjectParent 55 2008-05-12 19:14:42Z cubicool $
|
||||
// Code by: Jeremy Moles (cubicool) 2007-2008
|
||||
|
||||
#ifndef OSGWIDGET_UI_OBJECT_PARENT
|
||||
#define OSGWIDGET_UI_OBJECT_PARENT
|
||||
@ -26,6 +25,7 @@ template <typename T>
|
||||
class UIObjectParent
|
||||
{
|
||||
public:
|
||||
|
||||
typedef T object_type;
|
||||
typedef osg::observer_ptr<object_type> ptr_type;
|
||||
typedef std::vector<ptr_type> Vector;
|
||||
|
@ -11,13 +11,12 @@
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
// -*-c++-*- osgWidget - Code by: Jeremy Moles (cubicool) 2007-2008
|
||||
// $Id: Util 59 2008-05-15 20:55:31Z cubicool $
|
||||
// Code by: Jeremy Moles (cubicool) 2007-2008
|
||||
|
||||
#ifndef OSGWIDGET_UTIL
|
||||
#define OSGWIDGET_UTIL
|
||||
|
||||
#include <ctype.h>
|
||||
#include <cctype>
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
#include <osg/Camera>
|
||||
@ -71,26 +70,12 @@ class WindowManager;
|
||||
|
||||
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);
|
||||
OSGWIDGET_EXPORT osg::Camera* createOrthoCamera (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*);
|
||||
OSGWIDGET_EXPORT int createExample (osgViewer::Viewer&, WindowManager*, osg::Node* = 0);
|
||||
OSGWIDGET_EXPORT bool writeWindowManagerNode (WindowManager*);
|
||||
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
// -*-c++-*- osgWidget - Code by: Jeremy Moles (cubicool) 2007-2008
|
||||
// $Id: Version 64 2008-06-30 21:32:00Z cubicool $
|
||||
// Code by: Jeremy Moles (cubicool) 2007-2008
|
||||
|
||||
#ifndef OSGWIDGET_VERSION
|
||||
#define OSGWIDGET_VERSION
|
||||
|
@ -11,8 +11,7 @@
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
// -*-c++-*- osgWidget - Code by: Jeremy Moles (cubicool) 2007-2008
|
||||
// $Id: ViewerEventHandlers 31 2008-04-01 19:36:41Z cubicool $
|
||||
// Code by: Jeremy Moles (cubicool) 2007-2008
|
||||
|
||||
#ifndef OSGWIDGET_VIEWER_EVENT_HANDLERS
|
||||
#define OSGWIDGET_VIEWER_EVENT_HANDLERS
|
||||
@ -31,6 +30,7 @@ namespace osgWidget {
|
||||
class OSGWIDGET_EXPORT MouseHandler: public osgGA::GUIEventHandler
|
||||
{
|
||||
public:
|
||||
|
||||
MouseHandler(WindowManager*);
|
||||
|
||||
virtual bool handle(
|
||||
@ -46,7 +46,7 @@ class OSGWIDGET_EXPORT MouseHandler: public osgGA::GUIEventHandler
|
||||
|
||||
protected:
|
||||
|
||||
osg::ref_ptr<WindowManager> _wm;
|
||||
osg::observer_ptr<WindowManager> _wm;
|
||||
|
||||
bool _handleMousePush (float, float, int);
|
||||
bool _handleMouseRelease (float, float, int);
|
||||
@ -57,13 +57,13 @@ class OSGWIDGET_EXPORT MouseHandler: public osgGA::GUIEventHandler
|
||||
|
||||
MouseAction _isMouseEvent (osgGA::GUIEventAdapter::EventType) const;
|
||||
bool _doMouseEvent (float, float, MouseEvent);
|
||||
|
||||
};
|
||||
|
||||
// This handles the forwarding of keypress events.
|
||||
class OSGWIDGET_EXPORT KeyboardHandler: public osgGA::GUIEventHandler
|
||||
{
|
||||
public:
|
||||
|
||||
KeyboardHandler(WindowManager*);
|
||||
|
||||
virtual bool handle(
|
||||
@ -74,7 +74,7 @@ class OSGWIDGET_EXPORT KeyboardHandler: public osgGA::GUIEventHandler
|
||||
);
|
||||
|
||||
protected:
|
||||
osg::ref_ptr<WindowManager> _wm;
|
||||
osg::observer_ptr<WindowManager> _wm;
|
||||
|
||||
};
|
||||
|
||||
@ -82,7 +82,8 @@ class OSGWIDGET_EXPORT KeyboardHandler: public osgGA::GUIEventHandler
|
||||
class OSGWIDGET_EXPORT ResizeHandler: public osgGA::GUIEventHandler
|
||||
{
|
||||
public:
|
||||
ResizeHandler(WindowManager*, osg::Camera*);
|
||||
|
||||
ResizeHandler(WindowManager*, osg::Camera* = 0);
|
||||
|
||||
virtual bool handle(
|
||||
const osgGA::GUIEventAdapter&,
|
||||
@ -93,9 +94,30 @@ class OSGWIDGET_EXPORT ResizeHandler: public osgGA::GUIEventHandler
|
||||
|
||||
protected:
|
||||
|
||||
osg::ref_ptr<WindowManager> _wm;
|
||||
osg::ref_ptr<osg::Camera> _camera;
|
||||
osg::observer_ptr<WindowManager> _wm;
|
||||
osg::observer_ptr<osg::Camera> _camera;
|
||||
};
|
||||
|
||||
// This class provides a hotkey that lets you toggle back and forth between
|
||||
// a camera and setting the CameraManipulator's home point.
|
||||
class OSGWIDGET_EXPORT CameraSwitchHandler: public osgGA::GUIEventHandler
|
||||
{
|
||||
public:
|
||||
|
||||
CameraSwitchHandler(WindowManager*, osg::Camera*);
|
||||
|
||||
virtual bool handle(
|
||||
const osgGA::GUIEventAdapter&,
|
||||
osgGA::GUIActionAdapter&,
|
||||
osg::Object*,
|
||||
osg::NodeVisitor*
|
||||
);
|
||||
|
||||
protected:
|
||||
|
||||
osg::observer_ptr<WindowManager> _wm;
|
||||
osg::observer_ptr<osg::Camera> _camera;
|
||||
osg::ref_ptr<osg::Node> _oldNode;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -11,8 +11,7 @@
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
// -*-c++-*- osgWidget - Code by: Jeremy Moles (cubicool) 2007-2008
|
||||
// $Id: Widget 64 2008-06-30 21:32:00Z cubicool $
|
||||
// Code by: Jeremy Moles (cubicool) 2007-2008
|
||||
|
||||
#ifndef OSGWIDGET_WIDGET
|
||||
#define OSGWIDGET_WIDGET
|
||||
@ -44,14 +43,14 @@ public:
|
||||
LR = LOWER_RIGHT,
|
||||
UR = UPPER_RIGHT,
|
||||
UL = UPPER_LEFT,
|
||||
ALL_CORNERS = 4
|
||||
ALL_CORNERS = 4
|
||||
};
|
||||
|
||||
enum Layer {
|
||||
LAYER_TOP = 20,
|
||||
LAYER_HIGH = 15,
|
||||
LAYER_MIDDLE = 10,
|
||||
LAYER_LOW = 5,
|
||||
LAYER_TOP = 100,
|
||||
LAYER_HIGH = 75,
|
||||
LAYER_MIDDLE = 50,
|
||||
LAYER_LOW = 25,
|
||||
LAYER_BG = 0
|
||||
};
|
||||
|
||||
@ -94,7 +93,8 @@ public:
|
||||
// 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 managed(WindowManager*) {
|
||||
}
|
||||
|
||||
virtual void unmanaged(WindowManager*) {
|
||||
}
|
||||
@ -117,6 +117,7 @@ public:
|
||||
void setColor (color_type, color_type, color_type, color_type, Corner = ALL_CORNERS);
|
||||
void addColor (color_type, color_type, color_type, color_type, Corner = ALL_CORNERS);
|
||||
void setTexCoord (texcoord_type, texcoord_type, Corner = ALL_CORNERS);
|
||||
void setLayer (Layer l, unsigned int offset = 0);
|
||||
|
||||
// These are additional texture coordinate setting methods.
|
||||
// This method will use a given origin as the LOWER_LEFT point and texture the
|
||||
@ -127,8 +128,9 @@ public:
|
||||
void setTexCoordWrapHorizontal ();
|
||||
void setTexCoordWrapVertical ();
|
||||
|
||||
bool setImage (osg::Image*, bool=false);
|
||||
bool setImage (const std::string&, bool=false);
|
||||
bool setImage (osg::Image*, bool = false, bool = false);
|
||||
bool setImage (const std::string&, bool = false, bool = false);
|
||||
bool setTexture (osg::Texture*, bool = false, bool = false);
|
||||
|
||||
void addX (point_type);
|
||||
void addY (point_type);
|
||||
@ -149,7 +151,6 @@ public:
|
||||
const Color& getColor (Corner = ALL_CORNERS) const;
|
||||
const TexCoord& getTexCoord (Corner = ALL_CORNERS) const;
|
||||
|
||||
Corner convertCorner (Corner) const;
|
||||
Color getImageColorAtXY (point_type x, point_type y) const;
|
||||
XYCoord localXY (double, double) const;
|
||||
|
||||
@ -216,6 +217,14 @@ public:
|
||||
setTexCoordRegion(xy.x(), xy.y(), w, h);
|
||||
}
|
||||
|
||||
void setTexCoordRegion(point_type x, point_type y, const XYCoord& wh) {
|
||||
setTexCoordRegion(x, y, wh.x(), wh.y());
|
||||
}
|
||||
|
||||
void setTexCoordRegion(const XYCoord& xy, const XYCoord& wh) {
|
||||
setTexCoordRegion(xy.x(), xy.y(), wh.x(), wh.y());
|
||||
}
|
||||
|
||||
void addColor(const Color& col, Corner p = ALL_CORNERS) {
|
||||
addColor(col.r(), col.g(), col.b(), col.a(), p);
|
||||
}
|
||||
@ -237,11 +246,6 @@ public:
|
||||
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;
|
||||
}
|
||||
@ -394,8 +398,6 @@ public:
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
|
||||
point_type _calculateZ(unsigned int) const;
|
||||
|
||||
PointArray* _verts() {
|
||||
@ -422,15 +424,23 @@ public:
|
||||
return dynamic_cast<const TexCoordArray*>(getTexCoordArray(0));
|
||||
}
|
||||
|
||||
osg::Texture2D* _texture() {
|
||||
osg::Texture* _texture() {
|
||||
osg::StateSet* ss = getStateSet();
|
||||
|
||||
if(!ss) return 0;
|
||||
|
||||
return dynamic_cast<osg::Texture2D*>(
|
||||
getStateSet()->getTextureAttribute(0, osg::StateAttribute::TEXTURE)
|
||||
ss->getTextureAttribute(0, osg::StateAttribute::TEXTURE)
|
||||
);
|
||||
}
|
||||
|
||||
const osg::Texture2D* _texture() const {
|
||||
const osg::Texture* _texture() const {
|
||||
const osg::StateSet* ss = getStateSet();
|
||||
|
||||
if(!ss) return 0;
|
||||
|
||||
return dynamic_cast<const osg::Texture2D*>(
|
||||
getStateSet()->getTextureAttribute(0, osg::StateAttribute::TEXTURE)
|
||||
ss->getTextureAttribute(0, osg::StateAttribute::TEXTURE)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -11,8 +11,7 @@
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
// -*-c++-*- osgWidget - Code by: Jeremy Moles (cubicool) 2007-2008
|
||||
// $Id: Window 66 2008-07-14 21:54:09Z cubicool $
|
||||
// Code by: Jeremy Moles (cubicool) 2007-2008
|
||||
|
||||
#ifndef OSGWIDGET_WINDOW
|
||||
#define OSGWIDGET_WINDOW
|
||||
@ -73,7 +72,8 @@ class OSGWIDGET_EXPORT Window:
|
||||
virtual void unmanaged (WindowManager*);
|
||||
virtual void positioned ();
|
||||
|
||||
bool setWindow(Window*);
|
||||
bool setWindow (Window*);
|
||||
void updateSizeFromWindow ();
|
||||
|
||||
Window* getWindow() {
|
||||
return _window.get();
|
||||
@ -139,7 +139,8 @@ class OSGWIDGET_EXPORT Window:
|
||||
|
||||
// This method wraps our Geode's addDrawable() method and returns the index of
|
||||
// the newly-added Drawable.
|
||||
unsigned int addDrawableAndGetIndex(osg::Drawable*);
|
||||
unsigned int addDrawableAndGetIndex (osg::Drawable*);
|
||||
unsigned int addChildAndGetIndex (osg::Node*);
|
||||
|
||||
bool isVisible () const;
|
||||
bool isXYWithinVisible (float, float) const;
|
||||
@ -147,6 +148,7 @@ class OSGWIDGET_EXPORT Window:
|
||||
void addVisibleArea (int = 0, int = 0, int = 0, int = 0);
|
||||
bool setFocused (const Widget*);
|
||||
bool setFocused (const std::string&);
|
||||
bool grabFocus ();
|
||||
bool setFirstFocusable ();
|
||||
bool setNextFocusable ();
|
||||
bool getFocusList (WidgetList&) const;
|
||||
@ -157,7 +159,11 @@ class OSGWIDGET_EXPORT Window:
|
||||
XYCoord getAbsoluteOrigin () const;
|
||||
|
||||
// This method wraps the current Window in a EmbeddedWindow object and returns it.
|
||||
EmbeddedWindow* embed();
|
||||
EmbeddedWindow* embed(
|
||||
const std::string& = "",
|
||||
Widget::Layer = Widget::LAYER_MIDDLE,
|
||||
unsigned int = 0
|
||||
);
|
||||
|
||||
Widget* getFocused() {
|
||||
return _focused.get();
|
||||
@ -313,6 +319,14 @@ class OSGWIDGET_EXPORT Window:
|
||||
_y = y;
|
||||
}
|
||||
|
||||
void setZ(matrix_type z) {
|
||||
_z = z;
|
||||
}
|
||||
|
||||
void setZRange(matrix_type zRange) {
|
||||
_zRange = zRange;
|
||||
}
|
||||
|
||||
void setPosition(matrix_type x, matrix_type y, matrix_type z) {
|
||||
_x = x;
|
||||
_y = y;
|
||||
@ -328,6 +342,10 @@ class OSGWIDGET_EXPORT Window:
|
||||
_y = y;
|
||||
}
|
||||
|
||||
void setOrigin(const XYCoord& xy) {
|
||||
setOrigin(xy.x(), xy.y());
|
||||
}
|
||||
|
||||
void setRotate(matrix_type r) {
|
||||
_r = r;
|
||||
}
|
||||
@ -382,19 +400,19 @@ class OSGWIDGET_EXPORT Window:
|
||||
}
|
||||
|
||||
void attachMoveCallback() {
|
||||
addCallback(Callback(&callbackWindowMove, EVENT_MOUSE_DRAG));
|
||||
addCallback(new Callback(&callbackWindowMove, EVENT_MOUSE_DRAG));
|
||||
}
|
||||
|
||||
void attachRotateCallback() {
|
||||
addCallback(Callback(&callbackWindowRotate, EVENT_MOUSE_DRAG));
|
||||
addCallback(new Callback(&callbackWindowRotate, EVENT_MOUSE_DRAG));
|
||||
}
|
||||
|
||||
void attachScaleCallback() {
|
||||
addCallback(Callback(&callbackWindowScale, EVENT_MOUSE_DRAG));
|
||||
addCallback(new Callback(&callbackWindowScale, EVENT_MOUSE_DRAG));
|
||||
}
|
||||
|
||||
void attachTabFocusCallback() {
|
||||
addCallback(Callback(&callbackWindowTabFocus, EVENT_KEY_DOWN));
|
||||
addCallback(new Callback(&callbackWindowTabFocus, EVENT_KEY_DOWN));
|
||||
}
|
||||
|
||||
typedef point_type (Widget::*Getter)() const;
|
||||
|
@ -11,8 +11,7 @@
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
// -*-c++-*- osgWidget - Code by: Jeremy Moles (cubicool) 2007-2008
|
||||
// $Id: WindowManager 66 2008-07-14 21:54:09Z cubicool $
|
||||
// Code by: Jeremy Moles (cubicool) 2007-2008
|
||||
|
||||
#ifndef OSGWIDGET_WINDOW_MANAGER
|
||||
#define OSGWIDGET_WINDOW_MANAGER
|
||||
@ -40,11 +39,10 @@ typedef osgUtil::LineSegmentIntersector::Intersections Intersections;
|
||||
class OSGWIDGET_EXPORT WindowManager: public osg::Switch, public UIObjectParent<Window> {
|
||||
public:
|
||||
enum WmFlags {
|
||||
WM_USE_LUA = 0x00000001,
|
||||
WM_USE_PYTHON = 0x00000002,
|
||||
WM_PICK_DEBUG = 0x00000004,
|
||||
WM_NO_INVERT_Y = 0x00000008,
|
||||
WM_NO_BETA_WARN = 0x00000010
|
||||
WM_USE_LUA = 0x00000001,
|
||||
WM_USE_PYTHON = 0x00000002,
|
||||
WM_USE_RENDERBINS = 0x00000004,
|
||||
WM_PICK_DEBUG = 0x00000008
|
||||
};
|
||||
|
||||
enum PointerDirection {
|
||||
@ -91,6 +89,9 @@ class OSGWIDGET_EXPORT WindowManager: public osg::Switch, public UIObjectParent<
|
||||
void setStyleManager (StyleManager*);
|
||||
void resizeAllWindows (bool = true);
|
||||
|
||||
XYCoord windowXY (double, double) const;
|
||||
XYCoord localXY (double, double) const;
|
||||
|
||||
// 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);
|
||||
@ -119,8 +120,8 @@ class OSGWIDGET_EXPORT WindowManager: public osg::Switch, public UIObjectParent<
|
||||
return (_flags & WM_USE_PYTHON) != 0;
|
||||
}
|
||||
|
||||
bool isInvertedY() const {
|
||||
return (_flags & WM_NO_INVERT_Y) == 0;
|
||||
bool isUsingRenderBins() const {
|
||||
return (_flags & WM_USE_RENDERBINS) != 0;
|
||||
}
|
||||
|
||||
int getMouseKeysDown() const {
|
||||
@ -242,6 +243,11 @@ class OSGWIDGET_EXPORT WindowManager: public osg::Switch, public UIObjectParent<
|
||||
_height = h;
|
||||
}
|
||||
|
||||
void setWindowSize(point_type w, point_type h) {
|
||||
_windowWidth = w;
|
||||
_windowHeight = 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.
|
||||
@ -282,10 +288,20 @@ class OSGWIDGET_EXPORT WindowManager: public osg::Switch, public UIObjectParent<
|
||||
}
|
||||
};
|
||||
|
||||
// A functor used to sort the Windows by their BinNum component in descending order.
|
||||
struct WindowBinNumberCompare: public std::binary_function<ptr_type, ptr_type, bool> {
|
||||
bool operator()(const ptr_type& x, const ptr_type& y) {
|
||||
return
|
||||
x.get()->getOrCreateStateSet()->getBinNumber() >
|
||||
y.get()->getOrCreateStateSet()->getBinNumber()
|
||||
;
|
||||
}
|
||||
};
|
||||
|
||||
point_type _width;
|
||||
point_type _height;
|
||||
point_type _zNear;
|
||||
point_type _zFar;
|
||||
point_type _windowWidth;
|
||||
point_type _windowHeight;
|
||||
matrix_type _numForeground;
|
||||
matrix_type _numBackground;
|
||||
unsigned int _flags;
|
||||
|
@ -1,11 +1,10 @@
|
||||
// -*-c++-*- osgWidget - Code by: Jeremy Moles (cubicool) 2007-2008
|
||||
// $Id: Box.cpp 64 2008-06-30 21:32:00Z cubicool $
|
||||
|
||||
#include <osgWidget/Box>
|
||||
|
||||
namespace osgWidget {
|
||||
|
||||
Box::Box(const std::string& name, BOX_TYPE bt, bool uniform):
|
||||
Box::Box(const std::string& name, BoxType bt, bool uniform):
|
||||
Window (name),
|
||||
_boxType (bt),
|
||||
_uniform (uniform),
|
||||
|
@ -1,5 +1,4 @@
|
||||
// -*-c++-*- osgWidget - Code by: Jeremy Moles (cubicool) 2007-2008
|
||||
// $Id: Canvas.cpp 66 2008-07-14 21:54:09Z cubicool $
|
||||
|
||||
#include <osgWidget/Canvas>
|
||||
|
||||
@ -20,13 +19,11 @@ void Canvas::_resizeImplementation(point_type w, point_type h) {
|
||||
}
|
||||
|
||||
bool Canvas::addWidget(Widget* widget, point_type x, point_type y) {
|
||||
if(Window::addWidget(widget)) {
|
||||
widget->setOrigin(x, y);
|
||||
if(!widget) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
widget->setOrigin(x, y);
|
||||
|
||||
return Window::addWidget(widget);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,13 +1,15 @@
|
||||
// -*-c++-*- osgWidget - Code by: Jeremy Moles (cubicool) 2007-2008
|
||||
// $Id: Frame.cpp 59 2008-05-15 20:55:31Z cubicool $
|
||||
|
||||
#include <osg/io_utils>
|
||||
#include <osgDB/ReadFile>
|
||||
#include <osgWidget/WindowManager>
|
||||
#include <osgWidget/Frame>
|
||||
#include <cassert>
|
||||
|
||||
namespace osgWidget {
|
||||
|
||||
std::string Frame::cornerToString(CORNER c) {
|
||||
std::string Frame::cornerTypeToString(CornerType c)
|
||||
{
|
||||
if(c == CORNER_LOWER_LEFT) return "CornerLowerLeft";
|
||||
|
||||
else if(c == CORNER_LOWER_RIGHT) return "CornerLowerRight";
|
||||
@ -17,7 +19,8 @@ std::string Frame::cornerToString(CORNER c) {
|
||||
else return "CornerUpperLeft";
|
||||
}
|
||||
|
||||
std::string Frame::borderToString(BORDER b) {
|
||||
std::string Frame::borderTypeToString(BorderType b)
|
||||
{
|
||||
if(b == BORDER_LEFT) return "BorderLeft";
|
||||
|
||||
else if(b == BORDER_RIGHT) return "BorderRight";
|
||||
@ -27,54 +30,44 @@ std::string Frame::borderToString(BORDER b) {
|
||||
else return "BorderBottom";
|
||||
}
|
||||
|
||||
Frame::Corner::Corner(CORNER corner, point_type width, point_type height):
|
||||
Widget (cornerToString(corner), width, height),
|
||||
_corner (corner) {
|
||||
setEventMask(EVENT_MASK_MOUSE_DRAG);
|
||||
Frame::Corner::Corner(CornerType corner, point_type width, point_type height):
|
||||
Widget (cornerTypeToString(corner), width, height),
|
||||
_corner (corner)
|
||||
{
|
||||
}
|
||||
|
||||
Frame::Corner::Corner(const Corner& corner, const osg::CopyOp& co):
|
||||
Widget (corner, co),
|
||||
_corner (corner._corner) {
|
||||
_corner (corner._corner)
|
||||
{
|
||||
}
|
||||
|
||||
bool Frame::Corner::mouseDrag(double x, double y, WindowManager* wm) {
|
||||
Window* parent = getParent();
|
||||
void Frame::Corner::parented(Window* window) {
|
||||
Frame* parent = dynamic_cast<Frame*>(getParent());
|
||||
|
||||
if(!parent) return false;
|
||||
if(!parent) return;
|
||||
|
||||
if(wm->isInvertedY()) {
|
||||
if(_corner == CORNER_UPPER_LEFT) {
|
||||
if(parent->resizeAdd(-x, -y)) parent->addOrigin(x, y);
|
||||
}
|
||||
if(parent->canResize()) setEventMask(EVENT_MASK_MOUSE_DRAG);
|
||||
}
|
||||
|
||||
else if(_corner == CORNER_UPPER_RIGHT) {
|
||||
if(parent->resizeAdd(x, -y)) parent->addY(y);
|
||||
}
|
||||
bool Frame::Corner::mouseDrag(double x, double y, WindowManager* wm)
|
||||
{
|
||||
Frame* parent = dynamic_cast<Frame*>(getParent());
|
||||
|
||||
else if(_corner == CORNER_LOWER_RIGHT) parent->resizeAdd(x, y);
|
||||
if(!parent || !parent->canResize()) return false;
|
||||
|
||||
else {
|
||||
if(parent->resizeAdd(-x, y)) parent->addX(x);
|
||||
}
|
||||
if(_corner == CORNER_UPPER_LEFT) {
|
||||
if(parent->resizeAdd(-x, y)) parent->addX(x);
|
||||
}
|
||||
|
||||
else if(_corner == CORNER_UPPER_RIGHT) parent->resizeAdd(x, y);
|
||||
|
||||
else if(_corner == CORNER_LOWER_RIGHT) {
|
||||
if(parent->resizeAdd(x, -y)) parent->addY(y);
|
||||
}
|
||||
|
||||
// These are basically flipped-around versions of the above routines; we
|
||||
// do it this way to avoid lots of uncessary if tests.
|
||||
else {
|
||||
if(_corner == CORNER_UPPER_LEFT) {
|
||||
if(parent->resizeAdd(-x, y)) parent->addX(x);
|
||||
}
|
||||
|
||||
else if(_corner == CORNER_UPPER_RIGHT) parent->resizeAdd(x, y);
|
||||
|
||||
else if(_corner == CORNER_LOWER_RIGHT) {
|
||||
if(parent->resizeAdd(x, -y)) parent->addY(y);
|
||||
}
|
||||
|
||||
else {
|
||||
if(parent->resizeAdd(-x, -y)) parent->addOrigin(x, y);
|
||||
}
|
||||
if(parent->resizeAdd(-x, -y)) parent->addOrigin(x, y);
|
||||
}
|
||||
|
||||
parent->update();
|
||||
@ -82,34 +75,84 @@ bool Frame::Corner::mouseDrag(double x, double y, WindowManager* wm) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Frame::Border::Border(BORDER border, point_type width, point_type height):
|
||||
Widget (borderToString(border), width, height),
|
||||
_border (border) {
|
||||
Frame::Border::Border(BorderType border, point_type width, point_type height):
|
||||
Widget (borderTypeToString(border), width, height),
|
||||
_border (border)
|
||||
{
|
||||
setCanFill(true);
|
||||
setEventMask(EVENT_MASK_MOUSE_DRAG);
|
||||
}
|
||||
|
||||
Frame::Border::Border(const Border& border, const osg::CopyOp& co):
|
||||
Widget (border, co),
|
||||
_border (border._border) {
|
||||
_border (border._border)
|
||||
{
|
||||
}
|
||||
|
||||
bool Frame::Border::mouseDrag(double x, double y, WindowManager* wm) {
|
||||
Window* parent = getParent();
|
||||
void Frame::Border::parented(Window* window) {
|
||||
Frame* parent = dynamic_cast<Frame*>(getParent());
|
||||
|
||||
if(!parent) return false;
|
||||
if(!parent) return;
|
||||
|
||||
if(_border == BORDER_LEFT) {
|
||||
if(parent->resizeAdd(-x, 0.0f)) parent->addX(x);
|
||||
if(parent->canResize()) setEventMask(EVENT_MASK_MOUSE_DRAG);
|
||||
}
|
||||
|
||||
void Frame::Border::positioned()
|
||||
{
|
||||
osg::Image* image = _image();
|
||||
|
||||
if(!image) return;
|
||||
|
||||
Frame* parent = dynamic_cast<Frame*>(getParent());
|
||||
|
||||
if(!parent || !parent->canTexture()) return;
|
||||
|
||||
point_type w = image->s() / 8.0f;
|
||||
point_type h = getHeight();
|
||||
|
||||
if(_border == BORDER_LEFT) setTexCoordRegion(w * 3, 0.0f, w, h);
|
||||
|
||||
else if(_border == BORDER_RIGHT) setTexCoordRegion(w * 4, 0.0f, w, h);
|
||||
|
||||
else if(_border == BORDER_TOP) {
|
||||
// TODO: Temporary; fix this.
|
||||
point_type tx1 = (w * 2) / image->s();
|
||||
point_type tx2 = w / image->s();
|
||||
point_type tx3 = getWidth() / w;
|
||||
|
||||
setTexCoord(tx1, tx3, LL);
|
||||
setTexCoord(tx1, 0.0f, LR);
|
||||
setTexCoord(tx2, 0.0f, UR);
|
||||
setTexCoord(tx2, tx3, UL);
|
||||
}
|
||||
|
||||
else if(_border == BORDER_RIGHT) parent->resizeAdd(x, 0.0f);
|
||||
else {
|
||||
point_type tx1 = (w * 7) / image->s();
|
||||
point_type tx2 = (w * 6) / image->s();
|
||||
point_type tx3 = getWidth() / w;
|
||||
|
||||
else if(_border == BORDER_TOP) parent->addOrigin(x, y);
|
||||
setTexCoord(tx1, tx3, LL);
|
||||
setTexCoord(tx1, 0.0f, LR);
|
||||
setTexCoord(tx2, 0.0f, UR);
|
||||
setTexCoord(tx2, tx3, UL);
|
||||
}
|
||||
}
|
||||
|
||||
bool Frame::Border::mouseDrag(double x, double y, WindowManager* wm)
|
||||
{
|
||||
Frame* parent = dynamic_cast<Frame*>(getParent());
|
||||
|
||||
if(!parent) return false;
|
||||
|
||||
if(_border == BORDER_TOP && parent->canMove()) parent->addOrigin(x, y);
|
||||
|
||||
else {
|
||||
// The only BORDER that inverted-Y affects is this...
|
||||
if(wm->isInvertedY()) parent->resizeAdd(0.0f, y);
|
||||
if(!parent->canResize()) return false;
|
||||
|
||||
if(_border == BORDER_LEFT) {
|
||||
if(parent->resizeAdd(-x, 0.0f)) parent->addX(x);
|
||||
}
|
||||
|
||||
else if(_border == BORDER_RIGHT) parent->resizeAdd(x, 0.0f);
|
||||
|
||||
else {
|
||||
if(parent->resizeAdd(0.0f, -y)) parent->addY(y);
|
||||
@ -121,54 +164,29 @@ bool Frame::Border::mouseDrag(double x, double y, WindowManager* wm) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Frame::Frame(const std::string& name):
|
||||
Table(name, 3, 3) {
|
||||
Frame::Frame(const std::string& name, unsigned int flags):
|
||||
Table (name, 3, 3),
|
||||
_flags (flags)
|
||||
{
|
||||
}
|
||||
|
||||
Frame::Frame(const Frame& frame, const osg::CopyOp& co):
|
||||
Table(frame, co) {
|
||||
Table(frame, co)
|
||||
{
|
||||
}
|
||||
|
||||
Widget* Frame::_getCorner(CORNER c) const {
|
||||
return const_cast<Widget*>(getByName(cornerToString(c)));
|
||||
Widget* Frame::_getCorner(CornerType c) const
|
||||
{
|
||||
return const_cast<Widget*>(getByName(cornerTypeToString(c)));
|
||||
}
|
||||
|
||||
Widget* Frame::_getBorder(BORDER b) const {
|
||||
return const_cast<Widget*>(getByName(borderToString(b)));
|
||||
Widget* Frame::_getBorder(BorderType b) const
|
||||
{
|
||||
return const_cast<Widget*>(getByName(borderTypeToString(b)));
|
||||
}
|
||||
|
||||
void Frame::managed(WindowManager* wm) {
|
||||
Window::managed(wm);
|
||||
|
||||
// Our Frame is created in an inverted-Y environment, so if this is the case
|
||||
// just return here.
|
||||
if(wm->isInvertedY()) return;
|
||||
|
||||
Corner* ll = getCorner(CORNER_LOWER_LEFT);
|
||||
Corner* lr = getCorner(CORNER_LOWER_RIGHT);
|
||||
Corner* ul = getCorner(CORNER_UPPER_LEFT);
|
||||
Corner* ur = getCorner(CORNER_UPPER_RIGHT);
|
||||
Border* t = getBorder(BORDER_TOP);
|
||||
Border* b = getBorder(BORDER_BOTTOM);
|
||||
|
||||
if(!ll || !lr || !ul || !ur || !t || !b) {
|
||||
warn()
|
||||
<< "One or more of your Corner/Border objects in the Frame ["
|
||||
<< _name << "] are invalid; cannot invert orientation." << std::endl
|
||||
;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ll->setCornerAndName(CORNER_UPPER_LEFT);
|
||||
lr->setCornerAndName(CORNER_UPPER_RIGHT);
|
||||
ul->setCornerAndName(CORNER_LOWER_LEFT);
|
||||
ur->setCornerAndName(CORNER_LOWER_RIGHT);
|
||||
t->setBorderAndName(BORDER_BOTTOM);
|
||||
b->setBorderAndName(BORDER_TOP);
|
||||
}
|
||||
|
||||
bool Frame::setWindow(Window* window) {
|
||||
bool Frame::setWindow(Window* window)
|
||||
{
|
||||
if(!window) return false;
|
||||
|
||||
EmbeddedWindow* ew = getEmbeddedWindow();
|
||||
@ -186,24 +204,25 @@ Frame* Frame::createSimpleFrame(
|
||||
point_type ch,
|
||||
point_type w,
|
||||
point_type h,
|
||||
unsigned int flags,
|
||||
Frame* exFrame
|
||||
) {
|
||||
Frame* frame = 0;
|
||||
|
||||
// Use an "existing frame" if we have it (for example, if you've in inherited from
|
||||
// Frame and want to use this stuff.
|
||||
if(!exFrame) frame = new Frame(name);
|
||||
if(!exFrame) frame = new Frame(name, flags);
|
||||
|
||||
else frame = exFrame;
|
||||
|
||||
frame->addWidget(new Corner(CORNER_UPPER_LEFT, cw, ch), 0, 0);
|
||||
frame->addWidget(new Border(BORDER_TOP, w, ch), 0, 1);
|
||||
frame->addWidget(new Corner(CORNER_UPPER_RIGHT, cw, ch), 0, 2);
|
||||
frame->addWidget(new Border(BORDER_LEFT, cw, h), 1, 0);
|
||||
frame->addWidget(new Border(BORDER_RIGHT, cw, h), 1, 2);
|
||||
frame->addWidget(new Corner(CORNER_LOWER_LEFT, cw, ch), 2, 0);
|
||||
frame->addWidget(new Border(BORDER_BOTTOM, w, ch), 2, 1);
|
||||
frame->addWidget(new Corner(CORNER_LOWER_RIGHT, cw, ch), 2, 2);
|
||||
frame->addWidget(new Corner(CORNER_LOWER_LEFT, cw, ch), 0, 0);
|
||||
frame->addWidget(new Border(BORDER_BOTTOM, w, ch), 0, 1);
|
||||
frame->addWidget(new Corner(CORNER_LOWER_RIGHT, cw, ch), 0, 2);
|
||||
frame->addWidget(new Border(BORDER_LEFT, cw, h), 1, 0);
|
||||
frame->addWidget(new Border(BORDER_RIGHT, cw, h), 1, 2);
|
||||
frame->addWidget(new Corner(CORNER_UPPER_LEFT, cw, ch), 2, 0);
|
||||
frame->addWidget(new Border(BORDER_TOP, w, ch), 2, 1);
|
||||
frame->addWidget(new Corner(CORNER_UPPER_RIGHT, cw, ch), 2, 2);
|
||||
|
||||
EmbeddedWindow* ew = new EmbeddedWindow(name, w, h);
|
||||
|
||||
@ -214,6 +233,7 @@ Frame* Frame::createSimpleFrame(
|
||||
return frame;
|
||||
}
|
||||
|
||||
/*
|
||||
Frame* Frame::createSimpleFrameWithSingleTexture(
|
||||
const std::string& name,
|
||||
const std::string& texture,
|
||||
@ -247,5 +267,332 @@ Frame* Frame::createSimpleFrameWithSingleTexture(
|
||||
|
||||
return frame;
|
||||
}
|
||||
*/
|
||||
|
||||
// Inspired by: http://www.wowwiki.com/EdgeFiles
|
||||
Frame* Frame::createSimpleFrameWithSingleTexture(
|
||||
const std::string& name,
|
||||
osg::Image* image,
|
||||
point_type width,
|
||||
point_type height,
|
||||
unsigned int flags,
|
||||
Frame* exFrame
|
||||
) {
|
||||
Frame* frame = 0;
|
||||
|
||||
double w = width;
|
||||
double h = height;
|
||||
|
||||
if (image)
|
||||
{
|
||||
w = image->s() / 8.0f;
|
||||
h = image->t();
|
||||
}
|
||||
|
||||
// The same as above...
|
||||
if(!exFrame) frame = createSimpleFrame(name, w, h, width, height, flags);
|
||||
|
||||
else frame = createSimpleFrame(name, w, h, width, height, 0, exFrame);
|
||||
|
||||
if (image)
|
||||
{
|
||||
|
||||
for(unsigned int i = 0; i < 9; i++) frame->getObjects()[i]->setImage(image);
|
||||
|
||||
XYCoord twh(w, h);
|
||||
|
||||
frame->getCorner(CORNER_UPPER_LEFT )->setTexCoordRegion(0.0f, 0.0f, twh);
|
||||
frame->getBorder(BORDER_TOP )->setTexCoordRegion(w, 0.0f, twh);
|
||||
frame->getCorner(CORNER_UPPER_RIGHT)->setTexCoordRegion(w * 2, 0.0f, twh);
|
||||
frame->getBorder(BORDER_LEFT )->setTexCoordRegion(w * 3, 0.0f, twh);
|
||||
frame->getBorder(BORDER_RIGHT )->setTexCoordRegion(w * 4, 0.0f, twh);
|
||||
frame->getCorner(CORNER_LOWER_LEFT )->setTexCoordRegion(w * 5, 0.0f, twh);
|
||||
frame->getBorder(BORDER_BOTTOM )->setTexCoordRegion(w * 6, 0.0f, twh);
|
||||
frame->getCorner(CORNER_LOWER_RIGHT)->setTexCoordRegion(w * 7, 0.0f, twh);
|
||||
|
||||
// We set all of these to wrap vertically, but the REAL texture coordinates will
|
||||
// be generated properly in the positioned() method.
|
||||
frame->getByRowCol(0, 1)->setTexCoordWrapVertical();
|
||||
frame->getByRowCol(1, 0)->setTexCoordWrapVertical();
|
||||
frame->getByRowCol(1, 2)->setTexCoordWrapVertical();
|
||||
frame->getByRowCol(2, 1)->setTexCoordWrapVertical();
|
||||
|
||||
// frame->getEmbeddedWindow()->setTexCoordRegion(cw, ch, tw - (cw * 2.0f), th - (ch * 2.0f));
|
||||
}
|
||||
else
|
||||
{
|
||||
osg::notify(osg::WARN) << "createSimpleFrameWithSingleTexture with a null image, the frame " << name << " will be use texture" << std::endl;
|
||||
}
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
bool Frame::resizeFrame(point_type w, point_type h) {
|
||||
Border* left = getBorder(BORDER_LEFT);
|
||||
Border* right = getBorder(BORDER_RIGHT);
|
||||
Border* top = getBorder(BORDER_TOP);
|
||||
Border* bottom = getBorder(BORDER_BOTTOM);
|
||||
|
||||
if(!left || !right || !top || !bottom) return false;
|
||||
|
||||
return resize(
|
||||
left->getWidth() + right->getWidth() + w,
|
||||
top->getHeight() + bottom->getHeight() + h
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
osg::Image* createNatifEdgeImageFromTheme(osg::Image* theme);
|
||||
|
||||
Frame* Frame::createSimpleFrameFromTheme(
|
||||
const std::string& name,
|
||||
osg::Image* image,
|
||||
point_type width,
|
||||
point_type height,
|
||||
unsigned int flags,
|
||||
Frame* exFrame
|
||||
) {
|
||||
|
||||
osg::ref_ptr<osg::Image> natifImage = createNatifEdgeImageFromTheme(image);
|
||||
Frame* frame;
|
||||
|
||||
frame = createSimpleFrameWithSingleTexture(name, natifImage.get(), width, height, flags, exFrame);
|
||||
|
||||
if (frame && image && natifImage.valid())
|
||||
{
|
||||
const unsigned int bpps = image->getPixelSizeInBits() / 8;
|
||||
const unsigned int one_third_s = image->s()/3;
|
||||
unsigned char* srcdata = (unsigned char*)image->data();
|
||||
osg::Vec4 color(0,0,0,1);
|
||||
for (unsigned int d = 0; d < bpps; d++)
|
||||
{
|
||||
color[d] = srcdata[one_third_s * image->s() * bpps + (one_third_s) * bpps + d] * 1.0/255.0;
|
||||
}
|
||||
frame->getEmbeddedWindow()->setColor(color);
|
||||
}
|
||||
return frame;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// (c) 2006-2008 Jean-Sébastien Guay
|
||||
// adapted by Cedric Pinson
|
||||
|
||||
/** Implementation of copyImage. */
|
||||
template<typename T>
|
||||
void copyDataImpl(const osg::Image* source,
|
||||
const unsigned int x1, const unsigned int y1,
|
||||
const unsigned int x2, const unsigned int y2,
|
||||
osg::Image* destination,
|
||||
const unsigned int xd = 0, const unsigned int yd = 0)
|
||||
{
|
||||
if ((unsigned int)destination->s() >= xd + (x2 - x1) &&
|
||||
(unsigned int)destination->t() >= yd + (y2 - y1))
|
||||
{
|
||||
const unsigned int bpps = source->getPixelSizeInBits() / (8 * sizeof(T));
|
||||
|
||||
T* srcdata = (T*)source->data();
|
||||
T* dstdata = (T*)destination->data();
|
||||
|
||||
for (unsigned int y = 0; y < y2 - y1; ++y)
|
||||
{
|
||||
for (unsigned int x = 0; x < x2 - x1; ++x)
|
||||
{
|
||||
for (unsigned int d = 0; d < bpps; d++)
|
||||
{
|
||||
T v = srcdata[(y + y1) * source->s() * bpps + (x + x1) * bpps + d];
|
||||
dstdata[(yd + y) * destination->s() * bpps + (xd + x) * bpps + d] = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
assert(false && "copyDataImpl: Incorrect image dimensions.");
|
||||
}
|
||||
|
||||
/** Copies a rectangle of corners (x1, y1), (x2, y2) from an image into
|
||||
another image starting at position (xd, yd). No scaling is done, the
|
||||
pixels are just copied, so the destination image must be at least
|
||||
(xd + (x2 - x1)) by (yd + (y2 - y1)) pixels. */
|
||||
void copyData(const osg::Image* source,
|
||||
const unsigned int x1, const unsigned int y1,
|
||||
const unsigned int x2, const unsigned int y2,
|
||||
osg::Image* destination,
|
||||
const unsigned int xd, const unsigned int yd)
|
||||
{
|
||||
if (source->getDataType() == destination->getDataType())
|
||||
{
|
||||
if (source->getDataType() == GL_UNSIGNED_BYTE)
|
||||
{
|
||||
copyDataImpl<unsigned char>(source, x1, y1, x2, y2,
|
||||
destination, xd, yd);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(false && "copyData not implemented for this data type");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(false && "source and destination images must be of the same type.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Implementation of rotateImage. */
|
||||
template<typename T>
|
||||
osg::Image* rotateImageImpl(osg::Image* image)
|
||||
{
|
||||
if (image->s() == image->t())
|
||||
{
|
||||
const unsigned int s = image->s();
|
||||
const unsigned int bpp = image->getPixelSizeInBits() / (8 * sizeof(T));
|
||||
|
||||
osg::ref_ptr<osg::Image> destination = new osg::Image;
|
||||
destination->allocateImage(s, s, 1,
|
||||
image->getPixelFormat(), image->getDataType(),
|
||||
image->getPacking());
|
||||
destination->setInternalTextureFormat(image->getInternalTextureFormat());
|
||||
|
||||
T* srcdata = (T*)image->data();
|
||||
T* dstdata = (T*)destination->data();
|
||||
|
||||
for (unsigned int y = 0; y < s; ++y)
|
||||
{
|
||||
for (unsigned int x = 0; x < s; ++x)
|
||||
{
|
||||
for (unsigned int p = 0; p < bpp; p++)
|
||||
dstdata[y * s * bpp + x * bpp + p] = srcdata[x * s * bpp + y * bpp + p];
|
||||
}
|
||||
}
|
||||
|
||||
return destination.release();
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(false && "rotateImageImpl: Image must be square.");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/** Rotates an osg::Image by 90 degrees. Returns a new osg::Image, be sure to
|
||||
store it in a ref_ptr so it will be freed correctly. */
|
||||
osg::Image* rotateImage(osg::Image* image)
|
||||
{
|
||||
if (image->getDataType() == GL_UNSIGNED_BYTE)
|
||||
{
|
||||
return rotateImageImpl<unsigned char>(image);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(false && "rotateImage not implemented for this data type");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// SOURCE
|
||||
// +---+---+---+
|
||||
// | 1 | 2 | 3 |
|
||||
// +---+---+---+
|
||||
// | 4 | | 5 |
|
||||
// +---+---+---+
|
||||
// | 6 | 7 | 8 |
|
||||
// +---+---+---+
|
||||
|
||||
|
||||
// FINAL
|
||||
// +---+---+---+---+---+---+---+---+
|
||||
// | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
|
||||
// +---+---+---+---+---+---+---+---+
|
||||
|
||||
// 1. Upper-Left corner.
|
||||
// 2. Top border (rotated 90 degrees CCW).
|
||||
// 3. Upper-Right corner.
|
||||
// 4. Left border.
|
||||
// 5. Right border.
|
||||
// 6. Bottom-Left corner.
|
||||
// 7. Bottom border (rotated 90 degrees CCW).
|
||||
// 8. Bottom-Right corner.
|
||||
|
||||
osg::Image* createNatifEdgeImageFromTheme(osg::Image* theme)
|
||||
{
|
||||
if (!theme) {
|
||||
osg::notify(osg::WARN) << "can't create a natif edge image from null image theme as argument" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
osg::ref_ptr<osg::Image> final = new osg::Image;
|
||||
const int s = theme->s();
|
||||
const int t = theme->t();
|
||||
const GLenum pixelFormat = theme->getPixelFormat();
|
||||
const GLenum dataType = theme->getDataType();
|
||||
const GLint internalFormat = theme->getInternalTextureFormat();
|
||||
unsigned int packing = theme->getPacking();
|
||||
|
||||
if (s != t)
|
||||
{
|
||||
osg::notify(osg::WARN) << "width and height are different, bad format theme image " << theme->getFileName() << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// check size
|
||||
int ceilvalue = static_cast<int>(ceil(s * 1.0 / 3));
|
||||
int intvalue = s/3;
|
||||
if (intvalue != ceilvalue)
|
||||
{
|
||||
osg::notify(osg::WARN) << "the size of theme file " << theme->getFileName() << " can not be divided by 3, check the documentation about theme format" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
const unsigned int one_third_s = s/3;
|
||||
const unsigned int one_third_t = t/3;
|
||||
|
||||
final->allocateImage(8 * one_third_s , one_third_t, 1, pixelFormat, dataType, packing);
|
||||
final->setInternalTextureFormat(internalFormat);
|
||||
|
||||
// copy 1 (6 in source)
|
||||
copyData(theme, 0, 2 * one_third_s, one_third_s, 3 * one_third_s, final.get(), 0, 0);
|
||||
|
||||
// rotate and copy 2
|
||||
osg::ref_ptr<osg::Image> rotateandcopy2 = new osg::Image;
|
||||
rotateandcopy2->allocateImage(one_third_s , one_third_t, 1, pixelFormat, dataType, packing);
|
||||
rotateandcopy2->setInternalTextureFormat(internalFormat);
|
||||
copyData(theme, one_third_s, 0, 2 * one_third_s , one_third_s, rotateandcopy2.get(), 0, 0);
|
||||
rotateandcopy2 = rotateImage(rotateandcopy2.get());
|
||||
rotateandcopy2->flipHorizontal();
|
||||
copyData(rotateandcopy2.get(), 0, 0, one_third_s , one_third_s, final.get(), 6*one_third_s, 0);
|
||||
|
||||
// copy 3 (8 in source)
|
||||
copyData(theme, 2*one_third_s , 2 *one_third_s, 3*one_third_s , 3 * one_third_s, final.get(), 2 * one_third_s, 0);
|
||||
|
||||
// copy 4
|
||||
copyData(theme, 0, one_third_s, one_third_s , 2 * one_third_s, final.get(), 3 * one_third_s, 0);
|
||||
|
||||
// copy 5
|
||||
copyData(theme, 2*one_third_s , one_third_s, 3 * one_third_s , 2 * one_third_s, final.get(), 4 * one_third_s, 0);
|
||||
|
||||
// copy 6 (1 in source)
|
||||
copyData(theme, 0 , 0, one_third_s, one_third_s, final.get(), 5 * one_third_s, 0);
|
||||
|
||||
// rotate and copy 7
|
||||
osg::ref_ptr<osg::Image> rotateandcopy7 = new osg::Image;
|
||||
rotateandcopy7->allocateImage(one_third_s , one_third_t, 1, pixelFormat, dataType, packing);
|
||||
rotateandcopy7->setInternalTextureFormat(internalFormat);
|
||||
copyData(theme, one_third_s, 2*one_third_s, 2 * one_third_s , 3 * one_third_s, rotateandcopy7.get(), 0, 0);
|
||||
rotateandcopy7 = rotateImage(rotateandcopy7.get());
|
||||
rotateandcopy7->flipHorizontal();
|
||||
copyData(rotateandcopy7.get(), 0, 0, one_third_s , one_third_s, final.get(), one_third_s, 0);
|
||||
|
||||
// copy 8 (3 in source)
|
||||
copyData(theme, 2 * one_third_s, 0, 3 * one_third_s , one_third_s , final.get(), 7 * one_third_s, 0);
|
||||
|
||||
return final.release();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
// -*-c++-*- osgWidget - Code by: Jeremy Moles (cubicool) 2007-2008
|
||||
// $Id: Input.cpp 65 2008-07-14 16:29:28Z cubicool $
|
||||
|
||||
#include <osg/io_utils>
|
||||
#include <osgWidget/WindowManager>
|
||||
@ -22,7 +21,7 @@ _cursor (new Widget("cursor")) {
|
||||
// Make the cursor un-copyable.
|
||||
_cursor->setCanClone(false);
|
||||
_cursor->setDataVariance(osg::Object::DYNAMIC);
|
||||
_cursor->setColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
_cursor->setColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
|
||||
setEventMask(
|
||||
// For showing/hiding the "cursor."
|
||||
@ -46,9 +45,9 @@ void Input::_calculateSize(const XYCoord& size) {
|
||||
point_type width = size.x() + _cursor->getWidth();
|
||||
point_type height = _cursor->getHeight();
|
||||
|
||||
if(width > getWidth()) setWidth(osg::round(width));
|
||||
// if(width > getWidth()) setWidth(osg::round(width));
|
||||
|
||||
if(height > getHeight()) setHeight(osg::round(height));
|
||||
// if(height > getHeight()) setHeight(osg::round(height));
|
||||
}
|
||||
|
||||
void Input::_calculateCursorOffsets() {
|
||||
@ -59,28 +58,22 @@ void Input::_calculateCursorOffsets() {
|
||||
|
||||
const osgText::Text::GlyphQuads& gq = tgqmi->second;
|
||||
|
||||
point_type accum = 0.0f;
|
||||
osg::Vec3 pos = _text->getPosition();
|
||||
|
||||
std::ostream& os = warn() << "_offsets[ ";
|
||||
|
||||
for(unsigned int i = 0; i < _maxSize; i++) {
|
||||
osg::Vec2 ul = gq.getCoords()[0 + (i * 4)];
|
||||
osg::Vec2 ll = gq.getCoords()[1 + (i * 4)];
|
||||
osg::Vec2 lr = gq.getCoords()[2 + (i * 4)];
|
||||
osg::Vec2 ur = gq.getCoords()[3 + (i * 4)];
|
||||
osg::Vec3 ul = gq.getTransformedCoords(0)[0 + (i * 4)];
|
||||
osg::Vec3 ll = gq.getTransformedCoords(0)[1 + (i * 4)];
|
||||
osg::Vec3 lr = gq.getTransformedCoords(0)[2 + (i * 4)];
|
||||
osg::Vec3 ur = gq.getTransformedCoords(0)[3 + (i * 4)];
|
||||
|
||||
accum += osg::round(lr.x() - ll.x());
|
||||
|
||||
_offsets[i] = accum;
|
||||
|
||||
os << _offsets[i] << " (" << static_cast<char>(_text->getText()[i]) << ") ";
|
||||
_offsets[i] = lr.x() - pos.x();
|
||||
|
||||
// warn() << "vb: " << gq.getGlyphs()[i]->getHorizontalBearing() << std::endl;
|
||||
}
|
||||
|
||||
os << "]" << std::endl;
|
||||
}
|
||||
|
||||
bool Input::focus(WindowManager*) {
|
||||
_cursor->setColor(1.0f, 1.0f, 1.0f, 0.5f);
|
||||
_cursor->setColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -112,7 +105,7 @@ void Input::positioned() {
|
||||
;
|
||||
|
||||
point_type x = getX() + _xoff;
|
||||
point_type y = getY() + th + _yoff;
|
||||
point_type y = getY() + _yoff;
|
||||
|
||||
// XYCoord size = getTextSize();
|
||||
|
||||
@ -129,7 +122,6 @@ bool Input::keyUp(int key, int mask, WindowManager*) {
|
||||
}
|
||||
|
||||
bool Input::keyDown(int key, int mask, WindowManager*) {
|
||||
/*
|
||||
osgText::String& s = _text->getText();
|
||||
|
||||
if(key == osgGA::GUIEventAdapter::KEY_BackSpace) {
|
||||
@ -166,16 +158,30 @@ bool Input::keyDown(int key, int mask, WindowManager*) {
|
||||
_calculateSize(getTextSize());
|
||||
|
||||
getParent()->resize();
|
||||
*/
|
||||
|
||||
warn() << "Input is disabled until someone can help me understand how to use osgText; sorry..." << std::endl;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void Input::setCursor(Widget*)
|
||||
{
|
||||
warn() << "Input::setCursor(Widget*) not implemented yet."<<std::endl;
|
||||
void Input::setCursor(Widget*) {
|
||||
}
|
||||
|
||||
unsigned int Input::calculateBestYOffset(const std::string& s) {
|
||||
const osgText::FontResolution fr(_text->getCharacterHeight(), _text->getCharacterHeight());
|
||||
|
||||
osgText::String utf(s);
|
||||
|
||||
unsigned int descent = 0;
|
||||
|
||||
for(osgText::String::iterator i = utf.begin(); i != utf.end(); i++) {
|
||||
osgText::Font* font = const_cast<osgText::Font*>(_text->getFont());
|
||||
osgText::Font::Glyph* glyph = font->getGlyph(fr, *i);
|
||||
unsigned int d = abs(glyph->getHorizontalBearing().y());
|
||||
|
||||
if(d > descent) descent = d;
|
||||
}
|
||||
|
||||
return descent;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
// -*-c++-*- osgWidget - Code by: Jeremy Moles (cubicool) 2007-2008
|
||||
// $Id: Label.cpp 59 2008-05-15 20:55:31Z cubicool $
|
||||
|
||||
#include <osg/Math>
|
||||
#include <osgWidget/WindowManager>
|
||||
@ -9,12 +8,17 @@ namespace osgWidget {
|
||||
|
||||
Label::Label(const std::string& name, const std::string& label):
|
||||
Widget (name, 0, 0),
|
||||
_textIndex (0),
|
||||
_text (new osgText::Text()) {
|
||||
_text->setText(label);
|
||||
_text (new osgText::Text()),
|
||||
_textIndex (0) {
|
||||
_text->setAlignment(osgText::Text::LEFT_BOTTOM);
|
||||
_text->setDataVariance(osg::Object::DYNAMIC);
|
||||
|
||||
if(label.size()) {
|
||||
_text->setText(label);
|
||||
|
||||
_calculateSize(getTextSize());
|
||||
}
|
||||
|
||||
// TODO: Make a patch for this!
|
||||
// If you're wondering why we don't use this let me explain...
|
||||
//
|
||||
@ -36,7 +40,7 @@ _textIndex (label._textIndex) {
|
||||
}
|
||||
|
||||
void Label::_calculateSize(const XYCoord& size) {
|
||||
if(size.x() && size.y()) setMinimumSize(size.x(), size.y());
|
||||
// if(size.x() && size.y()) setMinimumSize(size.x(), size.y());
|
||||
|
||||
if(getWidth() < size.x()) setWidth(size.x());
|
||||
|
||||
@ -45,8 +49,15 @@ void Label::_calculateSize(const XYCoord& size) {
|
||||
|
||||
// TODO: This will almost certainly get out of sync. :(
|
||||
void Label::parented(Window* parent) {
|
||||
// If we've been cloned, use the index of the old text Drawable.
|
||||
if(_textIndex) parent->getGeode()->setDrawable(_textIndex, _text.get());
|
||||
osg::Geode* geode = parent->getGeode();
|
||||
|
||||
// If we've been cloned, use the index of the old text Drawable if it's already there.
|
||||
// However, we have a problem here: imagine a Label gets cloned AFTER being added to
|
||||
// a Window; it'll have a _textIndex, but that _textIndex won't apply to the
|
||||
// currently cloned object. In this case, we'll need to check to be SURE.
|
||||
osgText::Text* text = dynamic_cast<osgText::Text*>(geode->getDrawable(_textIndex));
|
||||
|
||||
if(text) parent->getGeode()->setDrawable(_textIndex, _text.get());
|
||||
|
||||
// Otherwise, add it as new.
|
||||
else _textIndex = parent->addDrawableAndGetIndex(_text.get());
|
||||
@ -58,33 +69,16 @@ void Label::unparented(Window* parent) {
|
||||
_textIndex = 0;
|
||||
}
|
||||
|
||||
void Label::managed(WindowManager* wm) {
|
||||
if(wm->isInvertedY()) {
|
||||
// We rotate along our X axis, so we need to make sure and translate the
|
||||
// text later to preserve centering.
|
||||
_text->setAxisAlignment(osgText::Text::USER_DEFINED_ROTATION);
|
||||
_text->setRotation(osg::Quat(
|
||||
osg::DegreesToRadians(180.0f),
|
||||
osg::Vec3(1.0f, 0.0f, 0.0f)
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
void Label::positioned() {
|
||||
XYCoord size = getTextSize();
|
||||
point_type x = osg::round(((getWidth() - size.x()) / 2.0f) + getX());
|
||||
point_type y = 0.0f;
|
||||
point_type y = osg::round(((getHeight() - size.y()) / 2.0f) + getY());
|
||||
point_type z = _calculateZ(getLayer() + 1);
|
||||
|
||||
if(getWindowManager() && getWindowManager()->isInvertedY()) y =
|
||||
osg::round(((getHeight() - size.y()) / 2.0f) + getY() + size.y())
|
||||
;
|
||||
|
||||
else y = osg::round(((getHeight() - size.y()) / 2.0f) + getY());
|
||||
|
||||
// These values are permisable with CENTER_CENTER mode is active.
|
||||
// point_type x = round(getX() + (getWidth() / 2.0f));
|
||||
// point_type y = round(getY() + (getHeight() / 2.0f));
|
||||
|
||||
|
||||
/*
|
||||
warn() << "Label widget size : " << getWidth() << " x " << getHeight() << std::endl;
|
||||
warn() << "Label widget tsize: " << getWidthTotal() << " x " << getHeightTotal() << std::endl;
|
||||
@ -94,12 +88,18 @@ void Label::positioned() {
|
||||
warn() << "------------------------------------" << std::endl;
|
||||
*/
|
||||
|
||||
_text->setPosition(osg::Vec3(x, y, _calculateZ(getLayer() + 1)));
|
||||
}
|
||||
const WindowManager* wm = _getWindowManager();
|
||||
|
||||
void Label::update()
|
||||
{
|
||||
warn() << "Label::update() not implemented yet."<<std::endl;
|
||||
if(wm && wm->isUsingRenderBins()) {
|
||||
_text->getOrCreateStateSet()->setRenderBinDetails(
|
||||
static_cast<int>(z * OSGWIDGET_RENDERBIN_MOD),
|
||||
"RenderBin"
|
||||
);
|
||||
|
||||
z = 0.0f;
|
||||
}
|
||||
|
||||
_text->setPosition(osg::Vec3(x, y, z));
|
||||
}
|
||||
|
||||
void Label::setLabel(const std::string& label) {
|
||||
|
@ -1,5 +1,4 @@
|
||||
// -*-c++-*- osgWidget - Code by: Jeremy Moles (cubicool) 2007-2008
|
||||
// $Id: Lua.cpp 2 2008-01-24 16:11:26Z cubicool $
|
||||
|
||||
#include <osgDB/FileUtils>
|
||||
#include <osgWidget/Lua>
|
||||
|
@ -1,5 +1,4 @@
|
||||
// -*-c++-*- osgWidget - Code by: Jeremy Moles (cubicool) 2007-2008
|
||||
// $Id: Python.cpp 59 2008-05-15 20:55:31Z cubicool $
|
||||
|
||||
// Python.h needs to be included before anything else.
|
||||
#ifdef OSGWIDGET_USEPYTHON
|
||||
@ -172,7 +171,7 @@ bool PythonEngine::runFile(const std::string& filePath) {
|
||||
return false;
|
||||
}
|
||||
|
||||
FILE* f = osgDB::fopen(filePath.c_str(), "r");
|
||||
FILE* f = fopen(filePath.c_str(), "r");
|
||||
PyObject* r = PyRun_File(f, filePath.c_str(), Py_file_input, _data->main, _data->main);
|
||||
|
||||
fclose(f);
|
||||
|
@ -1,5 +1,4 @@
|
||||
// -*-c++-*- osgWidget - Code by: Jeremy Moles (cubicool) 2007-2008
|
||||
// $Id: StyleManager.cpp 55 2008-05-12 19:14:42Z cubicool $
|
||||
|
||||
#include <sstream>
|
||||
#include <osg/io_utils>
|
||||
|
@ -1,5 +1,4 @@
|
||||
// -*-c++-*- osgWidget - Code by: Jeremy Moles (cubicool) 2007-2008
|
||||
// $Id: Table.cpp 48 2008-05-05 14:13:20Z cubicool $
|
||||
|
||||
#include <osgWidget/Table>
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
// -*-c++-*- osgWidget - Code by: Jeremy Moles (cubicool) 2007-2008
|
||||
// $Id: Util.cpp 59 2008-05-15 20:55:31Z cubicool $
|
||||
|
||||
#include <osg/io_utils>
|
||||
|
||||
@ -36,14 +35,6 @@ std::string generateRandomName(const std::string& base) {
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
osg::Matrix createInvertedYOrthoProjectionMatrix(matrix_type width, matrix_type height) {
|
||||
osg::Matrix m = osg::Matrix::ortho2D(0.0f, width, 0.0f, height);
|
||||
osg::Matrix s = osg::Matrix::scale(1.0f, -1.0f, 1.0f);
|
||||
osg::Matrix t = osg::Matrix::translate(0.0f, -height, 0.0f);
|
||||
|
||||
return t * s * m;
|
||||
}
|
||||
|
||||
osg::Camera* createOrthoCamera(matrix_type width, matrix_type height) {
|
||||
osg::Camera* camera = new osg::Camera();
|
||||
|
||||
@ -61,20 +52,12 @@ osg::Camera* createOrthoCamera(matrix_type width, matrix_type height) {
|
||||
return camera;
|
||||
}
|
||||
|
||||
osg::Camera* createInvertedYOrthoCamera(matrix_type width, matrix_type height) {
|
||||
osg::Camera* camera = createOrthoCamera(width, height);
|
||||
int createExample(osgViewer::Viewer& viewer, WindowManager* wm, osg::Node* node) {
|
||||
if(!wm) return 1;
|
||||
|
||||
camera->setProjectionMatrix(createInvertedYOrthoProjectionMatrix(width, height));
|
||||
|
||||
return camera;
|
||||
}
|
||||
|
||||
osg::Group* _createExampleCommon(osgViewer::View* view, WindowManager* wm, osg::Node* node) {
|
||||
if(!wm) return 0;
|
||||
|
||||
view->setUpViewInWindow(
|
||||
0,
|
||||
0,
|
||||
viewer.setUpViewInWindow(
|
||||
50,
|
||||
50,
|
||||
static_cast<int>(wm->getWidth()),
|
||||
static_cast<int>(wm->getHeight())
|
||||
);
|
||||
@ -86,87 +69,23 @@ osg::Group* _createExampleCommon(osgViewer::View* view, WindowManager* wm, osg::
|
||||
|
||||
if(node) group->addChild(node);
|
||||
|
||||
view->addEventHandler(new osgWidget::MouseHandler(wm));
|
||||
view->addEventHandler(new osgWidget::KeyboardHandler(wm));
|
||||
view->addEventHandler(new osgWidget::ResizeHandler(wm, camera));
|
||||
view->addEventHandler(new osgViewer::StatsHandler());
|
||||
view->addEventHandler(new osgViewer::WindowSizeHandler());
|
||||
view->addEventHandler(new osgGA::StateSetManipulator(
|
||||
view->getCamera()->getOrCreateStateSet()
|
||||
viewer.addEventHandler(new osgWidget::MouseHandler(wm));
|
||||
viewer.addEventHandler(new osgWidget::KeyboardHandler(wm));
|
||||
viewer.addEventHandler(new osgWidget::ResizeHandler(wm, camera));
|
||||
viewer.addEventHandler(new osgWidget::CameraSwitchHandler(wm, camera));
|
||||
viewer.addEventHandler(new osgViewer::StatsHandler());
|
||||
viewer.addEventHandler(new osgViewer::WindowSizeHandler());
|
||||
viewer.addEventHandler(new osgGA::StateSetManipulator(
|
||||
viewer.getCamera()->getOrCreateStateSet()
|
||||
));
|
||||
|
||||
wm->resizeAllWindows();
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
int createExample(osgViewer::Viewer& viewer, WindowManager* wm, osg::Node* node) {
|
||||
osg::Group* group = _createExampleCommon(&viewer, wm, node);
|
||||
|
||||
viewer.setSceneData(group);
|
||||
|
||||
return viewer.run();
|
||||
}
|
||||
|
||||
// TODO: This function is totally broken; I don't really have any idea of how to do this.
|
||||
// Incredibly frustrating stuff.
|
||||
int createCompositeExample(
|
||||
osgViewer::CompositeViewer& viewer,
|
||||
osgViewer::View* view,
|
||||
WindowManager* wm,
|
||||
osg::Node* node
|
||||
) {
|
||||
osg::Group* group = _createExampleCommon(view, wm, node);
|
||||
osg::MatrixTransform* watcher = new osg::MatrixTransform();
|
||||
|
||||
watcher->addChild(wm);
|
||||
|
||||
// Setup the main 2D view.
|
||||
viewer.addView(view);
|
||||
|
||||
view->setSceneData(group);
|
||||
|
||||
// The view that "watches" the main view.
|
||||
osgViewer::View* viewWatcher = new osgViewer::View();
|
||||
|
||||
viewer.addView(viewWatcher);
|
||||
|
||||
int w = static_cast<int>(wm->getWidth());
|
||||
int h = static_cast<int>(wm->getHeight());
|
||||
|
||||
viewWatcher->setUpViewInWindow(0, 0, w, h);
|
||||
|
||||
// Setup our parent MatrixTransform so things look right in perspective.
|
||||
watcher->setMatrix(
|
||||
osg::Matrix::scale(1.0f, -1.0f, 1000.0f) *
|
||||
osg::Matrix::rotate(osg::DegreesToRadians(90.0f), osg::Vec3d(1.0f, 0.0f, 0.0f))
|
||||
);
|
||||
|
||||
watcher->getOrCreateStateSet()->setAttributeAndModes(
|
||||
new osg::Scissor(0, 0, w, h),
|
||||
osg::StateAttribute::OVERRIDE
|
||||
);
|
||||
|
||||
osgGA::TrackballManipulator* tb = new osgGA::TrackballManipulator();
|
||||
|
||||
warn() << watcher->getMatrix() << std::endl;
|
||||
|
||||
/*
|
||||
const osg::BoundingSphere& bs = watcher->getBound();
|
||||
|
||||
tb->setHomePosition(
|
||||
bs.center() + osg::Vec3(0.0f, -3.5f * bs.radius(), 0.0f),
|
||||
bs.center(),
|
||||
osg::Vec3(0.0f, 1.0f, 0.0f)
|
||||
);
|
||||
*/
|
||||
|
||||
viewWatcher->setSceneData(watcher);
|
||||
viewWatcher->setCameraManipulator(tb);
|
||||
|
||||
return viewer.run();
|
||||
}
|
||||
|
||||
bool writeWindowManagerNode(WindowManager* wm) {
|
||||
osgDB::writeNodeFile(*wm->getParent(0), "osgWidget.osg");
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
// -*-c++-*- osgWidget - Code by: Jeremy Moles (cubicool) 2007-2008
|
||||
// $Id: ViewerEventHandlers.cpp 59 2008-05-15 20:55:31Z cubicool $
|
||||
|
||||
#include <osgWidget/ViewerEventHandlers>
|
||||
|
||||
@ -175,16 +174,87 @@ bool ResizeHandler::handle(
|
||||
osg::Matrix::value_type w = gea.getWindowWidth();
|
||||
osg::Matrix::value_type h = gea.getWindowHeight();
|
||||
|
||||
if(_wm->isInvertedY()) _camera->setProjectionMatrix(
|
||||
createInvertedYOrthoProjectionMatrix(w, h)
|
||||
);
|
||||
if(_camera.valid()) {
|
||||
_camera->setProjectionMatrix(osg::Matrix::ortho2D(0.0f, w, 0.0f, h));
|
||||
|
||||
else _camera->setProjectionMatrix(osg::Matrix::ortho2D(0.0f, w, 0.0f, h));
|
||||
_wm->setSize(w, h);
|
||||
}
|
||||
|
||||
_wm->setSize(w, h);
|
||||
_wm->setWindowSize(w, h);
|
||||
_wm->resizeAllWindows();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
CameraSwitchHandler::CameraSwitchHandler(WindowManager* wm, osg::Camera* camera):
|
||||
_wm (wm),
|
||||
_camera (camera) {
|
||||
}
|
||||
|
||||
bool CameraSwitchHandler::handle(
|
||||
const osgGA::GUIEventAdapter& gea,
|
||||
osgGA::GUIActionAdapter& gaa,
|
||||
osg::Object* obj,
|
||||
osg::NodeVisitor* nv
|
||||
) {
|
||||
if(
|
||||
gea.getEventType() != osgGA::GUIEventAdapter::KEYDOWN ||
|
||||
gea.getKey() != osgGA::GUIEventAdapter::KEY_F12
|
||||
) return false;
|
||||
|
||||
osgViewer::View* view = dynamic_cast<osgViewer::View*>(&gaa);
|
||||
|
||||
if(!view) return false;
|
||||
|
||||
osg::Node* oldNode = view->getSceneData();
|
||||
|
||||
osg::MatrixTransform* oldTrans = dynamic_cast<osg::MatrixTransform*>(oldNode);
|
||||
|
||||
if(!oldTrans) {
|
||||
// Imagine this is the number of pixels...
|
||||
double scale = 2000.0f;
|
||||
double width = _wm->getWidth();
|
||||
double height = _wm->getHeight();
|
||||
|
||||
_oldNode = oldNode;
|
||||
|
||||
osg::MatrixTransform* mt = new osg::MatrixTransform();
|
||||
|
||||
mt->setMatrix(
|
||||
osg::Matrix::translate(width / 2.0f, 0.0f, 0.0f) *
|
||||
osg::Matrix::scale(1.0f, 1.0f, scale) *
|
||||
osg::Matrix::rotate(osg::DegreesToRadians(45.0f), 0.0f, 1.0f, 0.0f)
|
||||
);
|
||||
|
||||
mt->addChild(_wm.get());
|
||||
mt->getOrCreateStateSet()->setMode(
|
||||
GL_LIGHTING,
|
||||
osg::StateAttribute::PROTECTED | osg::StateAttribute::OFF
|
||||
);
|
||||
mt->getOrCreateStateSet()->setMode(
|
||||
GL_SCISSOR_TEST,
|
||||
osg::StateAttribute::OVERRIDE | osg::StateAttribute::OFF
|
||||
);
|
||||
|
||||
osgGA::MatrixManipulator* mm = view->getCameraManipulator();
|
||||
|
||||
// mm->setDistance(3000.0f);
|
||||
// mm->setMinimumZoomScale(10.0f);
|
||||
mm->setHomePosition(
|
||||
// eye
|
||||
osg::Vec3(width / 2.0f, height, 100.0f),
|
||||
// center
|
||||
osg::Vec3(0.0f, 0.0f, -(scale / 2.0f)),
|
||||
// up
|
||||
osg::Vec3(0.0f, 1.0f, 0.0f)
|
||||
);
|
||||
|
||||
view->setSceneData(mt);
|
||||
}
|
||||
|
||||
else view->setSceneData(_oldNode.get());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3,8 +3,7 @@
|
||||
|
||||
#include <osg/io_utils>
|
||||
#include <osg/Math>
|
||||
#include <osg/BlendFunc>
|
||||
#include <osg/TexMat>
|
||||
#include <osg/TextureRectangle>
|
||||
#include <osgDB/ReadFile>
|
||||
#include <osgDB/FileUtils>
|
||||
#include <osgWidget/WindowManager>
|
||||
@ -34,8 +33,8 @@ _canFill (false),
|
||||
_canClone (true),
|
||||
_isManaged (false),
|
||||
_isStyled (false),
|
||||
_minWidth (w),
|
||||
_minHeight (h) {
|
||||
_minWidth (0.0f),
|
||||
_minHeight (0.0f) {
|
||||
_name = name.size() ? name : generateRandomName("Widget");
|
||||
|
||||
if(!_norms.valid()) {
|
||||
@ -63,9 +62,6 @@ _minHeight (h) {
|
||||
|
||||
setDimensions(0.0f, 0.0f, w, h);
|
||||
setColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
getOrCreateStateSet()->setMode(GL_BLEND, osg::StateAttribute::ON);
|
||||
getOrCreateStateSet()->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
|
||||
}
|
||||
|
||||
Widget::Widget(const Widget& widget, const osg::CopyOp& co):
|
||||
@ -108,26 +104,13 @@ WindowManager* Widget::_getWindowManager() const {
|
||||
}
|
||||
|
||||
osg::Image* Widget::_getImage() const {
|
||||
const osg::Texture2D* texture = _texture();
|
||||
const osg::Texture* texture = _texture();
|
||||
|
||||
if(texture) return const_cast<osg::Image*>(texture->getImage(0));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Widget::managed(WindowManager* wm) {
|
||||
if(!wm->isInvertedY()) return;
|
||||
|
||||
osg::Matrix s = osg::Matrix::scale(1.0f, -1.0f, 1.0f);
|
||||
osg::Matrix t = osg::Matrix::translate(0.0f, -1.0, 0.0f);
|
||||
|
||||
getOrCreateStateSet()->setTextureAttributeAndModes(
|
||||
0,
|
||||
new osg::TexMat(t * s),
|
||||
osg::StateAttribute::ON
|
||||
);
|
||||
}
|
||||
|
||||
void Widget::setDimensions(point_type x, point_type y, point_type w, point_type h, point_type z) {
|
||||
if(w != -1.0f && w < _minWidth) {
|
||||
warn()
|
||||
@ -205,6 +188,14 @@ void Widget::setDimensions(point_type x, point_type y, point_type w, point_type
|
||||
}
|
||||
}
|
||||
|
||||
const WindowManager* wm = _getWindowManager();
|
||||
|
||||
if(wm && wm->isUsingRenderBins()) {
|
||||
getOrCreateStateSet()->setRenderBinDetails(static_cast<int>(z), "RenderBin");
|
||||
|
||||
z = 0.0f;
|
||||
}
|
||||
|
||||
(*verts)[LL].set(x, y, z);
|
||||
(*verts)[LR].set(x + w, y, z);
|
||||
(*verts)[UR].set(x + w, y + h, z);
|
||||
@ -221,7 +212,7 @@ void Widget::setColor(color_type r, color_type g, color_type b, color_type a, Co
|
||||
(*cols)[UL].set(r, g, b, a);
|
||||
}
|
||||
|
||||
else (*cols)[convertCorner(p)].set(r, g, b, a);
|
||||
else (*cols)[p].set(r, g, b, a);
|
||||
}
|
||||
|
||||
void Widget::addColor(color_type r, color_type g, color_type b, color_type a, Corner p) {
|
||||
@ -234,7 +225,7 @@ void Widget::addColor(color_type r, color_type g, color_type b, color_type a, Co
|
||||
(*cols)[UL] += Color(r, g, b, a);
|
||||
}
|
||||
|
||||
else (*cols)[convertCorner(p)] += Color(r, g, b, a);
|
||||
else (*cols)[p] += Color(r, g, b, a);
|
||||
}
|
||||
|
||||
void Widget::setTexCoord(texcoord_type tx, texcoord_type ty, Corner p) {
|
||||
@ -247,7 +238,15 @@ void Widget::setTexCoord(texcoord_type tx, texcoord_type ty, Corner p) {
|
||||
(*texs)[UL].set(tx, ty);
|
||||
}
|
||||
|
||||
else (*texs)[convertCorner(p)].set(tx, ty);
|
||||
else (*texs)[p].set(tx, ty);
|
||||
}
|
||||
|
||||
// TODO: We chop off any offset here if you use TOP; we need to do the same
|
||||
// for BG, etc.
|
||||
void Widget::setLayer(Layer layer, unsigned int offset) {
|
||||
if(layer == LAYER_TOP) offset = 0;
|
||||
|
||||
_layer = layer + offset;
|
||||
}
|
||||
|
||||
void Widget::setTexCoordRegion(point_type x, point_type y, point_type w, point_type h) {
|
||||
@ -263,27 +262,27 @@ void Widget::setTexCoordRegion(point_type x, point_type y, point_type w, point_t
|
||||
// Set the LOWER_LEFT point.
|
||||
XYCoord t(x / tw, y / tw);
|
||||
|
||||
(*texs)[UL] = t;
|
||||
(*texs)[LL] = t;
|
||||
|
||||
// Set the LOWER_RIGHT point.
|
||||
t += XYCoord(w / tw, 0.0f);
|
||||
|
||||
(*texs)[UR] = t;
|
||||
(*texs)[LR] = t;
|
||||
|
||||
// Set the UPPER_RIGHT point.
|
||||
t += XYCoord(0.0f, h / th);
|
||||
|
||||
(*texs)[LR] = t;
|
||||
(*texs)[UR] = t;
|
||||
|
||||
// Set the UPPER_LEFT point.
|
||||
t += XYCoord(-(w / tw), 0.0f);
|
||||
|
||||
(*texs)[LL] = t;
|
||||
(*texs)[UL] = t;
|
||||
}
|
||||
|
||||
void Widget::setTexCoordWrapHorizontal() {
|
||||
osg::Image* image = _image();
|
||||
osg::Texture2D* texture = _texture();
|
||||
osg::Image* image = _image();
|
||||
osg::Texture* texture = _texture();
|
||||
|
||||
if(!image || !texture || image->s() == 0.0f) return;
|
||||
|
||||
@ -294,8 +293,8 @@ void Widget::setTexCoordWrapHorizontal() {
|
||||
}
|
||||
|
||||
void Widget::setTexCoordWrapVertical() {
|
||||
osg::Image* image = _image();
|
||||
osg::Texture2D* texture = _texture();
|
||||
osg::Image* image = _image();
|
||||
osg::Texture* texture = _texture();
|
||||
|
||||
if(!image || !texture || image->t() == 0.0f) return;
|
||||
|
||||
@ -311,35 +310,27 @@ XYCoord Widget::localXY(double _x, double _y) const {
|
||||
return _parent->localXY(_x, _y) - getOrigin();
|
||||
}
|
||||
|
||||
bool Widget::setImage(osg::Image* image, bool setTexCoords) {
|
||||
bool Widget::setImage(osg::Image* image, bool setTexCoords, bool useTextRect) {
|
||||
if(!image) {
|
||||
warn() << "Widget [" << _name << "] cannot use a NULL image." << std::endl;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
osg::Texture2D* texture = new osg::Texture2D();
|
||||
osg::Texture* texture = 0;
|
||||
|
||||
texture->setDataVariance(osg::Object::DYNAMIC);
|
||||
if(useTextRect) texture = new osg::TextureRectangle();
|
||||
|
||||
else texture = new osg::Texture2D();
|
||||
|
||||
if(!texture) return false;
|
||||
|
||||
texture->setImage(0, image);
|
||||
|
||||
getOrCreateStateSet()->setTextureAttributeAndModes(
|
||||
0,
|
||||
texture,
|
||||
osg::StateAttribute::ON
|
||||
);
|
||||
|
||||
if(setTexCoords) {
|
||||
setTexCoord(0.0f, 0.0f, LOWER_LEFT);
|
||||
setTexCoord(1.0f, 0.0f, LOWER_RIGHT);
|
||||
setTexCoord(1.0f, 1.0f, UPPER_RIGHT);
|
||||
setTexCoord(0.0f, 1.0f, UPPER_LEFT);
|
||||
}
|
||||
|
||||
return true;
|
||||
return setTexture(texture, setTexCoords, useTextRect);
|
||||
}
|
||||
|
||||
bool Widget::setImage(const std::string& filePath, bool setTexCoords) {
|
||||
bool Widget::setImage(const std::string& filePath, bool setTexCoords, bool useTextRect) {
|
||||
if(!osgDB::findDataFile(filePath).size()) {
|
||||
warn()
|
||||
<< "Widget [" << _name
|
||||
@ -350,7 +341,37 @@ bool Widget::setImage(const std::string& filePath, bool setTexCoords) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return setImage(osgDB::readImageFile(filePath), setTexCoords);
|
||||
return setImage(osgDB::readImageFile(filePath), setTexCoords, useTextRect);
|
||||
}
|
||||
|
||||
bool Widget::setTexture(osg::Texture* texture, bool setTexCoords, bool useTextRect) {
|
||||
if(!texture) return false;
|
||||
|
||||
getOrCreateStateSet()->setTextureAttributeAndModes(
|
||||
0,
|
||||
texture,
|
||||
osg::StateAttribute::ON
|
||||
);
|
||||
|
||||
if(setTexCoords) {
|
||||
if(useTextRect) {
|
||||
osg::Image* image = texture->getImage(0);
|
||||
|
||||
setTexCoord(0.0f, 0.0f, LOWER_LEFT);
|
||||
setTexCoord(image->s(), 0.0f, LOWER_RIGHT);
|
||||
setTexCoord(image->s(), image->t(), UPPER_RIGHT);
|
||||
setTexCoord(0.0f, image->t(), UPPER_LEFT);
|
||||
}
|
||||
|
||||
else {
|
||||
setTexCoord(0.0f, 0.0f, LOWER_LEFT);
|
||||
setTexCoord(1.0f, 0.0f, LOWER_RIGHT);
|
||||
setTexCoord(1.0f, 1.0f, UPPER_RIGHT);
|
||||
setTexCoord(0.0f, 1.0f, UPPER_LEFT);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Widget::setPadding(point_type pad) {
|
||||
@ -451,7 +472,7 @@ const Point& Widget::getPoint(Corner p) const {
|
||||
|
||||
if(p == ALL_CORNERS) point = UPPER_LEFT;
|
||||
|
||||
return (*_verts())[convertCorner(point)];
|
||||
return (*_verts())[point];
|
||||
}
|
||||
|
||||
const Color& Widget::getColor(Corner p) const {
|
||||
@ -459,7 +480,7 @@ const Color& Widget::getColor(Corner p) const {
|
||||
|
||||
if(p == ALL_CORNERS) point = UPPER_LEFT;
|
||||
|
||||
return (*_cols())[convertCorner(point)];
|
||||
return (*_cols())[point];
|
||||
}
|
||||
|
||||
const TexCoord& Widget::getTexCoord(Corner p) const {
|
||||
@ -467,25 +488,7 @@ const TexCoord& Widget::getTexCoord(Corner p) const {
|
||||
|
||||
if(p == ALL_CORNERS) point = UPPER_LEFT;
|
||||
|
||||
return (*_texs())[convertCorner(point)];
|
||||
}
|
||||
|
||||
// This converts our points back and forth depding on whether or not we're in an
|
||||
// inverted-Y WindowManager.
|
||||
Widget::Corner Widget::convertCorner(Corner p) const {
|
||||
const WindowManager* wm = getWindowManager();
|
||||
|
||||
if(!wm || !wm->isInvertedY()) return p;
|
||||
|
||||
if(p == UPPER_LEFT) return LOWER_LEFT;
|
||||
|
||||
else if(p == UPPER_RIGHT) return LOWER_RIGHT;
|
||||
|
||||
else if(p == LOWER_LEFT) return UPPER_LEFT;
|
||||
|
||||
else if(p == LOWER_RIGHT) return UPPER_RIGHT;
|
||||
|
||||
else return p;
|
||||
return (*_texs())[point];
|
||||
}
|
||||
|
||||
Color Widget::getImageColorAtXY(point_type x, point_type y) const {
|
||||
|
@ -70,7 +70,11 @@ void Window::EmbeddedWindow::parented(Window* parent) {
|
||||
}
|
||||
|
||||
void Window::EmbeddedWindow::unparented(Window*) {
|
||||
// TODO: Figure out what's necessary here...
|
||||
if(_window.valid()) {
|
||||
_window->_parent = 0;
|
||||
|
||||
if(_parent) _parent->removeChild(_window.get());
|
||||
}
|
||||
}
|
||||
|
||||
void Window::EmbeddedWindow::managed(WindowManager* wm) {
|
||||
@ -95,6 +99,8 @@ void Window::EmbeddedWindow::positioned() {
|
||||
// If the widget is fillable, ask the internal Window to resize itself.
|
||||
// Whether or not the Window honors this reqest will be up to it.
|
||||
_window->setOrigin(x, y);
|
||||
_window->setZ(_calculateZ(getLayer() + 1));
|
||||
_window->setZRange(_calculateZ(LAYER_TOP - (getLayer() + 1)));
|
||||
_window->setVisibleArea(0, 0, static_cast<int>(w), static_cast<int>(h));
|
||||
_window->resize(w, h);
|
||||
}
|
||||
@ -109,7 +115,6 @@ bool Window::EmbeddedWindow::setWindow(Window* win) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: I need to handle there already being a Window here.
|
||||
_window = win;
|
||||
|
||||
_window->resize();
|
||||
@ -124,21 +129,27 @@ bool Window::EmbeddedWindow::setWindow(Window* win) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void Window::EmbeddedWindow::updateSizeFromWindow() {
|
||||
setSize(_window->getSize());
|
||||
|
||||
if(_parent) _parent->resize();
|
||||
}
|
||||
|
||||
Window::Window(const std::string& name):
|
||||
_parent (0),
|
||||
_wm (0),
|
||||
_index (0),
|
||||
_x (0.0f),
|
||||
_y (0.0f),
|
||||
_z (0.0f),
|
||||
_zRange (0.0f),
|
||||
_strata (STRATA_NONE),
|
||||
_vis (VM_FULL),
|
||||
_r (0.0f),
|
||||
_s (1.0f),
|
||||
_scaleDenom (100.0f),
|
||||
_vAnchor (VA_NONE),
|
||||
_hAnchor (HA_NONE) {
|
||||
_parent (0),
|
||||
_wm (0),
|
||||
_index (0),
|
||||
_x (0.0f),
|
||||
_y (0.0f),
|
||||
_z (0.0f),
|
||||
_zRange (0.0f),
|
||||
_strata (STRATA_NONE),
|
||||
_vis (VM_FULL),
|
||||
_r (0.0f),
|
||||
_s (1.0f),
|
||||
_scaleDenom (100.0f),
|
||||
_vAnchor (VA_NONE),
|
||||
_hAnchor (HA_NONE) {
|
||||
_name = name.size() ? name : generateRandomName("Window");
|
||||
|
||||
// TODO: Fix the "bg" name.
|
||||
@ -146,7 +157,7 @@ _hAnchor (HA_NONE) {
|
||||
Widget* bg = new Widget(name + "bg", 0.0f, 0.0f);
|
||||
|
||||
bg->setLayer(Widget::LAYER_BG);
|
||||
bg->setColor(0.0f, 0.0f, 0.0f, 0.5f);
|
||||
bg->setColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
_setParented(bg);
|
||||
|
||||
@ -201,7 +212,14 @@ _visibleArea (window._visibleArea) {
|
||||
for(unsigned int i = 1; i < geode->getNumDrawables(); i++) {
|
||||
Widget* widget = dynamic_cast<Widget*>(geode->getDrawable(i));
|
||||
|
||||
if(!widget || !widget->canClone()) continue;
|
||||
if(!widget) continue;
|
||||
|
||||
// TODO: Properly test this...
|
||||
if(!widget->canClone()) {
|
||||
// geode->removeDrawable(widget);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
_setParented(widget);
|
||||
|
||||
@ -286,22 +304,11 @@ bool Window::resizePercent(point_type width, point_type height) {
|
||||
}
|
||||
|
||||
void Window::update() {
|
||||
// Update all embedded children; the zRange values continue to decrease in precision
|
||||
// as you add more and more embedded Windows.
|
||||
WindowList wl;
|
||||
|
||||
getEmbeddedList(wl);
|
||||
|
||||
// Each child Window gets half the zRange of it's parent Window. This means the more
|
||||
// you embed Windows into other Windows, the less depth precision you're going to have.
|
||||
for(WindowList::iterator w = wl.begin(); w != wl.end(); w++) {
|
||||
Window* win = w->get();
|
||||
|
||||
win->_z = _zRange / 2.0f;
|
||||
win->_zRange = _zRange / 2.0f;
|
||||
|
||||
win->update();
|
||||
}
|
||||
for(WindowList::iterator w = wl.begin(); w != wl.end(); w++) w->get()->update();
|
||||
|
||||
matrix_type x = _x;
|
||||
matrix_type y = _y;
|
||||
@ -319,6 +326,42 @@ void Window::update() {
|
||||
|
||||
xy.set(x, y);
|
||||
}
|
||||
|
||||
matrix_type z = _z;
|
||||
|
||||
// We can't do proper scissoring until we have access to our parent WindowManager, and
|
||||
// we need to determine the sorting method we want to use.
|
||||
if(_wm) {
|
||||
if(_wm->isUsingRenderBins()) {
|
||||
getOrCreateStateSet()->setRenderBinDetails(
|
||||
static_cast<int>((1.0f - fabs(_z)) * OSGWIDGET_RENDERBIN_MOD),
|
||||
"RenderBin"
|
||||
);
|
||||
|
||||
z = 0.0f;
|
||||
}
|
||||
|
||||
int sx = static_cast<int>(xy.x());
|
||||
int sy = static_cast<int>(xy.y());
|
||||
int sw = static_cast<int>(_width.current);
|
||||
int sh = static_cast<int>(_height.current);
|
||||
|
||||
// This sets the Scissor area to some offset defined by the user.
|
||||
if(_vis == VM_PARTIAL) {
|
||||
sw = static_cast<int>(_visibleArea[2]);
|
||||
sh = static_cast<int>(_visibleArea[3]);
|
||||
}
|
||||
|
||||
// Otherwise, use the size of the WindowManager itself.
|
||||
else if(_vis == VM_ENTIRE) {
|
||||
sx = 0;
|
||||
sy = 0;
|
||||
sw = static_cast<int>(_wm->getWidth());
|
||||
sh = static_cast<int>(_wm->getHeight());
|
||||
}
|
||||
|
||||
_scissor()->setScissor(sx, sy, sw, sh);
|
||||
}
|
||||
|
||||
// Update the Window itself, setting it's matrix according to translate, rotate, and
|
||||
// scale values.
|
||||
@ -326,47 +369,11 @@ void Window::update() {
|
||||
osg::DegreesToRadians(_r),
|
||||
osg::Vec3d(0.0f, 0.0f, 1.0f)
|
||||
);
|
||||
|
||||
|
||||
osg::Matrix s = osg::Matrix::scale(_s, _s, 1.0f);
|
||||
osg::Matrix t = osg::Matrix::translate(x - _visibleArea[0], y - _visibleArea[1], _z);
|
||||
osg::Matrix t = osg::Matrix::translate(x - _visibleArea[0], y - _visibleArea[1], z);
|
||||
|
||||
setMatrix(r * s * t);
|
||||
|
||||
// We can't do proper scissoring until we have access to our parent WindowManager.
|
||||
if(_wm) {
|
||||
int x = static_cast<int>(xy.x());
|
||||
int y = static_cast<int>(xy.y());
|
||||
int w = static_cast<int>(_width.current);
|
||||
int h = static_cast<int>(_height.current);
|
||||
int wmh = static_cast<int>(_wm->getHeight());
|
||||
int nx = x;
|
||||
int ny = y;
|
||||
int nw = w;
|
||||
int nh = h;
|
||||
|
||||
// This sets the Scissor area to the full size of the Window.
|
||||
if(_vis == VM_FULL && _wm->isInvertedY()) ny = wmh - h - y;
|
||||
|
||||
// This sets the Scissor area to some offset defined by the user.
|
||||
else if(_vis == VM_PARTIAL) {
|
||||
if(_wm->isInvertedY()) ny = wmh - y - static_cast<int>(_visibleArea[3]);
|
||||
|
||||
// else ny = static_cast<int>(_visibleArea[3]);
|
||||
|
||||
nw = static_cast<int>(_visibleArea[2]);
|
||||
nh = static_cast<int>(_visibleArea[3]);
|
||||
}
|
||||
|
||||
// Otherwise, use the size of the WindowManager itself.
|
||||
else {
|
||||
nx = 0;
|
||||
ny = 0;
|
||||
nw = static_cast<int>(_wm->getWidth());
|
||||
nh = wmh;
|
||||
}
|
||||
|
||||
_scissor()->setScissor(nx, ny, nw, nh);
|
||||
}
|
||||
}
|
||||
|
||||
void Window::_setWidthAndHeightUnknownSizeError(const std::string& size, point_type val) {
|
||||
@ -526,9 +533,9 @@ void Window::_setParented(Widget* widget, bool setUnparented) {
|
||||
}
|
||||
|
||||
else {
|
||||
widget->_parent = 0;
|
||||
|
||||
widget->unparented(this);
|
||||
|
||||
widget->_parent = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -639,6 +646,7 @@ void Window::addVisibleArea(int x, int y, int w, int h) {
|
||||
_visibleArea[3] += h;
|
||||
}
|
||||
|
||||
// The topmost Window always has this method called, instead of the embedded window directly.
|
||||
bool Window::setFocused(const Widget* widget) {
|
||||
// TODO: I've turned on the warn() here, but perhaps I shouldn't? I need to define
|
||||
// the conditions under which it's okay to call setFocus() with a NULL widget.
|
||||
@ -650,7 +658,28 @@ bool Window::setFocused(const Widget* widget) {
|
||||
|
||||
ConstIterator i = std::find(begin(), end(), widget);
|
||||
|
||||
bool found = false;
|
||||
|
||||
if(i == end()) {
|
||||
// We couldn't find the widget in the toplevel, so lets see if one of our
|
||||
// EmbeddedWindow objects has it.
|
||||
WindowList wl;
|
||||
|
||||
getEmbeddedList(wl);
|
||||
|
||||
for(WindowList::iterator w = wl.begin(); w != wl.end(); w++) {
|
||||
ConstIterator ii = std::find(w->get()->begin(), w->get()->end(), widget);
|
||||
|
||||
if(ii != w->get()->end()) {
|
||||
found = true;
|
||||
i = ii;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else found = true;
|
||||
|
||||
if(!found) {
|
||||
warn()
|
||||
<< "Window [" << _name
|
||||
<< "] couldn't find the Widget [" << widget->getName()
|
||||
@ -666,9 +695,31 @@ bool Window::setFocused(const Widget* widget) {
|
||||
}
|
||||
|
||||
bool Window::setFocused(const std::string& name) {
|
||||
Widget* w = getByName(name);
|
||||
Widget* w1 = getByName(name);
|
||||
|
||||
if(!w) {
|
||||
bool found = false;
|
||||
|
||||
if(!w1) {
|
||||
// Just like above, we couldn't find the widget in the toplevel, so lets see if
|
||||
// one of our EmbeddedWindow objects has it. The difference here is that we
|
||||
// search by name.
|
||||
WindowList wl;
|
||||
|
||||
getEmbeddedList(wl);
|
||||
|
||||
for(WindowList::iterator w = wl.begin(); w != wl.end(); w++) {
|
||||
Widget* w2 = w->get()->getByName(name);
|
||||
|
||||
if(w2) {
|
||||
found = true;
|
||||
w1 = w2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else found = true;
|
||||
|
||||
if(!found) {
|
||||
warn()
|
||||
<< "Window [" << _name
|
||||
<< "] couldn't find a Widget named [" << name
|
||||
@ -678,11 +729,17 @@ bool Window::setFocused(const std::string& name) {
|
||||
return false;
|
||||
}
|
||||
|
||||
_setFocused(w);
|
||||
_setFocused(w1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Window::grabFocus() {
|
||||
if(!_wm) return false;
|
||||
|
||||
return _wm->setFocused(this);
|
||||
}
|
||||
|
||||
bool Window::setFirstFocusable() {
|
||||
WidgetList focusList;
|
||||
|
||||
@ -724,8 +781,6 @@ XYCoord Window::localXY(double absx, double absy) const {
|
||||
double x = absx - xy.x();
|
||||
double y = absy - xy.y();
|
||||
|
||||
if(_wm && _wm->isInvertedY()) y = (_wm->getHeight() - absy) - xy.y();
|
||||
|
||||
return XYCoord(x + _visibleArea[0], y + _visibleArea[1]);
|
||||
}
|
||||
|
||||
@ -746,13 +801,21 @@ XYCoord Window::getAbsoluteOrigin() const {
|
||||
return xy;
|
||||
}
|
||||
|
||||
Window::EmbeddedWindow* Window::embed() {
|
||||
EmbeddedWindow* ew = new EmbeddedWindow(_name + "Embedded", getWidth(), getHeight());
|
||||
Window::EmbeddedWindow* Window::embed(
|
||||
const std::string& newName,
|
||||
Widget::Layer layer,
|
||||
unsigned int layerOffset
|
||||
) {
|
||||
EmbeddedWindow* ew = new EmbeddedWindow(
|
||||
newName.size() > 0 ? newName : _name + "Embedded",
|
||||
getWidth(),
|
||||
getHeight()
|
||||
);
|
||||
|
||||
ew->setWindow(this);
|
||||
ew->setSize(getWidth(), getHeight());
|
||||
ew->setMinimumSize(getMinWidth(), getMinHeight());
|
||||
ew->setCanFill(true);
|
||||
ew->setLayer(layer, layerOffset);
|
||||
|
||||
return ew;
|
||||
}
|
||||
@ -779,7 +842,11 @@ bool Window::getEmbeddedList(WindowList& wl) const {
|
||||
|
||||
if(!ew || !ew->getWindow()) continue;
|
||||
|
||||
wl.push_back(ew->getWindow());
|
||||
else {
|
||||
wl.push_back(ew->getWindow());
|
||||
|
||||
ew->getWindow()->getEmbeddedList(wl);
|
||||
}
|
||||
}
|
||||
|
||||
return wl.size() != 0;
|
||||
@ -852,6 +919,12 @@ unsigned int Window::addDrawableAndGetIndex(osg::Drawable* drawable) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int Window::addChildAndGetIndex(osg::Node* node) {
|
||||
if(addChild(node)) return getChildIndex(node);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// All of the subsequent functions are very boring and uninteresting, although hopefully
|
||||
// self-explanatory. They simply wrap calls to _compare<>() with the proper templates, and
|
||||
// forward the optional iteration ranges...
|
||||
@ -945,7 +1018,7 @@ Window::Sizes Window::_getWidthImplementation() const {
|
||||
|
||||
point_type w = osg::round(bb.xMax() - bb.xMin());
|
||||
|
||||
return Sizes(w, w);
|
||||
return Sizes(w, 0.0f);
|
||||
}
|
||||
|
||||
Window::Sizes Window::_getHeightImplementation() const {
|
||||
@ -953,7 +1026,7 @@ Window::Sizes Window::_getHeightImplementation() const {
|
||||
|
||||
point_type h = osg::round(bb.yMax() - bb.yMin());
|
||||
|
||||
return Sizes(h, h);
|
||||
return Sizes(h, 0.0f);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -23,8 +23,8 @@ WindowManager::WindowManager(
|
||||
):
|
||||
_width (width),
|
||||
_height (height),
|
||||
_zNear (0.0f),
|
||||
_zFar (-1.0f),
|
||||
_windowWidth (width),
|
||||
_windowHeight (height),
|
||||
_numForeground (0.0f),
|
||||
_numBackground (0.0f),
|
||||
_flags (flags),
|
||||
@ -56,6 +56,8 @@ _styleManager (new StyleManager()) {
|
||||
if(!_python->initialize()) warn() << "Error creating PythonEngine." << std::endl;
|
||||
}
|
||||
|
||||
if(_flags & WM_USE_RENDERBINS) getOrCreateStateSet()->setMode(GL_DEPTH_TEST, false);
|
||||
|
||||
// Setup our picking debug (is debug the right word here?) Window...
|
||||
if(_flags & WM_PICK_DEBUG) {
|
||||
_pickWindow = new Box("PickWindow", Box::VERTICAL);
|
||||
@ -79,28 +81,11 @@ _styleManager (new StyleManager()) {
|
||||
_updatePickWindow(0, 0, 0);
|
||||
}
|
||||
|
||||
if(!(_flags & WM_NO_BETA_WARN)) {
|
||||
Box* box = new Box("BetaWarningBox", Box::VERTICAL);
|
||||
Label* label = new Label("BetaWarning");
|
||||
|
||||
label->setFontSize(15);
|
||||
label->setFontColor(0.0f, 0.0f, 1.0f, 1.0f);
|
||||
label->setFont("fonts/arial.ttf");
|
||||
label->setPadding(5.0f);
|
||||
label->setCanFill(true);
|
||||
label->setLabel("This is BETA software! Please see: http://osgwidget.googlecode.com");
|
||||
|
||||
box->getBackground()->setColor(1.0f, 0.7f, 0.0f, 1.0f);
|
||||
box->addWidget(label);
|
||||
box->setNodeMask(~_nodeMask);
|
||||
box->removeEventMask(EVENT_MASK_FOCUS);
|
||||
box->setStrata(Window::STRATA_BACKGROUND);
|
||||
box->setOrigin(0.0f, 0.0f);
|
||||
|
||||
addChild(box);
|
||||
|
||||
box->resizePercent(100.0f, 0.0f);
|
||||
}
|
||||
getOrCreateStateSet()->setMode(
|
||||
GL_BLEND,
|
||||
osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE
|
||||
);
|
||||
getOrCreateStateSet()->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
|
||||
}
|
||||
|
||||
WindowManager::WindowManager(const WindowManager& wm, const osg::CopyOp& co):
|
||||
@ -140,7 +125,8 @@ bool WindowManager::_handleMousePushed(float x, float y, bool& down) {
|
||||
|
||||
if(!_lastPush) return false;
|
||||
|
||||
bool handled = _lastPush->callMethodAndCallbacks(ev);
|
||||
// TODO: This is the old way; it didn't allow Event handler code to call grabFocus().
|
||||
// bool handled = _lastPush->callMethodAndCallbacks(ev);
|
||||
|
||||
if(_focusMode != PFM_SLOPPY) {
|
||||
if(ev._window) {
|
||||
@ -155,7 +141,7 @@ bool WindowManager::_handleMousePushed(float x, float y, bool& down) {
|
||||
else if(_focusMode == PFM_UNFOCUS) setFocused(0);
|
||||
}
|
||||
|
||||
return handled;
|
||||
return _lastPush->callMethodAndCallbacks(ev);
|
||||
}
|
||||
|
||||
bool WindowManager::_handleMouseReleased(float x, float y, bool& down) {
|
||||
@ -181,10 +167,7 @@ bool WindowManager::_handleMouseReleased(float x, float y, bool& down) {
|
||||
|
||||
void WindowManager::_getPointerXYDiff(float& x, float& y) {
|
||||
x -= _lastX;
|
||||
|
||||
if(isInvertedY()) y = -(y - _lastY);
|
||||
|
||||
else y -= _lastY;
|
||||
y -= _lastY;
|
||||
}
|
||||
|
||||
void WindowManager::_updatePickWindow(const WidgetList* wl, point_type x, point_type y) {
|
||||
@ -299,9 +282,10 @@ bool WindowManager::pickAtXY(float x, float y, WidgetList& wl) {
|
||||
|
||||
// Make sure that our window is valid, and that our pick is within the
|
||||
// "visible area" of the Window.
|
||||
if(!win ||
|
||||
(win->getVisibilityMode()==Window::VM_PARTIAL && !win->isPointerXYWithinVisible(x, y)))
|
||||
{
|
||||
if(
|
||||
!win ||
|
||||
(win->getVisibilityMode() == Window::VM_PARTIAL && !win->isPointerXYWithinVisible(x, y))
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -334,6 +318,49 @@ bool WindowManager::pickAtXY(float x, float y, WidgetList& wl) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
bool WindowManager::pickAtXY(float x, float y, WidgetList& wl) {
|
||||
Intersections intr;
|
||||
|
||||
if(!_view->computeIntersections(x, y, intr, _nodeMask)) return false;
|
||||
|
||||
typedef std::vector<osg::observer_ptr<Window> > WindowVector;
|
||||
|
||||
WindowVector windows;
|
||||
|
||||
Window* activeWin = 0;
|
||||
|
||||
for(Intersections::iterator i = intr.begin(); i != intr.end(); i++) {
|
||||
Window* win = dynamic_cast<Window*>(i->nodePath.back()->getParent(0));
|
||||
|
||||
if(
|
||||
!win ||
|
||||
(win->getVisibilityMode() == Window::VM_PARTIAL && !win->isPointerXYWithinVisible(x, y))
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(activeWin != win) {
|
||||
activeWin = win;
|
||||
|
||||
windows.push_back(win);
|
||||
}
|
||||
}
|
||||
|
||||
if(!windows.size()) return false;
|
||||
|
||||
std::sort(windows.begin(), windows.end(), WindowBinNumberCompare());
|
||||
|
||||
for(WindowVector::iterator i = windows.begin(); i != windows.end(); i++) {
|
||||
warn() << "- " << i->get()->getName() << " " << i->get()->getOrCreateStateSet()->getBinNumber() << std::endl;
|
||||
}
|
||||
|
||||
warn() << std::endl;
|
||||
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
|
||||
bool WindowManager::setFocused(Window* window) {
|
||||
Event ev(this);
|
||||
|
||||
@ -371,7 +398,7 @@ bool WindowManager::setFocused(Window* window) {
|
||||
// the Z space allocated to it so that it can properly arrange it's children. We
|
||||
// add 2 additional Windows here for anything that should appear in the background
|
||||
// and foreground areas.
|
||||
matrix_type zRange = (_zNear - _zFar) / (focusable.size() + 2.0f);
|
||||
matrix_type zRange = 1.0f / (focusable.size() + 2.0f);
|
||||
|
||||
// Our offset for the following for() loop.
|
||||
unsigned int i = 3;
|
||||
@ -457,6 +484,16 @@ void WindowManager::resizeAllWindows(bool visible) {
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the application window coordinates of the WindowManager XY position.
|
||||
XYCoord WindowManager::windowXY(double x, double y) const {
|
||||
return XYCoord((_windowWidth / _width) * x, (_windowHeight / _height) * y);
|
||||
}
|
||||
|
||||
// Returns the WindowManager coordinates of the application window XY position.
|
||||
XYCoord WindowManager::localXY(double x, double y) const {
|
||||
return XYCoord((_width / _windowWidth) * x, (_height / _windowHeight) * y);
|
||||
}
|
||||
|
||||
// This is called by a ViewerEventHandler/MouseHandler (or whatever) as the pointer moves
|
||||
// around and intersects with objects. It also resets our state data (_widget, _leftDown,
|
||||
// etc.) The return value of this method is mostly useless.
|
||||
@ -574,11 +611,7 @@ bool WindowManager::keyUp(int key, int mask) {
|
||||
// A convenience wrapper for creating a proper orthographic camera using the current
|
||||
// width and height.
|
||||
osg::Camera* WindowManager::createParentOrthoCamera() {
|
||||
osg::Camera* camera = 0;
|
||||
|
||||
if(isInvertedY()) camera = createInvertedYOrthoCamera(_width, _height);
|
||||
|
||||
else camera = createOrthoCamera(_width, _height);
|
||||
osg::Camera* camera = createOrthoCamera(_width, _height);
|
||||
|
||||
camera->addChild(this);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user