X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FGUI%2Fnew_gui.cxx;h=8a3a12f3c9bd120f683ef1ac72c66d0844853578;hb=897f295988b446d50b099a51d81df20df88a3a60;hp=90cff403d7c2ea9a346ea9d5448a1a6f6a6bc3f2;hpb=63672604bf0323dfc6d5cba0eb7b30240fcf07be;p=flightgear.git diff --git a/src/GUI/new_gui.cxx b/src/GUI/new_gui.cxx index 90cff403d..8a3a12f3c 100644 --- a/src/GUI/new_gui.cxx +++ b/src/GUI/new_gui.cxx @@ -5,299 +5,182 @@ #include #include -#include -SG_USING_STD(vector); +#include +#include -#include #include
+#include "menubar.hxx" +#include "dialog.hxx" - -//////////////////////////////////////////////////////////////////////// -// Callbacks. -//////////////////////////////////////////////////////////////////////// - -/** - * Action callback. - */ -static void -action_callback (puObject * object) -{ - 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++) - info->bindings[i]->fire(); - gui->setCurrentWidget(0); -} - +SG_USING_STD(map); //////////////////////////////////////////////////////////////////////// -// Implementation of GUIInfo. +// Implementation of NewGUI. //////////////////////////////////////////////////////////////////////// -GUIInfo::GUIInfo (GUIWidget * w) - : widget(w) -{ -} -GUIInfo::~GUIInfo () +NewGUI::NewGUI () + : _menubar(new FGMenuBar), + _active_dialog(0) { - for (int i = 0; i < bindings.size(); i++) { - delete bindings[i]; - bindings[i] = 0; - } } - - -//////////////////////////////////////////////////////////////////////// -// Implementation of GUIWidget. -//////////////////////////////////////////////////////////////////////// - -GUIWidget::GUIWidget (SGPropertyNode_ptr props) - : _object(0) +NewGUI::~NewGUI () { - display(props); + clear(); } -GUIWidget::~GUIWidget () +void +NewGUI::init () { - 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; - } + char path1[1024]; + char path2[1024]; + ulMakePath(path1, globals->get_fg_root().c_str(), "gui"); + ulMakePath(path2, path1, "dialogs"); + readDir(path2); + _menubar->init(); } void -GUIWidget::updateValue (const char * objectName) +NewGUI::reinit () { - for (int i = 0; i < _propertyObjects.size(); i++) { - if (_propertyObjects[i]->name == objectName) - _propertyObjects[i]->object - ->setValue(_propertyObjects[i]->node->getStringValue()); - } + unbind(); + clear(); + _menubar = new FGMenuBar; + init(); + bind(); } void -GUIWidget::applyValue (const char * objectName) +NewGUI::bind () { - for (int i = 0; i < _propertyObjects.size(); i++) { - if (_propertyObjects[i]->name == objectName) - _propertyObjects[i]->node - ->setStringValue(_propertyObjects[i] - ->object->getStringValue()); - } + fgTie("/sim/menubar/visibility", this, + &NewGUI::getMenuBarVisible, &NewGUI::setMenuBarVisible); } void -GUIWidget::updateValues () +NewGUI::unbind () { - for (int i = 0; i < _propertyObjects.size(); i++) { - puObject * object = _propertyObjects[i]->object; - SGPropertyNode_ptr node = _propertyObjects[i]->node; - object->setValue(node->getStringValue()); - } + fgUntie("/sim/menubar/visibility"); } void -GUIWidget::applyValues () +NewGUI::update (double delta_time_sec) { - for (int i = 0; i < _propertyObjects.size(); i++) { - puObject * object = _propertyObjects[i]->object; - SGPropertyNode_ptr node = _propertyObjects[i]->node; - node->setStringValue(object->getStringValue()); - } + // NO OP } -void -GUIWidget::display (SGPropertyNode_ptr props) +bool +NewGUI::showDialog (const string &name) { - 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(); + if (_dialog_props.find(name) == _dialog_props.end()) { + SG_LOG(SG_GENERAL, SG_ALERT, "Dialog " << name << " not defined"); + return false; } else { - SG_LOG(SG_GENERAL, SG_ALERT, "Widget " - << props->getStringValue("name", "[unnamed]") - << " does not contain a proper GUI definition"); + if(!_active_dialogs[name]) + _active_dialogs[name] = new FGDialog(_dialog_props[name]); + return true; } } -puObject * -GUIWidget::makeObject (SGPropertyNode * props, int parentWidth, int parentHeight) +bool +NewGUI::closeActiveDialog () { - int width = props->getIntValue("width", parentWidth); - int height = props->getIntValue("height", parentHeight); - - int x = props->getIntValue("x", (parentWidth - width) / 2); - int y = props->getIntValue("y", (parentHeight - height) / 2); - - string type = props->getName(); - if (type == "") - type = props->getStringValue("type"); - if (type == "") { - SG_LOG(SG_GENERAL, SG_ALERT, "No type specified for GUI object"); - return 0; - } + if (_active_dialog == 0) + return false; - if (type == "dialog") { - puPopup * dialog; - if (props->getBoolValue("modal", false)) - dialog = new puDialogBox(x, y); - else - dialog = new puPopup(x, y); - setupGroup(dialog, props, width, height, true); - return dialog; - } else if (type == "group") { - puGroup * group = new puGroup(x, y); - setupGroup(group, props, width, height, false); - return group; - } else if (type == "input") { - puInput * input = new puInput(x, y, x + width, y + height); - setupObject(input, props); - return input; - } else if (type == "text") { - puText * text = new puText(x, y); - setupObject(text, props); - return text; - } else if (type == "button") { - puButton * b; - const char * legend = props->getStringValue("legend", "[none]"); - if (props->getBoolValue("one-shot", true)) - b = new puOneShot(x, y, legend); - else - b = new puButton(x, y, legend); - setupObject(b, props); - return b; - } else { - return 0; - } + // 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 + map::iterator iter = _active_dialogs.begin(); + for(/**/; iter != _active_dialogs.end(); iter++) + if(iter->second == _active_dialog) + _active_dialogs.erase(iter); + + delete _active_dialog; + _active_dialog = 0; + return true; } -void -GUIWidget::setupObject (puObject * object, SGPropertyNode * props) +bool +NewGUI::closeDialog (const string& name) { - if (props->hasValue("legend")) - object->setLegend(props->getStringValue("legend")); - - if (props->hasValue("label")) - object->setLabel(props->getStringValue("label")); - - 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()); - if (name != 0) - _propertyObjects.push_back(new PropertyObject(name, object, node)); - } - - 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); + if(_active_dialogs.find(name) != _active_dialogs.end()) { + if(_active_dialog == _active_dialogs[name]) + _active_dialog = 0; + delete _active_dialogs[name]; + _active_dialogs.erase(name); + return true; } - - object->makeReturnDefault(props->getBoolValue("default")); + return false; // dialog wasn't open... } void -GUIWidget::setupGroup (puGroup * group, SGPropertyNode * props, - int width, int height, bool makeFrame) +NewGUI::setActiveDialog (FGDialog * dialog) { - setupObject(group, props); - - if (makeFrame) - new puFrame(0, 0, width, height); - - int nChildren = props->nChildren(); - for (int i = 0; i < nChildren; i++) - makeObject(props->getChild(i), width, height); - group->close(); + _active_dialog = dialog; } -GUIWidget::PropertyObject::PropertyObject (const char * n, - puObject * o, - SGPropertyNode_ptr p) - : name(n), - object(o), - node(p) +FGDialog * +NewGUI::getActiveDialog () { + return _active_dialog; } - - -//////////////////////////////////////////////////////////////////////// -// Implementation of NewGUI. -//////////////////////////////////////////////////////////////////////// - - -NewGUI::NewGUI () - : _current_widget(0) +FGMenuBar * +NewGUI::getMenuBar () { + return _menubar; } -NewGUI::~NewGUI () +bool +NewGUI::getMenuBarVisible () const { + return _menubar->isVisible(); } void -NewGUI::init () +NewGUI::setMenuBarVisible (bool visible) { - char path[1024]; - ulMakePath(path, getenv("FG_ROOT"), "gui"); - readDir(path); + if (visible) + _menubar->show(); + else + _menubar->hide(); } void -NewGUI::update (double delta_time_sec) +NewGUI::clear () { - // NO OP + delete _menubar; + _menubar = 0; + _dialog_props.clear(); } -void -NewGUI::display (const string &name) +static bool +test_extension (const char * path, const char * ext) { - if (_widgets.find(name) == _widgets.end()) - SG_LOG(SG_GENERAL, SG_ALERT, "Dialog " << name << " not defined"); - else - new GUIWidget(_widgets[name]); + int pathlen = strlen(path); + int extlen = strlen(ext); + + for (int i = 1; i <= pathlen && i <= extlen; i++) { + if (path[pathlen-i] != ext[extlen-i]) + return false; + } + return true; } void -NewGUI::setCurrentWidget (GUIWidget * widget) -{ - _current_widget = widget; -} - -GUIWidget * -NewGUI::getCurrentWidget () +NewGUI::newDialog (SGPropertyNode* props) { - return _current_widget; + const char* cname = props->getStringValue("name"); + if(!cname) { + SG_LOG(SG_GENERAL, SG_ALERT, "New dialog has no property"); + return; + } + string name = props->getStringValue("name"); + _dialog_props[name] = props; } void @@ -311,32 +194,32 @@ NewGUI::readDir (const char * path) return; } - ulDirEnt * dirEnt = ulReadDir(dir); - while (dirEnt != 0) { + for (ulDirEnt * dirEnt = ulReadDir(dir); + dirEnt != 0; + dirEnt = ulReadDir(dir)) { + char subpath[1024]; ulMakePath(subpath, path, dirEnt->d_name); - if (dirEnt->d_isdir && dirEnt->d_name[0] != '.') { - readDir(subpath); - } else { - SGPropertyNode_ptr props = new SGPropertyNode; + if (!dirEnt->d_isdir && test_extension(subpath, ".xml")) { + SGPropertyNode * props = new SGPropertyNode; try { readProperties(subpath, props); } catch (const sg_exception &ex) { - SG_LOG(SG_INPUT, SG_ALERT, "Error parsing GUI file " + SG_LOG(SG_INPUT, SG_ALERT, "Error parsing dialog " << subpath); + delete props; + continue; } if (!props->hasValue("name")) { - SG_LOG(SG_INPUT, SG_WARN, "GUI file " << subpath + SG_LOG(SG_INPUT, SG_WARN, "dialog " << subpath << " has no name; skipping."); - } else { - string name = props->getStringValue("name"); - SG_LOG(SG_INPUT, SG_BULK, "Saving GUI node " << name); - _widgets[name] = props; + delete props; + continue; } + newDialog(props); } - dirEnt = ulReadDir(dir); } ulCloseDir(dir); }