Discussion:
Rotate a standard Cocoa control?
(too old to reply)
Jerry Krinock
2015-05-07 20:11:16 UTC
Permalink
I would like to subclass NSSlider to make it work like the "volume control" on a mid 19th-century radio receiver. That is, I want the minimum value to be at 7 o'clock, and the maximum value to be at 5 o'clock. There two issues in using the circular version of NSSlider for this:

1. There is no dead zone between the minimum and maximum settings. (What were they thinking?)
2. The min and max settings are at the top, 12 o'clock.

I've solved the first issue by overriding -closestTickMarkValueToValue:. (Oh, I'm also using "detents", allowsTickMarkValuesOnly = YES).

I think I could solve the second issue with more complicated code in -closestTickMarkValueToValue:, but I'd also need to remap the values somehow and this might be a mess. So I was wondering if instead there was an easy way to rotate the control on the screen by, say 165 degrees.

Am I correct that the answer is "no"? Keep in mind that we're not just drawing here; this is a control; we need mouse clicks, etc.

Indeed, I'm not much of a drawing and graphics guy.
_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-in.narkive.net

This email sent to ***@ml-in
David Rowland
2015-05-07 20:36:55 UTC
Permalink
In iOS I have used the “transform” property of UIView to rotate a slider.

David
Post by Jerry Krinock
1. There is no dead zone between the minimum and maximum settings. (What were they thinking?)
2. The min and max settings are at the top, 12 o'clock.
I've solved the first issue by overriding -closestTickMarkValueToValue:. (Oh, I'm also using "detents", allowsTickMarkValuesOnly = YES).
I think I could solve the second issue with more complicated code in -closestTickMarkValueToValue:, but I'd also need to remap the values somehow and this might be a mess. So I was wondering if instead there was an easy way to rotate the control on the screen by, say 165 degrees.
Am I correct that the answer is "no"? Keep in mind that we're not just drawing here; this is a control; we need mouse clicks, etc.
Indeed, I'm not much of a drawing and graphics guy.
_______________________________________________
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
https://lists.apple.com/mailman/options/cocoa-dev/rowlandd%40sbcglobal.net
_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-in.narkive.net
Michael David Crawford
2015-05-07 21:09:24 UTC
Permalink
You could do what Apple's UIKit engineers do: implement your own
subclass of UIView, with your own drawing and hit testing. Then you
could put your radio in a wooden cabinet, maybe model some of the warm
distortion that vacuum tubes yield
Michael David Crawford, Consulting Software Engineer
***@gmail.com
http://www.warplife.com/mdc/

Available for Software Development in the Portland, Oregon Metropolitan
Area.
In iOS I have used the "transform" property of UIView to rotate a slider.
David
Post by Jerry Krinock
1. There is no dead zone between the minimum and maximum settings. (What were they thinking?)
2. The min and max settings are at the top, 12 o'clock.
I've solved the first issue by overriding -closestTickMarkValueToValue:. (Oh, I'm also using "detents", allowsTickMarkValuesOnly = YES).
I think I could solve the second issue with more complicated code in -closestTickMarkValueToValue:, but I'd also need to remap the values somehow and this might be a mess. So I was wondering if instead there was an easy way to rotate the control on the screen by, say 165 degrees.
Am I correct that the answer is "no"? Keep in mind that we're not just drawing here; this is a control; we need mouse clicks, etc.
Indeed, I'm not much of a drawing and graphics guy.
_______________________________________________
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
https://lists.apple.com/mailman/options/cocoa-dev/rowlandd%40sbcglobal.net
_______________________________________________
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
https://lists.apple.com/mailman/options/cocoa-dev/mdcrawford%40gmail.com
_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-in.narkive.net

This email sent to ***@ml-in.narkiv
Graham Cox
2015-05-07 22:55:33 UTC
Permalink
Post by Jerry Krinock
a mid 19th-century radio receiver
Really Jerry? Radio receivers weren’t a thing until the 1920s!
Post by Jerry Krinock
Am I correct that the answer is "no"? Keep in mind that we're not just drawing here; this is a control; we need mouse clicks, etc.
Indeed, I'm not much of a drawing and graphics guy.
I suggest it’s time to break out the subclass. I suspect it’s not going to be a hugely difficult task. One thing I’ve found is a good approach to custom controls is to draw the graphical parts separately (in a drawing app) and just use them as an included resource. That way you don’t get bogged down in low level drawing code, it’s easy to modify or customise and you can concentrate your coding effort on the functioning of the control rather than its appearance.

