Implement input component
It is required to redirect keyboard input (both physical or not) when a GUI line edit is focused. This means other components cannot be activated on key presses. Therefore, this new component is meant as a higher-level abstraction compared to the `keyboard`/`pad`/`mouse` components, which: - Implements the same APIs provided by `keyboard`, `mouse` and `pad`. - Returns the same results as the APIs above if no GUI element is focused, no input otherwise. Note: replacing calls to `keyboard`/`pad`/`mouse` with `input` will be implemented in a future commit.
This commit is contained in:
parent
b8d3eff412
commit
684587a3c3
|
@ -10,6 +10,7 @@ set(components
|
||||||
gfx
|
gfx
|
||||||
gui
|
gui
|
||||||
header
|
header
|
||||||
|
input
|
||||||
instance
|
instance
|
||||||
keyboard
|
keyboard
|
||||||
menu
|
menu
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
add_library(input
|
||||||
|
"src/input.c"
|
||||||
|
)
|
||||||
|
target_include_directories(input PUBLIC "inc")
|
||||||
|
target_link_libraries(input PUBLIC keyboard mouse pad peripheral)
|
|
@ -0,0 +1,56 @@
|
||||||
|
#ifndef INPUT_H
|
||||||
|
#define INPUT_H
|
||||||
|
|
||||||
|
#include <keyboard.h>
|
||||||
|
#include <mouse.h>
|
||||||
|
#include <pad.h>
|
||||||
|
#include <peripheral.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef void (*input_ch)(char ch, void *user);
|
||||||
|
typedef void (*input_erase)(void *user);
|
||||||
|
|
||||||
|
struct input
|
||||||
|
{
|
||||||
|
input_ch cb;
|
||||||
|
input_erase erase;
|
||||||
|
void *user;
|
||||||
|
unsigned char t;
|
||||||
|
bool repeat;
|
||||||
|
struct keyboard_combo prev;
|
||||||
|
};
|
||||||
|
|
||||||
|
void input_update(struct input *in, const union peripheral *p);
|
||||||
|
int input_render(const struct input *in, const union peripheral *p);
|
||||||
|
bool input_keyboard_justpressed(const struct input *in,
|
||||||
|
const struct keyboard *k,
|
||||||
|
const struct keyboard_combo *c);
|
||||||
|
bool input_keyboard_pressed(const struct input *in,
|
||||||
|
const struct keyboard *k,
|
||||||
|
const struct keyboard_combo *c);
|
||||||
|
bool input_keyboard_justreleased(const struct input *in,
|
||||||
|
const struct keyboard *k,
|
||||||
|
const struct keyboard_combo *c);
|
||||||
|
bool input_pad_pressed(const struct input *in, const struct pad *p,
|
||||||
|
enum pad_key k);
|
||||||
|
bool input_pad_justpressed(const struct input *in, const struct pad *p,
|
||||||
|
enum pad_key k);
|
||||||
|
bool input_pad_released(const struct input *in, const struct pad *p,
|
||||||
|
enum pad_key k);
|
||||||
|
bool input_mouse_pressed(const struct input *in, const struct mouse *m,
|
||||||
|
enum mouse_button b);
|
||||||
|
bool input_mouse_justpressed(const struct input *in, const struct mouse *m,
|
||||||
|
enum mouse_button b);
|
||||||
|
bool input_mouse_justreleased(const struct input *in, const struct mouse *m,
|
||||||
|
enum mouse_button b);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* INPUT_H */
|
|
@ -0,0 +1,175 @@
|
||||||
|
#include <input.h>
|
||||||
|
#include <keyboard.h>
|
||||||
|
#include <mouse.h>
|
||||||
|
#include <pad.h>
|
||||||
|
#include <peripheral.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
static void send_input(struct input *const in, const struct keyboard *const k,
|
||||||
|
const enum keyboard_key key)
|
||||||
|
{
|
||||||
|
if (key != KEYBOARD_KEY_NONE)
|
||||||
|
{
|
||||||
|
switch (key)
|
||||||
|
{
|
||||||
|
case KEYBOARD_KEY_BACKSPACE:
|
||||||
|
in->erase(in->user);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KEYBOARD_KEY_ESC:
|
||||||
|
*in = (const struct input){0};
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
const char ch = keyboard_to_char(k, key);
|
||||||
|
|
||||||
|
if (isprint(ch))
|
||||||
|
in->cb(ch, in->user);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void update_keyboard(struct input *const in,
|
||||||
|
const struct keyboard *const k)
|
||||||
|
{
|
||||||
|
struct keyboard_combo c;
|
||||||
|
|
||||||
|
if (keyboard_any_justpressed(k, &c))
|
||||||
|
for (size_t i = 0; i < sizeof c.keys / sizeof *c.keys; i++)
|
||||||
|
send_input(in, k, c.keys[i]);
|
||||||
|
else if (keyboard_any_pressed(k, &c))
|
||||||
|
{
|
||||||
|
if (memcmp(&c, &in->prev, sizeof c))
|
||||||
|
{
|
||||||
|
in->repeat = false;
|
||||||
|
in->t = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
enum {LONG_INTERVAL = 25, SHORT_INTERVAL = 2};
|
||||||
|
|
||||||
|
if (!in->repeat)
|
||||||
|
{
|
||||||
|
if (++in->t >= LONG_INTERVAL)
|
||||||
|
in->repeat = true;
|
||||||
|
}
|
||||||
|
else if (++in->t >= SHORT_INTERVAL)
|
||||||
|
{
|
||||||
|
for (size_t i = 0;
|
||||||
|
i < sizeof c.keys / sizeof *c.keys; i++)
|
||||||
|
send_input(in, k, c.keys[i]);
|
||||||
|
|
||||||
|
in->t = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
in->prev = c;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
in->repeat = false;
|
||||||
|
in->t = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void input_update(struct input *const in, const union peripheral *const p)
|
||||||
|
{
|
||||||
|
switch (p->common.type)
|
||||||
|
{
|
||||||
|
case PERIPHERAL_TYPE_KEYBOARD_MOUSE:
|
||||||
|
if (in->cb && in->erase)
|
||||||
|
update_keyboard(in, &p->kbm.keyboard);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PERIPHERAL_TYPE_TOUCH:
|
||||||
|
/* Fall through. */
|
||||||
|
case PERIPHERAL_TYPE_PAD:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int input_render(const struct input *const in, const union peripheral *const p)
|
||||||
|
{
|
||||||
|
switch (p->common.type)
|
||||||
|
{
|
||||||
|
case PERIPHERAL_TYPE_KEYBOARD_MOUSE:
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case PERIPHERAL_TYPE_TOUCH:
|
||||||
|
/* Fall through. */
|
||||||
|
case PERIPHERAL_TYPE_PAD:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool input_keyboard_justpressed(const struct input *const in,
|
||||||
|
const struct keyboard *const k,
|
||||||
|
const struct keyboard_combo *const c)
|
||||||
|
{
|
||||||
|
return in->cb ? false : keyboard_justpressed(k, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool input_keyboard_pressed(const struct input *const in,
|
||||||
|
const struct keyboard *const k,
|
||||||
|
const struct keyboard_combo *const c)
|
||||||
|
{
|
||||||
|
return in->cb ? false : keyboard_pressed(k, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool input_keyboard_justreleased(const struct input *const in,
|
||||||
|
const struct keyboard *const k,
|
||||||
|
const struct keyboard_combo *const c)
|
||||||
|
{
|
||||||
|
return in->cb ? false : keyboard_justreleased(k, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool input_pad_pressed(const struct input *const in,
|
||||||
|
const struct pad *const p,
|
||||||
|
const enum pad_key k)
|
||||||
|
{
|
||||||
|
return in->cb ? false : pad_pressed(p, k);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool input_pad_justpressed(const struct input *const in,
|
||||||
|
const struct pad *const p,
|
||||||
|
const enum pad_key k)
|
||||||
|
{
|
||||||
|
return in->cb ? false : pad_justpressed(p, k);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool input_pad_released(const struct input *const in,
|
||||||
|
const struct pad *const p,
|
||||||
|
const enum pad_key k)
|
||||||
|
{
|
||||||
|
return in->cb ? false : pad_released(p, k);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool input_mouse_pressed(const struct input *const in,
|
||||||
|
const struct mouse *const m,
|
||||||
|
const enum mouse_button b)
|
||||||
|
{
|
||||||
|
return in->cb ? false : mouse_pressed(m, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool input_mouse_justpressed(const struct input *const in,
|
||||||
|
const struct mouse *const m,
|
||||||
|
const enum mouse_button b)
|
||||||
|
{
|
||||||
|
return in->cb ? false : mouse_justpressed(m, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool input_mouse_justreleased(const struct input *const in,
|
||||||
|
const struct mouse *const m,
|
||||||
|
const enum mouse_button b)
|
||||||
|
{
|
||||||
|
return in->cb ? false : mouse_justreleased(m, b);
|
||||||
|
}
|
Loading…
Reference in New Issue