X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=otk%2Flabel.cc;h=c56f91f8022aebfbc7920e48d76b3c3a440f187a;hb=ee9eaed6cd48db249711912133758679a029b5b1;hp=fa12a0fa2f2fdb8226161f2bb0fb12ba9503041f;hpb=ee896d9d664b6076635da98dced82b8b3258cebe;p=chaz%2Fopenbox diff --git a/otk/label.cc b/otk/label.cc index fa12a0fa..c56f91f8 100644 --- a/otk/label.cc +++ b/otk/label.cc @@ -5,72 +5,151 @@ #endif #include "label.hh" +#include "display.hh" +#include "rendercontrol.hh" + +#include namespace otk { -OtkLabel::OtkLabel(OtkWidget *parent) - : OtkWidget(parent), _text("") +Label::Label(Widget *parent) + : Widget(parent), + _text(""), + _justify_horz(RenderStyle::LeftTopJustify), + _justify_vert(RenderStyle::LeftTopJustify), + _highlight(true) { - const ScreenInfo *info = OBDisplay::screenInfo(getScreen()); - _xftdraw = XftDrawCreate(OBDisplay::display, getWindow(), info->getVisual(), - info->getColormap()); - - setStyle(getStyle()); + styleChanged(*RenderStyle::style(screen())); +} + +Label::~Label() +{ +} + +void Label::setHorizontalJustify(RenderStyle::Justify j) +{ + _justify_horz = j; + refresh(); +} + +void Label::setVerticalJustify(RenderStyle::Justify j) +{ + _justify_vert = j; + refresh(); } -OtkLabel::~OtkLabel() +void Label::setHighlighted(bool h) { - XftDrawDestroy(_xftdraw); + _highlight = h; + styleChanged(*RenderStyle::style(screen())); + refresh(); } -void OtkLabel::setStyle(Style *style) +void Label::setText(const ustring &text) { - OtkWidget::setStyle(style); + bool utf = text.utf8(); + std::string s = text.c_str(); // use a normal string, for its functionality + + _parsedtext.clear(); + + // parse it into multiple lines + std::string::size_type p = 0; + while (p != std::string::npos) { + std::string::size_type p2 = s.find('\n', p); + _parsedtext.push_back(s.substr(p, (p2==std::string::npos?p2:p2-p))); + _parsedtext.back().setUtf8(utf); + p = (p2==std::string::npos?p2:p2+1); + } + calcDefaultSizes(); +} - setTexture(getStyle()->getLabelUnfocus()); +void Label::setFont(const Font *f) +{ + _font = f; + calcDefaultSizes(); } +void Label::calcDefaultSizes() +{ + unsigned int longest = 0; + // find the longest line + std::vector::iterator it, end = _parsedtext.end(); + for (it = _parsedtext.begin(); it != end; ++it) { + unsigned int length = _font->measureString(*it); + if (length > longest) longest = length; + } + setMinSize(Size(longest + borderWidth() * 2 + bevel() * 4, + _parsedtext.size() * _font->height() + borderWidth() * 2 + + bevel() * 2)); +} + +void Label::styleChanged(const RenderStyle &style) +{ + if (_highlight) { + _texture = style.labelFocusBackground(); + _forecolor = style.textFocusColor(); + } else { + _texture = style.labelUnfocusBackground(); + _forecolor = style.textUnfocusColor(); + } + _font = style.labelFont(); + Widget::styleChanged(style); + calcDefaultSizes(); +} -void OtkLabel::update(void) +void Label::renderForeground(Surface &surface) { - if (_dirty) { - const BFont &ft = getStyle()->getFont(); - unsigned int sidemargin = getStyle()->getBevelWidth() * 2; + const RenderControl *control = display->renderControl(screen()); + unsigned int sidemargin = bevel() * 2; + int y = bevel(); + unsigned int w = area().width() - borderWidth() * 2 - sidemargin * 2; + unsigned int h = area().height() - borderWidth() * 2 - bevel() * 2; - std::string t = _text; // the actual text to draw + switch (_justify_vert) { + case RenderStyle::RightBottomJustify: + y += h - (_parsedtext.size() * _font->height()); + if (y < bevel()) y = bevel(); + break; + case RenderStyle::CenterJustify: + y += (h - (_parsedtext.size() * _font->height())) / 2; + if (y < bevel()) y = bevel(); + break; + case RenderStyle::LeftTopJustify: + break; + } + + if (w <= 0) return; // can't fit anything + + std::vector::iterator it, end = _parsedtext.end(); + for (it = _parsedtext.begin(); it != end; ++it, y += _font->height()) { + ustring t = *it; // the actual text to draw int x = sidemargin; // x coord for the text // find a string that will fit inside the area for text - int max_length = width() - sidemargin * 2; - if (max_length <= 0) { - t = ""; // can't fit anything - } else { - size_t text_len = t.size(); - int length; + ustring::size_type text_len = t.size(); + unsigned int length; - do { - t.resize(text_len); - length = ft.measureString(t); - } while (length > max_length && text_len-- > 0); - - // justify the text - switch (getStyle()->textJustify()) { - case Style::RightJustify: - x += max_length - length; - break; - case Style::CenterJustify: - x += (max_length - length) / 2; - break; - case Style::LeftJustify: - break; - } - } + do { + t.resize(text_len); + length = _font->measureString(t); + } while (length > w && text_len-- > 0); - OtkWidget::update(); + if (text_len <= 0) continue; // won't fit anything - ft.drawString(_xftdraw, x, 0, *getStyle()->getTextUnfocus(), t); - } else - OtkWidget::update(); + // justify the text + switch (_justify_horz) { + case RenderStyle::RightBottomJustify: + x += w - length; + break; + case RenderStyle::CenterJustify: + x += (w - length) / 2; + break; + case RenderStyle::LeftTopJustify: + break; + } + + control->drawString(surface, *_font, x, y, *_forecolor, t); + } } }