1 // new_gui.cxx: implementation of XML-configurable GUI support.
11 #include <simgear/misc/exception.hxx>
12 #include <Main/fg_props.hxx>
16 ////////////////////////////////////////////////////////////////////////
18 ////////////////////////////////////////////////////////////////////////
24 action_callback (puObject * object)
26 GUIInfo * info = (GUIInfo *)object->getUserData();
28 (NewGUI *)globals->get_subsystem_mgr()
29 ->get_group(FGSubsystemMgr::INIT)->get_subsystem("gui");
30 gui->setCurrentWidget(info->widget);
31 for (int i = 0; i < info->bindings.size(); i++) {
32 std::cerr << "Firing binding " << i << ": " << info->bindings[i]->getCommandName() << std::endl;
33 info->bindings[i]->fire();
34 std::cerr << "done\n";
36 std::cerr << "All bindings fired\n";
37 gui->setCurrentWidget(0);
42 ////////////////////////////////////////////////////////////////////////
43 // Implementation of GUIInfo.
44 ////////////////////////////////////////////////////////////////////////
46 GUIInfo::GUIInfo (GUIWidget * w)
53 for (int i = 0; i < bindings.size(); i++) {
61 ////////////////////////////////////////////////////////////////////////
62 // Implementation of GUIWidget.
63 ////////////////////////////////////////////////////////////////////////
65 GUIWidget::GUIWidget (SGPropertyNode_ptr props)
71 GUIWidget::~GUIWidget ()
73 std::cerr << "Destroying widget\n";
77 for (i = 0; i < _info.size(); i++) {
82 for (i = 0; i < _propertyObjects.size(); i++) {
83 delete _propertyObjects[i];
84 _propertyObjects[i] = 0;
89 GUIWidget::updateValue (const char * objectName)
91 for (int i = 0; i < _propertyObjects.size(); i++) {
92 if (_propertyObjects[i]->name == objectName)
93 _propertyObjects[i]->object
94 ->setValue(_propertyObjects[i]->node->getStringValue());
99 GUIWidget::applyValue (const char * objectName)
101 for (int i = 0; i < _propertyObjects.size(); i++) {
102 if (_propertyObjects[i]->name == objectName)
103 _propertyObjects[i]->node
104 ->setStringValue(_propertyObjects[i]
105 ->object->getStringValue());
110 GUIWidget::updateValues ()
112 for (int i = 0; i < _propertyObjects.size(); i++) {
113 puObject * object = _propertyObjects[i]->object;
114 SGPropertyNode_ptr node = _propertyObjects[i]->node;
115 object->setValue(node->getStringValue());
120 GUIWidget::applyValues ()
122 for (int i = 0; i < _propertyObjects.size(); i++) {
123 puObject * object = _propertyObjects[i]->object;
124 SGPropertyNode_ptr node = _propertyObjects[i]->node;
125 node->setStringValue(object->getStringValue());
130 GUIWidget::display (SGPropertyNode_ptr props)
133 SG_LOG(SG_GENERAL, SG_ALERT, "This widget is already active");
137 _object = makeObject(props, 1024, 768);
142 SG_LOG(SG_GENERAL, SG_ALERT, "Widget "
143 << props->getStringValue("name", "[unnamed]")
144 << " does not contain a proper GUI definition");
149 GUIWidget::makeObject (SGPropertyNode * props, int parentWidth, int parentHeight)
151 int width = props->getIntValue("width", parentWidth);
152 int height = props->getIntValue("height", parentHeight);
154 int x = props->getIntValue("x", (parentWidth - width) / 2);
155 int y = props->getIntValue("y", (parentHeight - height) / 2);
157 string type = props->getName();
159 type = props->getStringValue("type");
161 SG_LOG(SG_GENERAL, SG_ALERT, "No type specified for GUI object");
165 if (type == "dialog") {
167 if (props->getBoolValue("modal", false))
168 dialog = new puDialogBox(x, y);
170 dialog = new puPopup(x, y);
171 setupGroup(dialog, props, width, height, true);
173 } else if (type == "group") {
174 puGroup * group = new puGroup(x, y);
175 setupGroup(group, props, width, height, false);
177 } else if (type == "input") {
178 puInput * input = new puInput(x, y, x + width, y + height);
179 setupObject(input, props);
181 } else if (type == "text") {
182 puText * text = new puText(x, y);
183 setupObject(text, props);
185 } else if (type == "button") {
187 const char * legend = props->getStringValue("legend", "[none]");
188 if (props->getBoolValue("one-shot", true))
189 b = new puOneShot(x, y, legend);
191 b = new puButton(x, y, legend);
192 setupObject(b, props);
200 GUIWidget::setupObject (puObject * object, SGPropertyNode * props)
202 if (props->hasValue("legend"))
203 object->setLegend(props->getStringValue("legend"));
205 if (props->hasValue("label"))
206 object->setLabel(props->getStringValue("label"));
208 if (props->hasValue("property")) {
209 const char * name = props->getStringValue("name");
212 const char * propname = props->getStringValue("property");
213 SGPropertyNode_ptr node = fgGetNode(propname, true);
214 object->setValue(node->getStringValue());
216 _propertyObjects.push_back(new PropertyObject(name, object, node));
219 vector<SGPropertyNode_ptr> nodes = props->getChildren("binding");
220 if (nodes.size() > 0) {
221 GUIInfo * info = new GUIInfo(this);
223 for (int i = 0; i < nodes.size(); i++)
224 info->bindings.push_back(new FGBinding(nodes[i]));
225 object->setCallback(action_callback);
226 object->setUserData(info);
227 _info.push_back(info);
230 object->makeReturnDefault(props->getBoolValue("default"));
234 GUIWidget::setupGroup (puGroup * group, SGPropertyNode * props,
235 int width, int height, bool makeFrame)
237 setupObject(group, props);
240 new puFrame(0, 0, width, height);
242 int nChildren = props->nChildren();
243 for (int i = 0; i < nChildren; i++)
244 makeObject(props->getChild(i), width, height);
248 GUIWidget::PropertyObject::PropertyObject (const char * n,
250 SGPropertyNode_ptr p)
259 ////////////////////////////////////////////////////////////////////////
260 // Implementation of NewGUI.
261 ////////////////////////////////////////////////////////////////////////
277 ulMakePath(path, getenv("FG_ROOT"), "gui");
282 NewGUI::update (double delta_time_sec)
288 NewGUI::display (const string &name)
290 if (_widgets.find(name) == _widgets.end())
291 SG_LOG(SG_GENERAL, SG_ALERT, "Dialog " << name << " not defined");
293 new GUIWidget(_widgets[name]);
297 NewGUI::setCurrentWidget (GUIWidget * widget)
299 _current_widget = widget;
303 NewGUI::getCurrentWidget ()
305 return _current_widget;
309 NewGUI::readDir (const char * path)
311 ulDir * dir = ulOpenDir(path);
314 SG_LOG(SG_GENERAL, SG_ALERT, "Failed to read GUI files from "
319 ulDirEnt * dirEnt = ulReadDir(dir);
320 while (dirEnt != 0) {
323 ulMakePath(subpath, path, dirEnt->d_name);
325 if (dirEnt->d_isdir && dirEnt->d_name[0] != '.') {
328 SGPropertyNode_ptr props = new SGPropertyNode;
330 readProperties(subpath, props);
331 } catch (const sg_exception &ex) {
332 SG_LOG(SG_INPUT, SG_ALERT, "Error parsing GUI file "
335 if (!props->hasValue("name")) {
336 SG_LOG(SG_INPUT, SG_WARN, "GUI file " << subpath
337 << " has no name; skipping.");
339 string name = props->getStringValue("name");
340 SG_LOG(SG_INPUT, SG_BULK, "Saving GUI node " << name);
341 _widgets[name] = props;
344 dirEnt = ulReadDir(dir);
349 // end of new_gui.cxx