launcher: fix light mode, group settings into resizable sections

This commit is contained in:
nmzik
2026-09-03 04:13:25 +02:00
parent e21c5f37d0
commit cd74809086
16 changed files with 494 additions and 422 deletions
+262 -357
View File
@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>560</width>
<height>450</height>
<width>760</width>
<height>620</height>
</rect>
</property>
<property name="windowTitle">
@@ -17,363 +17,278 @@
<locale language="English" country="UnitedStates"/>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="horizontalSpacing">
<number>8</number>
</property>
<property name="verticalSpacing">
<number>8</number>
</property>
<item row="0" column="0">
<widget class="QFrame" name="configuaration_groupbox">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
<layout class="QGridLayout" name="sectionsLayout" columnstretch="1,1">
<property name="horizontalSpacing">
<number>8</number>
</property>
<layout class="QFormLayout" name="formLayout_6">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<item row="0" column="0" colspan="2">
<widget class="QFrame" name="frame_4">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<layout class="QGridLayout" name="gridLayout_5">
<item row="0" column="0">
<widget class="QCheckBox" name="checkBox_vulkan_validation">
<property name="toolTip">
<string>Enable Vulkan validation layers</string>
</property>
<property name="text">
<string>Vulkan validation</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="checkBox_shader_validation">
<property name="toolTip">
<string>Validate SPIR-V binary</string>
</property>
<property name="text">
<string>Shader validation</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="checkBox_cmd_dump">
<property name="toolTip">
<string>Dump command buffers</string>
</property>
<property name="text">
<string>Command buffer dump</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="checkBox_renderdoc_capture">
<property name="toolTip">
<string>Enable RenderDoc capture</string>
</property>
<property name="text">
<string>RenderDoc capture</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="checkBox_fullscreen">
<property name="toolTip">
<string>Run in borderless desktop fullscreen</string>
</property>
<property name="text">
<string>Fullscreen</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="checkBox_red_zone_protection">
<property name="toolTip">
<string>Helps prevent crashes in some games on Windows</string>
</property>
<property name="text">
<string>Windows SysV red zone crash protection (Experimental)</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_user_name">
<property name="text">
<string>User name:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="MandatoryLineEdit" name="lineEdit_user_name">
<property name="toolTip">
<string>Local user name exposed to games</string>
</property>
<property name="clearButtonEnabled">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_user_id">
<property name="text">
<string>User ID:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QSpinBox" name="spinBox_user_id">
<property name="toolTip">
<string>Local user ID exposed to games</string>
</property>
<property name="maximum">
<number>2147483647</number>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_16">
<property name="text">
<string>Screen resolution:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QComboBox" name="comboBox_screen_resolution">
<property name="toolTip">
<string>Window resolution</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_present_mode">
<property name="text">
<string>Present mode:</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QComboBox" name="comboBox_present_mode">
<property name="toolTip">
<string>Vulkan swapchain presentation mode</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_vblank_frequency">
<property name="text">
<string>Vblank frequency:</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QSpinBox" name="spinBox_vblank_frequency">
<property name="toolTip">
<string>Virtual display refresh rate used for frame pacing</string>
</property>
<property name="minimum">
<number>30</number>
</property>
<property name="maximum">
<number>360</number>
</property>
<property name="value">
<number>60</number>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_console_language">
<property name="text">
<string>Console language:</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QComboBox" name="comboBox_console_language">
<property name="toolTip">
<string>Language</string>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QLabel" name="label_20">
<property name="text">
<string>Shader optimization type:</string>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QComboBox" name="comboBox_shader_optimization_type">
<property name="toolTip">
<string>Optimize shaders for code size or performance</string>
</property>
</widget>
</item>
<item row="8" column="0">
<widget class="QLabel" name="label_21">
<property name="text">
<string>Shader log direction:</string>
</property>
</widget>
</item>
<item row="8" column="1">
<widget class="QComboBox" name="comboBox_shader_log_direction">
<property name="toolTip">
<string>Dump shaders to file or console window. If enabled may decrease emulator performance</string>
</property>
</widget>
</item>
<item row="9" column="0">
<widget class="QLabel" name="label_22">
<property name="text">
<string>Shader log folder:</string>
</property>
</widget>
</item>
<item row="9" column="1">
<widget class="MandatoryLineEdit" name="lineEdit_shader_log_folder">
<property name="toolTip">
<string>Specify directory to dump shaders</string>
</property>
<property name="clearButtonEnabled">
<bool>true</bool>
</property>
</widget>
</item>
<item row="10" column="0">
<widget class="QLabel" name="label_24">
<property name="text">
<string>Command buffer dump folder:</string>
</property>
</widget>
</item>
<item row="10" column="1">
<widget class="MandatoryLineEdit" name="lineEdit_cmd_dump_folder">
<property name="toolTip">
<string>Specify directory to dump command buffers</string>
</property>
<property name="clearButtonEnabled">
<bool>true</bool>
</property>
</widget>
</item>
<item row="11" column="0">
<widget class="QLabel" name="label_25">
<property name="text">
<string>Printf direction:</string>
</property>
</widget>
</item>
<item row="11" column="1">
<widget class="QComboBox" name="comboBox_printf_direction">
<property name="toolTip">
<string>Print logs to file or console window. If enabled may decrease emulator performance</string>
</property>
</widget>
</item>
<item row="12" column="0">
<widget class="QLabel" name="label_26">
<property name="text">
<string>Printf output file:</string>
</property>
</widget>
</item>
<item row="12" column="1">
<widget class="MandatoryLineEdit" name="lineEdit_printf_file">
<property name="toolTip">
<string>Specify file to dump logs</string>
</property>
<property name="clearButtonEnabled">
<bool>true</bool>
</property>
</widget>
</item>
<item row="13" column="0">
<widget class="QLabel" name="label_27">
<property name="text">
<string>Profiler direction:</string>
</property>
</widget>
</item>
<item row="13" column="1">
<widget class="QComboBox" name="comboBox_profiler_direction">
<property name="toolTip">
<string>Enable or disable profiler. If enabled may decrease emulator performance</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="1">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QPushButton" name="ok_button">
<property name="minimumSize">
<size>
<width>80</width>
<height>25</height>
</size>
</property>
<property name="text">
<string>Save</string>
</property>
<property name="default">
<bool>true</bool>
<property name="verticalSpacing">
<number>8</number>
</property>
<item row="0" column="0">
<widget class="QGroupBox" name="user_profile_group">
<property name="title">
<string>User profile</string>
</property>
<layout class="QFormLayout" name="userProfileLayout">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label_user_name">
<property name="text"><string>User name:</string></property>
</widget>
</item>
<item row="0" column="1">
<widget class="MandatoryLineEdit" name="lineEdit_user_name">
<property name="toolTip"><string>Local user name exposed to games</string></property>
<property name="clearButtonEnabled"><bool>true</bool></property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_user_id">
<property name="text"><string>User ID:</string></property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="spinBox_user_id">
<property name="toolTip"><string>Local user ID exposed to games</string></property>
<property name="maximum"><number>2147483647</number></property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_console_language">
<property name="text"><string>Console language:</string></property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="comboBox_console_language">
<property name="toolTip"><string>Language</string></property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="1" rowspan="2">
<widget class="QGroupBox" name="graphics_group">
<property name="title">
<string>Graphics &amp;&amp; display</string>
</property>
<layout class="QFormLayout" name="graphicsLayout">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label_screen_resolution">
<property name="text"><string>Screen resolution:</string></property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="comboBox_screen_resolution">
<property name="toolTip"><string>Window resolution</string></property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_present_mode">
<property name="text"><string>Present mode:</string></property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="comboBox_present_mode">
<property name="toolTip"><string>Vulkan swapchain presentation mode</string></property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_vblank_frequency">
<property name="text"><string>Vblank frequency:</string></property>
</widget>
</item>
<item row="2" column="1">
<widget class="QSpinBox" name="spinBox_vblank_frequency">
<property name="toolTip"><string>Virtual display refresh rate used for frame pacing</string></property>
<property name="minimum"><number>30</number></property>
<property name="maximum"><number>360</number></property>
<property name="value"><number>60</number></property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_shader_optimization">
<property name="text"><string>Shader optimization:</string></property>
</widget>
</item>
<item row="3" column="1">
<widget class="QComboBox" name="comboBox_shader_optimization_type">
<property name="toolTip"><string>Optimize shaders for code size or performance</string></property>
</widget>
</item>
<item row="4" column="1">
<widget class="QCheckBox" name="checkBox_fullscreen">
<property name="toolTip"><string>Run in borderless desktop fullscreen</string></property>
<property name="text"><string>Fullscreen</string></property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QGroupBox" name="debug_group">
<property name="title">
<string>Debugging &amp;&amp; logs</string>
</property>
<layout class="QGridLayout" name="debugLayout" columnstretch="0,1,0,1">
<property name="horizontalSpacing"><number>8</number></property>
<property name="verticalSpacing"><number>6</number></property>
<item row="0" column="0" colspan="2">
<widget class="QCheckBox" name="checkBox_vulkan_validation">
<property name="toolTip"><string>Enable Vulkan validation layers</string></property>
<property name="text"><string>Vulkan validation</string></property>
<property name="checked"><bool>true</bool></property>
</widget>
</item>
<item row="0" column="2" colspan="2">
<widget class="QCheckBox" name="checkBox_shader_validation">
<property name="toolTip"><string>Validate SPIR-V binary</string></property>
<property name="text"><string>Shader validation</string></property>
<property name="checked"><bool>true</bool></property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QCheckBox" name="checkBox_renderdoc_capture">
<property name="toolTip"><string>Enable RenderDoc capture</string></property>
<property name="text"><string>RenderDoc capture</string></property>
</widget>
</item>
<item row="1" column="2" colspan="2">
<widget class="QCheckBox" name="checkBox_cmd_dump">
<property name="toolTip"><string>Dump command buffers</string></property>
<property name="text"><string>Command buffer dump</string></property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_shader_log_direction">
<property name="text"><string>Shader logging:</string></property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="comboBox_shader_log_direction">
<property name="toolTip"><string>Dump shaders to file or console window. If enabled may decrease emulator performance</string></property>
</widget>
</item>
<item row="2" column="2">
<widget class="QLabel" name="label_shader_log_folder">
<property name="text"><string>Shader log folder:</string></property>
</widget>
</item>
<item row="2" column="3">
<widget class="MandatoryLineEdit" name="lineEdit_shader_log_folder">
<property name="toolTip"><string>Specify directory to dump shaders</string></property>
<property name="clearButtonEnabled"><bool>true</bool></property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_printf_direction">
<property name="text"><string>Printf output:</string></property>
</widget>
</item>
<item row="3" column="1">
<widget class="QComboBox" name="comboBox_printf_direction">
<property name="toolTip"><string>Print logs to file or console window. If enabled may decrease emulator performance</string></property>
</widget>
</item>
<item row="3" column="2">
<widget class="QLabel" name="label_printf_file">
<property name="text"><string>Printf output file:</string></property>
</widget>
</item>
<item row="3" column="3">
<widget class="MandatoryLineEdit" name="lineEdit_printf_file">
<property name="toolTip"><string>Specify file to dump logs</string></property>
<property name="clearButtonEnabled"><bool>true</bool></property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_profiler_direction">
<property name="text"><string>Profiler:</string></property>
</widget>
</item>
<item row="4" column="1">
<widget class="QComboBox" name="comboBox_profiler_direction">
<property name="toolTip"><string>Enable or disable profiler. If enabled may decrease emulator performance</string></property>
</widget>
</item>
<item row="4" column="2">
<widget class="QLabel" name="label_cmd_dump_folder">
<property name="text"><string>Command buffer folder:</string></property>
</widget>
</item>
<item row="4" column="3">
<widget class="MandatoryLineEdit" name="lineEdit_cmd_dump_folder">
<property name="toolTip"><string>Specify directory to dump command buffers</string></property>
<property name="clearButtonEnabled"><bool>true</bool></property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="0">
<widget class="QGroupBox" name="compatibility_group">
<property name="title">
<string>Compatibility</string>
</property>
<layout class="QHBoxLayout" name="compatibilityLayout">
<item>
<widget class="QCheckBox" name="checkBox_red_zone_protection">
<property name="toolTip"><string>Helps prevent crashes in some games on Windows</string></property>
<property name="text"><string>Windows SysV red zone crash protection (Experimental)</string></property>
</widget>
</item>
<item>
<spacer name="compatibilitySpacer">
<property name="orientation"><enum>Qt::Horizontal</enum></property>
<property name="sizeHint" stdset="0">
<size><width>40</width><height>20</height></size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item row="2" column="0">
<layout class="QHBoxLayout" name="buttonLayout">
<item>
<widget class="QPushButton" name="clear_button">
<property name="minimumSize"><size><width>80</width><height>25</height></size></property>
<property name="text"><string>Reset</string></property>
<property name="toolTip"><string>Restore default settings</string></property>
</widget>
</item>
<item>
<spacer name="buttonSpacer">
<property name="orientation"><enum>Qt::Horizontal</enum></property>
<property name="sizeHint" stdset="0"><size><width>40</width><height>20</height></size></property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="cancel_button">
<property name="minimumSize">
<size>
<width>80</width>
<height>25</height>
</size>
</property>
<property name="text">
<string>Cancel</string>
</property>
<property name="minimumSize"><size><width>80</width><height>25</height></size></property>
<property name="text"><string>Cancel</string></property>
</widget>
</item>
<item>
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<widget class="QPushButton" name="ok_button">
<property name="minimumSize"><size><width>80</width><height>25</height></size></property>
<property name="text"><string>Save</string></property>
<property name="default"><bool>true</bool></property>
</widget>
</item>
<item>
<widget class="QPushButton" name="clear_button">
<property name="minimumSize">
<size>
<width>80</width>
<height>25</height>
</size>
</property>
<property name="text">
<string>Clear</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
@@ -392,16 +307,6 @@
<signal>clicked()</signal>
<receiver>ConfigurationEditDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>496</x>
<y>65</y>
</hint>
<hint type="destinationlabel">
<x>280</x>
<y>180</y>
</hint>
</hints>
</connection>
</connections>
</ui>
+1 -1
View File
@@ -1,5 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<g fill="none" stroke="#e8f1ff" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<g fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M8 4h11l5 5v7M24 9h-5V4M16 27H8a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2"/>
<path d="m15 24 1-4 8-8 4 4-8 8-4 1Z"/>
<path d="m22 14 4 4" opacity=".8"/>

