diff --git a/include/justui/jscene.h b/include/justui/jscene.h index bfb979b..47fbf19 100644 --- a/include/justui/jscene.h +++ b/include/justui/jscene.h @@ -87,12 +87,13 @@ void *jscene_focused_widget(jscene *scene); The selected widget, obviously, must be a descendant of the scene. */ void jscene_set_focused_widget(jscene *scene, void *widget); -/* jscene_process_key(): Send a downwards key event to the focused widget +/* jscene_process_key_event(): Send a key event to the focused widget Returns true if the event was accepted, false if it was ignored. */ -bool jscene_process_key(jscene *scene, key_event_t event); +bool jscene_process_key_event(jscene *scene, key_event_t event); -/* jscene_process_event(): Send a downards GUI event to the focused widget */ -// bool jscene_process_event(jscene *scene, jevent event); +/* jscene_process_event(): Bubble an event up from its source + Returns true if the event was accepted along the way, false if ignored. */ +bool jscene_process_event(jscene *scene, jevent event); /* jscene_run(): Run a scene's main loop diff --git a/src/jscene.c b/src/jscene.c index 275bff0..ac21ceb 100644 --- a/src/jscene.c +++ b/src/jscene.c @@ -136,7 +136,6 @@ void jscene_set_focused_widget(jscene *s, void *w0) if(w) jwidget_event(w, (jevent){ .type = JWIDGET_FOCUS_IN }); } -/* jscene_process_event(): Send an event to the focused widget */ bool jscene_process_key_event(jscene *scene, key_event_t event) { jwidget *candidate = scene->focus; @@ -150,6 +149,19 @@ bool jscene_process_key_event(jscene *scene, key_event_t event) return false; } +bool jscene_process_event(GUNUSED jscene *scene, jevent event) +{ + if(!event.source) return false; + jwidget *candidate = ((jwidget *)event.source)->parent; + + while(candidate) { + if(jwidget_event(candidate, event)) return true; + candidate = candidate->parent; + } + + return false; +} + /* jscene_run(): Run a scene's main loop */ jevent jscene_run(jscene *s) { @@ -166,7 +178,7 @@ jevent jscene_run(jscene *s) /* Queued GUI events */ e = jscene_read_event(s); - if(e.type != JSCENE_NONE) break; + if(e.type != JSCENE_NONE && !jscene_process_event(s, e)) break; /* Queued keyboard events */ key_event_t k = keydev_read(d);