Skip to content

Commit

Permalink
Merge pull request mixxxdj#11767 from ronso0/refocus-library
Browse files Browse the repository at this point in the history
Refocus library
  • Loading branch information
daschuer authored Jul 28, 2023
2 parents cde8402 + fe58227 commit fe25d77
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 33 deletions.
12 changes: 7 additions & 5 deletions src/library/autodj/dlgautodj.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -349,8 +349,9 @@ void DlgAutoDJ::slotTransitionModeChanged(int newIndex) {
m_pAutoDJProcessor->setTransitionMode(
static_cast<AutoDJProcessor::TransitionMode>(
fadeModeCombobox->itemData(newIndex).toInt()));
// Move focus to tracks table to immediately allow keyboard shortcuts again.
setFocus();
// Clicking on a transition mode item moves keyboard focus to the list widget.
// Move focus back to the previously focused library widget.
ControlObject::set(ConfigKey("[Library]", "refocus_prev_widget"), 1);
}

void DlgAutoDJ::slotRepeatPlaylistChanged(int checkState) {
Expand Down Expand Up @@ -394,12 +395,13 @@ void DlgAutoDJ::setFocus() {
}

void DlgAutoDJ::keyPressEvent(QKeyEvent* pEvent) {
// Return, Enter and Escape key move focus to the AutoDJ queue to immediately
// allow keyboard shortcuts again.
// If we receive key events either the mode selector or the spinbox are focused.
// Return, Enter and Escape move focus back to the previously focused
// library widget in order to immediately allow keyboard shortcuts again.
if (pEvent->key() == Qt::Key_Return ||
pEvent->key() == Qt::Key_Enter ||
pEvent->key() == Qt::Key_Escape) {
setFocus();
ControlObject::set(ConfigKey("[Library]", "refocus_prev_widget"), 1);
return;
}
return QWidget::keyPressEvent(pEvent);
Expand Down
50 changes: 39 additions & 11 deletions src/library/librarycontrol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ void LoadToGroupController::slotLoadToGroupAndPlay(double v) {
LibraryControl::LibraryControl(Library* pLibrary)
: QObject(pLibrary),
m_pLibrary(pLibrary),
m_pFocusedWidget(FocusWidget::None),
m_focusedWidget(FocusWidget::None),
m_prevFocusedWidget(FocusWidget::None),
m_pLibraryWidget(nullptr),
m_pSidebarWidget(nullptr),
m_pSearchbox(nullptr),
Expand Down Expand Up @@ -172,6 +173,17 @@ LibraryControl::LibraryControl(Library* pLibrary)
});
#endif

// Pure trigger control. Alternative for signal/slot since widgets that want
// to call refocusPrevLibraryWidget() are cumbersome to connect to.
// This CO is never actually set or read so the value just needs to be not 0
m_pRefocusPrevWidgetCO = std::make_unique<ControlPushButton>(
ConfigKey("[Library]", "refocus_prev_widget"));
m_pRefocusPrevWidgetCO->setButtonMode(ControlPushButton::TRIGGER);
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
m_pRefocusPrevWidgetCO->connectValueChangeRequest(this,
&LibraryControl::refocusPrevLibraryWidget);
#endif

// Control to "goto" the currently selected item in focused widget (context dependent)
m_pGoToItem = std::make_unique<ControlPushButton>(ConfigKey("[Library]", "GoToItem"));
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
Expand Down Expand Up @@ -411,7 +423,7 @@ LibraryControl::LibraryControl(Library* pLibrary)
connect(app,
&QApplication::focusChanged,
this,
&LibraryControl::updateFocusedWidgetControls);
&LibraryControl::slotFocusedWidgetChanged);
// Also update controls if the window focus changed.
// Even though any new menu window has focus and will receive keypress events
// it does NOT have a focused widget before the first click or keypress.
Expand Down Expand Up @@ -628,7 +640,7 @@ void LibraryControl::slotMoveVertical(double v) {
return;
}

