jfkeys: add event processing to jfkeys

This requires jfkeys to _get_ the events, which needs to be done
manually by its owner to some degree (in gintctl, gscreen handles it).

Currently there are just 6 values 0..5 for F1..F6, but future expansion
for rotating menus with more than 6 entries and nested menus might add
to this set.
This commit is contained in:
Lephenixnoir 2024-09-06 16:19:01 +02:00
parent 93eb0df38a
commit f28d7a9cb8
No known key found for this signature in database
GPG key ID: 1BBA026E13FC0495
3 changed files with 61 additions and 25 deletions

View file

@ -39,7 +39,7 @@
* "/NAME" for a menu key;
* ".NAME" for an entry key;
* "@NAME" for an action key;
" "#NAME" for a special key.
* "#NAME" for a special key.
The names are separated by semicolons, eg. "/F1;;/F3;.F4;@F5;#F6". Several
sets of function keys can be defined if separated by a '|' character. For
@ -51,7 +51,11 @@
with its 128x64 resolution, the convention is that the image is 128x8, and
key #i is positioned at x = 21i+2 with width 19. The equivalent of "|"-
separated levels is allowed by stacking up rows of keys (in which case the
image is of height 9n-1 for n rows). */
image is of height 9n-1 for n rows).
jkfeys will gobble keyboard events for F1..F6 and emit JFKEYS_TRIGGERED
events instead. However, in general jfkeys doesn't have keyboard focus, so
you have to give the events manually. */
typedef struct {
jwidget widget;
int8_t level;
@ -72,6 +76,9 @@ typedef struct {
} jfkeys;
/* Events */
extern uint16_t JFKEYS_TRIGGERED;
/* jfkeys_create2(): Create a set of function keys
Both the image and text specification are provided; one of them should

View file

@ -203,7 +203,6 @@ bool jwidget_event(void *w, jevent e);
gets the functions `jpainted_poly_csize` and `jpainted_poly_render` from
context, registers the type at startup and provides `jpainted_type_id` for
the widget creation function. */
#define J_DEFINE_WIDGET(NAME, ...) \
static int NAME##_type_id = -1; \
J_REPEAT(J_DEFINE_WIDGET_POLY_PROTO, (NAME), __VA_ARGS__) \
@ -215,10 +214,25 @@ bool jwidget_event(void *w, jevent e);
static void j_register_##NAME(void) { \
NAME##_type_id = j_register_widget(&type_##NAME); \
}
#define J_DEFINE_WIDGET_POLY(NAME, METHOD) \
.METHOD = NAME##_poly_##METHOD,
#define J_DEFINE_WIDGET_POLY_PROTO(NAME, METHOD) \
extern jwidget_poly_##METHOD##_t NAME##_poly_##METHOD;
/* Helper macro for defining new events. Each parameter is an event name to
define, e.g.
```
J_DEFINE_EVENTS(MYWIDGET_EVENT1, MYWIDGET_EVENT2, MYWIDGET_EVENT3)
``` */
#define J_DEFINE_EVENTS(...) \
uint16_t __VA_ARGS__; \
__attribute__((constructor)) \
static void J_DEFINE_EVENTS_NAME(__COUNTER__)(void) { \
J_REPEAT(J_DEFINE_EVENTS_INIT, (), __VA_ARGS__) \
}
#define J_DEFINE_EVENTS_NAME2(COUNTER) _j_init_##COUNTER
#define J_DEFINE_EVENTS_NAME(COUNTER) J_DEFINE_EVENTS_NAME2(COUNTER)
#define J_DEFINE_EVENTS_INIT(EVENT) EVENT = j_register_event();
#endif /* _J_JWIDGET_API */

View file

@ -4,8 +4,8 @@
#include <gint/std/stdlib.h>
#include <gint/std/string.h>
/* Type identified for jfkeys */
static int jfkeys_type_id = -1;
J_DEFINE_WIDGET(jfkeys, csize, render, event)
J_DEFINE_EVENTS(JFKEYS_TRIGGERED)
extern font_t j_font_fkeys_fx;
@ -89,14 +89,14 @@ static char const *get_label(char const *level, int key, size_t *len)
// Polymorphic widget operations
//---
static void jfkeys_poly_csize(void *f0)
void jfkeys_poly_csize(void *f0)
{
jfkeys *f = f0;
f->widget.w = DWIDTH;
f->widget.h = JFKEYS_HEIGHT;
}
static void jfkeys_poly_render(void *f0, int base_x, int y)
void jfkeys_poly_render(void *f0, int base_x, int y)
{
jfkeys *f = f0;
@ -156,6 +156,38 @@ static void jfkeys_poly_render(void *f0, int base_x, int y)
dfont(old_font);
}
bool jfkeys_poly_event(void *f0, jevent e)
{
jfkeys *f = f0;
jevent te;
te.source = f;
te.type = JFKEYS_TRIGGERED;
if(e.type == JWIDGET_KEY && e.key.type == KEYEV_DOWN) {
int fun = keycode_function(e.key.key);
if(fun >= 0) {
te.data = fun - 1;
jwidget_emit(f, te);
return true;
}
#if GINT_HW_CP
static uint8_t const CP_Fk[6] = {
KEY_EQUALS, KEY_X, KEY_Y, KEY_Z, KEY_CARET, KEY_DIV };
for(int i = 0; i < 6; i++) {
if(e.key.key == CP_Fk[i]) {
te.data = i;
jwidget_emit(f, te);
return true;
}
}
#endif
}
return jwidget_poly_event(f, e);
}
int jfkeys_level(jfkeys *f)
{
return f->level;
@ -193,20 +225,3 @@ void jfkeys_set_font(jfkeys *keys, font_t const *font)
{
keys->font = font;
}
/* jfkeys type definition */
static jwidget_poly type_jfkeys = {
.name = "jfkeys",
.csize = jfkeys_poly_csize,
.layout = NULL,
.render = jfkeys_poly_render,
.event = NULL,
.destroy = NULL,
};
/* Type registration */
__attribute__((constructor))
static void j_register_jfkeys(void)
{
jfkeys_type_id = j_register_widget(&type_jfkeys);
}