更新缓存机制
This commit is contained in:
parent
927909da8d
commit
e5846ed637
|
|
@ -12,6 +12,7 @@ int main(int argc, char* argv[])
|
|||
|
||||
MapPresent p;
|
||||
p.show();
|
||||
p.zoomTo(1);
|
||||
|
||||
//QObject::connect(&p, &MapPresent::mouseIn, [=]() {
|
||||
// qDebug() << "Mouse Enter";
|
||||
|
|
|
|||
|
|
@ -20,15 +20,34 @@ MapPresent::MapPresent(QWidget* parent /*= nullptr*/)
|
|||
_type_present_delegate[delegate->unitType()] = delegate;
|
||||
connect(this, &MapPresent::mouseOut, delegate, &BasicUnitDelegate::hotClear);
|
||||
connect(this, &MapPresent::mouseHover, delegate, &BasicUnitDelegate::hotIndexSet);
|
||||
connect(delegate, &BasicUnitDelegate::updateRequest, [=]() { this->update(); });
|
||||
connect(delegate, &BasicUnitDelegate::updateRequest, [=](const PresentIndex& idx) {
|
||||
if (idx.isValid() && !_updated_units.contains(idx)) {
|
||||
_updated_units.append(idx);
|
||||
}
|
||||
|
||||
this->update();
|
||||
});
|
||||
|
||||
this->setMouseTracking(true);
|
||||
}
|
||||
|
||||
void MapPresent::zoomTo(double percent)
|
||||
{
|
||||
this->_scale_times = std::max(1.0 / 2, percent);
|
||||
this->visible_units_tidy();
|
||||
|
||||
this->update();
|
||||
}
|
||||
|
||||
double MapPresent::zoomTimes() const
|
||||
{
|
||||
return _scale_times;
|
||||
}
|
||||
|
||||
PresentIndex MapPresent::indexGet(const QPointF& pos) const
|
||||
{
|
||||
QList<PresentOption> templist;
|
||||
for (auto unit : _visible_units) {
|
||||
for (auto& unit : _visible_units) {
|
||||
if (unit.outline.contains(pos)) {
|
||||
templist << unit;
|
||||
|
||||
|
|
@ -59,7 +78,7 @@ QRectF MapPresent::outlineGet(const PresentIndex& idx) const
|
|||
auto widget_rect = this->rect();
|
||||
auto widget_center = widget_rect.center();
|
||||
|
||||
const float ap_len = _primitive_region_len / 2;
|
||||
const float ap_len = _primitive_region_len * _scale_times / 2;
|
||||
auto a2_vec = ap_len * sqrt(3) / 2;
|
||||
auto n_yinc = QVector3D(a2_vec, ap_len * 3 / 2, 0);
|
||||
auto n_xinc = QVector3D(a2_vec, -ap_len * 3 / 2, 0);
|
||||
|
|
@ -75,24 +94,34 @@ QRectF MapPresent::outlineGet(const PresentIndex& idx) const
|
|||
void MapPresent::paintEvent(QPaintEvent* ev)
|
||||
{
|
||||
QWidget::paintEvent(ev);
|
||||
UnitPresentDelegate& t = *_type_present_delegate[0];
|
||||
|
||||
QPainter p(this);
|
||||
for (auto opt : _visible_units) {
|
||||
p.save();
|
||||
if (_updated_units.size()) {
|
||||
QPainter pic_painter(&_paint_buffer);
|
||||
|
||||
for (auto idx : _updated_units) {
|
||||
pic_painter.save();
|
||||
|
||||
auto rect = opt.outline;
|
||||
p.translate(rect.topLeft());
|
||||
rect.moveTo(0, 0);
|
||||
auto opt = _visible_units[idx];
|
||||
auto rect = opt.outline;
|
||||
pic_painter.translate(rect.topLeft());
|
||||
rect.moveTo(0, 0);
|
||||
|
||||
auto clip_path = BasicUnitDelegate::clipPathGet(rect);
|
||||
p.setClipPath(clip_path);
|
||||
auto clip_path = BasicUnitDelegate::clipPathGet(rect);
|
||||
pic_painter.setClipPath(clip_path);
|
||||
|
||||
opt.outline = rect;
|
||||
t.paint(&p, opt);
|
||||
opt.outline = rect;
|
||||
UnitPresentDelegate& t = *_type_present_delegate[0];
|
||||
t.paint(&pic_painter, opt);
|
||||
|
||||
p.restore();
|
||||
pic_painter.restore();
|
||||
}
|
||||
|
||||
_updated_units.clear();
|
||||
}
|
||||
|
||||
QPainter widget_painter(this);
|
||||
// ת·¢ÀÛ»ý
|
||||
widget_painter.drawPixmap(rect(), _paint_buffer);
|
||||
}
|
||||
|
||||
void MapPresent::resizeEvent(QResizeEvent* event)
|
||||
|
|
@ -138,8 +167,9 @@ void MapPresent::visible_units_tidy() {
|
|||
_visible_units.clear();
|
||||
|
||||
QRectF curr_outline = this->rect();
|
||||
_visible_units << AssumeOpt(_center_index, outlineGet(_center_index));
|
||||
_paint_buffer = QPixmap(curr_outline.toRect().size());
|
||||
|
||||
_visible_units[_center_index] = AssumeOpt(_center_index, outlineGet(_center_index));
|
||||
int visible_count = 1, deduce_x = 1;
|
||||
while (visible_count) {
|
||||
visible_count = 0;
|
||||
|
|
@ -148,13 +178,14 @@ void MapPresent::visible_units_tidy() {
|
|||
for (auto unit : siblings) {
|
||||
auto visible_rect = outlineGet(unit);
|
||||
if (curr_outline.intersects(visible_rect)) {
|
||||
_visible_units << AssumeOpt(unit, visible_rect);
|
||||
_visible_units[unit] = AssumeOpt(unit, visible_rect);
|
||||
visible_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO ¹¹½¨¿ìËÙ²âÊÔ×éÖ¯½á¹¹
|
||||
for (auto optx : _visible_units)
|
||||
_updated_units.append(optx.index);
|
||||
}
|
||||
|
||||
QList<PresentIndex> MapPresent::siblingsGet(const PresentIndex& center, uint16_t dist) const
|
||||
|
|
@ -192,6 +223,21 @@ QList<PresentIndex> MapPresent::item_supply(const PresentIndex& a, const Present
|
|||
return items;
|
||||
}
|
||||
|
||||
void MapPresent::unit_option_paint(QPainter& widget_painter, const PresentOption& xopt)
|
||||
{
|
||||
auto opt = xopt;
|
||||
auto rect = opt.outline;
|
||||
widget_painter.translate(rect.topLeft());
|
||||
rect.moveTo(0, 0);
|
||||
|
||||
auto clip_path = BasicUnitDelegate::clipPathGet(rect);
|
||||
widget_painter.setClipPath(clip_path);
|
||||
|
||||
opt.outline = rect;
|
||||
UnitPresentDelegate& t = *_type_present_delegate[0];
|
||||
t.paint(&widget_painter, opt);
|
||||
}
|
||||
|
||||
PresentIndex& PresentIndex::operator+=(const PresentIndex& other)
|
||||
{
|
||||
row += other.row;
|
||||
|
|
@ -209,6 +255,13 @@ bool PresentIndex::isValid() const
|
|||
return row != INT_MAX && col != INT_MAX;
|
||||
}
|
||||
|
||||
bool PresentIndex::operator<(const PresentIndex& other) const
|
||||
{
|
||||
if (row == other.row)
|
||||
return col < other.col;
|
||||
return row < other.row;
|
||||
}
|
||||
|
||||
bool PresentIndex::operator==(const PresentIndex& other) const
|
||||
{
|
||||
return row == other.row && col == other.col;
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#include "mappresent_global.h"
|
||||
#include <QWidget>
|
||||
#include <memory>
|
||||
#include <QMap>
|
||||
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -23,6 +24,7 @@ struct MAPPRESENT_EXPORT PresentIndex {
|
|||
PresentIndex& operator+=(const PresentIndex& other);
|
||||
bool operator!=(const PresentIndex& other) const;
|
||||
bool operator==(const PresentIndex& other) const;
|
||||
bool operator<(const PresentIndex& other) const;
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -79,11 +81,11 @@ private:
|
|||
/// <summary>
|
||||
/// 初级区域矩形变长
|
||||
/// </summary>
|
||||
const float _primitive_region_len = 100;
|
||||
const float _primitive_region_len = 64;
|
||||
/// <summary>
|
||||
/// 缩放倍数
|
||||
/// </summary>
|
||||
short _scale_times = 1;
|
||||
double _scale_times = 1;
|
||||
/// <summary>
|
||||
/// 当前瓦片地图中心索引
|
||||
/// </summary>
|
||||
|
|
@ -91,9 +93,18 @@ private:
|
|||
|
||||
// ===================================
|
||||
/// <summary>
|
||||
/// 绘制中转缓冲区
|
||||
/// </summary>
|
||||
QPixmap _paint_buffer;
|
||||
/// <summary>
|
||||
/// 试图核心索引
|
||||
/// </summary>
|
||||
QList<PresentOption> _visible_units;
|
||||
QMap<PresentIndex, PresentOption> _visible_units;
|
||||
/// <summary>
|
||||
/// 被更新的单元索引
|
||||
/// </summary>
|
||||
QList<PresentIndex> _updated_units;
|
||||
|
||||
/// <summary>
|
||||
/// 可视化单元整理
|
||||
/// </summary>
|
||||
|
|
@ -111,11 +122,15 @@ private:
|
|||
/// 类型化绘制委托
|
||||
/// </summary>
|
||||
QHash<int, UnitPresentDelegate*> _type_present_delegate;
|
||||
void unit_option_paint(QPainter& widget_painter, const PresentOption &opt);
|
||||
|
||||
|
||||
public:
|
||||
MapPresent(QWidget* parent = nullptr);
|
||||
|
||||
void zoomTo(double percent);
|
||||
double zoomTimes() const;
|
||||
|
||||
/// <summary>
|
||||
/// 通过widget上定位获取绘制索引
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ void BasicUnitDelegate::paint(QPainter* p, const PresentOption& option)
|
|||
ft.setPixelSize(alen * 0.3);
|
||||
p->setFont(ft);
|
||||
|
||||
p->setPen(Qt::white);
|
||||
p->setPen(Qt::black);
|
||||
auto text_rect = QRectF(center.x() - xspan, center.y() - alen / 2, xspan * 2, alen);
|
||||
auto text_str = QString("(%1,%2)").arg(option.index.row).arg(option.index.col);
|
||||
p->drawText(text_rect, Qt::AlignCenter, text_str);
|
||||
|
|
@ -69,14 +69,19 @@ QPainterPath BasicUnitDelegate::clipPathGet(const QRectF& rect)
|
|||
|
||||
void BasicUnitDelegate::hotClear()
|
||||
{
|
||||
auto prev_idx = _hot_index;
|
||||
_hot_index = PresentIndex();
|
||||
emit this->updateRequest(_hot_index);
|
||||
|
||||
emit this->updateRequest(prev_idx);
|
||||
}
|
||||
|
||||
void BasicUnitDelegate::hotIndexSet(const PresentIndex& idx)
|
||||
{
|
||||
if (_hot_index != idx) {
|
||||
auto prev_idx = _hot_index;
|
||||
_hot_index = idx;
|
||||
|
||||
emit this->updateRequest(prev_idx);
|
||||
emit this->updateRequest(idx);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue