From 908e1e9abaf0bab44acb999f37bd472ec007488c Mon Sep 17 00:00:00 2001 From: spycrab Date: Fri, 16 Jun 2017 01:42:12 +0200 Subject: [PATCH] Qt: Implement graphics window and controls --- Source/Core/DolphinQt2/CMakeLists.txt | 12 ++ .../Config/Graphics/GraphicsBool.cpp | 49 ++++++++ .../DolphinQt2/Config/Graphics/GraphicsBool.h | 41 +++++++ .../Config/Graphics/GraphicsChoice.cpp | 28 +++++ .../Config/Graphics/GraphicsChoice.h | 24 ++++ .../Config/Graphics/GraphicsSlider.cpp | 25 ++++ .../Config/Graphics/GraphicsSlider.h | 23 ++++ .../Config/Graphics/GraphicsWidget.cpp | 23 ++++ .../Config/Graphics/GraphicsWidget.h | 34 ++++++ .../Config/Graphics/GraphicsWindow.cpp | 113 ++++++++++++++++++ .../Config/Graphics/GraphicsWindow.h | 47 ++++++++ Source/Core/DolphinQt2/MainWindow.cpp | 28 +++++ Source/Core/DolphinQt2/MainWindow.h | 3 + 13 files changed, 450 insertions(+) create mode 100644 Source/Core/DolphinQt2/Config/Graphics/GraphicsBool.cpp create mode 100644 Source/Core/DolphinQt2/Config/Graphics/GraphicsBool.h create mode 100644 Source/Core/DolphinQt2/Config/Graphics/GraphicsChoice.cpp create mode 100644 Source/Core/DolphinQt2/Config/Graphics/GraphicsChoice.h create mode 100644 Source/Core/DolphinQt2/Config/Graphics/GraphicsSlider.cpp create mode 100644 Source/Core/DolphinQt2/Config/Graphics/GraphicsSlider.h create mode 100644 Source/Core/DolphinQt2/Config/Graphics/GraphicsWidget.cpp create mode 100644 Source/Core/DolphinQt2/Config/Graphics/GraphicsWidget.h create mode 100644 Source/Core/DolphinQt2/Config/Graphics/GraphicsWindow.cpp create mode 100644 Source/Core/DolphinQt2/Config/Graphics/GraphicsWindow.h diff --git a/Source/Core/DolphinQt2/CMakeLists.txt b/Source/Core/DolphinQt2/CMakeLists.txt index 35bbb61284..8227cf5f6f 100644 --- a/Source/Core/DolphinQt2/CMakeLists.txt +++ b/Source/Core/DolphinQt2/CMakeLists.txt @@ -1,9 +1,12 @@ find_package(Qt5Widgets REQUIRED) +find_Package(Qt5Gui REQUIRED) set_property(TARGET Qt5::Core PROPERTY INTERFACE_COMPILE_FEATURES "") message(STATUS "Found Qt version ${Qt5Core_VERSION}") include_directories(${CMAKE_CURRENT_BINARY_DIR}) +include_directories(${Qt5Gui_PRIVATE_INCLUDE_DIRS}) + add_definitions(-DQT_USE_QSTRINGBUILDER -DQT_NO_CAST_FROM_ASCII -DQT_NO_CAST_TO_ASCII) set(CMAKE_AUTOMOC ON) @@ -23,6 +26,15 @@ set(SRCS WiiUpdate.h Config/ControllersWindow.cpp Config/FilesystemWidget.cpp + Config/Graphics/AdvancedWidget.cpp + Config/Graphics/EnhancementsWidget.cpp + Config/Graphics/GeneralWidget.cpp + Config/Graphics/HacksWidget.cpp + Config/Graphics/GraphicsBool.cpp + Config/Graphics/GraphicsChoice.cpp + Config/Graphics/GraphicsSlider.cpp + Config/Graphics/GraphicsWidget.cpp + Config/Graphics/GraphicsWindow.cpp Config/InfoWidget.cpp Config/Mapping/GCKeyboardEmu.cpp Config/Mapping/GCPadEmu.cpp diff --git a/Source/Core/DolphinQt2/Config/Graphics/GraphicsBool.cpp b/Source/Core/DolphinQt2/Config/Graphics/GraphicsBool.cpp new file mode 100644 index 0000000000..dae8431c0b --- /dev/null +++ b/Source/Core/DolphinQt2/Config/Graphics/GraphicsBool.cpp @@ -0,0 +1,49 @@ +// Copyright 2017 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#include "DolphinQt2/Config/Graphics/GraphicsBool.h" + +#include "Core/Config/Config.h" + +#include + +GraphicsBool::GraphicsBool(const QString& label, const Config::ConfigInfo& setting, + bool reverse) + : QCheckBox(label), m_setting(setting), m_reverse(reverse) +{ + connect(this, &QCheckBox::toggled, this, &GraphicsBool::Update); + setChecked(Config::Get(m_setting) ^ reverse); + + if (Config::GetActiveLayerForConfig(m_setting) != Config::LayerType::Base) + { + QFont bf = font(); + bf.setBold(true); + setFont(bf); + } +} + +void GraphicsBool::Update() +{ + Config::SetBaseOrCurrent(m_setting, static_cast(isChecked() ^ m_reverse)); +} + +GraphicsBoolEx::GraphicsBoolEx(const QString& label, const Config::ConfigInfo& setting, + bool reverse) + : QRadioButton(label), m_setting(setting), m_reverse(reverse) +{ + connect(this, &QCheckBox::toggled, this, &GraphicsBoolEx::Update); + setChecked(Config::Get(m_setting) ^ reverse); + + if (Config::GetActiveLayerForConfig(m_setting) != Config::LayerType::Base) + { + QFont bf = font(); + bf.setBold(true); + setFont(bf); + } +} + +void GraphicsBoolEx::Update() +{ + Config::SetBaseOrCurrent(m_setting, static_cast(isChecked() ^ m_reverse)); +} diff --git a/Source/Core/DolphinQt2/Config/Graphics/GraphicsBool.h b/Source/Core/DolphinQt2/Config/Graphics/GraphicsBool.h new file mode 100644 index 0000000000..461a2598b1 --- /dev/null +++ b/Source/Core/DolphinQt2/Config/Graphics/GraphicsBool.h @@ -0,0 +1,41 @@ +// Copyright 2017 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#pragma once + +#include +#include + +namespace Config +{ +template +struct ConfigInfo; +}; + +class GraphicsBool : public QCheckBox +{ + Q_OBJECT +public: + GraphicsBool(const QString& label, const Config::ConfigInfo& setting, bool reverse = false); + +private: + void Update(); + + const Config::ConfigInfo& m_setting; + bool m_reverse; +}; + +class GraphicsBoolEx : public QRadioButton +{ + Q_OBJECT +public: + GraphicsBoolEx(const QString& label, const Config::ConfigInfo& setting, + bool reverse = false); + +private: + void Update(); + + const Config::ConfigInfo& m_setting; + bool m_reverse; +}; diff --git a/Source/Core/DolphinQt2/Config/Graphics/GraphicsChoice.cpp b/Source/Core/DolphinQt2/Config/Graphics/GraphicsChoice.cpp new file mode 100644 index 0000000000..9fbc537894 --- /dev/null +++ b/Source/Core/DolphinQt2/Config/Graphics/GraphicsChoice.cpp @@ -0,0 +1,28 @@ +// Copyright 2017 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#include "DolphinQt2/Config/Graphics/GraphicsChoice.h" + +#include "Core/Config/Config.h" + +GraphicsChoice::GraphicsChoice(const QStringList& options, const Config::ConfigInfo& setting) + : m_setting(setting) +{ + addItems(options); + connect(this, static_cast(&QComboBox::currentIndexChanged), this, + &GraphicsChoice::Update); + setCurrentIndex(Config::Get(m_setting)); + + if (Config::GetActiveLayerForConfig(m_setting) != Config::LayerType::Base) + { + QFont bf = font(); + bf.setBold(true); + setFont(bf); + } +} + +void GraphicsChoice::Update(int choice) +{ + Config::SetBaseOrCurrent(m_setting, choice); +} diff --git a/Source/Core/DolphinQt2/Config/Graphics/GraphicsChoice.h b/Source/Core/DolphinQt2/Config/Graphics/GraphicsChoice.h new file mode 100644 index 0000000000..31f5e7e1fe --- /dev/null +++ b/Source/Core/DolphinQt2/Config/Graphics/GraphicsChoice.h @@ -0,0 +1,24 @@ +// Copyright 2017 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#pragma once + +#include + +namespace Config +{ +template +struct ConfigInfo; +}; + +class GraphicsChoice : public QComboBox +{ +public: + GraphicsChoice(const QStringList& options, const Config::ConfigInfo& setting); + +private: + void Update(int choice); + + const Config::ConfigInfo& m_setting; +}; diff --git a/Source/Core/DolphinQt2/Config/Graphics/GraphicsSlider.cpp b/Source/Core/DolphinQt2/Config/Graphics/GraphicsSlider.cpp new file mode 100644 index 0000000000..b15f3018d2 --- /dev/null +++ b/Source/Core/DolphinQt2/Config/Graphics/GraphicsSlider.cpp @@ -0,0 +1,25 @@ +// Copyright 2017 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#include "DolphinQt2/Config/Graphics/GraphicsSlider.h" + +#include "Core/Config/Config.h" + +GraphicsSlider::GraphicsSlider(int minimum, int maximum, const Config::ConfigInfo& setting, + int tick) + : QSlider(Qt::Horizontal), m_setting(setting) +{ + setMinimum(minimum); + setMaximum(maximum); + setTickInterval(tick); + + setValue(Config::Get(setting)); + + connect(this, &GraphicsSlider::valueChanged, this, &GraphicsSlider::Update); +} + +void GraphicsSlider::Update(int value) +{ + Config::SetBaseOrCurrent(m_setting, value); +} diff --git a/Source/Core/DolphinQt2/Config/Graphics/GraphicsSlider.h b/Source/Core/DolphinQt2/Config/Graphics/GraphicsSlider.h new file mode 100644 index 0000000000..3fd54dd664 --- /dev/null +++ b/Source/Core/DolphinQt2/Config/Graphics/GraphicsSlider.h @@ -0,0 +1,23 @@ +// Copyright 2017 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#pragma once + +#include + +namespace Config +{ +template +struct ConfigInfo; +}; + +class GraphicsSlider : public QSlider +{ +public: + GraphicsSlider(int minimum, int maximum, const Config::ConfigInfo& setting, int tick = 0); + void Update(int value); + +private: + const Config::ConfigInfo& m_setting; +}; diff --git a/Source/Core/DolphinQt2/Config/Graphics/GraphicsWidget.cpp b/Source/Core/DolphinQt2/Config/Graphics/GraphicsWidget.cpp new file mode 100644 index 0000000000..94e316f364 --- /dev/null +++ b/Source/Core/DolphinQt2/Config/Graphics/GraphicsWidget.cpp @@ -0,0 +1,23 @@ +// Copyright 2017 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#include "DolphinQt2/Config/Graphics/GraphicsWidget.h" + +#include +#include +#include +#include +#include + +#include "DolphinQt2/Config/Graphics/GraphicsWindow.h" + +GraphicsWidget::GraphicsWidget(GraphicsWindow* parent) +{ + parent->RegisterWidget(this); +} + +void GraphicsWidget::AddDescription(QWidget* widget, const char* description) +{ + emit DescriptionAdded(widget, description); +} diff --git a/Source/Core/DolphinQt2/Config/Graphics/GraphicsWidget.h b/Source/Core/DolphinQt2/Config/Graphics/GraphicsWidget.h new file mode 100644 index 0000000000..04e5a1afeb --- /dev/null +++ b/Source/Core/DolphinQt2/Config/Graphics/GraphicsWidget.h @@ -0,0 +1,34 @@ +// Copyright 2017 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#pragma once + +#include + +class GraphicsWindow; +class QFormLayout; +class QGroupBox; +class QLabel; + +class GraphicsWidget : public QWidget +{ + Q_OBJECT +public: + explicit GraphicsWidget(GraphicsWindow* parent); + +signals: + void DescriptionAdded(QWidget* widget, const char* description); + +protected: + void AddWidget(const QString& name, QWidget* widget); + void AddWidget(QWidget* widget); + + void AddDescription(QWidget* widget, const char* description); + + virtual void LoadSettings() = 0; + virtual void SaveSettings() = 0; + +private: + QFormLayout* m_main_layout; +}; diff --git a/Source/Core/DolphinQt2/Config/Graphics/GraphicsWindow.cpp b/Source/Core/DolphinQt2/Config/Graphics/GraphicsWindow.cpp new file mode 100644 index 0000000000..f32623f22e --- /dev/null +++ b/Source/Core/DolphinQt2/Config/Graphics/GraphicsWindow.cpp @@ -0,0 +1,113 @@ +// Copyright 2017 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#include "DolphinQt2/Config/Graphics/GraphicsWindow.h" + +#include +#include +#include +#include +#include +#include + +#include "Core/ConfigManager.h" +#include "DolphinQt2/Config/Graphics/AdvancedWidget.h" +#include "DolphinQt2/Config/Graphics/EnhancementsWidget.h" +#include "DolphinQt2/Config/Graphics/GeneralWidget.h" +#include "DolphinQt2/Config/Graphics/HacksWidget.h" +#include "DolphinQt2/MainWindow.h" + +GraphicsWindow::GraphicsWindow(X11Utils::XRRConfiguration* xrr_config, MainWindow* parent) + : QDialog(parent), m_xrr_config(xrr_config) +{ + CreateMainLayout(); + ConnectWidgets(); + + setWindowTitle(tr("Graphics")); + setWindowFlags(Qt::Window); + + OnBackendChanged(QString::fromStdString(SConfig::GetInstance().m_strVideoBackend)); + + connect(parent, &MainWindow::EmulationStarted, this, &GraphicsWindow::EmulationStarted); + connect(parent, &MainWindow::EmulationStopped, this, &GraphicsWindow::EmulationStopped); +} + +void GraphicsWindow::CreateMainLayout() +{ + auto* main_layout = new QVBoxLayout(); + auto* description_box = new QGroupBox(tr("Description")); + auto* description_layout = new QVBoxLayout(); + m_description = + new QLabel(tr("Move the mouse pointer over an option to display a detailed description.")); + m_tab_widget = new QTabWidget(); + m_button_box = new QDialogButtonBox(QDialogButtonBox::Ok); + + description_box->setLayout(description_layout); + description_box->setMinimumHeight(205); + + m_description->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + m_description->setWordWrap(true); + m_description->setAlignment(Qt::AlignTop | Qt::AlignLeft); + + description_layout->addWidget(m_description); + + main_layout->addWidget(m_tab_widget); + main_layout->addWidget(description_box); + main_layout->addWidget(m_button_box); + + auto* general_widget = new GeneralWidget(m_xrr_config, this); + auto* enhancements_widget = new EnhancementsWidget(this); + auto* hacks_widget = new HacksWidget(this); + auto* advanced_widget = new AdvancedWidget(this); + + connect(general_widget, &GeneralWidget::BackendChanged, this, &GraphicsWindow::OnBackendChanged); + + m_tab_widget->addTab(general_widget, tr("General")); + m_tab_widget->addTab(enhancements_widget, tr("Enhancements")); + m_tab_widget->addTab(hacks_widget, tr("Hacks")); + m_tab_widget->addTab(advanced_widget, tr("Advanced")); + + setLayout(main_layout); +} + +void GraphicsWindow::ConnectWidgets() +{ + connect(m_button_box, &QDialogButtonBox::accepted, this, &QDialog::accept); +} + +void GraphicsWindow::OnBackendChanged(const QString& backend) +{ + setWindowTitle(tr("Dolphin %1 Graphics Configuration").arg(backend)); + emit BackendChanged(backend); +} + +void GraphicsWindow::RegisterWidget(GraphicsWidget* widget) +{ + connect(widget, &GraphicsWidget::DescriptionAdded, this, &GraphicsWindow::OnDescriptionAdded); +} + +void GraphicsWindow::OnDescriptionAdded(QWidget* widget, const char* description) +{ + m_widget_descriptions[widget] = description; + widget->installEventFilter(this); +} + +bool GraphicsWindow::eventFilter(QObject* object, QEvent* event) +{ + if (!m_widget_descriptions.contains(object)) + return false; + if (event->type() == QEvent::Enter) + { + m_description->setText(tr(m_widget_descriptions[object])); + return false; + } + + if (event->type() == QEvent::Leave) + { + m_description->setText( + tr("Move the mouse pointer over an option to display a detailed description.")); + } + + return false; +} diff --git a/Source/Core/DolphinQt2/Config/Graphics/GraphicsWindow.h b/Source/Core/DolphinQt2/Config/Graphics/GraphicsWindow.h new file mode 100644 index 0000000000..1d3748e62d --- /dev/null +++ b/Source/Core/DolphinQt2/Config/Graphics/GraphicsWindow.h @@ -0,0 +1,47 @@ +// Copyright 2017 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#pragma once + +#include +#include + +class GraphicsWidget; +class MainWindow; +class QLabel; +class QTabWidget; +class QDialogButtonBox; + +namespace X11Utils +{ +class XRRConfiguration; +} + +class GraphicsWindow final : public QDialog +{ + Q_OBJECT +public: + explicit GraphicsWindow(X11Utils::XRRConfiguration* xrr_config, MainWindow* parent); + + void RegisterWidget(GraphicsWidget* widget); + bool eventFilter(QObject* object, QEvent* event) override; +signals: + void BackendChanged(const QString& backend); + void EmulationStarted(); + void EmulationStopped(); + +private: + void CreateMainLayout(); + void ConnectWidgets(); + void OnBackendChanged(const QString& backend); + void OnDescriptionAdded(QWidget* widget, const char* description); + + QTabWidget* m_tab_widget; + QLabel* m_description; + QDialogButtonBox* m_button_box; + + X11Utils::XRRConfiguration* m_xrr_config; + + QHash m_widget_descriptions; +}; diff --git a/Source/Core/DolphinQt2/MainWindow.cpp b/Source/Core/DolphinQt2/MainWindow.cpp index de38910faa..da38a9dda0 100644 --- a/Source/Core/DolphinQt2/MainWindow.cpp +++ b/Source/Core/DolphinQt2/MainWindow.cpp @@ -2,6 +2,7 @@ // Licensed under GPLv2+ // Refer to the license.txt file included. +#include #include #include #include @@ -30,6 +31,8 @@ #include "DolphinQt2/AboutDialog.h" #include "DolphinQt2/Config/ControllersWindow.h" + +#include "DolphinQt2/Config/Graphics/GraphicsWindow.h" #include "DolphinQt2/Config/Mapping/MappingWindow.h" #include "DolphinQt2/Config/SettingsWindow.h" #include "DolphinQt2/Host.h" @@ -44,6 +47,11 @@ #include "UICommon/UICommon.h" +#if defined(HAVE_XRANDR) && HAVE_XRANDR +#include +#include "UICommon/X11Utils.h" +#endif + MainWindow::MainWindow() : QMainWindow(nullptr) { setWindowTitle(QString::fromStdString(scm_rev_str)); @@ -131,9 +139,21 @@ void MainWindow::CreateComponents() connect(this, &MainWindow::EmulationStopped, m_settings_window, &SettingsWindow::EmulationStopped); +#if defined(HAVE_XRANDR) && HAVE_XRANDR + m_graphics_window = new GraphicsWindow( + new X11Utils::XRRConfiguration( + static_cast(QGuiApplication::platformNativeInterface()->nativeResourceForWindow( + "display", windowHandle())), + winId()), + this); +#else + m_graphics_window = new GraphicsWindow(nullptr, this); +#endif + InstallHotkeyFilter(m_hotkey_window); InstallHotkeyFilter(m_controllers_window); InstallHotkeyFilter(m_settings_window); + InstallHotkeyFilter(m_graphics_window); } void MainWindow::ConnectMenuBar() @@ -212,6 +232,7 @@ void MainWindow::ConnectToolBar() connect(m_tool_bar, &ToolBar::ScreenShotPressed, this, &MainWindow::ScreenShot); connect(m_tool_bar, &ToolBar::SettingsPressed, this, &MainWindow::ShowSettingsWindow); connect(m_tool_bar, &ToolBar::ControllersPressed, this, &MainWindow::ShowControllersWindow); + connect(m_tool_bar, &ToolBar::GraphicsPressed, this, &MainWindow::ShowGraphicsWindow); connect(this, &MainWindow::EmulationStarted, m_tool_bar, &ToolBar::EmulationStarted); connect(this, &MainWindow::EmulationPaused, m_tool_bar, &ToolBar::EmulationPaused); @@ -476,6 +497,13 @@ void MainWindow::ShowHotkeyDialog() m_hotkey_window->activateWindow(); } +void MainWindow::ShowGraphicsWindow() +{ + m_graphics_window->show(); + m_graphics_window->raise(); + m_graphics_window->activateWindow(); +} + void MainWindow::StateLoad() { QString path = QFileDialog::getOpenFileName(this, tr("Select a File"), QDir::currentPath(), diff --git a/Source/Core/DolphinQt2/MainWindow.h b/Source/Core/DolphinQt2/MainWindow.h index 0cd572790d..48fbf9e3f2 100644 --- a/Source/Core/DolphinQt2/MainWindow.h +++ b/Source/Core/DolphinQt2/MainWindow.h @@ -19,6 +19,7 @@ class MappingWindow; class SettingsWindow; class ControllersWindow; class DragEnterEvent; +class GraphicsWindow; class MainWindow final : public QMainWindow { @@ -82,6 +83,7 @@ private: void ShowSettingsWindow(); void ShowControllersWindow(); + void ShowGraphicsWindow(); void ShowAboutDialog(); void ShowHotkeyDialog(); @@ -101,4 +103,5 @@ private: ControllersWindow* m_controllers_window; SettingsWindow* m_settings_window; MappingWindow* m_hotkey_window; + GraphicsWindow* m_graphics_window; };