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

KnobComposed masked ring #645

Conversation

ferranpujolcamins
Copy link
Contributor

Added support for a new "Ring" pixmap in WKnobComposed that is automatically masked.

A new "Ring" pixmap is added to WKnobComposed. It is automatically masked between MinAngle and MaxAngle as the knob is turned.

The BackPath pixmap is drawn on top of the new "Ring" pixmap. This allows the background to cast shadows to the ring.

The new "Centered" tag makes the ring totally masked at 12 o'clock position and makes it "sweep-in" as the knob is turned from there.

The new "RingMaskXOffset" and "RingMaskYOffset" should be used in case the Ring pixmap is not exactly centered in the middle of the canvas. They are relative to the center of the canvas.

The last commit is just to show the changes in action, it should be reverted before merging this PR. The new knobs are a bit ugly, I made them quickly. Don't judge this PR for their looks :)
LateNight probably needs a new set of knobs that integrate the ring well, if this PR is accepted, I'll make a new one with better knobs for LateNight.

…tically masked.

A new "Ring" pixmap is added to WKnobComposed. It is automatically masked between MinAngle and MaxAngle as the knob is turned.
The new "Centered" tag makes the ring totally masked at 12 o'clock position and makes it "sweep-in" as the knob is turned from there.
The new "RingMaskXOffset" and "RingMaskYOffset" should be used in case the Ring pixmap is not exactly centered in the middle of the canvas.
They are relative to the center of the canvas.
@daschuer
Copy link
Member

I have tested this patch and it just works.

Please move the test skin changes to https://github.com/mixxxdj/developer_skins. This way we can merge this without destroying anything.

The BackPath pixmap is drawn on top of the new "Ring" pixmap. This allows the background to cast shadows to the ring.

I am afraid this will be hard to explain. "The background is not the bottom layer"
Can't we achieve the shadow by a static shadow on the ring?

QPainterPath path;
int w = width();
int h = height();
path.moveTo(w/2.0 + m_iMaskXOffset, h/2.0 + m_iMaskYOffset);
Copy link
Member

Choose a reason for hiding this comment

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

These calculations are hard to understand. Please use intermediate variables with explaining names and add more comments.

@daschuer
Copy link
Member

"Centered" is hard to understand and somehow too common.
Can we calculate the value from the connected Control? It is the Zero point?
This is especially useful for Effect Knob where the scale of the connected control changes by the selected effect.
Otherwise "RingEmptyAngle" or something might be more self explaining.

@daschuer
Copy link
Member

RingMaskXOffset is hard to understand.
I think we can ditch it, if we set the Mask start point always to the Knob center, independent from the Ring dimensions.

@ferranpujolcamins
Copy link
Contributor Author

Thank you for reviewing this @daschuer later I'll try to address what you've commented.

Can we calculate the value from the connected Control? It is the Zero point?
This is especially useful for Effect Knob where the scale of the connected control changes by the selected effect.

You're right, this totally needs to be done. I'll see if I can achieve that.

RingMaskXOffset is hard to understand.

We can't get rid of the offset tags. As you can see in the picture, if the ring is not centered in the picture but the mask is draw centered, it just doesn't work.
path2987
However if you consider that the tags names are misleading I have no problem in changing them. I'll document the changes to the wiki, and probably add this picture, so it shouldn't be hard to understand anymore :)

I think we can ditch it, if we set the Mask start point always to the Knob center, independent from the Ring dimensions.

Thats a good idea and might work well with plain designs. But if designers want to give the skin some 3D sense, they'll probably have the knob offset from the center.

@daschuer
Copy link
Member

Thank you for the drawings. They clarify much.
Is the mask actually rounded? I wonder if it is reasonable to just cover a triangle from the rotation point towards the pixamp borders.

IMHO the ring center point should be match the knob center by default.

Could "RingMaskXOffset" become "RingCenterXOffset"?
It may also be a good strategy to postpone this feature to the time when there is a real demand.

@ferranpujolcamins
Copy link
Contributor Author

