]> git.mxchange.org Git - flightgear.git/blob - src/GUI/dialog.cxx
Unbundle dialog-box support from the top-level GUI manager, to
[flightgear.git] / src / GUI / dialog.cxx
1 // dialog.cxx: implementation of an XML-configurable dialog box.
2
3 #include <Input/input.hxx>
4
5 #include "dialog.hxx"
6 #include "new_gui.hxx"
7
8
9 \f
10 ////////////////////////////////////////////////////////////////////////
11 // Callbacks.
12 ////////////////////////////////////////////////////////////////////////
13
14 /**
15  * Action callback.
16  */
17 static void
18 action_callback (puObject * object)
19 {
20     GUIInfo * info = (GUIInfo *)object->getUserData();
21     NewGUI * gui =
22         (NewGUI *)globals->get_subsystem_mgr()
23           ->get_group(FGSubsystemMgr::INIT)->get_subsystem("gui");
24     gui->setCurrentWidget(info->widget);
25     for (int i = 0; i < info->bindings.size(); i++)
26         info->bindings[i]->fire();
27     gui->setCurrentWidget(0);
28 }
29
30
31 \f
32 ////////////////////////////////////////////////////////////////////////
33 // Implementation of GUIInfo.
34 ////////////////////////////////////////////////////////////////////////
35
36 GUIInfo::GUIInfo (FGDialog * w)
37     : widget(w)
38 {
39 }
40
41 GUIInfo::~GUIInfo ()
42 {
43     for (int i = 0; i < bindings.size(); i++) {
44         delete bindings[i];
45         bindings[i] = 0;
46     }
47 }
48
49
50 \f
51 ////////////////////////////////////////////////////////////////////////
52 // Implementation of FGDialog.
53 ////////////////////////////////////////////////////////////////////////
54
55 FGDialog::FGDialog (SGPropertyNode_ptr props)
56     : _object(0)
57 {
58     display(props);
59 }
60
61 FGDialog::~FGDialog ()
62 {
63     delete _object;
64
65     int i;
66     for (i = 0; i < _info.size(); i++) {
67         delete _info[i];
68         _info[i] = 0;
69     }
70
71     for (i = 0; i < _propertyObjects.size(); i++) {
72         delete _propertyObjects[i];
73         _propertyObjects[i] = 0;
74     }
75 }
76
77 void
78 FGDialog::updateValue (const char * objectName)
79 {
80     for (int i = 0; i < _propertyObjects.size(); i++) {
81         if (_propertyObjects[i]->name == objectName)
82             _propertyObjects[i]->object
83                 ->setValue(_propertyObjects[i]->node->getStringValue());
84     }
85 }
86
87 void
88 FGDialog::applyValue (const char * objectName)
89 {
90     for (int i = 0; i < _propertyObjects.size(); i++) {
91         if (_propertyObjects[i]->name == objectName)
92             _propertyObjects[i]->node
93                 ->setStringValue(_propertyObjects[i]
94                                  ->object->getStringValue());
95     }
96 }
97
98 void
99 FGDialog::updateValues ()
100 {
101     for (int i = 0; i < _propertyObjects.size(); i++) {
102         puObject * object = _propertyObjects[i]->object;
103         SGPropertyNode_ptr node = _propertyObjects[i]->node;
104         object->setValue(node->getStringValue());
105     }
106 }
107
108 void
109 FGDialog::applyValues ()
110 {
111     for (int i = 0; i < _propertyObjects.size(); i++) {
112         puObject * object = _propertyObjects[i]->object;
113         SGPropertyNode_ptr node = _propertyObjects[i]->node;
114         node->setStringValue(object->getStringValue());
115     }
116 }
117
118 void
119 FGDialog::display (SGPropertyNode_ptr props)
120 {
121     if (_object != 0) {
122         SG_LOG(SG_GENERAL, SG_ALERT, "This widget is already active");
123         return;
124     }
125
126     _object = makeObject(props, 1024, 768);
127
128     if (_object != 0) {
129         _object->reveal();
130     } else {
131         SG_LOG(SG_GENERAL, SG_ALERT, "Widget "
132                << props->getStringValue("name", "[unnamed]")
133                << " does not contain a proper GUI definition");
134     }
135 }
136
137 puObject *
138 FGDialog::makeObject (SGPropertyNode * props, int parentWidth, int parentHeight)
139 {
140     int width = props->getIntValue("width", parentWidth);
141     int height = props->getIntValue("height", parentHeight);
142
143     int x = props->getIntValue("x", (parentWidth - width) / 2);
144     int y = props->getIntValue("y", (parentHeight - height) / 2);
145
146     string type = props->getName();
147     if (type == "")
148         type = props->getStringValue("type");
149     if (type == "") {
150         SG_LOG(SG_GENERAL, SG_ALERT, "No type specified for GUI object");
151         return 0;
152     }
153
154     if (type == "dialog") {
155         puPopup * dialog;
156         if (props->getBoolValue("modal", false))
157             dialog = new puDialogBox(x, y);
158         else
159             dialog = new puPopup(x, y);
160         setupGroup(dialog, props, width, height, true);
161         return dialog;
162     } else if (type == "group") {
163         puGroup * group = new puGroup(x, y);
164         setupGroup(group, props, width, height, false);
165         return group;
166     } else if (type == "input") {
167         puInput * input = new puInput(x, y, x + width, y + height);
168         setupObject(input, props);
169         return input;
170     } else if (type == "text") {
171         puText * text = new puText(x, y);
172         setupObject(text, props);
173         return text;
174     } else if (type == "button") {
175         puButton * b;
176         const char * legend = props->getStringValue("legend", "[none]");
177         if (props->getBoolValue("one-shot", true))
178             b = new puOneShot(x, y, legend);
179         else
180             b = new puButton(x, y, legend);
181         setupObject(b, props);
182         return b;
183     } else {
184         return 0;
185     }
186 }
187
188 void
189 FGDialog::setupObject (puObject * object, SGPropertyNode * props)
190 {
191     if (props->hasValue("legend"))
192         object->setLegend(props->getStringValue("legend"));
193
194     if (props->hasValue("label"))
195         object->setLabel(props->getStringValue("label"));
196
197     if (props->hasValue("property")) {
198         const char * name = props->getStringValue("name");
199         if (name == 0)
200             name = "";
201         const char * propname = props->getStringValue("property");
202         SGPropertyNode_ptr node = fgGetNode(propname, true);
203         object->setValue(node->getStringValue());
204         if (name != 0)
205             _propertyObjects.push_back(new PropertyObject(name, object, node));
206     }
207
208     vector<SGPropertyNode_ptr> nodes = props->getChildren("binding");
209     if (nodes.size() > 0) {
210         GUIInfo * info = new GUIInfo(this);
211
212         for (int i = 0; i < nodes.size(); i++)
213             info->bindings.push_back(new FGBinding(nodes[i]));
214         object->setCallback(action_callback);
215         object->setUserData(info);
216         _info.push_back(info);
217     }
218
219     object->makeReturnDefault(props->getBoolValue("default"));
220 }
221
222 void
223 FGDialog::setupGroup (puGroup * group, SGPropertyNode * props,
224                     int width, int height, bool makeFrame)
225 {
226     setupObject(group, props);
227
228     if (makeFrame)
229         new puFrame(0, 0, width, height);
230
231     int nChildren = props->nChildren();
232     for (int i = 0; i < nChildren; i++)
233         makeObject(props->getChild(i), width, height);
234     group->close();
235 }
236
237
238 \f
239 ////////////////////////////////////////////////////////////////////////
240 // Implementation of FGDialog::PropertyObject.
241 ////////////////////////////////////////////////////////////////////////
242
243 FGDialog::PropertyObject::PropertyObject (const char * n,
244                                            puObject * o,
245                                            SGPropertyNode_ptr p)
246     : name(n),
247       object(o),
248       node(p)
249 {
250 }
251
252
253 // end of dialog.cxx