Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Track Info Dialog: Improve keyboard usability & resize behavior #13818

Open
wants to merge 39 commits into
base: main
Choose a base branch
from

Conversation

cr7pt0gr4ph7
Copy link
Contributor

@cr7pt0gr4ph7 cr7pt0gr4ph7 commented Oct 31, 2024

This PR bundles a number of keyboard usability improvements and general polish for the track info dialog.
It combines a number of small changes that are functionally independent and could be split off into their own PRs if necessary, but would likely produce merge conflicts due to most of them affecting the same set of files.

  • In short, the track info dialog and all of its controls (except for the cover art image) are now easily accessible and usable via the keyboard, tab order matches visual order and small screens/large font sizes are handled more gracefully.

  • The visual look is only changed minimally (the border style of the comments field now matches the other text fields & the "Import metadata" buttons display an ellipsis when collapsed below their minimum text width & a few pixel-level alignments, see below for details).

PS: If you want to quickly try it out without having to build it yourself, you can use the io.github.cr7pt0gr4ph7.Mixxx Flatpak published at cr7pt0gr4ph7/mixxx-flatpak that includes this and a few other changes. Parallel installation is possible, i.e. any existing official or Flatpak installation of Mixxx will not be affected:

sudo flatpak remote-add --if-not-exists mixxx-flatpak https://cr7pt0gr4ph7.github.io/mixxx-flatpak/default.flatpakrepo
sudo flatpak install io.github.cr7pt0gr4ph7.Mixxx

