mirror of
https://git.citron-emu.org/citron/emulator
synced 2025-12-19 18:53:32 +00:00
Add UI positioning option for configuration dialog
Allows users to switch between vertical and horizontal navigation layouts. Includes new UI positioning setting, dynamic layout switching, and style animation event filter for improved UX. Signed-off-by: Zephyron <zephyron@citron-emu.org>
This commit is contained in:
@@ -158,6 +158,8 @@ add_executable(citron
|
||||
configuration/shared_translation.h
|
||||
configuration/shared_widget.cpp
|
||||
configuration/shared_widget.h
|
||||
configuration/style_animation_event_filter.cpp
|
||||
configuration/style_animation_event_filter.h
|
||||
configuration/qt_config.cpp
|
||||
configuration/qt_config.h
|
||||
debugger/console.cpp
|
||||
|
||||
@@ -31,27 +31,49 @@
|
||||
color: %%TEXT_COLOR%%;
|
||||
}
|
||||
|
||||
QWidget {
|
||||
background-color: %%BACKGROUND_COLOR%%;
|
||||
color: %%TEXT_COLOR%%;
|
||||
QWidget#nav_container {
|
||||
background-color: %%SECONDARY_BG_COLOR%%;
|
||||
border-right: 1px solid %%TERTIARY_BG_COLOR%%;
|
||||
}
|
||||
|
||||
QStackedWidget {
|
||||
background-color: %%BACKGROUND_COLOR%%;
|
||||
border: 1px solid %%SECONDARY_BG_COLOR%%;
|
||||
border-radius: 8px;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
}
|
||||
|
||||
QScrollArea {
|
||||
background-color: %%BACKGROUND_COLOR%%;
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
QScrollArea > QWidget > QWidget {
|
||||
QPushButton.tabButton {
|
||||
background-color: transparent;
|
||||
color: %%TEXT_COLOR%%;
|
||||
padding: 10px;
|
||||
padding-left: 10px;
|
||||
margin: 0px 4px;
|
||||
border-radius: 6px;
|
||||
font-weight: 500;
|
||||
border: 2px solid transparent;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
QPushButton.tabButton:hover {
|
||||
background-color: %%HOVER_BG_COLOR%%;
|
||||
}
|
||||
|
||||
QPushButton.tabButton:checked {
|
||||
color: %%ACCENT_COLOR%%;
|
||||
font-weight: bold;
|
||||
background-color: %%FOCUS_BG_COLOR%%;
|
||||
border-left: 2px solid %%ACCENT_COLOR%%;
|
||||
}
|
||||
|
||||
/* All other styles remain the same... just paste this block at the top */
|
||||
|
||||
QWidget {
|
||||
background-color: %%BACKGROUND_COLOR%%;
|
||||
color: %%TEXT_COLOR%%;
|
||||
}
|
||||
|
||||
QScrollBar:vertical {
|
||||
@@ -102,103 +124,10 @@
|
||||
width: 0px;
|
||||
}
|
||||
|
||||
QPushButton.tabButton {
|
||||
background-color: %%BUTTON_BG_COLOR%%;
|
||||
color: %%TEXT_COLOR%%;
|
||||
padding: 10px 14px;
|
||||
margin: 2px;
|
||||
border-top-left-radius: 8px;
|
||||
border-top-right-radius: 8px;
|
||||
border-bottom-left-radius: 8px;
|
||||
border-bottom-right-radius: 8px;
|
||||
min-width: 85px;
|
||||
max-width: 160px;
|
||||
font-weight: 500;
|
||||
border: 1px solid %%SECONDARY_BG_COLOR%%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
QPushButton.tabButton:checked {
|
||||
background-color: %%ACCENT_COLOR%%;
|
||||
color: #ffffff;
|
||||
font-weight: bold;
|
||||
border-color: %%ACCENT_COLOR%%;
|
||||
}
|
||||
|
||||
QPushButton.tabButton:hover:!checked {
|
||||
background-color: %%HOVER_BG_COLOR%%;
|
||||
border-color: %%TERTIARY_BG_COLOR%%;
|
||||
}
|
||||
|
||||
QPushButton.tabButton:pressed {
|
||||
background-color: %%ACCENT_COLOR_PRESSED%%;
|
||||
}
|
||||
|
||||
QTabWidget {
|
||||
background-color: %%BACKGROUND_COLOR%%;
|
||||
border: none;
|
||||
}
|
||||
|
||||
QTabWidget::pane {
|
||||
border: 1px solid %%SECONDARY_BG_COLOR%%;
|
||||
background-color: %%BACKGROUND_COLOR%%;
|
||||
border-radius: 8px;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
QTabWidget::tab-bar {
|
||||
alignment: left;
|
||||
}
|
||||
|
||||
QTabBar {
|
||||
background-color: %%BACKGROUND_COLOR%%;
|
||||
border: none;
|
||||
}
|
||||
|
||||
QTabBar::tab {
|
||||
background-color: %%BUTTON_BG_COLOR%%;
|
||||
color: %%TEXT_COLOR%%;
|
||||
padding: 12px 20px;
|
||||
margin-right: 2px;
|
||||
margin-bottom: 2px;
|
||||
border-top-left-radius: 8px;
|
||||
border-top-right-radius: 8px;
|
||||
min-width: 100px;
|
||||
font-weight: 500;
|
||||
border: 1px solid %%SECONDARY_BG_COLOR%%;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
QTabBar::tab:selected {
|
||||
background-color: %%ACCENT_COLOR%%;
|
||||
color: #ffffff;
|
||||
font-weight: bold;
|
||||
border-color: %%ACCENT_COLOR%%;
|
||||
}
|
||||
|
||||
QTabBar::tab:hover:!selected {
|
||||
background-color: %%HOVER_BG_COLOR%%;
|
||||
border-color: %%TERTIARY_BG_COLOR%%;
|
||||
}
|
||||
|
||||
QTabBar QToolButton {
|
||||
background-color: %%BUTTON_BG_COLOR%%;
|
||||
border: 1px solid %%SECONDARY_BG_COLOR%%;
|
||||
border-radius: 4px;
|
||||
padding: 4px;
|
||||
margin: 2px;
|
||||
}
|
||||
|
||||
QTabBar QToolButton:hover {
|
||||
background-color: %%HOVER_BG_COLOR%%;
|
||||
border-color: %%ACCENT_COLOR%%;
|
||||
}
|
||||
|
||||
QTabBar::scroller {
|
||||
width: 30px;
|
||||
}
|
||||
|
||||
QGroupBox {
|
||||
font-weight: bold;
|
||||
border: 1px solid %%SECONDARY_BG_COLOR%%;
|
||||
@@ -270,7 +199,6 @@
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
|
||||
QComboBox QAbstractItemView {
|
||||
background-color: %%SECONDARY_BG_COLOR%%;
|
||||
border: 1px solid %%ACCENT_COLOR%%;
|
||||
@@ -279,22 +207,6 @@
|
||||
outline: none;
|
||||
}
|
||||
|
||||
QComboBox QAbstractItemView::item {
|
||||
padding: 8px;
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
QComboBox QAbstractItemView::item:selected {
|
||||
background-color: %%ACCENT_COLOR%%;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
QComboBox QAbstractItemView::item:hover {
|
||||
background-color: %%ACCENT_COLOR_HOVER%%;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
QLineEdit {
|
||||
background-color: %%SECONDARY_BG_COLOR%%;
|
||||
border: 1px solid %%TERTIARY_BG_COLOR%%;
|
||||
@@ -305,11 +217,6 @@
|
||||
selection-background-color: %%ACCENT_COLOR%%;
|
||||
}
|
||||
|
||||
QLineEdit:focus {
|
||||
border-color: %%ACCENT_COLOR%%;
|
||||
background-color: %%FOCUS_BG_COLOR%%;
|
||||
}
|
||||
|
||||
QPushButton {
|
||||
background-color: %%ACCENT_COLOR%%;
|
||||
color: #ffffff;
|
||||
@@ -323,227 +230,56 @@
|
||||
QPushButton:hover {
|
||||
background-color: %%ACCENT_COLOR_HOVER%%;
|
||||
}
|
||||
|
||||
QPushButton:pressed {
|
||||
background-color: %%ACCENT_COLOR_PRESSED%%;
|
||||
}
|
||||
|
||||
QPushButton:disabled {
|
||||
background-color: %%TERTIARY_BG_COLOR%%;
|
||||
color: %%DISABLED_TEXT_COLOR%%;
|
||||
}
|
||||
|
||||
QToolButton {
|
||||
background-color: %%ACCENT_COLOR%%;
|
||||
color: #ffffff;
|
||||
border: none;
|
||||
padding: 8px 12px;
|
||||
border-radius: 6px;
|
||||
font-weight: bold;
|
||||
min-width: 32px;
|
||||
min-height: 24px;
|
||||
}
|
||||
|
||||
QToolButton:hover {
|
||||
background-color: %%ACCENT_COLOR_HOVER%%;
|
||||
}
|
||||
|
||||
QToolButton:pressed {
|
||||
background-color: %%ACCENT_COLOR_PRESSED%%;
|
||||
}
|
||||
|
||||
QLabel {
|
||||
color: %%TEXT_COLOR%%;
|
||||
background-color: transparent;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
QListWidget {
|
||||
background-color: %%SECONDARY_BG_COLOR%%;
|
||||
border: 1px solid %%TERTIARY_BG_COLOR%%;
|
||||
border-radius: 6px;
|
||||
color: %%TEXT_COLOR%%;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
QListWidget::item {
|
||||
padding: 8px;
|
||||
border-radius: 4px;
|
||||
margin: 1px;
|
||||
}
|
||||
|
||||
QListWidget::item:selected {
|
||||
background-color: %%ACCENT_COLOR%%;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
QListWidget::item:hover:!selected {
|
||||
background-color: %%HOVER_BG_COLOR%%;
|
||||
}
|
||||
|
||||
QSlider::groove:horizontal {
|
||||
border: 1px solid %%TERTIARY_BG_COLOR%%;
|
||||
height: 8px;
|
||||
background-color: %%SECONDARY_BG_COLOR%%;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
QSlider::handle:horizontal {
|
||||
background-color: %%ACCENT_COLOR%%;
|
||||
border: 1px solid %%ACCENT_COLOR%%;
|
||||
width: 18px;
|
||||
margin: -5px 0;
|
||||
border-radius: 9px;
|
||||
}
|
||||
|
||||
QSlider::handle:horizontal:hover {
|
||||
background-color: %%ACCENT_COLOR_HOVER%%;
|
||||
}
|
||||
|
||||
QSpinBox, QDoubleSpinBox {
|
||||
background-color: %%SECONDARY_BG_COLOR%%;
|
||||
border: 1px solid %%TERTIARY_BG_COLOR%%;
|
||||
border-radius: 6px;
|
||||
padding: 6px;
|
||||
color: %%TEXT_COLOR%%;
|
||||
min-height: 20px;
|
||||
}
|
||||
|
||||
QSpinBox:focus, QDoubleSpinBox:focus {
|
||||
border-color: %%ACCENT_COLOR%%;
|
||||
background-color: %%FOCUS_BG_COLOR%%;
|
||||
}
|
||||
|
||||
QRadioButton {
|
||||
color: %%TEXT_COLOR%%;
|
||||
spacing: 8px;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
QRadioButton::indicator {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
border: 2px solid %%TERTIARY_BG_COLOR%%;
|
||||
border-radius: 8px;
|
||||
background-color: %%SECONDARY_BG_COLOR%%;
|
||||
}
|
||||
|
||||
QRadioButton::indicator:checked {
|
||||
background-color: %%ACCENT_COLOR%%;
|
||||
border-color: %%ACCENT_COLOR%%;
|
||||
}
|
||||
|
||||
QRadioButton::indicator:hover {
|
||||
border-color: %%ACCENT_COLOR%%;
|
||||
}
|
||||
|
||||
/* High DPI specific styles */
|
||||
@media (min-resolution: 192dpi) {
|
||||
QPushButton.tabButton {
|
||||
padding: 12px 16px;
|
||||
min-width: 90px;
|
||||
max-width: 170px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
QComboBox {
|
||||
min-width: 140px;
|
||||
min-height: 32px;
|
||||
padding: 10px 14px;
|
||||
}
|
||||
|
||||
QLineEdit {
|
||||
min-height: 24px;
|
||||
padding: 10px 14px;
|
||||
}
|
||||
|
||||
QPushButton {
|
||||
min-height: 24px;
|
||||
padding: 12px 24px;
|
||||
}
|
||||
|
||||
QCheckBox::indicator {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
QRadioButton::indicator {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-resolution: 240dpi) {
|
||||
QPushButton.tabButton {
|
||||
padding: 14px 18px;
|
||||
min-width: 95px;
|
||||
max-width: 180px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
QComboBox {
|
||||
min-width: 160px;
|
||||
min-height: 36px;
|
||||
padding: 12px 16px;
|
||||
}
|
||||
|
||||
QLineEdit {
|
||||
min-height: 28px;
|
||||
padding: 12px 16px;
|
||||
}
|
||||
|
||||
QPushButton {
|
||||
min-height: 28px;
|
||||
padding: 14px 28px;
|
||||
}
|
||||
|
||||
QCheckBox::indicator {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
}
|
||||
|
||||
QRadioButton::indicator {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
}
|
||||
</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="spacing">
|
||||
<number>8</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>12</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>12</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>12</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>12</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="tabContainer">
|
||||
<property name="spacing">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QScrollArea" name="topButtonScrollArea">
|
||||
<widget class="QWidget" name="nav_container">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="verticalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||
<property name="minimumWidth">
|
||||
<number>220</number>
|
||||
</property>
|
||||
<property name="horizontalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAsNeeded</enum>
|
||||
<property name="maximumWidth">
|
||||
<number>220</number>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QScrollArea" name="topButtonScrollArea">
|
||||
<property name="widgetResizable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
@@ -552,14 +288,11 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1376</width>
|
||||
<height>51</height>
|
||||
<width>220</width>
|
||||
<height>856</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="tabButtonsLayout">
|
||||
<property name="spacing">
|
||||
<number>4</number>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<widget class="QPushButton" name="generalTabButton">
|
||||
<property name="text">
|
||||
@@ -758,21 +491,52 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="tabButtonsSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="spacing">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>12</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>12</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>12</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>12</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QScrollArea" name="horizontalNavScrollArea">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>55</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="widgetResizable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QWidget" name="horizontalNavWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1168</width>
|
||||
<height>55</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalNavLayout"/>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
@@ -785,8 +549,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1376</width>
|
||||
<height>745</height>
|
||||
<width>1168</width>
|
||||
<height>777</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="scrollAreaLayout">
|
||||
@@ -807,25 +571,21 @@
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="bottomLayout">
|
||||
<property name="spacing">
|
||||
<number>12</number>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="standardButtons">
|
||||
@@ -836,6 +596,8 @@
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#include <QScrollBar>
|
||||
#include <QString>
|
||||
#include <QTimer>
|
||||
#include <QWheelEvent>
|
||||
#include <QVBoxLayout>
|
||||
#include "common/logging/log.h"
|
||||
#include "common/settings.h"
|
||||
#include "common/settings_enums.h"
|
||||
@@ -38,89 +38,29 @@
|
||||
#include "citron/configuration/configure_system.h"
|
||||
#include "citron/configuration/configure_ui.h"
|
||||
#include "citron/configuration/configure_web.h"
|
||||
#include "citron/configuration/style_animation_event_filter.h"
|
||||
#include "citron/hotkeys.h"
|
||||
#include "citron/theme.h"
|
||||
#include "citron/uisettings.h"
|
||||
|
||||
// Event filter class to forward wheel events to scroll area's scrollbar
|
||||
class ScrollAreaWheelEventFilter : public QObject {
|
||||
public:
|
||||
explicit ScrollAreaWheelEventFilter(QScrollArea* scroll_area, QObject* parent = nullptr,
|
||||
bool prefer_horizontal = false)
|
||||
: QObject(parent), scroll_area_(scroll_area), prefer_horizontal_(prefer_horizontal) {}
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject* obj, QEvent* event) override {
|
||||
if (event->type() == QEvent::Wheel && scroll_area_) {
|
||||
auto* wheel_event = static_cast<QWheelEvent*>(event);
|
||||
const QPoint angle_delta = wheel_event->angleDelta();
|
||||
|
||||
// Determine which scrollbar to use based on scroll direction and preference
|
||||
bool use_horizontal = prefer_horizontal_ || (std::abs(angle_delta.x()) > std::abs(angle_delta.y()));
|
||||
|
||||
if (use_horizontal) {
|
||||
// Try horizontal scrolling first
|
||||
if (scroll_area_->horizontalScrollBar()->maximum() > 0) {
|
||||
QApplication::sendEvent(scroll_area_->horizontalScrollBar(), wheel_event);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Try vertical scrolling
|
||||
if (scroll_area_->verticalScrollBar()->maximum() > 0) {
|
||||
QApplication::sendEvent(scroll_area_->verticalScrollBar(), wheel_event);
|
||||
return true;
|
||||
}
|
||||
|
||||
// If vertical didn't work and we didn't try horizontal, try it now
|
||||
if (!use_horizontal && scroll_area_->horizontalScrollBar()->maximum() > 0) {
|
||||
QApplication::sendEvent(scroll_area_->horizontalScrollBar(), wheel_event);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return QObject::eventFilter(obj, event);
|
||||
}
|
||||
|
||||
private:
|
||||
QScrollArea* scroll_area_;
|
||||
bool prefer_horizontal_;
|
||||
};
|
||||
|
||||
static QScrollArea* CreateScrollArea(QWidget* widget) {
|
||||
auto* scroll_area = new QScrollArea();
|
||||
scroll_area->setWidget(widget);
|
||||
scroll_area->setWidgetResizable(true);
|
||||
scroll_area->setFrameShape(QFrame::NoFrame);
|
||||
scroll_area->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
|
||||
scroll_area->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
|
||||
|
||||
// Install event filter on the widget to forward wheel events to scrollbar
|
||||
auto* filter = new ScrollAreaWheelEventFilter(scroll_area, scroll_area);
|
||||
widget->installEventFilter(filter);
|
||||
|
||||
return scroll_area;
|
||||
}
|
||||
|
||||
// Helper function to detect if the application should be in a dark theme state
|
||||
static bool IsDarkMode() {
|
||||
const std::string& theme_name = UISettings::values.theme;
|
||||
|
||||
// Priority 1: Check for explicitly chosen dark themes.
|
||||
if (theme_name == "qdarkstyle" || theme_name == "colorful_dark" ||
|
||||
theme_name == "qdarkstyle_midnight_blue" || theme_name == "colorful_midnight_blue") {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Priority 2: Check for adaptive themes ("default" and "colorful").
|
||||
// For these, we fall back to checking the OS palette.
|
||||
if (theme_name == "default" || theme_name == "colorful") {
|
||||
const QPalette palette = qApp->palette();
|
||||
const QColor text_color = palette.color(QPalette::WindowText);
|
||||
const QColor base_color = palette.color(QPalette::Window);
|
||||
return text_color.value() > base_color.value();
|
||||
return qApp->palette().color(QPalette::WindowText).value() >
|
||||
qApp->palette().color(QPalette::Window).value();
|
||||
}
|
||||
|
||||
// Fallback for any other unknown theme (assumed light).
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -128,9 +68,9 @@ ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry_,
|
||||
InputCommon::InputSubsystem* input_subsystem,
|
||||
std::vector<VkDeviceInfo::Record>& vk_device_records,
|
||||
Core::System& system_, bool enable_web_config)
|
||||
: QDialog(parent), ui{std::make_unique<Ui::ConfigureDialog>()},
|
||||
registry(registry_), system{system_}, builder{std::make_unique<ConfigurationShared::Builder>(
|
||||
this, !system_.IsPoweredOn())},
|
||||
: QDialog(parent), ui{std::make_unique<Ui::ConfigureDialog>()}, registry(registry_),
|
||||
system{system_},
|
||||
builder{std::make_unique<ConfigurationShared::Builder>(this, !system_.IsPoweredOn())},
|
||||
applets_tab{std::make_unique<ConfigureApplets>(system_, nullptr, *builder, this)},
|
||||
audio_tab{std::make_unique<ConfigureAudio>(system_, nullptr, *builder, this)},
|
||||
cpu_tab{std::make_unique<ConfigureCpu>(system_, nullptr, *builder, this)},
|
||||
@@ -151,38 +91,37 @@ input_tab{std::make_unique<ConfigureInput>(system_, this)},
|
||||
network_tab{std::make_unique<ConfigureNetwork>(system_, this)},
|
||||
profile_tab{std::make_unique<ConfigureProfileManager>(system_, this)},
|
||||
system_tab{std::make_unique<ConfigureSystem>(system_, nullptr, *builder, this)},
|
||||
web_tab{std::make_unique<ConfigureWeb>(this)},
|
||||
rainbow_timer{new QTimer(this)} {
|
||||
web_tab{std::make_unique<ConfigureWeb>(this)}, rainbow_timer{new QTimer(this)} {
|
||||
|
||||
Settings::SetConfiguringGlobal(true);
|
||||
|
||||
setWindowFlags(Qt::Dialog | Qt::WindowTitleHint | Qt::WindowSystemMenuHint |
|
||||
Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint);
|
||||
|
||||
setAttribute(Qt::WA_TranslucentBackground, false);
|
||||
setAttribute(Qt::WA_NoSystemBackground, false);
|
||||
setAttribute(Qt::WA_DontShowOnScreen, false);
|
||||
|
||||
ui->setupUi(this);
|
||||
|
||||
// Enable wheel event scrolling on the top button scroll area (horizontal scrolling)
|
||||
auto* top_button_filter = new ScrollAreaWheelEventFilter(ui->topButtonScrollArea, this, true);
|
||||
ui->topButtonScrollArea->widget()->installEventFilter(top_button_filter);
|
||||
ui->topButtonScrollArea->installEventFilter(top_button_filter);
|
||||
auto* animation_filter = new StyleAnimationEventFilter(this);
|
||||
const auto button_qlist = ui->topButtonWidget->findChildren<QPushButton*>();
|
||||
tab_buttons = std::vector<QPushButton*>(button_qlist.begin(), button_qlist.end());
|
||||
auto* nav_layout = new QVBoxLayout();
|
||||
nav_layout->setContentsMargins(8, 8, 8, 8);
|
||||
nav_layout->setSpacing(4);
|
||||
for (QPushButton* button : tab_buttons) {
|
||||
button->setParent(ui->topButtonWidget);
|
||||
// Buttons are added to a layout in SetUIPositioning
|
||||
if (button->property("class").toString() == QStringLiteral("tabButton")) {
|
||||
button->installEventFilter(animation_filter);
|
||||
}
|
||||
}
|
||||
delete ui->topButtonWidget->layout();
|
||||
ui->topButtonWidget->setLayout(nav_layout);
|
||||
|
||||
last_palette_text_color = qApp->palette().color(QPalette::WindowText);
|
||||
|
||||
if (!UISettings::values.configure_dialog_geometry.isEmpty()) {
|
||||
restoreGeometry(UISettings::values.configure_dialog_geometry);
|
||||
}
|
||||
|
||||
UpdateTheme();
|
||||
|
||||
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
|
||||
tab_button_group = std::make_unique<QButtonGroup>(this);
|
||||
tab_button_group->setExclusive(true);
|
||||
|
||||
tab_button_group->addButton(ui->generalTabButton, 0);
|
||||
tab_button_group->addButton(ui->uiTabButton, 1);
|
||||
tab_button_group->addButton(ui->systemTabButton, 2);
|
||||
@@ -217,36 +156,25 @@ rainbow_timer{new QTimer(this)} {
|
||||
|
||||
connect(tab_button_group.get(), qOverload<int>(&QButtonGroup::idClicked), this, [this](int id) {
|
||||
ui->stackedWidget->setCurrentIndex(id);
|
||||
if (id == 14) {
|
||||
debug_tab_tab->SetCurrentIndex(0);
|
||||
}
|
||||
});
|
||||
|
||||
connect(ui_tab.get(), &ConfigureUi::themeChanged, this, &ConfigureDialog::UpdateTheme);
|
||||
connect(ui_tab.get(), &ConfigureUi::UIPositioningChanged, this, &ConfigureDialog::SetUIPositioning);
|
||||
connect(rainbow_timer, &QTimer::timeout, this, &ConfigureDialog::UpdateTheme);
|
||||
|
||||
web_tab->SetWebServiceConfigEnabled(enable_web_config);
|
||||
hotkeys_tab->Populate(registry);
|
||||
|
||||
input_tab->Initialize(input_subsystem);
|
||||
|
||||
general_tab->SetResetCallback([&] { this->close(); });
|
||||
|
||||
SetConfiguration();
|
||||
|
||||
connect(ui_tab.get(), &ConfigureUi::LanguageChanged, this, &ConfigureDialog::OnLanguageChanged);
|
||||
|
||||
if (system.IsPoweredOn()) {
|
||||
QPushButton* apply_button = ui->buttonBox->button(QDialogButtonBox::Apply);
|
||||
if (apply_button) {
|
||||
connect(apply_button, &QAbstractButton::clicked, this,
|
||||
&ConfigureDialog::HandleApplyButtonClicked);
|
||||
if (auto* apply_button = ui->buttonBox->button(QDialogButtonBox::Apply)) {
|
||||
connect(apply_button, &QAbstractButton::clicked, this, &ConfigureDialog::HandleApplyButtonClicked);
|
||||
}
|
||||
}
|
||||
|
||||
ui->stackedWidget->setCurrentIndex(0);
|
||||
ui->generalTabButton->setChecked(true);
|
||||
ui->buttonBox->setFocus();
|
||||
|
||||
SetUIPositioning(QString::fromStdString(UISettings::values.ui_positioning.GetValue()));
|
||||
}
|
||||
|
||||
ConfigureDialog::~ConfigureDialog() {
|
||||
@@ -257,25 +185,17 @@ void ConfigureDialog::UpdateTheme() {
|
||||
QString accent_color_str;
|
||||
if (UISettings::values.enable_rainbow_mode.GetValue()) {
|
||||
rainbow_hue += 0.003f;
|
||||
if (rainbow_hue > 1.0f) {
|
||||
rainbow_hue = 0.0f;
|
||||
}
|
||||
if (rainbow_hue > 1.0f) rainbow_hue = 0.0f;
|
||||
QColor accent_color = QColor::fromHsvF(rainbow_hue, 0.8f, 1.0f);
|
||||
accent_color_str = accent_color.name(QColor::HexRgb);
|
||||
if (!rainbow_timer->isActive()) {
|
||||
rainbow_timer->start(150);
|
||||
}
|
||||
if (!rainbow_timer->isActive()) rainbow_timer->start(150);
|
||||
} else {
|
||||
if (rainbow_timer->isActive()) {
|
||||
rainbow_timer->stop();
|
||||
}
|
||||
if (rainbow_timer->isActive()) rainbow_timer->stop();
|
||||
accent_color_str = Theme::GetAccentColor();
|
||||
}
|
||||
|
||||
QColor accent_color(accent_color_str);
|
||||
const QString accent_color_hover = accent_color.lighter(115).name(QColor::HexRgb);
|
||||
const QString accent_color_pressed = accent_color.darker(120).name(QColor::HexRgb);
|
||||
|
||||
const bool is_dark = IsDarkMode();
|
||||
const QString bg_color = is_dark ? QStringLiteral("#2b2b2b") : QStringLiteral("#ffffff");
|
||||
const QString text_color = is_dark ? QStringLiteral("#ffffff") : QStringLiteral("#000000");
|
||||
@@ -285,20 +205,14 @@ void ConfigureDialog::UpdateTheme() {
|
||||
const QString hover_bg_color = is_dark ? QStringLiteral("#4d4d4d") : QStringLiteral("#e8f0fe");
|
||||
const QString focus_bg_color = is_dark ? QStringLiteral("#404040") : QStringLiteral("#e8f0fe");
|
||||
const QString disabled_text_color = is_dark ? QStringLiteral("#8d8d8d") : QStringLiteral("#a0a0a0");
|
||||
|
||||
static QString cached_template_style_sheet;
|
||||
if (cached_template_style_sheet.isEmpty()) {
|
||||
cached_template_style_sheet = property("templateStyleSheet").toString();
|
||||
}
|
||||
|
||||
QString style_sheet = cached_template_style_sheet;
|
||||
|
||||
// Replace accent colors (existing logic)
|
||||
style_sheet.replace(QStringLiteral("%%ACCENT_COLOR%%"), accent_color_str);
|
||||
style_sheet.replace(QStringLiteral("%%ACCENT_COLOR_HOVER%%"), accent_color_hover);
|
||||
style_sheet.replace(QStringLiteral("%%ACCENT_COLOR_PRESSED%%"), accent_color_pressed);
|
||||
|
||||
// Replace base theme colors (new logic)
|
||||
style_sheet.replace(QStringLiteral("%%BACKGROUND_COLOR%%"), bg_color);
|
||||
style_sheet.replace(QStringLiteral("%%TEXT_COLOR%%"), text_color);
|
||||
style_sheet.replace(QStringLiteral("%%SECONDARY_BG_COLOR%%"), secondary_bg_color);
|
||||
@@ -307,10 +221,7 @@ void ConfigureDialog::UpdateTheme() {
|
||||
style_sheet.replace(QStringLiteral("%%HOVER_BG_COLOR%%"), hover_bg_color);
|
||||
style_sheet.replace(QStringLiteral("%%FOCUS_BG_COLOR%%"), focus_bg_color);
|
||||
style_sheet.replace(QStringLiteral("%%DISABLED_TEXT_COLOR%%"), disabled_text_color);
|
||||
|
||||
setStyleSheet(style_sheet);
|
||||
|
||||
// This part is crucial to pass the theme to child tabs
|
||||
graphics_tab->SetTemplateStyleSheet(style_sheet);
|
||||
system_tab->SetTemplateStyleSheet(style_sheet);
|
||||
audio_tab->SetTemplateStyleSheet(style_sheet);
|
||||
@@ -318,6 +229,50 @@ void ConfigureDialog::UpdateTheme() {
|
||||
graphics_advanced_tab->SetTemplateStyleSheet(style_sheet);
|
||||
}
|
||||
|
||||
void ConfigureDialog::SetUIPositioning(const QString& positioning) {
|
||||
auto* v_layout = qobject_cast<QVBoxLayout*>(ui->topButtonWidget->layout());
|
||||
auto* h_layout = qobject_cast<QHBoxLayout*>(ui->horizontalNavWidget->layout());
|
||||
|
||||
if (!v_layout || !h_layout) {
|
||||
LOG_ERROR(Frontend, "Could not find navigation layouts to rearrange");
|
||||
return;
|
||||
}
|
||||
|
||||
if (positioning == QStringLiteral("Horizontal")) {
|
||||
ui->nav_container->hide();
|
||||
ui->horizontalNavScrollArea->show();
|
||||
// Remove stretch from vertical layout if it exists
|
||||
if (v_layout->count() > 0) {
|
||||
if (auto* item = v_layout->itemAt(v_layout->count() - 1); item && item->spacerItem()) {
|
||||
v_layout->takeAt(v_layout->count() - 1);
|
||||
delete item;
|
||||
}
|
||||
}
|
||||
for (QPushButton* button : tab_buttons) {
|
||||
v_layout->removeWidget(button);
|
||||
h_layout->addWidget(button);
|
||||
button->setStyleSheet(QStringLiteral("text-align: center;"));
|
||||
}
|
||||
h_layout->addStretch(1);
|
||||
} else { // Vertical
|
||||
ui->horizontalNavScrollArea->hide();
|
||||
ui->nav_container->show();
|
||||
// Remove stretch from horizontal layout if it exists
|
||||
if (h_layout->count() > 0) {
|
||||
if (auto* item = h_layout->itemAt(h_layout->count() - 1); item && item->spacerItem()) {
|
||||
h_layout->takeAt(h_layout->count() - 1);
|
||||
delete item;
|
||||
}
|
||||
}
|
||||
for (QPushButton* button : tab_buttons) {
|
||||
h_layout->removeWidget(button);
|
||||
v_layout->addWidget(button);
|
||||
button->setStyleSheet(QStringLiteral("")); // Reset to parent stylesheet
|
||||
}
|
||||
v_layout->addStretch(1);
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigureDialog::SetConfiguration() {}
|
||||
|
||||
void ConfigureDialog::ApplyConfiguration() {
|
||||
@@ -344,23 +299,18 @@ void ConfigureDialog::changeEvent(QEvent* event) {
|
||||
if (event->type() == QEvent::LanguageChange) {
|
||||
RetranslateUI();
|
||||
}
|
||||
|
||||
if (event->type() == QEvent::PaletteChange) {
|
||||
const QColor current_color = qApp->palette().color(QPalette::WindowText);
|
||||
if (current_color != last_palette_text_color) {
|
||||
last_palette_text_color = current_color;
|
||||
if (qApp->palette().color(QPalette::WindowText) != last_palette_text_color) {
|
||||
last_palette_text_color = qApp->palette().color(QPalette::WindowText);
|
||||
UpdateTheme();
|
||||
}
|
||||
}
|
||||
|
||||
QDialog::changeEvent(event);
|
||||
}
|
||||
|
||||
void ConfigureDialog::RetranslateUI() {
|
||||
const int old_index = ui->stackedWidget->currentIndex();
|
||||
|
||||
ui->retranslateUi(this);
|
||||
|
||||
SetConfiguration();
|
||||
ui->stackedWidget->setCurrentIndex(old_index);
|
||||
}
|
||||
|
||||
@@ -9,24 +9,17 @@
|
||||
#include <QColor>
|
||||
#include <QDialog>
|
||||
#include "common/settings_enums.h"
|
||||
#include "citron/configuration/shared_widget.h" // <-- Correct header for Builder
|
||||
#include "citron/configuration/shared_widget.h"
|
||||
|
||||
// Forward declarations for other types
|
||||
// Forward declarations
|
||||
class HotkeyRegistry;
|
||||
class QButtonGroup;
|
||||
class QPushButton;
|
||||
class QTimer;
|
||||
namespace InputCommon {
|
||||
class InputSubsystem;
|
||||
}
|
||||
namespace Core {
|
||||
class System;
|
||||
}
|
||||
namespace VkDeviceInfo {
|
||||
class Record;
|
||||
}
|
||||
namespace Ui {
|
||||
class ConfigureDialog;
|
||||
}
|
||||
namespace InputCommon { class InputSubsystem; }
|
||||
namespace Core { class System; }
|
||||
namespace VkDeviceInfo { class Record; }
|
||||
namespace Ui { class ConfigureDialog; }
|
||||
class ConfigureApplets;
|
||||
class ConfigureAudio;
|
||||
class ConfigureCpu;
|
||||
@@ -62,18 +55,17 @@ public slots:
|
||||
signals:
|
||||
void LanguageChanged(const QString& locale);
|
||||
|
||||
private slots:
|
||||
void SetUIPositioning(const QString& positioning);
|
||||
|
||||
private:
|
||||
void SetConfiguration();
|
||||
void HandleApplyButtonClicked();
|
||||
|
||||
void changeEvent(QEvent* event) override;
|
||||
void RetranslateUI();
|
||||
|
||||
void OnLanguageChanged(const QString& locale);
|
||||
|
||||
QColor last_palette_text_color;
|
||||
|
||||
// All members are now in the EXACT correct order to match the constructor
|
||||
std::unique_ptr<Ui::ConfigureDialog> ui;
|
||||
HotkeyRegistry& registry;
|
||||
Core::System& system;
|
||||
@@ -94,6 +86,7 @@ private:
|
||||
std::unique_ptr<ConfigureSystem> system_tab;
|
||||
std::unique_ptr<ConfigureWeb> web_tab;
|
||||
std::unique_ptr<QButtonGroup> tab_button_group;
|
||||
std::vector<QPushButton*> tab_buttons;
|
||||
QTimer* rainbow_timer;
|
||||
float rainbow_hue = 0.0f;
|
||||
};
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
#include <QCoreApplication>
|
||||
#include <QDirIterator>
|
||||
#include <QFileDialog>
|
||||
#include <QFormLayout>
|
||||
#include <QGroupBox>
|
||||
#include <QString>
|
||||
#include <QToolButton>
|
||||
#include <QVariant>
|
||||
@@ -115,6 +117,19 @@ resolution_setting{Settings::values.resolution_setup.GetValue()}, system{system_
|
||||
QString::fromUtf8(theme.second));
|
||||
}
|
||||
|
||||
ui_positioning_combo = new QComboBox(this);
|
||||
ui_positioning_combo->addItem(tr("Vertical"), QStringLiteral("Vertical"));
|
||||
ui_positioning_combo->addItem(tr("Horizontal"), QStringLiteral("Horizontal"));
|
||||
if (auto* layout = qobject_cast<QFormLayout*>(ui->theme_combobox->parentWidget()->layout())) {
|
||||
layout->addRow(tr("UI Positioning"), ui_positioning_combo);
|
||||
} else if (auto* group_layout = qobject_cast<QVBoxLayout*>(ui->theme_combobox->parentWidget()->layout())) {
|
||||
group_layout->addWidget(ui_positioning_combo);
|
||||
}
|
||||
|
||||
connect(ui_positioning_combo, &QComboBox::currentTextChanged, this, [this](const QString& text){
|
||||
emit UIPositioningChanged(text);
|
||||
});
|
||||
|
||||
InitializeIconSizeComboBox();
|
||||
InitializeRowComboBoxes();
|
||||
|
||||
@@ -174,6 +189,7 @@ ConfigureUi::~ConfigureUi() = default;
|
||||
void ConfigureUi::ApplyConfiguration() {
|
||||
UISettings::values.theme =
|
||||
ui->theme_combobox->itemData(ui->theme_combobox->currentIndex()).toString().toStdString();
|
||||
UISettings::values.ui_positioning = ui_positioning_combo->currentData().toString().toStdString();
|
||||
UISettings::values.enable_rainbow_mode = ui->rainbowModeCheckBox->isChecked();
|
||||
UISettings::values.show_add_ons = ui->show_add_ons->isChecked();
|
||||
UISettings::values.show_compat = ui->show_compat->isChecked();
|
||||
@@ -205,6 +221,8 @@ void ConfigureUi::SetConfiguration() {
|
||||
ui->theme_combobox->findData(QString::fromStdString(UISettings::values.theme)));
|
||||
ui->language_combobox->setCurrentIndex(ui->language_combobox->findData(
|
||||
QString::fromStdString(UISettings::values.language.GetValue())));
|
||||
ui_positioning_combo->setCurrentIndex(ui_positioning_combo->findData(
|
||||
QString::fromStdString(UISettings::values.ui_positioning.GetValue())));
|
||||
ui->rainbowModeCheckBox->setChecked(UISettings::values.enable_rainbow_mode.GetValue());
|
||||
ui->show_add_ons->setChecked(UISettings::values.show_add_ons.GetValue());
|
||||
ui->show_compat->setChecked(UISettings::values.show_compat.GetValue());
|
||||
@@ -252,6 +270,11 @@ void ConfigureUi::changeEvent(QEvent* event) {
|
||||
void ConfigureUi::RetranslateUI() {
|
||||
ui->retranslateUi(this);
|
||||
|
||||
const int pos_index = ui_positioning_combo->currentIndex();
|
||||
ui_positioning_combo->setItemText(0, tr("Vertical"));
|
||||
ui_positioning_combo->setItemText(1, tr("Horizontal"));
|
||||
ui_positioning_combo->setCurrentIndex(pos_index);
|
||||
|
||||
for (int i = 0; i < ui->game_icon_size_combobox->count(); i++) {
|
||||
ui->game_icon_size_combobox->setItemText(i,
|
||||
GetTranslatedGameIconSize(static_cast<size_t>(i)));
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
#include <QWidget>
|
||||
#include "common/settings_enums.h"
|
||||
|
||||
class QComboBox;
|
||||
|
||||
namespace Core {
|
||||
class System;
|
||||
}
|
||||
@@ -31,6 +33,7 @@ public:
|
||||
signals:
|
||||
void LanguageChanged(const QString& locale);
|
||||
void themeChanged();
|
||||
void UIPositioningChanged(const QString& positioning);
|
||||
|
||||
private slots:
|
||||
void OnLanguageChanged(int index);
|
||||
@@ -54,6 +57,7 @@ private:
|
||||
void UpdateWidthText();
|
||||
|
||||
std::unique_ptr<Ui::ConfigureUi> ui;
|
||||
QComboBox* ui_positioning_combo;
|
||||
|
||||
Settings::AspectRatio ratio;
|
||||
Settings::ResolutionSetup resolution_setting;
|
||||
|
||||
20
src/citron/configuration/style_animation_event_filter.cpp
Normal file
20
src/citron/configuration/style_animation_event_filter.cpp
Normal file
@@ -0,0 +1,20 @@
|
||||
// SPDX-FileCopyrightText: 2016 Citra Emulator Project
|
||||
// SPDX-FileCopyrightText: 2025 citron Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "citron/configuration/style_animation_event_filter.h"
|
||||
#include <QEvent>
|
||||
#include <QPropertyAnimation>
|
||||
#include <QWidget>
|
||||
|
||||
StyleAnimationEventFilter::StyleAnimationEventFilter(QObject* parent) : QObject(parent) {}
|
||||
|
||||
bool StyleAnimationEventFilter::eventFilter(QObject* obj, QEvent* event) {
|
||||
if (event->type() == QEvent::Enter || event->type() == QEvent::Leave) {
|
||||
if (auto* widget = qobject_cast<QWidget*>(obj)) {
|
||||
// Trigger style update for hover effects
|
||||
widget->update();
|
||||
}
|
||||
}
|
||||
return QObject::eventFilter(obj, event);
|
||||
}
|
||||
17
src/citron/configuration/style_animation_event_filter.h
Normal file
17
src/citron/configuration/style_animation_event_filter.h
Normal file
@@ -0,0 +1,17 @@
|
||||
// SPDX-FileCopyrightText: 2016 Citra Emulator Project
|
||||
// SPDX-FileCopyrightText: 2025 citron Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class StyleAnimationEventFilter : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit StyleAnimationEventFilter(QObject* parent = nullptr);
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject* obj, QEvent* event) override;
|
||||
};
|
||||
@@ -169,6 +169,7 @@ namespace UISettings {
|
||||
Setting<std::string> language{linkage, {}, "language", Category::Paths};
|
||||
|
||||
std::string theme;
|
||||
Setting<std::string> ui_positioning{linkage, "Vertical", "ui_positioning", Category::Ui};
|
||||
|
||||
Setting<std::string> accent_color{linkage, "#4a9eff", "accent_color", Category::Ui};
|
||||
Setting<bool> enable_rainbow_mode{linkage, false, "enable_rainbow_mode", Category::Ui};
|
||||
|
||||
Reference in New Issue
Block a user