Skip to content

Commit

Permalink
Experiemental slider improvement
Browse files Browse the repository at this point in the history
  • Loading branch information
Hartmnt committed Jan 5, 2024
1 parent 8dc98c9 commit e8ee737
Show file tree
Hide file tree
Showing 12 changed files with 179 additions and 50 deletions.
26 changes: 0 additions & 26 deletions src/mumble/InlineWidgets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,32 +9,6 @@
#include <QKeyEvent>
#include <QWidget>

UpDownKeyEventFilter::UpDownKeyEventFilter(QObject *parent) : QObject(parent) {
}

bool UpDownKeyEventFilter::eventFilter(QObject *obj, QEvent *event) {
// Converts up/down to tab/backtab
// Useful when overriding interactive QWidgetActions such as sliders

if (event->type() == QEvent::KeyPress) {
QKeyEvent *keyEvent = static_cast< QKeyEvent * >(event);

if (keyEvent->key() == Qt::Key_Up) {
QKeyEvent *keyPress = new QKeyEvent(QEvent::KeyPress, Qt::Key_Backtab, Qt::NoModifier);
QApplication::sendEvent(QApplication::focusWidget(), keyPress);
return true;
}

if (keyEvent->key() == Qt::Key_Down) {
QKeyEvent *keyPress = new QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier);
QApplication::sendEvent(QApplication::focusWidget(), keyPress);
return true;
}
}

return QObject::eventFilter(obj, event);
}

OverrideTabOrderFilter::OverrideTabOrderFilter(QObject *parent, QWidget *target)
: QObject(parent), focusTarget(target) {
}
Expand Down
10 changes: 0 additions & 10 deletions src/mumble/InlineWidgets.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,6 @@
#include <QMenu>
#include <QObject>

class UpDownKeyEventFilter : public QObject {
Q_OBJECT

public:
UpDownKeyEventFilter(QObject *parent);

protected:
bool eventFilter(QObject *obj, QEvent *event) override;
};

