添加creeper-qt最新依赖
This commit is contained in:
42
creeper-qt/widget/shape/ellipse.hh
Normal file
42
creeper-qt/widget/shape/ellipse.hh
Normal file
@@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
|
||||
#include "creeper-qt/utility/painter/helper.hh"
|
||||
#include "creeper-qt/utility/wrapper/property.hh"
|
||||
#include "creeper-qt/widget/shape/shape.hh"
|
||||
#include "creeper-qt/widget/widget.hh"
|
||||
|
||||
namespace creeper {
|
||||
|
||||
namespace ellipse::internal {
|
||||
class Ellipse : public Shape {
|
||||
protected:
|
||||
void paintEvent(QPaintEvent* event) override {
|
||||
auto painter = QPainter { this };
|
||||
painter.setRenderHint(QPainter::Antialiasing);
|
||||
|
||||
util::PainterHelper { painter }.ellipse(
|
||||
background_, border_color_, border_width_, rect());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
namespace ellipse::pro {
|
||||
using Token = common::Token<internal::Ellipse>;
|
||||
|
||||
// 通用属性
|
||||
using Background = common::pro::Background<Token>;
|
||||
|
||||
using BorderWidth = common::pro::BorderWidth<Token>;
|
||||
using BorderColor = common::pro::BorderColor<Token>;
|
||||
|
||||
template <typename T>
|
||||
concept trait = std::derived_from<T, Token>;
|
||||
|
||||
CREEPER_DEFINE_CHECKER(trait)
|
||||
using namespace widget::pro;
|
||||
}
|
||||
|
||||
using Ellipse =
|
||||
Declarative<ellipse::internal::Ellipse, CheckerOr<ellipse::pro::checker, widget::pro::checker>>;
|
||||
|
||||
}
|
||||
101
creeper-qt/widget/shape/rounded-rect.hh
Normal file
101
creeper-qt/widget/shape/rounded-rect.hh
Normal file
@@ -0,0 +1,101 @@
|
||||
#pragma once
|
||||
|
||||
#include "creeper-qt/utility/painter/helper.hh"
|
||||
#include "creeper-qt/utility/wrapper/property.hh"
|
||||
#include "creeper-qt/utility/wrapper/widget.hh"
|
||||
#include "creeper-qt/widget/shape/shape.hh"
|
||||
|
||||
namespace creeper::rounded_rect::internal {
|
||||
|
||||
class RoundedRect : public Shape {
|
||||
public:
|
||||
void set_radius(double radius) {
|
||||
radius_nx_ny_ = radius;
|
||||
radius_px_py_ = radius;
|
||||
radius_nx_py_ = radius;
|
||||
radius_px_ny_ = radius;
|
||||
update();
|
||||
}
|
||||
|
||||
void set_radius_nx_ny(double radius) {
|
||||
radius_nx_ny_ = radius;
|
||||
update();
|
||||
}
|
||||
void set_radius_px_py(double radius) {
|
||||
radius_px_py_ = radius;
|
||||
update();
|
||||
}
|
||||
void set_radius_nx_py(double radius) {
|
||||
radius_nx_py_ = radius;
|
||||
update();
|
||||
}
|
||||
void set_radius_px_ny(double radius) {
|
||||
radius_px_ny_ = radius;
|
||||
update();
|
||||
}
|
||||
|
||||
void set_radius_top_left(double radius) { set_radius_nx_ny(radius); }
|
||||
|
||||
void set_radius_top_right(double radius) { set_radius_px_ny(radius); }
|
||||
|
||||
void set_radius_bottom_left(double radius) { set_radius_nx_py(radius); }
|
||||
|
||||
void set_radius_bottom_right(double radius) { set_radius_px_py(radius); }
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent* event) override {
|
||||
auto painter = QPainter { this };
|
||||
|
||||
util::PainterHelper { painter }
|
||||
.set_render_hint(QPainter::Antialiasing)
|
||||
.rounded_rectangle( //
|
||||
background_, border_color_, border_width_, rect(),
|
||||
radius_nx_ny_, // tl: 左上
|
||||
radius_px_ny_, // tr: 右上
|
||||
radius_px_py_, // br: 右下
|
||||
radius_nx_py_ // bl: 左下
|
||||
)
|
||||
.done();
|
||||
}
|
||||
|
||||
private:
|
||||
double radius_nx_ny_ = 0;
|
||||
double radius_px_py_ = 0;
|
||||
double radius_nx_py_ = 0;
|
||||
double radius_px_ny_ = 0;
|
||||
};
|
||||
|
||||
}
|
||||
namespace creeper::rounded_rect::pro {
|
||||
using Token = common::Token<internal::RoundedRect>;
|
||||
|
||||
// 通用属性
|
||||
using Radius = common::pro::Radius<Token>;
|
||||
|
||||
using RadiusPxPy = common::pro::RadiusPxPy<Token>;
|
||||
using RadiusNxNy = common::pro::RadiusNxNy<Token>;
|
||||
using RadiusPxNy = common::pro::RadiusPxNy<Token>;
|
||||
using RadiusNxPy = common::pro::RadiusNxPy<Token>;
|
||||
|
||||
using RadiusTopLeft = RadiusNxNy;
|
||||
using RadiusTopRight = RadiusPxNy;
|
||||
using RadiusBottomLeft = RadiusNxPy;
|
||||
using RadiusBottomRight = RadiusPxPy;
|
||||
|
||||
using Background = common::pro::Background<Token>;
|
||||
|
||||
using BorderWidth = common::pro::BorderWidth<Token>;
|
||||
using BorderColor = common::pro::BorderColor<Token>;
|
||||
|
||||
template <typename T>
|
||||
concept trait = std::derived_from<T, Token>;
|
||||
|
||||
CREEPER_DEFINE_CHECKER(trait)
|
||||
using namespace widget::pro;
|
||||
}
|
||||
namespace creeper {
|
||||
|
||||
using RoundedRect = Declarative<rounded_rect::internal::RoundedRect,
|
||||
CheckerOr<rounded_rect::pro::checker, widget::pro::checker>>;
|
||||
|
||||
}
|
||||
23
creeper-qt/widget/shape/shape.hh
Normal file
23
creeper-qt/widget/shape/shape.hh
Normal file
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include <qpainter.h>
|
||||
#include <qwidget.h>
|
||||
|
||||
namespace creeper {
|
||||
|
||||
class Shape : public QWidget {
|
||||
public:
|
||||
using QWidget::QWidget;
|
||||
|
||||
void set_background(const QColor& color) { background_ = color; }
|
||||
|
||||
void set_border_color(const QColor& color) { border_color_ = color; }
|
||||
void set_border_width(double width) { border_width_ = width; }
|
||||
|
||||
protected:
|
||||
QColor background_ = Qt::gray;
|
||||
QColor border_color_ = Qt::black;
|
||||
double border_width_ = 0.;
|
||||
};
|
||||
|
||||
}
|
||||
128
creeper-qt/widget/shape/wave-circle.hh
Normal file
128
creeper-qt/widget/shape/wave-circle.hh
Normal file
@@ -0,0 +1,128 @@
|
||||
#pragma once
|
||||
|
||||
#include "creeper-qt/utility/solution/round-angle.hh"
|
||||
#include "creeper-qt/utility/wrapper/common.hh"
|
||||
#include "creeper-qt/utility/wrapper/property.hh"
|
||||
#include "creeper-qt/widget/shape/shape.hh"
|
||||
#include "creeper-qt/widget/widget.hh"
|
||||
|
||||
#include <cmath>
|
||||
#include <qpainterpath.h>
|
||||
#include <ranges>
|
||||
|
||||
namespace creeper::wave_circle::internal {
|
||||
|
||||
class WaveCircle : public Shape {
|
||||
public:
|
||||
auto set_flange_number(uint8_t number) noexcept {
|
||||
generate_request_ = true;
|
||||
flange_number_ = number;
|
||||
}
|
||||
auto set_flange_radius(double radius) noexcept {
|
||||
generate_request_ = true;
|
||||
flange_radius_ = radius;
|
||||
}
|
||||
auto set_overall_radius(double radius) noexcept {
|
||||
generate_request_ = true;
|
||||
overall_radius_ = radius;
|
||||
}
|
||||
auto set_protruding_ratio(double ratio) noexcept {
|
||||
generate_request_ = true;
|
||||
protruding_ratio_ = ratio;
|
||||
}
|
||||
|
||||
protected:
|
||||
auto paintEvent(QPaintEvent*) -> void override {
|
||||
if (generate_request_) generate_path();
|
||||
|
||||
auto painter = QPainter { this };
|
||||
painter.setRenderHint(QPainter::Antialiasing, true);
|
||||
painter.setOpacity(1);
|
||||
painter.setBrush({ background_ });
|
||||
painter.setPen(QPen {
|
||||
border_color_,
|
||||
border_width_,
|
||||
Qt::SolidLine,
|
||||
Qt::RoundCap,
|
||||
});
|
||||
painter.drawPath(path_cache_);
|
||||
}
|
||||
auto resizeEvent(QResizeEvent* e) -> void override {
|
||||
Shape::resizeEvent(e);
|
||||
generate_request_ = true;
|
||||
}
|
||||
|
||||
private:
|
||||
bool generate_request_ = true;
|
||||
QPainterPath path_cache_;
|
||||
|
||||
int8_t flange_number_ = 12;
|
||||
double flange_radius_ = 10;
|
||||
double overall_radius_ = 100;
|
||||
double protruding_ratio_ = 0.8;
|
||||
|
||||
auto generate_path() noexcept -> void {
|
||||
|
||||
const auto center = QPointF(width() / 2., height() / 2.);
|
||||
const auto step = 2 * std::numbers::pi / flange_number_;
|
||||
const auto radius = std::min(overall_radius_, std::min<double>(width(), height()));
|
||||
|
||||
std::vector<QPointF> outside(flange_number_ + 2), inside(flange_number_ + 2);
|
||||
for (auto&& [index, point] : std::views::enumerate(std::views::zip(outside, inside))) {
|
||||
auto& [outside, inside] = point;
|
||||
outside.setX(radius * std::cos(-index * step));
|
||||
outside.setY(radius * std::sin(-index * step));
|
||||
inside.setX(protruding_ratio_ * radius * std::cos(double(-index + 0.5) * step));
|
||||
inside.setY(protruding_ratio_ * radius * std::sin(double(-index + 0.5) * step));
|
||||
}
|
||||
|
||||
auto begin = QPointF {};
|
||||
path_cache_ = QPainterPath {};
|
||||
for (int index = 0; index < flange_number_; index++) {
|
||||
const auto convex = RoundAngleSolution(center + outside[index], center + inside[index],
|
||||
center + inside[index + 1], flange_radius_);
|
||||
const auto concave = RoundAngleSolution(center + inside[index + 1],
|
||||
center + outside[index + 1], center + outside[index], flange_radius_);
|
||||
if (index == 0) begin = convex.start, path_cache_.moveTo(begin);
|
||||
path_cache_.lineTo(convex.start);
|
||||
path_cache_.arcTo(convex.rect, convex.angle_begin, convex.angle_length);
|
||||
path_cache_.lineTo(concave.end);
|
||||
path_cache_.arcTo(
|
||||
concave.rect, concave.angle_begin + concave.angle_length, -concave.angle_length);
|
||||
}
|
||||
path_cache_.lineTo(begin);
|
||||
}
|
||||
};
|
||||
}
|
||||
namespace creeper::wave_circle::pro {
|
||||
|
||||
using Token = common::Token<internal::WaveCircle>;
|
||||
|
||||
using Background = common::pro::Background<Token>;
|
||||
using BorderWidth = common::pro::BorderWidth<Token>;
|
||||
using BorderColor = common::pro::BorderColor<Token>;
|
||||
|
||||
using FlangeNumber =
|
||||
SetterProp<Token, uint8_t, [](auto& self, const auto& v) { self.set_flange_number(v); }>;
|
||||
|
||||
using FlangeRadius =
|
||||
SetterProp<Token, double, [](auto& self, const auto& v) { self.set_flange_radius(v); }>;
|
||||
|
||||
using OverallRadius =
|
||||
SetterProp<Token, double, [](auto& self, const auto& v) { self.set_overall_radius(v); }>;
|
||||
|
||||
using ProtrudingRatio =
|
||||
SetterProp<Token, double, [](auto& self, const auto& v) { self.set_protruding_ratio(v); }>;
|
||||
|
||||
template <class T>
|
||||
concept trait = std::derived_from<T, Token>;
|
||||
|
||||
CREEPER_DEFINE_CHECKER(trait);
|
||||
using namespace widget::pro;
|
||||
}
|
||||
namespace creeper {
|
||||
|
||||
using WaveCircle = Declarative<wave_circle::internal::WaveCircle,
|
||||
CheckerOr<wave_circle::pro::checker, widget::pro::checker>>;
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user