1 /**************************************************************************/
2 /* */
3 /* Copyright (c) Microsoft Corporation. All rights reserved. */
4 /* */
5 /* This software is licensed under the Microsoft Software License */
6 /* Terms for Microsoft Azure RTOS. Full text of the license can be */
7 /* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
8 /* and in the root directory of this software. */
9 /* */
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_utility.h"
30 #include "gx_canvas.h"
31 #include "gx_context.h"
32 #include "gx_widget.h"
33 #include "gx_single_line_text_input.h"
34 #include "gx_text_input_cursor.h"
35
36 /**************************************************************************/
37 /* */
38 /* FUNCTION RELEASE */
39 /* */
40 /* _gx_single_line_text_input_draw PORTABLE C */
41 /* 6.1 */
42 /* AUTHOR */
43 /* */
44 /* Kenneth Maxwell, Microsoft Corporation */
45 /* */
46 /* DESCRIPTION */
47 /* */
48 /* This service draws a text input widget. This service is normally */
49 /* called internally during canvas refresh, but can also be called from*/
50 /* custom text input drawing functions. */
51 /* */
52 /* INPUT */
53 /* */
54 /* text_input Single-line text input widget */
55 /* control block. */
56 /* */
57 /* OUTPUT */
58 /* */
59 /* None */
60 /* */
61 /* CALLS */
62 /* */
63 /* _gx_widget_background_draw Draw widget background */
64 /* _gx_widget_border_draw Draw widget border */
65 /* _gx_widget_border_width_get Get widget border width */
66 /* _gx_widget_client_get Get widget client rectangle */
67 /* _gx_widget_children_draw Draw widget children */
68 /* _gx_context_line_color_set Set the line color for the */
69 /* context */
70 /* _gx_context_font_set Set the font in the context */
71 /* _gx_context_brush_width_set Set the width of brush */
72 /* _gx_canvas_text_draw Draw the text */
73 /* _gx_canvas_drawing_initiate Initiate drawing on specified */
74 /* canvas */
75 /* _gx_canvas_drawing_complete Complete drawing on specified */
76 /* canvas */
77 /* _gx_text_input_cursor_draw Draw a text input cursor */
78 /* _gx_utility_rectangle_overlap_detect Detect overlap of the */
79 /* supplied rectangles */
80 /* _gx_single_line_text_input_draw_position_get */
81 /* Get text draw start position */
82 /* */
83 /* CALLED BY */
84 /* */
85 /* Application Code */
86 /* GUIX Internal Code */
87 /* */
88 /* RELEASE HISTORY */
89 /* */
90 /* DATE NAME DESCRIPTION */
91 /* */
92 /* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */
93 /* 09-30-2020 Kenneth Maxwell Modified comment(s), */
94 /* resulting in version 6.1 */
95 /* */
96 /**************************************************************************/
_gx_single_line_text_input_draw(GX_SINGLE_LINE_TEXT_INPUT * text_input)97 VOID _gx_single_line_text_input_draw(GX_SINGLE_LINE_TEXT_INPUT *text_input)
98 {
99 UINT status = GX_SUCCESS;
100 GX_WIDGET *widget = (GX_WIDGET *)text_input;
101 GX_TEXT_INPUT_CURSOR *cursor_ptr = &text_input -> gx_single_line_text_input_cursor_instance;
102 GX_RESOURCE_ID fill_color;
103 GX_RESOURCE_ID text_color;
104 GX_VALUE border_width;
105 GX_VALUE client_height;
106 GX_VALUE x_pos;
107 GX_VALUE y_pos;
108 GX_RECTANGLE client;
109 GX_RECTANGLE overlap;
110 GX_CANVAS *canvas;
111 UINT start_mark = text_input -> gx_single_line_text_input_start_mark;
112 UINT end_mark = text_input -> gx_single_line_text_input_end_mark;
113 GX_VALUE text_width;
114 GX_BRUSH *brush;
115 GX_CHAR *input_buffer = text_input -> gx_single_line_text_input_buffer;
116 GX_STRING string;
117
118 /* Draw text input background. */
119 if (text_input -> gx_widget_style & GX_STYLE_ENABLED)
120 {
121 if (text_input -> gx_widget_style & GX_STYLE_TEXT_INPUT_READONLY)
122 {
123 fill_color = text_input -> gx_single_line_text_input_readonly_fill_color;
124 text_color = text_input -> gx_single_line_text_input_readonly_text_color;
125 }
126 else
127 {
128 fill_color = text_input -> gx_widget_normal_fill_color;
129 text_color = text_input -> gx_prompt_normal_text_color;
130 }
131 }
132 else
133 {
134 fill_color = text_input -> gx_widget_disabled_fill_color;
135 text_color = text_input -> gx_prompt_disabled_text_color;
136 }
137
138 _gx_widget_border_draw(widget, GX_COLOR_ID_WINDOW_BORDER, fill_color, fill_color, GX_TRUE);
139
140 _gx_context_font_set(text_input -> gx_prompt_font_id);
141
142 /* Calculate text draw position. */
143 status = _gx_single_line_text_input_draw_position_get(text_input, &x_pos, &y_pos);
144
145 if (status != GX_SUCCESS)
146 {
147 return;
148 }
149
150 /* Pickup widget width. */
151 _gx_widget_border_width_get(widget, &border_width);
152
153 /* Get client rectangle. */
154 _gx_widget_client_get(widget, border_width, &client);
155
156 _gx_context_line_color_set(text_color);
157
158 /* pick up current canvas */
159 canvas = _gx_system_current_draw_context -> gx_draw_context_canvas;
160 _gx_utility_rectangle_overlap_detect(&_gx_system_current_draw_context -> gx_draw_context_dirty, &client, &overlap);
161 _gx_canvas_drawing_initiate(canvas, widget, &overlap);
162
163 /* Draw the cursor. */
164 if ((start_mark == end_mark) &&
165 (text_input -> gx_widget_status & GX_STATUS_CURSOR_SHOW) &&
166 (text_input -> gx_widget_status & GX_STATUS_CURSOR_DRAW))
167 {
168 client_height = (GX_VALUE)(client.gx_rectangle_bottom - client.gx_rectangle_top + 1);
169
170 if (!(cursor_ptr -> gx_text_input_cursor_flags & GX_CURSOR_USE_CUSTOM_HEIGHT))
171 {
172 cursor_ptr -> gx_text_input_cursor_height = (GX_VALUE)(client_height - 4);
173 }
174 cursor_ptr -> gx_text_input_cursor_pos.gx_point_y = (GX_VALUE)(client.gx_rectangle_top + (client_height >> 1));
175
176 _gx_text_input_cursor_draw(cursor_ptr);
177 }
178
179 /* Is there a string? */
180 if (input_buffer && (*input_buffer))
181 {
182 /* Draw the text. */
183 if (start_mark == end_mark)
184 {
185 string.gx_string_ptr = input_buffer;
186 string.gx_string_length = text_input -> gx_single_line_text_input_string_size;
187 _gx_canvas_text_draw_ext(x_pos, y_pos, &string);
188 }
189 else
190 {
191 _gx_context_brush_get(&brush);
192
193 if (start_mark > end_mark)
194 {
195 GX_SWAP_VALS(start_mark, end_mark);
196 }
197
198 if (start_mark > 0)
199 {
200 /* Draw text[0:start_mark - 1] with normak text color. */
201 string.gx_string_ptr = input_buffer;
202 string.gx_string_length = start_mark;
203 _gx_system_string_width_get_ext(brush -> gx_brush_font, &string, &text_width);
204 _gx_canvas_text_draw_ext(x_pos, y_pos, &string);
205 x_pos = (GX_VALUE)(x_pos + text_width);
206 }
207
208 /* Draw text[start_mark:end_mark - 1] with highlight text color. */
209 _gx_context_line_color_set(text_input -> gx_prompt_selected_text_color);
210 _gx_context_fill_color_set(text_input -> gx_widget_selected_fill_color);
211 _gx_context_brush_width_set(0);
212
213 string.gx_string_ptr = input_buffer + start_mark;
214 string.gx_string_length = (UINT)(end_mark - start_mark);
215 _gx_system_string_width_get_ext(brush -> gx_brush_font, &string, &text_width);
216
217 client_height = (GX_VALUE)(client.gx_rectangle_bottom - client.gx_rectangle_top + 1);
218
219 if (!(cursor_ptr -> gx_text_input_cursor_flags & GX_CURSOR_USE_CUSTOM_HEIGHT))
220 {
221 cursor_ptr -> gx_text_input_cursor_height = (GX_VALUE)(client_height - 4);
222 }
223
224 client.gx_rectangle_left = x_pos;
225 client.gx_rectangle_right = (GX_VALUE)(x_pos + text_width - 1);
226 client.gx_rectangle_top = (GX_VALUE)(client.gx_rectangle_top + ((client_height - cursor_ptr -> gx_text_input_cursor_height) >> 1));
227 client.gx_rectangle_bottom = (GX_VALUE)(client.gx_rectangle_top + cursor_ptr -> gx_text_input_cursor_height - 1);
228
229 _gx_canvas_rectangle_draw(&client);
230 _gx_canvas_text_draw_ext(x_pos, y_pos, &string);
231 x_pos = (GX_VALUE)(x_pos + text_width);
232
233 if (end_mark < text_input -> gx_single_line_text_input_string_size)
234 {
235 /* Draw text[end_mark:] with normal text color. */
236 _gx_context_line_color_set(text_color);
237
238 string.gx_string_ptr = input_buffer + end_mark;
239 string.gx_string_length = text_input -> gx_single_line_text_input_string_size - end_mark;
240 _gx_canvas_text_draw_ext(x_pos, y_pos, &string);
241 }
242 }
243 }
244
245 _gx_canvas_drawing_complete(canvas, GX_FALSE);
246
247 _gx_widget_children_draw(widget);
248 }
249
250