]> git.mxchange.org Git - flightgear.git/blobdiff - src/GUI/new_gui.cxx
Some autopilot fixes
[flightgear.git] / src / GUI / new_gui.cxx
index 3ac483abcb246dff0266658b8b83be4fbae67e92..220d4c3fcbb35579b3e4bbc4136ddf2354008e33 100644 (file)
@@ -1,29 +1,40 @@
 // new_gui.cxx: implementation of XML-configurable GUI support.
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include "new_gui.hxx"
+
 #include <algorithm>
 #include <iostream>
 #include <cstring>
 #include <sys/types.h>
-#include <plib/ul.h>
-
-#include "new_gui.hxx"
 
 #include <plib/pu.h>
-#include <plib/ul.h>
 
 #include <simgear/compiler.h>
 #include <simgear/structure/exception.hxx>
+#include <simgear/props/props_io.hxx>
+#include <simgear/misc/sg_dir.hxx>
+
+#include <boost/algorithm/string/case_conv.hpp>
 
 #include <Main/fg_props.hxx>
 
+#if defined(SG_UNIX) && !defined(SG_MAC) 
+#include "GL/glx.h"
+#endif
+
 #include "menubar.hxx"
 #include "dialog.hxx"
 
 extern puFont FONT_HELVETICA_14;
 extern puFont FONT_SANS_12B;
 
+using std::map;
+using std::string;
 
-
-\f
 ////////////////////////////////////////////////////////////////////////
 // Implementation of NewGUI.
 ////////////////////////////////////////////////////////////////////////
@@ -48,11 +59,8 @@ void
 NewGUI::init ()
 {
     setStyle();
-    char path1[1024];
-    char path2[1024];
-    ulMakePath(path1, globals->get_fg_root().c_str(), "gui");
-    ulMakePath(path2, path1, "dialogs");
-    readDir(path2);
+    SGPath p(globals->get_fg_root(), "gui/dialogs");
+    readDir(p);
     _menubar->init();
 }
 
@@ -225,19 +233,6 @@ NewGUI::setMenuBarVisible (bool visible)
         _menubar->hide();
 }
 
