X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FGUI%2Fnew_gui.hxx;h=6bc2707157eec18780bbf377ecab6b9441d24a75;hb=fc71333bdd0217a9ff4880305daf6d4d10fb0b40;hp=91a6aa3dfcec00471b8759beede0014b7af311f2;hpb=011118315322b4b3186d30fed4ce368ff4430c04;p=flightgear.git diff --git a/src/GUI/new_gui.hxx b/src/GUI/new_gui.hxx index 91a6aa3df..6bc270715 100644 --- a/src/GUI/new_gui.hxx +++ b/src/GUI/new_gui.hxx @@ -1,4 +1,4 @@ -// new_gui.hxx - XML-configurable GUI subsystem. +// new_gui.hxx - XML-configured GUI subsystem. #ifndef __NEW_GUI_HXX #define __NEW_GUI_HXX 1 @@ -7,143 +7,352 @@ # error This library requires C++ #endif +#ifdef HAVE_CONFIG_H +# include +#endif + #include #include // for SG_USING_STD -#include +#include +#include +#include +#include #include -SG_USING_STD(vector); - #include -SG_USING_STD(map); -#include
+using std::vector; +using std::map; +using std::string; + #include
-#include -class GUIWidget; +class SGBinding; + +class FGMenuBar; +class FGDialog; +class FGColor; +class FGFontCache; /** - * Information about a GUI widget. + * XML-configured GUI subsystem. + * + * This subsystem manages the graphical user interface for FlightGear. + * It creates a menubar from the XML configuration file in + * $FG_ROOT/gui/menubar.xml, then stores the configuration properties + * for XML-configured dialog boxes found in $FG_ROOT/gui/dialogs/. It + * can show or hide the menubar, and can display any dialog by name. */ -struct GUIInfo +class NewGUI : public SGSubsystem { - GUIInfo (GUIWidget * w); - virtual ~GUIInfo (); +public: - GUIWidget * widget; - vector bindings; -}; + /** + * Constructor. + */ + NewGUI (); + + /** + * Destructor. + */ + virtual ~NewGUI (); + /** + * Initialize the GUI subsystem. + */ + virtual void init (); -/** - * Top-level GUI widget. - */ -class GUIWidget -{ -public: + /** + * Reinitialize the GUI subsystem. Reloads all XML dialogs. + */ + virtual void reinit (); + /** + * Bind properties for the GUI subsystem. + * + * Currently, this method binds the properties for showing and + * hiding the menu. + */ + virtual void bind (); /** - * Construct a new GUI widget configured by a property tree. + * Unbind properties for the GUI subsystem. */ - GUIWidget (SGPropertyNode_ptr props); + virtual void unbind (); + /** + * Update the GUI subsystem. + * + * Currently, this method is a no-op, because nothing the GUI + * subsystem does is time-dependent. + */ + virtual void update (double delta_time_sec); /** - * Destructor. + * Redraw the GUI picking up new GUI colors. + */ + virtual void redraw (); + + /** + * Creates a new dialog box, using the same property format as the + * gui/dialogs configuration files. Does not display the + * resulting dialog. If a pre-existing dialog of the same name + * exists, it will be deleted. The node argument will be stored + * in the GUI subsystem using SGPropertNode_ptr reference counting. + * It should not be deleted by user code. + * + * @param node A property node containing the dialog definition */ - virtual ~GUIWidget (); + virtual void newDialog (SGPropertyNode* node); + + /** + * Display a dialog box. + * + * At initialization time, the subsystem reads all of the XML + * configuration files from the directory $FG_ROOT/gui/dialogs/. + * The configuration for each dialog specifies a name, and this + * method invokes the dialog with the name specified (if it + * exists). + * + * @param name The name of the dialog box. + * @return true if the dialog exists, false otherwise. + */ + virtual bool showDialog (const string &name); /** - * Update the values of all GUI objects with a specific name. + * Close the currenty active dialog. This function is intended to + * be called from code (pui callbacks, for instance) that registers + * its dialog object as active via setActiveDialog(). Other + * user-level code should use the closeDialog(name) API. * - * This method copies from the property to the GUI object. + * @return true if a dialog was active, false otherwise + */ + virtual bool closeActiveDialog (); + + /** + * Close a named dialog, if it is open. * - * @param objectName The name of the GUI object(s) to update. - * Use the empty name for all unnamed objects. + * @param name The name of the dialog box. + * @return true if the dialog was active, false otherwise. */ - virtual void updateValue (const char * objectName); + virtual bool closeDialog (const string &name); + /** + * Get dialog property tree's root node. + * @param name The name of the dialog box. + * @return node pointer if the dialog was found, zero otherwise. + */ + virtual SGPropertyNode_ptr getDialogProperties (const string &name); + + /** + * Return a pointer to the current menubar. + */ + virtual FGMenuBar * getMenuBar (); /** - * Apply the values of all GUI objects with a specific name. + * Ignore this method. * - * This method copies from the GUI object to the property. + * This method is for internal use only, but it has to be public + * so that a non-class callback can see it. + */ + virtual void setActiveDialog (FGDialog * dialog); + + /** + * Get the dialog currently active, if any. * - * @param objectName The name of the GUI object(s) to update. - * Use the empty name for all unnamed objects. + * @return The active dialog, or 0 if none is active. */ - virtual void applyValue (const char * objectName); + virtual FGDialog * getActiveDialog (); /** - * Update the values of all GUI objects. + * Get the named dialog if active. * - * This method copies from the properties to the GUI objects. + * @return The named dialog, or 0 if it isn't active. */ - virtual void updateValues (); + virtual FGDialog * getDialog (const string &name); + + + virtual FGColor *getColor (const char * name) const { + _citt_t it = _colors.find(name); + return (it != _colors.end()) ? it->second : NULL; + } + virtual FGColor *getColor (const string &name) const { + _citt_t it = _colors.find(name.c_str()); + return (it != _colors.end()) ? it->second : NULL; + } + + virtual puFont *getDefaultFont() { return _font; } +protected: + + /** + * Test if the menubar is visible. + * + * This method exists only for binding. + */ + virtual bool getMenuBarVisible () const; + /** - * Apply the values of all GUI objects. + * Show or hide the menubar. * - * This method copies from the GUI objects to the properties. + * This method exists only for binding. */ - virtual void applyValues (); + virtual void setMenuBarVisible (bool visible); + virtual void setStyle (); + virtual void setupFont (SGPropertyNode *); + + /** + * Used by reinit() and redraw() to close all dialogs and to apply + * current GUI colors. If "reload" is false, reopens all dialogs. + * Otherwise reloads all XML dialog files from disk and reopens all + * but Nasal * generated dialogs, omitting dynamic widgets. (This + * is only useful for GUI development.) + */ + virtual void reset (bool reload); private: - GUIWidget (const GUIWidget &); // just for safety - - void display (SGPropertyNode_ptr props); - puObject * makeObject (SGPropertyNode * props, - int parentWidth, int parentHeight); - void setupObject (puObject * object, SGPropertyNode * props); - void setupGroup (puGroup * group, SGPropertyNode * props, - int width, int height, bool makeFrame = false); - - puObject * _object; - vector _info; - struct PropertyObject { - PropertyObject (const char * name, - puObject * object, - SGPropertyNode_ptr node); - string name; - puObject * object; - SGPropertyNode_ptr node; + struct ltstr + { + bool operator()(const char* s1, const char* s2) const { + return strcmp(s1, s2) < 0; + } }; - vector _propertyObjects; + + puFont *_font; + map _colors; + typedef map::iterator _itt_t; + typedef map::const_iterator _citt_t; + + void clear_colors(); + + // Read all the configuration files in a directory. + void readDir (const char * path); + + FGMenuBar * _menubar; + FGDialog * _active_dialog; + map _active_dialogs; + map _dialog_props; + }; -class NewGUI : public FGSubsystem -{ +class FGColor { public: + FGColor() { clear(); } + FGColor(float r, float g, float b, float a = 1.0f) { set(r, g, b, a); } + FGColor(const SGPropertyNode *prop) { set(prop); } + FGColor(FGColor *c) { + if (c) set(c->_red, c->_green, c->_blue, c->_alpha); + } + + inline void clear() { _red = _green = _blue = _alpha = -1.0f; } + // merges in non-negative components from property with children etc. + bool merge(const SGPropertyNode *prop); + bool merge(const FGColor *color); + + bool set(const SGPropertyNode *prop) { clear(); return merge(prop); }; + bool set(const FGColor *color) { clear(); return merge(color); } + bool set(float r, float g, float b, float a = 1.0f) { + _red = r, _green = g, _blue = b, _alpha = a; + return true; + } + bool isValid() const { + return _red >= 0.0 && _green >= 0.0 && _blue >= 0.0; + } + void print() const; + + inline void setRed(float red) { _red = red; } + inline void setGreen(float green) { _green = green; } + inline void setBlue(float blue) { _blue = blue; } + inline void setAlpha(float alpha) { _alpha = alpha; } + + inline float red() const { return clamp(_red); } + inline float green() const { return clamp(_green); } + inline float blue() const { return clamp(_blue); } + inline float alpha() const { return _alpha < 0.0 ? 1.0 : clamp(_alpha); } + +protected: + float _red, _green, _blue, _alpha; - NewGUI (); - virtual ~NewGUI (); - virtual void init (); - virtual void update (double delta_time_sec); - virtual void display (const string &name); +private: + float clamp(float f) const { return f < 0.0 ? 0.0 : f > 1.0 ? 1.0 : f; } +}; - virtual void setCurrentWidget (GUIWidget * widget); - virtual GUIWidget * getCurrentWidget (); +/** + * A class to keep all fonts available for future use. + * This also assures a font isn't resident more than once. + */ +class FGFontCache { private: + // The parameters of a request to the cache. + struct FntParams + { + const std::string name; + const float size; + const float slant; + FntParams() : size(0.0f), slant(0.0f) {} + FntParams(const FntParams& rhs) + : name(rhs.name), size(rhs.size), slant(rhs.slant) + { + } + FntParams(const std::string& name_, float size_, float slant_) + : name(name_), size(size_), slant(slant_) + { + } + }; + struct FntParamsLess + : public std::binary_function + { + bool operator() (const FntParams& f1, const FntParams& f2) const; + }; + struct fnt { + fnt(puFont *pu = 0) : pufont(pu), texfont(0) {} + ~fnt() { if (texfont) { delete pufont; delete texfont; } } + // Font used by plib GUI code + puFont *pufont; + // TXF font + fntTexFont *texfont; + }; + // Path to the font directory + SGPath _path; - void readDir (const char * path); + typedef map TexFontMap; + typedef map PuFontMap; + TexFontMap _texFonts; + PuFontMap _puFonts; - GUIWidget * _current_widget; - map _widgets; + bool _initialized; + struct fnt *getfnt(const char *name, float size, float slant); + void init(); +public: + FGFontCache(); + ~FGFontCache(); + + puFont *get(const char *name, float size=15.0, float slant=0.0); + puFont *get(SGPropertyNode *node); + + fntTexFont *getTexFont(const char *name, float size=15.0, float slant=0.0); + + SGPath getfntpath(const char *name); + /** + * Preload all the fonts in the FlightGear font directory. It is + * important to load the font textures early, with the proper + * graphics context current, so that no plib (or our own) code + * tries to load a font from disk when there's no current graphics + * context. + */ + bool initializeFonts(); }; #endif // __NEW_GUI_HXX -// end of new_gui.hxx