Zappy GUI
C++ graphic client: renderer, camera, network
Loading...
Searching...
No Matches
TooltipWidget.cpp
Go to the documentation of this file.
1
2
3#include "TooltipWidget.hpp"
4
5#include <algorithm>
6#include <stdexcept>
7
8#include "TextRenderer.hpp"
9
10TooltipWidget& TooltipWidget::addLine(const std::string& text, Color color)
11{
12 _lines.push_back({{text}, {color}});
13 return *this;
14}
15
16TooltipWidget& TooltipWidget::addColoredLine(const std::vector<std::string>& segments,
17 const std::vector<Color>& colors)
18{
19 if (segments.size() != colors.size())
20 throw std::invalid_argument("segments and colors size mismatch");
21 _lines.push_back({segments, colors});
22 return *this;
23}
24
26{
27 _lines.clear();
28 return *this;
29}
30
32{
33 _x = x;
34 _y = y;
36 return *this;
37}
38
40{
41 _anchor = anchor;
42 _margin = margin;
43 return *this;
44}
45
47{
48 _minWidth = minWidth;
49 return *this;
50}
51
53{
55 return *this;
56}
57
59{
60 _textAlign = align;
61 return *this;
62}
63
65{
66 _bgColor = color;
67 return *this;
68}
69
71{
72 _bgAlpha = alpha;
73 return *this;
74}
75
77{
78 _borderColor = color;
79 return *this;
80}
81
83{
84 _borderThickness = thickness;
85 return *this;
86}
87
89{
90 _padding = padding;
91 return *this;
92}
93
94Vector2 TooltipWidget::_resolvePosition(float boxWidth, float boxHeight) const
95{
96 if (_anchor == Anchor::None) return {_x, _y};
97
98 float sw = static_cast<float>(GetScreenWidth());
99 float sh = static_cast<float>(GetScreenHeight());
100
101 switch (_anchor) {
102 case Anchor::TopLeft:
103 return {_margin, _margin};
105 return {(sw - boxWidth) / 2.0f, _margin};
106 case Anchor::TopRight:
107 return {sw - boxWidth - _margin, _margin};
109 return {_margin, (sh - boxHeight) / 2.0f};
110 case Anchor::Center:
111 return {(sw - boxWidth) / 2.0f, (sh - boxHeight) / 2.0f};
113 return {sw - boxWidth - _margin, (sh - boxHeight) / 2.0f};
115 return {_margin, sh - boxHeight - _margin};
117 return {(sw - boxWidth) / 2.0f, sh - boxHeight - _margin};
119 return {sw - boxWidth - _margin, sh - boxHeight - _margin};
120 default:
121 return {_x, _y};
122 }
123}
124
125void TooltipWidget::draw(int scaledFontSize) const
126{
127 if (_lines.empty()) return;
128
129 int lineSpacing = scaledFontSize / 4;
130 int contentWidth = 0;
131 int contentHeight = 0;
132
133 for (const auto& line : _lines) {
134 int lineWidth = 0;
135 for (size_t i = 0; i < line.segments.size(); ++i)
136 lineWidth += TextRenderer::measure(line.segments[i], scaledFontSize);
137 contentWidth = std::max(contentWidth, lineWidth);
138 contentHeight += scaledFontSize + lineSpacing;
139 }
140 contentHeight -= lineSpacing;
141
142 float boxWidth = std::max(static_cast<float>(contentWidth + _padding * 2), _minWidth);
143 float boxHeight = static_cast<float>(contentHeight + _padding * 2) + _extraBottomPadding;
144
145 Vector2 pos = _resolvePosition(boxWidth, boxHeight);
146 Rectangle rect = {pos.x, pos.y, boxWidth, boxHeight};
147 _lastBounds = rect;
148
149 Color bg = {_bgColor.r, _bgColor.g, _bgColor.b, _bgAlpha};
150 DrawRectangleRounded(rect, 0.2f, 8, bg);
151 if (_borderThickness > 0)
152 DrawRectangleRoundedLines(rect, 0.2f, 8, static_cast<float>(_borderThickness),
154
155 float textY = pos.y + _padding;
156 for (const auto& line : _lines) {
157 int lineWidth = 0;
158 for (size_t i = 0; i < line.segments.size(); ++i)
159 lineWidth += TextRenderer::measure(line.segments[i], scaledFontSize);
160
161 float textX = pos.x + _padding;
162 if (_textAlign == TextAlign::Center) textX = pos.x + (boxWidth - lineWidth) / 2.0f;
163
164 for (size_t i = 0; i < line.segments.size(); ++i) {
165 TextRenderer::draw(line.segments[i], static_cast<int>(textX), static_cast<int>(textY),
166 scaledFontSize, line.colors[i]);
167 textX += TextRenderer::measure(line.segments[i], scaledFontSize);
168 }
169 textY += scaledFontSize + lineSpacing;
170 }
171}
Stateful tooltip panel component implementing IWidget.
static void draw(const std::string &text, int x, int y, int fontSize, Color color)
static int measure(const std::string &text, int fontSize)
A configurable, stateful tooltip panel.
TooltipWidget & addLine(const std::string &text, Color color=WHITE)
Adds a single-color text line.
TooltipWidget & setExtraBottomPadding(float px)
Adds extra blank space at the bottom of the box (e.g. to reserve room for a button).
TooltipWidget & setPosition(float x, float y)
Absolute position. Sets anchor to None.
TooltipWidget & clearLines()
Removes all lines.
std::vector< Line > _lines
TooltipWidget & setBorderColor(Color color)
TooltipWidget & setTextAlign(TextAlign align)
float _extraBottomPadding
Rectangle _lastBounds
TooltipWidget & setAnchor(Anchor anchor, float margin=10.0f)
Auto-positioning relative to screen edges.
TooltipWidget & setMinWidth(float minWidth)
Override minimum panel width (0 = fit to content).
TooltipWidget & setBackgroundColor(Color color)
TooltipWidget & setPadding(int padding)
TooltipWidget & setBackgroundAlpha(unsigned char alpha)
TextAlign _textAlign
Vector2 _resolvePosition(float boxWidth, float boxHeight) const
void draw(int scaledFontSize) const override
Draws the widget.
TooltipWidget & addColoredLine(const std::vector< std::string > &segments, const std::vector< Color > &colors)
Adds a line with multiple colored segments (inline spans).
TooltipWidget & setBorderThickness(int thickness)
unsigned char _bgAlpha