summaryrefslogtreecommitdiff
path: root/desktop/textarea.h
blob: 82e0de95bbd90e09cfb2ce14166e29c472ecec89 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
/*
 * Copyright 2006 John-Mark Bell <jmb@netsurf-browser.org>
 * Copyright 2009 Paul Blokus <paul_pl@users.sourceforge.net>
 *
 * This file is part of NetSurf, http://www.netsurf-browser.org/
 *
 * NetSurf is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License.
 *
 * NetSurf is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/**
 * \file
 * Single/Multi-line UTF-8 text area interface
 */

#ifndef NETSURF_DESKTOP_TEXTAREA_H
#define NETSURF_DESKTOP_TEXTAREA_H

#include <stdint.h>
#include <stdbool.h>

#include "netsurf/plot_style.h"
#include "netsurf/mouse.h"

struct textarea;
struct redraw_context;

/**
 * Text area flags
 */
typedef enum {
	TEXTAREA_DEFAULT	= (1 << 0),	/**< Standard input */
	TEXTAREA_MULTILINE	= (1 << 1),	/**< Multiline area */
	TEXTAREA_READONLY	= (1 << 2),	/**< Non-editable */
	TEXTAREA_INTERNAL_CARET	= (1 << 3),	/**< Render own caret */
	TEXTAREA_PASSWORD	= (1 << 4)	/**< Obscured display */
} textarea_flags;


/**
 * Textarea drag status
 */
typedef enum {
	TEXTAREA_DRAG_NONE,
	TEXTAREA_DRAG_SCROLLBAR,
	TEXTAREA_DRAG_SELECTION
} textarea_drag_type;


/**
 * textarea message types
 */
typedef enum {
	TEXTAREA_MSG_DRAG_REPORT,	/**< Textarea drag start/end report */
	TEXTAREA_MSG_SELECTION_REPORT,	/**< Textarea text selection presence */
	TEXTAREA_MSG_REDRAW_REQUEST,	/**< Textarea redraw request */
	TEXTAREA_MSG_CARET_UPDATE,	/**< Textarea caret */
	TEXTAREA_MSG_TEXT_MODIFIED	/**< Textarea text modified */
} textarea_msg_type;


/**
 * textarea message
 */
struct textarea_msg {
	struct textarea *ta;		/**< The textarea widget */

	textarea_msg_type type;		/**< Indicates message data type */
	union {
		textarea_drag_type drag;	/**< With _DRAG_REPORT */
		struct {
			bool have_selection;	/**< Selection exists */
			bool read_only;		/**< Selection can't be cut */
		} selection;			/**< With _SELECTION_REPORT */
		struct rect redraw;		/**< With _REDRAW_REQUEST */
		struct {
			enum {
				TEXTAREA_CARET_SET_POS,	/**< Set coord/height */
				TEXTAREA_CARET_HIDE	/**< Hide */
			} type;
			struct {
				int x;			/**< Caret x-coord */
				int y;			/**< Caret y-coord */
				int height;		/**< Caret height */
				struct rect *clip;	/**< Caret clip rect */
			} pos;			/**< With _CARET_SET_POS */
		} caret;			/**< With _CARET_UPDATE */
		struct {
			const char *text;	/**< UTF8 text */
			unsigned int len;	/**< Byte length of text */
		} modified;			/**< With _TEXT_MODIFIED */
	} data;				/**< Depends on msg type */
};


/**
 * textarea setup parameters
 */
typedef struct textarea_setup {
	int width;		/**< Textarea width */
	int height;		/**< Textarea height */

	int pad_top;		/**< Textarea top padding */
	int pad_right;		/**< Textarea right padding */
	int pad_bottom;		/**< Textarea bottom padding */
	int pad_left;		/**< Textarea left padding */

	int border_width;	/**< Textarea border width */
	colour border_col;	/**< Textarea border colour */

	colour selected_text;	/**< Textarea selected text colour */
	colour selected_bg;	/**< Textarea selection background colour */
	plot_font_style_t text;	/**< Textarea background colour and font */

} textarea_setup;


/**
 * Text area mouse input status flags
 */
typedef enum {
	TEXTAREA_MOUSE_NONE	= 0,		/**< Not relevant */
	TEXTAREA_MOUSE_USED	= (1 <<  0),	/**< Took action with input */
	TEXTAREA_MOUSE_EDITOR	= (1 <<  1),	/**< Hover: caret pointer */
	TEXTAREA_MOUSE_SELECTION= (1 <<  2),	/**< Hover: selection */
	TEXTAREA_MOUSE_SCR_USED	= (1 <<  3),	/**< Scrollbar action */
	TEXTAREA_MOUSE_SCR_BOTH	= (1 <<  4),	/**< Scrolling both bars */
	TEXTAREA_MOUSE_SCR_UP	= (1 <<  5),	/**< Hover: scroll up */
	TEXTAREA_MOUSE_SCR_PUP	= (1 <<  6),	/**< Hover: scroll page up */
	TEXTAREA_MOUSE_SCR_VRT	= (1 <<  7),	/**< Hover: vert. drag bar */
	TEXTAREA_MOUSE_SCR_PDWN	= (1 <<  8),	/**< Hover: scroll page down */
	TEXTAREA_MOUSE_SCR_DWN	= (1 <<  9),	/**< Hover: scroll down */
	TEXTAREA_MOUSE_SCR_LFT	= (1 << 10),	/**< Hover: scroll left */
	TEXTAREA_MOUSE_SCR_PLFT	= (1 << 11),	/**< Hover: scroll page left */
	TEXTAREA_MOUSE_SCR_HRZ	= (1 << 12),	/**< Hover: horiz. drag bar */
	TEXTAREA_MOUSE_SCR_PRGT	= (1 << 13),	/**< Hover: scroll page right */
	TEXTAREA_MOUSE_SCR_RGT	= (1 << 14)	/**< Hover: scroll right */
} textarea_mouse_status;


