GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_single_line_text_input_draw.c Lines: 71 71 100.0 %
Date: 2024-12-05 08:52:37 Branches: 28 28 100.0 %

Line Branch Exec Source
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
/**   Text Input Management (Single Line Text Input)                      */
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_utility.h"
29
#include "gx_canvas.h"
30
#include "gx_context.h"
31
#include "gx_widget.h"
32
#include "gx_single_line_text_input.h"
33
#include "gx_text_input_cursor.h"
34
35
/**************************************************************************/
36
/*                                                                        */
37
/*  FUNCTION                                               RELEASE        */
38
/*                                                                        */
39
/*    _gx_single_line_text_input_draw                     PORTABLE C      */
40
/*                                                           6.1          */
41
/*  AUTHOR                                                                */
42
/*                                                                        */
43
/*    Kenneth Maxwell, Microsoft Corporation                              */
44
/*                                                                        */
45
/*  DESCRIPTION                                                           */
46
/*                                                                        */
47
/*    This service draws a text input widget. This service is normally    */
48
/*    called internally during canvas refresh, but can also be called from*/
49
/*    custom text input drawing functions.                                */
50
/*                                                                        */
51
/*  INPUT                                                                 */
52
/*                                                                        */
53
/*    text_input                            Single-line text input widget */
54
/*                                            control block.              */
55
/*                                                                        */
56
/*  OUTPUT                                                                */
57
/*                                                                        */
58
/*    None                                                                */
59
/*                                                                        */
60
/*  CALLS                                                                 */
61
/*                                                                        */
62
/*    _gx_widget_background_draw            Draw widget background        */
63
/*    _gx_widget_border_draw                Draw widget border            */
64
/*    _gx_widget_border_width_get           Get widget border width       */
65
/*    _gx_widget_client_get                 Get widget client rectangle   */
66
/*   _gx_widget_children_draw               Draw widget children          */
67
/*    _gx_context_line_color_set            Set the line color for the    */
68
/*                                            context                     */
69
/*    _gx_context_font_set                  Set the font in the context   */
70
/*    _gx_context_brush_width_set           Set the width of brush        */
71
/*    _gx_canvas_text_draw                  Draw the text                 */
72
/*    _gx_canvas_drawing_initiate           Initiate drawing on specified */
73
/*                                            canvas                      */
74
/*    _gx_canvas_drawing_complete           Complete drawing on specified */
75
/*                                            canvas                      */
76
/*    _gx_text_input_cursor_draw            Draw a text input cursor      */
77
/*    _gx_utility_rectangle_overlap_detect  Detect overlap of the         */
78
/*                                            supplied rectangles         */
79
/*    _gx_single_line_text_input_draw_position_get                        */
80
/*                                          Get text draw start position  */
81
/*                                                                        */
82
/*  CALLED BY                                                             */
83
/*                                                                        */
84
/*    Application Code                                                    */
85
/*    GUIX Internal Code                                                  */
86
/*                                                                        */
87
/*  RELEASE HISTORY                                                       */
88
/*                                                                        */
89
/*    DATE              NAME                      DESCRIPTION             */
90
/*                                                                        */
91
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
92
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
93
/*                                            resulting in version 6.1    */
94
/*                                                                        */
95
/**************************************************************************/
96
50740
VOID  _gx_single_line_text_input_draw(GX_SINGLE_LINE_TEXT_INPUT *text_input)
97
{
98
50740
UINT                  status = GX_SUCCESS;
99
50740
GX_WIDGET            *widget = (GX_WIDGET *)text_input;
100
50740
GX_TEXT_INPUT_CURSOR *cursor_ptr = &text_input -> gx_single_line_text_input_cursor_instance;
101
GX_RESOURCE_ID        fill_color;
102
GX_RESOURCE_ID        text_color;
103
GX_VALUE              border_width;
104
GX_VALUE              client_height;
105
GX_VALUE              x_pos;
106
GX_VALUE              y_pos;
107
GX_RECTANGLE          client;
108
GX_RECTANGLE          overlap;
109
GX_CANVAS            *canvas;
110
50740
UINT                  start_mark = text_input -> gx_single_line_text_input_start_mark;
111
50740
UINT                  end_mark = text_input -> gx_single_line_text_input_end_mark;
112
GX_VALUE              text_width;
113
GX_BRUSH             *brush;
114
50740
GX_CHAR              *input_buffer = text_input -> gx_single_line_text_input_buffer;
115
GX_STRING             string;
116
117
    /* Draw text input background.  */
118
50740
    if (text_input -> gx_widget_style & GX_STYLE_ENABLED)
119
    {
120
50731
        if (text_input -> gx_widget_style & GX_STYLE_TEXT_INPUT_READONLY)
121
        {
122
6
            fill_color = text_input -> gx_single_line_text_input_readonly_fill_color;
123
6
            text_color = text_input -> gx_single_line_text_input_readonly_text_color;
124
        }
125
        else
126
        {
127
50725
            fill_color = text_input -> gx_widget_normal_fill_color;
128
50725
            text_color = text_input -> gx_prompt_normal_text_color;
129
        }
130
    }
131
    else
132
    {
133
9
        fill_color = text_input -> gx_widget_disabled_fill_color;
134
9
        text_color = text_input -> gx_prompt_disabled_text_color;
135
    }
136
137
50740
    _gx_widget_border_draw(widget, GX_COLOR_ID_WINDOW_BORDER, fill_color, fill_color, GX_TRUE);
138
139
50740
    _gx_context_font_set(text_input -> gx_prompt_font_id);
140
141
    /* Calculate text draw position. */
142
50740
    status = _gx_single_line_text_input_draw_position_get(text_input, &x_pos, &y_pos);
143
144
50740
    if (status != GX_SUCCESS)
145
    {
146
6
        return;
147
    }
148
149
    /* Pickup widget width. */
150
50734
    _gx_widget_border_width_get(widget, &border_width);
151
152
    /* Get client rectangle. */
153
50734
    _gx_widget_client_get(widget, border_width, &client);
154
155
50734
    _gx_context_line_color_set(text_color);
156
157
    /* pick up current canvas */
158
50734
    canvas = _gx_system_current_draw_context -> gx_draw_context_canvas;
159
50734
    _gx_utility_rectangle_overlap_detect(&_gx_system_current_draw_context -> gx_draw_context_dirty, &client, &overlap);
160
50734
    _gx_canvas_drawing_initiate(canvas, widget, &overlap);
161
162
    /* Draw the cursor. */
163
50734
    if ((start_mark == end_mark) &&
164
48806
        (text_input -> gx_widget_status & GX_STATUS_CURSOR_SHOW) &&
165
17203
        (text_input -> gx_widget_status & GX_STATUS_CURSOR_DRAW))
166
    {
167
17197
        client_height = (GX_VALUE)(client.gx_rectangle_bottom - client.gx_rectangle_top + 1);
168
169
17197
        if (!(cursor_ptr -> gx_text_input_cursor_flags & GX_CURSOR_USE_CUSTOM_HEIGHT))
170
        {
171
17192
            cursor_ptr -> gx_text_input_cursor_height = (GX_VALUE)(client_height - 4);
172
        }
173
17197
        cursor_ptr -> gx_text_input_cursor_pos.gx_point_y = (GX_VALUE)(client.gx_rectangle_top + (client_height >> 1));
174
175
17197
        _gx_text_input_cursor_draw(cursor_ptr);
176
    }
177
178
    /* Is there a string?  */
179

50734
    if (input_buffer && (*input_buffer))
180
    {
181
        /* Draw the text.  */
182
44900
        if (start_mark == end_mark)
183
        {
184
42973
            string.gx_string_ptr = input_buffer;
185
42973
            string.gx_string_length = text_input -> gx_single_line_text_input_string_size;
186
42973
            _gx_canvas_text_draw_ext(x_pos, y_pos, &string);
187
        }
188
        else
189
        {
190
1927
            _gx_context_brush_get(&brush);
191
192
1927
            if (start_mark > end_mark)
193
            {
194
1024
                GX_SWAP_VALS(start_mark, end_mark);
195
            }
196
197
1927
            if (start_mark > 0)
198
            {
199
                /* Draw text[0:start_mark - 1] with normak text color. */
200
1351
                string.gx_string_ptr = input_buffer;
201
1351
                string.gx_string_length = start_mark;
202
1351
                _gx_system_string_width_get_ext(brush -> gx_brush_font, &string, &text_width);
203
1351
                _gx_canvas_text_draw_ext(x_pos, y_pos, &string);
204
1351
                x_pos = (GX_VALUE)(x_pos + text_width);
205
            }
206
207
            /* Draw text[start_mark:end_mark - 1] with highlight text color. */
208
1927
            _gx_context_line_color_set(text_input -> gx_prompt_selected_text_color);
209
1927
            _gx_context_fill_color_set(text_input -> gx_widget_selected_fill_color);
210
1927
            _gx_context_brush_width_set(0);
211
212
1927
            string.gx_string_ptr = input_buffer + start_mark;
213
1927
            string.gx_string_length = (UINT)(end_mark - start_mark);
214
1927
            _gx_system_string_width_get_ext(brush -> gx_brush_font, &string, &text_width);
215
216
1927
            client_height = (GX_VALUE)(client.gx_rectangle_bottom - client.gx_rectangle_top + 1);
217
218
1927
            if (!(cursor_ptr -> gx_text_input_cursor_flags & GX_CURSOR_USE_CUSTOM_HEIGHT))
219
            {
220
1922
                cursor_ptr -> gx_text_input_cursor_height = (GX_VALUE)(client_height - 4);
221
            }
222
223
1927
            client.gx_rectangle_left = x_pos;
224
1927
            client.gx_rectangle_right = (GX_VALUE)(x_pos + text_width - 1);
225
1927
            client.gx_rectangle_top = (GX_VALUE)(client.gx_rectangle_top + ((client_height - cursor_ptr -> gx_text_input_cursor_height) >> 1));
226
1927
            client.gx_rectangle_bottom = (GX_VALUE)(client.gx_rectangle_top + cursor_ptr -> gx_text_input_cursor_height - 1);
227
228
1927
            _gx_canvas_rectangle_draw(&client);
229
1927
            _gx_canvas_text_draw_ext(x_pos, y_pos, &string);
230
1927
            x_pos = (GX_VALUE)(x_pos + text_width);
231
232
1927
            if (end_mark < text_input -> gx_single_line_text_input_string_size)
233
            {
234
                /* Draw text[end_mark:] with normal text color. */
235
1618
                _gx_context_line_color_set(text_color);
236
237
1618
                string.gx_string_ptr = input_buffer + end_mark;
238
1618
                string.gx_string_length = text_input -> gx_single_line_text_input_string_size - end_mark;
239
1618
                _gx_canvas_text_draw_ext(x_pos, y_pos, &string);
240
            }
241
        }
242
    }
243
244
50734
    _gx_canvas_drawing_complete(canvas, GX_FALSE);
245
246
50734
    _gx_widget_children_draw(widget);
247
}
248