GUI: add explicit close hook to FGDialog
Allow triggering close of dialogs explicitly, rather than relying on ref-count drop to delete them. Compat dialogs have a Nasal peer and we can't rely on GC to cause a timely close of the dialog.
This commit is contained in:
parent
437ebfd272
commit
98958af2a3
6 changed files with 34 additions and 1 deletions
|
@ -47,6 +47,8 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
// the Nasal peer does not hold an owning reference to the
|
||||
// main dialog object (dialogs are owned by the NewGUI subsystem)
|
||||
SGWeakPtr<FGPUICompatDialog> _dialog;
|
||||
};
|
||||
|
||||
|
@ -107,9 +109,14 @@ FGPUICompatDialog::FGPUICompatDialog(SGPropertyNode* props) : FGDialog(props),
|
|||
}
|
||||
|
||||
FGPUICompatDialog::~FGPUICompatDialog()
|
||||
{
|
||||
// nothing to do, all work was done in close()
|
||||
}
|
||||
|
||||
void FGPUICompatDialog::close()
|
||||
{
|
||||
if (_peer) {
|
||||
_peer->callMethod<void>("doClose");
|
||||
_peer->callMethod<void>("onClose");
|
||||
}
|
||||
|
||||
_props->setIntValue("lastx", getX());
|
||||
|
@ -124,6 +131,8 @@ FGPUICompatDialog::~FGPUICompatDialog()
|
|||
}
|
||||
nas->deleteModule(_module.c_str());
|
||||
}
|
||||
|
||||
_peer.clear();
|
||||
}
|
||||
|
||||
bool FGPUICompatDialog::init()
|
||||
|
|
|
@ -112,6 +112,8 @@ public:
|
|||
double width() const;
|
||||
double height() const;
|
||||
|
||||
void close() override;
|
||||
|
||||
private:
|
||||
friend naRef f_makeDialogPeer(const nasal::CallContext& ctx);
|
||||
friend naRef f_dialogRootObject(FGPUICompatDialog& dialog, naContext c);
|
||||
|
|
|
@ -1464,6 +1464,11 @@ void FGPUIDialog::applySize(puObject* object)
|
|||
object->setSize(w, h);
|
||||
}
|
||||
|
||||
void FGPUIDialog::close()
|
||||
{
|
||||
// no-op for PUI version
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Implementation of FGDialog::PropertyObject.
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -102,6 +102,8 @@ public:
|
|||
*/
|
||||
virtual void update();
|
||||
|
||||
void close() override;
|
||||
|
||||
/**
|
||||
* Recompute the dialog's layout
|
||||
*/
|
||||
|
|
|
@ -63,6 +63,14 @@ public:
|
|||
|
||||
virtual const char *getName() { return ""; }
|
||||
virtual void bringToFront() {}
|
||||
|
||||
/**
|
||||
* @brief Close the dialog. This should actually close the GUI
|
||||
* assets associated, if you want an 'are you sure?' interaction, it
|
||||
* needs to be handled in advance of this interaction.
|
||||
*/
|
||||
virtual void close() = 0;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Construct a new GUI widget configured by a property tree.
|
||||
|
|
|
@ -331,12 +331,19 @@ NewGUI::closeActiveDialog ()
|
|||
if (_active_dialog == 0)
|
||||
return false;
|
||||
|
||||
// TODO support a request-close callback here, optionally
|
||||
// many places in code assume this code-path does an
|
||||
// immediate close, but for some UI paths it would be nice to
|
||||
// allow some dialogs the chance to inervene
|
||||
|
||||
// Kill any entries in _active_dialogs... Is there an STL
|
||||
// algorithm to do (delete map entries by value, not key)? I hate
|
||||
// the STL :) -Andy
|
||||
auto iter = _active_dialogs.begin();
|
||||
for(/**/; iter != _active_dialogs.end(); iter++) {
|
||||
if(iter->second == _active_dialog) {
|
||||
_active_dialog->close();
|
||||
|
||||
_active_dialogs.erase(iter);
|
||||
// iter is no longer valid
|
||||
break;
|
||||
|
|
Loading…
Add table
Reference in a new issue