]> git.mxchange.org Git - flightgear.git/blob - src/Cockpit/panel.hxx
Make a subtle change to tile loading/unloading policy in order to make the tile
[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 #ifdef HAVE_WINDOWS_H
34 #  include <windows.h>
35 #endif
36
37 #include <plib/ssg.h>
38 #include <plib/fnt.h>
39
40 #include <simgear/compiler.h>
41 #include <simgear/props/props.hxx>
42 #include <simgear/structure/subsystem_mgr.hxx>
43 #include <simgear/math/interpolater.hxx>
44 #include <simgear/timing/timestamp.hxx>
45
46 #include <cmath>
47 #include <vector>
48 #include <map>
49
50 #include <Main/fg_props.hxx>
51 #include <Input/input.hxx>
52
53 SG_USING_STD(vector);
54 SG_USING_STD(map);
55
56 class FGPanelInstrument;
57
58
59 \f
60 ////////////////////////////////////////////////////////////////////////
61 // Texture management.
62 ////////////////////////////////////////////////////////////////////////
63
64
65 /**
66  * Texture manager (should migrate out into FGFS).
67  *
68  * This class ensures that no texture is loaded more than once.
69  */
70 class FGTextureManager
71 {
72 public:
73   static ssgTexture * createTexture(const string &relativePath);
74 private:
75   static map<string,ssgTexture *> _textureMap;
76 };
77
78
79 /**
80  * Cropped texture (should migrate out into FGFS).
81  *
82  * This structure wraps an SSG texture with cropping information.
83  */
84 class FGCroppedTexture
85 {
86 public:
87
88   FGCroppedTexture ();
89   FGCroppedTexture (const string &path,
90                   float _minX = 0.0, float _minY = 0.0,
91                   float _maxX = 1.0, float _maxY = 1.0);
92   virtual ~FGCroppedTexture ();
93
94   virtual void setPath (const string &path) { _path = path; }
95
96   virtual const string &getPath () const { return _path; }
97
98   virtual ssgTexture * getTexture ();
99
100   virtual void setCrop (float minX, float minY, float maxX, float maxY) {
101     _minX = minX; _minY = minY; _maxX = maxX; _maxY = maxY;
102   }
103
104   virtual float getMinX () const { return _minX; }
105   virtual float getMinY () const { return _minY; }
106   virtual float getMaxX () const { return _maxX; }
107   virtual float getMaxY () const { return _maxY; }
108
109
110 private:
111   string _path;
112   ssgTexture * _texture;
113   float _minX, _minY, _maxX, _maxY;
114 };
115
116
117 \f
118 ////////////////////////////////////////////////////////////////////////
119 // Top-level panel.
120 ////////////////////////////////////////////////////////////////////////
121
122
123 /**
124  * Instrument panel class.
125  *
126  * The panel is a container that has a background texture and holds
127  * zero or more instruments.  The panel will order the instruments to
128  * redraw themselves when necessary, and will pass mouse clicks on to
129  * the appropriate instruments for processing.
130  */
131 class FGPanel : public SGSubsystem
132 {
133 public:
134
135   FGPanel ();
136   virtual ~FGPanel ();
137
138                                 // Update the panel (every frame).
139   virtual void init ();
140   virtual void bind ();
141   virtual void unbind ();
142   virtual void draw ();
143   virtual void update (double dt);
144   virtual void update (GLfloat winx, GLfloat winw, GLfloat winy, GLfloat winh);
145
146   virtual void updateMouseDelay();
147
148                                 // transfer pointer ownership!!!
149   virtual void addInstrument (FGPanelInstrument * instrument);
150
151                                 // Background texture.
152   virtual void setBackground (ssgTexture * texture);
153
154                                 // Background multiple textures.
155   virtual void setMultiBackground (ssgTexture * texture, int idx);
156
157                                 // Make the panel visible or invisible.
158   virtual bool getVisibility () const;
159   virtual void setVisibility (bool visibility);
160
161                                 // Full width of panel.
162   virtual void setWidth (int width) { _width = width; }
163   virtual int getWidth () const { return _width; }
164
165                                 // Full height of panel.
166   virtual void setHeight (int height) { _height = height; }
167   virtual int getHeight () const { return _height; }
168
169                                 // X-offset
170   virtual void setXOffset (int offset);
171   virtual int getXOffset () const { return _x_offset->getIntValue(); }
172
173                                 // Y-offset.
174   virtual void setYOffset (int offset);
175   virtual int getYOffset () const { return _y_offset->getIntValue(); }
176
177                                 // View height.
178   virtual void setViewHeight (int height) { _view_height = height; }
179   virtual int getViewHeight () const { return _view_height; }
180
181                                 // Handle a mouse click.
182   virtual bool doMouseAction (int button, int updown, int x, int y);
183   virtual bool doLocalMouseAction(int button, int updown, int x, int y);
184
185 private:
186   void setupVirtualCockpit();
187   void cleanupVirtualCockpit();
188
189   mutable bool _mouseDown;
190   mutable int _mouseButton, _mouseX, _mouseY;
191   mutable int _mouseDelay;
192   mutable FGPanelInstrument * _mouseInstrument;
193   typedef vector<FGPanelInstrument *> instrument_list_type;
194   int _width;
195   int _height;
196   int _view_height;
197
198   SGPropertyNode * _visibility;
199   SGPropertyNode * _x_offset;
200   SGPropertyNode * _y_offset;
201   SGPropertyNode * _jitter;
202   SGPropertyNode * _flipx;
203
204   const SGPropertyNode * _xsize_node;
205   const SGPropertyNode * _ysize_node;
206   
207   ssgTexture * _bg;
208   ssgTexture * _mbg[8];
209                                 // List of instruments in panel.
210   instrument_list_type _instruments;
211 };
212
213
214 \f
215 ////////////////////////////////////////////////////////////////////////
216 // Actions
217 ////////////////////////////////////////////////////////////////////////
218
219
220 /**
221  * Class for user actions.
222  *
223  * The actions are command bindings, like bindings for the keyboard
224  * or joystick, but they are tied to specific mouse actions in
225  * rectangular areas of the panel.
226  */
227 class FGPanelAction : public SGConditional
228 {
229 public:
230   FGPanelAction ();
231   FGPanelAction (int button, int x, int y, int w, int h, bool repeatable);
232   virtual ~FGPanelAction ();
233
234                                 // Getters.
235   virtual int getButton () const { return _button; }
236   virtual int getX () const { return _x; }
237   virtual int getY () const { return _y; }
238   virtual int getWidth () const { return _w; }
239   virtual int getHeight () const { return _h; }
240
241                                 // Setters.
242
243                                 // transfer pointer ownership
244   virtual void addBinding (FGBinding * binding, int updown);
245   virtual void setButton (int button) { _button = button; }
246   virtual void setX (int x) { _x = x; }
247   virtual void setY (int y) { _y = y; }
248   virtual void setWidth (int w) { _w = w; }
249   virtual void setHeight (int h) { _h = h; }
250
251                                 // Check whether we're in the area.
252   virtual bool inArea (int button, int x, int y)
253   {
254     return (button == _button &&
255             x >= _x &&
256             x < _x + _w &&
257             y >= _y &&
258             y < _y + _h);
259   }
260
261                                 // Perform the action.
262   virtual bool doAction (int updown);
263
264 private:
265   typedef vector<FGBinding *> binding_list_t;
266
267   int _button;
268   int _x;
269   int _y;
270   int _w;
271   int _h;
272   bool _repeatable;
273   int _last_state;
274   binding_list_t _bindings[2];
275 };
276
277
278 \f
279 ////////////////////////////////////////////////////////////////////////
280 // Transformations.
281 ////////////////////////////////////////////////////////////////////////
282
283
284 /**
285  * A transformation for a layer.
286  */
287 class FGPanelTransformation : public SGConditional
288 {
289 public:
290
291   enum Type {
292     XSHIFT,
293     YSHIFT,
294     ROTATION
295   };
296
297   FGPanelTransformation ();
298   virtual ~FGPanelTransformation ();
299
300   Type type;
301   const SGPropertyNode * node;
302   float min;
303   float max;
304   bool has_mod;
305   float mod;
306   float factor;
307   float offset;
308   SGInterpTable * table;
309 };
310
311
312
313 \f
314 ////////////////////////////////////////////////////////////////////////
315 // Layers
316 ////////////////////////////////////////////////////////////////////////
317
318
319 /**
320  * A single layer of a multi-layered instrument.
321  *
322  * Each layer can be subject to a series of transformations based
323  * on current FGFS instrument readings: for example, a texture
324  * representing a needle can rotate to show the airspeed.
325  */
326 class FGInstrumentLayer : public SGConditional
327 {
328 public:
329
330   FGInstrumentLayer (int w = -1, int h = -1);
331   virtual ~FGInstrumentLayer ();
332
333   virtual void draw () = 0;
334   virtual void transform () const;
335
336   virtual int getWidth () const { return _w; }
337   virtual int getHeight () const { return _h; }
338   virtual void setWidth (int w) { _w = w; }
339   virtual void setHeight (int h) { _h = h; }
340
341                                 // Transfer pointer ownership!!
342                                 // DEPRECATED
343   virtual void addTransformation (FGPanelTransformation * transformation);
344
345 protected:
346   int _w, _h;
347
348   typedef vector<FGPanelTransformation *> transformation_list;
349   transformation_list _transformations;
350 };
351
352
353 \f
354 ////////////////////////////////////////////////////////////////////////
355 // Instruments.
356 ////////////////////////////////////////////////////////////////////////
357
358
359 /**
360  * Abstract base class for a panel instrument.
361  *
362  * A panel instrument consists of zero or more actions, associated
363  * with mouse clicks in rectangular areas.  Currently, the only
364  * concrete class derived from this is FGLayeredInstrument, but others
365  * may show up in the future (some complex instruments could be 
366  * entirely hand-coded, for example).
367  */
368 class FGPanelInstrument : public SGConditional
369 {
370 public:
371   FGPanelInstrument ();
372   FGPanelInstrument (int x, int y, int w, int h);
373   virtual ~FGPanelInstrument ();
374
375   virtual void draw () = 0;
376   virtual void drawHotspots();
377
378   virtual void setPosition(int x, int y);
379   virtual void setSize(int w, int h);
380
381   virtual int getXPos () const;
382   virtual int getYPos () const;
383   virtual int getWidth () const;
384   virtual int getHeight () const;
385
386                                 // Coordinates relative to centre.
387                                 // Transfer pointer ownership!!
388   virtual void addAction (FGPanelAction * action);
389
390                                 // Coordinates relative to centre.
391   virtual bool doMouseAction (int button, int updown, int x, int y);
392
393 protected:
394   int _x, _y, _w, _h;
395   typedef vector<FGPanelAction *> action_list_type;
396   action_list_type _actions;
397 };
398
399
400 /**
401  * An instrument constructed of multiple layers.
402  *
403  * Each individual layer can be rotated or shifted to correspond
404  * to internal FGFS instrument readings.
405  */
406 class FGLayeredInstrument : public FGPanelInstrument
407 {
408 public:
409   FGLayeredInstrument (int x, int y, int w, int h);
410   virtual ~FGLayeredInstrument ();
411
412   virtual void draw ();
413
414                                 // Transfer pointer ownership!!
415   virtual int addLayer (FGInstrumentLayer *layer);
416   virtual int addLayer (FGCroppedTexture &texture, int w = -1, int h = -1);
417
418                                 // Transfer pointer ownership!!
419   virtual void addTransformation (FGPanelTransformation * transformation);
420
421 protected:
422   typedef vector<FGInstrumentLayer *> layer_list;
423   layer_list _layers;
424 };
425
426
427 /**
428  * An instrument layer containing a group of sublayers.
429  *
430  * This class is useful for gathering together a group of related
431  * layers, either to hold in an external file or to work under
432  * the same condition.
433  */
434 class FGGroupLayer : public FGInstrumentLayer
435 {
436 public:
437   FGGroupLayer ();
438   virtual ~FGGroupLayer ();
439   virtual void draw ();
440                                 // transfer pointer ownership
441   virtual void addLayer (FGInstrumentLayer * layer);
442 protected:
443   vector<FGInstrumentLayer *> _layers;
444 };
445
446
447 /**
448  * A textured layer of an instrument.
449  *
450  * This is a layer holding a single texture.  Normally, the texture's
451  * backgound should be transparent so that lower layers and the panel
452  * background can show through.
453  */
454 class FGTexturedLayer : public FGInstrumentLayer
455 {
456 public:
457   FGTexturedLayer (int w = -1, int h = -1) : FGInstrumentLayer(w, h) {}
458   FGTexturedLayer (const FGCroppedTexture &texture, int w = -1, int h = -1);
459   virtual ~FGTexturedLayer ();
460
461   virtual void draw ();
462
463   virtual void setTexture (const FGCroppedTexture &texture) {
464     _texture = texture;
465   }
466   virtual FGCroppedTexture &getTexture () { return _texture; }
467   virtual const FGCroppedTexture &getTexture () const { return _texture; }
468
469 private:
470   mutable FGCroppedTexture _texture;
471 };
472
473
474 /**
475  * A text layer of an instrument.
476  *
477  * This is a layer holding a string of static and/or generated text.
478  * It is useful for instruments that have text displays, such as
479  * a chronometer, GPS, or NavCom radio.
480  */
481 class FGTextLayer : public FGInstrumentLayer
482 {
483 public:
484   enum ChunkType {
485     TEXT,
486     TEXT_VALUE,
487     DOUBLE_VALUE
488   };
489
490   class Chunk : public SGConditional
491   {
492   public:
493     Chunk (const string &text, const string &fmt = "%s");
494     Chunk (ChunkType type, const SGPropertyNode * node,
495            const string &fmt = "", float mult = 1.0, float offs = 0.0,
496            bool truncation = false);
497
498     const char * getValue () const;
499   private:
500     ChunkType _type;
501     string _text;
502     const SGPropertyNode * _node;
503     string _fmt;
504     float _mult;
505     float _offs;
506     bool _trunc;
507     mutable char _buf[1024];
508   };
509
510   FGTextLayer (int w = -1, int h = -1);
511   virtual ~FGTextLayer ();
512
513   virtual void draw ();
514
515                                 // Transfer pointer!!
516   virtual void addChunk (Chunk * chunk);
517   virtual void setColor (float r, float g, float b);
518   virtual void setPointSize (float size);
519   virtual void setFontName ( const string &name );
520   virtual void setFont (fntFont * font);
521
522 private:
523
524   void recalc_value () const;
525
526   typedef vector<Chunk *> chunk_list;
527   chunk_list _chunks;
528   float _color[4];
529
530   float _pointSize;
531   mutable string _font_name;
532   mutable string _value;
533   mutable SGTimeStamp _then;
534   mutable SGTimeStamp _now;
535 };
536
537
538 /**
539  * A group layer that switches among its children.
540  *
541  * The first layer that passes its condition will be drawn, and
542  * any following layers will be ignored.
543  */
544 class FGSwitchLayer : public FGGroupLayer
545 {
546 public:
547                                 // Transfer pointers!!
548   FGSwitchLayer ();
549   virtual void draw ();
550
551 };
552
553
554
555 \f
556 ////////////////////////////////////////////////////////////////////////
557 // Functions.
558 ////////////////////////////////////////////////////////////////////////
559
560 /**
561  * Test whether the panel should be visible.
562  */
563 bool fgPanelVisible ();
564
565
566 \f
567 #endif // __PANEL_HXX
568
569 // end of panel.hxx
570
571
572