@@ -116,6 +116,12 @@ typedef struct _twin_screen twin_screen_t;
116116typedef struct _twin_pixmap twin_pixmap_t ;
117117typedef struct _twin_animation twin_animation_t ;
118118
119+ /** Button signal types (used in unified event system) */
120+ typedef enum _twin_button_signal {
121+ TwinButtonSignalDown /**< Sent when button pressed */ ,
122+ TwinButtonSignalUp /**< Sent when button released inside widget */
123+ } twin_button_signal_t ;
124+
119125/**
120126 * Event type enumeration for input and system events
121127 *
@@ -147,7 +153,11 @@ typedef enum _twin_event_kind {
147153 TwinEventPaint = 0x1001 /**< Widget needs painting */ ,
148154 TwinEventQueryGeometry = 0x1002 /**< Widget geometry query */ ,
149155 TwinEventConfigure = 0x1003 /**< Widget configuration change */ ,
150- TwinEventDestroy = 0x1004 /**< Widget destruction */
156+ TwinEventDestroy = 0x1004 /**< Widget destruction */ ,
157+
158+ /* Button signals (unified with event system) */
159+ TwinEventButtonSignalDown = 0x2001 /**< Button pressed signal */ ,
160+ TwinEventButtonSignalUp = 0x2002 /**< Button released signal */
151161} twin_event_kind_t ;
152162
153163/**
@@ -177,7 +187,10 @@ typedef struct _twin_event {
177187 struct {
178188 twin_rect_t extents ; /**< New widget geometry */
179189 } configure ; /**< Widget configuration event data */
180- } u ; /**< Event-specific data union */
190+ struct {
191+ twin_button_signal_t signal ; /**< Button signal type */
192+ } button_signal ; /**< Button signal event data */
193+ } u ; /**< Event-specific data union */
181194} twin_event_t ;
182195
183196/**
@@ -588,11 +601,27 @@ typedef enum _twin_box_dir {
588601
589602typedef enum _twin_dispatch_result {
590603 TwinDispatchDone /**< Event processing complete */ ,
591- TwinDispatchContinue /**< Continue event propagation */
604+ TwinDispatchContinue /**< Continue event propagation */ ,
605+ TwinDispatchReject /**< Cannot handle this event */
592606} twin_dispatch_result_t ;
593607
594- typedef twin_dispatch_result_t (* twin_dispatch_proc_t )(twin_widget_t * widget ,
595- twin_event_t * event );
608+ /**
609+ * Widget event handler function signature
610+ *
611+ * All widget event handlers use this signature with closure support.
612+ * The closure parameter enables stateful event handling without global state.
613+ *
614+ * @widget : Widget receiving the event
615+ * @event : Event to process
616+ * @closure : User data pointer for stateful handling
617+ * @return : Dispatch result (Done, Continue, or Reject)
618+ *
619+ * This type is used for both framework-level handlers and application
620+ * callbacks.
621+ */
622+ typedef twin_dispatch_result_t (* twin_widget_proc_t )(twin_widget_t * widget ,
623+ twin_event_t * event ,
624+ void * closure );
596625
597626typedef struct _twin_widget_layout {
598627 twin_coord_t width , height ; /**< Preferred dimensions */
@@ -614,10 +643,15 @@ struct _twin_widget {
614643 twin_widget_t * next ; /**< Next sibling widget */
615644 twin_box_t * parent ; /**< Parent container */
616645
617- /* Widget behavior */
618- twin_dispatch_proc_t dispatch ; /**< Event dispatch handler */
619- twin_rect_t extents ; /**< Current geometry */
620- twin_widget_t * copy_geom ; /**< Geometry source widget */
646+ /* Event handling:
647+ * - handler: Framework event handler (processes paint, configure, etc.)
648+ * - callback: Application callback (optional, receives button clicks, etc.)
649+ */
650+ twin_widget_proc_t handler ; /**< Widget event handler (framework) */
651+ twin_widget_proc_t callback ; /**< Application callback (optional) */
652+ void * callback_data ; /**< Callback user data */
653+ twin_rect_t extents ; /**< Current geometry */
654+ twin_widget_t * copy_geom ; /**< Geometry source widget */
621655
622656 /* Widget state */
623657 bool paint ; /**< Needs painting */
@@ -659,41 +693,24 @@ typedef struct _twin_label {
659693 twin_align_t align ; /**< Text alignment */
660694} twin_label_t ;
661695
662- typedef enum _twin_button_signal {
663- TwinButtonSignalDown /**< Sent when button pressed */ ,
664- TwinButtonSignalUp /**< Sent when button released inside widget */
665- } twin_button_signal_t ;
666-
667696typedef struct _twin_button twin_button_t ;
668697
669- typedef void (* twin_button_signal_proc_t )(twin_button_t * button ,
670- twin_button_signal_t signal ,
671- void * closure );
698+ /**
699+ * Button click callback signature
700+ * @button : Button that was clicked
701+ * @data : User data provided when callback was registered
702+ *
703+ * Similar to GTK's "clicked" signal.
704+ * Fires when the button is pressed and released.
705+ */
706+ typedef void (* twin_button_callback_t )(twin_button_t * button , void * data );
672707
673708struct _twin_button {
674- twin_label_t label ; /**< Base label widget */
675- bool pressed ; /**< Button pressed state */
676- bool active ; /**< Button active state */
677- twin_button_signal_proc_t signal ; /**< Signal callback */
678- void * closure ; /**< Callback closure */
679- };
680-
681- typedef enum _twin_scroll_signal {
682- TwinScrollSignalUpArrow /**< Up arrow clicked */ ,
683- TwinScrollSignalDownArrow /**< Down arrow clicked */ ,
684- TwinScrollSignalThumb /**< Thumb/slider clicked */ ,
685- TwinScrollSignalAboveThumb /**< Area above thumb clicked */ ,
686- TwinScrollSignalBelowThumb /**< Area below thumb clicked */
687- } twin_scroll_signal_t ;
688-
689- typedef struct _twin_scroll twin_scroll_t ;
690-
691- typedef void (* twin_scroll_signal_proc_t )(twin_scroll_t * scroll ,
692- twin_scroll_signal_t signal ,
693- void * closure );
694-
695- struct _twin_scroll {
696- twin_widget_t widget ; /**< Base widget */
709+ twin_label_t label ; /**< Base label widget */
710+ bool pressed ; /**< Button pressed state */
711+ bool active ; /**< Button active state */
712+ twin_button_callback_t click_callback ; /**< Modern click callback */
713+ void * click_data ; /**< User data for click callback */
697714};
698715
699716typedef struct _twin_context {
@@ -726,6 +743,37 @@ twin_button_t *twin_button_create(twin_box_t *parent,
726743 twin_fixed_t font_size ,
727744 twin_style_t font_style );
728745
746+ /**
747+ * Register callback for button clicks
748+ * @button : Button widget
749+ * @callback : Function to call when button is clicked
750+ * @data : User data to pass to callback
751+ *
752+ * The callback is invoked when the button is pressed and released (clicked).
753+ *
754+ * Example:
755+ * void on_button_clicked(twin_button_t *btn, void *data) {
756+ * printf("Button clicked!\n");
757+ * }
758+ * twin_button_on_clicked(my_button, on_button_clicked, my_data);
759+ */
760+ void twin_button_on_clicked (twin_button_t * button ,
761+ twin_button_callback_t callback ,
762+ void * data );
763+
764+ /**
765+ * Set application callback for widget events (low-level API)
766+ * @widget : Widget to configure
767+ * @callback : Application callback function
768+ * @data : User data passed to callback
769+ *
770+ * Allows applications to respond to widget events (e.g., button clicks).
771+ * The callback receives events after the widget's core handler processes them.
772+ */
773+ void twin_widget_set_callback (twin_widget_t * widget ,
774+ twin_widget_proc_t callback ,
775+ void * data );
776+
729777/**
730778 * Create default mouse cursor pixmap
731779 * @hx : Output hotspot X coordinate
@@ -1376,14 +1424,14 @@ twin_fixed_t twin_widget_height(twin_widget_t *widget);
13761424/* Request widget repaint */
13771425void twin_widget_queue_paint (twin_widget_t * widget );
13781426
1379- /* Create widget with custom dispatch handler */
1380- twin_widget_t * twin_widget_create_with_dispatch (twin_box_t * parent ,
1381- twin_argb32_t background ,
1382- twin_coord_t width ,
1383- twin_coord_t height ,
1384- twin_stretch_t hstretch ,
1385- twin_stretch_t vstretch ,
1386- twin_dispatch_proc_t dispatch );
1427+ /* Create widget with custom event handler */
1428+ twin_widget_t * twin_widget_create_with_handler (twin_box_t * parent ,
1429+ twin_argb32_t background ,
1430+ twin_coord_t width ,
1431+ twin_coord_t height ,
1432+ twin_stretch_t hstretch ,
1433+ twin_stretch_t vstretch ,
1434+ twin_widget_proc_t handler );
13871435
13881436/*
13891437 * Custom widget support - allows creating widgets without accessing internals
@@ -1403,19 +1451,19 @@ typedef struct {
14031451} twin_custom_widget_t ;
14041452
14051453/**
1406- * Create a custom widget with user-defined data and dispatch handler.
1454+ * Create a custom widget with user-defined data and event handler.
14071455 *
14081456 * @parent : Parent box widget to contain this widget
14091457 * @background : Background color (ARGB32 format)
14101458 * @width : Preferred width in pixels (0 for flexible)
14111459 * @height : Preferred height in pixels (0 for flexible)
14121460 * @hstretch : Horizontal stretch factor for layout
14131461 * @vstretch : Vertical stretch factor for layout
1414- * @dispatch : Custom event dispatch function for this widget
1462+ * @handler : Custom event handler function for this widget
14151463 * @data_size : Size of custom data to allocate (0 for no data)
14161464 * @return : Newly created custom widget, or NULL on failure
14171465 *
1418- * The dispatch function will be called for all events sent to this widget.
1466+ * The handler function will be called for all events sent to this widget.
14191467 * Custom data (if requested) is zero-initialized and accessible via
14201468 * twin_custom_widget_data().
14211469 */
@@ -1425,7 +1473,7 @@ twin_custom_widget_t *twin_custom_widget_create(twin_box_t *parent,
14251473 twin_coord_t height ,
14261474 twin_stretch_t hstretch ,
14271475 twin_stretch_t vstretch ,
1428- twin_dispatch_proc_t dispatch ,
1476+ twin_widget_proc_t handler ,
14291477 size_t data_size );
14301478
14311479/**
0 commit comments