X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FCockpit%2Fpanel.hxx;h=ab4f5264fabee673544d1a7ba01370b312607c45;hb=fdbfd6fd0b789eecf2c532d048a75d15f8d35ad8;hp=13e4f4aad0a2f683f249dd788a10cad5187ee208;hpb=06f56d14657d2582ec5441f77ad04d401dfae305;p=flightgear.git diff --git a/src/Cockpit/panel.hxx b/src/Cockpit/panel.hxx index 13e4f4aad..ab4f5264f 100644 --- a/src/Cockpit/panel.hxx +++ b/src/Cockpit/panel.hxx @@ -1,4 +1,4 @@ -// panel.hxx - default, 2D single-engine prop instrument panel +// panel.hxx - generic support classes for a 2D panel. // // Written by David Megginson, started January 2000. // @@ -11,100 +11,306 @@ // WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // General Public License for more details. -// +// // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software -// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // // $Id$ #ifndef __PANEL_HXX #define __PANEL_HXX -#ifndef __cplusplus -# error This library requires C++ -#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include -#ifdef HAVE_CONFIG_H -# include -#endif +#include +#include +#include -#ifdef HAVE_WINDOWS_H -# include -#endif +#include
-#include -#include +class FGPanelInstrument; +class fntFont; +class DCLGPS; -#include -#include +//////////////////////////////////////////////////////////////////////// +// Texture management. +//////////////////////////////////////////////////////////////////////// -FG_USING_STD(vector); -class FGPanelInstrument; +/** + * Texture manager (should migrate out into FGFS). + * + * This class ensures that no texture is loaded more than once. + */ +class FGTextureManager +{ +public: + static osg::Texture2D* createTexture(const std::string &relativePath, + bool staticTexture = true); + static void addTexture(const std::string &relativePath, osg::Texture2D* texture); +private: + static std::map > _textureMap; +}; + + +/** + * Cropped texture (should migrate out into FGFS). + * + * This structure wraps an SSG texture with cropping information. + */ +class FGCroppedTexture +{ +public: + + FGCroppedTexture (); + FGCroppedTexture (const std::string &path, + float _minX = 0.0, float _minY = 0.0, + float _maxX = 1.0, float _maxY = 1.0); + virtual ~FGCroppedTexture (); + + virtual void setPath (const std::string &path) { _path = path; } + + virtual const std::string &getPath () const { return _path; } + + virtual osg::StateSet* getTexture (); + + virtual void setCrop (float minX, float minY, float maxX, float maxY) { + _minX = minX; _minY = minY; _maxX = maxX; _maxY = maxY; + } + + virtual float getMinX () const { return _minX; } + virtual float getMinY () const { return _minY; } + virtual float getMaxX () const { return _maxX; } + virtual float getMaxY () const { return _maxY; } + + +private: + std::string _path; + osg::ref_ptr _texture; + float _minX, _minY, _maxX, _maxY; +}; //////////////////////////////////////////////////////////////////////// -// Instrument panel class. +// Top-level panel. //////////////////////////////////////////////////////////////////////// -class FGPanel + +/** + * Instrument panel class. + * + * The panel is a container that has a background texture and holds + * zero or more instruments. The panel will order the instruments to + * redraw themselves when necessary, and will pass mouse clicks on to + * the appropriate instruments for processing. + */ +class FGPanel : public SGSubsystem { public: - typedef vector instrument_list_type; - FGPanel (); virtual ~FGPanel (); - // Legacy interface from old panel. - static FGPanel * OurPanel; - virtual float get_height () const; - virtual void ReInit (int x, int y, int finx, int finy); - virtual void Update () const; + // Update the panel (every frame). + virtual void init (); + virtual void bind (); + virtual void unbind (); + virtual void draw (osg::State& state); + virtual void update (double); + void update (osg::State& state); + virtual void update (osg::State& state, GLfloat winx, GLfloat winw, GLfloat winy, GLfloat winh); -private: - int _x, _y, _w, _h; - int _panel_h; + virtual void updateMouseDelay(); + + // transfer pointer ownership!!! + virtual void addInstrument (FGPanelInstrument * instrument); + + // Background texture. + virtual void setBackground (osg::Texture2D* texture); + + // Background multiple textures. + virtual void setMultiBackground (osg::Texture2D* texture, int idx); - ssgTexture * _bg; + // Make the panel visible or invisible. + virtual bool getVisibility () const; + virtual void setVisibility (bool visibility); + // Full width of panel. + virtual void setWidth (int width) { _width = width; } + virtual int getWidth () const { return _width; } + + // Full height of panel. + virtual void setHeight (int height) { _height = height; } + virtual int getHeight () const { return _height; } + + // X-offset + virtual void setXOffset (int offset); + virtual int getXOffset () const { return _x_offset->getIntValue(); } + + // Y-offset. + virtual void setYOffset (int offset); + virtual int getYOffset () const { return _y_offset->getIntValue(); } + + // View height. + virtual void setViewHeight (int height) { _view_height = height; } + virtual int getViewHeight () const { return _view_height; } + + // Handle a mouse click. + virtual bool doMouseAction (int button, int updown, int x, int y); + virtual bool doLocalMouseAction(int button, int updown, int x, int y); + + virtual void setDepthTest (bool enable); + + bool getAutohide(void) const { return _autohide; }; + void setAutohide(bool enable) { _autohide = enable; }; + +private: + void setupVirtualCockpit(); + void cleanupVirtualCockpit(); + + mutable bool _mouseDown; + mutable int _mouseButton, _mouseX, _mouseY; + mutable int _mouseDelay; + mutable FGPanelInstrument * _mouseInstrument; + typedef std::vector instrument_list_type; + int _width; + int _height; + int _view_height; + + SGPropertyNode_ptr _visibility; + SGPropertyNode_ptr _x_offset; + SGPropertyNode_ptr _y_offset; + SGPropertyNode_ptr _jitter; + SGPropertyNode_ptr _flipx; + + SGConstPropertyNode_ptr _xsize_node; + SGConstPropertyNode_ptr _ysize_node; + + osg::ref_ptr _bg; + osg::ref_ptr _mbg[8]; + // List of instruments in panel. instrument_list_type _instruments; + bool _enable_depth_test; + bool _autohide; }; //////////////////////////////////////////////////////////////////////// -// Instrument base class. +// Actions //////////////////////////////////////////////////////////////////////// -class FGPanelInstrument + +/** + * Class for user actions. + * + * The actions are command bindings, like bindings for the keyboard + * or joystick, but they are tied to specific mouse actions in + * rectangular areas of the panel. + */ +class FGPanelAction : public SGConditional { public: - FGPanelInstrument (); - FGPanelInstrument (int x, int y, int w, int h); - virtual ~FGPanelInstrument (); + FGPanelAction (); + FGPanelAction (int button, int x, int y, int w, int h, bool repeatable); + virtual ~FGPanelAction (); + + // Getters. + virtual int getButton () const { return _button; } + virtual int getX () const { return _x; } + virtual int getY () const { return _y; } + virtual int getWidth () const { return _w; } + virtual int getHeight () const { return _h; } + + // Setters. + + // transfer pointer ownership + virtual void addBinding (SGBinding * binding, int updown); + virtual void setButton (int button) { _button = button; } + virtual void setX (int x) { _x = x; } + virtual void setY (int y) { _y = y; } + virtual void setWidth (int w) { _w = w; } + virtual void setHeight (int h) { _h = h; } + + // Check whether we're in the area. + virtual bool inArea (int button, int x, int y) + { + return (button == _button && + x >= _x && + x < _x + _w && + y >= _y && + y < _y + _h); + } - virtual void draw () const = 0; + // Perform the action. + virtual bool doAction (int updown); - virtual void setPosition(int x, int y); - virtual void setSize(int w, int h); +private: + typedef std::vector binding_list_t; + + int _button; + int _x; + int _y; + int _w; + int _h; + bool _repeatable; + int _last_state; + binding_list_t _bindings[2]; +}; - virtual int getXPos () const; - virtual int getYPos () const; -protected: - int _x, _y, _w, _h; + +//////////////////////////////////////////////////////////////////////// +// Transformations. +//////////////////////////////////////////////////////////////////////// + + +/** + * A transformation for a layer. + */ +class FGPanelTransformation : public SGConditional +{ +public: + + enum Type { + XSHIFT, + YSHIFT, + ROTATION + }; + + FGPanelTransformation (); + virtual ~FGPanelTransformation (); + + Type type; + SGConstPropertyNode_ptr node; + float min; + float max; + bool has_mod; + float mod; + float factor; + float offset; + SGInterpTable * table; }; + //////////////////////////////////////////////////////////////////////// -// A single layer of an instrument. +// Layers //////////////////////////////////////////////////////////////////////// + /** * A single layer of a multi-layered instrument. * @@ -112,51 +318,80 @@ protected: * on current FGFS instrument readings: for example, a texture * representing a needle can rotate to show the airspeed. */ -class FGInstrumentLayer +class FGInstrumentLayer : public SGConditional { public: - typedef enum { - XSHIFT, - YSHIFT, - ROTATION - } transform_type; - - typedef double (*transform_func)(); - - FGInstrumentLayer (); - FGInstrumentLayer (int w, int h, int z); + FGInstrumentLayer (int w = -1, int h = -1); virtual ~FGInstrumentLayer (); - virtual void draw () const = 0; + virtual void draw (osg::State& state) = 0; virtual void transform () const; - virtual void addTransformation (transform_type type, transform_func func, - double min, double max, - double factor = 1.0, double offset = 0.0); + virtual int getWidth () const { return _w; } + virtual int getHeight () const { return _h; } + virtual void setWidth (int w) { _w = w; } + virtual void setHeight (int h) { _h = h; } + + // Transfer pointer ownership!! + // DEPRECATED + virtual void addTransformation (FGPanelTransformation * transformation); protected: - int _w, _h, _z; - - typedef struct { - transform_type type; - transform_func func; - double min; - double max; - double factor; - double offset; - } transformation; - typedef vector transformation_list; + int _w, _h; + + typedef std::vector transformation_list; transformation_list _transformations; }; //////////////////////////////////////////////////////////////////////// -// An instrument composed of layered textures. +// Instruments. //////////////////////////////////////////////////////////////////////// +/** + * Abstract base class for a panel instrument. + * + * A panel instrument consists of zero or more actions, associated + * with mouse clicks in rectangular areas. Currently, the only + * concrete class derived from this is FGLayeredInstrument, but others + * may show up in the future (some complex instruments could be + * entirely hand-coded, for example). + */ +class FGPanelInstrument : public SGConditional +{ +public: + FGPanelInstrument (); + FGPanelInstrument (int x, int y, int w, int h); + virtual ~FGPanelInstrument (); + + virtual void draw (osg::State& state) = 0; + virtual void drawHotspots(osg::State& state); + + virtual void setPosition(int x, int y); + virtual void setSize(int w, int h); + + virtual int getXPos () const; + virtual int getYPos () const; + virtual int getWidth () const; + virtual int getHeight () const; + + // Coordinates relative to centre. + // Transfer pointer ownership!! + virtual void addAction (FGPanelAction * action); + + // Coordinates relative to centre. + virtual bool doMouseAction (int button, int updown, int x, int y); + +protected: + int _x, _y, _w, _h; + typedef std::vector action_list_type; + action_list_type _actions; +}; + + /** * An instrument constructed of multiple layers. * @@ -166,91 +401,192 @@ protected: class FGLayeredInstrument : public FGPanelInstrument { public: - typedef vector layer_list; FGLayeredInstrument (int x, int y, int w, int h); virtual ~FGLayeredInstrument (); - virtual void draw () const; - - virtual void addLayer (FGInstrumentLayer *layer); - virtual void addLayer (int i, const char *textureName); - virtual void addTransformation (int layer, - FGInstrumentLayer::transform_type type, - FGInstrumentLayer::transform_func func, - double min, double max, - double factor = 1.0, double offset = 0.0); - virtual void addTransformation (int layer, - FGInstrumentLayer::transform_type type, - double offset) { - addTransformation(layer, type, 0, 0.0, 0.0, 1.0, offset); - } + virtual void draw (osg::State& state); + + // Transfer pointer ownership!! + virtual int addLayer (FGInstrumentLayer *layer); + virtual int addLayer (const FGCroppedTexture &texture, int w = -1, int h = -1); + + // Transfer pointer ownership!! + virtual void addTransformation (FGPanelTransformation * transformation); protected: + typedef std::vector layer_list; layer_list _layers; }; - -//////////////////////////////////////////////////////////////////////// -// A textured layer of an instrument. -//////////////////////////////////////////////////////////////////////// +/** + * An empty-shell instrument that exists soley in + * order to redirect commands from the panel to a + * complex instrument inherited from SGSubsystem. + * + * Currently the only complex instrument is the KLN89, + * which we've hardwired this to for now. + */ +class FGSpecialInstrument : public FGPanelInstrument +{ +public: + FGSpecialInstrument(DCLGPS* sb); + //FGSpecialInstrument (int x, int y, int w, int h); + virtual ~FGSpecialInstrument (); + + virtual void draw (osg::State& state); + +protected: + DCLGPS* complex; +}; + + +/** + * An instrument layer containing a group of sublayers. + * + * This class is useful for gathering together a group of related + * layers, either to hold in an external file or to work under + * the same condition. + */ +class FGGroupLayer : public FGInstrumentLayer +{ +public: + FGGroupLayer (); + virtual ~FGGroupLayer (); + virtual void draw (osg::State& state); + // transfer pointer ownership + virtual void addLayer (FGInstrumentLayer * layer); +protected: + std::vector _layers; +}; + /** * A textured layer of an instrument. * - * This is a type of layer designed to hold a texture; normally, - * the texture's background should be transparent so that - * other layers or the panel background show through. + * This is a layer holding a single texture. Normally, the texture's + * backgound should be transparent so that lower layers and the panel + * background can show through. */ -class FGTexturedInstrumentLayer : public FGInstrumentLayer +class FGTexturedLayer : public FGInstrumentLayer { public: - FGTexturedInstrumentLayer (const char * textureName, - int w, int h, int z); - FGTexturedInstrumentLayer (ssgTexture * texture, - int w, int h, int z); - virtual ~FGTexturedInstrumentLayer (); + FGTexturedLayer (int w = -1, int h = -1) : FGInstrumentLayer(w, h) {} + FGTexturedLayer (const FGCroppedTexture &texture, int w = -1, int h = -1); + virtual ~FGTexturedLayer (); - virtual void draw () const; + virtual void draw (osg::State& state); - virtual void setTexture (const char *textureName); - virtual void setTexture (ssgTexture * texture) { _texture = texture; } + virtual void setTexture (const FGCroppedTexture &texture) { + _texture = texture; + } + virtual const FGCroppedTexture &getTexture () const { return _texture; } + virtual FGCroppedTexture *getTexture() { return &_texture; } + + void setEmissive(bool e) { _emissive = e; } private: - ssgTexture * _texture; + FGCroppedTexture _texture; + bool _emissive; }; - -//////////////////////////////////////////////////////////////////////// -// A text layer of an instrument. -//////////////////////////////////////////////////////////////////////// - -class FGCharInstrumentLayer : public FGInstrumentLayer +/** + * A text layer of an instrument. + * + * This is a layer holding a string of static and/or generated text. + * It is useful for instruments that have text displays, such as + * a chronometer, GPS, or NavCom radio. + */ +class FGTextLayer : public FGInstrumentLayer { public: - typedef char * (*text_func)(char *); - FGCharInstrumentLayer (text_func func, - int w, int h, int z); - virtual ~FGCharInstrumentLayer (); - - virtual void draw () const; + enum ChunkType { + TEXT, + TEXT_VALUE, + DOUBLE_VALUE + }; + + class Chunk : public SGConditional + { + public: + Chunk (const std::string &text, const std::string &fmt = "%s"); + Chunk (ChunkType type, const SGPropertyNode * node, + const std::string &fmt = "", float mult = 1.0, float offs = 0.0, + bool truncation = false); + + const char * getValue () const; + private: + ChunkType _type; + std::string _text; + SGConstPropertyNode_ptr _node; + std::string _fmt; + float _mult; + float _offs; + bool _trunc; + mutable char _buf[1024]; + }; + + FGTextLayer (int w = -1, int h = -1); + virtual ~FGTextLayer (); + + virtual void draw (osg::State& state); + + // Transfer pointer!! + virtual void addChunk (Chunk * chunk); virtual void setColor (float r, float g, float b); virtual void setPointSize (float size); + virtual void setFontName ( const std::string &name ); virtual void setFont (fntFont * font); private: - text_func _func; - float _color[3]; - // FIXME: need only one globally - mutable fntRenderer _renderer; - mutable char _buf[1024]; + + void recalc_value () const; + + typedef std::vector chunk_list; + chunk_list _chunks; + float _color[4]; + + float _pointSize; + mutable std::string _font_name; + mutable std::string _value; + mutable SGTimeStamp _then; + mutable SGTimeStamp _now; +}; + + +/** + * A group layer that switches among its children. + * + * The first layer that passes its condition will be drawn, and + * any following layers will be ignored. + */ +class FGSwitchLayer : public FGGroupLayer +{ +public: + // Transfer pointers!! + FGSwitchLayer (); + virtual void draw (osg::State& state); + }; + + +//////////////////////////////////////////////////////////////////////// +// Functions. +//////////////////////////////////////////////////////////////////////// + +/** + * Test whether the panel should be visible. + */ +bool fgPanelVisible (); + + #endif // __PANEL_HXX // end of panel.hxx +