all repos — mgba @ c9e1f5d6a62fdea62acc56c55fec310a8b91dcb4

mGBA Game Boy Advance Emulator

src/platform/qt/BattleChipModel.cpp (view raw)

  1/* Copyright (c) 2013-2019 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 "BattleChipModel.h"
  7
  8#include "ConfigController.h"
  9#include "GBAApp.h"
 10
 11#include <QFile>
 12#include <QMimeData>
 13#include <QResource>
 14
 15using namespace QGBA;
 16
 17BattleChipModel::BattleChipModel(QObject* parent)
 18	: QAbstractListModel(parent)
 19{
 20	QResource::registerResource(GBAApp::dataDir() + "/chips.rcc", "/exe");
 21	QResource::registerResource(ConfigController::configDir() + "/chips.rcc", "/exe");
 22}
 23
 24int BattleChipModel::rowCount(const QModelIndex& parent) const {
 25	if (parent.isValid()) {
 26		return 0;
 27	}
 28	return m_deck.count();
 29}
 30
 31QVariant BattleChipModel::data(const QModelIndex& index, int role) const {
 32	const BattleChip& item = m_deck[index.row()];
 33
 34	switch (role) {
 35	case Qt::DisplayRole:
 36		return item.name;
 37	case Qt::DecorationRole:
 38		return item.icon.scaled(item.icon.size() * m_scale);
 39	case Qt::UserRole:
 40		return item.id;
 41	}
 42	return QVariant();
 43}
 44
 45Qt::ItemFlags BattleChipModel::flags(const QModelIndex& index) const {
 46	return Qt::ItemIsSelectable | Qt::ItemIsDropEnabled | Qt::ItemIsDragEnabled | Qt::ItemIsEnabled | Qt::ItemNeverHasChildren;
 47}
 48
 49bool BattleChipModel::removeRows(int row, int count, const QModelIndex& parent) {
 50	if (parent.isValid()) {
 51		return false;
 52	}
 53	beginRemoveRows(QModelIndex(), row, row + count - 1);
 54	for (size_t i = 0; i < count; ++i) {
 55		m_deck.removeAt(row);
 56	}
 57	endRemoveRows();
 58	return true;
 59}
 60
 61QStringList BattleChipModel::mimeTypes() const {
 62	return {"text/plain"};
 63}
 64
 65Qt::DropActions BattleChipModel::supportedDropActions() const {
 66	return Qt::MoveAction;
 67}
 68
 69QMimeData* BattleChipModel::mimeData(const QModelIndexList& indices) const {
 70	QStringList deck;
 71	for (const QModelIndex& index : indices) {
 72		if (index.parent().isValid()) {
 73			continue;
 74		}
 75		deck.append(QString::number(m_deck[index.row()].id));
 76	}
 77
 78	QMimeData* mimeData = new QMimeData();
 79	mimeData->setData("text/plain", deck.join(',').toLocal8Bit());
 80	return mimeData;
 81}
 82
 83bool BattleChipModel::dropMimeData(const QMimeData* data, Qt::DropAction, int row, int, const QModelIndex& parent) {
 84	if (parent.parent().isValid()) {
 85		return false;
 86	}
 87	QStringList deck = QString::fromLocal8Bit(data->data("text/plain")).split(',');
 88	if (deck.isEmpty()) {
 89		return true;
 90	}
 91
 92	row = parent.row();
 93	beginInsertRows(QModelIndex(), row, row + deck.count() - 1);
 94	for (int i = 0; i < deck.count(); ++i) {
 95		int id = deck[i].toInt();
 96		m_deck.insert(row + i, createChip(id));
 97	}
 98	endInsertRows();
 99	return true;
100}
101
102void BattleChipModel::setFlavor(int flavor) {
103	m_chipIdToName.clear();
104	if (flavor == GBA_FLAVOR_BEAST_LINK_GATE_US) {
105		flavor = GBA_FLAVOR_BEAST_LINK_GATE;
106	}
107	m_flavor = flavor;
108
109	QFile file(QString(":/exe/exe%1/chip-names.txt").arg(flavor));
110	file.open(QIODevice::ReadOnly | QIODevice::Text);
111	int id = 0;
112	while (true) {
113		QByteArray line = file.readLine();
114		if (line.isEmpty()) {
115			break;
116		}
117		++id;
118		if (line.trimmed().isEmpty()) {
119			continue;
120		}
121		QString name = QString::fromUtf8(line).trimmed();
122		m_chipIdToName[id] = name;
123	}
124
125}
126
127void BattleChipModel::addChip(int id) {
128	beginInsertRows(QModelIndex(), m_deck.count(), m_deck.count());
129	m_deck.append(createChip(id));
130	endInsertRows();
131}
132
133void BattleChipModel::removeChip(const QModelIndex& index) {
134	beginRemoveRows(QModelIndex(), index.row(), index.row());
135	m_deck.removeAt(index.row());
136	endRemoveRows();
137}
138
139void BattleChipModel::setChips(QList<int> ids) {
140	beginResetModel();
141	m_deck.clear();
142	for (int id : ids) {
143		m_deck.append(createChip(id));
144	}
145	endResetModel();
146}
147
148void BattleChipModel::clear() {
149	beginResetModel();
150	m_deck.clear();
151	endResetModel();
152}
153
154void BattleChipModel::setScale(int scale) {
155	m_scale = scale;
156}
157
158void BattleChipModel::reloadAssets() {
159	QResource::unregisterResource(ConfigController::configDir() + "/chips.rcc", "/exe");
160	QResource::unregisterResource(GBAApp::dataDir() + "/chips.rcc", "/exe");
161
162	QResource::registerResource(GBAApp::dataDir() + "/chips.rcc", "/exe");
163	QResource::registerResource(ConfigController::configDir() + "/chips.rcc", "/exe");
164
165	emit layoutAboutToBeChanged();
166	setFlavor(m_flavor);
167	for (int i = 0; i < m_deck.count(); ++i) {
168		m_deck[i] = createChip(m_deck[i].id);
169	}
170	emit layoutChanged();
171}
172
173BattleChipModel::BattleChip BattleChipModel::createChip(int id) const {
174	QString path = QString(":/exe/exe%1/%2.png").arg(m_flavor).arg(id, 3, 10, QLatin1Char('0'));
175	if (!QFile(path).exists()) {
176		path = QString(":/exe/exe%1/placeholder.png").arg(m_flavor);
177	}
178	QPixmap icon(path);
179
180	BattleChip chip = {
181		id,
182		m_chipIdToName[id],
183		icon
184	};
185	return chip;
186}