mirror of
https://github.com/Drezil/imgui.git
synced 2024-11-22 11:57:00 +00:00
InputText: Added support for Page Up/Down in InputTextMultiline. (#3430)
+ fix stb_textedit.h to build with C language (amend fbf70070
)
This commit is contained in:
parent
8eca736a7a
commit
ec945f44b5
@ -50,6 +50,7 @@ Other Changes:
|
|||||||
- Nav: Fixed using Alt to toggle the Menu layer when inside a Modal window. (#787)
|
- Nav: Fixed using Alt to toggle the Menu layer when inside a Modal window. (#787)
|
||||||
- Scrolling: Fixed SetScrollHere functions edge snapping when called during a frame where ContentSize
|
- Scrolling: Fixed SetScrollHere functions edge snapping when called during a frame where ContentSize
|
||||||
is changing (issue introduced in 1.78). (#3452).
|
is changing (issue introduced in 1.78). (#3452).
|
||||||
|
- InputText: Added support for Page Up/Down in InputTextMultiline(). (#3430) [@Xipiryon]
|
||||||
- InputText: Added selection helpers in ImGuiInputTextCallbackData().
|
- InputText: Added selection helpers in ImGuiInputTextCallbackData().
|
||||||
- InputText: Added ImGuiInputTextFlags_CallbackEdit to modify internally owned buffer after an edit.
|
- InputText: Added ImGuiInputTextFlags_CallbackEdit to modify internally owned buffer after an edit.
|
||||||
(note that InputText() already returns true on edit, the callback is useful mainly to manipulate the
|
(note that InputText() already returns true on edit, the callback is useful mainly to manipulate the
|
||||||
@ -59,8 +60,9 @@ Other Changes:
|
|||||||
- InputText: Fixed minor scrolling glitch when erasing trailing lines in InputTextMultiline().
|
- InputText: Fixed minor scrolling glitch when erasing trailing lines in InputTextMultiline().
|
||||||
- InputText: Fixed cursor being partially covered after using Ctrl+End key.
|
- InputText: Fixed cursor being partially covered after using Ctrl+End key.
|
||||||
- InputText: Fixed callback's helper DeleteChars() function when cursor is inside the deleted block. (#3454)
|
- InputText: Fixed callback's helper DeleteChars() function when cursor is inside the deleted block. (#3454)
|
||||||
- InputText: Fixed minor inconsistency when pressing Down on the last line when it doesn't have a carriage
|
- InputText: Made pressing Down arrow on the last line when it doesn't have a carriage return not move to the end
|
||||||
return (it used to move to the end of the line). [@Xipiryon]
|
of the line (so it is consistent with Up arrow, and behave same as Notepad and Visual Studio. Note that some
|
||||||
|
other text editors instead would move the crusor to the end of the line). [@Xipiryon]
|
||||||
- DragFloat, DragScalar: Fixed ImGuiSliderFlags_ClampOnInput not being honored in the special case
|
- DragFloat, DragScalar: Fixed ImGuiSliderFlags_ClampOnInput not being honored in the special case
|
||||||
where v_min == v_max. (#3361)
|
where v_min == v_max. (#3361)
|
||||||
- SliderInt, SliderScalar: Fixed reaching of maximum value with inverted integer min/max ranges, both
|
- SliderInt, SliderScalar: Fixed reaching of maximum value with inverted integer min/max ranges, both
|
||||||
|
@ -3590,6 +3590,8 @@ static bool STB_TEXTEDIT_INSERTCHARS(STB_TEXTEDIT_STRING* obj, int pos, const Im
|
|||||||
#define STB_TEXTEDIT_K_REDO 0x20000B // keyboard input to perform redo
|
#define STB_TEXTEDIT_K_REDO 0x20000B // keyboard input to perform redo
|
||||||
#define STB_TEXTEDIT_K_WORDLEFT 0x20000C // keyboard input to move cursor left one word
|
#define STB_TEXTEDIT_K_WORDLEFT 0x20000C // keyboard input to move cursor left one word
|
||||||
#define STB_TEXTEDIT_K_WORDRIGHT 0x20000D // keyboard input to move cursor right one word
|
#define STB_TEXTEDIT_K_WORDRIGHT 0x20000D // keyboard input to move cursor right one word
|
||||||
|
#define STB_TEXTEDIT_K_PGUP 0x20000E // keyboard input to move cursor up a page
|
||||||
|
#define STB_TEXTEDIT_K_PGDOWN 0x20000F // keyboard input to move cursor down a page
|
||||||
#define STB_TEXTEDIT_K_SHIFT 0x400000
|
#define STB_TEXTEDIT_K_SHIFT 0x400000
|
||||||
|
|
||||||
#define STB_TEXTEDIT_IMPLEMENTATION
|
#define STB_TEXTEDIT_IMPLEMENTATION
|
||||||
@ -3856,6 +3858,8 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
|||||||
bool clear_active_id = false;
|
bool clear_active_id = false;
|
||||||
bool select_all = (g.ActiveId != id) && ((flags & ImGuiInputTextFlags_AutoSelectAll) != 0 || user_nav_input_start) && (!is_multiline);
|
bool select_all = (g.ActiveId != id) && ((flags & ImGuiInputTextFlags_AutoSelectAll) != 0 || user_nav_input_start) && (!is_multiline);
|
||||||
|
|
||||||
|
float scroll_y = is_multiline ? draw_window->Scroll.y : FLT_MAX;
|
||||||
|
|
||||||
const bool init_make_active = (focus_requested || user_clicked || user_scroll_finish || user_nav_input_start);
|
const bool init_make_active = (focus_requested || user_clicked || user_scroll_finish || user_nav_input_start);
|
||||||
const bool init_state = (init_make_active || user_scroll_active);
|
const bool init_state = (init_make_active || user_scroll_active);
|
||||||
if (init_state && g.ActiveId != id)
|
if (init_state && g.ActiveId != id)
|
||||||
@ -3916,7 +3920,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
|||||||
g.ActiveIdUsingNavInputMask |= (1 << ImGuiNavInput_Cancel);
|
g.ActiveIdUsingNavInputMask |= (1 << ImGuiNavInput_Cancel);
|
||||||
g.ActiveIdUsingKeyInputMask |= ((ImU64)1 << ImGuiKey_Home) | ((ImU64)1 << ImGuiKey_End);
|
g.ActiveIdUsingKeyInputMask |= ((ImU64)1 << ImGuiKey_Home) | ((ImU64)1 << ImGuiKey_End);
|
||||||
if (is_multiline)
|
if (is_multiline)
|
||||||
g.ActiveIdUsingKeyInputMask |= ((ImU64)1 << ImGuiKey_PageUp) | ((ImU64)1 << ImGuiKey_PageDown); // FIXME-NAV: Page up/down actually not supported yet by widget, but claim them ahead.
|
g.ActiveIdUsingKeyInputMask |= ((ImU64)1 << ImGuiKey_PageUp) | ((ImU64)1 << ImGuiKey_PageDown);
|
||||||
if (flags & (ImGuiInputTextFlags_CallbackCompletion | ImGuiInputTextFlags_AllowTabInput)) // Disable keyboard tabbing out as we will use the \t character.
|
if (flags & (ImGuiInputTextFlags_CallbackCompletion | ImGuiInputTextFlags_AllowTabInput)) // Disable keyboard tabbing out as we will use the \t character.
|
||||||
g.ActiveIdUsingKeyInputMask |= ((ImU64)1 << ImGuiKey_Tab);
|
g.ActiveIdUsingKeyInputMask |= ((ImU64)1 << ImGuiKey_Tab);
|
||||||
}
|
}
|
||||||
@ -4055,6 +4059,9 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
|||||||
IM_ASSERT(state != NULL);
|
IM_ASSERT(state != NULL);
|
||||||
IM_ASSERT(io.KeyMods == GetMergedKeyModFlags() && "Mismatching io.KeyCtrl/io.KeyShift/io.KeyAlt/io.KeySuper vs io.KeyMods"); // We rarely do this check, but if anything let's do it here.
|
IM_ASSERT(io.KeyMods == GetMergedKeyModFlags() && "Mismatching io.KeyCtrl/io.KeyShift/io.KeyAlt/io.KeySuper vs io.KeyMods"); // We rarely do this check, but if anything let's do it here.
|
||||||
|
|
||||||
|
const int row_count_per_page = ImMax((int)((inner_size.y - style.FramePadding.y) / g.FontSize), 1);
|
||||||
|
state->Stb.row_count_per_page = row_count_per_page;
|
||||||
|
|
||||||
const int k_mask = (io.KeyShift ? STB_TEXTEDIT_K_SHIFT : 0);
|
const int k_mask = (io.KeyShift ? STB_TEXTEDIT_K_SHIFT : 0);
|
||||||
const bool is_osx = io.ConfigMacOSXBehaviors;
|
const bool is_osx = io.ConfigMacOSXBehaviors;
|
||||||
const bool is_osx_shift_shortcut = is_osx && (io.KeyMods == (ImGuiKeyModFlags_Super | ImGuiKeyModFlags_Shift));
|
const bool is_osx_shift_shortcut = is_osx && (io.KeyMods == (ImGuiKeyModFlags_Super | ImGuiKeyModFlags_Shift));
|
||||||
@ -4074,6 +4081,8 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
|||||||
else if (IsKeyPressedMap(ImGuiKey_RightArrow)) { state->OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_LINEEND : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDRIGHT : STB_TEXTEDIT_K_RIGHT) | k_mask); }
|
else if (IsKeyPressedMap(ImGuiKey_RightArrow)) { state->OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_LINEEND : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDRIGHT : STB_TEXTEDIT_K_RIGHT) | k_mask); }
|
||||||
else if (IsKeyPressedMap(ImGuiKey_UpArrow) && is_multiline) { if (io.KeyCtrl) SetScrollY(draw_window, ImMax(draw_window->Scroll.y - g.FontSize, 0.0f)); else state->OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_TEXTSTART : STB_TEXTEDIT_K_UP) | k_mask); }
|
else if (IsKeyPressedMap(ImGuiKey_UpArrow) && is_multiline) { if (io.KeyCtrl) SetScrollY(draw_window, ImMax(draw_window->Scroll.y - g.FontSize, 0.0f)); else state->OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_TEXTSTART : STB_TEXTEDIT_K_UP) | k_mask); }
|
||||||
else if (IsKeyPressedMap(ImGuiKey_DownArrow) && is_multiline) { if (io.KeyCtrl) SetScrollY(draw_window, ImMin(draw_window->Scroll.y + g.FontSize, GetScrollMaxY())); else state->OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_TEXTEND : STB_TEXTEDIT_K_DOWN) | k_mask); }
|
else if (IsKeyPressedMap(ImGuiKey_DownArrow) && is_multiline) { if (io.KeyCtrl) SetScrollY(draw_window, ImMin(draw_window->Scroll.y + g.FontSize, GetScrollMaxY())); else state->OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_TEXTEND : STB_TEXTEDIT_K_DOWN) | k_mask); }
|
||||||
|
else if (IsKeyPressedMap(ImGuiKey_PageUp) && is_multiline) { state->OnKeyPressed(STB_TEXTEDIT_K_PGUP | k_mask); scroll_y -= row_count_per_page * g.FontSize; }
|
||||||
|
else if (IsKeyPressedMap(ImGuiKey_PageDown) && is_multiline) { state->OnKeyPressed(STB_TEXTEDIT_K_PGDOWN | k_mask); scroll_y += row_count_per_page * g.FontSize; }
|
||||||
else if (IsKeyPressedMap(ImGuiKey_Home)) { state->OnKeyPressed(io.KeyCtrl ? STB_TEXTEDIT_K_TEXTSTART | k_mask : STB_TEXTEDIT_K_LINESTART | k_mask); }
|
else if (IsKeyPressedMap(ImGuiKey_Home)) { state->OnKeyPressed(io.KeyCtrl ? STB_TEXTEDIT_K_TEXTSTART | k_mask : STB_TEXTEDIT_K_LINESTART | k_mask); }
|
||||||
else if (IsKeyPressedMap(ImGuiKey_End)) { state->OnKeyPressed(io.KeyCtrl ? STB_TEXTEDIT_K_TEXTEND | k_mask : STB_TEXTEDIT_K_LINEEND | k_mask); }
|
else if (IsKeyPressedMap(ImGuiKey_End)) { state->OnKeyPressed(io.KeyCtrl ? STB_TEXTEDIT_K_TEXTEND | k_mask : STB_TEXTEDIT_K_LINEEND | k_mask); }
|
||||||
else if (IsKeyPressedMap(ImGuiKey_Delete) && !is_readonly) { state->OnKeyPressed(STB_TEXTEDIT_K_DELETE | k_mask); }
|
else if (IsKeyPressedMap(ImGuiKey_Delete) && !is_readonly) { state->OnKeyPressed(STB_TEXTEDIT_K_DELETE | k_mask); }
|
||||||
@ -4443,12 +4452,11 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
|||||||
if (is_multiline)
|
if (is_multiline)
|
||||||
{
|
{
|
||||||
// Test if cursor is vertically visible
|
// Test if cursor is vertically visible
|
||||||
float scroll_y = draw_window->Scroll.y;
|
|
||||||
const float scroll_max_y = ImMax((text_size.y + style.FramePadding.y * 2.0f) - inner_size.y, 0.0f);
|
|
||||||
if (cursor_offset.y - g.FontSize < scroll_y)
|
if (cursor_offset.y - g.FontSize < scroll_y)
|
||||||
scroll_y = ImMax(0.0f, cursor_offset.y - g.FontSize);
|
scroll_y = ImMax(0.0f, cursor_offset.y - g.FontSize);
|
||||||
else if (cursor_offset.y - inner_size.y >= scroll_y)
|
else if (cursor_offset.y - inner_size.y >= scroll_y)
|
||||||
scroll_y = cursor_offset.y - inner_size.y + style.FramePadding.y * 2.0f;
|
scroll_y = cursor_offset.y - inner_size.y + style.FramePadding.y * 2.0f;
|
||||||
|
const float scroll_max_y = ImMax((text_size.y + style.FramePadding.y * 2.0f) - inner_size.y, 0.0f);
|
||||||
scroll_y = ImClamp(scroll_y, 0.0f, scroll_max_y);
|
scroll_y = ImClamp(scroll_y, 0.0f, scroll_max_y);
|
||||||
draw_pos.y += (draw_window->Scroll.y - scroll_y); // Manipulate cursor pos immediately avoid a frame of lag
|
draw_pos.y += (draw_window->Scroll.y - scroll_y); // Manipulate cursor pos immediately avoid a frame of lag
|
||||||
draw_window->Scroll.y = scroll_y;
|
draw_window->Scroll.y = scroll_y;
|
||||||
|
@ -148,6 +148,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
|
||||||
@ -170,10 +172,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,
|
||||||
@ -337,6 +335,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
|
||||||
@ -855,12 +857,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;
|
||||||
@ -869,23 +875,25 @@ 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;
|
||||||
|
int start = find.first_char + find.length;
|
||||||
|
|
||||||
|
if (find.length == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
// [DEAR IMGUI]
|
// [DEAR IMGUI]
|
||||||
// going down while being on the last line shouldn't bring us to that line end
|
// going down while being on the last line shouldn't bring us to that line end
|
||||||
if (STB_TEXTEDIT_GETCHAR(str, find.first_char + find.length - 1) != STB_TEXTEDIT_NEWLINE)
|
if (STB_TEXTEDIT_GETCHAR(str, find.first_char + find.length - 1) != STB_TEXTEDIT_NEWLINE)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
float goal_x = state->has_preferred_x ? state->preferred_x : find.x;
|
// now find character position down a row
|
||||||
float x;
|
|
||||||
int start = find.first_char + find.length;
|
|
||||||
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;
|
||||||
@ -907,17 +915,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;
|
||||||
@ -932,11 +948,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);
|
||||||
|
|
||||||
|
for (j = 0; j < row_count; ++j) {
|
||||||
|
float x, goal_x = state->has_preferred_x ? state->preferred_x : find.x;
|
||||||
|
|
||||||
// can only go up if there's a previous row
|
// can only go up if there's a previous row
|
||||||
if (find.prev_first != find.first_char) {
|
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;
|
||||||
@ -958,6 +977,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;
|
||||||
}
|
}
|
||||||
@ -1081,10 +1108,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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1356,6 +1379,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