]> git.mxchange.org Git - flightgear.git/blob - src/GUI/new_gui.cxx
The code to find the highest hit below you didn't work quite right when
[flightgear.git] / src / GUI / new_gui.cxx
1 // new_gui.cxx: implementation of XML-configurable GUI support.
2
3 #include "new_gui.hxx"
4
5 #include <plib/pu.h>
6 #include <plib/ul.h>
7
8 #include <simgear/compiler.h>
9 #include <simgear/structure/exception.hxx>
10
11 #include <Main/fg_props.hxx>
12
13 #include "menubar.hxx"
14 #include "dialog.hxx"
15
16 SG_USING_STD(map);
17
18 \f
19 ////////////////////////////////////////////////////////////////////////
20 // Implementation of NewGUI.
21 ////////////////////////////////////////////////////////////////////////
22
23
24 NewGUI::NewGUI ()
25     : _menubar(new FGMenuBar),
26       _active_dialog(0)
27 {
28 }
29
30 NewGUI::~NewGUI ()
31 {
32     clear();
33 }
34
35 void
36 NewGUI::init ()
37 {
38     char path1[1024];
39     char path2[1024];
40     ulMakePath(path1, globals->get_fg_root().c_str(), "gui");
41     ulMakePath(path2, path1, "dialogs");
42     readDir(path2);
43     _menubar->init();
44 }
45
46 void
47 NewGUI::reinit ()
48 {
49     unbind();
50     clear();
51     _menubar = new FGMenuBar;
52     init();
53     bind();
54 }
55
56 void
57 NewGUI::bind ()
58 {
59     fgTie("/sim/menubar/visibility", this,
60           &NewGUI::getMenuBarVisible, &NewGUI::setMenuBarVisible);
61 }
62
63 void
64 NewGUI::unbind ()
65 {
66     fgUntie("/sim/menubar/visibility");
67 }
68
69 void
70 NewGUI::update (double delta_time_sec)
71 {
72     // NO OP
73 }
74
75 bool
76 NewGUI::showDialog (const string &name)
77 {
78     if (_dialog_props.find(name) == _dialog_props.end()) {
79         SG_LOG(SG_GENERAL, SG_ALERT, "Dialog " << name << " not defined");
80         return false;
81     } else {
82         new FGDialog(_dialog_props[name]); // it will be deleted by a callback
83         return true;
84     }
85 }
86
87 bool
88 NewGUI::closeActiveDialog ()
89 {
90     if (_active_dialog == 0) {
91         return false;
92     } else {
93         delete _active_dialog;
94         _active_dialog = 0;
95         return true;
96     }
97 }
98
99 void
100 NewGUI::setActiveDialog (FGDialog * dialog)
101 {
102     _active_dialog = dialog;
103 }
104
105 FGDialog *
106 NewGUI::getActiveDialog ()
107 {
108     return _active_dialog;
109 }
110
111 FGMenuBar *
112 NewGUI::getMenuBar ()
113 {
114     return _menubar;
115 }
116
117 bool
118 NewGUI::getMenuBarVisible () const
119 {
120     return _menubar->isVisible();
121 }
122
123 void
124 NewGUI::setMenuBarVisible (bool visible)
125 {
126     if (visible)
127         _menubar->show();
128     else
129         _menubar->hide();
130 }
131
132 void
133 NewGUI::clear ()
134 {
135     delete _menubar;
136     _menubar = 0;
137
138     map<string,SGPropertyNode *>::iterator it;
139     for (it = _dialog_props.begin(); it != _dialog_props.end(); it++)
140         delete it->second;
141     _dialog_props.clear();
142 }
143
144 static bool
145 test_extension (const char * path, const char * ext)
146 {
147     int pathlen = strlen(path);
148     int extlen = strlen(ext);
149     
150     for (int i = 1; i <= pathlen && i <= extlen; i++) {
151         if (path[pathlen-i] != ext[extlen-i])
152             return false;
153     }
154     return true;
155 }
156
157 void
158 NewGUI::readDir (const char * path)
159 {
160     ulDir * dir = ulOpenDir(path);
161
162     if (dir == 0) {
163         SG_LOG(SG_GENERAL, SG_ALERT, "Failed to read GUI files from "
164                << path);
165         return;
166     }
167
168     for (ulDirEnt * dirEnt = ulReadDir(dir);
169          dirEnt != 0;
170          dirEnt = ulReadDir(dir)) {
171
172         char subpath[1024];
173
174         ulMakePath(subpath, path, dirEnt->d_name);
175
176         if (!dirEnt->d_isdir && test_extension(subpath, ".xml")) {
177             SGPropertyNode * props = new SGPropertyNode;
178             try {
179                 readProperties(subpath, props);
180             } catch (const sg_exception &ex) {
181                 SG_LOG(SG_INPUT, SG_ALERT, "Error parsing dialog "
182                        << subpath);
183                 delete props;
184                 continue;
185             }
186             if (!props->hasValue("name")) {
187                 SG_LOG(SG_INPUT, SG_WARN, "dialog " << subpath
188                    << " has no name; skipping.");
189                 delete props;
190                 continue;
191             }
192             string name = props->getStringValue("name");
193             SG_LOG(SG_INPUT, SG_BULK, "Saving dialog " << name);
194             if (_dialog_props[name] != 0)
195                 delete _dialog_props[name];
196             _dialog_props[name] = props;
197         }
198     }
199     ulCloseDir(dir);
200 }
201
202 // end of new_gui.cxx