1 /*
2  * Copyright 2006 John-Mark Bell <jmb@netsurf-browser.org>
3  * Copyright 2009 Paul Blokus <paul_pl@users.sourceforge.net>
4  *
5  * This file is part of NetSurf, http://www.netsurf-browser.org/
6  *
7  * NetSurf is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; version 2 of the License.
10  *
11  * NetSurf is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 /**
21  * \file
22  * Single/Multi-line UTF-8 text area interface
23  */
24 
25 #ifndef NETSURF_DESKTOP_TEXTAREA_H
26 #define NETSURF_DESKTOP_TEXTAREA_H
27 
28 #include <stdint.h>
29 #include <stdbool.h>
30 
31 #include "netsurf/plot_style.h"
32 #include "netsurf/mouse.h"
33 
34 struct textarea;
35 struct redraw_context;
36 
37 /**
38  * Text area flags
39  */
40 typedef enum {
41 	TEXTAREA_DEFAULT	= (1 << 0),	/**< Standard input */
42 	TEXTAREA_MULTILINE	= (1 << 1),	/**< Multiline area */
43 	TEXTAREA_READONLY	= (1 << 2),	/**< Non-editable */
44 	TEXTAREA_INTERNAL_CARET	= (1 << 3),	/**< Render own caret */
45 	TEXTAREA_PASSWORD	= (1 << 4)	/**< Obscured display */
46 } textarea_flags;
47 
48 
49 /**
50  * Textarea drag status
51  */
52 typedef enum {
53 	TEXTAREA_DRAG_NONE,
54 	TEXTAREA_DRAG_SCROLLBAR,
55 	TEXTAREA_DRAG_SELECTION
56 } textarea_drag_type;
57 
58 
59 /**
60  * textarea message types
61  */
62 typedef enum {
63 	TEXTAREA_MSG_DRAG_REPORT,	/**< Textarea drag start/end report */
64 	TEXTAREA_MSG_SELECTION_REPORT,	/**< Textarea text selection presence */
65 	TEXTAREA_MSG_REDRAW_REQUEST,	/**< Textarea redraw request */
66 	TEXTAREA_MSG_CARET_UPDATE,	/**< Textarea caret */
67 	TEXTAREA_MSG_TEXT_MODIFIED	/**< Textarea text modified */
68 } textarea_msg_type;
69 
70 
71 /**
72  * textarea message
73  */
74 struct textarea_msg {
75 	struct textarea *ta;		/**< The textarea widget */
76 
77 	textarea_msg_type type;		/**< Indicates message data type */
78 	union {
79 		textarea_drag_type drag;	/**< With _DRAG_REPORT */
80 		struct {
81 			bool have_selection;	/**< Selection exists */
82 			bool read_only;		/**< Selection can't be cut */
83 		} selection;			/**< With _SELECTION_REPORT */
84 		struct rect redraw;		/**< With _REDRAW_REQUEST */
85 		struct {
86 			enum {
87 				TEXTAREA_CARET_SET_POS,	/**< Set coord/height */
88 				TEXTAREA_CARET_HIDE	/**< Hide */
89 			} type;
90 			struct {
91 				int x;			/**< Caret x-coord */
92 				int y;			/**< Caret y-coord */
93 				int height;		/**< Caret height */
94 				struct rect *clip;	/**< Caret clip rect */
95 			} pos;			/**< With _CARET_SET_POS */
96 		} caret;			/**< With _CARET_UPDATE */
97 		struct {
98 			const char *text;	/**< UTF8 text */
99 			unsigned int len;	/**< Byte length of text */
100 		} modified;			/**< With _TEXT_MODIFIED */
101 	} data;				/**< Depends on msg type */
102 };
103 
104 
105 /**
106  * textarea setup parameters
107  */
108 typedef struct textarea_setup {
109 	int width;		/**< Textarea width */
110 	int height;		/**< Textarea height */
111 
112 	int pad_top;		/**< Textarea top padding */
113 	int pad_right;		/**< Textarea right padding */
114 	int pad_bottom;		/**< Textarea bottom padding */
115 	int pad_left;		/**< Textarea left padding */
116 
117 	int border_width;	/**< Textarea border width */
118 	colour border_col;	/**< Textarea border colour */
119 
120 	colour selected_text;	/**< Textarea selected text colour */
121 	colour selected_bg;	/**< Textarea selection background colour */
122 	plot_font_style_t text;	/**< Textarea background colour and font */
123 
124 } textarea_setup;
125 
126 
127 /**
128  * Text area mouse input status flags
129  */
130 typedef enum {
131 	TEXTAREA_MOUSE_NONE	= 0,		/**< Not relevant */
132 	TEXTAREA_MOUSE_USED	= (1 <<  0),	/**< Took action with input */
133 	TEXTAREA_MOUSE_EDITOR	= (1 <<  1),	/**< Hover: caret pointer */
134 	TEXTAREA_MOUSE_SELECTION= (1 <<  2),	/**< Hover: selection */
135 	TEXTAREA_MOUSE_SCR_USED	= (1 <<  3),	/**< Scrollbar action */
136 	TEXTAREA_MOUSE_SCR_BOTH	= (1 <<  4),	/**< Scrolling both bars */
137 	TEXTAREA_MOUSE_SCR_UP	= (1 <<  5),	/**< Hover: scroll up */
138 	TEXTAREA_MOUSE_SCR_PUP	= (1 <<  6),	/**< Hover: scroll page up */
139 	TEXTAREA_MOUSE_SCR_VRT	= (1 <<  7),	/**< Hover: vert. drag bar */
140 	TEXTAREA_MOUSE_SCR_PDWN	= (1 <<  8),	/**< Hover: scroll page down */
141 	TEXTAREA_MOUSE_SCR_DWN	= (1 <<  9),	/**< Hover: scroll down */
142 	TEXTAREA_MOUSE_SCR_LFT	= (1 << 10),	/**< Hover: scroll left */
143 	TEXTAREA_MOUSE_SCR_PLFT	= (1 << 11),	/**< Hover: scroll page left */
144 	TEXTAREA_MOUSE_SCR_HRZ	= (1 << 12),	/**< Hover: horiz. drag bar */
145 	TEXTAREA_MOUSE_SCR_PRGT	= (1 << 13),	/**< Hover: scroll page right */
146 	TEXTAREA_MOUSE_SCR_RGT	= (1 << 14)	/**< Hover: scroll right */
147 } textarea_mouse_status;
148 
149 
150 /**
151  * Client callback for the textarea
152  *
153  * \param data user data passed at textarea creation
154  * \param msg textarea message data
155  */
156 typedef void(*textarea_client_callback)(void *data, struct textarea_msg *msg);
157 
158 
159 /**
160  * Create a text area.
161  *
162  * \param flags flags controlling the text area creation
163  * \param setup	textarea settings and style
164  * \param callback will be called when textarea wants to redraw
165  * \param data	user specified data which will be passed to callbacks
166  * \return Opaque handle for textarea or 0 on error
167  */
168 struct textarea *textarea_create(const textarea_flags flags,
169 		const textarea_setup *setup,
170 		textarea_client_callback callback, void *data);
171 
172 
173 /**
174  * Destroy a text area
175  *
176  * \param ta Text area to destroy
177  */
178 void textarea_destroy(struct textarea *ta);
179 
180 
181 /**
182  * Set the text in a text area, discarding any current text
183  *
184  * \param ta Text area
185  * \param text UTF-8 text to set text area's contents to
186  * \return true on success, false on memory exhaustion
187  */
188 bool textarea_set_text(struct textarea *ta, const char *text);
189 
190 
191 /**
192  * Insert the text in a text area at the caret, replacing any selection.
193  *
194  * \param ta Text area
195  * \param text UTF-8 text to set text area's contents to
196  * \param text_length length of text.
197  * \return true on success, false on memory exhaustion or if ta lacks caret
198  */
199 bool textarea_drop_text(struct textarea *ta, const char *text,
200 		size_t text_length);
201 
202 
203 /**
204  * Extract the text from a text area
205  *
206  * \param ta Text area
207  * \param buf Pointer to buffer to receive data, or NULL
208  *            to read length required (includes trailing '\0')
209  * \param len Length (bytes) of buffer pointed to by buf, or 0 to read length
210  * \return Length (bytes) written/required or -1 on error
211  */
212 int textarea_get_text(struct textarea *ta, char *buf, unsigned int len);
213 
214 
215 /**
216  * Access text data in a text area
217  *
218  * \param[in]  ta   Text area
219  * \param[out] len  Returns byte length of returned text, if passed non-NULL.
220  * \return textarea string data.
221  */
222 const char * textarea_data(struct textarea *ta, unsigned int *len);
223 
224 
225 /**
226  * Set the caret's position
227  *
228  * \param ta	Text area
229  * \param caret 0-based character index to place caret at, -1 removes
230  *		  the caret
231  * \return true on success false otherwise
232  */
233 bool textarea_set_caret(struct textarea *ta, int caret);
234 
235 
236 /**
237  * Handle redraw requests for text areas
238  *
239  * \param ta	textarea to render
240  * \param x	x coordinate of textarea top
241  * \param y	y coordinate of textarea left
242  * \param bg	background colour under textarea
243  * \param scale scale to render at
244  * \param clip	clip rectangle
245  * \param ctx	current redraw context
246  */
247 void textarea_redraw(struct textarea *ta, int x, int y, colour bg, float scale,
248 		const struct rect *clip, const struct redraw_context *ctx);
249 
250 
251 /**
252  * Key press handling for text areas.
253  *
254  * \param ta	The text area which got the keypress
255  * \param key	The ucs4 character codepoint
256  * \return	true if the keypress is dealt with, false otherwise.
257  */
258 bool textarea_keypress(struct textarea *ta, uint32_t key);
259 
260 
261 /**
262  * Handles all kinds of mouse action
263  *
264  * \param ta	Text area
265  * \param mouse	the mouse state at action moment
266  * \param x	X coordinate
267  * \param y	Y coordinate
268  * \return the textarea mouse status
269  */
270 textarea_mouse_status textarea_mouse_action(struct textarea *ta,
271 		browser_mouse_state mouse, int x, int y);
272 
273 
274 /**
275  * Clear any selection in the textarea.
276  *
277  * \param ta textarea widget
278  * \return true if there was a selection to clear, false otherwise
279  */
280 bool textarea_clear_selection(struct textarea *ta);
281 
282 
283 /**
284  * Get selected text.
285  *
286  * ownership of the returned string is passed to caller which needs to
287  *  free it.
288  *
289  * \param ta Textarea widget
290  * \return Selected text, or NULL if none.
291  */
292 char *textarea_get_selection(struct textarea *ta);
293 
294 
295 /**
296  * Gets the dimensions of a textarea
297  *
298  * \param ta		textarea widget
299  * \param width		if not NULL, gets updated to the width of the textarea
300  * \param height	if not NULL, gets updated to the height of the textarea
301  */
302 void textarea_get_dimensions(struct textarea *ta, int *width, int *height);
303 
304 
305 /**
306  * Set the dimensions of a textarea.
307  *
308  * This causes a reflow of the text and does not emit a redraw
309  * request.  Up to client to call textarea_redraw.
310  *
311  * \param ta		textarea widget
312  * \param width		the new width of the textarea
313  * \param height	the new height of the textarea
314  */
315 void textarea_set_dimensions(struct textarea *ta, int width, int height);
316 
317 
318 /**
319  * Set the dimensions and padding of a textarea.
320  *
321  * This causes a reflow of the text. Does not emit a redraw request.
322  * Up to client to call textarea_redraw.
323  *
324  * \param ta		textarea widget
325  * \param width		the new width of the textarea
326  * \param height	the new height of the textarea
327  * \param top		the new top padding of the textarea
328  * \param right		the new right padding of the textarea
329  * \param bottom	the new bottom padding of the textarea
330  * \param left		the new left padding of the textarea
331  */
332 void textarea_set_layout(
333 		struct textarea *ta,
334 		const plot_font_style_t *fstyle,
335 		int width, int height,
336 		int top, int right,
337 		int bottom, int left);
338 
339 
340 /**
341  * Scroll a textarea by an amount.
342  *
343  * Only does anything if multi-line textarea has scrollbars.  If it
344  * scrolls, it will emit a redraw request.
345  *
346  * \param ta	textarea widget
347  * \param scrx	number of px try to scroll in x direction
348  * \param scry	number of px try to scroll in y direction
349  * \return true iff the textarea was scrolled
350  */
351 bool textarea_scroll(struct textarea *ta, int scrx, int scry);
352 
353 #endif
354