diff --git a/apps/action.c b/apps/action.c index 5aeab25e1d..989313f41c 100644 --- a/apps/action.c +++ b/apps/action.c @@ -35,6 +35,10 @@ static intptr_t last_data = 0; static int last_action = ACTION_NONE; static bool repeated = false; +#ifdef HAVE_TOUCHPAD +static bool short_press = false; +#endif + #define REPEAT_WINDOW_TICKS HZ/10 static int last_action_tick = 0; @@ -132,7 +136,25 @@ static int get_action_worker(int context, int timeout, return ACTION_NONE; /* "safest" return value */ } last_context = context; - +#ifdef HAVE_TOUCHPAD + if (button&BUTTON_TOUCHPAD) + { + repeated = false; + short_press = false; + if (last_button&BUTTON_TOUCHPAD) + { + if ((button&BUTTON_REL) && + ((last_button&BUTTON_REPEAT)==0)) + { + short_press = true; + } + else if (button&BUTTON_REPEAT) + repeated = true; + } + last_button = button; + return ACTION_TOUCHPAD; + } +#endif #ifndef HAS_BUTTON_HOLD screen_has_lock = ((context&ALLOW_SOFTLOCK)==ALLOW_SOFTLOCK); if (screen_has_lock && (keys_locked == true)) @@ -250,3 +272,35 @@ int get_action_statuscode(int *button) ret |= ACTION_REPEAT; return ret; } + +#ifdef HAVE_TOUCHPAD +/* return BUTTON_NONE on error + BUTTON_REPEAT if repeated press + BUTTON_REL if its a short press + BUTTON_TOUCHPAD otherwise +*/ +int action_get_touchpad_press(short *x, short *y) +{ + static int last_data = 0; + int data; + if ((last_button&BUTTON_TOUCHPAD) == 0) + return BUTTON_NONE; + data = button_get_data(); + if (last_button&BUTTON_REL) + { + *x = (last_data&0xffff0000)>>16; + *y = (last_data&0xffff); + } + else + { + *x = (data&0xffff0000)>>16; + *y = (data&0xffff); + } + last_data = data; + if (repeated) + return BUTTON_REPEAT; + if (short_press) + return BUTTON_REL; + return BUTTON_NONE; +} +#endif diff --git a/apps/action.h b/apps/action.h index 9859c2c50c..c1c60c9b0b 100644 --- a/apps/action.h +++ b/apps/action.h @@ -78,6 +78,7 @@ enum { ACTION_NONE = BUTTON_NONE, ACTION_UNKNOWN, ACTION_REDRAW, /* returned if keys are locked and we splash()'ed */ + ACTION_TOUCHPAD, /* standard actions, use these first */ ACTION_STD_PREV, @@ -259,4 +260,13 @@ int get_action_statuscode(int *button); BUTTON_NONE or flagged with SYS_EVENT */ intptr_t get_action_data(void); +#ifdef HAVE_TOUCHPAD +/* return BUTTON_NONE on error + BUTTON_REPEAT if repeated press + BUTTON_REL if its a short press + BUTTON_TOUCHPAD otherwise +*/ +int action_get_touchpad_press(short *x, short *y); +#endif + #endif /* __ACTION_H__ */ diff --git a/apps/gui/list.c b/apps/gui/list.c index 2450720a13..feee1ec7a7 100644 --- a/apps/gui/list.c +++ b/apps/gui/list.c @@ -911,6 +911,81 @@ void gui_synclist_speak_item(struct gui_synclist * lists) extern intptr_t get_action_data(void); +#if defined(HAVE_TOUCHPAD) +unsigned gui_synclist_do_touchpad(struct gui_synclist * lists) +{ + struct gui_list *gui_list = &(lists->gui_list[SCREEN_MAIN]); + short x,y; + unsigned button = action_get_touchpad_press(&x, &y); + int line; + if (xdisplay->nb_lines - SHOW_LIST_TITLE; + if (nb_lines < gui_list->nb_items) + { + height = nb_lines * gui_list->display->char_height; + size = height*nb_lines / gui_list->nb_items; + new_selection = (y*(gui_list->nb_items-nb_lines))/(height-size); + gui_synclist_select_item(lists, new_selection); + nb_lines /= 2; + if (new_selection - gui_list->start_item > nb_lines) + { + new_selection = gui_list->start_item+nb_lines; + } + FOR_NB_SCREENS(line) + lists->gui_list[line].selected_item = new_selection; + return ACTION_REDRAW; + } + } + } + else + { + if (button != BUTTON_REL && button != BUTTON_REPEAT) + return ACTION_NONE; + /* title or statusbar is cancel */ + if (global_settings.statusbar) + { + if (y < STATUSBAR_HEIGHT && !SHOW_LIST_TITLE ) + return ACTION_STD_CANCEL; + y -= STATUSBAR_HEIGHT; + } + /* title goes up one level */ + if (SHOW_LIST_TITLE) + { + if (y < gui_list->display->char_height) + return ACTION_STD_CANCEL; + y -= gui_list->display->char_height; + } + /* pressing an item will select it. + pressing the selected item will "enter" it */ + line = y / gui_list->display->char_height; + if (line != gui_list->selected_item - gui_list->start_item) + gui_synclist_select_item(lists, gui_list->start_item+line); + + if (button == BUTTON_REPEAT) + return ACTION_STD_CONTEXT; + else + return ACTION_STD_OK; + } + return ACTION_NONE; +} +#endif + bool gui_synclist_do_button(struct gui_synclist * lists, unsigned *actionptr, enum list_wrap wrap) { @@ -950,6 +1025,11 @@ bool gui_synclist_do_button(struct gui_synclist * lists, } } #endif + +#if defined(HAVE_TOUCHPAD) + if (action == ACTION_TOUCHPAD) + action = *actionptr = gui_synclist_do_touchpad(lists); +#endif switch (wrap) { @@ -971,6 +1051,10 @@ bool gui_synclist_do_button(struct gui_synclist * lists, switch (action) { + case ACTION_REDRAW: + gui_synclist_draw(lists); + return true; + #ifdef HAVE_VOLUME_IN_LIST case ACTION_LIST_VOLUP: global_settings.volume += 2;