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