FlightGear next
gui_mgr.cxx
Go to the documentation of this file.
1// Canvas gui/dialog manager
2//
3// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
4//
5// This program is free software; you can redistribute it and/or
6// modify it under the terms of the GNU General Public License as
7// published by the Free Software Foundation; either version 2 of the
8// License, or (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful, but
11// WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13// General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program; if not, write to the Free Software
17// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18
19#include "gui_mgr.hxx"
20
21#include <Main/fg_os.hxx>
22#include <Main/fg_props.hxx>
23#include <Main/globals.hxx>
24
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>
30
31#include <osg/BlendFunc>
32#include <osgViewer/Viewer>
33#include <osgViewer/View>
34#include <osgGA/GUIEventHandler>
35
36class DesktopGroup;
37typedef SGSharedPtr<DesktopGroup> DesktopPtr;
38typedef SGWeakPtr<DesktopGroup> DesktopWeakPtr;
39
40namespace sc = simgear::canvas;
41using osgEA = osgGA::GUIEventAdapter;
42
43/*
44RESIZE AREAS
45============
46
47| || | _ inside corner region (L-shaped part inside margin) both
48|___||_|_ _ _/ directions can be resized (outside only one axis)
49| || | |
50| || |
51| || |_____|__ _
52| || | } margin_neg \
53| ========|== <-- window border |_ area where resize
54| | } margin_pos | can be initiated
55|____________|__/ _/
56|<- corner ->|
57*/
58const float RESIZE_MARGIN_POS = 12;
59const float RESIZE_MARGIN_NEG = 2;
60const float RESIZE_CORNER = 20;
61
66 public osgGA::GUIEventHandler
67{
68 public:
69 GUIEventHandler(const DesktopWeakPtr& desktop_group);
70
71 bool handle( const osgEA& ea,
72 osgGA::GUIActionAdapter&,
73 osg::Object*,
74 osg::NodeVisitor* );
75
76 protected:
78};
79
84 public sc::Placement
85{
86 public:
87 WindowPlacement( SGPropertyNode* node,
88 sc::WindowPtr window,
89 sc::CanvasPtr canvas ):
90 Placement(node),
91 _window(window),
92 _canvas(canvas)
93 {}
94
99 {
100 sc::WindowPtr window = _window.lock();
101 sc::CanvasPtr canvas = _canvas.lock();
102
103 if( window && canvas && canvas == window->getCanvasContent().lock() )
104 window->setCanvasContent( sc::CanvasPtr() );
105 }
106
107 private:
108 sc::WindowWeakPtr _window;
109 sc::CanvasWeakPtr _canvas;
110};
111
116 public sc::Group
117{
118 public:
119 DesktopGroup(osg::Camera* camera);
120
121 void setFocusWindow(const sc::WindowPtr& window);
122
123 bool grabPointer(const sc::WindowPtr& window);
124 void ungrabPointer(const sc::WindowPtr& window);
125
126 sc::WindowPtr windowAtPosition(const osg::Vec2f& screen_pos);
127 osg::Vec2f toScreenPos(const osgEA& ea) const;
128
129 bool handleOsgEvent(const osgEA& ea);
130
131 protected:
132
133 friend class GUIMgr;
134
135 SGPropertyChangeCallback<DesktopGroup> _cb_mouse_mode;
136 bool _handle_events {true};
137
138 simgear::PropertyObject<int> _width,
140
141 sc::WindowWeakPtr _last_push,
147
148 uint8_t _resize {sc::Window::NONE};
150 bool _drag_finished {false};
151
152 osg::Vec2f _drag_start,
155
156 uint32_t _last_key_down_no_mod {~0u}; // Key repeat for non modifier keys
157
158 bool canHandleInput() const;
159 bool handleMouse(const osgEA& ea);
160 bool handleKeyboard(const osgEA& ea);
161
162 bool propagateEvent( const sc::EventPtr& event,
163 const sc::WindowPtr& active_window );
164 bool propagateRootEvent(const sc::EventPtr& event);
165
166 void handleResize(int x, int y, int width, int height);
167 bool handleDrag(const sc::EventPtr& event);
168 void finishDrag(const sc::WindowPtr& drag_src, const sc::EventPtr& event);
169 void handleMouseMode(SGPropertyNode* node);
170
174 sc::ElementFactory
175 getChildFactory(const std::string& type) const
176 {
177 if( type == "window" )
178 return &Element::create<sc::Window>;
179
180 return Group::getChildFactory(type);
181 }
182};
183
184//------------------------------------------------------------------------------
186 _desktop( desktop_group )
187{
188
189}
190
191//------------------------------------------------------------------------------
193 osgGA::GUIActionAdapter&,
194 osg::Object*,
195 osg::NodeVisitor* )
196{
197 if( ea.getHandled() )
198 return false;
199
200 DesktopPtr desktop = _desktop.lock();
201 return desktop && desktop->handleOsgEvent(ea);
202}
203
204//------------------------------------------------------------------------------
205DesktopGroup::DesktopGroup(osg::Camera* camera) : Group(sc::CanvasPtr(), fgGetNode("/canvas/desktop", true)),
206 _cb_mouse_mode(this,
208 fgGetNode("/devices/status/mice/mouse[0]/mode", true)),
209 _width(_node, "size[0]"),
210 _height(_node, "size[1]")
211{
212#if !defined(BUILDING_TESTSUITE)
213 if (!camera) {
214 SG_LOG(SG_GUI, SG_WARN, "DesktopGroup: failed to get GUI camera.");
215 return;
216 }
217
218 camera->addChild(_scene_group.get());
219
220 osg::StateSet* stateSet = _scene_group->getOrCreateStateSet();
221 stateSet->setDataVariance(osg::Object::STATIC);
222 stateSet->setRenderBinDetails(1000, "RenderBin");
223
224 // speed optimization?
225 stateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
226 stateSet->setMode(GL_CULL_FACE, osg::StateAttribute::OFF);
227
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));
232#endif
233
234 _width = _height = -1;
235}
236
237//------------------------------------------------------------------------------
238void DesktopGroup::setFocusWindow(const sc::WindowPtr& window)
239{
240 _focus_window = window;
241}
242
243//------------------------------------------------------------------------------
244bool DesktopGroup::grabPointer(const sc::WindowPtr& window)
245{
246 sc::WindowPtr resize = _resize_window.lock();
247 if( (resize && resize != window) || !_pointer_grab_window.expired() )
248 // Already grabbed (resize -> implicit grab)
249 return false;
250
251 _pointer_grab_window = window;
252 return true;
253}
254
255//------------------------------------------------------------------------------
256void DesktopGroup::ungrabPointer(const sc::WindowPtr& window)
257{
258 if( _pointer_grab_window.expired() )
259 SG_LOG(SG_GUI, SG_WARN, "ungrabPointer: no active grab.");
260 else if( window != _pointer_grab_window.lock() )
261 SG_LOG(SG_GUI, SG_WARN, "ungrabPointer: window is not owner of the grab.");
262 else
263 _pointer_grab_window.reset();
264}
265
266//------------------------------------------------------------------------------
267sc::WindowPtr DesktopGroup::windowAtPosition(const osg::Vec2f& screen_pos)
268{
269 for( int i = _scene_group->getNumChildren() - 1; i >= 0; --i )
270 {
271 osg::Group *element = _scene_group->getChild(i)->asGroup();
272
273 if( !element || !element->getUserData() )
274 continue; // TODO: warn/log?
275
276 sc::WindowPtr window =
277 dynamic_cast<sc::Window*>
278 (
279 static_cast<sc::Element::OSGUserData*>(
280 element->getUserData()
281 )->element.get()
282 );
283
284 if( !window || !window->isCapturingEvents() || !window->isVisible() )
285 continue;
286
287 float margin = window->isResizable() ? RESIZE_MARGIN_POS : 0;
288 if( window->getScreenRegion().contains( screen_pos.x(),
289 screen_pos.y(),
290 margin ) )
291 {
292 return window;
293 }
294 }
295
296 return {};
297}
298
299//------------------------------------------------------------------------------
300osg::Vec2f DesktopGroup::toScreenPos(const osgEA& ea) const
301{
302 float x = SGMiscf::round(0.5 * (ea.getXnormalized() + 1) * _width);
303 float y = SGMiscf::round(0.5 * (ea.getYnormalized() + 1) * _height);
304
305 if( ea.getMouseYOrientation() != osgEA::Y_INCREASING_DOWNWARDS )
306 y = _height - y;
307
308 return {x, y};
309}
310
311//------------------------------------------------------------------------------
313{
314 switch( ea.getEventType() )
315 {
316 case osgEA::PUSH:
317 case osgEA::RELEASE:
318// case osgEA::DOUBLECLICK:
319// // DOUBLECLICK doesn't seem to be triggered...
320 case osgEA::DRAG:
321 case osgEA::MOVE:
322 case osgEA::SCROLL:
323 return handleMouse(ea);
324 case osgEA::KEYDOWN:
325 case osgEA::KEYUP:
326 return handleKeyboard(ea);
327 case osgEA::RESIZE:
328 handleResize( ea.getWindowX(),
329 ea.getWindowY(),
330 ea.getWindowWidth(),
331 ea.getWindowHeight() );
332 return false; // Let other event handlers also consume resize events
333 default:
334 return false;
335 }
336}
337
338//------------------------------------------------------------------------------
340{
341 return _handle_events
342 && _scene_group.valid()
343 && _scene_group->getNumChildren() > 0;
344}
345
346//------------------------------------------------------------------------------
348{
349 if( !canHandleInput() )
350 return false;
351
352 osg::Vec2f mouse_pos = toScreenPos(ea),
353 delta = mouse_pos - _last_mouse_pos;
354 _last_mouse_pos = mouse_pos;
355
356 if( auto resize_window = _resize_window.lock() )
357 {
358 switch( ea.getEventType() )
359 {
360 case osgEA::RELEASE:
361 resize_window->handleResize(sc::Window::NONE);
362 _resize_window.reset();
363 break;
364 case osgEA::DRAG:
365 resize_window->handleResize(_resize, mouse_pos - _drag_start);
366 return true;
367 default:
368 // Ignore all other events while resizing
369 return true;
370 }
371 }
372
373 sc::MouseEventPtr event(new sc::MouseEvent(ea));
374 event->screen_pos = mouse_pos;
375 event->delta = delta;
376
377 if( !_drag_finished && ea.getEventType() == osgEA::DRAG )
378 return handleDrag(event);
379
380 if( auto last_drag = _last_drag.lock() )
381 {
382 if( ea.getEventType() == osgEA::RELEASE )
383 finishDrag(last_drag, event);
384 else
385 // While dragging ignore all other mouse events
386 return true;
387 }
388
389 sc::WindowPtr window_at_cursor = _pointer_grab_window.lock();
390 if( !window_at_cursor )
391 window_at_cursor = windowAtPosition(event->screen_pos);
392
393 if( window_at_cursor )
394 {
395 const SGRect<float>& reg = window_at_cursor->getScreenRegion();
396
397 if( window_at_cursor->isResizable()
398 && !reg.contains( event->getScreenX(),
399 event->getScreenY(),
401 {
402 if( !_last_cursor )
404
405 _resize = 0;
406
407 if( event->getScreenX() <= reg.l() + RESIZE_CORNER )
408 _resize |= sc::Window::LEFT;
409 else if( event->getScreenX() >= reg.r() - RESIZE_CORNER )
410 _resize |= sc::Window::RIGHT;
411
412 if( event->getScreenY() <= reg.t() + RESIZE_CORNER )
413 _resize |= sc::Window::TOP;
414 else if( event->getScreenY() >= reg.b() - RESIZE_CORNER )
415 _resize |= sc::Window::BOTTOM;
416
417 static const FGMouseCursor::Cursor cursor_mapping[] =
418 {
430 };
431
432 if( !cursor_mapping[_resize] )
433 return false;
434
435 fgSetMouseCursor(cursor_mapping[_resize]);
436
437 if( ea.getEventType() == osgEA::PUSH )
438 {
439 _resize_window = window_at_cursor;
440 _drag_start = event->screen_pos;
441
442 window_at_cursor->raise();
443 window_at_cursor->handleResize(_resize | sc::Window::INIT);
444 }
445
446 return true;
447 }
448 }
449
450 if( _last_cursor )
451 {
454 return true;
455 }
456
457 switch( ea.getEventType() )
458 {
459 case osgEA::PUSH:
460 _last_push = window_at_cursor;
461 _drag_finished = false;
462 event->type = sc::Event::MOUSE_DOWN;
463 break;
464 case osgEA::SCROLL:
465 switch( ea.getScrollingMotion() )
466 {
467 case osgEA::SCROLL_UP:
468 event->delta.y() = 1;
469 break;
470 case osgEA::SCROLL_DOWN:
471 event->delta.y() = -1;
472 break;
473 default:
474 return false;
475 }
476
477 // osg sends two events for every scrolling motion. We don't need
478 // duplicate events, so lets ignore the second event with the same
479 // timestamp.
480 if( _last_scroll_time == ea.getTime() )
481 return window_at_cursor ? true : false;
482 _last_scroll_time = ea.getTime();
483
484 event->type = sc::Event::WHEEL;
485 break;
486
487 // If drag has not been handled yet it has been aborted. So let's treat it
488 // like a normal mouse movement.
489 case osgEA::DRAG:
490 case osgEA::MOVE:
491 {
492 sc::WindowPtr last_mouse_over = _last_mouse_over.lock();
493 if( last_mouse_over && last_mouse_over != window_at_cursor )
494 last_mouse_over->handleEvent(event->clone(sc::Event::MOUSE_LEAVE));
495
496 _last_mouse_over = window_at_cursor;
497 event->type = sc::Event::MOUSE_MOVE;
498 break;
499 }
500 case osgEA::RELEASE:
501 {
502 sc::WindowPtr last_push = _last_push.lock();
503 if( last_push && last_push != window_at_cursor )
504 {
505 // Leave old window
506 last_push->handleEvent(event->clone(sc::Event::MOUSE_LEAVE));
507 }
508
509 _last_push.reset();
510 event->type = sc::Event::MOUSE_UP;
511 break;
512 }
513
514 default:
515 return false;
516 }
517
518 return propagateEvent(event, window_at_cursor);
519}
520
521//------------------------------------------------------------------------------
523{
524 if( !canHandleInput() )
525 return false;
526
527 sc::KeyboardEventPtr event(new sc::KeyboardEvent(ea));
528
529 if( auto drag = _last_drag.lock() )
530 {
531 if( ea.getKey() == osgEA::KEY_Escape )
532 finishDrag(drag, event);
533
534 // While dragging ignore all key events
535 return true;
536 }
537
538 // Detect key repeat (of non modifier keys)
539 if( !event->isModifier() )
540 {
541 if( event->getType() == sc::Event::KEY_DOWN )
542 {
543 if( event->keyCode() == _last_key_down_no_mod )
544 event->setRepeat(true);
545 _last_key_down_no_mod = event->keyCode();
546 }
547 else
548 {
549 if( event->keyCode() == _last_key_down_no_mod )
551 }
552 }
553
554 sc::WindowPtr active_window = _focus_window.lock();
555 bool handled = propagateEvent(event, active_window);
556
557 if( event->getType() == sc::Event::KEY_DOWN
558 && !event->defaultPrevented()
559 && event->isPrint() )
560 {
561 handled |= propagateEvent(event->clone(sc::Event::KEY_PRESS), active_window);
562 }
563
564 return handled;
565}
566
567//------------------------------------------------------------------------------
568bool DesktopGroup::propagateEvent( const sc::EventPtr& event,
569 const sc::WindowPtr& active_window )
570{
571 return active_window
572 ? active_window->handleEvent(event)
573 : propagateRootEvent(event);
574}
575
576//------------------------------------------------------------------------------
577bool DesktopGroup::propagateRootEvent(const sc::EventPtr& event)
578{
579 handleEvent(event);
580
581 // stopPropagation() on DesktopGroup stops propagation to internal event
582 // handling.
583 return event->propagation_stopped;
584}
585
586//------------------------------------------------------------------------------
587void DesktopGroup::handleResize(int x, int y, int width, int height)
588{
589 if( _width == width && _height == height )
590 return;
591
592 _width = width;
593 _height = height;
594
595 if( _scene_group.valid() )
596 {
597 // Origin should be at top left corner, therefore we need to mirror the
598 // y-axis
599 _scene_group->setMatrix(osg::Matrix(
600 1, 0, 0, 0,
601 0, -1, 0, 0,
602 0, 0, 1, 0,
603 0, _height, 0, 1
604 ));
605 }
606}
607
608//------------------------------------------------------------------------------
609bool DesktopGroup::handleDrag(const sc::EventPtr& event)
610{
611 event->type = sc::Event::DRAG;
612
613 auto drag_window = _last_drag.lock();
614 if( !drag_window )
615 {
616 _last_drag = drag_window = _last_push.lock();
617
618 if( drag_window )
619 drag_window->handleEvent(event->clone(sc::Event::DRAG_START));
620 }
621
622 // TODO: dragover
623 return drag_window && drag_window->handleEvent(event);
624}
625
626//------------------------------------------------------------------------------
627void DesktopGroup::finishDrag( const sc::WindowPtr& drag_src,
628 const sc::EventPtr& event )
629{
630 drag_src->handleEvent(event->clone(sc::Event::DRAG_END));
631 _last_drag.reset();
632 _drag_finished = true;
633}
634
635//------------------------------------------------------------------------------
636void DesktopGroup::handleMouseMode(SGPropertyNode* node)
637{
638 // pass-through indicates events should pass through to the UI
639 _handle_events = fgGetNode("/input/mice/mouse[0]/mode", node->getIntValue())
640 ->getBoolValue("pass-through");
641}
642
643//------------------------------------------------------------------------------
645{
646
647}
648
649//------------------------------------------------------------------------------
650void GUIMgr::setGUIViewAndCamera(osgViewer::View* view, osg::Camera* cam)
651{
652 _viewerView = view;
653 _camera = cam;
654}
655
656//------------------------------------------------------------------------------
657sc::WindowPtr GUIMgr::createWindow(const std::string& name)
658{
659 sc::WindowPtr window = _desktop->createChild<sc::Window>(name);
660 if( name.empty() )
661 window->set("id", std::to_string(window->getProps()->getIndex()));
662 return window;
663}
664
665//------------------------------------------------------------------------------
667{
668 if (_desktop && _event_handler) {
669 SG_LOG(SG_GUI, SG_WARN, "GUIMgr::init() already initialized.");
670 return;
671 }
672
673 auto camera = _camera;
674#if !defined(BUILDING_TESTSUITE)
675 assert(_viewerView);
676 if (!camera) {
677 camera = _viewerView->getCamera();
678 }
679#endif
680
681 DesktopPtr desktop(new DesktopGroup(camera));
682 desktop->handleResize(
683 0,
684 0,
685 fgGetInt("/sim/startup/xsize"),
686 fgGetInt("/sim/startup/ysize"));
687 _desktop = desktop;
688
689 _event_handler = new GUIEventHandler(desktop);
690
691#if !defined(BUILDING_TESTSUITE)
692 _viewerView->getEventHandlers()
693 // GUI is on top of everything so lets install as first event handler
694 .push_front(_event_handler);
695#endif
696
697 sc::Canvas::addPlacementFactory(
698 "window",
699 std::bind(&GUIMgr::addWindowPlacement, this, std::placeholders::_1, std::placeholders::_2));
700
701 _desktop->getProps()->fireCreatedRecursive();
702}
703
704//------------------------------------------------------------------------------
706{
707 if( !_desktop && !_event_handler )
708 {
709 SG_LOG(SG_GUI, SG_WARN, "GUIMgr::shutdown() not running.");
710 return;
711 }
712
713 sc::Canvas::removePlacementFactory("window");
714
715 if( _desktop )
716 {
717 _desktop->destroy();
718 _desktop.reset();
719 }
720
721 if( _event_handler )
722 {
723#if !defined(BUILDING_TESTSUITE)
724 _viewerView->removeEventHandler(_event_handler);
725#endif
726 _event_handler = 0;
727 }
728
729 _viewerView = nullptr;
730}
731
732//------------------------------------------------------------------------------
733void GUIMgr::update(double dt)
734{
735 _desktop->update(dt);
736}
737
738//------------------------------------------------------------------------------
739sc::GroupPtr GUIMgr::getDesktop()
740{
741 return _desktop;
742}
743
744//------------------------------------------------------------------------------
745void GUIMgr::setInputFocus(const simgear::canvas::WindowPtr& window)
746{
747 static_cast<DesktopGroup*>(_desktop.get())->setFocusWindow(window);
748}
749
750//------------------------------------------------------------------------------
751bool GUIMgr::grabPointer(const sc::WindowPtr& window)
752{
753 return static_cast<DesktopGroup*>(_desktop.get())->grabPointer(window);
754}
755
756//------------------------------------------------------------------------------
757void GUIMgr::ungrabPointer(const sc::WindowPtr& window)
758{
759 static_cast<DesktopGroup*>(_desktop.get())->ungrabPointer(window);
760}
761
762//------------------------------------------------------------------------------
763sc::Placements
764GUIMgr::addWindowPlacement( SGPropertyNode* placement,
765 sc::CanvasPtr canvas )
766{
767 const std::string& id = placement->getStringValue("id");
768
769 sc::Placements placements;
770 sc::WindowPtr window = _desktop->getChild<sc::Window>(id);
771 if( window )
772 {
773 window->setCanvasContent(canvas);
774 placements.push_back(
775 sc::PlacementPtr(
776 new WindowPlacement(placement, window, canvas)
777 ));
778 }
779 return placements;
780}
781
782
783// Register the subsystem.
784SGSubsystemMgr::Registrant<GUIMgr> registrantGUIMgr(
785 SGSubsystemMgr::DISPLAY,
786 {
787 {"viewer", SGSubsystemMgr::Dependency::HARD},
788 });
#define i(x)
Desktop root group.
Definition gui_mgr.cxx:117
sc::WindowPtr windowAtPosition(const osg::Vec2f &screen_pos)
Definition gui_mgr.cxx:267
void setFocusWindow(const sc::WindowPtr &window)
Definition gui_mgr.cxx:238
SGPropertyChangeCallback< DesktopGroup > _cb_mouse_mode
Definition gui_mgr.cxx:135
bool _handle_events
Definition gui_mgr.cxx:136
osg::Vec2f _last_mouse_pos
Definition gui_mgr.cxx:153
sc::WindowWeakPtr _focus_window
Definition gui_mgr.cxx:145
FGMouseCursor::Cursor _last_cursor
Definition gui_mgr.cxx:149
friend class GUIMgr
Definition gui_mgr.cxx:133
void handleResize(int x, int y, int width, int height)
Definition gui_mgr.cxx:587
bool canHandleInput() const
Definition gui_mgr.cxx:339
osg::Vec2f toScreenPos(const osgEA &ea) const
Definition gui_mgr.cxx:300
simgear::PropertyObject< int > _width
Definition gui_mgr.cxx:138
sc::WindowWeakPtr _last_push
Definition gui_mgr.cxx:141
void handleMouseMode(SGPropertyNode *node)
Definition gui_mgr.cxx:636
bool handleDrag(const sc::EventPtr &event)
Definition gui_mgr.cxx:609
simgear::PropertyObject< int > _height
Definition gui_mgr.cxx:139
void ungrabPointer(const sc::WindowPtr &window)
Definition gui_mgr.cxx:256
sc::WindowWeakPtr _last_drag
Definition gui_mgr.cxx:142
bool _drag_finished
Definition gui_mgr.cxx:150
bool handleOsgEvent(const osgEA &ea)
Definition gui_mgr.cxx:312
double _last_scroll_time
Definition gui_mgr.cxx:154
bool propagateRootEvent(const sc::EventPtr &event)
Definition gui_mgr.cxx:577
bool propagateEvent(const sc::EventPtr &event, const sc::WindowPtr &active_window)
Definition gui_mgr.cxx:568
uint8_t _resize
Definition gui_mgr.cxx:148
sc::WindowWeakPtr _pointer_grab_window
Definition gui_mgr.cxx:146
void finishDrag(const sc::WindowPtr &drag_src, const sc::EventPtr &event)
Definition gui_mgr.cxx:627
bool grabPointer(const sc::WindowPtr &window)
Definition gui_mgr.cxx:244
sc::WindowWeakPtr _resize_window
Definition gui_mgr.cxx:144
DesktopGroup(osg::Camera *camera)
Definition gui_mgr.cxx:205
bool handleKeyboard(const osgEA &ea)
Definition gui_mgr.cxx:522
uint32_t _last_key_down_no_mod
Definition gui_mgr.cxx:156
osg::Vec2f _drag_start
Definition gui_mgr.cxx:152
bool handleMouse(const osgEA &ea)
Definition gui_mgr.cxx:347
sc::WindowWeakPtr _last_mouse_over
Definition gui_mgr.cxx:143
sc::ElementFactory getChildFactory(const std::string &type) const
Definition gui_mgr.cxx:175
Event handler.
Definition gui_mgr.cxx:67
DesktopWeakPtr _desktop
Definition gui_mgr.cxx:77
bool handle(const osgEA &ea, osgGA::GUIActionAdapter &, osg::Object *, osg::NodeVisitor *)
Definition gui_mgr.cxx:192
GUIEventHandler(const DesktopWeakPtr &desktop_group)
Definition gui_mgr.cxx:185
void setInputFocus(const simgear::canvas::WindowPtr &window)
Set the input (keyboard) focus to the given window.
Definition gui_mgr.cxx:745
void update(double dt) override
Definition gui_mgr.cxx:733
void init() override
Definition gui_mgr.cxx:666
simgear::canvas::WindowPtr createWindow(const std::string &name="")
Definition gui_mgr.cxx:657
void shutdown() override
Definition gui_mgr.cxx:705
void setGUIViewAndCamera(osgViewer::View *view, osg::Camera *cam)
specify the osgViewer::View and Camera
Definition gui_mgr.cxx:650
osg::ref_ptr< osgViewer::View > _viewerView
Definition gui_mgr.hxx:83
simgear::canvas::GroupPtr getDesktop()
Get simgear::canvas::Group containing all windows.
Definition gui_mgr.cxx:739
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...
Definition gui_mgr.cxx:751
void ungrabPointer(const simgear::canvas::WindowPtr &window)
Releases the grab acquired for this window with grabPointer().
Definition gui_mgr.cxx:757
simgear::canvas::GroupPtr _desktop
Definition gui_mgr.hxx:81
osg::ref_ptr< osg::Camera > _camera
Definition gui_mgr.hxx:84
osg::ref_ptr< GUIEventHandler > _event_handler
Definition gui_mgr.hxx:82
simgear::canvas::Placements addWindowPlacement(SGPropertyNode *placement, simgear::canvas::CanvasPtr canvas)
Definition gui_mgr.cxx:764
Track a canvas placement on a window.
Definition gui_mgr.cxx:85
WindowPlacement(SGPropertyNode *node, sc::WindowPtr window, sc::CanvasPtr canvas)
Definition gui_mgr.cxx:87
virtual ~WindowPlacement()
Remove placement from window.
Definition gui_mgr.cxx:98
const char * name
void fgSetMouseCursor(FGMouseCursor::Cursor cursor)
FGMouseCursor::Cursor fgGetMouseCursor()
int fgGetInt(const char *name, int defaultValue)
Get an int value for a property.
Definition fg_props.cxx:532
const float RESIZE_MARGIN_NEG
Definition gui_mgr.cxx:59
SGSharedPtr< DesktopGroup > DesktopPtr
Definition gui_mgr.cxx:37
osgGA::GUIEventAdapter osgEA
Definition gui_mgr.cxx:41
SGWeakPtr< DesktopGroup > DesktopWeakPtr
Definition gui_mgr.cxx:38
const float RESIZE_MARGIN_POS
Definition gui_mgr.cxx:58
const float RESIZE_CORNER
Definition gui_mgr.cxx:60
SGSubsystemMgr::Registrant< GUIMgr > registrantGUIMgr(SGSubsystemMgr::DISPLAY, { {"viewer", SGSubsystemMgr::Dependency::HARD}, })
SGPropertyNode * fgGetNode(const char *path, bool create)
Get a property node.
Definition proptest.cpp:27