Changeset View
Standalone View
src/lib/elementary/efl_ui_clickable.c
- This file was added.
1 | #ifdef HAVE_CONFIG_H | ||||
---|---|---|---|---|---|
2 | # include <config.h> | ||||
3 | #endif | ||||
4 | | ||||
5 | #define EFL_UI_CLICKABLE_PROTECTED 1 | ||||
6 | | ||||
7 | #include <Efl_Ui.h> | ||||
8 | #include "elm_priv.h" | ||||
9 | | ||||
10 | typedef struct { | ||||
11 | Eina_Bool pressed; | ||||
12 | int pressed_before; | ||||
13 | Efl_Loop_Timer *timer; | ||||
14 | double clicked_last_time; | ||||
15 | } Button_State; | ||||
16 | | ||||
17 | typedef struct { | ||||
18 | Button_State state[3]; | ||||
19 | } Efl_Ui_Clickable_Data; | ||||
20 | | ||||
21 | #define MY_CLASS EFL_UI_CLICKABLE_MIXIN | ||||
22 | | ||||
23 | #define DOUBLE_CLICK_TIME ((double)0.1) //in seconds | ||||
24 | #define LONGPRESS_TIMEOUT ((double)1.0) //in seconds | ||||
segfaultxavi: A comment explaining what are these defines, including the units? Pleeeez? | |||||
Done ReplyWe measure *everything* in efl in seconds ... + this is a double. i don't think anyone will measure ms in doubles ... bu5hm4n: We measure *everything* in efl in seconds ... + this is a double. i don't think anyone will… | |||||
25 | | ||||
26 | static void | ||||
27 | _timer_longpress(void *data, const Efl_Event *ev) | ||||
28 | { | ||||
29 | Button_State *state; | ||||
30 | Efl_Ui_Clickable_Data *pd = efl_data_scope_get(data, MY_CLASS); | ||||
31 | | ||||
32 | for (int i = 0; i < 3; ++i) | ||||
33 | { | ||||
34 | state = &pd->state[i]; | ||||
35 | if (state->timer == ev->object) | ||||
36 | { | ||||
37 | efl_del(state->timer); | ||||
38 | state->timer = NULL; | ||||
39 | efl_event_callback_call(data, EFL_UI_EVENT_LONGPRESSED, &i); | ||||
40 | } | ||||
41 | } | ||||
42 | } | ||||
43 | | ||||
44 | EOLIAN static void | ||||
45 | _efl_ui_clickable_press(Eo *obj EINA_UNUSED, Efl_Ui_Clickable_Data *pd, unsigned int button) | ||||
46 | { | ||||
47 | Button_State *state; | ||||
48 | EINA_SAFETY_ON_FALSE_RETURN(button < 3); | ||||
49 | if (pd->state[button].pressed) return; | ||||
50 | | ||||
Done ReplyI'd feel safer if you check first if state->timer is not NULL. Users of this mixin might call you twice without calling _unpress... segfaultxavi: I'd feel safer if you check first if `state->timer` is not NULL. Users of this mixin might call… | |||||
51 | INF("Widget %s,%p is pressed(%d)", efl_class_name_get(obj), obj, button); | ||||
Done ReplyThis interval (1 second) is hardcoded here? shouldn't it be #defined at the top of the file, or be a configurable value? segfaultxavi: This interval (1 second) is hardcoded here? shouldn't it be #defined at the top of the file, or… | |||||
52 | | ||||
53 | state = &pd->state[button]; | ||||
54 | EINA_SAFETY_ON_FALSE_RETURN(!state->timer); | ||||
55 | | ||||
56 | state->pressed = EINA_TRUE; | ||||
57 | state->timer = efl_add(EFL_LOOP_TIMER_CLASS, obj, | ||||
zmikeUnsubmitted Done ReplyThis should also add a mouse-out event on the object and terminate the longpress timer if it is reached. zmike: This should also add a mouse-out event on the object and terminate the longpress timer if it is… | |||||
bu5hm4nAuthorUnsubmitted Not Done ReplyMhm i am not so sure if i want to solve it that way, right now the clickable implementation only contains the state. No event handling code or so. I think i will keep it that way, and add another function to it. Which must be called when the longpress stuff etc. should be canceled bu5hm4n: Mhm i am not so sure if i want to solve it that way, right now the clickable implementation… | |||||
58 | efl_loop_timer_interval_set(efl_added, LONGPRESS_TIMEOUT), | ||||
59 | efl_event_callback_add(efl_added, EFL_LOOP_TIMER_EVENT_TIMER_TICK, _timer_longpress, obj)); | ||||
60 | | ||||
61 | efl_event_callback_call(obj, EFL_UI_EVENT_PRESSED, &button); | ||||
62 | } | ||||
63 | | ||||
64 | EOLIAN static void | ||||
65 | _efl_ui_clickable_unpress(Eo *obj EINA_UNUSED, Efl_Ui_Clickable_Data *pd, unsigned int button) | ||||
66 | { | ||||
67 | Efl_Ui_Clickable_Clicked clicked; | ||||
68 | Button_State *state; | ||||
Done ReplyAgain, I do not like hardcoded values hidden in the code :) segfaultxavi: Again, I do not like hardcoded values hidden in the code :) | |||||
69 | EINA_SAFETY_ON_FALSE_RETURN(button < 3); | ||||
70 | if (!pd->state[button].pressed) return; | ||||
zmikeUnsubmitted Done ReplyUnpress events can occur on objects which weren't originally pressed, this check should be removed. zmike: Unpress events can occur on objects which weren't originally pressed, this check should be… | |||||
bu5hm4nAuthorUnsubmitted Done ReplyTrue. bu5hm4n: True. | |||||
71 | | ||||
72 | INF("Widget %s,%p is unpressed(%d)", efl_class_name_get(obj), obj, button); | ||||
73 | | ||||
74 | state = &pd->state[button]; | ||||
75 | | ||||
Done ReplyI'd feel safer if you checked first that this is not NULL, in case the user called _unpress twice. segfaultxavi: I'd feel safer if you checked first that this is not NULL, in case the user called _unpress… | |||||
76 | //eval if this is a repeated click | ||||
77 | if (state->clicked_last_time > 0.0 && ecore_time_unix_get() - state->clicked_last_time < DOUBLE_CLICK_TIME) | ||||
78 | state->pressed_before++; | ||||
79 | else | ||||
80 | state->pressed_before = 0; | ||||
81 | //reset state | ||||
82 | state->clicked_last_time = ecore_time_unix_get(); | ||||
83 | state->pressed = EINA_FALSE; | ||||
84 | if (state->timer) | ||||
85 | efl_del(state->timer); | ||||
86 | state->timer = NULL; | ||||
87 | | ||||
88 | //populate state | ||||
89 | efl_event_callback_call(obj, EFL_UI_EVENT_UNPRESSED, &button); | ||||
90 | clicked.repeated = state->pressed_before; | ||||
91 | clicked.button = button; | ||||
92 | if (button == 1) | ||||
zmikeUnsubmitted Done ReplyThis event should only occur if the object was previously pressed. zmike: This event should only occur if the object was previously pressed. | |||||
bu5hm4nAuthorUnsubmitted Done ReplyTrue. bu5hm4n: True. | |||||
93 | efl_event_callback_call(obj, EFL_UI_EVENT_CLICKED, &clicked); | ||||
94 | efl_event_callback_call(obj, EFL_UI_EVENT_CLICKED_ALL, &clicked); | ||||
95 | } | ||||
96 | #include "efl_ui_clickable.eo.c" |
A comment explaining what are these defines, including the units? Pleeeez?