diff --git a/include/justui/jfkeys.h b/include/justui/jfkeys.h index 58f0442..4444a57 100644 --- a/include/justui/jfkeys.h +++ b/include/justui/jfkeys.h @@ -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 diff --git a/include/justui/jwidget-api.h b/include/justui/jwidget-api.h index 968842f..e3a9723 100644 --- a/include/justui/jwidget-api.h +++ b/include/justui/jwidget-api.h @@ -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 */ diff --git a/src/jfkeys.c b/src/jfkeys.c index b51cd12..d508071 100644 --- a/src/jfkeys.c +++ b/src/jfkeys.c @@ -4,8 +4,8 @@ #include #include -/* 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); -}