1 // panel.hxx - default, 2D single-engine prop instrument panel
3 // Written by David Megginson, started January 2000.
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License as
7 // published by the Free Software Foundation; either version 2 of the
8 // License, or (at your option) any later version.
10 // This program is distributed in the hope that it will be useful, but
11 // WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 # error This library requires C++
40 #include <simgear/misc/props.hxx>
49 class FGPanelInstrument;
53 ////////////////////////////////////////////////////////////////////////
54 // Texture manager (should migrate out into FGFS).
56 // This class ensures that no texture is loaded more than once.
57 ////////////////////////////////////////////////////////////////////////
59 class FGTextureManager
62 static ssgTexture * createTexture(const string &relativePath);
64 static map<string,ssgTexture *>_textureMap;
69 ////////////////////////////////////////////////////////////////////////
70 // Cropped texture (should migrate out into FGFS).
72 // This class defines a rectangular cropped area of a texture.
73 ////////////////////////////////////////////////////////////////////////
78 CroppedTexture (const string &path,
79 float _minX = 0.0, float _minY = 0.0,
80 float _maxX = 1.0, float _maxY = 1.0)
81 : texture(FGTextureManager::createTexture(path)),
82 minX(_minX), minY(_minY), maxX(_maxX), maxY(_maxY) {}
85 float minX, minY, maxX, maxY;
90 ////////////////////////////////////////////////////////////////////////
91 // Instrument panel class.
93 // The panel is a container that has a background texture and holds
94 // zero or more instruments. The panel will order the instruments to
95 // redraw themselves when necessary, and will pass mouse clicks on to
96 // the appropriate instruments for processing.
97 ////////////////////////////////////////////////////////////////////////
103 FGPanel (int x, int y, int w, int h);
106 // transfer pointer ownership!!!
107 virtual void addInstrument (FGPanelInstrument * instrument);
109 // Update the panel (every frame).
110 virtual void update () const;
112 // Background texture.
113 virtual void setBackground (ssgTexture * texture);
115 // Make the panel visible or invisible.
116 virtual bool getVisibility () const;
117 virtual void setVisibility (bool visibility);
119 // Handle a mouse click.
120 virtual bool doMouseAction (int button, int updown, int x, int y);
125 int _mouseButton, _mouseX, _mouseY;
126 mutable int _mouseDelay;
127 FGPanelInstrument * _mouseInstrument;
128 typedef vector<FGPanelInstrument *> instrument_list_type;
132 // List of instruments in panel.
133 instrument_list_type _instruments;
138 ////////////////////////////////////////////////////////////////////////
139 // Base class for user action types.
141 // Individual instruments can have actions associated with a mouse
142 // click in a rectangular area. Current concrete classes are
143 // FGAdjustAction and FGSwapAction.
144 ////////////////////////////////////////////////////////////////////////
149 virtual void doAction () = 0;
154 ////////////////////////////////////////////////////////////////////////
155 // Adjustment action.
157 // This is an action to increase or decrease an FGFS value by a certain
158 // increment within a certain range. If the wrap flag is true, the
159 // value will wrap around if it goes below min or above max; otherwise,
160 // it will simply stop at min or max.
161 ////////////////////////////////////////////////////////////////////////
163 class FGAdjustAction : public FGPanelAction
166 FGAdjustAction (SGValue * value, float increment,
167 float min, float max, bool wrap=false);
168 virtual ~FGAdjustAction ();
169 virtual void doAction ();
181 ////////////////////////////////////////////////////////////////////////
184 // This is an action to swap two values. It's currently used in the
185 // navigation radios.
186 ////////////////////////////////////////////////////////////////////////
188 class FGSwapAction : public FGPanelAction
191 FGSwapAction (SGValue * value1, SGValue * value2);
192 virtual ~FGSwapAction ();
193 virtual void doAction ();
202 ////////////////////////////////////////////////////////////////////////
205 // This is an action to toggle a boolean value.
206 ////////////////////////////////////////////////////////////////////////
208 class FGToggleAction : public FGPanelAction
211 FGToggleAction (SGValue * value);
212 virtual ~FGToggleAction ();
213 virtual void doAction ();
221 ////////////////////////////////////////////////////////////////////////
222 // Abstract base class for a panel instrument.
224 // A panel instrument consists of zero or more actions, associated
225 // with mouse clicks in rectangular areas. Currently, the only
226 // concrete class derived from this is FGLayeredInstrument, but others
227 // may show up in the future (some complex instruments could be
228 // entirely hand-coded, for example).
229 ////////////////////////////////////////////////////////////////////////
231 class FGPanelInstrument
234 FGPanelInstrument ();
235 FGPanelInstrument (int x, int y, int w, int h);
236 virtual ~FGPanelInstrument ();
238 virtual void draw () = 0;
240 virtual void setPosition(int x, int y);
241 virtual void setSize(int w, int h);
243 virtual int getXPos () const;
244 virtual int getYPos () const;
245 virtual int getWidth () const;
246 virtual int getHeight () const;
248 // Coordinates relative to centre.
249 // Transfer pointer ownership!!
250 virtual void addAction (int button, int x, int y, int w, int h,
251 FGPanelAction * action);
253 // Coordinates relative to centre.
254 virtual bool doMouseAction (int button, int x, int y);
264 FGPanelAction * action;
266 typedef vector<inst_action> action_list_type;
267 action_list_type _actions;
272 ////////////////////////////////////////////////////////////////////////
273 // Abstract base class for an instrument layer.
275 // The FGLayeredInstrument class builds up instruments by using layers
276 // of textures or text. Each layer can have zero or more
277 // transformations applied to it: for example, a needle layer can
278 // rotate to show the altitude or airspeed.
279 ////////////////////////////////////////////////////////////////////////
282 * A single layer of a multi-layered instrument.
284 * Each layer can be subject to a series of transformations based
285 * on current FGFS instrument readings: for example, a texture
286 * representing a needle can rotate to show the airspeed.
288 class FGInstrumentLayer
297 FGInstrumentLayer (int w = -1, int h = -1);
298 virtual ~FGInstrumentLayer ();
300 virtual void draw () = 0;
301 virtual void transform () const;
303 virtual int getWidth () const { return _w; }
304 virtual int getHeight () const { return _h; }
305 virtual void setWidth (int w) { _w = w; }
306 virtual void setHeight (int h) { _h = h; }
308 virtual void addTransformation (transform_type type, const SGValue * value,
309 float min, float max,
310 float factor = 1.0, float offset = 0.0);
317 const SGValue * value;
323 typedef vector<transformation *> transformation_list;
324 transformation_list _transformations;
329 ////////////////////////////////////////////////////////////////////////
330 // An instrument composed of layers.
332 // This class represents an instrument which is simply a series of
333 // layers piled one on top of the other, each one undergoing its own
334 // set of transformations. For example, one layer can represent
335 // the instrument's face (which doesn't move), while the next layer
336 // can represent a needle that rotates depending on an FGFS variable.
337 ////////////////////////////////////////////////////////////////////////
341 * An instrument constructed of multiple layers.
343 * Each individual layer can be rotated or shifted to correspond
344 * to internal FGFS instrument readings.
346 class FGLayeredInstrument : public FGPanelInstrument
349 typedef vector<FGInstrumentLayer *> layer_list;
350 FGLayeredInstrument (int x, int y, int w, int h);
351 virtual ~FGLayeredInstrument ();
353 virtual void draw ();
355 // Transfer pointer ownership!!
356 virtual int addLayer (FGInstrumentLayer *layer);
357 virtual int addLayer (CroppedTexture &texture,
358 int w = -1, int h = -1);
359 virtual void addTransformation (FGInstrumentLayer::transform_type type,
360 const SGValue * value,
361 float min, float max,
362 float factor = 1.0, float offset = 0.0);
363 virtual void addTransformation (FGInstrumentLayer::transform_type type,
372 ////////////////////////////////////////////////////////////////////////
373 // A textured layer of an instrument.
375 // This is a layer holding a single texture. Normally, the texture's
376 // backgound should be transparent so that lower layers and the panel
377 // background can show through.
378 ////////////////////////////////////////////////////////////////////////
380 class FGTexturedLayer : public FGInstrumentLayer
383 FGTexturedLayer (int w = -1, int h = -1) : FGInstrumentLayer(w, h) {}
384 FGTexturedLayer (CroppedTexture &texture, int w = -1, int h = -1);
385 virtual ~FGTexturedLayer ();
387 virtual void draw ();
389 virtual void setTexture (CroppedTexture &texture) { _texture = &texture; }
390 virtual CroppedTexture &getTexture () { return *_texture; }
393 mutable CroppedTexture * _texture;
398 ////////////////////////////////////////////////////////////////////////
399 // A text layer of an instrument.
401 // This is a layer holding a string of static and/or generated text.
402 // It is useful for instruments that have text displays, such as
403 // a chronometer, GPS, or NavCom radio.
404 ////////////////////////////////////////////////////////////////////////
406 class FGTextLayer : public FGInstrumentLayer
409 typedef enum ChunkType {
417 Chunk (char * text, char * fmt = "%s");
418 Chunk (ChunkType type, const SGValue * value,
419 char * fmt = 0, float mult = 1.0);
421 char * getValue () const;
426 const SGValue * _value;
430 mutable char _buf[1024];
433 FGTextLayer (int w = -1, int h = -1, Chunk * chunk1 = 0, Chunk * chunk2 = 0,
435 virtual ~FGTextLayer ();
437 virtual void draw ();
439 // Transfer pointer!!
440 virtual void addChunk (Chunk * chunk);
441 virtual void setColor (float r, float g, float b);
442 virtual void setPointSize (float size);
443 virtual void setFont (fntFont * font);
446 typedef vector<Chunk *> chunk_list;
449 // FIXME: need only one globally
450 mutable fntRenderer _renderer;
455 ////////////////////////////////////////////////////////////////////////
456 // A layer that switches between two other layers.
457 ////////////////////////////////////////////////////////////////////////
459 class FGSwitchLayer : public FGInstrumentLayer
462 // Transfer pointers!!
463 FGSwitchLayer (int w, int h, const SGValue * value,
464 FGInstrumentLayer * layer1,
465 FGInstrumentLayer * layer2);
466 virtual ~FGSwitchLayer ();
468 virtual void draw ();
471 const SGValue * _value;
472 FGInstrumentLayer * _layer1, * _layer2;
477 ////////////////////////////////////////////////////////////////////////
478 // The current panel, if any.
479 ////////////////////////////////////////////////////////////////////////
481 extern FGPanel * current_panel;
485 #endif // __PANEL_HXX