Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added substring flags and a substring for newlines #403

Merged
merged 3 commits into from
Oct 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 27 additions & 17 deletions examples/editbox.c
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,6 @@ static void SaveCandidates(EditBox *edit, const SDL_Event *event)
if (i == selected_candidate) {
edit->selected_candidate_start = (int)(uintptr_t)(dst - candidate_text);
edit->selected_candidate_length = length;
SDL_Log("Selected candidate: %d/%d\n", edit->selected_candidate_start, edit->selected_candidate_length);
}
SDL_memcpy(dst, event->edit_candidates.candidates[i], length);
dst += length;
Expand Down Expand Up @@ -238,10 +237,20 @@ static void DrawCandidates(EditBox *edit)
float x, y;

/* Position the candidate window */
TTF_SubString cursor;
int offset = edit->composition_start;
if (edit->composition_cursor_length > 0) {
// Place the candidates at the active clause
offset += edit->composition_cursor;
}
if (!TTF_GetTextSubString(edit->text, offset, &cursor)) {
return;
}

SDL_GetRenderSafeArea(renderer, &safe_rect);
TTF_GetTextSize(edit->candidates, &candidates_w, &candidates_h);
candidates_rect.x = edit->cursor_rect.x;
candidates_rect.y = edit->cursor_rect.y + edit->cursor_rect.h + 2.0f;
candidates_rect.x = edit->rect.x + cursor.rect.x;
candidates_rect.y = edit->rect.y + cursor.rect.y + cursor.rect.h + 2.0f;
candidates_rect.w = 1.0f + 2.0f + candidates_w + 2.0f + 1.0f;
candidates_rect.h = 1.0f + 2.0f + candidates_h + 2.0f + 1.0f;
if ((candidates_rect.x + candidates_rect.w) > safe_rect.w) {
Expand Down Expand Up @@ -294,10 +303,10 @@ static void UpdateTextInputArea(EditBox *edit)
}

SDL_Rect rect;
rect.x = (int)SDL_floorf(window_edit_rect_min.x);
rect.y = (int)SDL_floorf(window_edit_rect_min.y);
rect.w = (int)SDL_floorf(window_edit_rect_max.x - window_edit_rect_min.x);
rect.h = (int)SDL_floorf(window_edit_rect_max.y - window_edit_rect_min.y);
rect.x = (int)SDL_roundf(window_edit_rect_min.x);
rect.y = (int)SDL_roundf(window_edit_rect_min.y);
rect.w = (int)SDL_roundf(window_edit_rect_max.x - window_edit_rect_min.x);
rect.h = (int)SDL_roundf(window_edit_rect_max.y - window_edit_rect_min.y);
int cursor_offset = (int)SDL_roundf(window_cursor.x - window_edit_rect_min.x);
SDL_SetTextInputArea(edit->window, &rect, cursor_offset);
}
Expand Down Expand Up @@ -447,6 +456,10 @@ void EditBox_Draw(EditBox *edit)

