OpenSceneGraph/src/osgWidget/StyleManager.cpp

413 lines
9.0 KiB
C++

// -*-c++-*- osgWidget - Code by: Jeremy Moles (cubicool) 2007-2008
#include <sstream>
#include <osg/io_utils>
#include <osgWidget/StyleManager>
namespace osgWidget {
Style::Style(const std::string& name, const std::string& style):
_style(style) {
setName(name);
}
Style::Style(const Style& style, const osg::CopyOp& co):
osg::Object (style, co),
_style (style._style) {
}
bool Style::applyStyle(Widget* widget, Reader r) {
std::string str;
osg::Vec2 vec2;
osg::Vec3 vec3;
osg::Vec4 vec4;
float f;
if(_match("pos %i %i", r) || _match("pos %f %f", r)) {
r.readSequence(vec2);
widget->setOrigin(vec2);
}
else if(_match("pos-x %i", r) || _match("pos-x %f", r)) {
r.readSequence(f);
widget->setX(f);
}
else if(_match("pos-y %i", r) || _match("pos-y %f", r)) {
r.readSequence(f);
widget->setY(f);
}
else if(_match("size %i %i", r) || _match("size %f %f", r)) {
r.readSequence(vec2);
widget->setSize(vec2);
}
else if(_match("width %i", r) || _match("width %f", r)) {
r.readSequence(f);
widget->setWidth(f);
}
else if(_match("height %i", r) || _match("height %f", r)) {
r.readSequence(f);
widget->setHeight(f);
}
// Color using 4x 0-255 integers.
else if(_match("color %i %i %i %i", r)) {
r.readSequence(vec4);
widget->setColor(vec4 / 255.0f);
}
// Color using 3x 0-255 integers with a default alpha of 255.
else if(_match("color %i %i %i", r)) {
r.readSequence(vec3);
widget->setColor(osg::Vec4(vec3[0], vec3[1], vec3[2], 255.0f) / 255.0f);
}
// Color using 4x 0.0f-1.0f floats.
else if(_match("color %f %f %f %f", r)) {
r.readSequence(vec4);
widget->setColor(vec4);
}
// Color using 3x 0.0f-1.0f floats with a default alpha of 1.0f.
else if(_match("color %f %f %f", r)) {
r.readSequence(vec3);
widget->setColor(osg::Vec4(vec3[0], vec3[1], vec3[2], 1.0f));
}
// Set padding uniformly.
else if(_match("padding %i", r)) {
r.readSequence(f);
widget->setPadding(f);
}
// Set left padding.
else if(_match("padding-left %i", r)) {
r.readSequence(f);
widget->setPadLeft(f);
}
// Set right padding.
else if(_match("padding-right %i", r)) {
r.readSequence(f);
widget->setPadRight(f);
}
// Set top padding.
else if(_match("padding-top %i", r)) {
r.readSequence(f);
widget->setPadTop(f);
}
// Set bottom padding.
else if(_match("padding-bottom %i", r)) {
r.readSequence(f);
widget->setPadBottom(f);
}
else if(_match("layer %w", r)) {
r.readSequence(str);
widget->setLayer(strToLayer(str));
}
else if(_match("valign %w", r)) {
r.readSequence(str);
widget->setAlignVertical(strToVAlign(str));
}
else if(_match("halign %w", r)) {
r.readSequence(str);
widget->setAlignHorizontal(strToHAlign(str));
}
else if(_match("coordmode %w", r)) {
r.readSequence(str);
widget->setCoordinateMode(strToCoordMode(str));
}
else if(_match("fill %w", r)) {
r.readSequence(str);
widget->setCanFill(strToFill(str));
}
else if(_match("image %s", r)) {
r.readSequence(str);
widget->setImage(str, true);
}
// Otherwise, increment the stream pointer.
else return false;
return true;
}
bool Style::applyStyle(Label* /*label*/, Reader /*r*/) {
return false;
}
bool Style::applyStyle(Input* /*input*/, Reader /*r*/) {
return false;
}
bool Style::applyStyle(Window* window, Reader r) {
osg::Vec2 vec2;
float f;
if(_match("pos %i %i", r) || _match("pos %f %f", r)) {
r.readSequence(vec2);
window->setOrigin(vec2.x(), vec2.y());
}
else if(_match("pos-x %i", r) || _match("pos-x %f", r)) {
r.readSequence(f);
window->setX(f);
}
else if(_match("pos-y %i", r) || _match("pos-y %f", r)) {
r.readSequence(f);
window->setY(f);
}
else if(_match("size %i %i", r) || _match("size %f %f", r)) {
r.readSequence(vec2);
window->resize(vec2.x(), vec2.y());
}
else if(_match("width %i", r) || _match("width %f", r)) {
r.readSequence(f);
window->resize(f);
}
else if(_match("height %i", r) || _match("height %f", r)) {
r.readSequence(f);
window->resize(0.0f, f);
}
else return false;
return true;
}
bool Style::applyStyle(Canvas* /*label*/, Reader /*r*/) {
return false;
}
bool Style::applyStyle(Window::EmbeddedWindow*, Reader /*r*/) {
return false;
}
bool Style::applyStyle(Box* box, Reader r) {
if(applyStyle(static_cast<Window*>(box), r)) return true;
return false;
}
bool Style::applyStyle(Frame::Corner*, Reader /*r*/) {
return false;
}
bool Style::applyStyle(Frame::Border*, Reader /*r*/) {
return false;
}
Widget::Layer Style::strToLayer(const std::string& layer)
{
std::string l = lowerCase(layer);
if(l == "top") return Widget::LAYER_TOP;
else if(l == "high") return Widget::LAYER_HIGH;
else if(l == "middle") return Widget::LAYER_MIDDLE;
else if(l == "low") return Widget::LAYER_LOW;
else if(l == "bg") return Widget::LAYER_BG;
else {
warn() << "Unkown Layer name [" << layer << "]; using LAYER_MIDDLE." << std::endl;
return Widget::LAYER_MIDDLE;
}
}
Widget::VerticalAlignment Style::strToVAlign(const std::string& valign) {
std::string va = lowerCase(valign);
if(va == "center") return Widget::VA_CENTER;
else if(va == "top") return Widget::VA_TOP;
else if(va == "bottom") return Widget::VA_BOTTOM;
else {
warn() << "Unkown VAlign name [" << valign << "]; using VA_CENTER." << std::endl;
return Widget::VA_CENTER;
}
}
Widget::HorizontalAlignment Style::strToHAlign(const std::string& halign) {
std::string ha = lowerCase(halign);
if(ha == "center") return Widget::HA_CENTER;
else if(ha == "left") return Widget::HA_LEFT;
else if(ha == "right") return Widget::HA_RIGHT;
else {
warn() << "Unkown HAlign name [" << halign << "]; using HA_CENTER." << std::endl;
return Widget::HA_CENTER;
}
}
Widget::CoordinateMode Style::strToCoordMode(const std::string& coordmode) {
std::string cm = lowerCase(coordmode);
if(cm == "absolute") return Widget::CM_ABSOLUTE;
else if(cm == "relative") return Widget::CM_RELATIVE;
else {
warn()
<< "Unkown CoordMode name [" << coordmode
<< "]; using CM_ABSOLUTE." << std::endl
;
return Widget::CM_ABSOLUTE;
}
}
bool Style::strToFill(const std::string& fill) {
std::string cm = lowerCase(fill);
if(cm == "true") return true;
else if(cm == "false") return false;
else {
warn()
<< "Unkown Fill name [" << fill
<< "]; using false." << std::endl
;
return false;
}
}
StyleManager::StyleManager() {
}
StyleManager::StyleManager(const StyleManager& manager, const osg::CopyOp& co):
osg::Object(manager, co) {
for(ConstIterator i = _styles.begin(); i != _styles.end(); i++) if(i->second.valid()) {
_styles[i->first] = new Style(*i->second.get(), osg::CopyOp::DEEP_COPY_ALL);
}
}
bool StyleManager::_applyStyleToObject(osg::Object* obj, const std::string& style) {
std::string c = obj->className();
if(!std::string("Widget").compare(c)) return _coerceAndApply<Widget>(
obj,
style,
c
);
else if(!std::string("Label").compare(c)) return _coerceAndApply<Label>(
obj,
style,
c
);
else if(!std::string("Box").compare(c)) return _coerceAndApply<Box>(
obj,
style,
c
);
else if(!std::string("Canvas").compare(c)) return _coerceAndApply<Canvas>(
obj,
style,
c
);
else if(!std::string("Window").compare(c)) return _coerceAndApply<Window>(
obj,
style,
c
);
else if(!std::string("Input").compare(c)) return _coerceAndApply<Input>(
obj,
style,
c
);
else if(!std::string("Corner").compare(c)) return _coerceAndApply<Frame::Corner>(
obj,
style,
c
);
else if(!std::string("Border").compare(c)) return _coerceAndApply<Frame::Border>(
obj,
style,
c
);
else if(!std::string("EmbeddedWindow").compare(c)) return _coerceAndApply<Window::EmbeddedWindow>(
obj,
style,
c
);
else warn()
<< "StyleManager does not support coercion of objects of type "
<< c << "." << std::endl
;
return false;
}
bool StyleManager::addStyle(Style* style) {
if(!style || style->getName().empty()) {
warn() << "Cannot add a NULL or nameless Style object." << std::endl;
return false;
}
_styles[style->getName()] = style;
return true;
}
}