X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FGUI%2Fnew_gui.cxx;h=bb8eb52dba624941d88c664b9c1f198935811ff4;hb=4befe0e6ea6b5f21119364f1175a0b6c8e97395c;hp=c13456068ba39ca860d08ff393669c0e021a3b4c;hpb=9e344ee64594e4932e11227a95e6efcafad1cd86;p=flightgear.git diff --git a/src/GUI/new_gui.cxx b/src/GUI/new_gui.cxx index c13456068..bb8eb52db 100644 --- a/src/GUI/new_gui.cxx +++ b/src/GUI/new_gui.cxx @@ -19,6 +19,7 @@ #include #include +#include #include
@@ -32,10 +33,17 @@ #include "FGCocoaMenuBar.hxx" #endif +#if defined(SG_WINDOWS) +#include "FGWindowsMenuBar.hxx" +#endif + #include "FGPUIDialog.hxx" #include "FGFontCache.hxx" #include "FGColor.hxx" +// ignore the word Navaid here, it's a DataCache +#include + using std::map; using std::string; @@ -48,16 +56,10 @@ using std::string; NewGUI::NewGUI () : _active_dialog(0) { -#if defined(SG_MAC) - _menubar.reset(new FGCocoaMenuBar); -#else - _menubar.reset(new FGPUIMenuBar); -#endif } NewGUI::~NewGUI () { - _dialog_props.clear(); for (_itt_t it = _colors.begin(); it != _colors.end(); ++it) delete it->second; } @@ -65,12 +67,38 @@ NewGUI::~NewGUI () void NewGUI::init () { + createMenuBarImplementation(); + fgTie("/sim/menubar/visibility", this, + &NewGUI::getMenuBarVisible, &NewGUI::setMenuBarVisible); + setStyle(); SGPath p(globals->get_fg_root(), "gui/dialogs"); readDir(p); + + SGPath aircraftDialogDir(string(fgGetString("/sim/aircraft-dir")), "gui/dialogs"); + if (aircraftDialogDir.exists()) { + readDir(aircraftDialogDir); + } + + // Fix for http://code.google.com/p/flightgear-bugs/issues/detail?id=947 + fgGetNode("sim/menubar")->setAttribute(SGPropertyNode::PRESERVE, true); _menubar->init(); } +void +NewGUI::shutdown() +{ + DialogDict::iterator it = _active_dialogs.begin(); + for (; it != _active_dialogs.end(); ++it) { + delete it->second; + } + _active_dialogs.clear(); + + fgUntie("/sim/menubar/visibility"); + _menubar.reset(); + _dialog_props.clear(); +} + void NewGUI::reinit () { @@ -84,56 +112,72 @@ NewGUI::redraw () reset(false); } +void +NewGUI::createMenuBarImplementation() +{ +#if defined(SG_MAC) + if (fgGetBool("/sim/menubar/native", true)) { + _menubar.reset(new FGCocoaMenuBar); + } +#endif +#if defined(SG_WINDOWS) + if (fgGetBool("/sim/menubar/native", true)) { + // Windows-native menubar disabled for the moment, fall-through + // to PUI version + // _menubar.reset(new FGWindowsMenuBar); + } +#endif + if (!_menubar.get()) { + _menubar.reset(new FGPUIMenuBar); + } +} + void NewGUI::reset (bool reload) { - map::iterator iter; - std::vector dlg; + DialogDict::iterator iter; + string_list openDialogs; // close all open dialogs and remember them ... for (iter = _active_dialogs.begin(); iter != _active_dialogs.end(); ++iter) - dlg.push_back(iter->first); + openDialogs.push_back(iter->first); - unsigned int i; - for (i = 0; i < dlg.size(); i++) - closeDialog(dlg[i]); + BOOST_FOREACH(string d, openDialogs) + closeDialog(d); setStyle(); unbind(); -#if !defined(SG_MAC) - _menubar.reset(new FGPUIMenuBar); -#endif if (reload) { _dialog_props.clear(); + _dialog_names.clear(); init(); } else { + createMenuBarImplementation(); _menubar->init(); } bind(); // open dialogs again - for (i = 0; i < dlg.size(); i++) - showDialog(dlg[i]); + BOOST_FOREACH(string d, openDialogs) + showDialog(d); } void NewGUI::bind () { - fgTie("/sim/menubar/visibility", this, - &NewGUI::getMenuBarVisible, &NewGUI::setMenuBarVisible); } void NewGUI::unbind () { - fgUntie("/sim/menubar/visibility"); } void NewGUI::update (double delta_time_sec) { + SG_UNUSED(delta_time_sec); map::iterator iter = _active_dialogs.begin(); for(/**/; iter != _active_dialogs.end(); iter++) iter->second->update(); @@ -142,14 +186,18 @@ NewGUI::update (double delta_time_sec) bool NewGUI::showDialog (const string &name) { - if (_dialog_props.find(name) == _dialog_props.end()) { + // first, check if it's already shown + if (_active_dialogs.find(name) != _active_dialogs.end()) + return true; + + // check we know about the dialog by name + if (_dialog_names.find(name) == _dialog_names.end()) { SG_LOG(SG_GENERAL, SG_ALERT, "Dialog " << name << " not defined"); return false; - } else { - if(!_active_dialogs[name]) - _active_dialogs[name] = new FGPUIDialog(_dialog_props[name]); - return true; } + + _active_dialogs[name] = new FGPUIDialog(getDialogProperties(name)); + return true; } bool @@ -191,11 +239,27 @@ NewGUI::closeDialog (const string& name) SGPropertyNode_ptr NewGUI::getDialogProperties (const string &name) { - if(_dialog_props.find(name) != _dialog_props.end()) - return _dialog_props[name]; + if (_dialog_names.find(name) == _dialog_names.end()) { + SG_LOG(SG_GENERAL, SG_ALERT, "Dialog " << name << " not defined"); + return NULL; + } + + NameDialogDict::iterator it = _dialog_props.find(name); + if (it == _dialog_props.end()) { + // load the XML + SGPath path = _dialog_names[name]; + SGPropertyNode_ptr props = new SGPropertyNode; + try { + readProperties(path.str(), props); + } catch (const sg_exception &) { + SG_LOG(SG_INPUT, SG_ALERT, "Error parsing dialog " << path); + return NULL; + } + + it = _dialog_props.insert(it, std::make_pair(name, props)); + } - SG_LOG(SG_GENERAL, SG_DEBUG, "dialog '" << name << "' missing"); - return 0; + return it->second; } FGDialog * @@ -250,40 +314,62 @@ NewGUI::newDialog (SGPropertyNode* props) return; } string name = cname; - if(_active_dialogs.find(name) == _active_dialogs.end()) + + if(_active_dialogs.find(name) == _active_dialogs.end()) { _dialog_props[name] = props; + // add a dummy path entry, so we believe the dialog exists + _dialog_names[name] = SGPath(); + } } void NewGUI::readDir (const SGPath& path) { simgear::Dir dir(path); + if( !dir.exists() ) + { + SG_LOG(SG_INPUT, SG_INFO, "directory does not exist: " << path.str()); + return; + } + + flightgear::NavDataCache* cache = flightgear::NavDataCache::instance(); + flightgear::NavDataCache::Transaction txn(cache); simgear::PathList xmls = dir.children(simgear::Dir::TYPE_FILE, ".xml"); - for (unsigned int i=0; iisCachedFileModified(xmlPath)) { + // cached, easy + string name = cache->readStringProperty(xmlPath.str()); + _dialog_names[name] = xmlPath; + continue; + } + + // we need to parse the actual XML + SGPropertyNode_ptr props = new SGPropertyNode; try { - readProperties(xmls[i].str(), props); + readProperties(xmlPath.str(), props); } catch (const sg_exception &) { - SG_LOG(SG_INPUT, SG_ALERT, "Error parsing dialog " - << xmls[i].str()); - delete props; - continue; + SG_LOG(SG_INPUT, SG_ALERT, "Error parsing dialog " << xmlPath); + continue; } + SGPropertyNode *nameprop = props->getNode("name"); if (!nameprop) { - SG_LOG(SG_INPUT, SG_WARN, "dialog " << xmls[i].str() - << " has no name; skipping."); - delete props; - continue; + SG_LOG(SG_INPUT, SG_WARN, "dialog " << xmlPath << " has no name; skipping."); + continue; } + string name = nameprop->getStringValue(); - _dialog_props[name] = props; - } -} - - - + _dialog_names[name] = xmlPath; + // update cached values + if (!cache->isReadOnly()) { + cache->stampCacheFile(xmlPath); + cache->writeStringProperty(xmlPath.str(), name); + } + } // of directory children iteration + + txn.commit(); +} //////////////////////////////////////////////////////////////////////// // Style handling. //////////////////////////////////////////////////////////////////////// @@ -329,7 +415,7 @@ NewGUI::setStyle (void) void NewGUI::setupFont (SGPropertyNode *node) { - _font = globals->get_fontcache()->get(node); + _font = FGFontCache::instance()->get(node); puSetDefaultFonts(*_font, *_font); return; }