- make the alignment function a static HUD member (for namespace
encapsulation, but a real namespace would probably be better) - extend alignment to optionally adjust x/y, and to return absolute l/r/b/t coordinates (as opposed to plib's relative ones!) - implement tape gaps as per Curt's order :-) - shuffling stuff around for fun
This commit is contained in:
parent
6afe252440
commit
4419aa2cb3
6 changed files with 133 additions and 92 deletions
|
@ -448,6 +448,33 @@ void HUD::setColor() const
|
|||
|
||||
|
||||
|
||||
void HUD::textAlign(fntRenderer *rend, const char *s, int align,
|
||||
float *x, float *y, float *l, float *r, float *t, float *b)
|
||||
{
|
||||
fntFont *font = rend->getFont();
|
||||
float gap = font->getGap();
|
||||
float left, right, bot, top;
|
||||
font->getBBox(s, rend->getPointSize(), rend->getSlant(), &left, &right, &bot, &top);
|
||||
|
||||
if (align & HUD::HCENTER)
|
||||
*x = *x - left + gap - (right - left - gap) / 2.0;
|
||||
else if (align & HUD::RIGHT)
|
||||
*x = *x - right;
|
||||
else if (align & HUD::LEFT)
|
||||
*x = *x - left;
|
||||
|
||||
if (align & HUD::VCENTER)
|
||||
*y = *y - bot - (top - bot) / 2.0;
|
||||
else if (align & HUD::TOP)
|
||||
*y = *y - top;
|
||||
else if (align & HUD::BOTTOM)
|
||||
*y = *y - bot;
|
||||
|
||||
*l = *x + left;
|
||||
*r = *x + right;
|
||||
*b = *y + bot;
|
||||
*t = *y + top;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -464,25 +491,8 @@ HUDText::HUDText(fntRenderer *fnt, float x, float y, const char *s, int align, i
|
|||
strncpy(_msg, s, BUFSIZE);
|
||||
if (!align || !s[0])
|
||||
return;
|
||||
|
||||
fntFont *f = _fnt->getFont();
|
||||
float gap = f->getGap();
|
||||
float left, right, bot, top;
|
||||
f->getBBox(s, _fnt->getPointSize(), _fnt->getSlant(), &left, &right, &bot, &top);
|
||||
|
||||
if (align & HCENTER)
|
||||
_x = x - left + gap - (right - left - gap) / 2.0;
|
||||
else if (align & RIGHT)
|
||||
_x = x - right;
|
||||
else if (align & LEFT)
|
||||
_x = x - left;
|
||||
|
||||
if (align & VCENTER)
|
||||
_y = y - bot - (top - bot) / 2.0;
|
||||
else if (align & TOP)
|
||||
_y = y - top;
|
||||
else if (align & BOTTOM)
|
||||
_y = y - bot;
|
||||
float ign;
|
||||
HUD::textAlign(fnt, s, align, &_x, &_y, &ign, &ign, &ign, &ign);
|
||||
}
|
||||
|
||||
|
||||
|
@ -542,3 +552,29 @@ void HUDText::draw()
|
|||
}
|
||||
|
||||
|
||||
void TextList::align(const char *s, int align, float *x, float *y,
|
||||
float *l, float *r, float *b, float *t) const
|
||||
{
|
||||
HUD::textAlign(_font, s, align, x, y, l, r, b, t);
|
||||
}
|
||||
|
||||
|
||||
void TextList::draw()
|
||||
{
|
||||
assert(_font);
|
||||
|
||||
// FIXME
|
||||
glPushAttrib(GL_COLOR_BUFFER_BIT);
|
||||
glEnable(GL_BLEND);
|
||||
|
||||
_font->begin();
|
||||
vector<HUDText>::iterator it, end = _list.end();
|
||||
for (it = _list.begin(); it != end; ++it)
|
||||
it->draw();
|
||||
_font->end();
|
||||
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glPopAttrib();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -53,7 +53,6 @@ class FGViewer;
|
|||
class SGCondition;
|
||||
|
||||
|
||||
|
||||
class LineSegment {
|
||||
public:
|
||||
LineSegment(GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1)
|
||||
|
@ -93,15 +92,6 @@ class HUDText {
|
|||
public:
|
||||
HUDText(fntRenderer *f, float x, float y, const char *s, int align = 0, int digits = 0);
|
||||
void draw();
|
||||
enum {
|
||||
LEFT = 0x0001,
|
||||
RIGHT = 0x0002,
|
||||
TOP = 0x0004,
|
||||
BOTTOM = 0x0008,
|
||||
HCENTER = 0x0010,
|
||||
VCENTER = 0x0020,
|
||||
CENTER = (HCENTER|VCENTER),
|
||||
};
|
||||
|
||||
private:
|
||||
fntRenderer *_fnt;
|
||||
|
@ -122,22 +112,9 @@ public:
|
|||
_list.push_back(HUDText(_font, x, y, s, align, digit));
|
||||
}
|
||||
void erase() { _list.erase(_list.begin(), _list.end()); }
|
||||
void draw() {
|
||||
assert(_font);
|
||||
|
||||
// FIXME
|
||||
glPushAttrib(GL_COLOR_BUFFER_BIT);
|
||||
glEnable(GL_BLEND);
|
||||
|
||||
_font->begin();
|
||||
vector<HUDText>::iterator it, end = _list.end();
|
||||
for (it = _list.begin(); it != end; ++it)
|
||||
it->draw();
|
||||
_font->end();
|
||||
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glPopAttrib();
|
||||
}
|
||||
void align(const char *s, int align, float *x, float *y,
|
||||
float *l, float *r, float *b, float *t) const;
|
||||
void draw();
|
||||
|
||||
private:
|
||||
fntRenderer *_font;
|
||||
|
@ -169,6 +146,8 @@ public:
|
|||
inline bool is3D() const { return _3Denabled; }
|
||||
inline float alphaClamp() const { return _cl; }
|
||||
inline double timer() const { return _timer; }
|
||||
static void textAlign(fntRenderer *r, const char *s, int align, float *x, float *y,
|
||||
float *l, float *r, float *b, float *t);
|
||||
|
||||
enum Units { FEET, METER };
|
||||
Units getUnits() const { return _units; }
|
||||
|
@ -183,6 +162,11 @@ public:
|
|||
NOTICKS = 0x0020,
|
||||
NOTEXT = 0x0040,
|
||||
BOTH = (LEFT|RIGHT),
|
||||
|
||||
// for alignment (with LEFT, RIGHT, TOP, BOTTOM)
|
||||
HCENTER = 0x0080,
|
||||
VCENTER = 0x0100,
|
||||
CENTER = (HCENTER|VCENTER),
|
||||
};
|
||||
|
||||
protected:
|
||||
|
|
|
@ -132,11 +132,11 @@ void HUD::Gauge::draw(void)
|
|||
int(disp_val * _input.factor()/*+.5*/)); /// was data_scaling(), which makes no sense
|
||||
|
||||
if (option_left() && option_right())
|
||||
draw_text(_center_x, marker_ys, buf, HUDText::CENTER);
|
||||
draw_text(_center_x, marker_ys, buf, CENTER);
|
||||
else if (option_left())
|
||||
draw_text(marker_xs, marker_ys, buf, HUDText::RIGHT|HUDText::VCENTER);
|
||||
draw_text(marker_xs, marker_ys, buf, RIGHT|VCENTER);
|
||||
else
|
||||
draw_text(marker_xe, marker_ys, buf, HUDText::LEFT|HUDText::VCENTER);
|
||||
draw_text(marker_xe, marker_ys, buf, LEFT|VCENTER);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -252,16 +252,16 @@ void HUD::Gauge::draw(void)
|
|||
draw_line(marker_xs, marker_ye, marker_xs, top);
|
||||
|
||||
if (!option_notext())
|
||||
draw_text(marker_xs, marker_ys, buf, HUDText::CENTER);
|
||||
draw_text(marker_xs, marker_ys, buf, CENTER);
|
||||
|
||||
} else {
|
||||
draw_line(marker_xs, marker_ys, marker_xs, marker_ye);
|
||||
|
||||
if (!option_notext()) {
|
||||
if (option_top())
|
||||
draw_text(marker_xs, top, buf, HUDText::TOP|HUDText::HCENTER);
|
||||
draw_text(marker_xs, top, buf, TOP|HCENTER);
|
||||
else
|
||||
draw_text(marker_xs, _y, buf, HUDText::BOTTOM|HUDText::HCENTER);
|
||||
draw_text(marker_xs, _y, buf, BOTTOM|HCENTER);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,13 +44,13 @@ HUD::Label::Label(HUD *hud, const SGPropertyNode *n, float x, float y) :
|
|||
|
||||
const char *halign = n->getStringValue("halign", "center");
|
||||
if (!strcmp(halign, "left"))
|
||||
_halign = HUDText::LEFT;
|
||||
_halign = LEFT;
|
||||
else if (!strcmp(halign, "right"))
|
||||
_halign = HUDText::RIGHT;
|
||||
_halign = RIGHT;
|
||||
else
|
||||
_halign = HUDText::HCENTER;
|
||||
_halign = HCENTER;
|
||||
|
||||
_halign |= HUDText::VCENTER;
|
||||
_halign |= VCENTER;
|
||||
|
||||
const char *pre = n->getStringValue("prefix", 0);
|
||||
const char *post = n->getStringValue("postfix", 0);
|
||||
|
@ -155,11 +155,11 @@ void HUD::Label::draw(void)
|
|||
else if (_mode == DOUBLE) // not really supported yet
|
||||
snprintf(buf, BUFSIZE, _format.c_str(), double(_input.getFloatValue()));
|
||||
|
||||
if (_halign & HUDText::HCENTER)
|
||||
if (_halign & HCENTER)
|
||||
draw_text(_center_x, _center_y, buf, _halign, get_digits());
|
||||
else if (_halign & HUDText::LEFT)
|
||||
else if (_halign & LEFT)
|
||||
draw_text(_x, _center_y, buf, _halign, get_digits());
|
||||
else // if (_halign & HUDText::RIGHT)
|
||||
else // if (_halign & RIGHT)
|
||||
draw_text(_x + _w, _center_y, buf, _halign, get_digits());
|
||||
}
|
||||
|
||||
|
|
|
@ -494,8 +494,8 @@ void HUD::Ladder::draw(void)
|
|||
draw_nadir(0.0, y);
|
||||
}
|
||||
|
||||
draw_text(x_ini - 4, y, buf, HUDText::VCENTER|HUDText::LEFT);
|
||||
draw_text(x_end + 4, y, buf, HUDText::VCENTER|HUDText::RIGHT);
|
||||
draw_text(x_ini - 4, y, buf, VCENTER|LEFT);
|
||||
draw_text(x_end + 4, y, buf, VCENTER|RIGHT);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -530,8 +530,8 @@ void HUD::Ladder::draw(void)
|
|||
draw_line(x_ini, y, x_end, y);
|
||||
draw_line(x_ini2, y, x_end2, y);
|
||||
|
||||
draw_text(x_ini - 2.0, y, buf, HUDText::VCENTER|HUDText::RIGHT);
|
||||
draw_text(x_end2 + 2.0, y, buf, HUDText::VCENTER|HUDText::LEFT);
|
||||
draw_text(x_ini - 2.0, y, buf, VCENTER|RIGHT);
|
||||
draw_text(x_end2 + 2.0, y, buf, VCENTER|LEFT);
|
||||
|
||||
} else if (i > 0) {
|
||||
//draw climb bar vertical lines
|
||||
|
@ -542,8 +542,8 @@ void HUD::Ladder::draw(void)
|
|||
draw_line(x_ini, y, x_end, y);
|
||||
draw_line(x_ini2, y, x_end2, y);
|
||||
|
||||
draw_text(x_ini + 0.5, y - 0.5, buf, HUDText::TOP|HUDText::LEFT);
|
||||
draw_text(x_end2 - 0.5, y - 0.5, buf, HUDText::TOP|HUDText::RIGHT);
|
||||
draw_text(x_ini + 0.5, y - 0.5, buf, TOP|LEFT);
|
||||
draw_text(x_end2 - 0.5, y - 0.5, buf, TOP|RIGHT);
|
||||
|
||||
if (i == 90 && _zenith)
|
||||
draw_zenith(0.0, y);
|
||||
|
@ -565,9 +565,9 @@ void HUD::Ladder::draw(void)
|
|||
draw_stipple_line(x_ini2, y, x_end2, y_end);
|
||||
|
||||
float yoffs = 1.0 + (y - y_end) / 4.0; // too hackish?
|
||||
draw_text(x_ini + 3.0, y_end + yoffs, buf, HUDText::BOTTOM|HUDText::HCENTER);
|
||||
draw_text(x_ini + 3.0, y_end + yoffs, buf, BOTTOM|HCENTER);
|
||||
// right number shifted in a little more, because of the minus
|
||||
draw_text(x_end2 - 4.0, y_end + yoffs, buf, HUDText::BOTTOM|HUDText::HCENTER);
|
||||
draw_text(x_end2 - 4.0, y_end + yoffs, buf, BOTTOM|HCENTER);
|
||||
|
||||
if (i == -90 && _nadir)
|
||||
draw_nadir(0.0, y);
|
||||
|
|
|
@ -33,7 +33,7 @@ HUD::Tape::Tape(HUD *hud, const SGPropertyNode *n, float x, float y) :
|
|||
_draw_cap_right(n->getBoolValue("cap-right", false)),
|
||||
_draw_cap_left(n->getBoolValue("cap-left", false)),
|
||||
_marker_offset(n->getFloatValue("marker-offset", 0.0)),
|
||||
_label_gap(n->getFloatValue("label-gap-width", 0.0)),
|
||||
_label_gap(n->getFloatValue("label-gap-width", 0.0) / 2.0),
|
||||
_pointer(n->getBoolValue("enable-pointer", true)),
|
||||
_zoom(n->getIntValue("zoom"))
|
||||
{
|
||||
|
@ -261,9 +261,9 @@ void HUD::Tape::draw(void) // (HUD_scale * pscale)
|
|||
|
||||
float y = _y + (v - vmin) * factor();
|
||||
|
||||
if (y < _y + 4)
|
||||
if (y < _y + 0)
|
||||
continue;
|
||||
if (y > top - 4)
|
||||
if (y > top - 0)
|
||||
break;
|
||||
|
||||
if (div_ratio && i % div_ratio) { // minor div
|
||||
|
@ -312,6 +312,9 @@ void HUD::Tape::draw(void) // (HUD_scale * pscale)
|
|||
|
||||
snprintf(buf, BUFSIZE, "%d", display_value);
|
||||
|
||||
float x;
|
||||
int align;
|
||||
|
||||
if (option_both()) {
|
||||
if (_tick_type == LINE) {
|
||||
draw_line(_x, y, marker_xs, y);
|
||||
|
@ -321,8 +324,7 @@ void HUD::Tape::draw(void) // (HUD_scale * pscale)
|
|||
draw_bullet(_x, y, 5.0);
|
||||
}
|
||||
|
||||
if (!option_notext())
|
||||
draw_text(marker_xs, y, buf, HUDText::CENTER);
|
||||
x = marker_xs, align = CENTER;
|
||||
|
||||
} else {
|
||||
if (_tick_type == LINE)
|
||||
|
@ -330,13 +332,24 @@ void HUD::Tape::draw(void) // (HUD_scale * pscale)
|
|||
else // _tick_type == CIRCLE
|
||||
draw_bullet(marker_xs + 4, y, 5.0);
|
||||
|
||||
if (!option_notext()) {
|
||||
if (option_left())
|
||||
draw_text(marker_xs, y, buf, HUDText::RIGHT|HUDText::VCENTER);
|
||||
else
|
||||
draw_text(marker_xe + 1.0, y, buf, HUDText::LEFT|HUDText::VCENTER);
|
||||
}
|
||||
} // End if huds-both
|
||||
if (option_left())
|
||||
x = marker_xs, align = RIGHT|VCENTER;
|
||||
else
|
||||
x = marker_xe, align = LEFT|VCENTER;
|
||||
}
|
||||
|
||||
if (!option_notext()) {
|
||||
float l, r, b, t;
|
||||
_hud->_text_list.align(buf, align, &x, &y, &l, &r, &b, &t);
|
||||
if (b < _y || t > top)
|
||||
continue;
|
||||
if (_label_gap == 0.0)
|
||||
draw_text(x, y, buf);
|
||||
else if (b < _center_x - _label_gap && t < _center_x - _label_gap)
|
||||
draw_text(x, y, buf);
|
||||
else if (b > _center_x + _label_gap && t > _center_x + _label_gap)
|
||||
draw_text(x, y, buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // end of zoom
|
||||
|
@ -452,9 +465,9 @@ void HUD::Tape::draw(void) // (HUD_scale * pscale)
|
|||
|
||||
float x = _x + (v - vmin) * factor();
|
||||
|
||||
if (x < _x + 4)
|
||||
if (x < _x + 0)
|
||||
continue;
|
||||
if (x > right - 4)
|
||||
if (x > right - 0)
|
||||
break;
|
||||
|
||||
if (div_ratio && i % div_ratio) { // minor div
|
||||
|
@ -489,26 +502,34 @@ void HUD::Tape::draw(void) // (HUD_scale * pscale)
|
|||
|
||||
snprintf(buf, BUFSIZE, "%d", display_value);
|
||||
|
||||
// Draw major ticks and text only if far enough from the edge. // FIXME
|
||||
if (x < _x + 10 || x + 10 > _x + _w)
|
||||
continue;
|
||||
float y;
|
||||
int align;
|
||||
|
||||
if (option_both()) {
|
||||
draw_line(x, _y, x, marker_ye);
|
||||
draw_line(x, marker_ye, x, _y + _h);
|
||||
|
||||
if (!option_notext())
|
||||
draw_text(x, marker_ys, buf, HUDText::CENTER);
|
||||
y = marker_ys, align = CENTER;
|
||||
|
||||
} else {
|
||||
draw_line(x, marker_ys, x, marker_ye);
|
||||
|
||||
if (!option_notext()) {
|
||||
if (option_top())
|
||||
draw_text(x, top, buf, HUDText::TOP|HUDText::HCENTER);
|
||||
else
|
||||
draw_text(x, _y, buf, HUDText::BOTTOM|HUDText::HCENTER);
|
||||
}
|
||||
if (option_top())
|
||||
y = top, align = TOP|HCENTER;
|
||||
else
|
||||
y = _y, align = BOTTOM|HCENTER;
|
||||
}
|
||||
|
||||
if (!option_notext()) {
|
||||
float l, r, b, t;
|
||||
_hud->_text_list.align(buf, align, &x, &y, &l, &r, &b, &t);
|
||||
if (l < _x || r > right)
|
||||
continue;
|
||||
if (_label_gap == 0.0)
|
||||
draw_text(x, y, buf);
|
||||
else if (l < _center_x - _label_gap && r < _center_x - _label_gap)
|
||||
draw_text(x, y, buf);
|
||||
else if (l > _center_x + _label_gap && r > _center_x + _label_gap)
|
||||
draw_text(x, y, buf);
|
||||
}
|
||||
}
|
||||
} // end for
|
||||
|
|
Loading…
Add table
Reference in a new issue