1 // panel.hxx - generic support classes for a 2D 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 structure wraps an SSG texture with cropping information.
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);
123 mutable bool _visibility;
124 mutable bool _mouseDown;
125 mutable int _mouseButton, _mouseX, _mouseY;
126 mutable int _mouseDelay;
127 mutable 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 include
143 // FGAdjustAction, FGSwapAction, and FGToggleAction.
144 ////////////////////////////////////////////////////////////////////////
150 FGPanelAction (int button, int x, int y, int w, int h);
151 virtual ~FGPanelAction ();
154 virtual int getButton () const { return _button; }
155 virtual int getX () const { return _x; }
156 virtual int getY () const { return _y; }
157 virtual int getWidth () const { return _w; }
158 virtual int getHeight () const { return _h; }
161 virtual void setButton (int button) { _button = button; }
162 virtual void setX (int x) { _x = x; }
163 virtual void setY (int y) { _y = y; }
164 virtual void setWidth (int w) { _w = w; }
165 virtual void setHeight (int h) { _h = h; }
167 // Check whether we're in the area.
168 virtual bool inArea (int button, int x, int y)
170 return (button == _button &&
177 // Perform the action.
178 virtual void doAction () = 0;
190 ////////////////////////////////////////////////////////////////////////
191 // Adjustment action.
193 // This is an action to increase or decrease an FGFS value by a certain
194 // increment within a certain range. If the wrap flag is true, the
195 // value will wrap around if it goes below min or above max; otherwise,
196 // it will simply stop at min or max.
197 ////////////////////////////////////////////////////////////////////////
199 class FGAdjustAction : public FGPanelAction
202 FGAdjustAction (int button, int x, int y, int w, int h,
203 SGValue * value, float increment,
204 float min, float max, bool wrap=false);
205 virtual ~FGAdjustAction ();
206 virtual void doAction ();
218 ////////////////////////////////////////////////////////////////////////
221 // This is an action to swap two values. It's currently used in the
222 // navigation radios.
223 ////////////////////////////////////////////////////////////////////////
225 class FGSwapAction : public FGPanelAction
228 FGSwapAction (int button, int x, int y, int w, int h,
229 SGValue * value1, SGValue * value2);
230 virtual ~FGSwapAction ();
231 virtual void doAction ();
240 ////////////////////////////////////////////////////////////////////////
243 // This is an action to toggle a boolean value.
244 ////////////////////////////////////////////////////////////////////////
246 class FGToggleAction : public FGPanelAction
249 FGToggleAction (int button, int x, int y, int w, int h,
251 virtual ~FGToggleAction ();
252 virtual void doAction ();
260 ////////////////////////////////////////////////////////////////////////
261 // Abstract base class for a panel instrument.
263 // A panel instrument consists of zero or more actions, associated
264 // with mouse clicks in rectangular areas. Currently, the only
265 // concrete class derived from this is FGLayeredInstrument, but others
266 // may show up in the future (some complex instruments could be
267 // entirely hand-coded, for example).
268 ////////////////////////////////////////////////////////////////////////
270 class FGPanelInstrument
273 FGPanelInstrument ();
274 FGPanelInstrument (int x, int y, int w, int h);
275 virtual ~FGPanelInstrument ();
277 virtual void draw () = 0;
279 virtual void setPosition(int x, int y);
280 virtual void setSize(int w, int h);
282 virtual int getXPos () const;
283 virtual int getYPos () const;
284 virtual int getWidth () const;
285 virtual int getHeight () const;
287 // Coordinates relative to centre.
288 // Transfer pointer ownership!!
289 virtual void addAction (FGPanelAction * action);
291 // Coordinates relative to centre.
292 virtual bool doMouseAction (int button, int x, int y);
296 typedef vector<FGPanelAction *> action_list_type;
297 action_list_type _actions;
302 ////////////////////////////////////////////////////////////////////////
303 // Abstract base class for an instrument layer.
305 // The FGLayeredInstrument class builds up instruments by using layers
306 // of textures or text. Each layer can have zero or more
307 // transformations applied to it: for example, a needle layer can
308 // rotate to show the altitude or airspeed.
309 ////////////////////////////////////////////////////////////////////////
313 * A transformation for a layer.
315 class FGPanelTransformation {
324 FGPanelTransformation ();
325 FGPanelTransformation (Type type, const SGValue * value,
326 float min, float max,
327 float factor, float offset);
328 virtual ~FGPanelTransformation ();
331 const SGValue * value;
341 * A single layer of a multi-layered instrument.
343 * Each layer can be subject to a series of transformations based
344 * on current FGFS instrument readings: for example, a texture
345 * representing a needle can rotate to show the airspeed.
347 class FGInstrumentLayer
351 FGInstrumentLayer (int w = -1, int h = -1);
352 virtual ~FGInstrumentLayer ();
354 virtual void draw () = 0;
355 virtual void transform () const;
357 virtual int getWidth () const { return _w; }
358 virtual int getHeight () const { return _h; }
359 virtual void setWidth (int w) { _w = w; }
360 virtual void setHeight (int h) { _h = h; }
362 // Transfer pointer ownership!!
364 virtual void addTransformation (FGPanelTransformation * transformation);
369 typedef vector<FGPanelTransformation *> transformation_list;
370 transformation_list _transformations;
375 ////////////////////////////////////////////////////////////////////////
376 // An instrument composed of layers.
378 // This class represents an instrument which is simply a series of
379 // layers piled one on top of the other, each one undergoing its own
380 // set of transformations. For example, one layer can represent
381 // the instrument's face (which doesn't move), while the next layer
382 // can represent a needle that rotates depending on an FGFS variable.
383 ////////////////////////////////////////////////////////////////////////
387 * An instrument constructed of multiple layers.
389 * Each individual layer can be rotated or shifted to correspond
390 * to internal FGFS instrument readings.
392 class FGLayeredInstrument : public FGPanelInstrument
395 typedef vector<FGInstrumentLayer *> layer_list;
396 FGLayeredInstrument (int x, int y, int w, int h);
397 virtual ~FGLayeredInstrument ();
399 virtual void draw ();
401 // Transfer pointer ownership!!
402 virtual int addLayer (FGInstrumentLayer *layer);
403 virtual int addLayer (CroppedTexture &texture, int w = -1, int h = -1);
405 // Transfer pointer ownership!!
406 virtual void addTransformation (FGPanelTransformation * transformation);
414 ////////////////////////////////////////////////////////////////////////
415 // A textured layer of an instrument.
417 // This is a layer holding a single texture. Normally, the texture's
418 // backgound should be transparent so that lower layers and the panel
419 // background can show through.
420 ////////////////////////////////////////////////////////////////////////
422 class FGTexturedLayer : public FGInstrumentLayer
425 FGTexturedLayer (int w = -1, int h = -1) : FGInstrumentLayer(w, h) {}
426 FGTexturedLayer (const CroppedTexture &texture, int w = -1, int h = -1);
427 virtual ~FGTexturedLayer ();
429 virtual void draw ();
431 virtual void setTexture (const CroppedTexture &texture) {
434 virtual CroppedTexture &getTexture () { return _texture; }
435 virtual const CroppedTexture &getTexture () const { return _texture; }
438 mutable CroppedTexture _texture;
443 ////////////////////////////////////////////////////////////////////////
444 // A moving window on a texture.
446 // This layer automatically recrops a cropped texture based on
447 // property values, creating a moving window over the texture.
448 ////////////////////////////////////////////////////////////////////////
450 class FGWindowLayer : public FGTexturedLayer
453 FGWindowLayer (int w = -1, int h = -1);
454 FGWindowLayer (const CroppedTexture &texture, int w = -1, int h = -1);
455 virtual ~FGWindowLayer ();
457 virtual void draw ();
459 virtual const SGValue * getXValue () const { return _xValue; }
460 virtual void setXValue (const SGValue * value) { _xValue = value; }
461 virtual const SGValue * getYValue () const { return _yValue; }
462 virtual void setYValue (const SGValue * value) { _yValue = value; }
465 const SGValue * _xValue;
466 const SGValue * _yValue;
471 ////////////////////////////////////////////////////////////////////////
472 // A text layer of an instrument.
474 // This is a layer holding a string of static and/or generated text.
475 // It is useful for instruments that have text displays, such as
476 // a chronometer, GPS, or NavCom radio.
477 ////////////////////////////////////////////////////////////////////////
479 class FGTextLayer : public FGInstrumentLayer
482 typedef enum ChunkType {
490 Chunk (const string &text, const string &fmt = "%s");
491 Chunk (ChunkType type, const SGValue * value,
492 const string &fmt = "", float mult = 1.0);
494 const char * getValue () const;
498 const SGValue * _value;
501 mutable char _buf[1024];
504 FGTextLayer (int w = -1, int h = -1, Chunk * chunk1 = 0, Chunk * chunk2 = 0,
506 virtual ~FGTextLayer ();
508 virtual void draw ();
510 // Transfer pointer!!
511 virtual void addChunk (Chunk * chunk);
512 virtual void setColor (float r, float g, float b);
513 virtual void setPointSize (float size);
514 virtual void setFont (fntFont * font);
517 typedef vector<Chunk *> chunk_list;
522 // FIXME: need only one globally
523 mutable fntRenderer _renderer;
528 ////////////////////////////////////////////////////////////////////////
529 // A layer that switches between two other layers.
530 ////////////////////////////////////////////////////////////////////////
532 class FGSwitchLayer : public FGInstrumentLayer
535 // Transfer pointers!!
536 FGSwitchLayer (int w, int h, const SGValue * value,
537 FGInstrumentLayer * layer1,
538 FGInstrumentLayer * layer2);
539 virtual ~FGSwitchLayer ();
541 virtual void draw ();
544 const SGValue * _value;
545 FGInstrumentLayer * _layer1, * _layer2;
550 ////////////////////////////////////////////////////////////////////////
551 // The current panel, if any.
552 ////////////////////////////////////////////////////////////////////////
554 extern FGPanel * current_panel;
558 #endif // __PANEL_HXX