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 Wheel Management (Generic Scroll Wheel) */
18 /** */
19 /**************************************************************************/
20
21 #define GX_SOURCE_CODE
22
23
24 /* Include necessary system files. */
25
26 #include "gx_api.h"
27 #include "gx_widget.h"
28 #include "gx_window.h"
29 #include "gx_scroll_wheel.h"
30 #include "gx_utility.h"
31 #include "gx_system.h"
32
33 /**************************************************************************/
34 /* */
35 /* FUNCTION RELEASE */
36 /* */
37 /* _gx_generic_scroll_wheel_scroll PORTABLE C */
38 /* 6.2.1 */
39 /* AUTHOR */
40 /* */
41 /* Ting Zhu, Microsoft Corporation */
42 /* */
43 /* DESCRIPTION */
44 /* */
45 /* This function moves up or down the generic scroll wheel. */
46 /* */
47 /* INPUT */
48 /* */
49 /* wheel Generic scroll wheel control */
50 /* block */
51 /* amount Shifting value */
52 /* */
53 /* OUTPUT */
54 /* */
55 /* None */
56 /* */
57 /* CALLS */
58 /* */
59 /* _gx_scroll_wheel_selected_row_calculate */
60 /* Calculate the new selected row*/
61 /* _gx_widget_first_visible_client_child_get */
62 /* Get the first visible client */
63 /* _gx_widget_next_visible_client_child_get */
64 /* Get the next visible client */
65 /* _gx_widget_scroll_shift Shift a widget */
66 /* _gx_generic_scroll_wheel_up_wrap Scroll up the scroll wheel */
67 /* _gx_generic_scroll_wheel_down_wrap Scroll down the scroll wheel */
68 /* _gx_system_dirty_mark Mark the widget as dirty */
69 /* */
70 /* CALLED BY */
71 /* */
72 /* GUIX Internal Code */
73 /* */
74 /* RELEASE HISTORY */
75 /* */
76 /* DATE NAME DESCRIPTION */
77 /* */
78 /* 06-02-2021 Ting Zhu Initial Version 6.1.7 */
79 /* 10-31-2022 Kenneth Maxwell Modified comment(s), */
80 /* changed return type, */
81 /* resulting in version 6.2.0 */
82 /* 03-08-2023 Ting Zhu Modified comment(s), */
83 /* changed return type, */
84 /* resulting in version 6.2.1 */
85 /* */
86 /**************************************************************************/
_gx_generic_scroll_wheel_scroll(GX_GENERIC_SCROLL_WHEEL * wheel,GX_VALUE shift)87 UINT _gx_generic_scroll_wheel_scroll(GX_GENERIC_SCROLL_WHEEL *wheel, GX_VALUE shift)
88 {
89 GX_WIDGET *child;
90 INT y_shift;
91 INT min_shift;
92 INT max_shift;
93
94 if (!shift)
95 {
96 return GX_SUCCESS;
97 }
98
99 if (!wheel -> gx_scroll_wheel_wrap_style_check((GX_SCROLL_WHEEL *)wheel))
100 {
101 if ((shift > 0 && wheel -> gx_scroll_wheel_selected_row == 0) ||
102 (shift < 0 && wheel -> gx_scroll_wheel_selected_row == wheel -> gx_scroll_wheel_total_rows - 1))
103 {
104 y_shift = wheel -> gx_scroll_wheel_selected_yshift + shift;
105
106 min_shift = (wheel -> gx_scroll_wheel_selected_row - wheel -> gx_scroll_wheel_total_rows + 1) * wheel -> gx_scroll_wheel_row_height;
107 max_shift = (wheel -> gx_scroll_wheel_selected_row * wheel -> gx_scroll_wheel_row_height);
108
109 if ((y_shift < min_shift) || (y_shift > max_shift))
110 {
111
112 /* Slow down the speed when scroll outside the valid row range. */
113 shift = (GX_VALUE)(shift + wheel -> gx_scroll_wheel_shift_error);
114 wheel -> gx_scroll_wheel_shift_error = (GX_BYTE)(shift % 4);
115 shift /= 4;
116 }
117 else
118 {
119 wheel -> gx_scroll_wheel_shift_error = 0;
120 }
121 }
122 }
123
124 wheel -> gx_scroll_wheel_selected_yshift = (GX_VALUE)(wheel -> gx_scroll_wheel_selected_yshift + shift);
125
126 /* Calculate the new selected row. */
127 _gx_scroll_wheel_selected_row_calculate((GX_SCROLL_WHEEL *)wheel);
128
129
130 /* First shift my child widgets. */
131 child = _gx_widget_first_visible_client_child_get((GX_WIDGET *)wheel);
132
133 while (child)
134 {
135 _gx_widget_scroll_shift(child, 0, shift, GX_TRUE);
136
137 if (child -> gx_widget_style & GX_STYLE_DRAW_SELECTED)
138 {
139 child -> gx_widget_style &= (~GX_STYLE_DRAW_SELECTED);
140 }
141
142 child = _gx_widget_next_visible_client_child_get(child);
143 }
144
145 /* Next check to see if we need to wrap any child widgets. */
146
147 if ((wheel -> gx_generic_scroll_wheel_callback != GX_NULL) &&
148 (wheel -> gx_generic_scroll_wheel_visible_rows < wheel -> gx_scroll_wheel_total_rows) &&
149 ((wheel -> gx_generic_scroll_wheel_child_count < wheel -> gx_scroll_wheel_total_rows) || (wheel -> gx_widget_style & GX_STYLE_WRAP)))
150 {
151
152 /* This means we have fewer children than list rows, so we
153 need to move and re-use the child widgets. */
154 if (shift < 0)
155 {
156 _gx_generic_scroll_wheel_up_wrap(wheel);
157 }
158 else
159 {
160 _gx_generic_scroll_wheel_down_wrap(wheel);
161 }
162 }
163
164 if (wheel -> gx_widget_status & GX_STATUS_VISIBLE)
165 {
166 _gx_system_dirty_mark((GX_WIDGET *)wheel);
167 }
168 return GX_SUCCESS;
169 }
170
171