1 // HUD_gauge.cxx -- HUD Gauge Instrument
3 // Written by Michele America, started September 1997.
5 // Copyright (C) 1997 Michele F. America [micheleamerica#geocities:com]
6 // Copyright (C) 2006 Melchior FRANZ [mfranz#aon:at]
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.
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.
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.
25 HUD::Gauge::Gauge(HUD *hud, const SGPropertyNode *n, float x, float y) :
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.
37 void HUD::Gauge::draw(void)
39 if (!_input.isValid())
42 float marker_xs, marker_xe;
43 float marker_ys, marker_ye;
45 float width, height, bottom_4;
48 const int BUFSIZE = 80;
52 float vmin = _input.min();
53 float vmax = _input.max();
54 float cur_value = _input.getFloatValue();
56 width = _x + _w; // FIXME huh?
60 // Draw the basic markings for the scale...
61 if (option_vert()) { // Vertical scale
63 draw_line(_x, _y, width, _y);
66 draw_line(_x, height, width, height);
71 if (option_left()) { // Read left, so line down right side
72 draw_line(width, _y, width, height);
73 marker_xs = marker_xe - _w / 3.0; // Adjust tick
76 if (option_right()) { // Read right, so down left sides
77 draw_line(_x, _y, _x, height);
78 marker_xe = _x + _w / 3.0; // Adjust tick
81 // At this point marker x_start and x_end values are transposed.
82 // To keep this from confusing things they are now interchanged.
84 marker_ye = marker_xs;
85 marker_xs = marker_xe;
86 marker_xe = marker_ye;
89 // Work through from bottom to top of scale. Calculating where to put
90 // minor and major ticks.
92 if (!option_noticks()) { // If not no ticks...:)
93 // Calculate x marker offsets
94 int last = (int)vmax + 1;
97 for (; i < last; i++) {
98 // Calculate the location of this tick
99 marker_ys = _y + (i - vmin) * factor()/* +.5f*/;
101 // We compute marker_ys even though we don't know if we will use
102 // either major or minor divisions. Simpler.
104 if (_minor_divs) { // Minor tick marks
105 if (!(i % (int)_minor_divs)) {
106 if (option_left() && option_right()) {
107 draw_line(_x, marker_ys, marker_xs - 3, marker_ys);
108 draw_line(marker_xe + 3, marker_ys, width, marker_ys);
110 } else if (option_left()) {
111 draw_line(marker_xs + 3, marker_ys, marker_xe, marker_ys);
113 draw_line(marker_xs, marker_ys, marker_xe - 3, marker_ys);
118 // Now we work on the major divisions. Since these are also labeled
119 // and no labels are drawn otherwise, we label inside this if
122 if (_major_divs) { // Major tick mark
123 if (!(i % (int)_major_divs)) {
124 if (option_left() && option_right()) {
125 draw_line(_x, marker_ys, marker_xs, marker_ys);
126 draw_line(marker_xe, marker_ys, width, marker_ys);
128 draw_line(marker_xs, marker_ys, marker_xe, marker_ys);
131 if (!option_notext()) {
133 snprintf(buf, BUFSIZE, "%d",
134 int(disp_val * _input.factor()/*+.5*/)); /// was data_scaling(), which makes no sense
136 lenstr = text_width(buf);
138 if (option_left() && option_right()) {
139 text_x = _center_x - lenstr/2 ;
141 } else if (option_left()) {
142 text_x = marker_xs - lenstr;
144 text_x = marker_xe - lenstr;
146 // Now we know where to put the text.
148 draw_text(text_x, text_y, buf, 0);
155 // Now that the scale is drawn, we draw in the pointer(s). Since labels
156 // have been drawn, text_x and text_y may be recycled. This is used
157 // with the marker start stops to produce a pointer for each side reading
159 text_y = _y + ((cur_value - vmin) * factor() /*+.5f*/);
160 // text_x = marker_xs - _x;
162 if (option_right()) {
163 glBegin(GL_LINE_STRIP);
164 glVertex2f(_x, text_y + 5);
165 glVertex2f(marker_xe, text_y);
166 glVertex2f(_x, text_y - 5);
170 glBegin(GL_LINE_STRIP);
171 glVertex2f(width, text_y + 5);
172 glVertex2f(marker_xs, text_y);
173 glVertex2f(width, text_y - 5);
176 // End if VERTICAL SCALE TYPE
178 } else { // Horizontal scale by default
180 draw_line(_x, _y, _x, height);
183 draw_line(width, _y, width, height );
185 marker_ys = _y; // Starting point for
186 marker_ye = height; // tick y location calcs
187 marker_xs = _x + (cur_value - vmin) * factor() /*+ .5f*/;
191 draw_line(_x, _y, width, _y);
193 marker_ye = _y + _h / 2.0; // Tick point adjust
195 glBegin(GL_LINE_STRIP);
196 glVertex2f(marker_xs - bottom_4, _y);
197 glVertex2f(marker_xs, marker_ye);
198 glVertex2f(marker_xs + bottom_4, _y);
202 if (option_bottom()) {
204 draw_line(_x, height, width, height);
206 marker_ys = height - _h / 2.0;
209 glBegin(GL_LINE_STRIP);
210 glVertex2f(marker_xs + bottom_4, height);
211 glVertex2f(marker_xs, marker_ys );
212 glVertex2f(marker_xs - bottom_4, height);
217 int last = (int)vmax + 1;
219 for (; i <last ; i++) {
221 if (!_modulo && i < _input.min())
225 marker_xs = _x + (i - vmin) * factor()/* +.5f*/;
226 // marker_xs = _x + (int)((i - vmin) * factor() + .5f);
228 if (!(i % (int)_minor_divs)) {
229 // draw in ticks only if they aren't too close to the edge.
230 if (((marker_xs + 5) > _x)
231 || ((marker_xs - 5) < (width))) {
234 draw_line(marker_xs, _y, marker_xs, marker_ys - 4);
235 draw_line(marker_xs, marker_ye + 4, marker_xs, height);
237 } else if (option_top()) {
238 draw_line(marker_xs, marker_ys, marker_xs, marker_ye - 4);
240 draw_line(marker_xs, marker_ys + 4, marker_xs, marker_ye);
247 if (!(i % (int)_major_divs)) {
253 disp_val = i % (int)_modulo;
257 snprintf(buf, BUFSIZE, "%d",
258 int(disp_val * _input.factor()/* +.5*/)); // was data_scaling(), which makes no sense
259 lenstr = text_width(buf);
261 // Draw major ticks and text only if far enough from the edge.
262 if (((marker_xs - 10) > _x)
263 && ((marker_xs + 10) < width)) {
265 draw_line(marker_xs, _y, marker_xs, marker_ys);
266 draw_line(marker_xs, marker_ye, marker_xs, height);
268 if (!option_notext())
269 draw_text(marker_xs - lenstr, marker_ys + 4, buf, 0);
272 draw_line(marker_xs, marker_ys, marker_xs, marker_ye);
274 if (!option_notext()) {
276 draw_text(marker_xs - lenstr, height - 10, buf, 0);
278 draw_text(marker_xs - lenstr, _y, buf, 0);