Skip to content

Commit 92b0b67

Browse files
committed
Unify widget callback mechanism
Previous design had widget-specific callbacks (button signals, scroll signals) scattered across different widgets, each managing its own closure storage. Now all widgets use a unified callback mechanism: - Single callback signature: (widget, event, closure) → result - Closure stored in twin_widget_t.callback_data - Button clicks emit TwinEventButtonSignalDown event - Applications register callbacks via twin_widget_set_callback() Removed obsolete scroll signal typedefs and widget-specific callback fields. Custom widgets and button handlers now use the same dispatch pattern. Button event types now correctly reflect their semantics: - TwinEventButtonSignalDown: emitted on button press - TwinEventButtonSignalUp: emitted on button release (click completion) Applications updated to listen for ButtonSignalUp instead of Down, matching the GTK convention where click callbacks trigger on release. Fixed closure propagation in box container: all child handler calls now pass child->callback_data instead of NULL, ensuring widgets receive their registered callback context.
1 parent a5d0b01 commit 92b0b67

File tree

14 files changed

+236
-155
lines changed

14 files changed

+236
-155
lines changed

.gitignore

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,7 @@ __pycache__/
2929
*.pyc
3030

3131
# Configuration
32-
.config
33-
.config.old
32+
.config*
3433
config.h
3534

3635
# CI pipeline

apps/animation.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,11 @@ static twin_time_t _apps_animation_timeout(twin_time_t now, void *closure)
5656
}
5757

5858
static twin_dispatch_result_t _apps_animation_dispatch(twin_widget_t *widget,
59-
twin_event_t *event)
59+
twin_event_t *event,
60+
void *closure)
6061
{
62+
(void) closure; /* unused parameter */
63+
6164
twin_custom_widget_t *custom = twin_widget_get_custom(widget);
6265
if (!custom)
6366
return TwinDispatchContinue;

apps/calc.c

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -129,18 +129,20 @@ static void _apps_calc_digit(apps_calc_t *calc, int digit)
129129
_apps_calc_update_value(calc);
130130
}
131131

132-
static void _apps_calc_button_signal(twin_button_t *button,
133-
twin_button_signal_t signal,
134-
void *closure)
132+
static twin_dispatch_result_t _apps_calc_button_clicked(twin_widget_t *widget,
133+
twin_event_t *event,
134+
void *data)
135135
{
136-
apps_calc_t *calc = closure;
136+
if (event->kind != TwinEventButtonSignalUp)
137+
return TwinDispatchContinue;
138+
139+
apps_calc_t *calc = data;
140+
twin_button_t *button = (twin_button_t *) widget;
137141
int a, b;
138142

139-
if (signal != TwinButtonSignalDown)
140-
return;
141143
int i = _apps_calc_button_to_id(calc, button);
142144
if (i < 0)
143-
return;
145+
return TwinDispatchContinue;
144146

145147
switch (i) {
146148
#define _(x) APPS_CALC_##x
@@ -191,6 +193,7 @@ static void _apps_calc_button_signal(twin_button_t *button,
191193
_apps_calc_digit(calc, i);
192194
break;
193195
}
196+
return TwinDispatchDone;
194197
}
195198

196199
void apps_calc_start(twin_screen_t *screen,
@@ -220,8 +223,8 @@ void apps_calc_start(twin_screen_t *screen,
220223
APPS_CALC_BUTTON_SIZE, APPS_CALC_BUTTON_STYLE);
221224
twin_widget_set(&calc->buttons[b]->label.widget,
222225
APPS_CALC_BUTTON_BG);
223-
calc->buttons[b]->signal = _apps_calc_button_signal;
224-
calc->buttons[b]->closure = calc;
226+
twin_widget_set_callback(&calc->buttons[b]->label.widget,
227+
_apps_calc_button_clicked, calc);
225228
calc->buttons[b]->label.widget.shape = TwinShapeEllipse;
226229
if (i || j)
227230
calc->buttons[b]->label.widget.copy_geom =

apps/clock.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,8 +204,11 @@ static twin_time_t _apps_clock_timeout(twin_time_t now, void *closure)
204204
}
205205

206206
static twin_dispatch_result_t _apps_clock_dispatch(twin_widget_t *widget,
207-
twin_event_t *event)
207+
twin_event_t *event,
208+
void *closure)
208209
{
210+
(void) closure; /* unused parameter */
211+
209212
twin_custom_widget_t *custom = twin_widget_get_custom(widget);
210213
if (!custom)
211214
return TwinDispatchContinue;

apps/image.c

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,11 @@ static void _apps_image_paint(twin_custom_widget_t *custom)
5454
}
5555

