Add a toolbar above the on-screen keyboard with extra keys that are missing from iOS keyboard (#576)

* Add required images to assets

* Add toolbar above keyboard with more key options

* Fix tvOS errors
This commit is contained in:
goob47
2023-09-29 00:49:35 -05:00
committed by GitHub
parent 514e415956
commit 884deb9244
18 changed files with 245 additions and 3 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "AltIcon.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -1,6 +1,6 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
"author" : "xcode",
"version" : 1
}
}
}

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "ControlIcon.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "DeleteIcon.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "doneIcon.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 405 B

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "EscapeIcon.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "ShiftIcon.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 719 B

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "TabIcon.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "WindowsIcon.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@@ -352,6 +352,23 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
// Prepare the textbox used to capture keyboard events.
keyInputField.delegate = self;
keyInputField.text = @"0";
#if !TARGET_OS_TV
// Prepare the toolbar above the keyboard for more options
UIToolbar *customToolbarView = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, self.bounds.size.width, 44)];
UIBarButtonItem *doneBarButton = [self createButtonWithImageNamed:@"DoneIcon.png" backgroundColor:[UIColor clearColor] target:self action:@selector(toolbarButtonClicked:) keyCode:@"0x00" isToggleable:NO];
UIBarButtonItem *windowsBarButton = [self createButtonWithImageNamed:@"WindowsIcon.png" backgroundColor:[UIColor blackColor] target:self action:@selector(toolbarButtonClicked:) keyCode:@"0x5B" isToggleable:YES];
UIBarButtonItem *tabBarButton = [self createButtonWithImageNamed:@"TabIcon.png" backgroundColor:[UIColor blackColor] target:self action:@selector(toolbarButtonClicked:) keyCode:@"0x09" isToggleable:NO];
UIBarButtonItem *shiftBarButton = [self createButtonWithImageNamed:@"ShiftIcon.png" backgroundColor:[UIColor blackColor] target:self action:@selector(toolbarButtonClicked:) keyCode:@"0xA0" isToggleable:YES];
UIBarButtonItem *escapeBarButton = [self createButtonWithImageNamed:@"EscapeIcon.png" backgroundColor:[UIColor blackColor] target:self action:@selector(toolbarButtonClicked:) keyCode:@"0x1B" isToggleable:NO];
UIBarButtonItem *controlBarButton = [self createButtonWithImageNamed:@"ControlIcon.png" backgroundColor:[UIColor blackColor] target:self action:@selector(toolbarButtonClicked:) keyCode:@"0xA2" isToggleable:YES];
UIBarButtonItem *altBarButton = [self createButtonWithImageNamed:@"AltIcon.png" backgroundColor:[UIColor blackColor] target:self action:@selector(toolbarButtonClicked:) keyCode:@"0xA4" isToggleable:YES];
UIBarButtonItem *deleteBarButton = [self createButtonWithImageNamed:@"DeleteIcon.png" backgroundColor:[UIColor blackColor] target:self action:@selector(toolbarButtonClicked:) keyCode:@"0x2E" isToggleable:NO];
UIBarButtonItem *flexibleSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
[customToolbarView setItems:[NSArray arrayWithObjects:doneBarButton, windowsBarButton, escapeBarButton, tabBarButton, shiftBarButton, controlBarButton, altBarButton, deleteBarButton, flexibleSpace, nil]];
keyInputField.inputAccessoryView = customToolbarView;
#endif
[keyInputField becomeFirstResponder];
[keyInputField addTarget:self action:@selector(onKeyboardPressed:) forControlEvents:UIControlEventEditingChanged];
@@ -364,6 +381,63 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
}
}
- (UIBarButtonItem *)createButtonWithImageNamed:(NSString *)imageName backgroundColor:(UIColor *)backgroundColor target:(id)target action:(SEL)action keyCode:(NSString *)keyCode isToggleable:(BOOL)isToggleable {
UIImage *image = [UIImage imageNamed:imageName];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setImage:image forState:UIControlStateNormal];
button.frame = CGRectMake(0, 0, 30, 30);
button.imageView.contentMode = UIViewContentModeScaleAspectFit;
button.imageView.backgroundColor = backgroundColor;
button.imageView.layer.cornerRadius = 10.0;
button.imageEdgeInsets = UIEdgeInsetsMake(6, 6, 6, 6);
[button addTarget:target action:action forControlEvents:UIControlEventTouchUpInside];
objc_setAssociatedObject(button, "keyCode", keyCode, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
objc_setAssociatedObject(button, "isToggleable", @(isToggleable), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
objc_setAssociatedObject(button, "isOn", @(NO), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
UIBarButtonItem *barButton = [[UIBarButtonItem alloc] initWithCustomView:button];
return barButton;
}
- (void)toolbarButtonClicked:(UIButton *)sender {
BOOL isToggleable = [objc_getAssociatedObject(sender, "isToggleable") boolValue];
BOOL isOn = [objc_getAssociatedObject(sender, "isOn") boolValue];
if (isToggleable){
isOn = !isOn;
// Update the button's appearance based on its new state
if (isOn) {
sender.imageView.backgroundColor = [UIColor lightGrayColor];
} else {
sender.imageView.backgroundColor = [UIColor blackColor];
}
}
// Update the new on/off state of the button
objc_setAssociatedObject(sender, "isOn", @(isOn), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
// Get the keyCode parameter and convert to short for key press event
NSString *keyCodeString = objc_getAssociatedObject(sender, "keyCode");
unsigned int keyCodeInteger = 0;
NSScanner *scanner = [NSScanner scannerWithString:keyCodeString];
[scanner scanHexInt:&keyCodeInteger];
short keyCodeShort = (short)keyCodeInteger;
// Close keyboard if done button clicked
if ([keyCodeString isEqual: @"0x00"]){
[[UIApplication sharedApplication] sendAction:@selector(resignFirstResponder) to:nil from:nil forEvent:nil];
} else {
// Send key press event using keyCode parameter, toggle if necessary
// FOR SOME REASON CTRL-ALT-DELETE DOESN'T WORK???
if (isToggleable){
if (isOn){
LiSendKeyboardEvent(keyCodeShort, KEY_ACTION_DOWN, 0);
} else {
LiSendKeyboardEvent(keyCodeShort, KEY_ACTION_UP, 0);
}
} else {
LiSendKeyboardEvent(keyCodeShort, KEY_ACTION_DOWN, 0);
usleep(50 * 1000);
LiSendKeyboardEvent(keyCodeShort, KEY_ACTION_UP, 0);
}
}
}
- (BOOL)handleMouseButtonEvent:(int)buttonAction forTouches:(NSSet *)touches withEvent:(UIEvent *)event {
#if !TARGET_OS_TV
if (@available(iOS 13.4, *)) {