1
0
Fork 0

PUI: window (FgPopup) handling changes

- I think I've fixed a long standing problem with clicks traveling through windows and bringing the dialog window underneath to the foreground.

- Added /sim/gui/dialogs/current-dialog that contains the name of the currently active (in front) dialog window.

- Changed dialog-open to bring a dialog to the front if it is already open.
This commit is contained in:
Richard Harrison 2018-08-07 18:33:57 +02:00
parent 6513dc1137
commit c13bfe2722
4 changed files with 40 additions and 12 deletions

View file

@ -101,8 +101,8 @@ validate_format(const char *f)
// //
class fgPopup : public puPopup { class fgPopup : public puPopup {
public: public:
fgPopup(int x, int y, bool r = true, bool d = true) : fgPopup(FGPUIDialog *parent_dialog, int x, int y, bool r = true, bool d = true) :
puPopup(x, y), _draggable(d), _resizable(r), _dragging(false) puPopup(x, y), _draggable(d), _resizable(r), _dragging(false), parentDialog(parent_dialog)
{} {}
int checkHit(int b, int up, int x, int y); int checkHit(int b, int up, int x, int y);
int checkKey(int key, int updown); int checkKey(int key, int updown);
@ -114,6 +114,7 @@ public:
private: private:
enum { LEFT = 1, RIGHT = 2, TOP = 4, BOTTOM = 8 }; enum { LEFT = 1, RIGHT = 2, TOP = 4, BOTTOM = 8 };
bool _draggable; bool _draggable;
FGPUIDialog *parentDialog;
bool _resizable; bool _resizable;
bool _dragging; bool _dragging;
int _resizing; int _resizing;
@ -310,9 +311,15 @@ puObject *fgPopup::getActiveInputField(puObject *object)
int fgPopup::checkHit(int button, int updown, int x, int y) int fgPopup::checkHit(int button, int updown, int x, int y)
{ {
int result = 0; int result = 0;
if (updown != PU_DRAG && !_dragging) // still need to ensure that the hit is within this window. The code used to check _dragging
// as well, however that had the unfortunate side effect of allowing clicks to pass through to
// the underlying window. RJH-07-08-18.
if (updown == PU_UP || updown == PU_DOWN){
result = puPopup::checkHit(button, updown, x, y); result = puPopup::checkHit(button, updown, x, y);
if (result && parentDialog) {
fgSetString("/sim/gui/dialogs/current-dialog", parentDialog->getName());
}
}
if (!_draggable) if (!_draggable)
return result; return result;
@ -567,7 +574,6 @@ action_callback (puObject *object)
gui->setActiveDialog(0); gui->setActiveDialog(0);
} }
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// Static helper functions. // Static helper functions.
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
@ -662,7 +668,7 @@ FGPUIDialog::FGPUIDialog (SGPropertyNode *props) :
_needsRelayout(false) _needsRelayout(false)
{ {
_module = string("__dlg:") + props->getStringValue("name", "[unnamed]"); _module = string("__dlg:") + props->getStringValue("name", "[unnamed]");
_name = props->getStringValue("name", "[unnamed]");
SGPropertyNode *nasal = props->getNode("nasal"); SGPropertyNode *nasal = props->getNode("nasal");
if (nasal) { if (nasal) {
_nasal_close = nasal->getNode("close"); _nasal_close = nasal->getNode("close");
@ -710,6 +716,14 @@ FGPUIDialog::~FGPUIDialog ()
} }
} }
void FGPUIDialog::bringToFront() {
puMoveToLast(_object);
}
std::string FGPUIDialog::getName()
{
return _name;
}
void void
FGPUIDialog::updateValues(const std::string& objectName) FGPUIDialog::updateValues(const std::string& objectName)
{ {
@ -833,6 +847,9 @@ FGPUIDialog::display (SGPropertyNode *props)
// configuration file or from the layout widget. // configuration file or from the layout widget.
_object = makeObject(props, screenw, screenh); _object = makeObject(props, screenw, screenh);
//if (_object->getParent())
// _object->getParent()-> //setActiveCallback(FGPUIDialog_active_callback);
// Remove automatically generated properties, so the layout looks // Remove automatically generated properties, so the layout looks
// the same next time around, or restore x and y to preserve negative coords. // the same next time around, or restore x and y to preserve negative coords.
if (userx) if (userx)
@ -880,7 +897,7 @@ FGPUIDialog::makeObject (SGPropertyNode *props, int parentWidth, int parentHeigh
if (props->getBoolValue("modal", false)) if (props->getBoolValue("modal", false))
obj = new puDialogBox(x, y); obj = new puDialogBox(x, y);
else else
obj = new fgPopup(x, y, resizable, draggable); obj = new fgPopup(this, x, y, resizable, draggable);
setupGroup(obj, props, width, height, true); setupGroup(obj, props, width, height, true);
setColor(obj, props); setColor(obj, props);
return obj; return obj;
@ -1084,7 +1101,6 @@ FGPUIDialog::setupObject (puObject *object, SGPropertyNode *props)
object->setLabelPlace(PUPLACE_CENTERED_RIGHT); object->setLabelPlace(PUPLACE_CENTERED_RIGHT);
object->makeReturnDefault(props->getBoolValue("default")); object->makeReturnDefault(props->getBoolValue("default"));
info->node = props; info->node = props;
if (props->hasValue("legend")) { if (props->hasValue("legend")) {
info->legend = props->getStringValue("legend"); info->legend = props->getStringValue("legend");
object->setLegend(info->legend.c_str()); object->setLegend(info->legend.c_str());

View file

@ -100,7 +100,9 @@ public:
void setNeedsLayout() { void setNeedsLayout() {
_needsRelayout = true; _needsRelayout = true;
} }
virtual std::string getName();
virtual void bringToFront();
class ActiveWidget class ActiveWidget
{ {
public: public:
@ -164,6 +166,7 @@ private:
std::string _module; std::string _module;
SGPropertyNode_ptr _nasal_close; SGPropertyNode_ptr _nasal_close;
std::string _name;
// PUI provides no way for userdata to be deleted automatically // PUI provides no way for userdata to be deleted automatically
// with a GUI object, so we have to keep track of all the special // with a GUI object, so we have to keep track of all the special
// data we allocated and then free it manually when the dialog // data we allocated and then free it manually when the dialog

View file

@ -59,6 +59,8 @@ public:
*/ */
virtual void update () = 0; virtual void update () = 0;
virtual std::string getName() { return std::string(); }
virtual void bringToFront() {}
protected: protected:
/** /**
* Construct a new GUI widget configured by a property tree. * Construct a new GUI widget configured by a property tree.

View file

@ -201,16 +201,20 @@ bool
NewGUI::showDialog (const string &name) NewGUI::showDialog (const string &name)
{ {
// first, check if it's already shown // first, check if it's already shown
if (_active_dialogs.find(name) != _active_dialogs.end()) if (_active_dialogs.find(name) != _active_dialogs.end()){
return true; _active_dialogs[name]->bringToFront();
return true;
}
// check we know about the dialog by name // check we know about the dialog by name
if (_dialog_names.find(name) == _dialog_names.end()) { if (_dialog_names.find(name) == _dialog_names.end()) {
SG_LOG(SG_GENERAL, SG_ALERT, "Dialog " << name << " not defined"); SG_LOG(SG_GENERAL, SG_ALERT, "Dialog " << name << " not defined");
return false; return false;
} }
_active_dialogs[name] = new FGPUIDialog(getDialogProperties(name)); _active_dialogs[name] = new FGPUIDialog(getDialogProperties(name));
fgSetString("/sim/gui/dialogs/current-dialog", name);
// setActiveDialog(new FGPUIDialog(getDialogProperties(name)));
return true; return true;
} }
@ -289,6 +293,9 @@ NewGUI::getDialog (const string &name)
void void
NewGUI::setActiveDialog (FGDialog * dialog) NewGUI::setActiveDialog (FGDialog * dialog)
{ {
if (dialog){
fgSetString("/sim/gui/dialogs/current-dialog", dialog->getName());
}
_active_dialog = dialog; _active_dialog = dialog;
} }