GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_single_line_text_input_draw_position_get.c Lines: 62 62 100.0 %
Date: 2026-03-06 19:21:09 Branches: 29 29 100.0 %

Line Branch Exec Source
1
/***************************************************************************
2
 * Copyright (c) 2024 Microsoft Corporation
3
 * Copyright (c) 2026-present Eclipse ThreadX contributors
4
 *
5
 * This program and the accompanying materials are made available under the
6
 * terms of the MIT License which is available at
7
 * https://opensource.org/licenses/MIT.
8
 *
9
 * SPDX-License-Identifier: MIT
10
 **************************************************************************/
11
12
13
/**************************************************************************/
14
/**************************************************************************/
15
/**                                                                       */
16
/** GUIX Component                                                        */
17
/**                                                                       */
18
/**   Text Input Management (Single Line Text Input)                      */
19
/**                                                                       */
20
/**************************************************************************/
21
22
#define GX_SOURCE_CODE
23
24
25
/* Include necessary system files.  */
26
27
#include "gx_api.h"
28
#include "gx_context.h"
29
#include "gx_system.h"
30
#include "gx_widget.h"
31
#include "gx_single_line_text_input.h"
32
33
/**************************************************************************/
34
/*                                                                        */
35
/*  FUNCTION                                               RELEASE        */
36
/*                                                                        */
37
/*    _gx_single_line_text_input_draw_position_get        PORTABLE C      */
38
/*                                                           6.1          */
39
/*  AUTHOR                                                                */
40
/*                                                                        */
41
/*    Kenneth Maxwell, Microsoft Corporation                              */
42
/*                                                                        */
43
/*  DESCRIPTION                                                           */
44
/*                                                                        */
45
/*    This service calculates draw start position of text input text.     */
46
/*                                                                        */
47
/*  INPUT                                                                 */
48
/*                                                                        */
49
/*    text_input                            Single-line text input widget */
50
/*                                            control block.              */
51
/*                                                                        */
52
/*  OUTPUT                                                                */
53
/*                                                                        */
54
/*    None                                                                */
55
/*                                                                        */
56
/*  CALLS                                                                 */
57
/*                                                                        */
58
/*    _gx_context_brush_get                 Get brush of current context  */
59
/*    _gx_widget_border_width_get           Get widget border width       */
60
/*    _gx_widget_client_get                 Get widget client rectangle   */
61
/*    _gx_system_string_width_get           Get the width of a string     */
62
/*    _gx_single_line_text_input_position_update                          */
63
/*                                          Update cursor position by     */
64
/*                                            insert index                */
65
/*                                                                        */
66
/*                                                                        */
67
/*  CALLED BY                                                             */
68
/*                                                                        */
69
/*    _gx_single_line_text_input_draw                                     */
70
/*                                                                        */
71
/**************************************************************************/
72
50741
UINT _gx_single_line_text_input_draw_position_get(GX_SINGLE_LINE_TEXT_INPUT *text_input, GX_VALUE *xpos, GX_VALUE *ypos)
73
{
74
GX_VALUE     border_width;
75
UINT         text_height;
76
GX_VALUE     text_width;
77
GX_VALUE     client_height;
78
GX_VALUE     client_width;
79
GX_VALUE     x_pos;
80
GX_VALUE     y_pos;
81
GX_RECTANGLE client;
82
GX_BRUSH    *brush;
83
GX_BOOL      update_cursor_pos;
84
GX_STRING    string;
85
86
50741
    _gx_context_brush_get(&brush);
87
88
50741
    if (brush -> gx_brush_font == GX_NULL)
89
    {
90
7
        return(GX_FAILURE);
91
    }
92
93
50734
    if (text_input -> gx_widget_style & GX_STYLE_CURSOR_ALWAYS)
94
    {
95
11905
        update_cursor_pos = GX_TRUE;
96
    }
97
    else
98
    {
99
38829
        update_cursor_pos = GX_FALSE;
100
    }
101
102
    /* Pickup widget width. */
103
50734
    _gx_widget_border_width_get((GX_WIDGET *)text_input, &border_width);
104
105
50734
    _gx_widget_client_get((GX_WIDGET *)text_input, border_width, &client);
106
107
50734
    client_width = (GX_VALUE)(client.gx_rectangle_right - client.gx_rectangle_left + 1);
108
50734
    client_height = (GX_VALUE)(client.gx_rectangle_bottom - client.gx_rectangle_top + 1);
109
110
111
50734
    text_height = brush -> gx_brush_font -> gx_font_line_height;
112
50734
    string.gx_string_ptr = text_input -> gx_single_line_text_input_buffer;
113
50734
    string.gx_string_length = text_input -> gx_single_line_text_input_string_size;
114
50734
    _gx_system_string_width_get_ext(brush -> gx_brush_font, &string, &text_width);
115
116
50734
    switch (text_input -> gx_widget_style & GX_STYLE_TEXT_ALIGNMENT_MASK)
117
    {
118
3931
    case GX_STYLE_TEXT_RIGHT:
119
3931
        x_pos = (GX_VALUE)(client.gx_rectangle_right - 1);
120
121
3931
        x_pos = (GX_VALUE)(x_pos - text_input -> gx_single_line_text_input_xoffset);
122
123
3931
        if (text_width < (client_width - 3))
124
        {
125
            /* Text width is shorter than client width. */
126
689
            if (text_input -> gx_single_line_text_input_xoffset != text_width)
127
            {
128
                /* If xoffset is not equal to text width,
129
                   reset xoffset and update cursor position. */
130
84
                text_input -> gx_single_line_text_input_xoffset = text_width;
131
84
                update_cursor_pos = GX_TRUE;
132
            }
133
        }
134
3242
        else if (x_pos > client.gx_rectangle_left + 1)
135
        {
136
            /* If text start/end position is inside client area,
137
               reset xoffset value and update cursor position. */
138
157
            text_input -> gx_single_line_text_input_xoffset = text_width;
139
157
            update_cursor_pos = GX_TRUE;
140
        }
141
142
3931
        x_pos = (GX_VALUE)(client.gx_rectangle_right - 1);
143
3931
        break;
144
145
6492
    case GX_STYLE_TEXT_CENTER:
146
6492
        x_pos = (GX_VALUE)(client.gx_rectangle_left + 1 + (client_width >> 1));
147
6492
        x_pos = (GX_VALUE)(x_pos - text_input -> gx_single_line_text_input_xoffset);
148
149
6492
        if (text_width < (client_width - 3))
150
        {
151
            /* Text width is shorter than client width. */
152
1066
            if (text_input -> gx_single_line_text_input_xoffset != ((text_width + 1) >> 1))
153
            {
154
                /* If xoffset is not equal to 0,
155
                   reset xoffset value and update cursor position. */
156
67
                text_input -> gx_single_line_text_input_xoffset = (GX_VALUE)((text_width + 1) >> 1);
157
67
                update_cursor_pos = GX_TRUE;
158
            }
159
        }
160
5426
        else if ((x_pos > client.gx_rectangle_left + 1) ||
161
5108
                 (x_pos + text_width < client.gx_rectangle_right - 1))
162
        {
163
            /* If text start/end position is inside client area,
164
               reset xoffset value and update cursor position. */
165
319
            text_input -> gx_single_line_text_input_xoffset = (GX_VALUE)((text_width + 1) >> 1);
166
319
            update_cursor_pos = GX_TRUE;
167
        }
168
6492
        x_pos = (GX_VALUE)(client.gx_rectangle_left + 1 + (client_width >> 1));
169
6492
        break;
170
171
40311
    case GX_STYLE_TEXT_LEFT:
172
    default:
173
40311
        x_pos = (GX_VALUE)(client.gx_rectangle_left + 1);
174
175
40311
        x_pos = (GX_VALUE)(x_pos - text_input -> gx_single_line_text_input_xoffset);
176
177
40311
        if (text_width < (client_width - 3))
178
        {
179
            /* Text width is shorter than client width. */
180
33486
            if (text_input -> gx_single_line_text_input_xoffset != 0)
181
            {
182
                /* If xoffset is not equal to 0,
183
                   reset xoffset value and update cursor position. */
184
2
                text_input -> gx_single_line_text_input_xoffset = 0;
185
2
                update_cursor_pos = GX_TRUE;
186
            }
187
        }
188
6825
        else if (x_pos + text_width < client.gx_rectangle_right - 1)
189
        {
190
            /* If text start/end position is inside client area,
191
               reset xoffset value and update cursor position. */
192
1
            text_input -> gx_single_line_text_input_xoffset = 0;
193
1
            update_cursor_pos = GX_TRUE;
194
        }
195
196
40311
        x_pos = (GX_VALUE)(client.gx_rectangle_left + 1);
197
40311
        break;
198
    }
199
200
50734
    if (update_cursor_pos)
201
    {
202
12160
        _gx_single_line_text_input_position_update(text_input);
203
    }
204
205
50734
    x_pos = (GX_VALUE)(x_pos - text_input -> gx_single_line_text_input_xoffset);
206
207
50734
    y_pos = (GX_VALUE)(text_input -> gx_widget_size.gx_rectangle_top + border_width);
208
50734
    y_pos = (GX_VALUE)(y_pos - text_input -> gx_single_line_text_input_yoffset);
209
50734
    y_pos = (GX_VALUE)(y_pos + (GX_VALUE)(((INT)client_height - (INT)text_height) >> 1));
210
211
50734
    *xpos = x_pos;
212
50734
    *ypos = y_pos;
213
214
50734
    return GX_SUCCESS;
215
}
216