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 a menu key;
* ".NAME" for an entry key; * ".NAME" for an entry key;
* "@NAME" for an action 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 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 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 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 "|"- 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 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 { typedef struct {
jwidget widget; jwidget widget;
int8_t level; int8_t level;
@ -72,6 +76,9 @@ typedef struct {
} jfkeys; } jfkeys;
/* Events */
extern uint16_t JFKEYS_TRIGGERED;
/* jfkeys_create2(): Create a set of function keys /* jfkeys_create2(): Create a set of function keys
Both the image and text specification are provided; one of them should 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 gets the functions `jpainted_poly_csize` and `jpainted_poly_render` from
context, registers the type at startup and provides `jpainted_type_id` for context, registers the type at startup and provides `jpainted_type_id` for
the widget creation function. */ the widget creation function. */
#define J_DEFINE_WIDGET(NAME, ...) \ #define J_DEFINE_WIDGET(NAME, ...) \
static int NAME##_type_id = -1; \ static int NAME##_type_id = -1; \
J_REPEAT(J_DEFINE_WIDGET_POLY_PROTO, (NAME), __VA_ARGS__) \ 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) { \ static void j_register_##NAME(void) { \
NAME##_type_id = j_register_widget(&type_##NAME); \ NAME##_type_id = j_register_widget(&type_##NAME); \
} }
#define J_DEFINE_WIDGET_POLY(NAME, METHOD) \ #define J_DEFINE_WIDGET_POLY(NAME, METHOD) \
.METHOD = NAME##_poly_##METHOD, .METHOD = NAME##_poly_##METHOD,
#define J_DEFINE_WIDGET_POLY_PROTO(NAME, METHOD) \ #define J_DEFINE_WIDGET_POLY_PROTO(NAME, METHOD) \
extern jwidget_poly_##METHOD##_t NAME##_poly_##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 */ #endif /* _J_JWIDGET_API */

View file

@ -4,8 +4,8 @@
#include <gint/std/stdlib.h> #include <gint/std/stdlib.h>
#include <gint/std/string.h> #include <gint/std/string.h>
/* Type identified for jfkeys */ J_DEFINE_WIDGET(jfkeys, csize, render, event)
static int jfkeys_type_id = -1; J_DEFINE_EVENTS(JFKEYS_TRIGGERED)
extern font_t j_font_fkeys_fx; 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 // Polymorphic widget operations
//--- //---
static void jfkeys_poly_csize(void *f0) void jfkeys_poly_csize(void *f0)
{ {
jfkeys *f = f0; jfkeys *f = f0;
f->widget.w = DWIDTH; f->widget.w = DWIDTH;
f->widget.h = JFKEYS_HEIGHT; 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; jfkeys *f = f0;
@ -156,6 +156,38 @@ static void jfkeys_poly_render(void *f0, int base_x, int y)
dfont(old_font); 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) int jfkeys_level(jfkeys *f)
{ {
return f->level; return f->level;
@ -193,20 +225,3 @@ void jfkeys_set_font(jfkeys *keys, font_t const *font)
{ {
keys->font = 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);
}