]> git.mxchange.org Git - flightgear.git/blob - src/GUI/new_gui.hxx
Added two missing files from JSBSim.org that were missing in the last sync.
[flightgear.git] / src / GUI / new_gui.hxx
1 // new_gui.hxx - XML-configured GUI subsystem.
2
3 #ifndef __NEW_GUI_HXX
4 #define __NEW_GUI_HXX 1
5
6 #ifndef __cplusplus
7 # error This library requires C++
8 #endif
9
10 #ifdef HAVE_CONFIG_H
11 #  include <config.h>
12 #endif
13
14 #include <plib/pu.h>
15
16 #include <simgear/compiler.h>   // for SG_USING_STD
17 #include <simgear/props/props.hxx>
18 #include <simgear/structure/subsystem_mgr.hxx>
19 #include <simgear/misc/sg_path.hxx>
20
21 #include <functional>
22 #include <vector>
23 #include <map>
24
25 using std::vector;
26 using std::map;
27 using std::string;
28
29 #include <Main/fg_props.hxx>
30
31 class SGBinding;
32
33 class FGMenuBar;
34 class FGDialog;
35 class FGColor;
36 class FGFontCache;
37
38
39 /**
40  * XML-configured GUI subsystem.
41  *
42  * This subsystem manages the graphical user interface for FlightGear.
43  * It creates a menubar from the XML configuration file in
44  * $FG_ROOT/gui/menubar.xml, then stores the configuration properties
45  * for XML-configured dialog boxes found in $FG_ROOT/gui/dialogs/.  It
46  * can show or hide the menubar, and can display any dialog by name.
47  */
48 class NewGUI : public SGSubsystem
49 {
50 public:
51
52     /**
53      * Constructor.
54      */
55     NewGUI ();
56
57     /**
58      * Destructor.
59      */
60     virtual ~NewGUI ();
61
62     /**
63      * Initialize the GUI subsystem.
64      */
65     virtual void init ();
66
67     /**
68      * Reinitialize the GUI subsystem. Reloads all XML dialogs.
69      */
70     virtual void reinit ();
71
72     /**
73      * Bind properties for the GUI subsystem.
74      *
75      * Currently, this method binds the properties for showing and
76      * hiding the menu.
77      */
78     virtual void bind ();
79
80     /**
81      * Unbind properties for the GUI subsystem.
82      */
83     virtual void unbind ();
84
85     /**
86      * Update the GUI subsystem.
87      *
88      * Currently, this method is a no-op, because nothing the GUI
89      * subsystem does is time-dependent.
90      */
91     virtual void update (double delta_time_sec);
92
93     /**
94      * Redraw the GUI picking up new GUI colors.
95      */
96     virtual void redraw ();
97
98     /**
99      * Creates a new dialog box, using the same property format as the
100      * gui/dialogs configuration files.  Does not display the
101      * resulting dialog.  If a pre-existing dialog of the same name
102      * exists, it will be deleted.  The node argument will be stored
103      * in the GUI subsystem using SGPropertNode_ptr reference counting.
104      * It should not be deleted by user code.
105      *
106      * @param node A property node containing the dialog definition
107      */
108     virtual void newDialog (SGPropertyNode* node);
109
110     /**
111      * Display a dialog box.
112      *
113      * At initialization time, the subsystem reads all of the XML
114      * configuration files from the directory $FG_ROOT/gui/dialogs/.
115      * The configuration for each dialog specifies a name, and this
116      * method invokes the dialog with the name specified (if it
117      * exists).
118      *
119      * @param name The name of the dialog box.
120      * @return true if the dialog exists, false otherwise.
121      */
122     virtual bool showDialog (const string &name);
123
124
125     /**
126      * Close the currenty active dialog.  This function is intended to
127      * be called from code (pui callbacks, for instance) that registers
128      * its dialog object as active via setActiveDialog().  Other
129      * user-level code should use the closeDialog(name) API.
130      *
131      * @return true if a dialog was active, false otherwise
132      */
133     virtual bool closeActiveDialog ();
134
135     /**
136      * Close a named dialog, if it is open.
137      *
138      * @param name The name of the dialog box.
139      * @return true if the dialog was active, false otherwise.
140      */
141     virtual bool closeDialog (const string &name);
142
143     /**
144      * Get dialog property tree's root node.
145      * @param name The name of the dialog box.
146      * @return node pointer if the dialog was found, zero otherwise.
147      */
148     virtual SGPropertyNode_ptr getDialogProperties (const string &name);
149
150     /**
151      * Return a pointer to the current menubar.
152      */
153     virtual FGMenuBar * getMenuBar ();
154
155     /**
156      * Ignore this method.
157      *
158      * This method is for internal use only, but it has to be public
159      * so that a non-class callback can see it.
160      */
161     virtual void setActiveDialog (FGDialog * dialog);
162
163     /**
164      * Get the dialog currently active, if any.
165      *
166      * @return The active dialog, or 0 if none is active.
167      */
168     virtual FGDialog * getActiveDialog ();
169
170
171     /**
172      * Get the named dialog if active.
173      *
174      * @return The named dialog, or 0 if it isn't active.
175      */
176     virtual FGDialog * getDialog (const string &name);
177
178
179     virtual FGColor *getColor (const char * name) const {
180         _citt_t it = _colors.find(name);
181         return (it != _colors.end()) ? it->second : NULL;
182     }
183     virtual FGColor *getColor (const string &name) const {
184         _citt_t it = _colors.find(name.c_str());
185         return (it != _colors.end()) ? it->second : NULL;
186     }
187
188     virtual puFont *getDefaultFont() { return _font; }
189
190
191 protected:
192
193     /**
194      * Test if the menubar is visible.
195      *
196      * This method exists only for binding.
197      */
198     virtual bool getMenuBarVisible () const;
199
200     /**
201      * Show or hide the menubar.
202      *
203      * This method exists only for binding.
204      */
205     virtual void setMenuBarVisible (bool visible);
206
207     virtual void setStyle ();
208     virtual void setupFont (SGPropertyNode *);
209
210     /**
211      * Used by reinit() and redraw() to close all dialogs and to apply
212      * current GUI colors. If "reload" is false, reopens all dialogs.
213      * Otherwise reloads all XML dialog files from disk and reopens all
214      * but Nasal * generated dialogs, omitting dynamic widgets. (This
215      * is only useful for GUI development.)
216      */
217     virtual void reset (bool reload);
218
219 private:
220     struct ltstr
221     {
222         bool operator()(const char* s1, const char* s2) const {
223             return strcmp(s1, s2) < 0;
224         }
225     };
226
227     puFont *_font;
228     map<const char*,FGColor*, ltstr> _colors;
229     typedef map<const char*,FGColor*, ltstr>::iterator _itt_t;
230     typedef map<const char*,FGColor*, ltstr>::const_iterator _citt_t;
231
232     void clear_colors();
233
234     // Read all the configuration files in a directory.
235     void readDir (const char * path);
236
237     FGMenuBar * _menubar;
238     FGDialog * _active_dialog;
239     map<string,FGDialog *> _active_dialogs;
240     map<string,SGPropertyNode_ptr> _dialog_props;
241
242 };
243
244
245 class FGColor {
246 public:
247     FGColor() { clear(); }
248     FGColor(float r, float g, float b, float a = 1.0f) { set(r, g, b, a); }
249     FGColor(const SGPropertyNode *prop) { set(prop); }
250     FGColor(FGColor *c) { 
251         if (c) set(c->_red, c->_green, c->_blue, c->_alpha);
252     }
253
254     inline void clear() { _red = _green = _blue = _alpha = -1.0f; }
255     // merges in non-negative components from property with children <red> etc.
256     bool merge(const SGPropertyNode *prop);
257     bool merge(const FGColor *color);
258
259     bool set(const SGPropertyNode *prop) { clear(); return merge(prop); };
260     bool set(const FGColor *color) { clear(); return merge(color); }
261     bool set(float r, float g, float b, float a = 1.0f) {
262         _red = r, _green = g, _blue = b, _alpha = a;
263         return true;
264     }
265     bool isValid() const {
266         return _red >= 0.0 && _green >= 0.0 && _blue >= 0.0;
267     }
268     void print() const;
269
270     inline void setRed(float red) { _red = red; }
271     inline void setGreen(float green) { _green = green; }
272     inline void setBlue(float blue) { _blue = blue; }
273     inline void setAlpha(float alpha) { _alpha = alpha; }
274
275     inline float red() const { return clamp(_red); }
276     inline float green() const { return clamp(_green); }
277     inline float blue() const { return clamp(_blue); }
278     inline float alpha() const { return _alpha < 0.0 ? 1.0 : clamp(_alpha); }
279
280 protected:
281     float _red, _green, _blue, _alpha;
282
283 private:
284     float clamp(float f) const { return f < 0.0 ? 0.0 : f > 1.0 ? 1.0 : f; }
285 };
286
287
288
289 /**
290  * A class to keep all fonts available for future use.
291  * This also assures a font isn't resident more than once.
292  */
293 class FGFontCache {
294 private:
295     // The parameters of a request to the cache.
296     struct FntParams
297     {
298         const std::string name;
299         const float size;
300         const float slant;
301         FntParams() : size(0.0f), slant(0.0f) {}
302         FntParams(const FntParams& rhs)
303             : name(rhs.name), size(rhs.size), slant(rhs.slant)
304         {
305         }
306         FntParams(const std::string& name_, float size_, float slant_)
307             : name(name_), size(size_), slant(slant_)
308         {
309         }
310     };
311     struct FntParamsLess
312         : public std::binary_function<const FntParams, const FntParams, bool>
313     {
314         bool operator() (const FntParams& f1, const FntParams& f2) const;
315     };
316     struct fnt {
317         fnt(puFont *pu = 0) : pufont(pu), texfont(0) {}
318         ~fnt() { if (texfont) { delete pufont; delete texfont; } }
319         // Font used by plib GUI code
320         puFont *pufont;
321         // TXF font
322         fntTexFont *texfont;
323     };
324     // Path to the font directory
325     SGPath _path;
326
327     typedef map<const string, fntTexFont*> TexFontMap;
328     typedef map<const FntParams, fnt*, FntParamsLess> PuFontMap;
329     TexFontMap _texFonts;
330     PuFontMap _puFonts;
331
332     bool _initialized;
333     struct fnt *getfnt(const char *name, float size, float slant);
334     void init();
335
336 public:
337     FGFontCache();
338     ~FGFontCache();
339
340     puFont *get(const char *name, float size=15.0, float slant=0.0);
341     puFont *get(SGPropertyNode *node);
342
343     fntTexFont *getTexFont(const char *name, float size=15.0, float slant=0.0);
344
345     SGPath getfntpath(const char *name);
346     /**
347      * Preload all the fonts in the FlightGear font directory. It is
348      * important to load the font textures early, with the proper
349      * graphics context current, so that no plib (or our own) code
350      * tries to load a font from disk when there's no current graphics
351      * context.
352      */
353     bool initializeFonts();
354 };
355
356
357 #endif // __NEW_GUI_HXX
358