1 // new_gui.cxx: implementation of XML-configurable GUI support.
11 #include <simgear/misc/exception.hxx>
12 #include <Main/fg_props.hxx>
14 #include "menubar.hxx"
18 ////////////////////////////////////////////////////////////////////////
20 ////////////////////////////////////////////////////////////////////////
26 action_callback (puObject * object)
28 GUIInfo * info = (GUIInfo *)object->getUserData();
30 (NewGUI *)globals->get_subsystem_mgr()
31 ->get_group(FGSubsystemMgr::INIT)->get_subsystem("gui");
32 gui->setCurrentWidget(info->widget);
33 for (int i = 0; i < info->bindings.size(); i++)
34 info->bindings[i]->fire();
35 gui->setCurrentWidget(0);
40 ////////////////////////////////////////////////////////////////////////
41 // Implementation of GUIInfo.
42 ////////////////////////////////////////////////////////////////////////
44 GUIInfo::GUIInfo (GUIWidget * w)
51 for (int i = 0; i < bindings.size(); i++) {
59 ////////////////////////////////////////////////////////////////////////
60 // Implementation of GUIWidget.
61 ////////////////////////////////////////////////////////////////////////
63 GUIWidget::GUIWidget (SGPropertyNode_ptr props)
69 GUIWidget::~GUIWidget ()
74 for (i = 0; i < _info.size(); i++) {
79 for (i = 0; i < _propertyObjects.size(); i++) {
80 delete _propertyObjects[i];
81 _propertyObjects[i] = 0;
86 GUIWidget::updateValue (const char * objectName)
88 for (int i = 0; i < _propertyObjects.size(); i++) {
89 if (_propertyObjects[i]->name == objectName)
90 _propertyObjects[i]->object
91 ->setValue(_propertyObjects[i]->node->getStringValue());
96 GUIWidget::applyValue (const char * objectName)
98 for (int i = 0; i < _propertyObjects.size(); i++) {
99 if (_propertyObjects[i]->name == objectName)
100 _propertyObjects[i]->node
101 ->setStringValue(_propertyObjects[i]
102 ->object->getStringValue());
107 GUIWidget::updateValues ()
109 for (int i = 0; i < _propertyObjects.size(); i++) {
110 puObject * object = _propertyObjects[i]->object;
111 SGPropertyNode_ptr node = _propertyObjects[i]->node;
112 object->setValue(node->getStringValue());
117 GUIWidget::applyValues ()
119 for (int i = 0; i < _propertyObjects.size(); i++) {
120 puObject * object = _propertyObjects[i]->object;
121 SGPropertyNode_ptr node = _propertyObjects[i]->node;
122 node->setStringValue(object->getStringValue());
127 GUIWidget::display (SGPropertyNode_ptr props)
130 SG_LOG(SG_GENERAL, SG_ALERT, "This widget is already active");
134 _object = makeObject(props, 1024, 768);
139 SG_LOG(SG_GENERAL, SG_ALERT, "Widget "
140 << props->getStringValue("name", "[unnamed]")
141 << " does not contain a proper GUI definition");
146 GUIWidget::makeObject (SGPropertyNode * props, int parentWidth, int parentHeight)
148 int width = props->getIntValue("width", parentWidth);
149 int height = props->getIntValue("height", parentHeight);
151 int x = props->getIntValue("x", (parentWidth - width) / 2);
152 int y = props->getIntValue("y", (parentHeight - height) / 2);
154 string type = props->getName();
156 type = props->getStringValue("type");
158 SG_LOG(SG_GENERAL, SG_ALERT, "No type specified for GUI object");
162 if (type == "dialog") {
164 if (props->getBoolValue("modal", false))
165 dialog = new puDialogBox(x, y);
167 dialog = new puPopup(x, y);
168 setupGroup(dialog, props, width, height, true);
170 } else if (type == "group") {
171 puGroup * group = new puGroup(x, y);
172 setupGroup(group, props, width, height, false);
174 } else if (type == "input") {
175 puInput * input = new puInput(x, y, x + width, y + height);
176 setupObject(input, props);
178 } else if (type == "text") {
179 puText * text = new puText(x, y);
180 setupObject(text, props);
182 } else if (type == "button") {
184 const char * legend = props->getStringValue("legend", "[none]");
185 if (props->getBoolValue("one-shot", true))
186 b = new puOneShot(x, y, legend);
188 b = new puButton(x, y, legend);
189 setupObject(b, props);
197 GUIWidget::setupObject (puObject * object, SGPropertyNode * props)
199 if (props->hasValue("legend"))
200 object->setLegend(props->getStringValue("legend"));
202 if (props->hasValue("label"))
203 object->setLabel(props->getStringValue("label"));
205 if (props->hasValue("property")) {
206 const char * name = props->getStringValue("name");
209 const char * propname = props->getStringValue("property");
210 SGPropertyNode_ptr node = fgGetNode(propname, true);
211 object->setValue(node->getStringValue());
213 _propertyObjects.push_back(new PropertyObject(name, object, node));
216 vector<SGPropertyNode_ptr> nodes = props->getChildren("binding");
217 if (nodes.size() > 0) {
218 GUIInfo * info = new GUIInfo(this);
220 for (int i = 0; i < nodes.size(); i++)
221 info->bindings.push_back(new FGBinding(nodes[i]));
222 object->setCallback(action_callback);
223 object->setUserData(info);
224 _info.push_back(info);
227 object->makeReturnDefault(props->getBoolValue("default"));
231 GUIWidget::setupGroup (puGroup * group, SGPropertyNode * props,
232 int width, int height, bool makeFrame)
234 setupObject(group, props);
237 new puFrame(0, 0, width, height);
239 int nChildren = props->nChildren();
240 for (int i = 0; i < nChildren; i++)
241 makeObject(props->getChild(i), width, height);
245 GUIWidget::PropertyObject::PropertyObject (const char * n,
247 SGPropertyNode_ptr p)
256 ////////////////////////////////////////////////////////////////////////
257 // Implementation of NewGUI.
258 ////////////////////////////////////////////////////////////////////////
262 : _menubar(new FGMenuBar),
277 ulMakePath(path1, getenv("FG_ROOT"), "gui");
278 ulMakePath(path2, path1, "dialogs");
280 #if !defined(FG_OLD_MENUBAR)
286 NewGUI::update (double delta_time_sec)
292 NewGUI::display (const string &name)
294 if (_widgets.find(name) == _widgets.end())
295 SG_LOG(SG_GENERAL, SG_ALERT, "Dialog " << name << " not defined");
297 new GUIWidget(_widgets[name]);
301 NewGUI::setCurrentWidget (GUIWidget * widget)
303 _current_widget = widget;
307 NewGUI::getCurrentWidget ()
309 return _current_widget;
313 NewGUI::getMenuBar ()
319 NewGUI::readDir (const char * path)
321 ulDir * dir = ulOpenDir(path);
324 SG_LOG(SG_GENERAL, SG_ALERT, "Failed to read GUI files from "
329 ulDirEnt * dirEnt = ulReadDir(dir);
330 while (dirEnt != 0) {
333 ulMakePath(subpath, path, dirEnt->d_name);
335 if (dirEnt->d_isdir && dirEnt->d_name[0] != '.') {
338 SGPropertyNode_ptr props = new SGPropertyNode;
340 readProperties(subpath, props);
341 } catch (const sg_exception &ex) {
342 SG_LOG(SG_INPUT, SG_ALERT, "Error parsing GUI file "
345 if (!props->hasValue("name")) {
346 SG_LOG(SG_INPUT, SG_WARN, "GUI file " << subpath
347 << " has no name; skipping.");
349 string name = props->getStringValue("name");
350 SG_LOG(SG_INPUT, SG_BULK, "Saving GUI node " << name);
351 _widgets[name] = props;
354 dirEnt = ulReadDir(dir);
359 // end of new_gui.cxx