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 Point mid_scr = get_centroid();
55 float cur_value = _input.getFloatValue();
57 width = _x + _w; // FIXME huh?
61 // Draw the basic markings for the scale...
62 if (option_vert()) { // Vertical scale
64 draw_line(_x, _y, width, _y);
67 draw_line(_x, height, width, height);
72 if (option_left()) { // Read left, so line down right side
73 draw_line(width, _y, width, height);
74 marker_xs = marker_xe - _w / 3.0; // Adjust tick
77 if (option_right()) { // Read right, so down left sides
78 draw_line(_x, _y, _x, height);
79 marker_xe = _x + _w / 3.0; // Adjust tick
82 // At this point marker x_start and x_end values are transposed.
83 // To keep this from confusing things they are now interchanged.
85 marker_ye = marker_xs;
86 marker_xs = marker_xe;
87 marker_xe = marker_ye;
90 // Work through from bottom to top of scale. Calculating where to put
91 // minor and major ticks.
93 if (!option_noticks()) { // If not no ticks...:)
94 // Calculate x marker offsets
95 int last = (int)vmax + 1;
98 for (; i < last; i++) {
99 // Calculate the location of this tick
100 marker_ys = _y + (i - vmin) * factor()/* +.5f*/;
102 // We compute marker_ys even though we don't know if we will use
103 // either major or minor divisions. Simpler.
105 if (_minor_divs) { // Minor tick marks
106 if (!(i % (int)_minor_divs)) {
107 if (option_left() && option_right()) {
108 draw_line(_x, marker_ys, marker_xs - 3, marker_ys);
109 draw_line(marker_xe + 3, marker_ys, width, marker_ys);
111 } else if (option_left()) {
112 draw_line(marker_xs + 3, marker_ys, marker_xe, marker_ys);
114 draw_line(marker_xs, marker_ys, marker_xe - 3, marker_ys);
119 // Now we work on the major divisions. Since these are also labeled
120 // and no labels are drawn otherwise, we label inside this if
123 if (_major_divs) { // Major tick mark
124 if (!(i % (int)_major_divs)) {
125 if (option_left() && option_right()) {
126 draw_line(_x, marker_ys, marker_xs, marker_ys);
127 draw_line(marker_xe, marker_ys, width, marker_ys);
129 draw_line(marker_xs, marker_ys, marker_xe, marker_ys);
132 if (!option_notext()) {
134 snprintf(buf, BUFSIZE, "%d",
135 int(disp_val * _input.factor()/*+.5*/)); /// was data_scaling(), which makes no sense
137 lenstr = text_width(buf);
139 if (option_left() && option_right()) {
140 text_x = mid_scr.x - lenstr/2 ;
142 } else if (option_left()) {
143 text_x = marker_xs - lenstr;
145 text_x = marker_xe - lenstr;
147 // Now we know where to put the text.
149 draw_text(text_x, text_y, buf, 0);
156 // Now that the scale is drawn, we draw in the pointer(s). Since labels
157 // have been drawn, text_x and text_y may be recycled. This is used
158 // with the marker start stops to produce a pointer for each side reading
160 text_y = _y + ((cur_value - vmin) * factor() /*+.5f*/);
161 // text_x = marker_xs - _x;
163 if (option_right()) {
164 glBegin(GL_LINE_STRIP);
165 glVertex2f(_x, text_y + 5);
166 glVertex2f(marker_xe, text_y);
167 glVertex2f(_x, text_y - 5);
171 glBegin(GL_LINE_STRIP);
172 glVertex2f(width, text_y + 5);
173 glVertex2f(marker_xs, text_y);
174 glVertex2f(width, text_y - 5);
177 // End if VERTICAL SCALE TYPE
179 } else { // Horizontal scale by default
181 draw_line(_x, _y, _x, height);
184 draw_line(width, _y, width, height );
186 marker_ys = _y; // Starting point for
187 marker_ye = height; // tick y location calcs
188 marker_xs = _x + (cur_value - vmin) * factor() /*+ .5f*/;
192 draw_line(_x, _y, width, _y);
194 marker_ye = _y + _h / 2.0; // Tick point adjust
196 glBegin(GL_LINE_STRIP);
197 glVertex2f(marker_xs - bottom_4, _y);
198 glVertex2f(marker_xs, marker_ye);
199 glVertex2f(marker_xs + bottom_4, _y);
203 if (option_bottom()) {
205 draw_line(_x, height, width, height);
207 marker_ys = height - _h / 2.0;
210 glBegin(GL_LINE_STRIP);
211 glVertex2f(marker_xs + bottom_4, height);
212 glVertex2f(marker_xs, marker_ys );
213 glVertex2f(marker_xs - bottom_4, height);
218 int last = (int)vmax + 1;
220 for (; i <last ; i++) {
222 if (!modulo() && i < _input.min())
226 marker_xs = _x + (i - vmin) * factor()/* +.5f*/;
227 // marker_xs = _x + (int)((i - vmin) * factor() + .5f);
229 if (!(i % (int)_minor_divs)) {
230 // draw in ticks only if they aren't too close to the edge.
231 if (((marker_xs + 5) > _x)
232 || ((marker_xs - 5) < (width))) {
235 draw_line(marker_xs, _y, marker_xs, marker_ys - 4);
236 draw_line(marker_xs, marker_ye + 4, marker_xs, height);
238 } else if (option_top()) {
239 draw_line(marker_xs, marker_ys, marker_xs, marker_ye - 4);
241 draw_line(marker_xs, marker_ys + 4, marker_xs, marker_ye);
248 if (!(i % (int)_major_divs)) {
252 disp_val += modulo();
254 disp_val = i % (int)modulo();
258 snprintf(buf, BUFSIZE, "%d",
259 int(disp_val * _input.factor()/* +.5*/)); // was data_scaling(), which makes no sense
260 lenstr = text_width(buf);
262 // Draw major ticks and text only if far enough from the edge.
263 if (((marker_xs - 10) > _x)
264 && ((marker_xs + 10) < width)) {
266 draw_line(marker_xs, _y, marker_xs, marker_ys);
267 draw_line(marker_xs, marker_ye, marker_xs, height);
269 if (!option_notext())
270 draw_text(marker_xs - lenstr, marker_ys + 4, buf, 0);
273 draw_line(marker_xs, marker_ys, marker_xs, marker_ye);
275 if (!option_notext()) {
277 draw_text(marker_xs - lenstr, height - 10, buf, 0);
279 draw_text(marker_xs - lenstr, _y, buf, 0);