]> git.mxchange.org Git - flightgear.git/blob - src/GUI/new_gui.cxx
Clean-up: move autosave.xml loading code to proper method
[flightgear.git] / src / GUI / new_gui.cxx
1 // new_gui.cxx: implementation of XML-configurable GUI support.
2
3 #ifdef HAVE_CONFIG_H
4 #  include <config.h>
5 #endif
6
7 #include "new_gui.hxx"
8
9 #include <algorithm>
10 #include <iostream>
11 #include <cstring>
12 #include <sys/types.h>
13
14 #include <plib/pu.h>
15
16 #include <simgear/compiler.h>
17 #include <simgear/structure/exception.hxx>
18 #include <simgear/props/props_io.hxx>
19 #include <simgear/misc/sg_dir.hxx>
20
21 #include <boost/algorithm/string/case_conv.hpp>
22
23 #include <Main/fg_props.hxx>
24
25 #if defined(SG_UNIX) && !defined(SG_MAC) 
26 #include "GL/glx.h"
27 #endif
28
29 #include "FGPUIMenuBar.hxx"
30
31 #if defined(SG_MAC)
32 #include "FGCocoaMenuBar.hxx"
33 #endif
34
35 #include "FGPUIDialog.hxx"
36 #include "FGFontCache.hxx"
37 #include "FGColor.hxx"
38
39 using std::map;
40 using std::string;
41
42 ////////////////////////////////////////////////////////////////////////
43 // Implementation of NewGUI.
44 ////////////////////////////////////////////////////////////////////////
45
46
47
48 NewGUI::NewGUI () :
49   _active_dialog(0)
50 {
51 #if defined(SG_MAC)
52   _menubar.reset(new FGCocoaMenuBar);
53 #else
54   _menubar.reset(new FGPUIMenuBar);
55 #endif
56 }
57
58 NewGUI::~NewGUI ()
59 {
60     _dialog_props.clear();
61     for (_itt_t it = _colors.begin(); it != _colors.end(); ++it)
62         delete it->second;
63 }
64
65 void
66 NewGUI::init ()
67 {
68     setStyle();
69     SGPath p(globals->get_fg_root(), "gui/dialogs");
70     readDir(p);
71     _menubar->init();
72 }
73
74 void
75 NewGUI::reinit ()
76 {
77     reset(true);
78     fgSetBool("/sim/signals/reinit-gui", true);
79 }
80
81 void
82 NewGUI::redraw ()
83 {
84     reset(false);
85 }
86
87 void
88 NewGUI::reset (bool reload)
89 {
90     map<string,FGDialog *>::iterator iter;
91     std::vector<string> dlg;
92     // close all open dialogs and remember them ...
93     for (iter = _active_dialogs.begin(); iter != _active_dialogs.end(); ++iter)
94         dlg.push_back(iter->first);
95
96     unsigned int i;
97     for (i = 0; i < dlg.size(); i++)
98         closeDialog(dlg[i]);
99
100     setStyle();
101
102     unbind();
103 #if !defined(SG_MAC)
104     _menubar.reset(new FGPUIMenuBar);
105 #endif
106
107     if (reload) {
108         _dialog_props.clear();
109         init();
110     } else {
111         _menubar->init();
112     }
113
114     bind();
115
116     // open dialogs again
117     for (i = 0; i < dlg.size(); i++)
118         showDialog(dlg[i]);
119 }
120
121 void
122 NewGUI::bind ()
123 {
124     fgTie("/sim/menubar/visibility", this,
125           &NewGUI::getMenuBarVisible, &NewGUI::setMenuBarVisible);
126 }
127
128 void
129 NewGUI::unbind ()
130 {
131     fgUntie("/sim/menubar/visibility");
132 }
133
134 void
135 NewGUI::update (double delta_time_sec)
136 {
137     map<string,FGDialog *>::iterator iter = _active_dialogs.begin();
138     for(/**/; iter != _active_dialogs.end(); iter++)
139         iter->second->update();
140 }
141
142 bool
143 NewGUI::showDialog (const string &name)
144 {
145     if (_dialog_props.find(name) == _dialog_props.end()) {
146         SG_LOG(SG_GENERAL, SG_ALERT, "Dialog " << name << " not defined");
147         return false;
148     } else {
149         if(!_active_dialogs[name])
150             _active_dialogs[name] = new FGPUIDialog(_dialog_props[name]);
151         return true;
152     }
153 }
154
155 bool
156 NewGUI::closeActiveDialog ()
157 {
158     if (_active_dialog == 0)
159         return false;
160
161     // Kill any entries in _active_dialogs...  Is there an STL
162     // algorithm to do (delete map entries by value, not key)?  I hate
163     // the STL :) -Andy
164     map<string,FGDialog *>::iterator iter = _active_dialogs.begin();
165     for(/**/; iter != _active_dialogs.end(); iter++) {
166         if(iter->second == _active_dialog) {
167             _active_dialogs.erase(iter);
168             // iter is no longer valid
169             break;
170         }
171     }
172
173     delete _active_dialog;
174     _active_dialog = 0;
175     return true;
176 }
177
178 bool
179 NewGUI::closeDialog (const string& name)
180 {
181     if(_active_dialogs.find(name) != _active_dialogs.end()) {
182         if(_active_dialog == _active_dialogs[name])
183             _active_dialog = 0;
184         delete _active_dialogs[name];
185         _active_dialogs.erase(name);
186         return true;
187     }
188     return false; // dialog wasn't open...
189 }
190
191 SGPropertyNode_ptr
192 NewGUI::getDialogProperties (const string &name)
193 {
194     if(_dialog_props.find(name) != _dialog_props.end())
195         return _dialog_props[name];
196
197     SG_LOG(SG_GENERAL, SG_DEBUG, "dialog '" << name << "' missing");
198     return 0;
199 }
200
201 FGDialog *
202 NewGUI::getDialog (const string &name)
203 {
204     if(_active_dialogs.find(name) != _active_dialogs.end())
205         return _active_dialogs[name];
206
207     SG_LOG(SG_GENERAL, SG_DEBUG, "dialog '" << name << "' missing");
208     return 0;
209 }
210
211 void
212 NewGUI::setActiveDialog (FGDialog * dialog)
213 {
214     _active_dialog = dialog;
215 }
216
217 FGDialog *
218 NewGUI::getActiveDialog ()
219 {
220     return _active_dialog;
221 }
222
223 FGMenuBar *
224 NewGUI::getMenuBar ()
225 {
226     return _menubar.get();
227 }
228
229 bool
230 NewGUI::getMenuBarVisible () const
231 {
232     return _menubar->isVisible();
233 }
234
235 void
236 NewGUI::setMenuBarVisible (bool visible)
237 {
238     if (visible)
239         _menubar->show();
240     else
241         _menubar->hide();
242 }
243
244 void
245 NewGUI::newDialog (SGPropertyNode* props)
246 {
247     const char* cname = props->getStringValue("name");
248     if(!cname) {
249         SG_LOG(SG_GENERAL, SG_ALERT, "New dialog has no <name> property");
250         return;
251     }
252     string name = cname;
253     if(_active_dialogs.find(name) == _active_dialogs.end())
254         _dialog_props[name] = props;
255 }
256
257 void
258 NewGUI::readDir (const SGPath& path)
259 {
260     simgear::Dir dir(path);
261     simgear::PathList xmls = dir.children(simgear::Dir::TYPE_FILE, ".xml");
262     
263     for (unsigned int i=0; i<xmls.size(); ++i) {
264       SGPropertyNode * props = new SGPropertyNode;
265       try {
266           readProperties(xmls[i].str(), props);
267       } catch (const sg_exception &) {
268           SG_LOG(SG_INPUT, SG_ALERT, "Error parsing dialog "
269                  << xmls[i].str());
270           delete props;
271           continue;
272       }
273       SGPropertyNode *nameprop = props->getNode("name");
274       if (!nameprop) {
275           SG_LOG(SG_INPUT, SG_WARN, "dialog " << xmls[i].str()
276              << " has no name; skipping.");
277           delete props;
278           continue;
279       }
280       string name = nameprop->getStringValue();
281       _dialog_props[name] = props;
282     }
283 }
284
285
286 \f
287 ////////////////////////////////////////////////////////////////////////
288 // Style handling.
289 ////////////////////////////////////////////////////////////////////////
290
291 void
292 NewGUI::setStyle (void)
293 {
294     _itt_t it;
295     for (it = _colors.begin(); it != _colors.end(); ++it)
296       delete it->second;
297     _colors.clear();
298
299     // set up the traditional colors as default
300     _colors["background"] = new FGColor(0.8f, 0.8f, 0.9f, 0.85f);
301     _colors["foreground"] = new FGColor(0.0f, 0.0f, 0.0f, 1.0f);
302     _colors["highlight"]  = new FGColor(0.7f, 0.7f, 0.7f, 1.0f);
303     _colors["label"]      = new FGColor(0.0f, 0.0f, 0.0f, 1.0f);
304     _colors["legend"]     = new FGColor(0.0f, 0.0f, 0.0f, 1.0f);
305     _colors["misc"]       = new FGColor(0.0f, 0.0f, 0.0f, 1.0f);
306     _colors["inputfield"] = new FGColor(0.8f, 0.7f, 0.7f, 1.0f);
307
308     //puSetDefaultStyle();
309
310     int which = fgGetInt("/sim/gui/current-style", 0);
311     SGPropertyNode *sim = globals->get_props()->getNode("sim/gui", true);
312     SGPropertyNode *n = sim->getChild("style", which);
313     if (!n)
314         n = sim->getChild("style", 0, true);
315
316     setupFont(n->getNode("fonts/gui", true));
317     n = n->getNode("colors", true);
318
319     for (int i = 0; i < n->nChildren(); i++) {
320         SGPropertyNode *child = n->getChild(i);
321         _colors[child->getName()] = new FGColor(child);
322     }
323
324     FGColor *c = _colors["background"];
325     puSetDefaultColourScheme(c->red(), c->green(), c->blue(), c->alpha());
326 }
327
328
329 void
330 NewGUI::setupFont (SGPropertyNode *node)
331 {
332     _font = globals->get_fontcache()->get(node);
333     puSetDefaultFonts(*_font, *_font);
334     return;
335 }
336
337 // end of new_gui.cxx