Before

Width:  |  Height:  |  Size: 336 B

After

Width:  |  Height:  |  Size: 336 B

+1 -1
View File
@@ -1,5 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<g fill="none" stroke="#e8f1ff" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<g fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M5 8h3M14 8h13M5 16h13M24 16h3M5 24h6M17 24h10"/>
<circle cx="11" cy="8" r="3"/>
<circle cx="21" cy="16" r="3"/>

Before

Width:  |  Height:  |  Size: 344 B

After

Width:  |  Height:  |  Size: 344 B

+3 -3
View File
@@ -1,9 +1,9 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<g fill="none" stroke="#e8f1ff" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<g fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M10 10h12c3.6 0 5.8 2.3 6.6 6.8l.9 5.1c.4 2.4-.8 4.1-2.8 4.1-1.4 0-2.5-.7-3.6-2.3L21.3 21H10.7l-1.8 2.7C7.8 25.3 6.7 26 5.3 26c-2 0-3.2-1.7-2.8-4.1l.9-5.1C4.2 12.3 6.4 10 10 10Z"/>
<path d="M8 16h6M11 13v6"/>
<circle cx="22" cy="15" r="1" fill="#e8f1ff" stroke="none"/>
<circle cx="25" cy="18" r="1" fill="#e8f1ff" stroke="none"/>
<circle cx="22" cy="15" r="1" fill="#000000" stroke="none"/>
<circle cx="25" cy="18" r="1" fill="#000000" stroke="none"/>
<path d="M13 7h6M16 4v6" opacity=".8"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 574 B

