1 /***************************************************************************
2  * Copyright (c) 2024 Microsoft Corporation
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the MIT License which is available at
6  * https://opensource.org/licenses/MIT.
7  *
8  * SPDX-License-Identifier: MIT
9  **************************************************************************/
10 
11 
12 /**************************************************************************/
13 /**************************************************************************/
14 /**                                                                       */
15 /** GUIX Component                                                        */
16 /**                                                                       */
17 /**   Scroll Management (Scroll Thumb)                                    */
18 /**                                                                       */
19 /**************************************************************************/
20 
21 #define GX_SOURCE_CODE
22 
23 
24 /* Include necessary system files.  */
25 
26 #include "gx_api.h"
27 #include "gx_system.h"
28 #include "gx_widget.h"
29 #include "gx_scrollbar.h"
30 #include "gx_button.h"
31 
32 /**************************************************************************/
33 /*                                                                        */
34 /*  FUNCTION                                               RELEASE        */
35 /*                                                                        */
36 /*    _gx_scroll_thumb_event_process                      PORTABLE C      */
37 /*                                                           6.1          */
38 /*  AUTHOR                                                                */
39 /*                                                                        */
40 /*    Kenneth Maxwell, Microsoft Corporation                              */
41 /*                                                                        */
42 /*  DESCRIPTION                                                           */
43 /*                                                                        */
44 /*    This function processes events for a scrollbar thumb button         */
45 /*                                                                        */
46 /*  INPUT                                                                 */
47 /*                                                                        */
48 /*    scroll_thumb                          Scroll thumb widget control   */
49 /*                                            block                       */
50 /*    event                                 Pointer to event to process   */
51 /*                                                                        */
52 /*  OUTPUT                                                                */
53 /*                                                                        */
54 /*    status                                Completion status             */
55 /*                                                                        */
56 /*  CALLS                                                                 */
57 /*                                                                        */
58 /*    _gx_button_event_process              Default button event process  */
59 /*    _gx_system_input_capture              Default widget event process  */
60 /*    _gx_system_input_release              Direct all input events       */
61 /*    _gx_widget_shift                      Shift the widget              */
62 /*    _gx_widget_height_get                 Get the height of widget      */
63 /*    _gx_scroll_thumb_shift_limit          Limit the travel of the       */
64 /*                                            scrollbar thumb button      */
65 /*    _gx_widget_width_get                  Get the width of widget       */
66 /*    [_gx_widget_event_process_function]   Widget event process routine  */
67 /*    _gx_widget_event_process              Default widget event process  */
68 /*                                                                        */
69 /*  CALLED BY                                                             */
70 /*                                                                        */
71 /*    Application Code                                                    */
72 /*    GUIX Internal Code                                                  */
73 /*                                                                        */
74 /*  RELEASE HISTORY                                                       */
75 /*                                                                        */
76 /*    DATE              NAME                      DESCRIPTION             */
77 /*                                                                        */
78 /*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
79 /*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
80 /*                                            resulting in version 6.1    */
81 /*                                                                        */
82 /**************************************************************************/
_gx_scroll_thumb_event_process(GX_SCROLL_THUMB * thumb,GX_EVENT * event_ptr)83 UINT  _gx_scroll_thumb_event_process(GX_SCROLL_THUMB *thumb, GX_EVENT *event_ptr)
84 {
85 GX_EVENT   newevent;
86 GX_WIDGET *widget = (GX_WIDGET *)thumb;
87 UINT       status;
88 INT        shift;
89 GX_VALUE   widget_height;
90 GX_VALUE   widget_width;
91 
92     /* Default status to success.  */
93     status =  GX_SUCCESS;
94 
95     /* Process relative to the type of event.  */
96     switch (event_ptr -> gx_event_type)
97     {
98     case GX_EVENT_SHOW:
99         status = _gx_widget_event_process(widget, event_ptr);
100         if (thumb -> gx_scroll_thumb_pixelmap)
101         {
102             if (_gx_widget_transparent_pixelmap_detect(widget, thumb -> gx_scroll_thumb_pixelmap))
103             {
104                 _gx_widget_status_add(widget, GX_STATUS_TRANSPARENT);
105             }
106         }
107         break;
108 
109     case GX_EVENT_PEN_DOWN:
110         _gx_system_input_capture(widget);
111 
112         thumb -> gx_scroll_thumb_drag_mode = GX_TRUE;
113 
114         if (widget -> gx_widget_style & GX_SCROLLBAR_VERTICAL)
115         {
116             thumb -> gx_scroll_thumb_start_drag = event_ptr -> gx_event_payload.gx_event_pointdata.gx_point_y;
117         }
118         else
119         {
120             thumb -> gx_scroll_thumb_start_drag = event_ptr -> gx_event_payload.gx_event_pointdata.gx_point_x;
121         }
122         break;
123 
124     case GX_EVENT_PEN_UP:
125         if (widget ->gx_widget_status & GX_STATUS_OWNS_INPUT)
126         {
127             _gx_system_input_release(widget);
128         }
129         break;
130 
131     case GX_EVENT_PEN_DRAG:
132         if (thumb -> gx_widget_style & GX_SCROLLBAR_VERTICAL)
133         {
134             if (event_ptr -> gx_event_payload.gx_event_pointdata.gx_point_y != thumb -> gx_scroll_thumb_start_drag)
135             {
136                 shift = event_ptr -> gx_event_payload.gx_event_pointdata.gx_point_y - thumb -> gx_scroll_thumb_start_drag;
137                 shift = _gx_scroll_thumb_shift_limit(thumb, shift);
138 
139                 if (shift)
140                 {
141                     _gx_widget_shift(widget, 0, (GX_VALUE)shift, GX_TRUE);
142                     thumb -> gx_scroll_thumb_start_drag = event_ptr -> gx_event_payload.gx_event_pointdata.gx_point_y;
143                     newevent.gx_event_type = GX_EVENT_VERTICAL_SCROLL;
144                     newevent.gx_event_payload.gx_event_intdata[0] = widget -> gx_widget_size.gx_rectangle_top;
145 
146                     _gx_widget_height_get(widget, &widget_height);
147                     newevent.gx_event_payload.gx_event_intdata[1] = (INT)widget_height;
148 
149                     newevent.gx_event_sender = GX_ID_SCROLL_THUMB;
150 
151                     /* send the scroll event to my parent scrollbar */
152                     thumb -> gx_widget_parent -> gx_widget_event_process_function(thumb -> gx_widget_parent, &newevent);
153                 }
154             }
155         }
156         else
157         {
158             if (event_ptr -> gx_event_payload.gx_event_pointdata.gx_point_x != thumb -> gx_scroll_thumb_start_drag)
159             {
160                 shift = event_ptr -> gx_event_payload.gx_event_pointdata.gx_point_x - thumb -> gx_scroll_thumb_start_drag;
161                 shift = _gx_scroll_thumb_shift_limit(thumb, shift);
162 
163                 if (shift)
164                 {
165                     _gx_widget_shift(widget, (GX_VALUE)shift, 0, GX_TRUE);
166                     thumb -> gx_scroll_thumb_start_drag = event_ptr -> gx_event_payload.gx_event_pointdata.gx_point_x;
167                     newevent.gx_event_type = GX_EVENT_HORIZONTAL_SCROLL;
168                     newevent.gx_event_payload.gx_event_intdata[0] = widget -> gx_widget_size.gx_rectangle_left;
169 
170                     _gx_widget_width_get(widget, &widget_width);
171                     newevent.gx_event_payload.gx_event_intdata[1] = (INT)widget_width;
172                     newevent.gx_event_sender = GX_ID_SCROLL_THUMB;
173 
174                     /* send the scroll event to my parent scrollbar */
175                     widget -> gx_widget_parent -> gx_widget_event_process_function(thumb -> gx_widget_parent, &newevent);
176                 }
177             }
178         }
179         break;
180 
181     default:
182 
183         /* Call the widget default processing.  */
184         status =  _gx_widget_event_process(widget, event_ptr);
185     }
186 
187     /* Return completion status.  */
188     return(status);
189 }
190 
191