From 41eaa58c13311ace0f2374d40224ae14deb15256 Mon Sep 17 00:00:00 2001 From: James Turner Date: Sun, 10 Nov 2013 12:32:00 -0800 Subject: [PATCH] Reset: panel-node cleans up listener. Also get rid of the global FGPanelNode pointer. --- src/Model/panelnode.cxx | 122 +++++++++++++++++++++------------------- src/Model/panelnode.hxx | 13 ++++- 2 files changed, 73 insertions(+), 62 deletions(-) diff --git a/src/Model/panelnode.cxx b/src/Model/panelnode.cxx index 9e664b4c7..1194a4512 100644 --- a/src/Model/panelnode.cxx +++ b/src/Model/panelnode.cxx @@ -43,30 +43,18 @@ private: FGPanelNode* _panelNode; }; -static FGPanelNode* global_panel = NULL; - -/** - * Built-in command: pass a mouse click to the panel. - * - * button: the mouse button number, zero-based. - * is-down: true if the button is down, false if it is up. - * x-pos: the x position of the mouse click. - * y-pos: the y position of the mouse click. - */ -static bool -do_panel_mouse_click (const SGPropertyNode * arg) +class PanelPathListener : public SGPropertyChangeListener { - if (global_panel) - return global_panel->getPanel() - ->doMouseAction(arg->getIntValue("button"), - arg->getBoolValue("is-down") ? PU_DOWN : PU_UP, - arg->getIntValue("x-pos"), - arg->getIntValue("y-pos")); - else - return false; - - return false; -} +public: + PanelPathListener(FGPanelNode* pn) : _panelNode(pn) {} + + virtual void valueChanged (SGPropertyNode * node) + { + _panelNode->setPanelPath(node->getStringValue()); + } +private: + FGPanelNode* _panelNode; +}; class FGPanelPickCallback : public SGPickCallback { public: @@ -138,12 +126,14 @@ public: private: FGPanelNode* panel; - SGPropertyNode* visProp; + SGPropertyNode_ptr visProp; }; FGPanelNode::FGPanelNode(SGPropertyNode* props) : - _resizeToViewport(false) + _is2d(false), + _resizeToViewport(false), + _listener(NULL) { commonInit(); _panelPath = props->getStringValue("path"); @@ -168,22 +158,47 @@ FGPanelNode::FGPanelNode(SGPropertyNode* props) : } FGPanelNode::FGPanelNode() : + _is2d(true), _resizeToViewport(true), _depthTest(false) { + SGCommandMgr::instance()->addCommand("panel-mouse-click", this, &FGPanelNode::panelMouseClickCommand); + + SGPropertyNode* pathNode = fgGetNode("/sim/panel/path"); + _pathListener.reset(new PanelPathListener(this)); + pathNode->addChangeListener(_pathListener.get()); + setPanelPath(pathNode->getStringValue()); + // for a 2D panel, various options adjust the transformation // matrix. We need to pass this data on to OSG or its bounding box // will be stale, and picking will break. // http://code.google.com/p/flightgear-bugs/issues/detail?id=864 - PanelTransformListener* ptl = new PanelTransformListener(this); - fgGetNode("/sim/panel/x-offset", true)->addChangeListener(ptl); - fgGetNode("/sim/panel/y-offset", true)->addChangeListener(ptl); - fgGetNode("/sim/startup/xsize", true)->addChangeListener(ptl); - fgGetNode("/sim/startup/ysize", true)->addChangeListener(ptl); + _listener = new PanelTransformListener(this); + fgGetNode("/sim/panel/x-offset", true)->addChangeListener(_listener); + fgGetNode("/sim/panel/y-offset", true)->addChangeListener(_listener); + fgGetNode("/sim/startup/xsize", true)->addChangeListener(_listener); + fgGetNode("/sim/startup/ysize", true)->addChangeListener(_listener); commonInit(); } +FGPanelNode::~FGPanelNode() +{ + if (_is2d) { + SGCommandMgr::instance()->removeCommand("panel-mouse-click"); + SGPropertyNode* pathNode = fgGetNode("/sim/panel/path"); + pathNode->removeChangeListener(_pathListener.get()); + } + + if (_listener) { + fgGetNode("/sim/panel/x-offset", true)->removeChangeListener(_listener); + fgGetNode("/sim/panel/y-offset", true)->removeChangeListener(_listener); + fgGetNode("/sim/startup/xsize", true)->removeChangeListener(_listener); + fgGetNode("/sim/startup/ysize", true)->removeChangeListener(_listener); + delete _listener; + } +} + void FGPanelNode::setPanelPath(const std::string& panel) { if (panel == _panelPath) { @@ -264,10 +279,6 @@ void FGPanelNode::initWithPanel() dirtyBound(); } -FGPanelNode::~FGPanelNode() -{ -} - osg::Matrix FGPanelNode::transformMatrix() const { if (!_panel) { @@ -374,33 +385,9 @@ static osg::Node* createGeode(FGPanelNode* panel) return geode; } -class PanelPathListener : public SGPropertyChangeListener -{ -public: - PanelPathListener(FGPanelNode* pn) : _panelNode(pn) {} - - virtual void valueChanged (SGPropertyNode * node) - { - _panelNode->setPanelPath(node->getStringValue()); - } -private: - FGPanelNode* _panelNode; -}; - - osg::Node* FGPanelNode::create2DPanelNode() { - SGCommandMgr::instance()->addCommand("panel-mouse-click", do_panel_mouse_click); - - SGPropertyNode* pathNode = fgGetNode("/sim/panel/path"); - - FGPanelNode* drawable = new FGPanelNode(); -// need a global to keep the panel_mouse_click command working, sadly - global_panel = drawable; - - PanelPathListener* ppo = new PanelPathListener(drawable); - pathNode->addChangeListener(ppo); - drawable->setPanelPath(pathNode->getStringValue()); + FGPanelNode* drawable = new FGPanelNode; osg::Switch* ps = new osg::Switch; osg::StateSet* stateSet = ps->getOrCreateStateSet(); @@ -424,3 +411,20 @@ osg::Node* FGPanelNode::load(SGPropertyNode *n) drawable->lazyLoad(); // force load now for 2.5D panels return createGeode(drawable); } + +/** + * Built-in command: pass a mouse click to the panel. + * + * button: the mouse button number, zero-based. + * is-down: true if the button is down, false if it is up. + * x-pos: the x position of the mouse click. + * y-pos: the y position of the mouse click. + */ +bool +FGPanelNode::panelMouseClickCommand(const SGPropertyNode * arg) +{ + return _panel->doMouseAction(arg->getIntValue("button"), + arg->getBoolValue("is-down") ? PU_DOWN : PU_UP, + arg->getIntValue("x-pos"), + arg->getIntValue("y-pos")); +} diff --git a/src/Model/panelnode.hxx b/src/Model/panelnode.hxx index 772ef9e32..9d9a7c836 100644 --- a/src/Model/panelnode.hxx +++ b/src/Model/panelnode.hxx @@ -5,6 +5,7 @@ #include #include +#include #include #include @@ -15,9 +16,7 @@ class SGPropertyNode; class FGPanelNode : public osg::Drawable { -public: - FGPanelNode(); - +public: FGPanelNode(SGPropertyNode* props); virtual ~FGPanelNode(); @@ -51,9 +50,14 @@ public: */ bool isVisible2d() const; private: + FGPanelNode(); // for 2D panels + void commonInit(); void initWithPanel(); + bool panelMouseClickCommand(const SGPropertyNode * arg); + + const bool _is2d; SGSharedPtr _panel; std::string _panelPath; @@ -69,6 +73,9 @@ private: // coordinates into 3D coordinates of the panel quadrilateral. osg::Matrix _xform; + SGPropertyChangeListener* _listener; + std::auto_ptr _pathListener; + /// should the 2D panel auto-hide when the view orientation changes mutable SGPropertyNode_ptr _autoHide2d; -- 2.39.5