After

Width:  |  Height:  |  Size: 574 B

+1 -1
View File
@@ -1,5 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<g fill="none" stroke="#e8f1ff" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<g fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M6 9h20M12 9V5h8v4M9 9l1 18h12l1-18"/>
<path d="M14 14v8M18 14v8" opacity=".8"/>
</g>

Before

Width:  |  Height:  |  Size: 272 B

After

Width:  |  Height:  |  Size: 272 B

@@ -10,6 +10,7 @@ class QByteArray;
class QGroupBox;
class QListWidget;
class QMoveEvent;
class QResizeEvent;
class QToolButton;
class QSettings;
class QWidget;
@@ -48,6 +49,7 @@ protected:
void AddGameDirectoryItem(const QString& dir);
void moveEvent(QMoveEvent* event) override;
void resizeEvent(QResizeEvent* event) override;
static QByteArray g_last_geometry;
@@ -11,6 +11,7 @@
class ConfigurationItem;
class CompatibilityDatabase;
class QEvent;
class QTreeWidgetItem;
class QPoint;
class MainDialog;
@@ -52,6 +53,9 @@ signals:
void Run();
void Select();
protected:
void changeEvent(QEvent* event) override;
public slots:
void WriteSettings();
void ReadSettings();
@@ -74,6 +78,7 @@ private:
void ClearCustomSettings(ConfigurationItem* item);
void SelectItem(QTreeWidgetItem* witem);
void ApplyCompatibility();
void UpdateToolbarIcons();
[[nodiscard]] bool HasValidGameDirectory() const;
ConfigurationItem* m_selected_item = nullptr;
+3 -2
View File
@@ -1,7 +1,6 @@
#ifndef GAME_LIST_TREE_WIDGET_H
#define GAME_LIST_TREE_WIDGET_H
#include <QColor>
#include <QPaintEvent>
#include <QPainter>
#include <QPalette>
@@ -44,7 +43,9 @@ protected:
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));
auto overlay = palette().color(QPalette::Base);
overlay.setAlpha(185);
painter.fillRect(event->rect(), overlay);
}
}
+12
View File
@@ -0,0 +1,12 @@
#ifndef LAUNCHER_THEME_H
#define LAUNCHER_THEME_H
class QApplication;
namespace LauncherTheme {
void Initialize(QApplication& application);
} // namespace LauncherTheme
#endif // LAUNCHER_THEME_H
+3
View File
@@ -5,4 +5,7 @@
<file alias="input-mapping.svg">icons/input-mapping.svg</file>
<file alias="remove-configuration.svg">icons/remove-configuration.svg</file>
</qresource>
<qresource prefix="/styles">
<file alias="launcher.qss">styles/launcher.qss</file>
</qresource>
</RCC>
+12 -2
View File
@@ -18,6 +18,7 @@
#include <QListWidget>
#include <QMessageBox>
#include <QPushButton>
#include <QResizeEvent>
#include <QSettings>
#include <QSpinBox>
#include <QStyle>
@@ -115,7 +116,10 @@ ConfigurationEditDialog::ConfigurationEditDialog(Configuration& info, QWidget* p
m_ui->lineEdit_printf_file->setEnabled(log == Configuration::LogDirection::File);
});
layout()->setSizeConstraint(QLayout::SetFixedSize);
// Keep the controls at a usable minimum while allowing the settings window
// and its expanding fields to use any additional space the user gives them.
layout()->setSizeConstraint(QLayout::SetMinimumSize);
setSizeGripEnabled(true);
restoreGeometry(g_last_geometry);
@@ -248,7 +252,8 @@ void ConfigurationEditDialog::SetGameDirectories(const QStringList& dirs) {
m_game_dirs_group->setVisible(true);
update_game_directory_buttons();
adjustSize();
layout()->activate();
resize(size().expandedTo(minimumSizeHint()));
}
QStringList ConfigurationEditDialog::GetGameDirectories() const {
@@ -288,6 +293,11 @@ void ConfigurationEditDialog::moveEvent(QMoveEvent* event) {
g_last_geometry = saveGeometry();
}
void ConfigurationEditDialog::resizeEvent(QResizeEvent* event) {
QDialog::resizeEvent(event);
g_last_geometry = saveGeometry();
}
static void UpdateInfo(Configuration& info, Ui::ConfigurationEditDialog& ui) {
info.user_name = ui.lineEdit_user_name->text().trimmed();
info.user_id = ui.spinBox_user_id->value();
+4 -14
View File
@@ -127,10 +127,12 @@ ConfigurationItem::ConfigurationItem(std::unique_ptr<Configuration> info, QTreeW
layout->setSpacing(6);
m_status_indicator = new QLabel(m_status_widget);
m_status_indicator->setObjectName(QStringLiteral("game_status_indicator"));
m_status_indicator->setFixedSize(QSize(12, 12));
layout->addWidget(m_status_indicator);
m_status_combo = new NoWheelComboBox(m_status_widget);
m_status_combo->setObjectName(QStringLiteral("game_status_editor"));
MakeTransparent(m_status_combo);
AddStatus(m_status_combo, Configuration::GameStatus::Unknown);
AddStatus(m_status_combo, Configuration::GameStatus::MainMenu);
@@ -139,26 +141,16 @@ ConfigurationItem::ConfigurationItem(std::unique_ptr<Configuration> info, QTreeW
AddStatus(m_status_combo, Configuration::GameStatus::DoesntBoot);
m_status_combo->setSizeAdjustPolicy(QComboBox::AdjustToContents);
m_status_combo->setFixedWidth(125);
m_status_combo->setStyleSheet(QStringLiteral(
"QComboBox { background: transparent; border: 0; color: #eef4ff; padding-left: 2px; }"
"QComboBox:focus { background: rgba(255,255,255,35); border-radius: 3px; }"
"QComboBox::drop-down { border: 0; }"
"QComboBox QAbstractItemView { background: #181c24; color: #eef4ff; "
"selection-background-color: #267bd8; }"));
layout->addWidget(m_status_combo);
layout->addStretch(1);
parent->setItemWidget(this, StatusColumn, m_status_widget);
m_comment_edit = new QLineEdit(parent);
m_comment_edit->setObjectName(QStringLiteral("game_comment_editor"));
MakeTransparent(m_comment_edit);
m_comment_edit->setClearButtonEnabled(true);
m_comment_edit->setFrame(false);
m_comment_edit->setStyleSheet(QStringLiteral(
"QLineEdit { background: transparent; border: 0; color: #eef4ff; padding-left: 2px; "
"selection-background-color: #267bd8; }"
"QLineEdit:focus { background: rgba(255,255,255,35); "
"border: 1px solid rgba(255,255,255,90); border-radius: 3px; }"));
parent->setItemWidget(this, CommentsColumn, m_comment_edit);
Update();
@@ -260,8 +252,6 @@ void ConfigurationItem::UpdateIcon() {
void ConfigurationItem::UpdateStatusIndicator() {
m_status_indicator->setStyleSheet(
QStringLiteral(
"background-color: %1; border: 1px solid rgba(255, 255, 255, 90); border-radius: 6px;")
.arg(GetStatusColor(m_info->game_status)));
QStringLiteral("background-color: %1;").arg(GetStatusColor(m_info->game_status)));
m_status_indicator->setToolTip(GetStatusText(m_info->game_status));
}
+29 -35
View File
@@ -30,6 +30,8 @@
#include <QLineEdit>
#include <QMenu>
#include <QMessageBox>
#include <QPainter>
#include <QPalette>
#include <QPushButton>
#include <QRegularExpression>
#include <QSet>
@@ -131,7 +133,7 @@ static QString GetPic0Path(const Configuration& info) {
return QFileInfo::exists(path) ? QFileInfo(path).absoluteFilePath() : QString();
}
static void ApplyGameListStyle(Ui::ConfigurationListWidget* ui) {
static void ConfigureGameList(Ui::ConfigurationListWidget* ui) {
ui->cfgs_list->setAlternatingRowColors(false);
ui->cfgs_list->setAllColumnsShowFocus(true);
ui->cfgs_list->setIndentation(0);
@@ -142,35 +144,6 @@ static void ApplyGameListStyle(Ui::ConfigurationListWidget* ui) {
ui->cfgs_list->header()->setDefaultAlignment(Qt::AlignLeft | Qt::AlignVCenter);
ui->cfgs_list->header()->setHighlightSections(false);
ui->cfgs_list->header()->setStretchLastSection(true);
ui->cfgs_list->setStyleSheet(QStringLiteral(
"QTreeWidget { background: transparent; border: 1px solid rgba(255,255,255,42); "
"color: #eef4ff; outline: 0; }"
"QTreeWidget::item { background: rgba(8,10,16,92); "
"border-bottom: 1px solid rgba(255,255,255,24); padding: 4px; }"
"QTreeWidget::item:selected { background: rgba(32,118,210,150); color: #ffffff; }"
"QHeaderView::section { background: rgba(22,25,31,235); color: #dce6f6; border: 0; "
"border-right: 1px solid rgba(255,255,255,35); border-bottom: 1px solid "
"rgba(255,255,255,45); "
"padding: 5px 6px; }"
"QScrollBar:vertical { background: rgba(12,14,18,150); width: 14px; margin: 0; }"
"QScrollBar::handle:vertical { background: rgba(220,230,245,120); min-height: 36px; }"
"QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical { height: 0; }"));
ui->search_line_edit->setStyleSheet(QStringLiteral(
"QLineEdit { background: rgba(12,14,18,210); border: 1px solid rgba(255,255,255,42); "
"border-radius: 4px; color: #eef4ff; padding: 5px 8px; selection-background-color: "
"#267bd8; }"
"QLineEdit:focus { border-color: rgba(80,160,255,180); }"));
ui->global_settings_button->setStyleSheet(QStringLiteral(
"QToolButton { background: rgba(255,255,255,18); border: 1px solid transparent; "
"border-radius: 5px; padding: 3px; }"
"QToolButton:hover { background: rgba(255,255,255,45); border-color: rgba(255,255,255,70); "
"}"
"QToolButton:disabled { background: transparent; }"));
ui->edit_button->setStyleSheet(ui->global_settings_button->styleSheet());
ui->delete_button->setStyleSheet(ui->global_settings_button->styleSheet());
ui->input_mapping_button->setStyleSheet(ui->global_settings_button->styleSheet());
}
static void AddSaveDataDir(QStringList* dirs, QSet<QString>* seen, const QString& root,
@@ -226,14 +199,11 @@ ConfigurationListWidget::ConfigurationListWidget(QWidget* parent)
m_compatibility = new CompatibilityDatabase(
QCoreApplication::arguments().contains(QStringLiteral("--local")), this);
m_ui->setupUi(this);
ApplyGameListStyle(m_ui);
ConfigureGameList(m_ui);
m_ui->global_settings_button->setIcon(QIcon(QStringLiteral(":/icons/global-settings.svg")));
UpdateToolbarIcons();
m_ui->global_settings_button->setToolTip(tr("Edit global settings and game folders"));
m_ui->input_mapping_button->setIcon(QIcon(QStringLiteral(":/icons/input-mapping.svg")));
m_ui->input_mapping_button->setToolTip(tr("Edit global input mapping"));
m_ui->edit_button->setIcon(QIcon(QStringLiteral(":/icons/edit-configuration.svg")));
m_ui->delete_button->setIcon(QIcon(QStringLiteral(":/icons/remove-configuration.svg")));
m_ui->delete_button->setEnabled(false);
m_ui->edit_button->setEnabled(false);
@@ -287,6 +257,30 @@ ConfigurationListWidget::~ConfigurationListWidget() {
delete m_ui;
}
void ConfigurationListWidget::changeEvent(QEvent* event) {
QWidget::changeEvent(event);
if (event->type() == QEvent::ApplicationPaletteChange || event->type() == QEvent::PaletteChange) {
UpdateToolbarIcons();
}
}
void ConfigurationListWidget::UpdateToolbarIcons() {
const auto color = palette().color(QPalette::Window).lightness() < 128 ? QColor(Qt::white)
: QColor(Qt::black);
const auto set_icon = [&color](QToolButton* button, const QString& resource) {
auto pixmap = QIcon(resource).pixmap(button->iconSize(), button->devicePixelRatioF());
QPainter painter(&pixmap);
painter.setCompositionMode(QPainter::CompositionMode_SourceIn);
painter.fillRect(pixmap.rect(), color);
button->setIcon(QIcon(pixmap));
};
set_icon(m_ui->global_settings_button, QStringLiteral(":/icons/global-settings.svg"));
set_icon(m_ui->input_mapping_button, QStringLiteral(":/icons/input-mapping.svg"));
set_icon(m_ui->edit_button, QStringLiteral(":/icons/edit-configuration.svg"));
set_icon(m_ui->delete_button, QStringLiteral(":/icons/remove-configuration.svg"));
}
void ConfigurationListWidget::WriteSettings() {
QFile file = QFile(QDir(".").absoluteFilePath(CONF_FILE_NAME));
std::unique_ptr<QSettings> s;
+45
View File
@@ -0,0 +1,45 @@
#include "launcherTheme.h"
#include <QApplication>
#include <QEvent>
#include <QFile>
#include <QObject>
#include <QTimer>
namespace {
class PaletteChangeFilter final: public QObject {
public:
explicit PaletteChangeFilter(QApplication& application)
: QObject(&application), m_application(application) {}
protected:
bool eventFilter(QObject* watched, QEvent* event) override {
if (event->type() == QEvent::ApplicationPaletteChange && !m_refresh_pending) {
m_refresh_pending = true;
QTimer::singleShot(0, &m_application, [this] {
m_application.setStyleSheet(m_application.styleSheet());
m_refresh_pending = false;
});
}
return QObject::eventFilter(watched, event);
}
private:
QApplication& m_application;
bool m_refresh_pending = false;
};
} // namespace
namespace LauncherTheme {
void Initialize(QApplication& application) {
QFile style_sheet_file(QStringLiteral(":/styles/launcher.qss"));
if (style_sheet_file.open(QIODevice::ReadOnly | QIODevice::Text)) {
application.setStyleSheet(QString::fromUtf8(style_sheet_file.readAll()));
application.installEventFilter(new PaletteChangeFilter(application));
}
}
} // namespace LauncherTheme
+3 -6
View File
@@ -1,18 +1,15 @@
#include "mainDialog.h"
#include "launcherTheme.h"
#include <QApplication>
#include <QArgument>
#include <QObject>
#include <QStyleFactory>
class QStyle;
int main(int argc, char* argv[]) {
QApplication a(argc, argv);
MainDialog w;
LauncherTheme::Initialize(a);
QStyle* s = QStyleFactory::create("fusion");
QApplication::setStyle(s);
MainDialog w;
QObject::connect(&a, &QApplication::aboutToQuit, &w, &MainDialog::Quit);
+108
View File
@@ -0,0 +1,108 @@
GameListTreeWidget#cfgs_list {
background: transparent;
border: 1px solid palette(mid);
color: palette(text);
outline: 0;
}
GameListTreeWidget#cfgs_list::item {
background: transparent;
border-bottom: 1px solid palette(mid);
padding: 4px;
}
GameListTreeWidget#cfgs_list::item:selected {
background: palette(highlight);
color: palette(highlighted-text);
}
GameListTreeWidget#cfgs_list QHeaderView::section {
background: palette(button);
color: palette(button-text);
border: 0;
border-right: 1px solid palette(mid);
border-bottom: 1px solid palette(mid);
padding: 5px 6px;
}
QLineEdit#search_line_edit {
background: palette(base);
border: 1px solid palette(mid);
border-radius: 4px;
color: palette(text);
padding: 5px 8px;
selection-background-color: palette(highlight);
selection-color: palette(highlighted-text);
}
QLineEdit#search_line_edit:focus {
border-color: palette(highlight);
}
QToolButton#global_settings_button,
QToolButton#input_mapping_button,
QToolButton#edit_button,
QToolButton#delete_button {
background: transparent;
border: 1px solid transparent;
border-radius: 5px;
padding: 3px;
}
QToolButton#global_settings_button:hover,
QToolButton#input_mapping_button:hover,
QToolButton#edit_button:hover,
QToolButton#delete_button:hover {
background: palette(button);
border-color: palette(mid);
}
QToolButton#global_settings_button:pressed,
QToolButton#input_mapping_button:pressed,
QToolButton#edit_button:pressed,
QToolButton#delete_button:pressed {
background: palette(midlight);
}
QComboBox#game_status_editor {
background: transparent;
border: 0;
color: palette(text);
padding-left: 2px;
}
QComboBox#game_status_editor:focus {
background: palette(button);
border-radius: 3px;
}
QComboBox#game_status_editor::drop-down {
border: 0;
}
QComboBox#game_status_editor QAbstractItemView {
background: palette(base);
color: palette(text);
selection-background-color: palette(highlight);
selection-color: palette(highlighted-text);
}
QLineEdit#game_comment_editor {
background: transparent;
border: 0;
color: palette(text);
padding-left: 2px;
selection-background-color: palette(highlight);
selection-color: palette(highlighted-text);
}
QLineEdit#game_comment_editor:focus {
background: palette(base);
border: 1px solid palette(mid);
border-radius: 3px;
}
QLabel#game_status_indicator {
border: 1px solid palette(base);
border-radius: 6px;
}