]> git.mxchange.org Git - flightgear.git/blob - src/GUI/dialog.hxx
Autopilot: clean up the helpers code (which drives the various /internal/) properties...
[flightgear.git] / src / GUI / dialog.hxx
1 // dialog.hxx - XML-configured dialog box.
2
3 #ifndef __DIALOG_HXX
4 #define __DIALOG_HXX 1
5
6 #ifndef __cplusplus
7 # error This library requires C++
8 #endif
9
10 #include <plib/puAux.h>
11
12 #include <simgear/compiler.h>   // for SG_USING_STD
13 #include <simgear/props/props.hxx>
14 #include <simgear/misc/sg_path.hxx>
15 #include <simgear/props/condition.hxx>
16
17 #include <vector>
18 using std::vector;
19
20
21 // ugly temporary workaround for plib's lack of user defined class ids  FIXME
22 #define FGCLASS_LIST          0x00000001
23 #define FGCLASS_AIRPORTLIST   0x00000002
24 #define FGCLASS_PROPERTYLIST  0x00000004
25 class GUI_ID { public: GUI_ID(int id) : id(id) {} virtual ~GUI_ID() {} int id; };
26
27
28
29 class FGDialog;
30 class NewGUI;
31 class FGColor;
32
33
34 /**
35  * An XML-configured dialog box.
36  *
37  * The GUI manager stores only the property tree for the dialog
38  * boxes.  This class creates a PUI dialog box on demand from
39  * the properties in that tree.  The manager recreates the dialog
40  * every time it needs to show it.
41  */
42 class FGDialog
43 {
44 public:
45
46     /**
47      * Construct a new GUI widget configured by a property tree.
48      *
49      * The configuration properties are not part of the main
50      * FlightGear property tree; the GUI manager reads them
51      * from individual configuration files.
52      *
53      * @param props A property tree describing the dialog.
54      */
55     FGDialog (SGPropertyNode * props);
56
57
58     /**
59      * Destructor.
60      */
61     virtual ~FGDialog ();
62
63
64     /**
65      * Update the values of all GUI objects with a specific name,
66      * or all if name is 0 (default).
67      *
68      * This method copies values from the FlightGear property tree to
69      * the GUI object(s).
70      *
71      * @param objectName The name of the GUI object(s) to update.
72      *        Use the empty name for all unnamed objects.
73      */
74     virtual void updateValues (const char * objectName = 0);
75
76
77     /**
78      * Apply the values of all GUI objects with a specific name,
79      * or all if name is 0 (default)
80      *
81      * This method copies values from the GUI object(s) to the
82      * FlightGear property tree.
83      *
84      * @param objectName The name of the GUI object(s) to update.
85      *        Use the empty name for all unnamed objects.
86      */
87     virtual void applyValues (const char * objectName = 0);
88
89
90     /**
91      * Update state.  Called on active dialogs before rendering.
92      */
93     virtual void update ();
94
95     /**
96      * Recompute the dialog's layout
97      */
98     void relayout();
99     
100     
101     void setNeedsLayout() {
102       _needsRelayout = true;
103     }
104 private:
105
106     enum {
107         BACKGROUND = 0x01,
108         FOREGROUND = 0x02,
109         HIGHLIGHT = 0x04,
110         LABEL = 0x08,
111         LEGEND = 0x10,
112         MISC = 0x20,
113         EDITFIELD = 0x40
114     };
115
116     // Private copy constructor to avoid unpleasant surprises.
117     FGDialog (const FGDialog &);
118
119     // Show the dialog.
120     void display (SGPropertyNode * props);
121
122     // Build the dialog or a subobject of it.
123     puObject * makeObject (SGPropertyNode * props,
124                            int parentWidth, int parentHeight);
125
126     // Common configuration for all GUI objects.
127     void setupObject (puObject * object, SGPropertyNode * props);
128
129     // Common configuration for all GUI group objects.
130     void setupGroup (puGroup * group, SGPropertyNode * props,
131                      int width, int height, bool makeFrame = false);
132
133     // Set object colors: the "which" argument defines which color qualities
134     // (PUCOL_LABEL, etc.) should pick up the <color> property.
135     void setColor(puObject * object, SGPropertyNode * props, int which = 0);
136
137     // return key code number for keystring
138     int getKeyCode(const char *keystring);
139
140     /**
141      * Apply layout sizes to a tree of puObjects
142      */
143     void applySize(puObject *object);
144
145     // The top-level PUI object.
146     puObject * _object;
147
148     // The GUI subsystem.
149     NewGUI * _gui;
150
151     // The dialog font. Defaults to the global gui font, but can get
152     // overridden by a top level font definition.
153     puFont * _font;
154
155     // The source xml tree, so that we can pass data back, such as the
156     // last position.
157     SGPropertyNode_ptr _props;
158
159     bool _needsRelayout;
160
161     // Nasal module.
162     string _module;
163     SGPropertyNode_ptr _nasal_close;
164
165     // PUI provides no way for userdata to be deleted automatically
166     // with a GUI object, so we have to keep track of all the special
167     // data we allocated and then free it manually when the dialog
168     // closes.
169     vector<void *> _info;
170     struct PropertyObject {
171         PropertyObject (const char * name,
172                         puObject * object,
173                         SGPropertyNode_ptr node);
174         string name;
175         puObject * object;
176         SGPropertyNode_ptr node;
177     };
178     vector<PropertyObject *> _propertyObjects;
179     vector<PropertyObject *> _liveObjects;
180     
181     class ConditionalObject : public SGConditional
182     {
183     public:
184       ConditionalObject(const std::string& aName, puObject* aPu) :
185         _name(aName),
186         _pu(aPu)
187       { ; }
188     
189       void update(FGDialog* aDlg);
190     
191     private:
192       const std::string _name;
193       puObject* _pu;      
194     };
195     
196     typedef SGSharedPtr<ConditionalObject> ConditionalObjectRef;
197     vector<ConditionalObjectRef> _conditionalObjects;
198 };
199
200 //
201 // Custom subclass of puPopup to implement "draggable" windows in the
202 // interface.  Note that this is a subclass of puPopup, not
203 // puDialogBox.  Sadly, PUI (mis)uses subclassing to implement a
204 // boolean property: modality.  That means that we can't implement
205 // dragging of both puPopup windows and puDialogBoxes with the same
206 // code.  Rather than duplicate code, I've chosen to implement only
207 // "non-modal dragability" here.  Modal dialog boxes (like the exit
208 // confirmation) are not draggable.
209 //
210 class fgPopup : public puPopup {
211 public:
212     fgPopup(int x, int y, bool r = true, bool d = true) :
213             puPopup(x, y), _draggable(d), _resizable(r), _dragging(false)
214     {}
215     int checkHit(int b, int up, int x, int y);
216     int checkKey(int key, int updown);
217     int getHitObjects(puObject *, int x, int y);
218     puObject *getKeyObject(puObject *, int key);
219     puObject *getActiveInputField(puObject *);
220     void applySize(puObject *);
221 private:
222     enum { LEFT = 1, RIGHT = 2, TOP = 4, BOTTOM = 8 };
223     bool _draggable;
224     bool _resizable;
225     bool _dragging;
226     int _resizing;
227     int _start_cursor;
228     int _cursor;
229     int _dlgX, _dlgY, _dlgW, _dlgH;
230     int _startX, _startY;
231 };
232
233
234 class fgValueList {
235 public:
236     fgValueList(SGPropertyNode *p);
237     virtual ~fgValueList();
238     virtual void update();
239
240 protected:
241     char **_list;
242
243 private:
244     void make_list();
245     void destroy_list();
246     SGPropertyNode_ptr _props;
247 };
248
249
250 class fgList : public fgValueList, public puaList, public GUI_ID {
251 public:
252     fgList(int x1, int y1, int x2, int y2, SGPropertyNode *p, int sw) :
253             fgValueList(p), puaList(x1, y1, x2, y2, _list, sw), GUI_ID(FGCLASS_LIST) {}
254     void update();
255 };
256
257 class fgComboBox : public fgValueList, public puaComboBox {
258 public:
259     fgComboBox(int x1, int y1, int x2, int y2, SGPropertyNode *p, bool editable) :
260         fgValueList(p), puaComboBox(x1, y1, x2, y2, _list, editable) {}
261         
262     void update();
263 };
264
265 class fgSelectBox : public fgValueList, public puaSelectBox {
266 public:
267     fgSelectBox(int x1, int y1, int x2, int y2, SGPropertyNode *p) :
268         fgValueList(p), puaSelectBox(x1, y1, x2, y2, _list) {}
269 };
270
271 #endif // __DIALOG_HXX