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 /**   Multi Line Text Input Management (Multi 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_window.h"
29 #include "gx_widget.h"
30 #include "gx_scrollbar.h"
31 #include "gx_multi_line_text_view.h"
32 #include "gx_multi_line_text_input.h"
33 #include "gx_utility.h"
34 
35 /**************************************************************************/
36 /*                                                                        */
37 /*  FUNCTION                                               RELEASE        */
38 /*                                                                        */
39 /*    _gx_multi_line_text_input_cursor_visible            PORTABLE C      */
40 /*                                                           6.1          */
41 /*  AUTHOR                                                                */
42 /*                                                                        */
43 /*    Kenneth Maxwell, Microsoft Corporation                              */
44 /*                                                                        */
45 /*  DESCRIPTION                                                           */
46 /*                                                                        */
47 /*    This function scrolls multi line text input text to make the cursor */
48 /*    visible.                                                            */
49 /*                                                                        */
50 /*  INPUT                                                                 */
51 /*                                                                        */
52 /*    text_input                            Multi line text input         */
53 /*                                            control block               */
54 /*                                                                        */
55 /*  OUTPUT                                                                */
56 /*                                                                        */
57 /*    None                                                                */
58 /*                                                                        */
59 /*  CALLS                                                                 */
60 /*                                                                        */
61 /*    _gx_window_scrollbar_find             Find scrollbar for a window   */
62 /*    _gx_scrollbar_reset                   Reset scrollbar information   */
63 /*    _gx_multi_line_text_view_line_cache_update                          */
64 /*                                          Update line index cache       */
65 /*    _gx_system_dirty_mark                 Mark widget as dirty          */
66 /*    _gx_utility_rectangle_resize          Increase the size of rectangle*/
67 /*                                            as specified                */
68 /*                                                                        */
69 /*  CALLED BY                                                             */
70 /*                                                                        */
71 /*    GUIX Intercal Code                                                  */
72 /*                                                                        */
73 /*  RELEASE HISTORY                                                       */
74 /*                                                                        */
75 /*    DATE              NAME                      DESCRIPTION             */
76 /*                                                                        */
77 /*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
78 /*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
79 /*                                            resulting in version 6.1    */
80 /*                                                                        */
81 /**************************************************************************/
82 
_gx_multi_line_text_input_cursor_visible(GX_MULTI_LINE_TEXT_INPUT * text_input)83 UINT _gx_multi_line_text_input_cursor_visible(GX_MULTI_LINE_TEXT_INPUT *text_input)
84 {
85 GX_TEXT_INPUT_CURSOR *cursor_ptr = &text_input -> gx_multi_line_text_input_cursor_instance;
86 GX_RECTANGLE          client;
87 INT                   shift;
88 GX_SCROLLBAR         *scroll;
89 GX_FONT              *font;
90 GX_VALUE              line_height;
91 GX_VALUE              ypos;
92 
93     _gx_widget_font_get((GX_WIDGET *)text_input, text_input -> gx_multi_line_text_view_font_id, &font);
94 
95     if (!font)
96     {
97         return GX_FAILURE;
98     }
99 
100     client = text_input -> gx_window_client;
101 
102     if (text_input -> gx_multi_line_text_view_whitespace)
103     {
104         /* Offset client bounding box.  */
105         _gx_utility_rectangle_resize(&client, (GX_VALUE)(-text_input -> gx_multi_line_text_view_whitespace));
106     }
107 
108     line_height = (GX_VALUE)(font -> gx_font_line_height + text_input -> gx_multi_line_text_view_line_space);
109 
110     ypos = (GX_VALUE)(cursor_ptr -> gx_text_input_cursor_pos.gx_point_y - (line_height >> 1));
111 
112     if (ypos < client.gx_rectangle_top)
113     {
114         shift = client.gx_rectangle_top - ypos;
115     }
116     else if (ypos + line_height - 1 > client.gx_rectangle_bottom)
117     {
118         shift = client.gx_rectangle_bottom - (ypos + line_height - 1);
119     }
120     else
121     {
122         shift = 0;
123     }
124 
125     if (shift)
126     {
127         text_input -> gx_multi_line_text_view_text_scroll_shift += shift;
128         cursor_ptr -> gx_text_input_cursor_pos.gx_point_y = (GX_VALUE)(cursor_ptr -> gx_text_input_cursor_pos.gx_point_y + shift);
129 
130         _gx_window_scrollbar_find((GX_WINDOW *)text_input, GX_TYPE_VERTICAL_SCROLL, &scroll);
131         if (scroll)
132         {
133             /* Reset scrollbar.  */
134             _gx_scrollbar_reset(scroll, GX_NULL);
135         }
136         else
137         {
138 
139             if (text_input -> gx_multi_line_text_view_text_total_rows >
140                 text_input -> gx_multi_line_text_view_cache_size)
141             {
142                 _gx_multi_line_text_view_line_cache_update((GX_MULTI_LINE_TEXT_VIEW *)text_input);
143             }
144         }
145 
146         _gx_system_dirty_mark((GX_WIDGET *)text_input);
147     }
148 
149     return GX_SUCCESS;
150 }
151 
152