aboutsummaryrefslogtreecommitdiff
path: root/mapman/src/painter.cpp
blob: 5b3ad3bd05541c7032b55c1d3209ea8c6bb29bdd (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#include "painter.hpp"
#include "library.hpp"
#include "utils.hpp"

#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsSimpleTextItem>
#include <QGraphicsRectItem>
#include <QGraphicsPixmapItem>
#include <QGraphicsSceneDragDropEvent>
#include <QMimeData>
#include <QPixmapCache>

class drop_rect : public QGraphicsRectItem
{
public:
    drop_rect(int pos, map_painter *painter);
signals:
    void dropped(int pos, int id);
protected:
    void dragEnterEvent(QGraphicsSceneDragDropEvent *e);
    void dropEvent(QGraphicsSceneDragDropEvent *e);
private:
    int p;
    map_painter *pt;
};

drop_rect::drop_rect(int pos, map_painter *painter) :
    QGraphicsRectItem(QRectF(0, 0, 128, 128), nullptr),
    p(pos),
    pt(painter)
{
    setAcceptDrops(true);
    setPen(QPen(Qt::GlobalColor::black, 4));
}

void drop_rect::dragEnterEvent(QGraphicsSceneDragDropEvent *e)
{
    auto ba = e->mimeData()->data("application/x-map-id");
    e->setAccepted(ba.length() >= 4);
}

void drop_rect::dropEvent(QGraphicsSceneDragDropEvent *e)
{
    auto ba = e->mimeData()->data("application/x-map-id");
    if (ba.length() >= 4)
    {
        e->setDropAction(Qt::DropAction::CopyAction);
        pt->set_map_id(p, true, *reinterpret_cast<int*>(ba.data()), true);
    }
    else e->setDropAction(Qt::DropAction::IgnoreAction);
}

map_painter::map_painter() : l(nullptr)
{
    s = new QGraphicsScene(0, 0, 0, 0);
    v = new QGraphicsView(s);
    hc = vc = 0;
}

map_painter::~map_painter()
{
    delete s;
    delete v;
}

void map_painter::set_dimension(int h, int v)
{
    hc = h;
    vc = v;
    s->setSceneRect(0, 0, hc * 128, vc * 128);
    s->clear();
    slices.clear();
    slices.resize(hc * vc, nullptr);
    bgspr.clear();
    bgspr.resize(hc * vc, {nullptr, nullptr});
    for (int i = 0; i < vc; ++i)
        for (int j = 0; j < hc; ++j)
        {
            auto t = s->addSimpleText(QString::number(i * hc + j));
            t->setPos(j * 128 + 64 - t->boundingRect().width() / 2, i * 128 + 64 - t->boundingRect().height() / 2);
            auto r = new drop_rect(i * hc + j, this);
            s->addItem(r);
            bgspr[i * hc + j] = {t, r};
            r->setPos(j * 128, i * 128);
        }
}

void map_painter::set_map_id(int pos, bool populated, int id, bool user_input)
{
    if (!l || pos >= hc * vc || pos < 0) return;
    if (slices[pos])
    {
        s->removeItem(slices[pos]);
        delete slices[pos];
        slices[pos] = nullptr;
    }
    auto [t, r] = bgspr[pos];
    if (populated)
    {
        QPixmap pm;
        if (!QPixmapCache::find(QString("map_%1").arg(id), &pm))
        {
            pm = pixmap_of_map_data(l->get_map(id).map_data);
            QPixmapCache::insert(QString("map_%1").arg(id), pm);
        }
        auto p = s->addPixmap(pm);
        int x = pos / hc;
        int y = pos % hc;
        p->setPos(y * 128, x * 128);
        slices[pos] = p;
        static_cast<QAbstractGraphicsShapeItem*>(t)->setPen(QColor(Qt::GlobalColor::transparent));
        static_cast<QAbstractGraphicsShapeItem*>(r)->setPen(QColor(Qt::GlobalColor::transparent));
    }
    if (user_input)
        emit map_id_changed(pos, populated, id);
}

void map_painter::set_map_library(map_library *lib) { l = lib; }