I wouldn’t be surprised if there is a 3rd-party solution out there for this already.

—Graham



_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-in.narkive.net

This email
Michael David Crawford
2015-05-07 23:04:19 UTC
Permalink
If you draw your own control, it might help you to get started to make
a very rough drawing of the control, one with no moving parts but with
the areas of the control clearly delineated so you know where to do
your hit-testing. Then draw your indicator with a black circle or
square. Then draw the indicator with an image from a PNG. At the
very end have a designer do nice graphics.
Michael David Crawford, Consulting Software Engineer
***@gmail.com
http://www.warplife.com/mdc/

Available for Software Development in the Portland, Oregon Metropolitan
Area.
Post by Jerry Krinock
a mid 19th-century radio receiver
Really Jerry? Radio receivers weren't a thing until the 1920s!
Post by Jerry Krinock
Am I correct that the answer is "no"? Keep in mind that we're not just drawing here; this is a control; we need mouse clicks, etc.
Indeed, I'm not much of a drawing and graphics guy.
I suggest it's time to break out the subclass. I suspect it's not going to be a hugely difficult task. One thing I've found is a good approach to custom controls is to draw the graphical parts separately (in a drawing app) and just use them as an included resource. That way you don't get bogged down in low level drawing code, it's easy to modify or customise and you can concentrate your coding effort on the functioning of the control rather than its appearance.
I wouldn't be surprised if there is a 3rd-party solution out there for this already.
--Graham
_______________________________________________
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
https://lists.apple.com/mailman/options/cocoa-dev/mdcrawford%40gmail.com
_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-in.narkive.net

This email sent to ***@ml-in.n
Graham Cox
2015-05-07 23:24:19 UTC
Permalink
Post by Michael David Crawford
Then draw the indicator with an image from a PNG
I usually use PDF, because then you get scalable graphics without having to worry about 2x, 3x screens and so on. Any slower performance is usually unnoticeable for simple graphics. SVG should also work in theory but the built-in support is limited (I don’t think it’s supported by NSImage, only WebKit) and also somewhat incomplete. Stick with PDF, it’s native.

—Graham



_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-in.narkive.net

This email sent to ***@ml-in.narkive.
Michael David Crawford
2015-05-07 23:25:42 UTC
Permalink
Thanks!
Michael David Crawford, Consulting Software Engineer
***@gmail.com
http://www.warplife.com/mdc/

Available for Software Development in the Portland, Oregon Metropolitan
Area.
Post by Michael David Crawford
Then draw the indicator with an image from a PNG
I usually use PDF, because then you get scalable graphics without having to worry about 2x, 3x screens and so on. Any slower performance is usually unnoticeable for simple graphics. SVG should also work in theory but the built-in support is limited (I don't think it's supported by NSImage, only WebKit) and also somewhat incomplete. Stick with PDF, it's native.
--Graham
_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-in.nark
Graham Cox
2015-05-08 03:54:43 UTC
Permalink
Post by Jerry Krinock
I would like to subclass NSSlider to make it work like the "volume control" on a mid 19th-century radio receiver. That is, I want the minimum value to be at 7 o'clock, and the maximum value to be at 5 o'clock.
Jerry,

Since I found the problem interesting and also potentially useful for something of my own down the track, I thought I’d have a quick go at making a control like this.

It’s here: http://apptree.net/code/GCVolumeControl.zip


It’s fairly basic, though it does what you want with the positioning and stopping on tick marks, etc. I subclassed NSControl rather than NSSlider but I kept some of the same method names so it’s easy to swap in. The knob itself is just a PDF resource which I created using my own Artboard app (graphic and original file included). Obviously you can change this to anything you like - my quick and dirty image is likely a bit short of your needs.

