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