cleaned up and improved GameOptions Model & Page
- added array support - cleaned up logic - ran clang-format - added description & default value columns - added basic editing support (bools only) - no saving Co-authored-by: TheLastRar <TheLastRar@users.noreply.github.com> Signed-off-by: Tayou <tayou@gmx.net>
This commit is contained in:
parent
564567a568
commit
511076d3ba
@ -1,129 +1,400 @@
|
||||
#include "GameOptions.h"
|
||||
#include <QDebug>
|
||||
#include <QSaveFile>
|
||||
#include "FileSystem.h"
|
||||
|
||||
namespace {
|
||||
bool load(const QString& path, std::vector<GameOptionItem>& contents, int& version)
|
||||
{
|
||||
contents.clear();
|
||||
QFile file(path);
|
||||
if (!file.open(QFile::ReadOnly)) {
|
||||
qWarning() << "Failed to read options file.";
|
||||
return false;
|
||||
}
|
||||
version = 0;
|
||||
while (!file.atEnd()) {
|
||||
auto line = file.readLine();
|
||||
if (line.endsWith('\n')) {
|
||||
line.chop(1);
|
||||
}
|
||||
auto separatorIndex = line.indexOf(':');
|
||||
if (separatorIndex == -1) {
|
||||
continue;
|
||||
}
|
||||
auto key = QString::fromUtf8(line.data(), separatorIndex);
|
||||
auto value = QString::fromUtf8(line.data() + separatorIndex + 1, line.size() - 1 - separatorIndex);
|
||||
qDebug() << "!!" << key << "!!";
|
||||
if (key == "version") {
|
||||
version = value.toInt();
|
||||
continue;
|
||||
}
|
||||
contents.emplace_back(GameOptionItem{ key, value });
|
||||
}
|
||||
qDebug() << "Loaded" << path << "with version:" << version;
|
||||
return true;
|
||||
}
|
||||
bool save(const QString& path, std::vector<GameOptionItem>& mapping, int version)
|
||||
{
|
||||
QSaveFile out(path);
|
||||
if (!out.open(QIODevice::WriteOnly)) {
|
||||
return false;
|
||||
}
|
||||
if (version != 0) {
|
||||
QString versionLine = QString("version:%1\n").arg(version);
|
||||
out.write(versionLine.toUtf8());
|
||||
}
|
||||
auto iter = mapping.begin();
|
||||
while (iter != mapping.end()) {
|
||||
out.write(iter->key.toUtf8());
|
||||
out.write(":");
|
||||
out.write(iter->value.toUtf8());
|
||||
out.write("\n");
|
||||
iter++;
|
||||
}
|
||||
return out.commit();
|
||||
}
|
||||
} // namespace
|
||||
|
||||
GameOptions::GameOptions(const QString& path) : path(path)
|
||||
{
|
||||
reload();
|
||||
}
|
||||
|
||||
QVariant GameOptions::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if (role != Qt::DisplayRole) {
|
||||
return QAbstractListModel::headerData(section, orientation, role);
|
||||
}
|
||||
switch (section) {
|
||||
case 0:
|
||||
return tr("Key");
|
||||
case 1:
|
||||
return tr("Value");
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
|
||||
QVariant GameOptions::data(const QModelIndex& index, int role) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return QVariant();
|
||||
|
||||
int row = index.row();
|
||||
int column = index.column();
|
||||
|
||||
if (row < 0 || row >= int(contents.size()))
|
||||
return QVariant();
|
||||
|
||||
switch (role) {
|
||||
case Qt::DisplayRole:
|
||||
if (column == 0) {
|
||||
return contents[row].key;
|
||||
} else {
|
||||
return contents[row].value;
|
||||
}
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
int GameOptions::rowCount(const QModelIndex&) const
|
||||
{
|
||||
return contents.size();
|
||||
}
|
||||
|
||||
int GameOptions::columnCount(const QModelIndex&) const
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
bool GameOptions::isLoaded() const
|
||||
{
|
||||
return loaded;
|
||||
}
|
||||
|
||||
bool GameOptions::reload()
|
||||
{
|
||||
beginResetModel();
|
||||
loaded = load(path, contents, version);
|
||||
endResetModel();
|
||||
return loaded;
|
||||
}
|
||||
|
||||
bool GameOptions::save()
|
||||
{
|
||||
return ::save(path, contents, version);
|
||||
}
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
/*
|
||||
* Prism Launcher - Minecraft Launcher
|
||||
* Copyright (C) 2023 Tayou <tayou@gmx.net>
|
||||
* Copyright (C) 2023 TheLastRar <TheLastRar@users.noreply.github.com>
|
||||
*
|
||||
* 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, version 3.
|
||||
*
|
||||
* 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 <QDebug>
|
||||
#include <QSaveFile>
|
||||
#include "FileSystem.h"
|
||||
|
||||
#include "FileSystem.h"
|
||||
#include "GameOptions.h"
|
||||
|
||||
static Qt::CheckState boolToState(bool b)
|
||||
{
|
||||
return b ? Qt::Checked : Qt::Unchecked;
|
||||
};
|
||||
|
||||
namespace {
|
||||
bool load(const QString& path, std::vector<GameOptionItem>& contents, int& version)
|
||||
{
|
||||
contents.clear();
|
||||
QFile file(path);
|
||||
if (!file.open(QFile::ReadOnly)) {
|
||||
qWarning() << "Failed to read options file.";
|
||||
return false;
|
||||
}
|
||||
|
||||
version = 0;
|
||||
while (!file.atEnd()) {
|
||||
// This should be handled by toml++ or some other toml parser rather than this manual parsing
|
||||
QString line = QString::fromUtf8(file.readLine());
|
||||
if (line.endsWith('\n')) {
|
||||
line.chop(1);
|
||||
}
|
||||
if (line.endsWith('\r')) {
|
||||
line.chop(1);
|
||||
}
|
||||
GameOptionItem item = GameOptionItem();
|
||||
|
||||
auto parts = line.split(':');
|
||||
|
||||
item.key = parts[0];
|
||||
item.value = parts[1];
|
||||
item.type = OptionType::String;
|
||||
qDebug() << "Reading Game Options Key:" << item.key;
|
||||
|
||||
if (item.key == "version") {
|
||||
version = item.value.toInt();
|
||||
continue;
|
||||
};
|
||||
|
||||
bool isInt = false;
|
||||
bool isFloat = false;
|
||||
item.intValue = item.value.toInt(&isInt);
|
||||
item.floatValue = item.value.toFloat(&isFloat);
|
||||
if (isInt) {
|
||||
item.type = OptionType::Int;
|
||||
// qDebug() << "The value" << value << "is a int";
|
||||
} else if (isFloat) {
|
||||
item.type = OptionType::Float;
|
||||
// qDebug() << "The value" << value << "is a float";
|
||||
} else if (item.value == "true" || item.value == "false") {
|
||||
item.boolValue = item.value == "true" ? true : false;
|
||||
item.type = OptionType::Bool;
|
||||
qDebug() << "The value" << item.value << "is a bool";
|
||||
} else if (item.value.endsWith("]") && item.value.startsWith("[")) {
|
||||
qDebug() << "The value" << item.value << "is an array";
|
||||
for (QString part : item.value.mid(1, item.value.size() - 2).split(",")) {
|
||||
GameOptionChildItem child{ part, static_cast<int>(contents.size()) };
|
||||
qDebug() << "Array has entry" << part;
|
||||
item.children.append(child);
|
||||
}
|
||||
}
|
||||
contents.emplace_back(item);
|
||||
}
|
||||
qDebug() << "Loaded" << path << "with version:" << version;
|
||||
return true;
|
||||
}
|
||||
bool save(const QString& path, std::vector<GameOptionItem>& mapping, int version)
|
||||
{
|
||||
QSaveFile out(path);
|
||||
if (!out.open(QIODevice::WriteOnly)) {
|
||||
return false;
|
||||
}
|
||||
if (version != 0) {
|
||||
QString versionLine = QString("version:%1\n").arg(version);
|
||||
out.write(versionLine.toUtf8());
|
||||
}
|
||||
auto iter = mapping.begin();
|
||||
while (iter != mapping.end()) {
|
||||
out.write(iter->key.toUtf8());
|
||||
out.write(":");
|
||||
out.write(iter->value.toUtf8());
|
||||
out.write("\n");
|
||||
iter++;
|
||||
}
|
||||
return out.commit();
|
||||
}
|
||||
} // namespace
|
||||
|
||||
GameOptions::GameOptions(const QString& path) : path(path)
|
||||
{
|
||||
reload();
|
||||
}
|
||||
|
||||
QVariant GameOptions::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if (role != Qt::DisplayRole) {
|
||||
return QAbstractItemModel::headerData(section, orientation, role);
|
||||
}
|
||||
switch (section) {
|
||||
case 0:
|
||||
return tr("Key");
|
||||
case 1:
|
||||
return tr("Description");
|
||||
case 2:
|
||||
return tr("Value");
|
||||
case 3:
|
||||
return tr("Default Value");
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
bool GameOptions::setData(const QModelIndex& index, const QVariant& value, int role)
|
||||
{
|
||||
auto row = index.row();
|
||||
auto column = (Column)index.column();
|
||||
if (column == Column::Value) {
|
||||
switch (contents[row].type) {
|
||||
case OptionType::String: {
|
||||
contents[row].value = value.toString();
|
||||
}
|
||||
case OptionType::Int: {
|
||||
contents[row].intValue = value.toInt();
|
||||
}
|
||||
case OptionType::Bool: {
|
||||
contents[row].boolValue = value.toBool();
|
||||
}
|
||||
case OptionType::Float: {
|
||||
contents[row].floatValue = value.toFloat();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Qt::ItemFlags GameOptions::flags(const QModelIndex& index) const
|
||||
{
|
||||
Qt::ItemFlags flags = QAbstractItemModel::flags(index);
|
||||
|
||||
if (!index.isValid())
|
||||
return flags;
|
||||
|
||||
Column column = (Column)index.column();
|
||||
|
||||
if (column == Column::Key) {
|
||||
return flags;
|
||||
}
|
||||
|
||||
if (index.parent().isValid()) {
|
||||
return flags;
|
||||
}
|
||||
|
||||
if (contents[index.row()].children.count() > 0) {
|
||||
return flags;
|
||||
}
|
||||
|
||||
flags = flags | Qt::ItemFlag::ItemIsEditable;
|
||||
if (column == Column::Value || column == Column::DefaultValue) {
|
||||
flags = flags | Qt::ItemFlag::ItemIsUserCheckable;
|
||||
}
|
||||
if (column == Column::DefaultValue) {
|
||||
flags = flags & ~Qt::ItemFlag::ItemIsEnabled;
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
QVariant GameOptions::data(const QModelIndex& index, int role) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return QVariant();
|
||||
|
||||
int row = index.row();
|
||||
Column column = (Column)index.column();
|
||||
|
||||
if (row < 0 || row >= int(contents.size()))
|
||||
return QVariant();
|
||||
|
||||
if (index.parent().isValid()) {
|
||||
switch (role) {
|
||||
case Qt::DisplayRole: {
|
||||
if (column == Column::Value) {
|
||||
GameOptionChildItem* item = static_cast<GameOptionChildItem*>(index.internalPointer());
|
||||
return item->value;
|
||||
} else {
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
default: {
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (role) {
|
||||
case Qt::DisplayRole: {
|
||||
switch (column) {
|
||||
case Column::Key: {
|
||||
return contents[row].key;
|
||||
}
|
||||
case Column::Description: {
|
||||
return "Description goes here!";
|
||||
}
|
||||
case Column::Value: {
|
||||
switch (contents[row].type) {
|
||||
case OptionType::String: {
|
||||
return contents[row].value;
|
||||
}
|
||||
case OptionType::Int: {
|
||||
return contents[row].intValue;
|
||||
}
|
||||
case OptionType::Bool: {
|
||||
return contents[row].boolValue;
|
||||
}
|
||||
case OptionType::Float: {
|
||||
return contents[row].floatValue;
|
||||
}
|
||||
case OptionType::KeyBind: {
|
||||
return contents[row].value;
|
||||
}
|
||||
default: {
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
}
|
||||
case Column::DefaultValue: {
|
||||
switch (contents[row].type) {
|
||||
case OptionType::String: {
|
||||
return contents[row].value;
|
||||
}
|
||||
case OptionType::Int: {
|
||||
return contents[row].intValue;
|
||||
}
|
||||
case OptionType::Bool: {
|
||||
return contents[row].boolValue;
|
||||
}
|
||||
case OptionType::Float: {
|
||||
return contents[row].floatValue;
|
||||
}
|
||||
case OptionType::KeyBind: {
|
||||
return contents[row].value;
|
||||
}
|
||||
default: {
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
}
|
||||
default: {
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
}
|
||||
case Qt::CheckStateRole: {
|
||||
switch (column) {
|
||||
case Column::Value: {
|
||||
if (contents[row].type == OptionType::Bool) {
|
||||
return boolToState(contents[row].boolValue);
|
||||
} else {
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
case Column::DefaultValue: {
|
||||
return boolToState(contents[row].boolValue);
|
||||
} else {
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
default: {
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
}
|
||||
default: {
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QModelIndex GameOptions::index(int row, int column, const QModelIndex& parent) const
|
||||
{
|
||||
if (!hasIndex(row, column, parent))
|
||||
return QModelIndex();
|
||||
|
||||
if (parent.isValid()) {
|
||||
if (parent.parent().isValid())
|
||||
return QModelIndex();
|
||||
|
||||
GameOptionItem* item = static_cast<GameOptionItem*>(parent.internalPointer());
|
||||
return createIndex(row, column, &item->children[row]);
|
||||
} else {
|
||||
return createIndex(row, column, &contents[row]);
|
||||
}
|
||||
}
|
||||
|
||||
QModelIndex GameOptions::parent(const QModelIndex& index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return QModelIndex();
|
||||
|
||||
const void* childItem = index.internalPointer();
|
||||
|
||||
// Determine where childItem points to
|
||||
if (childItem >= &contents[0] && childItem <= &contents.back()) {
|
||||
// Parent is root/contents
|
||||
return QModelIndex();
|
||||
} else {
|
||||
GameOptionChildItem* child = static_cast<GameOptionChildItem*>(index.internalPointer());
|
||||
return createIndex(child->parentRow, 0, &contents[child->parentRow]);
|
||||
}
|
||||
}
|
||||
|
||||
int GameOptions::rowCount(const QModelIndex& parent) const
|
||||
{
|
||||
if (!parent.isValid()) {
|
||||
return static_cast<int>(contents.size());
|
||||
} else {
|
||||
if (parent.column() > 0)
|
||||
return 0;
|
||||
|
||||
// Our tree model is only one layer deep
|
||||
// If we have parent, we can't go deeper
|
||||
if (parent.parent().isValid())
|
||||
return 0;
|
||||
|
||||
GameOptionItem* item = static_cast<GameOptionItem*>(parent.internalPointer());
|
||||
return item->children.count();
|
||||
}
|
||||
}
|
||||
|
||||
int GameOptions::columnCount(const QModelIndex& parent) const
|
||||
{
|
||||
// Our tree model is only one layer deep
|
||||
// If we have parent, we can't go deeper
|
||||
if (parent.parent().isValid())
|
||||
return 0;
|
||||
|
||||
return 4;
|
||||
}
|
||||
|
||||
bool GameOptions::isLoaded() const
|
||||
{
|
||||
return loaded;
|
||||
}
|
||||
|
||||
bool GameOptions::reload()
|
||||
{
|
||||
beginResetModel();
|
||||
loaded = load(path, contents, version);
|
||||
endResetModel();
|
||||
return loaded;
|
||||
}
|
||||
|
||||
bool GameOptions::save()
|
||||
{
|
||||
return ::save(path, contents, version);
|
||||
}
|
||||
|
@ -1,32 +1,85 @@
|
||||
#pragma once
|
||||
|
||||
#include <QAbstractListModel>
|
||||
#include <QString>
|
||||
#include <map>
|
||||
|
||||
struct GameOptionItem {
|
||||
QString key;
|
||||
QString value;
|
||||
};
|
||||
|
||||
class GameOptions : public QAbstractListModel {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit GameOptions(const QString& path);
|
||||
virtual ~GameOptions() = default;
|
||||
|
||||
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||
int columnCount(const QModelIndex& parent) const override;
|
||||
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
|
||||
|
||||
bool isLoaded() const;
|
||||
bool reload();
|
||||
bool save();
|
||||
|
||||
private:
|
||||
std::vector<GameOptionItem> contents;
|
||||
bool loaded = false;
|
||||
QString path;
|
||||
int version = 0;
|
||||
};
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
/*
|
||||
* Prism Launcher - Minecraft Launcher
|
||||
* Copyright (C) 2023 Tayou <tayou@gmx.net>
|
||||
* Copyright (C) 2023 TheLastRar <TheLastRar@users.noreply.github.com>
|
||||
*
|
||||
* 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, version 3.
|
||||
*
|
||||
* 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 <QAbstractListModel>
|
||||
#include <QString>
|
||||
#include <map>
|
||||
|
||||
enum class OptionType { String, Int, Float, Bool, KeyBind };
|
||||
|
||||
struct GameOptionChildItem {
|
||||
QString value;
|
||||
int parentRow;
|
||||
};
|
||||
|
||||
struct GameOptionItem {
|
||||
QString key;
|
||||
bool boolValue;
|
||||
int intValue;
|
||||
float floatValue;
|
||||
QString value;
|
||||
OptionType type;
|
||||
QList<GameOptionChildItem> children;
|
||||
};
|
||||
|
||||
class GameOptions : public QAbstractItemModel {
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum class Column { Key, Description, Value, DefaultValue };
|
||||
explicit GameOptions(const QString& path);
|
||||
virtual ~GameOptions() = default;
|
||||
|
||||
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||
int columnCount(const QModelIndex& parent) const override;
|
||||
Qt::ItemFlags flags(const QModelIndex& index) const override;
|
||||
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
|
||||
QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const override;
|
||||
QModelIndex parent(const QModelIndex& index) const override;
|
||||
|
||||
bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override;
|
||||
|
||||
bool isLoaded() const;
|
||||
bool reload();
|
||||
bool save();
|
||||
|
||||
private:
|
||||
std::vector<GameOptionItem> contents;
|
||||
bool loaded = false;
|
||||
QString path;
|
||||
int version = 0;
|
||||
};
|
||||
|
@ -1,74 +1,96 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
/*
|
||||
* Prism Launcher - Minecraft Launcher
|
||||
* Copyright (c) 2022 Jamie Mansfield <jmansfield@cadixdev.org>
|
||||
*
|
||||
* 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, version 3.
|
||||
*
|
||||
* 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 "GameOptionsPage.h"
|
||||
#include "minecraft/MinecraftInstance.h"
|
||||
#include "minecraft/gameoptions/GameOptions.h"
|
||||
#include "ui_GameOptionsPage.h"
|
||||
|
||||
GameOptionsPage::GameOptionsPage(MinecraftInstance* inst, QWidget* parent) : QWidget(parent), ui(new Ui::GameOptionsPage)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->tabWidget->tabBar()->hide();
|
||||
m_model = inst->gameOptionsModel();
|
||||
ui->optionsView->setModel(m_model.get());
|
||||
auto head = ui->optionsView->header();
|
||||
if (head->count()) {
|
||||
head->setSectionResizeMode(0, QHeaderView::ResizeToContents);
|
||||
for (int i = 1; i < head->count(); i++) {
|
||||
head->setSectionResizeMode(i, QHeaderView::Stretch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GameOptionsPage::~GameOptionsPage()
|
||||
{
|
||||
// m_model->save();
|
||||
}
|
||||
|
||||
void GameOptionsPage::openedImpl()
|
||||
{
|
||||
// m_model->observe();
|
||||
}
|
||||
|
||||
void GameOptionsPage::closedImpl()
|
||||
{
|
||||
// m_model->unobserve();
|
||||
}
|
||||
|
||||
void GameOptionsPage::retranslate()
|
||||
{
|
||||
ui->retranslateUi(this);
|
||||
}
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
/*
|
||||
* Prism Launcher - Minecraft Launcher
|
||||
* Copyright (c) 2022 Jamie Mansfield <jmansfield@cadixdev.org>
|
||||
* Copyright (C) 2023 Tayou <tayou@gmx.net>
|
||||
* Copyright (C) 2023 TheLastRar <TheLastRar@users.noreply.github.com>
|
||||
*
|
||||
* 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, version 3.
|
||||
*
|
||||
* 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 "GameOptionsPage.h"
|
||||
#include "minecraft/MinecraftInstance.h"
|
||||
#include "minecraft/gameoptions/GameOptions.h"
|
||||
#include "ui_GameOptionsPage.h"
|
||||
|
||||
GameOptionsPage::GameOptionsPage(MinecraftInstance* inst, QWidget* parent) : QWidget(parent), ui(new Ui::GameOptionsPage)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->tabWidget->tabBar()->hide();
|
||||
m_model = inst->gameOptionsModel();
|
||||
ui->optionsView->setModel(m_model.get());
|
||||
auto head = ui->optionsView->header();
|
||||
head->setDefaultSectionSize(250);
|
||||
if (head->count()) {
|
||||
for (int i = 1; i < head->count(); i++) {
|
||||
head->setSectionResizeMode(i, QHeaderView::Stretch);
|
||||
}
|
||||
head->setSectionResizeMode(head->count() -1, QHeaderView::Stretch);
|
||||
}
|
||||
connect(ui->optionsView, &QTreeView::doubleClicked, this, &GameOptionsPage::OptionDoubleClicked);
|
||||
}
|
||||
|
||||
GameOptionsPage::~GameOptionsPage()
|
||||
{
|
||||
// m_model->save();
|
||||
}
|
||||
|
||||
void GameOptionsPage::openedImpl()
|
||||
{
|
||||
// m_model->observe();
|
||||
}
|
||||
|
||||
void GameOptionsPage::closedImpl()
|
||||
{
|
||||
// m_model->unobserve();
|
||||
}
|
||||
|
||||
void GameOptionsPage::retranslate()
|
||||
{
|
||||
ui->retranslateUi(this);
|
||||
}
|
||||
|
||||
// QTreeView's double click checks if the cell clicked on has children
|
||||
// but a typical tree model would only have children in the first column
|
||||
// Workaround this by calling expand ourself
|
||||
void GameOptionsPage::OptionDoubleClicked(const QModelIndex& index)
|
||||
{
|
||||
if (!index.isValid() || index.column() == 0)
|
||||
return;
|
||||
|
||||
const QModelIndex firstColumn = ui->optionsView->model()->index(index.row(), 0, index.parent());
|
||||
if (!ui->optionsView->model()->hasChildren(firstColumn))
|
||||
return;
|
||||
|
||||
if (ui->optionsView->isExpanded(firstColumn))
|
||||
ui->optionsView->collapse(firstColumn);
|
||||
else
|
||||
ui->optionsView->expand(firstColumn);
|
||||
}
|
||||
|
@ -2,6 +2,8 @@
|
||||
/*
|
||||
* Prism Launcher - Minecraft Launcher
|
||||
* Copyright (c) 2022 Jamie Mansfield <jmansfield@cadixdev.org>
|
||||
* Copyright (C) 2023 Tayou <tayou@gmx.net>
|
||||
* Copyright (C) 2023 TheLastRar <TheLastRar@users.noreply.github.com>
|
||||
*
|
||||
* 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
|
||||
@ -67,4 +69,7 @@ class GameOptionsPage : public QWidget, public BasePage {
|
||||
private: // data
|
||||
Ui::GameOptionsPage* ui = nullptr;
|
||||
std::shared_ptr<GameOptions> m_model;
|
||||
|
||||
private Q_SLOTS:
|
||||
void OptionDoubleClicked(const QModelIndex& index);
|
||||
};
|
||||
|
@ -66,7 +66,7 @@
|
||||
</size>
|
||||
</property>
|
||||
<property name="rootIsDecorated">
|
||||
<bool>false</bool>
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<attribute name="headerStretchLastSection">
|
||||
<bool>false</bool>
|
||||
|
Loading…
x
Reference in New Issue
Block a user