]> git.mxchange.org Git - flightgear.git/blobdiff - src/Canvas/gui_mgr.cxx
Fix for bug 1304 - crash loading XML route
[flightgear.git] / src / Canvas / gui_mgr.cxx
index 3188430e395529bd94aa5bca00169e64577f986b..453893886ba6ca100590fb8b7135c330242ab758 100644 (file)
@@ -116,6 +116,7 @@ class DesktopGroup:
     uint8_t _resize;
     int     _last_cursor;
 
+    osg::Vec2 _drag_start;
     float _last_x,
           _last_y;
     double _last_scroll_time;
@@ -135,27 +136,6 @@ class DesktopGroup:
 
       return Group::getChildFactory(type);
     }
-
-    /**
-     *
-     */
-    simgear::canvas::Placements
-    addPlacement(SGPropertyNode* node, simgear::canvas::CanvasPtr canvas)
-    {
-      const std::string& id = node->getStringValue("id");
-
-      simgear::canvas::Placements placements;
-      canvas::WindowPtr window = getChild<canvas::Window>(id);
-      if( window )
-      {
-        window->setCanvasContent(canvas);
-        placements.push_back(
-          simgear::canvas::PlacementPtr(
-            new WindowPlacement(node, window, canvas)
-        ));
-      }
-      return placements;
-    }
 };
 
 //------------------------------------------------------------------------------
@@ -198,13 +178,6 @@ DesktopGroup::DesktopGroup():
   assert(camera);
   camera->addChild( getMatrixTransform() );
 
-  simgear::canvas::Canvas::addPlacementFactory
-  (
-    "window",
-    boost::bind(&DesktopGroup::addPlacement, this, _1, _2)
-  );
-
-
   osg::StateSet* stateSet = _transform->getOrCreateStateSet();
   stateSet->setDataVariance(osg::Object::STATIC);
   stateSet->setRenderBinDetails(1000, "RenderBin");
@@ -225,6 +198,10 @@ DesktopGroup::DesktopGroup():
   // Do not change values on reinit
   _width.node()->setAttribute(SGPropertyNode::PRESERVE, true);
   _height.node()->setAttribute(SGPropertyNode::PRESERVE, true);
+
+  // Do not restore windows on reinit (all windows will need to be recreated,
+  // but hey it's a reset ;-))
+  _node->setAttribute(SGPropertyNode::PRESERVE, true);
 }
 
 //------------------------------------------------------------------------------
@@ -302,7 +279,8 @@ bool DesktopGroup::handleMouse(const osgGA::GUIEventAdapter& ea)
         _resize_window.reset();
         break;
       case osgGA::GUIEventAdapter::DRAG:
-        _resize_window.lock()->handleResize(_resize, event->delta);
+        _resize_window.lock()->handleResize( _resize,
+                                             event->screen_pos - _drag_start );
         return true;
       default:
         return false;
@@ -379,9 +357,10 @@ bool DesktopGroup::handleMouse(const osgGA::GUIEventAdapter& ea)
       if( ea.getEventType() == osgGA::GUIEventAdapter::PUSH )
       {
         _resize_window = window_at_cursor;
+        _drag_start = event->screen_pos;
+
         window_at_cursor->raise();
-        window_at_cursor->handleResize( _resize | canvas::Window::INIT,
-                                        event->delta );
+        window_at_cursor->handleResize(_resize | canvas::Window::INIT);
       }
 
       return true;
@@ -505,14 +484,9 @@ void DesktopGroup::handleMouseMode(SGPropertyNode* node)
 }
 
 //------------------------------------------------------------------------------
-GUIMgr::GUIMgr():
-  _desktop( new DesktopGroup ),
-  _event_handler( new GUIEventHandler(
-    boost::static_pointer_cast<DesktopGroup>(_desktop)
-  ))
+GUIMgr::GUIMgr()
 {
-  // We handle the property listener manually within ::init and ::shutdown.
-  _desktop->removeListener();
+
 }
 
 //------------------------------------------------------------------------------
@@ -531,32 +505,43 @@ canvas::WindowPtr GUIMgr::createWindow(const std::string& name)
 //------------------------------------------------------------------------------
 void GUIMgr::init()
 {
-  boost::static_pointer_cast<DesktopGroup>(_desktop)->handleResize
+  DesktopPtr desktop( new DesktopGroup );
+  desktop->handleResize
   (
     0,
     0,
     fgGetInt("/sim/startup/xsize"),
     fgGetInt("/sim/startup/ysize")
   );
+  _desktop = desktop;
 
+  _event_handler = new GUIEventHandler(desktop);
   globals->get_renderer()
          ->getViewer()
          ->getEventHandlers()
          // GUI is on top of everything so lets install as first event handler
          .push_front( _event_handler );
 
-  _desktop->getProps()->addChangeListener(_desktop.get());
+  simgear::canvas::Canvas::addPlacementFactory
+  (
+    "window",
+    boost::bind(&GUIMgr::addWindowPlacement, this, _1, _2)
+  );
+
   _desktop->getProps()->fireCreatedRecursive();
 }
 
 //------------------------------------------------------------------------------
 void GUIMgr::shutdown()
 {
-  _desktop->getProps()->removeChangeListener(_desktop.get());
+  _desktop->destroy();
+  _desktop.reset();
+  simgear::canvas::Canvas::removePlacementFactory("window");
 
   globals->get_renderer()
          ->getViewer()
          ->removeEventHandler( _event_handler );
+  _event_handler = 0;
 }
 
 //------------------------------------------------------------------------------
@@ -570,3 +555,23 @@ simgear::canvas::GroupPtr GUIMgr::getDesktop()
 {
   return _desktop;
 }
+
+//------------------------------------------------------------------------------
+simgear::canvas::Placements
+GUIMgr::addWindowPlacement( SGPropertyNode* placement,
+                            simgear::canvas::CanvasPtr canvas )
+{
+  const std::string& id = placement->getStringValue("id");
+
+  simgear::canvas::Placements placements;
+  canvas::WindowPtr window = _desktop->getChild<canvas::Window>(id);
+  if( window )
+  {
+    window->setCanvasContent(canvas);
+    placements.push_back(
+      simgear::canvas::PlacementPtr(
+        new WindowPlacement(placement, window, canvas)
+    ));
+  }
+  return placements;
+}