290 lines
7.1 KiB
C++
290 lines
7.1 KiB
C++
// Filename: guiLabel.cxx
|
|
// Created by: cary (26Oct00)
|
|
//
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
#include "guiLabel.h"
|
|
|
|
#include <textNode.h>
|
|
#include <transformTransition.h>
|
|
#include <colorTransition.h>
|
|
|
|
TypeHandle GuiLabel::_type_handle;
|
|
|
|
void GuiLabel::recompute_transform(void) {
|
|
switch (_type) {
|
|
case SIMPLE_TEXT:
|
|
{
|
|
LMatrix4f mat = LMatrix4f::scale_mat(_scale) *
|
|
LMatrix4f::translate_mat(_pos);
|
|
TextNode* n = DCAST(TextNode, _geom);
|
|
n->set_transform(mat);
|
|
}
|
|
break;
|
|
case SIMPLE_TEXTURE:
|
|
{
|
|
LMatrix4f mat = LMatrix4f::scale_mat(_scale) *
|
|
LMatrix4f::translate_mat(_pos);
|
|
_internal->set_transition(new TransformTransition(mat));
|
|
}
|
|
break;
|
|
default:
|
|
gui_cat->warning() << "recompute_transform on invalid label type ("
|
|
<< (int)_type << ")" << endl;
|
|
}
|
|
set_properties();
|
|
}
|
|
|
|
void GuiLabel::set_properties(void) {
|
|
switch (_type) {
|
|
case SIMPLE_TEXT:
|
|
{
|
|
TextNode* n = DCAST(TextNode, _geom);
|
|
n->set_text_color(_foreground);
|
|
n->clear_card();
|
|
if ((_have_background) || (_tex == (Texture*)0L)) {
|
|
if (_have_background)
|
|
n->set_card_color(_background);
|
|
if (_tex != (Texture*)0L)
|
|
n->set_card_texture(_tex);
|
|
if (_have_width || _have_height) {
|
|
n->set_card_as_margin(simple_text_margin_left,
|
|
simple_text_margin_right,
|
|
simple_text_margin_bottom,
|
|
simple_text_margin_top);
|
|
LVecBase4f v = n->get_card_actual();
|
|
float w = v[1] - v[0];
|
|
float h = v[3] - v[2];
|
|
if (_have_width) {
|
|
w = _width - w;
|
|
w *= 0.5;
|
|
v[1] += w;
|
|
v[0] -= w;
|
|
} else {
|
|
v[0] -= simple_text_margin_left;
|
|
v[1] += simple_text_margin_right;
|
|
}
|
|
if (_have_height) {
|
|
h = _height - h;
|
|
h *= 0.5;
|
|
v[3] += h;
|
|
v[2] -= h;
|
|
} else {
|
|
v[2] -= simple_text_margin_bottom;
|
|
v[3] += simple_text_margin_top;
|
|
}
|
|
n->set_card_actual(v[0], v[1], v[2], v[3]);
|
|
} else
|
|
n->set_card_as_margin(simple_text_margin_left,
|
|
simple_text_margin_right,
|
|
simple_text_margin_bottom,
|
|
simple_text_margin_top);
|
|
}
|
|
}
|
|
break;
|
|
case SIMPLE_TEXTURE:
|
|
_internal->set_transition(new ColorTransition(_foreground));
|
|
break;
|
|
default:
|
|
gui_cat->warning() << "recompute_transform on invalid label type ("
|
|
<< (int)_type << ")" << endl;
|
|
}
|
|
}
|
|
|
|
GuiLabel::~GuiLabel(void) {
|
|
if (gui_cat->is_debug())
|
|
gui_cat->debug() << "deleting label (0x" << (void*)this << ")" << endl;
|
|
}
|
|
|
|
#include <textureTransition.h>
|
|
#include <geomTristrip.h>
|
|
|
|
GuiLabel* GuiLabel::make_simple_texture_label(Texture* texture) {
|
|
GuiLabel* ret = new GuiLabel();
|
|
ret->_type = SIMPLE_TEXTURE;
|
|
ret->_tex = texture;
|
|
ret->_geom = new NamedNode("GUI label");
|
|
GeomNode* n2 = new GeomNode();
|
|
ret->_internal = new RenderRelation(ret->_geom, n2);
|
|
ret->_internal->set_transition(new TextureTransition(texture));
|
|
GeomTristrip *geoset = new GeomTristrip;
|
|
PTA_int lengths(0);
|
|
lengths.push_back(4);
|
|
PTA_Vertexf verts;
|
|
float l, r, b, t;
|
|
{
|
|
// compute {l, r, b, t}
|
|
int xs = texture->_pbuffer->get_xsize();
|
|
int ys = texture->_pbuffer->get_ysize();
|
|
float ratio;
|
|
|
|
if (xs > ys) {
|
|
// horizontally dominant
|
|
ratio = ((float)ys) / ((float)xs);
|
|
ratio *= 0.5;
|
|
l = -0.5;
|
|
r = 0.5;
|
|
b = -ratio;
|
|
t = ratio;
|
|
} else {
|
|
// vertically dominant
|
|
ratio = ((float)xs) / ((float)ys);
|
|
ratio *= 0.5;
|
|
l = -ratio;
|
|
r = ratio;
|
|
b = -0.5;
|
|
t = 0.5;
|
|
}
|
|
}
|
|
verts.push_back(Vertexf::rfu(l, 0., t));
|
|
verts.push_back(Vertexf::rfu(l, 0., b));
|
|
verts.push_back(Vertexf::rfu(r, 0., t));
|
|
verts.push_back(Vertexf::rfu(r, 0., b));
|
|
geoset->set_num_prims(1);
|
|
geoset->set_lengths(lengths);
|
|
geoset->set_coords(verts, G_PER_VERTEX);
|
|
PTA_TexCoordf uvs;
|
|
uvs.push_back(TexCoordf(0., 1.));
|
|
uvs.push_back(TexCoordf(0., 0.));
|
|
uvs.push_back(TexCoordf(1., 1.));
|
|
uvs.push_back(TexCoordf(1., 0.));
|
|
geoset->set_texcoords(uvs, G_PER_VERTEX);
|
|
n2->add_geom(geoset);
|
|
return ret;
|
|
}
|
|
|
|
GuiLabel* GuiLabel::make_simple_text_label(const string& text, Node* font,
|
|
Texture* tex) {
|
|
GuiLabel* ret = new GuiLabel();
|
|
ret->_type = SIMPLE_TEXT;
|
|
TextNode* n = new TextNode("GUI label");
|
|
ret->_geom = n;
|
|
ret->_tex = tex;
|
|
n->set_font(font);
|
|
n->set_align(TM_ALIGN_CENTER);
|
|
n->set_text_color(ret->get_foreground_color());
|
|
n->set_text(text);
|
|
if (tex != (Texture*)0L)
|
|
n->set_card_texture(tex);
|
|
ret->set_scale(1.);
|
|
ret->set_pos(LVector3f(0., 0., 0.));
|
|
ret->recompute_transform();
|
|
return ret;
|
|
}
|
|
|
|
void GuiLabel::get_extents(float& l, float& r, float& b, float& t) {
|
|
switch (_type) {
|
|
case SIMPLE_TEXT:
|
|
{
|
|
TextNode* n = DCAST(TextNode, _geom);
|
|
if (n->has_card()) {
|
|
LVecBase4f v = n->get_card_transformed();
|
|
l = v[0];
|
|
r = v[1];
|
|
b = v[2];
|
|
t = v[3];
|
|
} else {
|
|
LVector3f ul = n->get_upper_left_3d() - LPoint3f::origin();
|
|
LVector3f lr = n->get_lower_right_3d() - LPoint3f::origin();
|
|
LVector3f up = LVector3f::up();
|
|
LVector3f right = LVector3f::right();
|
|
l = ul.dot(right);
|
|
r = lr.dot(right);
|
|
b = lr.dot(up);
|
|
t = ul.dot(up);
|
|
}
|
|
}
|
|
break;
|
|
case SIMPLE_TEXTURE:
|
|
{
|
|
float xs = _tex->_pbuffer->get_xsize();
|
|
float ys = _tex->_pbuffer->get_ysize();
|
|
float ratio;
|
|
LVector3f ul, lr;
|
|
|
|
if (xs > ys) {
|
|
// horizontally dominant
|
|
ratio = ((float)ys) / ((float)xs);
|
|
ratio *= 0.5;
|
|
ul = LVector3f::rfu(-0.5, 0., ratio);
|
|
lr = LVector3f::rfu(0.5, 0., -ratio);
|
|
} else {
|
|
// vertically dominant
|
|
ratio = ((float)xs) / ((float)ys);
|
|
ratio *= 0.5;
|
|
ul = LVector3f::rfu(-ratio, 0., 0.5);
|
|
lr = LVector3f::rfu(ratio, 0., -0.5);
|
|
}
|
|
LMatrix4f mat = LMatrix4f::scale_mat(_scale) *
|
|
LMatrix4f::translate_mat(_pos);
|
|
ul = mat * ul;
|
|
lr = mat * lr;
|
|
l = ul.dot(ul.right());
|
|
r = lr.dot(lr.right());
|
|
b = lr.dot(lr.up());
|
|
t = ul.dot(ul.up());
|
|
}
|
|
break;
|
|
default:
|
|
gui_cat->warning()
|
|
<< "trying to get extents from something I don't know how to" << endl;
|
|
l = b = 0.;
|
|
r = t = 1.;
|
|
}
|
|
}
|
|
|
|
float GuiLabel::get_width(void) {
|
|
float w;
|
|
TextNode* n = DCAST(TextNode, _geom);
|
|
if (n->has_card()) {
|
|
LVecBase4f v = n->get_card_actual();
|
|
w = v[1] - v[0];
|
|
} else {
|
|
w = n->get_width();
|
|
}
|
|
return w;
|
|
}
|
|
|
|
float GuiLabel::get_height(void) {
|
|
float h;
|
|
TextNode* n = DCAST(TextNode, _geom);
|
|
if (n->has_card()) {
|
|
LVecBase4f v = n->get_card_actual();
|
|
h = v[3] - v[2];
|
|
} else {
|
|
h = n->get_width();
|
|
}
|
|
return h;
|
|
}
|
|
|
|
void GuiLabel::set_foreground_color(const Colorf& color) {
|
|
_foreground = color;
|
|
set_properties();
|
|
}
|
|
|
|
void GuiLabel::set_background_color(const Colorf& color) {
|
|
static Colorf zero(0., 0., 0., 0.);
|
|
|
|
_background = color;
|
|
_have_background = (color != zero);
|
|
set_properties();
|
|
}
|
|
|
|
void GuiLabel::set_text(const string& val) {
|
|
switch (_type) {
|
|
case SIMPLE_TEXT:
|
|
{
|
|
TextNode* n = DCAST(TextNode, _geom);
|
|
n->set_text(val);
|
|
}
|
|
break;
|
|
case SIMPLE_TEXTURE:
|
|
gui_cat->warning() << "tried to set text on a texture label" << endl;
|
|
break;
|
|
default:
|
|
gui_cat->warning() << "trying to set text on an unknown label type ("
|
|
<< (int)_type << ")" << endl;
|
|
}
|
|
recompute();
|
|
}
|