1 // new_gui.cxx: implementation of XML-configurable GUI support.
11 #include <simgear/misc/exception.hxx>
12 #include <Main/fg_props.hxx>
16 * Callback to update all property values.
19 update_callback (puObject * object)
21 ((NewGUI *)object->getUserData())->updateProperties();
26 * Callback to close the dialog.
29 close_callback (puObject * object)
31 ((NewGUI *)object->getUserData())->closeActiveObject();
36 * Callback to apply the property value for every field.
39 apply_callback (puObject * object)
41 ((NewGUI *)object->getUserData())->applyProperties();
42 update_callback(object);
47 * Callback to apply the property values and close the dialog.
50 close_apply_callback (puObject * object)
52 apply_callback(object);
53 close_callback(object);
71 ulMakePath(path, getenv("FG_ROOT"), "gui");
72 std::cerr << "Reading from " << path << std::endl;
74 std::cerr << "Done reading from " << path << std::endl;
78 NewGUI::update (double delta_time_sec)
84 NewGUI::display (const string &name)
86 if (_activeObject != 0) {
87 SG_LOG(SG_GENERAL, SG_ALERT, "Another GUI object is still active");
91 if (_objects.find(name) == _objects.end()) {
92 SG_LOG(SG_GENERAL, SG_ALERT, "Dialog " << name << " not defined");
95 SGPropertyNode_ptr props = _objects[name];
97 _activeObject = makeObject(props, 1024, 768);
99 if (_activeObject != 0) {
100 _activeObject->reveal();
102 SG_LOG(SG_GENERAL, SG_ALERT, "Dialog " << name
103 << " does not contain a proper GUI definition");
108 NewGUI::applyProperties ()
110 for (int i = 0; i < _propertyObjects.size(); i++) {
111 puObject * object = _propertyObjects[i].object;
112 SGPropertyNode_ptr node = _propertyObjects[i].node;
113 node->setStringValue(object->getStringValue());
118 NewGUI::updateProperties ()
120 for (int i = 0; i < _propertyObjects.size(); i++) {
121 puObject * object = _propertyObjects[i].object;
122 SGPropertyNode_ptr node = _propertyObjects[i].node;
123 object->setValue(node->getStringValue());
128 NewGUI::closeActiveObject ()
130 delete _activeObject;
132 _propertyObjects.clear();
136 NewGUI::readDir (const char * path)
138 ulDir * dir = ulOpenDir(path);
139 std::cerr << "Directory opened successfully" << std::endl;
142 SG_LOG(SG_GENERAL, SG_ALERT, "Failed to read GUI files from "
147 ulDirEnt * dirEnt = ulReadDir(dir);
148 while (dirEnt != 0) {
151 ulMakePath(subpath, path, dirEnt->d_name);
153 std::cerr << "Subpath is " << subpath << std::endl;
154 if (dirEnt->d_isdir && dirEnt->d_name[0] != '.') {
157 SGPropertyNode_ptr props = new SGPropertyNode;
159 readProperties(subpath, props);
160 } catch (const sg_exception &ex) {
161 SG_LOG(SG_INPUT, SG_ALERT, "Error parsing GUI file "
164 if (!props->hasValue("name")) {
165 SG_LOG(SG_INPUT, SG_WARN, "GUI file " << subpath
166 << " has no name; skipping.");
168 string name = props->getStringValue("name");
169 SG_LOG(SG_INPUT, SG_BULK, "Saving GUI node " << name);
170 _objects[name] = props;
173 dirEnt = ulReadDir(dir);
179 NewGUI::makeObject (SGPropertyNode * props, int parentWidth, int parentHeight)
181 int width = props->getIntValue("width", parentWidth);
182 int height = props->getIntValue("height", parentHeight);
184 int x = props->getIntValue("x", (parentWidth - width) / 2);
185 int y = props->getIntValue("y", (parentHeight - height) / 2);
187 string type = props->getName();
189 type = props->getStringValue("type");
191 SG_LOG(SG_GENERAL, SG_ALERT, "No type specified for GUI object");
195 if (type == "dialog") {
197 if (props->getBoolValue("modal", false))
198 dialog = new puDialogBox(x, y);
200 dialog = new puPopup(x, y);
201 setupGroup(dialog, props, width, height, true);
203 } else if (type == "group") {
204 puGroup * group = new puGroup(x, y);
205 setupGroup(group, props, width, height, false);
207 } else if (type == "input") {
208 puInput * input = new puInput(x, y, x + width, y + height);
209 setupObject(input, props);
211 } else if (type == "text") {
212 puText * text = new puText(x, y);
213 setupObject(text, props);
215 } else if (type == "button") {
217 const char * legend = props->getStringValue("legend", "[none]");
218 if (props->getBoolValue("one-shot", true))
219 b = new puOneShot(x, y, legend);
221 b = new puButton(x, y, legend);
222 setupObject(b, props);
230 NewGUI::setupObject (puObject * object, SGPropertyNode * props)
232 object->setUserData(this);
234 if (props->hasValue("legend"))
235 object->setLegend(props->getStringValue("legend"));
237 if (props->hasValue("label"))
238 object->setLabel(props->getStringValue("label"));
240 if (props->hasValue("default-value-prop")) {
241 const char * name = props->getStringValue("default-value-prop");
242 SGPropertyNode_ptr node = fgGetNode(name, true);
243 object->setValue(node->getStringValue());
244 _propertyObjects.push_back(PropertyObject(object, node));
247 if (props->hasValue("action")) {
248 string action = props->getStringValue("action");
249 if (action == "update")
250 object->setCallback(update_callback);
251 else if (action == "close")
252 object->setCallback(close_callback);
253 else if (action == "apply")
254 object->setCallback(apply_callback);
255 else if (action == "close-apply")
256 object->setCallback(close_apply_callback);
258 SG_LOG(SG_GENERAL, SG_ALERT, "Unknown GUI action " + action);
261 object->makeReturnDefault(props->getBoolValue("default"));
265 NewGUI::setupGroup (puGroup * group, SGPropertyNode * props,
266 int width, int height, bool makeFrame)
268 setupObject(group, props);
271 new puFrame(0, 0, width, height);
273 int nChildren = props->nChildren();
274 for (int i = 0; i < nChildren; i++)
275 makeObject(props->getChild(i), width, height);
279 NewGUI::PropertyObject::PropertyObject (puObject * o, SGPropertyNode_ptr n)
285 // end of new_gui.cxx