mirror of
https://github.com/nothings/stb
synced 2024-12-14 12:07:13 +03:00
Support for Page Up/Down
(changes from ocornut/imgui/commit/ec945f44)
This commit is contained in:
parent
76a0a00874
commit
85bc8060be
@ -142,6 +142,8 @@
|
|||||||
// STB_TEXTEDIT_K_RIGHT keyboard input to move cursor right
|
// STB_TEXTEDIT_K_RIGHT keyboard input to move cursor right
|
||||||
// STB_TEXTEDIT_K_UP keyboard input to move cursor up
|
// STB_TEXTEDIT_K_UP keyboard input to move cursor up
|
||||||
// STB_TEXTEDIT_K_DOWN keyboard input to move cursor down
|
// STB_TEXTEDIT_K_DOWN keyboard input to move cursor down
|
||||||
|
// STB_TEXTEDIT_K_PGUP keyboard input to move cursor up a page
|
||||||
|
// STB_TEXTEDIT_K_PGDOWN keyboard input to move cursor down a page
|
||||||
// STB_TEXTEDIT_K_LINESTART keyboard input to move cursor to start of line // e.g. HOME
|
// STB_TEXTEDIT_K_LINESTART keyboard input to move cursor to start of line // e.g. HOME
|
||||||
// STB_TEXTEDIT_K_LINEEND keyboard input to move cursor to end of line // e.g. END
|
// STB_TEXTEDIT_K_LINEEND keyboard input to move cursor to end of line // e.g. END
|
||||||
// STB_TEXTEDIT_K_TEXTSTART keyboard input to move cursor to start of text // e.g. ctrl-HOME
|
// STB_TEXTEDIT_K_TEXTSTART keyboard input to move cursor to start of text // e.g. ctrl-HOME
|
||||||
@ -164,10 +166,6 @@
|
|||||||
// STB_TEXTEDIT_K_TEXTSTART2 secondary keyboard input to move cursor to start of text
|
// STB_TEXTEDIT_K_TEXTSTART2 secondary keyboard input to move cursor to start of text
|
||||||
// STB_TEXTEDIT_K_TEXTEND2 secondary keyboard input to move cursor to end of text
|
// STB_TEXTEDIT_K_TEXTEND2 secondary keyboard input to move cursor to end of text
|
||||||
//
|
//
|
||||||
// Todo:
|
|
||||||
// STB_TEXTEDIT_K_PGUP keyboard input to move cursor up a page
|
|
||||||
// STB_TEXTEDIT_K_PGDOWN keyboard input to move cursor down a page
|
|
||||||
//
|
|
||||||
// Keyboard input must be encoded as a single integer value; e.g. a character code
|
// Keyboard input must be encoded as a single integer value; e.g. a character code
|
||||||
// and some bitflags that represent shift states. to simplify the interface, SHIFT must
|
// and some bitflags that represent shift states. to simplify the interface, SHIFT must
|
||||||
// be a bitflag, so we can test the shifted state of cursor movements to allow selection,
|
// be a bitflag, so we can test the shifted state of cursor movements to allow selection,
|
||||||
@ -331,6 +329,10 @@ typedef struct
|
|||||||
// each textfield keeps its own insert mode state. to keep an app-wide
|
// each textfield keeps its own insert mode state. to keep an app-wide
|
||||||
// insert mode, copy this value in/out of the app state
|
// insert mode, copy this value in/out of the app state
|
||||||
|
|
||||||
|
int row_count_per_page;
|
||||||
|
// page size in number of row.
|
||||||
|
// this value MUST be set to >0 for pageup or pagedown in multilines documents.
|
||||||
|
|
||||||
/////////////////////
|
/////////////////////
|
||||||
//
|
//
|
||||||
// private data
|
// private data
|
||||||
@ -849,12 +851,16 @@ retry:
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case STB_TEXTEDIT_K_DOWN:
|
case STB_TEXTEDIT_K_DOWN:
|
||||||
case STB_TEXTEDIT_K_DOWN | STB_TEXTEDIT_K_SHIFT: {
|
case STB_TEXTEDIT_K_DOWN | STB_TEXTEDIT_K_SHIFT:
|
||||||
|
case STB_TEXTEDIT_K_PGDOWN:
|
||||||
|
case STB_TEXTEDIT_K_PGDOWN | STB_TEXTEDIT_K_SHIFT: {
|
||||||
StbFindState find;
|
StbFindState find;
|
||||||
StbTexteditRow row;
|
StbTexteditRow row;
|
||||||
int i, sel = (key & STB_TEXTEDIT_K_SHIFT) != 0;
|
int i, j, sel = (key & STB_TEXTEDIT_K_SHIFT) != 0;
|
||||||
|
int is_page = (key & ~STB_TEXTEDIT_K_SHIFT) == STB_TEXTEDIT_K_PGDOWN;
|
||||||
|
int row_count = is_page ? state->row_count_per_page : 1;
|
||||||
|
|
||||||
if (state->single_line) {
|
if (!is_page && state->single_line) {
|
||||||
// on windows, up&down in single-line behave like left&right
|
// on windows, up&down in single-line behave like left&right
|
||||||
key = STB_TEXTEDIT_K_RIGHT | (key & STB_TEXTEDIT_K_SHIFT);
|
key = STB_TEXTEDIT_K_RIGHT | (key & STB_TEXTEDIT_K_SHIFT);
|
||||||
goto retry;
|
goto retry;
|
||||||
@ -863,17 +869,20 @@ retry:
|
|||||||
if (sel)
|
if (sel)
|
||||||
stb_textedit_prep_selection_at_cursor(state);
|
stb_textedit_prep_selection_at_cursor(state);
|
||||||
else if (STB_TEXT_HAS_SELECTION(state))
|
else if (STB_TEXT_HAS_SELECTION(state))
|
||||||
stb_textedit_move_to_last(str,state);
|
stb_textedit_move_to_last(str, state);
|
||||||
|
|
||||||
// compute current position of cursor point
|
// compute current position of cursor point
|
||||||
stb_textedit_clamp(str, state);
|
stb_textedit_clamp(str, state);
|
||||||
stb_textedit_find_charpos(&find, str, state->cursor, state->single_line);
|
stb_textedit_find_charpos(&find, str, state->cursor, state->single_line);
|
||||||
|
|
||||||
// now find character position down a row
|
for (j = 0; j < row_count; ++j) {
|
||||||
if (find.length) {
|
float x, goal_x = state->has_preferred_x ? state->preferred_x : find.x;
|
||||||
float goal_x = state->has_preferred_x ? state->preferred_x : find.x;
|
|
||||||
float x;
|
|
||||||
int start = find.first_char + find.length;
|
int start = find.first_char + find.length;
|
||||||
|
|
||||||
|
if (find.length == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// now find character position down a row
|
||||||
state->cursor = start;
|
state->cursor = start;
|
||||||
STB_TEXTEDIT_LAYOUTROW(&row, str, state->cursor);
|
STB_TEXTEDIT_LAYOUTROW(&row, str, state->cursor);
|
||||||
x = row.x0;
|
x = row.x0;
|
||||||
@ -895,17 +904,25 @@ retry:
|
|||||||
|
|
||||||
if (sel)
|
if (sel)
|
||||||
state->select_end = state->cursor;
|
state->select_end = state->cursor;
|
||||||
|
|
||||||
|
// go to next line
|
||||||
|
find.first_char = find.first_char + find.length;
|
||||||
|
find.length = row.num_chars;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case STB_TEXTEDIT_K_UP:
|
case STB_TEXTEDIT_K_UP:
|
||||||
case STB_TEXTEDIT_K_UP | STB_TEXTEDIT_K_SHIFT: {
|
case STB_TEXTEDIT_K_UP | STB_TEXTEDIT_K_SHIFT:
|
||||||
|
case STB_TEXTEDIT_K_PGUP:
|
||||||
|
case STB_TEXTEDIT_K_PGUP | STB_TEXTEDIT_K_SHIFT: {
|
||||||
StbFindState find;
|
StbFindState find;
|
||||||
StbTexteditRow row;
|
StbTexteditRow row;
|
||||||
int i, sel = (key & STB_TEXTEDIT_K_SHIFT) != 0;
|
int i, j, prev_scan, sel = (key & STB_TEXTEDIT_K_SHIFT) != 0;
|
||||||
|
int is_page = (key & ~STB_TEXTEDIT_K_SHIFT) == STB_TEXTEDIT_K_PGUP;
|
||||||
|
int row_count = is_page ? state->row_count_per_page : 1;
|
||||||
|
|
||||||
if (state->single_line) {
|
if (!is_page && state->single_line) {
|
||||||
// on windows, up&down become left&right
|
// on windows, up&down become left&right
|
||||||
key = STB_TEXTEDIT_K_LEFT | (key & STB_TEXTEDIT_K_SHIFT);
|
key = STB_TEXTEDIT_K_LEFT | (key & STB_TEXTEDIT_K_SHIFT);
|
||||||
goto retry;
|
goto retry;
|
||||||
@ -920,11 +937,14 @@ retry:
|
|||||||
stb_textedit_clamp(str, state);
|
stb_textedit_clamp(str, state);
|
||||||
stb_textedit_find_charpos(&find, str, state->cursor, state->single_line);
|
stb_textedit_find_charpos(&find, str, state->cursor, state->single_line);
|
||||||
|
|
||||||
// can only go up if there's a previous row
|
for (j = 0; j < row_count; ++j) {
|
||||||
if (find.prev_first != find.first_char) {
|
float x, goal_x = state->has_preferred_x ? state->preferred_x : find.x;
|
||||||
|
|
||||||
|
// can only go up if there's a previous row
|
||||||
|
if (find.prev_first == find.first_char)
|
||||||
|
break;
|
||||||
|
|
||||||
// now find character position up a row
|
// now find character position up a row
|
||||||
float goal_x = state->has_preferred_x ? state->preferred_x : find.x;
|
|
||||||
float x;
|
|
||||||
state->cursor = find.prev_first;
|
state->cursor = find.prev_first;
|
||||||
STB_TEXTEDIT_LAYOUTROW(&row, str, state->cursor);
|
STB_TEXTEDIT_LAYOUTROW(&row, str, state->cursor);
|
||||||
x = row.x0;
|
x = row.x0;
|
||||||
@ -946,6 +966,14 @@ retry:
|
|||||||
|
|
||||||
if (sel)
|
if (sel)
|
||||||
state->select_end = state->cursor;
|
state->select_end = state->cursor;
|
||||||
|
|
||||||
|
// go to previous line
|
||||||
|
// (we need to scan previous line the hard way. maybe we could expose this as a new API function?)
|
||||||
|
prev_scan = find.prev_first > 0 ? find.prev_first - 1 : 0;
|
||||||
|
while (prev_scan > 0 && STB_TEXTEDIT_GETCHAR(str, prev_scan - 1) != STB_TEXTEDIT_NEWLINE)
|
||||||
|
--prev_scan;
|
||||||
|
find.first_char = find.prev_first;
|
||||||
|
find.prev_first = prev_scan;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1069,10 +1097,6 @@ retry:
|
|||||||
state->has_preferred_x = 0;
|
state->has_preferred_x = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// @TODO:
|
|
||||||
// STB_TEXTEDIT_K_PGUP - move cursor up a page
|
|
||||||
// STB_TEXTEDIT_K_PGDOWN - move cursor down a page
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1337,6 +1361,7 @@ static void stb_textedit_clear_state(STB_TexteditState *state, int is_single_lin
|
|||||||
state->initialized = 1;
|
state->initialized = 1;
|
||||||
state->single_line = (unsigned char) is_single_line;
|
state->single_line = (unsigned char) is_single_line;
|
||||||
state->insert_mode = 0;
|
state->insert_mode = 0;
|
||||||
|
state->row_count_per_page = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// API initialize
|
// API initialize
|
||||||
|
Loading…
Reference in New Issue
Block a user