]> git.mxchange.org Git - flightgear.git/blob - src/Instrumentation/HUD/HUD_label.cxx
NavDisplay enhancements for Syd.
[flightgear.git] / src / Instrumentation / HUD / HUD_label.cxx
1 // HUD_label.cxx -- HUD Label
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 #ifdef HAVE_CONFIG_H
23 #  include <config.h>
24 #endif
25
26 #include "HUD.hxx"
27
28
29 HUD::Label::Label(HUD *hud, const SGPropertyNode *n, float x, float y) :
30     Item(hud, n, x, y),
31     _input(n->getNode("input", false)),
32     _box(n->getBoolValue("box", false)),
33     _pointer_width(n->getFloatValue("pointer-width", 7.0)),
34     _pointer_length(n->getFloatValue("pointer-length", 5.0)),
35     _blink_condition(0),
36     _blink_interval(n->getFloatValue("blinking/interval", -1.0f)),
37     _blink_target(0.0),
38     _blink_state(true)
39 {
40     const SGPropertyNode *node = n->getNode("blinking/condition");
41     if (node)
42        _blink_condition = sgReadCondition(globals->get_props(), node);
43
44     const char *halign = n->getStringValue("halign", "center");
45     if (!strcmp(halign, "left"))
46         _halign = LEFT;
47     else if (!strcmp(halign, "right"))
48         _halign = RIGHT;
49     else
50         _halign = HCENTER;
51
52     _halign |= VCENTER;
53
54     const char *pre = n->getStringValue("prefix", 0);
55     const char *post = n->getStringValue("postfix", 0);
56     const char *fmt = n->getStringValue("format", 0);
57
58     if (pre)
59         _format = pre;
60
61     if (fmt)
62         _format += fmt;
63     else
64         _format += "%s";
65
66     if (post)
67         _format += post;
68
69     _mode = check_format(_format.c_str());
70     if (_mode == INVALID) {
71         SG_LOG(SG_INPUT, SG_ALERT, "HUD: invalid format '" << _format.c_str()
72                 << "' in <label> '" << _name << '\'');
73         _format = "INVALID";
74         _mode = NONE;
75     }
76
77     blink();
78 }
79
80
81 void HUD::Label::draw(void)
82 {
83     if (!((_mode == NONE || _input.isValid()) && blink()))
84         return;
85
86     if (_box) {
87         float l, r, p;
88         float pw = _pointer_width / 2.0;
89
90         l = _center_x - pw;
91         r = _center_x + pw;
92         bool draw_parallel = fabs(_pointer_width - _w) > 2.0; // draw lines left and right of arrow?
93
94         if (option_bottom()) {
95             if (draw_parallel) {
96                 draw_line(_x, _y, l, _y);
97                 draw_line(r, _y, _x + _w, _y);
98             }
99             p = _y - _pointer_length;
100             draw_line(l, _y, _center_x, p);
101             draw_line(_center_x, p, r, _y);
102         } else
103             draw_line(_x, _y, _x + _w, _y);
104
105         if (option_top()) {
106             if (draw_parallel) {
107                 draw_line(_x, _y + _h, l, _y + _h);
108                 draw_line(r, _y + _h, _x + _w, _y + _h);
109             }
110             p = _y + _h + _pointer_length;
111             draw_line(l, _y + _h, _center_x, p);
112             draw_line(_center_x, p, r, _y + _h);
113         } else
114             draw_line(_x + _w, _y + _h, _x, _y + _h);
115
116         l = _center_y - pw;
117         r = _center_y + pw;
118         draw_parallel = fabs(_pointer_width - _h) > 2.0;
119
120         if (option_left()) {
121             if (draw_parallel) {
122                 draw_line(_x, _y, _x, l);
123                 draw_line(_x, r, _x, _y + _h);
124             }
125             p = _x - _pointer_length;
126             draw_line(_x, l, p, _center_y);
127             draw_line(p, _center_y, _x, r);
128         } else
129             draw_line(_x, _y + _h, _x, _y);
130
131         if (option_right()) {
132             if (draw_parallel) {
133                 draw_line(_x + _w, _y, _x + _w, l);
134                 draw_line(_x + _w, r, _x + _w, _y + _h);
135             }
136             p = _x + _w + _pointer_length;
137             draw_line(_x + _w, l, p, _center_y);
138             draw_line(p, _center_y, _x + _w, r);
139         } else
140             draw_line(_x + _w, _y, _x + _w, _y + _h);
141     }
142
143     const int BUFSIZE = 256;
144     char buf[BUFSIZE+1];
145         buf[ BUFSIZE] = '\0';  // Be sure to terminate properly
146     if (_mode == NONE)
147         snprintf(buf, BUFSIZE, _format.c_str(), 0);
148     else if (_mode == STRING)
149         snprintf(buf, BUFSIZE, _format.c_str(), _input.getStringValue());
150     else if (_mode == INT)
151         snprintf(buf, BUFSIZE, _format.c_str(), int(_input.getFloatValue()));
152     else if (_mode == LONG)
153         snprintf(buf, BUFSIZE, _format.c_str(), long(_input.getFloatValue()));
154     else if (_mode == FLOAT)
155         snprintf(buf, BUFSIZE, _format.c_str(), float(_input.getFloatValue()));
156     else if (_mode == DOUBLE) // not really supported yet
157         snprintf(buf, BUFSIZE, _format.c_str(), double(_input.getFloatValue()));
158
159     if (_halign & HCENTER)
160         draw_text(_center_x, _center_y, buf, _halign, get_digits());
161     else if (_halign & LEFT)
162         draw_text(_x, _center_y, buf, _halign, get_digits());
163     else // if (_halign & RIGHT)
164         draw_text(_x + _w, _center_y, buf, _halign, get_digits());
165 }
166
167
168 bool HUD::Label::blink()
169 {
170     if (_blink_interval < 0.0f)
171         return true;
172
173     if (_blink_condition && !_blink_condition->test())
174         return true;
175
176     if (_hud->timer() < _blink_target)
177         return _blink_state;
178
179     _blink_target = _hud->timer() + _blink_interval;
180     return _blink_state = !_blink_state;
181 }
182
183