# include <config.h>
#endif
-#include <simgear/props/condition.hxx>
#include "HUD.hxx"
HUD::Label::Label(HUD *hud, const SGPropertyNode *n, float x, float y) :
Item(hud, n, x, y),
_input(n->getNode("input", false)),
- _fontsize(fgGetInt("/sim/startup/xsize") > 1000 ? FONT_LARGE : FONT_SMALL), // FIXME
_box(n->getBoolValue("box", false)),
+ _pointer_width(n->getFloatValue("pointer-width", 7.0)),
+ _pointer_length(n->getFloatValue("pointer-length", 5.0)),
_blink_condition(0),
_blink_interval(n->getFloatValue("blinking/interval", -1.0f)),
_blink_target(0.0),
const char *halign = n->getStringValue("halign", "center");
if (!strcmp(halign, "left"))
- _halign = LEFT_ALIGN;
+ _halign = LEFT;
else if (!strcmp(halign, "right"))
- _halign = RIGHT_ALIGN;
+ _halign = RIGHT;
else
- _halign = CENTER_ALIGN;
+ _halign = HCENTER;
+
+ _halign |= VCENTER;
const char *pre = n->getStringValue("prefix", 0);
const char *post = n->getStringValue("postfix", 0);
if (pre)
_format = pre;
+
if (fmt)
_format += fmt;
else
_format += "%s";
+
if (post)
_format += post;
_mode = check_format(_format.c_str());
if (_mode == INVALID) {
- SG_LOG(SG_INPUT, SG_ALERT, "HUD: invalid format '" << _format.c_str() << '\'');
+ SG_LOG(SG_INPUT, SG_ALERT, "HUD: invalid format '" << _format.c_str()
+ << "' in <label> '" << _name << '\'');
_format = "INVALID";
_mode = NONE;
}
void HUD::Label::draw(void)
{
- if (!(_mode == NONE || _input.isValid() && blink()))
+ if (!((_mode == NONE || _input.isValid()) && blink()))
return;
if (_box) {
- float h = _hud->_font_size; // FIXME
-
- glPushMatrix();
- glLoadIdentity();
-
- glBegin(GL_LINES);
- glVertex2f(_x - 2.0, _y - 2.0);
- glVertex2f(_x + _w + 2.0, _y - 2.0);
- glVertex2f(_x + _w + 2.0, _y + h + 2.0);
- glVertex2f(_x - 2.0, _y + h + 2.0);
- glEnd();
-
- glEnable(GL_LINE_STIPPLE);
- glLineStipple(1, 0xAAAA);
-
- glBegin(GL_LINES);
- glVertex2f(_x + _w + 2.0, _y - 2.0);
- glVertex2f(_x + _w + 2.0, _y + h + 2.0);
- glVertex2f(_x - 2.0, _y + h + 2.0);
- glVertex2f(_x - 2.0, _y - 2.0);
- glEnd();
-
- glDisable(GL_LINE_STIPPLE);
- glPopMatrix();
+ float l, r, p;
+ float pw = _pointer_width / 2.0;
+
+ l = _center_x - pw;
+ r = _center_x + pw;
+ bool draw_parallel = fabs(_pointer_width - _w) > 2.0; // draw lines left and right of arrow?
+
+ if (option_bottom()) {
+ if (draw_parallel) {
+ draw_line(_x, _y, l, _y);
+ draw_line(r, _y, _x + _w, _y);
+ }
+ p = _y - _pointer_length;
+ draw_line(l, _y, _center_x, p);
+ draw_line(_center_x, p, r, _y);
+ } else
+ draw_line(_x, _y, _x + _w, _y);
+
+ if (option_top()) {
+ if (draw_parallel) {
+ draw_line(_x, _y + _h, l, _y + _h);
+ draw_line(r, _y + _h, _x + _w, _y + _h);
+ }
+ p = _y + _h + _pointer_length;
+ draw_line(l, _y + _h, _center_x, p);
+ draw_line(_center_x, p, r, _y + _h);
+ } else
+ draw_line(_x + _w, _y + _h, _x, _y + _h);
+
+ l = _center_y - pw;
+ r = _center_y + pw;
+ draw_parallel = fabs(_pointer_width - _h) > 2.0;
+
+ if (option_left()) {
+ if (draw_parallel) {
+ draw_line(_x, _y, _x, l);
+ draw_line(_x, r, _x, _y + _h);
+ }
+ p = _x - _pointer_length;
+ draw_line(_x, l, p, _center_y);
+ draw_line(p, _center_y, _x, r);
+ } else
+ draw_line(_x, _y + _h, _x, _y);
+
+ if (option_right()) {
+ if (draw_parallel) {
+ draw_line(_x + _w, _y, _x + _w, l);
+ draw_line(_x + _w, r, _x + _w, _y + _h);
+ }
+ p = _x + _w + _pointer_length;
+ draw_line(_x + _w, l, p, _center_y);
+ draw_line(p, _center_y, _x + _w, r);
+ } else
+ draw_line(_x + _w, _y, _x + _w, _y + _h);
}
const int BUFSIZE = 256;
- char buf[BUFSIZE];
+ char buf[BUFSIZE+1];
+ buf[ BUFSIZE] = '\0'; // Be sure to terminate properly
if (_mode == NONE)
- snprintf(buf, BUFSIZE, _format.c_str());
+ snprintf(buf, BUFSIZE, _format.c_str(), 0);
else if (_mode == STRING)
snprintf(buf, BUFSIZE, _format.c_str(), _input.getStringValue());
else if (_mode == INT)
else if (_mode == DOUBLE) // not really supported yet
snprintf(buf, BUFSIZE, _format.c_str(), double(_input.getFloatValue()));
- float posincr;
- float lenstr = text_width(buf);
-
- if (_halign == RIGHT_ALIGN)
- posincr = _w - lenstr;
- else if (_halign == CENTER_ALIGN)
- posincr = (_w - lenstr) / 2.0;
- else // LEFT_ALIGN
- posincr = 0;
-
- if (_fontsize == FONT_SMALL)
- draw_text(_x + posincr, _y, buf, get_digits());
- else if (_fontsize == FONT_LARGE)
- draw_text(_x + posincr, _y, buf, get_digits());
-}
-
-
-// make sure the format matches '[ -+#]?\d*(\.\d*)?(l?[df]|s)'
-//
-HUD::Label::Format HUD::Label::check_format(const char *f) const
-{
- bool l = false;
- Format fmt = STRING;
-
- for (; *f; f++) {
- if (*f == '%') {
- if (f[1] == '%')
- f++;
- else
- break;
- }
- }
- if (*f++ != '%')
- return NONE;
- if (*f == ' ' || *f == '+' || *f == '-' || *f == '#')
- f++;
- while (*f && isdigit(*f))
- f++;
- if (*f == '.') {
- f++;
- while (*f && isdigit(*f))
- f++;
- }
- if (*f == 'l')
- l = true, f++;
-
- if (*f == 'd')
- fmt = l ? LONG : INT;
- else if (*f == 'f')
- fmt = l ? DOUBLE : FLOAT;
- else if (*f == 's') {
- if (l)
- return INVALID;
- fmt = STRING;
- } else
- return INVALID;
-
- for (++f; *f; f++) {
- if (*f == '%') {
- if (f[1] == '%')
- f++;
- else
- return INVALID;
- }
- }
- return fmt;
+ if (_halign & HCENTER)
+ draw_text(_center_x, _center_y, buf, _halign, get_digits());
+ else if (_halign & LEFT)
+ draw_text(_x, _center_y, buf, _halign, get_digits());
+ else // if (_halign & RIGHT)
+ draw_text(_x + _w, _center_y, buf, _halign, get_digits());
}