Files
keyboard/CustomKeyboard/View/KBKeyboardView/KBKeyboardKeyFactory.m
2026-03-04 12:54:57 +08:00

187 lines
6.2 KiB
Objective-C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//
// 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