From Jeremy Moles, updates to osgWidget

Merged my Robert Osfield from OpenSceneGraph-osgWidget-dev.
This commit is contained in:
Robert Osfield 2008-11-28 14:35:33 +00:00
parent d3b2d9b074
commit 9748fdd605
35 changed files with 1234 additions and 639 deletions

View File

@ -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);
META_Object(osgWidget, Box);
Box (const std::string& = "", BOX_TYPE = HORIZONTAL, bool = false);
//! 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;
};
}

View File

@ -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:

View File

@ -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,12 +202,18 @@ 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(0) {}
Callback(const Callback& rhs): osg::Referenced(rhs), _type(rhs._type), _data(rhs._data), _callback(rhs._callback) {}
Callback():_type(EVENT_NONE),_data(0) {}
Callback(const Callback& 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>
@ -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,6 +250,7 @@ class OSGWIDGET_EXPORT Callback
const void* getData() const {
return _data;
}
protected:
EventType _type;
void* _data;
@ -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;

View File

@ -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

View File

@ -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,
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,
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,
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;
};
}

View File

@ -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;

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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);
// 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*);
}

View File

@ -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

View File

@ -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;
};
}

View File

@ -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
@ -48,10 +47,10 @@ public:
};
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)
);
}

View File

@ -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;

View File

@ -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
@ -42,9 +41,8 @@ class OSGWIDGET_EXPORT WindowManager: public osg::Switch, public UIObjectParent<
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_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;

View File

@ -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),

View File

@ -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)) {
if(!widget) return false;
widget->setOrigin(x, y);
return true;
}
return false;
return Window::addWidget(widget);
}
}

View File

@ -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,41 +30,32 @@ 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);
}
}
// 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);
}
@ -75,42 +69,91 @@ bool Frame::Corner::mouseDrag(double x, double y, WindowManager* wm) {
else {
if(parent->resizeAdd(-x, -y)) parent->addOrigin(x, y);
}
}
parent->update();
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;
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 {
point_type tx1 = (w * 7) / image->s();
point_type tx2 = (w * 6) / 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);
}
}
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 {
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(_border == BORDER_TOP) parent->addOrigin(x, y);
else {
// The only BORDER that inverted-Y affects is this...
if(wm->isInvertedY()) parent->resizeAdd(0.0f, y);
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 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_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_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();
}
}

View File

@ -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;
std::ostream& os = warn() << "_offsets[ ";
osg::Vec3 pos = _text->getPosition();
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] = lr.x() - pos.x();
_offsets[i] = accum;
os << _offsets[i] << " (" << static_cast<char>(_text->getText()[i]) << ") ";
// 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;
}
}

View File

@ -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,28 +69,11 @@ 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;
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());
point_type y = osg::round(((getHeight() - size.y()) / 2.0f) + getY());
point_type z = _calculateZ(getLayer() + 1);
// These values are permisable with CENTER_CENTER mode is active.
// point_type x = round(getX() + (getWidth() / 2.0f));
@ -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) {

View File

@ -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>

View File

@ -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);

View File

@ -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>

View File

@ -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>

View File

@ -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");

View File

@ -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)
);
else _camera->setProjectionMatrix(osg::Matrix::ortho2D(0.0f, w, 0.0f, h));
if(_camera.valid()) {
_camera->setProjectionMatrix(osg::Matrix::ortho2D(0.0f, w, 0.0f, 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;
}
}

View File

@ -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::Texture* texture = _texture();
if(!image || !texture || image->s() == 0.0f) return;
@ -295,7 +294,7 @@ void Widget::setTexCoordWrapHorizontal() {
void Widget::setTexCoordWrapVertical() {
osg::Image* image = _image();
osg::Texture2D* texture = _texture();
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;
if(useTextRect) texture = new osg::TextureRectangle();
else texture = new osg::Texture2D();
if(!texture) return false;
texture->setDataVariance(osg::Object::DYNAMIC);
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 {

View File

@ -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,6 +129,12 @@ 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),
@ -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;
@ -320,6 +327,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.
osg::Matrix r = osg::Matrix::rotate(
@ -328,45 +371,9 @@ void Window::update() {
);
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;
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);
}
}

View File

@ -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);