5656
static twin_dispatch_result_t _apps_image_dispatch(twin_widget_t *widget,
57-
twin_event_t *event)
57+
twin_event_t *event,
58+
void *closure)
5859
{
60+
(void) closure; /* unused parameter */
61+
5962
twin_custom_widget_t *custom = twin_widget_get_custom(widget);
6063
if (!custom)
6164
return TwinDispatchContinue;
@@ -70,15 +73,16 @@ static twin_dispatch_result_t _apps_image_dispatch(twin_widget_t *widget,
7073
return TwinDispatchContinue;
7174
}
7275

73-
static void _apps_image_button_signal(twin_button_t *button,
74-
twin_button_signal_t signal,
75-
void *closure)
76+
static twin_dispatch_result_t _apps_image_button_clicked(twin_widget_t *widget,
77+
twin_event_t *event,
78+
void *data)
7679
{
77-
(void) button; /* unused parameter */
78-
if (signal != TwinButtonSignalDown)
79-
return;
80+
(void) widget; /* unused parameter */
81+
82+
if (event->kind != TwinEventButtonSignalUp)
83+
return TwinDispatchContinue;
8084

81-
twin_custom_widget_t *custom = closure;
85+
twin_custom_widget_t *custom = data;
8286
apps_image_data_t *img =
8387
(apps_image_data_t *) twin_custom_widget_data(custom);
8488
const int n = sizeof(tvg_files) / sizeof(tvg_files[0]);
@@ -87,10 +91,11 @@ static void _apps_image_button_signal(twin_button_t *button,
8791
twin_pixmap_t *pix = twin_tvg_to_pixmap_scale(
8892
tvg_files[img->image_idx], TWIN_ARGB32, APP_WIDTH, APP_HEIGHT);
8993
if (!pix)
90-
return;
94+
return TwinDispatchContinue;
9195
img->pixes[img->image_idx] = pix;
9296
}
9397
twin_custom_widget_queue_paint(custom);
98+
return TwinDispatchDone;
9499
}
95100

96101
static twin_custom_widget_t *_apps_image_init(twin_box_t *parent)
@@ -113,8 +118,8 @@ static twin_custom_widget_t *_apps_image_init(twin_box_t *parent)
113118
twin_button_create(parent, "Next Image", 0xFF482722, D(10),
114119
TwinStyleBold | TwinStyleOblique);
115120
twin_widget_set(&button->label.widget, 0xFFFEE4CE);
116-
button->signal = _apps_image_button_signal;
117-
button->closure = custom;
121+
twin_widget_set_callback(&button->label.widget, _apps_image_button_clicked,
122+
custom);
118123
button->label.widget.shape = TwinShapeRectangle;
119124

120125
return custom;

apps/line.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,11 @@ static int _apps_line_hit(apps_line_data_t *line,
7171
}
7272

7373
static twin_dispatch_result_t _apps_line_dispatch(twin_widget_t *widget,
74-
twin_event_t *event)
74+
twin_event_t *event,
75+
void *closure)
7576
{
77+
(void) closure; /* unused parameter */
78+
7679
twin_custom_widget_t *custom = twin_widget_get_custom(widget);
7780
if (!custom)
7881
return TwinDispatchContinue;

apps/spline.c

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -113,20 +113,22 @@ static void _apps_spline_paint(twin_custom_widget_t *custom)
113113
twin_path_destroy(path);
114114
}
115115

116-
static void _apps_spline_button_signal(twin_button_t *button,
117-
twin_button_signal_t signal,
118-
void *closure)
116+
static twin_dispatch_result_t _apps_spline_button_clicked(twin_widget_t *widget,
117+
twin_event_t *event,
118+
void *data)
119119
{
120-
(void) button; /* unused parameter */
121-
if (signal != TwinButtonSignalDown)
122-
return;
120+
(void) widget; /* unused parameter */
123121

124-
twin_custom_widget_t *custom = closure;
122+
if (event->kind != TwinEventButtonSignalUp)
123+
return TwinDispatchContinue;
124+
125+
twin_custom_widget_t *custom = data;
125126
apps_spline_data_t *spline =
126127
(apps_spline_data_t *) twin_custom_widget_data(custom);
127128
spline->n_points = (spline->n_points == 3) ? 4 : 3;
128129
_init_control_point(spline);
129130
twin_custom_widget_queue_paint(custom);
131+
return TwinDispatchDone;
130132
}
131133

132134
static twin_dispatch_result_t _apps_spline_update_pos(
@@ -167,8 +169,11 @@ static int _apps_spline_hit(apps_spline_data_t *spline,
167169
}
168170

169171
static twin_dispatch_result_t _apps_spline_dispatch(twin_widget_t *widget,
170-
twin_event_t *event)
172+
twin_event_t *event,
173+
void *closure)
171174
{
175+
(void) closure; /* unused parameter */
176+
172177
twin_custom_widget_t *custom = twin_widget_get_custom(widget);
173178
if (!custom)
174179
return TwinDispatchContinue;
@@ -227,8 +232,8 @@ static twin_custom_widget_t *_apps_spline_init(twin_box_t *parent, int n_points)
227232
twin_button_create(parent, "Switch curve", 0xffae0000, D(10),
228233
TwinStyleBold | TwinStyleOblique);
229234
twin_widget_set(&button->label.widget, 0xc0808080);
230-
button->signal = _apps_spline_button_signal;
231-
button->closure = custom;
235+
twin_widget_set_callback(&button->label.widget, _apps_spline_button_clicked,
236+
custom);
232237
button->label.widget.shape = TwinShapeRectangle;
233238

234239
return custom;

0 commit comments

Comments
 (0)