]> git.mxchange.org Git - flightgear.git/blob - utils/fgpanel/panel.hxx
Merge branch 'next' into durk-atc
[flightgear.git] / utils / fgpanel / panel.hxx
1 //  panel.hxx - generic support classes for a 2D panel.
2 //
3 //  Written by David Megginson, started January 2000.
4 //  Adopted for standalone fgpanel application by Torsten Dreyer, August 2009
5 //
6 //  This program is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU General Public License as
8 //  published by the Free Software Foundation; either version 2 of the
9 //  License, or (at your option) any later version.
10 // 
11 //  This program is distributed in the hope that it will be useful, but
12 //  WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 //  General Public License for more details.
15 //
16 //  You should have received a copy of the GNU General Public License
17 //  along with this program; if not, write to the Free Software
18 //  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19 //
20 //  $Id$
21
22 #ifndef __PANEL_HXX
23 #define __PANEL_HXX
24
25 #ifndef __cplusplus
26 # error This library requires C++
27 #endif
28
29
30 #ifdef HAVE_CONFIG_H
31 #  include <config.h>
32 #endif
33
34 #include <plib/fnt.h>
35
36 #include <simgear/props/condition.hxx>
37 #include <simgear/structure/subsystem_mgr.hxx>
38 #include <simgear/math/interpolater.hxx>
39 #include <simgear/sg_inlines.h>
40 #include "FGTextureLoaderInterface.hxx"
41
42 class FGPanelInstrument;
43
44 \f
45 ////////////////////////////////////////////////////////////////////////
46 // Texture management.
47 ////////////////////////////////////////////////////////////////////////
48
49 class FGCroppedTexture;
50 typedef SGSharedPtr<FGCroppedTexture> FGCroppedTexture_ptr;
51 /**
52  * Cropped texture (should migrate out into FGFS).
53  *
54  * This structure wraps an SSG texture with cropping information.
55  */
56 class FGCroppedTexture : public SGReferenced
57 {
58 public:
59   FGCroppedTexture (const string &path,
60                   float _minX = 0.0, float _minY = 0.0,
61                   float _maxX = 1.0, float _maxY = 1.0);
62
63   virtual ~FGCroppedTexture ();
64
65   virtual void setPath (const string &path) { _path = path; }
66
67   virtual const string &getPath () const { return _path; }
68
69   virtual void setCrop (float minX, float minY, float maxX, float maxY) {
70     _minX = minX; _minY = minY; _maxX = maxX; _maxY = maxY;
71   }
72
73   static void registerTextureLoader( const string & extension, FGTextureLoaderInterface * loader ) {
74     if( textureLoader.count( extension ) == 0 )
75       textureLoader[extension] = loader;
76   }
77
78   virtual float getMinX () const { return _minX; }
79   virtual float getMinY () const { return _minY; }
80   virtual float getMaxX () const { return _maxX; }
81   virtual float getMaxY () const { return _maxY; }
82   GLuint getTexture() const { return _texture; }
83
84   virtual void bind( bool doGLBind = true );
85
86 private:
87   string _path;
88   float _minX, _minY, _maxX, _maxY;
89
90   GLuint _texture;
91   static GLuint current_bound_texture;
92   static map<string,GLuint> cache;
93   static map<string,FGTextureLoaderInterface*> textureLoader;
94 };
95
96
97 \f
98 ////////////////////////////////////////////////////////////////////////
99 // Top-level panel.
100 ////////////////////////////////////////////////////////////////////////
101
102
103 /**
104  * Instrument panel class.
105  *
106  * The panel is a container that has a background texture and holds
107  * zero or more instruments.  The panel will order the instruments to
108  * redraw themselves when necessary, and will pass mouse clicks on to
109  * the appropriate instruments for processing.
110  */
111 class FGPanel : public SGSubsystem
112 {
113 public:
114
115   FGPanel ( SGPropertyNode_ptr root );
116   virtual ~FGPanel ();
117
118                                 // Update the panel (every frame).
119   virtual void init ();
120   virtual void bind ();
121   virtual void unbind ();
122 //  virtual void draw ();
123   virtual void update (double dt);
124
125                                 // transfer pointer ownership!!!
126   virtual void addInstrument (FGPanelInstrument * instrument);
127
128                                 // Background texture.
129   virtual void setBackground (FGCroppedTexture_ptr texture);
130   inline void setBackgroundWidth( double d ) {
131     _bg_width = d;
132   }
133
134   inline void setBackgroundHeight( double d ) {
135     _bg_height = d;
136   }
137
138                                 // Background multiple textures.
139   virtual void setMultiBackground (FGCroppedTexture_ptr texture , int idx);
140
141                                 // Full width of panel.
142   virtual void setWidth (int width) { _width = width; }
143   virtual int getWidth () const { return _width; }
144
145                                 // Full height of panel.
146   virtual void setHeight (int height) { _height = height; }
147   virtual int getHeight () const { return _height; }
148
149 private:
150
151   typedef vector<FGPanelInstrument *> instrument_list_type;
152   int _width;
153   int _height;
154
155   SGPropertyNode_ptr _root;
156   SGPropertyNode_ptr _flipx;
157   SGPropertyNode_ptr _rotate;
158
159   FGCroppedTexture_ptr _bg;
160   double _bg_width;
161   double _bg_height;
162   FGCroppedTexture_ptr _mbg[8];
163                                 // List of instruments in panel.
164   instrument_list_type _instruments;
165
166   GLuint initDisplayList;
167
168   GLuint getInitDisplayList();
169 };
170
171
172 \f
173 ////////////////////////////////////////////////////////////////////////
174 // Transformations.
175 ////////////////////////////////////////////////////////////////////////
176
177
178 /**
179  * A transformation for a layer.
180  */
181 class FGPanelTransformation : public SGConditional
182 {
183 public:
184
185   enum Type {
186     XSHIFT,
187     YSHIFT,
188     ROTATION
189   };
190
191   FGPanelTransformation ();
192   virtual ~FGPanelTransformation ();
193
194   Type type;
195   SGConstPropertyNode_ptr node;
196   float min;
197   float max;
198   bool has_mod;
199   float mod;
200   float factor;
201   float offset;
202   SGInterpTable * table;
203 };
204
205
206
207 \f
208 ////////////////////////////////////////////////////////////////////////
209 // Layers
210 ////////////////////////////////////////////////////////////////////////
211
212
213 /**
214  * A single layer of a multi-layered instrument.
215  *
216  * Each layer can be subject to a series of transformations based
217  * on current FGFS instrument readings: for example, a texture
218  * representing a needle can rotate to show the airspeed.
219  */
220 class FGInstrumentLayer : public SGConditional
221 {
222 public:
223
224   FGInstrumentLayer (int w = -1, int h = -1);
225   virtual ~FGInstrumentLayer ();
226
227   virtual void draw () = 0;
228   virtual void transform () const;
229
230   virtual int getWidth () const { return _w; }
231   virtual int getHeight () const { return _h; }
232   virtual void setWidth (int w) { _w = w; }
233   virtual void setHeight (int h) { _h = h; }
234
235                                 // Transfer pointer ownership!!
236                                 // DEPRECATED
237   virtual void addTransformation (FGPanelTransformation * transformation);
238
239 protected:
240   int _w, _h;
241
242   typedef vector<FGPanelTransformation *> transformation_list;
243   transformation_list _transformations;
244 };
245
246
247 \f
248 ////////////////////////////////////////////////////////////////////////
249 // Instruments.
250 ////////////////////////////////////////////////////////////////////////
251
252
253 /**
254  * Abstract base class for a panel instrument.
255  *
256  * A panel instrument consists of zero or more actions, associated
257  * with mouse clicks in rectangular areas.  Currently, the only
258  * concrete class derived from this is FGLayeredInstrument, but others
259  * may show up in the future (some complex instruments could be 
260  * entirely hand-coded, for example).
261  */
262 class FGPanelInstrument : public SGConditional
263 {
264 public:
265   FGPanelInstrument ();
266   FGPanelInstrument (int x, int y, int w, int h);
267   virtual ~FGPanelInstrument ();
268
269   virtual void draw () = 0;
270
271   virtual void setPosition(int x, int y);
272   virtual void setSize(int w, int h);
273
274   virtual int getXPos () const;
275   virtual int getYPos () const;
276   virtual int getWidth () const;
277   virtual int getHeight () const;
278
279 protected:
280   int _x, _y, _w, _h;
281 };
282
283
284 /**
285  * An instrument constructed of multiple layers.
286  *
287  * Each individual layer can be rotated or shifted to correspond
288  * to internal FGFS instrument readings.
289  */
290 class FGLayeredInstrument : public FGPanelInstrument
291 {
292 public:
293   FGLayeredInstrument (int x, int y, int w, int h);
294   virtual ~FGLayeredInstrument ();
295
296   virtual void draw ();
297
298                                 // Transfer pointer ownership!!
299   virtual int addLayer (FGInstrumentLayer *layer);
300   virtual int addLayer (FGCroppedTexture_ptr texture, int w = -1, int h = -1);
301
302                                 // Transfer pointer ownership!!
303   virtual void addTransformation (FGPanelTransformation * transformation);
304
305 protected:
306   typedef vector<FGInstrumentLayer *> layer_list;
307   layer_list _layers;
308 };
309
310
311 /**
312  * An instrument layer containing a group of sublayers.
313  *
314  * This class is useful for gathering together a group of related
315  * layers, either to hold in an external file or to work under
316  * the same condition.
317  */
318 class FGGroupLayer : public FGInstrumentLayer
319 {
320 public:
321   FGGroupLayer ();
322   virtual ~FGGroupLayer ();
323   virtual void draw ();
324                                 // transfer pointer ownership
325   virtual void addLayer (FGInstrumentLayer * layer);
326 protected:
327   vector<FGInstrumentLayer *> _layers;
328 };
329
330
331 /**
332  * A textured layer of an instrument.
333  *
334  * This is a layer holding a single texture.  Normally, the texture's
335  * backgound should be transparent so that lower layers and the panel
336  * background can show through.
337  */
338 class FGTexturedLayer : public FGInstrumentLayer
339 {
340 public:
341   FGTexturedLayer (int w = -1, int h = -1) : FGInstrumentLayer(w, h) {}
342   FGTexturedLayer (FGCroppedTexture_ptr texture, int w = -1, int h = -1);
343   virtual ~FGTexturedLayer ();
344
345   virtual void draw ();
346
347   virtual void setTexture (FGCroppedTexture_ptr texture) {
348     _texture = texture;
349   }
350   FGCroppedTexture_ptr getTexture() { return _texture; }
351
352   void setEmissive(bool e) { _emissive = e; }
353
354 private:
355   GLuint getDisplayList();
356
357   FGCroppedTexture_ptr _texture;
358   bool _emissive;
359   GLuint displayList;
360 };
361
362
363 /**
364  * A text layer of an instrument.
365  *
366  * This is a layer holding a string of static and/or generated text.
367  * It is useful for instruments that have text displays, such as
368  * a chronometer, GPS, or NavCom radio.
369  */
370 class FGTextLayer : public FGInstrumentLayer
371 {
372 public:
373   enum ChunkType {
374     TEXT,
375     TEXT_VALUE,
376     DOUBLE_VALUE
377   };
378
379   class Chunk : public SGConditional
380   {
381   public:
382     Chunk (const string &text, const string &fmt = "%s");
383     Chunk (ChunkType type, const SGPropertyNode * node,
384            const string &fmt = "", float mult = 1.0, float offs = 0.0,
385            bool truncation = false);
386
387     const char * getValue () const;
388   private:
389     ChunkType _type;
390     string _text;
391     SGConstPropertyNode_ptr _node;
392     string _fmt;
393     float _mult;
394     float _offs;
395     bool _trunc;
396     mutable char _buf[1024];
397     
398   };
399
400   FGTextLayer (int w = -1, int h = -1);
401   virtual ~FGTextLayer ();
402
403   virtual void draw ();
404
405                                 // Transfer pointer!!
406   virtual void addChunk (Chunk * chunk);
407   virtual void setColor (float r, float g, float b);
408   virtual void setPointSize (float size);
409   virtual void setFontName ( const string &name );
410   virtual void setFont (fntFont * font);
411
412 private:
413
414   void recalc_value () const;
415
416   typedef vector<Chunk *> chunk_list;
417   chunk_list _chunks;
418   float _color[4];
419
420   float _pointSize;
421   mutable string _font_name;
422   mutable string _value;
423   mutable SGTimeStamp _then;
424   mutable SGTimeStamp _now;
425
426   static fntRenderer text_renderer;
427 };
428
429
430 /**
431  * A group layer that switches among its children.
432  *
433  * The first layer that passes its condition will be drawn, and
434  * any following layers will be ignored.
435  */
436 class FGSwitchLayer : public FGGroupLayer
437 {
438 public:
439                                 // Transfer pointers!!
440   FGSwitchLayer ();
441   virtual void draw ();
442
443 };
444
445 \f
446 #endif // __PANEL_HXX
447
448 // end of panel.hxx
449
450
451