-static bool
-test_extension (const char * path, const char * ext)
-{
-    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::newDialog (SGPropertyNode* props)
 {
@@ -252,49 +247,31 @@ NewGUI::newDialog (SGPropertyNode* props)
 }
 
 void
-NewGUI::readDir (const char * path)
+NewGUI::readDir (const SGPath& path)
 {
-    ulDir * dir = ulOpenDir(path);
-
-    if (dir == 0) {
-        SG_LOG(SG_GENERAL, SG_ALERT, "Failed to read GUI files from "
-               << path);
-        return;
-    }
-
-    for (ulDirEnt * dirEnt = ulReadDir(dir);
-         dirEnt != 0;
-         dirEnt = ulReadDir(dir)) {
-
-        char subpath[1024];
-
-        ulMakePath(subpath, path, dirEnt->d_name);
-
-        if (!dirEnt->d_isdir && test_extension(subpath, ".xml")) {
-            SGPropertyNode * props = new SGPropertyNode;
-            try {
-                readProperties(subpath, props);
-            } catch (const sg_exception &) {
-                SG_LOG(SG_INPUT, SG_ALERT, "Error parsing dialog "
-                       << subpath);
-                delete props;
-                continue;
-            }
-            SGPropertyNode *nameprop = props->getNode("name");
-            if (!nameprop) {
-                SG_LOG(SG_INPUT, SG_WARN, "dialog " << subpath
-                   << " has no name; skipping.");
-                delete props;
-                continue;
-            }
-            string name = nameprop->getStringValue();
-            if (_dialog_props[name])
-                delete (SGPropertyNode *)_dialog_props[name];
-
-            _dialog_props[name] = props;
-        }
+    simgear::Dir dir(path);
+    simgear::PathList xmls = dir.children(simgear::Dir::TYPE_FILE, ".xml");
+    
+    for (unsigned int i=0; i<xmls.size(); ++i) {
+      SGPropertyNode * props = new SGPropertyNode;
+      try {
+          readProperties(xmls[i].str(), props);
+      } catch (const sg_exception &) {
+          SG_LOG(SG_INPUT, SG_ALERT, "Error parsing dialog "
+                 << xmls[i].str());
+          delete props;
+          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;
+      }
+      string name = nameprop->getStringValue();
+      _dialog_props[name] = props;
     }
-    ulCloseDir(dir);
 }
 
 
@@ -444,6 +421,11 @@ FGFontCache::FGFontCache() :
 
 FGFontCache::~FGFontCache()
 {
+#if defined(SG_UNIX) && !defined(SG_MAC) 
+   // Ugly workaround for a crash on exit with multiple screens configured
+   if (!glXGetCurrentContext())
+      return;
+#endif
    PuFontMap::iterator it, end = _puFonts.end();
    for (it = _puFonts.begin(); it != end; ++it)
        delete it->second;
@@ -467,24 +449,29 @@ inline bool FGFontCache::FntParamsLess::operator()(const FntParams& f1,
 struct FGFontCache::fnt *
 FGFontCache::getfnt(const char *name, float size, float slant)
 {
-    string fontName(name);
+    string fontName = boost::to_lower_copy(string(name));
     FntParams fntParams(fontName, size, slant);
     PuFontMap::iterator i = _puFonts.find(fntParams);
-    if (i != _puFonts.end())
+    if (i != _puFonts.end()) {
+        // found in the puFonts map, all done
         return i->second;
+    }
+    
     // fntTexFont s are all preloaded into the _texFonts map
     TexFontMap::iterator texi = _texFonts.find(fontName);
-    fntTexFont* texfont = 0;
-    puFont* pufont = 0;
+    fntTexFont* texfont = NULL;
+    puFont* pufont = NULL;
     if (texi != _texFonts.end()) {
         texfont = texi->second;
     } else {
+        // check the built-in PUI fonts (in guifonts array)
         const GuiFont* guifont = std::find_if(&guifonts[0], guifontsEnd,
                                               GuiFont::Predicate(name));
         if (guifont != guifontsEnd) {
             pufont = guifont->font;
         }
     }
+    
     fnt* f = new fnt;
     if (pufont) {
         f->pufont = pufont;
@@ -526,16 +513,18 @@ FGFontCache::get(SGPropertyNode *node)
 
 void FGFontCache::init()
 {
-    if (!_initialized) {
-        char *envp = ::getenv("FG_FONTS");
-        if (envp != NULL) {
-            _path.set(envp);
-        } else {
-            _path.set(globals->get_fg_root());
-            _path.append("Fonts");
-        }
-        _initialized = true;
+    if (_initialized) {
+        return;
     }
+    
+    char *envp = ::getenv("FG_FONTS");
+    if (envp != NULL) {
+        _path.set(envp);
+    } else {
+        _path.set(globals->get_fg_root());
+        _path.append("Fonts");
+    }
+    _initialized = true;
 }
 
 SGPath
@@ -551,7 +540,7 @@ FGFontCache::getfntpath(const char *name)
 
     path = SGPath(_path);
     path.append("Helvetica.txf");
-    
+    SG_LOG(SG_GENERAL, SG_WARN, "Unknown font name '" << name << "', defaulting to Helvetica");
     return path;
 }
 
@@ -568,9 +557,11 @@ bool FGFontCache::initializeFonts()
         path.append(dirEntry->d_name);
         if (path.extension() == fontext) {
             fntTexFont* f = new fntTexFont;
-            if (f->load((char *)path.c_str()))
-                _texFonts[string(dirEntry->d_name)] = f;
-            else
+            if (f->load((char *)path.c_str())) {
+                // convert font names in the map to lowercase for matching
+                string fontName = boost::to_lower_copy(string(dirEntry->d_name));
+                _texFonts[fontName] = f;
+            } else
                 delete f;
         }
     }