aboutsummaryrefslogtreecommitdiff
path: root/src/libui_sdl/libui/darwin/slider.m
diff options
context:
space:
mode:
Diffstat (limited to 'src/libui_sdl/libui/darwin/slider.m')
-rw-r--r--src/libui_sdl/libui/darwin/slider.m147
1 files changed, 147 insertions, 0 deletions
diff --git a/src/libui_sdl/libui/darwin/slider.m b/src/libui_sdl/libui/darwin/slider.m
new file mode 100644
index 0000000..f00da50
--- /dev/null
+++ b/src/libui_sdl/libui/darwin/slider.m
@@ -0,0 +1,147 @@
+// 14 august 2015
+#import "uipriv_darwin.h"
+
+// Horizontal sliders have no intrinsic width; we'll use the default Interface Builder width for them.
+// This will also be used for the initial frame size, to ensure the slider is always horizontal (see below).
+#define sliderWidth 92
+
+@interface libui_intrinsicWidthNSSlider : NSSlider
+@end
+
+@implementation libui_intrinsicWidthNSSlider
+
+- (NSSize)intrinsicContentSize
+{
+ NSSize s;
+
+ s = [super intrinsicContentSize];
+ s.width = sliderWidth;
+ return s;
+}
+
+@end
+
+struct uiSlider {
+ uiDarwinControl c;
+ NSSlider *slider;
+ void (*onChanged)(uiSlider *, void *);
+ void *onChangedData;
+};
+
+@interface sliderDelegateClass : NSObject {
+ struct mapTable *sliders;
+}
+- (IBAction)onChanged:(id)sender;
+- (void)registerSlider:(uiSlider *)b;
+- (void)unregisterSlider:(uiSlider *)b;
+@end
+
+@implementation sliderDelegateClass
+
+- (id)init
+{
+ self = [super init];
+ if (self)
+ self->sliders = newMap();
+ return self;
+}
+
+- (void)dealloc
+{
+ mapDestroy(self->sliders);
+ [super dealloc];
+}
+
+- (IBAction)onChanged:(id)sender
+{
+ uiSlider *s;
+
+ s = (uiSlider *) mapGet(self->sliders, sender);
+ (*(s->onChanged))(s, s->onChangedData);
+}
+
+- (void)registerSlider:(uiSlider *)s
+{
+ mapSet(self->sliders, s->slider, s);
+ [s->slider setTarget:self];
+ [s->slider setAction:@selector(onChanged:)];
+}
+
+- (void)unregisterSlider:(uiSlider *)s
+{
+ [s->slider setTarget:nil];
+ mapDelete(self->sliders, s->slider);
+}
+
+@end
+
+static sliderDelegateClass *sliderDelegate = nil;
+
+uiDarwinControlAllDefaultsExceptDestroy(uiSlider, slider)
+
+static void uiSliderDestroy(uiControl *c)
+{
+ uiSlider *s = uiSlider(c);
+
+ [sliderDelegate unregisterSlider:s];
+ [s->slider release];
+ uiFreeControl(uiControl(s));
+}
+
+int uiSliderValue(uiSlider *s)
+{
+ return [s->slider integerValue];
+}
+
+void uiSliderSetValue(uiSlider *s, int value)
+{
+ [s->slider setIntegerValue:value];
+}
+
+void uiSliderOnChanged(uiSlider *s, void (*f)(uiSlider *, void *), void *data)
+{
+ s->onChanged = f;
+ s->onChangedData = data;
+}
+
+static void defaultOnChanged(uiSlider *s, void *data)
+{
+ // do nothing
+}
+
+uiSlider *uiNewSlider(int min, int max)
+{
+ uiSlider *s;
+ NSSliderCell *cell;
+ int temp;
+
+ if (min >= max) {
+ temp = min;
+ min = max;
+ max = temp;
+ }
+
+ uiDarwinNewControl(uiSlider, s);
+
+ // a horizontal slider is defined as one where the width > height, not by a flag
+ // to be safe, don't use NSZeroRect, but make it horizontal from the get-go
+ s->slider = [[libui_intrinsicWidthNSSlider alloc]
+ initWithFrame:NSMakeRect(0, 0, sliderWidth, 2)];
+ [s->slider setMinValue:min];
+ [s->slider setMaxValue:max];
+ [s->slider setAllowsTickMarkValuesOnly:NO];
+ [s->slider setNumberOfTickMarks:0];
+ [s->slider setTickMarkPosition:NSTickMarkAbove];
+
+ cell = (NSSliderCell *) [s->slider cell];
+ [cell setSliderType:NSLinearSlider];
+
+ if (sliderDelegate == nil) {
+ sliderDelegate = [[sliderDelegateClass new] autorelease];
+ [delegates addObject:sliderDelegate];
+ }
+ [sliderDelegate registerSlider:s];
+ uiSliderOnChanged(s, defaultOnChanged, NULL);
+
+ return s;
+}