]> git.mxchange.org Git - flightgear.git/blob - src/Cockpit/panel.hxx
38a7725eeda67c7e21555ecd569e05da25de4e6e
[flightgear.git] / src / Cockpit / panel.hxx
1 //  panel.hxx - generic support classes for a 2D panel.
2 //
3 //  Written by David Megginson, started January 2000.
4 //
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.
9 // 
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.
14 // 
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.
18 //
19 //  $Id$
20
21 #ifndef __PANEL_HXX
22 #define __PANEL_HXX
23
24 #ifndef __cplusplus                                                          
25 # error This library requires C++
26 #endif                                   
27
28
29 #ifdef HAVE_CONFIG_H
30 #  include <config.h>
31 #endif
32
33 #include <simgear/compiler.h>
34
35 #ifdef HAVE_WINDOWS_H          
36 #  include <windows.h>
37 #endif
38
39 #include <GL/glut.h>
40 #include <plib/ssg.h>
41
42 #include <simgear/misc/props.hxx>
43 #include <simgear/timing/timestamp.hxx>
44
45 #include <vector>
46 #include <map>
47 #include <plib/fnt.h>
48
49
50 FG_USING_STD(vector);
51 FG_USING_STD(map);
52
53 class FGPanelInstrument;
54
55
56 \f
57 ////////////////////////////////////////////////////////////////////////
58 // Texture manager (should migrate out into FGFS).
59 //
60 // This class ensures that no texture is loaded more than once.
61 ////////////////////////////////////////////////////////////////////////
62
63 class FGTextureManager
64 {
65 public:
66   static ssgTexture * createTexture(const string &relativePath);
67 private:
68   static map<string,ssgTexture *> _textureMap;
69 };
70
71
72 \f
73 ////////////////////////////////////////////////////////////////////////
74 // Cropped texture (should migrate out into FGFS).
75 //
76 // This structure wraps an SSG texture with cropping information.
77 ////////////////////////////////////////////////////////////////////////
78
79 class FGCroppedTexture
80 {
81 public:
82
83   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 ();
88
89   virtual void setPath (const string &path) { _path = path; }
90
91   virtual const string &getPath () const { return _path; }
92
93   virtual ssgTexture * getTexture ();
94
95   virtual void setCrop (float minX, float minY, float maxX, float maxY) {
96     _minX = minX; _minY = minY; _maxX = maxX; _maxY = maxY;
97   }
98
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; }
103
104
105 private:
106   string _path;
107   ssgTexture * _texture;
108   float _minX, _minY, _maxX, _maxY;
109 };
110
111
112 \f
113 ////////////////////////////////////////////////////////////////////////
114 // Instrument panel class.
115 //
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 ////////////////////////////////////////////////////////////////////////
121
122 class FGPanel
123 {
124 public:
125
126   FGPanel (int window_x, int window_y, int window_w, int window_h);
127   virtual ~FGPanel ();
128
129                                 // transfer pointer ownership!!!
130   virtual void addInstrument (FGPanelInstrument * instrument);
131
132                                 // Update the panel (every frame).
133   virtual void update () const;
134
135                                 // Background texture.
136   virtual void setBackground (ssgTexture * texture);
137
138                                 // Make the panel visible or invisible.
139   virtual bool getVisibility () const;
140   virtual void setVisibility (bool visibility);
141
142                                 // Full width of panel.
143   virtual void setWidth (int width) { _width = width; }
144   virtual int getWidth () const { return _width; }
145
146                                 // Full height of panel.
147   virtual void setHeight (int height) { _height = height; }
148   virtual int getHeight () const { return _height; }
149
150                                 // X-offset
151   virtual void setXOffset (int offset);
152   virtual int getXOffset () const { return _x_offset; }
153
154                                 // Y-offset.
155   virtual void setYOffset (int offset);
156   virtual int getYOffset () const { return _y_offset; }
157
158                                 // View height.
159   virtual void setViewHeight (int height) { _view_height = height; }
160   virtual int getViewHeight () const { return _view_height; }
161
162                                 // Handle a mouse click.
163   virtual bool doMouseAction (int button, int updown, int x, int y);
164
165 private:
166   mutable bool _visibility;
167   mutable bool _mouseDown;
168   mutable int _mouseButton, _mouseX, _mouseY;
169   mutable int _mouseDelay;
170   mutable FGPanelInstrument * _mouseInstrument;
171   typedef vector<FGPanelInstrument *> instrument_list_type;
172   int _winx, _winy, _winw, _winh;
173   int _width;
174   int _height;
175   int _x_offset;
176   int _y_offset;
177   int _view_height;
178   
179   ssgTexture * _bg;
180                                 // List of instruments in panel.
181   instrument_list_type _instruments;
182 };
183
184
185 \f
186 ////////////////////////////////////////////////////////////////////////
187 // Base class for user action types.
188 //
189 // Individual instruments can have actions associated with a mouse
190 // click in a rectangular area.  Current concrete classes include
191 // FGAdjustAction, FGSwapAction, and FGToggleAction.
192 ////////////////////////////////////////////////////////////////////////
193
194 class FGPanelAction
195 {
196 public:
197   FGPanelAction ();
198   FGPanelAction (int button, int x, int y, int w, int h);
199   virtual ~FGPanelAction ();
200
201                                 // Getters.
202   virtual int getButton () const { return _button; }
203   virtual int getX () const { return _x; }
204   virtual int getY () const { return _y; }
205   virtual int getWidth () const { return _w; }
206   virtual int getHeight () const { return _h; }
207
208                                 // Setters.
209   virtual void setButton (int button) { _button = button; }
210   virtual void setX (int x) { _x = x; }
211   virtual void setY (int y) { _y = y; }
212   virtual void setWidth (int w) { _w = w; }
213   virtual void setHeight (int h) { _h = h; }
214
215                                 // Check whether we're in the area.
216   virtual bool inArea (int button, int x, int y)
217   {
218     return (button == _button &&
219             x >= _x &&
220             x < _x + _w &&
221             y >= _y &&
222             y < _y + _h);
223   }
224
225                                 // Perform the action.
226   virtual void doAction () = 0;
227
228 private:
229   int _button;
230   int _x;
231   int _y;
232   int _w;
233   int _h;
234 };
235
236
237 \f
238 ////////////////////////////////////////////////////////////////////////
239 // Adjustment action.
240 //
241 // This is an action to increase or decrease an FGFS value by a certain
242 // increment within a certain range.  If the wrap flag is true, the
243 // value will wrap around if it goes below min or above max; otherwise,
244 // it will simply stop at min or max.
245 ////////////////////////////////////////////////////////////////////////
246
247 class FGAdjustAction : public FGPanelAction
248 {
249 public:
250   FGAdjustAction (int button, int x, int y, int w, int h,
251                   SGValue * value, float increment,
252                   float min, float max, bool wrap=false);
253   virtual ~FGAdjustAction ();
254   virtual void doAction ();
255
256 private:
257   SGValue * _value;
258   float _increment;
259   float _min;
260   float _max;
261   bool _wrap;
262 };
263
264
265 \f
266 ////////////////////////////////////////////////////////////////////////
267 // Swap action.
268 //
269 // This is an action to swap two values.  It's currently used in the
270 // navigation radios.
271 ////////////////////////////////////////////////////////////////////////
272
273 class FGSwapAction : public FGPanelAction
274 {
275 public:
276   FGSwapAction (int button, int x, int y, int w, int h,
277                 SGValue * value1, SGValue * value2);
278   virtual ~FGSwapAction ();
279   virtual void doAction ();
280
281 private:
282   SGValue * _value1;
283   SGValue * _value2;
284 };
285
286
287 \f
288 ////////////////////////////////////////////////////////////////////////
289 // Toggle action.
290 //
291 // This is an action to toggle a boolean value.
292 ////////////////////////////////////////////////////////////////////////
293
294 class FGToggleAction : public FGPanelAction
295 {
296 public:
297   FGToggleAction (int button, int x, int y, int w, int h,
298                   SGValue * value);
299   virtual ~FGToggleAction ();
300   virtual void doAction ();
301
302 private:
303   SGValue * _value;
304 };
305
306
307 \f
308 ////////////////////////////////////////////////////////////////////////
309 // Abstract base class for a panel instrument.
310 //
311 // A panel instrument consists of zero or more actions, associated
312 // with mouse clicks in rectangular areas.  Currently, the only
313 // concrete class derived from this is FGLayeredInstrument, but others
314 // may show up in the future (some complex instruments could be 
315 // entirely hand-coded, for example).
316 ////////////////////////////////////////////////////////////////////////
317
318 class FGPanelInstrument
319 {
320 public:
321   FGPanelInstrument ();
322   FGPanelInstrument (int x, int y, int w, int h);
323   virtual ~FGPanelInstrument ();
324
325   virtual void draw () = 0;
326
327   virtual void setPosition(int x, int y);
328   virtual void setSize(int w, int h);
329
330   virtual int getXPos () const;
331   virtual int getYPos () const;
332   virtual int getWidth () const;
333   virtual int getHeight () const;
334
335                                 // Coordinates relative to centre.
336                                 // Transfer pointer ownership!!
337   virtual void addAction (FGPanelAction * action);
338
339                                 // Coordinates relative to centre.
340   virtual bool doMouseAction (int button, int x, int y);
341
342 protected:
343   int _x, _y, _w, _h;
344   typedef vector<FGPanelAction *> action_list_type;
345   action_list_type _actions;
346 };
347
348
349 \f
350 ////////////////////////////////////////////////////////////////////////
351 // Abstract base class for an instrument layer.
352 //
353 // The FGLayeredInstrument class builds up instruments by using layers
354 // of textures or text.  Each layer can have zero or more
355 // transformations applied to it: for example, a needle layer can
356 // rotate to show the altitude or airspeed.
357 ////////////////////////////////////////////////////////////////////////
358
359
360 /**
361  * A transformation for a layer.
362  */
363 class FGPanelTransformation {
364 public:
365
366   enum Type {
367     XSHIFT,
368     YSHIFT,
369     ROTATION
370   };
371
372   FGPanelTransformation ();
373   virtual ~FGPanelTransformation ();
374
375   Type type;
376   const SGValue * value;
377   float min;
378   float max;
379   float factor;
380   float offset;
381 };
382
383
384
385 /**
386  * A single layer of a multi-layered instrument.
387  *
388  * Each layer can be subject to a series of transformations based
389  * on current FGFS instrument readings: for example, a texture
390  * representing a needle can rotate to show the airspeed.
391  */
392 class FGInstrumentLayer
393 {
394 public:
395
396   FGInstrumentLayer (int w = -1, int h = -1);
397   virtual ~FGInstrumentLayer ();
398
399   virtual void draw () = 0;
400   virtual void transform () const;
401
402   virtual int getWidth () const { return _w; }
403   virtual int getHeight () const { return _h; }
404   virtual void setWidth (int w) { _w = w; }
405   virtual void setHeight (int h) { _h = h; }
406
407                                 // Transfer pointer ownership!!
408                                 // DEPRECATED
409   virtual void addTransformation (FGPanelTransformation * transformation);
410
411 protected:
412   int _w, _h;
413
414   typedef vector<FGPanelTransformation *> transformation_list;
415   transformation_list _transformations;
416 };
417
418
419 \f
420 ////////////////////////////////////////////////////////////////////////
421 // An instrument composed of layers.
422 //
423 // This class represents an instrument which is simply a series of
424 // layers piled one on top of the other, each one undergoing its own
425 // set of transformations.  For example, one layer can represent
426 // the instrument's face (which doesn't move), while the next layer
427 // can represent a needle that rotates depending on an FGFS variable.
428 ////////////////////////////////////////////////////////////////////////
429
430
431 /**
432  * An instrument constructed of multiple layers.
433  *
434  * Each individual layer can be rotated or shifted to correspond
435  * to internal FGFS instrument readings.
436  */
437 class FGLayeredInstrument : public FGPanelInstrument
438 {
439 public:
440   FGLayeredInstrument (int x, int y, int w, int h);
441   virtual ~FGLayeredInstrument ();
442
443   virtual void draw ();
444
445                                 // Transfer pointer ownership!!
446   virtual int addLayer (FGInstrumentLayer *layer);
447   virtual int addLayer (FGCroppedTexture &texture, int w = -1, int h = -1);
448
449                                 // Transfer pointer ownership!!
450   virtual void addTransformation (FGPanelTransformation * transformation);
451
452 protected:
453   typedef vector<FGInstrumentLayer *> layer_list;
454   layer_list _layers;
455 };
456
457
458 \f
459 ////////////////////////////////////////////////////////////////////////
460 // A textured layer of an instrument.
461 //
462 // This is a layer holding a single texture.  Normally, the texture's
463 // backgound should be transparent so that lower layers and the panel
464 // background can show through.
465 ////////////////////////////////////////////////////////////////////////
466
467 class FGTexturedLayer : public FGInstrumentLayer
468 {
469 public:
470   FGTexturedLayer (int w = -1, int h = -1) : FGInstrumentLayer(w, h) {}
471   FGTexturedLayer (const FGCroppedTexture &texture, int w = -1, int h = -1);
472   virtual ~FGTexturedLayer ();
473
474   virtual void draw ();
475
476   virtual void setTexture (const FGCroppedTexture &texture) {
477     _texture = texture;
478   }
479   virtual FGCroppedTexture &getTexture () { return _texture; }
480   virtual const FGCroppedTexture &getTexture () const { return _texture; }
481
482 private:
483   mutable FGCroppedTexture _texture;
484 };
485
486
487 \f
488 ////////////////////////////////////////////////////////////////////////
489 // A text layer of an instrument.
490 //
491 // This is a layer holding a string of static and/or generated text.
492 // It is useful for instruments that have text displays, such as
493 // a chronometer, GPS, or NavCom radio.
494 ////////////////////////////////////////////////////////////////////////
495
496 class FGTextLayer : public FGInstrumentLayer
497 {
498 public:
499   typedef enum ChunkType {
500     TEXT,
501     TEXT_VALUE,
502     DOUBLE_VALUE
503   };
504
505   class Chunk {
506   public:
507     Chunk (const string &text, const string &fmt = "%s");
508     Chunk (ChunkType type, const SGValue * value,
509            const string &fmt = "", float mult = 1.0);
510
511     const char * getValue () const;
512   private:
513     ChunkType _type;
514     string _text;
515     const SGValue * _value;
516     string _fmt;
517     float _mult;
518     mutable char _buf[1024];
519   };
520
521   FGTextLayer (int w = -1, int h = -1);
522   virtual ~FGTextLayer ();
523
524   virtual void draw ();
525
526                                 // Transfer pointer!!
527   virtual void addChunk (Chunk * chunk);
528   virtual void setColor (float r, float g, float b);
529   virtual void setPointSize (float size);
530   virtual void setFont (fntFont * font);
531
532 private:
533
534   void recalc_value () const;
535
536   typedef vector<Chunk *> chunk_list;
537   chunk_list _chunks;
538   float _color[4];
539
540   float _pointSize;
541
542   mutable string _value;
543   mutable SGTimeStamp _then;
544   mutable SGTimeStamp _now;
545 };
546
547
548 \f
549 ////////////////////////////////////////////////////////////////////////
550 // A layer that switches between two other layers.
551 ////////////////////////////////////////////////////////////////////////
552
553 class FGSwitchLayer : public FGInstrumentLayer
554 {
555 public:
556                                 // Transfer pointers!!
557   FGSwitchLayer (int w, int h, const SGValue * value,
558                  FGInstrumentLayer * layer1,
559                  FGInstrumentLayer * layer2);
560   virtual ~FGSwitchLayer ();
561
562   virtual void draw ();
563
564 private:
565   const SGValue * _value;
566   FGInstrumentLayer * _layer1, * _layer2;
567 };
568
569
570 \f
571 ////////////////////////////////////////////////////////////////////////
572 // Functions.
573 ////////////////////////////////////////////////////////////////////////
574
575 bool fgPanelVisible ();
576
577
578 \f
579 ////////////////////////////////////////////////////////////////////////
580 // The current panel, if any.
581 ////////////////////////////////////////////////////////////////////////
582
583 extern FGPanel * current_panel;
584
585
586 \f
587 #endif // __PANEL_HXX
588
589 // end of panel.hxx
590
591