Hopefully you find it useful, and at least having the source you can customise it easily compared to standard classes. No licensing issues from me either.

—Graham



_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-in.
Robert Martin
2015-05-08 20:08:57 UTC
Permalink
Graham,

Thanks so much for posting this. I’ve always wondered how to go about doing this kind of thing, but never had the actual need in a project to prod me to figure it out. Your app and code are terrific at making things clear.

Thanks,

Rob
Post by Graham Cox
Post by Jerry Krinock
I would like to subclass NSSlider to make it work like the "volume control" on a mid 19th-century radio receiver. That is, I want the minimum value to be at 7 o'clock, and the maximum value to be at 5 o'clock.
Jerry,
Since I found the problem interesting and also potentially useful for something of my own down the track, I thought I’d have a quick go at making a control like this.
It’s here: http://apptree.net/code/GCVolumeControl.zip
It’s fairly basic, though it does what you want with the positioning and stopping on tick marks, etc. I subclassed NSControl rather than NSSlider but I kept some of the same method names so it’s easy to swap in. The knob itself is just a PDF resource which I created using my own Artboard app (graphic and original file included). Obviously you can change this to anything you like - my quick and dirty image is likely a bit short of your needs.
Hopefully you find it useful, and at least having the source you can customise it easily compared to standard classes. No licensing issues from me either.
—Graham
_______________________________________________
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
https://lists.apple.com/mailman/options/cocoa-dev/robmartin%40frontiernet.net
_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-in.narkive.
Graham Cox
2015-05-08 23:59:09 UTC
Permalink
Post by Robert Martin
Graham,
Thanks so much for posting this. I’ve always wondered how to go about doing this kind of thing, but never had the actual need in a project to prod me to figure it out. Your app and code are terrific at making things clear.
You’re welcome. There’s a few things I need to tweak to make it into production quality code, such as conformance to NSCoding - I’ll post an update later if I get the chance.

—Graham



_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-
Jerry Krinock
2015-05-09 05:22:12 UTC
Permalink
Graham, from one who has been using your code since MacZoop, I say thank you AGAIN :)

After using Apple’s NSSlider in circular style, I discovered other issues in addition to the two mentioned in my original post…

- NSSlider has only one size.

- NSSlider requires the eyesight and dexterity of a 14-year-old to use it.

-- In order to turn NSSlider “up” or “down”, the user must make a circular motion on the mouse or trackpad. Yours works correctly: Drag up or down in a straight line. This is the way the circular controls in GarageBand work.

Go Graham!


_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-
Steve Mills
2015-05-09 06:28:21 UTC
Permalink
Post by Jerry Krinock
Graham, from one who has been using your code since MacZoop, I say thank you AGAIN :)
After using Apple’s NSSlider in circular style, I discovered other issues in addition to the two mentioned in my original post…
- NSSlider has only one size.
- NSSlider requires the eyesight and dexterity of a 14-year-old to use it.
-- In order to turn NSSlider “up” or “down”, the user must make a circular motion on the mouse or trackpad. Yours works correctly: Drag up or down in a straight line. This is the way the circular controls in GarageBand work.
Go Graham!
Ditto, especially to the part about the correct way to mouse a knob. Trying to run a mouse around a knob in a circular motion might be intuitive, but it’s one of the worst motions you could do with a mouse. You’d be better off training an actual mouse to push your mouse in a circular motion. Up and down is far more natural and easier to control, but I also think side to side is also intuitive and natural as well. I’d offer both if I ever need to do this, just *never* circular.

--
Steve Mills
Drummer, Mac geek


