This commit is contained in:
codeboss 2025-10-12 20:21:45 +08:00
parent 6376ae1ed6
commit 03512aae5b
4 changed files with 82 additions and 39 deletions

View File

@ -8,6 +8,26 @@
#include <QMouseEvent>
class OptionGroup {
private:
PresentOption _bind_opt;
std::shared_ptr<OptionGroup> _next_group;
public:
OptionGroup(const PresentOption& opt, std::shared_ptr<OptionGroup> next = nullptr)
:_bind_opt(opt), _next_group(next) {
}
std::shared_ptr<OptionGroup> nextGet() const {
return _next_group;
}
const PresentOption& optionGet() const {
return _bind_opt;
}
};
MapPresent::MapPresent(QWidget* parent /*= nullptr*/)
:QWidget(parent)
{
@ -25,11 +45,17 @@ MapPresent::MapPresent(QWidget* parent /*= nullptr*/)
PresentIndex MapPresent::indexGet(const QPointF& pos) const
{
decltype(_visible_units) templist;
for (auto& unit : _visible_units) {
QList<PresentOption> templist;
for (auto unit_g : _visible_units) {
while (unit_g) {
auto unit = unit_g->optionGet();
if (unit.outline.contains(pos)) {
templist << unit;
}
unit_g = unit_g->nextGet();
}
}
while (templist.size() > 1) {
@ -69,31 +95,33 @@ QRectF MapPresent::outlineGet(const PresentIndex& idx) const
return QRectF(target_center.toPointF(), QSizeF(ap_len * 2, ap_len * 2));
}
#include <QElapsedTimer>
#include <QtDebug>
void MapPresent::paintEvent(QPaintEvent* ev)
{
QWidget::paintEvent(ev);
UnitPresentDelegate& t = *_present_delegate[0];
QPainter p(this);
for (auto opt : _visible_units) {
for (auto opt_g : _visible_units) {
while (opt_g) {
p.save();
auto opt = opt_g->optionGet();
auto rect = opt.outline;
p.translate(rect.topLeft());
rect.moveTo(0, 0);
auto end_pts = BasicUnitDelegate::endPointsGet(rect);
QPainterPath clicp_path;
clicp_path.moveTo(end_pts.first());
for (auto idx = 0; idx < end_pts.size(); ++idx) {
clicp_path.lineTo(end_pts[idx]);
}
p.setClipPath(clicp_path);
auto clip_path = BasicUnitDelegate::clipPathGet(rect);
p.setClipPath(clip_path);
opt.outline = rect;
t.paint(&p, opt);
p.restore();
opt_g = opt_g->nextGet();
}
}
}
@ -140,20 +168,27 @@ void MapPresent::visibleUnitsTidy() {
_visible_units.clear();
QRectF curr_outline = this->rect();
_visible_units << AssumeOpt(_center_index, outlineGet(_center_index));
_visible_units << std::make_shared<OptionGroup>(
AssumeOpt(_center_index, outlineGet(_center_index))
);
int visible_count = 1, deduce_x = 1;
while (visible_count) {
visible_count = 0;
std::shared_ptr<OptionGroup> prev_g = nullptr;
auto siblings = siblingsGet(_center_index, deduce_x++);
for (auto unit : siblings) {
auto visible_rect = outlineGet(unit);
if (curr_outline.intersects(visible_rect)) {
_visible_units << AssumeOpt(unit, visible_rect);
prev_g = std::make_shared<OptionGroup>(AssumeOpt(unit, visible_rect), prev_g);
visible_count++;
}
}
if (prev_g) {
_visible_units << prev_g;
}
}
// TODO ¹¹½¨¿ìËÙ²âÊÔ×éÖ¯½á¹¹
@ -219,3 +254,10 @@ bool PresentIndex::operator==(const PresentIndex& other) const
UnitPresentDelegate::UnitPresentDelegate(QObject* parent /*= nullptr*/)
:QObject(parent) {
}
PresentOption& PresentOption::operator=(const PresentOption& other)
{
index = other.index;
outline = other.outline;
return *this;
}

View File

@ -2,6 +2,8 @@
#include "mappresent_global.h"
#include <QWidget>
#include <memory>
/// <summary>
/// 餅秶坰竘
@ -36,8 +38,7 @@ struct PresentOption {
/// </summary>
QRectF outline;
bool isMouseOver = false;
bool isSelected = false;
PresentOption& operator=(const PresentOption& other);
};
/// <summary>
@ -68,6 +69,7 @@ signals:
void updateRequest(const PresentIndex &idx);
};
class OptionGroup;
/// <summary>
/// 價插華芞餅秶
/// </summary>
@ -89,7 +91,7 @@ private:
PresentIndex _center_index;
// ===================================
QList<PresentOption> _visible_units;
QList<std::shared_ptr<OptionGroup>> _visible_units;
void visibleUnitsTidy();
QList<PresentIndex> siblingsGet(const PresentIndex& center, uint16_t dist = 1) const;

View File

@ -22,22 +22,16 @@ void BasicUnitDelegate::paint(QPainter* p, const PresentOption& option)
QRadialGradient brush(center, alen);
brush.setColorAt(0, Qt::gray);
brush.setColorAt(1, Qt::white);
p->fillRect(rect, brush);
p->setBrush(brush);
QList<QPointF> points = endPointsGet(rect);
QVector<QLineF> lines;
for (auto idx = 0; idx < 6; ++idx) {
lines << QLineF(points[idx], points[idx + 1]);
}
auto pathx = clipPathGet(rect);
if (_hot_index == option.index) {
auto pen = p->pen();
pen.setColor(Qt::red);
pen.setWidth(10);
p->setPen(pen);
}
p->drawLines(lines);
p->drawPath(pathx);
auto ft = p->font();
ft.setPixelSize(alen * 0.3);
@ -49,7 +43,7 @@ void BasicUnitDelegate::paint(QPainter* p, const PresentOption& option)
p->drawText(text_rect, Qt::AlignCenter, text_str);
}
QList<QPointF> BasicUnitDelegate::endPointsGet(const QRectF& rect)
QPainterPath BasicUnitDelegate::clipPathGet(const QRectF& rect)
{
auto center = rect.center();
auto alen = rect.width() / 2;
@ -64,7 +58,12 @@ QList<QPointF> BasicUnitDelegate::endPointsGet(const QRectF& rect)
points << QPointF(center.x() - xspan, center.y() + alen / 2);
points << QPointF(center.x() - xspan, center.y() - alen / 2);
return points;
QPainterPath clicp_path;
clicp_path.moveTo(points.first());
for (auto idx = 0; idx < points.size(); ++idx) {
clicp_path.lineTo(points[idx]);
}
return clicp_path;
}
void BasicUnitDelegate::hotClear()

View File

@ -10,7 +10,7 @@ public:
int unitType() const override;
void paint(QPainter* p, const PresentOption& option) override;
static QList<QPointF> endPointsGet(const QRectF& rect);
static QPainterPath clipPathGet(const QRectF& rect);
void hotClear();
void hotIndexSet(const PresentIndex &idx);