mirror of
https://github.com/obsproject/obs-studio.git
synced 2026-05-18 21:38:29 -04:00
frontend: Create event filter for widget state styles
This commit is contained in:
@@ -1760,7 +1760,6 @@ QTableView::indicator:unchecked {
|
||||
QCheckBox::indicator:unchecked:hover,
|
||||
QGroupBox::indicator:unchecked:hover,
|
||||
QTableView::indicator:unchecked:hover {
|
||||
border: none;
|
||||
image: url(theme:Yami/checkbox_unchecked_focus.svg);
|
||||
}
|
||||
|
||||
@@ -2321,11 +2320,11 @@ idian--ToggleSwitch {
|
||||
border: var(--highlight_width) solid transparent;
|
||||
}
|
||||
|
||||
idian--ToggleSwitch:hover {
|
||||
idian--ToggleSwitch.hover {
|
||||
border-color: var(--grey4);
|
||||
}
|
||||
|
||||
idian--ToggleSwitch:checked:hover {
|
||||
idian--ToggleSwitch.checked.hover {
|
||||
border-color: var(--white1);
|
||||
}
|
||||
|
||||
@@ -2333,13 +2332,13 @@ idian--ToggleSwitch.keyFocus {
|
||||
border-color: var(--highlight_color);
|
||||
}
|
||||
|
||||
idian--Row idian--ToggleSwitch:hover,
|
||||
idian--Row idian--ToggleSwitch.hover,
|
||||
idian--Row.hover > idian--ToggleSwitch.row-buddy {
|
||||
border-color: var(--grey1);
|
||||
}
|
||||
|
||||
idian--Row idian--ToggleSwitch:checked:hover,
|
||||
idian--Row.hover idian--ToggleSwitch.row-buddy:checked {
|
||||
idian--Row idian--ToggleSwitch.hover.checked,
|
||||
idian--Row.hover > idian--ToggleSwitch.checked.row-buddy {
|
||||
border-color: var(--white1);
|
||||
}
|
||||
|
||||
@@ -2358,7 +2357,7 @@ idian--Row QComboBox:focus {
|
||||
border-color: transparent;
|
||||
}
|
||||
|
||||
idian--Row QComboBox:hover {
|
||||
idian--Row QComboBox.hover {
|
||||
border-color: var(--grey1);
|
||||
}
|
||||
|
||||
@@ -2383,7 +2382,7 @@ idian--Row QComboBox QAbstractItemView::item {
|
||||
padding: var(--padding_base) var(--padding_large);
|
||||
}
|
||||
|
||||
idian--Row QComboBox QAbstractItemView::item:hover,
|
||||
idian--Row QComboBox QAbstractItemView.hover::item,
|
||||
idian--Row QComboBox QAbstractItemView::item:selected {
|
||||
background-color: var(--list_item_bg_selected);
|
||||
padding: var(--padding_base) var(--padding_large);
|
||||
@@ -2406,32 +2405,30 @@ idian--Row idian--CheckBox {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
idian--Row idian--CheckBox::indicator,
|
||||
idian--Row idian--CheckBox::indicator:unchecked:hover {
|
||||
idian--CheckBox::indicator {
|
||||
border: var(--highlight_width) solid transparent;
|
||||
border-radius: var(--border_radius);
|
||||
}
|
||||
|
||||
idian--Row.hover > idian--CheckBox.row-buddy::indicator,
|
||||
idian--Row > idian--CheckBox::indicator:unchecked:hover,
|
||||
idian--Row > idian--CheckBox::indicator:hover {
|
||||
border-color: var(--grey1);
|
||||
}
|
||||
|
||||
idian--Row.hover > idian--CheckBox.row-buddy::indicator:unchecked,
|
||||
idian--CheckBox.keyFocus::indicator:unchecked {
|
||||
idian--CheckBox.keyFocus::indicator,
|
||||
idian--Row.hover > idian--CheckBox.row-buddy::indicator {
|
||||
image: url(theme:Yami/checkbox_unchecked_focus.svg);
|
||||
}
|
||||
|
||||
idian--Row idian--CheckBox.keyFocus::indicator,
|
||||
idian--Row.hover > idian--CheckBox::indicator {
|
||||
idian--CheckBox.keyFocus.checked::indicator,
|
||||
idian--Row.hover > idian--CheckBox.row-buddy.checked::indicator {
|
||||
image: url(theme:Yami/checkbox_checked_focus.svg);
|
||||
}
|
||||
|
||||
idian--Row idian--CheckBox.keyFocus::indicator,
|
||||
idian--Row idian--CheckBox.keyFocus::indicator:unchecked,
|
||||
idian--Row idian--CheckBox.keyFocus::indicator:hover,
|
||||
idian--Row idian--CheckBox.keyFocus::indicator:unchecked:hover {
|
||||
idian--CheckBox.hover::indicator,
|
||||
idian--CheckBox.checked.hover::indicator,
|
||||
idian--Row.hover > idian--CheckBox.row-buddy::indicator
|
||||
idian--Row.hover > idian--CheckBox.row-buddy.checked::indicator {
|
||||
border-color: var(--grey1);
|
||||
}
|
||||
|
||||
idian--CheckBox.keyFocus::indicator,
|
||||
idian--CheckBox.keyFocus.checked::indicator {
|
||||
border-color: var(--highlight_color);
|
||||
}
|
||||
|
||||
@@ -2503,16 +2500,15 @@ idian--RowFrame.hover .btn-frame {
|
||||
background: var(--grey4);
|
||||
}
|
||||
|
||||
idian--RowFrame.hover idian--Row,
|
||||
idian--RowFrame.hover idian--Row.hover {
|
||||
idian--RowFrame.hover idian--Row {
|
||||
background: var(--grey4);
|
||||
border: 2px solid var(--grey1);
|
||||
border: var(--highlight_width) solid var(--grey1);
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
idian--RowFrame.hover .row-buddy {
|
||||
background: var(--grey4);
|
||||
border: 2px solid var(--grey1);
|
||||
border: var(--highlight_width) solid var(--grey1);
|
||||
border-left: none;
|
||||
}
|
||||
|
||||
|
||||
@@ -229,3 +229,8 @@ QCalendarWidget QToolButton:pressed {
|
||||
QCalendarWidget QSpinBox {
|
||||
background-color: var(--primary_dark);
|
||||
}
|
||||
|
||||
idian--ToggleSwitch {
|
||||
qproperty-background_checked: var(--button_bg);
|
||||
qproperty-background_checked_hover: var(--primary_light);
|
||||
}
|
||||
|
||||
@@ -324,3 +324,33 @@ QCalendarWidget #qt_calendar_prevmonth {
|
||||
QCalendarWidget #qt_calendar_nextmonth {
|
||||
qproperty-icon: url(theme:Light/right.svg);
|
||||
}
|
||||
|
||||
/* Idian Widgets */
|
||||
idian--ToggleSwitch {
|
||||
qproperty-background: var(--grey8);
|
||||
qproperty-background_hover: var(--grey7);
|
||||
qproperty-background_checked: var(--primary);
|
||||
qproperty-background_checked_hover: var(--primary_light);
|
||||
}
|
||||
|
||||
idian--Row QComboBox::down-arrow {
|
||||
image: url(theme:Light/collapse.svg);
|
||||
}
|
||||
|
||||
idian--CheckBox.keyFocus::indicator,
|
||||
idian--Row.hover > idian--CheckBox.row-buddy::indicator {
|
||||
image: url(theme:Light/checkbox_unchecked_focus.svg);
|
||||
}
|
||||
|
||||
idian--CheckBox.keyFocus.checked::indicator,
|
||||
idian--Row.hover > idian--CheckBox.row-buddy.checked::indicator {
|
||||
image: url(theme:Light/checkbox_checked_focus.svg);
|
||||
}
|
||||
|
||||
idian--ExpandButton::indicator {
|
||||
image: url(theme:Light/down.svg);
|
||||
}
|
||||
|
||||
idian--ExpandButton::indicator:checked {
|
||||
image: url(theme:Light/up.svg);
|
||||
}
|
||||
|
||||
@@ -22,7 +22,10 @@ target_sources(
|
||||
include/Idian/Row.hpp
|
||||
include/Idian/SpinBox.hpp
|
||||
include/Idian/ToggleSwitch.hpp
|
||||
include/Idian/Utils.cpp
|
||||
include/Idian/Utils.hpp
|
||||
include/Idian/StateEventFilter.cpp
|
||||
include/Idian/StateEventFilter.hpp
|
||||
widgets/Group.cpp
|
||||
widgets/PropertiesList.cpp
|
||||
widgets/Row.cpp
|
||||
|
||||
@@ -21,4 +21,7 @@
|
||||
|
||||
using idian::CheckBox;
|
||||
|
||||
CheckBox::CheckBox(QWidget *parent) : QCheckBox(parent), Utils(this) {}
|
||||
CheckBox::CheckBox(QWidget *parent) : QCheckBox(parent), Utils(this)
|
||||
{
|
||||
Utils::applyStateStylingEventFilter(this);
|
||||
}
|
||||
|
||||
@@ -25,7 +25,10 @@
|
||||
|
||||
using idian::ComboBox;
|
||||
|
||||
ComboBox::ComboBox(QWidget *parent) : QComboBox(parent), Utils(this) {}
|
||||
ComboBox::ComboBox(QWidget *parent) : QComboBox(parent), Utils(this)
|
||||
{
|
||||
Utils::applyStateStylingEventFilter(this);
|
||||
}
|
||||
|
||||
void ComboBox::showPopup()
|
||||
{
|
||||
|
||||
@@ -38,6 +38,8 @@ ToggleSwitch::ToggleSwitch(QWidget *parent)
|
||||
animBgColor(new QPropertyAnimation(this, "blend", this)),
|
||||
Utils(this)
|
||||
{
|
||||
Utils::applyStateStylingEventFilter(this);
|
||||
|
||||
offPos = rect().width() / 2 - 18;
|
||||
onPos = rect().width() / 2 + 18;
|
||||
xPos = offPos;
|
||||
|
||||
@@ -28,19 +28,6 @@ class CheckBox : public QCheckBox, public Utils {
|
||||
|
||||
public:
|
||||
CheckBox(QWidget *parent = nullptr);
|
||||
|
||||
protected:
|
||||
void focusInEvent(QFocusEvent *e) override
|
||||
{
|
||||
Utils::showKeyFocused(e);
|
||||
QAbstractButton::focusInEvent(e);
|
||||
}
|
||||
|
||||
void focusOutEvent(QFocusEvent *e) override
|
||||
{
|
||||
Utils::hideKeyFocused(e);
|
||||
QAbstractButton::focusOutEvent(e);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace idian
|
||||
|
||||
@@ -41,18 +41,6 @@ protected:
|
||||
void hidePopup() override;
|
||||
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
|
||||
void focusInEvent(QFocusEvent *e) override
|
||||
{
|
||||
Utils::showKeyFocused(e);
|
||||
QComboBox::focusInEvent(e);
|
||||
}
|
||||
|
||||
void focusOutEvent(QFocusEvent *e) override
|
||||
{
|
||||
Utils::hideKeyFocused(e);
|
||||
QComboBox::focusOutEvent(e);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace idian
|
||||
|
||||
@@ -39,7 +39,13 @@ class GenericRow : public QFrame, public Utils {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
GenericRow(QWidget *parent = nullptr) : QFrame(parent), Utils(this) { setAccessibleName(""); };
|
||||
GenericRow(QWidget *parent = nullptr) : QFrame(parent), Utils(this)
|
||||
{
|
||||
setAttribute(Qt::WA_Hover, true);
|
||||
|
||||
applyStateStylingEventFilter(this);
|
||||
setAccessibleName("");
|
||||
};
|
||||
|
||||
virtual void setTitle(const QString &title) = 0;
|
||||
virtual void setDescription(const QString &description) = 0;
|
||||
@@ -84,18 +90,6 @@ protected:
|
||||
void keyReleaseEvent(QKeyEvent *) override;
|
||||
bool hasDescription() const { return descriptionLabel != nullptr; }
|
||||
|
||||
void focusInEvent(QFocusEvent *event) override
|
||||
{
|
||||
Utils::showKeyFocused(event);
|
||||
QFrame::focusInEvent(event);
|
||||
}
|
||||
|
||||
void focusOutEvent(QFocusEvent *event) override
|
||||
{
|
||||
Utils::hideKeyFocused(event);
|
||||
QFrame::focusOutEvent(event);
|
||||
}
|
||||
|
||||
private:
|
||||
QGridLayout *layout;
|
||||
|
||||
@@ -127,18 +121,6 @@ protected:
|
||||
explicit ExpandButton(QWidget *parent = nullptr);
|
||||
|
||||
void paintEvent(QPaintEvent *) override;
|
||||
|
||||
void focusInEvent(QFocusEvent *event) override
|
||||
{
|
||||
Utils::showKeyFocused(event);
|
||||
QAbstractButton::focusInEvent(event);
|
||||
}
|
||||
|
||||
void focusOutEvent(QFocusEvent *event) override
|
||||
{
|
||||
Utils::hideKeyFocused(event);
|
||||
QAbstractButton::focusOutEvent(event);
|
||||
}
|
||||
};
|
||||
|
||||
class RowFrame : protected QFrame, protected Utils {
|
||||
@@ -153,18 +135,6 @@ protected:
|
||||
void enterEvent(QEnterEvent *) override;
|
||||
void leaveEvent(QEvent *) override;
|
||||
|
||||
void focusInEvent(QFocusEvent *event) override
|
||||
{
|
||||
Utils::showKeyFocused(event);
|
||||
QWidget::focusInEvent(event);
|
||||
}
|
||||
|
||||
void focusOutEvent(QFocusEvent *event) override
|
||||
{
|
||||
Utils::hideKeyFocused(event);
|
||||
QWidget::focusOutEvent(event);
|
||||
}
|
||||
|
||||
private:
|
||||
friend class CollapsibleRow;
|
||||
};
|
||||
|
||||
78
shared/qt/idian/include/Idian/StateEventFilter.cpp
Normal file
78
shared/qt/idian/include/Idian/StateEventFilter.cpp
Normal file
@@ -0,0 +1,78 @@
|
||||
#include <Idian/StateEventFilter.hpp>
|
||||
#include <Idian/Utils.hpp>
|
||||
|
||||
#include <QAbstractButton>
|
||||
#include <QLabel>
|
||||
|
||||
namespace idian {
|
||||
StateEventFilter::StateEventFilter(idian::Utils *utils, QWidget *target) : QObject(target), target(target), utils(utils)
|
||||
{
|
||||
QAbstractButton *button = qobject_cast<QAbstractButton *>(target);
|
||||
if (button) {
|
||||
connect(button, &QAbstractButton::toggled, this, &StateEventFilter::updateCheckedState);
|
||||
}
|
||||
}
|
||||
|
||||
bool StateEventFilter::eventFilter(QObject *obj, QEvent *event)
|
||||
{
|
||||
if (!obj->isWidgetType()) {
|
||||
return QObject::eventFilter(obj, event);
|
||||
}
|
||||
|
||||
QWidget *widget = qobject_cast<QWidget *>(obj);
|
||||
QFocusEvent *focusEvent = nullptr;
|
||||
|
||||
switch (event->type()) {
|
||||
case QEvent::FocusIn:
|
||||
utils->toggleClass(widget, "focus", true);
|
||||
|
||||
focusEvent = static_cast<QFocusEvent *>(event);
|
||||
if (focusEvent->reason() != Qt::MouseFocusReason && focusEvent->reason() != Qt::PopupFocusReason) {
|
||||
utils->toggleClass(widget, "keyFocus", true);
|
||||
} else {
|
||||
utils->toggleClass(widget, "keyFocus", false);
|
||||
}
|
||||
|
||||
utils->polishChildren(widget);
|
||||
break;
|
||||
case QEvent::FocusOut:
|
||||
utils->toggleClass(widget, "focus", false);
|
||||
|
||||
focusEvent = static_cast<QFocusEvent *>(event);
|
||||
if (focusEvent->reason() != Qt::PopupFocusReason) {
|
||||
utils->toggleClass(widget, "keyFocus", false);
|
||||
utils->polishChildren(widget);
|
||||
}
|
||||
|
||||
break;
|
||||
case QEvent::MouseButtonPress:
|
||||
break;
|
||||
case QEvent::HoverEnter:
|
||||
if (widget->isEnabled()) {
|
||||
utils->toggleClass(widget, "hover", true);
|
||||
}
|
||||
|
||||
utils->polishChildren(widget);
|
||||
break;
|
||||
case QEvent::HoverLeave:
|
||||
utils->toggleClass(widget, "hover", false);
|
||||
|
||||
utils->polishChildren(widget);
|
||||
break;
|
||||
case QEvent::EnabledChange:
|
||||
bool widgetEnabled = widget->isEnabled();
|
||||
utils->toggleClass(widget, "disabled", !widgetEnabled);
|
||||
|
||||
utils->polishChildren(widget);
|
||||
break;
|
||||
}
|
||||
|
||||
return QObject::eventFilter(obj, event);
|
||||
}
|
||||
|
||||
void StateEventFilter::updateCheckedState(bool checked)
|
||||
{
|
||||
utils->toggleClass(target, "checked", checked);
|
||||
}
|
||||
|
||||
} // namespace idian
|
||||
25
shared/qt/idian/include/Idian/StateEventFilter.hpp
Normal file
25
shared/qt/idian/include/Idian/StateEventFilter.hpp
Normal file
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include <Idian/Utils.hpp>
|
||||
|
||||
#include <QWidget>
|
||||
#include <QAbstractbutton>
|
||||
#include <QStyleOptionButton>
|
||||
|
||||
namespace idian {
|
||||
class StateEventFilter : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit StateEventFilter(idian::Utils *utils, QWidget *parent);
|
||||
|
||||
bool eventFilter(QObject *obj, QEvent *event);
|
||||
|
||||
public slots:
|
||||
void updateCheckedState(bool checked);
|
||||
|
||||
private:
|
||||
Utils *utils;
|
||||
QWidget *target;
|
||||
};
|
||||
} // namespace idian
|
||||
@@ -82,18 +82,6 @@ protected:
|
||||
void keyReleaseEvent(QKeyEvent *) override;
|
||||
void mouseReleaseEvent(QMouseEvent *) override;
|
||||
|
||||
void focusInEvent(QFocusEvent *e) override
|
||||
{
|
||||
Utils::showKeyFocused(e);
|
||||
QAbstractButton::focusInEvent(e);
|
||||
}
|
||||
|
||||
void focusOutEvent(QFocusEvent *e) override
|
||||
{
|
||||
Utils::hideKeyFocused(e);
|
||||
QAbstractButton::focusOutEvent(e);
|
||||
}
|
||||
|
||||
private slots:
|
||||
void onClicked(bool checked);
|
||||
|
||||
|
||||
10
shared/qt/idian/include/Idian/Utils.cpp
Normal file
10
shared/qt/idian/include/Idian/Utils.cpp
Normal file
@@ -0,0 +1,10 @@
|
||||
#include <Idian/Utils.hpp>
|
||||
#include <Idian/StateEventFilter.hpp>
|
||||
|
||||
namespace idian {
|
||||
|
||||
void Utils::applyStateStylingEventFilter(QWidget *widget)
|
||||
{
|
||||
widget->installEventFilter(new StateEventFilter(this, widget));
|
||||
}
|
||||
} // namespace idian
|
||||
@@ -18,6 +18,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <QFocusEvent>
|
||||
#include <QPainter>
|
||||
#include <QRegularExpression>
|
||||
#include <QStyle>
|
||||
#include <QWidget>
|
||||
@@ -39,23 +40,6 @@ public:
|
||||
|
||||
Utils(QWidget *w) { parent = w; }
|
||||
|
||||
// Set a custom property whenever the widget has keyboard focus specifically
|
||||
void showKeyFocused(QFocusEvent *e)
|
||||
{
|
||||
if (e->reason() != Qt::MouseFocusReason && e->reason() != Qt::PopupFocusReason) {
|
||||
addClass("keyFocus");
|
||||
} else {
|
||||
removeClass("keyFocus");
|
||||
}
|
||||
}
|
||||
|
||||
void hideKeyFocused(QFocusEvent *e)
|
||||
{
|
||||
if (e->reason() != Qt::PopupFocusReason) {
|
||||
removeClass("keyFocus");
|
||||
}
|
||||
}
|
||||
|
||||
// Force all children widgets to repaint
|
||||
void polishChildren() { polishChildren(parent); }
|
||||
|
||||
@@ -91,9 +75,11 @@ public:
|
||||
}
|
||||
|
||||
classList.removeDuplicates();
|
||||
classList.removeAll("");
|
||||
classList.append(classname);
|
||||
|
||||
widget->setProperty("class", classList.join(" "));
|
||||
QString newClasses = classList.isEmpty() ? "" : classList.join(" ");
|
||||
widget->setProperty("class", newClasses);
|
||||
|
||||
repolish(widget);
|
||||
}
|
||||
@@ -118,9 +104,11 @@ public:
|
||||
}
|
||||
|
||||
classList.removeDuplicates();
|
||||
classList.removeAll("");
|
||||
classList.removeAll(classname);
|
||||
|
||||
widget->setProperty("class", classList.join(" "));
|
||||
QString newClasses = classList.isEmpty() ? "" : classList.join(" ");
|
||||
widget->setProperty("class", newClasses);
|
||||
|
||||
repolish(widget);
|
||||
}
|
||||
@@ -136,6 +124,8 @@ public:
|
||||
removeClass(widget, classname);
|
||||
}
|
||||
}
|
||||
|
||||
void applyStateStylingEventFilter(QWidget *widget);
|
||||
};
|
||||
|
||||
} // namespace idian
|
||||
|
||||
@@ -157,8 +157,6 @@ void Row::enterEvent(QEnterEvent *event)
|
||||
setCursor(Qt::PointingHandCursor);
|
||||
}
|
||||
|
||||
Utils::addClass("hover");
|
||||
|
||||
if (buddyWidget)
|
||||
Utils::repolish(buddyWidget);
|
||||
|
||||
@@ -171,8 +169,6 @@ void Row::enterEvent(QEnterEvent *event)
|
||||
|
||||
void Row::leaveEvent(QEvent *event)
|
||||
{
|
||||
Utils::removeClass("hover");
|
||||
|
||||
if (buddyWidget)
|
||||
Utils::repolish(buddyWidget);
|
||||
|
||||
@@ -236,6 +232,7 @@ void Row::connectBuddyWidget(QWidget *widget)
|
||||
// Button for expanding a collapsible ActionRow
|
||||
ExpandButton::ExpandButton(QWidget *parent) : QAbstractButton(parent), Utils(this)
|
||||
{
|
||||
Utils::applyStateStylingEventFilter(this);
|
||||
setCheckable(true);
|
||||
}
|
||||
|
||||
@@ -358,13 +355,17 @@ void CollapsibleRow::addRow(GenericRow *actionRow)
|
||||
propertyList->addRow(actionRow);
|
||||
}
|
||||
|
||||
RowFrame::RowFrame(QWidget *parent) : QFrame(parent), Utils(this) {}
|
||||
RowFrame::RowFrame(QWidget *parent) : QFrame(parent), Utils(this)
|
||||
{
|
||||
setAttribute(Qt::WA_Hover, true);
|
||||
|
||||
Utils::applyStateStylingEventFilter(this);
|
||||
}
|
||||
|
||||
void RowFrame::enterEvent(QEnterEvent *event)
|
||||
{
|
||||
setCursor(Qt::PointingHandCursor);
|
||||
|
||||
Utils::addClass("hover");
|
||||
Utils::polishChildren();
|
||||
|
||||
QWidget::enterEvent(event);
|
||||
@@ -372,7 +373,6 @@ void RowFrame::enterEvent(QEnterEvent *event)
|
||||
|
||||
void RowFrame::leaveEvent(QEvent *event)
|
||||
{
|
||||
Utils::removeClass("hover");
|
||||
Utils::polishChildren();
|
||||
|
||||
QWidget::leaveEvent(event);
|
||||
|
||||
Reference in New Issue
Block a user