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

QML: Refactor Knob/Slider controls #3955

Merged
merged 21 commits into from
Jun 6, 2021

Conversation

Holzhaus
Copy link
Member

@Holzhaus Holzhaus commented Jun 6, 2021

Split Sliders and Knobs into 3 components each:

  • Basic (independent of CO)
  • Control (Connected to CO)
  • ResettableControl (same as above + ability to reset on doubleclick)

@Holzhaus Holzhaus added the skins label Jun 6, 2021
res/skins/QMLDemo/Mixxx/Controls/Knob.qml Outdated Show resolved Hide resolved
res/skins/QMLDemo/Slider.qml Outdated Show resolved Hide resolved
res/skins/QMLDemo/Mixxx/Controls/Slider.qml Show resolved Hide resolved
res/skins/QMLDemo/ControlKnob.qml Outdated Show resolved Hide resolved
res/skins/QMLDemo/ControlKnob.qml Show resolved Hide resolved
res/skins/QMLDemo/ControlKnob.qml Outdated Show resolved Hide resolved
res/skins/QMLDemo/Mixxx/Controls/Knob.qml Show resolved Hide resolved
res/skins/QMLDemo/Mixxx/Controls/Knob.qml Show resolved Hide resolved
id: root

property string resetGroup: group
property string resetKey: key + "_set_default"
Copy link
Member

Choose a reason for hiding this comment

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

maybe instead of relying on _set_default of a ControlPotMeter control, it would be better to expose ControlProxyt::reset() to the qmlcontrolproxy?

Copy link
Member Author

Choose a reason for hiding this comment

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

This is just a default value, you can override resetKey if you want.

Copy link
Member

Choose a reason for hiding this comment

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

Right, but my point is that COs already seem have a concept of resetting themselves (slot ControlProxy::reset(), ControlObject::reset()) so it would make sense to expose that same slot on the QML proxy as well. That would be better than relying on the fact that there is some CO variant whose only purpose is to reset the control. The _set_default variant seems like a workaround that was needed because of the legacy skin and controller mapping system (before there was even JS engine).

Copy link
Member Author

Choose a reason for hiding this comment

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

Good point. I'll look into that in a follow up PR, this one is already pretty large. I don't want to add C++ changes, too.

Copy link
Member

Choose a reason for hiding this comment

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

I also spend some time on that already :)

res/skins/QMLDemo/Mixxx/MathUtils.js Outdated Show resolved Hide resolved
res/skins/QMLDemo/Mixxx/Controls/Knob.qml Outdated Show resolved Hide resolved
res/skins/QMLDemo/Mixxx/Controls/Knob.qml Show resolved Hide resolved
Comment on lines +78 to +79
const change = (root.max - root.min) * Mixxx.MathUtils.clamp(delta, -100, 100) / 100;
const value = Mixxx.MathUtils.clamp(root.value + change, root.min, root.max);
Copy link
Member

Choose a reason for hiding this comment

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

the first clamp seems unnecessary to me.

Copy link
Member Author

Choose a reason for hiding this comment

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

PLease make a concrete suggestion. Just removing the clamp will make the value go to the minimum/maximum on the slightest mouse move.

Copy link
Member

Choose a reason for hiding this comment

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

That doesn't seem right. I'll try to debug whats going on here then.

Copy link
Member

Choose a reason for hiding this comment

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

I can remove both clamps and the it works just as well. Could it be a screen resolution / pixel density issue?
In addition, there is also a deadzone which makes the control ignore the drag for small movements. You would have to set dragThreshold: 0 but thats only been added in 5.15.

Maybe using a DragHandler is a bad idea after all...
Can you elaborate on why you are replacing the mousearea with a draghandler at all?

Copy link
Member Author

Choose a reason for hiding this comment

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

If I use a mousearea, double-click to reset doesn't work anymore due to event propagation issues.

I you have a simpler, working solution, let's merge know and you open a follow up PR.

Copy link
Member

Choose a reason for hiding this comment

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

I now understand the issue. I don't think composing mouseareas together is a good idea. especially not for the purpose of being able to reset a control. IMO the better approach is to make the reset functionality part of the ControlProxy object and then just give the knob and slider a property bool resetable: false.

I know this is making a large part of this PR irrelevant so I can understand if you are opposed to it.
I would be ok with working on this myself though my schedule makes that difficult atm.

Copy link
Member Author

@Holzhaus Holzhaus Jun 6, 2021

Choose a reason for hiding this comment

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

The main issue is that there may be even other things you might want to do, like rightclicking support etc. Adding everything to the base componet is bad design IMHO. Trying to add config options for every single thing someone may want to use is futile and makes the code a complexity nightmare. Stuff should be flexible and composable.

Also, besides that the DragHanlder approach works, it also is the right thing to use semantically IMHO. If the only issue is the drag threshold, we can improve the precision in the JS code or wait for Qt 5.15 as minimum requirement. I doubt QML will be finished before that point in time anyway.

Copy link
Member

Choose a reason for hiding this comment

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

I see your point about composability... it just seems a bit wrong how we do it. The code of the baseclass is not very maintainable like this as well. Maybe we are just missing something. I'm fine with merging as is though I'd like to look into some alternative soon.

Copy link
Member Author

Choose a reason for hiding this comment

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

I mean we can also factor out the Arc feature into a separate ArcKnob if you think that helps. But other than that the Knob.qml in Mixxx.Controls is pretty slim already.

Everything that is not in the Mixxx subdirectory is skin-local and doesn't need to be reusable. We can later check which parts may be useful and move it into the Mixxx directory.

Copy link
Member

Choose a reason for hiding this comment

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

That would make sense architectually, but there is no practical reason for doing that right now.

res/skins/QMLDemo/Knob.qml Outdated Show resolved Hide resolved
@Holzhaus Holzhaus requested a review from Swiftb0y June 6, 2021 16:24
Copy link
Member

@Swiftb0y Swiftb0y left a comment

Choose a reason for hiding this comment

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

LGTM. Do you want to clean up the commit history or is it fine to merge as is? I'm not familiar with git etiquette in that regard...

@Holzhaus
Copy link
Member Author

Holzhaus commented Jun 6, 2021

Let's just merge as-is. No commits breaks the build or is broken or something.

@Swiftb0y Swiftb0y merged commit 937658a into mixxxdj:main Jun 6, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

2 participants