]> git.mxchange.org Git - flightgear.git/blob - src/Cockpit/hud_gaug.cxx
- fix more cases of scale tick aliasing to get smooth scale movements
[flightgear.git] / src / Cockpit / hud_gaug.cxx
1
2 #include "hud.hxx"
3
4
5 #ifdef USE_HUD_TextList
6 #define textString( x , y, text, digit )  TextString( text, x , y,digit )
7 #else
8 #define textString( x , y, text, digit )  puDrawString ( guiFnt, text, x, y )
9 #endif
10
11 //============== Top of gauge_instr class member definitions ==============
12
13 gauge_instr::gauge_instr(
14              int      x,
15              int      y,
16              UINT     width,
17              UINT     height,
18              FLTFNPTR load_fn,
19              UINT     options,
20              float    disp_scale,
21              float    maxValue,
22              float    minValue,
23              UINT     major_divs,
24              UINT     minor_divs,
25              int      dp_showing,
26              UINT     modulus,
27              bool     working) :
28     instr_scale( x, y, width, height,
29                  load_fn, options,
30                  (maxValue - minValue), // Always shows span?
31                  maxValue, minValue,
32                  disp_scale,
33                  major_divs, minor_divs,
34                  modulus, dp_showing,
35                  working)
36 {
37     //  UINT options = get_options();
38     //  huds_vert    = options & HUDS_VERT;
39     //  huds_left    = options & HUDS_LEFT;
40     //  huds_right   = options & HUDS_RIGHT;
41     //  huds_both    = (options & HUDS_BOTH) == HUDS_BOTH;
42     //  huds_noticks = options & HUDS_NOTICKS;
43     //  huds_notext  = options & HUDS_NOTEXT;
44     //  huds_top     = options & HUDS_TOP;
45     //  huds_bottom  = options & HUDS_BOTTOM;
46 }
47
48
49 gauge_instr::~gauge_instr()
50 {
51 }
52
53
54 gauge_instr::gauge_instr( const gauge_instr & image) :
55     instr_scale( (instr_scale &) image)
56 {
57     //  UINT options = get_options();
58     //  huds_vert = options & HUDS_VERT;
59     //  huds_left = options & HUDS_LEFT;
60     //  huds_right = options & HUDS_RIGHT;
61     //  huds_both = (options & HUDS_BOTH) == HUDS_BOTH;
62     //  huds_noticks = options & HUDS_NOTICKS;
63     //  huds_notext = options & HUDS_NOTEXT;
64     //  huds_top = options & HUDS_TOP;
65     //  huds_bottom =  options & HUDS_BOTTOM;
66 }
67
68
69 gauge_instr & gauge_instr::operator=(const gauge_instr & rhs)
70 {
71     if (!(this == &rhs)) {
72         instr_scale::operator = (rhs);
73     }
74     return *this;
75 }
76
77
78 // As implemented, draw only correctly draws a horizontal or vertical
79 // scale. It should contain a variation that permits clock type displays.
80 // Now is supports "tickless" displays such as control surface indicators.
81 // This routine should be worked over before using. Current value would be
82 // fetched and not used if not commented out. Clearly that is intollerable.
83
84 void gauge_instr::draw (void)
85 {
86     float marker_xs, marker_xe;
87     float marker_ys, marker_ye;
88     int text_x, text_y;
89     int width, height, bottom_4;
90     int lenstr;
91     int i;
92     char TextScale[80];
93     bool condition;
94     int disp_val = 0;
95     float vmin       = min_val();
96     float vmax       = max_val();
97     POINT mid_scr    = get_centroid();
98     float cur_value  = get_value();
99     RECT  scrn_rect  = get_location();
100     UINT options     = get_options();
101
102     width = scrn_rect.left + scrn_rect.right;
103     height = scrn_rect.top  + scrn_rect.bottom,
104     bottom_4 = scrn_rect.bottom / 4;
105     // Draw the basic markings for the scale...
106
107     if ( huds_vert(options) ) { // Vertical scale
108         drawOneLine( scrn_rect.left,     // Bottom tick bar
109                      scrn_rect.top,
110                      width,
111                      scrn_rect.top);
112
113         drawOneLine( scrn_rect.left,    // Top tick bar
114                      height,
115                      width,
116                      height );
117
118         marker_xs = scrn_rect.left;
119         marker_xe = width;
120
121         if ( huds_left(options) ) {     // Read left, so line down right side
122             drawOneLine( width,
123                          scrn_rect.top,
124                          width,
125                          height);
126
127             marker_xs  = marker_xe - scrn_rect.right / 3.0;   // Adjust tick xs
128         }
129
130         if ( huds_right(options) ) {     // Read  right, so down left sides
131             drawOneLine( scrn_rect.left,
132                          scrn_rect.top,
133                          scrn_rect.left,
134                          height);
135
136             marker_xe = scrn_rect.left + scrn_rect.right / 3.0;     // Adjust tick xe
137         }
138
139         // At this point marker x_start and x_end values are transposed.
140         // To keep this from confusing things they are now interchanged.
141         if ( huds_both(options) ) {
142             marker_ye = marker_xs;
143             marker_xs = marker_xe;
144             marker_xe = marker_ye;
145         }
146
147         // Work through from bottom to top of scale. Calculating where to put
148         // minor and major ticks.
149
150         if ( !huds_noticks(options)) {    // If not no ticks...:)
151             // Calculate x marker offsets
152             int last = (int)vmax + 1; //FloatToInt(vmax)+1;
153             i = (int)vmin; //FloatToInt(vmin);
154             for (; i < last; i++) {
155                 // for ( i = (int)vmin; i <= (int)vmax; i++ ) {
156
157                 // Calculate the location of this tick
158                 marker_ys = scrn_rect.top + (i - vmin) * factor()/* +.5f*/;
159
160                 // We compute marker_ys even though we don't know if we will use
161                 // either major or minor divisions. Simpler.
162
163                 if ( div_min()) {                  // Minor tick marks
164                     if ( !(i%(int)div_min()) ) {
165                         if ( huds_left(options) && huds_right(options) ) {
166                             drawOneLine( scrn_rect.left, marker_ys,
167                                          marker_xs - 3, marker_ys );
168                             drawOneLine( marker_xe + 3, marker_ys,
169                                          width, marker_ys );
170                         }
171                         else {
172                             if ( huds_left(options) ) {
173                                 drawOneLine( marker_xs + 3, marker_ys, marker_xe, marker_ys );
174                             }
175                             else {
176                                 drawOneLine( marker_xs, marker_ys, marker_xe - 3, marker_ys );
177                             }
178                         }
179                     }
180                 }
181
182                 // Now we work on the major divisions. Since these are also labeled
183                 // and no labels are drawn otherwise, we label inside this if
184                 // statement.
185
186                 if ( div_max()) {                  // Major tick mark
187                     if ( !(i%(int)div_max()) )            {
188                         if ( huds_left(options) && huds_right(options) ) {
189                             drawOneLine( scrn_rect.left, marker_ys,
190                                          marker_xs, marker_ys );
191                             drawOneLine( marker_xe, marker_ys,
192                                          width, marker_ys );
193                         }
194                         else {
195                             drawOneLine( marker_xs, marker_ys, marker_xe, marker_ys );
196                         }
197
198                         if ( !huds_notext(options) ) {
199                             disp_val = i;
200                             sprintf( TextScale, "%d",
201                                      FloatToInt(disp_val * data_scaling()/*+.5*/ ));
202
203                             lenstr = getStringWidth( TextScale );
204
205                             if ( huds_left(options) && huds_right(options) ) {
206                                 text_x = mid_scr.x -  lenstr/2 ;
207                             }
208                             else {
209                                 if ( huds_left(options) )              {
210                                     text_x = FloatToInt(marker_xs - lenstr);
211                                 }
212                                 else {
213                                     text_x = FloatToInt(marker_xe - lenstr);
214                                 }
215                             }
216                             // Now we know where to put the text.
217                             text_y = FloatToInt(marker_ys);
218                             textString( text_x, text_y, TextScale, 0 );
219                         }
220                     }
221                 }  //
222             }  //
223         }  //
224         // Now that the scale is drawn, we draw in the pointer(s). Since labels
225         // have been drawn, text_x and text_y may be recycled. This is used
226         // with the marker start stops to produce a pointer for each side reading
227
228         text_y = scrn_rect.top + FloatToInt((cur_value - vmin) * factor() /*+.5f*/);
229         //    text_x = marker_xs - scrn_rect.left;
230
231         if ( huds_right(options) ) {
232             glBegin(GL_LINE_STRIP);
233             glVertex2f( scrn_rect.left, text_y + 5);
234             glVertex2f( FloatToInt(marker_xe),      text_y);
235             glVertex2f( scrn_rect.left, text_y - 5);
236             glEnd();
237         }
238         if ( huds_left(options) ) {
239             glBegin(GL_LINE_STRIP);
240             glVertex2f( width,      text_y + 5);
241             glVertex2f( FloatToInt(marker_xs),  text_y);
242             glVertex2f( width,      text_y - 5);
243             glEnd();
244         }
245         // End if VERTICAL SCALE TYPE
246
247     } else {                             // Horizontal scale by default
248         drawOneLine( scrn_rect.left,     // left tick bar
249                      scrn_rect.top,
250                      scrn_rect.left,
251                      height);
252
253         drawOneLine( width,    // right tick bar
254                      scrn_rect.top,
255                      width,
256                      height );
257
258         marker_ys = scrn_rect.top;                       // Starting point for
259         marker_ye = height;                              // tick y location calcs
260         marker_xs = scrn_rect.left + (cur_value - vmin) * factor() /*+ .5f*/;
261
262         if ( huds_top(options) ) {
263             drawOneLine( scrn_rect.left,
264                          scrn_rect.top,
265                          width,
266                          scrn_rect.top);                    // Bottom box line
267
268             marker_ye  = scrn_rect.top + scrn_rect.bottom / 2.0;   // Tick point adjust
269             // Bottom arrow
270             glBegin(GL_LINE_STRIP);
271             glVertex2f( marker_xs - bottom_4, scrn_rect.top);
272             glVertex2f( marker_xs, marker_ye);
273             glVertex2f( marker_xs + bottom_4, scrn_rect.top);
274             glEnd();
275         }
276         if ( huds_bottom(options) ) {
277             // Top box line
278             drawOneLine( scrn_rect.left, height, width, height);
279             // Tick point adjust
280             marker_ys = height - scrn_rect.bottom  / 2.0;
281
282             // Top arrow
283             glBegin(GL_LINE_STRIP);
284             glVertex2f( marker_xs + bottom_4, height);
285             glVertex2f( marker_xs, marker_ys );
286             glVertex2f( marker_xs - bottom_4, height);
287             glEnd();
288         }
289
290
291         int last = (int)vmax + 1; //FloatToInt(vmax)+1;
292         i = (int)vmin; //FloatToInt(vmin);
293         for ( ; i <last ; i++ )      {
294             condition = true;
295             if ( !modulo()) {
296                 if ( i < min_val()) {
297                     condition = false;
298                 }
299             }
300             if ( condition )        {
301                 marker_xs = scrn_rect.left + (i - vmin) * factor()/* +.5f*/;
302                 //        marker_xs = scrn_rect.left + (int)((i - vmin) * factor() + .5f);
303                 if ( div_min()){
304                     if ( !(i%(int)div_min()) ) {
305                         // draw in ticks only if they aren't too close to the edge.
306                         if ((( marker_xs + 5) > scrn_rect.left ) ||
307                            (( marker_xs - 5 )< (width))){
308
309                             if ( huds_both(options) ) {
310                                 drawOneLine( marker_xs, scrn_rect.top,
311                                              marker_xs, marker_ys - 4);
312                                 drawOneLine( marker_xs, marker_ye + 4,
313                                              marker_xs, height);
314                             }
315                             else {
316                                 if ( huds_top(options) ) {
317                                     drawOneLine( marker_xs, marker_ys,
318                                                  marker_xs, marker_ye - 4);
319                                 }
320                                 else {
321                                     drawOneLine( marker_xs, marker_ys + 4,
322                                                  marker_xs, marker_ye);
323                                 }
324                             }
325                         }
326                     }
327                 }
328                 if ( div_max()) {
329                     if ( !(i%(int)div_max()) ) {
330                         if (modulo()) {
331                             if ( disp_val < 0) {
332                                 while( disp_val < 0 ) {
333                                     disp_val += modulo();
334                                 }
335                             }
336                             disp_val = i % (int)modulo();
337                         } else {
338                             disp_val = i;
339                         }
340                         sprintf( TextScale, "%d",
341                                  FloatToInt(disp_val  * data_scaling()/* +.5*/ ));
342                         lenstr = getStringWidth( TextScale);
343
344                         // Draw major ticks and text only if far enough from the edge.
345                         if (( (marker_xs - 10)> scrn_rect.left ) &&
346                            ( (marker_xs + 10) < width )){
347                             if ( huds_both(options) ) {
348                                 drawOneLine( marker_xs, scrn_rect.top,
349                                              marker_xs, marker_ys);
350                                 drawOneLine( marker_xs, marker_ye,
351                                              marker_xs, height);
352
353                                 if ( !huds_notext(options) ) {
354                                     textString ( marker_xs - lenstr, marker_ys + 4,
355                                                  TextScale ,0);
356                                 }
357                             }
358                             else {
359                                 drawOneLine( marker_xs, marker_ys,
360                                              marker_xs, marker_ye );
361
362                                 if ( !huds_notext(options) ) {
363                                     if ( huds_top(options) )              {
364                                         textString ( marker_xs - lenstr,
365                                                      height - 10,
366                                                      TextScale, 0 );
367                                     }
368                                     else  {
369                                         textString( marker_xs - lenstr, scrn_rect.top,
370                                                     TextScale, 0 );
371                                     }
372                                 }
373                             }
374                         }
375                     }
376                 }
377             }
378         }
379     }
380 }
381
382