Is the mask actually rounded? I wonder if it is reasonable to just cover a triangle from the rotation point towards the pixamp borders.

Well, you almost guess what's really going on :) The mask is a pie like in the drawing, but the radius is actually the minimum that makes the rectangle containing the pixmaps to be inscribed inside the pie. What this means is that the whole knob area is masked, the picture I sent is not correct in this aspect.

Actually, the code you said is not clear (which I'm going to rewrite and comment) does the calculations needed for this..

IMHO the ring center point should be match the knob center by default.

Could "RingMaskXOffset" become "RingCenterXOffset"?

That's actually very reasonable, I'll fix this too.

It may also be a good strategy to postpone this feature to the time when there is a real demand.

Well, I'm the demand :)
I wanted this because I felt LateNight needs it. Imagine you are running Mixxx on a 15.6" laptop using LateNight with 4decks. You might actually be a bit far away from the screen. There's plenty of little knobs on the mixer section, and is difficult to see at a glance which EQ knobs are not at 12 o'clock. With a ring like the one I drafted in the PR, it is easier to identify active EQ knobs.

Additionally, this PR doesn't break neither modify any preexisting functionality, so it is safe in that aspect.

@daschuer
Copy link
Member

Well, I'm the demand :)

Sure! And I like this feature as well. I was only worrying about the ring offset feature.

@mixxx-buildbot
Copy link

Automated Message from BuildBot: Mixxx Admins, is this safe to test? Respond with: "ok to test", "add to whitelist", "skip ci", or "test this please" (to retest).

@daschuer
Copy link
Member

add to whitelist

@ferranpujolcamins
Copy link
Contributor Author

It's a good idea to take the offset respect the center of the knob pixmap instead of the center of the background, I like it. Also to rename the tags to RingMaskXOffset and RingMaskYOffset.

As I said, they are necessary if some skin designer wants to add a 3d effect. I've made a quick example: the first is a plain design where both the ring and the knob have the same center, the second design has vertical and horizontal ring offset plus an additional background.
rect2997

Don't worry, I promise I'll add proper documentation for this to the wiki :)

So, this will be ok once I find time to make all the discussed changes?

@daschuer
Copy link
Member

Ok, go ahead and thank you again for the good explanations.

@ferranpujolcamins
Copy link
Contributor Author

Oh, how shall I commit changes to developer skins? Shall I issue a PR with a copy of LateNight with the changes applied to it?

Now ring appears on top of background.
@daschuer
Copy link
Member

Yes. You may also maintain it as you own testing skin there.

and "RingMaskYOffset" to "RingCenterYOffset".
@ferranpujolcamins
Copy link
Contributor Author

Ok it turns out that this is a bit trickier than I thought. For CO we have defaultValue(). But defaultValue is not necessarily the reference value from which the ring mask should start expanding.
For example, for the echo effect, the feedback knob has the default value at 2 o'clock (because we want the default value to make the effect sound in all its glory). But we would like the ring to expand from the full counter clockwise position.

Furthermore, in the future we might offer the user the possibility to customize the controls default values, like Traktor does with the FX parameters. Clearly, we can't tie this with the CO defaultValue.

How can we handle this? Shall I add a new double member to CO that tells where the ring should start expanding, maybe something like "neutralValue" or "noEffectValue"?

@daschuer
Copy link
Member

"neutralValue" as a general ControlPotmeter addition sounds reasonable. I think if this defaults to zero it will fit for almost all COs.

@ferranpujolcamins
Copy link
Contributor Author

How do I get to the corresponding ControlPotmeter from WKnobComposed? From its m_connections inherited from WBaseWidget?

@daschuer
Copy link
Member

@ferranpujolcamins
Copy link
Contributor Author

Ok, so I've just realised I don't really understand how this should work, sorry.

Right now, in WKnobComposed, I have the ConfigKey of the corresponding CO. But, if I create a ControlPotmeter from it, the neutralValue is created arbitrarily on that ControlPotmeter, like m_stepCount for example. I don't know how each CO could have a specific neutralValue. Shouldn't neutralValue be in ControlDoublePrivate like defaultValue in order to achieve that?

