1 // HUD_label.cxx -- HUD Label
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.
26 #include <simgear/props/condition.hxx>
30 HUD::Label::Label(HUD *hud, const SGPropertyNode *n, float x, float 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)),
36 _blink_interval(n->getFloatValue("blinking/interval", -1.0f)),
40 const SGPropertyNode *node = n->getNode("blinking/condition");
42 _blink_condition = sgReadCondition(globals->get_props(), node);
44 const char *halign = n->getStringValue("halign", "center");
45 if (!strcmp(halign, "left"))
47 else if (!strcmp(halign, "right"))
48 _halign = RIGHT_ALIGN;
50 _halign = CENTER_ALIGN;
52 const char *pre = n->getStringValue("prefix", 0);
53 const char *post = n->getStringValue("postfix", 0);
54 const char *fmt = n->getStringValue("format", 0);
65 _mode = check_format(_format.c_str());
66 if (_mode == INVALID) {
67 SG_LOG(SG_INPUT, SG_ALERT, "HUD: invalid format '" << _format.c_str() << '\'');
76 void HUD::Label::draw(void)
78 if (!(_mode == NONE || _input.isValid() && blink()))
81 Rect scrn_rect = get_location();
84 float x = scrn_rect.left;
85 float y = scrn_rect.top;
86 float w = scrn_rect.right;
87 float h = _hud->_font_size; // FIXME
93 glVertex2f(x - 2.0, y - 2.0);
94 glVertex2f(x + w + 2.0, y - 2.0);
95 glVertex2f(x + w + 2.0, y + h + 2.0);
96 glVertex2f(x - 2.0, y + h + 2.0);
99 glEnable(GL_LINE_STIPPLE);
100 glLineStipple(1, 0xAAAA);
103 glVertex2f(x + w + 2.0, y - 2.0);
104 glVertex2f(x + w + 2.0, y + h + 2.0);
105 glVertex2f(x - 2.0, y + h + 2.0);
106 glVertex2f(x - 2.0, y - 2.0);
109 glDisable(GL_LINE_STIPPLE);
113 const int BUFSIZE = 256;
116 snprintf(buf, BUFSIZE, _format.c_str());
117 else if (_mode == STRING)
118 snprintf(buf, BUFSIZE, _format.c_str(), _input.getStringValue());
119 else if (_mode == INT)
120 snprintf(buf, BUFSIZE, _format.c_str(), int(_input.getFloatValue()));
121 else if (_mode == LONG)
122 snprintf(buf, BUFSIZE, _format.c_str(), long(_input.getFloatValue()));
123 else if (_mode == FLOAT)
124 snprintf(buf, BUFSIZE, _format.c_str(), float(_input.getFloatValue()));
125 else if (_mode == DOUBLE) // not really supported yet
126 snprintf(buf, BUFSIZE, _format.c_str(), double(_input.getFloatValue()));
129 float lenstr = text_width(buf);
131 if (_halign == RIGHT_ALIGN)
132 posincr = scrn_rect.right - lenstr;
133 else if (_halign == CENTER_ALIGN)
134 posincr = get_span() - (lenstr / 2); // FIXME get_span() ? really?
138 if (_fontsize == FONT_SMALL)
139 draw_text(scrn_rect.left + posincr, scrn_rect.top, buf, get_digits());
140 else if (_fontsize == FONT_LARGE)
141 draw_text(scrn_rect.left + posincr, scrn_rect.top, buf, get_digits());
145 // make sure the format matches '[ -+#]?\d*(\.\d*)?(l?[df]|s)'
147 HUD::Label::Format HUD::Label::check_format(const char *f) const
162 if (*f == ' ' || *f == '+' || *f == '-' || *f == '#')
164 while (*f && isdigit(*f))
168 while (*f && isdigit(*f))
175 fmt = l ? LONG : INT;
177 fmt = l ? DOUBLE : FLOAT;
178 else if (*f == 's') {
197 bool HUD::Label::blink()
199 if (_blink_interval < 0.0f)
202 if (_blink_condition && !_blink_condition->test())
205 if (_hud->timer() < _blink_target)
208 _blink_target = _hud->timer() + _blink_interval;
209 return _blink_state = !_blink_state;