_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-in.narkiv
h***@antarestech.com
2015-05-09 16:14:56 UTC
Permalink
Post by Steve Mills
Post by Jerry Krinock
Graham, from one who has been using your code since MacZoop, I say thank you AGAIN :)
After using Apple’s NSSlider in circular style, I discovered other
issues in addition to the two mentioned in my original post…
- NSSlider has only one size.
- NSSlider requires the eyesight and dexterity of a 14-year-old to use it.
-- In order to turn NSSlider “up” or “down”, the user must make a
circular motion on the mouse or trackpad. Yours works correctly: Drag
up or down in a straight line. This is the way the circular controls
in GarageBand work.
Go Graham!
Ditto, especially to the part about the correct way to mouse a knob.
Trying to run a mouse around a knob in a circular motion might be
intuitive, but it’s one of the worst motions you could do with a
mouse. You’d be better off training an actual mouse to push your mouse
in a circular motion. Up and down is far more natural and easier to
control, but I also think side to side is also intuitive and natural
as well. I’d offer both if I ever need to do this, just *never*
circular.
In our audio plug-ins, we have knobs that can be set to go either
circular or linear, or in cases where we can get the audio host
preference, we also allow "follow host", so that our knobs respond the
same way as the audio host (DAW) is set up. Our linear setting measures
the distance from an imaginary line running northwest to southeast
through the knob's center, so that either vertical or horizontal
movements work to turn them.

-Howard

_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-in.narkive
Graham Cox
2015-05-10 03:41:47 UTC
Permalink
Post by Jerry Krinock
Graham, from one who has been using your code since MacZoop, I say thank you AGAIN :)
After using Apple’s NSSlider in circular style, I discovered other issues in addition to the two mentioned in my original post…
- NSSlider has only one size.
- NSSlider requires the eyesight and dexterity of a 14-year-old to use it.
-- In order to turn NSSlider “up” or “down”, the user must make a circular motion on the mouse or trackpad. Yours works correctly: Drag up or down in a straight line. This is the way the circular controls in GarageBand work.
Go Graham!
Hi Jerry, you’re welcome - nice to be able to make a contribution again :)

I’ve updated the source a little - adds NSCoding, NSCopying, finer control with option and temporary snap on tickmarks with shift, plus allows the control to be scaled to a different size better (scales various rects rather than using fixed insets). I’ve also overridden the NSControl methods to get and set the value as int, float, NSInteger and string as well as double so it’s easier to use in a normal control’s place (these all end up setting the doubleValue).

I know what you mean about the mouse dragging, it’s a pain when controls seem baulky because they expect some complicated motion. I think Howard’s suggestion of also interpreting horizontal distance would be a good improvement as well, but I haven’t implemented that yet.

http://apptree.net/code/GCVolumeControl.zip

—Graham





_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-in.narkive.net

This email sent to geg
Graham Cox
2015-05-10 03:44:01 UTC
Permalink
Post by Graham Cox
I know what you mean about the mouse dragging, it’s a pain when controls seem baulky because they expect some complicated motion. I think Howard’s suggestion of also interpreting horizontal distance would be a good improvement as well, but I haven’t implemented that yet.
http://apptree.net/code/GCVolumeControl.zip
P.S. if you can think of any obvious improvements, bugs, etc, let me know.

—Graham
_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-in.narkive.net

This emai
Steve Mills
2015-05-10 04:18:34 UTC
Permalink
Post by Graham Cox
P.S. if you can think of any obvious improvements, bugs, etc, let me know.
Personally, I like it when controls also respond to the scrollwheel for inc/dec actions, like the way active Photoshop fields will inc/dec when you move the cursor into it and scrollwheel up/down. This would also be a nice way to move knobs/sliders.

--
Steve Mills
Drummer, Mac geek


_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-in.narkive.net

This em
Graham Cox
2015-05-10 04:20:08 UTC
Permalink
Post by Steve Mills
I like it when controls also respond to the scrollwheel for inc/dec actions
Me too, which is why it does :)

—Graham
_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-in.narkive.net

This email sent to gegs@
Steve Mills
2015-05-10 04:38:31 UTC
Permalink
Post by Graham Cox
Me too, which is why it does :)
Heh, I didn’t notice that before. One thing I’d suggest: When the knob is set to stop on tick marks, the scroll event should take it immediately to the next/prev tick instead of waiting for the float value to get close enough to the next tick value.

I also found it a bit disconcerting that the inc/dec action was dependent on whether you mouseDown’d on the left or right side. I usually just aim for the center, then click and drag, so that would make upward drags increase sometimes and decrease other times. I kinda expect an upward drag to always increase, because at this point, where a vertical drag will rotate a knob, we’ve gone beyond trying to simulate a real-world action that’s easier done with fingers, and instead going with an action that’s easier to do with the mouse. Know what I mean?

--
Steve Mills
Drummer, Mac geek


_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-in.narkive.ne
Kevin Meaney
2015-05-10 09:25:23 UTC
Permalink
I have recently done something similar for an angular slider. Like Graham the control responds to the scroll wheel. But as well I allow changing of the value by holding down the command key when moving the mouse.

Tracking a circular path is much easier if you are not at the same time holding down the mouse button down. Also to make it easier for the user the value is determined purely from the angle which is calculated from the center of the control rather than the user having to hold the mouse exactly within the track whilst moving. I also use Dave DeLong’s maths parser to calculate the value from the position so that the relationship between position and value just requires the evaluation of the equation.

Kevin
Post by Steve Mills
Post by Graham Cox
Me too, which is why it does :)
Heh, I didn’t notice that before. One thing I’d suggest: When the knob is set to stop on tick marks, the scroll event should take it immediately to the next/prev tick instead of waiting for the float value to get close enough to the next tick value.
I also found it a bit disconcerting that the inc/dec action was dependent on whether you mouseDown’d on the left or right side. I usually just aim for the center, then click and drag, so that would make upward drags increase sometimes and decrease other times. I kinda expect an upward drag to always increase, because at this point, where a vertical drag will rotate a knob, we’ve gone beyond trying to simulate a real-world action that’s easier done with fingers, and instead going with an action that’s easier to do with the mouse. Know what I mean?
--
Steve Mills
Drummer, Mac geek
_______________________________________________
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
https://lists.apple.com/mailman/options/cocoa-dev/ktam%40yvs.eu.com
_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-in.narkive.net

This email sent to ***@ml-
Graham Cox
2015-05-10 23:29:41 UTC
Permalink
Post by Steve Mills
Post by Graham Cox
Me too, which is why it does :)
Heh, I didn’t notice that before. One thing I’d suggest: When the knob is set to stop on tick marks, the scroll event should take it immediately to the next/prev tick instead of waiting for the float value to get close enough to the next tick value.
Yes, that might be better. As it is I have to keep track of the “unquantised” value so that the scrollwheel can accumulate until it hits the next threshold. The only reason I did it that way is so that the handling of snapping to tick marks works no matter where the events come from that change the value - in other words I don’t need to do extra work in the scroll wheel handler. But it might be better to do it the way you suggest.
Post by Steve Mills
I also found it a bit disconcerting that the inc/dec action was dependent on whether you mouseDown’d on the left or right side. I usually just aim for the center, then click and drag, so that would make upward drags increase sometimes and decrease other times. I kinda expect an upward drag to always increase, because at this point, where a vertical drag will rotate a knob, we’ve gone beyond trying to simulate a real-world action that’s easier done with fingers, and instead going with an action that’s easier to do with the mouse. Know what I mean?
Yes, I do. My thinking was that if you were to try a similar gesture on a real physical knob of this type, that’s how it would work - your finger would drive the knob according to which side you pushed on. I found this quite usable with a mouse where you can be very precise with where you click, but I haven’t tried it from a trackpad where it might be more troublesome. Just goes to show there’s more than one way to skin a cat, etc. Still, have source, can edit. I guess the real problem is there is no consistency between implementations of this kind of control, because everyone’s forced to write their own and each one does it a little differently according to the programmer’s own biases. If there were a consensus, I’d happily align myself with it.

—Graham



_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-in.narkive.net

This email sent to ***@ml-in.narkiv
Graham Cox
2015-05-11 02:47:06 UTC
Permalink
Post by Graham Cox
Post by Steve Mills
One thing I’d suggest: When the knob is set to stop on tick marks, the scroll event should take it immediately to the next/prev tick instead of waiting for the float value to get close enough to the next tick value.
Yes, that might be better. As it is I have to keep track of the “unquantised” value so that the scrollwheel can accumulate until it hits the next threshold. The only reason I did it that way is so that the handling of snapping to tick marks works no matter where the events come from that change the value - in other words I don’t need to do extra work in the scroll wheel handler. But it might be better to do it the way you suggest.
I”ve tried this out and indeed it’s a nicer behaviour when using the scrollwheel on my mouse. I generally use a Logitech mouse that has a clicky physical scroll wheel, rather than an optical sensor. One click jumps to the next tickmark in whatever direction I scroll - it’s pretty nice.

Unfortunately it’s horrible when using the scroll gesture on a trackpad. In that case my original implementation is much better. Sadly the -scrollWheel: event handler is invoked in either case but as far as I can tell there’s no way to determine what sort of input device the event originated from. Even dropping down to the CGEvent/CGEventSource API doesn’t get you that info it seems.

It’s a real shame because this is a clear example where one size doesn’t fit all. The trackpad gesture generates many -scrollWheel: events and even has some “inertia” in that I can swipe rapidly up or down with two fingers and the knob acts as if it has some weight, continuing to turn slightly even after my fingers leave the pad. That’s not bad using the original code, but when snapping to ticks and immediately jumping to the next value, the knob jumps all over the place.

Anyone know if there is a way to distinguish what sort of input device an event came from?

—Graham



_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-in.narkive.net

This email s
d***@gmail.com
2015-05-11 04:27:04 UTC
Permalink
There was a WWDC video on Responsive Scrolling.
It's not the easiest API to get sophisticated with, but worth it if you have the time.
The key is in the kinds of event phases you get.

It's all about NSEvent.
You just need to check things within the scrollWheel: method and branch accordingly.

Sent from my iPhone
Post by Graham Cox
Post by Graham Cox
Post by Steve Mills
One thing I’d suggest: When the knob is set to stop on tick marks, the scroll event should take it immediately to the next/prev tick instead of waiting for the float value to get close enough to the next tick value.
Yes, that might be better. As it is I have to keep track of the “unquantised” value so that the scrollwheel can accumulate until it hits the next threshold. The only reason I did it that way is so that the handling of snapping to tick marks works no matter where the events come from that change the value - in other words I don’t need to do extra work in the scroll wheel handler. But it might be better to do it the way you suggest.
I”ve tried this out and indeed it’s a nicer behaviour when using the scrollwheel on my mouse. I generally use a Logitech mouse that has a clicky physical scroll wheel, rather than an optical sensor. One click jumps to the next tickmark in whatever direction I scroll - it’s pretty nice.
Unfortunately it’s horrible when using the scroll gesture on a trackpad. In that case my original implementation is much better. Sadly the -scrollWheel: event handler is invoked in either case but as far as I can tell there’s no way to determine what sort of input device the event originated from. Even dropping down to the CGEvent/CGEventSource API doesn’t get you that info it seems.
It’s a real shame because this is a clear example where one size doesn’t fit all. The trackpad gesture generates many -scrollWheel: events and even has some “inertia” in that I can swipe rapidly up or down with two fingers and the knob acts as if it has some weight, continuing to turn slightly even after my fingers leave the pad. That’s not bad using the original code, but when snapping to ticks and immediately jumping to the next value, the knob jumps all over the place.
Anyone know if there is a way to distinguish what sort of input device an event came from?
―Graham
_______________________________________________
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
https://lists.apple.com/mailman/options/cocoa-dev/dangerwillrobinsondanger%40gmail.com
_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-in.narkive
Graham Cox
2015-05-11 09:01:51 UTC
Permalink
Post by d***@gmail.com
There was a WWDC video on Responsive Scrolling.
If that’s the one from WWDC 2013 that talks about NSScrollViewDidLiveScrollNotification and friends, I don’t think it’s relevant to this situation.

If you have a view that’s the content of a document’s scrollview (or any scrollview), then for responsive scrolling you shouldn’t override -scrollWheel:, because the way this is processed by NSScrollVIew is rather different and complex, and any override of your own will disable responsive scrolling. However, that’s not the situation here - I just want to use the scrollwheel to adjust a control’s value. How it’s adjusted to give the most usable behaviour depends on what sort of input device the user is using - a two-finger scroll swipe on a trackpad is a very different kind of input than a clicky scroll wheel on a mouse. Sadly there’s no way in -scrollWheel: to tell them apart. Unless I’ve missed something.

—Graham





_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-
d***@gmail.com
2015-05-11 09:15:27 UTC
Permalink
You've missed something.
NSScrollView coordinates the scrollers and the clip view total experience.

NSView is what implements the NSResponder method.
It still receives the same events that are sent from scrolling.

All the same things apply about interpreting the events that pass in to the scrollWheel: method.
It is your gateway to handle scrolling input in a view.



Sent from my iPhone
Post by Graham Cox
Post by d***@gmail.com
There was a WWDC video on Responsive Scrolling.
If that’s the one from WWDC 2013 that talks about NSScrollViewDidLiveScrollNotification and friends, I don’t think it’s relevant to this situation.
If you have a view that’s the content of a document’s scrollview (or any scrollview), then for responsive scrolling you shouldn’t override -scrollWheel:, because the way this is processed by NSScrollVIew is rather different and complex, and any override of your own will disable responsive scrolling. However, that’s not the situation here - I just want to use the scrollwheel to adjust a control’s value. How it’s adjusted to give the most usable behaviour depends on what sort of input device the user is using - a two-finger scroll swipe on a trackpad is a very different kind of input than a clicky scroll wheel on a mouse. Sadly there’s no way in -scrollWheel: to tell them apart. Unless I’ve missed something.
―Graham
_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-in.narkive.net
Graham Cox
2015-05-11 10:26:07 UTC
Permalink
Post by d***@gmail.com
It still receives the same events that are sent from scrolling.
I entirely understand that.
Post by d***@gmail.com
All the same things apply about interpreting the events that pass in to the scrollWheel: method.
It is your gateway to handle scrolling input in a view.
If so, how? The changes to NSScrollView for responsive scrolling are all implemented internal to it and NSClipView, and your app is expected to rely on various new notifications to get hooks into various phases of the whole sequence of scrolling a view. There is no support or changes to NSEvent, and nothing in the -[NSResponder scrollWheel:] handler itself that has changed - only NSScrollView overrides that method to set up a private concurrent event queue. Maybe within that queue there is some private stuff that gives it more information but it hasn’t been exposed to the public.

—Graham



_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-in.narkive.net

This email sent to g
Roland King
2015-05-11 11:25:51 UTC
Permalink
Post by Graham Cox
Post by d***@gmail.com
It still receives the same events that are sent from scrolling.
I entirely understand that.
Post by d***@gmail.com
All the same things apply about interpreting the events that pass in to the scrollWheel: method.
It is your gateway to handle scrolling input in a view.
If so, how? The changes to NSScrollView for responsive scrolling are all implemented internal to it and NSClipView, and your app is expected to rely on various new notifications to get hooks into various phases of the whole sequence of scrolling a view. There is no support or changes to NSEvent, and nothing in the -[NSResponder scrollWheel:] handler itself that has changed - only NSScrollView overrides that method to set up a private concurrent event queue. Maybe within that queue there is some private stuff that gives it more information but it hasn’t been exposed to the public.
—Graham
I thought they added phase and momentumPhase to NSEvent, plus hasPreciseScrollingDeltas, scrollingDeltaX and scrollingDeltaY to help disambiguate between clicky scrollwheels and draggy trackpads, give finer results and let you know what constitutes one motion. The phase brackets the actual events with Began, Ended, Changed and a few others and the preciseScrollingDeltas are .. more precise. Then when it’s all done you get a momentumPhase for deceleration.
_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-in.narkive.net

This email sent to ge
Graham Cox
2015-05-11 11:41:06 UTC
Permalink
Post by Roland King
I thought they added phase and momentumPhase to NSEvent, plus hasPreciseScrollingDeltas, scrollingDeltaX and scrollingDeltaY to help disambiguate between clicky scrollwheels and draggy trackpads, give finer results and let you know what constitutes one motion. The phase brackets the actual events with Began, Ended, Changed and a few others and the preciseScrollingDeltas are .. more precise. Then when it’s all done you get a momentumPhase for deceleration.
Aha… I do see those. They were not the subject of the WWDC video I watched - maybe dangerwill was referring to a different one? These look potentially useful, I’ll check them out.

—Graham



