Tbox widget
-----------

Tbox is a single line text edit widget.

.A tbox widget
image:tbox.png[Tbox widget]

Tbox attributes can be accessed as `widget->tbox`.

.Tbox widget constructor
[source,c]
-------------------------------------------------------------------------------
enum gp_widget_tbox_type {
        /* default */
        GP_WIDGET_TBOX_NONE,
        /* hidden text, e.g. password */
        GP_WIDGET_TBOX_HIDDEN,
        /* URL */
        GP_WIDGET_TBOX_URL,
        /* Filesystem path */
        GP_WIDGET_TBOX_PATH,
        /* File name */
        GP_WIDGET_TBOX_FILENAME,
};

gp_widget *gp_widget_tbox_new(const char *text, gp_widget_tattr tattr,
                              unsigned int len, unsigned int max_len,
                              const char *filter, enum gp_widget_tbox_type type);
-------------------------------------------------------------------------------

The `text` is the initial textbox text, could be NULL if textbox starts empty.

The `tattr` is link:widgets_tattr.html[text attribute].

The textbox width is computed so that it can hold `len` average font
characters. `Len` could be set to zero if non-NULL `text` is passed, then
`len` is computed from the `text` length.

The `max_len` can be used to limit maximal number of characters that can be
input to the textbox.

The `filter` can be used to limit which characters can be entered into the
textbox, there are also pre-defined filters such as `GP_TBOX_FILTER_HEX` that
limits the characters only to numbers and characters from `a` to `f`. If
`filter` is passed the widget width is computed so that it can fit `len`
characters from the `filter` set.

The `type` determines a textbox behavior, the 'HIDDEN' type replaces the
string shown to user with asterisks. The rests of the types changes the
textbox behavior for example when user is selecting text.

The `on_event` and `priv` are explained in the
link:widgets_events.html[widgets event].

.Text tbox functions
[source,c]
-------------------------------------------------------------------------------
/*
 * Sets textbox type.
 */
void gp_widget_tbox_type_set(gp_widget *self, enum gp_widget_tbox_type type);

/*
 * Sets textbox help text.
 */
void gp_widget_tbox_help_set(gp_widget *self, const char *help);

/*
 * Returns textbox text.
 */
const char *gp_widget_tbox_text(gp_widget *self);

/*
 * Retruns non-zero if textbox is empty.
 */
int gp_widget_tbox_is_empty(gp_widget *self);

/*
 * Sets tbox text.
 */
 void gp_widget_tbox_set(gp_widget *self, const char *str);

/*
 * Sets tbox text with a printf()-like syntax.
 */
int gp_widget_tbox_printf(gp_widget *self, const char *fmt, ...)
                          __attribute__((format (printf, 2, 3)));

/*
 * Sets tbox text to an empty string.
 */
void gp_widget_tbox_clear(gp_widget *self);

/*
 * Insert text at offset relative to whence.
 */
void gp_widget_tbox_ins(gp_widget *self, ssize_t off,
                        enum gp_seek_whence whence, const char *str);

/*
 * Shorthand for gp_widget_tbox_ins(self, 0, GP_SEEK_CUR, str);
 */
void gp_widget_tbox_append(gp_widget *self, const char *str);

/*
 * Deletes text at offset relative to whence.
 */
void gp_widget_tbox_del(gp_widget *self, ssize_t off,
                        enum gp_seek_whence whence, size_t len);
-------------------------------------------------------------------------------

.Cursor tbox functions
[source,c]
-------------------------------------------------------------------------------
gp_utf8_pos gp_widget_tbox_cursor_get(gp_widget *self);

void gp_widget_tbox_cursor_set(gp_widget *self, ssize_t off,
                               enum gp_seek_whence whence);
-------------------------------------------------------------------------------

.Selection tbox functions
[source,c]
-------------------------------------------------------------------------------
/*
 * Sets selection.
 */
void gp_widget_tbox_sel_set(gp_widget *self, ssize_t off,
                            enum gp_seek_whence whence, size_t len);
/*
 * Select whole text buffer.
 */
void gp_widget_tbox_sel_all(gp_widget *self);

/*
 * Clears textbox selection.
 */
void gp_widget_tbox_sel_clr(gp_widget *self);

/*
 * Delete selected text.
 */
void gp_widget_tbox_sel_del(gp_widget *self);

/*
 * Returns selection offset and length.
 */
gp_utf8_pos gp_widget_tbox_sel_len(gp_widget *self);
gp_utf8_pos gp_widget_tbox_sel_off(gp_widget *self);

/*
 * Returns non-zero when text is selected.
 */
void gp_widget_tbox_sel_all(gp_widget *self);
-------------------------------------------------------------------------------

Note also that all operations that modify text buffer or cursor position clear
the selection as well.

[source,c]
-------------------------------------------------------------------------------
/*
 * Sets selection delimiters.
 */
void gp_widget_tbox_sel_delim_set(gp_widget *self, const char *delim);
-------------------------------------------------------------------------------

Selection delimiters are used on double click to select continous substring.

If not set the default delimiters are whitespaces.

NOTE: If textbox contains URL or Path the delimiters should be set by setting
      the right textbox type.

.Tbox JSON attributes
[cols=",,,3",options="header"]
|===================================================
| Attribute     |  Type  |   Default   | Description
| text          | string |     ""      | Initial textbox text.
| help          | string |     ""      | Help text shown when text is empty.
| ttype         | string |    "none"   | A textbox type valid are:
                                         {"none", "hidden", "URL", "path", "filename"}
| len           |  uint  |             | Number of characters the texbox should fit.
| max_len       |  uint  |             | Maximal number of characters.
| tattr         |  tattr |    normal   | link:widgets_tattr.html[Text attribute].
| sel_delim     | string | whitespaces | If set any character from the string is
                                         selection delimiter.
|===================================================

.Tbox widget events
[cols=",3",options="header"]
|=============================================================
|   Widget event value       | Description
| GP_WIDGET_TBOX_TRIGGER     | Emitted on pressing enter.
| GP_WIDGET_TBOX_PRE_FILTER  | Filter before text is modified.
| GP_WIDGET_TBOX_POST_FILTER | Filter after text is modified.
| GP_WIDGET_TBOX_EDIT        | Emitted after text is modified by user.
| GP_WIDGET_TBOX_SET         | Emitted after text changed by a function call.
| GP_WIDGET_TBOX_PASTE       | Emitted before text is pasted.
|=============================================================

In the case of the `GP_WIDGET_TBOX_PRE_FILTER` and
`GP_WIDGET_TBOX_POST_FILTER` non-zero output from the event handler will
filter out the change, e.g. a character will will not be inserted.

When text is pasted into a textbox event hanlder will get the
`GP_WIDGET_TBOX_PASTE` event, followed by sequence of the filter events and
edit event for each pasted letter.

When text was set by one of the functions to set, clear or modify the text the
`GP_WIDGET_TBOX_SET` event is send instead. E.g. call 'gp_widget_tbox_del()'
or 'gp_widget_tbox_print()' will produce this event.
