From: david Date: Sun, 22 Dec 2002 19:52:26 +0000 (+0000) Subject: Reworked the XML-configurable GUI to use the same binding structure as X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=011118315322b4b3186d30fed4ce368ff4430c04;p=flightgear.git Reworked the XML-configurable GUI to use the same binding structure as the keyboard, joystick, mouse, and 2D panel. Exposed methods for applying and updating property values in GUI fields. --- diff --git a/src/GUI/new_gui.cxx b/src/GUI/new_gui.cxx index 53c1900cd..57fad0403 100644 --- a/src/GUI/new_gui.cxx +++ b/src/GUI/new_gui.cxx @@ -23,22 +23,39 @@ SG_USING_STD(vector); static void action_callback (puObject * object) { - GUIData * action = (GUIData *)object->getUserData(); - action->widget->action(action->command); + GUIInfo * info = (GUIInfo *)object->getUserData(); + NewGUI * gui = + (NewGUI *)globals->get_subsystem_mgr() + ->get_group(FGSubsystemMgr::INIT)->get_subsystem("gui"); + gui->setCurrentWidget(info->widget); + for (int i = 0; i < info->bindings.size(); i++) { + std::cerr << "Firing binding " << i << ": " << info->bindings[i]->getCommandName() << std::endl; + info->bindings[i]->fire(); + std::cerr << "done\n"; + } + std::cerr << "All bindings fired\n"; + gui->setCurrentWidget(0); } //////////////////////////////////////////////////////////////////////// -// Implementation of GUIData. +// Implementation of GUIInfo. //////////////////////////////////////////////////////////////////////// -GUIData::GUIData (GUIWidget * w, const char * c) - : widget(w), - command(c) +GUIInfo::GUIInfo (GUIWidget * w) + : widget(w) { } +GUIInfo::~GUIInfo () +{ + for (int i = 0; i < bindings.size(); i++) { + delete bindings[i]; + bindings[i] = 0; + } +} + //////////////////////////////////////////////////////////////////////// @@ -53,61 +70,78 @@ GUIWidget::GUIWidget (SGPropertyNode_ptr props) GUIWidget::~GUIWidget () { + std::cerr << "Destroying widget\n"; delete _object; + + int i; + for (i = 0; i < _info.size(); i++) { + delete _info[i]; + _info[i] = 0; + } + + for (i = 0; i < _propertyObjects.size(); i++) { + delete _propertyObjects[i]; + _propertyObjects[i] = 0; + } } void -GUIWidget::display (SGPropertyNode_ptr props) +GUIWidget::updateValue (const char * objectName) { - if (_object != 0) { - SG_LOG(SG_GENERAL, SG_ALERT, "This widget is already active"); - return; + for (int i = 0; i < _propertyObjects.size(); i++) { + if (_propertyObjects[i]->name == objectName) + _propertyObjects[i]->object + ->setValue(_propertyObjects[i]->node->getStringValue()); } +} - _object = makeObject(props, 1024, 768); - - if (_object != 0) { - _object->reveal(); - } else { - SG_LOG(SG_GENERAL, SG_ALERT, "Widget " - << props->getStringValue("name", "[unnamed]") - << " does not contain a proper GUI definition"); +void +GUIWidget::applyValue (const char * objectName) +{ + for (int i = 0; i < _propertyObjects.size(); i++) { + if (_propertyObjects[i]->name == objectName) + _propertyObjects[i]->node + ->setStringValue(_propertyObjects[i] + ->object->getStringValue()); } } void -GUIWidget::action (const string &command) +GUIWidget::updateValues () { - if (command == "close") { - delete this; - } else if (command == "apply") { - applyProperties(); - updateProperties(); - } else if (command == "update") { - updateProperties(); - } else if (command == "close-apply") { - applyProperties(); - delete this; + for (int i = 0; i < _propertyObjects.size(); i++) { + puObject * object = _propertyObjects[i]->object; + SGPropertyNode_ptr node = _propertyObjects[i]->node; + object->setValue(node->getStringValue()); } } void -GUIWidget::applyProperties () +GUIWidget::applyValues () { for (int i = 0; i < _propertyObjects.size(); i++) { - puObject * object = _propertyObjects[i].object; - SGPropertyNode_ptr node = _propertyObjects[i].node; + puObject * object = _propertyObjects[i]->object; + SGPropertyNode_ptr node = _propertyObjects[i]->node; node->setStringValue(object->getStringValue()); } } void -GUIWidget::updateProperties () +GUIWidget::display (SGPropertyNode_ptr props) { - for (int i = 0; i < _propertyObjects.size(); i++) { - puObject * object = _propertyObjects[i].object; - SGPropertyNode_ptr node = _propertyObjects[i].node; - object->setValue(node->getStringValue()); + if (_object != 0) { + SG_LOG(SG_GENERAL, SG_ALERT, "This widget is already active"); + return; + } + + _object = makeObject(props, 1024, 768); + + if (_object != 0) { + _object->reveal(); + } else { + SG_LOG(SG_GENERAL, SG_ALERT, "Widget " + << props->getStringValue("name", "[unnamed]") + << " does not contain a proper GUI definition"); } } @@ -171,17 +205,26 @@ GUIWidget::setupObject (puObject * object, SGPropertyNode * props) if (props->hasValue("label")) object->setLabel(props->getStringValue("label")); - if (props->hasValue("default-value-prop")) { - const char * name = props->getStringValue("default-value-prop"); - SGPropertyNode_ptr node = fgGetNode(name, true); + if (props->hasValue("property")) { + const char * name = props->getStringValue("name"); + if (name == 0) + name = ""; + const char * propname = props->getStringValue("property"); + SGPropertyNode_ptr node = fgGetNode(propname, true); object->setValue(node->getStringValue()); - _propertyObjects.push_back(PropertyObject(object, node)); + if (name != 0) + _propertyObjects.push_back(new PropertyObject(name, object, node)); } - if (props->hasValue("action")) { - _actions.push_back(GUIData(this, props->getStringValue("action"))); - object->setUserData(&_actions[_actions.size()-1]); + vector nodes = props->getChildren("binding"); + if (nodes.size() > 0) { + GUIInfo * info = new GUIInfo(this); + + for (int i = 0; i < nodes.size(); i++) + info->bindings.push_back(new FGBinding(nodes[i])); object->setCallback(action_callback); + object->setUserData(info); + _info.push_back(info); } object->makeReturnDefault(props->getBoolValue("default")); @@ -202,9 +245,12 @@ GUIWidget::setupGroup (puGroup * group, SGPropertyNode * props, group->close(); } -GUIWidget::PropertyObject::PropertyObject (puObject * o, SGPropertyNode_ptr n) - : object(o), - node(n) +GUIWidget::PropertyObject::PropertyObject (const char * n, + puObject * o, + SGPropertyNode_ptr p) + : name(n), + object(o), + node(p) { } @@ -216,6 +262,7 @@ GUIWidget::PropertyObject::PropertyObject (puObject * o, SGPropertyNode_ptr n) NewGUI::NewGUI () + : _current_widget(0) { } @@ -243,7 +290,19 @@ NewGUI::display (const string &name) if (_widgets.find(name) == _widgets.end()) SG_LOG(SG_GENERAL, SG_ALERT, "Dialog " << name << " not defined"); else - new GUIWidget(_widgets[name]); // PUI will delete it + new GUIWidget(_widgets[name]); +} + +void +NewGUI::setCurrentWidget (GUIWidget * widget) +{ + _current_widget = widget; +} + +GUIWidget * +NewGUI::getCurrentWidget () +{ + return _current_widget; } void diff --git a/src/GUI/new_gui.hxx b/src/GUI/new_gui.hxx index 6baf15b82..91a6aa3df 100644 --- a/src/GUI/new_gui.hxx +++ b/src/GUI/new_gui.hxx @@ -19,19 +19,22 @@ SG_USING_STD(vector); SG_USING_STD(map); #include
- +#include
+#include class GUIWidget; /** - * User data attached to a GUI object. + * Information about a GUI widget. */ -struct GUIData +struct GUIInfo { - GUIData (GUIWidget * w, const char * a); + GUIInfo (GUIWidget * w); + virtual ~GUIInfo (); + GUIWidget * widget; - string command; + vector bindings; }; @@ -41,16 +44,62 @@ struct GUIData class GUIWidget { public: + + + /** + * Construct a new GUI widget configured by a property tree. + */ GUIWidget (SGPropertyNode_ptr props); + + + /** + * Destructor. + */ virtual ~GUIWidget (); - virtual void action (const string &command); + + /** + * Update the values of all GUI objects with a specific name. + * + * This method copies from the property to the GUI object. + * + * @param objectName The name of the GUI object(s) to update. + * Use the empty name for all unnamed objects. + */ + virtual void updateValue (const char * objectName); + + + /** + * Apply the values of all GUI objects with a specific name. + * + * This method copies from the GUI object to the property. + * + * @param objectName The name of the GUI object(s) to update. + * Use the empty name for all unnamed objects. + */ + virtual void applyValue (const char * objectName); + + + /** + * Update the values of all GUI objects. + * + * This method copies from the properties to the GUI objects. + */ + virtual void updateValues (); + + + /** + * Apply the values of all GUI objects. + * + * This method copies from the GUI objects to the properties. + */ + virtual void applyValues (); + private: GUIWidget (const GUIWidget &); // just for safety + void display (SGPropertyNode_ptr props); - virtual void updateProperties (); - virtual void applyProperties (); puObject * makeObject (SGPropertyNode * props, int parentWidth, int parentHeight); void setupObject (puObject * object, SGPropertyNode * props); @@ -58,13 +107,16 @@ private: int width, int height, bool makeFrame = false); puObject * _object; - vector _actions; + vector _info; struct PropertyObject { - PropertyObject (puObject * object, SGPropertyNode_ptr node); + PropertyObject (const char * name, + puObject * object, + SGPropertyNode_ptr node); + string name; puObject * object; SGPropertyNode_ptr node; }; - vector _propertyObjects; + vector _propertyObjects; }; @@ -78,14 +130,20 @@ public: virtual void update (double delta_time_sec); virtual void display (const string &name); + virtual void setCurrentWidget (GUIWidget * widget); + virtual GUIWidget * getCurrentWidget (); + + private: void readDir (const char * path); + GUIWidget * _current_widget; map _widgets; }; + #endif // __NEW_GUI_HXX // end of new_gui.hxx