mirror of
https://github.com/Drezil/imgui.git
synced 2024-11-15 01:17:00 +00:00
InputText: fixed handling of scaled font. re-organized bits of code toward merging all sizes calculations (#200)
This commit is contained in:
parent
10b4fa44c1
commit
c6d77f3bf5
51
imgui.cpp
51
imgui.cpp
@ -1323,7 +1323,7 @@ struct ImGuiState
|
|||||||
{
|
{
|
||||||
Initialized = false;
|
Initialized = false;
|
||||||
Font = NULL;
|
Font = NULL;
|
||||||
FontBaseSize = FontSize = 0.0f;
|
FontSize = FontBaseSize = 0.0f;
|
||||||
FontTexUvWhitePixel = ImVec2(0.0f, 0.0f);
|
FontTexUvWhitePixel = ImVec2(0.0f, 0.0f);
|
||||||
|
|
||||||
Time = 0.0f;
|
Time = 0.0f;
|
||||||
@ -6514,13 +6514,11 @@ bool ImGui::RadioButton(const char* label, int* v, int v_button)
|
|||||||
return pressed;
|
return pressed;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ImVec2 CalcTextSizeW(ImFont* font, float font_size, float max_width, const ImWchar* text_begin, const ImWchar* text_end, const ImWchar** remaining = NULL, ImVec2* out_offset = NULL, bool stop_on_new_line = false)
|
static ImVec2 InputTextCalcTextSizeW(const ImWchar* text_begin, const ImWchar* text_end, const ImWchar** remaining = NULL, ImVec2* out_offset = NULL, bool stop_on_new_line = false)
|
||||||
{
|
{
|
||||||
if (!text_end)
|
ImFont* font = GImGui->Font;
|
||||||
text_end = text_begin + ImStrlenW(text_begin);
|
const float line_height = GImGui->FontSize;
|
||||||
|
const float scale = line_height / font->FontSize;
|
||||||
const float scale = font_size / font->FontSize;
|
|
||||||
const float line_height = font->FontSize * scale;
|
|
||||||
|
|
||||||
ImVec2 text_size = ImVec2(0,0);
|
ImVec2 text_size = ImVec2(0,0);
|
||||||
float line_width = 0.0f;
|
float line_width = 0.0f;
|
||||||
@ -6545,13 +6543,7 @@ static ImVec2 CalcTextSizeW(ImFont* font, float font_size, float max_width, cons
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const float char_width = font->GetCharAdvance((unsigned short)c);
|
const float char_width = font->GetCharAdvance((unsigned short)c) * scale;
|
||||||
if (line_width + char_width >= max_width)
|
|
||||||
{
|
|
||||||
s--;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
line_width += char_width;
|
line_width += char_width;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6573,15 +6565,14 @@ static ImVec2 CalcTextSizeW(ImFont* font, float font_size, float max_width, cons
|
|||||||
// Wrapper for stb_textedit.h to edit text (our wrapper is for: statically sized buffer, single-line, wchar characters. InputText converts between UTF-8 and wchar)
|
// Wrapper for stb_textedit.h to edit text (our wrapper is for: statically sized buffer, single-line, wchar characters. InputText converts between UTF-8 and wchar)
|
||||||
static int STB_TEXTEDIT_STRINGLEN(const STB_TEXTEDIT_STRING* obj) { return (int)obj->CurLenW; }
|
static int STB_TEXTEDIT_STRINGLEN(const STB_TEXTEDIT_STRING* obj) { return (int)obj->CurLenW; }
|
||||||
static ImWchar STB_TEXTEDIT_GETCHAR(const STB_TEXTEDIT_STRING* obj, int idx) { return obj->Text[idx]; }
|
static ImWchar STB_TEXTEDIT_GETCHAR(const STB_TEXTEDIT_STRING* obj, int idx) { return obj->Text[idx]; }
|
||||||
static float STB_TEXTEDIT_GETWIDTH(STB_TEXTEDIT_STRING* obj, int line_start_idx, int char_idx) { ImWchar c = obj->Text[line_start_idx+char_idx]; if (c == '\n') return STB_TEXTEDIT_GETWIDTH_NEWLINE; return GImGui->Font->GetCharAdvance(c); }
|
static float STB_TEXTEDIT_GETWIDTH(STB_TEXTEDIT_STRING* obj, int line_start_idx, int char_idx) { ImWchar c = obj->Text[line_start_idx+char_idx]; if (c == '\n') return STB_TEXTEDIT_GETWIDTH_NEWLINE; return GImGui->Font->GetCharAdvance(c) * (GImGui->FontSize / GImGui->Font->FontSize); }
|
||||||
static int STB_TEXTEDIT_KEYTOTEXT(int key) { return key >= 0x10000 ? 0 : key; }
|
static int STB_TEXTEDIT_KEYTOTEXT(int key) { return key >= 0x10000 ? 0 : key; }
|
||||||
static ImWchar STB_TEXTEDIT_NEWLINE = '\n';
|
static ImWchar STB_TEXTEDIT_NEWLINE = '\n';
|
||||||
static void STB_TEXTEDIT_LAYOUTROW(StbTexteditRow* r, STB_TEXTEDIT_STRING* obj, int line_start_idx)
|
static void STB_TEXTEDIT_LAYOUTROW(StbTexteditRow* r, STB_TEXTEDIT_STRING* obj, int line_start_idx)
|
||||||
{
|
{
|
||||||
ImGuiState& g = *GImGui;
|
|
||||||
const ImWchar* text = obj->Text.begin();
|
const ImWchar* text = obj->Text.begin();
|
||||||
const ImWchar* text_remaining = NULL;
|
const ImWchar* text_remaining = NULL;
|
||||||
const ImVec2 size = CalcTextSizeW(g.Font, g.FontSize, FLT_MAX, text + line_start_idx, text + obj->CurLenW, &text_remaining, NULL, true);
|
const ImVec2 size = InputTextCalcTextSizeW(text + line_start_idx, text + obj->CurLenW, &text_remaining, NULL, true);
|
||||||
r->x0 = 0.0f;
|
r->x0 = 0.0f;
|
||||||
r->x1 = size.x;
|
r->x1 = size.x;
|
||||||
r->baseline_y_delta = size.y;
|
r->baseline_y_delta = size.y;
|
||||||
@ -7099,18 +7090,21 @@ static bool InputTextEx(const char* label, char* buf, size_t buf_size, const ImV
|
|||||||
const float font_offy_dn = 2.0f;
|
const float font_offy_dn = 2.0f;
|
||||||
const ImVec2 render_pos = is_multiline ? draw_window->DC.CursorPos : frame_bb.Min + style.FramePadding;
|
const ImVec2 render_pos = is_multiline ? draw_window->DC.CursorPos : frame_bb.Min + style.FramePadding;
|
||||||
|
|
||||||
//const ImVec2 render_scroll = (g.ActiveId == id) ? edit_state.Scroll : ImVec2(0.f, 0.f);
|
|
||||||
const ImVec2 render_scroll = ImVec2((edit_state.Id == id) ? edit_state.ScrollX : 0.0f, 0.0f);
|
|
||||||
ImVec4 clip_rect(frame_bb.Min.x, frame_bb.Min.y, frame_bb.Min.x + size.x + style.FramePadding.x*2.0f, frame_bb.Min.y + size.y + style.FramePadding.y*2.0f);
|
ImVec4 clip_rect(frame_bb.Min.x, frame_bb.Min.y, frame_bb.Min.x + size.x + style.FramePadding.x*2.0f, frame_bb.Min.y + size.y + style.FramePadding.y*2.0f);
|
||||||
|
ImVec2 text_size(0.f, 0.f);
|
||||||
if (g.ActiveId == id || (edit_state.Id == id && is_multiline && g.ActiveId == draw_window->GetID("#SCROLLY")))
|
if (g.ActiveId == id || (edit_state.Id == id && is_multiline && g.ActiveId == draw_window->GetID("#SCROLLY")))
|
||||||
{
|
{
|
||||||
|
//const ImVec2 render_scroll = (g.ActiveId == id) ? edit_state.Scroll : ImVec2(0.f, 0.f);
|
||||||
|
ImVec2 render_scroll = ImVec2((edit_state.Id == id) ? edit_state.ScrollX : 0.0f, 0.0f);
|
||||||
edit_state.CursorAnim += g.IO.DeltaTime;
|
edit_state.CursorAnim += g.IO.DeltaTime;
|
||||||
|
|
||||||
// 1. Display the text (this can be more easily clipped)
|
// 1. Display the text (this can be more easily clipped)
|
||||||
// 2. Handle scrolling, highlight selection, display cursor: those all requires some form of 1d->2d cursor position calculation, which we will try to merge to minimize the cost.
|
// 2. Handle scrolling, highlight selection, display cursor: those all requires some form of 1d->2d cursor position calculation, which we will try to merge to minimize the cost.
|
||||||
ImVec2 cursor_offset;
|
ImVec2 cursor_offset;
|
||||||
CalcTextSizeW(g.Font, g.FontSize, FLT_MAX, edit_state.Text.begin(), edit_state.Text.begin() + edit_state.StbState.cursor, NULL, &cursor_offset);
|
InputTextCalcTextSizeW(edit_state.Text.begin(), edit_state.Text.begin() + edit_state.StbState.cursor, NULL, &cursor_offset);
|
||||||
|
|
||||||
|
if (is_multiline)
|
||||||
|
text_size = InputTextCalcTextSizeW(edit_state.Text.begin(), edit_state.Text.begin() + edit_state.CurLenW);
|
||||||
|
|
||||||
// Scroll
|
// Scroll
|
||||||
if (edit_state.CursorFollow)
|
if (edit_state.CursorFollow)
|
||||||
@ -7118,9 +7112,9 @@ static bool InputTextEx(const char* label, char* buf, size_t buf_size, const ImV
|
|||||||
// Horizontal scroll in chunks of quarter width
|
// Horizontal scroll in chunks of quarter width
|
||||||
const float scroll_increment_x = size.x * 0.25f;
|
const float scroll_increment_x = size.x * 0.25f;
|
||||||
if (cursor_offset.x < edit_state.ScrollX)
|
if (cursor_offset.x < edit_state.ScrollX)
|
||||||
edit_state.ScrollX = ImMax(0.0f, cursor_offset.x - scroll_increment_x);
|
render_scroll.x = edit_state.ScrollX = ImMax(0.0f, cursor_offset.x - scroll_increment_x);
|
||||||
else if (cursor_offset.x - size.x >= edit_state.ScrollX)
|
else if (cursor_offset.x - size.x >= edit_state.ScrollX)
|
||||||
edit_state.ScrollX = cursor_offset.x - size.x + scroll_increment_x;
|
render_scroll.x = edit_state.ScrollX = cursor_offset.x - size.x + scroll_increment_x;
|
||||||
|
|
||||||
// Vertical scroll
|
// Vertical scroll
|
||||||
if (is_multiline)
|
if (is_multiline)
|
||||||
@ -7142,12 +7136,12 @@ static bool InputTextEx(const char* label, char* buf, size_t buf_size, const ImV
|
|||||||
ImWchar* text_selected_begin = edit_state.Text.begin() + ImMin(select_begin_idx,select_end_idx);
|
ImWchar* text_selected_begin = edit_state.Text.begin() + ImMin(select_begin_idx,select_end_idx);
|
||||||
ImWchar* text_selected_end = edit_state.Text.begin() + ImMax(select_begin_idx,select_end_idx);
|
ImWchar* text_selected_end = edit_state.Text.begin() + ImMax(select_begin_idx,select_end_idx);
|
||||||
ImVec2 rect_pos;
|
ImVec2 rect_pos;
|
||||||
CalcTextSizeW(g.Font, g.FontSize, FLT_MAX, edit_state.Text.begin(), text_selected_begin, NULL, &rect_pos);
|
InputTextCalcTextSizeW(edit_state.Text.begin(), text_selected_begin, NULL, &rect_pos);
|
||||||
|
|
||||||
ImU32 bg_color = draw_window->Color(ImGuiCol_TextSelectedBg);
|
ImU32 bg_color = draw_window->Color(ImGuiCol_TextSelectedBg);
|
||||||
for (const ImWchar* p = text_selected_begin; p < text_selected_end; )
|
for (const ImWchar* p = text_selected_begin; p < text_selected_end; )
|
||||||
{
|
{
|
||||||
ImVec2 rect_size = CalcTextSizeW(g.Font, g.FontSize, FLT_MAX, p, text_selected_end, &p, NULL, true);
|
ImVec2 rect_size = InputTextCalcTextSizeW(p, text_selected_end, &p, NULL, true);
|
||||||
if (rect_size.x <= 0.0f) rect_size.x = (float)(int)(g.Font->GetCharAdvance((unsigned short)' ') * 0.50f); // So we can see selected empty lines
|
if (rect_size.x <= 0.0f) rect_size.x = (float)(int)(g.Font->GetCharAdvance((unsigned short)' ') * 0.50f); // So we can see selected empty lines
|
||||||
ImRect rect(render_pos - render_scroll + rect_pos + ImVec2(0.0f, (p == text_selected_begin) ? -font_offy_up : -g.FontSize), render_pos - render_scroll + rect_pos + ImVec2(rect_size.x, (p == text_selected_end) ? +font_offy_dn : 0.0f));
|
ImRect rect(render_pos - render_scroll + rect_pos + ImVec2(0.0f, (p == text_selected_begin) ? -font_offy_up : -g.FontSize), render_pos - render_scroll + rect_pos + ImVec2(rect_size.x, (p == text_selected_end) ? +font_offy_dn : 0.0f));
|
||||||
rect.Clip(clip_rect);
|
rect.Clip(clip_rect);
|
||||||
@ -7174,13 +7168,14 @@ static bool InputTextEx(const char* label, char* buf, size_t buf_size, const ImV
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Render text only
|
// Render text only
|
||||||
draw_window->DrawList->AddText(g.Font, g.FontSize, render_pos - render_scroll, draw_window->Color(ImGuiCol_Text), buf, NULL, 0.0f, is_multiline ? NULL : &clip_rect);
|
draw_window->DrawList->AddText(g.Font, g.FontSize, render_pos, draw_window->Color(ImGuiCol_Text), buf, NULL, 0.0f, is_multiline ? NULL : &clip_rect);
|
||||||
|
|
||||||
|
if (is_multiline)
|
||||||
|
text_size = g.Font->CalcTextSizeA(g.FontSize, FLT_MAX, 0.0f, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_multiline)
|
if (is_multiline)
|
||||||
{
|
{
|
||||||
// FIXME-OPT FIXME-WIP-MULTILINE
|
|
||||||
ImVec2 text_size = g.Font->CalcTextSizeA(g.FontSize, FLT_MAX, 0.0f, buf);
|
|
||||||
ImGui::Dummy(text_size + ImVec2(0.0f, g.FontSize)); // Always add room to scroll an extra line
|
ImGui::Dummy(text_size + ImVec2(0.0f, g.FontSize)); // Always add room to scroll an extra line
|
||||||
ImGui::EndChildFrame();
|
ImGui::EndChildFrame();
|
||||||
ImGui::EndGroup();
|
ImGui::EndGroup();
|
||||||
|
Loading…
Reference in New Issue
Block a user