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.
23 #include "HUD_private.hxx"
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;
46 const int BUFSIZE = 80;
50 float vmin = _input.min();
51 float vmax = _input.max();
52 float cur_value = _input.getFloatValue();
54 float right = _x + _w;
56 float bottom_4 = _h / 4.0; // FIXME
58 // Draw the basic markings for the scale...
59 if (option_vert()) { // Vertical scale
61 draw_line(_x, _y, right, _y);
64 draw_line(_x, top, right, top);
69 if (option_left()) { // Read left, so line down right side
70 draw_line(right, _y, right, top);
71 marker_xs = marker_xe - _w / 3.0; // Adjust tick
74 if (option_right()) { // Read right, so down left sides
75 draw_line(_x, _y, _x, top);
76 marker_xe = _x + _w / 3.0; // Adjust tick
79 // At this point marker x_start and x_end values are transposed.
80 // To keep this from confusing things they are now interchanged.
82 marker_ye = marker_xs;
83 marker_xs = marker_xe;
84 marker_xe = marker_ye;
87 // Work through from bottom to top of scale. Calculating where to put
88 // minor and major ticks.
90 if (!option_noticks()) { // If not no ticks...:)
91 // Calculate x marker offsets
92 int last = (int)vmax + 1;
95 for (; i < last; i++) {
96 // Calculate the location of this tick
97 marker_ys = _y + (i - vmin) * factor()/* +.5f*/;
99 // We compute marker_ys even though we don't know if we will use
100 // either major or minor divisions. Simpler.
102 if (_minor_divs) { // Minor tick marks
103 if (!(i % (int)_minor_divs)) {
104 if (option_left() && option_right()) {
105 draw_line(_x, marker_ys, marker_xs - 3, marker_ys);
106 draw_line(marker_xe + 3, marker_ys, right, marker_ys);
108 } else if (option_left()) {
109 draw_line(marker_xs + 3, marker_ys, marker_xe, marker_ys);
111 draw_line(marker_xs, marker_ys, marker_xe - 3, marker_ys);
116 // Now we work on the major divisions. Since these are also labeled
117 // and no labels are drawn otherwise, we label inside this if
120 if (_major_divs) { // Major tick mark
121 if (!(i % (int)_major_divs)) {
122 if (option_left() && option_right()) {
123 draw_line(_x, marker_ys, marker_xs, marker_ys);
124 draw_line(marker_xe, marker_ys, right, marker_ys);
126 draw_line(marker_xs, marker_ys, marker_xe, marker_ys);
129 if (!option_notext()) {
131 snprintf(buf, BUFSIZE, "%d",
132 int(disp_val * _input.factor()/*+.5*/)); /// was data_scaling(), which makes no sense
134 if (option_left() && option_right())
135 draw_text(_center_x, marker_ys, buf, CENTER);
136 else if (option_left())
137 draw_text(marker_xs, marker_ys, buf, RIGHT|VCENTER);
139 draw_text(marker_xe, marker_ys, buf, LEFT|VCENTER);
146 // Now that the scale is drawn, we draw in the pointer(s).
147 text_y = _y + ((cur_value - vmin) * factor() /*+.5f*/);
149 if (option_right()) {
150 glBegin(GL_LINE_STRIP);
151 glVertex2f(_x, text_y + 5);
152 glVertex2f(marker_xe, text_y);
153 glVertex2f(_x, text_y - 5);
157 glBegin(GL_LINE_STRIP);
158 glVertex2f(right, text_y + 5);
159 glVertex2f(marker_xs, text_y);
160 glVertex2f(right, text_y - 5);
163 // End if VERTICAL SCALE TYPE
165 } else { // Horizontal scale by default
167 draw_line(_x, _y, _x, top);
170 draw_line(right, _y, right, top );
172 marker_ys = _y; // Starting point for
173 marker_ye = top; // tick y location calcs
174 marker_xs = _x + (cur_value - vmin) * factor() /*+ .5f*/;
178 draw_line(_x, _y, right, _y);
180 marker_ye = _y + _h / 2.0; // Tick point adjust
182 glBegin(GL_LINE_STRIP);
183 glVertex2f(marker_xs - bottom_4, _y);
184 glVertex2f(marker_xs, marker_ye);
185 glVertex2f(marker_xs + bottom_4, _y);
189 if (option_bottom()) {
191 draw_line(_x, top, right, top);
193 marker_ys = top - _h / 2.0;
196 glBegin(GL_LINE_STRIP);
197 glVertex2f(marker_xs + bottom_4, top);
198 glVertex2f(marker_xs, marker_ys );
199 glVertex2f(marker_xs - bottom_4, top);
204 int last = (int)vmax + 1;
206 for (; i <last ; i++) {
208 if (!_modulo && i < _input.min())
212 marker_xs = _x + (i - vmin) * factor()/* +.5f*/;
213 // marker_xs = _x + (int)((i - vmin) * factor() + .5f);
215 if (!(i % (int)_minor_divs)) {
216 // draw in ticks only if they aren't too close to the edge.
217 if (((marker_xs + 5) > _x)
218 || ((marker_xs - 5) < right)) {
221 draw_line(marker_xs, _y, marker_xs, marker_ys - 4);
222 draw_line(marker_xs, marker_ye + 4, marker_xs, top);
224 } else if (option_top()) {
225 draw_line(marker_xs, marker_ys, marker_xs, marker_ye - 4);
227 draw_line(marker_xs, marker_ys + 4, marker_xs, marker_ye);
234 if (!(i % (int)_major_divs)) {
240 disp_val = i % (int)_modulo;
244 snprintf(buf, BUFSIZE, "%d",
245 int(disp_val * _input.factor()/* +.5*/)); // was data_scaling(), which makes no sense
247 // Draw major ticks and text only if far enough from the edge.
248 if (((marker_xs - 10) > _x)
249 && ((marker_xs + 10) < right)) {
251 draw_line(marker_xs, _y, marker_xs, marker_ys);
252 draw_line(marker_xs, marker_ye, marker_xs, top);
254 if (!option_notext())
255 draw_text(marker_xs, marker_ys, buf, CENTER);
258 draw_line(marker_xs, marker_ys, marker_xs, marker_ye);
260 if (!option_notext()) {
262 draw_text(marker_xs, top, buf, TOP|HCENTER);
264 draw_text(marker_xs, _y, buf, BOTTOM|HCENTER);