/**
 * Client callback for the textarea
 *
 * \param data user data passed at textarea creation
 * \param msg textarea message data
 */
typedef void(*textarea_client_callback)(void *data, struct textarea_msg *msg);


/**
 * Create a text area.
 *
 * \param flags flags controlling the text area creation
 * \param setup	textarea settings and style
 * \param callback will be called when textarea wants to redraw
 * \param data	user specified data which will be passed to callbacks
 * \return Opaque handle for textarea or 0 on error
 */
struct textarea *textarea_create(const textarea_flags flags,
		const textarea_setup *setup,
		textarea_client_callback callback, void *data);


/**
 * Destroy a text area
 *
 * \param ta Text area to destroy
 */
void textarea_destroy(struct textarea *ta);


/**
 * Set the text in a text area, discarding any current text
 *
 * \param ta Text area
 * \param text UTF-8 text to set text area's contents to
 * \return true on success, false on memory exhaustion
 */
bool textarea_set_text(struct textarea *ta, const char *text);


/**
 * Insert the text in a text area at the caret, replacing any selection.
 *
 * \param ta Text area
 * \param text UTF-8 text to set text area's contents to
 * \param text_length length of text.
 * \return true on success, false on memory exhaustion or if ta lacks caret
 */
bool textarea_drop_text(struct textarea *ta, const char *text,
		size_t text_length);


/**
 * Extract the text from a text area
 *
 * \param ta Text area
 * \param buf Pointer to buffer to receive data, or NULL
 *            to read length required (includes trailing '\0')
 * \param len Length (bytes) of buffer pointed to by buf, or 0 to read length
 * \return Length (bytes) written/required or -1 on error
 */
int textarea_get_text(struct textarea *ta, char *buf, unsigned int len);


/**
 * Access text data in a text area
 *
 * \param[in]  ta   Text area
 * \param[out] len  Returns byte length of returned text, if passed non-NULL.
 * \return textarea string data.
 */
const char * textarea_data(struct textarea *ta, unsigned int *len);


/**
 * Set the caret's position
 *
 * \param ta	Text area
 * \param caret 0-based character index to place caret at, -1 removes
 *		  the caret
 * \return true on success false otherwise
 */
bool textarea_set_caret(struct textarea *ta, int caret);


/**
 * Handle redraw requests for text areas
 *
 * \param ta	textarea to render
 * \param x	x coordinate of textarea top
 * \param y	y coordinate of textarea left
 * \param bg	background colour under textarea
 * \param scale scale to render at
 * \param clip	clip rectangle
 * \param ctx	current redraw context
 */
void textarea_redraw(struct textarea *ta, int x, int y, colour bg, float scale,
		const struct rect *clip, const struct redraw_context *ctx);


/**
 * Key press handling for text areas.
 *
 * \param ta	The text area which got the keypress
 * \param key	The ucs4 character codepoint
 * \return	true if the keypress is dealt with, false otherwise.
 */
bool textarea_keypress(struct textarea *ta, uint32_t key);


/**
 * Handles all kinds of mouse action
 *
 * \param ta	Text area
 * \param mouse	the mouse state at action moment
 * \param x	X coordinate
 * \param y	Y coordinate
 * \return the textarea mouse status
 */
textarea_mouse_status textarea_mouse_action(struct textarea *ta,
		browser_mouse_state mouse, int x, int y);


/**
 * Clear any selection in the textarea.
 *
 * \param ta textarea widget
 * \return true if there was a selection to clear, false otherwise
 */
bool textarea_clear_selection(struct textarea *ta);


/**
 * Get selected text.
 *
 * ownership of the returned string is passed to caller which needs to
 *  free it.
 *
 * \param ta Textarea widget
 * \return Selected text, or NULL if none.
 */
char *textarea_get_selection(struct textarea *ta);


/**
 * Gets the dimensions of a textarea
 *
 * \param ta		textarea widget
 * \param width		if not NULL, gets updated to the width of the textarea
 * \param height	if not NULL, gets updated to the height of the textarea
 */
void textarea_get_dimensions(struct textarea *ta, int *width, int *height);


/**
 * Set the dimensions of a textarea.
 *
 * This causes a reflow of the text and does not emit a redraw
 * request.  Up to client to call textarea_redraw.
 *
 * \param ta		textarea widget
 * \param width		the new width of the textarea
 * \param height	the new height of the textarea
 */
void textarea_set_dimensions(struct textarea *ta, int width, int height);


/**
 * Set the dimensions and padding of a textarea.
 *
 * This causes a reflow of the text. Does not emit a redraw request.
 * Up to client to call textarea_redraw.
 *
 * \param ta		textarea widget
 * \param width		the new width of the textarea
 * \param height	the new height of the textarea
 * \param top		the new top padding of the textarea
 * \param right		the new right padding of the textarea
 * \param bottom	the new bottom padding of the textarea
 * \param left		the new left padding of the textarea
 */
void textarea_set_layout(
		struct textarea *ta,
		const plot_font_style_t *fstyle,
		int width, int height,
		int top, int right,
		int bottom, int left);


/**
 * Scroll a textarea by an amount.
 *
 * Only does anything if multi-line textarea has scrollbars.  If it
 * scrolls, it will emit a redraw request.
 *
 * \param ta	textarea widget
 * \param scrx	number of px try to scroll in x direction
 * \param scry	number of px try to scroll in y direction
 * \return true iff the textarea was scrolled
 */
bool textarea_scroll(struct textarea *ta, int scrx, int scry);

#endif