187 lines
6.2 KiB
Objective-C
187 lines
6.2 KiB
Objective-C
//
|
||
// KBKeyboardKeyFactory.m
|
||
// CustomKeyboard
|
||
//
|
||
|
||
#import "KBKeyboardKeyFactory.h"
|
||
#import "KBKeyboardLayoutConfig.h"
|
||
#import "KBKey.h"
|
||
|
||
@interface KBKeyboardKeyFactory ()
|
||
@property (nonatomic, strong) KBKeyboardLayoutConfig *layoutConfig;
|
||
@end
|
||
|
||
@implementation KBKeyboardKeyFactory
|
||
|
||
- (instancetype)initWithLayoutConfig:(KBKeyboardLayoutConfig *)layoutConfig {
|
||
self = [super init];
|
||
if (self) {
|
||
_layoutConfig = layoutConfig;
|
||
}
|
||
return self;
|
||
}
|
||
|
||
- (KBKey *)keyForItemId:(NSString *)itemId shiftOn:(BOOL)shiftOn {
|
||
if (itemId.length == 0) { return nil; }
|
||
KBKeyboardKeyDef *def = [self.layoutConfig keyDefForIdentifier:itemId];
|
||
if (def) {
|
||
return [self keyFromDef:def identifier:itemId shiftOn:shiftOn];
|
||
}
|
||
|
||
NSRange range = [itemId rangeOfString:@":"];
|
||
if (range.location != NSNotFound) {
|
||
NSString *prefix = [itemId substringToIndex:range.location];
|
||
NSString *value = [itemId substringFromIndex:range.location + 1];
|
||
if ([prefix isEqualToString:@"letter"]) {
|
||
if (value.length >= 1) {
|
||
return [self letterKeyWithChar:value shiftOn:shiftOn];
|
||
}
|
||
return nil;
|
||
}
|
||
if ([prefix isEqualToString:@"digit"]) {
|
||
NSString *identifier = [NSString stringWithFormat:@"digit_%@", value];
|
||
KBKey *k = [KBKey keyWithIdentifier:identifier title:value output:value type:KBKeyTypeCharacter];
|
||
k.caseVariant = KBKeyCaseVariantNone;
|
||
return k;
|
||
}
|
||
if ([prefix isEqualToString:@"sym"]) {
|
||
NSString *identifier = [self kb_identifierForSymbol:value];
|
||
KBKey *k = [KBKey keyWithIdentifier:identifier title:value output:value type:KBKeyTypeCharacter];
|
||
k.caseVariant = KBKeyCaseVariantNone;
|
||
return k;
|
||
}
|
||
}
|
||
return nil;
|
||
}
|
||
|
||
- (KBKey *)keyFromDef:(KBKeyboardKeyDef *)def
|
||
identifier:(NSString *)identifier
|
||
shiftOn:(BOOL)shiftOn {
|
||
KBKeyType type = [self kb_keyTypeForDef:def];
|
||
NSString *title = def.title ?: @"";
|
||
if (type == KBKeyTypeShift && shiftOn && def.selectedTitle.length > 0) {
|
||
title = def.selectedTitle;
|
||
}
|
||
NSString *output = @"";
|
||
switch (type) {
|
||
case KBKeyTypeSpace:
|
||
output = @" ";
|
||
break;
|
||
case KBKeyTypeReturn:
|
||
output = @"\n";
|
||
break;
|
||
default:
|
||
output = @"";
|
||
break;
|
||
}
|
||
|
||
NSString *finalId = identifier;
|
||
if ([identifier isEqualToString:@"emoji"]) {
|
||
finalId = KBKeyIdentifierEmojiPanel;
|
||
} else if ([identifier isEqualToString:@"send"]) {
|
||
finalId = @"return";
|
||
}
|
||
|
||
KBKey *k = [KBKey keyWithIdentifier:finalId title:title output:output type:type];
|
||
if (type == KBKeyTypeShift) {
|
||
k.caseVariant = shiftOn ? KBKeyCaseVariantUpper : KBKeyCaseVariantLower;
|
||
} else {
|
||
k.caseVariant = KBKeyCaseVariantNone;
|
||
}
|
||
return k;
|
||
}
|
||
|
||
- (KBKey *)letterKeyWithChar:(NSString *)charString shiftOn:(BOOL)shiftOn {
|
||
if (charString.length == 0) { return nil; }
|
||
NSString *lower = charString.lowercaseString;
|
||
NSString *upper = charString.uppercaseString;
|
||
|
||
NSString *shown = shiftOn ? upper : lower;
|
||
NSString *identifier = [NSString stringWithFormat:@"letter_%@", lower];
|
||
|
||
KBKey *k = [KBKey keyWithIdentifier:identifier
|
||
title:shown
|
||
output:shown
|
||
type:KBKeyTypeCharacter];
|
||
k.caseVariant = shiftOn ? KBKeyCaseVariantUpper : KBKeyCaseVariantLower;
|
||
return k;
|
||
}
|
||
|
||
#pragma mark - Private
|
||
|
||
- (KBKeyType)kb_keyTypeForDef:(KBKeyboardKeyDef *)def {
|
||
NSString *type = def.type.lowercaseString;
|
||
if ([type isEqualToString:@"shift"]) return KBKeyTypeShift;
|
||
if ([type isEqualToString:@"backspace"]) return KBKeyTypeBackspace;
|
||
if ([type isEqualToString:@"mode"]) return KBKeyTypeModeChange;
|
||
if ([type isEqualToString:@"symbolstoggle"]) return KBKeyTypeSymbolsToggle;
|
||
if ([type isEqualToString:@"space"]) return KBKeyTypeSpace;
|
||
if ([type isEqualToString:@"return"]) return KBKeyTypeReturn;
|
||
if ([type isEqualToString:@"globe"]) return KBKeyTypeGlobe;
|
||
return KBKeyTypeCustom;
|
||
}
|
||
|
||
- (NSString *)kb_identifierForSymbol:(NSString *)symbol {
|
||
if (symbol.length == 0) { return nil; }
|
||
static NSDictionary<NSString *, NSString *> *map = nil;
|
||
static dispatch_once_t onceToken;
|
||
dispatch_once(&onceToken, ^{
|
||
map = @{
|
||
@"-": @"sym_minus",
|
||
@"/": @"sym_slash",
|
||
@":": @"sym_colon",
|
||
@";": @"sym_semicolon",
|
||
@"(": @"sym_paren_l",
|
||
@")": @"sym_paren_r",
|
||
@"¥": @"sym_money",
|
||
@"¥": @"sym_money",
|
||
@"&": @"sym_amp",
|
||
@"@": @"sym_at",
|
||
@"\"": @"sym_quote_double",
|
||
@"“": @"sym_quote_double",
|
||
@"”": @"sym_quote_double",
|
||
@".": @"sym_dot",
|
||
@"。": @"sym_chinese_dot",
|
||
@",": @"sym_comma",
|
||
@"、": @"sym_dun",
|
||
@"?": @"sym_question",
|
||
@"!": @"sym_exclam",
|
||
@"'": @"sym_quote_single",
|
||
@"‘": @"sym_quote_single",
|
||
@"’": @"sym_quote_single",
|
||
@"[": @"sym_bracket_l",
|
||
@"]": @"sym_bracket_r",
|
||
@"{": @"sym_brace_l",
|
||
@"}": @"sym_brace_r",
|
||
@"「": @"sym_corner_l",
|
||
@"」": @"sym_corner_r",
|
||
@"#": @"sym_hash",
|
||
@"%": @"sym_percent",
|
||
@"^": @"sym_caret",
|
||
@"*": @"sym_asterisk",
|
||
@"+": @"sym_plus",
|
||
@"=": @"sym_equal",
|
||
@"_": @"sym_underscore",
|
||
@"\\": @"sym_backslash",
|
||
@"|": @"sym_pipe",
|
||
@"~": @"sym_tilde",
|
||
@"<": @"sym_lt",
|
||
@">": @"sym_gt",
|
||
@"€": @"sym_euro",
|
||
@"$": @"sym_dollar",
|
||
@"£": @"sym_pound",
|
||
@"·": @"sym_bullet",
|
||
@"^_^": @"sym_face",
|
||
@"—": @"sym_emdash",
|
||
@"«": @"sym_guillemet_l",
|
||
@"»": @"sym_guillemet_r",
|
||
@"《": @"sym_book_title_l",
|
||
@"》": @"sym_book_title_r",
|
||
@"...": @"sym_ellipsis"
|
||
};
|
||
});
|
||
return map[symbol];
|
||
}
|
||
|
||
@end
|