GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_single_line_text_input_character_delete.c Lines: 72 72 100.0 %
Date: 2026-03-06 19:21:09 Branches: 25 25 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_system.h"
29
#include "gx_widget.h"
30
#include "gx_single_line_text_input.h"
31
#include "gx_utility.h"
32
33
/**************************************************************************/
34
/*                                                                        */
35
/*  FUNCTION                                               RELEASE        */
36
/*                                                                        */
37
/*    _gx_single_line_text_input_character_delete         PORTABLE C      */
38
/*                                                           6.1          */
39
/*  AUTHOR                                                                */
40
/*                                                                        */
41
/*    Kenneth Maxwell, Microsoft Corporation                              */
42
/*                                                                        */
43
/*  DESCRIPTION                                                           */
44
/*                                                                        */
45
/*    This service deletes the character after the text input cursor      */
46
/*    position.                                                           */
47
/*                                                                        */
48
/*  INPUT                                                                 */
49
/*                                                                        */
50
/*    text_input                             Single line text input       */
51
/*                                            control blcok               */
52
/*                                                                        */
53
/*  OUTPUT                                                                */
54
/*                                                                        */
55
/*    None                                                                */
56
/*                                                                        */
57
/*  CALLS                                                                 */
58
/*                                                                        */
59
/*    memmove                               Move a block of memory        */
60
/*    _gx_widget_border_width_get           Get widget border width       */
61
/*    _gx_widget_client_get                 Get widget client rectangle   */
62
/*    _gx_widget_font_get                   Get font by specified ID      */
63
/*    _gx_system_string_width_get           Get the width of a string     */
64
/*    _gx_system_dirty_partial_add          Mark the partial area of a    */
65
/*                                            widget as dirty             */
66
/*    _gx_utility_utf8_string_character_get Parse utf8 string to          */
67
/*                                            multi-byte glyph            */
68
/*    _gx_single_line_text_input_position_update                          */
69
/*                                          Update cursor position        */
70
/*                                            according to insert position*/
71
/*                                                                        */
72
/*  CALLED BY                                                             */
73
/*                                                                        */
74
/*    Application Code                                                    */
75
/*    GUIX Internal Code                                                  */
76
/*                                                                        */
77
/**************************************************************************/
78
586
UINT _gx_single_line_text_input_character_delete(GX_SINGLE_LINE_TEXT_INPUT *text_input)
79
{
80
586
GX_TEXT_INPUT_CURSOR *cursor_ptr = &text_input -> gx_single_line_text_input_cursor_instance;
81
UINT                  insert_pos;
82
GX_CHAR              *string_buffer;
83
UINT                  string_size;
84
GX_VALUE              border_width;
85
GX_VALUE              text_width;
86
GX_RECTANGLE          client;
87
GX_RECTANGLE          dirty_area;
88
GX_FONT              *gx_font;
89
GX_VALUE              x_pos;
90
GX_VALUE              offset;
91
GX_VALUE              del_char_width;
92
586
UINT                  glyph_len = 1;
93
94
GX_STRING             string;
95
96
586
    if (text_input -> gx_single_line_text_input_end_mark > text_input -> gx_single_line_text_input_start_mark)
97
    {
98
18
        return _gx_single_line_text_input_backspace(text_input);
99
    }
100
101
568
    insert_pos = text_input -> gx_single_line_text_input_insert_pos;
102
568
    string_buffer = text_input -> gx_single_line_text_input_buffer;
103
568
    string_size = text_input -> gx_single_line_text_input_string_size;
104
105
568
    if (insert_pos < string_size)
106
    {
107
542
        _gx_widget_border_width_get((GX_WIDGET *)text_input, &border_width);
108
542
        _gx_widget_client_get((GX_WIDGET *)text_input, border_width, &client);
109
110
542
        if (text_input -> gx_single_line_text_input_start_mark != text_input -> gx_single_line_text_input_end_mark)
111
        {
112
47
            glyph_len = text_input -> gx_single_line_text_input_start_mark - text_input -> gx_single_line_text_input_end_mark;
113
114
47
            if (cursor_ptr -> gx_text_input_cursor_pos.gx_point_x <= client.gx_rectangle_left ||
115
29
                cursor_ptr -> gx_text_input_cursor_pos.gx_point_x >= client.gx_rectangle_right)
116
            {
117
24
                _gx_single_line_text_input_left_arrow(text_input);
118
            }
119
47
            text_input -> gx_single_line_text_input_start_mark = 0;
120
47
            text_input -> gx_single_line_text_input_end_mark = 0;
121
        }
122
#ifdef GX_UTF8_SUPPORT
123
        else
124
        {
125
495
            string.gx_string_ptr = string_buffer + insert_pos;
126
495
            string.gx_string_length = string_size - insert_pos;
127
128
495
            _gx_utility_utf8_string_character_get(&string, GX_NULL, &glyph_len);
129
        }
130
#endif
131
542
        dirty_area = client;
132
133
542
        _gx_widget_font_get((GX_WIDGET *)text_input, text_input -> gx_prompt_font_id, &gx_font);
134
135
        /* Pick up text witth. */
136
542
        string.gx_string_ptr = string_buffer;
137
542
        string.gx_string_length = text_input -> gx_single_line_text_input_string_size;
138
139
542
        _gx_system_string_width_get_ext(gx_font, &string, &text_width);
140
141
542
        string.gx_string_ptr = string_buffer + insert_pos;
142
542
        string.gx_string_length = glyph_len;
143
144
542
        _gx_system_string_width_get_ext(gx_font, &string, &del_char_width);
145
146
542
        switch (text_input -> gx_widget_style & GX_STYLE_TEXT_ALIGNMENT_MASK)
147
        {
148
138
        case GX_STYLE_TEXT_RIGHT:
149
138
            x_pos = (GX_VALUE)(client.gx_rectangle_right - 1);
150
138
            x_pos = (GX_VALUE)(x_pos - text_input -> gx_single_line_text_input_xoffset);
151
152
138
            if (x_pos + text_width > client.gx_rectangle_right - 1)
153
            {
154
105
                offset = (GX_VALUE)((x_pos + text_width - del_char_width) - (client.gx_rectangle_right - 1));
155
156
105
                if (offset < 0)
157
                {
158
7
                    text_input -> gx_single_line_text_input_xoffset = (GX_VALUE)(text_input -> gx_single_line_text_input_xoffset + offset);
159
7
                    cursor_ptr -> gx_text_input_cursor_pos.gx_point_x = (GX_VALUE)(cursor_ptr -> gx_text_input_cursor_pos.gx_point_x - offset);
160
                }
161
            }
162
            else
163
            {
164
33
                text_input -> gx_single_line_text_input_xoffset = (GX_VALUE)(text_input -> gx_single_line_text_input_xoffset - del_char_width);
165
33
                cursor_ptr -> gx_text_input_cursor_pos.gx_point_x = (GX_VALUE)(cursor_ptr -> gx_text_input_cursor_pos.gx_point_x + del_char_width);
166
167
33
                dirty_area.gx_rectangle_right = cursor_ptr -> gx_text_input_cursor_pos.gx_point_x;
168
            }
169
138
            break;
170
171
135
        case GX_STYLE_TEXT_CENTER:
172
135
            x_pos = (GX_VALUE)(client.gx_rectangle_left + 1);
173
135
            x_pos = (GX_VALUE)(x_pos + ((client.gx_rectangle_right - client.gx_rectangle_left + 1) >> 1));
174
135
            x_pos = (GX_VALUE)(x_pos - text_input -> gx_single_line_text_input_xoffset);
175
135
            if (text_width <= (client.gx_rectangle_right - client.gx_rectangle_left + 1 - border_width))
176
            {
177
25
                dirty_area.gx_rectangle_left = (GX_VALUE)(x_pos - (cursor_ptr -> gx_text_input_cursor_width >> 1));
178
25
                dirty_area.gx_rectangle_right = (GX_VALUE)(x_pos + text_width + ((cursor_ptr -> gx_text_input_cursor_width + 1) >> 1) - 1);
179
            }
180
            /* Calculate the cursor position. */
181
135
            text_input -> gx_single_line_text_input_xoffset = (GX_VALUE)((text_width - del_char_width + 1) >> 1);
182
135
            cursor_ptr -> gx_text_input_cursor_pos.gx_point_x = (GX_VALUE)(cursor_ptr -> gx_text_input_cursor_pos.gx_point_x +
183
135
                                                                           (((text_width + 1) >> 1) - text_input -> gx_single_line_text_input_xoffset));
184
135
            break;
185
186
269
        case GX_STYLE_TEXT_LEFT:
187
        default:
188
269
            x_pos = (GX_VALUE)(client.gx_rectangle_left + 1);
189
269
            x_pos = (GX_VALUE)(x_pos - text_input -> gx_single_line_text_input_xoffset);
190
191
269
            if (x_pos < client.gx_rectangle_left + 1)
192
            {
193
34
                offset = (GX_VALUE)((client.gx_rectangle_right - 1) - (x_pos + text_width - del_char_width));
194
195
34
                if (offset > 0)
196
                {
197
18
                    if (offset > (client.gx_rectangle_left + 1 - x_pos))
198
                    {
199
6
                        offset = (GX_VALUE)(client.gx_rectangle_left + 1 - x_pos);
200
                    }
201
202
18
                    text_input -> gx_single_line_text_input_xoffset = (GX_VALUE)(text_input -> gx_single_line_text_input_xoffset - offset);
203
18
                    cursor_ptr -> gx_text_input_cursor_pos.gx_point_x = (GX_VALUE)(cursor_ptr -> gx_text_input_cursor_pos.gx_point_x + offset);
204
                }
205
            }
206
            else
207
            {
208
235
                dirty_area.gx_rectangle_left = (GX_VALUE)(cursor_ptr -> gx_text_input_cursor_pos.gx_point_x - (cursor_ptr -> gx_text_input_cursor_width >> 1));
209
235
                dirty_area.gx_rectangle_right = (GX_VALUE)(x_pos + text_width + cursor_ptr -> gx_text_input_cursor_width - 1);
210
            }
211
269
            break;
212
        }
213
214
215
        /* Delete a character from the string buffer. */
216
542
        memmove(string_buffer + insert_pos, string_buffer + insert_pos + glyph_len, string_size - insert_pos - glyph_len);
217
218
542
        string_buffer[string_size - glyph_len] = '\0';
219
542
        text_input -> gx_single_line_text_input_string_size -= glyph_len;
220
221
        /* Mark text input be changed.  */
222
542
        text_input -> gx_single_line_text_input_was_modified = GX_TRUE;
223
224
542
        _gx_system_dirty_partial_add((GX_WIDGET *)text_input, &dirty_area);
225
    }
226
227
568
    return GX_SUCCESS;
228
}
229