Преглед изворни кода

InputText: Word-Wrap: mouse clicks on word-wrapping points set cursor side correctly. (#3237, #952, #1062, #7363)

ocornut пре 3 недеља
родитељ
комит
985723ed94
1 измењених фајлова са 13 додато и 3 уклоњено
  1. 13 3
      imstb_textedit.h

+ 13 - 3
imstb_textedit.h

@@ -427,7 +427,7 @@ typedef struct
 //
 //
 
 
 // traverse the layout to locate the nearest character to a display position
 // traverse the layout to locate the nearest character to a display position
-static int stb_text_locate_coord(IMSTB_TEXTEDIT_STRING *str, float x, float y)
+static int stb_text_locate_coord(IMSTB_TEXTEDIT_STRING *str, float x, float y, int* out_side_on_line)
 {
 {
    StbTexteditRow r;
    StbTexteditRow r;
    int n = STB_TEXTEDIT_STRINGLEN(str);
    int n = STB_TEXTEDIT_STRINGLEN(str);
@@ -437,6 +437,7 @@ static int stb_text_locate_coord(IMSTB_TEXTEDIT_STRING *str, float x, float y)
    r.x0 = r.x1 = 0;
    r.x0 = r.x1 = 0;
    r.ymin = r.ymax = 0;
    r.ymin = r.ymax = 0;
    r.num_chars = 0;
    r.num_chars = 0;
+   *out_side_on_line = 0;
 
 
    // search rows to find one that straddles 'y'
    // search rows to find one that straddles 'y'
    while (i < n) {
    while (i < n) {
@@ -456,7 +457,10 @@ static int stb_text_locate_coord(IMSTB_TEXTEDIT_STRING *str, float x, float y)
 
 
    // below all text, return 'after' last character
    // below all text, return 'after' last character
    if (i >= n)
    if (i >= n)
+   {
+      *out_side_on_line = 1;
       return n;
       return n;
+   }
 
 
    // check if it's before the beginning of the line
    // check if it's before the beginning of the line
    if (x < r.x0)
    if (x < r.x0)
@@ -469,6 +473,7 @@ static int stb_text_locate_coord(IMSTB_TEXTEDIT_STRING *str, float x, float y)
       for (k=0; k < r.num_chars; k = IMSTB_TEXTEDIT_GETNEXTCHARINDEX(str, i + k) - i) {
       for (k=0; k < r.num_chars; k = IMSTB_TEXTEDIT_GETNEXTCHARINDEX(str, i + k) - i) {
          float w = STB_TEXTEDIT_GETWIDTH(str, i, k);
          float w = STB_TEXTEDIT_GETWIDTH(str, i, k);
          if (x < prev_x+w) {
          if (x < prev_x+w) {
+            *out_side_on_line = (k == 0) ? 0 : 1;
             if (x < prev_x+w/2)
             if (x < prev_x+w/2)
                return k+i;
                return k+i;
             else
             else
@@ -480,6 +485,7 @@ static int stb_text_locate_coord(IMSTB_TEXTEDIT_STRING *str, float x, float y)
    }
    }
 
 
    // if the last character is a newline, return that. otherwise return 'after' the last character
    // if the last character is a newline, return that. otherwise return 'after' the last character
+   *out_side_on_line = 1;
    if (STB_TEXTEDIT_GETCHAR(str, i+r.num_chars-1) == STB_TEXTEDIT_NEWLINE)
    if (STB_TEXTEDIT_GETCHAR(str, i+r.num_chars-1) == STB_TEXTEDIT_NEWLINE)
       return i+r.num_chars-1;
       return i+r.num_chars-1;
    else
    else
@@ -491,6 +497,7 @@ static void stb_textedit_click(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *st
 {
 {
    // In single-line mode, just always make y = 0. This lets the drag keep working if the mouse
    // In single-line mode, just always make y = 0. This lets the drag keep working if the mouse
    // goes off the top or bottom of the text
    // goes off the top or bottom of the text
+   int side_on_line;
    if( state->single_line )
    if( state->single_line )
    {
    {
       StbTexteditRow r;
       StbTexteditRow r;
@@ -498,16 +505,18 @@ static void stb_textedit_click(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *st
       y = r.ymin;
       y = r.ymin;
    }
    }
 
 
-   state->cursor = stb_text_locate_coord(str, x, y);
+   state->cursor = stb_text_locate_coord(str, x, y, &side_on_line);
    state->select_start = state->cursor;
    state->select_start = state->cursor;
    state->select_end = state->cursor;
    state->select_end = state->cursor;
    state->has_preferred_x = 0;
    state->has_preferred_x = 0;
+   str->LastMoveDirectionLR = (ImS8)(side_on_line ? ImGuiDir_Right : ImGuiDir_Left);
 }
 }
 
 
 // API drag: on mouse drag, move the cursor and selection endpoint to the clicked location
 // API drag: on mouse drag, move the cursor and selection endpoint to the clicked location
 static void stb_textedit_drag(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y)
 static void stb_textedit_drag(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y)
 {
 {
    int p = 0;
    int p = 0;
+   int side_on_line;
 
 
    // In single-line mode, just always make y = 0. This lets the drag keep working if the mouse
    // In single-line mode, just always make y = 0. This lets the drag keep working if the mouse
    // goes off the top or bottom of the text
    // goes off the top or bottom of the text
@@ -521,8 +530,9 @@ static void stb_textedit_drag(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *sta
    if (state->select_start == state->select_end)
    if (state->select_start == state->select_end)
       state->select_start = state->cursor;
       state->select_start = state->cursor;
 
 
-   p = stb_text_locate_coord(str, x, y);
+   p = stb_text_locate_coord(str, x, y, &side_on_line);
    state->cursor = state->select_end = p;
    state->cursor = state->select_end = p;
+   str->LastMoveDirectionLR = (ImS8)(side_on_line ? ImGuiDir_Right : ImGuiDir_Left);
 }
 }
 
 
 /////////////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////