1 // FGPUIDialog.hxx - XML-configured dialog box.
3 #ifndef FG_PUI_DIALOG_HXX
4 #define FG_PUI_DIALOG_HXX 1
8 #include <plib/puAux.h>
10 #include <simgear/props/props.hxx>
11 #include <simgear/misc/sg_path.hxx>
12 #include <simgear/props/condition.hxx>
17 // ugly temporary workaround for plib's lack of user defined class ids FIXME
18 #define FGCLASS_LIST 0x00000001
19 #define FGCLASS_AIRPORTLIST 0x00000002
20 #define FGCLASS_PROPERTYLIST 0x00000004
21 #define FGCLASS_WAYPOINTLIST 0x00000008
23 class GUI_ID { public: GUI_ID(int id) : id(id) {} virtual ~GUI_ID() {} int id; };
33 * An XML-configured dialog box.
35 * The GUI manager stores only the property tree for the dialog
36 * boxes. This class creates a PUI dialog box on demand from
37 * the properties in that tree. The manager recreates the dialog
38 * every time it needs to show it.
40 class FGPUIDialog : public FGDialog
45 * Construct a new GUI widget configured by a property tree.
47 * The configuration properties are not part of the main
48 * FlightGear property tree; the GUI manager reads them
49 * from individual configuration files.
51 * @param props A property tree describing the dialog.
53 FGPUIDialog (SGPropertyNode * props);
59 virtual ~FGPUIDialog ();
63 * Update the values of all GUI objects with a specific name,
64 * or all if name is 0 (default).
66 * This method copies values from the FlightGear property tree to
69 * @param objectName The name of the GUI object(s) to update.
70 * Use the empty name for all unnamed objects.
72 virtual void updateValues (const char * objectName = 0);
76 * Apply the values of all GUI objects with a specific name,
77 * or all if name is 0 (default)
79 * This method copies values from the GUI object(s) to the
80 * FlightGear property tree.
82 * @param objectName The name of the GUI object(s) to update.
83 * Use the empty name for all unnamed objects.
85 virtual void applyValues (const char * objectName = 0);
89 * Update state. Called on active dialogs before rendering.
91 virtual void update ();
94 * Recompute the dialog's layout
99 void setNeedsLayout() {
100 _needsRelayout = true;
115 void display (SGPropertyNode * props);
117 // Build the dialog or a subobject of it.
118 puObject * makeObject (SGPropertyNode * props,
119 int parentWidth, int parentHeight);
121 // Common configuration for all GUI objects.
122 void setupObject (puObject * object, SGPropertyNode * props);
124 // Common configuration for all GUI group objects.
125 void setupGroup (puGroup * group, SGPropertyNode * props,
126 int width, int height, bool makeFrame = false);
128 // Set object colors: the "which" argument defines which color qualities
129 // (PUCOL_LABEL, etc.) should pick up the <color> property.
130 void setColor(puObject * object, SGPropertyNode * props, int which = 0);
132 // return key code number for keystring
133 int getKeyCode(const char *keystring);
136 * Apply layout sizes to a tree of puObjects
138 void applySize(puObject *object);
140 // The top-level PUI object.
143 // The GUI subsystem.
146 // The dialog font. Defaults to the global gui font, but can get
147 // overridden by a top level font definition.
150 // The source xml tree, so that we can pass data back, such as the
152 SGPropertyNode_ptr _props;
158 SGPropertyNode_ptr _nasal_close;
160 // PUI provides no way for userdata to be deleted automatically
161 // with a GUI object, so we have to keep track of all the special
162 // data we allocated and then free it manually when the dialog
164 std::vector<void *> _info;
165 struct PropertyObject {
166 PropertyObject (const char * name,
168 SGPropertyNode_ptr node);
171 SGPropertyNode_ptr node;
173 std::vector<PropertyObject *> _propertyObjects;
174 std::vector<PropertyObject *> _liveObjects;
176 class ConditionalObject : public SGConditional
179 ConditionalObject(const std::string& aName, puObject* aPu) :
184 void update(FGPUIDialog* aDlg);
187 const std::string _name;
191 typedef SGSharedPtr<ConditionalObject> ConditionalObjectRef;
192 std::vector<ConditionalObjectRef> _conditionalObjects;
196 // Custom subclass of puPopup to implement "draggable" windows in the
197 // interface. Note that this is a subclass of puPopup, not
198 // puDialogBox. Sadly, PUI (mis)uses subclassing to implement a
199 // boolean property: modality. That means that we can't implement
200 // dragging of both puPopup windows and puDialogBoxes with the same
201 // code. Rather than duplicate code, I've chosen to implement only
202 // "non-modal dragability" here. Modal dialog boxes (like the exit
203 // confirmation) are not draggable.
205 class fgPopup : public puPopup {
207 fgPopup(int x, int y, bool r = true, bool d = true) :
208 puPopup(x, y), _draggable(d), _resizable(r), _dragging(false)
210 int checkHit(int b, int up, int x, int y);
211 int checkKey(int key, int updown);
212 int getHitObjects(puObject *, int x, int y);
213 puObject *getKeyObject(puObject *, int key);
214 puObject *getActiveInputField(puObject *);
215 void applySize(puObject *);
217 enum { LEFT = 1, RIGHT = 2, TOP = 4, BOTTOM = 8 };
224 int _dlgX, _dlgY, _dlgW, _dlgH;
225 int _startX, _startY;
231 fgValueList(SGPropertyNode *p);
232 virtual ~fgValueList();
233 virtual void update();
241 SGPropertyNode_ptr _props;
245 class fgList : public fgValueList, public puaList, public GUI_ID {
247 fgList(int x1, int y1, int x2, int y2, SGPropertyNode *p, int sw) :
248 fgValueList(p), puaList(x1, y1, x2, y2, _list, sw), GUI_ID(FGCLASS_LIST) {}
252 class fgComboBox : public fgValueList, public puaComboBox {
254 fgComboBox(int x1, int y1, int x2, int y2, SGPropertyNode *p, bool editable) :
256 puaComboBox(x1, y1, x2, y2, _list, editable),
262 virtual void setSize(int w, int h);
264 virtual int checkHit(int b, int up, int x, int y);
266 virtual void recalc_bbox();
271 class fgSelectBox : public fgValueList, public puaSelectBox {
273 fgSelectBox(int x1, int y1, int x2, int y2, SGPropertyNode *p) :
274 fgValueList(p), puaSelectBox(x1, y1, x2, y2, _list) {}
277 #endif // __DIALOG_HXX