forked from SelfControlApp/selfcontrol
-
Notifications
You must be signed in to change notification settings - Fork 0
/
SCDurationSlider.m
112 lines (88 loc) · 3.36 KB
/
SCDurationSlider.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
//
// SCTimeSlider.m
// SelfControl
//
// Created by Charlie Stigler on 4/17/21.
//
#import "SCDurationSlider.h"
#import "SCTimeIntervalFormatter.h"
#import <TransformerKit/NSValueTransformer+TransformerKit.h>
#define kValueTransformerName @"BlockDurationSliderTransformer"
@implementation SCDurationSlider
- (void)drawRect:(NSRect)dirtyRect {
[super drawRect:dirtyRect];
// Drawing code here.
}
- (instancetype)initWithCoder:(NSCoder *)coder {
if (self = [super initWithCoder: coder]) {
[self initializeDurationProperties];
}
return self;
}
- (instancetype)init {
if (self = [super init]) {
[self initializeDurationProperties];
}
return self;
}
- (void)initializeDurationProperties {
// default: 1 day max
_maxDuration = 1440;
// register an NSValueTransformer
[self registerMinutesValueTransformer];
}
- (void)setMaxDuration:(NSInteger)maxDuration {
_maxDuration = maxDuration;
[self setMinValue: 1]; // never start a block shorter than 1 minute
[self setMaxValue: self.maxDuration];
}
- (void)registerMinutesValueTransformer {
[NSValueTransformer registerValueTransformerWithName: kValueTransformerName
transformedValueClass: [NSNumber class]
returningTransformedValueWithBlock:^id _Nonnull(id _Nonnull value) {
// if it's not a number or convertable to one, IDK man
if (![value respondsToSelector: @selector(floatValue)]) return @0;
long minutesValue = lroundf([value floatValue]);
return @(minutesValue);
}];
}
- (NSInteger)durationValueMinutes {
return lroundf(self.floatValue);
}
- (void)bindDurationToObject:(id)obj keyPath:(NSString*)keyPath {
[self bind: @"value"
toObject: obj
withKeyPath: keyPath
options: @{
NSContinuouslyUpdatesValueBindingOption: @YES,
NSValueTransformerNameBindingOption: kValueTransformerName
}];
}
- (NSString*)durationDescription {
return [SCDurationSlider timeSliderDisplayStringFromNumberOfMinutes: self.durationValueMinutes];
}
// String conversion utility methods
+ (NSString *)timeSliderDisplayStringFromTimeInterval:(NSTimeInterval)numberOfSeconds {
static SCTimeIntervalFormatter* formatter = nil;
if (formatter == nil) {
formatter = [[SCTimeIntervalFormatter alloc] init];
}
NSString* formatted = [formatter stringForObjectValue:@(numberOfSeconds)];
return formatted;
}
+ (NSString *)timeSliderDisplayStringFromNumberOfMinutes:(NSInteger)numberOfMinutes {
if (numberOfMinutes < 0) return @"Invalid duration";
static NSCalendar* gregorian = nil;
if (gregorian == nil) {
gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
}
NSRange secondsRangePerMinute = [gregorian
rangeOfUnit:NSCalendarUnitSecond
inUnit:NSCalendarUnitMinute
forDate:[NSDate date]];
NSInteger numberOfSecondsPerMinute = (NSInteger)NSMaxRange(secondsRangePerMinute);
NSTimeInterval numberOfSecondsSelected = (NSTimeInterval)(numberOfSecondsPerMinute * numberOfMinutes);
NSString* displayString = [SCDurationSlider timeSliderDisplayStringFromTimeInterval:numberOfSecondsSelected];
return displayString;
}
@end