class OverrideTabOrderFilter : public QObject {
Q_OBJECT

Expand Down
1 change: 1 addition & 0 deletions src/mumble/ListenerVolumeSlider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ void ListenerVolumeSlider::on_VolumeSlider_changeCompleted() {
}

VolumeAdjustment adjustment = VolumeAdjustment::fromDBAdjustment(m_volumeSlider->value());
updateLabelValue();

if (handler->m_version >= Mumble::Protocol::PROTOBUF_INTRODUCTION_VERSION) {
// With the new audio protocol, volume adjustments for listeners are handled on the server and thus we want
Expand Down
1 change: 1 addition & 0 deletions src/mumble/MainWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
#endif

#include <QAccessible>
#include <QResizeEvent>
#include <QtCore/QStandardPaths>
#include <QtCore/QUrlQuery>
#include <QtGui/QClipboard>
Expand Down
42 changes: 41 additions & 1 deletion src/mumble/MenuLabel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,56 @@
// Mumble source tree or at <https://www.mumble.info/LICENSE>.

#include "MenuLabel.h"
#include "widgets/EventFilters.h"

#include <QLabel>

MenuLabel::MenuLabel(const QString &text, QObject *parent) : QWidgetAction(parent), m_text(text) {
MenuLabel::MenuLabel(const QString &text, QObject *parent)
: QWidgetAction(parent), m_text(text), m_accessibleName(""), m_accessibleDescription("") {
setMenuRole(QAction::NoRole);
}

QWidget *MenuLabel::createWidget(QWidget *parent) {
QLabel *label = new QLabel(m_text, parent);

label->setAccessibleName(m_accessibleName);
label->setAccessibleDescription(m_accessibleDescription);
label->setFocusPolicy(Qt::TabFocus);
label->installEventFilter(new SkipFocusEventFilter(label));

return label;
}

QString MenuLabel::text() {
return m_text;
}

void MenuLabel::setText(const QString &text) {
m_text = text;

QLabel *label = qobject_cast< QLabel * >(defaultWidget());
if (label) {
label->setText(text);
label->update();
}
}

void MenuLabel::setAccessibleName(const QString &name) {
m_accessibleName = name;

QLabel *label = qobject_cast< QLabel * >(defaultWidget());
if (label) {
label->setAccessibleName(m_accessibleName);
label->update();
}
}

void MenuLabel::setAccessibleDescription(const QString &description) {
m_accessibleDescription = description;

QLabel *label = qobject_cast< QLabel * >(defaultWidget());
if (label) {
label->setAccessibleDescription(m_accessibleDescription);
label->update();
}
}
9 changes: 8 additions & 1 deletion src/mumble/MenuLabel.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,18 @@ class MenuLabel : public QWidgetAction {
public:
MenuLabel(const QString &text, QObject *parent = nullptr);

QString text();
void setText(const QString &name);
void setAccessibleName(const QString &name);
void setAccessibleDescription(const QString &description);

protected:
QWidget *createWidget(QWidget *parent) override;

private:
const QString m_text;
QString m_text;
QString m_accessibleName;
QString m_accessibleDescription;
};

#endif
2 changes: 2 additions & 0 deletions src/mumble/UserLocalVolumeSlider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,7 @@ void UserLocalVolumeSlider::on_VolumeSlider_changeCompleted() {
} else {
Global::get().mw->logChangeNotPermanent(QObject::tr("Local Volume Adjustment..."), user);
}

updateLabelValue();
}
}
4 changes: 2 additions & 2 deletions src/mumble/UserLocalVolumeSlider.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ class UserLocalVolumeSlider : public VolumeSliderWidgetAction {
void setUser(unsigned int sessionId);

private slots:
void on_VolumeSlider_valueChanged(int value);
void on_VolumeSlider_changeCompleted();
void on_VolumeSlider_valueChanged(int value) override;
void on_VolumeSlider_changeCompleted() override;
};

#endif
49 changes: 40 additions & 9 deletions src/mumble/VolumeSliderWidgetAction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,30 @@
// Mumble source tree or at <https://www.mumble.info/LICENSE>.

#include "VolumeSliderWidgetAction.h"
#include "InlineWidgets.h"
#include "MumbleApplication.h"
#include "VolumeAdjustment.h"
#include "widgets/EventFilters.h"

#include <QSlider>
#include <QToolTip>
#include <QHBoxLayout>
#include <QLabel>

VolumeSliderWidgetAction::VolumeSliderWidgetAction(QWidget *parent)
: QWidgetAction(parent), m_volumeSlider(make_qt_unique< QSlider >(Qt::Horizontal, parent)) {
: QWidgetAction(parent),
m_widget(make_qt_unique< QWidget >(parent)),
m_volumeSlider(new QSlider(Qt::Horizontal, parent)),
m_label(new QLabel("0 db", parent)) {

m_volumeSlider->setMinimum(-30);
m_volumeSlider->setMaximum(30);
m_volumeSlider->setAccessibleName(tr("Slider for volume adjustment"));
m_volumeSlider->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
m_volumeSlider->setAccessibleName(tr("Local volume adjustment"));

m_label->setStyleSheet("QLabel { margin-left: 0px; padding: 0px; }");
m_volumeSlider->setStyleSheet("QSlider { margin-right: 0px; }");

KeyEventObserver *keyEventFilter = new KeyEventObserver(this, QEvent::KeyRelease, false,
{ Qt::Key_Left, Qt::Key_Right, Qt::Key_Up, Qt::Key_Down });
{ Qt::Key_Left, Qt::Key_Right });
m_volumeSlider->installEventFilter(keyEventFilter);

// The list of wheel events observed seems odd at first. We have to check for multiple
Expand All @@ -33,27 +41,50 @@ VolumeSliderWidgetAction::VolumeSliderWidgetAction(QWidget *parent)
new MouseWheelEventObserver(this, { Qt::ScrollMomentum, Qt::ScrollUpdate, Qt::ScrollEnd }, false);
m_volumeSlider->installEventFilter(wheelEventFilter);

connect(m_volumeSlider.get(), &QSlider::valueChanged, this,
connect(m_volumeSlider, &QSlider::valueChanged, this,
&VolumeSliderWidgetAction::on_VolumeSlider_valueChanged);
connect(m_volumeSlider.get(), &QSlider::sliderReleased, this,
connect(m_volumeSlider, &QSlider::sliderReleased, this,
[=]() { m_volumeSlider->setFocus(Qt::TabFocusReason); updateLabelValue(false); });
connect(m_volumeSlider, &QSlider::sliderReleased, this,
&VolumeSliderWidgetAction::on_VolumeSlider_changeCompleted);
connect(keyEventFilter, &KeyEventObserver::keyEventObserved, this,
&VolumeSliderWidgetAction::on_VolumeSlider_changeCompleted);
connect(wheelEventFilter, &MouseWheelEventObserver::wheelEventObserved, this,
&VolumeSliderWidgetAction::on_VolumeSlider_changeCompleted);

setDefaultWidget(m_volumeSlider.get());

UpDownKeyEventFilter *eventFilter = new UpDownKeyEventFilter(this);
m_volumeSlider->installEventFilter(eventFilter);

m_volumeSlider->setProperty("mouseTracking", true);

QHBoxLayout *layout = new QHBoxLayout();
layout->addWidget(m_volumeSlider);
layout->addWidget(m_label);
layout->setContentsMargins(0, 0, -1, 0);
layout->setSpacing(3);
m_widget->setLayout(layout);

m_widget->setFocusProxy(m_volumeSlider);
m_widget->setFocusPolicy(Qt::TabFocus);

setDefaultWidget(m_widget.get());
}

void VolumeSliderWidgetAction::updateLabelValue(bool checkMouseButtons) {
if (checkMouseButtons && MumbleApplication::instance()->mouseButtons() != Qt::NoButton) {
// Do not update the label while the user is dragging the slider.
// This will otherwise cause a glitchy experience.
return;
}

m_label->setText(QString("%01dB").arg(m_volumeSlider->value()));
}

void VolumeSliderWidgetAction::updateSliderValue(float value) {
int dbShift = VolumeAdjustment::toIntegerDBAdjustment(value);
m_volumeSlider->setValue(dbShift);
updateTooltip(dbShift);
updateLabelValue(false);
}

void VolumeSliderWidgetAction::updateTooltip(int value) {
Expand Down
7 changes: 6 additions & 1 deletion src/mumble/VolumeSliderWidgetAction.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#include "QtUtils.h"

class QSlider;
class QHBoxLayout;
class QLabel;

class VolumeSliderWidgetAction : public QWidgetAction {
Q_OBJECT
Expand All @@ -19,8 +21,11 @@ class VolumeSliderWidgetAction : public QWidgetAction {
VolumeSliderWidgetAction(QWidget *parent = nullptr);

protected:
qt_unique_ptr< QSlider > m_volumeSlider;
qt_unique_ptr< QWidget > m_widget;
QSlider* m_volumeSlider;
QLabel* m_label;

void updateLabelValue(bool checkMouseButtons = true);
void updateSliderValue(float value);
void displayTooltip(int value);
void updateTooltip(int value);
Expand Down
58 changes: 58 additions & 0 deletions src/mumble/widgets/EventFilters.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,15 @@

#include <algorithm>

#include <QApplication>
#include <QKeyEvent>
#include <QWheelEvent>
#include <QWidget>

#include <QString>
#include <QMessageBox>
#include <QDebug>

KeyEventObserver::KeyEventObserver(QObject *parent, QEvent::Type eventType, bool consume, std::vector< Qt::Key > keys)
: QObject(parent), m_eventType(eventType), m_consume(consume), m_keys(std::move(keys)) {
}
Expand Down Expand Up @@ -66,3 +71,56 @@ bool MouseWheelEventObserver::eventFilter(QObject *obj, QEvent *event) {

return m_consume;
}


UpDownKeyEventFilter::UpDownKeyEventFilter(QObject *parent) : QObject(parent) {
}

bool UpDownKeyEventFilter::eventFilter(QObject *obj, QEvent *event) {
// Converts up/down to tab/backtab
// Useful when overriding interactive QWidgetActions such as sliders

if (event->type() == QEvent::KeyPress) {
QKeyEvent *keyEvent = static_cast< QKeyEvent * >(event);

if (keyEvent->key() == Qt::Key_Up) {
QKeyEvent *keyPress = new QKeyEvent(QEvent::KeyPress, Qt::Key_Backtab, Qt::NoModifier);
QApplication::sendEvent(QApplication::focusWidget(), keyPress);
return true;
}

if (keyEvent->key() == Qt::Key_Down) {
QKeyEvent *keyPress = new QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier);
QApplication::sendEvent(QApplication::focusWidget(), keyPress);
return true;
}
}

return QObject::eventFilter(obj, event);
}

SkipFocusEventFilter::SkipFocusEventFilter(QObject *parent) : QObject(parent) {
}

bool SkipFocusEventFilter::eventFilter(QObject *obj, QEvent *event) {
if (event->type() == QEvent::KeyRelease) {
QKeyEvent *keyEvent = static_cast< QKeyEvent * >(event);

qDebug() << keyEvent->key();
qDebug() << QApplication::focusWidget() == obj;

if (keyEvent->key() == Qt::Key_Up || keyEvent->key() == Qt::Key_Backtab) {
QKeyEvent *keyPress = new QKeyEvent(QEvent::KeyPress, Qt::Key_Backtab, Qt::NoModifier);
QApplication::sendEvent(QApplication::focusWidget(), keyPress);
return true;
}

if (keyEvent->key() == Qt::Key_Down || keyEvent->key() == Qt::Key_Tab) {
QKeyEvent *keyPress = new QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier);
QApplication::sendEvent(QApplication::focusWidget(), keyPress);
return true;
}
}

return QObject::eventFilter(obj, event);
}
20 changes: 20 additions & 0 deletions src/mumble/widgets/EventFilters.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,24 @@ class MouseWheelEventObserver : public QObject {
bool m_consume;
};

class UpDownKeyEventFilter : public QObject {
Q_OBJECT

public:
UpDownKeyEventFilter(QObject *parent);

protected:
bool eventFilter(QObject *obj, QEvent *event) override;
};

class SkipFocusEventFilter : public QObject {
Q_OBJECT

public:
SkipFocusEventFilter(QObject *parent);

protected:
bool eventFilter(QObject *obj, QEvent *event) override;
};

#endif

0 comments on commit e8ee737

Please sign in to comment.