25#include <simgear/canvas/Canvas.hxx>
26#include <simgear/canvas/CanvasPlacement.hxx>
27#include <simgear/canvas/CanvasWindow.hxx>
28#include <simgear/canvas/events/KeyboardEvent.hxx>
29#include <simgear/scene/util/OsgMath.hxx>
31#include <osg/BlendFunc>
32#include <osgViewer/Viewer>
33#include <osgViewer/View>
34#include <osgGA/GUIEventHandler>
40namespace sc = simgear::canvas;
41using osgEA = osgGA::GUIEventAdapter;
66 public osgGA::GUIEventHandler
72 osgGA::GUIActionAdapter&,
100 sc::WindowPtr window = _window.lock();
101 sc::CanvasPtr
canvas = _canvas.lock();
103 if( window &&
canvas &&
canvas == window->getCanvasContent().lock() )
104 window->setCanvasContent( sc::CanvasPtr() );
108 sc::WindowWeakPtr _window;
109 sc::CanvasWeakPtr _canvas;
163 const sc::WindowPtr& active_window );
168 void finishDrag(
const sc::WindowPtr& drag_src,
const sc::EventPtr& event);
177 if( type ==
"window" )
178 return &Element::create<sc::Window>;
180 return Group::getChildFactory(type);
193 osgGA::GUIActionAdapter&,
197 if( ea.getHandled() )
201 return desktop && desktop->handleOsgEvent(ea);
208 fgGetNode(
"/devices/status/mice/mouse[0]/mode", true)),
212#if !defined(BUILDING_TESTSUITE)
214 SG_LOG(SG_GUI, SG_WARN,
"DesktopGroup: failed to get GUI camera.");
218 camera->addChild(_scene_group.get());
220 osg::StateSet* stateSet = _scene_group->getOrCreateStateSet();
221 stateSet->setDataVariance(osg::Object::STATIC);
222 stateSet->setRenderBinDetails(1000,
"RenderBin");
225 stateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
226 stateSet->setMode(GL_CULL_FACE, osg::StateAttribute::OFF);
228 stateSet->setMode(GL_BLEND, osg::StateAttribute::ON);
229 stateSet->setAttribute(
new osg::BlendFunc(
230 osg::BlendFunc::SRC_ALPHA,
231 osg::BlendFunc::ONE_MINUS_SRC_ALPHA));
259 SG_LOG(SG_GUI, SG_WARN,
"ungrabPointer: no active grab.");
261 SG_LOG(SG_GUI, SG_WARN,
"ungrabPointer: window is not owner of the grab.");
269 for(
int i = _scene_group->getNumChildren() - 1;
i >= 0; --
i )
271 osg::Group *element = _scene_group->getChild(
i)->asGroup();
273 if( !element || !element->getUserData() )
276 sc::WindowPtr window =
277 dynamic_cast<sc::Window*
>
279 static_cast<sc::Element::OSGUserData*
>(
280 element->getUserData()
284 if( !window || !window->isCapturingEvents() || !window->isVisible() )
288 if( window->getScreenRegion().contains( screen_pos.x(),
302 float x = SGMiscf::round(0.5 * (ea.getXnormalized() + 1) *
_width);
303 float y = SGMiscf::round(0.5 * (ea.getYnormalized() + 1) *
_height);
305 if( ea.getMouseYOrientation() != osgEA::Y_INCREASING_DOWNWARDS )
314 switch( ea.getEventType() )
331 ea.getWindowHeight() );
342 && _scene_group.valid()
343 && _scene_group->getNumChildren() > 0;
358 switch( ea.getEventType() )
361 resize_window->handleResize(sc::Window::NONE);
373 sc::MouseEventPtr event(
new sc::MouseEvent(ea));
374 event->screen_pos = mouse_pos;
375 event->delta = delta;
382 if( ea.getEventType() == osgEA::RELEASE )
390 if( !window_at_cursor )
393 if( window_at_cursor )
395 const SGRect<float>& reg = window_at_cursor->getScreenRegion();
397 if( window_at_cursor->isResizable()
398 && !reg.contains( event->getScreenX(),
437 if( ea.getEventType() == osgEA::PUSH )
442 window_at_cursor->raise();
443 window_at_cursor->handleResize(
_resize | sc::Window::INIT);
457 switch( ea.getEventType() )
462 event->type = sc::Event::MOUSE_DOWN;
465 switch( ea.getScrollingMotion() )
467 case osgEA::SCROLL_UP:
468 event->delta.y() = 1;
470 case osgEA::SCROLL_DOWN:
471 event->delta.y() = -1;
481 return window_at_cursor ? true :
false;
484 event->type = sc::Event::WHEEL;
493 if( last_mouse_over && last_mouse_over != window_at_cursor )
494 last_mouse_over->handleEvent(event->clone(sc::Event::MOUSE_LEAVE));
497 event->type = sc::Event::MOUSE_MOVE;
503 if( last_push && last_push != window_at_cursor )
506 last_push->handleEvent(event->clone(sc::Event::MOUSE_LEAVE));
510 event->type = sc::Event::MOUSE_UP;
527 sc::KeyboardEventPtr event(
new sc::KeyboardEvent(ea));
531 if( ea.getKey() == osgEA::KEY_Escape )
539 if( !event->isModifier() )
541 if( event->getType() == sc::Event::KEY_DOWN )
544 event->setRepeat(
true);
557 if( event->getType() == sc::Event::KEY_DOWN
558 && !event->defaultPrevented()
559 && event->isPrint() )
561 handled |=
propagateEvent(event->clone(sc::Event::KEY_PRESS), active_window);
569 const sc::WindowPtr& active_window )
572 ? active_window->handleEvent(event)
583 return event->propagation_stopped;
595 if( _scene_group.valid() )
599 _scene_group->setMatrix(osg::Matrix(
611 event->type = sc::Event::DRAG;
619 drag_window->handleEvent(event->clone(sc::Event::DRAG_START));
623 return drag_window && drag_window->handleEvent(event);
628 const sc::EventPtr& event )
630 drag_src->handleEvent(event->clone(sc::Event::DRAG_END));
640 ->getBoolValue(
"pass-through");
659 sc::WindowPtr window =
_desktop->createChild<sc::Window>(
name);
661 window->set(
"id", std::to_string(window->getProps()->getIndex()));
669 SG_LOG(SG_GUI, SG_WARN,
"GUIMgr::init() already initialized.");
674#if !defined(BUILDING_TESTSUITE)
682 desktop->handleResize(
691#if !defined(BUILDING_TESTSUITE)
697 sc::Canvas::addPlacementFactory(
701 _desktop->getProps()->fireCreatedRecursive();
709 SG_LOG(SG_GUI, SG_WARN,
"GUIMgr::shutdown() not running.");
713 sc::Canvas::removePlacementFactory(
"window");
723#if !defined(BUILDING_TESTSUITE)
767 const std::string&
id = placement->getStringValue(
"id");
769 sc::Placements placements;
770 sc::WindowPtr window =
_desktop->getChild<sc::Window>(id);
773 window->setCanvasContent(
canvas);
774 placements.push_back(
785 SGSubsystemMgr::DISPLAY,
787 {
"viewer", SGSubsystemMgr::Dependency::HARD},
sc::WindowPtr windowAtPosition(const osg::Vec2f &screen_pos)
void setFocusWindow(const sc::WindowPtr &window)
SGPropertyChangeCallback< DesktopGroup > _cb_mouse_mode
osg::Vec2f _last_mouse_pos
sc::WindowWeakPtr _focus_window
FGMouseCursor::Cursor _last_cursor
void handleResize(int x, int y, int width, int height)
bool canHandleInput() const
osg::Vec2f toScreenPos(const osgEA &ea) const
simgear::PropertyObject< int > _width
sc::WindowWeakPtr _last_push
void handleMouseMode(SGPropertyNode *node)
bool handleDrag(const sc::EventPtr &event)
simgear::PropertyObject< int > _height
void ungrabPointer(const sc::WindowPtr &window)
sc::WindowWeakPtr _last_drag
bool handleOsgEvent(const osgEA &ea)
bool propagateRootEvent(const sc::EventPtr &event)
bool propagateEvent(const sc::EventPtr &event, const sc::WindowPtr &active_window)
sc::WindowWeakPtr _pointer_grab_window
void finishDrag(const sc::WindowPtr &drag_src, const sc::EventPtr &event)
bool grabPointer(const sc::WindowPtr &window)
sc::WindowWeakPtr _resize_window
DesktopGroup(osg::Camera *camera)
bool handleKeyboard(const osgEA &ea)
uint32_t _last_key_down_no_mod
bool handleMouse(const osgEA &ea)
sc::WindowWeakPtr _last_mouse_over
sc::ElementFactory getChildFactory(const std::string &type) const
bool handle(const osgEA &ea, osgGA::GUIActionAdapter &, osg::Object *, osg::NodeVisitor *)
GUIEventHandler(const DesktopWeakPtr &desktop_group)
void setInputFocus(const simgear::canvas::WindowPtr &window)
Set the input (keyboard) focus to the given window.
void update(double dt) override
simgear::canvas::WindowPtr createWindow(const std::string &name="")
void setGUIViewAndCamera(osgViewer::View *view, osg::Camera *cam)
specify the osgViewer::View and Camera
osg::ref_ptr< osgViewer::View > _viewerView
simgear::canvas::GroupPtr getDesktop()
Get simgear::canvas::Group containing all windows.
bool grabPointer(const simgear::canvas::WindowPtr &window)
Grabs the pointer so that all events are passed to this window until the pointer is ungrabbed with un...
void ungrabPointer(const simgear::canvas::WindowPtr &window)
Releases the grab acquired for this window with grabPointer().
simgear::canvas::GroupPtr _desktop
osg::ref_ptr< osg::Camera > _camera
osg::ref_ptr< GUIEventHandler > _event_handler
simgear::canvas::Placements addWindowPlacement(SGPropertyNode *placement, simgear::canvas::CanvasPtr canvas)
Track a canvas placement on a window.
WindowPlacement(SGPropertyNode *node, sc::WindowPtr window, sc::CanvasPtr canvas)
virtual ~WindowPlacement()
Remove placement from window.
void fgSetMouseCursor(FGMouseCursor::Cursor cursor)
FGMouseCursor::Cursor fgGetMouseCursor()
int fgGetInt(const char *name, int defaultValue)
Get an int value for a property.
const float RESIZE_MARGIN_NEG
SGSharedPtr< DesktopGroup > DesktopPtr
osgGA::GUIEventAdapter osgEA
SGWeakPtr< DesktopGroup > DesktopWeakPtr
const float RESIZE_MARGIN_POS
const float RESIZE_CORNER
SGSubsystemMgr::Registrant< GUIMgr > registrantGUIMgr(SGSubsystemMgr::DISPLAY, { {"viewer", SGSubsystemMgr::Dependency::HARD}, })
SGPropertyNode * fgGetNode(const char *path, bool create)
Get a property node.