On the other hand, I understand neutralValue doesn't make sense for a binary CO, so it seems to me that the correct place would indeed be ControlPotmeter. So I'm a bit confused :(

@daschuer
Copy link
Member

ah, I see.

You cannot create a ControlPotmeter from an existing key. You can only create a ControObjectSlave to access the atomic value of the control Object.

You can also not access the ControlPotmeter via ControlParameterWidgetConnection -> ControlObjectSlave -> ControDoublePrivate

A possible solution would be to add getNeutralParameter() to the ControDoublePrivate and fill it by the ControlPotmeterBehavior class.

I wonder if this will fit to the target that we are able to change the NeutralParameter / NeutralValue on the effect knobs.

By the way: Parameter = normalized Value

@ferranpujolcamins
Copy link
Contributor Author

Thank you Daniel. I'm definitely going to finish this, but It's just a cosmetic feature, so I'm going to see if I can fix other skin issues first.

@ferranpujolcamins
Copy link
Contributor Author

A possible solution would be to add getNeutralParameter() to the ControDoublePrivate and fill it by the ControlPotmeterBehavior class.

@daschuer can you give me some more details about this? I don't really understand what you mean.

@@ -122,6 +131,8 @@ class EffectManifest {
bool m_isMasterEQ;
// This helps us at DlgPrefEQ's basic selection of Filter knob effects
bool m_isForFilterKnob;
// This helps the skin draw knob rings correctly.
double m_dSuperKnobScaleStart;
Copy link
Member

Choose a reason for hiding this comment

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

Please remove m_dSuperKnobScaleStart from the manifest.
It is a property of each effect parameter, but that is can be postponed to an later PR.

@daschuer
Copy link
Member

Your developer skins are working real nice, Thank you.
There are a view open comments before we can merge this.

Fixed comment in ControlAudioTaperPot.
Tabs -> Spaces.
@ferranpujolcamins
Copy link
Contributor Author

I addressed the issues.
Thank you for reviewing this.

@@ -25,7 +25,6 @@ class EffectManifest {
: m_isMixingEQ(false),
m_isMasterEQ(false),
m_isForFilterKnob(false),
m_dSuperKnobScaleStart(0.0),
Copy link
Member

Choose a reason for hiding this comment

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

this removes this initializer only ...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Wow sorry. Solved.

@daschuer
Copy link
Member

Travis has detected an issue:

src/effects/effectslot.cpp: In member function ‘double EffectSlot::superParameterScaleStart()’:

src/effects/effectslot.cpp:256:25: error: ‘class EffectManifest’ has no member named ‘superKnobScaleStart’

         return manifest.superKnobScaleStart();

@ferranpujolcamins
Copy link
Contributor Author

Sorry, I'll fix that. Should I completely remove knob rings from effect super knob or leave it with a default value like 0?

@daschuer
Copy link
Member

Yes.

@rryan
Copy link
Member

rryan commented Jan 28, 2017

What's the status on this PR?

@ferranpujolcamins
Copy link
Contributor Author

I plan to give it some love soon.

@Be-ing
Copy link
Contributor

Be-ing commented Apr 18, 2018

This pull request has not been updated in years so I am closing it to reduce the clutter of open PRs. If you solve the merge conflicts and would like to have this merged in the future, please reopen it.

@Be-ing Be-ing closed this Apr 18, 2018
@daschuer
Copy link
Member

We have the commitment that this will be revived soon.

@daschuer daschuer reopened this Apr 18, 2018
@Be-ing Be-ing added stalled and removed stalled labels Apr 18, 2018
@Be-ing Be-ing added this to the stalled milestone Apr 18, 2018
@ferranpujolcamins
Copy link
Contributor Author

My commitment for this is for 2.3 release. I'll rework it in a new branch anyway, so I'm closing this branch. I've filed a bug in launchpad to track this: https://bugs.launchpad.net/mixxx/+bug/1765399

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

Successfully merging this pull request may close these issues.

6 participants