Add Vim menu navigation

This commit is contained in:
Marcus Ziadé 2025-05-26 20:28:08 +03:00
parent 152e242485
commit 30a8c4bf42
3 changed files with 102 additions and 4 deletions

View File

@ -87,6 +87,7 @@ void render_texture(void *pixels, void *previous)
static const char *help[] = {
"Keyboard Shortcuts:\n"
" Open Menu: Escape\n"
" Menu Navigation: Arrow keys or hjkl\n"
" Open ROM: " MODIFIER_NAME "+O\n"
" Reset: " MODIFIER_NAME "+R\n"
" Pause: " MODIFIER_NAME "+P\n"
@ -2316,6 +2317,10 @@ void run_gui(bool is_running)
case SDL_SCANCODE_LEFT:
case SDL_SCANCODE_UP:
case SDL_SCANCODE_DOWN:
case SDL_SCANCODE_H:
case SDL_SCANCODE_J:
case SDL_SCANCODE_K:
case SDL_SCANCODE_L:
break;
default:
@ -2703,12 +2708,12 @@ void run_gui(bool is_running)
}
}
else if (gui_state == SHOWING_MENU) {
if (event.key.keysym.scancode == SDL_SCANCODE_DOWN && current_menu[current_selection + 1].string) {
if ((event.key.keysym.scancode == SDL_SCANCODE_DOWN || event.key.keysym.scancode == SDL_SCANCODE_J) && current_menu[current_selection + 1].string) {
current_selection++;
mouse_scroling = false;
should_render = true;
}
else if (event.key.keysym.scancode == SDL_SCANCODE_UP && current_selection) {
else if ((event.key.keysym.scancode == SDL_SCANCODE_UP || event.key.keysym.scancode == SDL_SCANCODE_K) && current_selection) {
current_selection--;
mouse_scroling = false;
should_render = true;
@ -2732,11 +2737,11 @@ void run_gui(bool is_running)
return;
}
}
else if (event.key.keysym.scancode == SDL_SCANCODE_RIGHT && current_menu[current_selection].backwards_handler) {
else if ((event.key.keysym.scancode == SDL_SCANCODE_RIGHT || event.key.keysym.scancode == SDL_SCANCODE_L) && current_menu[current_selection].backwards_handler) {
current_menu[current_selection].handler(current_selection);
should_render = true;
}
else if (event.key.keysym.scancode == SDL_SCANCODE_LEFT && current_menu[current_selection].backwards_handler) {
else if ((event.key.keysym.scancode == SDL_SCANCODE_LEFT || event.key.keysym.scancode == SDL_SCANCODE_H) && current_menu[current_selection].backwards_handler) {
current_menu[current_selection].backwards_handler(current_selection);
should_render = true;
}

View File

@ -2,4 +2,6 @@
@interface GBMenuViewController : UIAlertController
+ (instancetype)menu;
@property (nonatomic) NSInteger selectedButtonIndex;
@property (nonatomic, strong) NSArray<UIButton *> *menuButtons;
@end

View File

@ -29,6 +29,7 @@ static NSString *const tips[] = {
{
UILabel *_tipLabel;
UIVisualEffectView *_effectView;
NSMutableArray<UIButton *> *_buttons;
}
+ (instancetype)menu
@ -41,6 +42,8 @@ static NSString *const tips[] = {
[ret addAction:[UIAlertAction actionWithTitle:@"Close"
style:UIAlertActionStyleCancel
handler:nil]];
ret.selectedButtonIndex = 0;
ret->_buttons = [[NSMutableArray alloc] init];
return ret;
}
@ -80,6 +83,7 @@ static NSString *const tips[] = {
button.frame = CGRectMake(round(width * x), height * y, round(width), height);
button.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
[self.view addSubview:button];
[_buttons addObject:button];
if (!buttons[i].selector) {
button.enabled = false;
@ -102,6 +106,9 @@ static NSString *const tips[] = {
[button addTarget:block action:@selector(invoke) forControlEvents:UIControlEventTouchUpInside];
}
self.menuButtons = [_buttons copy];
[self updateSelectedButton];
_effectView = [[UIVisualEffectView alloc] initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleProminent]];
_effectView.layer.cornerRadius = 8;
_effectView.layer.masksToBounds = true;
@ -189,4 +196,88 @@ static NSString *const tips[] = {
return [[UIViewController alloc] init];
}
#pragma mark - Vim Navigation
- (BOOL)canBecomeFirstResponder
{
return YES;
}
- (NSArray<UIKeyCommand *> *)keyCommands
{
return @[
[UIKeyCommand keyCommandWithInput:@"h" modifierFlags:0 action:@selector(moveLeft)],
[UIKeyCommand keyCommandWithInput:@"j" modifierFlags:0 action:@selector(moveDown)],
[UIKeyCommand keyCommandWithInput:@"k" modifierFlags:0 action:@selector(moveUp)],
[UIKeyCommand keyCommandWithInput:@"l" modifierFlags:0 action:@selector(moveRight)],
[UIKeyCommand keyCommandWithInput:@"\r" modifierFlags:0 action:@selector(activateSelected)],
[UIKeyCommand keyCommandWithInput:@" " modifierFlags:0 action:@selector(activateSelected)],
];
}
- (void)moveLeft
{
if (self.selectedButtonIndex % 4 > 0) {
self.selectedButtonIndex--;
[self updateSelectedButton];
}
}
- (void)moveRight
{
if (self.selectedButtonIndex % 4 < 3 && self.selectedButtonIndex + 1 < self.menuButtons.count) {
self.selectedButtonIndex++;
[self updateSelectedButton];
}
}
- (void)moveUp
{
if (self.selectedButtonIndex >= 4) {
self.selectedButtonIndex -= 4;
[self updateSelectedButton];
}
}
- (void)moveDown
{
if (self.selectedButtonIndex + 4 < self.menuButtons.count) {
self.selectedButtonIndex += 4;
[self updateSelectedButton];
}
}
- (void)activateSelected
{
if (self.selectedButtonIndex >= 0 && self.selectedButtonIndex < self.menuButtons.count) {
UIButton *button = self.menuButtons[self.selectedButtonIndex];
if (button.enabled) {
[button sendActionsForControlEvents:UIControlEventTouchUpInside];
}
}
}
- (void)updateSelectedButton
{
for (NSInteger i = 0; i < self.menuButtons.count; i++) {
UIButton *button = self.menuButtons[i];
if (i == self.selectedButtonIndex) {
button.backgroundColor = [UIColor colorWithWhite:0.5 alpha:0.3];
button.layer.borderWidth = 2.0;
button.layer.borderColor = [UIColor systemBlueColor].CGColor;
button.layer.cornerRadius = 8.0;
} else {
button.backgroundColor = [UIColor clearColor];
button.layer.borderWidth = 0.0;
button.layer.borderColor = [UIColor clearColor].CGColor;
}
}
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[self becomeFirstResponder];
}
@end