-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
WStarRating: don't update track directly, use signals/slots #11565
Conversation
src/widget/wstarrating.cpp
Outdated
@@ -166,7 +174,11 @@ void WStarRating::mouseReleaseEvent(QMouseEvent* /*unused*/) { | |||
return; | |||
} | |||
|
|||
m_pCurrentTrack->setRating(m_starRating.starCount()); | |||
m_currRating = m_starRating.starCount(); | |||
if (m_updateTrack) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for addressing these issues. QML will hopefully help to prevent those mistakes in the (far away) future.
The widget should never directly update the track state on its own. Instead the receiver of the signal could do that if desired or otherwise reject the proposed new value by resetting the widget -> unidirectional data flow.
Offering both options is confusing and not maintainable. But I am afraid that trying to avoid this mixed behavior could open another Pandora's Box.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally the widget would only offer a slot for setting the rating (input, write-only) and emit a signal when the rating changed (output, read-only). Maybe a getter for reading the current rating on demand. No track pointer, no implicit context management.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understand what you're saying, and I agree that WStarRating becomes more complex and bit harder to maintain. Looks like this can be changed without too much hazzle, with a few changes to Track and BaseTrackPlayer(Impl) (and mediators like LegacySkinParser, and DlgTrackinfo, of course), and WStarRating would be quite clean then.
I think I'll take a stab at this for 2.4 beta, though it's out of scope for this quick bug fix.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then try to add the basic building blocks to the current design and (important!) TODO comments, i.e. to remove m_pCurrentTrack
. Otherwise the direction is unclear.
@uklotzde That was easier than I thought, though tedious. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Glad to hear that this was easier than expected. The refactoring avoids to pile up more legacy code.
src/widget/wstarrating.cpp
Outdated
m_starRating.setStarCount(star); | ||
update(); | ||
m_pCurrentTrack->setRating(star); | ||
emit ratingChangeRequest(star); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The signal should only be emitted if the value has actually changed to prevent cycles.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure. This just handles the group,stars_up
CO and changes the current value. The cycle prevention is in Track::setRating
.
However, I changed this method to work with m_currRating
, i.e. the stored value delivered by Track::ratingUpdated
, not the visual state (which avoids confusion in the unlikely case a user hovers the rating and uses the CO).
src/widget/wstarrating.cpp
Outdated
} | ||
|
||
void WStarRating::fillDebugTooltip(QStringList* debug) { | ||
WWidget::fillDebugTooltip(debug); | ||
|
||
QString currentRating = "-"; | ||
QString currentRating; | ||
currentRating.setNum(m_currRating); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the difference between m_currRating and m_starRating? The widget should not store any redundant state that could get inconsistent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
m_starRating.starCount()
is the current value of StarRating, i.e. what you see (for example while hovering).
m_currRating
is the confirmed value of the track / pending track record value in DlgTrackInfo, after LeaveEvent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then m_currRating
is redundant. The widget should maintain only a single value and don't care about the state of its clients or subscribers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then
m_currRating
is redundant.
Redundant with what?
The current value of StarRating
(separate paint class!) (starCount()) just reflects the count of currently painted stars, be it final (clicked, not necessarily accepted by Track or DlgTrackInfo) or temporary (hovering, mouse moving).
Only m_currRating
is storing the applied / real value and we need that for the COs and to restore the real value when leaving the widget (after mouse move, not clicked).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll check it later. Only viewed the diff, not the whole code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nevertheless my comments reveal that meaning and purpose of those member variables is unclear on first sight.
@@ -436,6 +436,7 @@ class Track : public QObject { | |||
// adjusted in the opposite direction to compensate (no audible change). | |||
void replayGainAdjusted(const mixxx::ReplayGain&); | |||
void colorUpdated(const mixxx::RgbColor::optional_t& color); | |||
void ratingUpdated(int rating); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer the neutral and agnostic changed terminology. That would be inconsistent with the existing signals, but we could add a TODO to rename those later.
pushed some fixups which I'd like to squash if they're okay. |
if (m_pCurrentTrack) { | ||
currentRating.setNum(m_pCurrentTrack->getRating()); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
showing - / 5
in the debug tooltip with no track would be the only reason to track the "track loaded" state. not worth the effort IMO
setting this to draft just to avoid accidental merge. |
Sure. I will take a final look when done. |
Go ahead, I'm done, I just addressed your review comments and packed the changes in small chunks for easy review. |
Stopping my review here. I wasn't able to fully understand what the code is supposed to do, already wasted too much time. If it works, then feel free to merge it. This has to be rewritten for QML anyway. |
Previously, WStarRating updated the track directly. Undesired side effect was that changing the rating in DlgTrackInfo causes Track::changed() to be emitted which in turn would clear other pending changes in the current dialog. Note that changing the rating or any other track property elsewhere (library or another DlgTrackInfo instance still causes track metadata to be reloaded.
@uklotzde Thanks for your time and ronso0#43. It's working fine now: rating is synced if updated anywhere (library, decks, DlgTrackInfo), and (still) it's not possible to set the rating in an empty deck (or empty DlgTrackInfo, if that could be displayed). |
5a7f496
to
169189a
Compare
@ronso0 do you still plan to rebase this or does it put to much work on us? |
1 similar comment
@ronso0 do you still plan to rebase this or does it put to much work on us? |
Thanks for the reminder! |
Meeh, too many conflicts IMO. Resolving those now and when merging to 2.4 is a PITA. As far as I can tell, unitl now there are only minor issues reported for 2.3 (fixed since 2.3.5) that don't justify another bugfix release, so let's merge to 2.4 and save the time for more important stuff. |
I also don't recommend rebasing. Too much has changed since then. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM and works good, Thank you.
Thanks for reviewing! |
Q_UNUSED(trackId); | ||
updateRatingFromTrack(); | ||
m_starCount = starCount; | ||
updateVisualRating(starCount); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
had to add emit ratingChanged(m_starCount)
in order to make the _up/_down controls to also update the track value
pushed a fix 0550e07
fixes #11540
changes to the star rating are now handled via change signals, like with the QLineEdits
edit: instead of working around the symptom, as per @uklotzde's suggestion, this PR now adds slots and signals for track rating. Now it's consistent with other track properties and WStarRating now much smaller.
Note: updating the rating (or any other track property) elsewhere emits the
trackCganged
signal and will therefore still wipe pending changes in the properties dialog. This is not a bug.