From 356a37edcfa78d62590b72ccc75e10839793990d Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 12 May 2015 11:49:24 +0100 Subject: [PATCH 01/11] Added window title text horizontal alignment option (#222),, ImGuiAlign_ type for future use. --- imgui.cpp | 22 +++++++++++----------- imgui.h | 10 ++++++++++ 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 43ed59d3..b4d8c092 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -498,7 +498,7 @@ static void LogText(const ImVec2& ref_pos, const char* text, const char* static void RenderText(ImVec2 pos, const char* text, const char* text_end = NULL, bool hide_text_after_hash = true); static void RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end, float wrap_width); -static void RenderTextClipped(ImVec2 pos, const char* text, const char* text_end, const ImVec2* text_size_if_known, const ImVec2& clip_max); +static void RenderTextClipped(ImVec2 pos, const char* text, const char* text_end, const ImVec2* text_size_if_known, const ImVec2& clip_max, ImGuiAlign align = ImGuiAlign_Default); static void RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool border = true, float rounding = 0.0f); static void RenderCollapseTriangle(ImVec2 p_min, bool opened, float scale = 1.0f, bool shadow = false); static void RenderCheckMark(ImVec2 pos, ImU32 col); @@ -559,6 +559,7 @@ ImGuiStyle::ImGuiStyle() WindowPadding = ImVec2(8,8); // Padding within a window WindowMinSize = ImVec2(32,32); // Minimum window size WindowRounding = 9.0f; // Radius of window corners rounding. Set to 0.0f to have rectangular windows + WindowTitleAlign = ImGuiAlign_Left; // Alignment for title bar text ChildWindowRounding = 0.0f; // Radius of child window corners rounding. Set to 0.0f to have rectangular windows FramePadding = ImVec2(4,3); // Padding within a framed rectangle (used by most widgets) FrameRounding = 0.0f; // Radius of frame corners rounding. Set to 0.0f to have rectangular frames (used by most widgets). @@ -2458,16 +2459,13 @@ static void RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end const int text_len = (int)(text_end - text); if (text_len > 0) { - // Render window->DrawList->AddText(g.Font, g.FontSize, pos, window->Color(ImGuiCol_Text), text, text_end, wrap_width); - - // Log as text if (g.LogEnabled) LogText(pos, text, text_end); } } -static void RenderTextClipped(ImVec2 pos, const char* text, const char* text_end, const ImVec2* text_size_if_known, const ImVec2& clip_max) +static void RenderTextClipped(ImVec2 pos, const char* text, const char* text_end, const ImVec2* text_size_if_known, const ImVec2& clip_max, ImGuiAlign align) { ImGuiState& g = *GImGui; ImGuiWindow* window = GetCurrentWindow(); @@ -2477,15 +2475,16 @@ static void RenderTextClipped(ImVec2 pos, const char* text, const char* text_end const int text_len = (int)(text_display_end - text); if (text_len > 0) { - const ImVec2 text_size = text_size_if_known ? *text_size_if_known : ImGui::CalcTextSize(text, text_display_end, false, 0.0f); - // Perform CPU side clipping for single clipped element to avoid using scissor state + const ImVec2 text_size = text_size_if_known ? *text_size_if_known : ImGui::CalcTextSize(text, text_display_end, false, 0.0f); const bool need_clipping = (pos.x + text_size.x >= clip_max.x) || (pos.y + text_size.y >= clip_max.y); + // Align + if (align & ImGuiAlign_Center) pos.x = ImMax(pos.x, (pos.x + clip_max.x - text_size.x) * 0.5f); + else if (align & ImGuiAlign_Right) pos.x = ImMax(pos.x, clip_max.x - text_size.x); + // Render window->DrawList->AddText(g.Font, g.FontSize, pos, window->Color(ImGuiCol_Text), text, text_display_end, 0.0f, need_clipping ? &clip_max : NULL); - - // Log as text if (g.LogEnabled) LogText(pos, text, text_display_end); } @@ -3547,8 +3546,9 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_ } const ImVec2 text_size = CalcTextSize(name, NULL, true); - const ImVec2 text_max = window->Pos + ImVec2(window->Size.x - (p_opened ? (title_bar_rect.GetHeight()-3) : style.FramePadding.x), style.FramePadding.y*2 + text_size.y); - RenderTextClipped(text_min, name, NULL, &text_size, text_max); + ImVec2 text_max = window->Pos + ImVec2(window->Size.x - (p_opened ? title_bar_rect.GetHeight()-3 : style.FramePadding.x), style.FramePadding.y*2 + text_size.y); + if (style.WindowTitleAlign & ImGuiAlign_Right) text_max.x -= style.FramePadding.x; + RenderTextClipped(text_min, name, NULL, &text_size, text_max, style.WindowTitleAlign); } if (flags & ImGuiWindowFlags_Popup) { diff --git a/imgui.h b/imgui.h index 639b0b9d..cdf5766a 100644 --- a/imgui.h +++ b/imgui.h @@ -42,6 +42,7 @@ typedef ImU32 ImGuiID; // unique ID used by widgets (typically hash typedef int ImGuiCol; // enum ImGuiCol_ typedef int ImGuiStyleVar; // enum ImGuiStyleVar_ typedef int ImGuiKey; // enum ImGuiKey_ +typedef int ImGuiAlign; // enum ImGuiAlign_ typedef int ImGuiColorEditMode; // enum ImGuiColorEditMode_ typedef int ImGuiMouseCursor; // enum ImGuiMouseCursor_ typedef int ImGuiWindowFlags; // enum ImGuiWindowFlags_ @@ -559,6 +560,14 @@ enum ImGuiStyleVar_ ImGuiStyleVar_GrabMinSize // float }; +enum ImGuiAlign_ +{ + ImGuiAlign_Left = 1 << 0, + ImGuiAlign_Center = 1 << 1, + ImGuiAlign_Right = 1 << 2, + ImGuiAlign_Default = ImGuiAlign_Left, +}; + // Enumeration for ColorEditMode() enum ImGuiColorEditMode_ { @@ -598,6 +607,7 @@ struct ImGuiStyle ImVec2 WindowPadding; // Padding within a window ImVec2 WindowMinSize; // Minimum window size float WindowRounding; // Radius of window corners rounding. Set to 0.0f to have rectangular windows + ImGuiAlign WindowTitleAlign; // Alignment for title bar text float ChildWindowRounding; // Radius of child window corners rounding. Set to 0.0f to have rectangular windows ImVec2 FramePadding; // Padding within a framed rectangle (used by most widgets) float FrameRounding; // Radius of frame corners rounding. Set to 0.0f to have rectangular frame (used by most widgets). From 30552ecfd61a7b5ab7cceaf7ecf32c5c2665371c Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 12 May 2015 11:51:22 +0100 Subject: [PATCH 02/11] Fixed comment (fix #223) --- imgui.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/imgui.h b/imgui.h index cdf5766a..61593ba5 100644 --- a/imgui.h +++ b/imgui.h @@ -318,11 +318,11 @@ namespace ImGui IMGUI_API bool VSliderInt(const char* label, const ImVec2& size, int* v, int v_min, int v_max, const char* display_format = "%.0f"); // Widgets: Drags (tip: ctrl+click on a drag box to input text) - IMGUI_API bool DragFloat(const char* label, float* v, float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* display_format = "%.3f", float power = 1.0f); // If v_max >= v_max we have no bound + IMGUI_API bool DragFloat(const char* label, float* v, float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* display_format = "%.3f", float power = 1.0f); // If v_min >= v_max we have no bound IMGUI_API bool DragFloat2(const char* label, float v[2], float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* display_format = "%.3f", float power = 1.0f); IMGUI_API bool DragFloat3(const char* label, float v[3], float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* display_format = "%.3f", float power = 1.0f); IMGUI_API bool DragFloat4(const char* label, float v[4], float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* display_format = "%.3f", float power = 1.0f); - IMGUI_API bool DragInt(const char* label, int* v, float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* display_format = "%.0f"); // If v_max >= v_max we have no bound + IMGUI_API bool DragInt(const char* label, int* v, float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* display_format = "%.0f"); // If v_min >= v_max we have no bound IMGUI_API bool DragInt2(const char* label, int v[2], float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* display_format = "%.0f"); IMGUI_API bool DragInt3(const char* label, int v[3], float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* display_format = "%.0f"); IMGUI_API bool DragInt4(const char* label, int v[4], float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* display_format = "%.0f"); From ad79db32c73ae98ed76ae875c016777183fd0f58 Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 12 May 2015 14:02:45 +0100 Subject: [PATCH 03/11] Window title text centering tweaks, RenderTextClipped() now has different args for pos_max and clip_max #222 --- imgui.cpp | 59 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 31 insertions(+), 28 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index b4d8c092..4c40ffc9 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -498,7 +498,7 @@ static void LogText(const ImVec2& ref_pos, const char* text, const char* static void RenderText(ImVec2 pos, const char* text, const char* text_end = NULL, bool hide_text_after_hash = true); static void RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end, float wrap_width); -static void RenderTextClipped(ImVec2 pos, const char* text, const char* text_end, const ImVec2* text_size_if_known, const ImVec2& clip_max, ImGuiAlign align = ImGuiAlign_Default); +static void RenderTextClipped(ImVec2 pos, const char* text, const char* text_end, const ImVec2* text_size_if_known, const ImVec2& pos_max, const ImVec2* clip_max = NULL, ImGuiAlign align = ImGuiAlign_Default); static void RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool border = true, float rounding = 0.0f); static void RenderCollapseTriangle(ImVec2 p_min, bool opened, float scale = 1.0f, bool shadow = false); static void RenderCheckMark(ImVec2 pos, ImU32 col); @@ -2465,29 +2465,30 @@ static void RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end } } -static void RenderTextClipped(ImVec2 pos, const char* text, const char* text_end, const ImVec2* text_size_if_known, const ImVec2& clip_max, ImGuiAlign align) +static void RenderTextClipped(ImVec2 pos, const char* text, const char* text_end, const ImVec2* text_size_if_known, const ImVec2& pos_max, const ImVec2* clip_max, ImGuiAlign align) { - ImGuiState& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - // Hide anything after a '##' string const char* text_display_end = FindTextDisplayEnd(text, text_end); const int text_len = (int)(text_display_end - text); - if (text_len > 0) - { - // Perform CPU side clipping for single clipped element to avoid using scissor state - const ImVec2 text_size = text_size_if_known ? *text_size_if_known : ImGui::CalcTextSize(text, text_display_end, false, 0.0f); - const bool need_clipping = (pos.x + text_size.x >= clip_max.x) || (pos.y + text_size.y >= clip_max.y); + if (text_len == 0) + return; - // Align - if (align & ImGuiAlign_Center) pos.x = ImMax(pos.x, (pos.x + clip_max.x - text_size.x) * 0.5f); - else if (align & ImGuiAlign_Right) pos.x = ImMax(pos.x, clip_max.x - text_size.x); + ImGuiState& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); - // Render - window->DrawList->AddText(g.Font, g.FontSize, pos, window->Color(ImGuiCol_Text), text, text_display_end, 0.0f, need_clipping ? &clip_max : NULL); - if (g.LogEnabled) - LogText(pos, text, text_display_end); - } + // Perform CPU side clipping for single clipped element to avoid using scissor state + const ImVec2 text_size = text_size_if_known ? *text_size_if_known : ImGui::CalcTextSize(text, text_display_end, false, 0.0f); + if (!clip_max) clip_max = &pos_max; + const bool need_clipping = (pos.x + text_size.x >= clip_max->x) || (pos.y + text_size.y >= clip_max->y); + + // Align + if (align & ImGuiAlign_Center) pos.x = ImMax(pos.x, (pos.x + pos_max.x - text_size.x) * 0.5f); + else if (align & ImGuiAlign_Right) pos.x = ImMax(pos.x, pos_max.x - text_size.x); + + // Render + window->DrawList->AddText(g.Font, g.FontSize, pos, window->Color(ImGuiCol_Text), text, text_display_end, 0.0f, need_clipping ? clip_max : NULL); + if (g.LogEnabled) + LogText(pos, text, text_display_end); } // Render a rectangle shaped with optional rounding and borders @@ -3538,17 +3539,19 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_ if (p_opened != NULL) CloseWindowButton(p_opened); - ImVec2 text_min = window->Pos + style.FramePadding; - if (!(flags & ImGuiWindowFlags_NoCollapse)) - { - RenderCollapseTriangle(window->Pos + style.FramePadding, !window->Collapsed, 1.0f, true); - text_min.x += g.FontSize + style.ItemInnerSpacing.x; - } - const ImVec2 text_size = CalcTextSize(name, NULL, true); - ImVec2 text_max = window->Pos + ImVec2(window->Size.x - (p_opened ? title_bar_rect.GetHeight()-3 : style.FramePadding.x), style.FramePadding.y*2 + text_size.y); - if (style.WindowTitleAlign & ImGuiAlign_Right) text_max.x -= style.FramePadding.x; - RenderTextClipped(text_min, name, NULL, &text_size, text_max, style.WindowTitleAlign); + if (!(flags & ImGuiWindowFlags_NoCollapse)) + RenderCollapseTriangle(window->Pos + style.FramePadding, !window->Collapsed, 1.0f, true); + + ImVec2 text_min = window->Pos + style.FramePadding; + ImVec2 text_max = window->Pos + ImVec2(window->Size.x - style.FramePadding.x, style.FramePadding.y*2 + text_size.y); + ImVec2 clip_max = ImVec2(window->Pos.x + window->Size.x - (p_opened ? title_bar_rect.GetHeight() - 3 : style.FramePadding.x), text_max.y); // Match the size of CloseWindowButton() + bool pad_left = (flags & ImGuiWindowFlags_NoCollapse) == 0; + bool pad_right = (p_opened != NULL); + if (style.WindowTitleAlign & ImGuiAlign_Center) pad_right = pad_left; + if (pad_left) text_min.x += g.FontSize + style.ItemInnerSpacing.x; + if (pad_right) text_max.x -= g.FontSize + style.ItemInnerSpacing.x; + RenderTextClipped(text_min, name, NULL, &text_size, text_max, &clip_max, style.WindowTitleAlign); } if (flags & ImGuiWindowFlags_Popup) { From 9d9cf31972b96f90e46ac547423d724bf8647ded Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 12 May 2015 14:53:29 +0100 Subject: [PATCH 04/11] ImFontAtlas: added ClearFonts(), making the different clear funcs more explicit (#224) --- imgui.cpp | 14 ++++++++++---- imgui.h | 7 ++++--- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 4c40ffc9..1ca522f5 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -343,6 +343,7 @@ - columns: columns header to act as button (~sort op) and allow resize/reorder (github issue #125) - columns: user specify columns size (github issue #125) - popup: border options. richer api like BeginChild() perhaps? (github issue #197) + - combo: sparse combo boxes (via function call?) - combo: turn child handling code into pop up helper - combo: contents should extends to fit label if combo widget is small - combo/listbox: keyboard control. need inputtext like non-active focus + key handling. considering keybord for custom listbox (see github pr #203) @@ -8384,10 +8385,8 @@ void ImFontAtlas::ClearTexData() TexPixelsRGBA32 = NULL; } -void ImFontAtlas::Clear() +void ImFontAtlas::ClearFonts() { - ClearInputData(); - ClearTexData(); for (size_t i = 0; i < Fonts.size(); i++) { Fonts[i]->~ImFont(); @@ -8396,6 +8395,13 @@ void ImFontAtlas::Clear() Fonts.clear(); } +void ImFontAtlas::Clear() +{ + ClearInputData(); + ClearTexData(); + ClearFonts(); +} + void ImGui::GetDefaultFontData(const void** fnt_data, unsigned int* fnt_size, const void** png_data, unsigned int* png_size) { printf("GetDefaultFontData() is obsoleted in ImGui 1.30.\n"); @@ -9824,7 +9830,7 @@ void ImGui::ShowTestWindow(bool* opened) ImGui::TreePop(); } - if (ImGui::TreeNode("Fonts")) + if (ImGui::TreeNode("Fonts", "Fonts (%d)", (int)ImGui::GetIO().Fonts->Fonts.size())) { ImGui::TextWrapped("Tip: Load fonts with GetIO().Fonts->AddFontFromFileTTF()."); for (size_t i = 0; i < ImGui::GetIO().Fonts->Fonts.size(); i++) diff --git a/imgui.h b/imgui.h index 61593ba5..378e9b30 100644 --- a/imgui.h +++ b/imgui.h @@ -979,8 +979,10 @@ struct ImFontAtlas IMGUI_API ImFont* AddFontFromFileTTF(const char* filename, float size_pixels, const ImWchar* glyph_ranges = NULL, int font_no = 0); IMGUI_API ImFont* AddFontFromMemoryTTF(void* ttf_data, int ttf_size, float size_pixels, const ImWchar* glyph_ranges = NULL, int font_no = 0); // Transfer ownership of 'ttf_data' to ImFontAtlas, will be deleted after Build() IMGUI_API ImFont* AddFontFromMemoryCompressedTTF(const void* compressed_ttf_data, int compressed_ttf_size, float size_pixels, const ImWchar* glyph_ranges = NULL, int font_no = 0); // 'compressed_ttf_data' untouched and still owned by caller. Compress with binary_to_compressed_c.cpp - IMGUI_API void ClearTexData(); // Saves RAM once the texture has been copied to graphics memory. - IMGUI_API void Clear(); + IMGUI_API void ClearTexData(); // Clear the CPU-side texture data. Saves RAM once the texture has been copied to graphics memory. + IMGUI_API void ClearInputData(); // Clear the input TTF data (inc sizes, glyph ranges) + IMGUI_API void ClearFonts(); // Clear the ImGui-side font data (glyphs storage, UV coordinates) + IMGUI_API void Clear(); // Clear all // Retrieve texture data // User is in charge of copying the pixels into graphics memory, then call SetTextureUserID() @@ -1011,7 +1013,6 @@ struct ImFontAtlas struct ImFontAtlasData; ImVector InputData; // Internal data IMGUI_API bool Build(); // Build pixels data. This is automatically for you by the GetTexData*** functions. - IMGUI_API void ClearInputData(); // Clear the input TTF data. IMGUI_API void RenderCustomTexData(int pass, void* rects); }; From 4b088ec7e896218bc67c79457fa6ce4def1f1bbb Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 12 May 2015 15:10:36 +0100 Subject: [PATCH 05/11] ImFontAtlas: Fix toward allowing to add extra font without clearing existing one (need to comment out ClearInputData) (#224) --- imgui.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 1ca522f5..e906baf4 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -8531,7 +8531,7 @@ bool ImFontAtlas::Build() for (size_t input_i = 0; input_i < InputData.size(); input_i++) { ImFontAtlasData& data = *InputData[input_i]; - IM_ASSERT(data.OutFont && !data.OutFont->IsLoaded()); + IM_ASSERT(data.OutFont && (!data.OutFont->IsLoaded() || data.OutFont->ContainerAtlas == this)); const int font_offset = stbtt_GetFontOffsetForIndex((unsigned char*)data.TTFData, data.FontNo); IM_ASSERT(font_offset >= 0); if (!stbtt_InitFont(&data.FontInfo, (unsigned char*)data.TTFData, font_offset)) @@ -8645,6 +8645,7 @@ bool ImFontAtlas::Build() int font_ascent, font_descent, font_line_gap; stbtt_GetFontVMetrics(&data.FontInfo, &font_ascent, &font_descent, &font_line_gap); data.OutFont->BaseLine = (font_ascent * font_scale); + data.OutFont->Glyphs.resize(0); const float uv_scale_x = 1.0f / TexWidth; const float uv_scale_y = 1.0f / TexHeight; From 5df542c3c09f09676c6f54e539736351219b8bf4 Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 12 May 2015 15:16:12 +0100 Subject: [PATCH 06/11] ImFontAtlas: doesn't clear input data, left to the application. (#224) --- examples/directx11_example/imgui_impl_dx11.cpp | 4 ++++ examples/directx9_example/imgui_impl_dx9.cpp | 4 ++++ examples/opengl3_example/imgui_impl_glfw_gl3.cpp | 4 ++++ examples/opengl_example/imgui_impl_glfw.cpp | 4 ++++ imgui.cpp | 1 - 5 files changed, 16 insertions(+), 1 deletion(-) diff --git a/examples/directx11_example/imgui_impl_dx11.cpp b/examples/directx11_example/imgui_impl_dx11.cpp index ee111484..4af5551d 100644 --- a/examples/directx11_example/imgui_impl_dx11.cpp +++ b/examples/directx11_example/imgui_impl_dx11.cpp @@ -230,6 +230,10 @@ static void ImGui_ImplDX11_CreateFontsTexture() samplerDesc.MaxLOD = 0.f; g_pd3dDevice->CreateSamplerState(&samplerDesc, &g_pFontSampler); } + + // Cleanup (don't clear the input data if you want to append new fonts later) + io.Fonts->ClearInputData(); + io.Fonts->ClearTexData(); } bool ImGui_ImplDX11_CreateDeviceObjects() diff --git a/examples/directx9_example/imgui_impl_dx9.cpp b/examples/directx9_example/imgui_impl_dx9.cpp index 3c14dc25..01628b9c 100644 --- a/examples/directx9_example/imgui_impl_dx9.cpp +++ b/examples/directx9_example/imgui_impl_dx9.cpp @@ -224,6 +224,10 @@ static void ImGui_ImplDX9_CreateFontsTexture() // Store our identifier io.Fonts->TexID = (void *)pTexture; + + // Cleanup (don't clear the input data if you want to append new fonts later) + io.Fonts->ClearInputData(); + io.Fonts->ClearTexData(); } bool ImGui_ImplDX9_CreateDeviceObjects() diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp index 5796c04e..cf7c5c99 100644 --- a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp +++ b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp @@ -174,6 +174,10 @@ void ImGui_ImplGlfwGL3_CreateFontsTexture() // Store our identifier io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Cleanup (don't clear the input data if you want to append new fonts later) + io.Fonts->ClearInputData(); + io.Fonts->ClearTexData(); } bool ImGui_ImplGlfwGL3_CreateDeviceObjects() diff --git a/examples/opengl_example/imgui_impl_glfw.cpp b/examples/opengl_example/imgui_impl_glfw.cpp index decf2529..c5f9b22a 100644 --- a/examples/opengl_example/imgui_impl_glfw.cpp +++ b/examples/opengl_example/imgui_impl_glfw.cpp @@ -156,6 +156,10 @@ bool ImGui_ImplGlfw_CreateDeviceObjects() // Store our identifier io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + // Cleanup (don't clear the input data if you want to append new fonts later) + io.Fonts->ClearInputData(); + io.Fonts->ClearTexData(); + return true; } diff --git a/imgui.cpp b/imgui.cpp index e906baf4..a5a70dae 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -8683,7 +8683,6 @@ bool ImFontAtlas::Build() ImGui::MemFree(buf_ranges); buf_packedchars = NULL; buf_ranges = NULL; - ClearInputData(); // Render into our custom data block RenderCustomTexData(1, &extra_rects); From 1e4c22c206e38d542c2b0eed8f910d8d0f834034 Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 12 May 2015 16:08:34 +0100 Subject: [PATCH 07/11] Added io.MetricsActiveWindows counter (#213) --- imgui.cpp | 2 ++ imgui.h | 1 + 2 files changed, 3 insertions(+) diff --git a/imgui.cpp b/imgui.cpp index a5a70dae..43da5574 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2255,6 +2255,7 @@ void ImGui::Render() // Gather windows to render g.IO.MetricsRenderVertices = 0; + g.IO.MetricsActiveWindows = 0; for (size_t i = 0; i < IM_ARRAYSIZE(g.RenderDrawLists); i++) g.RenderDrawLists[i].resize(0); for (size_t i = 0; i != g.Windows.size(); i++) @@ -2263,6 +2264,7 @@ void ImGui::Render() if (window->Active && window->HiddenFrames <= 0 && (window->Flags & (ImGuiWindowFlags_ChildWindow)) == 0) { // FIXME: Generalize this with a proper layering system so we can stack. + g.IO.MetricsActiveWindows++; if (window->Flags & ImGuiWindowFlags_Popup) AddWindowToRenderList(g.RenderDrawLists[1], window); else if (window->Flags & ImGuiWindowFlags_Tooltip) diff --git a/imgui.h b/imgui.h index 378e9b30..c56e1dee 100644 --- a/imgui.h +++ b/imgui.h @@ -700,6 +700,7 @@ struct ImGuiIO bool WantCaptureKeyboard; // Widget is active (= ImGui will use your keyboard input) float Framerate; // Framerate estimation, in frame per second. Rolling average estimation based on IO.DeltaTime over 120 frames int MetricsRenderVertices; // Vertices processed during last call to Render() + int MetricsActiveWindows; // Number of visible windows (exclude child windows) //------------------------------------------------------------------ // [Internal] ImGui will maintain those fields for you From e57ee2852ad35ae73dd33f928e928b9c2de5ee32 Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 14 May 2015 11:32:12 +0100 Subject: [PATCH 08/11] Comments --- imgui.cpp | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 43da5574..b30ff4d0 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -12,8 +12,8 @@ - PROGRAMMER GUIDE (read me!) - API BREAKING CHANGES (read me when you update!) - FREQUENTLY ASKED QUESTIONS (FAQ), TIPS - - Can I have multiple widgets with the same label? (Yes) - How do I update to a newer version of ImGui? + - Can I have multiple widgets with the same label? (Yes) - Why is my text output blurry? - How can I load a different font than the default? - How can I load multiple fonts? @@ -186,6 +186,16 @@ FREQUENTLY ASKED QUESTIONS (FAQ), TIPS ====================================== + Q: How do I update to a newer version of ImGui? + A: Overwrite the following files: + imgui.cpp + imgui.h + stb_rect_pack.h + stb_textedit.h + stb_truetype.h + Check the "API BREAKING CHANGES" sections for a list of occasional API breaking changes. If you have a problem with a function, search for its name + in the code, there will likely be a comment about it. Please report any issue to the GitHub page! + Q: Can I have multiple widgets with the same label? A: Yes. A primer on the use of labels/IDs in ImGui.. @@ -270,15 +280,6 @@ e.g. when displaying a single object that may change over time (1-1 relationship), using a static string as ID will preserve your node open/closed state when the targeted object change. e.g. when displaying a list of objects, using indices or pointers as ID will preserve the node open/closed state differently. experiment and see what makes more sense! - Q: How do I update to a newer version of ImGui? - A: Overwrite the following files: - imgui.cpp - imgui.h - stb_rect_pack.h - stb_textedit.h - stb_truetype.h - Check the "API BREAKING CHANGES" sections for a list of occasional API breaking changes. - Q: Why is my text output blurry? A: In your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) @@ -329,6 +330,7 @@ - main: considering adding EndFrame()/Init(). some constructs are awkward in the implementation because of the lack of them. - main: IsItemHovered() make it more consistent for various type of widgets, widgets with multiple components, etc. also effectively IsHovered() region sometimes differs from hot region, e.g tree nodes - main: IsItemHovered() info stored in a stack? so that 'if TreeNode() { Text; TreePop; } if IsHovered' return the hover state of the TreeNode? + - input text: add ImGuiInputTextFlags_EnterToApply? (off github issue #218) !- input number: large int not reliably supported because of int<>float conversions. - input number: optional range min/max for Input*() functions - input number: holding [-]/[+] buttons could increase the step speed non-linearly (or user-controlled) From 0e8c2f9d41db888c34e4eab41fab509baf65fa41 Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 18 May 2015 14:10:59 +0100 Subject: [PATCH 09/11] Comments --- imgui.h | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/imgui.h b/imgui.h index c56e1dee..19a233fb 100644 --- a/imgui.h +++ b/imgui.h @@ -36,7 +36,7 @@ struct ImGuiStorage; struct ImGuiStyle; typedef unsigned int ImU32; -typedef unsigned short ImWchar; // character for display +typedef unsigned short ImWchar; // character for keyboard input/display typedef void* ImTextureID; // user data to refer to a texture (e.g. store your texture handle/id) typedef ImU32 ImGuiID; // unique ID used by widgets (typically hashed from a stack of string) typedef int ImGuiCol; // enum ImGuiCol_ @@ -80,9 +80,9 @@ namespace ImGui IMGUI_API void MemFree(void* ptr); } -// std::vector<> like class to avoid dragging dependencies (also: windows implementation of STL with debug enabled is absurdly slow, so let's bypass it so our code runs fast in debug). +// Lightweight std::vector<> like class to avoid dragging dependencies (also: windows implementation of STL with debug enabled is absurdly slow, so let's bypass it so our code runs fast in debug). // Use '#define ImVector std::vector' if you want to use the STL type or your own type. -// Our implementation does NOT call c++ constructors! because the data types we use don't need them (but that could be added as well). Only provide the minimum functionalities we need. +// Our implementation does NOT call c++ constructors because we don't use them in ImGui. Don't use this class as a straight std::vector replacement in your code! #ifndef ImVector template class ImVector @@ -144,8 +144,11 @@ public: // - struct ImGuiTextFilter // Parse and apply text filters. In format "aaaaa[,bbbb][,ccccc]" // - struct ImGuiTextBuffer // Text buffer for logging/accumulating text // - struct ImGuiStorage // Custom key value storage (if you need to alter open/close states manually) +// - struct ImGuiTextEditCallbackData // Shared state of ImGui::InputText() when using custom callbacks +// - struct ImColor // Helper functions to created packed 32-bit RGBA color values // - struct ImDrawList // Draw command list -// - struct ImFont // TTF font loader, bake glyphs into bitmap +// - struct ImFontAtlas // Bake multiple fonts into a single texture, TTF font loader, bake glyphs into bitmap +// - struct ImFont // Single font // ImGui end-user API // In a namespace so that user can add extra functions in a separate file (e.g. Value() helpers for your vector or common types) From 060f8798167b7e9cfd17f911d4614fccc9e0aa01 Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 18 May 2015 16:39:37 +0100 Subject: [PATCH 10/11] Tweak internal ButtonBehavior() to ease passing extra options --- imgui.cpp | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index b30ff4d0..c3f9c0ea 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -495,8 +495,9 @@ struct ImGuiTextEditState; struct ImGuiIniData; struct ImGuiState; struct ImGuiWindow; +typedef int ImGuiButtonFlags; // enum ImGuiButtonFlags_ -static bool ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool* out_held, bool allow_key_modifiers, bool repeat = false, bool pressed_on_click = false); +static bool ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool* out_held, bool allow_key_modifiers, ImGuiButtonFlags flags = 0); static void LogText(const ImVec2& ref_pos, const char* text, const char* text_end = NULL); static void RenderText(ImVec2 pos, const char* text, const char* text_end = NULL, bool hide_text_after_hash = true); @@ -932,6 +933,12 @@ static bool ImLoadFileToMemory(const char* filename, const char* file_open_mode, //----------------------------------------------------------------------------- +enum ImGuiButtonFlags_ +{ + ImGuiButtonFlags_Repeat = (1 << 0), + ImGuiButtonFlags_PressedOnClick = (1 << 1) +}; + struct ImGuiColMod // Color modifier, backup of modified data so we can restore it { ImGuiCol Col; @@ -4546,13 +4553,13 @@ static bool IsHovered(const ImRect& bb, ImGuiID id) return false; } -static bool ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool* out_held, bool allow_key_modifiers, bool repeat, bool pressed_on_click) +static bool ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool* out_held, bool allow_key_modifiers, ImGuiButtonFlags flags) { ImGuiState& g = *GImGui; ImGuiWindow* window = GetCurrentWindow(); - const bool hovered = IsHovered(bb, id); bool pressed = false; + const bool hovered = IsHovered(bb, id); if (hovered) { g.HoveredId = id; @@ -4560,7 +4567,7 @@ static bool ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool { if (g.IO.MouseClicked[0]) { - if (pressed_on_click) + if (flags & ImGuiButtonFlags_PressedOnClick) { pressed = true; SetActiveId(0); @@ -4571,7 +4578,7 @@ static bool ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool } FocusWindow(window); } - else if (repeat && g.ActiveId && ImGui::IsMouseClicked(0, true)) + else if ((flags & ImGuiButtonFlags_Repeat) && g.ActiveId == id && ImGui::IsMouseClicked(0, true)) { pressed = true; } @@ -4617,7 +4624,7 @@ bool ImGui::Button(const char* label, const ImVec2& size_arg, bool repeat_when_h return false; bool hovered, held; - bool pressed = ButtonBehavior(bb, id, &hovered, &held, true, repeat_when_held); + bool pressed = ButtonBehavior(bb, id, &hovered, &held, true, repeat_when_held ? ImGuiButtonFlags_Repeat : 0); // Render const ImU32 col = window->Color((hovered && held) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button); @@ -7093,7 +7100,7 @@ bool ImGui::Selectable(const char* label, bool selected, const ImVec2& size_arg) return false; bool hovered, held; - bool pressed = ButtonBehavior(bb_with_spacing, id, &hovered, &held, true, false, false); + bool pressed = ButtonBehavior(bb_with_spacing, id, &hovered, &held, true); // Render if (hovered || selected) From 097fe51f972858db8377ebd30f2e3855b05384cd Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 18 May 2015 16:42:55 +0100 Subject: [PATCH 11/11] Hovering require to hover same child window. Reverted 860cf578f502cc566572b2a45207a0e5626a58bb (December 3), replaced by a flag resize grip. Might break something if you have childs overlapping non-childs. --- imgui.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index c3f9c0ea..351b535c 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -936,7 +936,8 @@ static bool ImLoadFileToMemory(const char* filename, const char* file_open_mode, enum ImGuiButtonFlags_ { ImGuiButtonFlags_Repeat = (1 << 0), - ImGuiButtonFlags_PressedOnClick = (1 << 1) + ImGuiButtonFlags_PressedOnClick = (1 << 1), + ImGuiButtonFlags_FlattenChilds = (1 << 2) }; struct ImGuiColMod // Color modifier, backup of modified data so we can restore it @@ -3438,7 +3439,7 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_ const ImRect resize_rect(window->Rect().GetBR()-ImVec2(14,14), window->Rect().GetBR()); const ImGuiID resize_id = window->GetID("#RESIZE"); bool hovered, held; - ButtonBehavior(resize_rect, resize_id, &hovered, &held, true); + ButtonBehavior(resize_rect, resize_id, &hovered, &held, true, ImGuiButtonFlags_FlattenChilds); resize_col = window->Color(held ? ImGuiCol_ResizeGripActive : hovered ? ImGuiCol_ResizeGripHovered : ImGuiCol_ResizeGrip); if (hovered || held) @@ -4539,13 +4540,13 @@ static inline bool IsWindowContentHoverable(ImGuiWindow* window) return true; } -static bool IsHovered(const ImRect& bb, ImGuiID id) +static bool IsHovered(const ImRect& bb, ImGuiID id, bool flatten_childs = false) { ImGuiState& g = *GImGui; if (g.HoveredId == 0) { ImGuiWindow* window = GetCurrentWindow(); - if (g.HoveredRootWindow == window->RootWindow) + if (g.HoveredWindow == window || (flatten_childs && g.HoveredRootWindow == window->RootWindow)) if ((g.ActiveId == 0 || g.ActiveId == id || g.ActiveIdIsFocusedOnly) && IsMouseHoveringRect(bb)) if (IsWindowContentHoverable(g.HoveredRootWindow)) return true; @@ -4559,7 +4560,7 @@ static bool ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool ImGuiWindow* window = GetCurrentWindow(); bool pressed = false; - const bool hovered = IsHovered(bb, id); + const bool hovered = IsHovered(bb, id, (flags & ImGuiButtonFlags_FlattenChilds) != 0); if (hovered) { g.HoveredId = id;