Canvas GUI: refactor and simplify based on canvas::Group
This commit is contained in:
parent
acddd0b0cf
commit
4f129a283b
4 changed files with 101 additions and 126 deletions
|
@ -34,6 +34,7 @@
|
|||
#include <osgGA/GUIEventHandler>
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
/**
|
||||
* Event handler
|
||||
|
@ -83,8 +84,8 @@ class WindowPlacement:
|
|||
canvas::WindowPtr window = _window.lock();
|
||||
simgear::canvas::CanvasPtr canvas = _canvas.lock();
|
||||
|
||||
if( window && canvas && canvas == window->getCanvas().lock() )
|
||||
window->setCanvas( simgear::canvas::CanvasPtr() );
|
||||
if( window && canvas && canvas == window->getCanvasContent().lock() )
|
||||
window->setCanvasContent( simgear::canvas::CanvasPtr() );
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -92,36 +93,31 @@ class WindowPlacement:
|
|||
simgear::canvas::CanvasWeakPtr _canvas;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
typedef boost::shared_ptr<canvas::Window> WindowPtr;
|
||||
WindowPtr windowFactory(SGPropertyNode* node)
|
||||
{
|
||||
return WindowPtr(new canvas::Window(node));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
GUIMgr::GUIMgr():
|
||||
PropertyBasedMgr( fgGetNode("/sim/gui/canvas", true),
|
||||
"window",
|
||||
&windowFactory ),
|
||||
Group(simgear::canvas::CanvasPtr(), fgGetNode("/sim/gui/canvas", true)),
|
||||
_event_handler( new GUIEventHandler(this) ),
|
||||
_transform( new osg::MatrixTransform ),
|
||||
_cb_mouse_mode( this,
|
||||
&GUIMgr::handleMouseMode,
|
||||
fgGetNode("/devices/status/mice/mouse[0]/mode") ),
|
||||
_handle_events(true),
|
||||
_width(_props, "size[0]"),
|
||||
_height(_props, "size[1]"),
|
||||
_width(_node, "size[0]"),
|
||||
_height(_node, "size[1]"),
|
||||
_resize(canvas::Window::NONE),
|
||||
_last_cursor(MOUSE_CURSOR_NONE),
|
||||
_last_x(-1),
|
||||
_last_y(-1),
|
||||
_last_scroll_time(0)
|
||||
{
|
||||
// We handle the property listener manually within ::init and ::shutdown.
|
||||
removeListener();
|
||||
|
||||
_width = _height = -1;
|
||||
|
||||
osg::Camera* camera =
|
||||
flightgear::getGUICamera( flightgear::CameraGroup::getDefault() );
|
||||
assert(camera);
|
||||
camera->addChild(_transform);
|
||||
camera->addChild( getMatrixTransform() );
|
||||
|
||||
simgear::canvas::Canvas::addPlacementFactory
|
||||
(
|
||||
|
@ -148,7 +144,14 @@ GUIMgr::GUIMgr():
|
|||
//------------------------------------------------------------------------------
|
||||
canvas::WindowPtr GUIMgr::createWindow(const std::string& name)
|
||||
{
|
||||
return boost::static_pointer_cast<canvas::Window>( createElement(name) );
|
||||
canvas::WindowPtr window = createChild<canvas::Window>(name);
|
||||
if( name.empty() )
|
||||
window->set<std::string>
|
||||
(
|
||||
"id",
|
||||
boost::lexical_cast<std::string>(window->getProps()->getIndex())
|
||||
);
|
||||
return window;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
@ -162,25 +165,32 @@ void GUIMgr::init()
|
|||
fgGetInt("/sim/startup/ysize")
|
||||
);
|
||||
|
||||
PropertyBasedMgr::init();
|
||||
|
||||
globals->get_renderer()
|
||||
->getViewer()
|
||||
->getEventHandlers()
|
||||
// GUI is on top of everything so lets install as first event handler
|
||||
.push_front( _event_handler );
|
||||
|
||||
_node->addChangeListener(this);
|
||||
_node->fireCreatedRecursive();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void GUIMgr::shutdown()
|
||||
{
|
||||
PropertyBasedMgr::shutdown();
|
||||
_node->removeChangeListener(this);
|
||||
|
||||
globals->get_renderer()
|
||||
->getViewer()
|
||||
->removeEventHandler( _event_handler );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void GUIMgr::update(double dt)
|
||||
{
|
||||
Group::update(dt);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool GUIMgr::handleEvent(const osgGA::GUIEventAdapter& ea)
|
||||
{
|
||||
|
@ -206,35 +216,12 @@ bool GUIMgr::handleEvent(const osgGA::GUIEventAdapter& ea)
|
|||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void GUIMgr::elementCreated(simgear::PropertyBasedElementPtr element)
|
||||
GUIMgr::ElementFactory GUIMgr::getChildFactory(const std::string& type) const
|
||||
{
|
||||
canvas::WindowPtr window =
|
||||
boost::static_pointer_cast<canvas::Window>(element);
|
||||
if( type == "window" )
|
||||
return &Element::create<canvas::Window>;
|
||||
|
||||
size_t layer_index = std::max(0, window->getProps()->getIntValue("layer", 1));
|
||||
osg::Group *layer = 0;
|
||||
|
||||
if( layer_index < _transform->getNumChildren() )
|
||||
{
|
||||
layer = _transform->getChild(layer_index)->asGroup();
|
||||
assert(layer);
|
||||
}
|
||||
else
|
||||
{
|
||||
while( _transform->getNumChildren() <= layer_index )
|
||||
{
|
||||
layer = new osg::Group;
|
||||
_transform->addChild(layer);
|
||||
}
|
||||
}
|
||||
|
||||
layer->addChild(window->getGroup());
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
canvas::WindowPtr GUIMgr::getWindow(size_t i)
|
||||
{
|
||||
return boost::static_pointer_cast<canvas::Window>(_elements[i]);
|
||||
return Group::getChildFactory(type);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
@ -242,19 +229,13 @@ simgear::canvas::Placements
|
|||
GUIMgr::addPlacement( SGPropertyNode* node,
|
||||
simgear::canvas::CanvasPtr canvas )
|
||||
{
|
||||
int placement_index = node->getIntValue("index", -1);
|
||||
const std::string& id = node->getStringValue("id");
|
||||
|
||||
simgear::canvas::Placements placements;
|
||||
for( size_t i = 0; i < _elements.size(); ++i )
|
||||
canvas::WindowPtr window = getChild<canvas::Window>(id);
|
||||
if( window )
|
||||
{
|
||||
if( placement_index >= 0 && static_cast<int>(i) != placement_index )
|
||||
continue;
|
||||
|
||||
canvas::WindowPtr window = getWindow(i);
|
||||
if( !window )
|
||||
continue;
|
||||
|
||||
window->setCanvas(canvas);
|
||||
window->setCanvasContent(canvas);
|
||||
placements.push_back(
|
||||
simgear::canvas::PlacementPtr(new WindowPlacement(node, window, canvas))
|
||||
);
|
||||
|
@ -323,38 +304,28 @@ bool GUIMgr::handleMouse(const osgGA::GUIEventAdapter& ea)
|
|||
canvas::WindowPtr window_at_cursor;
|
||||
for( int i = _transform->getNumChildren() - 1; i >= 0; --i )
|
||||
{
|
||||
osg::Group *layer = _transform->getChild(i)->asGroup();
|
||||
assert(layer);
|
||||
if( !layer->getNumChildren() )
|
||||
osg::Group *element = _transform->getChild(i)->asGroup();
|
||||
|
||||
assert(element);
|
||||
assert(element->getUserData());
|
||||
|
||||
canvas::WindowPtr window =
|
||||
boost::static_pointer_cast<canvas::Window>
|
||||
(
|
||||
static_cast<sc::Element::OSGUserData*>(element->getUserData())->element
|
||||
);
|
||||
|
||||
if( !window->isCapturingEvents() || !window->isVisible() )
|
||||
continue;
|
||||
|
||||
for( int j = layer->getNumChildren() - 1; j >= 0; --j )
|
||||
float margin = window->isResizable() ? resize_margin_pos : 0;
|
||||
if( window->getScreenRegion().contains( event->getScreenX(),
|
||||
event->getScreenY(),
|
||||
margin ) )
|
||||
{
|
||||
assert(layer->getChild(j)->getUserData());
|
||||
canvas::WindowPtr window =
|
||||
boost::static_pointer_cast<canvas::Window>
|
||||
(
|
||||
static_cast<sc::Element::OSGUserData*>
|
||||
(
|
||||
layer->getChild(j)->getUserData()
|
||||
)->element
|
||||
);
|
||||
|
||||
if( !window->isCapturingEvents() || !window->isVisible() )
|
||||
continue;
|
||||
|
||||
float margin = window->isResizable() ? resize_margin_pos : 0;
|
||||
if( window->getScreenRegion().contains( event->getScreenX(),
|
||||
event->getScreenY(),
|
||||
margin ) )
|
||||
{
|
||||
window_at_cursor = window;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( window_at_cursor )
|
||||
window_at_cursor = window;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( window_at_cursor )
|
||||
|
@ -400,7 +371,7 @@ bool GUIMgr::handleMouse(const osgGA::GUIEventAdapter& ea)
|
|||
if( ea.getEventType() == osgGA::GUIEventAdapter::PUSH )
|
||||
{
|
||||
_resize_window = window_at_cursor;
|
||||
window_at_cursor->doRaise();
|
||||
window_at_cursor->raise();
|
||||
window_at_cursor->handleResize( _resize | canvas::Window::INIT,
|
||||
event->delta );
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "canvas_fwd.hpp"
|
||||
|
||||
#include <simgear/canvas/canvas_fwd.hxx>
|
||||
#include <simgear/canvas/elements/CanvasGroup.hxx>
|
||||
#include <simgear/props/PropertyBasedMgr.hxx>
|
||||
#include <simgear/props/propertyObject.hxx>
|
||||
|
||||
|
@ -36,7 +37,8 @@ namespace osgGA
|
|||
|
||||
class GUIEventHandler;
|
||||
class GUIMgr:
|
||||
public simgear::PropertyBasedMgr
|
||||
public simgear::canvas::Group,
|
||||
public SGSubsystem
|
||||
{
|
||||
public:
|
||||
GUIMgr();
|
||||
|
@ -46,12 +48,15 @@ class GUIMgr:
|
|||
virtual void init();
|
||||
virtual void shutdown();
|
||||
|
||||
virtual void update(double dt);
|
||||
|
||||
bool handleEvent(const osgGA::GUIEventAdapter& ea);
|
||||
|
||||
protected:
|
||||
|
||||
typedef simgear::canvas::ElementFactory ElementFactory;
|
||||
|
||||
osg::ref_ptr<GUIEventHandler> _event_handler;
|
||||
osg::ref_ptr<osg::MatrixTransform> _transform;
|
||||
SGPropertyChangeCallback<GUIMgr> _cb_mouse_mode;
|
||||
bool _handle_events;
|
||||
|
||||
|
@ -68,9 +73,8 @@ class GUIMgr:
|
|||
_last_y;
|
||||
double _last_scroll_time;
|
||||
|
||||
virtual void elementCreated(simgear::PropertyBasedElementPtr element);
|
||||
virtual ElementFactory getChildFactory(const std::string& type) const;
|
||||
|
||||
canvas::WindowPtr getWindow(size_t i);
|
||||
simgear::canvas::Placements
|
||||
addPlacement(SGPropertyNode*, simgear::canvas::CanvasPtr canvas);
|
||||
|
||||
|
|
|
@ -32,8 +32,14 @@ namespace canvas
|
|||
namespace sc = simgear::canvas;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
Window::Window(SGPropertyNode* node):
|
||||
Image(sc::CanvasPtr(), node),
|
||||
const std::string Window::TYPE_NAME = "window";
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
Window::Window( const simgear::canvas::CanvasWeakPtr& canvas,
|
||||
const SGPropertyNode_ptr& node,
|
||||
const Style& parent_style,
|
||||
Element* parent ):
|
||||
Image(canvas, node, parent_style, parent),
|
||||
_attributes_dirty(0),
|
||||
_resizable(false),
|
||||
_capture_events(true),
|
||||
|
@ -75,9 +81,7 @@ namespace canvas
|
|||
{
|
||||
handled = true;
|
||||
const std::string& name = node->getNameString();
|
||||
if( name == "raise-top" )
|
||||
doRaise(node);
|
||||
else if( name == "resize" )
|
||||
if( name == "resize" )
|
||||
_resizable = node->getBoolValue();
|
||||
else if( name == "update" )
|
||||
update(0);
|
||||
|
@ -115,16 +119,16 @@ namespace canvas
|
|||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void Window::setCanvas(sc::CanvasPtr canvas)
|
||||
void Window::setCanvasContent(sc::CanvasPtr canvas)
|
||||
{
|
||||
_canvas_content = canvas;
|
||||
setSrcCanvas(canvas);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
sc::CanvasWeakPtr Window::getCanvas() const
|
||||
sc::CanvasWeakPtr Window::getCanvasContent() const
|
||||
{
|
||||
return getSrcCanvas();
|
||||
return _canvas_content;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -145,6 +149,14 @@ namespace canvas
|
|||
return _capture_events;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void Window::raise()
|
||||
{
|
||||
// on writing the z-index the window always is moved to the top of all other
|
||||
// windows with the same z-index.
|
||||
set<int>("z-index", get<int>("z-index", 0));
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void Window::handleResize(uint8_t mode, const osg::Vec2f& delta)
|
||||
{
|
||||
|
@ -173,29 +185,6 @@ namespace canvas
|
|||
_resize_left += delta.x();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void Window::doRaise(SGPropertyNode* node_raise)
|
||||
{
|
||||
if( node_raise && !node_raise->getBoolValue() )
|
||||
return;
|
||||
|
||||
// Keep a reference to ensure the window is not deleted between removing and
|
||||
// adding it back to the scenegraph
|
||||
osg::ref_ptr<osg::Group> window = getGroup();
|
||||
|
||||
BOOST_FOREACH(osg::Group* parent, getGroup()->getParents())
|
||||
{
|
||||
// Remove window...
|
||||
parent->removeChild(window);
|
||||
|
||||
// ...and add again as topmost window
|
||||
parent->addChild(window);
|
||||
}
|
||||
|
||||
if( node_raise )
|
||||
node_raise->setBoolValue(false);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void Window::parseDecorationBorder(const std::string& str)
|
||||
{
|
||||
|
|
|
@ -34,6 +34,7 @@ namespace canvas
|
|||
public simgear::canvas::Image
|
||||
{
|
||||
public:
|
||||
static const std::string TYPE_NAME;
|
||||
|
||||
enum Resize
|
||||
{
|
||||
|
@ -45,7 +46,12 @@ namespace canvas
|
|||
INIT = BOTTOM << 1
|
||||
};
|
||||
|
||||
Window(SGPropertyNode* node);
|
||||
typedef simgear::canvas::Style Style;
|
||||
|
||||
Window( const simgear::canvas::CanvasWeakPtr& canvas,
|
||||
const SGPropertyNode_ptr& node,
|
||||
const Style& parent_style = Style(),
|
||||
Element* parent = 0 );
|
||||
virtual ~Window();
|
||||
|
||||
virtual void update(double delta_time_sec);
|
||||
|
@ -55,17 +61,22 @@ namespace canvas
|
|||
const SGVec2<float> getPosition() const;
|
||||
const SGRect<float> getScreenRegion() const;
|
||||
|
||||
void setCanvas(simgear::canvas::CanvasPtr canvas);
|
||||
simgear::canvas::CanvasWeakPtr getCanvas() const;
|
||||
void setCanvasContent(simgear::canvas::CanvasPtr canvas);
|
||||
simgear::canvas::CanvasWeakPtr getCanvasContent() const;
|
||||
|
||||
simgear::canvas::CanvasPtr getCanvasDecoration();
|
||||
|
||||
bool isResizable() const;
|
||||
bool isCapturingEvents() const;
|
||||
|
||||
void handleResize(uint8_t mode, const osg::Vec2f& delta = osg::Vec2f());
|
||||
/**
|
||||
* Moves window on top of all other windows with the same z-index.
|
||||
*
|
||||
* @note If no z-index is set it defaults to 0.
|
||||
*/
|
||||
void raise();
|
||||
|
||||
void doRaise(SGPropertyNode* node_raise = 0);
|
||||
void handleResize(uint8_t mode, const osg::Vec2f& delta = osg::Vec2f());
|
||||
|
||||
protected:
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue