The latest version of this documentation may be found here.
SSCircularSlider's home page is located here.
SSCircularSlider is an NSView subclass that acts as a control for choosing both an angle and a distance (a vector, in other words). It is quite configurable, and has a nice Aqua appearance. It provides a circular base, with a knob that may be dragged within the constraints of the base to select values in two dimensions simultaneously. Some basic sets of constraining behavior are built into the class; others may be added by subclassing, or by modifying the class code itself.
SSCircularSlider comes with a palette and an inspector for Interface Builder. Those components are not documented, however; this documentation is only for the SSCircularSlider class itself. The palette and inspector may be used simply by opening the supplied palette in Interface Builder; documentation should not be needed.
SSCircularSlider was written partially for its own utility, and partially as a demonstration of the Aquatint app by Stick Software. It is copyrighted, but it is also open source, licensed under the terms of the Artistic License, which should be included in this distribution. It is provided to the community as a public service. Enjoy!
SSCircularSlider works best at either a large (80 by 80 pixels) size or a small (60 by 60 pixels) size. At these sizes, it has a nice Aqua appearance; at other sizes, it falls back on a very rudimentary Quartz appearance that will probably not be satisfactory for most applications.
SSCircularSlider can return and receive values in two forms: angle/distance or xOffset/yOffset.
The angle/distance form is accessed via the -setAngle:andDistance:
and -getAngle:andDistance:
methods. By default, the angle is in radians, with zero being to the right, and increasing in the counterclockwise direction (the standard mathematical way of describing angles). Using the -setAngleUnits:
method, this may be changed to use degrees, with zero at the top and increasing in the clockwise direction (the way many people learned to describe angles in school), with the following enumeration:
typedef enum _SSCircularSliderAngleUnits { SSAnglesAreRadians = 0, SSAnglesAreDegrees } SSCircularSliderAngleUnits;
The distance in the angle/distance form ranges from 0.0 at the center to 1.0 at the edge by default, but the maximum distance may be changed with the -setMaximumDistance:
method.
The xOffset/yOffset form is accessed via the -setXOffset:andYOffset:
and -getXOffset:YOffset:
methods. The x offset is positive to the right and negative to the left, the y offset is positive upward and negative downward. These values range from -1.0 to 1.0 by default (constrained such that the total distance from the center is not more than 1.0), but the maximum distance may be changed with the -setMaximumDistance:
method.
Some people have requested a third form for values to be vended in: an angle around the disc (0 to 360) with an angle from the center of the disc (0 to 90). This form may be gotten by simply setting the maximum distance to π/2 or 90 (for radians or degrees) with -setMaximumDistance:
, and then using the angle/distance form (changing to degrees using -setAngleUnits:
if desired). For this reason, I have chosen not to muddy the APIs with a third form at this time.
SSCircularSlider is configured to track the mouse automatically. Normally, the ball will stick to the mouse (as the user would expect a knob to behave). If the option key is pressed, the knob will move more slowly than the mouse, allowing fine-grained adjustments to the control's value. This feature is not obvious, so if it is important to your application, you are encouraged to mention it in the tooltip you provide on your slider, and in other documentation.
SSCircularSlider provides a number of facilities for contraining the range of legal values the user can select.
To constrain the allowed distance values, the -setAllowsCenterPoint:
and -setAllowsNonEdgePositions:
methods may be used. These can be used to exclude the exact center of the control from the legal value set, and to exclude all points not at the maximum distance from the legal value set. These choices determine the basic shape of the slider; by default, all points of less than or equal to the maximum distance are allowed, resulting is a solid disc shape.
The -setSnapBehavior:
method can be set to contrain angle values none of the time, all of the time, or when the shift key is pressed:
typedef enum _SSCircularSliderSnapBehavior { SSSnapNever = 0, SSSnapAlways, SSSnapOnShift } SSCircularSliderSnapBehavior;
This constraint works by "snapping" the knob to values that lie at particular angles. The -setNumberOfSnapMarks:
method determines how many such angles exist; they are always distributed evenly around the disc, beginning at the right (0 radians). The -setDrawTicksBehavior:
can be configured so that snap ticks are displayed around the disc, using the same SSCircularSliderSnapBehavior
enumeration above.
The -setAppearance:
method may be used to set the slider's tint to one of a set of enumerated values:
typedef enum _SSCircularSliderAppearance { InactiveTintedAppearance = -1, // for internal use only; use setEnabled:NO to disable the control SystemTintedAppearance = 0, BlueTintedAppearance, GraphiteTintedAppearance, QuartzAppearance } SSCircularSliderAppearance;
As noted in the Size section above, sizes other than 60x60 and 80x80 will be shown using the Quartz appearance regardless of the appearance value set.
Finally, the control may be enabled or disabled using the -setEnabled:
method, which changes its appearance as well as its responsiveness to clicks.
SSCircularSlider is a subclass of NSView, not of NSControl. This is mostly of no consequence (apart from meaning it isn't saddled with a huge load of inherited APIs that don't apply to it). However, it does mean that a target/action connection for it cannot be made directly in Interface Builder; such connections must be made in code using -setTarget:
and setAction:
. I have high hopes that Apple will correct this deficiency in Interface Builder in the future, to allow arbitrary classes to specify that they possess target/action connections.
An Interface Builder palette and inspector is part of the distribution of SSCircularSlider, so if you choose to load that palette in IB, you should be able to configure your circular sliders directly in IB. However, you can also configure them in code, of course; typically, such setup would be done immediately after a nib is loaded, using an outlet connected to the SSCircularSlider in need of configuration. The Circular Slider project, available at Stick Software's web site here, demonstrates the use of SSCircularSlider in a typical nib-based application.
Since it is not yet clear to what uses SSCircularSlider might be put, no delegate model has been put into this release, and no particular attention has been paid to allowing subclasses to modify the behavior of SSCircular Slider. If you see a need for these features in your application, feel free to contact us with suggestions or code changes. Please note that submitted code changes will be subject to the terms of Circular Slider's copyright notice, in order to allow us to integrate and distribute them in future versions of SSCircularSlider without legal issues arising.
Getting images
+ baseImageWithCenter:nonEdge:big:Creation & Archiving
- initWithFrame:Appearance & Enabling
- setAppearance:Value units
- setMaximumDistance:Getting and setting values
- setAngle:andDistance:Value constraints
- setAllowsCenterPoint:Target action
- setTarget:+ (NSImage *)baseImageWithCenter:(BOOL)center nonEdge:(BOOL)nonEdge big:(BOOL)big
Returns a "base" image that conforms to the flags passed in. The flag center
determines whether the center position is legal or not, nonEdge
whether the interior positions are legal or not, and big
whether the image fetched should be the 80x80 or the 60x60 size. The image returned is suitable for drawing as the base of a circular slider. Each possible image is loaded separately and lazily from the app bundle, and cached permanently in memory.
See Also: + knobImageWithTint:highlighted:big:
+ (NSImage *)knobImageWithTint:(SSCircularSliderAppearance)tint highlighted:(BOOL)highlighted big:(BOOL)big
Returns a "knob" image that conforms to the flags passed in. The enumerated value tint
determines whether the image returned is blue, graphite or inactive; it should have only the values BlueTintedAppearance
, GraphiteTintedAppearance
or InactiveTintedAppearance
. The flag highlighted
determines whether a darkened, highlighted knob image is returned. The flag big
determines which size of knob is returned; normally a big knob is used with an 80x80 circular slider, a small knob with a 60x60 one. The image returned is suitable for drawing as the knob of a circular slider. Each possible image is loaded separately and lazily from the app bundle, and cached permanently in memory.
See Also: + baseImageWithCenter:nonEdge:big:
- (SEL)action
Returns the selector that would be sent as an action if the slider's value were changed by the user. There is no default action.
See Also: - setAction:, - target, - sendAction
- (BOOL)allowsCenterPoint
Returns YES
if the center point (0.0, 0.0) of the slider is allowed as a value. Note that positions arbitrarily close to (0.0, 0.0), within the precision limits of the float type, will still be legal.
See Also: - setAllowsCenterPoint:, - allowsNonEdgePositions, - constrainAngle:andDistance:
- (BOOL)allowsNonEdgePositions
Returns YES
if interior points (distance greater than 0.0 and less than the maximum distance) are allowed as values.
See Also: - setAllowsNonEdgePositions:, - allowsCenterPoint, - constrainAngle:andDistance:
- (SSCircularSliderAngleUnits)angleUnits
Returns SSAnglesAreRadians
if angles given and taken by the receiver will be in radians, with zero at the right and increasing counterclockwise. Returns SSAnglesAreDegrees
if angles given and taken by the receiver will be in degrees, with zero at the top and increasing clockwise.
See Also: - setAngleUnits:, - getAngle:andDistance:, - setAngle:andDistance:
- (SSCircularSliderAppearance)appearance
Returns the enumerated value of the slider's appearance setting. This should be one of SystemTintedAppearance
, BlueTintedAppearance
, GraphiteTintedAppearance
, or QuartzAppearance
.
See Also: - setAppearance:
- (void)constrainAngle:(float *)angle andDistance:(float *)distance
Constrains the angle and distance passed in, based upon the slider's current constraints (maximum distance, allowing the center point, allowing interior points, and angle snapping). The constrained values are returned in the pointers passed in; the return value is YES
if the constrained values differ from the values passed in, NO
if the values passed in were not modified. This method is called whenever the control's value is changed, including during the tracking loop resulting from a mouse-down in the slider.
Because this method is part of SSCircularSlider's internal API, and is not really intended to be called by users of the class, the angle passed in (and out) should always be in radians, since that is the internal representation for angles.
See Also: - constrainState, - allowsCenterPoint, - allowsNonEdgePositions, - maximumDistance, - snapBehavior
- (SSCircularSliderAppearance)constrainState
Constrains the current state of the slider by calling - constrainAngle:andDistance:. If the contrained values differ from the unconstrained values, they are set back into the slider's state, setNeedsDisplay:YES
is called, and YES
is returned. If the constrained values are the same as the unconstrained values, NO
is returned. This method is called whenever the constraints of a slider change, such that the slider's current value may no longer be valid.
See Also: - constrainAngle:andDistance:, - allowsCenterPoint, - allowsNonEdgePositions, - maximumDistance, - snapBehavior
- (SSCircularSliderSnapBehavior)drawTicksBehavior
Returns the tick drawing behavior used by the receiver. Tick drawing can occur never, always, or when shift is down, according to the values SSSnapNever
, SSSnapAlways
, and SSSnapOnShift
.
See Also: - setDrawTicksBehavior:, - numberOfSnapMarks, - snapBehavior
- (void)encodeWithCoder:(NSCoder *)coder
This calls -[NSView encodeWithCoder:]
, and then archives further values defining the receiver into the NSCoder's data stream. Typically, this is called by Interface Builder when archiving a nib; it would be unusual to call it yourself.
See Also: - initWithCoder:
- (id)initWithFrame:(NSRect)frame
A designated initializer for SSCircularSlider. It calls -[NSView initWithFrame:]
and then sets up default values for the slider's attributes. By default, sliders are enabled, allow the interior and center positions, have a maximum distance of 1.0, an initial value of angle 0.0 and distance 1.0, and use the tint SSSystemTintedAppearance
. The action is unset, but their target is FirstResponder, and they are set to fire their action continuously during tracking.
- (id)initWithCoder:(NSCoder *)coder
A designated initializer for SSCircularSlider. It calls -[NSView initWithCoder:]
and then decodes the further values archived in the coder's data stream. Typically, this initializer is called automatically when instantiating SSCircularSlider from a nib; it would be unusual to call it yourself.
See Also: - encodeWithCoder:
- (BOOL)isContinuous
Returns YES
if the slider's action will be sent to the target continuously as the knob is dragged by the user. If NO
, the slider's action is sent only when tracking is completed.
See Also: - setContinuous:, - sendAction
- (BOOL)isEnabled
Returns YES
if the control's value can be changed by the user. Disabled sliders are drawn with a dimmed appearance.
See Also: - setEnabled:
- (void)getAngle:(float *)angle andDistance:(float *)distance
Returns the slider's current value as an angle and distance from the center. The angle is returned in the units specified by - angleUnits.
See Also: - setAngle:andDistance:, - angleUnits, - getXOffset:andYOffset:
- (void)getXOffset:(float *)xOffset andYOffset:(float *)yOffset
Returns the slider's current value as an x and y offset from the center.
See Also: - setXOffset:andYOffset:, - getAngle:andDistance:
- (float)maximumDistance
Returns the maximum distance from the center allowed for values. Values at the maximum distance will always be found around the rim of the slider's base; the slider's "scale" is adjusted to ensure that this remains true at all times.
See Also: - setMaximumDistance:
- (int)numberOfSnapMarks
Returns the number of discrete angles that the current angle-snapping behavior (available from - snapBehavior) will use. The first angle snapped to is always at radian 0.0 (to the right, in other words); the other angles are distributed evenly around the circumference of the slider.
See Also: - setNumberOfSnapMarks:, - snapBehavior, - drawTicksBehavior
- (BOOL)sendAction
Sends the slider's action to the slider's control. This method does not typically need to be called; it is called as appropriate by SSCircularSlider's tracking loop automatically. However, sendAction is not normally called when the control's value is changed programmatically, so this method may be called to force the action to be sent in these cases if desired.
See Also: - sendAction:to:, - target, - action, - isContinuous
- (BOOL)sendAction:(SEL)theAction to:(id)theTarget
Sends theAction
to theTarget
with the slider as sender. This method does not typically need to be called.
See Also: - sendAction
- (void)setAction:(SEL)aSelector
Sets the action that will be sent when the user changes the value of the slider. There is no default action.
See Also: - action, - setTarget:, - sendAction
- (void)setAllowsCenterPoint:(BOOL)flag
Sets whether the center point (0.0, 0.0) is allowed as a value. Note that positions arbitrarily close to (0.0, 0.0), within the precision limits of the float type, will still be legal. To exclude a larger set of values surrounding (0.0, 0.0), an override of - constrainAngle:andDistance: would be necessary.
See Also: - allowsCenterPoint, - setAllowsNonEdgePositions:
- (void)setAllowsNonEdgePositions:(BOOL)flag
Sets whether interior positions with distance greater than 0.0 and less than the maximum distance are allowed as values. To implement a more complex definition of legal versus illegal values, - constrainAngle:andDistance: may be overridden.
See Also: - allowsNonEdgePositions, - setAllowsCenterPoint:
- (void)setAngle:(float)angle andDistance:(float)distance
Sets the current value of the slider to the angle and distance given. The value is constrained by - constrainAngle:andDistance: before it is set on the slider. The angle passed in is expected to be in the units specified by - setAngleUnits:.
See Also: - getAngle:andDistance:, - setAngleUnits:, - setXOffset:andYOffset:, - constrainAngle:andDistance:
- (void)setAngleUnits:(SSCircularSliderAngleUnits)units
Sets the units used to represent degrees in the API. Pass in SSAnglesAreRadians
if you want angles given and taken by the receiver to be in radians, with zero at the right and increasing counterclockwise. Pass in SSAnglesAreDegrees
if you want angles given and taken by the receiver to be in degrees, with zero at the top and increasing clockwise.
See Also: - angleUnits, - setAngle:andDistance:, - getAngle:andDistance:
- (void)setAppearance:(SSCircularSliderAppearance)appearance
Sets the slider's appearance to one of SystemTintedAppearance
, BlueTintedAppearance
, GraphiteTintedAppearance
, or QuartzAppearance
. Note that if the slider's frame is a size other than 80x80 or 60x60 pixels, QuartzAppearance
will be used regardless of this setting.
See Also: - appearance
- (void)setContinuous:(BOOL)flag
Sets whether the slider's action is sent continuously as the user drags the knob, or only at the completion of tracking.
See Also: - isContinuous, - sendAction
- (void)setDrawTicksBehavior:(SSCircularSliderSnapBehavior)behavior
Sets the tick drawing behavior used by the receiver. Ticks can be drawn never, always, or when shift is down, according to the values SSSnapNever
, SSSnapAlways
, and SSSnapOnShift
. The ticks are drawn at angles determined by - setNumberOfSnapMarks:. The behavior of angle snapping can be controlled separately using - setSnapBehavior:.
See Also: - drawTicksBehavior, - setNumberOfSnapMarks:, - setSnapBehavior:
- (void)setEnabled:(BOOL)flag
Sets whether the slider's value can be changed by the user. Disabled sliders are drawn with a dimmed appearance.
See Also: - isEnabled
- (void)setMaximumDistance:(float)maxDistance
Sets the maximum distance allowed for values. This does not change the appearance of the slider, but rather, the values assigned to the various points the knob can be dragged. Values at the maximum distance will always be found around the rim of the slider's base; the slider's "scale" is adjusted to ensure that this remains true at all times.
See Also: - maximumDistance
- (void)setNumberOfSnapMarks:(int)count
Sets the number of discrete angles that the angle-snapping behavior set by - setSnapBehavior: will use. The first angle snapped to is always at radian 0.0 (to the right, in other words); the other angles are distributed evenly around the circumference of the slider.
See Also: - numberOfSnapMarks, - setSnapBehavior:, - setDrawTicksBehavior:
- (void)setSnapBehavior:(SSCircularSliderSnapBehavior)behavior
Sets the angle snap behavior used by the receiver. Snapping can occur never, always, or when shift is down, according to the values SSSnapNever
, SSSnapAlways
, and SSSnapOnShift
. The snapping happens at angles determined by - setNumberOfSnapMarks:. The behavior of tick drawing can be controlled separately using - setDrawTicksBehavior:.
See Also: - snapBehavior, - setNumberOfSnapMarks:, - setDrawTicksBehavior:
- (void)setTarget:(id)anObject
Sets the target to which actions will be sent when the user changes the value of the control. The FirstResponder is the default target, represented by a target value of nil.
See Also: - target, - setAction:, - sendAction
- (void)setXOffset:(float)xOffset andYOffset:(float)yOffset
Sets the current value of the slider to the x and y offsets given. The value is converted to an angle and distance, and then constrained by - constrainAngle:andDistance:, before it is set on the slider.
See Also: - getXOffset:andYOffset:, - setAngle:andDistance:, - constrainAngle:andDistance:
- (SSCircularSliderSnapBehavior)snapBehavior
Returns the angle snap behavior used by the receiver. Snapping can occur never, always, or when shift is down, according to the values SSSnapNever
, SSSnapAlways
, and SSSnapOnShift
.
See Also: - setSnapBehavior:, - numberOfSnapMarks, - drawTicksBehavior
- (id)target
Returns the target to which actions will be sent when the user changes the value of the control. The FirstResponder is the default target, represented by a target value of nil.
See Also: - setTarget:, - action, - sendAction