source: mainline/uspace/lib/ui/src/entry.c@ 73abf49

serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 73abf49 was db3895d, checked in by Jiri Svoboda <jiri@…>, 5 years ago

Set cursor shape to I-beam when hovering over text entry

  • Property mode set to 100644
File size: 6.6 KB
Line 
1/*
2 * Copyright (c) 2021 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup libui
30 * @{
31 */
32/**
33 * @file Text entry.
34 *
35 * Currentry text entry is always read-only. It differs from label mostly
36 * by its looks.
37 */
38
39#include <errno.h>
40#include <gfx/context.h>
41#include <gfx/render.h>
42#include <gfx/text.h>
43#include <stdlib.h>
44#include <str.h>
45#include <ui/control.h>
46#include <ui/paint.h>
47#include <ui/entry.h>
48#include <ui/ui.h>
49#include <ui/window.h>
50#include "../private/entry.h"
51#include "../private/resource.h"
52
53static void ui_entry_ctl_destroy(void *);
54static errno_t ui_entry_ctl_paint(void *);
55static ui_evclaim_t ui_entry_ctl_pos_event(void *, pos_event_t *);
56
57enum {
58 ui_entry_hpad = 4,
59 ui_entry_vpad = 4,
60 ui_entry_hpad_text = 1,
61 ui_entry_vpad_text = 0
62};
63
64/** Text entry control ops */
65ui_control_ops_t ui_entry_ops = {
66 .destroy = ui_entry_ctl_destroy,
67 .paint = ui_entry_ctl_paint,
68 .pos_event = ui_entry_ctl_pos_event
69};
70
71/** Create new text entry.
72 *
73 * @param window UI window
74 * @param text Text
75 * @param rentry Place to store pointer to new text entry
76 * @return EOK on success, ENOMEM if out of memory
77 */
78errno_t ui_entry_create(ui_window_t *window, const char *text,
79 ui_entry_t **rentry)
80{
81 ui_entry_t *entry;
82 errno_t rc;
83
84 entry = calloc(1, sizeof(ui_entry_t));
85 if (entry == NULL)
86 return ENOMEM;
87
88 rc = ui_control_new(&ui_entry_ops, (void *) entry, &entry->control);
89 if (rc != EOK) {
90 free(entry);
91 return rc;
92 }
93
94 entry->text = str_dup(text);
95 if (entry->text == NULL) {
96 ui_control_delete(entry->control);
97 free(entry);
98 return ENOMEM;
99 }
100
101 entry->window = window;
102 entry->halign = gfx_halign_left;
103 *rentry = entry;
104 return EOK;
105}
106
107/** Destroy text entry.
108 *
109 * @param entry Text entry or @c NULL
110 */
111void ui_entry_destroy(ui_entry_t *entry)
112{
113 if (entry == NULL)
114 return;
115
116 ui_control_delete(entry->control);
117 free(entry);
118}
119
120/** Get base control from text entry.
121 *
122 * @param entry Text entry
123 * @return Control
124 */
125ui_control_t *ui_entry_ctl(ui_entry_t *entry)
126{
127 return entry->control;
128}
129
130/** Set text entry rectangle.
131 *
132 * @param entry Text entry
133 * @param rect New text entry rectangle
134 */
135void ui_entry_set_rect(ui_entry_t *entry, gfx_rect_t *rect)
136{
137 entry->rect = *rect;
138}
139
140/** Set text entry horizontal text alignment.
141 *
142 * @param entry Text entry
143 * @param halign Horizontal alignment
144 */
145void ui_entry_set_halign(ui_entry_t *entry, gfx_halign_t halign)
146{
147 entry->halign = halign;
148}
149
150/** Set entry text.
151 *
152 * @param entry Text entry
153 * @param text New entry text
154 * @return EOK on success, ENOMEM if out of memory
155 */
156errno_t ui_entry_set_text(ui_entry_t *entry, const char *text)
157{
158 char *tcopy;
159
160 tcopy = str_dup(text);
161 if (tcopy == NULL)
162 return ENOMEM;
163
164 free(entry->text);
165 entry->text = tcopy;
166
167 return EOK;
168}
169
170/** Paint text entry.
171 *
172 * @param entry Text entry
173 * @return EOK on success or an error code
174 */
175errno_t ui_entry_paint(ui_entry_t *entry)
176{
177 ui_resource_t *res;
178 gfx_text_fmt_t fmt;
179 gfx_coord2_t pos;
180 gfx_coord_t hpad;
181 gfx_coord_t vpad;
182 gfx_rect_t inside;
183 errno_t rc;
184
185 res = ui_window_get_res(entry->window);
186
187 if (res->textmode) {
188 hpad = ui_entry_hpad_text;
189 vpad = ui_entry_vpad_text;
190 } else {
191 hpad = ui_entry_hpad;
192 vpad = ui_entry_vpad;
193 }
194
195 if (res->textmode == false) {
196 /* Paint inset frame */
197 rc = ui_paint_inset_frame(res, &entry->rect, &inside);
198 if (rc != EOK)
199 goto error;
200 } else {
201 inside = entry->rect;
202 }
203
204 /* Paint entry background */
205
206 rc = gfx_set_color(res->gc, res->entry_bg_color);
207 if (rc != EOK)
208 goto error;
209
210 rc = gfx_fill_rect(res->gc, &inside);
211 if (rc != EOK)
212 goto error;
213
214 switch (entry->halign) {
215 case gfx_halign_left:
216 case gfx_halign_justify:
217 pos.x = inside.p0.x + hpad;
218 break;
219 case gfx_halign_center:
220 pos.x = (inside.p0.x + inside.p1.x) / 2;
221 break;
222 case gfx_halign_right:
223 pos.x = inside.p1.x - hpad - 1;
224 break;
225 }
226
227 pos.y = inside.p0.y + vpad;
228
229 gfx_text_fmt_init(&fmt);
230 fmt.color = res->entry_fg_color;
231 fmt.halign = entry->halign;
232 fmt.valign = gfx_valign_top;
233
234 rc = gfx_puttext(res->font, &pos, &fmt, entry->text);
235 if (rc != EOK)
236 goto error;
237
238 rc = gfx_update(res->gc);
239 if (rc != EOK)
240 goto error;
241
242 return EOK;
243error:
244 return rc;
245}
246
247/** Destroy text entry control.
248 *
249 * @param arg Argument (ui_entry_t *)
250 */
251void ui_entry_ctl_destroy(void *arg)
252{
253 ui_entry_t *entry = (ui_entry_t *) arg;
254
255 ui_entry_destroy(entry);
256}
257
258/** Paint text entry control.
259 *
260 * @param arg Argument (ui_entry_t *)
261 * @return EOK on success or an error code
262 */
263errno_t ui_entry_ctl_paint(void *arg)
264{
265 ui_entry_t *entry = (ui_entry_t *) arg;
266
267 return ui_entry_paint(entry);
268}
269
270/** Handle text entry control position event.
271 *
272 * @param arg Argument (ui_entry_t *)
273 * @param pos_event Position event
274 * @return @c ui_claimed iff the event is claimed
275 */
276ui_evclaim_t ui_entry_ctl_pos_event(void *arg, pos_event_t *event)
277{
278 ui_entry_t *entry = (ui_entry_t *) arg;
279 gfx_coord2_t pos;
280
281 if (event->type == POS_UPDATE) {
282 pos.x = event->hpos;
283 pos.y = event->vpos;
284
285 if (gfx_pix_inside_rect(&pos, &entry->rect)) {
286 if (!entry->pointer_inside) {
287 ui_window_set_ctl_cursor(entry->window,
288 ui_curs_ibeam);
289 entry->pointer_inside = true;
290 }
291 } else {
292 if (entry->pointer_inside) {
293 ui_window_set_ctl_cursor(entry->window,
294 ui_curs_arrow);
295 entry->pointer_inside = false;
296 }
297 }
298 }
299
300 return ui_unclaimed;
301}
302
303/** @}
304 */
Note: See TracBrowser for help on using the repository browser.