structurelibraryview.cpp 5.58 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
/*
 * <32021 by Stellaris. Copying Art is an act of love. Love is not subject to law.
 */
#include "structurelibraryview.hpp"
#include "ui_structurelibraryview.h"

#include "structurereader.hpp"

#include <QFile>
#include <QTextStream>
Yann Boucher's avatar
Yann Boucher committed
11
12
#include <QPixmap>
#include <QImage>
13
14
15
#include <QDrag>
#include <QMimeData>

16
17
18
19
20
21
22
23
24
25
26
#include <QDebug>

StructureLibraryView::StructureLibraryView(QWidget *parent) :
    QFrame(parent),
    ui(new Ui::StructureLibraryView)
{
    ui->setupUi(this);

    load_structures();

    connect(ui->tree, &QTreeWidget::itemClicked, this, &StructureLibraryView::update_info);
27
    connect(ui->tree, &QTreeWidget::itemDoubleClicked, this, &StructureLibraryView::create_drag);
28
    connect(ui->button_copy, &QPushButton::pressed, this, &StructureLibraryView::copy_button_clicked);
29
30
31
32
    connect(&m_watcher, &QFileSystemWatcher::directoryChanged, [this](const QString&)
    {
        load_structures();
    });
33
34
35
36
37
38
39
40
41
}

StructureLibraryView::~StructureLibraryView()
{
    delete ui;
}

void StructureLibraryView::load_structures()
{
42
43
44
    // clear the previously watched directories
    m_watcher.removePaths(m_watcher.directories());

45
46
    QTreeWidgetItem* pattern_list = add_directory_contents(QDir("patterns/"));
    pattern_list->setText(0, "Patterns");
47
    ui->tree->clear();
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
    ui->tree->addTopLevelItem(pattern_list);
    pattern_list->setExpanded(true);
}

QTreeWidgetItem *StructureLibraryView::add_directory_contents(const QDir &dir)
{
    QTreeWidgetItem* root = new QTreeWidgetItem;

    QFileInfoList dirs = dir.entryInfoList(QStringList(), QDir::Dirs | QDir::NoDotAndDotDot);
    Q_FOREACH (QFileInfo dir, dirs)
    {
        QTreeWidgetItem *child = add_directory_contents(QDir(dir.absoluteFilePath()));
        // empty directory
        if (child->childCount() == 0)
            continue;

        child->setText(0, dir.fileName());
        root->addChild(child);
    }

    QFileInfoList files = dir.entryInfoList(QStringList() << "*.rle" << "*.json", QDir::Files);
    Q_FOREACH (QFileInfo file, files)
    {
        Structure s;
72
        bool valid = try_load_structure(file.absoluteFilePath(), s);
73
74
75
76
77
78
79
80
81
82
83
        if (!valid)
            continue;

        QTreeWidgetItem *child = new QTreeWidgetItem();
        child->setText(0, file.fileName());
        // data is the complete filepath of the structure, store it so it can be easily accessed when an item is selected
        child->setData(0, Qt::UserRole, file.absoluteFilePath());

        root->addChild(child);
    }

84
85
86
    // register this directory for filesystem watching
    m_watcher.addPath(dir.absolutePath());

87
88
89
    return root;
}

90
bool StructureLibraryView::try_load_structure(const QString &filename, Structure &s)
91
{
92
    try
93
    {
94
95
        s = load_structure(filename.toStdString());
        return true;
96
    }
97
    catch (const StructureReaderException& e)
98
    {
99
        //qDebug() << "StructureReaderException : " << e.what() << "\n";
100
        return false;
101
    }
102
103
}

Yann Boucher's avatar
Yann Boucher committed
104
105
106
107
108
void StructureLibraryView::update_preview(const Structure &s)
{
    QPixmap pix;

    /** to check wether load ok */
109
    if(pix.convertFromImage(create_preview_image(s, Qt::white))){
Yann Boucher's avatar
Yann Boucher committed
110
111
112
113
114
115
        /** scale pixmap to fit in label'size and keep ratio of pixmap */
        pix = pix.scaled(ui->preview->size() - 2*QSize(ui->preview->lineWidth(), ui->preview->lineWidth()),Qt::KeepAspectRatio);
        ui->preview->setPixmap(pix);
    }
}

116
117
118
119
120
121
122
123
124
125
QImage StructureLibraryView::create_preview_image(const Structure &s, QColor background)
{
    QImage img(s.width(), s.height(), QImage::Format_ARGB32);
    img.fill(background);
    for (const auto& cell : s)
        img.setPixelColor(cell.first.x, cell.first.y, QColor(Qt::black));

    return img;
}

126
127
128
129
130
void StructureLibraryView::update_info(QTreeWidgetItem *item, int column)
{
    (void)column;

    Structure s;
131
    if (!try_load_structure(item->data(0, Qt::UserRole).toString(), s))
132
133
134
135
    {
        ui->button_copy->setEnabled(false);
        return;
    }
Yann Boucher's avatar
Yann Boucher committed
136
137
138
139
    if (!s.title.empty())
        ui->struct_title->setText(QString::fromStdString(s.title));
    else
    {
Yann Boucher's avatar
Yann Boucher committed
140
        QString filename = QFileInfo(item->data(0, Qt::UserRole).toString()).baseName();
Yann Boucher's avatar
Yann Boucher committed
141
142
143
144
        if (!filename.isEmpty()) // failsafe, in case it actually is empty
            filename.replace(0, 1, filename[0].toUpper());
        ui->struct_title->setText(filename);
    }
145
146
147
    ui->struct_author->setText(QString::fromStdString(s.author));
    ui->struct_date->setText(QString::fromStdString(s.date));
    ui->struct_desc->setPlainText(QString::fromStdString(s.desc));
Yann Boucher's avatar
Yann Boucher committed
148
149
150
    ui->struct_size->setText(QString::number(s.width()) + "x" + QString::number(s.height()));

    update_preview(s);
151
152
153
154
155
156
157
158
159
160
161
162

    ui->button_copy->setEnabled(true);
}

void StructureLibraryView::copy_button_clicked()
{
    if (ui->tree->selectedItems().size() == 0)
        return;

    QTreeWidgetItem* item = ui->tree->selectedItems()[0];

    Structure s;
163
    if (!try_load_structure(item->data(0, Qt::UserRole).toString(), s))
164
165
166
167
        return;

    emit structure_copied(s);
}
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194

void StructureLibraryView::create_drag(QTreeWidgetItem *item, int column)
{
    (void)column;

    Structure s;
    if (!try_load_structure(item->data(0, Qt::UserRole).toString(), s))
    {
        ui->button_copy->setEnabled(false);
        return;
    }

    QDrag* drag = new QDrag(this);
    QMimeData* mimeData = new QMimeData;

    QString filename = QFileInfo(item->data(0, Qt::UserRole).toString()).absoluteFilePath();
    QPixmap pix;
    QImage img = create_preview_image(s, Qt::transparent);
    pix.convertFromImage(img);
    pix = pix.scaled(QSize(100, 100), Qt::KeepAspectRatio);

    mimeData->setText(filename);
    drag->setMimeData(mimeData);
    drag->setPixmap(pix);

    drag->exec(Qt::CopyAction);
}