mirror of
https://git.planet-casio.com/Lephenixnoir/JustUI.git
synced 2025-06-03 01:15:15 +02:00
jscene, jlist: start handling touch events
This commit is contained in:
parent
cd73b2ea6f
commit
50df5fe37c
6 changed files with 72 additions and 1 deletions
|
@ -16,6 +16,6 @@
|
|||
#endif
|
||||
|
||||
/* Set to 1 to enable a touch-following widget inspector. */
|
||||
#define J_CONFIG_TOUCH_INSPECTOR (J_CONFIG_TOUCH && 1)
|
||||
#define J_CONFIG_TOUCH_INSPECTOR (J_CONFIG_TOUCH && 0)
|
||||
|
||||
#endif /* _JUSTUI_CONFIG */
|
||||
|
|
|
@ -77,6 +77,8 @@ typedef struct jlist {
|
|||
|
||||
/* Currently selected item, -1 if none */
|
||||
int cursor;
|
||||
/* Index of the currently touch-clicked item, -1 none */
|
||||
int touch_cursor;
|
||||
/* User data pointer */
|
||||
void *user;
|
||||
|
||||
|
|
|
@ -434,6 +434,9 @@ void jwidget_render(void *w, int x, int y);
|
|||
while the widget has focus, the focus will be lost. */
|
||||
void jwidget_set_focus_policy(void *w, jwidget_focus_policy_t fp);
|
||||
|
||||
/* Check whether a widget accepts focus. */
|
||||
bool jwidget_accepts_focus(void *w);
|
||||
|
||||
/* Check whether a widget is currently focused within its surrounding scope. */
|
||||
GINLINE static bool jwidget_has_focus(void *w)
|
||||
{
|
||||
|
|
49
src/jlist.c
49
src/jlist.c
|
@ -1,6 +1,7 @@
|
|||
#include <justui/jwidget.h>
|
||||
#include <justui/jwidget-api.h>
|
||||
#include <justui/jlist.h>
|
||||
#include <justui/config.h>
|
||||
#include "util.h"
|
||||
|
||||
#include <gint/display.h>
|
||||
|
@ -38,6 +39,7 @@ jlist *jlist_create(jlist_item_info_function info_function,
|
|||
l->info_function = info_function;
|
||||
l->paint_function = paint_function;
|
||||
l->cursor = -1;
|
||||
l->touch_cursor = -1;
|
||||
l->user = NULL;
|
||||
return l;
|
||||
}
|
||||
|
@ -165,6 +167,25 @@ jrect jlist_selected_region(jlist *l)
|
|||
// Polymorphic widget operations
|
||||
//---
|
||||
|
||||
static int item_index_at(void *l0, int ly)
|
||||
{
|
||||
jlist *l = l0;
|
||||
int y = 0;
|
||||
|
||||
for(int i = 0; i < l->item_count; i++) {
|
||||
jlist_item_info *info = &l->items[i];
|
||||
int h = info->delegate
|
||||
? jwidget_full_height(info->delegate)
|
||||
: info->natural_height;
|
||||
|
||||
if(ly >= y && ly < y + h)
|
||||
return i;
|
||||
y += h;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void jlist_poly_csize(void *l0)
|
||||
{
|
||||
jlist *l = l0;
|
||||
|
@ -224,10 +245,38 @@ static bool jlist_poly_event(void *l0, jevent e)
|
|||
{
|
||||
jlist *l = l0;
|
||||
|
||||
if(e.type == JWIDGET_FOCUS_CHANGED && !jwidget_has_active_focus(l))
|
||||
l->touch_cursor = -1;
|
||||
|
||||
if(e.type != JWIDGET_KEY || l->cursor < 0)
|
||||
return false;
|
||||
|
||||
key_event_t ev = e.key;
|
||||
|
||||
#if J_CONFIG_TOUCH
|
||||
if(ev.type == KEYEV_TOUCH_DOWN || ev.type == KEYEV_TOUCH_DRAG ||
|
||||
ev.type == KEYEV_TOUCH_UP) {
|
||||
int lx = ev.x - jwidget_absolute_content_x(l);
|
||||
int ly = ev.y - jwidget_absolute_content_y(l);
|
||||
uint w = jwidget_content_width(l);
|
||||
uint h = jwidget_content_height(l);
|
||||
int index = ((uint)lx < w && (uint)ly < h) ? item_index_at(l, ly) : -1;
|
||||
|
||||
if(ev.type == KEYEV_TOUCH_DOWN && index >= 0) {
|
||||
jlist_select(l, index);
|
||||
l->touch_cursor = jlist_selected_item(l);
|
||||
}
|
||||
if(ev.type == KEYEV_TOUCH_DRAG && index >= 0)
|
||||
jlist_select(l, index);
|
||||
if(ev.type == KEYEV_TOUCH_UP && index >= 0 && index == l->touch_cursor) {
|
||||
jevent e = { .type = JLIST_ITEM_TRIGGERED,
|
||||
.data = l->touch_cursor };
|
||||
jwidget_emit(l, e);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(ev.type != KEYEV_DOWN && ev.type != KEYEV_HOLD)
|
||||
return false;
|
||||
|
||||
|
|
10
src/jscene.c
10
src/jscene.c
|
@ -283,6 +283,16 @@ void jscene_show_and_focus(jscene *scene, void *w0)
|
|||
|
||||
bool jscene_process_key_event(jscene *scene, key_event_t event)
|
||||
{
|
||||
/* If the event is a touch down, start by moving the focus. */
|
||||
#if J_CONFIG_TOUCH
|
||||
if(event.type == KEYEV_TOUCH_DOWN) {
|
||||
jwidget *w = jscene_widget_at(scene, event.x - scene->x,
|
||||
event.y - scene->y, true);
|
||||
if(w && jwidget_accepts_focus(w))
|
||||
jscene_set_focused_widget(scene, w);
|
||||
}
|
||||
#endif
|
||||
|
||||
jwidget *candidate = jscene_focused_widget(scene);
|
||||
jevent e = { .type = JWIDGET_KEY, .key = event };
|
||||
|
||||
|
|
|
@ -753,6 +753,13 @@ void jwidget_set_focus_policy(void *w0, jwidget_focus_policy_t fp)
|
|||
w->focus_policy = fp;
|
||||
}
|
||||
|
||||
bool jwidget_accepts_focus(void *w0)
|
||||
{
|
||||
J_CAST(w)
|
||||
return w->focus_policy == J_FOCUS_POLICY_SCOPE ||
|
||||
w->focus_policy == J_FOCUS_POLICY_ACCEPT;
|
||||
}
|
||||
|
||||
static void notify_focus_changed(jwidget *w)
|
||||
{
|
||||
jevent e;
|
||||
|
|
Loading…
Add table
Reference in a new issue