1
This commit is contained in:
187
CustomKeyboard/Model/KBKeyboardLayoutConfig.m
Normal file
187
CustomKeyboard/Model/KBKeyboardLayoutConfig.m
Normal file
@@ -0,0 +1,187 @@
|
||||
//
|
||||
// KBKeyboardLayoutConfig.m
|
||||
// CustomKeyboard
|
||||
//
|
||||
|
||||
#import "KBKeyboardLayoutConfig.h"
|
||||
#import <MJExtension/MJExtension.h>
|
||||
#import "KBConfig.h"
|
||||
|
||||
static NSString * const kKBKeyboardLayoutConfigFileName = @"kb_keyboard_layout_config";
|
||||
|
||||
@implementation KBKeyboardLayoutMetrics
|
||||
@end
|
||||
|
||||
@implementation KBKeyboardLayoutFonts
|
||||
@end
|
||||
|
||||
@implementation KBKeyboardKeyDef
|
||||
@end
|
||||
|
||||
@implementation KBKeyboardRowItem
|
||||
|
||||
+ (NSDictionary *)mj_replacedKeyFromPropertyName {
|
||||
return @{ @"itemId": @"id" };
|
||||
}
|
||||
|
||||
+ (NSArray<KBKeyboardRowItem *> *)itemsFromRawArray:(NSArray *)raw {
|
||||
if (![raw isKindOfClass:[NSArray class]] || raw.count == 0) {
|
||||
return @[];
|
||||
}
|
||||
NSMutableArray<KBKeyboardRowItem *> *items = [NSMutableArray arrayWithCapacity:raw.count];
|
||||
for (id obj in raw) {
|
||||
if ([obj isKindOfClass:[NSString class]]) {
|
||||
KBKeyboardRowItem *item = [KBKeyboardRowItem new];
|
||||
item.itemId = (NSString *)obj;
|
||||
[items addObject:item];
|
||||
continue;
|
||||
}
|
||||
if ([obj isKindOfClass:[NSDictionary class]]) {
|
||||
KBKeyboardRowItem *item = [KBKeyboardRowItem mj_objectWithKeyValues:obj];
|
||||
if (item.itemId.length == 0) {
|
||||
NSString *fallback = ((NSDictionary *)obj)[@"id"];
|
||||
if ([fallback isKindOfClass:[NSString class]]) {
|
||||
item.itemId = fallback;
|
||||
}
|
||||
}
|
||||
if (item.itemId.length > 0) {
|
||||
[items addObject:item];
|
||||
}
|
||||
}
|
||||
}
|
||||
return items.copy;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation KBKeyboardRowSegments
|
||||
|
||||
- (NSArray<KBKeyboardRowItem *> *)leftItems {
|
||||
return [KBKeyboardRowItem itemsFromRawArray:self.left ?: @[]];
|
||||
}
|
||||
|
||||
- (NSArray<KBKeyboardRowItem *> *)centerItems {
|
||||
return [KBKeyboardRowItem itemsFromRawArray:self.center ?: @[]];
|
||||
}
|
||||
|
||||
- (NSArray<KBKeyboardRowItem *> *)rightItems {
|
||||
return [KBKeyboardRowItem itemsFromRawArray:self.right ?: @[]];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation KBKeyboardRowConfig
|
||||
|
||||
- (NSArray<KBKeyboardRowItem *> *)resolvedItems {
|
||||
return [KBKeyboardRowItem itemsFromRawArray:self.items ?: @[]];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation KBKeyboardLayout
|
||||
|
||||
+ (NSDictionary *)mj_objectClassInArray {
|
||||
return @{ @"rows": [KBKeyboardRowConfig class] };
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation KBKeyboardLayoutConfig
|
||||
|
||||
+ (instancetype)sharedConfig {
|
||||
static KBKeyboardLayoutConfig *config = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
NSString *path = [[NSBundle mainBundle] pathForResource:kKBKeyboardLayoutConfigFileName ofType:@"json"];
|
||||
NSData *data = path.length ? [NSData dataWithContentsOfFile:path] : nil;
|
||||
config = data ? [KBKeyboardLayoutConfig configFromJSONData:data] : nil;
|
||||
});
|
||||
return config;
|
||||
}
|
||||
|
||||
+ (instancetype)configFromJSONData:(NSData *)data {
|
||||
if (data.length == 0) { return nil; }
|
||||
NSError *error = nil;
|
||||
id json = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
|
||||
if (error || ![json isKindOfClass:[NSDictionary class]]) {
|
||||
return nil;
|
||||
}
|
||||
NSDictionary *dict = (NSDictionary *)json;
|
||||
KBKeyboardLayoutConfig *config = [KBKeyboardLayoutConfig mj_objectWithKeyValues:dict];
|
||||
|
||||
NSDictionary *keyDefsRaw = dict[@"keyDefs"];
|
||||
if ([keyDefsRaw isKindOfClass:[NSDictionary class]]) {
|
||||
NSMutableDictionary<NSString *, KBKeyboardKeyDef *> *defs = [NSMutableDictionary dictionaryWithCapacity:keyDefsRaw.count];
|
||||
[keyDefsRaw enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
|
||||
if (![key isKindOfClass:[NSString class]] || ![obj isKindOfClass:[NSDictionary class]]) {
|
||||
return;
|
||||
}
|
||||
KBKeyboardKeyDef *def = [KBKeyboardKeyDef mj_objectWithKeyValues:obj];
|
||||
if (def) {
|
||||
defs[key] = def;
|
||||
}
|
||||
}];
|
||||
config.keyDefs = defs.copy;
|
||||
}
|
||||
|
||||
NSDictionary *layoutsRaw = dict[@"layouts"];
|
||||
if ([layoutsRaw isKindOfClass:[NSDictionary class]]) {
|
||||
NSMutableDictionary<NSString *, KBKeyboardLayout *> *layouts = [NSMutableDictionary dictionaryWithCapacity:layoutsRaw.count];
|
||||
[layoutsRaw enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
|
||||
if (![key isKindOfClass:[NSString class]] || ![obj isKindOfClass:[NSDictionary class]]) {
|
||||
return;
|
||||
}
|
||||
KBKeyboardLayout *layout = [KBKeyboardLayout mj_objectWithKeyValues:obj];
|
||||
if (layout) {
|
||||
layouts[key] = layout;
|
||||
}
|
||||
}];
|
||||
config.layouts = layouts.copy;
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
- (CGFloat)scaledValue:(CGFloat)designValue {
|
||||
CGFloat baseWidth = (self.designWidth > 0.0) ? self.designWidth : KB_DESIGN_WIDTH;
|
||||
CGFloat scale = KBScreenWidth() / baseWidth;
|
||||
return designValue * scale;
|
||||
}
|
||||
|
||||
- (CGFloat)keyboardAreaDesignHeight {
|
||||
KBKeyboardLayout *layout = [self layoutForName:@"letters"] ?: self.layouts.allValues.firstObject;
|
||||
NSUInteger rowCount = layout.rows.count;
|
||||
if (rowCount == 0) { return 0.0; }
|
||||
|
||||
CGFloat rowSpacing = self.metrics.rowSpacing.doubleValue;
|
||||
CGFloat topInset = self.metrics.topInset.doubleValue;
|
||||
CGFloat bottomInset = self.metrics.bottomInset.doubleValue;
|
||||
|
||||
CGFloat total = topInset + bottomInset + rowSpacing * (rowCount - 1);
|
||||
for (KBKeyboardRowConfig *row in layout.rows) {
|
||||
CGFloat height = row.height.doubleValue;
|
||||
if (height <= 0.0) {
|
||||
height = self.metrics.keyHeight.doubleValue;
|
||||
}
|
||||
if (height <= 0.0) { height = 40.0; }
|
||||
total += height;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
- (CGFloat)keyboardAreaScaledHeight {
|
||||
CGFloat designHeight = [self keyboardAreaDesignHeight];
|
||||
return designHeight > 0.0 ? [self scaledValue:designHeight] : 0.0;
|
||||
}
|
||||
|
||||
- (KBKeyboardLayout *)layoutForName:(NSString *)name {
|
||||
if (name.length == 0) { return nil; }
|
||||
return self.layouts[name];
|
||||
}
|
||||
|
||||
- (KBKeyboardKeyDef *)keyDefForIdentifier:(NSString *)identifier {
|
||||
if (identifier.length == 0) { return nil; }
|
||||
return self.keyDefs[identifier];
|
||||
}
|
||||
|
||||
@end
|
||||
Reference in New Issue
Block a user