Support open/closed apple tap events from touch keyboard

This commit is contained in:
Aaron Culliney 2019-11-10 15:30:58 -08:00
parent c0fd258c40
commit 5aa691815b
2 changed files with 64 additions and 10 deletions

View File

@ -123,11 +123,6 @@ static inline void _press_key(subvariant_s *subvariant, keypad_press_t pressIdx)
++(subvariant->keyPressCount);
}
// No-op callback
static void touchkpad_nopCallback(uint8_t textFlashCounter) {
(void)textFlashCounter;
}
// End-of-video-frame callback (handling tap delay and auto-strobe)
static void touchkpad_frameCallback(uint8_t textFlashCounter) {
@ -224,7 +219,7 @@ static void touchkpad_frameCallback(uint8_t textFlashCounter) {
if ((kpad.axis.currEventType == TOUCH_UP) && (kpad.butt.currEventType == TOUCH_UP)) {
// all touch up occurred -- unlatch the callback
TOUCH_JOY_LOG("\t\t+++kpad callback done");
kpad.frameCallback = touchkpad_nopCallback;
kpad.frameCallback = NULL;
kpad.axis.scancodes[REPEAT_IDX_A] = -1;
kpad.axis.scancodes[REPEAT_IDX_B] = -1;
kpad.butt.scancodes[REPEAT_IDX_A] = -1;

View File

@ -41,6 +41,8 @@
#define KBD_OBJ_W GL_MODEL_MAX // model width fits screen
#define KBD_OBJ_H_LANDSCAPE GL_MODEL_MAX
#define KBD_BUTTON_HOLD_FRAMES 7 // >= 1/10 sec (seems reasonable for AppleSoft BASIC sampling ;)
typedef enum keyboard_variant_t {
KBD_VARIANT_DEFAULT=0,
KBD_VARIANT_LOWERCASE,
@ -122,6 +124,8 @@ static struct {
static struct {
GLModel *model;
video_frame_callback_fn frameCallback;
GLfloat modelHeight;
GLfloat modelSkewY;
bool modelDirty;
@ -141,6 +145,9 @@ static struct {
struct timespec timingBegin;
uint8_t button0Count;
uint8_t button1Count;
bool prefsChanged;
} kbd = { 0 };
@ -149,6 +156,54 @@ static void gltouchkbd_applyPrefs(void);
// ----------------------------------------------------------------------------
// Misc internal methods
// End-of-video-frame callback ...
//
// NOTE : Currently this is only handling the joystick buttons being pressed for a set number of frames.
//
// But could we augment the touch keyboard to implement full auto-repeat functionality (following a similar state machine to
// gltouchjoy_kpad variant)?
//
// At present time, the show-stopper for auto-repeat is that it breaks fundamental existing UI/UX:
//
// - It is possible now with this touch keyboard to place a thumb down indefinitely, keeping the keyboard lit up rather than
// invisible, while you then hunt for the key you want to select on the touch up. This is fundamental UI/UX that has always
// been supported, and auto-repeat functionality directly challenges that!
//
// - Presumably an auto-repeat keyboard would press the key tapped on touch down (possibly after a delay to detect either
// long-press or motion beyond the x/y threshold of the touch down key) ... and this would break the existing "hold-and-hunt"
// functionality.
//
// - It's worth noting that auto-repeat is implicitly handled by hardware keyboards on all major platforms we compile on.
// Presumably if auto-repeat is important, then just use a hardware keyboard...
//
// - What about a special gesture or special sticky (AUTO-LOCK) key that engages the auto-repeat behavior?
//
static void touchkbd_frameCallback(uint8_t textFlashCounter) {
// When activated, this is called every video frame -- ~16.688 millis
ASSERT_ON_CPU_THREAD();
if (kbd.button0Count) {
--kbd.button0Count;
}
if (!kbd.button0Count) {
run_args.joy_button0 = 0x0;
}
if (kbd.button1Count) {
--kbd.button1Count;
}
if (!kbd.button1Count) {
run_args.joy_button1 = 0x0;
}
if (!kbd.button0Count && !kbd.button1Count) {
// unlatch frame callback ...
kbd.frameCallback = NULL;
}
}
#warning FIXME TODO ... make this a generic GLModelHUDElement function
static void _rerender_character(int col, int row) {
GLModelHUDElement *hudKeyboard = (GLModelHUDElement *)(kbd.model->custom);
@ -407,13 +462,15 @@ static inline int64_t _tap_key_at_point(float x, float y) {
break;
case MOUSETEXT_OPENAPPLE:
run_args.joy_button0 = run_args.joy_button0 ? 0x0 : 0x80;
scancode = SCODE_L_ALT;
run_args.joy_button0 = 0x80;
kbd.button0Count = KBD_BUTTON_HOLD_FRAMES;
kbd.frameCallback = touchkbd_frameCallback;
break;
case MOUSETEXT_CLOSEDAPPLE:
run_args.joy_button1 = run_args.joy_button1 ? 0x0 : 0x80;
scancode = SCODE_R_ALT;
run_args.joy_button1 = 0x80;
kbd.button1Count = KBD_BUTTON_HOLD_FRAMES;
kbd.frameCallback = touchkbd_frameCallback;
break;
case MOUSETEXT_CURSOR0:
@ -1146,6 +1203,8 @@ static void _init_gltouchkbd(void) {
prefs_registerListener(PREF_DOMAIN_KEYBOARD, &gltouchkbd_prefsChanged);
prefs_registerListener(PREF_DOMAIN_TOUCHSCREEN, &gltouchkbd_prefsChanged);
prefs_registerListener(PREF_DOMAIN_INTERFACE, &gltouchkbd_prefsChanged);
video_registerFrameCallback(&kbd.frameCallback);
}
static __attribute__((constructor)) void __init_gltouchkbd(void) {