mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-21 03:16:54 +02:00
Initial commit
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
#ifndef LAUNCHER_INCLUDE_COMMON_H_
|
||||
#define LAUNCHER_INCLUDE_COMMON_H_
|
||||
|
||||
// IWYU pragma: begin_exports
|
||||
#include <QArgument>
|
||||
#include <QObject>
|
||||
|
||||
#include <cinttypes>
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
// IWYU pragma: end_exports
|
||||
|
||||
#define KYTY_QT_CLASS_NO_COPY(name) \
|
||||
public: \
|
||||
name(const name&) = delete; /* NOLINT(bugprone-macro-parentheses) */ \
|
||||
name& operator=(const name&) = delete; /* NOLINT(bugprone-macro-parentheses) */ \
|
||||
name(name&&) noexcept = delete; /* NOLINT(bugprone-macro-parentheses) */ \
|
||||
name& operator=(name&&) noexcept = delete; /* NOLINT(bugprone-macro-parentheses) */
|
||||
|
||||
#endif /* LAUNCHER_INCLUDE_COMMON_H_ */
|
||||
@@ -0,0 +1,40 @@
|
||||
#ifndef COMPATIBILITY_DATABASE_H
|
||||
#define COMPATIBILITY_DATABASE_H
|
||||
|
||||
#include "common.h"
|
||||
#include "configuration.h"
|
||||
|
||||
#include <QMap>
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
|
||||
struct CompatibilityEntry {
|
||||
Configuration::GameStatus status = Configuration::GameStatus::Unknown;
|
||||
QString comment;
|
||||
};
|
||||
|
||||
class CompatibilityDatabase: public QObject {
|
||||
Q_OBJECT
|
||||
KYTY_QT_CLASS_NO_COPY(CompatibilityDatabase);
|
||||
|
||||
public:
|
||||
explicit CompatibilityDatabase(bool local, QObject* parent = nullptr);
|
||||
|
||||
[[nodiscard]] bool IsLocal() const { return m_local; }
|
||||
[[nodiscard]] const CompatibilityEntry* Find(const QString& title_id) const;
|
||||
|
||||
void Load();
|
||||
void SetStatus(const QString& title_id, Configuration::GameStatus status);
|
||||
void SetComment(const QString& title_id, const QString& comment);
|
||||
|
||||
signals:
|
||||
void Updated();
|
||||
|
||||
private:
|
||||
void Save() const;
|
||||
|
||||
QMap<QString, CompatibilityEntry> m_entries;
|
||||
bool m_local = false;
|
||||
};
|
||||
|
||||
#endif // COMPATIBILITY_DATABASE_H
|
||||
@@ -0,0 +1,178 @@
|
||||
#ifndef LAUNCHER_INCLUDE_CONFIGURATION_H_
|
||||
#define LAUNCHER_INCLUDE_CONFIGURATION_H_
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QChar>
|
||||
#include <QMetaEnum>
|
||||
#include <QMetaType>
|
||||
#include <QSettings>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <QVariant>
|
||||
|
||||
#define KYTY_CFG_SET(n) s->setValue(#n, QVariant::fromValue(n).toString());
|
||||
#define KYTY_CFG_GET(n) n = s->value(#n).value<decltype(n)>();
|
||||
|
||||
template <class T>
|
||||
inline QStringList EnumToList() {
|
||||
QStringList ret;
|
||||
auto me = QMetaEnum::fromType<T>();
|
||||
int count = me.keyCount();
|
||||
for (int i = 0; i < count; i++) {
|
||||
auto key = QString(me.key(i));
|
||||
ret << (key.startsWith('R') && key.size() > 2 && key.at(1).isDigit()
|
||||
? key.remove('R').toLower()
|
||||
: key);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T TextToEnum(const QString& text) {
|
||||
auto me = QMetaEnum::fromType<T>();
|
||||
return static_cast<T>(me.keyToValue(
|
||||
((text.size() > 1 && text.at(0).isDigit()) ? 'R' + text.toUpper() : text).toUtf8().data()));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
QString EnumToText(T value) {
|
||||
auto me = QMetaEnum::fromType<T>();
|
||||
auto key = QString(me.valueToKey(static_cast<int>(value)));
|
||||
return (key.startsWith('R') && key.size() > 2 && key.at(1).isDigit() ? key.remove('R').toLower()
|
||||
: key);
|
||||
}
|
||||
|
||||
class Configuration: public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum class Resolution {
|
||||
R1280X720,
|
||||
R1920X1080,
|
||||
};
|
||||
Q_ENUM(Resolution)
|
||||
|
||||
enum class ShaderOptimizationType { None, Size, Performance };
|
||||
Q_ENUM(ShaderOptimizationType)
|
||||
|
||||
enum class ShaderLogDirection { Silent, Console, File };
|
||||
Q_ENUM(ShaderLogDirection)
|
||||
|
||||
enum class ProfilerDirection { None, Network };
|
||||
Q_ENUM(ProfilerDirection)
|
||||
|
||||
enum class LogDirection { Silent, Console, File };
|
||||
Q_ENUM(LogDirection)
|
||||
|
||||
enum class GameStatus { Unknown, InGame, Logo, DoesntBoot, MainMenu };
|
||||
Q_ENUM(GameStatus)
|
||||
|
||||
Configuration() = default;
|
||||
|
||||
QString name;
|
||||
QString title_id; /* Serial / title id from sce_sys/param.json */
|
||||
QString firmwareVer; /* requiredSystemSoftwareVersion from sce_sys/param.json */
|
||||
QString basedir; /* Game base directory */
|
||||
QString game_path; /* Launcher-unique game path */
|
||||
bool custom_settings = false;
|
||||
GameStatus game_status = GameStatus::Unknown;
|
||||
QString game_comment;
|
||||
|
||||
Resolution screen_resolution = Resolution::R1280X720;
|
||||
int vblank_frequency = 60;
|
||||
bool vulkan_validation_enabled = true;
|
||||
bool shader_validation_enabled = true;
|
||||
ShaderOptimizationType shader_optimization_type = ShaderOptimizationType::Performance;
|
||||
ShaderLogDirection shader_log_direction = ShaderLogDirection::Silent;
|
||||
QString shader_log_folder = "_Shaders";
|
||||
bool command_buffer_dump_enabled = false;
|
||||
QString command_buffer_dump_folder = "_Buffers";
|
||||
LogDirection printf_direction = LogDirection::Silent;
|
||||
QString printf_output_file = "_kyty.txt";
|
||||
ProfilerDirection profiler_direction = ProfilerDirection::None;
|
||||
bool renderdoc_enabled = false;
|
||||
bool ngg_rectlist_draw_enabled = true;
|
||||
|
||||
QString elf = QStringLiteral("eboot.bin");
|
||||
|
||||
void CopyEmulatorSettingsFrom(const Configuration& other) {
|
||||
screen_resolution = other.screen_resolution;
|
||||
vblank_frequency = other.vblank_frequency;
|
||||
vulkan_validation_enabled = other.vulkan_validation_enabled;
|
||||
shader_validation_enabled = other.shader_validation_enabled;
|
||||
shader_optimization_type = other.shader_optimization_type;
|
||||
shader_log_direction = other.shader_log_direction;
|
||||
shader_log_folder = other.shader_log_folder;
|
||||
command_buffer_dump_enabled = other.command_buffer_dump_enabled;
|
||||
command_buffer_dump_folder = other.command_buffer_dump_folder;
|
||||
printf_direction = other.printf_direction;
|
||||
printf_output_file = other.printf_output_file;
|
||||
profiler_direction = other.profiler_direction;
|
||||
renderdoc_enabled = other.renderdoc_enabled;
|
||||
ngg_rectlist_draw_enabled = other.ngg_rectlist_draw_enabled;
|
||||
}
|
||||
|
||||
void CopyFrom(const Configuration& other) {
|
||||
name = other.name;
|
||||
title_id = other.title_id;
|
||||
firmwareVer = other.firmwareVer;
|
||||
basedir = other.basedir;
|
||||
game_path = other.game_path;
|
||||
custom_settings = other.custom_settings;
|
||||
game_status = other.game_status;
|
||||
game_comment = other.game_comment;
|
||||
CopyEmulatorSettingsFrom(other);
|
||||
elf = other.elf;
|
||||
}
|
||||
|
||||
void WriteSettings(QSettings* s) const {
|
||||
KYTY_CFG_SET(name);
|
||||
KYTY_CFG_SET(basedir);
|
||||
KYTY_CFG_SET(game_path);
|
||||
KYTY_CFG_SET(custom_settings);
|
||||
KYTY_CFG_SET(screen_resolution);
|
||||
KYTY_CFG_SET(vblank_frequency);
|
||||
KYTY_CFG_SET(vulkan_validation_enabled);
|
||||
KYTY_CFG_SET(shader_validation_enabled);
|
||||
KYTY_CFG_SET(shader_optimization_type);
|
||||
KYTY_CFG_SET(shader_log_direction);
|
||||
KYTY_CFG_SET(shader_log_folder);
|
||||
KYTY_CFG_SET(command_buffer_dump_enabled);
|
||||
KYTY_CFG_SET(command_buffer_dump_folder);
|
||||
KYTY_CFG_SET(printf_direction);
|
||||
KYTY_CFG_SET(printf_output_file);
|
||||
KYTY_CFG_SET(profiler_direction);
|
||||
KYTY_CFG_SET(renderdoc_enabled);
|
||||
KYTY_CFG_SET(ngg_rectlist_draw_enabled);
|
||||
KYTY_CFG_SET(elf);
|
||||
}
|
||||
|
||||
void ReadSettings(QSettings* s) {
|
||||
KYTY_CFG_GET(name);
|
||||
KYTY_CFG_GET(basedir);
|
||||
KYTY_CFG_GET(game_path);
|
||||
KYTY_CFG_GET(custom_settings);
|
||||
KYTY_CFG_GET(screen_resolution);
|
||||
vblank_frequency = s->value("vblank_frequency", vblank_frequency).toInt();
|
||||
KYTY_CFG_GET(vulkan_validation_enabled);
|
||||
KYTY_CFG_GET(shader_validation_enabled);
|
||||
KYTY_CFG_GET(shader_optimization_type);
|
||||
KYTY_CFG_GET(shader_log_direction);
|
||||
KYTY_CFG_GET(shader_log_folder);
|
||||
KYTY_CFG_GET(command_buffer_dump_enabled);
|
||||
KYTY_CFG_GET(command_buffer_dump_folder);
|
||||
KYTY_CFG_GET(printf_direction);
|
||||
KYTY_CFG_GET(printf_output_file);
|
||||
KYTY_CFG_GET(profiler_direction);
|
||||
KYTY_CFG_GET(renderdoc_enabled);
|
||||
ngg_rectlist_draw_enabled =
|
||||
s->value("ngg_rectlist_draw_enabled", ngg_rectlist_draw_enabled).toBool();
|
||||
elf = s->value("elf", elf).toString();
|
||||
}
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(Configuration*)
|
||||
|
||||
#endif /* LAUNCHER_INCLUDE_CONFIGURATION_H_ */
|
||||
@@ -0,0 +1,65 @@
|
||||
#ifndef CONFIGURATION_EDIT_DIALOG_H
|
||||
#define CONFIGURATION_EDIT_DIALOG_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include <QDialog>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
class QByteArray;
|
||||
class QGroupBox;
|
||||
class QListWidget;
|
||||
class QMoveEvent;
|
||||
class QToolButton;
|
||||
class QSettings;
|
||||
class QWidget;
|
||||
|
||||
class Configuration;
|
||||
namespace Ui {
|
||||
class ConfigurationEditDialog;
|
||||
} // namespace Ui
|
||||
|
||||
class ConfigurationEditDialog: public QDialog {
|
||||
Q_OBJECT
|
||||
KYTY_QT_CLASS_NO_COPY(ConfigurationEditDialog);
|
||||
|
||||
public:
|
||||
explicit ConfigurationEditDialog(Configuration& info, QWidget* parent = nullptr);
|
||||
~ConfigurationEditDialog() override;
|
||||
|
||||
static void WriteSettings(QSettings& s);
|
||||
static void ReadSettings(QSettings& s);
|
||||
|
||||
void SetTitle(const QString& str);
|
||||
void SetGameDirectories(const QStringList& dirs);
|
||||
[[nodiscard]] QStringList GetGameDirectories() const;
|
||||
|
||||
private:
|
||||
Ui::ConfigurationEditDialog* m_ui = nullptr;
|
||||
Configuration& m_info;
|
||||
QGroupBox* m_game_dirs_group = nullptr;
|
||||
QListWidget* m_game_dirs_list = nullptr;
|
||||
QToolButton* m_remove_game_dir_button = nullptr;
|
||||
bool m_show_game_dirs = false;
|
||||
|
||||
protected:
|
||||
void Init(const Configuration& info);
|
||||
void InitGameDirectories();
|
||||
void AddGameDirectoryItem(const QString& dir);
|
||||
|
||||
void moveEvent(QMoveEvent* event) override;
|
||||
|
||||
static QByteArray g_last_geometry;
|
||||
|
||||
/*slots:*/
|
||||
|
||||
void update_info();
|
||||
void adjust_size();
|
||||
void save();
|
||||
void clear();
|
||||
void add_game_directory();
|
||||
void remove_selected_game_directories();
|
||||
void update_game_directory_buttons();
|
||||
};
|
||||
|
||||
#endif // CONFIGURATION_EDIT_DIALOG_H
|
||||
@@ -0,0 +1,48 @@
|
||||
#ifndef CONFIGURATION_ITEM_H
|
||||
#define CONFIGURATION_ITEM_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include <QTreeWidgetItem>
|
||||
|
||||
#include <memory>
|
||||
|
||||
class QComboBox;
|
||||
class QLabel;
|
||||
class QLineEdit;
|
||||
class QTreeWidget;
|
||||
class QWidget;
|
||||
|
||||
class Configuration;
|
||||
class ConfigurationItem: public QTreeWidgetItem {
|
||||
public:
|
||||
explicit ConfigurationItem(std::unique_ptr<Configuration> info, QTreeWidget* parent);
|
||||
~ConfigurationItem() override;
|
||||
|
||||
void Update();
|
||||
bool operator<(const QTreeWidgetItem& other) const override;
|
||||
|
||||
KYTY_QT_CLASS_NO_COPY(ConfigurationItem);
|
||||
|
||||
Configuration& GetInfo() { return *m_info; }
|
||||
[[nodiscard]] const Configuration& GetInfo() const { return *m_info; }
|
||||
// void SetInfo(Configuration* info);
|
||||
void SetRunning(bool state);
|
||||
void SetCompatibilityEditable(bool editable);
|
||||
[[nodiscard]] bool IsRunning() const { return m_running; }
|
||||
QComboBox* GetStatusCombo() { return m_status_combo; }
|
||||
QLineEdit* GetCommentEdit() { return m_comment_edit; }
|
||||
|
||||
private:
|
||||
void UpdateIcon();
|
||||
void UpdateStatusIndicator();
|
||||
|
||||
std::unique_ptr<Configuration> m_info;
|
||||
bool m_running = false;
|
||||
QComboBox* m_status_combo = nullptr;
|
||||
QLabel* m_status_indicator = nullptr;
|
||||
QWidget* m_status_widget = nullptr;
|
||||
QLineEdit* m_comment_edit = nullptr;
|
||||
};
|
||||
|
||||
#endif // CONFIGURATION_ITEM_H
|
||||
@@ -0,0 +1,86 @@
|
||||
#ifndef CONFIGURATION_LIST_WIDGET_H
|
||||
#define CONFIGURATION_LIST_WIDGET_H
|
||||
|
||||
#include "common.h"
|
||||
#include "configuration.h"
|
||||
|
||||
#include <QMap>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <QWidget>
|
||||
|
||||
class ConfigurationItem;
|
||||
class CompatibilityDatabase;
|
||||
class QTreeWidgetItem;
|
||||
class QPoint;
|
||||
class MainDialog;
|
||||
|
||||
namespace Ui {
|
||||
class ConfigurationListWidget;
|
||||
} // namespace Ui
|
||||
|
||||
class ConfigurationListWidget: public QWidget {
|
||||
Q_OBJECT
|
||||
KYTY_QT_CLASS_NO_COPY(ConfigurationListWidget);
|
||||
|
||||
public:
|
||||
explicit ConfigurationListWidget(QWidget* parent = nullptr);
|
||||
~ConfigurationListWidget() override;
|
||||
|
||||
void SetRunEnabled(bool flag) { m_run_enabled = flag; }
|
||||
[[nodiscard]] bool IsRunEnabled() const { return m_run_enabled; }
|
||||
|
||||
[[nodiscard]] const ConfigurationItem* GetSelectedItem() const { return m_selected_item; }
|
||||
ConfigurationItem* GetSelectedItem() { return m_selected_item; }
|
||||
|
||||
void SetMainDialog(MainDialog* main_dialog) { m_main_dialog = main_dialog; }
|
||||
MainDialog* GetMainDialog() { return m_main_dialog; }
|
||||
|
||||
[[nodiscard]] const QString& GetSettingsFile() const { return m_settings_file; }
|
||||
[[nodiscard]] const QStringList& GetGameDirectories() const { return m_game_dirs; }
|
||||
[[nodiscard]] bool CanViewSelectedTrophies() const;
|
||||
|
||||
bool EnsureGameDirectory();
|
||||
void ScanGameDirectory();
|
||||
void ViewTrophies();
|
||||
|
||||
signals:
|
||||
|
||||
void Run();
|
||||
void Select();
|
||||
|
||||
public slots:
|
||||
void WriteSettings();
|
||||
void ReadSettings();
|
||||
|
||||
protected slots:
|
||||
|
||||
void edit_configuration();
|
||||
void delete_configuartion();
|
||||
void edit_global_settings();
|
||||
void run_configuration();
|
||||
void list_currentItemChanged(QTreeWidgetItem* current, QTreeWidgetItem* previous);
|
||||
void list_itemDoubleClicked(QTreeWidgetItem* witem, int column);
|
||||
void show_context_menu(const QPoint& pos);
|
||||
void open_game_folder();
|
||||
void remove_save_data();
|
||||
void filter_configurations(const QString& text);
|
||||
|
||||
private:
|
||||
void ClearCustomSettings(ConfigurationItem* item);
|
||||
void SelectItem(QTreeWidgetItem* witem);
|
||||
void ApplyCompatibility();
|
||||
[[nodiscard]] bool HasValidGameDirectory() const;
|
||||
|
||||
ConfigurationItem* m_selected_item = nullptr;
|
||||
bool m_run_enabled = true;
|
||||
Ui::ConfigurationListWidget* m_ui = nullptr;
|
||||
MainDialog* m_main_dialog = nullptr;
|
||||
QString m_settings_file;
|
||||
QStringList m_game_dirs;
|
||||
Configuration m_global_info;
|
||||
QMap<QString, Configuration*> m_custom_infos;
|
||||
CompatibilityDatabase* m_compatibility = nullptr;
|
||||
};
|
||||
|
||||
#endif // CONFIGURATION_LIST_WIDGET_H
|
||||
@@ -0,0 +1,73 @@
|
||||
#ifndef GAME_LIST_TREE_WIDGET_H
|
||||
#define GAME_LIST_TREE_WIDGET_H
|
||||
|
||||
#include <QColor>
|
||||
#include <QPaintEvent>
|
||||
#include <QPainter>
|
||||
#include <QPalette>
|
||||
#include <QPixmap>
|
||||
#include <QPoint>
|
||||
#include <QResizeEvent>
|
||||
#include <QString>
|
||||
#include <QTreeWidget>
|
||||
|
||||
class GameListTreeWidget: public QTreeWidget {
|
||||
public:
|
||||
explicit GameListTreeWidget(QWidget* parent = nullptr): QTreeWidget(parent) {
|
||||
setAutoFillBackground(false);
|
||||
viewport()->setAutoFillBackground(false);
|
||||
}
|
||||
|
||||
void SetBackgroundImage(const QString& path) {
|
||||
if (m_path == path) {
|
||||
return;
|
||||
}
|
||||
m_path = path;
|
||||
m_source = QPixmap();
|
||||
if (!path.isEmpty()) {
|
||||
m_source.load(path);
|
||||
}
|
||||
UpdateScaledBackground();
|
||||
viewport()->update();
|
||||
}
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent* event) override {
|
||||
QTreeWidget::resizeEvent(event);
|
||||
UpdateScaledBackground();
|
||||
}
|
||||
|
||||
void paintEvent(QPaintEvent* event) override {
|
||||
{
|
||||
QPainter painter(viewport());
|
||||
if (m_scaled.isNull()) {
|
||||
painter.fillRect(event->rect(), palette().brush(QPalette::Base));
|
||||
} else {
|
||||
painter.drawPixmap(m_scaled_pos, m_scaled);
|
||||
painter.fillRect(event->rect(), QColor(0, 0, 0, 115));
|
||||
}
|
||||
}
|
||||
|
||||
QTreeWidget::paintEvent(event);
|
||||
}
|
||||
|
||||
private:
|
||||
void UpdateScaledBackground() {
|
||||
m_scaled = QPixmap();
|
||||
if (m_source.isNull() || viewport()->size().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_scaled = m_source.scaled(viewport()->size(), Qt::KeepAspectRatioByExpanding,
|
||||
Qt::FastTransformation);
|
||||
m_scaled_pos = QPoint((viewport()->width() - m_scaled.width()) / 2,
|
||||
(viewport()->height() - m_scaled.height()) / 2);
|
||||
}
|
||||
|
||||
QString m_path;
|
||||
QPixmap m_source;
|
||||
QPixmap m_scaled;
|
||||
QPoint m_scaled_pos;
|
||||
};
|
||||
|
||||
#endif // GAME_LIST_TREE_WIDGET_H
|
||||
@@ -0,0 +1,40 @@
|
||||
#ifndef MAIN_DIALOG_H
|
||||
#define MAIN_DIALOG_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include <QDialog>
|
||||
#include <QString>
|
||||
|
||||
class QWidget;
|
||||
class QProcess;
|
||||
class MainDialogPrivate;
|
||||
class QSettings;
|
||||
class QResizeEvent;
|
||||
|
||||
class Configuration;
|
||||
class MainDialog: public QDialog {
|
||||
Q_OBJECT
|
||||
KYTY_QT_CLASS_NO_COPY(MainDialog);
|
||||
|
||||
signals:
|
||||
void Start();
|
||||
void Quit();
|
||||
void Resize();
|
||||
|
||||
public:
|
||||
explicit MainDialog(QWidget* parent = nullptr);
|
||||
~MainDialog() override = default;
|
||||
|
||||
void RunInterpreter(QProcess* process, const Configuration& info);
|
||||
|
||||
static void WriteSettings(QSettings& s);
|
||||
static void ReadSettings(QSettings& s);
|
||||
|
||||
void resizeEvent(QResizeEvent* event) override;
|
||||
|
||||
private:
|
||||
MainDialogPrivate* m_p = nullptr;
|
||||
};
|
||||
|
||||
#endif // MAIN_DIALOG_H
|
||||
@@ -0,0 +1,29 @@
|
||||
#ifndef MANDATORY_LINEEDIT_H
|
||||
#define MANDATORY_LINEEDIT_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include <QLineEdit>
|
||||
#include <QString>
|
||||
|
||||
class QPaintEvent;
|
||||
class QWidget;
|
||||
|
||||
constexpr char MANDATORY_AND_EMPTY[] = "mandatory_and_empty";
|
||||
|
||||
class MandatoryLineEdit: public QLineEdit {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MandatoryLineEdit(QWidget* parent = nullptr);
|
||||
|
||||
void paintEvent(QPaintEvent* event) override;
|
||||
|
||||
static bool FindEmpty(QObject* p);
|
||||
|
||||
protected slots:
|
||||
|
||||
void changed(const QString& text);
|
||||
};
|
||||
|
||||
#endif // MANDATORY_LINEEDIT_H
|
||||
@@ -0,0 +1,27 @@
|
||||
#ifndef TROPHY_VIEWER_DIALOG_H
|
||||
#define TROPHY_VIEWER_DIALOG_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
class QTabWidget;
|
||||
class QWidget;
|
||||
|
||||
class Configuration;
|
||||
class TrophyViewerDialog: public QDialog {
|
||||
KYTY_QT_CLASS_NO_COPY(TrophyViewerDialog);
|
||||
|
||||
public:
|
||||
explicit TrophyViewerDialog(QWidget* parent = nullptr);
|
||||
|
||||
static bool HasTrophyData(const Configuration* info);
|
||||
static void ShowForGame(const Configuration* info, QWidget* parent);
|
||||
|
||||
private:
|
||||
bool LoadGame(const Configuration& info, QString& error);
|
||||
|
||||
QTabWidget* m_tabs = nullptr;
|
||||
};
|
||||
|
||||
#endif // TROPHY_VIEWER_DIALOG_H
|
||||
Reference in New Issue
Block a user