mirror of
https://git.citron-emu.org/citron/emulator
synced 2025-12-19 10:43:33 +00:00
Improve StyleAnimationEventFilter with padding animations
Replace simple style updates with smooth padding animations (10px ↔ 14px) on tab button hover. Add PaddingAnimator helper class and proper animation tracking for better visual feedback. Signed-off-by: Zephyron <zephyron@citron-emu.org>
This commit is contained in:
@@ -1,20 +1,75 @@
|
|||||||
// SPDX-FileCopyrightText: 2016 Citra Emulator Project
|
|
||||||
// SPDX-FileCopyrightText: 2025 citron Emulator Project
|
// SPDX-FileCopyrightText: 2025 citron Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include "citron/configuration/style_animation_event_filter.h"
|
#include "citron/configuration/style_animation_event_filter.h"
|
||||||
#include <QEvent>
|
#include <QEvent>
|
||||||
|
#include <QPushButton>
|
||||||
#include <QPropertyAnimation>
|
#include <QPropertyAnimation>
|
||||||
#include <QWidget>
|
|
||||||
|
// A helper class that owns the property being animated.
|
||||||
|
class PaddingAnimator : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(int padding READ GetPadding WRITE SetPadding)
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit PaddingAnimator(QPushButton* button, int initial_padding)
|
||||||
|
: QObject(button), target_button(button), current_padding(initial_padding) {}
|
||||||
|
|
||||||
|
void SetPadding(int padding) {
|
||||||
|
current_padding = padding;
|
||||||
|
target_button->setStyleSheet(QStringLiteral("padding-left: %1px;").arg(padding));
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetPadding() const { return current_padding; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
QPushButton* target_button;
|
||||||
|
int current_padding;
|
||||||
|
};
|
||||||
|
|
||||||
StyleAnimationEventFilter::StyleAnimationEventFilter(QObject* parent) : QObject(parent) {}
|
StyleAnimationEventFilter::StyleAnimationEventFilter(QObject* parent) : QObject(parent) {}
|
||||||
|
StyleAnimationEventFilter::~StyleAnimationEventFilter() = default;
|
||||||
|
|
||||||
bool StyleAnimationEventFilter::eventFilter(QObject* obj, QEvent* event) {
|
void StyleAnimationEventFilter::animatePadding(QPushButton* button, int end) {
|
||||||
if (event->type() == QEvent::Enter || event->type() == QEvent::Leave) {
|
if (animations.contains(button)) {
|
||||||
if (auto* widget = qobject_cast<QWidget*>(obj)) {
|
animations.value(button)->stop();
|
||||||
// Trigger style update for hover effects
|
|
||||||
widget->update();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int start_padding = 10; // Assume a default start padding
|
||||||
|
// A better approach would be to parse the current stylesheet, but this is safer for now.
|
||||||
|
if (end == 10) { // If shrinking, start from the expanded state
|
||||||
|
start_padding = 14;
|
||||||
}
|
}
|
||||||
return QObject::eventFilter(obj, event);
|
|
||||||
|
auto* animator = new PaddingAnimator(button, start_padding);
|
||||||
|
auto* animation = new QPropertyAnimation(animator, "padding", this);
|
||||||
|
|
||||||
|
animation->setDuration(150);
|
||||||
|
animation->setStartValue(start_padding);
|
||||||
|
animation->setEndValue(end);
|
||||||
|
animation->setEasingCurve(QEasingCurve::OutQuad);
|
||||||
|
|
||||||
|
animations.insert(button, animation);
|
||||||
|
|
||||||
|
connect(animation, &QPropertyAnimation::finished, this, [this, button](){
|
||||||
|
animations.remove(button);
|
||||||
|
});
|
||||||
|
|
||||||
|
animation->start(QAbstractAnimation::DeleteWhenStopped);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool StyleAnimationEventFilter::eventFilter(QObject* watched, QEvent* event) {
|
||||||
|
auto* button = qobject_cast<QPushButton*>(watched);
|
||||||
|
if (!button) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event->type() == QEvent::Enter) {
|
||||||
|
animatePadding(button, 14); // Grow
|
||||||
|
} else if (event->type() == QEvent::Leave) {
|
||||||
|
animatePadding(button, 10); // Shrink
|
||||||
|
}
|
||||||
|
return QObject::eventFilter(watched, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "citron/configuration/style_animation_event_filter.moc"
|
||||||
|
|||||||
@@ -1,17 +1,26 @@
|
|||||||
// SPDX-FileCopyrightText: 2016 Citra Emulator Project
|
|
||||||
// SPDX-FileCopyrightText: 2025 citron Emulator Project
|
// SPDX-FileCopyrightText: 2025 citron Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
#include <QHash>
|
||||||
|
|
||||||
class StyleAnimationEventFilter : public QObject {
|
class QPropertyAnimation;
|
||||||
|
class QPushButton;
|
||||||
|
|
||||||
|
class StyleAnimationEventFilter final : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit StyleAnimationEventFilter(QObject* parent = nullptr);
|
explicit StyleAnimationEventFilter(QObject* parent = nullptr);
|
||||||
|
~StyleAnimationEventFilter() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool eventFilter(QObject* obj, QEvent* event) override;
|
bool eventFilter(QObject* watched, QEvent* event) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void animatePadding(QPushButton* button, int end);
|
||||||
|
|
||||||
|
QHash<QPushButton*, QPropertyAnimation*> animations;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user