GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_single_line_text_input_character_insert.c Lines: 57 57 100.0 %
Date: 2026-03-06 19:21:09 Branches: 13 13 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_context.h"
30
#include "gx_widget.h"
31
#include "gx_single_line_text_input.h"
32
33
34
/**************************************************************************/
35
/*                                                                        */
36
/*  FUNCTION                                               RELEASE        */
37
/*                                                                        */
38
/*    _gx_single_line_text_input_character_insert         PORTABLE C      */
39
/*                                                           6.1          */
40
/*  AUTHOR                                                                */
41
/*                                                                        */
42
/*    Kenneth Maxwell, Microsoft Corporation                              */
43
/*                                                                        */
44
/*  DESCRIPTION                                                           */
45
/*                                                                        */
46
/*    This services inserts a character into the text input string at the */
47
/*    current cursor position.                                            */
48
/*                                                                        */
49
/*  INPUT                                                                 */
50
/*                                                                        */
51
/*    text_input                            Single-line text input widget */
52
/*                                            control block               */
53
/*    insert_str                            Byte string of insert         */
54
/*                                            character                   */
55
/*    insert_size                           String size of insert         */
56
/*                                            character                   */
57
/*                                                                        */
58
/*  OUTPUT                                                                */
59
/*                                                                        */
60
/*    None                                                                */
61
/*                                                                        */
62
/*  CALLS                                                                 */
63
/*                                                                        */
64
/*    memmove                               Move a block of memory        */
65
/*    _gx_widget_font_get                   Get font by specified ID      */
66
/*    _gx_widget_border_width_get           Get the widget border width   */
67
/*    _gx_widget_client_get                 Get widget client rectangle   */
68
/*    _gx_system_string_width_get           Get the width of a string     */
69
/*    _gx_system_dirty_partial_add          Mark the partial area of a    */
70
/*                                            widget as dirty             */
71
/*    _gx_single_line_text_input_backspace  Remove text before the cursor */
72
/*    _gx_single_line_text_input_character_delete                         */
73
/*                                          Remove text after the cursor  */
74
/*                                                                        */
75
/*  CALLED BY                                                             */
76
/*                                                                        */
77
/*    Application Code                                                    */
78
/*    GUIX Internal Code                                                  */
79
/*                                                                        */
80
/**************************************************************************/
81
1973
UINT _gx_single_line_text_input_character_insert(GX_SINGLE_LINE_TEXT_INPUT *text_input, GX_UBYTE *insert_str, UINT insert_size)
82
{
83
GX_TEXT_INPUT_CURSOR *cursor_ptr;
84
UINT                  buffer_size;
85
GX_CHAR              *string_buffer;
86
UINT                  string_size;
87
GX_VALUE              new_cursor_pos;
88
UINT                  insert_pos;
89
GX_VALUE              border_width;
90
GX_VALUE              client_right;
91
GX_VALUE              client_width;
92
GX_VALUE              insert_width;
93
GX_VALUE              text_width;
94
GX_FONT              *gx_font;
95
GX_RECTANGLE          dirty_area;
96
GX_STRING             string;
97
98
    /* Delete hightlight text. */
99
1973
    if (text_input -> gx_single_line_text_input_start_mark != text_input -> gx_single_line_text_input_end_mark)
100
    {
101
4
        if (text_input -> gx_single_line_text_input_end_mark > text_input -> gx_single_line_text_input_start_mark)
102
        {
103
3
            _gx_single_line_text_input_backspace(text_input);
104
        }
105
        else
106
        {
107
1
            _gx_single_line_text_input_character_delete(text_input);
108
        }
109
    }
110
111
1973
    cursor_ptr = &text_input -> gx_single_line_text_input_cursor_instance;
112
113
1973
    buffer_size = text_input -> gx_single_line_text_input_buffer_size;
114
1973
    string_size = text_input -> gx_single_line_text_input_string_size;
115
116
    /* Judge whether there have remaining buffer size.  */
117
1973
    if (buffer_size < string_size + insert_size + 1)
118
    {
119
318
        return GX_FAILURE;
120
    }
121
122
1655
    string_buffer = text_input -> gx_single_line_text_input_buffer;
123
124
1655
    _gx_widget_font_get((GX_WIDGET *)text_input, text_input -> gx_prompt_font_id, &gx_font);
125
126
    /* Pick up text witth. */
127
1655
    string.gx_string_ptr = string_buffer;
128
1655
    string.gx_string_length = text_input -> gx_single_line_text_input_string_size;
129
1655
    _gx_system_string_width_get_ext(gx_font, &string, &text_width);
130
131
    /* Insert a char to the string buffer. */
132
1655
    insert_pos = text_input -> gx_single_line_text_input_insert_pos;
133
1655
    memmove(string_buffer + insert_pos + insert_size, string_buffer + insert_pos, string_size - insert_pos);
134
1655
    memmove(string_buffer + insert_pos, insert_str, insert_size);
135
1655
    string_buffer[string_size + insert_size] = '\0';
136
137
    /* Update the input string size and cursor position. */
138
1655
    text_input -> gx_single_line_text_input_string_size += insert_size;
139
1655
    text_input -> gx_single_line_text_input_insert_pos += insert_size;
140
141
    /* Calculate inside widget right. */
142
1655
    _gx_widget_border_width_get((GX_WIDGET *)text_input, &border_width);
143
1655
    _gx_widget_client_get((GX_WIDGET *)text_input, border_width, &dirty_area);
144
1655
    client_right = dirty_area.gx_rectangle_right;
145
146
    /* Get inset character width. */
147
1655
    string.gx_string_ptr = (GX_CONST GX_CHAR *)insert_str;
148
1655
    string.gx_string_length = insert_size;
149
1655
    _gx_system_string_width_get_ext(gx_font, &string, &insert_width);
150
151
1655
    switch (text_input -> gx_widget_style & GX_STYLE_TEXT_ALIGNMENT_MASK)
152
    {
153
375
    case GX_STYLE_TEXT_RIGHT:
154
375
        text_input -> gx_single_line_text_input_xoffset = (GX_VALUE)(text_input -> gx_single_line_text_input_xoffset + insert_width);
155
156
375
        dirty_area.gx_rectangle_right = cursor_ptr -> gx_text_input_cursor_pos.gx_point_x;
157
375
        break;
158
159
373
    case GX_STYLE_TEXT_CENTER:
160
        /* Calculate the cursor position. */
161
373
        client_width = (GX_VALUE)(dirty_area.gx_rectangle_right - dirty_area.gx_rectangle_left + 1);
162
373
        text_width = (GX_VALUE)(text_width + insert_width);
163
373
        new_cursor_pos = (GX_VALUE)(cursor_ptr -> gx_text_input_cursor_pos.gx_point_x -
164
373
                                    (((text_width + 1) >> 1) - text_input -> gx_single_line_text_input_xoffset) +
165
                                    insert_width);
166
        /* Update offset in x axis. */
167
373
        text_input -> gx_single_line_text_input_xoffset = (GX_VALUE)((text_width + 1) >> 1);
168
169
        /* Update offset in x axis. */
170
373
        if (new_cursor_pos < client_right - 1)
171
        {
172
186
            dirty_area.gx_rectangle_left = (GX_VALUE)(dirty_area.gx_rectangle_left + 1 + (client_width >> 1) - text_input -> gx_single_line_text_input_xoffset);
173
186
            dirty_area.gx_rectangle_right = (GX_VALUE)(dirty_area.gx_rectangle_left + text_width);
174
186
            dirty_area.gx_rectangle_left = (GX_VALUE)(dirty_area.gx_rectangle_left - (cursor_ptr -> gx_text_input_cursor_width >> 1));
175
186
            dirty_area.gx_rectangle_right = (GX_VALUE)(dirty_area.gx_rectangle_right + ((cursor_ptr -> gx_text_input_cursor_width + 1) >> 1) - 1);
176
        }
177
178
373
        cursor_ptr -> gx_text_input_cursor_pos.gx_point_x = new_cursor_pos;
179
373
        break;
180
181
907
    case GX_STYLE_TEXT_LEFT:
182
    default:
183
        /* Calculate cursor position. */
184
907
        new_cursor_pos = (GX_VALUE)(cursor_ptr -> gx_text_input_cursor_pos.gx_point_x + insert_width);
185
186
        /* Update offset in x axis. */
187
907
        if (new_cursor_pos > client_right - 1)
188
        {
189
354
            text_input -> gx_single_line_text_input_xoffset = (GX_VALUE)(text_input -> gx_single_line_text_input_xoffset + new_cursor_pos - client_right + 1);
190
191
354
            new_cursor_pos = (GX_VALUE)(client_right - 1);
192
        }
193
        else
194
        {
195
553
            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));
196
553
            dirty_area.gx_rectangle_right = (GX_VALUE)(new_cursor_pos + text_width + cursor_ptr -> gx_text_input_cursor_width - 1);
197
        }
198
199
        /* Update x coordinate of cursor position. */
200
907
        cursor_ptr -> gx_text_input_cursor_pos.gx_point_x = new_cursor_pos;
201
907
        break;
202
    }
203
204
    /* Mark the text input widget be changed. */
205
1655
    text_input -> gx_single_line_text_input_was_modified = GX_TRUE;
206
207
1655
    _gx_system_dirty_partial_add((GX_WIDGET *)text_input, &dirty_area);
208
209
1655
    return GX_SUCCESS;
210
}
211