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++
33 #include <simgear/compiler.h>
42 #include <simgear/misc/props.hxx>
48 #include <Time/timestamp.hxx>
53 class FGPanelInstrument;
57 ////////////////////////////////////////////////////////////////////////
58 // Texture manager (should migrate out into FGFS).
60 // This class ensures that no texture is loaded more than once.
61 ////////////////////////////////////////////////////////////////////////
63 class FGTextureManager
66 static ssgTexture * createTexture(const string &relativePath);
68 static map<string,ssgTexture *> _textureMap;
73 ////////////////////////////////////////////////////////////////////////
74 // Cropped texture (should migrate out into FGFS).
76 // This structure wraps an SSG texture with cropping information.
77 ////////////////////////////////////////////////////////////////////////
79 class FGCroppedTexture
84 FGCroppedTexture (const string &path,
85 float _minX = 0.0, float _minY = 0.0,
86 float _maxX = 1.0, float _maxY = 1.0);
87 virtual ~FGCroppedTexture ();
89 virtual void setPath (const string &path) { _path = path; }
91 virtual const string &getPath () const { return _path; }
93 virtual ssgTexture * getTexture ();
95 virtual void setCrop (float minX, float minY, float maxX, float maxY) {
96 _minX = minX; _minY = minY; _maxX = maxX; _maxY = maxY;
99 virtual float getMinX () const { return _minX; }
100 virtual float getMinY () const { return _minY; }
101 virtual float getMaxX () const { return _maxX; }
102 virtual float getMaxY () const { return _maxY; }
107 ssgTexture * _texture;
108 float _minX, _minY, _maxX, _maxY;
113 ////////////////////////////////////////////////////////////////////////
114 // Instrument panel class.
116 // The panel is a container that has a background texture and holds
117 // zero or more instruments. The panel will order the instruments to
118 // redraw themselves when necessary, and will pass mouse clicks on to
119 // the appropriate instruments for processing.
120 ////////////////////////////////////////////////////////////////////////
126 FGPanel (int x, int y, int w, int h);
129 // transfer pointer ownership!!!
130 virtual void addInstrument (FGPanelInstrument * instrument);
132 // Update the panel (every frame).
133 virtual void update () const;
135 // Background texture.
136 virtual void setBackground (ssgTexture * texture);
138 // Make the panel visible or invisible.
139 virtual bool getVisibility () const;
140 virtual void setVisibility (bool visibility);
142 // Handle a mouse click.
143 virtual bool doMouseAction (int button, int updown, int x, int y);
146 mutable bool _visibility;
147 mutable bool _mouseDown;
148 mutable int _mouseButton, _mouseX, _mouseY;
149 mutable int _mouseDelay;
150 mutable FGPanelInstrument * _mouseInstrument;
151 typedef vector<FGPanelInstrument *> instrument_list_type;
155 // List of instruments in panel.
156 instrument_list_type _instruments;
161 ////////////////////////////////////////////////////////////////////////
162 // Base class for user action types.
164 // Individual instruments can have actions associated with a mouse
165 // click in a rectangular area. Current concrete classes include
166 // FGAdjustAction, FGSwapAction, and FGToggleAction.
167 ////////////////////////////////////////////////////////////////////////
173 FGPanelAction (int button, int x, int y, int w, int h);
174 virtual ~FGPanelAction ();
177 virtual int getButton () const { return _button; }
178 virtual int getX () const { return _x; }
179 virtual int getY () const { return _y; }
180 virtual int getWidth () const { return _w; }
181 virtual int getHeight () const { return _h; }
184 virtual void setButton (int button) { _button = button; }
185 virtual void setX (int x) { _x = x; }
186 virtual void setY (int y) { _y = y; }
187 virtual void setWidth (int w) { _w = w; }
188 virtual void setHeight (int h) { _h = h; }
190 // Check whether we're in the area.
191 virtual bool inArea (int button, int x, int y)
193 return (button == _button &&
200 // Perform the action.
201 virtual void doAction () = 0;
213 ////////////////////////////////////////////////////////////////////////
214 // Adjustment action.
216 // This is an action to increase or decrease an FGFS value by a certain
217 // increment within a certain range. If the wrap flag is true, the
218 // value will wrap around if it goes below min or above max; otherwise,
219 // it will simply stop at min or max.
220 ////////////////////////////////////////////////////////////////////////
222 class FGAdjustAction : public FGPanelAction
225 FGAdjustAction (int button, int x, int y, int w, int h,
226 SGValue * value, float increment,
227 float min, float max, bool wrap=false);
228 virtual ~FGAdjustAction ();
229 virtual void doAction ();
241 ////////////////////////////////////////////////////////////////////////
244 // This is an action to swap two values. It's currently used in the
245 // navigation radios.
246 ////////////////////////////////////////////////////////////////////////
248 class FGSwapAction : public FGPanelAction
251 FGSwapAction (int button, int x, int y, int w, int h,
252 SGValue * value1, SGValue * value2);
253 virtual ~FGSwapAction ();
254 virtual void doAction ();
263 ////////////////////////////////////////////////////////////////////////
266 // This is an action to toggle a boolean value.
267 ////////////////////////////////////////////////////////////////////////
269 class FGToggleAction : public FGPanelAction
272 FGToggleAction (int button, int x, int y, int w, int h,
274 virtual ~FGToggleAction ();
275 virtual void doAction ();
283 ////////////////////////////////////////////////////////////////////////
284 // Abstract base class for a panel instrument.
286 // A panel instrument consists of zero or more actions, associated
287 // with mouse clicks in rectangular areas. Currently, the only
288 // concrete class derived from this is FGLayeredInstrument, but others
289 // may show up in the future (some complex instruments could be
290 // entirely hand-coded, for example).
291 ////////////////////////////////////////////////////////////////////////
293 class FGPanelInstrument
296 FGPanelInstrument ();
297 FGPanelInstrument (int x, int y, int w, int h);
298 virtual ~FGPanelInstrument ();
300 virtual void draw () = 0;
302 virtual void setPosition(int x, int y);
303 virtual void setSize(int w, int h);
305 virtual int getXPos () const;
306 virtual int getYPos () const;
307 virtual int getWidth () const;
308 virtual int getHeight () const;
310 // Coordinates relative to centre.
311 // Transfer pointer ownership!!
312 virtual void addAction (FGPanelAction * action);
314 // Coordinates relative to centre.
315 virtual bool doMouseAction (int button, int x, int y);
319 typedef vector<FGPanelAction *> action_list_type;
320 action_list_type _actions;
325 ////////////////////////////////////////////////////////////////////////
326 // Abstract base class for an instrument layer.
328 // The FGLayeredInstrument class builds up instruments by using layers
329 // of textures or text. Each layer can have zero or more
330 // transformations applied to it: for example, a needle layer can
331 // rotate to show the altitude or airspeed.
332 ////////////////////////////////////////////////////////////////////////
336 * A transformation for a layer.
338 class FGPanelTransformation {
347 FGPanelTransformation ();
348 virtual ~FGPanelTransformation ();
351 const SGValue * value;
361 * A single layer of a multi-layered instrument.
363 * Each layer can be subject to a series of transformations based
364 * on current FGFS instrument readings: for example, a texture
365 * representing a needle can rotate to show the airspeed.
367 class FGInstrumentLayer
371 FGInstrumentLayer (int w = -1, int h = -1);
372 virtual ~FGInstrumentLayer ();
374 virtual void draw () = 0;
375 virtual void transform () const;
377 virtual int getWidth () const { return _w; }
378 virtual int getHeight () const { return _h; }
379 virtual void setWidth (int w) { _w = w; }
380 virtual void setHeight (int h) { _h = h; }
382 // Transfer pointer ownership!!
384 virtual void addTransformation (FGPanelTransformation * transformation);
389 typedef vector<FGPanelTransformation *> transformation_list;
390 transformation_list _transformations;
395 ////////////////////////////////////////////////////////////////////////
396 // An instrument composed of layers.
398 // This class represents an instrument which is simply a series of
399 // layers piled one on top of the other, each one undergoing its own
400 // set of transformations. For example, one layer can represent
401 // the instrument's face (which doesn't move), while the next layer
402 // can represent a needle that rotates depending on an FGFS variable.
403 ////////////////////////////////////////////////////////////////////////
407 * An instrument constructed of multiple layers.
409 * Each individual layer can be rotated or shifted to correspond
410 * to internal FGFS instrument readings.
412 class FGLayeredInstrument : public FGPanelInstrument
415 FGLayeredInstrument (int x, int y, int w, int h);
416 virtual ~FGLayeredInstrument ();
418 virtual void draw ();
420 // Transfer pointer ownership!!
421 virtual int addLayer (FGInstrumentLayer *layer);
422 virtual int addLayer (FGCroppedTexture &texture, int w = -1, int h = -1);
424 // Transfer pointer ownership!!
425 virtual void addTransformation (FGPanelTransformation * transformation);
428 typedef vector<FGInstrumentLayer *> layer_list;
434 ////////////////////////////////////////////////////////////////////////
435 // A textured layer of an instrument.
437 // This is a layer holding a single texture. Normally, the texture's
438 // backgound should be transparent so that lower layers and the panel
439 // background can show through.
440 ////////////////////////////////////////////////////////////////////////
442 class FGTexturedLayer : public FGInstrumentLayer
445 FGTexturedLayer (int w = -1, int h = -1) : FGInstrumentLayer(w, h) {}
446 FGTexturedLayer (const FGCroppedTexture &texture, int w = -1, int h = -1);
447 virtual ~FGTexturedLayer ();
449 virtual void draw ();
451 virtual void setTexture (const FGCroppedTexture &texture) {
454 virtual FGCroppedTexture &getTexture () { return _texture; }
455 virtual const FGCroppedTexture &getTexture () const { return _texture; }
458 mutable FGCroppedTexture _texture;
463 ////////////////////////////////////////////////////////////////////////
464 // A text layer of an instrument.
466 // This is a layer holding a string of static and/or generated text.
467 // It is useful for instruments that have text displays, such as
468 // a chronometer, GPS, or NavCom radio.
469 ////////////////////////////////////////////////////////////////////////
471 class FGTextLayer : public FGInstrumentLayer
474 typedef enum ChunkType {
482 Chunk (const string &text, const string &fmt = "%s");
483 Chunk (ChunkType type, const SGValue * value,
484 const string &fmt = "", float mult = 1.0);
486 const char * getValue () const;
490 const SGValue * _value;
493 mutable char _buf[1024];
496 FGTextLayer (int w = -1, int h = -1);
497 virtual ~FGTextLayer ();
499 virtual void draw ();
501 // Transfer pointer!!
502 virtual void addChunk (Chunk * chunk);
503 virtual void setColor (float r, float g, float b);
504 virtual void setPointSize (float size);
505 virtual void setFont (fntFont * font);
509 void recalc_value () const;
511 typedef vector<Chunk *> chunk_list;
517 mutable string _value;
518 mutable FGTimeStamp _then;
519 mutable FGTimeStamp _now;
524 ////////////////////////////////////////////////////////////////////////
525 // A layer that switches between two other layers.
526 ////////////////////////////////////////////////////////////////////////
528 class FGSwitchLayer : public FGInstrumentLayer
531 // Transfer pointers!!
532 FGSwitchLayer (int w, int h, const SGValue * value,
533 FGInstrumentLayer * layer1,
534 FGInstrumentLayer * layer2);
535 virtual ~FGSwitchLayer ();
537 virtual void draw ();
540 const SGValue * _value;
541 FGInstrumentLayer * _layer1, * _layer2;
546 ////////////////////////////////////////////////////////////////////////
547 // The current panel, if any.
548 ////////////////////////////////////////////////////////////////////////
550 extern FGPanel * current_panel;
554 #endif // __PANEL_HXX