(As a sidenote, the changes from #13632 have been integrated).

Summary

The Git history has been rewritten to group related commits together into the following changesets (presented in the chronological order of their Git history):

Add "Last Played" field (2 commits)

Because, why not? This was the only piece of metadata that was available as a column but not shown in the track info dialog. There's space in the layout for it, so let's just add it.

Will be shown as - when not present in the track's metadata.

General Cleanup (6 commits)

These should all (hopefully) be uncontentious:

  • Fix alignment of the labels for "Comments" and "Grouping" by moving them a few pixels.
  • Make text in the "Bitrate" field selectable, like the other read-only fields.
  • Just a bit of miscellanceous cleanup:
    • Give the QGroupBoxes speaking names instead of auto-generated ones
    • Use variables to avoid code duplication in updateTrackMetatdataFields
    • Use empty lines to logically group related fields in dlgtrackinfo.h.

Edit star rating via keyboard (5 commits)

The star rating widget was focusable, but it was not possible to use the keyboard to actually change the rating.

  • Pressing the 0, 1, ..., 9 key now sets the rating. The result will be clamped to the range 0..maxStarCount (Reason: The existing code internally allows for a maxStarCount other than 5).
  • Pressing the + or Right key increments the rating.
  • Pressing the - or Left key increments the rating.

As a sidenote, editing the star rating cells in the library table view was suffienctly different to be split into the separate PR #13717.

Improve track list navigation (3 commits)

Navigation within a list of tracks has been improved by adding keyboard shortcuts (Alt+Left/Alt+Right1 2) and conditionally enabling/disabling the prev/next buttons. Focus is kept within the currently focused editor when moving to another track, but any "on focus" behaviours (like selecting all text in a QLineEdit) for the current control are re-triggered.

Future work: It is currently not explained (or visually indicated) to the user that navigating to the previous/next track cancels changes made to the current track (like Escape or Cancel would do).

Resize behaviour (5 commits)

  • Avoid the minimum size of WMultiLineTextEdit (the "Comments" field) jumping to a larger size when the dialog is resized by the user.

  • Text edit widgets: Show the start of the contained text (e.g. the album title) by default instead of the end when the text's length exceeds the widgets width.

  • Allow the Import metadata from MusicBrainz and Re-import metadata from file to be collapsed to smaller widths by displaying an ellipsis (...).

Keyboard navigation using Up/Down (6 commits)

Add Up/Down as an alternative to Tab/Shift+Tab for moving focus within the track info dialog to make the keyboard experience a bit more seamless.

  • Exception: For the "Comments" control, focus only moves out of the text editor when the cursor is at the very start or end of the content when you start to hold down the corresponding arrow key, i.e. when you are at the start of the "Comments" field and hold down Down to move the cursor to the very end, focus does not leave the "Comments" field until you release the Down key and then press it again.

  • Exception: For the BPM spinner on the second tab, Up and Down retain their original behavior (Note: haven't found a good way to differentiate between the different user intentions here)

Edit color picker via keyboard (3 commits)

The color picker popover could be triggered, but not controlled, via the keyboard.

  • Space or Enter on the color picker button triggers the popover and moves focus into the popover.
  • Tab/Shift+Tab and Up/Down/Left/Right can be used to navigate within the color picker popover when it is open.
  • Pressing Esc closes the color picker popover without making a selection.
  • Pressing Enter or Space selects the focused color and closes the color picker popover.

Tooltip for cover art image (1 commit)

Added a compact tooltip to the cover art image to indicate the available interactions (left click/right click).

Merge & additional cleanup (2 commits)

Footnotes

  1. Sidenote: Alt+Left/Right was choosen because Ctrl+Left/Right and Left/Right already have a meaning within the text edit widgets.

  2. Sidenote: Alt+Up/Down can be added if desired.

This makes these two labels have the same alignment and pixel position
(relative to their input control) as all the other labels in the dialog.
All other similar fields in the dialog are selectable, so this
seems to just have been an oversight.
…zing

Also fix the sizePolicy of other widgets, such that the "Comments"
field gets all available remaining vertical space.
This is needed to avoid breaking keyboard navigation in a few cases.
The menu is already automatically opened by QPushButton::pressed, no need
to do it twice. This caused problems when Enter is used to open the color
picker popup.
@cr7pt0gr4ph7 cr7pt0gr4ph7 changed the title Usability/Keyboard: Polish the track info dialog Usability/Keyboard: Polish up the Track Info dialog Oct 31, 2024
@cr7pt0gr4ph7 cr7pt0gr4ph7 changed the title Usability/Keyboard: Polish up the Track Info dialog Track Info Dialog: Improve keyboard usability & resize behavior Oct 31, 2024
@ronso0
Copy link
Member

ronso0 commented Oct 31, 2024

PS: If you want to quickly try it out without having to build it yourself, you can

... just download the CI builds. Info is here https://github.com/mixxxdj/mixxx/wiki/Testing#github-pull-requests

@cr7pt0gr4ph7 cr7pt0gr4ph7 force-pushed the ready-for-merge/track-info-dialog branch from 2d8fdf7 to 25c005f Compare October 31, 2024 19:30
@cr7pt0gr4ph7 cr7pt0gr4ph7 force-pushed the ready-for-merge/track-info-dialog branch from 033e06c to 0f3fefd Compare October 31, 2024 20:36
@ronso0
Copy link
Member

ronso0 commented Nov 1, 2024

Can you please provide before/after screenshots?

@cr7pt0gr4ph7
Copy link
Contributor Author

cr7pt0gr4ph7 commented Nov 1, 2024

As requested, here are before and after screenshots (note: different looking window decorations may be related to Wayland vs. X11):

(Update: The change in the alignment of the "Comments" label is not intentional and will be fixed)
(Update 2: The screenshots were taken before the merge with #13632. Updated screenshots will be provided shortly)

Before After (at minimum size)
"Before" screenshot "After" screenshot, minimum size
Before After (at an expanded size)
"Before" screenshot "After" screenshot, expanded size
After: Unfocused comments field After: Focused comments field
Unfocused comments field Focused comments field
After: Focused star rating
Focused star rating editor
After: Focus rectangle in color picker
Bildschirmfoto vom 2024-11-01 20-38-29

Copy link
Member

@ronso0 ronso0 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this PR!

Just skimmed through the code and did a shallow first round of review.

m_propertyWidgets.insert("samplerate", txtSamplerate);
m_propertyWidgets.insert("replaygain", txtReplayGain);
m_propertyWidgets.insert("replaygain_peak", txtReplayGain);
m_propertyWidgets.insert("track_locations.location", txtLocation);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The purpose of the QWidget* list is being able to focus editable fields.
What's the benefit of adding the QLabels?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WTrackProperty can be used by skins for arbitrary properties, including the non-editable ones. So, basically, just for completeness sake & to provide uniform behavior for those properties, too.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm AFAIU non-editable fileds (labels) can't be focused anyway, so wouldn't the UI state be somewhat unclear then?
I mean, we wouldn't know the current focus widget/position until we press Tab/Shift+Tab, right?

src/widget/wstarrating.cpp Outdated Show resolved Hide resolved
src/widget/wbasicpushbutton.cpp Outdated Show resolved Hide resolved
Comment on lines +85 to +87
if ((currentSize.height() < fullSize.height() ||
currentSize.width() < fullSize.width()) &&
!txtLabel.isEmpty()) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need to check the height here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is possible that there is enough horizontal space but not enough vertical space to display the full button text. The simplest case I can think of is when QPushButton::text() contains linebreaks, but the button height is restricted to a single line.

The fallback tooltip should be enabled in all cases where the button text is not fully visible, which applies here. (Sidenote: It is not enabled when the button text is fully visible to avoid "useless"/confusing tooltips that only duplicate the information shown on the button itself.)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should implement only the cases we need currently and expand as soon as we need multi-line buttons.
IMHO the context should be clear so that we don't need multi-line buttons in the first place.
Or do you have an exmple where we might need one?

src/widget/wbasicpushbutton.cpp Outdated Show resolved Hide resolved
src/widget/wcolorpicker.cpp Outdated Show resolved Hide resolved
@cr7pt0gr4ph7
Copy link
Contributor Author

Thanks for this PR!

Just skimmed through the code and did a shallow first round of review.

Thank your for the quick review, very much appreciated 👍

/// to be used like the Tab/Backtab keys.
///
/// See WLabel when you need to connect to a ControlObject.
class WBasicLabel : public QLabel {
Copy link
Contributor Author

@cr7pt0gr4ph7 cr7pt0gr4ph7 Nov 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ronso0 I'm thinking whether it make sense to separate the skin widgets and the "basic" widgets into separate folders, e.g src/widget/basic. My gut feeling would be to create a more granular folder structure, though the current practice within Mixxx seems to favor bigger directories + prefixes.

As an aside, one additionally could consider moving the skin widgets into src/widget/skin - though that's a lot of code churn for probably not a lot of benefit.

What are your thoughts on this?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I'd rather stick to the widgets directory tbh.


/// Subclass of QLineEdit that allows the Up and Down arrow keys
/// to be used like the Tab/Backtab keys.
class WBasicLineEdit : public QLineEdit {
Copy link
Contributor Author

@cr7pt0gr4ph7 cr7pt0gr4ph7 Nov 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same applies here...

/// otherwise overflow the available space.
///
/// See WPushButton when you need to connect to a ControlObject.
class WBasicPushButton : public QPushButton {
Copy link
Contributor Author

@cr7pt0gr4ph7 cr7pt0gr4ph7 Nov 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

...and here...


/// Subclass of QTabWidget that allows the Up and Down arrow keys
/// to be used like the Tab/Backtab keys.
class WBasicTabWidget : public QTabWidget {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And here


/// An implementation of QPlainTextTedit with a more sensible minimum
/// size of 2 text lines.
class WMultiLineTextEdit : public QPlainTextEdit {
Copy link
Contributor Author

@cr7pt0gr4ph7 cr7pt0gr4ph7 Nov 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

...and here.

@ronso0
Copy link
Member

ronso0 commented Nov 3, 2024

I think the buttons should stretch to full width as before
image

Previously it looked better with the stars centered below the cover art
image

@ronso0
Copy link
Member

ronso0 commented Nov 3, 2024

I think the buttons should stretch to full width as before

Oh, they already do. (just the screen shot doesn't reflect that)

@ronso0
Copy link
Member

ronso0 commented Nov 3, 2024

It's nice the star rating can now be focused, but a focus frame would be helpful to make it clear.

@ronso0
Copy link
Member

ronso0 commented Nov 3, 2024

The color button now is two lines tall for me (Qt 6.2.3), both in DlgTrackInfo and DlgTrackInfoMulti.

@ronso0
Copy link
Member

ronso0 commented Nov 3, 2024

Just tried this branch and navigation feels nice indeed!
I wonder if the Down/Up navigation will discovered by users since it's rather unusual (at least I didn't see it in other apps, yet). I guess all we can do is document it in the manual.

re Down/Up for moving focus:
There's an inconsistency now between the single and multi-track dialog now since pressing on the multi-track fields (QComboBoxes) chnages the selected item. Not sure if we should override/disable that and let users open the drop-down with Ctrl+Space like in WSearchLineEdit.

@ronso0
Copy link
Member

ronso0 commented Nov 3, 2024

I'll take a look at this huge change set soonish.

@ronso0
Copy link
Member

ronso0 commented Nov 5, 2024

FWIW I can't seem to shrink the single-track dialog to squeeze the buttons?

Copy link
Member

@ronso0 ronso0 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some more findings

Comment on lines +278 to +280
m_pWCoverArtLabel->setToolTip(
tr("Left-click to show larger preview") + "\n" +
tr("Right-click for more options"));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's move this to WCoverArtLabel so it hasto be translated only once.
Can go to the ctor, protected with if (m_pCoverMenu != nullptr)

<property name="sizeConstraint">
<enum>QLayout::SetDefaultConstraint</enum>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignVCenter</set>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be

Suggested change
<set>Qt::AlignRight|Qt::AlignVCenter</set>
<set>Qt::AlignRight|Qt::AlignTop</set>

like previously set in dlgtrackinfo.cpp

(same in dlgtrackinfomulti.ui I think)

</property>
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this needs to be nested in a layout to restore the alignment (right | v-center)

(same in dlgtrackinfomulti.ui I think)

Comment on lines +5 to +6
/// Subclass of QLabel that allows the Up and Down arrow keys
/// to be used like the Tab/Backtab keys.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Subclass of QLabel that allows the Up and Down arrow keys
/// to be used like the Tab/Backtab keys.
/// Subclass of QLabel for DlgTrackInfo/~Multi and similar dialogs
/// that allows the Up and Down arrow keys to move keyboard focus
/// to the prev/next focusable widget.

Just to clarify that it's not supposed to be used in skins.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or add that info to the line below

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or prefix the class, eg. WDlgLabel?
(applies to all new sub-classes)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants