aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTeddy Wing2018-08-21 05:45:16 +0200
committerTeddy Wing2018-08-21 06:06:47 +0200
commit9ebf6a1461f6322691abc5f6547fcf6eb6f2dae4 (patch)
treee11470629bb6b8c5264c371bcced64b349c26777
parent4e62e8ad7abf833a3d2cb7ddfe01161e91c648ad (diff)
downloadDomeKey-9ebf6a1461f6322691abc5f6547fcf6eb6f2dae4.tar.bz2
HeadphoneKey: Add system for handling dead keys
We need a way to listen for multiple presses of the headphone buttons. Once a timeout has been reached, the recorded button presses that happened within the space of the timeout will be those used for performing an associated action. We add an enum for headphone buttons to give them an easy name to refer to. The default timeout between button presses before an action gets executed is 1000 milliseconds. This will be customisable later with a configuration file. Already pressed "dead" keys within the timeout are stored in `_key_buffer`. This buffer gets cleared when we run an action. I you've pressed a headphone button key, we always try to run an action, so this will always get cleared, even if no mapping action is found. I decided to start `_key_buffer` with a capacity of 5 at random because that seemed like more than enough button presses for a single mapping. handleDeadKey:: - In order to append a `HeadphoneButton` from our enum, I needed to convert it to an `id` type because `NSArray` doesn't allow anything else. - Call `maybeRunAction` with our timeout. Before doing this, make sure we cancel any previous delayed calls to `maybeRunAction` because they might be executed before the most recent headphone button press and thus run the wrong action. Cancelling enables us to only run the action once the timeout has elapsed after the most recent headphone button press. maybeRunAction: - Just log the headphone button presses for now. - Remove all presses from `_key_buffer` so to make way for a new key mapping. - I'm now thinking I should rename this method to remove the `maybe`. Since the `performSelector` gets cancelled outside of this method, the "maybe" doesn't make sense to me here any more.
-rw-r--r--DomeKey/HeadphoneKey.h12
-rw-r--r--DomeKey/HeadphoneKey.m27
2 files changed, 39 insertions, 0 deletions
diff --git a/DomeKey/HeadphoneKey.h b/DomeKey/HeadphoneKey.h
index 0d4e729..c1b8e85 100644
--- a/DomeKey/HeadphoneKey.h
+++ b/DomeKey/HeadphoneKey.h
@@ -14,8 +14,20 @@ typedef enum KeyPress : BOOL {
KeyPressUp = NO
} KeyPress;
+typedef enum HeadphoneButton : NSUInteger {
+ HeadphoneButton_Play,
+ HeadphoneButton_Up,
+ HeadphoneButton_Down
+} HeadphoneButton;
+
+static const unsigned int TIMEOUT_MILLISECONDS = 1000;
+
@interface HeadphoneKey : NSObject {
NSArray *_mikeys;
+ NSMutableArray *_key_buffer;
}
+- (void)handleDeadKey:(HeadphoneButton)button;
+- (void)maybeRunAction;
+
@end
diff --git a/DomeKey/HeadphoneKey.m b/DomeKey/HeadphoneKey.m
index 0593173..d5fdb8d 100644
--- a/DomeKey/HeadphoneKey.m
+++ b/DomeKey/HeadphoneKey.m
@@ -14,6 +14,8 @@
{
self = [super init];
if (self) {
+ _key_buffer = [[NSMutableArray alloc] initWithCapacity:5];
+
_mikeys = [DDHidAppleMikey allMikeys];
[_mikeys makeObjectsPerformSelector:@selector(setDelegate:)
withObject:self];
@@ -32,15 +34,40 @@
switch (usageId) {
case kHIDUsage_Csmr_PlayOrPause:
NSLog(@"Middle");
+ [self handleDeadKey:HeadphoneButton_Play];
break;
case kHIDUsage_Csmr_VolumeIncrement:
NSLog(@"Top");
+ [self handleDeadKey:HeadphoneButton_Up];
break;
case kHIDUsage_Csmr_VolumeDecrement:
NSLog(@"Bottom");
+ [self handleDeadKey:HeadphoneButton_Down];
break;
}
}
}
+- (void)handleDeadKey:(HeadphoneButton)button
+{
+ NSNumber *storable_button = [NSNumber numberWithUnsignedInteger:button];
+ [_key_buffer addObject:storable_button];
+
+ [NSObject cancelPreviousPerformRequestsWithTarget:self
+ selector:@selector(maybeRunAction)
+ object:nil];
+
+ NSTimeInterval timeout_seconds = TIMEOUT_MILLISECONDS / 1000.0;
+ [self performSelector:@selector(maybeRunAction)
+ withObject:nil
+ afterDelay:timeout_seconds];
+}
+
+- (void)maybeRunAction
+{
+ NSLog(@"%@", _key_buffer);
+
+ [_key_buffer removeAllObjects];
+}
+
@end