Register
Essence » Wiki » Textboxes

UI Elements > Controls > Textboxes

Guidelines

An empty textbox.

Textboxes are used to collect text input from the user.

When they receive keyboard focus, they will process keyboard input to provide a consistent text editing interface. If a user is likely to reenter text, select the previous text when receiving focus, so that it can be overwritten.

A textbox where all the text has been automatically selected.

Textboxes can either contain a single line of text, or contain multiple lines. Only use a multiline textbox when necessary, such as when a large amount of text needs to be entered, or when the user needs to specify line breaks. You should aim to make textboxes large enough to contain any text the user might reasonably need to enter without scrolling. In resizable window, you may want to expand the textbox to fill the available space.

A multiline textbox that has been resized to fill its containing window.

If the purpose of a textbox is not obvious, make sure a label is included to the left or above the textbox. When using multiple textboxes, their labels should be aligned to the right. A label should not be an instruction, but rather an indication of what the textbox should contain.

Two labeled textboxes.

If a textbox is updated in commands, such as changing the name of a file, then use the command textbox style. When a command textbox loses keyboard focus, its text will reset to its previous value. If the user presses the enter key, then the corresponding command will be performed, and the text will be confirmed.

A command textbox.

Do not use a textbox when there are a set of standard options. Consider using a combobox instead.

Do not assign meaning to special values of a textbox. Use other controls instead in conjunction with the textbox. This includes using a delimiter in a textbox to input a list of multiple items; consider using a list view instead.

An example demonstrating how other controls can be used to augment the power of a textbox.

Textboxes can be placed in the following grid styles:

  • Group boxes
  • Containers
  • Tab pane content
  • Toolbars

Using textboxes

Creating a textbox

The OSTextboxCreate function is used to create a textbox.

1
OSObject textbox = OSTextboxCreate(OS_TEXTBOX_STYLE_NORMAL, OS_TEXTBOX_WRAP_MODE_NONE);

There are different textbox styles you can use, such as:

  • OS_TEXTBOX_STYLE_NORMAL: a plain textbox
  • OS_TEXTBOX_STYLE_COMMAND: a command textbox (see OSControlSetCommand)
  • OS_TEXTBOX_STYLE_LARGE: a textbox with large text
  • OS_TEXTBOX_STYLE_MULTILINE: a multiline textbox.

These styles can be ORed with OS_TEXTBOX_STYLE_NO_BORDER to remove the standard border from the textbox.

The textbox can then be added to a grid using OSGridAddElement:

1
2
OSGridAddElement(container, 0 /*column*/, 0 /*row*/, OSLabelCreate(OSLiteral("Name:"), OS_CELL_H_RIGHT)
OSGridAddElement(container, 1 /*column*/, 0 /*row*/, textbox, OS_CELL_H_FILL);

You can assign a notification callback to a textbox using OSElementSetNotificationCallback:

1
OSElementSetNotificationCallback(textbox, OS_MAKE_NOTIFICATION_CALLBACK(ProcessTextboxNotification, argumentPointer));

You can assign a command to the textbox using OSControlSetCommand:

1
OSControlSetCommand(textbox, commandGroup + commandDoThing);

The command's notification callback will now receive the textbox's notifications.

Responding to the text being modified

By setting a notification callback as shown above, you will receive OSNOTIFICATIONMODIFIED notifications.

For example,

1
2
3
4
5
6
7
8
OSResponse ProcessTextboxNotification(OSNotification *notification) {
    OSObject textbox = notification->generator;
    void *argument = notification->argument;

    if (notification->type == OS_NOTIFICATION_MODIFIED) {
        // The textbox's contents has been modified.
    }
}

Responding to losing keyboard focus

By setting a notification callback as shown above, you will receive OSNOTIFICATIONEND_EDIT notifications.

For example,

1
2
3
4
5
6
7
8
OSResponse ProcessTextboxNotification(OSNotification *notification) {
    OSObject textbox = notification->generator;
    void *argument = notification->argument;

    if (notification->type == OS_NOTIFICATION_END_EDIT) {
        // The textbox has lost keyboard focus.
    }
}

Reading the text

You can get the text from a textbox using OSControlGetText:

1
2
3
4
OSString string;
OSControlGetText(textbox, &string);
OSPrint("The textbox's contains the text '%s'. This is %d UTF-8 characters.\n", 
    string.bytes, string.buffer, string.characters);

Changing the text

You can change a textbox's contents using OSControlSetText:

1
2
const char *text = "Hello, world!";
OSControlSetText(textbox, text, OSCStringLength(text), OS_RESIZE_MODE_IGNORE);

Inserting text at the caret

You can insert text at the caret's position using OSTextboxInsert:

1
2
const char *text = "---";
OSTextboxInsert(textbox, text, OSCStringLength(text));

Removing selected text

You can remove the selected text using OSTextboxRemove:

1
OSTextboxRemove(textbox);

Setting the selected text

You can select text using OSTextboxSetSelection:

1
2
uintptr_t byteFrom = 3, byteTo = 5;
OSTextboxSetSelection(textbox, byteFrom, byteTo);

Getting the selection range

You can find the range of selected text using OSTextboxGetSelection:

1
2
uintptr_t byteFrom, byteTo;
OSTextboxGetSelection(textbox, &byteFrom, &byteTo);