X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FGUI%2Fnew_gui.cxx;h=ff9c7ad3c337c370a9ed1d79f66e50589fb83778;hb=1ae2b59333dc914d10bcc726bc94e71cbf3e411e;hp=0e62c99c9cfc3f09111cd98a9217537b86d75ec1;hpb=591001a24e6038bb31d706250e4d96475a46c050;p=flightgear.git diff --git a/src/GUI/new_gui.cxx b/src/GUI/new_gui.cxx index 0e62c99c9..ff9c7ad3c 100644 --- a/src/GUI/new_gui.cxx +++ b/src/GUI/new_gui.cxx @@ -1,4 +1,9 @@ // new_gui.cxx: implementation of XML-configurable GUI support. +#include +#include +#include +#include +#include #include "new_gui.hxx" @@ -7,14 +12,13 @@ #include #include +#include #include
#include "menubar.hxx" #include "dialog.hxx" -SG_USING_STD(map); - extern puFont FONT_HELVETICA_14; extern puFont FONT_SANS_12B; @@ -28,15 +32,17 @@ extern puFont FONT_SANS_12B; NewGUI::NewGUI () - : _font(FONT_HELVETICA_14), - _menubar(new FGMenuBar), + : _menubar(new FGMenuBar), _active_dialog(0) { } NewGUI::~NewGUI () { - clear(); + delete _menubar; + _dialog_props.clear(); + for (_itt_t it = _colors.begin(); it != _colors.end(); ++it) + delete it->second; } void @@ -53,25 +59,48 @@ NewGUI::init () void NewGUI::reinit () +{ + reset(true); + fgSetBool("/sim/signals/reinit-gui", true); +} + +void +NewGUI::redraw () +{ + reset(false); +} + +void +NewGUI::reset (bool reload) { map::iterator iter; vector dlg; // close all open dialogs and remember them ... - for (iter = _active_dialogs.begin(); iter != _active_dialogs.end(); iter++) { + for (iter = _active_dialogs.begin(); iter != _active_dialogs.end(); ++iter) dlg.push_back(iter->first); - closeDialog(iter->first); - } - unbind(); - clear(); + unsigned int i; + for (i = 0; i < dlg.size(); i++) + closeDialog(dlg[i]); + setStyle(); + + unbind(); + delete _menubar; _menubar = new FGMenuBar; - init(); + + if (reload) { + _dialog_props.clear(); + init(); + } else { + _menubar->init(); + } + bind(); - // open remembered dialogs again (no nasal generated ones, unfortunately) -// for (unsigned int i = 0; i < dlg.size(); i++) -// showDialog(dlg[i]); + // open dialogs again + for (i = 0; i < dlg.size(); i++) + showDialog(dlg[i]); } void @@ -144,6 +173,26 @@ NewGUI::closeDialog (const string& name) return false; // dialog wasn't open... } +SGPropertyNode_ptr +NewGUI::getDialogProperties (const string &name) +{ + if(_dialog_props.find(name) != _dialog_props.end()) + return _dialog_props[name]; + + SG_LOG(SG_GENERAL, SG_DEBUG, "dialog '" << name << "' missing"); + return 0; +} + +FGDialog * +NewGUI::getDialog (const string &name) +{ + if(_active_dialogs.find(name) != _active_dialogs.end()) + return _active_dialogs[name]; + + SG_LOG(SG_GENERAL, SG_DEBUG, "dialog '" << name << "' missing"); + return 0; +} + void NewGUI::setActiveDialog (FGDialog * dialog) { @@ -177,14 +226,6 @@ NewGUI::setMenuBarVisible (bool visible) _menubar->hide(); } -void -NewGUI::clear () -{ - delete _menubar; - _menubar = 0; - _dialog_props.clear(); -} - static bool test_extension (const char * path, const char * ext) { @@ -207,7 +248,7 @@ NewGUI::newDialog (SGPropertyNode* props) return; } string name = cname; - if(!_active_dialogs[name]) + if(_active_dialogs.find(name) == _active_dialogs.end()) _dialog_props[name] = props; } @@ -266,91 +307,47 @@ NewGUI::readDir (const char * path) void NewGUI::setStyle (void) { + _itt_t it; + for (it = _colors.begin(); it != _colors.end(); ++it) + delete it->second; _colors.clear(); // set up the traditional colors as default - _colors["background"] = FGColor(0.8f, 0.8f, 0.9f, 0.85f); - _colors["foreground"] = FGColor(0.0f, 0.0f, 0.0f, 1.0f); - _colors["highlight"] = FGColor(0.7f, 0.7f, 0.7f, 1.0f); - _colors["label"] = FGColor(0.0f, 0.0f, 0.0f, 1.0f); - _colors["legend"] = FGColor(0.0f, 0.0f, 0.0f, 1.0f); - _colors["misc"] = FGColor(0.0f, 0.0f, 0.0f, 1.0f); + _colors["background"] = new FGColor(0.8f, 0.8f, 0.9f, 0.85f); + _colors["foreground"] = new FGColor(0.0f, 0.0f, 0.0f, 1.0f); + _colors["highlight"] = new FGColor(0.7f, 0.7f, 0.7f, 1.0f); + _colors["label"] = new FGColor(0.0f, 0.0f, 0.0f, 1.0f); + _colors["legend"] = new FGColor(0.0f, 0.0f, 0.0f, 1.0f); + _colors["misc"] = new FGColor(0.0f, 0.0f, 0.0f, 1.0f); + _colors["inputfield"] = new FGColor(0.8f, 0.7f, 0.7f, 1.0f); //puSetDefaultStyle(); - string path = fgGetString("/sim/current-gui", "/sim/gui"); - string p; + int which = fgGetInt("/sim/gui/current-style", 0); + SGPropertyNode *sim = globals->get_props()->getNode("sim/gui", true); + SGPropertyNode *n = sim->getChild("style", which); + if (!n) + n = sim->getChild("style", 0, true); - p = path + "/font"; - setupFont(fgGetNode(p.c_str(), true)); - - p = path + "/colors"; - SGPropertyNode *n = fgGetNode(p.c_str(), true); + setupFont(n->getNode("fonts/gui", true)); + n = n->getNode("colors", true); for (int i = 0; i < n->nChildren(); i++) { SGPropertyNode *child = n->getChild(i); - _colors[child->getName()] = FGColor(child); + _colors[child->getName()] = new FGColor(child); } - FGColor c = _colors["background"]; - puSetDefaultColourScheme(c.red(), c.green(), c.blue(), c.alpha()); + FGColor *c = _colors["background"]; + puSetDefaultColourScheme(c->red(), c->green(), c->blue(), c->alpha()); } - - -static const struct { - char *name; - puFont *font; -} guifonts[] = { - "default", &FONT_HELVETICA_14, - "FIXED_8x13", &PUFONT_8_BY_13, - "FIXED_9x15", &PUFONT_9_BY_15, - "TIMES_10", &PUFONT_TIMES_ROMAN_10, - "TIMES_24", &PUFONT_TIMES_ROMAN_24, - "HELVETICA_10", &PUFONT_HELVETICA_10, - "HELVETICA_12", &PUFONT_HELVETICA_12, - "HELVETICA_14", &FONT_HELVETICA_14, - "HELVETICA_18", &PUFONT_HELVETICA_18, - "SANS_12B", &FONT_SANS_12B, - 0, 0, -}; - void NewGUI::setupFont (SGPropertyNode *node) { - string fontname = node->getStringValue("name", "Helvetica.txf"); - float size = node->getFloatValue("size", 15.0); - float slant = node->getFloatValue("slant", 0.0); - - int i; - for (i = 0; guifonts[i].name; i++) - if (fontname == guifonts[i].name) - break; - if (guifonts[i].name) - _font = *guifonts[i].font; - else { - SGPath fontpath; - char* envp = ::getenv("FG_FONTS"); - if (envp != NULL) { - fontpath.set(envp); - } else { - fontpath.set(globals->get_fg_root()); - fontpath.append("Fonts"); - } - - SGPath path(fontpath); - path.append(fontname); - - if (_tex_font.load((char *)path.c_str())) { - _font.initialize((fntFont *)&_tex_font, size, slant); - } else { - _font = *guifonts[0].font; - fontname = "default"; - } - } - puSetDefaultFonts(_font, _font); - node->setStringValue("name", fontname.c_str()); + _font = globals->get_fontcache()->get(node); + puSetDefaultFonts(*_font, *_font); + return; } @@ -360,6 +357,12 @@ NewGUI::setupFont (SGPropertyNode *node) // FGColor class. //////////////////////////////////////////////////////////////////////// +void +FGColor::print() const { + std::cerr << "red=" << _red << ", green=" << _green + << ", blue=" << _blue << ", alpha=" << _alpha << std::endl; +} + bool FGColor::merge(const SGPropertyNode *node) { @@ -380,18 +383,200 @@ FGColor::merge(const SGPropertyNode *node) } bool -FGColor::merge(const FGColor& color) +FGColor::merge(const FGColor *color) { bool dirty = false; - if (color._red >= 0.0) - _red = color._red, dirty = true; - if (color._green >= 0.0) - _green = color._green, dirty = true; - if (color._blue >= 0.0) - _blue = color._blue, dirty = true; - if (color._alpha >= 0.0) - _alpha = color._alpha, dirty = true; + if (color && color->_red >= 0.0) + _red = color->_red, dirty = true; + if (color && color->_green >= 0.0) + _green = color->_green, dirty = true; + if (color && color->_blue >= 0.0) + _blue = color->_blue, dirty = true; + if (color && color->_alpha >= 0.0) + _alpha = color->_alpha, dirty = true; return dirty; } + + + +//////////////////////////////////////////////////////////////////////// +// FGFontCache class. +//////////////////////////////////////////////////////////////////////// + +namespace +{ +struct GuiFont +{ + const char *name; + puFont *font; + struct Predicate + : public std::unary_function + { + Predicate(const char* name_) : name(name_) {} + bool operator() (const GuiFont& f1) const + { + return std::strcmp(f1.name, name) == 0; + } + const char* name; + }; +}; + +const GuiFont guifonts[] = { + { "default", &FONT_HELVETICA_14 }, + { "FIXED_8x13", &PUFONT_8_BY_13 }, + { "FIXED_9x15", &PUFONT_9_BY_15 }, + { "TIMES_10", &PUFONT_TIMES_ROMAN_10 }, + { "TIMES_24", &PUFONT_TIMES_ROMAN_24 }, + { "HELVETICA_10", &PUFONT_HELVETICA_10 }, + { "HELVETICA_12", &PUFONT_HELVETICA_12 }, + { "HELVETICA_14", &FONT_HELVETICA_14 }, + { "HELVETICA_18", &PUFONT_HELVETICA_18 }, + { "SANS_12B", &FONT_SANS_12B } +}; + +const GuiFont* guifontsEnd = &guifonts[sizeof(guifonts)/ sizeof(guifonts[0])]; +} + +FGFontCache::FGFontCache() : + _initialized(false) +{ +} + +FGFontCache::~FGFontCache() +{ + PuFontMap::iterator it, end = _puFonts.end(); + for (it = _puFonts.begin(); it != end; ++it) + delete it->second; +} + +inline bool FGFontCache::FntParamsLess::operator()(const FntParams& f1, + const FntParams& f2) const +{ + int comp = f1.name.compare(f2.name); + if (comp < 0) + return true; + else if (comp > 0) + return false; + if (f1.size < f2.size) + return true; + else if (f1.size > f2.size) + return false; + return f1.slant < f2.slant; +} + +struct FGFontCache::fnt * +FGFontCache::getfnt(const char *name, float size, float slant) +{ + string fontName(name); + FntParams fntParams(fontName, size, slant); + PuFontMap::iterator i = _puFonts.find(fntParams); + if (i != _puFonts.end()) + return i->second; + // fntTexFont s are all preloaded into the _texFonts map + TexFontMap::iterator texi = _texFonts.find(fontName); + fntTexFont* texfont = 0; + puFont* pufont = 0; + if (texi != _texFonts.end()) { + texfont = texi->second; + } else { + 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; + } else if (texfont) { + f->texfont = texfont; + f->pufont = new puFont; + f->pufont->initialize(static_cast(f->texfont), size, slant); + } else { + f->pufont = guifonts[0].font; + } + _puFonts[fntParams] = f; + return f; +} + +puFont * +FGFontCache::get(const char *name, float size, float slant) +{ + return getfnt(name, size, slant)->pufont; +} + +fntTexFont * +FGFontCache::getTexFont(const char *name, float size, float slant) +{ + return getfnt(name, size, slant)->texfont; +} + +puFont * +FGFontCache::get(SGPropertyNode *node) +{ + if (!node) + return get("Helvetica.txf", 15.0, 0.0); + + const char *name = node->getStringValue("name", "Helvetica.txf"); + float size = node->getFloatValue("size", 15.0); + float slant = node->getFloatValue("slant", 0.0); + + return get(name, size, slant); +} + +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; + } +} + +SGPath +FGFontCache::getfntpath(const char *name) +{ + init(); + SGPath path(_path); + if (name && std::string(name) != "") { + path.append(name); + if (path.exists()) + return path; + } + + path = SGPath(_path); + path.append("Helvetica.txf"); + + return path; +} + +bool FGFontCache::initializeFonts() +{ + static string fontext("txf"); + init(); + ulDir* fontdir = ulOpenDir(_path.c_str()); + if (!fontdir) + return false; + const ulDirEnt *dirEntry; + while ((dirEntry = ulReadDir(fontdir)) != 0) { + SGPath path(_path); + 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 + delete f; + } + } + ulCloseDir(fontdir); + return true; +} + // end of new_gui.cxx