diff --git a/specter/include/Specter/Button.hpp b/specter/include/Specter/Button.hpp index eef2e3aee..bfe723147 100644 --- a/specter/include/Specter/Button.hpp +++ b/specter/include/Specter/Button.hpp @@ -9,16 +9,26 @@ namespace Specter class Button : public Control { +public: + enum class Style + { + Block, + Text, + }; + +private: + Style m_style; + Zeus::CColor m_textColor; std::string m_textStr; std::unique_ptr m_text; SolidShaderVert m_verts[28]; ViewBlock m_bBlock; - boo::IGraphicsBufferD* m_bBlockBuf; + boo::IGraphicsBufferD* m_bBlockBuf = nullptr; - boo::IGraphicsBufferD* m_bVertsBuf; - boo::IVertexFormat* m_bVtxFmt; /* OpenGL only */ - boo::IShaderDataBinding* m_bShaderBinding; + boo::IGraphicsBufferD* m_bVertsBuf = nullptr; + boo::IVertexFormat* m_bVtxFmt = nullptr; /* OpenGL only */ + boo::IShaderDataBinding* m_bShaderBinding = nullptr; int m_nomWidth, m_nomHeight; bool m_pressed = false; @@ -28,6 +38,7 @@ class Button : public Control void setHover(); void setPressed(); void setDisabled(); + public: class Resources { @@ -38,7 +49,11 @@ public: }; Button(ViewResources& res, View& parentView, - IButtonBinding* controlBinding, const std::string& text); + IButtonBinding* controlBinding, const std::string& text, + Style style=Style::Block); + Button(ViewResources& res, View& parentView, + IButtonBinding* controlBinding, const std::string& text, + const Zeus::CColor& textColor, Style style=Style::Block); void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey); void mouseUp(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey); void mouseEnter(const boo::SWindowCoord&); @@ -46,7 +61,9 @@ public: void resized(const boo::SWindowRect& rootView, const boo::SWindowRect& sub); void draw(boo::IGraphicsCommandQueue* gfxQ); + void setText(const std::string& text, const Zeus::CColor& textColor); void setText(const std::string& text); + void colorGlyphs(const Zeus::CColor& newColor); int nominalWidth() const {return m_nomWidth;} int nominalHeight() const {return m_nomHeight;} }; diff --git a/specter/include/Specter/Control.hpp b/specter/include/Specter/Control.hpp index 7e598b437..c0d48c38f 100644 --- a/specter/include/Specter/Control.hpp +++ b/specter/include/Specter/Control.hpp @@ -9,8 +9,8 @@ namespace Specter struct IControlBinding { - virtual const std::string& name() const=0; - virtual const std::string& help() const=0; + virtual const char* name() const=0; + virtual const char* help() const=0; }; struct IButtonBinding : IControlBinding @@ -37,8 +37,8 @@ struct CVarControlBinding : IControlBinding HECL::CVar* m_cvar; CVarControlBinding(HECL::CVar* cvar) : m_cvar(cvar) {} - const std::string& name() const {return m_cvar->name();} - const std::string& help() const {return m_cvar->rawHelp();} + const char* name() const {return m_cvar->name().c_str();} + const char* help() const {return m_cvar->rawHelp().c_str();} }; class Control : public View diff --git a/specter/include/Specter/MultiLineTextView.hpp b/specter/include/Specter/MultiLineTextView.hpp index d46548cfb..1ad733be1 100644 --- a/specter/include/Specter/MultiLineTextView.hpp +++ b/specter/include/Specter/MultiLineTextView.hpp @@ -13,14 +13,20 @@ class MultiLineTextView : public View ViewResources& m_viewSystem; std::vector> m_lines; const FontAtlas& m_fontAtlas; + TextView::Alignment m_align; size_t m_lineCapacity; float m_lineHeight; int m_width; std::string LineWrap(const std::string& str, int wrap); std::wstring LineWrap(const std::wstring& str, int wrap); + public: - MultiLineTextView(ViewResources& res, View& parentView, const FontAtlas& font, size_t lineCapacity=256, float lineHeight=1.0); - MultiLineTextView(ViewResources& res, View& parentView, FontTag font, size_t lineCapacity=256, float lineHeight=1.0); + MultiLineTextView(ViewResources& res, View& parentView, const FontAtlas& font, + TextView::Alignment align=TextView::Alignment::Left, + size_t lineCapacity=256, float lineHeight=1.0); + MultiLineTextView(ViewResources& res, View& parentView, FontTag font, + TextView::Alignment align=TextView::Alignment::Left, + size_t lineCapacity=256, float lineHeight=1.0); void typesetGlyphs(const std::string& str, const Zeus::CColor& defaultColor=Zeus::CColor::skWhite, @@ -29,6 +35,8 @@ public: const Zeus::CColor& defaultColor=Zeus::CColor::skWhite, unsigned wrap=0); + void colorGlyphs(const Zeus::CColor& newColor); + void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub); void draw(boo::IGraphicsCommandQueue* gfxQ); diff --git a/specter/include/Specter/TextView.hpp b/specter/include/Specter/TextView.hpp index 03b77be7b..dd9eee799 100644 --- a/specter/include/Specter/TextView.hpp +++ b/specter/include/Specter/TextView.hpp @@ -14,11 +14,21 @@ class ViewResources; class TextView : public View { +public: + enum class Alignment + { + Left, + Center, + Right + }; + +private: size_t m_capacity; boo::IGraphicsBufferD* m_glyphBuf; boo::IVertexFormat* m_vtxFmt = nullptr; /* OpenGL only */ boo::IShaderDataBinding* m_shaderBinding; const FontAtlas& m_fontAtlas; + Alignment m_align; bool m_valid = false; int m_width = 0; @@ -44,8 +54,8 @@ public: #endif }; - TextView(ViewResources& res, View& parentView, const FontAtlas& font, size_t capacity=256); - TextView(ViewResources& res, View& parentView, FontTag font, size_t capacity=256); + TextView(ViewResources& res, View& parentView, const FontAtlas& font, Alignment align=Alignment::Left, size_t capacity=256); + TextView(ViewResources& res, View& parentView, FontTag font, Alignment align=Alignment::Left, size_t capacity=256); struct RenderGlyph { diff --git a/specter/lib/Button.cpp b/specter/lib/Button.cpp index 3b52c1ab4..8b6a941e6 100644 --- a/specter/lib/Button.cpp +++ b/specter/lib/Button.cpp @@ -12,8 +12,14 @@ void Button::Resources::init(boo::IGraphicsDataFactory* factory, const ThemeData } Button::Button(ViewResources& res, View& parentView, - IButtonBinding* controlBinding, const std::string& text) -: Control(res, parentView, controlBinding), m_textStr(text) + IButtonBinding* controlBinding, const std::string& text, + Style style) +: Button(res, parentView, controlBinding, text, res.themeData().uiText(), style) {} + +Button::Button(ViewResources& res, View& parentView, + IButtonBinding* controlBinding, const std::string& text, + const Zeus::CColor& textColor, Style style) +: Control(res, parentView, controlBinding), m_style(style), m_textColor(textColor), m_textStr(text) { m_bBlockBuf = res.m_factory->newDynamicBuffer(boo::BufferUse::Uniform, sizeof(ViewBlock), 1); m_bVertsBuf = res.m_factory->newDynamicBuffer(boo::BufferUse::Vertex, sizeof(SolidShaderVert), 28); @@ -39,105 +45,185 @@ Button::Button(ViewResources& res, View& parentView, m_bVertsBuf, nullptr, nullptr, 1, bufs, 0, nullptr); } - commitResources(res); + if (style == Style::Block) + { + m_verts[0].m_color = res.themeData().button1Inactive(); + m_verts[1].m_color = res.themeData().button2Inactive(); + m_verts[2].m_color = res.themeData().button1Inactive(); + m_verts[3].m_color = res.themeData().button2Inactive(); + m_verts[4].m_color = res.themeData().button2Inactive(); + for (int i=5 ; i<28 ; ++i) + m_verts[i].m_color = res.themeData().button2Inactive(); + m_bVertsBuf->load(m_verts, sizeof(SolidShaderVert) * 28); + } + else + { + for (int i=0 ; i<4 ; ++i) + m_verts[i].m_color = Zeus::CColor::skClear; + m_bVertsBuf->load(m_verts, sizeof(SolidShaderVert) * 4); + } + m_text.reset(new TextView(res, *this, res.m_mainFont)); setText(m_textStr); - m_verts[0].m_color = res.themeData().button1Inactive(); - m_verts[1].m_color = res.themeData().button2Inactive(); - m_verts[2].m_color = res.themeData().button1Inactive(); - m_verts[3].m_color = res.themeData().button2Inactive(); - m_verts[4].m_color = res.themeData().button2Inactive(); - for (int i=5 ; i<28 ; ++i) - m_verts[i].m_color = res.themeData().button2Inactive(); - m_bVertsBuf->load(m_verts, sizeof(SolidShaderVert) * 28); } -void Button::setText(const std::string& text) +void Button::setText(const std::string &text) +{ + setText(text, m_textColor); +} + +void Button::setText(const std::string& text, const Zeus::CColor& textColor) { m_textStr = text; + m_textColor = textColor; - m_text->typesetGlyphs(text, rootView().themeData().uiText()); + m_text->typesetGlyphs(text, textColor); float pf = rootView().viewRes().pixelFactor(); - float width = m_text->nominalWidth() + 10 * pf; - float height = 20 * pf; - m_verts[0].m_pos.assign(1, height+1, 0); - m_verts[1].m_pos.assign(1, 1, 0); - m_verts[2].m_pos.assign(width+1, height+1, 0); - m_verts[3].m_pos.assign(width+1, 1, 0); - m_verts[4].m_pos.assign(width+1, 1, 0); + float width, height; - m_verts[5].m_pos.assign(1, height+1, 0); - m_verts[6].m_pos.assign(1, height+1, 0); - m_verts[7].m_pos.assign(0, height+1, 0); - m_verts[8].m_pos.assign(1, 1, 0); - m_verts[9].m_pos.assign(0, 1, 0); - m_verts[10].m_pos.assign(0, 1, 0); + if (m_style == Style::Block) + { + width = m_text->nominalWidth() + 12 * pf; + height = 20 * pf; + m_verts[0].m_pos.assign(1, height+1, 0); + m_verts[1].m_pos.assign(1, 1, 0); + m_verts[2].m_pos.assign(width+1, height+1, 0); + m_verts[3].m_pos.assign(width+1, 1, 0); + m_verts[4].m_pos.assign(width+1, 1, 0); - m_verts[11].m_pos.assign(width+2, height+1, 0); - m_verts[12].m_pos.assign(width+2, height+1, 0); - m_verts[13].m_pos.assign(width+1, height+1, 0); - m_verts[14].m_pos.assign(width+2, 1, 0); - m_verts[15].m_pos.assign(width+1, 1, 0); - m_verts[16].m_pos.assign(width+1, 1, 0); + m_verts[5].m_pos.assign(1, height+1, 0); + m_verts[6].m_pos.assign(1, height+1, 0); + m_verts[7].m_pos.assign(0, height+1, 0); + m_verts[8].m_pos.assign(1, 1, 0); + m_verts[9].m_pos.assign(0, 1, 0); + m_verts[10].m_pos.assign(0, 1, 0); - m_verts[17].m_pos.assign(1, height+2, 0); - m_verts[18].m_pos.assign(1, height+2, 0); - m_verts[19].m_pos.assign(1, height+1, 0); - m_verts[20].m_pos.assign(width+1, height+2, 0); - m_verts[21].m_pos.assign(width+1, height+1, 0); - m_verts[22].m_pos.assign(width+1, height+1, 0); + m_verts[11].m_pos.assign(width+2, height+1, 0); + m_verts[12].m_pos.assign(width+2, height+1, 0); + m_verts[13].m_pos.assign(width+1, height+1, 0); + m_verts[14].m_pos.assign(width+2, 1, 0); + m_verts[15].m_pos.assign(width+1, 1, 0); + m_verts[16].m_pos.assign(width+1, 1, 0); - m_verts[23].m_pos.assign(1, 1, 0); - m_verts[24].m_pos.assign(1, 1, 0); - m_verts[25].m_pos.assign(1, 0, 0); - m_verts[26].m_pos.assign(width+1, 1, 0); - m_verts[27].m_pos.assign(width+1, 0, 0); + m_verts[17].m_pos.assign(1, height+2, 0); + m_verts[18].m_pos.assign(1, height+2, 0); + m_verts[19].m_pos.assign(1, height+1, 0); + m_verts[20].m_pos.assign(width+1, height+2, 0); + m_verts[21].m_pos.assign(width+1, height+1, 0); + m_verts[22].m_pos.assign(width+1, height+1, 0); - m_bVertsBuf->load(m_verts, sizeof(SolidShaderVert) * 28); - m_nomWidth = width + 2; + m_verts[23].m_pos.assign(1, 1, 0); + m_verts[24].m_pos.assign(1, 1, 0); + m_verts[25].m_pos.assign(1, 0, 0); + m_verts[26].m_pos.assign(width+1, 1, 0); + m_verts[27].m_pos.assign(width+1, 0, 0); + + m_bVertsBuf->load(m_verts, sizeof(SolidShaderVert) * 28); + } + else + { + width = m_text->nominalWidth(); + height = 10 * pf; + m_verts[0].m_pos.assign(1*pf, -1*pf, 0); + m_verts[1].m_pos.assign(1*pf, -2*pf, 0); + m_verts[2].m_pos.assign(width, -1*pf, 0); + m_verts[3].m_pos.assign(width, -2*pf, 0); + + m_bVertsBuf->load(m_verts, sizeof(SolidShaderVert) * 4); + } + + m_nomWidth = width; m_nomHeight = height; } +void Button::colorGlyphs(const Zeus::CColor& newColor) +{ + m_textColor = newColor; + m_text->colorGlyphs(newColor); +} + void Button::setInactive() { - m_verts[0].m_color = rootView().themeData().button1Inactive(); - m_verts[1].m_color = rootView().themeData().button2Inactive(); - m_verts[2].m_color = rootView().themeData().button1Inactive(); - m_verts[3].m_color = rootView().themeData().button2Inactive(); - m_verts[4].m_color = rootView().themeData().button2Inactive(); - m_bVertsBuf->load(m_verts, sizeof(SolidShaderVert) * 28); + if (m_style == Style::Block) + { + m_verts[0].m_color = rootView().themeData().button1Inactive(); + m_verts[1].m_color = rootView().themeData().button2Inactive(); + m_verts[2].m_color = rootView().themeData().button1Inactive(); + m_verts[3].m_color = rootView().themeData().button2Inactive(); + m_verts[4].m_color = rootView().themeData().button2Inactive(); + m_bVertsBuf->load(m_verts, sizeof(SolidShaderVert) * 28); + } + else + { + for (int i=0 ; i<4 ; ++i) + m_verts[i].m_color = Zeus::CColor::skClear; + m_bVertsBuf->load(m_verts, sizeof(SolidShaderVert) * 4); + m_text->colorGlyphs(m_textColor); + } } void Button::setHover() { - m_verts[0].m_color = rootView().themeData().button1Hover(); - m_verts[1].m_color = rootView().themeData().button2Hover(); - m_verts[2].m_color = rootView().themeData().button1Hover(); - m_verts[3].m_color = rootView().themeData().button2Hover(); - m_verts[4].m_color = rootView().themeData().button2Hover(); - m_bVertsBuf->load(m_verts, sizeof(SolidShaderVert) * 28); + if (m_style == Style::Block) + { + m_verts[0].m_color = rootView().themeData().button1Hover(); + m_verts[1].m_color = rootView().themeData().button2Hover(); + m_verts[2].m_color = rootView().themeData().button1Hover(); + m_verts[3].m_color = rootView().themeData().button2Hover(); + m_verts[4].m_color = rootView().themeData().button2Hover(); + m_bVertsBuf->load(m_verts, sizeof(SolidShaderVert) * 28); + } + else + { + for (int i=0 ; i<4 ; ++i) + m_verts[i].m_color = m_textColor; + m_bVertsBuf->load(m_verts, sizeof(SolidShaderVert) * 4); + m_text->colorGlyphs(m_textColor); + } } void Button::setPressed() { - m_verts[0].m_color = rootView().themeData().button1Press(); - m_verts[1].m_color = rootView().themeData().button2Press(); - m_verts[2].m_color = rootView().themeData().button1Press(); - m_verts[3].m_color = rootView().themeData().button2Press(); - m_verts[4].m_color = rootView().themeData().button2Press(); - m_bVertsBuf->load(m_verts, sizeof(SolidShaderVert) * 28); + if (m_style == Style::Block) + { + m_verts[0].m_color = rootView().themeData().button1Press(); + m_verts[1].m_color = rootView().themeData().button2Press(); + m_verts[2].m_color = rootView().themeData().button1Press(); + m_verts[3].m_color = rootView().themeData().button2Press(); + m_verts[4].m_color = rootView().themeData().button2Press(); + m_bVertsBuf->load(m_verts, sizeof(SolidShaderVert) * 28); + } + else + { + for (int i=0 ; i<4 ; ++i) + m_verts[i].m_color = m_textColor; + m_bVertsBuf->load(m_verts, sizeof(SolidShaderVert) * 4); + m_text->colorGlyphs(m_textColor); + } } void Button::setDisabled() { - m_verts[0].m_color = rootView().themeData().button1Disabled(); - m_verts[1].m_color = rootView().themeData().button2Disabled(); - m_verts[2].m_color = rootView().themeData().button1Disabled(); - m_verts[3].m_color = rootView().themeData().button2Disabled(); - m_verts[4].m_color = rootView().themeData().button2Disabled(); - m_bVertsBuf->load(m_verts, sizeof(SolidShaderVert) * 28); + if (m_style == Style::Block) + { + m_verts[0].m_color = rootView().themeData().button1Disabled(); + m_verts[1].m_color = rootView().themeData().button2Disabled(); + m_verts[2].m_color = rootView().themeData().button1Disabled(); + m_verts[3].m_color = rootView().themeData().button2Disabled(); + m_verts[4].m_color = rootView().themeData().button2Disabled(); + m_bVertsBuf->load(m_verts, sizeof(SolidShaderVert) * 28); + } + else + { + for (int i=0 ; i<4 ; ++i) + m_verts[i].m_color = Zeus::CColor::skClear; + m_bVertsBuf->load(m_verts, sizeof(SolidShaderVert) * 4); + Zeus::CColor dimText = m_textColor; + dimText[3] *= 0.5; + m_text->colorGlyphs(dimText); + } } void Button::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod) @@ -184,11 +270,14 @@ void Button::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub) { View::resized(root, sub); boo::SWindowRect textRect = sub; + float pf = rootView().viewRes().pixelFactor(); m_bBlock.setViewRect(root, sub); m_bBlockBuf->load(&m_bBlock, sizeof(ViewBlock)); - float pf = rootView().viewRes().pixelFactor(); - textRect.location[0] += 5 * pf; - textRect.location[1] += 8 * pf; + if (m_style == Style::Block) + { + textRect.location[0] += 5 * pf; + textRect.location[1] += 8 * pf; + } m_text->resized(root, textRect); } @@ -197,7 +286,10 @@ void Button::draw(boo::IGraphicsCommandQueue* gfxQ) View::draw(gfxQ); gfxQ->setShaderDataBinding(m_bShaderBinding); gfxQ->setDrawPrimitive(boo::Primitive::TriStrips); - gfxQ->draw(0, 28); + if (m_style == Style::Block) + gfxQ->draw(0, 28); + else + gfxQ->draw(0, 4); m_text->draw(gfxQ); } diff --git a/specter/lib/MultiLineTextView.cpp b/specter/lib/MultiLineTextView.cpp index 44590a5f6..7845ca576 100644 --- a/specter/lib/MultiLineTextView.cpp +++ b/specter/lib/MultiLineTextView.cpp @@ -129,11 +129,13 @@ std::wstring MultiLineTextView::LineWrap(const std::wstring& str, int wrap) MultiLineTextView::MultiLineTextView(ViewResources& res, View& parentView, const FontAtlas& font, + TextView::Alignment align, size_t lineCapacity, float lineHeight) : View(res, parentView), m_viewSystem(res), m_fontAtlas(font), + m_align(align), m_lineCapacity(lineCapacity), m_lineHeight(lineHeight) { @@ -143,11 +145,13 @@ MultiLineTextView::MultiLineTextView(ViewResources& res, MultiLineTextView::MultiLineTextView(ViewResources& res, View& parentView, FontTag font, + TextView::Alignment align, size_t lineCapacity, float lineHeight) : MultiLineTextView(res, parentView, res.m_textRes.m_fcache->lookupAtlas(font), + align, lineCapacity, lineHeight) {} @@ -190,7 +194,7 @@ void MultiLineTextView::typesetGlyphs(const std::string& str, utf8proc_ssize_t sz = utf8proc_iterate(it, -1, &ch); if (ch == '\n' || ch == '\0') { - m_lines.emplace_back(new TextView(m_viewSystem, *this, m_fontAtlas, m_lineCapacity)); + m_lines.emplace_back(new TextView(m_viewSystem, *this, m_fontAtlas, m_align, m_lineCapacity)); m_lines.back()->typesetGlyphs(std::string((char*)beginIt, it - beginIt), defaultColor); m_width = std::max(m_width, m_lines.back()->nominalWidth()); beginIt = it + 1; @@ -235,7 +239,7 @@ void MultiLineTextView::typesetGlyphs(const std::wstring& str, { if (*it == L'\n' || *it == L'\0') { - m_lines.emplace_back(new TextView(m_viewSystem, *this, m_fontAtlas, m_lineCapacity)); + m_lines.emplace_back(new TextView(m_viewSystem, *this, m_fontAtlas, m_align, m_lineCapacity)); m_lines.back()->typesetGlyphs(std::wstring(beginIt, it), defaultColor); m_width = std::max(m_width, m_lines.back()->nominalWidth()); beginIt = it + 1; @@ -247,6 +251,12 @@ void MultiLineTextView::typesetGlyphs(const std::wstring& str, updateSize(); } +void MultiLineTextView::colorGlyphs(const Zeus::CColor& newColor) +{ + for (std::unique_ptr& tv : m_lines) + tv->colorGlyphs(newColor); +} + void MultiLineTextView::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub) { View::resized(root, sub); diff --git a/specter/lib/TextView.cpp b/specter/lib/TextView.cpp index c6e9d4901..54d74e908 100644 --- a/specter/lib/TextView.cpp +++ b/specter/lib/TextView.cpp @@ -259,10 +259,11 @@ void TextView::Resources::init(boo::MetalDataFactory* factory, FontCache* fcache #endif -TextView::TextView(ViewResources& res, View& parentView, const FontAtlas& font, size_t capacity) +TextView::TextView(ViewResources& res, View& parentView, const FontAtlas& font, Alignment align, size_t capacity) : View(res, parentView), m_capacity(capacity), - m_fontAtlas(font) + m_fontAtlas(font), + m_align(align) { m_glyphBuf = res.m_factory->newDynamicBuffer(boo::BufferUse::Vertex, @@ -312,8 +313,8 @@ TextView::TextView(ViewResources& res, View& parentView, const FontAtlas& font, commitResources(res); } -TextView::TextView(ViewResources& res, View& parentView, FontTag font, size_t capacity) -: TextView(res, parentView, res.m_textRes.m_fcache->lookupAtlas(font), capacity) {} +TextView::TextView(ViewResources& res, View& parentView, FontTag font, Alignment align, size_t capacity) +: TextView(res, parentView, res.m_textRes.m_fcache->lookupAtlas(font), align, capacity) {} TextView::RenderGlyph::RenderGlyph(int& adv, const FontAtlas::Glyph& glyph, const Zeus::CColor& defaultColor) { @@ -386,6 +387,29 @@ void TextView::typesetGlyphs(const std::string& str, const Zeus::CColor& default break; } + if (m_align == Alignment::Right) + { + int adj = -adv; + for (RenderGlyph& g : m_glyphs) + { + g.m_pos[0][0] += adj; + g.m_pos[1][0] += adj; + g.m_pos[2][0] += adj; + g.m_pos[3][0] += adj; + } + } + else if (m_align == Alignment::Center) + { + int adj = -adv / 2; + for (RenderGlyph& g : m_glyphs) + { + g.m_pos[0][0] += adj; + g.m_pos[1][0] += adj; + g.m_pos[2][0] += adj; + g.m_pos[3][0] += adj; + } + } + m_width = adv; m_valid = false; updateSize(); @@ -420,6 +444,29 @@ void TextView::typesetGlyphs(const std::wstring& str, const Zeus::CColor& defaul break; } + if (m_align == Alignment::Right) + { + int adj = -adv; + for (RenderGlyph& g : m_glyphs) + { + g.m_pos[0][0] += adj; + g.m_pos[1][0] += adj; + g.m_pos[2][0] += adj; + g.m_pos[3][0] += adj; + } + } + else if (m_align == Alignment::Center) + { + int adj = -adv / 2; + for (RenderGlyph& g : m_glyphs) + { + g.m_pos[0][0] += adj; + g.m_pos[1][0] += adj; + g.m_pos[2][0] += adj; + g.m_pos[3][0] += adj; + } + } + m_width = adv; m_valid = false; updateSize(); diff --git a/specter/lib/Tooltip.cpp b/specter/lib/Tooltip.cpp index f1cc53844..14968e04f 100644 --- a/specter/lib/Tooltip.cpp +++ b/specter/lib/Tooltip.cpp @@ -44,8 +44,8 @@ Tooltip::Tooltip(ViewResources& res, View& parentView, const std::string& title, for (int i=0 ; i<4 ; ++i) { - m_cornersOutline[i].reset(new TextView(res, *this, res.m_curveFont, 1)); - m_cornersFilled[i].reset(new TextView(res, *this, res.m_curveFont, 1)); + m_cornersOutline[i].reset(new TextView(res, *this, res.m_curveFont, TextView::Alignment::Left, 1)); + m_cornersFilled[i].reset(new TextView(res, *this, res.m_curveFont, TextView::Alignment::Left, 1)); } m_cornersOutline[0]->typesetGlyphs(L"\xF4F0"); m_cornersFilled[0]->typesetGlyphs(L"\xF4F1", res.themeData().tooltipBackground());