]> git.mxchange.org Git - flightgear.git/blob - src/Instrumentation/HUD/HUD_gauge.cxx
new HUD (work in progress)
[flightgear.git] / src / Instrumentation / HUD / HUD_gauge.cxx
1 // HUD_gauge.cxx -- HUD Gauge Instrument
2 //
3 // Written by Michele America, started September 1997.
4 //
5 // Copyright (C) 1997  Michele F. America  [micheleamerica#geocities:com]
6 // Copyright (C) 2006  Melchior FRANZ  [mfranz#aon:at]
7 //
8 // This program is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU General Public License as
10 // published by the Free Software Foundation; either version 2 of the
11 // License, or (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful, but
14 // WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 // General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the Free Software
20 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21
22 #include "HUD.hxx"
23
24
25 HUD::Gauge::Gauge(HUD *hud, const SGPropertyNode *n, float x, float y) :
26     Scale(hud, n, x, y)
27 {
28 }
29
30
31 // As implemented, draw only correctly draws a horizontal or vertical
32 // scale. It should contain a variation that permits clock type displays.
33 // Now is supports "tickless" displays such as control surface indicators.
34 // This routine should be worked over before using. Current value would be
35 // fetched and not used if not commented out. Clearly that is intollerable.
36
37 void HUD::Gauge::draw(void)
38 {
39     if (!_input.isValid())
40         return;
41
42     float marker_xs, marker_xe;
43     float marker_ys, marker_ye;
44     float text_x, text_y;
45     float width, height, bottom_4;
46     float lenstr;
47     int i;
48     const int BUFSIZE = 80;
49     char buf[BUFSIZE];
50     bool condition;
51     int disp_val = 0;
52     float vmin = _input.min();
53     float vmax = _input.max();
54     Point mid_scr = get_centroid();
55     float cur_value = _input.getFloatValue();
56     Rect  scrn_rect = get_location();
57
58     width = scrn_rect.left + scrn_rect.right;
59     height = scrn_rect.top + scrn_rect.bottom;
60     bottom_4 = scrn_rect.bottom / 4.0;
61
62     // Draw the basic markings for the scale...
63     if (option_vert()) { // Vertical scale
64         // Bottom tick bar
65         draw_line(scrn_rect.left, scrn_rect.top, width, scrn_rect.top);
66
67         // Top tick bar
68         draw_line( scrn_rect.left, height, width, height);
69
70         marker_xs = scrn_rect.left;
71         marker_xe = width;
72
73         if (option_left()) { // Read left, so line down right side
74             draw_line(width, scrn_rect.top, width, height);
75             marker_xs  = marker_xe - scrn_rect.right / 3.0;   // Adjust tick
76         }
77
78         if (option_right()) {     // Read  right, so down left sides
79             draw_line(scrn_rect.left, scrn_rect.top, scrn_rect.left, height);
80             marker_xe = scrn_rect.left + scrn_rect.right / 3.0;   // Adjust tick
81         }
82
83         // At this point marker x_start and x_end values are transposed.
84         // To keep this from confusing things they are now interchanged.
85         if (option_both()) {
86             marker_ye = marker_xs;
87             marker_xs = marker_xe;
88             marker_xe = marker_ye;
89         }
90
91         // Work through from bottom to top of scale. Calculating where to put
92         // minor and major ticks.
93
94         if (!option_noticks()) {    // If not no ticks...:)
95             // Calculate x marker offsets
96             int last = (int)vmax + 1;    // float_to_int(vmax)+1;
97             i = (int)vmin; //float_to_int(vmin);
98
99             for (; i < last; i++) {
100                 // Calculate the location of this tick
101                 marker_ys = scrn_rect.top + (i - vmin) * factor()/* +.5f*/;
102
103                 // We compute marker_ys even though we don't know if we will use
104                 // either major or minor divisions. Simpler.
105
106                 if (_minor_divs) {                  // Minor tick marks
107                     if (!(i % (int)_minor_divs)) {
108                         if (option_left() && option_right()) {
109                             draw_line(scrn_rect.left, marker_ys, marker_xs - 3, marker_ys);
110                             draw_line(marker_xe + 3, marker_ys, width, marker_ys);
111
112                         } else if (option_left()) {
113                             draw_line(marker_xs + 3, marker_ys, marker_xe, marker_ys);
114                         } else {
115                             draw_line(marker_xs, marker_ys, marker_xe - 3, marker_ys);
116                         }
117                     }
118                 }
119
120                 // Now we work on the major divisions. Since these are also labeled
121                 // and no labels are drawn otherwise, we label inside this if
122                 // statement.
123
124                 if (_major_divs) {                  // Major tick mark
125                     if (!(i % (int)_major_divs)) {
126                         if (option_left() && option_right()) {
127                             draw_line(scrn_rect.left, marker_ys, marker_xs, marker_ys);
128                             draw_line(marker_xe, marker_ys, width, marker_ys);
129                         } else {
130                             draw_line(marker_xs, marker_ys, marker_xe, marker_ys);
131                         }
132
133                         if (!option_notext()) {
134                             disp_val = i;
135                             snprintf(buf, BUFSIZE, "%d",
136                                     int(disp_val * _input.factor()/*+.5*/));  /// was data_scaling(), which makes no sense
137
138                             lenstr = text_width(buf);
139
140                             if (option_left() && option_right()) {
141                                 text_x = mid_scr.x - lenstr/2 ;
142
143                             } else if (option_left()) {
144                                 text_x = marker_xs - lenstr;
145                             } else {
146                                 text_x = marker_xe - lenstr;
147                             }
148                             // Now we know where to put the text.
149                             text_y = marker_ys;
150                             draw_text(text_x, text_y, buf, 0);
151                         }
152                     }
153                 }
154             }
155         }
156
157         // Now that the scale is drawn, we draw in the pointer(s). Since labels
158         // have been drawn, text_x and text_y may be recycled. This is used
159         // with the marker start stops to produce a pointer for each side reading
160
161         text_y = scrn_rect.top + ((cur_value - vmin) * factor() /*+.5f*/);
162         //    text_x = marker_xs - scrn_rect.left;
163
164         if (option_right()) {
165             glBegin(GL_LINE_STRIP);
166             glVertex2f(scrn_rect.left, text_y + 5);
167             glVertex2f(marker_xe, text_y);
168             glVertex2f(scrn_rect.left, text_y - 5);
169             glEnd();
170         }
171         if (option_left()) {
172             glBegin(GL_LINE_STRIP);
173             glVertex2f(width, text_y + 5);
174             glVertex2f(marker_xs, text_y);
175             glVertex2f(width, text_y - 5);
176             glEnd();
177         }
178         // End if VERTICAL SCALE TYPE
179
180     } else {                             // Horizontal scale by default
181         // left tick bar
182         draw_line(scrn_rect.left, scrn_rect.top, scrn_rect.left, height);
183
184         // right tick bar
185         draw_line(width, scrn_rect.top, width, height );
186
187         marker_ys = scrn_rect.top;                       // Starting point for
188         marker_ye = height;                              // tick y location calcs
189         marker_xs = scrn_rect.left + (cur_value - vmin) * factor() /*+ .5f*/;
190
191         if (option_top()) {
192             // Bottom box line
193             draw_line(scrn_rect.left, scrn_rect.top, width, scrn_rect.top);
194
195             marker_ye = scrn_rect.top + scrn_rect.bottom / 2.0;   // Tick point adjust
196             // Bottom arrow
197             glBegin(GL_LINE_STRIP);
198             glVertex2f(marker_xs - bottom_4, scrn_rect.top);
199             glVertex2f(marker_xs, marker_ye);
200             glVertex2f(marker_xs + bottom_4, scrn_rect.top);
201             glEnd();
202         }
203
204         if (option_bottom()) {
205             // Top box line
206             draw_line(scrn_rect.left, height, width, height);
207             // Tick point adjust
208             marker_ys = height - scrn_rect.bottom / 2.0;
209
210             // Top arrow
211             glBegin(GL_LINE_STRIP);
212             glVertex2f(marker_xs + bottom_4, height);
213             glVertex2f(marker_xs, marker_ys );
214             glVertex2f(marker_xs - bottom_4, height);
215             glEnd();
216         }
217
218
219         int last = (int)vmax + 1; //float_to_int(vmax)+1;
220         i = (int)vmin; //float_to_int(vmin);
221         for (; i <last ; i++) {
222             condition = true;
223             if (!modulo() && i < _input.min())
224                     condition = false;
225
226             if (condition) {
227                 marker_xs = scrn_rect.left + (i - vmin) * factor()/* +.5f*/;
228                 //        marker_xs = scrn_rect.left + (int)((i - vmin) * factor() + .5f);
229                 if (_minor_divs) {
230                     if (!(i % (int)_minor_divs)) {
231                         // draw in ticks only if they aren't too close to the edge.
232                         if (((marker_xs + 5) > scrn_rect.left)
233                                || ((marker_xs - 5) < (width))) {
234
235                             if (option_both()) {
236                                 draw_line(marker_xs, scrn_rect.top, marker_xs, marker_ys - 4);
237                                 draw_line(marker_xs, marker_ye + 4, marker_xs, height);
238
239                             } else if (option_top()) {
240                                 draw_line(marker_xs, marker_ys, marker_xs, marker_ye - 4);
241                             } else {
242                                 draw_line(marker_xs, marker_ys + 4, marker_xs, marker_ye);
243                             }
244                         }
245                     }
246                 }
247
248                 if (_major_divs) {
249                     if (!(i % (int)_major_divs)) {
250                         if (modulo()) {
251                             if (disp_val < 0) {
252                                 while (disp_val < 0)
253                                     disp_val += modulo();
254                             }
255                             disp_val = i % (int)modulo();
256                         } else {
257                             disp_val = i;
258                         }
259                         snprintf(buf, BUFSIZE, "%d",
260                                 int(disp_val * _input.factor()/* +.5*/)); // was data_scaling(), which makes no sense
261                         lenstr = text_width(buf);
262
263                         // Draw major ticks and text only if far enough from the edge.
264                         if (((marker_xs - 10) > scrn_rect.left)
265                                 && ((marker_xs + 10) < width)) {
266                             if (option_both()) {
267                                 draw_line(marker_xs, scrn_rect.top, marker_xs, marker_ys);
268                                 draw_line(marker_xs, marker_ye, marker_xs, height);
269
270                                 if (!option_notext())
271                                     draw_text(marker_xs - lenstr, marker_ys + 4, buf, 0);
272
273                             } else {
274                                 draw_line(marker_xs, marker_ys, marker_xs, marker_ye);
275
276                                 if (!option_notext()) {
277                                     if (option_top())
278                                         draw_text(marker_xs - lenstr, height - 10, buf, 0);
279                                     else
280                                         draw_text(marker_xs - lenstr, scrn_rect.top, buf, 0);
281                                 }
282                             }
283                         }
284                     }
285                 }
286             }
287         }
288     }
289 }
290
291