src/platform/qt/TileView.cpp (view raw)
1/* Copyright (c) 2013-2016 Jeffrey Pfau
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6#include "TileView.h"
7
8#include "CoreController.h"
9#include "GBAApp.h"
10
11#include <QAction>
12#include <QClipboard>
13#include <QTimer>
14
15#ifdef M_CORE_GB
16#include <mgba/internal/gb/gb.h>
17#endif
18
19using namespace QGBA;
20
21TileView::TileView(std::shared_ptr<CoreController> controller, QWidget* parent)
22 : AssetView(controller, parent)
23 , m_controller(controller)
24{
25 m_ui.setupUi(this);
26 m_ui.tile->setController(controller);
27
28 connect(m_ui.tiles, &TilePainter::indexPressed, m_ui.tile, &AssetTile::selectIndex);
29 connect(m_ui.tiles, &TilePainter::needsRedraw, this, [this]() {
30 updateTiles(true);
31 });
32 connect(m_ui.paletteId, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &TileView::updatePalette);
33
34 switch (m_controller->platform()) {
35#ifdef M_CORE_GBA
36 case mPLATFORM_GBA:
37 m_ui.tile->setBoundary(2048, 0, 2);
38 break;
39#endif
40#ifdef M_CORE_GB
41 case mPLATFORM_GB:
42 m_ui.palette256->setEnabled(false);
43 m_ui.tile->setBoundary(1024, 0, 0);
44 break;
45#endif
46 default:
47 return;
48 }
49
50 connect(m_ui.palette256, &QAbstractButton::toggled, [this](bool selected) {
51 if (selected) {
52 m_ui.paletteId->setValue(0);
53 }
54 switch (m_controller->platform()) {
55#ifdef M_CORE_GBA
56 case mPLATFORM_GBA:
57 m_ui.tile->setBoundary(2048 >> selected, selected, selected + 2);
58 break;
59#endif
60#ifdef M_CORE_GB
61 case mPLATFORM_GB:
62 return;
63#endif
64 default:
65 break;
66 }
67 updateTiles(true);
68 });
69 connect(m_ui.magnification, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), [this](int mag) {
70 if (!m_ui.tileFit->isChecked()) {
71 m_ui.tiles->setMinimumSize(mag * 8 * m_ui.tilesPerRow->value(), m_ui.tiles->minimumSize().height());
72 }
73 updateTiles(true);
74 });
75
76 connect(m_ui.tilesPerRow, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), [this](int count) {
77 m_ui.tiles->setMinimumSize(m_ui.magnification->value() * 8 * count, m_ui.tiles->minimumSize().height());
78 updateTiles(true);
79 });
80
81 connect(m_ui.tileFit, &QAbstractButton::toggled, [this](bool selected) {
82 if (!selected) {
83 m_ui.tiles->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
84 m_ui.tiles->setMinimumSize(m_ui.magnification->value() * 8 * m_ui.tilesPerRow->value(), m_ui.tiles->minimumSize().height());
85 } else {
86 m_ui.tiles->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
87 }
88 updateTiles(true);
89 });
90
91 connect(m_ui.exportAll, &QAbstractButton::clicked, this, &TileView::exportTiles);
92 connect(m_ui.exportOne, &QAbstractButton::clicked, this, &TileView::exportTile);
93 connect(m_ui.copyAll, &QAbstractButton::clicked, this, &TileView::copyTiles);
94 connect(m_ui.copyOne, &QAbstractButton::clicked, this, &TileView::copyTile);
95
96 QAction* exportAll = new QAction(this);
97 exportAll->setShortcut(QKeySequence::Save);
98 connect(exportAll, &QAction::triggered, this, &TileView::exportTiles);
99 addAction(exportAll);
100
101 QAction* copyOne = new QAction(this);
102 copyOne->setShortcut(QKeySequence::Copy);
103 connect(copyOne, &QAction::triggered, this, &TileView::copyTile);
104 addAction(copyOne);
105}
106
107#ifdef M_CORE_GBA
108void TileView::updateTilesGBA(bool force) {
109 if (m_ui.palette256->isChecked()) {
110 m_ui.tiles->setTileCount(1536);
111 mTileCache* cache = mTileCacheSetGetPointer(&m_cacheSet->tiles, 1);
112 for (int i = 0; i < 1024; ++i) {
113 const color_t* data = mTileCacheGetTileIfDirty(cache, &m_tileStatus[16 * i], i, 0);
114 if (data) {
115 m_ui.tiles->setTile(i, data);
116 } else if (force) {
117 m_ui.tiles->setTile(i, mTileCacheGetTile(cache, i, 0));
118 }
119 }
120 cache = mTileCacheSetGetPointer(&m_cacheSet->tiles, 3);
121 for (int i = 1024; i < 1536; ++i) {
122 const color_t* data = mTileCacheGetTileIfDirty(cache, &m_tileStatus[16 * i], i - 1024, 0);
123 if (data) {
124 m_ui.tiles->setTile(i, data);
125 } else if (force) {
126 m_ui.tiles->setTile(i, mTileCacheGetTile(cache, i - 1024, 0));
127 }
128 }
129 } else {
130 mTileCache* cache = mTileCacheSetGetPointer(&m_cacheSet->tiles, 0);
131 m_ui.tiles->setTileCount(3072);
132 for (int i = 0; i < 2048; ++i) {
133 const color_t* data = mTileCacheGetTileIfDirty(cache, &m_tileStatus[16 * i], i, m_paletteId);
134 if (data) {
135 m_ui.tiles->setTile(i, data);
136 } else if (force) {
137 m_ui.tiles->setTile(i, mTileCacheGetTile(cache, i, m_paletteId));
138 }
139 }
140 cache = mTileCacheSetGetPointer(&m_cacheSet->tiles, 2);
141 for (int i = 2048; i < 3072; ++i) {
142 const color_t* data = mTileCacheGetTileIfDirty(cache, &m_tileStatus[16 * i], i - 2048, m_paletteId);
143 if (data) {
144 m_ui.tiles->setTile(i, data);
145 } else if (force) {
146 m_ui.tiles->setTile(i, mTileCacheGetTile(cache, i - 2048, m_paletteId));
147 }
148 }
149 }
150}
151#endif
152
153#ifdef M_CORE_GB
154void TileView::updateTilesGB(bool force) {
155 const GB* gb = static_cast<const GB*>(m_controller->thread()->core->board);
156 int count = gb->model >= GB_MODEL_CGB ? 1024 : 512;
157 m_ui.tiles->setTileCount(count);
158 mTileCache* cache = mTileCacheSetGetPointer(&m_cacheSet->tiles, 0);
159 for (int i = 0; i < count; ++i) {
160 const color_t* data = mTileCacheGetTileIfDirty(cache, &m_tileStatus[8 * i], i, m_paletteId);
161 if (data) {
162 m_ui.tiles->setTile(i, data);
163 } else if (force) {
164 m_ui.tiles->setTile(i, mTileCacheGetTile(cache, i, m_paletteId));
165 }
166 }
167}
168#endif
169
170void TileView::updatePalette(int palette) {
171 m_paletteId = palette;
172 m_ui.tile->setPalette(palette);
173 updateTiles(true);
174}
175
176void TileView::exportTiles() {
177 QString filename = GBAApp::app()->getSaveFileName(this, tr("Export tiles"),
178 tr("Portable Network Graphics (*.png)"));
179 if (filename.isNull()) {
180 return;
181 }
182 CoreController::Interrupter interrupter(m_controller);
183 updateTiles(false);
184 QPixmap pixmap(m_ui.tiles->backing());
185 pixmap.save(filename, "PNG");
186}
187
188void TileView::exportTile() {
189 QString filename = GBAApp::app()->getSaveFileName(this, tr("Export tile"),
190 tr("Portable Network Graphics (*.png)"));
191 if (filename.isNull()) {
192 return;
193 }
194 CoreController::Interrupter interrupter(m_controller);
195 updateTiles(false);
196 QImage image(m_ui.tile->activeTile());
197 image.save(filename, "PNG");
198}
199
200void TileView::copyTiles() {
201 CoreController::Interrupter interrupter(m_controller);
202 updateTiles(false);
203 GBAApp::app()->clipboard()->setPixmap(m_ui.tiles->backing());
204}
205
206void TileView::copyTile() {
207 CoreController::Interrupter interrupter(m_controller);
208 updateTiles(false);
209 GBAApp::app()->clipboard()->setImage(m_ui.tile->activeTile());
210}