]> git.mxchange.org Git - flightgear.git/blob - src/Instrumentation/HUD/HUD_label.cxx
bracesless blocks are peanuts! It's forgotten "else" that do real harm. :-)
[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 <simgear/props/condition.hxx>
27 #include "HUD.hxx"
28
29
30 HUD::Label::Label(HUD *hud, const SGPropertyNode *n, float x, float y) :
31     Item(hud, n, x, y),
32     _input(n->getNode("input", false)),
33     _fontsize(fgGetInt("/sim/startup/xsize") > 1000 ? FONT_LARGE : FONT_SMALL),         // FIXME
34     _box(n->getBoolValue("box", false)),
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_ALIGN;
47     else if (!strcmp(halign, "right"))
48         _halign = RIGHT_ALIGN;
49     else
50         _halign = CENTER_ALIGN;
51
52     const char *pre = n->getStringValue("prefix", 0);
53     const char *post = n->getStringValue("postfix", 0);
54     const char *fmt = n->getStringValue("format", 0);
55
56     if (pre)
57         _format = pre;
58     if (fmt)
59         _format += fmt;
60     else
61         _format += "%s";
62     if (post)
63         _format += post;
64
65     _mode = check_format(_format.c_str());
66     if (_mode == INVALID) {
67         SG_LOG(SG_INPUT, SG_ALERT, "HUD: invalid format '" << _format.c_str() << '\'');
68         _format = "INVALID";
69         _mode = NONE;
70     }
71
72     blink();
73 }
74
75
76 void HUD::Label::draw(void)
77 {
78     if (!(_mode == NONE || _input.isValid() && blink()))
79         return;
80
81     if (_box) {
82         float h = _hud->_font_size;                     // FIXME
83
84         glPushMatrix();
85         glLoadIdentity();
86
87         glBegin(GL_LINES);
88         glVertex2f(_x - 2.0,  _y - 2.0);
89         glVertex2f(_x + _w + 2.0, _y - 2.0);
90         glVertex2f(_x + _w + 2.0, _y + h + 2.0);
91         glVertex2f(_x - 2.0,  _y + h + 2.0);
92         glEnd();
93
94         glEnable(GL_LINE_STIPPLE);
95         glLineStipple(1, 0xAAAA);
96
97         glBegin(GL_LINES);
98         glVertex2f(_x + _w + 2.0, _y - 2.0);
99         glVertex2f(_x + _w + 2.0, _y + h + 2.0);
100         glVertex2f(_x - 2.0, _y + h + 2.0);
101         glVertex2f(_x - 2.0, _y - 2.0);
102         glEnd();
103
104         glDisable(GL_LINE_STIPPLE);
105         glPopMatrix();
106     }
107
108     const int BUFSIZE = 256;
109     char buf[BUFSIZE];
110     if (_mode == NONE)
111         snprintf(buf, BUFSIZE, _format.c_str());
112     else if (_mode == STRING)
113         snprintf(buf, BUFSIZE, _format.c_str(), _input.getStringValue());
114     else if (_mode == INT)
115         snprintf(buf, BUFSIZE, _format.c_str(), int(_input.getFloatValue()));
116     else if (_mode == LONG)
117         snprintf(buf, BUFSIZE, _format.c_str(), long(_input.getFloatValue()));
118     else if (_mode == FLOAT)
119         snprintf(buf, BUFSIZE, _format.c_str(), float(_input.getFloatValue()));
120     else if (_mode == DOUBLE) // not really supported yet
121         snprintf(buf, BUFSIZE, _format.c_str(), double(_input.getFloatValue()));
122
123     float posincr;
124     float lenstr = text_width(buf);
125
126     if (_halign == RIGHT_ALIGN)
127         posincr = _w - lenstr;
128     else if (_halign == CENTER_ALIGN)
129         posincr = (_w - lenstr) / 2.0;
130     else // LEFT_ALIGN
131         posincr = 0;
132
133     if (_fontsize == FONT_SMALL)
134         draw_text(_x + posincr, _y, buf, get_digits());
135     else if (_fontsize == FONT_LARGE)
136         draw_text(_x + posincr, _y, buf, get_digits());
137 }
138
139
140 // make sure the format matches '[ -+#]?\d*(\.\d*)?(l?[df]|s)'
141 //
142 HUD::Label::Format HUD::Label::check_format(const char *f) const
143 {
144     bool l = false;
145     Format fmt = STRING;
146
147     for (; *f; f++) {
148         if (*f == '%') {
149             if (f[1] == '%')
150                 f++;
151             else
152                 break;
153         }
154     }
155     if (*f++ != '%')
156         return NONE;
157     if (*f == ' ' || *f == '+' || *f == '-' || *f == '#')
158         f++;
159     while (*f && isdigit(*f))
160         f++;
161     if (*f == '.') {
162         f++;
163         while (*f && isdigit(*f))
164             f++;
165     }
166     if (*f == 'l')
167         l = true, f++;
168
169     if (*f == 'd')
170         fmt = l ? LONG : INT;
171     else if (*f == 'f')
172         fmt = l ? DOUBLE : FLOAT;
173     else if (*f == 's') {
174         if (l)
175             return INVALID;
176         fmt = STRING;
177     } else
178         return INVALID;
179
180     for (++f; *f; f++) {
181         if (*f == '%') {
182             if (f[1] == '%')
183                 f++;
184             else
185                 return INVALID;
186         }
187     }
188     return fmt;
189 }
190
191
192 bool HUD::Label::blink()
193 {
194     if (_blink_interval < 0.0f)
195         return true;
196
197     if (_blink_condition && !_blink_condition->test())
198         return true;
199
200     if (_hud->timer() < _blink_target)
201         return _blink_state;
202
203     _blink_target = _hud->timer() + _blink_interval;
204     return _blink_state = !_blink_state;
205 }
206
207