X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FCockpit%2Fpanel.hxx;h=1adc9e811569859c14e7cdf5e909cea6bfed5f24;hb=29275ce1ecf9c4ea302aacca8c5ae5d4d3319a17;hp=0f2910872286911b765a30acb3ab998422a24657;hpb=c2226f6e3480c99306fe197b8aef63c9613e825b;p=flightgear.git diff --git a/src/Cockpit/panel.hxx b/src/Cockpit/panel.hxx index 0f2910872..1adc9e811 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. // @@ -30,6 +30,8 @@ # include #endif +#include + #ifdef HAVE_WINDOWS_H # include #endif @@ -37,47 +39,149 @@ #include #include +#include +#include + #include -#include +#include #include +#include
+ + FG_USING_STD(vector); -FG_USING_STD(hash_map); +FG_USING_STD(map); class FGPanelInstrument; + + +//////////////////////////////////////////////////////////////////////// +// Texture manager (should migrate out into FGFS). +// +// This class ensures that no texture is loaded more than once. +//////////////////////////////////////////////////////////////////////// + +class FGTextureManager +{ +public: + static ssgTexture * createTexture(const string &relativePath); +private: + static map _textureMap; +}; + + + +//////////////////////////////////////////////////////////////////////// +// Cropped texture (should migrate out into FGFS). +// +// This structure wraps an SSG texture with cropping information. +//////////////////////////////////////////////////////////////////////// + +class FGCroppedTexture +{ +public: + + FGCroppedTexture (); + FGCroppedTexture (const string &path, + float _minX = 0.0, float _minY = 0.0, + float _maxX = 1.0, float _maxY = 1.0); + virtual ~FGCroppedTexture (); + + virtual void setPath (const string &path) { _path = path; } + + virtual const string &getPath () const { return _path; } + + virtual ssgTexture * 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: + string _path; + ssgTexture * _texture; + float _minX, _minY, _maxX, _maxY; +}; + + //////////////////////////////////////////////////////////////////////// // 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 +class FGPanel : public FGSubsystem { public: - FGPanel (); + FGPanel (int window_x, int window_y, int window_w, int window_h); virtual ~FGPanel (); - virtual ssgTexture * createTexture (const char * relativePath); + // Update the panel (every frame). + virtual void init (); + virtual void bind (); + virtual void unbind (); + virtual void update (); - // 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; + // transfer pointer ownership!!! + virtual void addInstrument (FGPanelInstrument * instrument); -private: + // Background texture. + virtual void setBackground (ssgTexture * texture); - typedef vector instrument_list_type; + // Make the panel visible or invisible. + virtual bool getVisibility () const; + virtual void setVisibility (bool visibility); - int _x, _y, _w, _h; - int _panel_h; + // Full width of panel. + virtual void setWidth (int width) { _width = width; } + virtual int getWidth () const { return _width; } - ssgTexture * _bg; + // Full height of panel. + virtual void setHeight (int height) { _height = height; } + virtual int getHeight () const { return _height; } - // Internalization table. - hash_map _textureMap; + // X-offset + virtual void setXOffset (int offset); + virtual int getXOffset () const { return _x_offset; } + // Y-offset. + virtual void setYOffset (int offset); + virtual int getYOffset () const { return _y_offset; } + + // 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); + +private: + mutable bool _visibility; + mutable bool _mouseDown; + mutable int _mouseButton, _mouseX, _mouseY; + mutable int _mouseDelay; + mutable FGPanelInstrument * _mouseInstrument; + typedef vector instrument_list_type; + int _winx, _winy, _winw, _winh; + int _width; + int _height; + int _x_offset; + int _y_offset; + int _view_height; + + ssgTexture * _bg; // List of instruments in panel. instrument_list_type _instruments; }; @@ -85,7 +189,135 @@ private: //////////////////////////////////////////////////////////////////////// -// Instrument base class. +// Base class for user action types. +// +// Individual instruments can have actions associated with a mouse +// click in a rectangular area. Current concrete classes include +// FGAdjustAction, FGSwapAction, and FGToggleAction. +//////////////////////////////////////////////////////////////////////// + +class FGPanelAction +{ +public: + FGPanelAction (); + FGPanelAction (int button, int x, int y, int w, int h); + 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. + 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); + } + + // Perform the action. + virtual void doAction () = 0; + +private: + int _button; + int _x; + int _y; + int _w; + int _h; +}; + + + +//////////////////////////////////////////////////////////////////////// +// Adjustment action. +// +// This is an action to increase or decrease an FGFS value by a certain +// increment within a certain range. If the wrap flag is true, the +// value will wrap around if it goes below min or above max; otherwise, +// it will simply stop at min or max. +//////////////////////////////////////////////////////////////////////// + +class FGAdjustAction : public FGPanelAction +{ +public: + FGAdjustAction (int button, int x, int y, int w, int h, + SGValue * value, float increment, + float min, float max, bool wrap=false); + virtual ~FGAdjustAction (); + virtual void doAction (); + +private: + SGValue * _value; + float _increment; + float _min; + float _max; + bool _wrap; +}; + + + +//////////////////////////////////////////////////////////////////////// +// Swap action. +// +// This is an action to swap two values. It's currently used in the +// navigation radios. +//////////////////////////////////////////////////////////////////////// + +class FGSwapAction : public FGPanelAction +{ +public: + FGSwapAction (int button, int x, int y, int w, int h, + SGValue * value1, SGValue * value2); + virtual ~FGSwapAction (); + virtual void doAction (); + +private: + SGValue * _value1; + SGValue * _value2; +}; + + + +//////////////////////////////////////////////////////////////////////// +// Toggle action. +// +// This is an action to toggle a boolean value. +//////////////////////////////////////////////////////////////////////// + +class FGToggleAction : public FGPanelAction +{ +public: + FGToggleAction (int button, int x, int y, int w, int h, + SGValue * value); + virtual ~FGToggleAction (); + virtual void doAction (); + +private: + SGValue * _value; +}; + + + +//////////////////////////////////////////////////////////////////////// +// 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 @@ -95,24 +327,66 @@ public: FGPanelInstrument (int x, int y, int w, int h); virtual ~FGPanelInstrument (); - virtual void draw () const = 0; + virtual void draw () = 0; 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 x, int y); protected: int _x, _y, _w, _h; + typedef vector action_list_type; + action_list_type _actions; }; //////////////////////////////////////////////////////////////////////// -// A single layer of an instrument. +// Abstract base class for an instrument layer. +// +// The FGLayeredInstrument class builds up instruments by using layers +// of textures or text. Each layer can have zero or more +// transformations applied to it: for example, a needle layer can +// rotate to show the altitude or airspeed. //////////////////////////////////////////////////////////////////////// + +/** + * A transformation for a layer. + */ +class FGPanelTransformation { +public: + + enum Type { + XSHIFT, + YSHIFT, + ROTATION + }; + + FGPanelTransformation (); + virtual ~FGPanelTransformation (); + + Type type; + const SGValue * value; + float min; + float max; + float factor; + float offset; +}; + + + /** * A single layer of a multi-layered instrument. * @@ -123,45 +397,39 @@ protected: class FGInstrumentLayer { 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 () = 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 vector transformation_list; transformation_list _transformations; }; //////////////////////////////////////////////////////////////////////// -// An instrument composed of layered textures. +// An instrument composed of layers. +// +// This class represents an instrument which is simply a series of +// layers piled one on top of the other, each one undergoing its own +// set of transformations. For example, one layer can represent +// the instrument's face (which doesn't move), while the next layer +// can represent a needle that rotates depending on an FGFS variable. //////////////////////////////////////////////////////////////////////// @@ -174,26 +442,20 @@ 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, ssgTexture * texture); - 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 (); + + // Transfer pointer ownership!! + virtual int addLayer (FGInstrumentLayer *layer); + virtual int addLayer (FGCroppedTexture &texture, int w = -1, int h = -1); + + // Transfer pointer ownership!! + virtual void addTransformation (FGPanelTransformation * transformation); protected: + typedef vector layer_list; layer_list _layers; }; @@ -201,58 +463,131 @@ protected: //////////////////////////////////////////////////////////////////////// // A textured layer of an instrument. +// +// 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. //////////////////////////////////////////////////////////////////////// -/** - * 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. - */ -class FGTexturedInstrumentLayer : public FGInstrumentLayer +class FGTexturedLayer : public FGInstrumentLayer { public: - 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 (); - virtual void setTexture (ssgTexture * texture) { _texture = texture; } + virtual void setTexture (const FGCroppedTexture &texture) { + _texture = texture; + } + virtual FGCroppedTexture &getTexture () { return _texture; } + virtual const FGCroppedTexture &getTexture () const { return _texture; } private: - ssgTexture * _texture; + mutable FGCroppedTexture _texture; }; //////////////////////////////////////////////////////////////////////// // 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 FGCharInstrumentLayer : public FGInstrumentLayer +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; + typedef enum ChunkType { + TEXT, + TEXT_VALUE, + DOUBLE_VALUE + }; + + class Chunk { + public: + Chunk (const string &text, const string &fmt = "%s"); + Chunk (ChunkType type, const SGValue * value, + const string &fmt = "", float mult = 1.0); + + const char * getValue () const; + private: + ChunkType _type; + string _text; + const SGValue * _value; + string _fmt; + float _mult; + mutable char _buf[1024]; + }; + + FGTextLayer (int w = -1, int h = -1); + virtual ~FGTextLayer (); + + virtual void draw (); + + // Transfer pointer!! + virtual void addChunk (Chunk * chunk); virtual void setColor (float r, float g, float b); virtual void setPointSize (float size); 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 vector chunk_list; + chunk_list _chunks; + float _color[4]; + + float _pointSize; + + mutable string _value; + mutable SGTimeStamp _then; + mutable SGTimeStamp _now; }; + +//////////////////////////////////////////////////////////////////////// +// A layer that switches between two other layers. +//////////////////////////////////////////////////////////////////////// + +class FGSwitchLayer : public FGInstrumentLayer +{ +public: + // Transfer pointers!! + FGSwitchLayer (int w, int h, const SGValue * value, + FGInstrumentLayer * layer1, + FGInstrumentLayer * layer2); + virtual ~FGSwitchLayer (); + + virtual void draw (); + +private: + const SGValue * _value; + FGInstrumentLayer * _layer1, * _layer2; +}; + + + +//////////////////////////////////////////////////////////////////////// +// Functions. +//////////////////////////////////////////////////////////////////////// + +bool fgPanelVisible (); + + + +//////////////////////////////////////////////////////////////////////// +// The current panel, if any. +//////////////////////////////////////////////////////////////////////// + +extern FGPanel * current_panel; + + #endif // __PANEL_HXX