_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-in.narkive.
Graham Cox
2015-05-12 02:01:50 UTC
Permalink
Post by Graham Cox
Post by Roland King
I thought they added phase and momentumPhase to NSEvent, plus hasPreciseScrollingDeltas, scrollingDeltaX and scrollingDeltaY to help disambiguate between clicky scrollwheels and draggy trackpads, give finer results and let you know what constitutes one motion. The phase brackets the actual events with Began, Ended, Changed and a few others and the preciseScrollingDeltas are .. more precise. Then when it’s all done you get a momentumPhase for deceleration.
Aha… I do see those. They were not the subject of the WWDC video I watched - maybe dangerwill was referring to a different one? These look potentially useful, I’ll check them out.
OK, I think I have a nice all-round solution. Thanks Roland, these were exactly what I needed. Using the scrollwheel or trackpad scroll gestures works nicely for all the input devices I was able to test with, and also corrects for the user’s “natural direction” preference so that the control is consistent. Let me know if it sucks for your mouse/trackpad though.

I also added a few other enhancements. I think that’s about as far as I want to go with this for now, I ought to get on with some real work :)

http://apptree.net/code/GCVolumeControl.zip



—Graham



_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-in.narkive.net

This email sent to gegs@
d***@gmail.com
2015-05-29 04:54:48 UTC
Permalink
Post by Graham Cox
Aha… I do see those. They were not the subject of the WWDC video I watched - maybe dangerwill was referring to a different one? These look potentially useful, I’ll check them out.
―Graham
You had the right video I believe. The trick is it is dense material and they talk like it's all about the scroll view hierarchy but in fact scrolling input is implemented at the NSView level.
The NSScrollView hierarchy manages scrollers, rubberbanding and positioning of a view inside of a clipview. The document view is the view that receives and handles all the events and the reason NSView has an enclosingScrollView method, so it can talk to it if it's there.
The docs don't frame it up like this but it's real. :)
Controls are perfect use cases.


_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-in.narkive.net

This email
David Durkee
2015-05-10 04:26:07 UTC
Permalink
Although this can be a pain if the control is in a view that also scrolls. I think some Adobe applications have this issue.

David
Post by Steve Mills
Post by Graham Cox
P.S. if you can think of any obvious improvements, bugs, etc, let me know.
Personally, I like it when controls also respond to the scrollwheel for inc/dec actions, like the way active Photoshop fields will inc/dec when you move the cursor into it and scrollwheel up/down. This would also be a nice way to move knobs/sliders.
--
Steve Mills
Drummer, Mac geek
_______________________________________________
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
https://lists.apple.com/mailman/options/cocoa-dev/david%40dwdurkee.com
_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-in.narkive.net
Graham Cox
2015-05-10 04:34:41 UTC
Permalink
Post by David Durkee
Although this can be a pain if the control is in a view that also scrolls. I think some Adobe applications have this issue.
Many apps do, because of the way NSResponder works by passing unhandled events to the next responder. It happens with any nested scroll views, or any other view that implements the -scrollWheel: method.

I’m not sure if there’s any way to resolve it, because the target of a scroll wheel event is given solely by its frame, not whether it’s key, etc. One way would be to require a modifier key, but since that’s it's widely implemented that way, it isn’t very discoverable.

—Graham



_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-in.narkive.net

This email sent to ***@ml-in
Jerry Krinock
2015-05-29 04:03:21 UTC
Permalink
Epilog to a three-week old thread:

Surprise, there *is* a one-liner to rotate a standard Cocoa control:

http://digerati-illuminatus.blogspot.com/2009/09/how-do-you-rotate-nsbutton-nstextfield.html

(But Graham’s GCVolumeControl is still way better than circular NSSlider no matter how you rotate it.)
_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-in.narkive.net

This email sent to ***@ml-
Graham Cox
2015-05-29 12:10:49 UTC
Permalink
Post by Jerry Krinock
But Graham’s GCVolumeControl is still way better than circular NSSlider no matter how you rotate it.)
Kind of you Jerry. Make sure you grab the latest if you intend to use it - I made a useful number of improvements over the first version.

—Graham



_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-in.narkive.net
Continue reading on narkive:
Loading...