Modules/Widgets/tests/support/RecordingPainter.cpp
Шурупов Илья Викторович b32b60d470 Give the colour popup wheel, square, RGB, HSV and HSL pages
The colour popup now has five pages like the reference panel: the
wheel, a saturation/value square with a hue strip, and RGB, HSV and HSL
sliders whose tracks show the colour they would pick. A footer holds
the old/new colour swatch (tapping the old half restores it), a hex
field and a Copy button. Grey colours keep their hue across pages.
On tablets the menu gains a Color submenu with the colour commands and
lightness presets, and Settings lists the Color menu.

Painter gains a linear gradient fill, Slider an optional gradient track
and Widgets a ColorSquare.
2026-10-18 01:36:19 +03:00

109 lines
4 KiB
C++

#include "RecordingPainter.hpp"
#include <algorithm>
using namespace tp;
using namespace tp::ui;
using namespace tp::ui::testing;
void RecordingPainter::pushTranslation(Vec2F offset) { mOrigins.push_back(mOrigins.back() + offset); }
void RecordingPainter::popTranslation() {
if (mOrigins.size() > 1) mOrigins.pop_back();
}
void RecordingPainter::pushClip(const RectF& rect) {
const RectF windowRect = translated(rect, mOrigins.back());
mClips.push_back(mClips.empty() ? windowRect : intersection(mClips.back(), windowRect));
}
void RecordingPainter::popClip() {
if (!mClips.empty()) mClips.pop_back();
}
void RecordingPainter::drawFilledRect(const RectF& rect, const RGBA& color, halnf cornerRadius) {
record(PaintCommand::Kind::FillRect, rect, color, {}, cornerRadius);
}
void RecordingPainter::drawStrokedRect(const RectF& rect, const RGBA& color, halnf cornerRadius, halnf) {
record(PaintCommand::Kind::StrokeRect, rect, color, {}, cornerRadius);
}
void RecordingPainter::drawStrokedCircle(Vec2F center, halnf radius, const RGBA& color, halnf) {
record(
PaintCommand::Kind::StrokeCircle, makeRect(center - Vec2F(radius, radius), Vec2F(radius * 2, radius * 2)), color
);
}
void RecordingPainter::fillPolygon(const std::vector<Vec2F>& points, const RGBA& color) {
if (points.empty()) return;
Vec2F low = points.front();
Vec2F high = points.front();
for (const Vec2F& point : points) {
low = { std::min(low.x, point.x), std::min(low.y, point.y) };
high = { std::max(high.x, point.x), std::max(high.y, point.y) };
}
record(PaintCommand::Kind::Polygon, makeRect(low, high - low), color);
}
void RecordingPainter::polyline(const std::vector<Vec2F>& points, const RGBA& color, halnf) {
if (points.empty()) return;
Vec2F low = points.front();
Vec2F high = points.front();
for (const Vec2F& point : points) {
low = { std::min(low.x, point.x), std::min(low.y, point.y) };
high = { std::max(high.x, point.x), std::max(high.y, point.y) };
}
record(PaintCommand::Kind::Polyline, makeRect(low, high - low), color);
for (const Vec2F& point : points)
mCommands.back().points.push_back(point + mOrigins.back());
}
void RecordingPainter::fillCircle(Vec2F center, halnf radius, const RGBA& color) {
record(PaintCommand::Kind::Circle, makeRect(center - Vec2F(radius, radius), Vec2F(radius * 2, radius * 2)), color);
}
void RecordingPainter::line(Vec2F from, Vec2F to, const RGBA& color, halnf) {
record(PaintCommand::Kind::Line, makeRect(from, to - from), color);
}
void RecordingPainter::text(const std::string& text, const RectF& box, halnf, TextAlign, const RGBA& color) {
record(PaintCommand::Kind::Text, box, color, text);
}
void RecordingPainter::drawImage(const RectF& rect, ImageId, halnf) { record(PaintCommand::Kind::Image, rect, {}); }
void RecordingPainter::colorWheel(const RectF& rect, const HSV&, halnf) {
record(PaintCommand::Kind::ColorWheel, rect, {});
}
void RecordingPainter::fillGradientRect(const RectF& rect, const RGBA& from, const RGBA& to, bool, halnf cornerRadius) {
record(PaintCommand::Kind::Gradient, rect, from, {}, cornerRadius);
mCommands.back().endColor = to;
}
void RecordingPainter::verticalText(
const std::string& text, const RectF& box, halnf, TextDirection, const RGBA& color
) {
record(PaintCommand::Kind::Text, box, color, text);
}
halnf RecordingPainter::textWidth(const std::string& text, halnf fontSize) const {
return MonospaceTextMetrics().textWidth(text, fontSize);
}
const PaintCommand* RecordingPainter::findText(const std::string& text) const {
for (const PaintCommand& command : mCommands) {
if (command.kind == PaintCommand::Kind::Text && command.text == text) return &command;
}
return nullptr;
}
void RecordingPainter::record(
PaintCommand::Kind kind, const RectF& localRect, const RGBA& color, const std::string& text, halnf cornerRadius
) {
const RectF clip = mClips.empty() ? makeRect(-1.0e9f, -1.0e9f, 2.0e9f, 2.0e9f) : mClips.back();
mCommands.push_back({ kind, translated(localRect, mOrigins.back()), color, cornerRadius, text, clip });
}