switch (m_pFocusedWidget) {
switch (m_focusedWidget) {
case FocusWidget::Sidebar: {
int i = static_cast<int>(v);
slotSelectSidebarItem(i);
Expand Down Expand Up @@ -747,11 +759,8 @@ void LibraryControl::emitKeyEvent(QKeyEvent&& event) {
return;
}

switch (m_pFocusedWidget) {
case FocusWidget::None:
if (m_focusedWidget == FocusWidget::None) {
return setLibraryFocus(FocusWidget::TracksTable);
default:
break;
}

// Send the event pointer to the currently focused widget
Expand Down Expand Up @@ -818,7 +827,7 @@ void LibraryControl::setLibraryFocus(FocusWidget newFocusWidget) {
}

// ignore no-op
if (newFocusWidget == m_pFocusedWidget) {
if (newFocusWidget == m_focusedWidget) {
return;
}

Expand Down Expand Up @@ -850,13 +859,32 @@ void LibraryControl::setLibraryFocus(FocusWidget newFocusWidget) {
// to update [Library],focused_widget
}

void LibraryControl::slotFocusedWidgetChanged(QWidget* oldW, QWidget* newW) {
Q_UNUSED(newW);

// If one of the library widgets had focus store it so we can return to it,
// for example when we finish editing a WBeatSizeSpinBox.
if (m_pSearchbox && oldW == m_pSearchbox) {
m_prevFocusedWidget = FocusWidget::Searchbar;
} else if (m_pSidebarWidget && oldW == m_pSidebarWidget) {
m_prevFocusedWidget = FocusWidget::Sidebar;
} else if (m_pLibraryWidget && oldW == m_pLibraryWidget->currentWidget()) {
m_prevFocusedWidget = FocusWidget::TracksTable;
}
updateFocusedWidgetControls();
}

void LibraryControl::updateFocusedWidgetControls() {
m_pFocusedWidget = getFocusedWidget();
m_focusedWidget = getFocusedWidget();
// Update "[Library], focused_widget" control
double newVal = static_cast<double>(m_pFocusedWidget);
double newVal = static_cast<double>(m_focusedWidget);
m_pFocusedWidgetCO->setAndConfirm(newVal);
}

void LibraryControl::refocusPrevLibraryWidget() {
setLibraryFocus(m_prevFocusedWidget);
}

void LibraryControl::slotSelectSidebarItem(double v) {
if (!m_pSidebarWidget) {
return;
Expand Down Expand Up @@ -895,7 +923,7 @@ void LibraryControl::slotGoToItem(double v) {
return;
}

switch (m_pFocusedWidget) {
switch (m_focusedWidget) {
case FocusWidget::Sidebar:
// Focus the library if this is a leaf node in the tree
// Note that Tracks and AutoDJ always return 'false':
Expand Down
8 changes: 6 additions & 2 deletions src/library/librarycontrol.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,10 @@ class LibraryControl : public QObject {
void sidebarWidgetDeleted();
void searchboxWidgetDeleted();

// Update m_pFocusedWidget and m_pFocusedWidgetCO
// Update m_focusedWidget and m_pFocusedWidgetCO
void slotFocusedWidgetChanged(QWidget* oldW, QWidget* newW);
void updateFocusedWidgetControls();
void refocusPrevLibraryWidget();

void slotMoveUp(double);
void slotMoveDown(double);
Expand Down Expand Up @@ -134,7 +136,9 @@ class LibraryControl : public QObject {
std::unique_ptr<ControlPushButton> m_pMoveFocusBackward;
std::unique_ptr<ControlEncoder> m_pMoveFocus;
std::unique_ptr<ControlPushButton> m_pFocusedWidgetCO;
FocusWidget m_pFocusedWidget;
FocusWidget m_focusedWidget;
std::unique_ptr<ControlPushButton> m_pRefocusPrevWidgetCO;
FocusWidget m_prevFocusedWidget;

// Control to choose the currently selected item in focused widget (double click)
std::unique_ptr<ControlObject> m_pGoToItem;
Expand Down
8 changes: 3 additions & 5 deletions src/widget/wbeatspinbox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -286,15 +286,13 @@ bool WBeatSpinBox::event(QEvent* pEvent) {
}

void WBeatSpinBox::keyPressEvent(QKeyEvent* pEvent) {
// By default, Return & Enter keys apply current value.
// Here, Return, Enter and Escape apply and move focus to tracks table.
// TODO(ronso0) switch to previously focused (library?) widget instead
// By default, Return & Enter keys apply the current value.
// Additionally, move focus back to the previously focused library widget.
if (pEvent->key() == Qt::Key_Return ||
pEvent->key() == Qt::Key_Enter ||
pEvent->key() == Qt::Key_Escape) {
QDoubleSpinBox::keyPressEvent(pEvent);
ControlObject::set(ConfigKey("[Library]", "focused_widget"),
static_cast<double>(FocusWidget::TracksTable));
ControlObject::set(ConfigKey("[Library]", "refocus_prev_widget"), 1);
return;
}
return QDoubleSpinBox::keyPressEvent(pEvent);
Expand Down
8 changes: 3 additions & 5 deletions src/widget/weffectchainpresetselector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,9 @@ void WEffectChainPresetSelector::populate() {
void WEffectChainPresetSelector::slotEffectChainPresetSelected(int index) {
m_pChain->loadChainPreset(
m_pChainPresetManager->getPreset(currentData().toString()));
// After selecting an effect move focus to the tracks table in order
// to immediately allow keyboard shortcuts again.
// TODO(ronso0) switch to previously focused (library?) widget instead
ControlObject::set(ConfigKey("[Library]", "focused_widget"),
static_cast<double>(FocusWidget::TracksTable));
// Clicking a chain item moves keyboard focus to the list view.
// Move focus back to the previously focused library widget.
ControlObject::set(ConfigKey("[Library]", "refocus_prev_widget"), 1);
}

void WEffectChainPresetSelector::slotChainPresetChanged(const QString& name) {
Expand Down
8 changes: 3 additions & 5 deletions src/widget/weffectselector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,9 @@ void WEffectSelector::slotEffectSelected(int newIndex) {
m_pEffectSlot->loadEffectWithDefaults(pManifest);

setBaseTooltip(itemData(newIndex, Qt::ToolTipRole).toString());
// After selecting an effect send Shift+Tab to move focus to tracks table
// in order to immediately allow keyboard shortcuts again.
// TODO(ronso0) switch to previously focused (library?) widget instead
ControlObject::set(ConfigKey("[Library]", "focused_widget"),
static_cast<double>(FocusWidget::TracksTable));
// Clicking an effect item moves keyboard focus to the list view.
// Move focus back to the previously focused library widget.
ControlObject::set(ConfigKey("[Library]", "refocus_prev_widget"), 1);
}

void WEffectSelector::slotEffectUpdated() {
Expand Down

0 comments on commit fe25d77

Please sign in to comment.