static int GetCursorTextIndex(TTF_Font *font, int x, const TTF_SubString *substring)
{
if (substring->flags & TTF_SUBSTRING_LINE_END) {
return substring->offset;
}

bool round_down;
if (TTF_GetFontDirection(font) == TTF_DIRECTION_RTL) {
round_down = (x > (substring->rect.x + substring->rect.w / 2));
Expand Down Expand Up @@ -529,11 +542,11 @@ void EditBox_MoveCursorUp(EditBox *edit)
int fontHeight = TTF_GetFontHeight(edit->font);
int x, y;
if (TTF_GetFontDirection(edit->font) == TTF_DIRECTION_RTL) {
x = substring.rect.x + substring.rect.w;
x = substring.rect.x + substring.rect.w - 1;
} else {
x = substring.rect.x;
}
y = substring.rect.y - fontHeight;
y = substring.rect.y - fontHeight / 2;
if (TTF_GetTextSubStringForPoint(edit->text, x, y, &substring)) {
SetCursorPosition(edit, GetCursorTextIndex(edit->font, x, &substring));
}
Expand All @@ -551,11 +564,11 @@ void EditBox_MoveCursorDown(EditBox *edit)
int fontHeight = TTF_GetFontHeight(edit->font);
int x, y;
if (TTF_GetFontDirection(edit->font) == TTF_DIRECTION_RTL) {
x = substring.rect.x + substring.rect.w;
x = substring.rect.x + substring.rect.w - 1;
} else {
x = substring.rect.x;
}
y = substring.rect.y + substring.rect.h + fontHeight;
y = substring.rect.y + substring.rect.h + fontHeight / 2;
if (TTF_GetTextSubStringForPoint(edit->text, x, y, &substring)) {
SetCursorPosition(edit, GetCursorTextIndex(edit->font, x, &substring));
}
Expand Down Expand Up @@ -687,13 +700,12 @@ static bool HandleMouseDown(EditBox *edit, float x, float y)

if (!edit->has_focus) {
EditBox_SetFocus(edit, true);
return true;
}

/* Set the cursor position */
TTF_SubString substring;
int textX = (int)SDL_roundf(x - (edit->rect.x + 4.0f));
int textY = (int)SDL_roundf(y - (edit->rect.y + 4.0f));
int textX = (int)SDL_roundf(x - edit->rect.x);
int textY = (int)SDL_roundf(y - edit->rect.y);
if (!TTF_GetTextSubStringForPoint(edit->text, textX, textY, &substring)) {
SDL_Log("Couldn't get cursor location: %s\n", SDL_GetError());
return false;
Expand Down Expand Up @@ -820,9 +832,7 @@ void EditBox_Paste(EditBox *edit)
}

const char *text = SDL_GetClipboardText();
size_t length = SDL_strlen(text);
TTF_InsertTextString(edit->text, edit->cursor, text, length);
SetCursorPosition(edit, (int)(edit->cursor + length));
EditBox_Insert(edit, text);
}

void EditBox_Insert(EditBox *edit, const char *text)
Expand Down
71 changes: 57 additions & 14 deletions include/SDL3_ttf/SDL_ttf.h
Original file line number Diff line number Diff line change
Expand Up @@ -1687,30 +1687,49 @@ extern SDL_DECLSPEC bool SDLCALL TTF_GetTextWrapping(TTF_Text *text, bool *wrap,
*/
extern SDL_DECLSPEC bool SDLCALL TTF_GetTextSize(TTF_Text *text, int *w, int *h);

/**
* Flags for TTF_SubString
*
* \since This datatype is available since SDL_ttf 3.0.0.
*
* \sa TTF_SubString
*/
typedef Uint32 TTF_SubStringFlags;

#define TTF_SUBSTRING_TEXT_START 0x00000001 /**< This substring contains the beginning of the text */
#define TTF_SUBSTRING_LINE_START 0x00000002 /**< This substring contains the beginning of line `line_index` */
#define TTF_SUBSTRING_LINE_END 0x00000004 /**< This substring contains the end of line `line_index` */
#define TTF_SUBSTRING_TEXT_END 0x00000008 /**< This substring contains the end of the text */

/**
* The representation of a substring within text.
*
* \since This struct is available since SDL_ttf 3.0.0.
*
* \sa TTF_GetNextTextSubString
* \sa TTF_GetPreviousTextSubString
* \sa TTF_GetTextSubString
* \sa TTF_GetTextSubStringAtPoint
* \sa TTF_GetTextSubStringForLine
* \sa TTF_GetTextSubStringForPoint
* \sa TTF_GetTextSubStringsForRange
*/
typedef struct TTF_SubString
{
int offset; /**< The byte offset from the beginning of the text */
int length; /**< The byte length starting at the offset */
int line_index; /**< The index of the line that contains this substring */
int cluster_index; /**< The internal cluster index, used for quickly iterating */
SDL_Rect rect; /**< The rectangle, relative to the top left of the text, containing the substring */
TTF_SubStringFlags flags; /**< The flags for this substring */
int offset; /**< The byte offset from the beginning of the text */
int length; /**< The byte length starting at the offset */
int line_index; /**< The index of the line that contains this substring */
int cluster_index; /**< The internal cluster index, used for quickly iterating */
SDL_Rect rect; /**< The rectangle, relative to the top left of the text, containing the substring */
} TTF_SubString;

/**
* Get the substring of a text object that surrounds a text offset.
*
* If `offset` is less than 0, this will return a zero width substring at the
* beginning of the text. If `offset` is greater than or equal to the length
* of the text string, this will return a zero width substring at the end of
* the text.
* If `offset` is less than 0, this will return a zero length substring at the
* beginning of the text with the TTF_SUBSTRING_TEXT_START flag set. If `offset` is greater than or equal to the length
* of the text string, this will return a zero length substring at the end of
* the text with the TTF_SUBSTRING_TEXT_END flag set.
*
* \param text the TTF_Text to query.
* \param offset a byte offset into the text string.
Expand All @@ -1724,10 +1743,10 @@ extern SDL_DECLSPEC bool SDLCALL TTF_GetTextSubString(TTF_Text *text, int offset
/**
* Get the substring of a text object that contains the given line.
*
* If `line` is less than 0, this will return a zero width substring at the
* beginning of the text. If `line` is greater than or equal to
* `text->num_lines` this will return a zero width substring at the end of the
* text.
* If `line` is less than 0, this will return a zero length substring at the
* beginning of the text with the TTF_SUBSTRING_TEXT_START flag set. If `line` is greater than or equal to
* `text->num_lines` this will return a zero length substring at the end of the
* text with the TTF_SUBSTRING_TEXT_END flag set.
*
* \param text the TTF_Text to query.
* \param line a zero-based line index, in the range [0 .. text->num_lines-1].
Expand Down Expand Up @@ -1771,6 +1790,30 @@ extern SDL_DECLSPEC TTF_SubString ** SDLCALL TTF_GetTextSubStringsForRange(TTF_T
*/
extern SDL_DECLSPEC bool SDLCALL TTF_GetTextSubStringForPoint(TTF_Text *text, int x, int y, TTF_SubString *substring);

/**
* Get the previous substring in a text object
*
* If called at the start of the text, this will return a zero length substring with the TTF_SUBSTRING_TEXT_START flag set.
*
* \param text the TTF_Text to query.
* \param substring the TTF_SubString to query.
* \param next a pointer filled in with the previous substring.
* \returns true on success or false on failure; call SDL_GetError() for more information.
*/
extern SDL_DECLSPEC bool SDLCALL TTF_GetPreviousTextSubString(TTF_Text *text, const TTF_SubString *substring, TTF_SubString *previous);

/**
* Get the next substring in a text object
*
* If called at the end of the text, this will return a zero length substring with the TTF_SUBSTRING_TEXT_END flag set.
*
* \param text the TTF_Text to query.
* \param substring the TTF_SubString to query.
* \param next a pointer filled in with the next substring.
* \returns true on success or false on failure; call SDL_GetError() for more information.
*/
extern SDL_DECLSPEC bool SDLCALL TTF_GetNextTextSubString(TTF_Text *text, const TTF_SubString *substring, TTF_SubString *next);

/**
* Update the layout of a text object.
*
Expand Down
Loading
Loading