diff options
Diffstat (limited to 'meshmc/launcher/icons')
| -rw-r--r-- | meshmc/launcher/icons/IconList.cpp | 421 | ||||
| -rw-r--r-- | meshmc/launcher/icons/IconList.h | 118 | ||||
| -rw-r--r-- | meshmc/launcher/icons/IconUtils.cpp | 81 | ||||
| -rw-r--r-- | meshmc/launcher/icons/IconUtils.h | 36 | ||||
| -rw-r--r-- | meshmc/launcher/icons/MMCIcon.cpp | 134 | ||||
| -rw-r--r-- | meshmc/launcher/icons/MMCIcon.h | 77 |
6 files changed, 867 insertions, 0 deletions
diff --git a/meshmc/launcher/icons/IconList.cpp b/meshmc/launcher/icons/IconList.cpp new file mode 100644 index 0000000000..cc88dd0560 --- /dev/null +++ b/meshmc/launcher/icons/IconList.cpp @@ -0,0 +1,421 @@ +/* SPDX-FileCopyrightText: 2026 Project Tick + * SPDX-FileContributor: Project Tick + * SPDX-License-Identifier: GPL-3.0-or-later + * + * MeshMC - A Custom Launcher for Minecraft + * Copyright (C) 2026 Project Tick + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * Copyright 2013-2021 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "IconList.h" +#include <FileSystem.h> +#include <QMap> +#include <QEventLoop> +#include <QMimeData> +#include <QUrl> +#include <QFileSystemWatcher> +#include <QSet> +#include <QDebug> + +#define MAX_SIZE 1024 + +IconList::IconList(const QStringList& builtinPaths, QString path, + QObject* parent) + : QAbstractListModel(parent) +{ + QSet<QString> builtinNames; + + // add builtin icons + for (auto& builtinPath : builtinPaths) { + QDir instance_icons(builtinPath); + auto file_info_list = + instance_icons.entryInfoList(QDir::Files, QDir::Name); + for (auto file_info : file_info_list) { + builtinNames.insert(file_info.baseName()); + } + } + for (auto& builtinName : builtinNames) { + addThemeIcon(builtinName); + } + + m_watcher.reset(new QFileSystemWatcher()); + is_watching = false; + connect(m_watcher.get(), SIGNAL(directoryChanged(QString)), + SLOT(directoryChanged(QString))); + connect(m_watcher.get(), SIGNAL(fileChanged(QString)), + SLOT(fileChanged(QString))); + + directoryChanged(path); +} + +void IconList::directoryChanged(const QString& path) +{ + QDir new_dir(path); + if (m_dir.absolutePath() != new_dir.absolutePath()) { + m_dir.setPath(path); + m_dir.refresh(); + if (is_watching) + stopWatching(); + startWatching(); + } + if (!m_dir.exists()) + if (!FS::ensureFolderPathExists(m_dir.absolutePath())) + return; + m_dir.refresh(); + auto new_list = m_dir.entryList(QDir::Files, QDir::Name); + for (auto it = new_list.begin(); it != new_list.end(); it++) { + QString& foo = (*it); + foo = m_dir.filePath(foo); + } + auto new_set = QSet<QString>(new_list.begin(), new_list.end()); + QList<QString> current_list; + for (auto& it : icons) { + if (!it.has(IconType::FileBased)) + continue; + current_list.push_back(it.m_images[IconType::FileBased].filename); + } + QSet<QString> current_set(current_list.begin(), current_list.end()); + + QSet<QString> to_remove = current_set; + to_remove -= new_set; + + QSet<QString> to_add = new_set; + to_add -= current_set; + + for (auto remove : to_remove) { + qDebug() << "Removing " << remove; + QFileInfo rmfile(remove); + QString key = rmfile.baseName(); + int idx = getIconIndex(key); + if (idx == -1) + continue; + icons[idx].remove(IconType::FileBased); + if (icons[idx].type() == IconType::ToBeDeleted) { + beginRemoveRows(QModelIndex(), idx, idx); + icons.remove(idx); + reindex(); + endRemoveRows(); + } else { + dataChanged(index(idx), index(idx)); + } + m_watcher->removePath(remove); + emit iconUpdated(key); + } + + for (auto add : to_add) { + qDebug() << "Adding " << add; + QFileInfo addfile(add); + QString key = addfile.baseName(); + if (addIcon(key, QString(), addfile.filePath(), IconType::FileBased)) { + m_watcher->addPath(add); + emit iconUpdated(key); + } + } +} + +void IconList::fileChanged(const QString& path) +{ + qDebug() << "Checking " << path; + QFileInfo checkfile(path); + if (!checkfile.exists()) + return; + QString key = checkfile.baseName(); + int idx = getIconIndex(key); + if (idx == -1) + return; + QIcon icon(path); + if (!icon.availableSizes().size()) + return; + + icons[idx].m_images[IconType::FileBased].icon = icon; + dataChanged(index(idx), index(idx)); + emit iconUpdated(key); +} + +void IconList::SettingChanged(const Setting& setting, QVariant value) +{ + if (setting.id() != "IconsDir") + return; + + directoryChanged(value.toString()); +} + +void IconList::startWatching() +{ + auto abs_path = m_dir.absolutePath(); + FS::ensureFolderPathExists(abs_path); + is_watching = m_watcher->addPath(abs_path); + if (is_watching) { + qDebug() << "Started watching " << abs_path; + } else { + qDebug() << "Failed to start watching " << abs_path; + } +} + +void IconList::stopWatching() +{ + m_watcher->removePaths(m_watcher->files()); + m_watcher->removePaths(m_watcher->directories()); + is_watching = false; +} + +QStringList IconList::mimeTypes() const +{ + QStringList types; + types << "text/uri-list"; + return types; +} +Qt::DropActions IconList::supportedDropActions() const +{ + return Qt::CopyAction; +} + +bool IconList::dropMimeData(const QMimeData* data, Qt::DropAction action, + int row, int column, const QModelIndex& parent) +{ + if (action == Qt::IgnoreAction) + return true; + // check if the action is supported + if (!data || !(action & supportedDropActions())) + return false; + + // files dropped from outside? + if (data->hasUrls()) { + auto urls = data->urls(); + QStringList iconFiles; + for (auto url : urls) { + // only local files may be dropped... + if (!url.isLocalFile()) + continue; + iconFiles += url.toLocalFile(); + } + installIcons(iconFiles); + return true; + } + return false; +} + +Qt::ItemFlags IconList::flags(const QModelIndex& index) const +{ + Qt::ItemFlags defaultFlags = QAbstractListModel::flags(index); + if (index.isValid()) + return Qt::ItemIsDropEnabled | defaultFlags; + else + return Qt::ItemIsDropEnabled | defaultFlags; +} + +QVariant IconList::data(const QModelIndex& index, int role) const +{ + if (!index.isValid()) + return QVariant(); + + int row = index.row(); + + if (row < 0 || row >= icons.size()) + return QVariant(); + + switch (role) { + case Qt::DecorationRole: + return icons[row].icon(); + case Qt::DisplayRole: + return icons[row].name(); + case Qt::UserRole: + return icons[row].m_key; + default: + return QVariant(); + } +} + +int IconList::rowCount(const QModelIndex& parent) const +{ + return icons.size(); +} + +void IconList::installIcons(const QStringList& iconFiles) +{ + for (QString file : iconFiles) { + QFileInfo fileinfo(file); + if (!fileinfo.isReadable() || !fileinfo.isFile()) + continue; + QString target = FS::PathCombine(m_dir.dirName(), fileinfo.fileName()); + + QString suffix = fileinfo.suffix(); + if (suffix != "jpeg" && suffix != "png" && suffix != "jpg" && + suffix != "ico" && suffix != "svg" && suffix != "gif") + continue; + + if (!QFile::copy(file, target)) + continue; + } +} + +void IconList::installIcon(const QString& file, const QString& name) +{ + QFileInfo fileinfo(file); + if (!fileinfo.isReadable() || !fileinfo.isFile()) + return; + + QString target = FS::PathCombine(m_dir.dirName(), name); + + QFile::copy(file, target); +} + +bool IconList::iconFileExists(const QString& key) const +{ + auto iconEntry = icon(key); + if (!iconEntry) { + return false; + } + return iconEntry->has(IconType::FileBased); +} + +const MMCIcon* IconList::icon(const QString& key) const +{ + int iconIdx = getIconIndex(key); + if (iconIdx == -1) + return nullptr; + return &icons[iconIdx]; +} + +bool IconList::deleteIcon(const QString& key) +{ + int iconIdx = getIconIndex(key); + if (iconIdx == -1) + return false; + auto& iconEntry = icons[iconIdx]; + if (iconEntry.has(IconType::FileBased)) { + return QFile::remove(iconEntry.m_images[IconType::FileBased].filename); + } + return false; +} + +bool IconList::addThemeIcon(const QString& key) +{ + auto iter = name_index.find(key); + if (iter != name_index.end()) { + auto& oldOne = icons[*iter]; + oldOne.replace(Builtin, key); + dataChanged(index(*iter), index(*iter)); + return true; + } else { + // add a new icon + beginInsertRows(QModelIndex(), icons.size(), icons.size()); + { + MMCIcon mmc_icon; + mmc_icon.m_name = key; + mmc_icon.m_key = key; + mmc_icon.replace(Builtin, key); + icons.push_back(mmc_icon); + name_index[key] = icons.size() - 1; + } + endInsertRows(); + return true; + } +} + +bool IconList::addIcon(const QString& key, const QString& name, + const QString& path, const IconType type) +{ + // replace the icon even? is the input valid? + QIcon icon(path); + if (icon.isNull()) + return false; + auto iter = name_index.find(key); + if (iter != name_index.end()) { + auto& oldOne = icons[*iter]; + oldOne.replace(type, icon, path); + dataChanged(index(*iter), index(*iter)); + return true; + } else { + // add a new icon + beginInsertRows(QModelIndex(), icons.size(), icons.size()); + { + MMCIcon mmc_icon; + mmc_icon.m_name = name; + mmc_icon.m_key = key; + mmc_icon.replace(type, icon, path); + icons.push_back(mmc_icon); + name_index[key] = icons.size() - 1; + } + endInsertRows(); + return true; + } +} + +void IconList::saveIcon(const QString& key, const QString& path, + const char* format) const +{ + auto icon = getIcon(key); + auto pixmap = icon.pixmap(128, 128); + pixmap.save(path, format); +} + +void IconList::reindex() +{ + name_index.clear(); + int i = 0; + for (auto& iter : icons) { + name_index[iter.m_key] = i; + i++; + } +} + +QIcon IconList::getIcon(const QString& key) const +{ + int icon_index = getIconIndex(key); + + if (icon_index != -1) + return icons[icon_index].icon(); + + // Fallback for icons that don't exist. + icon_index = getIconIndex("grass"); + + if (icon_index != -1) + return icons[icon_index].icon(); + return QIcon(); +} + +int IconList::getIconIndex(const QString& key) const +{ + auto iter = name_index.find(key == "default" ? "grass" : key); + if (iter != name_index.end()) + return *iter; + + return -1; +} + +QString IconList::getDirectory() const +{ + return m_dir.absolutePath(); +} + +// #include "IconList.moc" diff --git a/meshmc/launcher/icons/IconList.h b/meshmc/launcher/icons/IconList.h new file mode 100644 index 0000000000..96c95e1b2a --- /dev/null +++ b/meshmc/launcher/icons/IconList.h @@ -0,0 +1,118 @@ +/* SPDX-FileCopyrightText: 2026 Project Tick + * SPDX-FileContributor: Project Tick + * SPDX-License-Identifier: GPL-3.0-or-later + * + * MeshMC - A Custom Launcher for Minecraft + * Copyright (C) 2026 Project Tick + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * Copyright 2013-2021 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include <QMutex> +#include <QAbstractListModel> +#include <QFile> +#include <QDir> +#include <QtGui/QIcon> +#include <memory> + +#include "MMCIcon.h" +#include "settings/Setting.h" + +#include "QObjectPtr.h" + +class QFileSystemWatcher; + +class IconList : public QAbstractListModel +{ + Q_OBJECT + public: + explicit IconList(const QStringList& builtinPaths, QString path, + QObject* parent = 0); + virtual ~IconList() {}; + + QIcon getIcon(const QString& key) const; + int getIconIndex(const QString& key) const; + QString getDirectory() const; + + virtual QVariant data(const QModelIndex& index, + int role = Qt::DisplayRole) const override; + virtual int + rowCount(const QModelIndex& parent = QModelIndex()) const override; + + virtual QStringList mimeTypes() const override; + virtual Qt::DropActions supportedDropActions() const override; + virtual bool dropMimeData(const QMimeData* data, Qt::DropAction action, + int row, int column, + const QModelIndex& parent) override; + virtual Qt::ItemFlags flags(const QModelIndex& index) const override; + + bool addThemeIcon(const QString& key); + bool addIcon(const QString& key, const QString& name, const QString& path, + const IconType type); + void saveIcon(const QString& key, const QString& path, + const char* format) const; + bool deleteIcon(const QString& key); + bool iconFileExists(const QString& key) const; + + void installIcons(const QStringList& iconFiles); + void installIcon(const QString& file, const QString& name); + + const MMCIcon* icon(const QString& key) const; + + void startWatching(); + void stopWatching(); + + signals: + void iconUpdated(QString key); + + private: + // hide copy constructor + IconList(const IconList&) = delete; + // hide assign op + IconList& operator=(const IconList&) = delete; + void reindex(); + + public slots: + void directoryChanged(const QString& path); + + protected slots: + void fileChanged(const QString& path); + void SettingChanged(const Setting& setting, QVariant value); + + private: + shared_qobject_ptr<QFileSystemWatcher> m_watcher; + bool is_watching; + QMap<QString, int> name_index; + QVector<MMCIcon> icons; + QDir m_dir; +}; diff --git a/meshmc/launcher/icons/IconUtils.cpp b/meshmc/launcher/icons/IconUtils.cpp new file mode 100644 index 0000000000..60ab6df406 --- /dev/null +++ b/meshmc/launcher/icons/IconUtils.cpp @@ -0,0 +1,81 @@ +/* SPDX-FileCopyrightText: 2026 Project Tick + * SPDX-FileContributor: Project Tick + * SPDX-License-Identifier: GPL-3.0-or-later + * + * MeshMC - A Custom Launcher for Minecraft + * Copyright (C) 2026 Project Tick + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#include "IconUtils.h" + +#include "FileSystem.h" +#include <QDirIterator> + +#include <array> + +namespace +{ + std::array<const char*, 6> validIconExtensions = { + {"svg", "png", "ico", "gif", "jpg", "jpeg"}}; +} + +namespace IconUtils +{ + + QString findBestIconIn(const QString& folder, const QString& iconKey) + { + int best_found = validIconExtensions.size(); + QString best_filename; + + QDirIterator it(folder, QDir::NoDotAndDotDot | QDir::Files, + QDirIterator::NoIteratorFlags); + while (it.hasNext()) { + it.next(); + auto fileInfo = it.fileInfo(); + + if (fileInfo.completeBaseName() != iconKey) + continue; + + auto extension = fileInfo.suffix(); + + for (int i = 0; i < best_found; i++) { + if (extension == validIconExtensions[i]) { + best_found = i; + qDebug() << i << " : " << fileInfo.fileName(); + best_filename = fileInfo.fileName(); + } + } + } + return FS::PathCombine(folder, best_filename); + } + + QString getIconFilter() + { + QString out; + QTextStream stream(&out); + stream << '('; + for (size_t i = 0; i < validIconExtensions.size() - 1; i++) { + if (i > 0) { + stream << " "; + } + stream << "*." << validIconExtensions[i]; + } + stream << " *." << validIconExtensions[validIconExtensions.size() - 1]; + stream << ')'; + return out; + } + +} // namespace IconUtils diff --git a/meshmc/launcher/icons/IconUtils.h b/meshmc/launcher/icons/IconUtils.h new file mode 100644 index 0000000000..a3c0216d4c --- /dev/null +++ b/meshmc/launcher/icons/IconUtils.h @@ -0,0 +1,36 @@ +/* SPDX-FileCopyrightText: 2026 Project Tick + * SPDX-FileContributor: Project Tick + * SPDX-License-Identifier: GPL-3.0-or-later + * + * MeshMC - A Custom Launcher for Minecraft + * Copyright (C) 2026 Project Tick + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#pragma once + +#include <QString> + +namespace IconUtils +{ + + // Given a folder and an icon key, find 'best' of the icons with the given + // key in there and return its path + QString findBestIconIn(const QString& folder, const QString& iconKey); + + // Get icon file type filter for file browser dialogs + QString getIconFilter(); + +} // namespace IconUtils diff --git a/meshmc/launcher/icons/MMCIcon.cpp b/meshmc/launcher/icons/MMCIcon.cpp new file mode 100644 index 0000000000..4784f172fd --- /dev/null +++ b/meshmc/launcher/icons/MMCIcon.cpp @@ -0,0 +1,134 @@ +/* SPDX-FileCopyrightText: 2026 Project Tick + * SPDX-FileContributor: Project Tick + * SPDX-License-Identifier: GPL-3.0-or-later + * + * MeshMC - A Custom Launcher for Minecraft + * Copyright (C) 2026 Project Tick + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * Copyright 2013-2021 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "MMCIcon.h" +#include <QFileInfo> +#include <xdgicon.h> + +IconType operator--(IconType& t, int) +{ + IconType temp = t; + switch (t) { + case IconType::Builtin: + t = IconType::ToBeDeleted; + break; + case IconType::Transient: + t = IconType::Builtin; + break; + case IconType::FileBased: + t = IconType::Transient; + break; + default: { + } + } + return temp; +} + +IconType MMCIcon::type() const +{ + return m_current_type; +} + +QString MMCIcon::name() const +{ + if (m_name.size()) + return m_name; + return m_key; +} + +bool MMCIcon::has(IconType _type) const +{ + return m_images[_type].present(); +} + +QIcon MMCIcon::icon() const +{ + if (m_current_type == IconType::ToBeDeleted) + return QIcon(); + auto& icon = m_images[m_current_type].icon; + if (!icon.isNull()) + return icon; + // FIXME: inject this. + return XdgIcon::fromTheme(m_images[m_current_type].key); +} + +void MMCIcon::remove(IconType rm_type) +{ + m_images[rm_type].filename = QString(); + m_images[rm_type].icon = QIcon(); + for (auto iter = rm_type; iter != IconType::ToBeDeleted; iter--) { + if (m_images[iter].present()) { + m_current_type = iter; + return; + } + } + m_current_type = IconType::ToBeDeleted; +} + +void MMCIcon::replace(IconType new_type, QIcon icon, QString path) +{ + if (new_type > m_current_type || m_current_type == IconType::ToBeDeleted) { + m_current_type = new_type; + } + m_images[new_type].icon = icon; + m_images[new_type].filename = path; + m_images[new_type].key = QString(); +} + +void MMCIcon::replace(IconType new_type, const QString& key) +{ + if (new_type > m_current_type || m_current_type == IconType::ToBeDeleted) { + m_current_type = new_type; + } + m_images[new_type].icon = QIcon(); + m_images[new_type].filename = QString(); + m_images[new_type].key = key; +} + +QString MMCIcon::getFilePath() const +{ + if (m_current_type == IconType::ToBeDeleted) { + return QString(); + } + return m_images[m_current_type].filename; +} + +bool MMCIcon::isBuiltIn() const +{ + return m_current_type == IconType::Builtin; +} diff --git a/meshmc/launcher/icons/MMCIcon.h b/meshmc/launcher/icons/MMCIcon.h new file mode 100644 index 0000000000..cc934c4c2e --- /dev/null +++ b/meshmc/launcher/icons/MMCIcon.h @@ -0,0 +1,77 @@ +/* SPDX-FileCopyrightText: 2026 Project Tick + * SPDX-FileContributor: Project Tick + * SPDX-License-Identifier: GPL-3.0-or-later + * + * MeshMC - A Custom Launcher for Minecraft + * Copyright (C) 2026 Project Tick + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * Copyright 2013-2021 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once +#include <QString> +#include <QDateTime> +#include <QIcon> + +enum IconType : unsigned { + Builtin, + Transient, + FileBased, + ICONS_TOTAL, + ToBeDeleted +}; + +struct MMCImage { + QIcon icon; + QString key; + QString filename; + bool present() const + { + return !icon.isNull() || !key.isEmpty(); + } +}; + +struct MMCIcon { + QString m_key; + QString m_name; + MMCImage m_images[ICONS_TOTAL]; + IconType m_current_type = ToBeDeleted; + + IconType type() const; + QString name() const; + bool has(IconType _type) const; + QIcon icon() const; + void remove(IconType rm_type); + void replace(IconType new_type, QIcon icon, QString path = QString()); + void replace(IconType new_type, const QString& key); + bool isBuiltIn() const; + QString getFilePath() const; +}; |
