From f8fede1d8bc2eb2eb5776d3d8426a436622dd96c Mon Sep 17 00:00:00 2001 From: ocornut Date: Sun, 21 Feb 2016 23:23:30 +0100 Subject: [PATCH 001/921] Added ColorPicker3/ColorPicker4, refactoring ColorEdit3/ColorEdit4 adding a bunch of flags and access to picker (wip #346) Still pretty much experimenting so may break API --- imgui.cpp | 375 +++++++++++++++++++++++++++++++++-------------- imgui.h | 27 ++-- imgui_demo.cpp | 13 +- imgui_internal.h | 3 +- 4 files changed, 291 insertions(+), 127 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 8617a6824..65046bd5e 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -149,6 +149,8 @@ Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. Also read releases logs https://github.com/ocornut/imgui/releases for more details. + - 2016/02/21 (1.48) - removed ColorEditMode() and ImGuiColorEditMode in favor of ImGuiColorEditFlags and parameters to ColorEdit*() functions + - replaced ColorEdit4() third parameter 'bool show_alpha=true' to 'ImGuiColorEditFlags flags=0x01' where ImGuiColorEditFlags_Alpha=0x01 for dodgy compatibility - 2016/01/23 (1.48) - fixed not honoring exact width passed to PushItemWidth(), previously it would add extra FramePadding.x*2 over that width. if you had manual pixel-perfect alignment in place it might affect you. - 2015/12/27 (1.48) - fixed ImDrawList::AddRect() which used to render a rectangle 1 px too large on each axis. - 2015/12/04 (1.47) - renamed Color() helpers to ValueColor() - dangerously named, rarely used and probably to be made obsolete. @@ -4025,7 +4027,6 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_ window->DC.TextWrapPosStack.resize(0); window->DC.AllowKeyboardFocusStack.resize(0); window->DC.ButtonRepeatStack.resize(0); - window->DC.ColorEditMode = ImGuiColorEditMode_UserSelect; window->DC.ColumnsCurrent = 0; window->DC.ColumnsCount = 1; window->DC.ColumnsStartPosY = window->DC.CursorPos.y; @@ -8501,23 +8502,18 @@ bool ImGui::ColorButton(const ImVec4& col, bool small_height, bool outline_borde return pressed; } -bool ImGui::ColorEdit3(const char* label, float col[3]) +bool ImGui::ColorEdit3(const char* label, float col[3], ImGuiColorEditFlags flags) { - float col4[4]; - col4[0] = col[0]; - col4[1] = col[1]; - col4[2] = col[2]; - col4[3] = 1.0f; - const bool value_changed = ImGui::ColorEdit4(label, col4, false); - col[0] = col4[0]; - col[1] = col4[1]; - col[2] = col4[2]; - return value_changed; + float col4[4] = { col[0], col[1], col[2], 1.0f }; + if (!ColorEdit4(label, col4, flags & ~ImGuiColorEditFlags_Alpha)) + return false; + col[0] = col4[0]; col[1] = col4[1]; col[2] = col4[2]; + return true; } -// Edit colors components (each component in 0.0f..1.0f range -// Use CTRL-Click to input value and TAB to go to next item. -bool ImGui::ColorEdit4(const char* label, float col[4], bool alpha) +// Edit colors components (each component in 0.0f..1.0f range) +// Click on colored square to open a color picker (unless ImGuiColorEditFlags_NoPicker is set). Use CTRL-Click to input value and TAB to go to next item. +bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flags) { ImGuiWindow* window = GetCurrentWindow(); if (window->SkipItems) @@ -8527,123 +8523,151 @@ bool ImGui::ColorEdit4(const char* label, float col[4], bool alpha) const ImGuiStyle& style = g.Style; const ImGuiID id = window->GetID(label); const float w_full = CalcItemWidth(); - const float square_sz = (g.FontSize + style.FramePadding.y * 2.0f); + const float square_sz_with_spacing = (flags & ImGuiColorEditFlags_NoColorSquare) ? 0.0f : (g.FontSize + style.FramePadding.y * 2.0f + style.ItemInnerSpacing.x); - ImGuiColorEditMode edit_mode = window->DC.ColorEditMode; - if (edit_mode == ImGuiColorEditMode_UserSelect || edit_mode == ImGuiColorEditMode_UserSelectShowButton) - edit_mode = g.ColorEditModeStorage.GetInt(id, 0) % 3; + // If no mode is specified default to RGB + if (!(flags & ImGuiColorEditFlags_ModeMask_)) + flags |= ImGuiColorEditFlags_RGB; + + // Read back edit mode from persistent storage + if (!(flags & ImGuiColorEditFlags_NoOptions)) + flags = (flags & (~ImGuiColorEditFlags_ModeMask_)) | (g.ColorEditModeStorage.GetInt(id, (flags & ImGuiColorEditFlags_ModeMask_)) & ImGuiColorEditFlags_ModeMask_); + + IM_ASSERT(ImIsPowerOfTwo((int)(flags & ImGuiColorEditFlags_ModeMask_))); // Check that exactly one of RGB/HSV/HEX is set float f[4] = { col[0], col[1], col[2], col[3] }; - if (edit_mode == ImGuiColorEditMode_HSV) + if (flags & ImGuiColorEditFlags_HSV) ImGui::ColorConvertRGBtoHSV(f[0], f[1], f[2], f[0], f[1], f[2]); int i[4] = { IM_F32_TO_INT8(f[0]), IM_F32_TO_INT8(f[1]), IM_F32_TO_INT8(f[2]), IM_F32_TO_INT8(f[3]) }; - int components = alpha ? 4 : 3; + bool alpha = (flags & ImGuiColorEditFlags_Alpha) != 0; bool value_changed = false; + int components = alpha ? 4 : 3; ImGui::BeginGroup(); ImGui::PushID(label); - const bool hsv = (edit_mode == 1); - switch (edit_mode) + if (flags & (ImGuiColorEditFlags_RGB | ImGuiColorEditFlags_HSV)) { - case ImGuiColorEditMode_RGB: - case ImGuiColorEditMode_HSV: - { - // RGB/HSV 0..255 Sliders - const float w_items_all = w_full - (square_sz + style.ItemInnerSpacing.x); - const float w_item_one = ImMax(1.0f, (float)(int)((w_items_all - (style.ItemInnerSpacing.x) * (components-1)) / (float)components)); - const float w_item_last = ImMax(1.0f, (float)(int)(w_items_all - (w_item_one + style.ItemInnerSpacing.x) * (components-1))); + // RGB/HSV 0..255 Sliders + const float w_items_all = w_full - square_sz_with_spacing; + const float w_item_one = ImMax(1.0f, (float)(int)((w_items_all - (style.ItemInnerSpacing.x) * (components-1)) / (float)components)); + const float w_item_last = ImMax(1.0f, (float)(int)(w_items_all - (w_item_one + style.ItemInnerSpacing.x) * (components-1))); - const bool hide_prefix = (w_item_one <= CalcTextSize("M:999").x); - const char* ids[4] = { "##X", "##Y", "##Z", "##W" }; - const char* fmt_table[3][4] = - { - { "%3.0f", "%3.0f", "%3.0f", "%3.0f" }, - { "R:%3.0f", "G:%3.0f", "B:%3.0f", "A:%3.0f" }, - { "H:%3.0f", "S:%3.0f", "V:%3.0f", "A:%3.0f" } - }; - const char** fmt = hide_prefix ? fmt_table[0] : hsv ? fmt_table[2] : fmt_table[1]; - - ImGui::PushItemWidth(w_item_one); - for (int n = 0; n < components; n++) - { - if (n > 0) - ImGui::SameLine(0, style.ItemInnerSpacing.x); - if (n + 1 == components) - ImGui::PushItemWidth(w_item_last); - value_changed |= ImGui::DragInt(ids[n], &i[n], 1.0f, 0, 255, fmt[n]); - } - ImGui::PopItemWidth(); - ImGui::PopItemWidth(); - } - break; - case ImGuiColorEditMode_HEX: + const bool hide_prefix = (w_item_one <= CalcTextSize("M:999").x); + const char* ids[4] = { "##X", "##Y", "##Z", "##W" }; + const char* fmt_table[3][4] = { - // RGB Hexadecimal Input - const float w_slider_all = w_full - square_sz; - char buf[64]; - if (alpha) - ImFormatString(buf, IM_ARRAYSIZE(buf), "#%02X%02X%02X%02X", i[0], i[1], i[2], i[3]); - else - ImFormatString(buf, IM_ARRAYSIZE(buf), "#%02X%02X%02X", i[0], i[1], i[2]); - ImGui::PushItemWidth(w_slider_all - style.ItemInnerSpacing.x); - if (ImGui::InputText("##Text", buf, IM_ARRAYSIZE(buf), ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsUppercase)) - { - value_changed |= true; - char* p = buf; - while (*p == '#' || ImCharIsSpace(*p)) - p++; - i[0] = i[1] = i[2] = i[3] = 0; - if (alpha) - sscanf(p, "%02X%02X%02X%02X", (unsigned int*)&i[0], (unsigned int*)&i[1], (unsigned int*)&i[2], (unsigned int*)&i[3]); // Treat at unsigned (%X is unsigned) - else - sscanf(p, "%02X%02X%02X", (unsigned int*)&i[0], (unsigned int*)&i[1], (unsigned int*)&i[2]); - } - ImGui::PopItemWidth(); + { "%3.0f", "%3.0f", "%3.0f", "%3.0f" }, // Short display + { "R:%3.0f", "G:%3.0f", "B:%3.0f", "A:%3.0f" }, // Long display for RGBA + { "H:%3.0f", "S:%3.0f", "V:%3.0f", "A:%3.0f" } // Long display for HSVV + }; + const char** fmt = hide_prefix ? fmt_table[0] : (flags & ImGuiColorEditFlags_HSV) ? fmt_table[2] : fmt_table[1]; + + ImGui::PushItemWidth(w_item_one); + for (int n = 0; n < components; n++) + { + if (n > 0) + ImGui::SameLine(0, style.ItemInnerSpacing.x); + if (n + 1 == components) + ImGui::PushItemWidth(w_item_last); + value_changed |= ImGui::DragInt(ids[n], &i[n], 1.0f, 0, 255, fmt[n]); } - break; + ImGui::PopItemWidth(); + ImGui::PopItemWidth(); } - - ImGui::SameLine(0, style.ItemInnerSpacing.x); - - const ImVec4 col_display(col[0], col[1], col[2], 1.0f); - if (ImGui::ColorButton(col_display)) - g.ColorEditModeStorage.SetInt(id, (edit_mode + 1) % 3); // Don't set local copy of 'edit_mode' right away! - - // Recreate our own tooltip over's ColorButton() one because we want to display correct alpha here - if (ImGui::IsItemHovered()) - ImGui::SetTooltip("Color:\n(%.2f,%.2f,%.2f,%.2f)\n#%02X%02X%02X%02X", col[0], col[1], col[2], col[3], IM_F32_TO_INT8(col[0]), IM_F32_TO_INT8(col[1]), IM_F32_TO_INT8(col[2]), IM_F32_TO_INT8(col[3])); - - if (window->DC.ColorEditMode == ImGuiColorEditMode_UserSelectShowButton) + else if (flags & ImGuiColorEditFlags_HEX) { - ImGui::SameLine(0, style.ItemInnerSpacing.x); - const char* button_titles[3] = { "RGB", "HSV", "HEX" }; - if (ButtonEx(button_titles[edit_mode], ImVec2(0,0), ImGuiButtonFlags_DontClosePopups)) - g.ColorEditModeStorage.SetInt(id, (edit_mode + 1) % 3); // Don't set local copy of 'edit_mode' right away! + // RGB Hexadecimal Input + const float w_slider_all = w_full - square_sz_with_spacing; + char buf[64]; + if (alpha) + ImFormatString(buf, IM_ARRAYSIZE(buf), "#%02X%02X%02X%02X", i[0], i[1], i[2], i[3]); + else + ImFormatString(buf, IM_ARRAYSIZE(buf), "#%02X%02X%02X", i[0], i[1], i[2]); + ImGui::PushItemWidth(w_slider_all); + if (ImGui::InputText("##Text", buf, IM_ARRAYSIZE(buf), ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsUppercase)) + { + value_changed |= true; + char* p = buf; + while (*p == '#' || ImCharIsSpace(*p)) + p++; + i[0] = i[1] = i[2] = i[3] = 0; + if (alpha) + sscanf(p, "%02X%02X%02X%02X", (unsigned int*)&i[0], (unsigned int*)&i[1], (unsigned int*)&i[2], (unsigned int*)&i[3]); // Treat at unsigned (%X is unsigned) + else + sscanf(p, "%02X%02X%02X", (unsigned int*)&i[0], (unsigned int*)&i[1], (unsigned int*)&i[2]); + } + ImGui::PopItemWidth(); } const char* label_display_end = FindTextDisplayEnd(label); + + bool picker_active = false; + if (!(flags & ImGuiColorEditFlags_NoColorSquare)) + { + ImGui::SameLine(0, style.ItemInnerSpacing.x); + + const ImVec4 col_display(col[0], col[1], col[2], 1.0f); + if (ImGui::ColorButton(col_display)) + { + if (!(flags & ImGuiColorEditFlags_NoPicker)) + { + ImGui::OpenPopup("picker"); + ImGui::SetNextWindowPos(window->DC.LastItemRect.GetBL() + ImVec2(-1,style.ItemSpacing.y)); + } + } + else if (!(flags & ImGuiColorEditFlags_NoOptions) && ImGui::IsItemHovered() && ImGui::IsMouseClicked(1)) + { + ImGui::OpenPopup("context"); + } + + if (ImGui::BeginPopup("picker")) + { + picker_active = true; + if (label != label_display_end) + ImGui::TextUnformatted(label, label_display_end); + ImGui::PushItemWidth(256.0f + (alpha ? 2 : 1) * (style.ItemInnerSpacing.x)); + value_changed |= ImGui::ColorPicker4("##picker", col, (flags & ImGuiColorEditFlags_Alpha) | (ImGuiColorEditFlags_RGB | ImGuiColorEditFlags_HSV | ImGuiColorEditFlags_HEX)); + ImGui::PopItemWidth(); + ImGui::EndPopup(); + } + if (!(flags & ImGuiColorEditFlags_NoOptions) && ImGui::BeginPopup("context")) + { + // FIXME-LOCALIZATION + if (ImGui::MenuItem("Edit as RGB", NULL, (flags & ImGuiColorEditFlags_RGB)?1:0)) g.ColorEditModeStorage.SetInt(id, (int)(ImGuiColorEditFlags_RGB)); + if (ImGui::MenuItem("Edit as HSV", NULL, (flags & ImGuiColorEditFlags_HSV)?1:0)) g.ColorEditModeStorage.SetInt(id, (int)(ImGuiColorEditFlags_HSV)); + if (ImGui::MenuItem("Edit as Hexadecimal", NULL, (flags & ImGuiColorEditFlags_HEX)?1:0)) g.ColorEditModeStorage.SetInt(id, (int)(ImGuiColorEditFlags_HEX)); + ImGui::EndPopup(); + } + + // Recreate our own tooltip over's ColorButton() one because we want to display correct alpha here + if (ImGui::IsItemHovered()) + ImGui::SetTooltip("Color:\n(%.2f,%.2f,%.2f,%.2f)\n#%02X%02X%02X%02X", col[0], col[1], col[2], col[3], IM_F32_TO_INT8(col[0]), IM_F32_TO_INT8(col[1]), IM_F32_TO_INT8(col[2]), IM_F32_TO_INT8(col[3])); + } + if (label != label_display_end) { - ImGui::SameLine(0, (window->DC.ColorEditMode == ImGuiColorEditMode_UserSelectShowButton) ? -1.0f : style.ItemInnerSpacing.x); + ImGui::SameLine(0, style.ItemInnerSpacing.x); ImGui::TextUnformatted(label, label_display_end); } // Convert back - for (int n = 0; n < 4; n++) - f[n] = i[n] / 255.0f; - if (edit_mode == 1) - ImGui::ColorConvertHSVtoRGB(f[0], f[1], f[2], f[0], f[1], f[2]); - - if (value_changed) + if (!picker_active) { - col[0] = f[0]; - col[1] = f[1]; - col[2] = f[2]; - if (alpha) - col[3] = f[3]; + for (int n = 0; n < 4; n++) + f[n] = i[n] / 255.0f; + if (flags & ImGuiColorEditFlags_HSV) + ImGui::ColorConvertHSVtoRGB(f[0], f[1], f[2], f[0], f[1], f[2]); + if (value_changed) + { + col[0] = f[0]; + col[1] = f[1]; + col[2] = f[2]; + if (alpha) + col[3] = f[3]; + } } ImGui::PopID(); @@ -8652,10 +8676,147 @@ bool ImGui::ColorEdit4(const char* label, float col[4], bool alpha) return value_changed; } -void ImGui::ColorEditMode(ImGuiColorEditMode mode) +bool ImGui::ColorPicker3(const char* label, float col[3], ImGuiColorEditFlags flags) { - ImGuiWindow* window = GetCurrentWindow(); - window->DC.ColorEditMode = mode; + float col4[4] = { col[0], col[1], col[2], 1.0f }; + if (!ColorPicker4(label, col4, flags & ~ImGuiColorEditFlags_Alpha)) + return false; + col[0] = col4[1]; col[1] = col4[1]; col[2] = col4[2]; + return true; +} + +// ColorPicker v2.50 WIP +// see https://github.com/ocornut/imgui/issues/346 +// TODO: Missing color square +// TODO: English strings in context menu (see FIXME-LOCALIZATION) +bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags flags) +{ + ImGuiIO& io = ImGui::GetIO(); + ImGuiStyle& style = ImGui::GetStyle(); + ImDrawList* draw_list = ImGui::GetWindowDrawList(); + + // Setup + bool alpha = (flags & ImGuiColorEditFlags_Alpha) != 0; + ImVec2 picker_pos = ImGui::GetCursorScreenPos(); + float bars_width = ImGui::GetWindowFontSize() * 1.0f; // Arbitrary smallish width of Hue/Alpha picking bars + float sv_picker_size = ImMax(bars_width * 2, ImGui::CalcItemWidth() - (alpha ? 2 : 1) * (bars_width + style.ItemInnerSpacing.x)); // Saturation/Value picking box + float bar0_pos_x = picker_pos.x + sv_picker_size + style.ItemInnerSpacing.x; + float bar1_pos_x = bar0_pos_x + bars_width + style.ItemInnerSpacing.x; + + float H,S,V; + ImGui::ColorConvertRGBtoHSV(col[0], col[1], col[2], H, S, V); + + // Color matrix logic + bool value_changed = false, hsv_changed = false; + ImGui::BeginGroup(); + ImGui::InvisibleButton("sv", ImVec2(sv_picker_size, sv_picker_size)); + if (ImGui::IsItemActive()) + { + S = ImSaturate((io.MousePos.x - picker_pos.x) / (sv_picker_size-1)); + V = 1.0f - ImSaturate((io.MousePos.y - picker_pos.y) / (sv_picker_size-1)); + value_changed = hsv_changed = true; + } + + // Hue bar logic + ImGui::SetCursorScreenPos(ImVec2(bar0_pos_x, picker_pos.y)); + ImGui::InvisibleButton("hue", ImVec2(bars_width, sv_picker_size)); + if (ImGui::IsItemActive()) + { + H = ImSaturate((io.MousePos.y - picker_pos.y) / (sv_picker_size-1)); + value_changed = hsv_changed = true; + } + + // Alpha bar logic + if (alpha) + { + ImGui::SetCursorScreenPos(ImVec2(bar1_pos_x, picker_pos.y)); + ImGui::InvisibleButton("alpha", ImVec2(bars_width, sv_picker_size)); + if (ImGui::IsItemActive()) + { + col[3] = 1.0f - ImSaturate((io.MousePos.y - picker_pos.y) / (sv_picker_size-1)); + value_changed = true; + } + } + + const char* label_display_end = FindTextDisplayEnd(label); + if (label != label_display_end) + { + ImGui::SameLine(0, style.ItemInnerSpacing.x); + ImGui::TextUnformatted(label, label_display_end); + } + + // Convert back color to RGB + if (hsv_changed) + ImGui::ColorConvertHSVtoRGB(H >= 1.0f ? H - 10 * 1e-6f : H, S > 0.0f ? S : 10*1e-6f, V > 0.0f ? V : 1e-6f, col[0], col[1], col[2]); + + // R,G,B and H,S,V slider color editor + if (!(flags & ImGuiColorEditFlags_NoSliders)) + { + if ((flags & ImGuiColorEditFlags_ModeMask_) == 0) + flags = ImGuiColorEditFlags_RGB | ImGuiColorEditFlags_HSV | ImGuiColorEditFlags_HEX; + ImGui::PushItemWidth((alpha ? bar1_pos_x : bar0_pos_x) + bars_width - picker_pos.x); + ImGuiColorEditFlags sub_flags = (alpha ? ImGuiColorEditFlags_Alpha : 0) | ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_NoOptions | ImGuiColorEditFlags_NoColorSquare; + if (flags & ImGuiColorEditFlags_RGB) + value_changed |= ImGui::ColorEdit4("##rgb", col, sub_flags | ImGuiColorEditFlags_RGB); + if (flags & ImGuiColorEditFlags_HSV) + value_changed |= ImGui::ColorEdit4("##hsv", col, sub_flags | ImGuiColorEditFlags_HSV); + if (flags & ImGuiColorEditFlags_HEX) + value_changed |= ImGui::ColorEdit4("##hex", col, sub_flags | ImGuiColorEditFlags_HEX); + ImGui::PopItemWidth(); + } + + // Try to cancel hue wrap (after ColorEdit), if any + if (value_changed) + { + float new_H, new_S, new_V; + ImGui::ColorConvertRGBtoHSV(col[0], col[1], col[2], new_H, new_S, new_V); + if (new_H <= 0 && H > 0) + { + if (new_V <= 0 && V != new_V) + ImGui::ColorConvertHSVtoRGB(H, S, new_V <= 0 ? V * 0.5f : new_V, col[0], col[1], col[2]); + else if (new_S <= 0) + ImGui::ColorConvertHSVtoRGB(H, new_S <= 0 ? S * 0.5f : new_S, new_V, col[0], col[1], col[2]); + } + } + + // Render hue bar + ImVec4 hue_color_f(1, 1, 1, 1); + ImGui::ColorConvertHSVtoRGB(H, 1, 1, hue_color_f.x, hue_color_f.y, hue_color_f.z); + ImU32 hue_colors[] = { IM_COL32(255,0,0,255), IM_COL32(255,255,0,255), IM_COL32(0,255,0,255), IM_COL32(0,255,255,255), IM_COL32(0,0,255,255), IM_COL32(255,0,255,255), IM_COL32(255,0,0,255) }; + for (int i = 0; i < 6; ++i) + { + draw_list->AddRectFilledMultiColor( + ImVec2(bar0_pos_x, picker_pos.y + i * (sv_picker_size / 6)), + ImVec2(bar0_pos_x + bars_width, picker_pos.y + (i + 1) * (sv_picker_size / 6)), + hue_colors[i], hue_colors[i], hue_colors[i + 1], hue_colors[i + 1]); + } + float bar0_line_y = (float)(int)(picker_pos.y + H * sv_picker_size + 0.5f); + draw_list->AddLine(ImVec2(bar0_pos_x - 1, bar0_line_y), ImVec2(bar0_pos_x + bars_width + 1, bar0_line_y), IM_COL32_WHITE); + + // Render alpha bar + if (alpha) + { + float alpha = ImSaturate(col[3]); + float bar1_line_y = (float)(int)(picker_pos.y + (1.0f-alpha) * sv_picker_size + 0.5f); + draw_list->AddRectFilledMultiColor(ImVec2(bar1_pos_x, picker_pos.y), ImVec2(bar1_pos_x + bars_width, picker_pos.y + sv_picker_size), IM_COL32_WHITE, IM_COL32_WHITE, IM_COL32_BLACK, IM_COL32_BLACK); + draw_list->AddLine(ImVec2(bar1_pos_x - 1, bar1_line_y), ImVec2(bar1_pos_x + bars_width + 1, bar1_line_y), IM_COL32_WHITE); + } + + // Render color matrix + ImU32 hue_color32 = ImGui::ColorConvertFloat4ToU32(hue_color_f); + draw_list->AddRectFilledMultiColor(picker_pos, picker_pos + ImVec2(sv_picker_size,sv_picker_size), IM_COL32_WHITE, hue_color32, hue_color32, IM_COL32_WHITE); + draw_list->AddRectFilledMultiColor(picker_pos, picker_pos + ImVec2(sv_picker_size,sv_picker_size), IM_COL32_BLACK_TRANS, IM_COL32_BLACK_TRANS, IM_COL32_BLACK, IM_COL32_BLACK); + + // Render cross-hair + const float CROSSHAIR_SIZE = 7.0f; + ImVec2 p((float)(int)(picker_pos.x + S * sv_picker_size + 0.5f), (float)(int)(picker_pos.y + (1 - V) * sv_picker_size + 0.5f)); + draw_list->AddLine(ImVec2(p.x - CROSSHAIR_SIZE, p.y), ImVec2(p.x - 2, p.y), IM_COL32_WHITE); + draw_list->AddLine(ImVec2(p.x + CROSSHAIR_SIZE, p.y), ImVec2(p.x + 2, p.y), IM_COL32_WHITE); + draw_list->AddLine(ImVec2(p.x, p.y + CROSSHAIR_SIZE), ImVec2(p.x, p.y + 2), IM_COL32_WHITE); + draw_list->AddLine(ImVec2(p.x, p.y - CROSSHAIR_SIZE), ImVec2(p.x, p.y - 2), IM_COL32_WHITE); + ImGui::EndGroup(); + + return value_changed; } // Horizontal separating line. diff --git a/imgui.h b/imgui.h index 5abc578be..fda65f4d8 100644 --- a/imgui.h +++ b/imgui.h @@ -64,7 +64,7 @@ typedef int ImGuiCol; // a color identifier for styling // e typedef int ImGuiStyleVar; // a variable identifier for styling // enum ImGuiStyleVar_ typedef int ImGuiKey; // a key identifier (ImGui-side enum) // enum ImGuiKey_ typedef int ImGuiAlign; // alignment // enum ImGuiAlign_ -typedef int ImGuiColorEditMode; // color edit mode for ColorEdit*() // enum ImGuiColorEditMode_ +typedef int ImGuiColorEditFlags; // color edit mode for ColorEdit*() // enum ImGuiColorEditFlags_ typedef int ImGuiMouseCursor; // a mouse cursor identifier // enum ImGuiMouseCursor_ typedef int ImGuiWindowFlags; // window flags for Begin*() // enum ImGuiWindowFlags_ typedef int ImGuiSetCond; // condition flags for Set*() // enum ImGuiSetCond_ @@ -256,9 +256,10 @@ namespace ImGui IMGUI_API bool Combo(const char* label, int* current_item, const char* items_separated_by_zeros, int height_in_items = -1); // separate items with \0, end item-list with \0\0 IMGUI_API bool Combo(const char* label, int* current_item, bool (*items_getter)(void* data, int idx, const char** out_text), void* data, int items_count, int height_in_items = -1); IMGUI_API bool ColorButton(const ImVec4& col, bool small_height = false, bool outline_border = true); - IMGUI_API bool ColorEdit3(const char* label, float col[3]); - IMGUI_API bool ColorEdit4(const char* label, float col[4], bool show_alpha = true); - IMGUI_API void ColorEditMode(ImGuiColorEditMode mode); // FIXME-OBSOLETE: This is inconsistent with most of the API and should be obsoleted. + IMGUI_API bool ColorEdit3(const char* label, float col[3], ImGuiColorEditFlags flags = 0); // click on colored squared to open a color picker, right-click for options + IMGUI_API bool ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flags = 0x01); // 0x01 = ImGuiColorEditFlags_Alpha = very dodgily backward compatible with 'bool show_alpha=true' + IMGUI_API bool ColorPicker3(const char* label, float col[3], ImGuiColorEditFlags flags = 0); + IMGUI_API bool ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags flags = 0x01); IMGUI_API void PlotLines(const char* label, const float* values, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0,0), int stride = sizeof(float)); IMGUI_API void PlotLines(const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0,0)); IMGUI_API void PlotHistogram(const char* label, const float* values, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0,0), int stride = sizeof(float)); @@ -609,14 +610,18 @@ enum ImGuiAlign_ ImGuiAlign_Default = ImGuiAlign_Left | ImGuiAlign_Top }; -// Enumeration for ColorEditMode() -enum ImGuiColorEditMode_ +// Enumeration for ColorEdit3() / ColorEdit4() / ColorPicker3() / ColorPicker4() +enum ImGuiColorEditFlags_ { - ImGuiColorEditMode_UserSelect = -2, - ImGuiColorEditMode_UserSelectShowButton = -1, - ImGuiColorEditMode_RGB = 0, - ImGuiColorEditMode_HSV = 1, - ImGuiColorEditMode_HEX = 2 + ImGuiColorEditFlags_Alpha = 1 << 0, // ColorEdit/ColorPicker: show/edit Alpha component. Must be 0x01 for compatibility with old API taking bool + ImGuiColorEditFlags_RGB = 1 << 1, // ColorEdit: Choose one among RGB/HSV/HEX. User can still use the options menu to change. ColorPicker: Choose any combination or RGB/HSX/HEX. + ImGuiColorEditFlags_HSV = 1 << 2, + ImGuiColorEditFlags_HEX = 1 << 3, + ImGuiColorEditFlags_NoPicker = 1 << 4, // ColorEdit: Disable picker when clicking on colored square + ImGuiColorEditFlags_NoOptions = 1 << 5, // ColorEdit: Disable toggling options menu when right-clicking colored square + ImGuiColorEditFlags_NoColorSquare = 1 << 6, // ColorEdit: Disable colored square + ImGuiColorEditFlags_NoSliders = 1 << 7, // ColorPicker: Disable RGB/HSV/HEX sliders + ImGuiColorEditFlags_ModeMask_ = ImGuiColorEditFlags_RGB|ImGuiColorEditFlags_HSV|ImGuiColorEditFlags_HEX }; // Enumeration for GetMouseCursor() diff --git a/imgui_demo.cpp b/imgui_demo.cpp index f0b460fcd..9a477a3f3 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -577,7 +577,7 @@ void ImGui::ShowTestWindow(bool* p_opened) static float col1[3] = { 1.0f,0.0f,0.2f }; static float col2[4] = { 0.4f,0.7f,0.0f,0.5f }; ImGui::ColorEdit3("color 1", col1); - ImGui::SameLine(); ShowHelpMarker("Click on the colored square to change edit mode.\nCTRL+click on individual component to input value.\n"); + ImGui::SameLine(); ShowHelpMarker("Click on the colored square to open a color picker.\nRight-click on the colored square to show options.\nCTRL+click on individual component to input value.\n"); ImGui::ColorEdit4("color 2", col2); @@ -1598,12 +1598,12 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) ImGui::SameLine(); ImGui::PushItemWidth(120); ImGui::Combo("##output_type", &output_dest, "To Clipboard\0To TTY"); ImGui::PopItemWidth(); ImGui::SameLine(); ImGui::Checkbox("Only Modified Fields", &output_only_modified); - static ImGuiColorEditMode edit_mode = ImGuiColorEditMode_RGB; - ImGui::RadioButton("RGB", &edit_mode, ImGuiColorEditMode_RGB); + static ImGuiColorEditFlags color_edit_flags = ImGuiColorEditFlags_RGB; + ImGui::RadioButton("RGB", &color_edit_flags, ImGuiColorEditFlags_RGB); ImGui::SameLine(); - ImGui::RadioButton("HSV", &edit_mode, ImGuiColorEditMode_HSV); + ImGui::RadioButton("HSV", &color_edit_flags, ImGuiColorEditFlags_HSV); ImGui::SameLine(); - ImGui::RadioButton("HEX", &edit_mode, ImGuiColorEditMode_HEX); + ImGui::RadioButton("HEX", &color_edit_flags, ImGuiColorEditFlags_HEX); //ImGui::Text("Tip: Click on colored square to change edit mode."); static ImGuiTextFilter filter; @@ -1611,14 +1611,13 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) ImGui::BeginChild("#colors", ImVec2(0, 300), true); ImGui::PushItemWidth(-160); - ImGui::ColorEditMode(edit_mode); for (int i = 0; i < ImGuiCol_COUNT; i++) { const char* name = ImGui::GetStyleColName(i); if (!filter.PassFilter(name)) continue; ImGui::PushID(i); - ImGui::ColorEdit4(name, (float*)&style.Colors[i], true); + ImGui::ColorEdit4(name, (float*)&style.Colors[i], color_edit_flags | ImGuiColorEditFlags_Alpha | ImGuiColorEditFlags_NoOptions); if (memcmp(&style.Colors[i], (ref ? &ref->Colors[i] : &def.Colors[i]), sizeof(ImVec4)) != 0) { ImGui::SameLine(); if (ImGui::Button("Revert")) style.Colors[i] = ref ? ref->Colors[i] : def.Colors[i]; diff --git a/imgui_internal.h b/imgui_internal.h index a4caacff7..7304af559 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -92,6 +92,7 @@ IMGUI_API ImU32 ImHash(const void* data, int data_size, ImU32 seed = 0); IMGUI_API void* ImLoadFileToMemory(const char* filename, const char* file_open_mode, int* out_file_size = NULL, int padding_bytes = 0); IMGUI_API bool ImIsPointInTriangle(const ImVec2& p, const ImVec2& a, const ImVec2& b, const ImVec2& c); static inline bool ImCharIsSpace(int c) { return c == ' ' || c == '\t' || c == 0x3000; } +static inline bool ImIsPowerOfTwo(int v) { return v != 0 && (v & (v - 1)) == 0; } static inline int ImUpperPowerOfTwo(int v) { v--; v |= v >> 1; v |= v >> 2; v |= v >> 4; v |= v >> 8; v |= v >> 16; v++; return v; } // Helpers: String @@ -540,7 +541,6 @@ struct IMGUI_API ImGuiDrawContext ImVector AllowKeyboardFocusStack; ImVector ButtonRepeatStack; ImVectorGroupStack; - ImGuiColorEditMode ColorEditMode; int StackSizesBackup[6]; // Store size of various stacks for asserting float IndentX; // Indentation / start position from left of window (increased by TreePush/TreePop, etc.) @@ -574,7 +574,6 @@ struct IMGUI_API ImGuiDrawContext ButtonRepeat = false; AllowKeyboardFocus = true; TextWrapPos = -1.0f; - ColorEditMode = ImGuiColorEditMode_RGB; memset(StackSizesBackup, 0, sizeof(StackSizesBackup)); IndentX = 0.0f; From a43a9e602a8f6059d6ef7977a7e0f4b8a84806e4 Mon Sep 17 00:00:00 2001 From: ocornut Date: Sun, 21 Feb 2016 23:55:01 +0100 Subject: [PATCH 002/921] ColorEdit4: support ImGuiColorEditFlags_NoSliders to display only a button (wip #346) --- imgui.cpp | 16 +++++++++++----- imgui.h | 2 +- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 65046bd5e..ce8f7a2d7 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -8525,15 +8525,20 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag const float w_full = CalcItemWidth(); const float square_sz_with_spacing = (flags & ImGuiColorEditFlags_NoColorSquare) ? 0.0f : (g.FontSize + style.FramePadding.y * 2.0f + style.ItemInnerSpacing.x); - // If no mode is specified default to RGB + // If no mode is specified, defaults to RGB if (!(flags & ImGuiColorEditFlags_ModeMask_)) flags |= ImGuiColorEditFlags_RGB; + // If we're not showing any slider there's no point in querying color mode, nor showing the options menu, nor doing any HSV conversions + if (flags & ImGuiColorEditFlags_NoSliders) + flags = (flags & (~ImGuiColorEditFlags_ModeMask_)) | ImGuiColorEditFlags_RGB | ImGuiColorEditFlags_NoOptions; + // Read back edit mode from persistent storage if (!(flags & ImGuiColorEditFlags_NoOptions)) flags = (flags & (~ImGuiColorEditFlags_ModeMask_)) | (g.ColorEditModeStorage.GetInt(id, (flags & ImGuiColorEditFlags_ModeMask_)) & ImGuiColorEditFlags_ModeMask_); - IM_ASSERT(ImIsPowerOfTwo((int)(flags & ImGuiColorEditFlags_ModeMask_))); // Check that exactly one of RGB/HSV/HEX is set + // Check that exactly one of RGB/HSV/HEX is set + IM_ASSERT(ImIsPowerOfTwo((int)(flags & ImGuiColorEditFlags_ModeMask_))); // float f[4] = { col[0], col[1], col[2], col[3] }; if (flags & ImGuiColorEditFlags_HSV) @@ -8548,7 +8553,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag ImGui::BeginGroup(); ImGui::PushID(label); - if (flags & (ImGuiColorEditFlags_RGB | ImGuiColorEditFlags_HSV)) + if ((flags & (ImGuiColorEditFlags_RGB | ImGuiColorEditFlags_HSV)) != 0 && (flags & ImGuiColorEditFlags_NoSliders) == 0) { // RGB/HSV 0..255 Sliders const float w_items_all = w_full - square_sz_with_spacing; @@ -8577,7 +8582,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag ImGui::PopItemWidth(); ImGui::PopItemWidth(); } - else if (flags & ImGuiColorEditFlags_HEX) + else if ((flags & ImGuiColorEditFlags_HEX) != 0 && (flags & ImGuiColorEditFlags_NoSliders) == 0) { // RGB Hexadecimal Input const float w_slider_all = w_full - square_sz_with_spacing; @@ -8607,7 +8612,8 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag bool picker_active = false; if (!(flags & ImGuiColorEditFlags_NoColorSquare)) { - ImGui::SameLine(0, style.ItemInnerSpacing.x); + if (!(flags & ImGuiColorEditFlags_NoSliders)) + ImGui::SameLine(0, style.ItemInnerSpacing.x); const ImVec4 col_display(col[0], col[1], col[2], 1.0f); if (ImGui::ColorButton(col_display)) diff --git a/imgui.h b/imgui.h index fda65f4d8..814fccf96 100644 --- a/imgui.h +++ b/imgui.h @@ -620,7 +620,7 @@ enum ImGuiColorEditFlags_ ImGuiColorEditFlags_NoPicker = 1 << 4, // ColorEdit: Disable picker when clicking on colored square ImGuiColorEditFlags_NoOptions = 1 << 5, // ColorEdit: Disable toggling options menu when right-clicking colored square ImGuiColorEditFlags_NoColorSquare = 1 << 6, // ColorEdit: Disable colored square - ImGuiColorEditFlags_NoSliders = 1 << 7, // ColorPicker: Disable RGB/HSV/HEX sliders + ImGuiColorEditFlags_NoSliders = 1 << 7, // ColorEdit: Disable sliders, show only a button. ColorPicker: Disable all RGB/HSV/HEX sliders. ImGuiColorEditFlags_ModeMask_ = ImGuiColorEditFlags_RGB|ImGuiColorEditFlags_HSV|ImGuiColorEditFlags_HEX }; From d39029f3a8c3c1b1853600b64b1c630f80774551 Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 23 Mar 2016 10:51:40 +0100 Subject: [PATCH 003/921] Branch fix --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 6837e549b..825e473a3 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -8635,7 +8635,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag ImGui::PopItemWidth(); } - const char* label_display_end = FindTextDisplayEnd(label); + const char* label_display_end = FindRenderedTextEnd(label); bool picker_active = false; if (!(flags & ImGuiColorEditFlags_NoColorSquare)) From 6a241d4895ade7c7bd0b1b3c6e55fe72fafe6564 Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 28 Mar 2016 23:38:04 +0200 Subject: [PATCH 004/921] ColorPicker3: Fixed --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 9ea985f56..8a4f77fb8 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -8741,7 +8741,7 @@ bool ImGui::ColorPicker3(const char* label, float col[3], ImGuiColorEditFlags fl float col4[4] = { col[0], col[1], col[2], 1.0f }; if (!ColorPicker4(label, col4, flags & ~ImGuiColorEditFlags_Alpha)) return false; - col[0] = col4[1]; col[1] = col4[1]; col[2] = col4[2]; + col[0] = col4[0]; col[1] = col4[1]; col[2] = col4[2]; return true; } From 9e817a7c38ba72def5fde244a9695eb4985e1bcd Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 28 Mar 2016 23:45:23 +0200 Subject: [PATCH 005/921] ColorPicker3/4: Fixed missing ID scoping (#346) --- imgui.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 8a4f77fb8..8ff7c63ff 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -8755,6 +8755,9 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl ImGuiStyle& style = ImGui::GetStyle(); ImDrawList* draw_list = ImGui::GetWindowDrawList(); + ImGui::PushID(label); + ImGui::BeginGroup(); + // Setup bool alpha = (flags & ImGuiColorEditFlags_Alpha) != 0; ImVec2 picker_pos = ImGui::GetCursorScreenPos(); @@ -8768,7 +8771,6 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl // Color matrix logic bool value_changed = false, hsv_changed = false; - ImGui::BeginGroup(); ImGui::InvisibleButton("sv", ImVec2(sv_picker_size, sv_picker_size)); if (ImGui::IsItemActive()) { @@ -8874,7 +8876,9 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl draw_list->AddLine(ImVec2(p.x + CROSSHAIR_SIZE, p.y), ImVec2(p.x + 2, p.y), IM_COL32_WHITE); draw_list->AddLine(ImVec2(p.x, p.y + CROSSHAIR_SIZE), ImVec2(p.x, p.y + 2), IM_COL32_WHITE); draw_list->AddLine(ImVec2(p.x, p.y - CROSSHAIR_SIZE), ImVec2(p.x, p.y - 2), IM_COL32_WHITE); + ImGui::EndGroup(); + ImGui::PopID(); return value_changed; } From 074a6853c7ac9b360efafb52349ff5e77ff09c41 Mon Sep 17 00:00:00 2001 From: ocornut Date: Sat, 9 Apr 2016 19:13:02 +0200 Subject: [PATCH 006/921] Moved comments --- imgui.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 316dea54f..f608f72b7 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -152,12 +152,12 @@ Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. Also read releases logs https://github.com/ocornut/imgui/releases for more details. + - 2016/04/09 (1.49) - removed ColorEditMode() and ImGuiColorEditMode in favor of ImGuiColorEditFlags and parameters to ColorEdit*() functions + replaced ColorEdit4() third parameter 'bool show_alpha=true' to 'ImGuiColorEditFlags flags=0x01' where ImGuiColorEditFlags_Alpha=0x01 for dodgy compatibility - 2016/04/03 (1.48) - removed style.WindowFillAlphaDefault setting which was redundant. Bake default BG alpha inside style.Colors[ImGuiCol_WindowBg] and all other Bg color values. (ref github issue #337). - 2016/04/03 (1.48) - renamed ImGuiCol_TooltipBg to ImGuiCol_PopupBg, used by popups/menus and tooltips. popups/menus were previously using ImGuiCol_WindowBg. (ref github issue #337) - 2016/03/21 (1.48) - renamed GetWindowFont() to GetFont(), GetWindowFontSize() to GetFontSize(). Kept inline redirection function (will obsolete). - 2016/03/02 (1.48) - InputText() completion/history/always callbacks: if you modify the text buffer manually (without using DeleteChars()/InsertChars() helper) you need to maintain the BufTextLen field. added an assert. - - 2016/02/21 (1.48) - removed ColorEditMode() and ImGuiColorEditMode in favor of ImGuiColorEditFlags and parameters to ColorEdit*() functions - - replaced ColorEdit4() third parameter 'bool show_alpha=true' to 'ImGuiColorEditFlags flags=0x01' where ImGuiColorEditFlags_Alpha=0x01 for dodgy compatibility - 2016/01/23 (1.48) - fixed not honoring exact width passed to PushItemWidth(), previously it would add extra FramePadding.x*2 over that width. if you had manual pixel-perfect alignment in place it might affect you. - 2015/12/27 (1.48) - fixed ImDrawList::AddRect() which used to render a rectangle 1 px too large on each axis. - 2015/12/04 (1.47) - renamed Color() helpers to ValueColor() - dangerously named, rarely used and probably to be made obsolete. From 5a47346f5a64b2a90440ba6ec055e7f345d55f6f Mon Sep 17 00:00:00 2001 From: Brian Swetland Date: Sat, 10 Sep 2016 18:21:49 -0700 Subject: [PATCH 007/921] ImFont: add RenderGlyph() to allow rendering of individual glyphs --- imgui.h | 1 + imgui_draw.cpp | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/imgui.h b/imgui.h index b85eaeffe..91d35ab9c 100644 --- a/imgui.h +++ b/imgui.h @@ -1376,6 +1376,7 @@ struct ImFont // 'wrap_width' enable automatic word-wrapping across multiple lines to fit into given width. 0.0f to disable. IMGUI_API ImVec2 CalcTextSizeA(float size, float max_width, float wrap_width, const char* text_begin, const char* text_end = NULL, const char** remaining = NULL) const; // utf8 IMGUI_API const char* CalcWordWrapPositionA(float scale, const char* text, const char* text_end, float wrap_width) const; + IMGUI_API void RenderGlyph(ImDrawList* draw_list, ImVec2 pos, ImU32 col, const ImFont::Glyph* glyph) const; IMGUI_API void RenderChar(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, unsigned short c) const; IMGUI_API void RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width = 0.0f, bool cpu_fine_clip = false) const; diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 455492983..b9e4b772f 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1979,6 +1979,15 @@ ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, cons return text_size; } +void ImFont::RenderGlyph(ImDrawList* draw_list, ImVec2 pos, ImU32 col, const ImFont::Glyph* glyph) const { + pos.x = (float)(int)pos.x + DisplayOffset.x; + pos.y = (float)(int)pos.y + DisplayOffset.y; + ImVec2 pos_tl(pos.x + glyph->X0, pos.y + glyph->Y0); + ImVec2 pos_br(pos.x + glyph->X1, pos.y + glyph->Y1); + draw_list->PrimReserve(6, 4); + draw_list->PrimRectUV(pos_tl, pos_br, ImVec2(glyph->U0, glyph->V0), ImVec2(glyph->U1, glyph->V1), col); +} + void ImFont::RenderChar(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, unsigned short c) const { if (c == ' ' || c == '\t' || c == '\n' || c == '\r') // Match behavior of RenderText(), those 4 codepoints are hard-coded. From 32dbe836d0cde14891d47ed054535283d0f567e2 Mon Sep 17 00:00:00 2001 From: Matt Keeter Date: Sat, 29 Oct 2016 15:33:09 -0400 Subject: [PATCH 008/921] Add user-facing IsPopupOpen function --- imgui.cpp | 28 ++++++++++++++++++---------- imgui.h | 1 + 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 07466840b..9c1ea04a1 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -687,7 +687,7 @@ static bool BeginPopupEx(const char* str_id, ImGuiWindowFlags extra_ static void CloseInactivePopups(); static void ClosePopupToLevel(int remaining); static void ClosePopup(ImGuiID id); -static bool IsPopupOpen(ImGuiID id); +static bool IsPopupIdOpen(ImGuiID id); static ImGuiWindow* GetFrontMostModalRootWindow(); static ImVec2 FindBestPopupWindowPos(const ImVec2& base_pos, const ImVec2& size, int* last_dir, const ImRect& rect_to_avoid); @@ -3367,7 +3367,7 @@ void ImGui::EndTooltip() ImGui::End(); } -static bool IsPopupOpen(ImGuiID id) +static bool IsPopupIdOpen(ImGuiID id) { ImGuiContext& g = *GImGui; return g.OpenPopupStack.Size > g.CurrentPopupStack.Size && g.OpenPopupStack[g.CurrentPopupStack.Size].PopupId == id; @@ -3451,7 +3451,7 @@ static void ClosePopupToLevel(int remaining) static void ClosePopup(ImGuiID id) { - if (!IsPopupOpen(id)) + if (!IsPopupIdOpen(id)) return; ImGuiContext& g = *GImGui; ClosePopupToLevel(g.OpenPopupStack.Size - 1); @@ -3481,7 +3481,7 @@ static bool BeginPopupEx(const char* str_id, ImGuiWindowFlags extra_flags) ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; const ImGuiID id = window->GetID(str_id); - if (!IsPopupOpen(id)) + if (!IsPopupIdOpen(id)) { ClearSetNextWindowData(); // We behave like Begin() and need to consume those values return false; @@ -3515,12 +3515,20 @@ bool ImGui::BeginPopup(const char* str_id) return BeginPopupEx(str_id, ImGuiWindowFlags_ShowBorders); } +bool ImGui::IsPopupOpen(const char* str_id) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + const ImGuiID id = window->GetID(str_id); + return IsPopupIdOpen(id); +} + bool ImGui::BeginPopupModal(const char* name, bool* p_open, ImGuiWindowFlags extra_flags) { ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; const ImGuiID id = window->GetID(name); - if (!IsPopupOpen(id)) + if (!IsPopupIdOpen(id)) { ClearSetNextWindowData(); // We behave like Begin() and need to consume those values return false; @@ -8415,7 +8423,7 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi const float arrow_size = (g.FontSize + style.FramePadding.x * 2.0f); const bool hovered = IsHovered(frame_bb, id); - bool popup_open = IsPopupOpen(id); + bool popup_open = IsPopupIdOpen(id); bool popup_opened_now = false; const ImRect value_bb(frame_bb.Min, frame_bb.Max - ImVec2(arrow_size, 0.0f)); @@ -8439,7 +8447,7 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi if (g.IO.MouseClicked[0]) { SetActiveID(0); - if (IsPopupOpen(id)) + if (IsPopupIdOpen(id)) { ClosePopup(id); } @@ -8453,7 +8461,7 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi } bool value_changed = false; - if (IsPopupOpen(id)) + if (IsPopupIdOpen(id)) { // Size default to hold ~7 items if (height_in_items < 0) @@ -8799,7 +8807,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled) ImGuiWindow* backed_focused_window = g.FocusedWindow; bool pressed; - bool menu_is_open = IsPopupOpen(id); + bool menu_is_open = IsPopupIdOpen(id); bool menuset_is_open = !(window->Flags & ImGuiWindowFlags_Popup) && (g.OpenPopupStack.Size > g.CurrentPopupStack.Size && g.OpenPopupStack[g.CurrentPopupStack.Size].ParentMenuSet == window->GetID("##menus")); if (menuset_is_open) g.FocusedWindow = window; @@ -8865,7 +8873,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled) want_open = true; if (!enabled) // explicitly close if an open menu becomes disabled, facilitate users code a lot in pattern such as 'if (BeginMenu("options", has_object)) { ..use object.. }' want_close = true; - if (want_close && IsPopupOpen(id)) + if (want_close && IsPopupIdOpen(id)) ClosePopupToLevel(GImGui->CurrentPopupStack.Size); if (!menu_is_open && want_open && g.OpenPopupStack.Size > g.CurrentPopupStack.Size) diff --git a/imgui.h b/imgui.h index edb1d68d5..c1a92ee0d 100644 --- a/imgui.h +++ b/imgui.h @@ -371,6 +371,7 @@ namespace ImGui // Popups IMGUI_API void OpenPopup(const char* str_id); // mark popup as open. popups are closed when user click outside, or activate a pressable item, or CloseCurrentPopup() is called within a BeginPopup()/EndPopup() block. popup identifiers are relative to the current ID-stack (so OpenPopup and BeginPopup needs to be at the same level). + IMGUI_API bool IsPopupOpen(const char* str_id); // return true if the popup is open IMGUI_API bool BeginPopup(const char* str_id); // return true if the popup is open, and you can start outputting to it. only call EndPopup() if BeginPopup() returned true! IMGUI_API bool BeginPopupModal(const char* name, bool* p_open = NULL, ImGuiWindowFlags extra_flags = 0); // modal dialog (can't close them by clicking outside) IMGUI_API bool BeginPopupContextItem(const char* str_id, int mouse_button = 1); // helper to open and begin popup when clicked on last item. read comments in .cpp! From 66c428129051b278d252de9b1ec66443e49d48da Mon Sep 17 00:00:00 2001 From: Geoffrey Tucker Date: Sat, 29 Oct 2016 15:44:08 -0700 Subject: [PATCH 009/921] Began improvements to columns API by splitting the Columns() function into BeginColumns() and EndColumns() and adding additional flags. The columns data still needs to be placed into a stack. --- imgui.cpp | 202 ++++++++++++++++++++++++++++++----------------- imgui.h | 33 +++++--- imgui_demo.cpp | 43 ++++++++++ imgui_draw.cpp | 4 +- imgui_internal.h | 6 +- 5 files changed, 199 insertions(+), 89 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 07466840b..8761f7843 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3507,7 +3507,7 @@ static bool BeginPopupEx(const char* str_id, ImGuiWindowFlags extra_flags) bool ImGui::BeginPopup(const char* str_id) { - if (GImGui->OpenPopupStack.Size <= GImGui->CurrentPopupStack.Size) // Early out for performance + if (GImGui->OpenPopupStack.Size <= GImGui->CurrentPopupStack.Size) // Early out for performance { ClearSetNextWindowData(); // We behave like Begin() and need to consume those values return false; @@ -9175,7 +9175,7 @@ void ImGui::EndGroup() ImGuiContext& g = *GImGui; ImGuiWindow* window = GetCurrentWindow(); - IM_ASSERT(!window->DC.GroupStack.empty()); // Mismatched BeginGroup()/EndGroup() calls + IM_ASSERT(!window->DC.GroupStack.empty()); // Mismatched BeginGroup()/EndGroup() calls ImGuiGroupData& group_data = window->DC.GroupStack.back(); @@ -9295,6 +9295,18 @@ int ImGui::GetColumnsCount() return window->DC.ColumnsCount; } +static float OffsetNormToPixels(float offsetNorm) +{ + ImGuiWindow* window = ImGui::GetCurrentWindowRead(); + return offsetNorm * (window->DC.ColumnsMaxX - window->DC.ColumnsMinX); +} + +static float PixelsToOffsetNorm(float offset) +{ + ImGuiWindow* window = ImGui::GetCurrentWindowRead(); + return (offset - window->DC.ColumnsMinX) / (window->DC.ColumnsMaxX - window->DC.ColumnsMinX); +} + static float GetDraggedColumnOffset(int column_index) { // Active (dragged) column always follow mouse. The reason we need this is that dragging a column to the right edge of an auto-resizing @@ -9305,7 +9317,9 @@ static float GetDraggedColumnOffset(int column_index) IM_ASSERT(g.ActiveId == window->DC.ColumnsSetId + ImGuiID(column_index)); float x = g.IO.MousePos.x - g.ActiveIdClickOffset.x - window->Pos.x; - x = ImClamp(x, ImGui::GetColumnOffset(column_index-1)+g.Style.ColumnsMinSpacing, ImGui::GetColumnOffset(column_index+1)-g.Style.ColumnsMinSpacing); + x = ImMax(x, ImGui::GetColumnOffset(column_index-1) + g.Style.ColumnsMinSpacing); + if ((window->DC.ColumnsFlags & ImGuiColumnsFlags_NoPreserveWidths)) + x = ImMin(x, ImGui::GetColumnOffset(column_index+1) - g.Style.ColumnsMinSpacing); return (float)(int)x; } @@ -9332,16 +9346,26 @@ float ImGui::GetColumnOffset(int column_index) void ImGui::SetColumnOffset(int column_index, float offset) { + ImGuiContext& g = *GImGui; ImGuiWindow* window = GetCurrentWindow(); if (column_index < 0) column_index = window->DC.ColumnsCurrent; IM_ASSERT(column_index < window->DC.ColumnsData.Size); - const float t = (offset - window->DC.ColumnsMinX) / (window->DC.ColumnsMaxX - window->DC.ColumnsMinX); - window->DC.ColumnsData[column_index].OffsetNorm = t; + + const bool preserveWidth = !(window->DC.ColumnsFlags & ImGuiColumnsFlags_NoPreserveWidths) && (column_index < window->DC.ColumnsCount-1); + const float width = preserveWidth ? GetColumnWidth(column_index) : 0.0f; + + if (!(window->DC.ColumnsFlags & ImGuiColumnsFlags_NoForceWithinWindow)) + offset = ImMin((float)(int)offset, window->DC.ColumnsMaxX - g.Style.ColumnsMinSpacing * (window->DC.ColumnsCount - column_index)); + const float offsetNorm = PixelsToOffsetNorm(offset); const ImGuiID column_id = window->DC.ColumnsSetId + ImGuiID(column_index); - window->DC.StateStorage->SetFloat(column_id, t); + window->DC.StateStorage->SetFloat(column_id, offsetNorm); + window->DC.ColumnsData[column_index].OffsetNorm = offsetNorm; + + if (preserveWidth) + SetColumnOffset(column_index+1, offset + ImMax(g.Style.ColumnsMinSpacing, width)); } float ImGui::GetColumnWidth(int column_index) @@ -9350,8 +9374,16 @@ float ImGui::GetColumnWidth(int column_index) if (column_index < 0) column_index = window->DC.ColumnsCurrent; - float w = GetColumnOffset(column_index+1) - GetColumnOffset(column_index); - return w; + return OffsetNormToPixels(window->DC.ColumnsData[column_index+1].OffsetNorm - window->DC.ColumnsData[column_index].OffsetNorm); +} + +void ImGui::SetColumnWidth(int column_index, float width) +{ + ImGuiWindow* window = GetCurrentWindowRead(); + if (column_index < 0) + column_index = window->DC.ColumnsCurrent; + + SetColumnOffset(column_index+1, GetColumnOffset(column_index) + width); } static void PushColumnClipRect(int column_index) @@ -9365,56 +9397,12 @@ static void PushColumnClipRect(int column_index) ImGui::PushClipRect(ImVec2(x1,-FLT_MAX), ImVec2(x2,+FLT_MAX), true); } -void ImGui::Columns(int columns_count, const char* id, bool border) +void ImGui::BeginColumns(const char* id, int columns_count, ImGuiColumnsFlags flags) { ImGuiContext& g = *GImGui; ImGuiWindow* window = GetCurrentWindow(); - IM_ASSERT(columns_count >= 1); - - if (window->DC.ColumnsCount != 1) - { - if (window->DC.ColumnsCurrent != 0) - ItemSize(ImVec2(0,0)); // Advance to column 0 - PopItemWidth(); - PopClipRect(); - window->DrawList->ChannelsMerge(); - - window->DC.ColumnsCellMaxY = ImMax(window->DC.ColumnsCellMaxY, window->DC.CursorPos.y); - window->DC.CursorPos.y = window->DC.ColumnsCellMaxY; - } - - // Draw columns borders and handle resize at the time of "closing" a columns set - if (window->DC.ColumnsCount != columns_count && window->DC.ColumnsCount != 1 && window->DC.ColumnsShowBorders && !window->SkipItems) - { - const float y1 = window->DC.ColumnsStartPosY; - const float y2 = window->DC.CursorPos.y; - for (int i = 1; i < window->DC.ColumnsCount; i++) - { - float x = window->Pos.x + GetColumnOffset(i); - const ImGuiID column_id = window->DC.ColumnsSetId + ImGuiID(i); - const ImRect column_rect(ImVec2(x-4,y1),ImVec2(x+4,y2)); - if (IsClippedEx(column_rect, &column_id, false)) - continue; - - bool hovered, held; - ButtonBehavior(column_rect, column_id, &hovered, &held); - if (hovered || held) - g.MouseCursor = ImGuiMouseCursor_ResizeEW; - - // Draw before resize so our items positioning are in sync with the line being drawn - const ImU32 col = GetColorU32(held ? ImGuiCol_ColumnActive : hovered ? ImGuiCol_ColumnHovered : ImGuiCol_Column); - const float xi = (float)(int)x; - window->DrawList->AddLine(ImVec2(xi, y1+1.0f), ImVec2(xi, y2), col); - - if (held) - { - if (g.ActiveIdIsJustActivated) - g.ActiveIdClickOffset.x -= 4; // Store from center of column line (we used a 8 wide rect for columns clicking) - x = GetDraggedColumnOffset(i); - SetColumnOffset(i, x); - } - } - } + IM_ASSERT(columns_count > 1); + IM_ASSERT(window->DC.ColumnsCount == 1); // Nested columns are currently not supported // Differentiate column ID with an arbitrary prefix for cases where users name their columns set the same as another widget. // In addition, when an identifier isn't explicitly provided we include the number of columns in the hash to make it uniquer. @@ -9425,7 +9413,7 @@ void ImGui::Columns(int columns_count, const char* id, bool border) // Set state for first column window->DC.ColumnsCurrent = 0; window->DC.ColumnsCount = columns_count; - window->DC.ColumnsShowBorders = border; + window->DC.ColumnsFlags = flags; const float content_region_width = (window->SizeContentsExplicit.x != 0.0f) ? window->SizeContentsExplicit.x : window->Size.x; window->DC.ColumnsMinX = window->DC.IndentX; // Lock our horizontal range @@ -9435,26 +9423,92 @@ void ImGui::Columns(int columns_count, const char* id, bool border) window->DC.ColumnsOffsetX = 0.0f; window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.IndentX + window->DC.ColumnsOffsetX); - if (window->DC.ColumnsCount != 1) + // Cache column offsets + window->DC.ColumnsData.resize(columns_count + 1); + for (int column_index = 0; column_index < columns_count + 1; column_index++) { - // Cache column offsets - window->DC.ColumnsData.resize(columns_count + 1); - for (int column_index = 0; column_index < columns_count + 1; column_index++) - { - const ImGuiID column_id = window->DC.ColumnsSetId + ImGuiID(column_index); - KeepAliveID(column_id); - const float default_t = column_index / (float)window->DC.ColumnsCount; - const float t = window->DC.StateStorage->GetFloat(column_id, default_t); // Cheaply store our floating point value inside the integer (could store a union into the map?) - window->DC.ColumnsData[column_index].OffsetNorm = t; - } - window->DrawList->ChannelsSplit(window->DC.ColumnsCount); - PushColumnClipRect(); - PushItemWidth(GetColumnWidth() * 0.65f); - } - else - { - window->DC.ColumnsData.resize(0); + const ImGuiID column_id = window->DC.ColumnsSetId + ImGuiID(column_index); + KeepAliveID(column_id); + const float default_t = column_index / (float)window->DC.ColumnsCount; + float t = window->DC.StateStorage->GetFloat(column_id, default_t); // Cheaply store our floating point value inside the integer (could store a union into the map?) + if (!(window->DC.ColumnsFlags & ImGuiColumnsFlags_NoForceWithinWindow)) + t = ImMin(t, PixelsToOffsetNorm(window->DC.ColumnsMaxX - g.Style.ColumnsMinSpacing * (window->DC.ColumnsCount - column_index))); + window->DC.ColumnsData[column_index].OffsetNorm = t; } + window->DrawList->ChannelsSplit(window->DC.ColumnsCount); + PushColumnClipRect(); + PushItemWidth(GetColumnWidth() * 0.65f); +} + +void ImGui::EndColumns() +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + IM_ASSERT(window->DC.ColumnsCount > 1); + + if (window->DC.ColumnsCurrent != 0) + ItemSize(ImVec2(0, 0)); // Advance to column 0 + PopItemWidth(); + PopClipRect(); + window->DrawList->ChannelsMerge(); + + window->DC.ColumnsCellMaxY = ImMax(window->DC.ColumnsCellMaxY, window->DC.CursorPos.y); + window->DC.CursorPos.y = window->DC.ColumnsCellMaxY; + + // Draw columns borders and handle resize + if (!(window->DC.ColumnsFlags & ImGuiColumnsFlags_NoBorder) && !window->SkipItems) + { + const float y1 = window->DC.ColumnsStartPosY; + const float y2 = window->DC.CursorPos.y; + for (int i = 1; i < window->DC.ColumnsCount; i++) + { + float x = window->Pos.x + GetColumnOffset(i); + const ImGuiID column_id = window->DC.ColumnsSetId + ImGuiID(i); + const ImRect column_rect(ImVec2(x - 4, y1), ImVec2(x + 4, y2)); + if (IsClippedEx(column_rect, &column_id, false)) + continue; + + bool hovered, held; + ButtonBehavior(column_rect, column_id, &hovered, &held); + if (hovered || held) + g.MouseCursor = ImGuiMouseCursor_ResizeEW; + + // Draw before resize so our items positioning are in sync with the line being drawn + const ImU32 col = GetColorU32(held ? ImGuiCol_ColumnActive : hovered ? ImGuiCol_ColumnHovered : ImGuiCol_Column); + const float xi = (float)(int)x; + window->DrawList->AddLine(ImVec2(xi, y1 + 1.0f), ImVec2(xi, y2), col); + + if (held) + { + if (g.ActiveIdIsJustActivated) + g.ActiveIdClickOffset.x -= 4; // Store from center of column line (we used a 8 wide rect for columns clicking) + x = GetDraggedColumnOffset(i); + SetColumnOffset(i, x); + } + } + } + + window->DC.ColumnsSetId = 0; + window->DC.ColumnsCurrent = 0; + window->DC.ColumnsCount = 1; + window->DC.ColumnsFlags = 0; + window->DC.ColumnsData.resize(0); +} + +void ImGui::Columns(int columns_count, const char* id, bool border) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + IM_ASSERT(columns_count >= 1); + + ImGuiColumnsFlags flags = 0; + flags |= (border ? 0 : ImGuiColumnsFlags_NoBorder); + + if (window->DC.ColumnsCount != columns_count && window->DC.ColumnsCount != 1) + EndColumns(); + + if (columns_count != 1) + BeginColumns(id, columns_count, flags); } void ImGui::Indent(float indent_w) diff --git a/imgui.h b/imgui.h index edb1d68d5..548d9cc65 100644 --- a/imgui.h +++ b/imgui.h @@ -73,6 +73,7 @@ typedef int ImGuiKey; // a key identifier (ImGui-side enum) // e typedef int ImGuiColorEditMode; // color edit mode for ColorEdit*() // enum ImGuiColorEditMode_ typedef int ImGuiMouseCursor; // a mouse cursor identifier // enum ImGuiMouseCursor_ typedef int ImGuiWindowFlags; // window flags for Begin*() // enum ImGuiWindowFlags_ +typedef int ImGuiColumnsFlags; // column flags for Columns() // enum ImGuiColumnsFlags_ typedef int ImGuiSetCond; // condition flags for Set*() // enum ImGuiSetCond_ typedef int ImGuiInputTextFlags; // flags for InputText*() // enum ImGuiInputTextFlags_ typedef int ImGuiSelectableFlags; // flags for Selectable() // enum ImGuiSelectableFlags_ @@ -221,13 +222,16 @@ namespace ImGui // Columns // You can also use SameLine(pos_x) for simplified columning. The columns API is still work-in-progress and rather lacking. - IMGUI_API void Columns(int count = 1, const char* id = NULL, bool border = true); // setup number of columns. use an identifier to distinguish multiple column sets. close with Columns(1). - IMGUI_API void NextColumn(); // next column - IMGUI_API int GetColumnIndex(); // get current column index - IMGUI_API float GetColumnOffset(int column_index = -1); // get position of column line (in pixels, from the left side of the contents region). pass -1 to use current column, otherwise 0..GetcolumnsCount() inclusive. column 0 is usually 0.0f and not resizable unless you call this - IMGUI_API void SetColumnOffset(int column_index, float offset_x); // set position of column line (in pixels, from the left side of the contents region). pass -1 to use current column - IMGUI_API float GetColumnWidth(int column_index = -1); // column width (== GetColumnOffset(GetColumnIndex()+1) - GetColumnOffset(GetColumnOffset()) - IMGUI_API int GetColumnsCount(); // number of columns (what was passed to Columns()) + IMGUI_API void BeginColumns(const char* id, int count, ImGuiColumnsFlags flags = 0); // setup number of columns. use an identifier to distinguish multiple column sets. close with EndColumns(). + IMGUI_API void EndColumns(); // close columns + IMGUI_API void NextColumn(); // next column, defaults to current row or next row if the current row is finished + IMGUI_API int GetColumnIndex(); // get current column index + IMGUI_API float GetColumnWidth(int column_index = -1); // get column width (in pixels). pass -1 to use current column + IMGUI_API void SetColumnWidth(int column_index, float width); // set column width (in pixels). pass -1 to use current column + IMGUI_API float GetColumnOffset(int column_index = -1); // get position of column line (in pixels, from the left side of the contents region). pass -1 to use current column, otherwise 0..GetColumnsCount() inclusive. column 0 is usually 0.0f and not resizable unless you call this + IMGUI_API void SetColumnOffset(int column_index, float offset_x); // set position of column line (in pixels, from the left side of the contents region). pass -1 to use current column + IMGUI_API int GetColumnsCount(); + IMGUI_API void Columns(int count = 1, const char* id = NULL, bool border = true); // ID scopes // If you are creating widgets in a loop you most likely want to push a unique identifier so ImGui can differentiate them. @@ -418,7 +422,7 @@ namespace ImGui IMGUI_API ImVec2 CalcTextSize(const char* text, const char* text_end = NULL, bool hide_text_after_double_hash = false, float wrap_width = -1.0f); IMGUI_API void CalcListClipping(int items_count, float items_height, int* out_items_display_start, int* out_items_display_end); // calculate coarse clipping for large list of evenly sized items. Prefer using the ImGuiListClipper higher-level helper if you can. - IMGUI_API bool BeginChildFrame(ImGuiID id, const ImVec2& size, ImGuiWindowFlags extra_flags = 0); // helper to create a child window / scrolling region that looks like a normal widget frame + IMGUI_API bool BeginChildFrame(ImGuiID id, const ImVec2& size, ImGuiWindowFlags extra_flags = 0); // helper to create a child window / scrolling region that looks like a normal widget frame IMGUI_API void EndChildFrame(); IMGUI_API ImVec4 ColorConvertU32ToFloat4(ImU32 in); @@ -506,6 +510,15 @@ enum ImGuiWindowFlags_ ImGuiWindowFlags_ChildMenu = 1 << 27 // Don't use! For internal use by BeginMenu() }; +// Flags for ImGui::Columns() +enum ImGuiColumnsFlags_ +{ + // Default: 0 + ImGuiColumnsFlags_NoBorder = 1 << 0, // Disable column dividers + ImGuiColumnsFlags_NoPreserveWidths = 1 << 1, // Disable column width preservation when adjusting columns + ImGuiColumnsFlags_NoForceWithinWindow = 1 << 2 // Disable forcing columns to fit within window +}; + // Flags for ImGui::InputText() enum ImGuiInputTextFlags_ { @@ -1029,8 +1042,8 @@ struct ImGuiTextEditCallbackData struct ImGuiSizeConstraintCallbackData { void* UserData; // Read-only. What user passed to SetNextWindowSizeConstraints() - ImVec2 Pos; // Read-only. Window position, for reference. - ImVec2 CurrentSize; // Read-only. Current window size. + ImVec2 Pos; // Read-only. Window position, for reference. + ImVec2 CurrentSize; // Read-only. Current window size. ImVec2 DesiredSize; // Read-write. Desired size, based on user's mouse position. Write to this field to restrain resizing. }; diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 544d6230f..3ebdb8ab7 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1400,6 +1400,49 @@ void ImGui::ShowTestWindow(bool* p_open) } */ + if (ImGui::TreeNode("Advanced settings")) + { + static bool border = true; + static bool preserveWidths = true; + static bool forceWithinWindow = true; + + ImGui::Checkbox("Border", &border); + ImGui::SameLine(); + ImGui::Checkbox("Preserve widths", &preserveWidths); + ImGui::SameLine(); + ImGui::Checkbox("Force within window", &forceWithinWindow); + + ImGuiColumnsFlags flags = 0; + flags |= (border ? 0 : ImGuiColumnsFlags_NoBorder); + flags |= (preserveWidths ? 0 : ImGuiColumnsFlags_NoPreserveWidths); + flags |= (forceWithinWindow ? 0 : ImGuiColumnsFlags_NoForceWithinWindow); + + ImGui::BeginColumns("AdvancedColumns", 4, flags); + ImGui::Separator(); + ImGui::Text("ID"); ImGui::NextColumn(); + ImGui::Text("Name"); ImGui::NextColumn(); + ImGui::Text("Path"); ImGui::NextColumn(); + ImGui::Text("Flags"); ImGui::NextColumn(); + ImGui::Separator(); + const char* names[3] = { "One", "Two", "Three" }; + const char* paths[3] = { "/path/one", "/path/two", "/path/three" }; + static int selected = -1; + for (int i = 0; i < 3; i++) + { + char label[32]; + sprintf(label, "%04d", i); + if (ImGui::Selectable(label, selected == i, ImGuiSelectableFlags_SpanAllColumns)) + selected = i; + ImGui::NextColumn(); + ImGui::Text(names[i]); ImGui::NextColumn(); + ImGui::Text(paths[i]); ImGui::NextColumn(); + ImGui::Text("...."); ImGui::NextColumn(); + } + ImGui::EndColumns(); + ImGui::Separator(); + ImGui::TreePop(); + } + // Create multiple items in a same cell before switching to next column if (ImGui::TreeNode("Mixed items")) { diff --git a/imgui_draw.cpp b/imgui_draw.cpp index ade417771..99004adcf 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1145,8 +1145,8 @@ ImFont* ImFontAtlas::AddFont(const ImFontConfig* font_cfg) ConfigData.push_back(*font_cfg); ImFontConfig& new_font_cfg = ConfigData.back(); - if (!new_font_cfg.DstFont) - new_font_cfg.DstFont = Fonts.back(); + if (!new_font_cfg.DstFont) + new_font_cfg.DstFont = Fonts.back(); if (!new_font_cfg.FontDataOwnedByAtlas) { new_font_cfg.FontData = ImGui::MemAlloc(new_font_cfg.FontDataSize); diff --git a/imgui_internal.h b/imgui_internal.h index 08f206adc..9eed7b943 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -282,7 +282,7 @@ struct ImGuiGroupData // Per column data for Columns() struct ImGuiColumnData { - float OffsetNorm; // Column start offset, normalized 0.0 (far left) -> 1.0 (far right) + float OffsetNorm; // Column start offset, normalized 0.0 (far left) -> 1.0 (far right) //float IndentX; }; @@ -571,7 +571,7 @@ struct IMGUI_API ImGuiDrawContext float ColumnsStartPosY; float ColumnsCellMinY; float ColumnsCellMaxY; - bool ColumnsShowBorders; + ImGuiColumnsFlags ColumnsFlags; ImGuiID ColumnsSetId; ImVector ColumnsData; @@ -603,7 +603,7 @@ struct IMGUI_API ImGuiDrawContext ColumnsMinX = ColumnsMaxX = 0.0f; ColumnsStartPosY = 0.0f; ColumnsCellMinY = ColumnsCellMaxY = 0.0f; - ColumnsShowBorders = true; + ColumnsFlags = 0; ColumnsSetId = 0; } }; From 8e8117c7b1297e12c3a2c6e4ab807e62fa0cd5c1 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 21 Jan 2017 19:23:47 +0100 Subject: [PATCH 010/921] stb_truetype update (with OpenType, Type 2 font handling) (#976) --- stb_truetype.h | 765 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 748 insertions(+), 17 deletions(-) diff --git a/stb_truetype.h b/stb_truetype.h index 88a2da16e..92b9a8754 100644 --- a/stb_truetype.h +++ b/stb_truetype.h @@ -1,4 +1,4 @@ -// stb_truetype.h - v1.12 - public domain +// stb_truetype.h - v1.14 - public domain // authored from 2009-2016 by Sean Barrett / RAD Game Tools // // This library processes TrueType files: @@ -20,10 +20,12 @@ // // Mikko Mononen: compound shape support, more cmap formats // Tor Andersson: kerning, subpixel rendering +// Dougall Johnson: OpenType / Type 2 font handling // // Misc other: // Ryan Gordon // Simon Glass +// github:IntellectualKitty // // Bug/warning reports/fixes: // "Zer" on mollyrocket (with fix) @@ -51,6 +53,7 @@ // // VERSION HISTORY // +// 1.13 (2017-01-02) support OpenType fonts, certain Apple fonts, num-fonts-in-TTC function // 1.12 (2016-10-25) suppress warnings about casting away const with -Wcast-qual // 1.11 (2016-04-02) fix unused-variable warning // 1.10 (2016-04-02) user-defined fabs(); rare memory leak; remove duplicate typedef @@ -95,7 +98,8 @@ // // "Load" a font file from a memory buffer (you have to keep the buffer loaded) // stbtt_InitFont() -// stbtt_GetFontOffsetForIndex() -- use for TTC font collections +// stbtt_GetFontOffsetForIndex() -- indexing for TTC font collections +// stbtt_GetNumberOfFonts() -- number of fonts for TTC font collections // // Render a unicode codepoint to a bitmap // stbtt_GetCodepointBitmap() -- allocates and returns a bitmap @@ -453,6 +457,14 @@ int main(int arg, char **argv) extern "C" { #endif +// private structure +typedef struct +{ + unsigned char *data; + int cursor; + int size; +} stbtt__buf; + ////////////////////////////////////////////////////////////////////////////// // // TEXTURE BAKING API @@ -522,7 +534,7 @@ typedef struct stbrp_rect stbrp_rect; STBTT_DEF int stbtt_PackBegin(stbtt_pack_context *spc, unsigned char *pixels, int width, int height, int stride_in_bytes, int padding, void *alloc_context); // Initializes a packing context stored in the passed-in stbtt_pack_context. // Future calls using this context will pack characters into the bitmap passed -// in here: a 1-channel bitmap that is weight x height. stride_in_bytes is +// in here: a 1-channel bitmap that is width * height. stride_in_bytes is // the distance from one row to the next (or 0 to mean they are packed tightly // together). "padding" is the amount of padding to leave between each // character (normally you want '1' for bitmaps you'll use as textures with @@ -621,14 +633,19 @@ struct stbtt_pack_context { // // +STBTT_DEF int stbtt_GetNumberOfFonts(const unsigned char *data); +// This function will determine the number of fonts in a font file. TrueType +// collection (.ttc) files may contain multiple fonts, while TrueType font +// (.ttf) files only contain one font. The number of fonts can be used for +// indexing with the previous function where the index is between zero and one +// less than the total fonts. If an error occurs, -1 is returned. + STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char *data, int index); // Each .ttf/.ttc file may have more than one font. Each font has a sequential // index number starting from 0. Call this function to get the font offset for // a given index; it returns -1 if the index is out of range. A regular .ttf // file will only define one font and it always be at offset 0, so it will -// return '0' for index 0, and -1 for all other indices. You can just skip -// this step if you know it's that kind of font. - +// return '0' for index 0, and -1 for all other indices. // The following structure is defined publically so you can declare one on // the stack or as a global or etc, but you should treat it as opaque. @@ -643,6 +660,13 @@ struct stbtt_fontinfo int loca,head,glyf,hhea,hmtx,kern; // table locations as offset from start of .ttf int index_map; // a cmap mapping for our chosen character encoding int indexToLocFormat; // format needed to map from glyph index to glyph + + stbtt__buf cff; // cff font data + stbtt__buf charstrings; // the charstring index + stbtt__buf gsubrs; // global charstring subroutines index + stbtt__buf subrs; // private charstring subroutines index + stbtt__buf fontdicts; // array of font dicts + stbtt__buf fdselect; // map from glyph to fontdict }; STBTT_DEF int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data, int offset); @@ -720,7 +744,8 @@ STBTT_DEF int stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_index, in enum { STBTT_vmove=1, STBTT_vline, - STBTT_vcurve + STBTT_vcurve, + STBTT_vcubic }; #endif @@ -729,7 +754,7 @@ STBTT_DEF int stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_index, in #define stbtt_vertex_type short // can't use stbtt_int16 because that's not visible in the header file typedef struct { - stbtt_vertex_type x,y,cx,cy; + stbtt_vertex_type x,y,cx,cy,cx1,cy1; unsigned char type,padding; } stbtt_vertex; #endif @@ -951,6 +976,152 @@ typedef int stbtt__test_oversample_pow2[(STBTT_MAX_OVERSAMPLE & (STBTT_MAX_OVERS #define STBTT__NOTUSED(v) (void)sizeof(v) #endif +////////////////////////////////////////////////////////////////////////// +// +// stbtt__buf helpers to parse data from file +// + +static stbtt_uint8 stbtt__buf_get8(stbtt__buf *b) +{ + if (b->cursor >= b->size) + return 0; + return b->data[b->cursor++]; +} + +static stbtt_uint8 stbtt__buf_peek8(stbtt__buf *b) +{ + if (b->cursor >= b->size) + return 0; + return b->data[b->cursor]; +} + +static void stbtt__buf_seek(stbtt__buf *b, int o) +{ + STBTT_assert(!(o > b->size || o < 0)); + b->cursor = (o > b->size || o < 0) ? b->size : o; +} + +static void stbtt__buf_skip(stbtt__buf *b, int o) +{ + stbtt__buf_seek(b, b->cursor + o); +} + +static stbtt_uint32 stbtt__buf_get(stbtt__buf *b, int n) +{ + stbtt_uint32 v = 0; + int i; + STBTT_assert(n >= 1 && n <= 4); + for (i = 0; i < n; i++) + v = (v << 8) | stbtt__buf_get8(b); + return v; +} + +static stbtt__buf stbtt__new_buf(const void *p, size_t size) +{ + stbtt__buf r; + STBTT_assert(size < 0x40000000); + r.data = (stbtt_uint8*) p; + r.size = (int) size; + r.cursor = 0; + return r; +} + +#define stbtt__buf_get16(b) stbtt__buf_get((b), 2) +#define stbtt__buf_get32(b) stbtt__buf_get((b), 4) + +static stbtt__buf stbtt__buf_range(const stbtt__buf *b, int o, int s) +{ + stbtt__buf r = stbtt__new_buf(NULL, 0); + if (o < 0 || s < 0 || o > b->size || s > b->size - o) return r; + r.data = b->data + o; + r.size = s; + return r; +} + +static stbtt__buf stbtt__cff_get_index(stbtt__buf *b) +{ + int count, start, offsize; + start = b->cursor; + count = stbtt__buf_get16(b); + if (count) { + offsize = stbtt__buf_get8(b); + STBTT_assert(offsize >= 1 && offsize <= 4); + stbtt__buf_skip(b, offsize * count); + stbtt__buf_skip(b, stbtt__buf_get(b, offsize) - 1); + } + return stbtt__buf_range(b, start, b->cursor - start); +} + +static stbtt_uint32 stbtt__cff_int(stbtt__buf *b) +{ + int b0 = stbtt__buf_get8(b); + if (b0 >= 32 && b0 <= 246) return b0 - 139; + else if (b0 >= 247 && b0 <= 250) return (b0 - 247)*256 + stbtt__buf_get8(b) + 108; + else if (b0 >= 251 && b0 <= 254) return -(b0 - 251)*256 - stbtt__buf_get8(b) - 108; + else if (b0 == 28) return stbtt__buf_get16(b); + else if (b0 == 29) return stbtt__buf_get32(b); + STBTT_assert(0); + return 0; +} + +static void stbtt__cff_skip_operand(stbtt__buf *b) { + int v, b0 = stbtt__buf_peek8(b); + STBTT_assert(b0 >= 28); + if (b0 == 30) { + stbtt__buf_skip(b, 1); + while (b->cursor < b->size) { + v = stbtt__buf_get8(b); + if ((v & 0xF) == 0xF || (v >> 4) == 0xF) + break; + } + } else { + stbtt__cff_int(b); + } +} + +static stbtt__buf stbtt__dict_get(stbtt__buf *b, int key) +{ + stbtt__buf_seek(b, 0); + while (b->cursor < b->size) { + int start = b->cursor, end, op; + while (stbtt__buf_peek8(b) >= 28) + stbtt__cff_skip_operand(b); + end = b->cursor; + op = stbtt__buf_get8(b); + if (op == 12) op = stbtt__buf_get8(b) | 0x100; + if (op == key) return stbtt__buf_range(b, start, end-start); + } + return stbtt__buf_range(b, 0, 0); +} + +static void stbtt__dict_get_ints(stbtt__buf *b, int key, int outcount, stbtt_uint32 *out) +{ + int i; + stbtt__buf operands = stbtt__dict_get(b, key); + for (i = 0; i < outcount && operands.cursor < operands.size; i++) + out[i] = stbtt__cff_int(&operands); +} + +static int stbtt__cff_index_count(stbtt__buf *b) +{ + stbtt__buf_seek(b, 0); + return stbtt__buf_get16(b); +} + +static stbtt__buf stbtt__cff_index_get(stbtt__buf b, int i) +{ + int count, offsize, start, end; + stbtt__buf_seek(&b, 0); + count = stbtt__buf_get16(&b); + offsize = stbtt__buf_get8(&b); + STBTT_assert(i >= 0 && i < count); + STBTT_assert(offsize >= 1 && offsize <= 4); + stbtt__buf_skip(&b, i*offsize); + start = stbtt__buf_get(&b, offsize); + end = stbtt__buf_get(&b, offsize); + return stbtt__buf_range(&b, 2+(count+1)*offsize+start, end - start); +} + ////////////////////////////////////////////////////////////////////////// // // accessors to parse data from file @@ -978,6 +1149,7 @@ static int stbtt__isfont(stbtt_uint8 *font) if (stbtt_tag(font, "typ1")) return 1; // TrueType with type 1 font -- we don't support this! if (stbtt_tag(font, "OTTO")) return 1; // OpenType with CFF if (stbtt_tag4(font, 0,1,0,0)) return 1; // OpenType 1.0 + if (stbtt_tag(font, "true")) return 1; // Apple specification for TrueType fonts return 0; } @@ -1014,6 +1186,35 @@ static int stbtt_GetFontOffsetForIndex_internal(unsigned char *font_collection, return -1; } +static int stbtt_GetNumberOfFonts_internal(unsigned char *font_collection) +{ + // if it's just a font, there's only one valid font + if (stbtt__isfont(font_collection)) + return 1; + + // check if it's a TTC + if (stbtt_tag(font_collection, "ttcf")) { + // version 1? + if (ttULONG(font_collection+4) == 0x00010000 || ttULONG(font_collection+4) == 0x00020000) { + return ttLONG(font_collection+8); + } + } + return 0; +} + +static stbtt__buf stbtt__get_subrs(stbtt__buf cff, stbtt__buf fontdict) +{ + stbtt_uint32 subrsoff = 0, private_loc[2] = { 0, 0 }; + stbtt__buf pdict; + stbtt__dict_get_ints(&fontdict, 18, 2, private_loc); + if (!private_loc[1] || !private_loc[0]) return stbtt__new_buf(NULL, 0); + pdict = stbtt__buf_range(&cff, private_loc[1], private_loc[0]); + stbtt__dict_get_ints(&pdict, 19, 1, &subrsoff); + if (!subrsoff) return stbtt__new_buf(NULL, 0); + stbtt__buf_seek(&cff, private_loc[1]+subrsoff); + return stbtt__cff_get_index(&cff); +} + static int stbtt_InitFont_internal(stbtt_fontinfo *info, unsigned char *data, int fontstart) { stbtt_uint32 cmap, t; @@ -1021,6 +1222,7 @@ static int stbtt_InitFont_internal(stbtt_fontinfo *info, unsigned char *data, in info->data = data; info->fontstart = fontstart; + info->cff = stbtt__new_buf(NULL, 0); cmap = stbtt__find_table(data, fontstart, "cmap"); // required info->loca = stbtt__find_table(data, fontstart, "loca"); // required @@ -1029,8 +1231,61 @@ static int stbtt_InitFont_internal(stbtt_fontinfo *info, unsigned char *data, in info->hhea = stbtt__find_table(data, fontstart, "hhea"); // required info->hmtx = stbtt__find_table(data, fontstart, "hmtx"); // required info->kern = stbtt__find_table(data, fontstart, "kern"); // not required - if (!cmap || !info->loca || !info->head || !info->glyf || !info->hhea || !info->hmtx) + + if (!cmap || !info->head || !info->hhea || !info->hmtx) return 0; + if (info->glyf) { + // required for truetype + if (!info->loca) return 0; + } else { + // initialization for CFF / Type2 fonts (OTF) + stbtt__buf b, topdict, topdictidx; + stbtt_uint32 cstype = 2, charstrings = 0, fdarrayoff = 0, fdselectoff = 0; + stbtt_uint32 cff; + + cff = stbtt__find_table(data, fontstart, "CFF "); + if (!cff) return 0; + + info->fontdicts = stbtt__new_buf(NULL, 0); + info->fdselect = stbtt__new_buf(NULL, 0); + + // @TODO this should use size from table (not 512MB) + info->cff = stbtt__new_buf(data+cff, 512*1024*1024); + b = info->cff; + + // read the header + stbtt__buf_skip(&b, 2); + stbtt__buf_seek(&b, stbtt__buf_get8(&b)); // hdrsize + + // @TODO the name INDEX could list multiple fonts, + // but we just use the first one. + stbtt__cff_get_index(&b); // name INDEX + topdictidx = stbtt__cff_get_index(&b); + topdict = stbtt__cff_index_get(topdictidx, 0); + stbtt__cff_get_index(&b); // string INDEX + info->gsubrs = stbtt__cff_get_index(&b); + + stbtt__dict_get_ints(&topdict, 17, 1, &charstrings); + stbtt__dict_get_ints(&topdict, 0x100 | 6, 1, &cstype); + stbtt__dict_get_ints(&topdict, 0x100 | 36, 1, &fdarrayoff); + stbtt__dict_get_ints(&topdict, 0x100 | 37, 1, &fdselectoff); + info->subrs = stbtt__get_subrs(b, topdict); + + // we only support Type 2 charstrings + if (cstype != 2) return 0; + if (charstrings == 0) return 0; + + if (fdarrayoff) { + // looks like a CID font + if (!fdselectoff) return 0; + stbtt__buf_seek(&b, fdarrayoff); + info->fontdicts = stbtt__cff_get_index(&b); + info->fdselect = stbtt__buf_range(&b, fdselectoff, b.size-fdselectoff); + } + + stbtt__buf_seek(&b, charstrings); + info->charstrings = stbtt__cff_get_index(&b); + } t = stbtt__find_table(data, fontstart, "maxp"); if (t) @@ -1181,6 +1436,8 @@ static int stbtt__GetGlyfOffset(const stbtt_fontinfo *info, int glyph_index) { int g1,g2; + STBTT_assert(!info->cff.size); + if (glyph_index >= info->numGlyphs) return -1; // glyph index out of range if (info->indexToLocFormat >= 2) return -1; // unknown index->glyph map format @@ -1195,15 +1452,21 @@ static int stbtt__GetGlyfOffset(const stbtt_fontinfo *info, int glyph_index) return g1==g2 ? -1 : g1; // if length is 0, return -1 } +static int stbtt__GetGlyphInfoT2(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1); + STBTT_DEF int stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1) { - int g = stbtt__GetGlyfOffset(info, glyph_index); - if (g < 0) return 0; + if (info->cff.size) { + stbtt__GetGlyphInfoT2(info, glyph_index, x0, y0, x1, y1); + } else { + int g = stbtt__GetGlyfOffset(info, glyph_index); + if (g < 0) return 0; - if (x0) *x0 = ttSHORT(info->data + g + 2); - if (y0) *y0 = ttSHORT(info->data + g + 4); - if (x1) *x1 = ttSHORT(info->data + g + 6); - if (y1) *y1 = ttSHORT(info->data + g + 8); + if (x0) *x0 = ttSHORT(info->data + g + 2); + if (y0) *y0 = ttSHORT(info->data + g + 4); + if (x1) *x1 = ttSHORT(info->data + g + 6); + if (y1) *y1 = ttSHORT(info->data + g + 8); + } return 1; } @@ -1215,7 +1478,10 @@ STBTT_DEF int stbtt_GetCodepointBox(const stbtt_fontinfo *info, int codepoint, i STBTT_DEF int stbtt_IsGlyphEmpty(const stbtt_fontinfo *info, int glyph_index) { stbtt_int16 numberOfContours; - int g = stbtt__GetGlyfOffset(info, glyph_index); + int g; + if (info->cff.size) + return stbtt__GetGlyphInfoT2(info, glyph_index, NULL, NULL, NULL, NULL) == 0; + g = stbtt__GetGlyfOffset(info, glyph_index); if (g < 0) return 1; numberOfContours = ttSHORT(info->data + g); return numberOfContours == 0; @@ -1237,7 +1503,7 @@ static int stbtt__close_shape(stbtt_vertex *vertices, int num_vertices, int was_ return num_vertices; } -STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **pvertices) +static int stbtt__GetGlyphShapeTT(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **pvertices) { stbtt_int16 numberOfContours; stbtt_uint8 *endPtsOfContours; @@ -1463,6 +1729,416 @@ STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, s return num_vertices; } +typedef struct +{ + int bounds; + int started; + float first_x, first_y; + float x, y; + stbtt_int32 min_x, max_x, min_y, max_y; + + stbtt_vertex *pvertices; + int num_vertices; +} stbtt__csctx; + +#define STBTT__CSCTX_INIT(bounds) {bounds,0, 0,0, 0,0, 0,0,0,0, NULL, 0} + +static void stbtt__track_vertex(stbtt__csctx *c, stbtt_int32 x, stbtt_int32 y) +{ + if (x > c->max_x || !c->started) c->max_x = x; + if (y > c->max_y || !c->started) c->max_y = y; + if (x < c->min_x || !c->started) c->min_x = x; + if (y < c->min_y || !c->started) c->min_y = y; + c->started = 1; +} + +static void stbtt__csctx_v(stbtt__csctx *c, stbtt_uint8 type, stbtt_int32 x, stbtt_int32 y, stbtt_int32 cx, stbtt_int32 cy, stbtt_int32 cx1, stbtt_int32 cy1) +{ + if (c->bounds) { + stbtt__track_vertex(c, x, y); + if (type == STBTT_vcubic) { + stbtt__track_vertex(c, cx, cy); + stbtt__track_vertex(c, cx1, cy1); + } + } else { + stbtt_setvertex(&c->pvertices[c->num_vertices], type, x, y, cx, cy); + c->pvertices[c->num_vertices].cx1 = (stbtt_int16) cx1; + c->pvertices[c->num_vertices].cy1 = (stbtt_int16) cy1; + } + c->num_vertices++; +} + +static void stbtt__csctx_close_shape(stbtt__csctx *ctx) +{ + if (ctx->first_x != ctx->x || ctx->first_y != ctx->y) + stbtt__csctx_v(ctx, STBTT_vline, (int)ctx->first_x, (int)ctx->first_y, 0, 0, 0, 0); +} + +static void stbtt__csctx_rmove_to(stbtt__csctx *ctx, float dx, float dy) +{ + stbtt__csctx_close_shape(ctx); + ctx->first_x = ctx->x = ctx->x + dx; + ctx->first_y = ctx->y = ctx->y + dy; + stbtt__csctx_v(ctx, STBTT_vmove, (int)ctx->x, (int)ctx->y, 0, 0, 0, 0); +} + +static void stbtt__csctx_rline_to(stbtt__csctx *ctx, float dx, float dy) +{ + ctx->x += dx; + ctx->y += dy; + stbtt__csctx_v(ctx, STBTT_vline, (int)ctx->x, (int)ctx->y, 0, 0, 0, 0); +} + +static void stbtt__csctx_rccurve_to(stbtt__csctx *ctx, float dx1, float dy1, float dx2, float dy2, float dx3, float dy3) +{ + float cx1 = ctx->x + dx1; + float cy1 = ctx->y + dy1; + float cx2 = cx1 + dx2; + float cy2 = cy1 + dy2; + ctx->x = cx2 + dx3; + ctx->y = cy2 + dy3; + stbtt__csctx_v(ctx, STBTT_vcubic, (int)ctx->x, (int)ctx->y, (int)cx1, (int)cy1, (int)cx2, (int)cy2); +} + +static stbtt__buf stbtt__get_subr(stbtt__buf idx, int n) +{ + int count = stbtt__cff_index_count(&idx); + int bias = 107; + if (count >= 33900) + bias = 32768; + else if (count >= 1240) + bias = 1131; + n += bias; + if (n < 0 || n >= count) + return stbtt__new_buf(NULL, 0); + return stbtt__cff_index_get(idx, n); +} + +static stbtt__buf stbtt__cid_get_glyph_subrs(const stbtt_fontinfo *info, int glyph_index) +{ + stbtt__buf fdselect = info->fdselect; + int nranges, start, end, v, fmt, fdselector = -1, i; + + stbtt__buf_seek(&fdselect, 0); + fmt = stbtt__buf_get8(&fdselect); + if (fmt == 0) { + // untested + stbtt__buf_skip(&fdselect, glyph_index); + fdselector = stbtt__buf_get8(&fdselect); + } else if (fmt == 3) { + nranges = stbtt__buf_get16(&fdselect); + start = stbtt__buf_get16(&fdselect); + for (i = 0; i < nranges; i++) { + v = stbtt__buf_get8(&fdselect); + end = stbtt__buf_get16(&fdselect); + if (glyph_index >= start && glyph_index < end) { + fdselector = v; + break; + } + start = end; + } + } + if (fdselector == -1) stbtt__new_buf(NULL, 0); + return stbtt__get_subrs(info->cff, stbtt__cff_index_get(info->fontdicts, fdselector)); +} + +static int stbtt__run_charstring(const stbtt_fontinfo *info, int glyph_index, stbtt__csctx *c) +{ + int in_header = 1, maskbits = 0, subr_stack_height = 0, sp = 0, v, i, b0; + int has_subrs = 0, clear_stack; + float s[48]; + stbtt__buf subr_stack[10], subrs = info->subrs, b; + float f; + +#define STBTT__CSERR(s) (0) + + // this currently ignores the initial width value, which isn't needed if we have hmtx + b = stbtt__cff_index_get(info->charstrings, glyph_index); + while (b.cursor < b.size) { + i = 0; + clear_stack = 1; + b0 = stbtt__buf_get8(&b); + switch (b0) { + // @TODO implement hinting + case 0x13: // hintmask + case 0x14: // cntrmask + if (in_header) + maskbits += (sp / 2); // implicit "vstem" + in_header = 0; + stbtt__buf_skip(&b, (maskbits + 7) / 8); + break; + + case 0x01: // hstem + case 0x03: // vstem + case 0x12: // hstemhm + case 0x17: // vstemhm + maskbits += (sp / 2); + break; + + case 0x15: // rmoveto + in_header = 0; + if (sp < 2) return STBTT__CSERR("rmoveto stack"); + stbtt__csctx_rmove_to(c, s[sp-2], s[sp-1]); + break; + case 0x04: // vmoveto + in_header = 0; + if (sp < 1) return STBTT__CSERR("vmoveto stack"); + stbtt__csctx_rmove_to(c, 0, s[sp-1]); + break; + case 0x16: // hmoveto + in_header = 0; + if (sp < 1) return STBTT__CSERR("hmoveto stack"); + stbtt__csctx_rmove_to(c, s[sp-1], 0); + break; + + case 0x05: // rlineto + if (sp < 2) return STBTT__CSERR("rlineto stack"); + for (; i + 1 < sp; i += 2) + stbtt__csctx_rline_to(c, s[i], s[i+1]); + break; + + // hlineto/vlineto and vhcurveto/hvcurveto alternate horizontal and vertical + // starting from a different place. + + case 0x07: // vlineto + if (sp < 1) return STBTT__CSERR("vlineto stack"); + goto vlineto; + case 0x06: // hlineto + if (sp < 1) return STBTT__CSERR("hlineto stack"); + for (;;) { + if (i >= sp) break; + stbtt__csctx_rline_to(c, s[i], 0); + i++; + vlineto: + if (i >= sp) break; + stbtt__csctx_rline_to(c, 0, s[i]); + i++; + } + break; + + case 0x1F: // hvcurveto + if (sp < 4) return STBTT__CSERR("hvcurveto stack"); + goto hvcurveto; + case 0x1E: // vhcurveto + if (sp < 4) return STBTT__CSERR("vhcurveto stack"); + for (;;) { + if (i + 3 >= sp) break; + stbtt__csctx_rccurve_to(c, 0, s[i], s[i+1], s[i+2], s[i+3], (sp - i == 5) ? s[i + 4] : 0.0f); + i += 4; + hvcurveto: + if (i + 3 >= sp) break; + stbtt__csctx_rccurve_to(c, s[i], 0, s[i+1], s[i+2], (sp - i == 5) ? s[i+4] : 0.0f, s[i+3]); + i += 4; + } + break; + + case 0x08: // rrcurveto + if (sp < 6) return STBTT__CSERR("rcurveline stack"); + for (; i + 5 < sp; i += 6) + stbtt__csctx_rccurve_to(c, s[i], s[i+1], s[i+2], s[i+3], s[i+4], s[i+5]); + break; + + case 0x18: // rcurveline + if (sp < 8) return STBTT__CSERR("rcurveline stack"); + for (; i + 5 < sp - 2; i += 6) + stbtt__csctx_rccurve_to(c, s[i], s[i+1], s[i+2], s[i+3], s[i+4], s[i+5]); + if (i + 1 >= sp) return STBTT__CSERR("rcurveline stack"); + stbtt__csctx_rline_to(c, s[i], s[i+1]); + break; + + case 0x19: // rlinecurve + if (sp < 8) return STBTT__CSERR("rlinecurve stack"); + for (; i + 1 < sp - 6; i += 2) + stbtt__csctx_rline_to(c, s[i], s[i+1]); + if (i + 5 >= sp) return STBTT__CSERR("rlinecurve stack"); + stbtt__csctx_rccurve_to(c, s[i], s[i+1], s[i+2], s[i+3], s[i+4], s[i+5]); + break; + + case 0x1A: // vvcurveto + case 0x1B: // hhcurveto + if (sp < 4) return STBTT__CSERR("(vv|hh)curveto stack"); + f = 0.0; + if (sp & 1) { f = s[i]; i++; } + for (; i + 3 < sp; i += 4) { + if (b0 == 0x1B) + stbtt__csctx_rccurve_to(c, s[i], f, s[i+1], s[i+2], s[i+3], 0.0); + else + stbtt__csctx_rccurve_to(c, f, s[i], s[i+1], s[i+2], 0.0, s[i+3]); + f = 0.0; + } + break; + + case 0x0A: // callsubr + if (!has_subrs) { + if (info->fdselect.size) + subrs = stbtt__cid_get_glyph_subrs(info, glyph_index); + has_subrs = 1; + } + // fallthrough + case 0x1D: // callgsubr + if (sp < 1) return STBTT__CSERR("call(g|)subr stack"); + v = (int) s[--sp]; + if (subr_stack_height >= 10) return STBTT__CSERR("recursion limit"); + subr_stack[subr_stack_height++] = b; + b = stbtt__get_subr(b0 == 0x0A ? subrs : info->gsubrs, v); + if (b.size == 0) return STBTT__CSERR("subr not found"); + b.cursor = 0; + clear_stack = 0; + break; + + case 0x0B: // return + if (subr_stack_height <= 0) return STBTT__CSERR("return outside subr"); + b = subr_stack[--subr_stack_height]; + clear_stack = 0; + break; + + case 0x0E: // endchar + stbtt__csctx_close_shape(c); + return 1; + + case 0x0C: { // two-byte escape + float dx1, dx2, dx3, dx4, dx5, dx6, dy1, dy2, dy3, dy4, dy5, dy6; + float dx, dy; + int b1 = stbtt__buf_get8(&b); + switch (b1) { + // @TODO These "flex" implementations ignore the flex-depth and resolution, + // and always draw beziers. + case 0x22: // hflex + if (sp < 7) return STBTT__CSERR("hflex stack"); + dx1 = s[0]; + dx2 = s[1]; + dy2 = s[2]; + dx3 = s[3]; + dx4 = s[4]; + dx5 = s[5]; + dx6 = s[6]; + stbtt__csctx_rccurve_to(c, dx1, 0, dx2, dy2, dx3, 0); + stbtt__csctx_rccurve_to(c, dx4, 0, dx5, -dy2, dx6, 0); + break; + + case 0x23: // flex + if (sp < 13) return STBTT__CSERR("flex stack"); + dx1 = s[0]; + dy1 = s[1]; + dx2 = s[2]; + dy2 = s[3]; + dx3 = s[4]; + dy3 = s[5]; + dx4 = s[6]; + dy4 = s[7]; + dx5 = s[8]; + dy5 = s[9]; + dx6 = s[10]; + dy6 = s[11]; + //fd is s[12] + stbtt__csctx_rccurve_to(c, dx1, dy1, dx2, dy2, dx3, dy3); + stbtt__csctx_rccurve_to(c, dx4, dy4, dx5, dy5, dx6, dy6); + break; + + case 0x24: // hflex1 + if (sp < 9) return STBTT__CSERR("hflex1 stack"); + dx1 = s[0]; + dy1 = s[1]; + dx2 = s[2]; + dy2 = s[3]; + dx3 = s[4]; + dx4 = s[5]; + dx5 = s[6]; + dy5 = s[7]; + dx6 = s[8]; + stbtt__csctx_rccurve_to(c, dx1, dy1, dx2, dy2, dx3, 0); + stbtt__csctx_rccurve_to(c, dx4, 0, dx5, dy5, dx6, -(dy1+dy2+dy5)); + break; + + case 0x25: // flex1 + if (sp < 11) return STBTT__CSERR("flex1 stack"); + dx1 = s[0]; + dy1 = s[1]; + dx2 = s[2]; + dy2 = s[3]; + dx3 = s[4]; + dy3 = s[5]; + dx4 = s[6]; + dy4 = s[7]; + dx5 = s[8]; + dy5 = s[9]; + dx6 = dy6 = s[10]; + dx = dx1+dx2+dx3+dx4+dx5; + dy = dy1+dy2+dy3+dy4+dy5; + if (STBTT_fabs(dx) > STBTT_fabs(dy)) + dy6 = -dy; + else + dx6 = -dx; + stbtt__csctx_rccurve_to(c, dx1, dy1, dx2, dy2, dx3, dy3); + stbtt__csctx_rccurve_to(c, dx4, dy4, dx5, dy5, dx6, dy6); + break; + + default: + return STBTT__CSERR("unimplemented"); + } + } break; + + default: + if (b0 != 255 && b0 != 28 && (b0 < 32 || b0 > 254)) + return STBTT__CSERR("reserved operator"); + + // push immediate + if (b0 == 255) { + f = (float)stbtt__buf_get32(&b) / 0x10000; + } else { + stbtt__buf_skip(&b, -1); + f = (float)(stbtt_int16)stbtt__cff_int(&b); + } + if (sp >= 48) return STBTT__CSERR("push stack overflow"); + s[sp++] = f; + clear_stack = 0; + break; + } + if (clear_stack) sp = 0; + } + return STBTT__CSERR("no endchar"); + +#undef STBTT__CSERR +} + +static int stbtt__GetGlyphShapeT2(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **pvertices) +{ + // runs the charstring twice, once to count and once to output (to avoid realloc) + stbtt__csctx count_ctx = STBTT__CSCTX_INIT(1); + stbtt__csctx output_ctx = STBTT__CSCTX_INIT(0); + if (stbtt__run_charstring(info, glyph_index, &count_ctx)) { + *pvertices = (stbtt_vertex*)STBTT_malloc(count_ctx.num_vertices*sizeof(stbtt_vertex), info->userdata); + output_ctx.pvertices = *pvertices; + if (stbtt__run_charstring(info, glyph_index, &output_ctx)) { + STBTT_assert(output_ctx.num_vertices == count_ctx.num_vertices); + return output_ctx.num_vertices; + } + } + *pvertices = NULL; + return 0; +} + +static int stbtt__GetGlyphInfoT2(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1) +{ + stbtt__csctx c = STBTT__CSCTX_INIT(1); + int r = stbtt__run_charstring(info, glyph_index, &c); + if (x0) { + *x0 = r ? c.min_x : 0; + *y0 = r ? c.min_y : 0; + *x1 = r ? c.max_x : 0; + *y1 = r ? c.max_y : 0; + } + return r ? c.num_vertices : 0; +} + +STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **pvertices) +{ + if (!info->cff.size) + return stbtt__GetGlyphShapeTT(info, glyph_index, pvertices); + else + return stbtt__GetGlyphShapeT2(info, glyph_index, pvertices); +} + STBTT_DEF void stbtt_GetGlyphHMetrics(const stbtt_fontinfo *info, int glyph_index, int *advanceWidth, int *leftSideBearing) { stbtt_uint16 numOfLongHorMetrics = ttUSHORT(info->data+info->hhea + 34); @@ -2333,6 +3009,48 @@ static int stbtt__tesselate_curve(stbtt__point *points, int *num_points, float x return 1; } +static void stbtt__tesselate_cubic(stbtt__point *points, int *num_points, float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3, float objspace_flatness_squared, int n) +{ + // @TODO this "flatness" calculation is just made-up nonsense that seems to work well enough + float dx0 = x1-x0; + float dy0 = y1-y0; + float dx1 = x2-x1; + float dy1 = y2-y1; + float dx2 = x3-x2; + float dy2 = y3-y2; + float dx = x3-x0; + float dy = y3-y0; + float longlen = (float) (STBTT_sqrt(dx0*dx0+dy0*dy0)+STBTT_sqrt(dx1*dx1+dy1*dy1)+STBTT_sqrt(dx2*dx2+dy2*dy2)); + float shortlen = (float) STBTT_sqrt(dx*dx+dy*dy); + float flatness_squared = longlen*longlen-shortlen*shortlen; + + if (n > 16) // 65536 segments on one curve better be enough! + return; + + if (flatness_squared > objspace_flatness_squared) { + float x01 = (x0+x1)/2; + float y01 = (y0+y1)/2; + float x12 = (x1+x2)/2; + float y12 = (y1+y2)/2; + float x23 = (x2+x3)/2; + float y23 = (y2+y3)/2; + + float xa = (x01+x12)/2; + float ya = (y01+y12)/2; + float xb = (x12+x23)/2; + float yb = (y12+y23)/2; + + float mx = (xa+xb)/2; + float my = (ya+yb)/2; + + stbtt__tesselate_cubic(points, num_points, x0,y0, x01,y01, xa,ya, mx,my, objspace_flatness_squared,n+1); + stbtt__tesselate_cubic(points, num_points, mx,my, xb,yb, x23,y23, x3,y3, objspace_flatness_squared,n+1); + } else { + stbtt__add_point(points, *num_points,x3,y3); + *num_points = *num_points+1; + } +} + // returns number of contours static stbtt__point *stbtt_FlattenCurves(stbtt_vertex *vertices, int num_verts, float objspace_flatness, int **contour_lengths, int *num_contours, void *userdata) { @@ -2389,6 +3107,14 @@ static stbtt__point *stbtt_FlattenCurves(stbtt_vertex *vertices, int num_verts, objspace_flatness_squared, 0); x = vertices[i].x, y = vertices[i].y; break; + case STBTT_vcubic: + stbtt__tesselate_cubic(points, &num_points, x,y, + vertices[i].cx, vertices[i].cy, + vertices[i].cx1, vertices[i].cy1, + vertices[i].x, vertices[i].y, + objspace_flatness_squared, 0); + x = vertices[i].x, y = vertices[i].y; + break; } } (*contour_lengths)[n] = num_points - start; @@ -3214,6 +3940,11 @@ STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char *data, int index) return stbtt_GetFontOffsetForIndex_internal((unsigned char *) data, index); } +STBTT_DEF int stbtt_GetNumberOfFonts(const unsigned char *data) +{ + return stbtt_GetNumberOfFonts_internal((unsigned char *) data); +} + STBTT_DEF int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data, int offset) { return stbtt_InitFont_internal(info, (unsigned char *) data, offset); From a7cf369e71e0911773e8c43d7c565eb3c0386c4d Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 28 Jan 2017 23:14:35 +0100 Subject: [PATCH 011/921] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 9c352696b..c1068990e 100644 --- a/README.md +++ b/README.md @@ -84,12 +84,12 @@ Gallery See the [Screenshots Thread](https://github.com/ocornut/imgui/issues/123) for some user creations. ![screenshot 1](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v148/examples_01.png) +[![screenshot game](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v149/gallery_TheDragonsTrap-01-thumb.jpg)](https://cloud.githubusercontent.com/assets/8225057/20628927/33e14cac-b329-11e6-80f6-9524e93b048a.png) ![screenshot 2](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v148/examples_02.png) -[![profiler](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v148/profiler-880.jpg)](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v148/profiler.png) +[![screenshot profiler](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v148/profiler-880.jpg)](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v148/profiler.png) -![screenshot 2](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v143/test_window_01.png) -![screenshot 3](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v143/test_window_02.png) +![screenshot 3](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v143/test_window_01.png) ![screenshot 4](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v143/test_window_03.png) ![screenshot 5](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v140/test_window_05_menus.png) ![screenshot 6](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v143/skinning_sample_02.png) From 4653197ca43a0b4302ac9b94b82d6e2c19f3e39a Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 28 Jan 2017 23:26:25 +0100 Subject: [PATCH 012/921] Update README, kinder --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c1068990e..68d57ee7e 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ Your code passes mouse/keyboard inputs and settings to ImGui (see example applic ImGui outputs vertex buffers and simple command-lists that you can render in your application. The number of draw calls and state changes is typically very small. Because it doesn't know or touch graphics state directly, you can call ImGui commands anywhere in your code (e.g. in the middle of a running algorithm, or in the middle of your own rendering process). Refer to the sample applications in the examples/ folder for instructions on how to integrate ImGui with your existing codebase. -_A common misunderstanding is that some people think immediate mode gui == immediate mode rendering, which usually implies hammering your driver/GPU with a bunch of inefficient draw calls and state changes, as the gui functions as called by the user. Some lazy IMGUI-style librairies may work this way but this is NOT what Dear ImGui does. Dear ImGui outputs vertex buffers and a small list of draw calls batches. It never touches your GPU directly. The draw call batches are rather optimal and you can render them later, in your app or even remotely._ +_A common misunderstanding is to think that immediate mode gui == immediate mode rendering, which usually implies hammering your driver/GPU with a bunch of inefficient draw calls and state changes, as the gui functions as called by the user. This is NOT what Dear ImGui does. Dear ImGui outputs vertex buffers and a small list of draw calls batches. It never touches your GPU directly. The draw call batches are decently optimal and you can render them later, in your app or even remotely._ ImGui allows you create elaborate tools as well as very short-lived ones. On the extreme side of short-liveness: using the Edit&Continue feature of modern compilers you can add a few widgets to tweaks variables while your application is running, and remove the code a minute later! ImGui is not just for tweaking values. You can use it to trace a running algorithm by just emitting text commands. You can use it along with your own reflection data to browse your dataset live. You can use it to expose the internals of a subsystem in your engine, to create a logger, an inspection tool, a profiler, a debugger, etc. @@ -46,7 +46,9 @@ You should be able to build the examples from sources (tested on Windows/Mac/Lin Bindings -------- -_NB: those third-party bindings may be more or less maintained, more or less close to the spirit of original API. People who create language bindings sometimes haven't used the C++ API themselves. ImGui was designed with C++ in mind and some of the subtleties may be lost in translation with other languages. If your language supports it, I would suggest replicating the function overloading and default parameters used in the original, else the API may be harder to use. In doubt, always check the original C++ version first!_ +_NB: those third-party bindings may be more or less maintained, more or less close to the spirit of original API and therefore I cannot give much guarantee about them. People who create language bindings sometimes haven't used the C++ API themselves (for the good reason that they aren't C++ users). ImGui was designed with C++ in mind and some of the subtleties may be lost in translation with other languages. If your language supports it, I would suggest replicating the function overloading and default parameters used in the original, else the API may be harder to use. In doubt, please check the original C++ version first!_ + +_Integrating Dear ImGui within your custom engine is a matter of wiring mouse/keyboard inputs and providing a render function that can bind a texture and render simple textured triangles. The examples/ folder is populated with applications doing just that. If you are an experienced programmer it should take you less than an hour to integrate Dear ImGui in your custom engine, but make sure to spend time reading the FAQ, the comments and other documentation!_ Languages: - cimgui: thin c-api wrapper for ImGui https://github.com/Extrawurst/cimgui From 6384eee34f08cb7eab8d835043e1738e4adcdf75 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 29 Jan 2017 16:52:52 +0100 Subject: [PATCH 013/921] Minor comments (#998) --- imgui.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.h b/imgui.h index 9d84a94fe..2d79df009 100644 --- a/imgui.h +++ b/imgui.h @@ -118,7 +118,7 @@ namespace ImGui IMGUI_API void ShowUserGuide(); // help block IMGUI_API void ShowStyleEditor(ImGuiStyle* ref = NULL); // style editor block. you can pass in a reference ImGuiStyle structure to compare to, revert to and save to (else it uses the default style) IMGUI_API void ShowTestWindow(bool* p_open = NULL); // test window demonstrating ImGui features - IMGUI_API void ShowMetricsWindow(bool* p_open = NULL); // metrics window for debugging ImGui + IMGUI_API void ShowMetricsWindow(bool* p_open = NULL); // metrics window for debugging ImGui (browse draw commands, individual vertices, window list, etc.) // Window IMGUI_API bool Begin(const char* name, bool* p_open = NULL, ImGuiWindowFlags flags = 0); // push window to the stack and start appending to it. see .cpp for details. return false when window is collapsed, so you can early out in your code. 'bool* p_open' creates a widget on the upper-right to close the window (which sets your bool to false). From 509df3e2790f9fb6162d9cb2a4f2f3dd6465fdb8 Mon Sep 17 00:00:00 2001 From: Marcell Kiss Date: Sat, 11 Feb 2017 12:08:59 +0100 Subject: [PATCH 014/921] Fix new Vulkan validation warnings --- examples/vulkan_example/imgui_impl_glfw_vulkan.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp b/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp index ef9da8954..6ac4e4c06 100644 --- a/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp +++ b/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp @@ -236,10 +236,10 @@ void ImGui_ImplGlfwVulkan_RenderDrawLists(ImDrawData* draw_data) VkMappedMemoryRange range[2] = {}; range[0].sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; range[0].memory = g_VertexBufferMemory[g_FrameIndex]; - range[0].size = vertex_size; + range[0].size = VK_WHOLE_SIZE; range[1].sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; range[1].memory = g_IndexBufferMemory[g_FrameIndex]; - range[1].size = index_size; + range[1].size = VK_WHOLE_SIZE; err = vkFlushMappedMemoryRanges(g_Device, 2, range); ImGui_ImplGlfwVulkan_VkResult(err); vkUnmapMemory(g_Device, g_VertexBufferMemory[g_FrameIndex]); @@ -483,6 +483,7 @@ bool ImGui_ImplGlfwVulkan_CreateFontsTexture(VkCommandBuffer command_buffer) region.imageSubresource.layerCount = 1; region.imageExtent.width = width; region.imageExtent.height = height; + region.imageExtent.depth = 1; vkCmdCopyBufferToImage(command_buffer, g_UploadBuffer, g_FontImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); VkImageMemoryBarrier use_barrier[1] = {}; From e0244c8f62f5d74d321bc45f8d51e002f926a988 Mon Sep 17 00:00:00 2001 From: Marcell Kiss Date: Sat, 11 Feb 2017 12:09:31 +0100 Subject: [PATCH 015/921] Fix scissor offset being negative --- examples/vulkan_example/imgui_impl_glfw_vulkan.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp b/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp index 6ac4e4c06..29aed598e 100644 --- a/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp +++ b/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp @@ -301,8 +301,8 @@ void ImGui_ImplGlfwVulkan_RenderDrawLists(ImDrawData* draw_data) else { VkRect2D scissor; - scissor.offset.x = (int32_t)(pcmd->ClipRect.x); - scissor.offset.y = (int32_t)(pcmd->ClipRect.y); + scissor.offset.x = (int32_t)(pcmd->ClipRect.x) > 0 ? (int32_t)(pcmd->ClipRect.x) : 0; // clamp these to 0, scissor offset.xy must be > 0 + scissor.offset.y = (int32_t)(pcmd->ClipRect.y) > 0 ? (int32_t)(pcmd->ClipRect.y) : 0; scissor.extent.width = (uint32_t)(pcmd->ClipRect.z - pcmd->ClipRect.x); scissor.extent.height = (uint32_t)(pcmd->ClipRect.w - pcmd->ClipRect.y + 1); // TODO: + 1?????? vkCmdSetScissor(g_CommandBuffer, 0, 1, &scissor); From fd90da38e16d04828f99998237d99681e52d1212 Mon Sep 17 00:00:00 2001 From: Peter Particle Date: Sun, 26 Feb 2017 13:25:54 +0100 Subject: [PATCH 016/921] Vulkan backend: g_FrameIndex not used fix -> huge perf gain Added a macro to switch between unlimited frame rate (VK_PRESENT_MODE_IMMEDIATE_KHR) and limited to 60 fps (VK_PRESENT_MODE_FIFO_KHR). Only the latter mode is guaranteed to be available, but the former one most likely is. --- examples/vulkan_example/main.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/examples/vulkan_example/main.cpp b/examples/vulkan_example/main.cpp index 8116e08c2..265ec803a 100644 --- a/examples/vulkan_example/main.cpp +++ b/examples/vulkan_example/main.cpp @@ -12,6 +12,7 @@ #include "imgui_impl_glfw_vulkan.h" #define IMGUI_MAX_POSSIBLE_BACK_BUFFERS 16 +#define IMGUI_UNLIMITED_FRAME_RATE static VkAllocationCallbacks* g_Allocator = NULL; static VkInstance g_Instance = VK_NULL_HANDLE; @@ -83,7 +84,12 @@ static void resize_vulkan(GLFWwindow* /*window*/, int w, int h) info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; info.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; info.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; + +#ifdef IMGUI_UNLIMITED_FRAME_RATE + info.presentMode = VK_PRESENT_MODE_IMMEDIATE_KHR; +#elif info.presentMode = VK_PRESENT_MODE_FIFO_KHR; +#endif info.clipped = VK_TRUE; info.oldSwapchain = old_swapchain; VkSurfaceCapabilitiesKHR cap; @@ -93,6 +99,7 @@ static void resize_vulkan(GLFWwindow* /*window*/, int w, int h) info.minImageCount = (cap.minImageCount + 2 < cap.maxImageCount) ? (cap.minImageCount + 2) : cap.maxImageCount; else info.minImageCount = cap.minImageCount + 2; + if (cap.currentExtent.width == 0xffffffff) { fb_width = w; @@ -462,7 +469,7 @@ static void frame_end() check_vk_result(err); check_vk_result(res); } - g_FrameIndex = (g_FrameIndex) % IMGUI_VK_QUEUED_FRAMES; + g_FrameIndex = (g_FrameIndex+1) % IMGUI_VK_QUEUED_FRAMES; } static void error_callback(int error, const char* description) From 337019a68f4ee1d1cc1fc9e023d07b0cbe04d505 Mon Sep 17 00:00:00 2001 From: Peter Particle Date: Sun, 26 Feb 2017 17:16:37 +0100 Subject: [PATCH 017/921] typo, #elif instead of #else, fixed --- examples/vulkan_example/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/vulkan_example/main.cpp b/examples/vulkan_example/main.cpp index 265ec803a..9e7455c35 100644 --- a/examples/vulkan_example/main.cpp +++ b/examples/vulkan_example/main.cpp @@ -87,7 +87,7 @@ static void resize_vulkan(GLFWwindow* /*window*/, int w, int h) #ifdef IMGUI_UNLIMITED_FRAME_RATE info.presentMode = VK_PRESENT_MODE_IMMEDIATE_KHR; -#elif +#else info.presentMode = VK_PRESENT_MODE_FIFO_KHR; #endif info.clipped = VK_TRUE; From fdd11658ebe9afd4336ffa9ff59e40d0633cbdaf Mon Sep 17 00:00:00 2001 From: Codecat Date: Wed, 15 Mar 2017 21:25:29 +0100 Subject: [PATCH 018/921] Fix ColorButton showing wrong hex value for alpha --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index cd1c12010..3c636d39b 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -8973,7 +8973,7 @@ bool ImGui::ColorButton(const ImVec4& col, bool small_height, bool outline_borde RenderFrame(bb.Min, bb.Max, GetColorU32(col), outline_border, style.FrameRounding); if (hovered) - SetTooltip("Color:\n(%.2f,%.2f,%.2f,%.2f)\n#%02X%02X%02X%02X", col.x, col.y, col.z, col.w, IM_F32_TO_INT8_SAT(col.x), IM_F32_TO_INT8_SAT(col.y), IM_F32_TO_INT8_SAT(col.z), IM_F32_TO_INT8_SAT(col.z)); + SetTooltip("Color:\n(%.2f,%.2f,%.2f,%.2f)\n#%02X%02X%02X%02X", col.x, col.y, col.z, col.w, IM_F32_TO_INT8_SAT(col.x), IM_F32_TO_INT8_SAT(col.y), IM_F32_TO_INT8_SAT(col.z), IM_F32_TO_INT8_SAT(col.w)); return pressed; } From 931bc6134534cbc01701e6d20d09cfd074a584e4 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 16 Mar 2017 21:55:36 +0100 Subject: [PATCH 019/921] Comment about ImGuiInputTextFlags_CtrlEnterForNewLine for InputTextMultiline() --- imgui.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.h b/imgui.h index 2d79df009..d6100cd28 100644 --- a/imgui.h +++ b/imgui.h @@ -521,7 +521,7 @@ enum ImGuiInputTextFlags_ ImGuiInputTextFlags_CallbackAlways = 1 << 8, // Call user function every time. User code may query cursor position, modify text buffer. ImGuiInputTextFlags_CallbackCharFilter = 1 << 9, // Call user function to filter character. Modify data->EventChar to replace/filter input, or return 1 to discard character. ImGuiInputTextFlags_AllowTabInput = 1 << 10, // Pressing TAB input a '\t' character into the text field - ImGuiInputTextFlags_CtrlEnterForNewLine = 1 << 11, // In multi-line mode, allow exiting edition by pressing Enter. Ctrl+Enter to add new line (by default adds new lines with Enter). + ImGuiInputTextFlags_CtrlEnterForNewLine = 1 << 11, // In multi-line mode, unfocus with Enter, add new line with Ctrl+Enter (default is opposite: unfocus with Ctrl+Enter, add line with Enter). ImGuiInputTextFlags_NoHorizontalScroll = 1 << 12, // Disable following the cursor horizontally ImGuiInputTextFlags_AlwaysInsertMode = 1 << 13, // Insert mode ImGuiInputTextFlags_ReadOnly = 1 << 14, // Read-only mode From b84eac53d884e773749cb76ed3e33b47f8c6b12e Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 17 Mar 2017 21:29:28 +0100 Subject: [PATCH 020/921] ImFont: Reorder field initialization to match declaration order --- imgui_draw.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 03b679d02..b6188ce8d 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1694,15 +1694,15 @@ void ImFont::Clear() { FontSize = 0.0f; DisplayOffset = ImVec2(0.0f, 1.0f); - ConfigData = NULL; - ConfigDataCount = 0; - Ascent = Descent = 0.0f; - ContainerAtlas = NULL; Glyphs.clear(); - FallbackGlyph = NULL; - FallbackXAdvance = 0.0f; IndexXAdvance.clear(); IndexLookup.clear(); + FallbackGlyph = NULL; + FallbackXAdvance = 0.0f; + ConfigDataCount = 0; + ConfigData = NULL; + ContainerAtlas = NULL; + Ascent = Descent = 0.0f; } void ImFont::BuildLookupTable() From e10ceebd36e4333c3da6f0c2250204e136a98241 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 17 Mar 2017 21:29:57 +0100 Subject: [PATCH 021/921] ImFont: Store the texture surface used to get an idea of how costly each font is. --- imgui.h | 1 + imgui_demo.cpp | 3 ++- imgui_draw.cpp | 5 ++++- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/imgui.h b/imgui.h index d6100cd28..358869869 100644 --- a/imgui.h +++ b/imgui.h @@ -1367,6 +1367,7 @@ struct ImFont ImFontConfig* ConfigData; // // Pointer within ContainerAtlas->ConfigData ImFontAtlas* ContainerAtlas; // // What we has been loaded into float Ascent, Descent; // // Ascent: distance from top to bottom of e.g. 'A' [0..FontSize] + int MetricsTotalSurface;// // Total surface in pixels to get an idea of the font rasterization/texture cost (not exact, we approximate the cost of padding between glyphs) // Methods IMGUI_API ImFont(); diff --git a/imgui_demo.cpp b/imgui_demo.cpp index dda0a53db..58f7a7957 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1750,10 +1750,11 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) ImGui::SameLine(); ShowHelpMarker("Note than the default embedded font is NOT meant to be scaled.\n\nFont are currently rendered into bitmaps at a given size at the time of building the atlas. You may oversample them to get some flexibility with scaling. You can also render at multiple sizes and select which one to use at runtime.\n\n(Glimmer of hope: the atlas system should hopefully be rewritten in the future to make scaling more natural and automatic.)"); ImGui::Text("Ascent: %f, Descent: %f, Height: %f", font->Ascent, font->Descent, font->Ascent - font->Descent); ImGui::Text("Fallback character: '%c' (%d)", font->FallbackChar, font->FallbackChar); + ImGui::Text("Texture surface: %d pixels (approx)", font->MetricsTotalSurface); for (int config_i = 0; config_i < font->ConfigDataCount; config_i++) { ImFontConfig* cfg = &font->ConfigData[config_i]; - ImGui::BulletText("Input %d: \'%s\'\nOversample: (%d,%d), PixelSnapH: %d", config_i, cfg->Name, cfg->OversampleH, cfg->OversampleV, cfg->PixelSnapH); + ImGui::BulletText("Input %d: \'%s\', Oversample: (%d,%d), PixelSnapH: %d", config_i, cfg->Name, cfg->OversampleH, cfg->OversampleV, cfg->PixelSnapH); } if (ImGui::TreeNode("Glyphs", "Glyphs (%d)", font->Glyphs.Size)) { diff --git a/imgui_draw.cpp b/imgui_draw.cpp index b6188ce8d..1b2e9e0c2 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1386,7 +1386,7 @@ bool ImFontAtlas::Build() { ImFontConfig& cfg = ConfigData[input_i]; ImFontTempBuildData& tmp = tmp_array[input_i]; - ImFont* dst_font = cfg.DstFont; + ImFont* dst_font = cfg.DstFont; // We can have multiple input fonts writing into a same destination font (when using MergeMode=true) float font_scale = stbtt_ScaleForPixelHeight(&tmp.FontInfo, cfg.SizePixels); int unscaled_ascent, unscaled_descent, unscaled_line_gap; @@ -1403,6 +1403,7 @@ bool ImFontAtlas::Build() dst_font->Ascent = ascent; dst_font->Descent = descent; dst_font->Glyphs.resize(0); + dst_font->MetricsTotalSurface = 0; } dst_font->ConfigDataCount++; float off_y = (cfg.MergeMode && cfg.MergeGlyphCenterV) ? (ascent - dst_font->Ascent) * 0.5f : 0.0f; @@ -1435,6 +1436,7 @@ bool ImFontAtlas::Build() glyph.XAdvance = (pc.xadvance + cfg.GlyphExtraSpacing.x); // Bake spacing into XAdvance if (cfg.PixelSnapH) glyph.XAdvance = (float)(int)(glyph.XAdvance + 0.5f); + dst_font->MetricsTotalSurface += (int)(glyph.X1 - glyph.X0 + 1.99f) * (int)(glyph.Y1 - glyph.Y0 + 1.99f); // +1 to account for average padding, +0.99 to round } } cfg.DstFont->BuildLookupTable(); @@ -1703,6 +1705,7 @@ void ImFont::Clear() ConfigData = NULL; ContainerAtlas = NULL; Ascent = Descent = 0.0f; + MetricsTotalSurface = 0; } void ImFont::BuildLookupTable() From 316555f9de52aebe7741090e26618e0b69fae657 Mon Sep 17 00:00:00 2001 From: Mikulas Florek Date: Fri, 24 Mar 2017 10:10:22 +0100 Subject: [PATCH 022/921] missing API --- imgui.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/imgui.h b/imgui.h index 358869869..50cf71df6 100644 --- a/imgui.h +++ b/imgui.h @@ -1020,9 +1020,9 @@ struct ImGuiTextEditCallbackData int SelectionEnd; // // Read-write // NB: Helper functions for text manipulation. Calling those function loses selection. - void DeleteChars(int pos, int bytes_count); - void InsertChars(int pos, const char* text, const char* text_end = NULL); - bool HasSelection() const { return SelectionStart != SelectionEnd; } + IMGUI_API void DeleteChars(int pos, int bytes_count); + IMGUI_API void InsertChars(int pos, const char* text, const char* text_end = NULL); + IMGUI_API bool HasSelection() const { return SelectionStart != SelectionEnd; } }; // Resizing callback data to apply custom constraint. As enabled by SetNextWindowSizeConstraints(). Callback is called during the next Begin(). From 7a37a1c3f6ea14209bbcc5030a68e0bde0e375e6 Mon Sep 17 00:00:00 2001 From: Mikulas Florek Date: Fri, 24 Mar 2017 12:45:09 +0100 Subject: [PATCH 023/921] do not export inline function, it causes problems on some compiers --- imgui.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.h b/imgui.h index 50cf71df6..bf6871786 100644 --- a/imgui.h +++ b/imgui.h @@ -1022,7 +1022,7 @@ struct ImGuiTextEditCallbackData // NB: Helper functions for text manipulation. Calling those function loses selection. IMGUI_API void DeleteChars(int pos, int bytes_count); IMGUI_API void InsertChars(int pos, const char* text, const char* text_end = NULL); - IMGUI_API bool HasSelection() const { return SelectionStart != SelectionEnd; } + bool HasSelection() const { return SelectionStart != SelectionEnd; } }; // Resizing callback data to apply custom constraint. As enabled by SetNextWindowSizeConstraints(). Callback is called during the next Begin(). From 12deb53b11eeb3f74ed1ff86ae91ca15345781d9 Mon Sep 17 00:00:00 2001 From: saschawillems Date: Sun, 26 Mar 2017 19:38:05 +0200 Subject: [PATCH 024/921] Set required depth member for buffer image copy --- examples/vulkan_example/imgui_impl_glfw_vulkan.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp b/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp index ef9da8954..72fa5bc88 100644 --- a/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp +++ b/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp @@ -483,6 +483,7 @@ bool ImGui_ImplGlfwVulkan_CreateFontsTexture(VkCommandBuffer command_buffer) region.imageSubresource.layerCount = 1; region.imageExtent.width = width; region.imageExtent.height = height; + region.imageExtent.depth = 1; vkCmdCopyBufferToImage(command_buffer, g_UploadBuffer, g_FontImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); VkImageMemoryBarrier use_barrier[1] = {}; From 4da26d85cdf4d84eb0e491fbfcf1efce3311d093 Mon Sep 17 00:00:00 2001 From: saschawillems Date: Sun, 26 Mar 2017 19:54:59 +0200 Subject: [PATCH 025/921] Clip negative scissor offsets to zero --- examples/vulkan_example/imgui_impl_glfw_vulkan.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp b/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp index 72fa5bc88..e7dfe32b7 100644 --- a/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp +++ b/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp @@ -301,8 +301,8 @@ void ImGui_ImplGlfwVulkan_RenderDrawLists(ImDrawData* draw_data) else { VkRect2D scissor; - scissor.offset.x = (int32_t)(pcmd->ClipRect.x); - scissor.offset.y = (int32_t)(pcmd->ClipRect.y); + scissor.offset.x = (int32_t)(pcmd->ClipRect.x) > 0 ? (int32_t)(pcmd->ClipRect.x) : 0; + scissor.offset.y = (int32_t)(pcmd->ClipRect.y) > 0 ? (int32_t)(pcmd->ClipRect.y) : 0; scissor.extent.width = (uint32_t)(pcmd->ClipRect.z - pcmd->ClipRect.x); scissor.extent.height = (uint32_t)(pcmd->ClipRect.w - pcmd->ClipRect.y + 1); // TODO: + 1?????? vkCmdSetScissor(g_CommandBuffer, 0, 1, &scissor); From 0e1950f7d661add0fb7fddd1c03213c6e9226990 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 1 Apr 2017 18:01:42 +0200 Subject: [PATCH 026/921] Comments about child menu positioning (#1086) --- imgui.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 3c636d39b..ff4617ba0 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4121,12 +4121,15 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us } else if (flags & ImGuiWindowFlags_ChildMenu) { + // Child menus typically request _any_ position within the parent menu item, and then our FindBestPopupWindowPos() function will move the new menu outside the parent bounds. + // This is how we end up with child menus appearing (most-commonly) on the right of the parent menu. IM_ASSERT(window_pos_set_by_api); + float horizontal_overlap = style.ItemSpacing.x; // We want some overlap to convey the relative depth of each popup (currently the amount of overlap it is hard-coded to style.ItemSpacing.x, may need to introduce another style value). ImRect rect_to_avoid; if (parent_window->DC.MenuBarAppending) rect_to_avoid = ImRect(-FLT_MAX, parent_window->Pos.y + parent_window->TitleBarHeight(), FLT_MAX, parent_window->Pos.y + parent_window->TitleBarHeight() + parent_window->MenuBarHeight()); else - rect_to_avoid = ImRect(parent_window->Pos.x + style.ItemSpacing.x, -FLT_MAX, parent_window->Pos.x + parent_window->Size.x - style.ItemSpacing.x - parent_window->ScrollbarSizes.x, FLT_MAX); // We want some overlap to convey the relative depth of each popup (here hard-coded to 4) + rect_to_avoid = ImRect(parent_window->Pos.x + horizontal_overlap, -FLT_MAX, parent_window->Pos.x + parent_window->Size.x - horizontal_overlap - parent_window->ScrollbarSizes.x, FLT_MAX); window->PosFloat = FindBestPopupWindowPos(window->PosFloat, window->Size, &window->AutoPosLastDirection, rect_to_avoid); } else if ((flags & ImGuiWindowFlags_Popup) != 0 && !window_pos_set_by_api && window_appearing_after_being_hidden) @@ -8861,6 +8864,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled) if (menuset_is_open) g.FocusedWindow = window; + // The reference position stored in popup_pos will be used by Begin() to find a suitable position for the child menu (using FindBestPopupWindowPos). ImVec2 popup_pos, pos = window->DC.CursorPos; if (window->DC.LayoutType == ImGuiLayoutType_Horizontal) { From 15d7f20d4fe17d20659878d9e827e78351853cff Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 1 Apr 2017 18:44:34 +0200 Subject: [PATCH 027/921] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 68d57ee7e..eecb1bc58 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ dear imgui, [![Build Status](https://travis-ci.org/ocornut/imgui.svg?branch=master)](https://travis-ci.org/ocornut/imgui) [![Coverity Status](https://scan.coverity.com/projects/4720/badge.svg)](https://scan.coverity.com/projects/4720) -(This library is free and will stay free, but needs your support to sustain its development. There are lots of desirable new features and maintenance to do. If you work for a company using ImGui or have the means to do so, please consider financial support) +(This library is free and will stay free, but needs your support to sustain its development. There are lots of desirable new features and maintenance to do. If you work for a company using ImGui or have the means to do so, please consider financial support. I can invoice for private support, custom development etc.) [![Patreon](https://cloud.githubusercontent.com/assets/8225057/5990484/70413560-a9ab-11e4-8942-1a63607c0b00.png)](http://www.patreon.com/imgui) [![PayPal](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5Q73FPZ9C526U) @@ -185,11 +185,11 @@ There is an unofficial but reasonably maintained [c-api for ImGui](https://githu Donate ------ -Can I donate to support the development of ImGui? +How can I help financing further development of Dear ImGui? [![Patreon](https://cloud.githubusercontent.com/assets/8225057/5990484/70413560-a9ab-11e4-8942-1a63607c0b00.png)](http://www.patreon.com/imgui) [![PayPal](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5Q73FPZ9C526U) -I'm currently an independent developer and your contributions are useful. I have setup an [**ImGui Patreon page**](http://www.patreon.com/imgui) if you want to donate and enable me to spend more time improving the library. If your company uses ImGui please consider making a contribution. One-off donations are also greatly appreciated. I am available for hire to work on or with ImGui. Thanks! +Your contributions are keeping the library alive. For end-users, I have setup an [**ImGui Patreon page**](http://www.patreon.com/imgui) if you want to donate and enable me to spend more time improving the library. If your company uses ImGui please consider making a contribution. One-off donations are also greatly appreciated. I can invoice for private support, custom development or whatever makes more sense in a given context. I am available for hire to work on or with ImGui. Please e-mail for details. Thanks! Credits ------- From 670775ac22e4fb93be2335d9c4ceb50f5f9ab056 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 13 Apr 2017 20:01:24 +0200 Subject: [PATCH 028/921] Added assert/comment about using MergeMode (#1100) --- imgui_draw.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 1b2e9e0c2..b0931b60c 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1143,6 +1143,10 @@ ImFont* ImFontAtlas::AddFont(const ImFontConfig* font_cfg) IM_PLACEMENT_NEW(font) ImFont(); Fonts.push_back(font); } + else + { + IM_ASSERT(!Fonts.empty()); // When using MergeMode make sure that a font has already been added before. You can use ImGui::AddFontDefault() to add the default imgui font. + } ConfigData.push_back(*font_cfg); ImFontConfig& new_font_cfg = ConfigData.back(); From 8df58e2cfde40c23556966a90730182f5245327a Mon Sep 17 00:00:00 2001 From: Michael Link Date: Tue, 25 Apr 2017 15:15:56 +0200 Subject: [PATCH 029/921] MenuItem should only be selected on release --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index ff4617ba0..502aed71e 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -8611,7 +8611,7 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl ImGuiButtonFlags button_flags = 0; if (flags & ImGuiSelectableFlags_Menu) button_flags |= ImGuiButtonFlags_PressedOnClick; - if (flags & ImGuiSelectableFlags_MenuItem) button_flags |= ImGuiButtonFlags_PressedOnClick|ImGuiButtonFlags_PressedOnRelease; + if (flags & ImGuiSelectableFlags_MenuItem) button_flags |= ImGuiButtonFlags_PressedOnRelease; if (flags & ImGuiSelectableFlags_Disabled) button_flags |= ImGuiButtonFlags_Disabled; if (flags & ImGuiSelectableFlags_AllowDoubleClick) button_flags |= ImGuiButtonFlags_PressedOnClickRelease | ImGuiButtonFlags_PressedOnDoubleClick; bool hovered, held; From 50b4b29beb5c48a9dde38dd0e240054b9a68b31e Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 26 Apr 2017 18:16:59 +0200 Subject: [PATCH 030/921] Examples: GLFW+GL3, SDL+GL3: Fixed modifying bound Texture0 (#1087, #1088, #1116) --- examples/apple_example/imguiex-ios/imgui_impl_ios.mm | 1 + examples/opengl3_example/imgui_impl_glfw_gl3.cpp | 6 +++--- examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp | 8 ++++---- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.mm b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm index 893dbf977..bfcae7cd1 100644 --- a/examples/apple_example/imguiex-ios/imgui_impl_ios.mm +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm @@ -617,6 +617,7 @@ void ImGui_ClipboardCallback(uSynergyCookie cookie, enum uSynergyClipboardFormat static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data) { // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled + // FIXME: Backport changes from imgui_impl_glfw_gl3.cpp GLint last_program, last_texture; glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp index 97a125d89..194a291fe 100644 --- a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp +++ b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp @@ -44,9 +44,10 @@ void ImGui_ImplGlfwGL3_RenderDrawLists(ImDrawData* draw_data) draw_data->ScaleClipRects(io.DisplayFramebufferScale); // Backup GL state + GLint last_active_texture; glGetIntegerv(GL_ACTIVE_TEXTURE, &last_active_texture); + glActiveTexture(GL_TEXTURE0); GLint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); - GLint last_active_texture; glGetIntegerv(GL_ACTIVE_TEXTURE, &last_active_texture); GLint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); GLint last_element_array_buffer; glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &last_element_array_buffer); GLint last_vertex_array; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array); @@ -68,7 +69,6 @@ void ImGui_ImplGlfwGL3_RenderDrawLists(ImDrawData* draw_data) glDisable(GL_CULL_FACE); glDisable(GL_DEPTH_TEST); glEnable(GL_SCISSOR_TEST); - glActiveTexture(GL_TEXTURE0); // Setup viewport, orthographic projection matrix glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); @@ -114,8 +114,8 @@ void ImGui_ImplGlfwGL3_RenderDrawLists(ImDrawData* draw_data) // Restore modified GL state glUseProgram(last_program); - glActiveTexture(last_active_texture); glBindTexture(GL_TEXTURE_2D, last_texture); + glActiveTexture(last_active_texture); glBindVertexArray(last_vertex_array); glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, last_element_array_buffer); diff --git a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp index 9acbf881c..8e3bad8d0 100644 --- a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp +++ b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp @@ -38,9 +38,10 @@ void ImGui_ImplSdlGL3_RenderDrawLists(ImDrawData* draw_data) draw_data->ScaleClipRects(io.DisplayFramebufferScale); // Backup GL state + GLint last_active_texture; glGetIntegerv(GL_ACTIVE_TEXTURE, &last_active_texture); + glActiveTexture(GL_TEXTURE0); GLint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); - GLint last_active_texture; glGetIntegerv(GL_ACTIVE_TEXTURE, &last_active_texture); GLint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); GLint last_element_array_buffer; glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &last_element_array_buffer); GLint last_vertex_array; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array); @@ -62,9 +63,8 @@ void ImGui_ImplSdlGL3_RenderDrawLists(ImDrawData* draw_data) glDisable(GL_CULL_FACE); glDisable(GL_DEPTH_TEST); glEnable(GL_SCISSOR_TEST); - glActiveTexture(GL_TEXTURE0); - // Setup orthographic projection matrix + // Setup viewport, orthographic projection matrix glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); const float ortho_projection[4][4] = { @@ -108,8 +108,8 @@ void ImGui_ImplSdlGL3_RenderDrawLists(ImDrawData* draw_data) // Restore modified GL state glUseProgram(last_program); - glActiveTexture(last_active_texture); glBindTexture(GL_TEXTURE_2D, last_texture); + glActiveTexture(last_active_texture); glBindVertexArray(last_vertex_array); glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, last_element_array_buffer); From f030087f8ece09d06db884a9562ccbc2d4ebfdd7 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 26 Apr 2017 18:27:10 +0200 Subject: [PATCH 031/921] Comments to redirect people to OpenGL3 examples (#1116) --- examples/README.txt | 18 +++++++++++------- examples/opengl2_example/imgui_impl_glfw.cpp | 5 +++-- .../sdl_opengl2_example/imgui_impl_sdl.cpp | 3 +++ 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/examples/README.txt b/examples/README.txt index 54be766a4..9491ff1a4 100644 --- a/examples/README.txt +++ b/examples/README.txt @@ -8,10 +8,11 @@ Third party languages and frameworks bindings: https://github.com/ocornut/imgui/ TL;DR; - Newcomers, read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup ImGui in your codebase. - - Refer to 'opengl2_example' to LEARN how the library is setup, it is the simplest one. + - To LEARN how the library is setup, you may refer to 'opengl2_example' because is the simplest one. The other examples requires more boilerplate and are harder to read. - - If you are using OpenGL in your application, probably use an opengl3_xxx backend. - Mixing old fixed pipeline OpenGL2 and programmable pipeline OpenGL3+ isn't well supported by drivers. + However, USE 'opengl3_example' in your application if you are using any modern OpenGL3+ calls. + Mixing old fixed pipeline OpenGL2 and programmable pipeline OpenGL3+ isn't well supported by some drivers. + If you are not sure, in doubt, use 'opengl3_example'. - If you are using of the backend provided here, so you can copy the imgui_impl_xxx.cpp/h files to your project and use them unmodified. - If you have your own engine, you probably want to start from one of the OpenGL example and adapt it to @@ -44,14 +45,17 @@ Also note that some setup or GPU drivers may be causing extra lag (possibly by e leaving you with no option but sadness/anger (Intel GPU drivers were reported as such). opengl2_example/ - GLFW + OpenGL example (old fixed pipeline). - This is simple to read. Prefer following this example to learn how ImGui works! + GLFW + OpenGL example (old, fixed graphic pipeline). + This is only provided as a reference to learn how ImGui integration works, because it is easier to read. + However, if your code is using GL3+ context, using this may confuse your driver. Please use the GL3 example below. (You might be able to use this code in a GL3/GL4 context but make sure you disable the programmable - pipeline by calling "glUseProgram(0)" before ImGui::Render.) + pipeline by calling "glUseProgram(0)" before ImGui::Render. It appears that many librairies and drivers + are having issues mixing GL2 calls and newer GL3/GL4 calls. So it isn't recommended that you use that.) opengl3_example/ GLFW + OpenGL example (programmable pipeline, binding modern functions with GL3W). - This uses more modern OpenGL calls and custom shaders. It's more messy. + This uses more modern OpenGL calls and custom shaders. + Prefer using that if you are using modern OpenGL3/4 in your application. directx9_example/ DirectX9 example, Windows only. diff --git a/examples/opengl2_example/imgui_impl_glfw.cpp b/examples/opengl2_example/imgui_impl_glfw.cpp index 3755c6088..f3bb0b2b8 100644 --- a/examples/opengl2_example/imgui_impl_glfw.cpp +++ b/examples/opengl2_example/imgui_impl_glfw.cpp @@ -1,9 +1,10 @@ // ImGui GLFW binding with OpenGL // In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. -// If your context is GL3/GL3 then prefer using the code in opengl3_example. +// If your context or own usage of OpenGL involve anything GL3/GL4, prefer using the code in opengl3_example. +// If you are not sure what that means, prefer using the code in opengl3_example. // You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). -// We cannot do that from GL2 code because the function doesn't exist. +// We cannot do that from GL2 code because the function doesn't exist. Mixing GL2 calls and GL3/GL4 calls is giving trouble to many librairies/drivers. // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. // If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl.cpp b/examples/sdl_opengl2_example/imgui_impl_sdl.cpp index 7be0fcdb4..f0758bdab 100644 --- a/examples/sdl_opengl2_example/imgui_impl_sdl.cpp +++ b/examples/sdl_opengl2_example/imgui_impl_sdl.cpp @@ -1,6 +1,9 @@ // ImGui SDL2 binding with OpenGL // In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// If your context or own usage of OpenGL involve anything GL3/GL4, prefer using the code in sdl_opengl3_example. +// If you are not sure what that means, prefer using the code in sdl_opengl3_example. + // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. // If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). // If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. From 104936ab1a78ff6a931d7a8d33afb1190e400ac4 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 26 Apr 2017 19:12:46 +0200 Subject: [PATCH 032/921] imconfig: Added comment about redefining ImDrawIdx --- imconfig.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/imconfig.h b/imconfig.h index 2a956d377..1daa25406 100644 --- a/imconfig.h +++ b/imconfig.h @@ -43,6 +43,9 @@ operator MyVec4() const { return MyVec4(x,y,z,w); } */ +//---- Use 32-bit vertex indices (instead of default: 16-bit) to allow meshes with more than 64K vertices +//#define ImDrawIdx unsigned int + //---- Tip: You can add extra functions within the ImGui:: namespace, here or in your own headers files. //---- e.g. create variants of the ImGui::Value() helper for your low-level math types, or your own widgets/helpers. /* From 659b3fd259c62820ec5c133da48214052d23213b Mon Sep 17 00:00:00 2001 From: Peter Date: Mon, 6 Feb 2017 10:30:16 +0100 Subject: [PATCH 033/921] Add ImDrawList::AddImageQuad Adds a function AddImageQuad(user_texture_id, a, b, c, d, uva, uvb, uvc, uvd, col) that shows a texture on a full quad. This allows showing arbitrary rotations of a texture. --- imgui.h | 1 + imgui_draw.cpp | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/imgui.h b/imgui.h index bf6871786..47b196c0e 100644 --- a/imgui.h +++ b/imgui.h @@ -1203,6 +1203,7 @@ struct ImDrawList IMGUI_API void AddText(const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL); IMGUI_API void AddText(const ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL, float wrap_width = 0.0f, const ImVec4* cpu_fine_clip_rect = NULL); IMGUI_API void AddImage(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& uv0 = ImVec2(0,0), const ImVec2& uv1 = ImVec2(1,1), ImU32 col = 0xFFFFFFFF); + IMGUI_API void AddImageQuad(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, const ImVec2& uva = ImVec2(0,0), const ImVec2& uvb = ImVec2(1,0), const ImVec2& uvc = ImVec2(1,1), const ImVec2& uvd = ImVec2(0,1), ImU32 col = 0xFFFFFFFF); IMGUI_API void AddPolyline(const ImVec2* points, const int num_points, ImU32 col, bool closed, float thickness, bool anti_aliased); IMGUI_API void AddConvexPolyFilled(const ImVec2* points, const int num_points, ImU32 col, bool anti_aliased); IMGUI_API void AddBezierCurve(const ImVec2& pos0, const ImVec2& cp0, const ImVec2& cp1, const ImVec2& pos1, ImU32 col, float thickness, int num_segments = 0); diff --git a/imgui_draw.cpp b/imgui_draw.cpp index b0931b60c..a5f0814c9 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -975,6 +975,23 @@ void ImDrawList::AddImage(ImTextureID user_texture_id, const ImVec2& a, const Im PopTextureID(); } +void ImDrawList::AddImageQuad(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, const ImVec2& uva, const ImVec2& uvb, const ImVec2& uvc, const ImVec2& uvd, ImU32 col) +{ + if ((col >> 24) == 0) + return; + + // FIXME-OPT: This is wasting draw calls. + const bool push_texture_id = _TextureIdStack.empty() || user_texture_id != _TextureIdStack.back(); + if (push_texture_id) + PushTextureID(user_texture_id); + + PrimReserve(6, 4); + PrimQuadUV(a, b, c, d, uva, uvb, uvc, uvd, col); + + if (push_texture_id) + PopTextureID(); +} + //----------------------------------------------------------------------------- // ImDrawData //----------------------------------------------------------------------------- From 32390a252f44683b810f1c3fbb9336123482d083 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 28 Apr 2017 10:28:52 +0200 Subject: [PATCH 034/921] Added UnrealEngine_ImGui link --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index eecb1bc58..595100512 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,7 @@ Frameworks: - Cinder backend for dear imgui https://github.com/simongeilfus/Cinder-ImGui - FlexGUI: Flexium/SFML backend for dear imgui https://github.com/DXsmiley/FlexGUI - IrrIMGUI: Irrlicht backend for dear imgui https://github.com/ZahlGraf/IrrIMGUI +- UnrealEngine_ImGui: Unreal Engine 4 backend for dear imgui https://github.com/sronsse/UnrealEngine_ImGui - LÖVE backend for dear imgui https://github.com/slages/love-imgui - Ogre backend for dear imgui https://bitbucket.org/LMCrashy/ogreimgui/src - ofxImGui: openFrameworks backend for dear imgui https://github.com/jvcleave/ofxImGui From 6e69923e35f62e42872a7bef399492e4314f4c43 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 28 Apr 2017 13:32:04 +0200 Subject: [PATCH 035/921] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 595100512..800dc51ae 100644 --- a/README.md +++ b/README.md @@ -179,7 +179,7 @@ This is [LumixEngine](https://github.com/nem0/LumixEngine) with a minor skinning Why using C++ (as opposed to C)? -ImGui takes advantage of a few C++ features for convenience but nothing anywhere Boost-insanity/quagmire. In particular, function overloading and default parameters are used to make the API easier to use and code more terse. Doing so I believe the API is sitting on a sweet spot and giving up on those features would make the API more cumbersome. Other features such as namespace, constructors and templates (in the case of the ImVector<> class) are also relied on as a convenience but could be removed. +ImGui takes advantage of a few C++ languages features for convenience but nothing anywhere Boost-insanity/quagmire. ImGui doesn't use any C++ header file. Language-wise, function overloading and default parameters are used to make the API easier to use and code more terse. Doing so I believe the API is sitting on a sweet spot and giving up on those features would make the API more cumbersome. Other features such as namespace, constructors and templates (in the case of the ImVector<> class) are also relied on as a convenience. There is an unofficial but reasonably maintained [c-api for ImGui](https://github.com/Extrawurst/cimgui) by Stephan Dilly. I would suggest using your target language functionality to try replicating the function overloading and default parameters used in C++ else the API may be harder to use. It was really designed with C++ in mind and may not make the same amount of sense with another language. Also see [Links](https://github.com/ocornut/imgui/wiki/Links) for third-party bindings to other languages. From 9ab9a846a18bf58d3350c5f33a9562af91c3f85b Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 28 Apr 2017 13:40:50 +0200 Subject: [PATCH 036/921] Update README.md --- README.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 800dc51ae..1ac2ab11b 100644 --- a/README.md +++ b/README.md @@ -3,9 +3,13 @@ dear imgui, [![Build Status](https://travis-ci.org/ocornut/imgui.svg?branch=master)](https://travis-ci.org/ocornut/imgui) [![Coverity Status](https://scan.coverity.com/projects/4720/badge.svg)](https://scan.coverity.com/projects/4720) -(This library is free and will stay free, but needs your support to sustain its development. There are lots of desirable new features and maintenance to do. If you work for a company using ImGui or have the means to do so, please consider financial support. I can invoice for private support, custom development etc.) +(This library is free and will stay free, but needs your support to sustain its development. There are lots of desirable new features and maintenance to do. If you work for a company using ImGui or have the means to do so, please consider financial support. I can invoice for private support, custom development etc. E-mail: omarcornut at gmail) -[![Patreon](https://cloud.githubusercontent.com/assets/8225057/5990484/70413560-a9ab-11e4-8942-1a63607c0b00.png)](http://www.patreon.com/imgui) [![PayPal](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5Q73FPZ9C526U) +Monthly donations via Patreon: +
[![Patreon](https://cloud.githubusercontent.com/assets/8225057/5990484/70413560-a9ab-11e4-8942-1a63607c0b00.png)](http://www.patreon.com/imgui) + +One-off donations via PayPal: +
[![PayPal](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5Q73FPZ9C526U) dear imgui (AKA ImGui), is a bloat-free graphical user interface library for C++. It outputs optimized vertex buffers that you can render anytime in your 3D-pipeline enabled application. It is fast, portable, renderer agnostic and self-contained (no external dependencies). @@ -33,9 +37,9 @@ Your code passes mouse/keyboard inputs and settings to ImGui (see example applic ImGui outputs vertex buffers and simple command-lists that you can render in your application. The number of draw calls and state changes is typically very small. Because it doesn't know or touch graphics state directly, you can call ImGui commands anywhere in your code (e.g. in the middle of a running algorithm, or in the middle of your own rendering process). Refer to the sample applications in the examples/ folder for instructions on how to integrate ImGui with your existing codebase. -_A common misunderstanding is to think that immediate mode gui == immediate mode rendering, which usually implies hammering your driver/GPU with a bunch of inefficient draw calls and state changes, as the gui functions as called by the user. This is NOT what Dear ImGui does. Dear ImGui outputs vertex buffers and a small list of draw calls batches. It never touches your GPU directly. The draw call batches are decently optimal and you can render them later, in your app or even remotely._ +_A common misunderstanding is to think that immediate mode gui == immediate mode rendering, which usually implies hammering your driver/GPU with a bunch of inefficient draw calls and state changes, as the gui functions are called by the user. This is NOT what Dear ImGui does. Dear ImGui outputs vertex buffers and a small list of draw calls batches. It never touches your GPU directly. The draw call batches are decently optimal and you can render them later, in your app or even remotely._ -ImGui allows you create elaborate tools as well as very short-lived ones. On the extreme side of short-liveness: using the Edit&Continue feature of modern compilers you can add a few widgets to tweaks variables while your application is running, and remove the code a minute later! ImGui is not just for tweaking values. You can use it to trace a running algorithm by just emitting text commands. You can use it along with your own reflection data to browse your dataset live. You can use it to expose the internals of a subsystem in your engine, to create a logger, an inspection tool, a profiler, a debugger, etc. +ImGui allows you create elaborate tools as well as very short-lived ones. On the extreme side of short-liveness: using the Edit&Continue feature of modern compilers you can add a few widgets to tweaks variables while your application is running, and remove the code a minute later! ImGui is not just for tweaking values. You can use it to trace a running algorithm by just emitting text commands. You can use it along with your own reflection data to browse your dataset live. You can use it to expose the internals of a subsystem in your engine, to create a logger, an inspection tool, a profiler, a debugger, an entire game making editor/framework, etc. Binaries/Demo ------------- From a606f2dcb5861aa34e13ce4a3c12234e5bb78148 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 28 Apr 2017 13:43:11 +0200 Subject: [PATCH 037/921] Update README.md --- README.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1ac2ab11b..b10c3f92b 100644 --- a/README.md +++ b/README.md @@ -192,9 +192,13 @@ Donate How can I help financing further development of Dear ImGui? -[![Patreon](https://cloud.githubusercontent.com/assets/8225057/5990484/70413560-a9ab-11e4-8942-1a63607c0b00.png)](http://www.patreon.com/imgui) [![PayPal](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5Q73FPZ9C526U) +Monthly donations via Patreon: +
[![Patreon](https://cloud.githubusercontent.com/assets/8225057/5990484/70413560-a9ab-11e4-8942-1a63607c0b00.png)](http://www.patreon.com/imgui) -Your contributions are keeping the library alive. For end-users, I have setup an [**ImGui Patreon page**](http://www.patreon.com/imgui) if you want to donate and enable me to spend more time improving the library. If your company uses ImGui please consider making a contribution. One-off donations are also greatly appreciated. I can invoice for private support, custom development or whatever makes more sense in a given context. I am available for hire to work on or with ImGui. Please e-mail for details. Thanks! +One-off donations via PayPal: +
[![PayPal](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5Q73FPZ9C526U) + +Your contributions are keeping the library alive. For end-users, I have setup an [**ImGui Patreon page**](http://www.patreon.com/imgui) if you want to donate and enable me to spend more time improving the library. If your company uses ImGui please consider making a contribution. One-off donations are also greatly appreciated. I can invoice for private support, custom development or whatever makes more sense in a given context. I am available for hire to work on or with ImGui. Please e-mail omarcornut at gmail for details. Thanks! Credits ------- From bbd44b4edd83d6b27e3d289a3a1341fce4187fab Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 30 Apr 2017 11:33:04 +0200 Subject: [PATCH 038/921] Clarified asserts in CheckStacksSize() when there is a stack mismatch --- imgui.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index ff4617ba0..b45e6aced 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3719,12 +3719,12 @@ static void CheckStacksSize(ImGuiWindow* window, bool write) // NOT checking: DC.ItemWidth, DC.AllowKeyboardFocus, DC.ButtonRepeat, DC.TextWrapPos (per window) to allow user to conveniently push once and not pop (they are cleared on Begin) ImGuiContext& g = *GImGui; int* p_backup = &window->DC.StackSizesBackup[0]; - { int current = window->IDStack.Size; if (write) *p_backup = current; else IM_ASSERT(*p_backup == current && "PushID/PopID Mismatch!"); p_backup++; } // User forgot PopID() - { int current = window->DC.GroupStack.Size; if (write) *p_backup = current; else IM_ASSERT(*p_backup == current && "BeginGroup/EndGroup Mismatch!"); p_backup++; } // User forgot EndGroup() - { int current = g.CurrentPopupStack.Size; if (write) *p_backup = current; else IM_ASSERT(*p_backup == current && "BeginMenu/EndMenu or BeginPopup/EndPopup Mismatch"); p_backup++; }// User forgot EndPopup()/EndMenu() - { int current = g.ColorModifiers.Size; if (write) *p_backup = current; else IM_ASSERT(*p_backup == current && "PushStyleColor/PopStyleColor Mismatch!"); p_backup++; } // User forgot PopStyleColor() - { int current = g.StyleModifiers.Size; if (write) *p_backup = current; else IM_ASSERT(*p_backup == current && "PushStyleVar/PopStyleVar Mismatch!"); p_backup++; } // User forgot PopStyleVar() - { int current = g.FontStack.Size; if (write) *p_backup = current; else IM_ASSERT(*p_backup == current && "PushFont/PopFont Mismatch!"); p_backup++; } // User forgot PopFont() + { int current = window->IDStack.Size; if (write) *p_backup = current; else IM_ASSERT(*p_backup == current && "PushID/PopID or TreeNode/TreePop Mismatch!"); p_backup++; } // Too few or too many PopID()/TreePop() + { int current = window->DC.GroupStack.Size; if (write) *p_backup = current; else IM_ASSERT(*p_backup == current && "BeginGroup/EndGroup Mismatch!"); p_backup++; } // Too few or too many EndGroup() + { int current = g.CurrentPopupStack.Size; if (write) *p_backup = current; else IM_ASSERT(*p_backup == current && "BeginMenu/EndMenu or BeginPopup/EndPopup Mismatch"); p_backup++;}// Too few or too many EndMenu()/EndPopup() + { int current = g.ColorModifiers.Size; if (write) *p_backup = current; else IM_ASSERT(*p_backup == current && "PushStyleColor/PopStyleColor Mismatch!"); p_backup++; } // Too few or too many PopStyleColor() + { int current = g.StyleModifiers.Size; if (write) *p_backup = current; else IM_ASSERT(*p_backup == current && "PushStyleVar/PopStyleVar Mismatch!"); p_backup++; } // Too few or too many PopStyleVar() + { int current = g.FontStack.Size; if (write) *p_backup = current; else IM_ASSERT(*p_backup == current && "PushFont/PopFont Mismatch!"); p_backup++; } // Too few or too many PopFont() IM_ASSERT(p_backup == window->DC.StackSizesBackup + IM_ARRAYSIZE(window->DC.StackSizesBackup)); } From d878462866eda650f72b4a77a9c237f31f464769 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 30 Apr 2017 12:10:30 +0200 Subject: [PATCH 039/921] End() avoid calling Columns() if no columns set is open, not sure what it wasn't the case. Pros: Faster. Avoid early crashes StackId underflow that are meant to be more gracefully caught by CheckStacksSize() (with more explicit assert). Cons: Excercise less code. --- imgui.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index b45e6aced..85a207b2e 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4434,7 +4434,8 @@ void ImGui::End() ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; - Columns(1, "#CloseColumns"); + if (window->DC.ColumnsCount != 1) // close columns set if any is open + Columns(1, "#CLOSECOLUMNS"); PopClipRect(); // inner window clip rectangle // Stop logging From 01286f6636021f0b7d1e9102b098a61439b89ada Mon Sep 17 00:00:00 2001 From: Gregg Tavares Date: Mon, 1 May 2017 16:05:45 +0900 Subject: [PATCH 040/921] Fix blend func state save/restore AFAIK there's no such enum as `GL_BLEND_SRC` or `GL_BLEND_DST` in OpenGL3 and OpenGL4. Maybe they're left over from previous versions? They don't even seem to exist in OpenGL 2.1. In fact checking they were deprecated in OpenGL 1.5 (they exist in 1.3) --- examples/opengl3_example/imgui_impl_glfw_gl3.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp index 194a291fe..dd02d8b1e 100644 --- a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp +++ b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp @@ -51,12 +51,14 @@ void ImGui_ImplGlfwGL3_RenderDrawLists(ImDrawData* draw_data) GLint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); GLint last_element_array_buffer; glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &last_element_array_buffer); GLint last_vertex_array; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array); - GLint last_blend_src; glGetIntegerv(GL_BLEND_SRC, &last_blend_src); - GLint last_blend_dst; glGetIntegerv(GL_BLEND_DST, &last_blend_dst); + GLint last_blend_src_rgb; glGetIntegerv(GL_BLEND_SRC_RGB, &last_blend_src_rgb); + GLint last_blend_dst_rgb; glGetIntegerv(GL_BLEND_DST_RGB, &last_blend_dst_rgb); + GLint last_blend_src_alpha; glGetIntegerv(GL_BLEND_SRC_ALPHA, &last_blend_src_alpha); + GLint last_blend_dst_alpha; glGetIntegerv(GL_BLEND_DST_ALPHA, &last_blend_dst_alpha); GLint last_blend_equation_rgb; glGetIntegerv(GL_BLEND_EQUATION_RGB, &last_blend_equation_rgb); GLint last_blend_equation_alpha; glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &last_blend_equation_alpha); GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); - GLint last_scissor_box[4]; glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box); + GLint last_scissor_box[4]; glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box); GLboolean last_enable_blend = glIsEnabled(GL_BLEND); GLboolean last_enable_cull_face = glIsEnabled(GL_CULL_FACE); GLboolean last_enable_depth_test = glIsEnabled(GL_DEPTH_TEST); @@ -120,7 +122,7 @@ void ImGui_ImplGlfwGL3_RenderDrawLists(ImDrawData* draw_data) glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, last_element_array_buffer); glBlendEquationSeparate(last_blend_equation_rgb, last_blend_equation_alpha); - glBlendFunc(last_blend_src, last_blend_dst); + glBlendFuncSeparate(last_blend_src_rgb, last_blend_dst_rgb, last_blend_src_alpha, last_blend_dst_alpha); if (last_enable_blend) glEnable(GL_BLEND); else glDisable(GL_BLEND); if (last_enable_cull_face) glEnable(GL_CULL_FACE); else glDisable(GL_CULL_FACE); if (last_enable_depth_test) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST); From 9fdd66330f241b344049017914a932c998008ee8 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 1 May 2017 12:20:51 +0200 Subject: [PATCH 041/921] Examples: SDL2+GL3: Fix blend func state save/restore (#1120) --- .../sdl_opengl3_example/imgui_impl_sdl_gl3.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp index 8e3bad8d0..7b7dacaa4 100644 --- a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp +++ b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp @@ -45,12 +45,14 @@ void ImGui_ImplSdlGL3_RenderDrawLists(ImDrawData* draw_data) GLint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); GLint last_element_array_buffer; glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &last_element_array_buffer); GLint last_vertex_array; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array); - GLint last_blend_src; glGetIntegerv(GL_BLEND_SRC, &last_blend_src); - GLint last_blend_dst; glGetIntegerv(GL_BLEND_DST, &last_blend_dst); + GLint last_blend_src_rgb; glGetIntegerv(GL_BLEND_SRC_RGB, &last_blend_src_rgb); + GLint last_blend_dst_rgb; glGetIntegerv(GL_BLEND_DST_RGB, &last_blend_dst_rgb); + GLint last_blend_src_alpha; glGetIntegerv(GL_BLEND_SRC_ALPHA, &last_blend_src_alpha); + GLint last_blend_dst_alpha; glGetIntegerv(GL_BLEND_DST_ALPHA, &last_blend_dst_alpha); GLint last_blend_equation_rgb; glGetIntegerv(GL_BLEND_EQUATION_RGB, &last_blend_equation_rgb); GLint last_blend_equation_alpha; glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &last_blend_equation_alpha); GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); - GLint last_scissor_box[4]; glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box); + GLint last_scissor_box[4]; glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box); GLboolean last_enable_blend = glIsEnabled(GL_BLEND); GLboolean last_enable_cull_face = glIsEnabled(GL_CULL_FACE); GLboolean last_enable_depth_test = glIsEnabled(GL_DEPTH_TEST); @@ -84,10 +86,10 @@ void ImGui_ImplSdlGL3_RenderDrawLists(ImDrawData* draw_data) const ImDrawIdx* idx_buffer_offset = 0; glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); - glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)cmd_list->VtxBuffer.Size * sizeof(ImDrawVert), (GLvoid*)cmd_list->VtxBuffer.Data, GL_STREAM_DRAW); + glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)cmd_list->VtxBuffer.Size * sizeof(ImDrawVert), (const GLvoid*)cmd_list->VtxBuffer.Data, GL_STREAM_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_ElementsHandle); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx), (GLvoid*)cmd_list->IdxBuffer.Data, GL_STREAM_DRAW); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx), (const GLvoid*)cmd_list->IdxBuffer.Data, GL_STREAM_DRAW); for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) { @@ -114,7 +116,7 @@ void ImGui_ImplSdlGL3_RenderDrawLists(ImDrawData* draw_data) glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, last_element_array_buffer); glBlendEquationSeparate(last_blend_equation_rgb, last_blend_equation_alpha); - glBlendFunc(last_blend_src, last_blend_dst); + glBlendFuncSeparate(last_blend_src_rgb, last_blend_dst_rgb, last_blend_src_alpha, last_blend_dst_alpha); if (last_enable_blend) glEnable(GL_BLEND); else glDisable(GL_BLEND); if (last_enable_cull_face) glEnable(GL_CULL_FACE); else glDisable(GL_CULL_FACE); if (last_enable_depth_test) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST); From 6517d68cdf93bc12e5b6a77c8af58af8846e33fb Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 1 May 2017 12:34:32 +0200 Subject: [PATCH 042/921] ImDrawList::AddImage* renamed uv_ parameters to be more consistent. Fix AddImageQuad to use IM_COL32_A_MASK (#1009) --- imgui.h | 8 ++++---- imgui_draw.cpp | 11 +++++------ 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/imgui.h b/imgui.h index 47b196c0e..7f48bd283 100644 --- a/imgui.h +++ b/imgui.h @@ -1050,9 +1050,9 @@ struct ImGuiSizeConstraintCallbackData #define IM_COL32_A_MASK 0xFF000000 #endif #define IM_COL32(R,G,B,A) (((ImU32)(A)<Font, GImGui->FontSize, pos, col, text_begin, text_end); } -void ImDrawList::AddImage(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& uv0, const ImVec2& uv1, ImU32 col) +void ImDrawList::AddImage(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& uv_a, const ImVec2& uv_b, ImU32 col) { if ((col & IM_COL32_A_MASK) == 0) return; @@ -969,24 +969,23 @@ void ImDrawList::AddImage(ImTextureID user_texture_id, const ImVec2& a, const Im PushTextureID(user_texture_id); PrimReserve(6, 4); - PrimRectUV(a, b, uv0, uv1, col); + PrimRectUV(a, b, uv_a, uv_b, col); if (push_texture_id) PopTextureID(); } -void ImDrawList::AddImageQuad(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, const ImVec2& uva, const ImVec2& uvb, const ImVec2& uvc, const ImVec2& uvd, ImU32 col) +void ImDrawList::AddImageQuad(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, const ImVec2& uv_a, const ImVec2& uv_b, const ImVec2& uv_c, const ImVec2& uv_d, ImU32 col) { - if ((col >> 24) == 0) + if ((col & IM_COL32_A_MASK) == 0) return; - // FIXME-OPT: This is wasting draw calls. const bool push_texture_id = _TextureIdStack.empty() || user_texture_id != _TextureIdStack.back(); if (push_texture_id) PushTextureID(user_texture_id); PrimReserve(6, 4); - PrimQuadUV(a, b, c, d, uva, uvb, uvc, uvd, col); + PrimQuadUV(a, b, c, d, uv_a, uv_b, uv_c, uv_d, col); if (push_texture_id) PopTextureID(); From a0a6c8a2efe933f8ca9475eda981b0c74b413e7f Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 1 May 2017 12:36:46 +0200 Subject: [PATCH 043/921] Renamed ImDrawList::PathFill() to ImDrawList::PathFillConvex() for clarity. (breaking API) --- imgui.cpp | 3 ++- imgui.h | 2 +- imgui_draw.cpp | 8 ++++---- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 85a207b2e..dd30abdf1 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -152,6 +152,7 @@ Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. Also read releases logs https://github.com/ocornut/imgui/releases for more details. + - 2017/05/01 (1.50) - Renamed ImDrawList::PathFill() to ImDrawList::PathFillConvex() for clarity. - 2016/11/06 (1.50) - BeginChild(const char*) now applies the stack id to the provided label, consistently with other functions as it should always have been. It shouldn't affect you unless (extremely unlikely) you were appending multiple times to a same child from different locations of the stack id. If that's the case, generate an id with GetId() and use it instead of passing string to BeginChild(). - 2016/10/15 (1.50) - avoid 'void* user_data' parameter to io.SetClipboardTextFn/io.GetClipboardTextFn pointers. We pass io.ClipboardUserData to it. - 2016/09/25 (1.50) - style.WindowTitleAlign is now a ImVec2 (ImGuiAlign enum was removed). set to (0.5f,0.5f) for horizontal+vertical centering, (0.0f,0.0f) for upper-left, etc. @@ -4284,7 +4285,7 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us window->DrawList->PathLineTo(br + ImVec2(-resize_corner_size, -window->BorderSize)); window->DrawList->PathLineTo(br + ImVec2(-window->BorderSize, -resize_corner_size)); window->DrawList->PathArcToFast(ImVec2(br.x - window_rounding - window->BorderSize, br.y - window_rounding - window->BorderSize), window_rounding, 0, 3); - window->DrawList->PathFill(resize_col); + window->DrawList->PathFillConvex(resize_col); } // Borders diff --git a/imgui.h b/imgui.h index 7f48bd283..d77c56c0f 100644 --- a/imgui.h +++ b/imgui.h @@ -1212,7 +1212,7 @@ struct ImDrawList inline void PathClear() { _Path.resize(0); } inline void PathLineTo(const ImVec2& pos) { _Path.push_back(pos); } inline void PathLineToMergeDuplicate(const ImVec2& pos) { if (_Path.Size == 0 || memcmp(&_Path[_Path.Size-1], &pos, 8) != 0) _Path.push_back(pos); } - inline void PathFill(ImU32 col) { AddConvexPolyFilled(_Path.Data, _Path.Size, col, true); PathClear(); } + inline void PathFillConvex(ImU32 col) { AddConvexPolyFilled(_Path.Data, _Path.Size, col, true); PathClear(); } inline void PathStroke(ImU32 col, bool closed, float thickness = 1.0f) { AddPolyline(_Path.Data, _Path.Size, col, closed, thickness, true); PathClear(); } IMGUI_API void PathArcTo(const ImVec2& centre, float radius, float a_min, float a_max, int num_segments = 10); IMGUI_API void PathArcToFast(const ImVec2& centre, float radius, int a_min_of_12, int a_max_of_12); // Use precomputed angles for a 12 steps circle diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 80bd83860..87b60c7d8 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -823,7 +823,7 @@ void ImDrawList::AddRectFilled(const ImVec2& a, const ImVec2& b, ImU32 col, floa if (rounding > 0.0f) { PathRect(a, b, rounding, rounding_corners_flags); - PathFill(col); + PathFillConvex(col); } else { @@ -868,7 +868,7 @@ void ImDrawList::AddQuadFilled(const ImVec2& a, const ImVec2& b, const ImVec2& c PathLineTo(b); PathLineTo(c); PathLineTo(d); - PathFill(col); + PathFillConvex(col); } void ImDrawList::AddTriangle(const ImVec2& a, const ImVec2& b, const ImVec2& c, ImU32 col, float thickness) @@ -890,7 +890,7 @@ void ImDrawList::AddTriangleFilled(const ImVec2& a, const ImVec2& b, const ImVec PathLineTo(a); PathLineTo(b); PathLineTo(c); - PathFill(col); + PathFillConvex(col); } void ImDrawList::AddCircle(const ImVec2& centre, float radius, ImU32 col, int num_segments, float thickness) @@ -910,7 +910,7 @@ void ImDrawList::AddCircleFilled(const ImVec2& centre, float radius, ImU32 col, const float a_max = IM_PI*2.0f * ((float)num_segments - 1.0f) / (float)num_segments; PathArcTo(centre, radius, 0.0f, a_max, num_segments); - PathFill(col); + PathFillConvex(col); } void ImDrawList::AddBezierCurve(const ImVec2& pos0, const ImVec2& cp0, const ImVec2& cp1, const ImVec2& pos1, ImU32 col, float thickness, int num_segments) From dbfd5d6e9afb4d6d140febee0e176b002c203d04 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 1 May 2017 12:55:47 +0200 Subject: [PATCH 044/921] Ignoring unreasonnable Clang -wformat-pedantic warning (#1090) See e.g. http://clang-developers.42468.n3.nabble.com/The-p-conversion-and-cast-to-void-td4044226.html --- imgui.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index dd30abdf1..b5b8a7473 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -639,11 +639,12 @@ // Clang warnings with -Weverything #ifdef __clang__ #pragma clang diagnostic ignored "-Wold-style-cast" // warning : use of old-style cast // yes, they are more terse. -#pragma clang diagnostic ignored "-Wfloat-equal" // warning : comparing floating point with == or != is unsafe // storing and comparing against same constants ok. +#pragma clang diagnostic ignored "-Wfloat-equal" // warning : comparing floating point with == or != is unsafe // storing and comparing against same constants (typically 0.0f) is ok. #pragma clang diagnostic ignored "-Wformat-nonliteral" // warning : format string is not a string literal // passing non-literal to vsnformat(). yes, user passing incorrect format strings can crash the code. #pragma clang diagnostic ignored "-Wexit-time-destructors" // warning : declaration requires an exit-time destructor // exit-time destruction order is undefined. if MemFree() leads to users code that has been disabled before exit it might cause problems. ImGui coding style welcomes static/globals. #pragma clang diagnostic ignored "-Wglobal-constructors" // warning : declaration requires a global destructor // similar to above, not sure what the exact difference it. #pragma clang diagnostic ignored "-Wsign-conversion" // warning : implicit conversion changes signedness // +#pragma clang diagnostic ignored "-Wformat-pedantic" // warning : format specifies type 'void *' but the argument has type 'xxxx *' // unreasonable, would lead to casting every %p arg to void*. probably enabled by -pedantic. #pragma clang diagnostic ignored "-Wint-to-void-pointer-cast" // warning : cast to 'void *' from smaller integer type 'int' // #elif defined(__GNUC__) #pragma GCC diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used From b3d237a5ceaabbdac52759abfb423be1d553b053 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 1 May 2017 13:47:59 +0200 Subject: [PATCH 045/921] Examples: SDL2: Added build .bat files for win32. --- examples/sdl_opengl2_example/build_win32.bat | 1 + examples/sdl_opengl3_example/build_win32.bat | 2 ++ 2 files changed, 3 insertions(+) create mode 100644 examples/sdl_opengl2_example/build_win32.bat create mode 100644 examples/sdl_opengl3_example/build_win32.bat diff --git a/examples/sdl_opengl2_example/build_win32.bat b/examples/sdl_opengl2_example/build_win32.bat new file mode 100644 index 000000000..6509f3aeb --- /dev/null +++ b/examples/sdl_opengl2_example/build_win32.bat @@ -0,0 +1 @@ +cl /Zi /MD /I ..\.. /I ..\libs\gl3w /I %SDL2DIR%\include main.cpp imgui_impl_sdl.cpp ..\..\imgui*.cpp ..\libs\gl3w\GL\gl3w.c /link /libpath:%SDL2DIR%\lib\x86 SDL2.lib SDL2main.lib opengl32.lib /subsystem:console diff --git a/examples/sdl_opengl3_example/build_win32.bat b/examples/sdl_opengl3_example/build_win32.bat new file mode 100644 index 000000000..b6e732710 --- /dev/null +++ b/examples/sdl_opengl3_example/build_win32.bat @@ -0,0 +1,2 @@ +set SDL2DIR=D:\T-Work\Libs\SDL\SDL2-2.0.3 +cl /Zi /MD /I ..\.. /I ..\libs\gl3w /I %SDL2DIR%\include main.cpp imgui_impl_sdl_gl3.cpp ..\..\imgui*.cpp ..\libs\gl3w\GL\gl3w.c /link /libpath:%SDL2DIR%\lib\x86 SDL2.lib SDL2main.lib opengl32.lib /subsystem:console From c3d9e0a6ebfdb8c3917b4a67a561b16fece7c861 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 1 May 2017 15:00:42 +0200 Subject: [PATCH 046/921] Examples: SDL2: Tweaked batch files for Win32. --- examples/.gitignore | 8 ++++++++ examples/sdl_opengl2_example/build_win32.bat | 4 +++- examples/sdl_opengl3_example/build_win32.bat | 5 +++-- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/examples/.gitignore b/examples/.gitignore index 54d153983..4a3d57c08 100644 --- a/examples/.gitignore +++ b/examples/.gitignore @@ -25,6 +25,14 @@ opengl3_example/Release/* opengl3_example/ipch/* opengl3_example/x64/* opengl3_example/opengl3_example +sdl_opengl2_example/Debug/* +sdl_opengl2_example/Release/* +sdl_opengl2_example/ipch/* +sdl_opengl2_example/x64/* +sdl_opengl3_example/Debug/* +sdl_opengl3_example/Release/* +sdl_opengl3_example/ipch/* +sdl_opengl3_example/x64/* *.opensdf *.sdf *.suo diff --git a/examples/sdl_opengl2_example/build_win32.bat b/examples/sdl_opengl2_example/build_win32.bat index 6509f3aeb..3cf81e60a 100644 --- a/examples/sdl_opengl2_example/build_win32.bat +++ b/examples/sdl_opengl2_example/build_win32.bat @@ -1 +1,3 @@ -cl /Zi /MD /I ..\.. /I ..\libs\gl3w /I %SDL2DIR%\include main.cpp imgui_impl_sdl.cpp ..\..\imgui*.cpp ..\libs\gl3w\GL\gl3w.c /link /libpath:%SDL2DIR%\lib\x86 SDL2.lib SDL2main.lib opengl32.lib /subsystem:console +@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. +mkdir Debug +cl /nologo /Zi /MD /I ..\.. /I ..\libs\gl3w /I %SDL_DIR%\include main.cpp imgui_impl_sdl.cpp ..\..\imgui*.cpp ..\libs\gl3w\GL\gl3w.c /FeDebug/sdl_opengl2_example.exe /FoDebug/ /link /libpath:%SDL_DIR%\lib\x86 SDL2.lib SDL2main.lib opengl32.lib /subsystem:console diff --git a/examples/sdl_opengl3_example/build_win32.bat b/examples/sdl_opengl3_example/build_win32.bat index b6e732710..43567542d 100644 --- a/examples/sdl_opengl3_example/build_win32.bat +++ b/examples/sdl_opengl3_example/build_win32.bat @@ -1,2 +1,3 @@ -set SDL2DIR=D:\T-Work\Libs\SDL\SDL2-2.0.3 -cl /Zi /MD /I ..\.. /I ..\libs\gl3w /I %SDL2DIR%\include main.cpp imgui_impl_sdl_gl3.cpp ..\..\imgui*.cpp ..\libs\gl3w\GL\gl3w.c /link /libpath:%SDL2DIR%\lib\x86 SDL2.lib SDL2main.lib opengl32.lib /subsystem:console +@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. +mkdir Debug +cl /nologo /Zi /MD /I ..\.. /I ..\libs\gl3w /I %SDL_DIR%\include main.cpp imgui_impl_sdl_gl3.cpp ..\..\imgui*.cpp ..\libs\gl3w\GL\gl3w.c /FeDebug/sdl_opengl3_example.exe /FoDebug/ /link /libpath:%SDL_DIR%\lib\x86 SDL2.lib SDL2main.lib opengl32.lib /subsystem:console From 497381dc3d4031bfb30de6027ea85bfded77e4f2 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 1 May 2017 15:53:50 +0200 Subject: [PATCH 047/921] Comments --- imgui_demo.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 58f7a7957..b8f4478e7 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1,9 +1,11 @@ // dear imgui, v1.50 WIP // (demo code) -// Don't remove this file from your project! It is useful reference code that you can execute. -// You can call ImGui::ShowTestWindow() in your code to learn about various features of ImGui. +// Message to the person tempted to delete this file when integrating ImGui into their code base: +// Do NOT remove this file from your project! It is useful reference code that you and other users will want to refer to. // Everything in this file will be stripped out by the linker if you don't call ImGui::ShowTestWindow(). +// During development, you can call ImGui::ShowTestWindow() in your code to learn about various features of ImGui. +// Removing this file from your project is hindering your access to documentation, likely leading you to poorer usage of the library. #if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) #define _CRT_SECURE_NO_WARNINGS From 5418bb19ffb9b39580633ad9468bcc0fdf9b5002 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 1 May 2017 16:14:13 +0200 Subject: [PATCH 048/921] Examples: Vulkan: windows batch file for 64-bits. --- examples/vulkan_example/build_win64.bat | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 examples/vulkan_example/build_win64.bat diff --git a/examples/vulkan_example/build_win64.bat b/examples/vulkan_example/build_win64.bat new file mode 100644 index 000000000..a8c05a55b --- /dev/null +++ b/examples/vulkan_example/build_win64.bat @@ -0,0 +1,4 @@ +@REM Build for Visual Studio compiler. Run your copy of amd64/vcvars32.bat to setup 64-bit command-line compiler. +mkdir Debug +cl /nologo /Zi /MD /I ..\.. /I ..\libs\glfw\include /I %VULKAN_SDK%\include *.cpp ..\..\*.cpp /FeDebug/vulkan_example.exe /FoDebug/ /link /LIBPATH:..\libs\glfw\lib-vc2010-64 /libpath:%VULKAN_SDK%\bin glfw3.lib opengl32.lib gdi32.lib shell32.lib vulkan-1.lib + From 56dff3a0803de0450ea242dd0757d2f51d9eb75a Mon Sep 17 00:00:00 2001 From: Peter Particle Date: Sun, 26 Feb 2017 13:36:40 +0100 Subject: [PATCH 049/921] Vulkan backend: optionally enabling vulkan validation layers and debug report callback Additional layer, extension and the callback itself are used/created when IMGUI_VULKAN_DEBUG_REPORT is defined. The callback reports seven (potential!) errors which will be fixed with another pull request. --- examples/vulkan_example/main.cpp | 71 +++++++++++++++++++++++++++++--- 1 file changed, 66 insertions(+), 5 deletions(-) diff --git a/examples/vulkan_example/main.cpp b/examples/vulkan_example/main.cpp index 9e7455c35..2ca245d8c 100644 --- a/examples/vulkan_example/main.cpp +++ b/examples/vulkan_example/main.cpp @@ -12,7 +12,8 @@ #include "imgui_impl_glfw_vulkan.h" #define IMGUI_MAX_POSSIBLE_BACK_BUFFERS 16 -#define IMGUI_UNLIMITED_FRAME_RATE +#define IMGUI_UNLIMITED_FRAME_RATE +#define IMGUI_VULKAN_DEBUG_REPORT static VkAllocationCallbacks* g_Allocator = NULL; static VkInstance g_Instance = VK_NULL_HANDLE; @@ -23,6 +24,7 @@ static VkSwapchainKHR g_Swapchain = VK_NULL_HANDLE; static VkRenderPass g_RenderPass = VK_NULL_HANDLE; static uint32_t g_QueueFamily = 0; static VkQueue g_Queue = VK_NULL_HANDLE; +static VkDebugReportCallbackEXT g_Debug_Report = VK_NULL_HANDLE; static VkFormat g_ImageFormat = VK_FORMAT_B8G8R8A8_UNORM; static VkFormat g_ViewFormat = VK_FORMAT_B8G8R8A8_UNORM; @@ -89,7 +91,7 @@ static void resize_vulkan(GLFWwindow* /*window*/, int w, int h) info.presentMode = VK_PRESENT_MODE_IMMEDIATE_KHR; #else info.presentMode = VK_PRESENT_MODE_FIFO_KHR; -#endif +#endif // IMGUI_UNLIMITED_FRAME_RATE info.clipped = VK_TRUE; info.oldSwapchain = old_swapchain; VkSurfaceCapabilitiesKHR cap; @@ -191,20 +193,71 @@ static void resize_vulkan(GLFWwindow* /*window*/, int w, int h) } } +#ifdef IMGUI_VULKAN_DEBUG_REPORT +static VKAPI_ATTR VkBool32 VKAPI_CALL debug_report( + VkDebugReportFlagsEXT, //flags, + VkDebugReportObjectTypeEXT objectType, + uint64_t, //object, + size_t, //location, + int32_t, //messageCode, + const char*, //pLayerPrefix, + const char* pMessage, + void*) //pUserData) +{ + printf( "ObjectType : %i\nMessage : %s\n\n", objectType, pMessage ); + return VK_FALSE; +} +#endif // IMGUI_VULKAN_DEBUG_REPORT + static void setup_vulkan(GLFWwindow* window) { VkResult err; // Create Vulkan Instance { - uint32_t glfw_extensions_count; - const char** glfw_extensions = glfwGetRequiredInstanceExtensions(&glfw_extensions_count); + uint32_t extensions_count; + const char** glfw_extensions = glfwGetRequiredInstanceExtensions(&extensions_count); + VkInstanceCreateInfo create_info = {}; create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; - create_info.enabledExtensionCount = glfw_extensions_count; +#ifdef IMGUI_VULKAN_DEBUG_REPORT + // enabling multiple validation layers grouped as lunarg standard validation + const char* layers[] = {"VK_LAYER_LUNARG_standard_validation"}; + create_info.enabledLayerCount = 1; + create_info.ppEnabledLayerNames = layers; + + // need additional storage for char pointer to debug report extension + const char** extensions = (const char**)malloc(sizeof(const char*) * (extensions_count + 1)); + for(size_t i = 0; i < extensions_count; i++) + extensions[i] = glfw_extensions[i]; + extensions[ extensions_count ] = "VK_EXT_debug_report"; + create_info.enabledExtensionCount = extensions_count+1; + create_info.ppEnabledExtensionNames = extensions; +#elif + create_info.enabledExtensionCount = extensions_count; create_info.ppEnabledExtensionNames = glfw_extensions; +#endif // IMGUI_VULKAN_DEBUG_REPORT + err = vkCreateInstance(&create_info, g_Allocator, &g_Instance); check_vk_result(err); + +#ifdef IMGUI_VULKAN_DEBUG_REPORT + free(extensions); + + // create the debug report callback + VkDebugReportCallbackCreateInfoEXT debug_report_ci ={}; + debug_report_ci.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT; + debug_report_ci.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT; + debug_report_ci.pfnCallback = debug_report; + debug_report_ci.pUserData = NULL; + + // get the proc address of the function pointer, required for used extensions + PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallbackEXT = + (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkCreateDebugReportCallbackEXT"); + + err = vkCreateDebugReportCallbackEXT( g_Instance, &debug_report_ci, g_Allocator, &g_Debug_Report ); + check_vk_result( err ); +#endif // IMGUI_VULKAN_DEBUG_REPORT } // Create Window Surface @@ -381,6 +434,14 @@ static void cleanup_vulkan() vkDestroyRenderPass(g_Device, g_RenderPass, g_Allocator); vkDestroySwapchainKHR(g_Device, g_Swapchain, g_Allocator); vkDestroySurfaceKHR(g_Instance, g_Surface, g_Allocator); + +#ifdef IMGUI_VULKAN_DEBUG_REPORT + // get the proc address of the function pointer, required for used extensions + auto vkDestroyDebugReportCallbackEXT = + (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkDestroyDebugReportCallbackEXT"); + vkDestroyDebugReportCallbackEXT(g_Instance, g_Debug_Report, g_Allocator); +#endif // IMGUI_VULKAN_DEBUG_REPORT + vkDestroyDevice(g_Device, g_Allocator); vkDestroyInstance(g_Instance, g_Allocator); } From 89d03d5cca8b9c52e359702eb58a7f4e87d5c153 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 1 May 2017 16:46:57 +0200 Subject: [PATCH 050/921] Examples: Vulkan: Disable IMGUI_VULKAN_DEBUG_REPORT by default. Update .bat files for newer VulkanSDK. --- examples/vulkan_example/build_win32.bat | 2 +- examples/vulkan_example/build_win64.bat | 2 +- examples/vulkan_example/main.cpp | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/vulkan_example/build_win32.bat b/examples/vulkan_example/build_win32.bat index e8b5a6c7a..b76741ae6 100644 --- a/examples/vulkan_example/build_win32.bat +++ b/examples/vulkan_example/build_win32.bat @@ -1,4 +1,4 @@ @REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. mkdir Debug -cl /nologo /Zi /MD /I ..\.. /I ..\libs\glfw\include /I %VULKAN_SDK%\include *.cpp ..\..\*.cpp /FeDebug/vulkan_example.exe /FoDebug/ /link /LIBPATH:..\libs\glfw\lib-vc2010-32 /libpath:%VULKAN_SDK%\bin32 glfw3.lib opengl32.lib gdi32.lib shell32.lib vulkan-1.lib +cl /nologo /Zi /MD /I ..\.. /I ..\libs\glfw\include /I %VULKAN_SDK%\include *.cpp ..\..\*.cpp /FeDebug/vulkan_example.exe /FoDebug/ /link /LIBPATH:..\libs\glfw\lib-vc2010-32 /libpath:%VULKAN_SDK%\lib32 glfw3.lib opengl32.lib gdi32.lib shell32.lib vulkan-1.lib diff --git a/examples/vulkan_example/build_win64.bat b/examples/vulkan_example/build_win64.bat index a8c05a55b..83ecf5a1e 100644 --- a/examples/vulkan_example/build_win64.bat +++ b/examples/vulkan_example/build_win64.bat @@ -1,4 +1,4 @@ @REM Build for Visual Studio compiler. Run your copy of amd64/vcvars32.bat to setup 64-bit command-line compiler. mkdir Debug -cl /nologo /Zi /MD /I ..\.. /I ..\libs\glfw\include /I %VULKAN_SDK%\include *.cpp ..\..\*.cpp /FeDebug/vulkan_example.exe /FoDebug/ /link /LIBPATH:..\libs\glfw\lib-vc2010-64 /libpath:%VULKAN_SDK%\bin glfw3.lib opengl32.lib gdi32.lib shell32.lib vulkan-1.lib +cl /nologo /Zi /MD /I ..\.. /I ..\libs\glfw\include /I %VULKAN_SDK%\include *.cpp ..\..\*.cpp /FeDebug/vulkan_example.exe /FoDebug/ /link /LIBPATH:..\libs\glfw\lib-vc2010-64 /libpath:%VULKAN_SDK%\lib glfw3.lib opengl32.lib gdi32.lib shell32.lib vulkan-1.lib diff --git a/examples/vulkan_example/main.cpp b/examples/vulkan_example/main.cpp index 2ca245d8c..7b2d85717 100644 --- a/examples/vulkan_example/main.cpp +++ b/examples/vulkan_example/main.cpp @@ -13,7 +13,7 @@ #define IMGUI_MAX_POSSIBLE_BACK_BUFFERS 16 #define IMGUI_UNLIMITED_FRAME_RATE -#define IMGUI_VULKAN_DEBUG_REPORT +//#define IMGUI_VULKAN_DEBUG_REPORT static VkAllocationCallbacks* g_Allocator = NULL; static VkInstance g_Instance = VK_NULL_HANDLE; @@ -233,7 +233,7 @@ static void setup_vulkan(GLFWwindow* window) extensions[ extensions_count ] = "VK_EXT_debug_report"; create_info.enabledExtensionCount = extensions_count+1; create_info.ppEnabledExtensionNames = extensions; -#elif +#else create_info.enabledExtensionCount = extensions_count; create_info.ppEnabledExtensionNames = glfw_extensions; #endif // IMGUI_VULKAN_DEBUG_REPORT From 33874073dc3275a7d99e20c9986d39998328b62f Mon Sep 17 00:00:00 2001 From: Peter Particle Date: Sun, 26 Feb 2017 17:31:02 +0100 Subject: [PATCH 051/921] Fixed all issues found by vulkan debug report. Reasons for the major design changes are commented. --- examples/vulkan_example/main.cpp | 118 ++++++++++++++++++++++++------- 1 file changed, 93 insertions(+), 25 deletions(-) diff --git a/examples/vulkan_example/main.cpp b/examples/vulkan_example/main.cpp index 7b2d85717..107557062 100644 --- a/examples/vulkan_example/main.cpp +++ b/examples/vulkan_example/main.cpp @@ -26,10 +26,9 @@ static uint32_t g_QueueFamily = 0; static VkQueue g_Queue = VK_NULL_HANDLE; static VkDebugReportCallbackEXT g_Debug_Report = VK_NULL_HANDLE; -static VkFormat g_ImageFormat = VK_FORMAT_B8G8R8A8_UNORM; -static VkFormat g_ViewFormat = VK_FORMAT_B8G8R8A8_UNORM; -static VkColorSpaceKHR g_ColorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR; +static VkSurfaceFormatKHR g_SurfaceFormat; static VkImageSubresourceRange g_ImageRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}; +static VkPresentModeKHR g_PresentMode; static VkPipelineCache g_PipelineCache = VK_NULL_HANDLE; static VkDescriptorPool g_DescriptorPool = VK_NULL_HANDLE; @@ -79,19 +78,14 @@ static void resize_vulkan(GLFWwindow* /*window*/, int w, int h) VkSwapchainCreateInfoKHR info = {}; info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; info.surface = g_Surface; - info.imageFormat = g_ImageFormat; - info.imageColorSpace = g_ColorSpace; + info.imageFormat = g_SurfaceFormat.format; + info.imageColorSpace = g_SurfaceFormat.colorSpace; info.imageArrayLayers = 1; info.imageUsage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; info.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; info.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; - -#ifdef IMGUI_UNLIMITED_FRAME_RATE - info.presentMode = VK_PRESENT_MODE_IMMEDIATE_KHR; -#else - info.presentMode = VK_PRESENT_MODE_FIFO_KHR; -#endif // IMGUI_UNLIMITED_FRAME_RATE + info.presentMode = g_PresentMode; info.clipped = VK_TRUE; info.oldSwapchain = old_swapchain; VkSurfaceCapabilitiesKHR cap; @@ -129,7 +123,7 @@ static void resize_vulkan(GLFWwindow* /*window*/, int w, int h) // Create the Render Pass: { VkAttachmentDescription attachment = {}; - attachment.format = g_ViewFormat; + attachment.format = g_SurfaceFormat.format; attachment.samples = VK_SAMPLE_COUNT_1_BIT; attachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; @@ -159,7 +153,7 @@ static void resize_vulkan(GLFWwindow* /*window*/, int w, int h) VkImageViewCreateInfo info = {}; info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; info.viewType = VK_IMAGE_VIEW_TYPE_2D; - info.format = g_ViewFormat; + info.format = g_SurfaceFormat.format; info.components.r = VK_COMPONENT_SWIZZLE_R; info.components.g = VK_COMPONENT_SWIZZLE_G; info.components.b = VK_COMPONENT_SWIZZLE_B; @@ -228,7 +222,7 @@ static void setup_vulkan(GLFWwindow* window) // need additional storage for char pointer to debug report extension const char** extensions = (const char**)malloc(sizeof(const char*) * (extensions_count + 1)); - for(size_t i = 0; i < extensions_count; i++) + for (size_t i = 0; i < extensions_count; i++) extensions[i] = glfw_extensions[i]; extensions[ extensions_count ] = "VK_EXT_debug_report"; create_info.enabledExtensionCount = extensions_count+1; @@ -266,11 +260,26 @@ static void setup_vulkan(GLFWwindow* window) check_vk_result(err); } - // Get GPU (WARNING here we assume the first gpu is one we can use) + // Get GPU { - uint32_t count = 1; - err = vkEnumeratePhysicalDevices(g_Instance, &count, &g_Gpu); + uint32_t gpu_count; + err = vkEnumeratePhysicalDevices(g_Instance, &gpu_count, NULL); check_vk_result(err); + + if( gpu_count == 1 ) { // only one gpu, assume it has a graphics queue family and use it + err = vkEnumeratePhysicalDevices( g_Instance, &gpu_count, &g_Gpu ); + check_vk_result( err ); + } else { + VkPhysicalDevice* gpus = (VkPhysicalDevice*)malloc(sizeof(VkPhysicalDevice) * gpu_count); + err = vkEnumeratePhysicalDevices(g_Instance, &gpu_count, gpus); + check_vk_result(err); + + // here a number > 1 of GPUs got reported, you should find the best fit GPU for your purpose + // e.g. VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU if available, or with the greatest memory available, etc. + // for sake of simplicity we'll just take the first one, assuming it has a graphics queue family + g_Gpu = gpus[0]; + free(gpus); + } } // Get queue @@ -303,26 +312,85 @@ static void setup_vulkan(GLFWwindow* window) // Get Surface Format { - VkFormat image_view_format[][2] = {{VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_B8G8R8A8_UNORM}, {VK_FORMAT_B8G8R8A8_SRGB, VK_FORMAT_B8G8R8A8_UNORM}}; + // Per Spec Format and View Format are expected to be the same unless VK_IMAGE_CREATE_MUTABLE_BIT was set at image creation + // Assuming that the default behaviour is without setting this bit, there is no need for seperate Spapchain image and image view format + // additionally severeal new color spaces were introduced with Vulkan Spec v1.0.40 + // hence we must make sure that a format with the mostly available color space, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, is found and used uint32_t count; vkGetPhysicalDeviceSurfaceFormatsKHR(g_Gpu, g_Surface, &count, NULL); VkSurfaceFormatKHR *formats = (VkSurfaceFormatKHR*)malloc(sizeof(VkSurfaceFormatKHR) * count); vkGetPhysicalDeviceSurfaceFormatsKHR(g_Gpu, g_Surface, &count, formats); - for (size_t i = 0; i < sizeof(image_view_format) / sizeof(image_view_format[0]); i++) + + // first check if only one format, VK_FORMAT_UNDEFINED, is available, which would imply that any format is available + if (count == 1) { - for (uint32_t j = 0; j < count; j++) + if( formats[0].format == VK_FORMAT_UNDEFINED ) { - if (formats[j].format == image_view_format[i][0]) - { - g_ImageFormat = image_view_format[i][0]; - g_ViewFormat = image_view_format[i][1]; - g_ColorSpace = formats[j].colorSpace; + g_SurfaceFormat.format = VK_FORMAT_B8G8R8A8_UNORM; + g_SurfaceFormat.colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR; + } + else + { // no point in searching another format + g_SurfaceFormat = formats[0]; + } + } + else + { + // request several formats, the first found will be used + VkFormat requestSurfaceImageFormat[] = {VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_B8G8R8_UNORM, VK_FORMAT_R8G8B8_UNORM}; + VkColorSpaceKHR requestSurfaceColorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR; + bool requestedFound = false; + for (size_t i = 0; i < sizeof(requestSurfaceImageFormat) / sizeof(requestSurfaceImageFormat[0]); i++) + { + if( requestedFound ) { + break; } + for (uint32_t j = 0; j < count; j++) + { + if (formats[j].format == requestSurfaceImageFormat[i] && formats[j].colorSpace == requestSurfaceColorSpace) + { + g_SurfaceFormat = formats[j]; + requestedFound = true; + } + } + } + + // if none of the requested image formats could be found, use the first available + if (!requestedFound) + { + g_SurfaceFormat = formats[0]; } } free(formats); } + + // Get Present Mode + { + // Requst a certain mode and confirm that it is available. If not use VK_PRESENT_MODE_FIFO_KHR which is mandatory +#ifdef IMGUI_UNLIMITED_FRAME_RATE + g_PresentMode = VK_PRESENT_MODE_IMMEDIATE_KHR; +#else + g_PresentMode = VK_PRESENT_MODE_FIFO_KHR; +#endif + uint32_t count = 0; + vkGetPhysicalDeviceSurfacePresentModesKHR( g_Gpu, g_Surface, &count, nullptr ); + VkPresentModeKHR* presentModes = ( VkPresentModeKHR* )malloc( sizeof( VkQueueFamilyProperties ) * count ); + vkGetPhysicalDeviceSurfacePresentModesKHR( g_Gpu, g_Surface, &count, presentModes ); + bool presentModeAvailable = false; + for (size_t i = 0; i < count; i++) + { + if (presentModes[i] == g_PresentMode) + { + presentModeAvailable = true; + break; + } + } + if( !presentModeAvailable ) + g_PresentMode = VK_PRESENT_MODE_FIFO_KHR; // allways available + } + + // Create Logical Device { int device_extension_count = 1; From eaae754211dbc92e583e24666253b62c2f5d0e1d Mon Sep 17 00:00:00 2001 From: Peter Particle Date: Sun, 26 Feb 2017 17:58:02 +0100 Subject: [PATCH 052/921] Removed redundant barrier. The transition of the swapchain image(s) can happen implicitly in the renderpass. This approach has been stated to be more efficient than using an explicit barrier. See "Vulkan Programming Guide", Chapter 7: "Graphics Pipelines", section "Renderpasses". --- examples/vulkan_example/main.cpp | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/examples/vulkan_example/main.cpp b/examples/vulkan_example/main.cpp index 107557062..4240ffce5 100644 --- a/examples/vulkan_example/main.cpp +++ b/examples/vulkan_example/main.cpp @@ -130,7 +130,7 @@ static void resize_vulkan(GLFWwindow* /*window*/, int w, int h) attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; attachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - attachment.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + attachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; VkAttachmentReference color_attachment = {}; color_attachment.attachment = 0; color_attachment.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; @@ -554,19 +554,6 @@ static void frame_end() { VkResult err; vkCmdEndRenderPass(g_CommandBuffer[g_FrameIndex]); - { - VkImageMemoryBarrier barrier = {}; - barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; - barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; - barrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT; - barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - barrier.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; - barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - barrier.image = g_BackBuffer[g_BackBufferIndex]; - barrier.subresourceRange = g_ImageRange; - vkCmdPipelineBarrier(g_CommandBuffer[g_FrameIndex], VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, NULL, 0, NULL, 1, &barrier); - } { VkPipelineStageFlags wait_stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; VkSubmitInfo info = {}; From a9add1ce63089f6e16e5f3c91cda101337153987 Mon Sep 17 00:00:00 2001 From: Peter Particle Date: Mon, 27 Feb 2017 14:50:10 +0100 Subject: [PATCH 053/921] Removed redundant VkResult plugged into VkPresentInfoKHR pResults attribute. This is only meaningful when we present directly to multiple swapchains. In that case we can an VkResult per swapchain. --- examples/vulkan_example/main.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/examples/vulkan_example/main.cpp b/examples/vulkan_example/main.cpp index 4240ffce5..957afc43f 100644 --- a/examples/vulkan_example/main.cpp +++ b/examples/vulkan_example/main.cpp @@ -572,7 +572,6 @@ static void frame_end() check_vk_result(err); } { - VkResult res; VkSwapchainKHR swapchains[1] = {g_Swapchain}; uint32_t indices[1] = {g_BackBufferIndex}; VkPresentInfoKHR info = {}; @@ -580,10 +579,8 @@ static void frame_end() info.swapchainCount = 1; info.pSwapchains = swapchains; info.pImageIndices = indices; - info.pResults = &res; err = vkQueuePresentKHR(g_Queue, &info); check_vk_result(err); - check_vk_result(res); } g_FrameIndex = (g_FrameIndex+1) % IMGUI_VK_QUEUED_FRAMES; } From 201d589714c6ef7ff40c87140818a2208b8686b7 Mon Sep 17 00:00:00 2001 From: Peter Particle Date: Mon, 27 Feb 2017 15:05:08 +0100 Subject: [PATCH 054/921] Image presentation now depends on the completeness of command buffer submission through semaphores. To maintain maximum frame rate we render to the last acquired swapchain image but present the last but one drawn image. This behavior is optional through conditional compilation macros. --- examples/vulkan_example/main.cpp | 73 +++++++++++++++++++++++--------- 1 file changed, 54 insertions(+), 19 deletions(-) diff --git a/examples/vulkan_example/main.cpp b/examples/vulkan_example/main.cpp index 957afc43f..f3a86e0ed 100644 --- a/examples/vulkan_example/main.cpp +++ b/examples/vulkan_example/main.cpp @@ -13,7 +13,9 @@ #define IMGUI_MAX_POSSIBLE_BACK_BUFFERS 16 #define IMGUI_UNLIMITED_FRAME_RATE +//#ifdef _DEBUG //#define IMGUI_VULKAN_DEBUG_REPORT +//#endif static VkAllocationCallbacks* g_Allocator = NULL; static VkInstance g_Instance = VK_NULL_HANDLE; @@ -34,7 +36,7 @@ static VkPipelineCache g_PipelineCache = VK_NULL_HANDLE; static VkDescriptorPool g_DescriptorPool = VK_NULL_HANDLE; static int fb_width, fb_height; -static uint32_t g_BackBufferIndex = 0; +static uint32_t g_BackbufferIndices[IMGUI_VK_QUEUED_FRAMES]; // keep track of recently rendered swapchain frame indices static uint32_t g_BackBufferCount = 0; static VkImage g_BackBuffer[IMGUI_MAX_POSSIBLE_BACK_BUFFERS] = {}; static VkImageView g_BackBufferView[IMGUI_MAX_POSSIBLE_BACK_BUFFERS] = {}; @@ -44,7 +46,8 @@ static uint32_t g_FrameIndex = 0; static VkCommandPool g_CommandPool[IMGUI_VK_QUEUED_FRAMES]; static VkCommandBuffer g_CommandBuffer[IMGUI_VK_QUEUED_FRAMES]; static VkFence g_Fence[IMGUI_VK_QUEUED_FRAMES]; -static VkSemaphore g_Semaphore[IMGUI_VK_QUEUED_FRAMES]; +static VkSemaphore g_PresentCompleteSemaphore[IMGUI_VK_QUEUED_FRAMES]; +static VkSemaphore g_RenderCompleteSemaphore[IMGUI_VK_QUEUED_FRAMES]; static VkClearValue g_ClearValue = {}; @@ -452,7 +455,9 @@ static void setup_vulkan(GLFWwindow* window) { VkSemaphoreCreateInfo info = {}; info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; - err = vkCreateSemaphore(g_Device, &info, g_Allocator, &g_Semaphore[i]); + err = vkCreateSemaphore(g_Device, &info, g_Allocator, &g_PresentCompleteSemaphore[i]); + check_vk_result(err); + err = vkCreateSemaphore(g_Device, &info, g_Allocator, &g_RenderCompleteSemaphore[i]); check_vk_result(err); } } @@ -492,7 +497,8 @@ static void cleanup_vulkan() vkDestroyFence(g_Device, g_Fence[i], g_Allocator); vkFreeCommandBuffers(g_Device, g_CommandPool[i], 1, &g_CommandBuffer[i]); vkDestroyCommandPool(g_Device, g_CommandPool[i], g_Allocator); - vkDestroySemaphore(g_Device, g_Semaphore[i], g_Allocator); + vkDestroySemaphore(g_Device, g_PresentCompleteSemaphore[i], g_Allocator); + vkDestroySemaphore(g_Device, g_RenderCompleteSemaphore[i], g_Allocator); } for (uint32_t i = 0; i < g_BackBufferCount; i++) { @@ -525,7 +531,7 @@ static void frame_begin() check_vk_result(err); } { - err = vkAcquireNextImageKHR(g_Device, g_Swapchain, UINT64_MAX, g_Semaphore[g_FrameIndex], VK_NULL_HANDLE, &g_BackBufferIndex); + err = vkAcquireNextImageKHR(g_Device, g_Swapchain, UINT64_MAX, g_PresentCompleteSemaphore[g_FrameIndex], VK_NULL_HANDLE, &g_BackbufferIndices[g_FrameIndex]); check_vk_result(err); } { @@ -541,7 +547,7 @@ static void frame_begin() VkRenderPassBeginInfo info = {}; info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; info.renderPass = g_RenderPass; - info.framebuffer = g_Framebuffer[g_BackBufferIndex]; + info.framebuffer = g_Framebuffer[g_BackbufferIndices[g_FrameIndex]]; info.renderArea.extent.width = fb_width; info.renderArea.extent.height = fb_height; info.clearValueCount = 1; @@ -559,10 +565,12 @@ static void frame_end() VkSubmitInfo info = {}; info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; info.waitSemaphoreCount = 1; - info.pWaitSemaphores = &g_Semaphore[g_FrameIndex]; + info.pWaitSemaphores = &g_PresentCompleteSemaphore[g_FrameIndex]; info.pWaitDstStageMask = &wait_stage; info.commandBufferCount = 1; info.pCommandBuffers = &g_CommandBuffer[g_FrameIndex]; + info.signalSemaphoreCount = 1; + info.pSignalSemaphores = &g_RenderCompleteSemaphore[g_FrameIndex]; err = vkEndCommandBuffer(g_CommandBuffer[g_FrameIndex]); check_vk_result(err); @@ -571,18 +579,32 @@ static void frame_end() err = vkQueueSubmit(g_Queue, 1, &info, g_Fence[g_FrameIndex]); check_vk_result(err); } - { - VkSwapchainKHR swapchains[1] = {g_Swapchain}; - uint32_t indices[1] = {g_BackBufferIndex}; - VkPresentInfoKHR info = {}; - info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; - info.swapchainCount = 1; - info.pSwapchains = swapchains; - info.pImageIndices = indices; - err = vkQueuePresentKHR(g_Queue, &info); - check_vk_result(err); - } - g_FrameIndex = (g_FrameIndex+1) % IMGUI_VK_QUEUED_FRAMES; +} + +static void frame_present() +{ + VkResult err; +// If IMGUI_UNLIMITED_FRAME_RATE is defined we present the latest but one frame +// Othrewise we present the latest rendered frame +#ifdef IMGUI_UNLIMITED_FRAME_RATE + uint32_t PresentIndex = (g_FrameIndex + IMGUI_VK_QUEUED_FRAMES - 1) % IMGUI_VK_QUEUED_FRAMES; +#else + uint32_t PresentIndex = g_FrameIndex; +#endif // IMGUI_UNLIMITED_FRAME_RATE + + VkSwapchainKHR swapchains[1] = {g_Swapchain}; + uint32_t indices[1] = {g_BackbufferIndices[PresentIndex]}; + VkPresentInfoKHR info = {}; + info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; + info.waitSemaphoreCount = 1; + info.pWaitSemaphores = &g_RenderCompleteSemaphore[PresentIndex]; + info.swapchainCount = 1; + info.pSwapchains = swapchains; + info.pImageIndices = indices; + err = vkQueuePresentKHR(g_Queue, &info); + check_vk_result(err); + + g_FrameIndex = (g_FrameIndex + 1) % IMGUI_VK_QUEUED_FRAMES; } static void error_callback(int error, const char* description) @@ -660,6 +682,18 @@ int main(int, char**) bool show_another_window = false; ImVec4 clear_color = ImColor(114, 144, 154); + // When IMGUI_UNLIMITED_FRAME_RATE is defined we render into latest image acquired from the swapchain + // but we display the image which was rendered before + // hence we must render once and increase the g_FrameIndex without presenting, which we do befor entering the render loop + // this is also the reason why frame_end() is split into frame_end() and frame_present(), the latter one not being called here +#ifdef IMGUI_UNLIMITED_FRAME_RATE + ImGui_ImplGlfwVulkan_NewFrame(); + frame_begin(); + ImGui_ImplGlfwVulkan_Render(g_CommandBuffer[g_FrameIndex]); + frame_end(); + g_FrameIndex = (g_FrameIndex + 1) % IMGUI_VK_QUEUED_FRAMES; +#endif // IMGUI_UNLIMITED_FRAME_RATE + // Main loop while (!glfwWindowShouldClose(window)) { @@ -702,6 +736,7 @@ int main(int, char**) frame_begin(); ImGui_ImplGlfwVulkan_Render(g_CommandBuffer[g_FrameIndex]); frame_end(); + frame_present(); } // Cleanup From f87b1525220254f6b1ad60ff6f5a6fa3ae5a8bd0 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 1 May 2017 17:07:05 +0200 Subject: [PATCH 055/921] Examples: Vulkan: Various very minor stylistic fixes, fixing typos in comments, etc. (#1042 #1043) --- examples/vulkan_example/main.cpp | 67 ++++++++++++-------------------- 1 file changed, 25 insertions(+), 42 deletions(-) diff --git a/examples/vulkan_example/main.cpp b/examples/vulkan_example/main.cpp index f3a86e0ed..265392699 100644 --- a/examples/vulkan_example/main.cpp +++ b/examples/vulkan_example/main.cpp @@ -192,16 +192,9 @@ static void resize_vulkan(GLFWwindow* /*window*/, int w, int h) #ifdef IMGUI_VULKAN_DEBUG_REPORT static VKAPI_ATTR VkBool32 VKAPI_CALL debug_report( - VkDebugReportFlagsEXT, //flags, - VkDebugReportObjectTypeEXT objectType, - uint64_t, //object, - size_t, //location, - int32_t, //messageCode, - const char*, //pLayerPrefix, - const char* pMessage, - void*) //pUserData) + VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, uint64_t object, size_t location, int32_t messageCode, const char* pLayerPrefix, const char* pMessage, void* pUserData) { - printf( "ObjectType : %i\nMessage : %s\n\n", objectType, pMessage ); + printf("[vulkan] ObjectType: %i\nMessage: %s\n\n", objectType, pMessage ); return VK_FALSE; } #endif // IMGUI_VULKAN_DEBUG_REPORT @@ -217,6 +210,9 @@ static void setup_vulkan(GLFWwindow* window) VkInstanceCreateInfo create_info = {}; create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; + create_info.enabledExtensionCount = extensions_count; + create_info.ppEnabledExtensionNames = glfw_extensions; + #ifdef IMGUI_VULKAN_DEBUG_REPORT // enabling multiple validation layers grouped as lunarg standard validation const char* layers[] = {"VK_LAYER_LUNARG_standard_validation"}; @@ -230,9 +226,6 @@ static void setup_vulkan(GLFWwindow* window) extensions[ extensions_count ] = "VK_EXT_debug_report"; create_info.enabledExtensionCount = extensions_count+1; create_info.ppEnabledExtensionNames = extensions; -#else - create_info.enabledExtensionCount = extensions_count; - create_info.ppEnabledExtensionNames = glfw_extensions; #endif // IMGUI_VULKAN_DEBUG_REPORT err = vkCreateInstance(&create_info, g_Allocator, &g_Instance); @@ -253,7 +246,7 @@ static void setup_vulkan(GLFWwindow* window) (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkCreateDebugReportCallbackEXT"); err = vkCreateDebugReportCallbackEXT( g_Instance, &debug_report_ci, g_Allocator, &g_Debug_Report ); - check_vk_result( err ); + check_vk_result(err); #endif // IMGUI_VULKAN_DEBUG_REPORT } @@ -269,20 +262,15 @@ static void setup_vulkan(GLFWwindow* window) err = vkEnumeratePhysicalDevices(g_Instance, &gpu_count, NULL); check_vk_result(err); - if( gpu_count == 1 ) { // only one gpu, assume it has a graphics queue family and use it - err = vkEnumeratePhysicalDevices( g_Instance, &gpu_count, &g_Gpu ); - check_vk_result( err ); - } else { - VkPhysicalDevice* gpus = (VkPhysicalDevice*)malloc(sizeof(VkPhysicalDevice) * gpu_count); - err = vkEnumeratePhysicalDevices(g_Instance, &gpu_count, gpus); - check_vk_result(err); + VkPhysicalDevice* gpus = (VkPhysicalDevice*)malloc(sizeof(VkPhysicalDevice) * gpu_count); + err = vkEnumeratePhysicalDevices(g_Instance, &gpu_count, gpus); + check_vk_result(err); - // here a number > 1 of GPUs got reported, you should find the best fit GPU for your purpose - // e.g. VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU if available, or with the greatest memory available, etc. - // for sake of simplicity we'll just take the first one, assuming it has a graphics queue family - g_Gpu = gpus[0]; - free(gpus); - } + // If a number >1 of GPUs got reported, you should find the best fit GPU for your purpose + // e.g. VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU if available, or with the greatest memory available, etc. + // for sake of simplicity we'll just take the first one, assuming it has a graphics queue family. + g_Gpu = gpus[0]; + free(gpus); } // Get queue @@ -316,8 +304,8 @@ static void setup_vulkan(GLFWwindow* window) // Get Surface Format { // Per Spec Format and View Format are expected to be the same unless VK_IMAGE_CREATE_MUTABLE_BIT was set at image creation - // Assuming that the default behaviour is without setting this bit, there is no need for seperate Spapchain image and image view format - // additionally severeal new color spaces were introduced with Vulkan Spec v1.0.40 + // Assuming that the default behavior is without setting this bit, there is no need for separate Spawchain image and image view format + // additionally several new color spaces were introduced with Vulkan Spec v1.0.40 // hence we must make sure that a format with the mostly available color space, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, is found and used uint32_t count; vkGetPhysicalDeviceSurfaceFormatsKHR(g_Gpu, g_Surface, &count, NULL); @@ -360,9 +348,7 @@ static void setup_vulkan(GLFWwindow* window) // if none of the requested image formats could be found, use the first available if (!requestedFound) - { g_SurfaceFormat = formats[0]; - } } free(formats); } @@ -377,9 +363,9 @@ static void setup_vulkan(GLFWwindow* window) g_PresentMode = VK_PRESENT_MODE_FIFO_KHR; #endif uint32_t count = 0; - vkGetPhysicalDeviceSurfacePresentModesKHR( g_Gpu, g_Surface, &count, nullptr ); - VkPresentModeKHR* presentModes = ( VkPresentModeKHR* )malloc( sizeof( VkQueueFamilyProperties ) * count ); - vkGetPhysicalDeviceSurfacePresentModesKHR( g_Gpu, g_Surface, &count, presentModes ); + vkGetPhysicalDeviceSurfacePresentModesKHR(g_Gpu, g_Surface, &count, nullptr); + VkPresentModeKHR* presentModes = (VkPresentModeKHR*)malloc(sizeof(VkQueueFamilyProperties) * count); + vkGetPhysicalDeviceSurfacePresentModesKHR(g_Gpu, g_Surface, &count, presentModes); bool presentModeAvailable = false; for (size_t i = 0; i < count; i++) { @@ -390,7 +376,7 @@ static void setup_vulkan(GLFWwindow* window) } } if( !presentModeAvailable ) - g_PresentMode = VK_PRESENT_MODE_FIFO_KHR; // allways available + g_PresentMode = VK_PRESENT_MODE_FIFO_KHR; // always available } @@ -511,8 +497,7 @@ static void cleanup_vulkan() #ifdef IMGUI_VULKAN_DEBUG_REPORT // get the proc address of the function pointer, required for used extensions - auto vkDestroyDebugReportCallbackEXT = - (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkDestroyDebugReportCallbackEXT"); + auto vkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkDestroyDebugReportCallbackEXT"); vkDestroyDebugReportCallbackEXT(g_Instance, g_Debug_Report, g_Allocator); #endif // IMGUI_VULKAN_DEBUG_REPORT @@ -584,8 +569,7 @@ static void frame_end() static void frame_present() { VkResult err; -// If IMGUI_UNLIMITED_FRAME_RATE is defined we present the latest but one frame -// Othrewise we present the latest rendered frame + // If IMGUI_UNLIMITED_FRAME_RATE is defined we present the latest but one frame. Otherwise we present the latest rendered frame #ifdef IMGUI_UNLIMITED_FRAME_RATE uint32_t PresentIndex = (g_FrameIndex + IMGUI_VK_QUEUED_FRAMES - 1) % IMGUI_VK_QUEUED_FRAMES; #else @@ -682,10 +666,9 @@ int main(int, char**) bool show_another_window = false; ImVec4 clear_color = ImColor(114, 144, 154); - // When IMGUI_UNLIMITED_FRAME_RATE is defined we render into latest image acquired from the swapchain - // but we display the image which was rendered before - // hence we must render once and increase the g_FrameIndex without presenting, which we do befor entering the render loop - // this is also the reason why frame_end() is split into frame_end() and frame_present(), the latter one not being called here + // When IMGUI_UNLIMITED_FRAME_RATE is defined we render into latest image acquired from the swapchain but we display the image which was rendered before. + // Hence we must render once and increase the g_FrameIndex without presenting, which we do before entering the render loop. + // This is also the reason why frame_end() is split into frame_end() and frame_present(), the later one not being called here. #ifdef IMGUI_UNLIMITED_FRAME_RATE ImGui_ImplGlfwVulkan_NewFrame(); frame_begin(); From b0db625cab7ef9fb2791504710a3b912ffc2ee33 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 1 May 2017 17:07:53 +0200 Subject: [PATCH 056/921] Examples: Vulkan: Fixed an extra validation (tested on Windows with VulkanSDK 1.0.46.0) (#1042) --- examples/vulkan_example/imgui_impl_glfw_vulkan.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp b/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp index e5bc426a4..d43929f6a 100644 --- a/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp +++ b/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp @@ -541,6 +541,7 @@ bool ImGui_ImplGlfwVulkan_CreateDeviceObjects() info.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT; info.minLod = -1000; info.maxLod = 1000; + info.maxAnisotropy = 1.0f; err = vkCreateSampler(g_Device, &info, g_Allocator, &g_FontSampler); ImGui_ImplGlfwVulkan_VkResult(err); } From 9614552ebaca1729e82524b70ea14304f1dc5a35 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 1 May 2017 17:16:40 +0200 Subject: [PATCH 057/921] README.md added link to Nicolas Guillemot flashtalk (#1099) --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index b10c3f92b..4fdad38dc 100644 --- a/README.md +++ b/README.md @@ -120,6 +120,7 @@ The Immediate Mode GUI paradigm may at first appear unusual to some users. This - [A presentation by Rickard Gustafsson and Johannes Algelind](http://www.cse.chalmers.se/edu/year/2011/course/TDA361/Advanced%20Computer%20Graphics/IMGUI.pdf). - [Jari Komppa's tutorial on building an ImGui library](http://iki.fi/sol/imgui/). - [Casey Muratori's original video that popularized the concept](https://mollyrocket.com/861). +- [Nicolas Guillemot's CppCon'16 flashtalk about Dear ImGui](https://www.youtube.com/watch?v=LSRJ1jZq90k). See the [Links page](https://github.com/ocornut/imgui/wiki/Links) for third-party bindings to different languages and frameworks. From df52f46b13891acf6298a6a783d7f024ccd9ab21 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 2 May 2017 10:43:00 +0200 Subject: [PATCH 058/921] Comments, documentation (#1121) --- extra_fonts/README.txt | 4 +++- extra_fonts/binary_to_compressed_c.cpp | 13 +++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/extra_fonts/README.txt b/extra_fonts/README.txt index 60d33e2e6..8df8340a8 100644 --- a/extra_fonts/README.txt +++ b/extra_fonts/README.txt @@ -96,7 +96,9 @@ EMBEDDING FONT IN SOURCE CODE --------------------------------- - Compile and use 'binary_to_compressed_c.cpp' to create a compressed C style array. Then load the font with: + Compile and use 'binary_to_compressed_c.cpp' to create a compressed C style array. + See the documentation in binary_to_compressed_c.cpp for instruction on how to use the tool. + Then load the font with: ImFont* font = io.Fonts->AddFontFromMemoryCompressedTTF(compressed_data, compressed_data_size, size_pixels, ...); diff --git a/extra_fonts/binary_to_compressed_c.cpp b/extra_fonts/binary_to_compressed_c.cpp index 79beaad6b..ee160a42a 100644 --- a/extra_fonts/binary_to_compressed_c.cpp +++ b/extra_fonts/binary_to_compressed_c.cpp @@ -7,12 +7,17 @@ // Note that even with compression, the output array is likely to be bigger than the binary file.. // Load compressed TTF fonts with ImGui::GetIO().Fonts->AddFontFromMemoryCompressedTTF() -// Single file application, build with: -// # cl.exe binary_to_compressed_c.cpp -// # gcc binary_to_compressed_c.cpp -// etc. +// Build with, e.g: +// # cl.exe binary_to_compressed_c.cpp +// # gcc binary_to_compressed_c.cpp // You can also find a precompiled Windows binary in the binary/demo package available from https://github.com/ocornut/imgui +// Usage: +// binary_to_compressed_c.exe [-base85] [-nocompress] +// Usage example: +// # binary_to_compressed_c.exe myfont.ttf MyFont > myfont.cpp +// # binary_to_compressed_c.exe -base85 myfont.ttf MyFont > myfont.cpp + #define _CRT_SECURE_NO_WARNINGS #include #include From bd9868f447b18e811fa76415aa2d55677955daa6 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 13 May 2017 20:25:09 +0200 Subject: [PATCH 059/921] Scrollbar: Avoid rendering when sizes are negative to reduce glitches (not sure how this ever slipped through - perhaps because of WindowMinSize settings). --- imgui.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/imgui.cpp b/imgui.cpp index b5b8a7473..5b1d4f228 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4474,6 +4474,8 @@ static void Scrollbar(ImGuiWindow* window, bool horizontal) : ImRect(window_rect.Max.x - style.ScrollbarSize, window->Pos.y + border_size, window_rect.Max.x - border_size, window_rect.Max.y - other_scrollbar_size_w - border_size); if (!horizontal) bb.Min.y += window->TitleBarHeight() + ((window->Flags & ImGuiWindowFlags_MenuBar) ? window->MenuBarHeight() : 0.0f); + if (bb.GetWidth() <= 0.0f || bb.GetHeight() <= 0.0f) + return; float window_rounding = (window->Flags & ImGuiWindowFlags_ChildWindow) ? style.ChildWindowRounding : style.WindowRounding; int window_rounding_corners; From 0828a1fd6c0ee7d53d4a7013a56002aaffc86896 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 14 May 2017 16:27:10 +0200 Subject: [PATCH 060/921] Fixed computation of ImFont::MetricsTotalSurface not taking oversampling into account --- imgui_demo.cpp | 2 +- imgui_draw.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index b8f4478e7..b503146c1 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1752,7 +1752,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) ImGui::SameLine(); ShowHelpMarker("Note than the default embedded font is NOT meant to be scaled.\n\nFont are currently rendered into bitmaps at a given size at the time of building the atlas. You may oversample them to get some flexibility with scaling. You can also render at multiple sizes and select which one to use at runtime.\n\n(Glimmer of hope: the atlas system should hopefully be rewritten in the future to make scaling more natural and automatic.)"); ImGui::Text("Ascent: %f, Descent: %f, Height: %f", font->Ascent, font->Descent, font->Ascent - font->Descent); ImGui::Text("Fallback character: '%c' (%d)", font->FallbackChar, font->FallbackChar); - ImGui::Text("Texture surface: %d pixels (approx)", font->MetricsTotalSurface); + ImGui::Text("Texture surface: %d pixels (approx) ~ %dx%d", font->MetricsTotalSurface, (int)sqrtf((int)font->MetricsTotalSurface), (int)sqrtf((int)font->MetricsTotalSurface)); for (int config_i = 0; config_i < font->ConfigDataCount; config_i++) { ImFontConfig* cfg = &font->ConfigData[config_i]; diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 87b60c7d8..fa7cac529 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1456,7 +1456,7 @@ bool ImFontAtlas::Build() glyph.XAdvance = (pc.xadvance + cfg.GlyphExtraSpacing.x); // Bake spacing into XAdvance if (cfg.PixelSnapH) glyph.XAdvance = (float)(int)(glyph.XAdvance + 0.5f); - dst_font->MetricsTotalSurface += (int)(glyph.X1 - glyph.X0 + 1.99f) * (int)(glyph.Y1 - glyph.Y0 + 1.99f); // +1 to account for average padding, +0.99 to round + dst_font->MetricsTotalSurface += (int)((glyph.U1 - glyph.U0) * TexWidth + 1.99f) * (int)((glyph.V1 - glyph.V0) * TexHeight + 1.99f); // +1 to account for average padding, +0.99 to round } } cfg.DstFont->BuildLookupTable(); From 0981d8e3813baa6473d4024009f636f6dacbb746 Mon Sep 17 00:00:00 2001 From: TinyTinni Date: Tue, 16 May 2017 12:49:47 +0200 Subject: [PATCH 061/921] fixes types --- examples/opengl3_example/imgui_impl_glfw_gl3.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp index dd02d8b1e..3edb36034 100644 --- a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp +++ b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp @@ -44,19 +44,19 @@ void ImGui_ImplGlfwGL3_RenderDrawLists(ImDrawData* draw_data) draw_data->ScaleClipRects(io.DisplayFramebufferScale); // Backup GL state - GLint last_active_texture; glGetIntegerv(GL_ACTIVE_TEXTURE, &last_active_texture); + GLenum last_active_texture; glGetIntegerv(GL_ACTIVE_TEXTURE, &last_active_texture); glActiveTexture(GL_TEXTURE0); GLint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); GLint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); GLint last_element_array_buffer; glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &last_element_array_buffer); GLint last_vertex_array; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array); - GLint last_blend_src_rgb; glGetIntegerv(GL_BLEND_SRC_RGB, &last_blend_src_rgb); - GLint last_blend_dst_rgb; glGetIntegerv(GL_BLEND_DST_RGB, &last_blend_dst_rgb); - GLint last_blend_src_alpha; glGetIntegerv(GL_BLEND_SRC_ALPHA, &last_blend_src_alpha); - GLint last_blend_dst_alpha; glGetIntegerv(GL_BLEND_DST_ALPHA, &last_blend_dst_alpha); - GLint last_blend_equation_rgb; glGetIntegerv(GL_BLEND_EQUATION_RGB, &last_blend_equation_rgb); - GLint last_blend_equation_alpha; glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &last_blend_equation_alpha); + GLenum last_blend_src_rgb; glGetIntegerv(GL_BLEND_SRC_RGB, &last_blend_src_rgb); + GLenum last_blend_dst_rgb; glGetIntegerv(GL_BLEND_DST_RGB, &last_blend_dst_rgb); + GLenum last_blend_src_alpha; glGetIntegerv(GL_BLEND_SRC_ALPHA, &last_blend_src_alpha); + GLenum last_blend_dst_alpha; glGetIntegerv(GL_BLEND_DST_ALPHA, &last_blend_dst_alpha); + GLenum last_blend_equation_rgb; glGetIntegerv(GL_BLEND_EQUATION_RGB, &last_blend_equation_rgb); + GLenum last_blend_equation_alpha; glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &last_blend_equation_alpha); GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); GLint last_scissor_box[4]; glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box); GLboolean last_enable_blend = glIsEnabled(GL_BLEND); From ad3c1e68ab8dcb44a6f5602fd9f5e149323b7398 Mon Sep 17 00:00:00 2001 From: Nicolas Guillemot Date: Tue, 16 May 2017 16:43:59 -0700 Subject: [PATCH 062/921] save and restore sampler in GL 3 examples --- examples/opengl3_example/imgui_impl_glfw_gl3.cpp | 3 +++ examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp | 3 +++ 2 files changed, 6 insertions(+) diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp index dd02d8b1e..155ab2b99 100644 --- a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp +++ b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp @@ -48,6 +48,7 @@ void ImGui_ImplGlfwGL3_RenderDrawLists(ImDrawData* draw_data) glActiveTexture(GL_TEXTURE0); GLint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + GLint last_sampler; glGetIntegerv(GL_SAMPLER_BINDING, &last_sampler); GLint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); GLint last_element_array_buffer; glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &last_element_array_buffer); GLint last_vertex_array; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array); @@ -107,6 +108,7 @@ void ImGui_ImplGlfwGL3_RenderDrawLists(ImDrawData* draw_data) else { glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glBindSampler(0, 0); // rely on combined texture/sampler state. glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer_offset); } @@ -117,6 +119,7 @@ void ImGui_ImplGlfwGL3_RenderDrawLists(ImDrawData* draw_data) // Restore modified GL state glUseProgram(last_program); glBindTexture(GL_TEXTURE_2D, last_texture); + glBindSampler(0, last_sampler); glActiveTexture(last_active_texture); glBindVertexArray(last_vertex_array); glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); diff --git a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp index 7b7dacaa4..77e33442b 100644 --- a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp +++ b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp @@ -42,6 +42,7 @@ void ImGui_ImplSdlGL3_RenderDrawLists(ImDrawData* draw_data) glActiveTexture(GL_TEXTURE0); GLint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + GLint last_sampler; glGetIntegerv(GL_SAMPLER_BINDING, &last_sampler); GLint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); GLint last_element_array_buffer; glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &last_element_array_buffer); GLint last_vertex_array; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array); @@ -101,6 +102,7 @@ void ImGui_ImplSdlGL3_RenderDrawLists(ImDrawData* draw_data) else { glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glBindSampler(0, 0); // rely on combined texture/sampler state. glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer_offset); } @@ -111,6 +113,7 @@ void ImGui_ImplSdlGL3_RenderDrawLists(ImDrawData* draw_data) // Restore modified GL state glUseProgram(last_program); glBindTexture(GL_TEXTURE_2D, last_texture); + glBindSampler(0, last_sampler); glActiveTexture(last_active_texture); glBindVertexArray(last_vertex_array); glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); From 3a7111cfcd8e80c6edb8820a5aacd2b06b716b74 Mon Sep 17 00:00:00 2001 From: TinyTinni Date: Wed, 17 May 2017 21:42:34 +0200 Subject: [PATCH 063/921] casting to GLint on init --- examples/opengl3_example/imgui_impl_glfw_gl3.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp index 3edb36034..ba321e81e 100644 --- a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp +++ b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp @@ -44,19 +44,19 @@ void ImGui_ImplGlfwGL3_RenderDrawLists(ImDrawData* draw_data) draw_data->ScaleClipRects(io.DisplayFramebufferScale); // Backup GL state - GLenum last_active_texture; glGetIntegerv(GL_ACTIVE_TEXTURE, &last_active_texture); + GLenum last_active_texture; glGetIntegerv(GL_ACTIVE_TEXTURE, (GLint*)&last_active_texture); glActiveTexture(GL_TEXTURE0); GLint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); GLint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); GLint last_element_array_buffer; glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &last_element_array_buffer); GLint last_vertex_array; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array); - GLenum last_blend_src_rgb; glGetIntegerv(GL_BLEND_SRC_RGB, &last_blend_src_rgb); - GLenum last_blend_dst_rgb; glGetIntegerv(GL_BLEND_DST_RGB, &last_blend_dst_rgb); - GLenum last_blend_src_alpha; glGetIntegerv(GL_BLEND_SRC_ALPHA, &last_blend_src_alpha); - GLenum last_blend_dst_alpha; glGetIntegerv(GL_BLEND_DST_ALPHA, &last_blend_dst_alpha); - GLenum last_blend_equation_rgb; glGetIntegerv(GL_BLEND_EQUATION_RGB, &last_blend_equation_rgb); - GLenum last_blend_equation_alpha; glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &last_blend_equation_alpha); + GLenum last_blend_src_rgb; glGetIntegerv(GL_BLEND_SRC_RGB, (GLint*)&last_blend_src_rgb); + GLenum last_blend_dst_rgb; glGetIntegerv(GL_BLEND_DST_RGB, (GLint*)&last_blend_dst_rgb); + GLenum last_blend_src_alpha; glGetIntegerv(GL_BLEND_SRC_ALPHA, (GLint*)&last_blend_src_alpha); + GLenum last_blend_dst_alpha; glGetIntegerv(GL_BLEND_DST_ALPHA, (GLint*)&last_blend_dst_alpha); + GLenum last_blend_equation_rgb; glGetIntegerv(GL_BLEND_EQUATION_RGB, (GLint*)&last_blend_equation_rgb); + GLenum last_blend_equation_alpha; glGetIntegerv(GL_BLEND_EQUATION_ALPHA, (GLint*)&last_blend_equation_alpha); GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); GLint last_scissor_box[4]; glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box); GLboolean last_enable_blend = glIsEnabled(GL_BLEND); From c5c77a347636134ea33257b030a775e9a0563ce0 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 26 May 2017 13:36:52 +0200 Subject: [PATCH 064/921] ImFontConfig: Added GlyphOffset to explicitely offset glyphs at font build time, useful for merged fonts. May remove MergeGlyphCenterV soon. --- imgui.h | 3 ++- imgui_draw.cpp | 10 ++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/imgui.h b/imgui.h index d77c56c0f..92e07c588 100644 --- a/imgui.h +++ b/imgui.h @@ -1270,9 +1270,10 @@ struct ImFontConfig int OversampleH, OversampleV; // 3, 1 // Rasterize at higher quality for sub-pixel positioning. We don't use sub-pixel positions on the Y axis. bool PixelSnapH; // false // Align every glyph to pixel boundary. Useful e.g. if you are merging a non-pixel aligned font with the default font. If enabled, you can set OversampleH/V to 1. ImVec2 GlyphExtraSpacing; // 0, 0 // Extra spacing (in pixels) between glyphs + ImVec2 GlyphOffset; // 0, 0 // Offset all glyphs from this font input const ImWchar* GlyphRanges; // // Pointer to a user-provided list of Unicode range (2 value per range, values are inclusive, zero-terminated list). THE ARRAY DATA NEEDS TO PERSIST AS LONG AS THE FONT IS ALIVE. bool MergeMode; // false // Merge into previous ImFont, so you can combine multiple inputs font into one ImFont (e.g. ASCII font + icons + Japanese glyphs). - bool MergeGlyphCenterV; // false // When merging (multiple ImFontInput for one ImFont), vertically center new glyphs instead of aligning their baseline + bool MergeGlyphCenterV; // false // When merging (multiple ImFontInput for one ImFont), vertically center new glyphs instead of aligning their baseline. Prefer using an explicit GlyphOffset.y setting instead, may obsolete MergeGlyphCenterV. // [Internal] char Name[32]; // Name (strictly for debugging) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index fa7cac529..c7bc928c5 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1043,6 +1043,7 @@ ImFontConfig::ImFontConfig() OversampleV = 1; PixelSnapH = false; GlyphExtraSpacing = ImVec2(0.0f, 0.0f); + GlyphOffset = ImVec2(0.0f, 0.0f); GlyphRanges = NULL; MergeMode = false; MergeGlyphCenterV = false; @@ -1426,7 +1427,8 @@ bool ImFontAtlas::Build() dst_font->MetricsTotalSurface = 0; } dst_font->ConfigDataCount++; - float off_y = (cfg.MergeMode && cfg.MergeGlyphCenterV) ? (ascent - dst_font->Ascent) * 0.5f : 0.0f; + float off_x = cfg.GlyphOffset.x, off_y = cfg.GlyphOffset.y; + float merge_off_y = (cfg.MergeMode && cfg.MergeGlyphCenterV) ? (ascent - dst_font->Ascent) * 0.5f : 0.0f; dst_font->FallbackGlyph = NULL; // Always clear fallback so FindGlyph can return NULL. It will be set again in BuildLookupTable() for (int i = 0; i < tmp.RangesCount; i++) @@ -1449,10 +1451,10 @@ bool ImFontAtlas::Build() dst_font->Glyphs.resize(dst_font->Glyphs.Size + 1); ImFont::Glyph& glyph = dst_font->Glyphs.back(); glyph.Codepoint = (ImWchar)codepoint; - glyph.X0 = q.x0; glyph.Y0 = q.y0; glyph.X1 = q.x1; glyph.Y1 = q.y1; + glyph.X0 = q.x0 + off_x; glyph.Y0 = q.y0 + off_y; glyph.X1 = q.x1 + off_x; glyph.Y1 = q.y1 + off_y; glyph.U0 = q.s0; glyph.V0 = q.t0; glyph.U1 = q.s1; glyph.V1 = q.t1; - glyph.Y0 += (float)(int)(dst_font->Ascent + off_y + 0.5f); - glyph.Y1 += (float)(int)(dst_font->Ascent + off_y + 0.5f); + glyph.Y0 += (float)(int)(dst_font->Ascent + merge_off_y + 0.5f); + glyph.Y1 += (float)(int)(dst_font->Ascent + merge_off_y + 0.5f); glyph.XAdvance = (pc.xadvance + cfg.GlyphExtraSpacing.x); // Bake spacing into XAdvance if (cfg.PixelSnapH) glyph.XAdvance = (float)(int)(glyph.XAdvance + 0.5f); From 026d021df166fe93f5560ecf2b58188556c75110 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 26 May 2017 13:40:53 +0200 Subject: [PATCH 065/921] Demo: Fixed warnings introduced in 0828a1fd6c0ee7d53d4a7013a56002aaffc86896 --- imgui_demo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index b503146c1..5f0d45b27 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1752,7 +1752,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) ImGui::SameLine(); ShowHelpMarker("Note than the default embedded font is NOT meant to be scaled.\n\nFont are currently rendered into bitmaps at a given size at the time of building the atlas. You may oversample them to get some flexibility with scaling. You can also render at multiple sizes and select which one to use at runtime.\n\n(Glimmer of hope: the atlas system should hopefully be rewritten in the future to make scaling more natural and automatic.)"); ImGui::Text("Ascent: %f, Descent: %f, Height: %f", font->Ascent, font->Descent, font->Ascent - font->Descent); ImGui::Text("Fallback character: '%c' (%d)", font->FallbackChar, font->FallbackChar); - ImGui::Text("Texture surface: %d pixels (approx) ~ %dx%d", font->MetricsTotalSurface, (int)sqrtf((int)font->MetricsTotalSurface), (int)sqrtf((int)font->MetricsTotalSurface)); + ImGui::Text("Texture surface: %d pixels (approx) ~ %dx%d", font->MetricsTotalSurface, (int)sqrtf((float)font->MetricsTotalSurface), (int)sqrtf((float)font->MetricsTotalSurface)); for (int config_i = 0; config_i < font->ConfigDataCount; config_i++) { ImFontConfig* cfg = &font->ConfigData[config_i]; From 9da53bcecdc2273fef86f032ad55c36393c38ebd Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 26 May 2017 13:42:36 +0200 Subject: [PATCH 066/921] ImFontConfig: Removed MergeGlyphCenterV in favor of a more multipurpose ImFontConfig::GlyphOffset. (Breaking change) --- imgui.cpp | 3 ++- imgui.h | 3 +-- imgui_draw.cpp | 9 ++++----- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 5b1d4f228..4fc6a9da5 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -152,7 +152,8 @@ Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. Also read releases logs https://github.com/ocornut/imgui/releases for more details. - - 2017/05/01 (1.50) - Renamed ImDrawList::PathFill() to ImDrawList::PathFillConvex() for clarity. + - 2017/05/26 (1.50) - Removed ImFontConfig::MergeGlyphCenterV in favor of a more multipurpose ImFontConfig::GlyphOffset. + - 2017/05/01 (1.50) - Renamed ImDrawList::PathFill() (rarely used directly) to ImDrawList::PathFillConvex() for clarity. - 2016/11/06 (1.50) - BeginChild(const char*) now applies the stack id to the provided label, consistently with other functions as it should always have been. It shouldn't affect you unless (extremely unlikely) you were appending multiple times to a same child from different locations of the stack id. If that's the case, generate an id with GetId() and use it instead of passing string to BeginChild(). - 2016/10/15 (1.50) - avoid 'void* user_data' parameter to io.SetClipboardTextFn/io.GetClipboardTextFn pointers. We pass io.ClipboardUserData to it. - 2016/09/25 (1.50) - style.WindowTitleAlign is now a ImVec2 (ImGuiAlign enum was removed). set to (0.5f,0.5f) for horizontal+vertical centering, (0.0f,0.0f) for upper-left, etc. diff --git a/imgui.h b/imgui.h index 92e07c588..63efc6374 100644 --- a/imgui.h +++ b/imgui.h @@ -1272,8 +1272,7 @@ struct ImFontConfig ImVec2 GlyphExtraSpacing; // 0, 0 // Extra spacing (in pixels) between glyphs ImVec2 GlyphOffset; // 0, 0 // Offset all glyphs from this font input const ImWchar* GlyphRanges; // // Pointer to a user-provided list of Unicode range (2 value per range, values are inclusive, zero-terminated list). THE ARRAY DATA NEEDS TO PERSIST AS LONG AS THE FONT IS ALIVE. - bool MergeMode; // false // Merge into previous ImFont, so you can combine multiple inputs font into one ImFont (e.g. ASCII font + icons + Japanese glyphs). - bool MergeGlyphCenterV; // false // When merging (multiple ImFontInput for one ImFont), vertically center new glyphs instead of aligning their baseline. Prefer using an explicit GlyphOffset.y setting instead, may obsolete MergeGlyphCenterV. + bool MergeMode; // false // Merge into previous ImFont, so you can combine multiple inputs font into one ImFont (e.g. ASCII font + icons + Japanese glyphs). You may want to use GlyphOffset.y when merge font of different heights. // [Internal] char Name[32]; // Name (strictly for debugging) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index c7bc928c5..ca500d4e0 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1046,7 +1046,6 @@ ImFontConfig::ImFontConfig() GlyphOffset = ImVec2(0.0f, 0.0f); GlyphRanges = NULL; MergeMode = false; - MergeGlyphCenterV = false; DstFont = NULL; memset(Name, 0, sizeof(Name)); } @@ -1427,8 +1426,8 @@ bool ImFontAtlas::Build() dst_font->MetricsTotalSurface = 0; } dst_font->ConfigDataCount++; - float off_x = cfg.GlyphOffset.x, off_y = cfg.GlyphOffset.y; - float merge_off_y = (cfg.MergeMode && cfg.MergeGlyphCenterV) ? (ascent - dst_font->Ascent) * 0.5f : 0.0f; + float off_x = cfg.GlyphOffset.x; + float off_y = cfg.GlyphOffset.y; dst_font->FallbackGlyph = NULL; // Always clear fallback so FindGlyph can return NULL. It will be set again in BuildLookupTable() for (int i = 0; i < tmp.RangesCount; i++) @@ -1453,8 +1452,8 @@ bool ImFontAtlas::Build() glyph.Codepoint = (ImWchar)codepoint; glyph.X0 = q.x0 + off_x; glyph.Y0 = q.y0 + off_y; glyph.X1 = q.x1 + off_x; glyph.Y1 = q.y1 + off_y; glyph.U0 = q.s0; glyph.V0 = q.t0; glyph.U1 = q.s1; glyph.V1 = q.t1; - glyph.Y0 += (float)(int)(dst_font->Ascent + merge_off_y + 0.5f); - glyph.Y1 += (float)(int)(dst_font->Ascent + merge_off_y + 0.5f); + glyph.Y0 += (float)(int)(dst_font->Ascent + 0.5f); + glyph.Y1 += (float)(int)(dst_font->Ascent + 0.5f); glyph.XAdvance = (pc.xadvance + cfg.GlyphExtraSpacing.x); // Bake spacing into XAdvance if (cfg.PixelSnapH) glyph.XAdvance = (float)(int)(glyph.XAdvance + 0.5f); From 62c4698a730cc572401909a79099f1ed3d9d5b46 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 27 May 2017 17:55:48 +0200 Subject: [PATCH 067/921] Further clarifications of the key indices passed to IsKeyXXX functions (#1159) --- imgui.cpp | 31 ++++++++++++++++--------------- imgui.h | 8 ++++---- 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 4fc6a9da5..59c07bd9a 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3148,25 +3148,26 @@ static bool IsKeyPressedMap(ImGuiKey key, bool repeat) return ImGui::IsKeyPressed(key_index, repeat); } -int ImGui::GetKeyIndex(ImGuiKey key) +int ImGui::GetKeyIndex(ImGuiKey imgui_key) { - IM_ASSERT(key >= 0 && key < ImGuiKey_COUNT); - return GImGui->IO.KeyMap[key]; + IM_ASSERT(imgui_key >= 0 && imgui_key < ImGuiKey_COUNT); + return GImGui->IO.KeyMap[imgui_key]; } -bool ImGui::IsKeyDown(int key_index) +// Note that imgui doesn't know the semantic of each entry of io.KeyDown[]. Use your own indices/enums according to how your backend/engine stored them into KeyDown[]! +bool ImGui::IsKeyDown(int user_key_index) { - if (key_index < 0) return false; - IM_ASSERT(key_index >= 0 && key_index < IM_ARRAYSIZE(GImGui->IO.KeysDown)); - return GImGui->IO.KeysDown[key_index]; + if (user_key_index < 0) return false; + IM_ASSERT(user_key_index >= 0 && user_key_index < IM_ARRAYSIZE(GImGui->IO.KeysDown)); + return GImGui->IO.KeysDown[user_key_index]; } -bool ImGui::IsKeyPressed(int key_index, bool repeat) +bool ImGui::IsKeyPressed(int user_key_index, bool repeat) { ImGuiContext& g = *GImGui; - if (key_index < 0) return false; - IM_ASSERT(key_index >= 0 && key_index < IM_ARRAYSIZE(g.IO.KeysDown)); - const float t = g.IO.KeysDownDuration[key_index]; + if (user_key_index < 0) return false; + IM_ASSERT(user_key_index >= 0 && user_key_index < IM_ARRAYSIZE(g.IO.KeysDown)); + const float t = g.IO.KeysDownDuration[user_key_index]; if (t == 0.0f) return true; @@ -3179,12 +3180,12 @@ bool ImGui::IsKeyPressed(int key_index, bool repeat) return false; } -bool ImGui::IsKeyReleased(int key_index) +bool ImGui::IsKeyReleased(int user_key_index) { ImGuiContext& g = *GImGui; - if (key_index < 0) return false; - IM_ASSERT(key_index >= 0 && key_index < IM_ARRAYSIZE(g.IO.KeysDown)); - if (g.IO.KeysDownDurationPrev[key_index] >= 0.0f && !g.IO.KeysDown[key_index]) + if (user_key_index < 0) return false; + IM_ASSERT(user_key_index >= 0 && user_key_index < IM_ARRAYSIZE(g.IO.KeysDown)); + if (g.IO.KeysDownDurationPrev[user_key_index] >= 0.0f && !g.IO.KeysDown[user_key_index]) return true; return false; } diff --git a/imgui.h b/imgui.h index 63efc6374..107ee8a2c 100644 --- a/imgui.h +++ b/imgui.h @@ -427,10 +427,10 @@ namespace ImGui IMGUI_API void ColorConvertHSVtoRGB(float h, float s, float v, float& out_r, float& out_g, float& out_b); // Inputs - IMGUI_API int GetKeyIndex(ImGuiKey key); // map ImGuiKey_* values into user's key index. == io.KeyMap[key] - IMGUI_API bool IsKeyDown(int key_index); // key_index into the keys_down[] array, imgui doesn't know the semantic of each entry, uses your own indices! - IMGUI_API bool IsKeyPressed(int key_index, bool repeat = true); // uses user's key indices as stored in the keys_down[] array. if repeat=true. uses io.KeyRepeatDelay / KeyRepeatRate - IMGUI_API bool IsKeyReleased(int key_index); // " + IMGUI_API int GetKeyIndex(ImGuiKey imgui_key); // map ImGuiKey_* values into user's key index. == io.KeyMap[key] + IMGUI_API bool IsKeyDown(int user_key_index); // is key being held. == io.KeysDown[user_key_index]. note that imgui doesn't know the semantic of each entry of io.KeyDown[]. Use your own indices/enums according to how your backend/engine stored them into KeyDown[]! + IMGUI_API bool IsKeyPressed(int user_key_index, bool repeat = true); // was key pressed (went from !Down to Down). if repeat=true, uses io.KeyRepeatDelay / KeyRepeatRate + IMGUI_API bool IsKeyReleased(int user_key_index); // was key released (went from Down to !Down).. IMGUI_API bool IsMouseDown(int button); // is mouse button held IMGUI_API bool IsMouseClicked(int button, bool repeat = false); // did mouse button clicked (went from !Down to Down) IMGUI_API bool IsMouseDoubleClicked(int button); // did mouse button double-clicked. a double-click returns false in IsMouseClicked(). uses io.MouseDoubleClickTime. From 32f5ef4f989908cc9ca62884968ba8f83f7e4bc5 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 1 Jun 2017 12:25:01 +0200 Subject: [PATCH 068/921] Added Pascal binding --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 4fdad38dc..d31ec39b0 100644 --- a/README.md +++ b/README.md @@ -62,6 +62,7 @@ Languages: - CyImGui: Python bindings for dear imgui using Cython: https://github.com/chromy/cyimgui - pyimgui: Another Python bindings for dear imgui: https://github.com/swistakm/pyimgui - LUA: https://github.com/patrickriordan/imgui_lua_bindings +- imgui-pas: P ascal bindings for imgui https://github.com/dpethes/imgui-pas Frameworks: - Main ImGui repository include examples for DirectX9, DirectX10, DirectX11, OpenGL2/3, Vulkan, Allegro 5, SDL+GL2/3, iOS and Marmalade: https://github.com/ocornut/imgui/tree/master/examples From 51c200ac0d5a8eaf4eb9eacc84ddcc5dbb3b5a9e Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 2 Jun 2017 11:23:35 +0200 Subject: [PATCH 069/921] Examples: DirectX9: Clarified texture release code (#1163) --- examples/directx9_example/imgui_impl_dx9.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/examples/directx9_example/imgui_impl_dx9.cpp b/examples/directx9_example/imgui_impl_dx9.cpp index 93472f65b..691cb4641 100644 --- a/examples/directx9_example/imgui_impl_dx9.cpp +++ b/examples/directx9_example/imgui_impl_dx9.cpp @@ -311,12 +311,13 @@ void ImGui_ImplDX9_InvalidateDeviceObjects() g_pIB->Release(); g_pIB = NULL; } - if (LPDIRECT3DTEXTURE9 tex = (LPDIRECT3DTEXTURE9)ImGui::GetIO().Fonts->TexID) - { - tex->Release(); - ImGui::GetIO().Fonts->TexID = 0; - } + + // At this point note that we set ImGui::GetIO().Fonts->TexID to be == g_FontTexture, so clear both. + if (g_FontTexture) + g_FontTexture->Release(); g_FontTexture = NULL; + ImGuiIO& io = ImGui::GetIO(); + io.Fonts->TexID = NULL; } void ImGui_ImplDX9_NewFrame() From 2acbd1ac2dc04d7c08c7045fb0ca40c29dbdeb74 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 2 Jun 2017 11:25:36 +0200 Subject: [PATCH 070/921] Using ImTextureID instead of void* in ImFontAtlas, not sure why I didn't do that earlier, make things more clear --- imgui.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/imgui.h b/imgui.h index 107ee8a2c..f99e664fc 100644 --- a/imgui.h +++ b/imgui.h @@ -1312,7 +1312,7 @@ struct ImFontAtlas // Pitch = Width * BytesPerPixels IMGUI_API void GetTexDataAsAlpha8(unsigned char** out_pixels, int* out_width, int* out_height, int* out_bytes_per_pixel = NULL); // 1 byte per-pixel IMGUI_API void GetTexDataAsRGBA32(unsigned char** out_pixels, int* out_width, int* out_height, int* out_bytes_per_pixel = NULL); // 4 bytes-per-pixel - void SetTexID(void* id) { TexID = id; } + void SetTexID(ImTextureID id) { TexID = id; } // Helpers to retrieve list of common Unicode ranges (2 value per range, values are inclusive, zero-terminated list) // NB: Make sure that your string are UTF-8 and NOT in your local code page. See FAQ for details. @@ -1325,7 +1325,7 @@ struct ImFontAtlas // Members // (Access texture data via GetTexData*() calls which will setup a default font for you.) - void* TexID; // User data to refer to the texture once it has been uploaded to user's graphic systems. It ia passed back to you during rendering. + ImTextureID TexID; // User data to refer to the texture once it has been uploaded to user's graphic systems. It is passed back to you during rendering via the ImDrawCmd structure. unsigned char* TexPixelsAlpha8; // 1 component per pixel, each component is unsigned 8-bit. Total size = TexWidth * TexHeight unsigned int* TexPixelsRGBA32; // 4 component per pixel, each component is unsigned 8-bit. Total size = TexWidth * TexHeight * 4 int TexWidth; // Texture width calculated during Build(). From 99ff2ec6fb8f5486dfeb14e9699195282fa0079c Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 2 Jun 2017 11:28:48 +0200 Subject: [PATCH 071/921] Examples: DirectX9/10/11: Comments --- examples/directx10_example/imgui_impl_dx10.cpp | 2 +- examples/directx11_example/imgui_impl_dx11.cpp | 2 +- examples/directx9_example/imgui_impl_dx9.cpp | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/examples/directx10_example/imgui_impl_dx10.cpp b/examples/directx10_example/imgui_impl_dx10.cpp index 5bda68df2..3c0f2d577 100644 --- a/examples/directx10_example/imgui_impl_dx10.cpp +++ b/examples/directx10_example/imgui_impl_dx10.cpp @@ -484,7 +484,7 @@ void ImGui_ImplDX10_InvalidateDeviceObjects() return; if (g_pFontSampler) { g_pFontSampler->Release(); g_pFontSampler = NULL; } - if (g_pFontTextureView) { g_pFontTextureView->Release(); g_pFontTextureView = NULL; ImGui::GetIO().Fonts->TexID = 0; } + if (g_pFontTextureView) { g_pFontTextureView->Release(); g_pFontTextureView = NULL; ImGui::GetIO().Fonts->TexID = NULL; } // We copied g_pFontTextureView to io.Fonts->TexID so let's clear that as well. if (g_pIB) { g_pIB->Release(); g_pIB = NULL; } if (g_pVB) { g_pVB->Release(); g_pVB = NULL; } diff --git a/examples/directx11_example/imgui_impl_dx11.cpp b/examples/directx11_example/imgui_impl_dx11.cpp index 0a3722ebc..0442d785f 100644 --- a/examples/directx11_example/imgui_impl_dx11.cpp +++ b/examples/directx11_example/imgui_impl_dx11.cpp @@ -485,7 +485,7 @@ void ImGui_ImplDX11_InvalidateDeviceObjects() return; if (g_pFontSampler) { g_pFontSampler->Release(); g_pFontSampler = NULL; } - if (g_pFontTextureView) { g_pFontTextureView->Release(); g_pFontTextureView = NULL; ImGui::GetIO().Fonts->TexID = 0; } + if (g_pFontTextureView) { g_pFontTextureView->Release(); g_pFontTextureView = NULL; ImGui::GetIO().Fonts->TexID = NULL; } // We copied g_pFontTextureView to io.Fonts->TexID so let's clear that as well. if (g_pIB) { g_pIB->Release(); g_pIB = NULL; } if (g_pVB) { g_pVB->Release(); g_pVB = NULL; } diff --git a/examples/directx9_example/imgui_impl_dx9.cpp b/examples/directx9_example/imgui_impl_dx9.cpp index 691cb4641..664983ac8 100644 --- a/examples/directx9_example/imgui_impl_dx9.cpp +++ b/examples/directx9_example/imgui_impl_dx9.cpp @@ -313,10 +313,11 @@ void ImGui_ImplDX9_InvalidateDeviceObjects() } // At this point note that we set ImGui::GetIO().Fonts->TexID to be == g_FontTexture, so clear both. + ImGuiIO& io = ImGui::GetIO(); + IM_ASSERT(g_FontTexture == io.Fonts->TexID); if (g_FontTexture) g_FontTexture->Release(); g_FontTexture = NULL; - ImGuiIO& io = ImGui::GetIO(); io.Fonts->TexID = NULL; } From 7ad84b22f8835fa883083a053947ca45244d78c5 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 2 Jun 2017 12:13:47 +0200 Subject: [PATCH 072/921] Comments --- imgui.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 59c07bd9a..fc3ac7632 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -280,8 +280,9 @@ stb_textedit.h stb_truetype.h Don't overwrite imconfig.h if you have made modification to your copy. - 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! + If you have a problem with a missing function/symbols, search for its name in the code, there will likely be a comment about it. + Check the "API BREAKING CHANGES" sections for a list of occasional API breaking changes. + Please report any issue to the GitHub page! Q: What is ImTextureID and how do I display an image? A: ImTextureID is a void* used to pass renderer-agnostic texture references around until it hits your render function. From 5e1caaaef3953091b5395cbeb17c67548d542801 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 2 Jun 2017 12:22:34 +0200 Subject: [PATCH 073/921] Version 1.50 --- imgui.cpp | 2 +- imgui.h | 4 ++-- imgui_demo.cpp | 2 +- imgui_draw.cpp | 2 +- imgui_internal.h | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index fc3ac7632..6d182e764 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.50 WIP +// dear imgui, v1.50 // (main code and documentation) // See ImGui::ShowTestWindow() in imgui_demo.cpp for demo code. diff --git a/imgui.h b/imgui.h index f99e664fc..8bca83f55 100644 --- a/imgui.h +++ b/imgui.h @@ -1,4 +1,4 @@ -// dear imgui, v1.50 WIP +// dear imgui, v1.50 // (headers) // See imgui.cpp file for documentation. @@ -16,7 +16,7 @@ #include // ptrdiff_t, NULL #include // memset, memmove, memcpy, strlen, strchr, strcpy, strcmp -#define IMGUI_VERSION "1.50 WIP" +#define IMGUI_VERSION "1.50" // Define attributes of all API symbols declarations, e.g. for DLL under Windows. #ifndef IMGUI_API diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 5f0d45b27..a37e741fe 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.50 WIP +// dear imgui, v1.50 // (demo code) // Message to the person tempted to delete this file when integrating ImGui into their code base: diff --git a/imgui_draw.cpp b/imgui_draw.cpp index ca500d4e0..96304507b 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.50 WIP +// dear imgui, v1.50 // (drawing and font code) // Contains implementation for diff --git a/imgui_internal.h b/imgui_internal.h index effc5ce7f..200eda95c 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1,4 +1,4 @@ -// dear imgui, v1.50 WIP +// dear imgui, v1.50 // (internals) // You may use this file to debug, understand or extend ImGui features but we don't provide any guarantee of forward compatibility! From 1cd1ca259efd38d560ac3c44e6353af81a9b72e3 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 2 Jun 2017 14:01:06 +0200 Subject: [PATCH 074/921] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d31ec39b0..9cb17933f 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ dear imgui, [![Build Status](https://travis-ci.org/ocornut/imgui.svg?branch=master)](https://travis-ci.org/ocornut/imgui) [![Coverity Status](https://scan.coverity.com/projects/4720/badge.svg)](https://scan.coverity.com/projects/4720) -(This library is free and will stay free, but needs your support to sustain its development. There are lots of desirable new features and maintenance to do. If you work for a company using ImGui or have the means to do so, please consider financial support. I can invoice for private support, custom development etc. E-mail: omarcornut at gmail) +(This library is free but needs your support to sustain its development. There are lots of desirable new features and maintenance to do. If you are an individual using dear imgui, please consider financial support via Patreon/PayPal. If your company is using dear imgui, please consider sponsorship (e.g. sponsoring a few weeks of development). I can invoice for private support, custom development etc. E-mail: omarcornut at gmail.) Monthly donations via Patreon:
[![Patreon](https://cloud.githubusercontent.com/assets/8225057/5990484/70413560-a9ab-11e4-8942-1a63607c0b00.png)](http://www.patreon.com/imgui) From a2f7c40e30bc09763f1c50943543dda41546ba2c Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 13 Jun 2017 11:29:21 +0200 Subject: [PATCH 075/921] Fixed comment (#1178) --- imgui_draw.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 96304507b..387a0d47b 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1161,7 +1161,7 @@ ImFont* ImFontAtlas::AddFont(const ImFontConfig* font_cfg) } else { - IM_ASSERT(!Fonts.empty()); // When using MergeMode make sure that a font has already been added before. You can use ImGui::AddFontDefault() to add the default imgui font. + IM_ASSERT(!Fonts.empty()); // When using MergeMode make sure that a font has already been added before. You can use ImGui::GetIO().Fonts->AddFontDefault() to add the default imgui font. } ConfigData.push_back(*font_cfg); From 12d265fa310c6f3f5d9f580989bf8b9e24df9dc6 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 13 Jun 2017 11:30:22 +0200 Subject: [PATCH 076/921] Version 1.51 WIP tag --- imgui.cpp | 2 +- imgui.h | 4 ++-- imgui_demo.cpp | 2 +- imgui_draw.cpp | 2 +- imgui_internal.h | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 6d182e764..57e44c007 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.50 +// dear imgui, v1.51 WIP // (main code and documentation) // See ImGui::ShowTestWindow() in imgui_demo.cpp for demo code. diff --git a/imgui.h b/imgui.h index 8bca83f55..340856f8b 100644 --- a/imgui.h +++ b/imgui.h @@ -1,4 +1,4 @@ -// dear imgui, v1.50 +// dear imgui, v1.51 WIP // (headers) // See imgui.cpp file for documentation. @@ -16,7 +16,7 @@ #include // ptrdiff_t, NULL #include // memset, memmove, memcpy, strlen, strchr, strcpy, strcmp -#define IMGUI_VERSION "1.50" +#define IMGUI_VERSION "1.51 WIP" // Define attributes of all API symbols declarations, e.g. for DLL under Windows. #ifndef IMGUI_API diff --git a/imgui_demo.cpp b/imgui_demo.cpp index a37e741fe..b198cd174 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.50 +// dear imgui, v1.51 WIP // (demo code) // Message to the person tempted to delete this file when integrating ImGui into their code base: diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 387a0d47b..f11e1984d 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.50 +// dear imgui, v1.51 WIP // (drawing and font code) // Contains implementation for diff --git a/imgui_internal.h b/imgui_internal.h index 200eda95c..f936f7237 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1,4 +1,4 @@ -// dear imgui, v1.50 +// dear imgui, v1.51 WIP // (internals) // You may use this file to debug, understand or extend ImGui features but we don't provide any guarantee of forward compatibility! From 978c84d2e9b733591431fed78d6e5ea78aa909df Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 16 Jun 2017 14:08:17 +0200 Subject: [PATCH 077/921] Removed dependency on int64_t type (unvailable in VS2008) by rewording an assert (#1184) --- imgui.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 57e44c007..6a5dbf025 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2598,14 +2598,16 @@ static void AddDrawListToRenderList(ImVector& out_render_list, ImDr return; } - // Draw list sanity check. Detect mismatch between PrimReserve() calls and incrementing _VtxCurrentIdx, _VtxWritePtr etc. + // Draw list sanity check. Detect mismatch between PrimReserve() calls and incrementing _VtxCurrentIdx, _VtxWritePtr etc. May trigger for you if you are using PrimXXX functions incorrectly. IM_ASSERT(draw_list->VtxBuffer.Size == 0 || draw_list->_VtxWritePtr == draw_list->VtxBuffer.Data + draw_list->VtxBuffer.Size); IM_ASSERT(draw_list->IdxBuffer.Size == 0 || draw_list->_IdxWritePtr == draw_list->IdxBuffer.Data + draw_list->IdxBuffer.Size); IM_ASSERT((int)draw_list->_VtxCurrentIdx == draw_list->VtxBuffer.Size); // Check that draw_list doesn't use more vertices than indexable (default ImDrawIdx = 2 bytes = 64K vertices) - // If this assert triggers because you are drawing lots of stuff manually, A) workaround by calling BeginChild()/EndChild() to put your draw commands in multiple draw lists, B) #define ImDrawIdx to a 'unsigned int' in imconfig.h and render accordingly. - IM_ASSERT((int64_t)draw_list->_VtxCurrentIdx <= ((int64_t)1L << (sizeof(ImDrawIdx)*8))); // Too many vertices in same ImDrawList. See comment above. + // If this assert triggers because you are drawing lots of stuff manually, you can: + // A) workaround by calling BeginChild()/EndChild() to put your draw commands in multiple draw lists, + // B) #define ImDrawIdx to a 'unsigned int' in imconfig.h and render accordingly. + IM_ASSERT((draw_list->_VtxCurrentIdx >> (sizeof(ImDrawIdx)*8)) == 0); // Too many vertices in same ImDrawList. See comment above. out_render_list.push_back(draw_list); GImGui->IO.MetricsRenderVertices += draw_list->VtxBuffer.Size; From 4c8d87d3fbfae5a96181b50b00ad701261c9d78b Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 17 Jun 2017 19:25:58 +0200 Subject: [PATCH 078/921] Comments (#1188) --- imgui.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 6a5dbf025..a9df90597 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2603,10 +2603,12 @@ static void AddDrawListToRenderList(ImVector& out_render_list, ImDr IM_ASSERT(draw_list->IdxBuffer.Size == 0 || draw_list->_IdxWritePtr == draw_list->IdxBuffer.Data + draw_list->IdxBuffer.Size); IM_ASSERT((int)draw_list->_VtxCurrentIdx == draw_list->VtxBuffer.Size); - // Check that draw_list doesn't use more vertices than indexable (default ImDrawIdx = 2 bytes = 64K vertices) + // Check that draw_list doesn't use more vertices than indexable (default ImDrawIdx = 2 bytes = 64K vertices per window) // If this assert triggers because you are drawing lots of stuff manually, you can: - // A) workaround by calling BeginChild()/EndChild() to put your draw commands in multiple draw lists, - // B) #define ImDrawIdx to a 'unsigned int' in imconfig.h and render accordingly. + // A) Add '#define ImDrawIdx unsigned int' in imconfig.h to raise the index size of 4 bytes. You'll need to handle the 4-bytes indices to your renderer. + // For example, the OpenGL example code detect index size at compile-time and does + // 'glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer_offset); + // B) If for some reason you cannot use 32-bit indices or don't want to, a workaround is to call BeginChild()/EndChild() because reaching the 64K limit to split your draw commands in multiple draw lists. IM_ASSERT((draw_list->_VtxCurrentIdx >> (sizeof(ImDrawIdx)*8)) == 0); // Too many vertices in same ImDrawList. See comment above. out_render_list.push_back(draw_list); From e47cf7977355e47677a60cd791d975b8891eaa90 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 17 Jun 2017 19:30:30 +0200 Subject: [PATCH 079/921] Comments tweaks, typos (#1188) --- imgui.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index a9df90597..c86fe4751 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2603,12 +2603,13 @@ static void AddDrawListToRenderList(ImVector& out_render_list, ImDr IM_ASSERT(draw_list->IdxBuffer.Size == 0 || draw_list->_IdxWritePtr == draw_list->IdxBuffer.Data + draw_list->IdxBuffer.Size); IM_ASSERT((int)draw_list->_VtxCurrentIdx == draw_list->VtxBuffer.Size); - // Check that draw_list doesn't use more vertices than indexable (default ImDrawIdx = 2 bytes = 64K vertices per window) + // Check that draw_list doesn't use more vertices than indexable in a single draw call (default ImDrawIdx = unsigned short = 2 bytes = 64K vertices per window) // If this assert triggers because you are drawing lots of stuff manually, you can: - // A) Add '#define ImDrawIdx unsigned int' in imconfig.h to raise the index size of 4 bytes. You'll need to handle the 4-bytes indices to your renderer. - // For example, the OpenGL example code detect index size at compile-time and does - // 'glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer_offset); - // B) If for some reason you cannot use 32-bit indices or don't want to, a workaround is to call BeginChild()/EndChild() because reaching the 64K limit to split your draw commands in multiple draw lists. + // A) Add '#define ImDrawIdx unsigned int' in imconfig.h to set the index size to 4 bytes. You'll need to handle the 4-bytes indices to your renderer. + // For example, the OpenGL example code detect index size at compile-time by doing: + // 'glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer_offset);' + // Your own engine or render API may use different parameters or function calls to specify index sizes. 2 and 4 bytes indices are generally supported by most API. + // B) If for some reason you cannot use 4 bytes indices or don't want to, a workaround is to call BeginChild()/EndChild() before reaching the 64K limit to split your draw commands in multiple draw lists. IM_ASSERT((draw_list->_VtxCurrentIdx >> (sizeof(ImDrawIdx)*8)) == 0); // Too many vertices in same ImDrawList. See comment above. out_render_list.push_back(draw_list); From a5e02109023bc5308ff0e0e72614cadfe24970c1 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 19 Jun 2017 21:19:48 +0200 Subject: [PATCH 080/921] Revert 978c84d2e9b733591431fed78d6e5ea78aa909df because int32 >> 32 tends to warns on some compilers/settings. Add ImU64 type. (#1184) --- imgui.cpp | 2 +- imgui.h | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index c86fe4751..79d4aa99d 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2610,7 +2610,7 @@ static void AddDrawListToRenderList(ImVector& out_render_list, ImDr // 'glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer_offset);' // Your own engine or render API may use different parameters or function calls to specify index sizes. 2 and 4 bytes indices are generally supported by most API. // B) If for some reason you cannot use 4 bytes indices or don't want to, a workaround is to call BeginChild()/EndChild() before reaching the 64K limit to split your draw commands in multiple draw lists. - IM_ASSERT((draw_list->_VtxCurrentIdx >> (sizeof(ImDrawIdx)*8)) == 0); // Too many vertices in same ImDrawList. See comment above. + IM_ASSERT(((ImU64)draw_list->_VtxCurrentIdx >> (sizeof(ImDrawIdx)*8)) == 0); // Too many vertices in same ImDrawList. See comment above. out_render_list.push_back(draw_list); GImGui->IO.MetricsRenderVertices += draw_list->VtxBuffer.Size; diff --git a/imgui.h b/imgui.h index 340856f8b..04e560563 100644 --- a/imgui.h +++ b/imgui.h @@ -79,6 +79,11 @@ typedef int ImGuiSelectableFlags; // flags for Selectable() // e typedef int ImGuiTreeNodeFlags; // flags for TreeNode*(), Collapsing*() // enum ImGuiTreeNodeFlags_ typedef int (*ImGuiTextEditCallback)(ImGuiTextEditCallbackData *data); typedef void (*ImGuiSizeConstraintCallback)(ImGuiSizeConstraintCallbackData* data); +#ifdef _MSC_VER +typedef unsigned __int64 ImU64; // 64-bit unsigned integer +#else +typedef unsigned long long ImU64; // 64-bit unsigned integer +#endif // Others helpers at bottom of the file: // class ImVector<> // Lightweight std::vector like class. From 1e981f00e522739ed0f612a50583e41db5d4d388 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 21 Jun 2017 13:50:31 +0200 Subject: [PATCH 081/921] Comments --- imgui.h | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/imgui.h b/imgui.h index 04e560563..288100e33 100644 --- a/imgui.h +++ b/imgui.h @@ -958,11 +958,11 @@ struct ImGuiTextBuffer // Helper: Simple Key->value storage // Typically you don't have to worry about this since a storage is held within each Window. -// We use it to e.g. store collapse state for a tree (Int 0/1), store color edit options. -// You can use it as custom user storage for temporary values. -// Declare your own storage if: +// We use it to e.g. store collapse state for a tree (Int 0/1), store color edit options. +// This is optimized for efficient reading (dichotomy into a contiguous buffer), rare writing (typically tied to user interactions) +// You can use it as custom user storage for temporary values. Declare your own storage if, for example: // - You want to manipulate the open/close state of a particular sub-tree in your interface (tree node uses Int 0/1 to store their state). -// - You want to store custom debug data easily without adding or editing structures in your code. +// - You want to store custom debug data easily without adding or editing structures in your code (probably not efficient, but convenient) // Types are NOT stored, so it is up to you to make sure your Key don't collide with different types. struct ImGuiStorage { @@ -1166,11 +1166,12 @@ struct ImDrawChannel // At the moment, each ImGui window contains its own ImDrawList but they could potentially be merged in the future. // If you want to add custom rendering within a window, you can use ImGui::GetWindowDrawList() to access the current draw list and add your own primitives. // You can interleave normal ImGui:: calls and adding primitives to the current draw list. -// All positions are in screen coordinates (0,0=top-left, 1 pixel per unit). Primitives are always added to the list and not culled (culling is done at render time and at a higher-level by ImGui:: functions). +// All positions are generally in pixel coordinates (top-left at (0,0), bottom-right at io.DisplaySize), however you are totally free to apply whatever transformation matrix to want to the data (if you apply such transformation you'll want to apply it to ClipRect as well) +// Primitives are always added to the list and not culled (culling is done at higher-level by ImGui:: functions). struct ImDrawList { // This is what you have to render - ImVector CmdBuffer; // Commands. Typically 1 command = 1 gpu draw call. + ImVector CmdBuffer; // Commands. Typically 1 command = 1 GPU draw call. ImVector IdxBuffer; // Index buffer. Each command consume ImDrawCmd::ElemCount of those ImVector VtxBuffer; // Vertex buffer. @@ -1261,7 +1262,7 @@ struct ImDrawData // Functions ImDrawData() { Valid = false; CmdLists = NULL; CmdListsCount = TotalVtxCount = TotalIdxCount = 0; } - IMGUI_API void DeIndexAllBuffers(); // For backward compatibility: convert all buffers from indexed to de-indexed, in case you cannot render indexed. Note: this is slow and most likely a waste of resources. Always prefer indexed rendering! + IMGUI_API void DeIndexAllBuffers(); // For backward compatibility or convenience: convert all buffers from indexed to de-indexed, in case you cannot render indexed. Note: this is slow and most likely a waste of resources. Always prefer indexed rendering! IMGUI_API void ScaleClipRects(const ImVec2& sc); // Helper to scale the ClipRect field of each ImDrawCmd. Use if your final output buffer is at a different scale than ImGui expects, or if there is a difference between your window resolution and framebuffer resolution. }; @@ -1280,7 +1281,7 @@ struct ImFontConfig bool MergeMode; // false // Merge into previous ImFont, so you can combine multiple inputs font into one ImFont (e.g. ASCII font + icons + Japanese glyphs). You may want to use GlyphOffset.y when merge font of different heights. // [Internal] - char Name[32]; // Name (strictly for debugging) + char Name[32]; // Name (strictly to ease debugging) ImFont* DstFont; IMGUI_API ImFontConfig(); @@ -1293,8 +1294,7 @@ struct ImFontConfig // 2. Call GetTexDataAsAlpha8() or GetTexDataAsRGBA32() to build and retrieve pixels data. // 3. Upload the pixels data into a texture within your graphics system. // 4. Call SetTexID(my_tex_id); and pass the pointer/identifier to your texture. This value will be passed back to you during rendering to identify the texture. -// 5. Call ClearTexData() to free textures memory on the heap. -// NB: If you use a 'glyph_ranges' array you need to make sure that your array persist up until the ImFont is cleared. We only copy the pointer, not the data. +// IMPORTANT: If you pass a 'glyph_ranges' array to AddFont*** functions, you need to make sure that your array persist up until the ImFont is build (when calling GetTextData*** or Build()). We only copy the pointer, not the data. struct ImFontAtlas { IMGUI_API ImFontAtlas(); @@ -1320,7 +1320,7 @@ struct ImFontAtlas void SetTexID(ImTextureID id) { TexID = id; } // Helpers to retrieve list of common Unicode ranges (2 value per range, values are inclusive, zero-terminated list) - // NB: Make sure that your string are UTF-8 and NOT in your local code page. See FAQ for details. + // NB: Make sure that your string are UTF-8 and NOT in your local code page. In C++11, you can create a UTF-8 string literally using the u8"Hello world" syntax. See FAQ for details. IMGUI_API const ImWchar* GetGlyphRangesDefault(); // Basic Latin, Extended Latin IMGUI_API const ImWchar* GetGlyphRangesKorean(); // Default + Korean characters IMGUI_API const ImWchar* GetGlyphRangesJapanese(); // Default + Hiragana, Katakana, Half-Width, Selection of 1946 Ideographs From d3f4309491517a4412b6738063ded96f61fa020f Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 24 Jun 2017 13:11:46 +0200 Subject: [PATCH 082/921] Comments about ImGuiStyleVar enum (#1198) --- imgui.cpp | 24 ++++++++++++------------ imgui.h | 30 ++++++++++++++++-------------- 2 files changed, 28 insertions(+), 26 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 79d4aa99d..4887a9150 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4748,18 +4748,18 @@ struct ImGuiStyleVarInfo static const ImGuiStyleVarInfo GStyleVarInfo[ImGuiStyleVar_Count_] = { - { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, Alpha) }, - { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowPadding) }, - { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowRounding) }, - { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowMinSize) }, - { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, ChildWindowRounding) }, - { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, FramePadding) }, - { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, FrameRounding) }, - { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, ItemSpacing) }, - { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, ItemInnerSpacing) }, - { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, IndentSpacing) }, - { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, GrabMinSize) }, - { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, ButtonTextAlign) }, + { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, Alpha) }, // ImGuiStyleVar_Alpha + { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowPadding) }, // ImGuiStyleVar_WindowPadding + { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowRounding) }, // ImGuiStyleVar_WindowRounding + { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowMinSize) }, // ImGuiStyleVar_WindowMinSize + { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, ChildWindowRounding) }, // ImGuiStyleVar_ChildWindowRounding + { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, FramePadding) }, // ImGuiStyleVar_FramePadding + { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, FrameRounding) }, // ImGuiStyleVar_FrameRounding + { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, ItemSpacing) }, // ImGuiStyleVar_ItemSpacing + { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, ItemInnerSpacing) }, // ImGuiStyleVar_ItemInnerSpacing + { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, IndentSpacing) }, // ImGuiStyleVar_IndentSpacing + { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, GrabMinSize) }, // ImGuiStyleVar_GrabMinSize + { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, ButtonTextAlign) }, // ImGuiStyleVar_ButtonTextAlign }; static const ImGuiStyleVarInfo* GetStyleVarInfo(ImGuiStyleVar idx) diff --git a/imgui.h b/imgui.h index 288100e33..008fdf113 100644 --- a/imgui.h +++ b/imgui.h @@ -636,22 +636,24 @@ enum ImGuiCol_ ImGuiCol_COUNT }; -// Enumeration for PushStyleVar() / PopStyleVar() -// NB: the enum only refers to fields of ImGuiStyle() which makes sense to be pushed/poped in UI code. Feel free to add others. +// Enumeration for PushStyleVar() / PopStyleVar() to temporarily modify the ImGuiStyle structure. +// NB: the enum only refers to fields of ImGuiStyle which makes sense to be pushed/poped inside UI code. During initialization, feel free to just poke into ImGuiStyle directly. +// NB: if changing this enum, you need to update the associated internal table GStyleVarInfo[] accordingly. This is where we link enum values to members offset/type. enum ImGuiStyleVar_ { - ImGuiStyleVar_Alpha, // float - ImGuiStyleVar_WindowPadding, // ImVec2 - ImGuiStyleVar_WindowRounding, // float - ImGuiStyleVar_WindowMinSize, // ImVec2 - ImGuiStyleVar_ChildWindowRounding, // float - ImGuiStyleVar_FramePadding, // ImVec2 - ImGuiStyleVar_FrameRounding, // float - ImGuiStyleVar_ItemSpacing, // ImVec2 - ImGuiStyleVar_ItemInnerSpacing, // ImVec2 - ImGuiStyleVar_IndentSpacing, // float - ImGuiStyleVar_GrabMinSize, // float - ImGuiStyleVar_ButtonTextAlign, // flags ImGuiAlign_* + // Enum name ......................// Member in ImGuiStyle structure (see ImGuiStyle for descriptions) + ImGuiStyleVar_Alpha, // float Alpha + ImGuiStyleVar_WindowPadding, // ImVec2 WindowPadding + ImGuiStyleVar_WindowRounding, // float WindowRounding + ImGuiStyleVar_WindowMinSize, // ImVec2 WindowMinSize + ImGuiStyleVar_ChildWindowRounding, // float ChildWindowRounding + ImGuiStyleVar_FramePadding, // ImVec2 FramePadding + ImGuiStyleVar_FrameRounding, // float FrameRounding + ImGuiStyleVar_ItemSpacing, // ImVec2 ItemSpacing + ImGuiStyleVar_ItemInnerSpacing, // ImVec2 ItemInnerSpacing + ImGuiStyleVar_IndentSpacing, // float IndentSpacing + ImGuiStyleVar_GrabMinSize, // float GrabMinSize + ImGuiStyleVar_ButtonTextAlign, // ImVec2 ButtonTextAlign ImGuiStyleVar_Count_ }; From e0aac34672d81ac7205c604087721faa3db4cb57 Mon Sep 17 00:00:00 2001 From: radius Date: Sun, 2 Jul 2017 11:21:24 -0500 Subject: [PATCH 083/921] fix compilation on MINGW --- examples/opengl3_example/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/opengl3_example/Makefile b/examples/opengl3_example/Makefile index 5d91708aa..d064a9059 100644 --- a/examples/opengl3_example/Makefile +++ b/examples/opengl3_example/Makefile @@ -39,7 +39,7 @@ ifeq ($(UNAME_S), Darwin) #APPLE CFLAGS = $(CXXFLAGS) endif -ifeq ($(UNAME_S), MINGW64_NT-6.3) +ifeq ($(findstring MINGW,$(UNAME_S)),MINGW) ECHO_MESSAGE = "Windows" LIBS = -lglfw3 -lgdi32 -lopengl32 -limm32 From d43695b74827185edeee21e8e2f83a3415680c8d Mon Sep 17 00:00:00 2001 From: radius Date: Sun, 2 Jul 2017 21:28:56 -0500 Subject: [PATCH 084/921] fix gl2 sample too --- examples/opengl2_example/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/opengl2_example/Makefile b/examples/opengl2_example/Makefile index 631abe4ba..b5953fc36 100644 --- a/examples/opengl2_example/Makefile +++ b/examples/opengl2_example/Makefile @@ -37,7 +37,7 @@ ifeq ($(UNAME_S), Darwin) #APPLE CFLAGS = $(CXXFLAGS) endif -ifeq ($(UNAME_S), MINGW64_NT-6.3) +ifeq ($(findstring MINGW,$(UNAME_S)),MINGW) ECHO_MESSAGE = "Windows" LIBS = -lglfw3 -lgdi32 -lopengl32 -limm32 From 8b6896faf9bf590cb2e88e9e914b10d1e46b4ef8 Mon Sep 17 00:00:00 2001 From: radius Date: Sun, 2 Jul 2017 21:33:13 -0500 Subject: [PATCH 085/921] add SDL GL3 makefile --- examples/opengl2_example/Makefile | 2 +- examples/opengl3_example/Makefile | 3 +- examples/sdl_opengl3_example/Makefile | 63 +++++++++++++++++++++++++++ 3 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 examples/sdl_opengl3_example/Makefile diff --git a/examples/opengl2_example/Makefile b/examples/opengl2_example/Makefile index b5953fc36..932aebede 100644 --- a/examples/opengl2_example/Makefile +++ b/examples/opengl2_example/Makefile @@ -1,6 +1,6 @@ # # Cross Platform Makefile -# Compatible with Ubuntu 14.04.1 and Mac OS X +# Compatible with MSYS2/MINGW, Ubuntu 14.04.1 and Mac OS X # # # if you using Mac OS X: diff --git a/examples/opengl3_example/Makefile b/examples/opengl3_example/Makefile index d064a9059..32343ed23 100644 --- a/examples/opengl3_example/Makefile +++ b/examples/opengl3_example/Makefile @@ -1,12 +1,13 @@ # # Cross Platform Makefile -# Compatible with Ubuntu 14.04.1 and Mac OS X +# Compatible with MSYS2/MINGW, Ubuntu 14.04.1 and Mac OS X # # # You will need GLFW (http://www.glfw.org) # # apt-get install libglfw-dev # Linux # brew install glfw # Mac OS X +# pacman -S --noconfirm --needed mingw-w64-x86_64-toolchain mingw-w64-x86_64-glfw # MSYS2 # #CXX = g++ diff --git a/examples/sdl_opengl3_example/Makefile b/examples/sdl_opengl3_example/Makefile new file mode 100644 index 000000000..e4aee574e --- /dev/null +++ b/examples/sdl_opengl3_example/Makefile @@ -0,0 +1,63 @@ +# +# Cross Platform Makefile +# Compatible with MSYS2/MINGW, Ubuntu 14.04.1 and Mac OS X +# +# +# You will need GLFW (http://www.glfw.org) +# +# apt-get install libglfw-dev # Linux +# brew install glfw # Mac OS X +# pacman -S --noconfirm --needed mingw-w64-x86_64-toolchain mingw-w64-x86_64-glfw # MSYS2 +# + +#CXX = g++ + +EXE = sdl_opengl3_example +OBJS = main.o imgui_impl_sdl_gl3.o +OBJS += ../../imgui.o ../../imgui_demo.o ../../imgui_draw.o +OBJS += ../libs/gl3w/GL/gl3w.o + +UNAME_S := $(shell uname -s) + + +ifeq ($(UNAME_S), Linux) #LINUX + ECHO_MESSAGE = "Linux" + LIBS = -lGL `pkg-config --static --libs glfw3` + + CXXFLAGS = -I../../ -I../libs/gl3w `pkg-config --cflags glfw3` + CXXFLAGS += -Wall -Wformat + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(UNAME_S), Darwin) #APPLE + ECHO_MESSAGE = "Mac OS X" + LIBS = -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo + #LIBS += -L/usr/local/lib -lglfw3 + LIBS += -L/usr/local/lib -lglfw + + CXXFLAGS = -I../../ -I../libs/gl3w -I/usr/local/include + CXXFLAGS += -Wall -Wformat + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(findstring MINGW,$(UNAME_S)),MINGW) + ECHO_MESSAGE = "Windows" + LIBS = -lgdi32 -lopengl32 -limm32 `pkg-config --static --libs sdl2` + + CXXFLAGS = -I../../ -I../libs/gl3w `pkg-config --cflags sdl2` + CXXFLAGS += -Wall -Wformat + CFLAGS = $(CXXFLAGS) +endif + + +.cpp.o: + $(CXX) $(CXXFLAGS) -c -o $@ $< + +all: $(EXE) + @echo Build complete for $(ECHO_MESSAGE) + +$(EXE): $(OBJS) + $(CXX) -o $(EXE) $(OBJS) $(CXXFLAGS) $(LIBS) + +clean: + rm $(EXE) $(OBJS) From afae9398cb2d0ed009328b5a6ff81b7db55af485 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 14 Jul 2017 17:49:42 +0800 Subject: [PATCH 086/921] Comments. Removed sort-of duplicate access to GImGui->Font in ImDrawList::AddText() so it's only in one place. --- imgui_draw.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index f11e1984d..e4a343b2c 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -933,7 +933,7 @@ void ImDrawList::AddText(const ImFont* font, float font_size, const ImVec2& pos, if (text_begin == text_end) return; - // Note: This is one of the few instance of breaking the encapsulation of ImDrawList, as we pull this from ImGui state, but it is just SO useful. + // IMPORTANT: This is one of the few instance of breaking the encapsulation of ImDrawList, as we pull this from ImGui state, but it is just SO useful. // Might just move Font/FontSize to ImDrawList? if (font == NULL) font = GImGui->Font; @@ -955,7 +955,7 @@ void ImDrawList::AddText(const ImFont* font, float font_size, const ImVec2& pos, void ImDrawList::AddText(const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end) { - AddText(GImGui->Font, GImGui->FontSize, pos, col, text_begin, text_end); + AddText(NULL, 0.0f, pos, col, text_begin, text_end); } void ImDrawList::AddImage(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& uv_a, const ImVec2& uv_b, ImU32 col) @@ -2167,8 +2167,7 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col } } - // We are NOT calling PrimRectUV() here because non-inlined causes too much overhead in a debug build. - // Inlined here: + // We are NOT calling PrimRectUV() here because non-inlined causes too much overhead in a debug builds. Inlined here: { idx_write[0] = (ImDrawIdx)(vtx_current_idx); idx_write[1] = (ImDrawIdx)(vtx_current_idx+1); idx_write[2] = (ImDrawIdx)(vtx_current_idx+2); idx_write[3] = (ImDrawIdx)(vtx_current_idx); idx_write[4] = (ImDrawIdx)(vtx_current_idx+2); idx_write[5] = (ImDrawIdx)(vtx_current_idx+3); From cb6d893a1308a06e1557cf4ef52168ef350224c6 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 14 Jul 2017 18:12:40 +0800 Subject: [PATCH 087/921] Comments (#383, #1224) --- imgui.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 4887a9150..e3c6f1abc 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -505,6 +505,7 @@ - input text multi-line: way to dynamically grow the buffer without forcing the user to initially allocate for worse case (follow up on #200) - input text multi-line: line numbers? status bar? (follow up on #200) - input text multi-line: behave better when user changes input buffer while editing is active (even though it is illegal behavior). namely, the change of buffer can create a scrollbar glitch (#725) + - input text multi-line: better horizontal scrolling support (#383, #1224) - input text: allow centering/positioning text so that ctrl+clicking Drag or Slider keeps the textual value at the same pixel position. - input number: optional range min/max for Input*() functions - input number: holding [-]/[+] buttons could increase the step speed non-linearly (or user-controlled) @@ -8130,7 +8131,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 select_start_offset.y = searches_result_line_number[1] * g.FontSize; } - // Calculate text height + // Store text height (note that we haven't calculated text width at all, see GitHub issues #383, #1224) if (is_multiline) text_size = ImVec2(size.x, line_count * g.FontSize); } From 03e6bfe84aeab5abbcdb87580b04ff71248dd152 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 14 Jul 2017 19:49:11 +0800 Subject: [PATCH 088/921] Comments --- imgui.h | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/imgui.h b/imgui.h index 008fdf113..f786f5d65 100644 --- a/imgui.h +++ b/imgui.h @@ -120,10 +120,12 @@ namespace ImGui IMGUI_API void NewFrame(); // start a new ImGui frame, you can submit any command from this point until NewFrame()/Render(). IMGUI_API void Render(); // ends the ImGui frame, finalize rendering data, then call your io.RenderDrawListsFn() function if set. IMGUI_API void Shutdown(); - IMGUI_API void ShowUserGuide(); // help block - IMGUI_API void ShowStyleEditor(ImGuiStyle* ref = NULL); // style editor block. you can pass in a reference ImGuiStyle structure to compare to, revert to and save to (else it uses the default style) - IMGUI_API void ShowTestWindow(bool* p_open = NULL); // test window demonstrating ImGui features - IMGUI_API void ShowMetricsWindow(bool* p_open = NULL); // metrics window for debugging ImGui (browse draw commands, individual vertices, window list, etc.) + + // Demo/Debug/Info + IMGUI_API void ShowTestWindow(bool* p_open = NULL); // create demo/test window. demonstrate most ImGui features. call this to learn about the library! try to make it always available in your application! + IMGUI_API void ShowMetricsWindow(bool* p_open = NULL); // create metrics window. display ImGui internals: browse window list, draw commands, individual vertices, basic internal state, etc. + IMGUI_API void ShowStyleEditor(ImGuiStyle* ref = NULL); // add style editor block (not a window). you can pass in a reference ImGuiStyle structure to compare to, revert to and save to (else it uses the default style) + IMGUI_API void ShowUserGuide(); // add basic help/info block (not a window): how to manipulate ImGui as a end-user (mouse/keyboard controls). // Window IMGUI_API bool Begin(const char* name, bool* p_open = NULL, ImGuiWindowFlags flags = 0); // push window to the stack and start appending to it. see .cpp for details. return false when window is collapsed, so you can early out in your code. 'bool* p_open' creates a widget on the upper-right to close the window (which sets your bool to false). @@ -467,7 +469,7 @@ namespace ImGui IMGUI_API ImGuiContext* GetCurrentContext(); IMGUI_API void SetCurrentContext(ImGuiContext* ctx); - // Obsolete (will be removed) + // Obsolete functions (Will be removed! Also see 'API BREAKING CHANGES' section in imgui.cpp) #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS static inline bool CollapsingHeader(const char* label, const char* str_id, bool framed = true, bool default_open = false) { (void)str_id; (void)framed; ImGuiTreeNodeFlags default_open_flags = 1<<5; return CollapsingHeader(label, (default_open ? default_open_flags : 0)); } // OBSOLETE 1.49+ static inline ImFont* GetWindowFont() { return GetFont(); } // OBSOLETE 1.48+ From 0fe5728971ebca1d2b59287e55adc297159ae561 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 15 Jul 2017 13:07:43 +0800 Subject: [PATCH 089/921] Examples: SDL+GL3: Makefile fix for Linux (#1229, #1209) --- examples/sdl_opengl3_example/Makefile | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/examples/sdl_opengl3_example/Makefile b/examples/sdl_opengl3_example/Makefile index e4aee574e..82cbcce00 100644 --- a/examples/sdl_opengl3_example/Makefile +++ b/examples/sdl_opengl3_example/Makefile @@ -22,9 +22,9 @@ UNAME_S := $(shell uname -s) ifeq ($(UNAME_S), Linux) #LINUX ECHO_MESSAGE = "Linux" - LIBS = -lGL `pkg-config --static --libs glfw3` + LIBS = -lGL -ldl `sdl2-config --libs` - CXXFLAGS = -I../../ -I../libs/gl3w `pkg-config --cflags glfw3` + CXXFLAGS = -I../../ -I../libs/gl3w `sdl2-config --cflags` CXXFLAGS += -Wall -Wformat CFLAGS = $(CXXFLAGS) endif @@ -32,8 +32,9 @@ endif ifeq ($(UNAME_S), Darwin) #APPLE ECHO_MESSAGE = "Mac OS X" LIBS = -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo + # FIXME: Missing SDL2 libs/includes #LIBS += -L/usr/local/lib -lglfw3 - LIBS += -L/usr/local/lib -lglfw + #LIBS += -L/usr/local/lib -lglfw CXXFLAGS = -I../../ -I../libs/gl3w -I/usr/local/include CXXFLAGS += -Wall -Wformat From 358e667b7aa340dee58bf9a3e9a6f0955fc6d93c Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 15 Jul 2017 13:13:09 +0800 Subject: [PATCH 090/921] Travis: Adding the SDL+GL3 project on the Travis build setup (for both Linux and OSX). Examples: SDL+GL3: Makefile blind fix for OSX (untested) (#1229, #1209) --- .travis.yml | 6 +++--- examples/sdl_opengl3_example/Makefile | 7 ++----- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index ccdb19429..005b6f832 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,10 +9,10 @@ compiler: - clang before_install: - - if [ $TRAVIS_OS_NAME == linux ]; then sudo add-apt-repository -y ppa:pyglfw/pyglfw && sudo apt-get update -qq && sudo apt-get install -y --no-install-recommends libglfw3-dev libxrandr-dev libxi-dev libxxf86vm-dev; fi - - if [ $TRAVIS_OS_NAME == osx ]; then brew update && brew install glfw3; fi + - if [ $TRAVIS_OS_NAME == linux ]; then sudo add-apt-repository -y ppa:pyglfw/pyglfw && sudo apt-get update -qq && sudo apt-get install -y --no-install-recommends libglfw3-dev libxrandr-dev libxi-dev libxxf86vm-dev libsdl2-dev; fi + - if [ $TRAVIS_OS_NAME == osx ]; then brew update && brew install glfw3 && brew install sdl2; fi script: - make -C examples/opengl2_example - make -C examples/opengl3_example - + - make -C examples/sdl_opengl3_example diff --git a/examples/sdl_opengl3_example/Makefile b/examples/sdl_opengl3_example/Makefile index 82cbcce00..5fd3321b3 100644 --- a/examples/sdl_opengl3_example/Makefile +++ b/examples/sdl_opengl3_example/Makefile @@ -31,12 +31,9 @@ endif ifeq ($(UNAME_S), Darwin) #APPLE ECHO_MESSAGE = "Mac OS X" - LIBS = -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo - # FIXME: Missing SDL2 libs/includes - #LIBS += -L/usr/local/lib -lglfw3 - #LIBS += -L/usr/local/lib -lglfw + LIBS = -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo -framework SDL2 - CXXFLAGS = -I../../ -I../libs/gl3w -I/usr/local/include + CXXFLAGS = -I../../ -I../libs/gl3w -I/usr/local/include -I /Library/Frameworks/SDL2.framework/Headers CXXFLAGS += -Wall -Wformat CFLAGS = $(CXXFLAGS) endif From 52df0032a501aca41eac4857e0eee67133f5c0ad Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 15 Jul 2017 13:19:13 +0800 Subject: [PATCH 091/921] Travis: Blind fix for SDL+GL3 project on the Travis build setup. Examples: SDL+GL3: Makefile blind fix for OSX (untested) (#1229, #1209) --- .travis.yml | 2 +- examples/sdl_opengl3_example/Makefile | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 005b6f832..044b87a96 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,7 @@ compiler: - clang before_install: - - if [ $TRAVIS_OS_NAME == linux ]; then sudo add-apt-repository -y ppa:pyglfw/pyglfw && sudo apt-get update -qq && sudo apt-get install -y --no-install-recommends libglfw3-dev libxrandr-dev libxi-dev libxxf86vm-dev libsdl2-dev; fi + - if [ $TRAVIS_OS_NAME == linux ]; then sudo add-apt-repository -y ppa:pyglfw/pyglfw && sudo apt-add-repository --yes ppa:zoogie/sdl2-snapshots && sudo apt-get update -qq && sudo apt-get install -y --no-install-recommends libglfw3-dev libxrandr-dev libxi-dev libxxf86vm-dev libsdl2-dev; fi - if [ $TRAVIS_OS_NAME == osx ]; then brew update && brew install glfw3 && brew install sdl2; fi script: diff --git a/examples/sdl_opengl3_example/Makefile b/examples/sdl_opengl3_example/Makefile index 5fd3321b3..a494f93f1 100644 --- a/examples/sdl_opengl3_example/Makefile +++ b/examples/sdl_opengl3_example/Makefile @@ -31,9 +31,9 @@ endif ifeq ($(UNAME_S), Darwin) #APPLE ECHO_MESSAGE = "Mac OS X" - LIBS = -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo -framework SDL2 + LIBS = -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo `sdl2-config --libs` - CXXFLAGS = -I../../ -I../libs/gl3w -I/usr/local/include -I /Library/Frameworks/SDL2.framework/Headers + CXXFLAGS = -I../../ -I../libs/gl3w -I/usr/local/include `sdl2-config --cflags` CXXFLAGS += -Wall -Wformat CFLAGS = $(CXXFLAGS) endif From be7fa76fddab090bc179bc5782695588bbdb4d02 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 15 Jul 2017 13:27:44 +0800 Subject: [PATCH 092/921] Fixed Clang unknown-warning-ignored warning by ignoring it..... we are truly living in a special time (#1090) --- imgui.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/imgui.cpp b/imgui.cpp index e3c6f1abc..a1c0cffc4 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -641,6 +641,7 @@ // Clang warnings with -Weverything #ifdef __clang__ +#pragma clang diagnostic ignored "-Wunknown-pragmas" // warning : unknown warning group '-Wformat-pedantic *' // not all warnings are known by all clang versions.. so ignoring warnings triggers new warnings on some configuration. great! #pragma clang diagnostic ignored "-Wold-style-cast" // warning : use of old-style cast // yes, they are more terse. #pragma clang diagnostic ignored "-Wfloat-equal" // warning : comparing floating point with == or != is unsafe // storing and comparing against same constants (typically 0.0f) is ok. #pragma clang diagnostic ignored "-Wformat-nonliteral" // warning : format string is not a string literal // passing non-literal to vsnformat(). yes, user passing incorrect format strings can crash the code. From 8261d9ff30b0ef409c2ebdc324b2f5234518e5e4 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 15 Jul 2017 17:11:53 +0800 Subject: [PATCH 093/921] Comments (#1172, #1231) --- imgui.h | 1 + imgui_demo.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/imgui.h b/imgui.h index f786f5d65..deb532930 100644 --- a/imgui.h +++ b/imgui.h @@ -1154,6 +1154,7 @@ struct ImDrawVert // You can override the vertex format layout by defining IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT in imconfig.h // The code expect ImVec2 pos (8 bytes), ImVec2 uv (8 bytes), ImU32 col (4 bytes), but you can re-order them or add other fields as needed to simplify integration in your engine. // The type has to be described within the macro (you can either declare the struct or use a typedef) +// NOTE: IMGUI DOESN'T CLEAR THE STRUCTURE AND DOESN'T CALL A CONSTRUCTOR. IF YOU ADD EXTRA FIELDS (SUCH AS A 'Z' COORDINATES) YOU WILL NEED TO CLEAR THE FIELD DURING RENDER OR TO IGNORE IT. IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT; #endif diff --git a/imgui_demo.cpp b/imgui_demo.cpp index b198cd174..0dbed6141 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -15,7 +15,7 @@ #include // toupper, isprint #include // sqrtf, powf, cosf, sinf, floorf, ceilf #include // vsnprintf, sscanf, printf -#include // NULL, malloc, free, qsort, atoi +#include // NULL, malloc, free, atoi #if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier #include // intptr_t #else From f3cf5e0322c9453fe63ce63019485203892c111b Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 15 Jul 2017 17:50:01 +0800 Subject: [PATCH 094/921] Examples: SDL+GL3: Fixed old comments (#1229) --- examples/sdl_opengl3_example/Makefile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/sdl_opengl3_example/Makefile b/examples/sdl_opengl3_example/Makefile index a494f93f1..364ca1239 100644 --- a/examples/sdl_opengl3_example/Makefile +++ b/examples/sdl_opengl3_example/Makefile @@ -3,11 +3,11 @@ # Compatible with MSYS2/MINGW, Ubuntu 14.04.1 and Mac OS X # # -# You will need GLFW (http://www.glfw.org) +# You will need SDL2 (http://www.libsdl.org) # -# apt-get install libglfw-dev # Linux -# brew install glfw # Mac OS X -# pacman -S --noconfirm --needed mingw-w64-x86_64-toolchain mingw-w64-x86_64-glfw # MSYS2 +# apt-get install libsdl2-dev # Linux +# brew install sdl2 # Mac OS X +# pacman -S mingw-w64-i686-SDL # MSYS2 # #CXX = g++ From 1987e23ce56ae673a9e515b5d5fcb55a4b3345c9 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 15 Jul 2017 17:52:52 +0800 Subject: [PATCH 095/921] ImDrawList::PrimReserve() minor renaming of locals to make things clearer --- imgui_draw.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index e4a343b2c..fa6838a6b 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -359,13 +359,13 @@ void ImDrawList::PrimReserve(int idx_count, int vtx_count) ImDrawCmd& draw_cmd = CmdBuffer.Data[CmdBuffer.Size-1]; draw_cmd.ElemCount += idx_count; - int vtx_buffer_size = VtxBuffer.Size; - VtxBuffer.resize(vtx_buffer_size + vtx_count); - _VtxWritePtr = VtxBuffer.Data + vtx_buffer_size; + int vtx_buffer_old_size = VtxBuffer.Size; + VtxBuffer.resize(vtx_buffer_old_size + vtx_count); + _VtxWritePtr = VtxBuffer.Data + vtx_buffer_old_size; - int idx_buffer_size = IdxBuffer.Size; - IdxBuffer.resize(idx_buffer_size + idx_count); - _IdxWritePtr = IdxBuffer.Data + idx_buffer_size; + int idx_buffer_old_size = IdxBuffer.Size; + IdxBuffer.resize(idx_buffer_old_size + idx_count); + _IdxWritePtr = IdxBuffer.Data + idx_buffer_old_size; } // Fully unrolled with inline call to keep our debug builds decently fast. From 41f944238b36242eb124846b24d979452940c7fa Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 15 Jul 2017 18:03:43 +0800 Subject: [PATCH 096/921] Comments about GlyphExtraSpacing (#1192) --- imgui.cpp | 3 ++- imgui.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index a1c0cffc4..864298a68 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -430,7 +430,8 @@ ImFontConfig config; config.OversampleH = 3; config.OversampleV = 1; - config.GlyphExtraSpacing.x = 1.0f; + config.GlyphOffset.y -= 2.0f; // Move everything by 2 pixels up + config.GlyphExtraSpacing.x = 1.0f; // Increase spacing between characters io.Fonts->LoadFromFileTTF("myfontfile.ttf", size_pixels, &config); // Combine multiple fonts into one (e.g. for icon fonts) diff --git a/imgui.h b/imgui.h index deb532930..7b892b83f 100644 --- a/imgui.h +++ b/imgui.h @@ -1280,7 +1280,7 @@ struct ImFontConfig float SizePixels; // // Size in pixels for rasterizer int OversampleH, OversampleV; // 3, 1 // Rasterize at higher quality for sub-pixel positioning. We don't use sub-pixel positions on the Y axis. bool PixelSnapH; // false // Align every glyph to pixel boundary. Useful e.g. if you are merging a non-pixel aligned font with the default font. If enabled, you can set OversampleH/V to 1. - ImVec2 GlyphExtraSpacing; // 0, 0 // Extra spacing (in pixels) between glyphs + ImVec2 GlyphExtraSpacing; // 0, 0 // Extra spacing (in pixels) between glyphs. Only X axis is supported for now. ImVec2 GlyphOffset; // 0, 0 // Offset all glyphs from this font input const ImWchar* GlyphRanges; // // Pointer to a user-provided list of Unicode range (2 value per range, values are inclusive, zero-terminated list). THE ARRAY DATA NEEDS TO PERSIST AS LONG AS THE FONT IS ALIVE. bool MergeMode; // false // Merge into previous ImFont, so you can combine multiple inputs font into one ImFont (e.g. ASCII font + icons + Japanese glyphs). You may want to use GlyphOffset.y when merge font of different heights. From d1145e990d14734961532847df72cf417855337b Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 16 Jul 2017 13:07:11 +0800 Subject: [PATCH 097/921] Comments tweak (#1231) --- imgui.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.h b/imgui.h index 7b892b83f..13720fbff 100644 --- a/imgui.h +++ b/imgui.h @@ -1154,7 +1154,7 @@ struct ImDrawVert // You can override the vertex format layout by defining IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT in imconfig.h // The code expect ImVec2 pos (8 bytes), ImVec2 uv (8 bytes), ImU32 col (4 bytes), but you can re-order them or add other fields as needed to simplify integration in your engine. // The type has to be described within the macro (you can either declare the struct or use a typedef) -// NOTE: IMGUI DOESN'T CLEAR THE STRUCTURE AND DOESN'T CALL A CONSTRUCTOR. IF YOU ADD EXTRA FIELDS (SUCH AS A 'Z' COORDINATES) YOU WILL NEED TO CLEAR THE FIELD DURING RENDER OR TO IGNORE IT. +// NOTE: IMGUI DOESN'T CLEAR THE STRUCTURE AND DOESN'T CALL A CONSTRUCTOR SO ANY CUSTOM FIELD WILL BE UNINITIALIZED. IF YOU ADD EXTRA FIELDS (SUCH AS A 'Z' COORDINATES) YOU WILL NEED TO CLEAR THEM DURING RENDER OR TO IGNORE THEM. IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT; #endif From 25f3717a1cb5c1a077438ce61bda44c6de1f5556 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 20 Jul 2017 20:57:46 +0800 Subject: [PATCH 098/921] Removed IsPosHoveringAnyWindow() which was severaly broken and misleading (most people want to use io.WantCaptureMouse). Added dummy function with assert for now. (#1237) --- imgui.cpp | 6 +----- imgui.h | 2 +- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 864298a68..c3bb973ea 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -152,6 +152,7 @@ Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. Also read releases logs https://github.com/ocornut/imgui/releases for more details. + - 2017/07/20 (1.51) - Removed IsPosHoveringAnyWindow(ImVec2), which was partly broken and misleading. ASSERT + redirect user to io.WantCaptureMouse - 2017/05/26 (1.50) - Removed ImFontConfig::MergeGlyphCenterV in favor of a more multipurpose ImFontConfig::GlyphOffset. - 2017/05/01 (1.50) - Renamed ImDrawList::PathFill() (rarely used directly) to ImDrawList::PathFillConvex() for clarity. - 2016/11/06 (1.50) - BeginChild(const char*) now applies the stack id to the provided label, consistently with other functions as it should always have been. It shouldn't affect you unless (extremely unlikely) you were appending multiple times to a same child from different locations of the stack id. If that's the case, generate an id with GetId() and use it instead of passing string to BeginChild(). @@ -3146,11 +3147,6 @@ bool ImGui::IsMouseHoveringAnyWindow() return g.HoveredWindow != NULL; } -bool ImGui::IsPosHoveringAnyWindow(const ImVec2& pos) -{ - return FindHoveredWindow(pos, false) != NULL; -} - static bool IsKeyPressedMap(ImGuiKey key, bool repeat) { const int key_index = GImGui->IO.KeyMap[key]; diff --git a/imgui.h b/imgui.h index 13720fbff..ffaf67ac1 100644 --- a/imgui.h +++ b/imgui.h @@ -417,7 +417,6 @@ namespace ImGui IMGUI_API bool IsRootWindowOrAnyChildHovered(); // is current root window or any of its child (including current window) hovered and hoverable (not blocked by a popup) IMGUI_API bool IsRectVisible(const ImVec2& size); // test if rectangle (of given size, starting from cursor position) is visible / not clipped. IMGUI_API bool IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max); // test if rectangle (in screen space) is visible / not clipped. to perform coarse clipping on user's side. - IMGUI_API bool IsPosHoveringAnyWindow(const ImVec2& pos); // is given position hovering any active imgui window IMGUI_API float GetTime(); IMGUI_API int GetFrameCount(); IMGUI_API const char* GetStyleColName(ImGuiCol idx); @@ -471,6 +470,7 @@ namespace ImGui // Obsolete functions (Will be removed! Also see 'API BREAKING CHANGES' section in imgui.cpp) #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS + static inline bool IsPosHoveringAnyWindow(const ImVec2&) { IM_ASSERT(0); return false; } // OBSOLETE 1.51+. This was partly broken. You probably wanted to use ImGui::GetIO().WantCaptureMouse instead. static inline bool CollapsingHeader(const char* label, const char* str_id, bool framed = true, bool default_open = false) { (void)str_id; (void)framed; ImGuiTreeNodeFlags default_open_flags = 1<<5; return CollapsingHeader(label, (default_open ? default_open_flags : 0)); } // OBSOLETE 1.49+ static inline ImFont* GetWindowFont() { return GetFont(); } // OBSOLETE 1.48+ static inline float GetWindowFontSize() { return GetFontSize(); } // OBSOLETE 1.48+ From 85d9c8fb460107e09c9c7c90a5fda285d45eceb9 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 20 Jul 2017 21:25:31 +0800 Subject: [PATCH 099/921] Internals: renaming IndexWithinParent to OrderWithinParent --- imgui.cpp | 8 ++++---- imgui_internal.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index c3bb973ea..7c6011d49 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1776,7 +1776,7 @@ ImGuiWindow::ImGuiWindow(const char* name) MoveId = GetID("#MOVE"); Flags = 0; - IndexWithinParent = 0; + OrderWithinParent = 0; PosFloat = Pos = ImVec2(0.0f, 0.0f); Size = SizeFull = ImVec2(0.0f, 0.0f); SizeContents = SizeContentsExplicit = ImVec2(0.0f, 0.0f); @@ -2568,7 +2568,7 @@ static int ChildWindowComparer(const void* lhs, const void* rhs) return d; if (int d = (a->Flags & ImGuiWindowFlags_ComboBox) - (b->Flags & ImGuiWindowFlags_ComboBox)) return d; - return (a->IndexWithinParent - b->IndexWithinParent); + return (a->OrderWithinParent - b->OrderWithinParent); } static void AddWindowToSortedBuffer(ImVector& out_sorted_windows, ImGuiWindow* window) @@ -3991,7 +3991,7 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us if (first_begin_of_the_frame) { window->Active = true; - window->IndexWithinParent = 0; + window->OrderWithinParent = 0; window->BeginCount = 0; window->ClipRect = ImVec4(-FLT_MAX,-FLT_MAX,+FLT_MAX,+FLT_MAX); window->LastFrameActive = current_frame; @@ -4111,7 +4111,7 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us // Position child window if (flags & ImGuiWindowFlags_ChildWindow) { - window->IndexWithinParent = parent_window->DC.ChildWindows.Size; + window->OrderWithinParent = parent_window->DC.ChildWindows.Size; parent_window->DC.ChildWindows.push_back(window); } if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Popup)) diff --git a/imgui_internal.h b/imgui_internal.h index f936f7237..ce91dff48 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -620,7 +620,7 @@ struct IMGUI_API ImGuiWindow char* Name; ImGuiID ID; // == ImHash(Name) ImGuiWindowFlags Flags; // See enum ImGuiWindowFlags_ - int IndexWithinParent; // Order within immediate parent window, if we are a child window. Otherwise 0. + int OrderWithinParent; // Order within immediate parent window, if we are a child window. Otherwise 0. ImVec2 PosFloat; ImVec2 Pos; // Position rounded-up to nearest pixel ImVec2 Size; // Current size (==SizeFull or collapsed title bar size) From e4007f7145161836d6880529b7a98ecdda0c8041 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 20 Jul 2017 22:30:56 +0800 Subject: [PATCH 100/921] Internals: Move GetVisibleRect() a few functions above so it gets to hang out with its peers. --- imgui.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 7c6011d49..8fa829625 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3380,6 +3380,14 @@ ImVec2 ImGui::CalcItemRectClosestPoint(const ImVec2& pos, bool on_edge, float ou return rect.GetClosestPoint(pos, on_edge); } +static ImRect GetVisibleRect() +{ + ImGuiContext& g = *GImGui; + if (g.IO.DisplayVisibleMin.x != g.IO.DisplayVisibleMax.x && g.IO.DisplayVisibleMin.y != g.IO.DisplayVisibleMax.y) + return ImRect(g.IO.DisplayVisibleMin, g.IO.DisplayVisibleMax); + return ImRect(0.0f, 0.0f, g.IO.DisplaySize.x, g.IO.DisplaySize.y); +} + // Tooltip is stored and turned into a BeginTooltip()/EndTooltip() sequence at the end of the frame. Each call override previous value. void ImGui::SetTooltipV(const char* fmt, va_list args) { @@ -3395,14 +3403,6 @@ void ImGui::SetTooltip(const char* fmt, ...) va_end(args); } -static ImRect GetVisibleRect() -{ - ImGuiContext& g = *GImGui; - if (g.IO.DisplayVisibleMin.x != g.IO.DisplayVisibleMax.x && g.IO.DisplayVisibleMin.y != g.IO.DisplayVisibleMax.y) - return ImRect(g.IO.DisplayVisibleMin, g.IO.DisplayVisibleMax); - return ImRect(0.0f, 0.0f, g.IO.DisplaySize.x, g.IO.DisplaySize.y); -} - void ImGui::BeginTooltip() { ImGuiWindowFlags flags = ImGuiWindowFlags_Tooltip|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_AlwaysAutoResize; From 100d30a0a1b058a8ef8350d5242c30e5ca0fa5e8 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 20 Jul 2017 23:12:58 +0800 Subject: [PATCH 101/921] Comments about IMGUI_DISABLE_TEST_WINDOWS (#1240, #169) --- imconfig.h | 3 ++- imgui_demo.cpp | 13 ++++++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/imconfig.h b/imconfig.h index 1daa25406..19911acce 100644 --- a/imconfig.h +++ b/imconfig.h @@ -20,7 +20,8 @@ //#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCS //#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCS -//---- Don't implement help and test window functionality (ShowUserGuide()/ShowStyleEditor()/ShowTestWindow() methods will be empty) +//---- Don't implement test window functionality (ShowTestWindow()/ShowStyleEditor()/ShowUserGuide() methods will be empty) +//---- It is very strongly recommended to NOT disable the test windows. Please read the comment at the top of imgui_demo.cpp to learn why. //#define IMGUI_DISABLE_TEST_WINDOWS //---- Don't define obsolete functions names diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 0dbed6141..f2d03396c 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -2,10 +2,17 @@ // (demo code) // Message to the person tempted to delete this file when integrating ImGui into their code base: -// Do NOT remove this file from your project! It is useful reference code that you and other users will want to refer to. +// Don't do it! Do NOT remove this file from your project! It is useful reference code that you and other users will want to refer to. // Everything in this file will be stripped out by the linker if you don't call ImGui::ShowTestWindow(). -// During development, you can call ImGui::ShowTestWindow() in your code to learn about various features of ImGui. -// Removing this file from your project is hindering your access to documentation, likely leading you to poorer usage of the library. +// During development, you can call ImGui::ShowTestWindow() in your code to learn about various features of ImGui. Have it wired in a debug menu! +// Removing this file from your project is hindering access to documentation for everyone in your team, likely leading you to poorer usage of the library. + +// Note that you can #define IMGUI_DISABLE_TEST_WINDOWS in imconfig.h for the same effect. +// If you want to link core ImGui in your public builds but not those test windows, #define IMGUI_DISABLE_TEST_WINDOWS in imconfig.h and those functions will be empty. +// For any other case, if you have ImGui available you probably want this to be available for reference and execution. + +// Thank you, +// -Your beloved friend, imgui_demo.cpp (that you won't delete) #if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) #define _CRT_SECURE_NO_WARNINGS From 138a9dbaeb14277532fb448d9a1e8a215c520e2c Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 21 Jul 2017 02:21:48 +0800 Subject: [PATCH 102/921] Tooltip: SetTooltip() is expanded immediately into a window, honoring current font / styling setting. Add internal mechanism to override tooltips (not exposed in BeginTooltip yet because bools are evil) (#862) --- imgui.cpp | 36 ++++++++++++++++++++++-------------- imgui.h | 4 ++-- imgui_internal.h | 4 ++-- 3 files changed, 26 insertions(+), 18 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 8fa829625..7ca66c79f 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2157,7 +2157,7 @@ void ImGui::NewFrame() g.Time += g.IO.DeltaTime; g.FrameCount += 1; - g.Tooltip[0] = '\0'; + g.TooltipOverrideCount = 0; g.OverlayDrawList.Clear(); g.OverlayDrawList.PushTextureID(g.IO.Fonts->TexID); g.OverlayDrawList.PushClipRectFullScreen(); @@ -2657,14 +2657,6 @@ void ImGui::EndFrame() IM_ASSERT(g.Initialized); // Forgot to call ImGui::NewFrame() IM_ASSERT(g.FrameCountEnded != g.FrameCount); // ImGui::EndFrame() called multiple times, or forgot to call ImGui::NewFrame() again - // Render tooltip - if (g.Tooltip[0]) - { - ImGui::BeginTooltip(); - ImGui::TextUnformatted(g.Tooltip); - ImGui::EndTooltip(); - } - // Notify OS when our Input Method Editor cursor has moved (e.g. CJK inputs using Microsoft IME) if (g.IO.ImeSetInputScreenPosFn && ImLengthSqr(g.OsImePosRequest - g.OsImePosSet) > 0.0001f) { @@ -3388,11 +3380,28 @@ static ImRect GetVisibleRect() return ImRect(0.0f, 0.0f, g.IO.DisplaySize.x, g.IO.DisplaySize.y); } -// Tooltip is stored and turned into a BeginTooltip()/EndTooltip() sequence at the end of the frame. Each call override previous value. -void ImGui::SetTooltipV(const char* fmt, va_list args) +// Not exposed publicly as BeginTooltip() because bool parameters are evil. Let's see if other needs arise first. +static void BeginTooltipEx(bool override_previous_tooltip) { ImGuiContext& g = *GImGui; - ImFormatStringV(g.Tooltip, IM_ARRAYSIZE(g.Tooltip), fmt, args); + char window_name[16]; + ImFormatString(window_name, IM_ARRAYSIZE(window_name), "##Tooltip%02d", g.TooltipOverrideCount); + if (override_previous_tooltip) + if (ImGuiWindow* window = ImGui::FindWindowByName(window_name)) + if (window->Active) + { + // Hide previous tooltips. We can't easily "reset" the content of a window so we create a new one. + window->HiddenFrames = 1; + ImFormatString(window_name, IM_ARRAYSIZE(window_name), "##Tooltip%02d", ++g.TooltipOverrideCount); + } + ImGui::Begin(window_name, NULL, ImGuiWindowFlags_Tooltip|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_AlwaysAutoResize); +} + +void ImGui::SetTooltipV(const char* fmt, va_list args) +{ + BeginTooltipEx(true); + TextV(fmt, args); + EndTooltip(); } void ImGui::SetTooltip(const char* fmt, ...) @@ -3405,8 +3414,7 @@ void ImGui::SetTooltip(const char* fmt, ...) void ImGui::BeginTooltip() { - ImGuiWindowFlags flags = ImGuiWindowFlags_Tooltip|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_AlwaysAutoResize; - ImGui::Begin("##Tooltip", NULL, flags); + BeginTooltipEx(false); } void ImGui::EndTooltip() diff --git a/imgui.h b/imgui.h index ffaf67ac1..2b37c5bea 100644 --- a/imgui.h +++ b/imgui.h @@ -361,9 +361,9 @@ namespace ImGui IMGUI_API void ValueColor(const char* prefix, ImU32 v); // Tooltips - IMGUI_API void SetTooltip(const char* fmt, ...) IM_PRINTFARGS(1); // set tooltip under mouse-cursor, typically use with ImGui::IsHovered(). last call wins + IMGUI_API void SetTooltip(const char* fmt, ...) IM_PRINTFARGS(1); // set text tooltip under mouse-cursor, typically use with ImGui::IsItemHovered(). overidde any previous call to SetTooltip(). IMGUI_API void SetTooltipV(const char* fmt, va_list args); - IMGUI_API void BeginTooltip(); // use to create full-featured tooltip windows that aren't just text + IMGUI_API void BeginTooltip(); // begin/append a tooltip window. to create full-featured tooltip (with any kind of contents). IMGUI_API void EndTooltip(); // Menus diff --git a/imgui_internal.h b/imgui_internal.h index ce91dff48..9a5e147d1 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -437,7 +437,7 @@ struct ImGuiContext float DragSpeedScaleSlow; float DragSpeedScaleFast; ImVec2 ScrollbarClickDeltaToGrabCenter; // Distance between mouse and center of grab box, normalized in parent space. Use storage? - char Tooltip[1024]; + int TooltipOverrideCount; char* PrivateClipboard; // If no custom clipboard handler is defined ImVec2 OsImePosRequest, OsImePosSet; // Cursor position request & last passed to the OS Input Method Editor @@ -506,7 +506,7 @@ struct ImGuiContext DragSpeedScaleSlow = 0.01f; DragSpeedScaleFast = 10.0f; ScrollbarClickDeltaToGrabCenter = ImVec2(0.0f, 0.0f); - memset(Tooltip, 0, sizeof(Tooltip)); + TooltipOverrideCount = 0; PrivateClipboard = NULL; OsImePosRequest = OsImePosSet = ImVec2(-1.0f, -1.0f); From 97bedd704c495b0759260045744b837e645ea70e Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 21 Jul 2017 03:06:25 +0800 Subject: [PATCH 103/921] Better, unified color tooltip (#346) --- imgui.cpp | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 696de7bc2..91c382bc8 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -8976,6 +8976,23 @@ void ImGui::EndMenu() EndPopup(); } +static void ColorTooltip(const float* col, ImGuiColorEditFlags flags) +{ + ImGuiContext& g = *GImGui; + int cr = IM_F32_TO_INT8_SAT(col[0]), cg = IM_F32_TO_INT8_SAT(col[1]), cb = IM_F32_TO_INT8_SAT(col[2]), ca = (flags & ImGuiColorEditFlags_Alpha) ? IM_F32_TO_INT8_SAT(col[3]) : 255; + BeginTooltipEx(true); + ImGuiWindow* window = ImGui::GetCurrentWindow(); + ImVec2 sz(g.FontSize * 3, g.FontSize * 3); + window->DrawList->AddRectFilled(window->DC.CursorPos, window->DC.CursorPos + sz, IM_COL32(cr,cg,cb,255)); + ImGui::Dummy(sz); + ImGui::SameLine(); + if (flags & ImGuiColorEditFlags_Alpha) + ImGui::Text("#%02X%02X%02X%02X\nR:%d, G:%d, B:%d, A:%d\n(%.3f, %.3f, %.3f, %.3f)", cr, cg, cb, ca, cr, cg, cb, ca, col[0], col[1], col[2], col[3]); + else + ImGui::Text("#%02X%02X%02X\nR: %d, G: %d, B: %d\n(%.3f, %.3f, %.3f)", cr, cg, cb, cr, cg, cb, col[0], col[1], col[2]); + ImGui::EndTooltip(); +} + // A little colored square. Return true when clicked. // FIXME: May want to display/ignore the alpha component in the color display? Yet show it in the tooltip. bool ImGui::ColorButton(const ImVec4& col, bool small_height, bool outline_border) @@ -8998,7 +9015,7 @@ bool ImGui::ColorButton(const ImVec4& col, bool small_height, bool outline_borde RenderFrame(bb.Min, bb.Max, GetColorU32(col), outline_border, style.FrameRounding); if (hovered) - SetTooltip("Color:\n(%.2f,%.2f,%.2f,%.2f)\n#%02X%02X%02X%02X", col.x, col.y, col.z, col.w, IM_F32_TO_INT8_SAT(col.x), IM_F32_TO_INT8_SAT(col.y), IM_F32_TO_INT8_SAT(col.z), IM_F32_TO_INT8_SAT(col.w)); + ColorTooltip(&col.x, ImGuiColorEditFlags_Alpha); return pressed; } @@ -9151,7 +9168,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag // Recreate our own tooltip over's ColorButton() one because we want to display correct alpha here if (IsItemHovered()) - SetTooltip("Color:\n(%.2f,%.2f,%.2f,%.2f)\n#%02X%02X%02X%02X", col[0], col[1], col[2], col[3], IM_F32_TO_INT8_SAT(col[0]), IM_F32_TO_INT8_SAT(col[1]), IM_F32_TO_INT8_SAT(col[2]), IM_F32_TO_INT8_SAT(col[3])); + ColorTooltip(col, flags); } if (label != label_display_end) @@ -9214,8 +9231,8 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl float bar1_pos_x = bar0_pos_x + bars_width + style.ItemInnerSpacing.x; // Recreate our own tooltip over's ColorButton() one because we want to display correct alpha here - if (IsItemHovered()) - SetTooltip("Color:\n(%.2f,%.2f,%.2f,%.2f)\n#%02X%02X%02X%02X", col[0], col[1], col[2], col[3], IM_F32_TO_INT8_SAT(col[0]), IM_F32_TO_INT8_SAT(col[1]), IM_F32_TO_INT8_SAT(col[2]), IM_F32_TO_INT8_SAT(col[3])); + //if (IsItemHovered()) + // ColorTooltip(col, flags); float H,S,V; ImGui::ColorConvertRGBtoHSV(col[0], col[1], col[2], H, S, V); From e79d7553b0baee74319c51e1297554ed970fc377 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 22 Jul 2017 16:52:41 +0800 Subject: [PATCH 104/921] ColorPicker: Don't use Alpha setting when enabling all 3 sliders (#346) --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 91c382bc8..8b3e10f99 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9283,9 +9283,9 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl if (!(flags & ImGuiColorEditFlags_NoSliders)) { if ((flags & ImGuiColorEditFlags_ModeMask_) == 0) - flags = ImGuiColorEditFlags_RGB | ImGuiColorEditFlags_HSV | ImGuiColorEditFlags_HEX; ImGui::PushItemWidth((alpha ? bar1_pos_x : bar0_pos_x) + bars_width - picker_pos.x); ImGuiColorEditFlags sub_flags = (alpha ? ImGuiColorEditFlags_Alpha : 0) | ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_NoOptions | ImGuiColorEditFlags_NoColorSquare; + flags |= ImGuiColorEditFlags_RGB | ImGuiColorEditFlags_HSV | ImGuiColorEditFlags_HEX; if (flags & ImGuiColorEditFlags_RGB) value_changed |= ImGui::ColorEdit4("##rgb", col, sub_flags | ImGuiColorEditFlags_RGB); if (flags & ImGuiColorEditFlags_HSV) From 1edeea2f5a11b32970f344e3e604d03ffa390633 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 22 Jul 2017 16:58:28 +0800 Subject: [PATCH 105/921] ColorPicker: Removed extraneous ImGui:: prefixes + minor comments (#346) --- imgui.cpp | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 8b3e10f99..78a7b606b 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9109,8 +9109,8 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag ImFormatString(buf, IM_ARRAYSIZE(buf), "#%02X%02X%02X%02X", i[0], i[1], i[2], i[3]); else ImFormatString(buf, IM_ARRAYSIZE(buf), "#%02X%02X%02X", i[0], i[1], i[2]); - ImGui::PushItemWidth(w_slider_all); - if (ImGui::InputText("##Text", buf, IM_ARRAYSIZE(buf), ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsUppercase)) + PushItemWidth(w_slider_all); + if (InputText("##Text", buf, IM_ARRAYSIZE(buf), ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsUppercase)) { value_changed |= true; char* p = buf; @@ -9213,20 +9213,21 @@ bool ImGui::ColorPicker3(const char* label, float col[3], ImGuiColorEditFlags fl // see https://github.com/ocornut/imgui/issues/346 // TODO: Missing color square // TODO: English strings in context menu (see FIXME-LOCALIZATION) +// Note: we adjust item height based on item widget, which may cause a flickering feedback loop (if automatic height makes a vertical scrollbar appears, affecting automatic width..) bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags flags) { ImGuiIO& io = ImGui::GetIO(); ImGuiStyle& style = ImGui::GetStyle(); ImDrawList* draw_list = ImGui::GetWindowDrawList(); - ImGui::PushID(label); - ImGui::BeginGroup(); + PushID(label); + BeginGroup(); // Setup bool alpha = (flags & ImGuiColorEditFlags_Alpha) != 0; ImVec2 picker_pos = ImGui::GetCursorScreenPos(); float bars_width = ImGui::GetWindowFontSize() * 1.0f; // Arbitrary smallish width of Hue/Alpha picking bars - float sv_picker_size = ImMax(bars_width * 2, ImGui::CalcItemWidth() - (alpha ? 2 : 1) * (bars_width + style.ItemInnerSpacing.x)); // Saturation/Value picking box + float sv_picker_size = ImMax(bars_width * 2, CalcItemWidth() - (alpha ? 2 : 1) * (bars_width + style.ItemInnerSpacing.x)); // Saturation/Value picking box float bar0_pos_x = picker_pos.x + sv_picker_size + style.ItemInnerSpacing.x; float bar1_pos_x = bar0_pos_x + bars_width + style.ItemInnerSpacing.x; @@ -9235,12 +9236,12 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl // ColorTooltip(col, flags); float H,S,V; - ImGui::ColorConvertRGBtoHSV(col[0], col[1], col[2], H, S, V); + ColorConvertRGBtoHSV(col[0], col[1], col[2], H, S, V); // Color matrix logic bool value_changed = false, hsv_changed = false; - ImGui::InvisibleButton("sv", ImVec2(sv_picker_size, sv_picker_size)); - if (ImGui::IsItemActive()) + InvisibleButton("sv", ImVec2(sv_picker_size, sv_picker_size)); + if (IsItemActive()) { S = ImSaturate((io.MousePos.x - picker_pos.x) / (sv_picker_size-1)); V = 1.0f - ImSaturate((io.MousePos.y - picker_pos.y) / (sv_picker_size-1)); @@ -9283,29 +9284,29 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl if (!(flags & ImGuiColorEditFlags_NoSliders)) { if ((flags & ImGuiColorEditFlags_ModeMask_) == 0) - ImGui::PushItemWidth((alpha ? bar1_pos_x : bar0_pos_x) + bars_width - picker_pos.x); ImGuiColorEditFlags sub_flags = (alpha ? ImGuiColorEditFlags_Alpha : 0) | ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_NoOptions | ImGuiColorEditFlags_NoColorSquare; flags |= ImGuiColorEditFlags_RGB | ImGuiColorEditFlags_HSV | ImGuiColorEditFlags_HEX; + PushItemWidth((alpha ? bar1_pos_x : bar0_pos_x) + bars_width - picker_pos.x); if (flags & ImGuiColorEditFlags_RGB) - value_changed |= ImGui::ColorEdit4("##rgb", col, sub_flags | ImGuiColorEditFlags_RGB); + value_changed |= ColorEdit4("##rgb", col, sub_flags | ImGuiColorEditFlags_RGB); if (flags & ImGuiColorEditFlags_HSV) - value_changed |= ImGui::ColorEdit4("##hsv", col, sub_flags | ImGuiColorEditFlags_HSV); + value_changed |= ColorEdit4("##hsv", col, sub_flags | ImGuiColorEditFlags_HSV); if (flags & ImGuiColorEditFlags_HEX) - value_changed |= ImGui::ColorEdit4("##hex", col, sub_flags | ImGuiColorEditFlags_HEX); - ImGui::PopItemWidth(); + value_changed |= ColorEdit4("##hex", col, sub_flags | ImGuiColorEditFlags_HEX); + PopItemWidth(); } // Try to cancel hue wrap (after ColorEdit), if any if (value_changed) { float new_H, new_S, new_V; - ImGui::ColorConvertRGBtoHSV(col[0], col[1], col[2], new_H, new_S, new_V); + ColorConvertRGBtoHSV(col[0], col[1], col[2], new_H, new_S, new_V); if (new_H <= 0 && H > 0) { if (new_V <= 0 && V != new_V) - ImGui::ColorConvertHSVtoRGB(H, S, new_V <= 0 ? V * 0.5f : new_V, col[0], col[1], col[2]); + ColorConvertHSVtoRGB(H, S, new_V <= 0 ? V * 0.5f : new_V, col[0], col[1], col[2]); else if (new_S <= 0) - ImGui::ColorConvertHSVtoRGB(H, new_S <= 0 ? S * 0.5f : new_S, new_V, col[0], col[1], col[2]); + ColorConvertHSVtoRGB(H, new_S <= 0 ? S * 0.5f : new_S, new_V, col[0], col[1], col[2]); } } @@ -9481,7 +9482,7 @@ void ImGui::EndGroup() window->DC.GroupStack.pop_back(); - //window->DrawList->AddRect(group_bb.Min, group_bb.Max, IM_COL32(255,0,255,255)); // Debug + //window->DrawList->AddRect(group_bb.Min, group_bb.Max, IM_COL32(255,0,255,255)); // [Debug] } // Gets back to previous line and continue with horizontal layout @@ -9941,7 +9942,7 @@ void ImGui::ShowMetricsWindow(bool* p_open) ImGui::Text("%d vertices, %d indices (%d triangles)", ImGui::GetIO().MetricsRenderVertices, ImGui::GetIO().MetricsRenderIndices, ImGui::GetIO().MetricsRenderIndices / 3); ImGui::Text("%d allocations", ImGui::GetIO().MetricsAllocs); static bool show_clip_rects = true; - ImGui::Checkbox("Show clipping rectangles when hovering a ImDrawCmd", &show_clip_rects); + ImGui::Checkbox("Show clipping rectangles when hovering an ImDrawCmd", &show_clip_rects); ImGui::Separator(); struct Funcs From eba33deaf374823b9edd6cb765a0ba0040121e3e Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 22 Jul 2017 17:35:18 +0800 Subject: [PATCH 106/921] ColorPicker: Longer white line for hue/alpha selection, scale down according to ItemInnerSpacing. (#346) --- imgui.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 78a7b606b..8eb52b9c6 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9228,6 +9228,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl ImVec2 picker_pos = ImGui::GetCursorScreenPos(); float bars_width = ImGui::GetWindowFontSize() * 1.0f; // Arbitrary smallish width of Hue/Alpha picking bars float sv_picker_size = ImMax(bars_width * 2, CalcItemWidth() - (alpha ? 2 : 1) * (bars_width + style.ItemInnerSpacing.x)); // Saturation/Value picking box + float bars_line_extrude = ImMin(2.0f, style.ItemInnerSpacing.x * 0.5f); float bar0_pos_x = picker_pos.x + sv_picker_size + style.ItemInnerSpacing.x; float bar1_pos_x = bar0_pos_x + bars_width + style.ItemInnerSpacing.x; @@ -9322,7 +9323,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl hue_colors[i], hue_colors[i], hue_colors[i + 1], hue_colors[i + 1]); } float bar0_line_y = (float)(int)(picker_pos.y + H * sv_picker_size + 0.5f); - draw_list->AddLine(ImVec2(bar0_pos_x - 1, bar0_line_y), ImVec2(bar0_pos_x + bars_width + 1, bar0_line_y), IM_COL32_WHITE); + draw_list->AddLine(ImVec2(bar0_pos_x - bars_line_extrude, bar0_line_y), ImVec2(bar0_pos_x + bars_width + bars_line_extrude, bar0_line_y), IM_COL32_WHITE); // Render alpha bar if (alpha) @@ -9330,7 +9331,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl float alpha = ImSaturate(col[3]); float bar1_line_y = (float)(int)(picker_pos.y + (1.0f-alpha) * sv_picker_size + 0.5f); draw_list->AddRectFilledMultiColor(ImVec2(bar1_pos_x, picker_pos.y), ImVec2(bar1_pos_x + bars_width, picker_pos.y + sv_picker_size), IM_COL32_WHITE, IM_COL32_WHITE, IM_COL32_BLACK, IM_COL32_BLACK); - draw_list->AddLine(ImVec2(bar1_pos_x - 1, bar1_line_y), ImVec2(bar1_pos_x + bars_width + 1, bar1_line_y), IM_COL32_WHITE); + draw_list->AddLine(ImVec2(bar1_pos_x - bars_line_extrude, bar1_line_y), ImVec2(bar1_pos_x + bars_width + bars_line_extrude, bar1_line_y), IM_COL32_WHITE); } // Render color matrix From dd9c2f97a81c3001cc3b0d62848e807b32945cc6 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 22 Jul 2017 17:38:38 +0800 Subject: [PATCH 107/921] ColorPicker: Renamed _NoSliders to _NoInputs (#346) --- imgui.cpp | 10 +++++----- imgui.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 8eb52b9c6..1e663de74 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9048,7 +9048,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag flags |= ImGuiColorEditFlags_RGB; // If we're not showing any slider there's no point in querying color mode, nor showing the options menu, nor doing any HSV conversions - if (flags & ImGuiColorEditFlags_NoSliders) + if (flags & ImGuiColorEditFlags_NoInputs) flags = (flags & (~ImGuiColorEditFlags_ModeMask_)) | ImGuiColorEditFlags_RGB | ImGuiColorEditFlags_NoOptions; // Read back edit mode from persistent storage @@ -9071,7 +9071,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag BeginGroup(); PushID(label); - if ((flags & (ImGuiColorEditFlags_RGB | ImGuiColorEditFlags_HSV)) != 0 && (flags & ImGuiColorEditFlags_NoSliders) == 0) + if ((flags & (ImGuiColorEditFlags_RGB | ImGuiColorEditFlags_HSV)) != 0 && (flags & ImGuiColorEditFlags_NoInputs) == 0) { // RGB/HSV 0..255 Sliders const float w_items_all = w_full - square_sz_with_spacing; @@ -9100,7 +9100,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag PopItemWidth(); PopItemWidth(); } - else if ((flags & ImGuiColorEditFlags_HEX) != 0 && (flags & ImGuiColorEditFlags_NoSliders) == 0) + else if ((flags & ImGuiColorEditFlags_HEX) != 0 && (flags & ImGuiColorEditFlags_NoInputs) == 0) { // RGB Hexadecimal Input const float w_slider_all = w_full - square_sz_with_spacing; @@ -9130,7 +9130,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag bool picker_active = false; if (!(flags & ImGuiColorEditFlags_NoColorSquare)) { - if (!(flags & ImGuiColorEditFlags_NoSliders)) + if (!(flags & ImGuiColorEditFlags_NoInputs)) SameLine(0, style.ItemInnerSpacing.x); const ImVec4 col_display(col[0], col[1], col[2], 1.0f); @@ -9282,7 +9282,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl ColorConvertHSVtoRGB(H >= 1.0f ? H - 10 * 1e-6f : H, S > 0.0f ? S : 10*1e-6f, V > 0.0f ? V : 1e-6f, col[0], col[1], col[2]); // R,G,B and H,S,V slider color editor - if (!(flags & ImGuiColorEditFlags_NoSliders)) + if (!(flags & ImGuiColorEditFlags_NoInputs)) { if ((flags & ImGuiColorEditFlags_ModeMask_) == 0) ImGuiColorEditFlags sub_flags = (alpha ? ImGuiColorEditFlags_Alpha : 0) | ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_NoOptions | ImGuiColorEditFlags_NoColorSquare; diff --git a/imgui.h b/imgui.h index a12c70175..b783700cc 100644 --- a/imgui.h +++ b/imgui.h @@ -670,7 +670,7 @@ enum ImGuiColorEditFlags_ ImGuiColorEditFlags_NoPicker = 1 << 4, // ColorEdit: Disable picker when clicking on colored square ImGuiColorEditFlags_NoOptions = 1 << 5, // ColorEdit: Disable toggling options menu when right-clicking colored square ImGuiColorEditFlags_NoColorSquare = 1 << 6, // ColorEdit: Disable colored square - ImGuiColorEditFlags_NoSliders = 1 << 7, // ColorEdit: Disable sliders, show only a button. ColorPicker: Disable all RGB/HSV/HEX sliders. + ImGuiColorEditFlags_NoInputs = 1 << 7, // ColorEdit: Disable inputs sliders/text edit, show only a button. ColorPicker: Disable all RGB/HSV/HEX sliders. ImGuiColorEditFlags_ModeMask_ = ImGuiColorEditFlags_RGB|ImGuiColorEditFlags_HSV|ImGuiColorEditFlags_HEX }; From 15be7e1a71079a5032e375e96f5dfac98c1647b2 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 22 Jul 2017 18:01:16 +0800 Subject: [PATCH 108/921] ColorPicker: new prototype for ColorButton() .Added _NoTooltip, _NoLabel flags. Changing _Alpha flag to _NoAlpha makes so much much sense and allow to revert default parameters to zero. ColorEdit4/Picker4 don't attempt to read/write fourth component, making ColorEdit3/Picker3 shorter/faster. Tooltip and Picker called from ColorEdit can have a title. Picker shows colored square. Moved ColorTooltip() to imgui_internal.h (#346) --- imgui.cpp | 143 ++++++++++++++++++++++++++++------------------- imgui.h | 18 +++--- imgui_internal.h | 2 + 3 files changed, 98 insertions(+), 65 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 1e663de74..25239625b 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -152,11 +152,12 @@ Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. Also read releases logs https://github.com/ocornut/imgui/releases for more details. - - 2016/08/xx (1.XX) - removed ColorEditMode() and ImGuiColorEditMode in favor of ImGuiColorEditFlags and parameters to ColorEdit*() functions - replaced ColorEdit4() third parameter 'bool show_alpha=true' to 'ImGuiColorEditFlags flags=0x01' where ImGuiColorEditFlags_Alpha=0x01 for dodgy compatibility - - 2017/07/20 (1.51) - Removed IsPosHoveringAnyWindow(ImVec2), which was partly broken and misleading. ASSERT + redirect user to io.WantCaptureMouse - - 2017/05/26 (1.50) - Removed ImFontConfig::MergeGlyphCenterV in favor of a more multipurpose ImFontConfig::GlyphOffset. - - 2017/05/01 (1.50) - Renamed ImDrawList::PathFill() (rarely used directly) to ImDrawList::PathFillConvex() for clarity. + - 2016/08/xx (1.XX) - removed ColorEditMode() and ImGuiColorEditMode in favor of ImGuiColorEditFlags and parameters to the various Color*() functions + - changed prototype of 'ColorEdit4(const char* label, float col[4], bool show_alpha = true)' to 'ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flags = 0)', where passing flags = 0x01 is a safe no-op (hello dodgy backward compatibility!) + - changed prototype of rarely used 'ColorButton(ImVec4 col, bool small_height = false, bool outline_border = true)' to 'ColorButton(const char* desc_id, ImVec4 col, ImGuiColorEditFlags flags = 0, ImVec2 size = ImVec2(0,0))' + - 2017/07/20 (1.51) - removed IsPosHoveringAnyWindow(ImVec2), which was partly broken and misleading. ASSERT + redirect user to io.WantCaptureMouse + - 2017/05/26 (1.50) - removed ImFontConfig::MergeGlyphCenterV in favor of a more multipurpose ImFontConfig::GlyphOffset. + - 2017/05/01 (1.50) - renamed ImDrawList::PathFill() (rarely used directly) to ImDrawList::PathFillConvex() for clarity. - 2016/11/06 (1.50) - BeginChild(const char*) now applies the stack id to the provided label, consistently with other functions as it should always have been. It shouldn't affect you unless (extremely unlikely) you were appending multiple times to a same child from different locations of the stack id. If that's the case, generate an id with GetId() and use it instead of passing string to BeginChild(). - 2016/10/15 (1.50) - avoid 'void* user_data' parameter to io.SetClipboardTextFn/io.GetClipboardTextFn pointers. We pass io.ClipboardUserData to it. - 2016/09/25 (1.50) - style.WindowTitleAlign is now a ImVec2 (ImGuiAlign enum was removed). set to (0.5f,0.5f) for horizontal+vertical centering, (0.0f,0.0f) for upper-left, etc. @@ -8976,26 +8977,43 @@ void ImGui::EndMenu() EndPopup(); } -static void ColorTooltip(const float* col, ImGuiColorEditFlags flags) +// Note: only access 3 floats if ImGuiColorEditFlags_NoAlpha flag is set. +void ImGui::ColorTooltip(const char* text, const float col[4], ImGuiColorEditFlags flags) { ImGuiContext& g = *GImGui; - int cr = IM_F32_TO_INT8_SAT(col[0]), cg = IM_F32_TO_INT8_SAT(col[1]), cb = IM_F32_TO_INT8_SAT(col[2]), ca = (flags & ImGuiColorEditFlags_Alpha) ? IM_F32_TO_INT8_SAT(col[3]) : 255; + + int cr = IM_F32_TO_INT8_SAT(col[0]), cg = IM_F32_TO_INT8_SAT(col[1]), cb = IM_F32_TO_INT8_SAT(col[2]), ca = (flags & ImGuiColorEditFlags_NoAlpha) ? 255 : IM_F32_TO_INT8_SAT(col[3]); BeginTooltipEx(true); - ImGuiWindow* window = ImGui::GetCurrentWindow(); + ImGuiWindow* window = GetCurrentWindow(); + + const char* text_end = text ? FindRenderedTextEnd(text, NULL) : text; + if (text_end > text) + { + TextUnformatted(text, text_end); + Separator(); + } + ImVec2 sz(g.FontSize * 3, g.FontSize * 3); window->DrawList->AddRectFilled(window->DC.CursorPos, window->DC.CursorPos + sz, IM_COL32(cr,cg,cb,255)); - ImGui::Dummy(sz); - ImGui::SameLine(); - if (flags & ImGuiColorEditFlags_Alpha) - ImGui::Text("#%02X%02X%02X%02X\nR:%d, G:%d, B:%d, A:%d\n(%.3f, %.3f, %.3f, %.3f)", cr, cg, cb, ca, cr, cg, cb, ca, col[0], col[1], col[2], col[3]); + Dummy(sz); + SameLine(); + if (flags & ImGuiColorEditFlags_NoAlpha) + Text("#%02X%02X%02X\nR: %d, G: %d, B: %d\n(%.3f, %.3f, %.3f)", cr, cg, cb, cr, cg, cb, col[0], col[1], col[2]); else - ImGui::Text("#%02X%02X%02X\nR: %d, G: %d, B: %d\n(%.3f, %.3f, %.3f)", cr, cg, cb, cr, cg, cb, col[0], col[1], col[2]); - ImGui::EndTooltip(); + Text("#%02X%02X%02X%02X\nR:%d, G:%d, B:%d, A:%d\n(%.3f, %.3f, %.3f, %.3f)", cr, cg, cb, ca, cr, cg, cb, ca, col[0], col[1], col[2], col[3]); + EndTooltip(); +} + +static inline float ColorSquareSize() +{ + ImGuiContext& g = *GImGui; + return g.FontSize + g.Style.FramePadding.y * 2.0f; } // A little colored square. Return true when clicked. // FIXME: May want to display/ignore the alpha component in the color display? Yet show it in the tooltip. -bool ImGui::ColorButton(const ImVec4& col, bool small_height, bool outline_border) +// 'desc_id' is not called 'label' because we don't display it next to the button, but only in the tooltip. +bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFlags flags, ImVec2 size) { ImGuiWindow* window = GetCurrentWindow(); if (window->SkipItems) @@ -9003,34 +9021,35 @@ bool ImGui::ColorButton(const ImVec4& col, bool small_height, bool outline_borde ImGuiContext& g = *GImGui; const ImGuiStyle& style = g.Style; - const ImGuiID id = window->GetID("#colorbutton"); - const float square_size = g.FontSize; - const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(square_size + style.FramePadding.y*2, square_size + (small_height ? 0 : style.FramePadding.y*2))); - ItemSize(bb, small_height ? 0.0f : style.FramePadding.y); + const ImGuiID id = window->GetID(desc_id); + if (size.x == 0.0f) + size.x = ColorSquareSize(); + if (size.y == 0.0f) + size.y = ColorSquareSize(); + const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size); + ItemSize(bb); if (!ItemAdd(bb, &id)) return false; bool hovered, held; bool pressed = ButtonBehavior(bb, id, &hovered, &held); - RenderFrame(bb.Min, bb.Max, GetColorU32(col), outline_border, style.FrameRounding); + window->DrawList->AddRectFilled(bb.Min, bb.Max, GetColorU32(*(ImVec4*)&col), style.FrameRounding); + //window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(border_col), style.FrameRounding); - if (hovered) - ColorTooltip(&col.x, ImGuiColorEditFlags_Alpha); + if (hovered && !(flags & ImGuiColorEditFlags_NoTooltip)) + ColorTooltip(desc_id, &col.x, flags & ImGuiColorEditFlags_NoAlpha); return pressed; } bool ImGui::ColorEdit3(const char* label, float col[3], ImGuiColorEditFlags flags) { - float col4[4] = { col[0], col[1], col[2], 1.0f }; - if (!ColorEdit4(label, col4, flags & ~ImGuiColorEditFlags_Alpha)) - return false; - col[0] = col4[0]; col[1] = col4[1]; col[2] = col4[2]; - return true; + return ColorEdit4(label, col, flags | ImGuiColorEditFlags_NoAlpha); } // Edit colors components (each component in 0.0f..1.0f range) // Click on colored square to open a color picker (unless ImGuiColorEditFlags_NoPicker is set). Use CTRL-Click to input value and TAB to go to next item. +// Note: only access 3 floats if ImGuiColorEditFlags_NoAlpha flag is set. bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flags) { ImGuiWindow* window = GetCurrentWindow(); @@ -9041,7 +9060,11 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag const ImGuiStyle& style = g.Style; const ImGuiID id = window->GetID(label); const float w_full = CalcItemWidth(); - const float square_sz_with_spacing = (flags & ImGuiColorEditFlags_NoColorSquare) ? 0.0f : (g.FontSize + style.FramePadding.y * 2.0f + style.ItemInnerSpacing.x); + const float w_extra = (flags & ImGuiColorEditFlags_NoColorSquare) ? 0.0f : (ColorSquareSize() + style.ItemInnerSpacing.x); + const float w_items_all = w_full - w_extra; + + const bool alpha = (flags & ImGuiColorEditFlags_NoAlpha) == 0; + const int components = alpha ? 4 : 3; // If no mode is specified, defaults to RGB if (!(flags & ImGuiColorEditFlags_ModeMask_)) @@ -9058,15 +9081,13 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag // Check that exactly one of RGB/HSV/HEX is set IM_ASSERT(ImIsPowerOfTwo((int)(flags & ImGuiColorEditFlags_ModeMask_))); // - float f[4] = { col[0], col[1], col[2], col[3] }; + float f[4] = { col[0], col[1], col[2], alpha ? col[3] : 1.0f }; if (flags & ImGuiColorEditFlags_HSV) ColorConvertRGBtoHSV(f[0], f[1], f[2], f[0], f[1], f[2]); int i[4] = { IM_F32_TO_INT8_UNBOUND(f[0]), IM_F32_TO_INT8_UNBOUND(f[1]), IM_F32_TO_INT8_UNBOUND(f[2]), IM_F32_TO_INT8_UNBOUND(f[3]) }; - bool alpha = (flags & ImGuiColorEditFlags_Alpha) != 0; bool value_changed = false; - int components = alpha ? 4 : 3; BeginGroup(); PushID(label); @@ -9074,7 +9095,6 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag if ((flags & (ImGuiColorEditFlags_RGB | ImGuiColorEditFlags_HSV)) != 0 && (flags & ImGuiColorEditFlags_NoInputs) == 0) { // RGB/HSV 0..255 Sliders - const float w_items_all = w_full - square_sz_with_spacing; const float w_item_one = ImMax(1.0f, (float)(int)((w_items_all - (style.ItemInnerSpacing.x) * (components-1)) / (float)components)); const float w_item_last = ImMax(1.0f, (float)(int)(w_items_all - (w_item_one + style.ItemInnerSpacing.x) * (components-1))); @@ -9103,13 +9123,12 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag else if ((flags & ImGuiColorEditFlags_HEX) != 0 && (flags & ImGuiColorEditFlags_NoInputs) == 0) { // RGB Hexadecimal Input - const float w_slider_all = w_full - square_sz_with_spacing; char buf[64]; if (alpha) ImFormatString(buf, IM_ARRAYSIZE(buf), "#%02X%02X%02X%02X", i[0], i[1], i[2], i[3]); else ImFormatString(buf, IM_ARRAYSIZE(buf), "#%02X%02X%02X", i[0], i[1], i[2]); - PushItemWidth(w_slider_all); + PushItemWidth(w_items_all); if (InputText("##Text", buf, IM_ARRAYSIZE(buf), ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsUppercase)) { value_changed |= true; @@ -9134,7 +9153,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag SameLine(0, style.ItemInnerSpacing.x); const ImVec4 col_display(col[0], col[1], col[2], 1.0f); - if (ColorButton(col_display)) + if (ColorButton("##ColorButton", col_display, flags)) { if (!(flags & ImGuiColorEditFlags_NoPicker)) { @@ -9151,9 +9170,12 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag { picker_active = true; if (label != label_display_end) + { TextUnformatted(label, label_display_end); - PushItemWidth(256.0f + (alpha ? 2 : 1) * (style.ItemInnerSpacing.x)); - value_changed |= ColorPicker4("##picker", col, (flags & ImGuiColorEditFlags_Alpha) | (ImGuiColorEditFlags_RGB | ImGuiColorEditFlags_HSV | ImGuiColorEditFlags_HEX)); + Separator(); + } + PushItemWidth(ColorSquareSize() * 12.0f); + value_changed |= ColorPicker4("##picker", col, (flags & ImGuiColorEditFlags_NoAlpha) | (ImGuiColorEditFlags_RGB | ImGuiColorEditFlags_HSV | ImGuiColorEditFlags_HEX)); PopItemWidth(); EndPopup(); } @@ -9167,11 +9189,11 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag } // Recreate our own tooltip over's ColorButton() one because we want to display correct alpha here - if (IsItemHovered()) - ColorTooltip(col, flags); + if (!(flags & ImGuiColorEditFlags_NoTooltip) && IsItemHovered()) + ColorTooltip(label, col, flags); } - if (label != label_display_end) + if (label != label_display_end && !(flags & ImGuiColorEditFlags_NoLabel)) { SameLine(0, style.ItemInnerSpacing.x); TextUnformatted(label, label_display_end); @@ -9203,32 +9225,35 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag bool ImGui::ColorPicker3(const char* label, float col[3], ImGuiColorEditFlags flags) { float col4[4] = { col[0], col[1], col[2], 1.0f }; - if (!ColorPicker4(label, col4, flags & ~ImGuiColorEditFlags_Alpha)) + if (!ColorPicker4(label, col4, flags | ImGuiColorEditFlags_NoAlpha)) return false; col[0] = col4[0]; col[1] = col4[1]; col[2] = col4[2]; return true; } -// ColorPicker v2.50 WIP +// ColorPicker v2.60 WIP // see https://github.com/ocornut/imgui/issues/346 -// TODO: Missing color square // TODO: English strings in context menu (see FIXME-LOCALIZATION) // Note: we adjust item height based on item widget, which may cause a flickering feedback loop (if automatic height makes a vertical scrollbar appears, affecting automatic width..) +// Note: only access 3 floats if ImGuiColorEditFlags_NoAlpha flag is set. bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags flags) { - ImGuiIO& io = ImGui::GetIO(); - ImGuiStyle& style = ImGui::GetStyle(); - ImDrawList* draw_list = ImGui::GetWindowDrawList(); + ImGuiContext& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + ImDrawList* draw_list = window->DrawList; + + ImGuiStyle& style = g.Style; + ImGuiIO& io = g.IO; PushID(label); BeginGroup(); // Setup - bool alpha = (flags & ImGuiColorEditFlags_Alpha) != 0; - ImVec2 picker_pos = ImGui::GetCursorScreenPos(); - float bars_width = ImGui::GetWindowFontSize() * 1.0f; // Arbitrary smallish width of Hue/Alpha picking bars - float sv_picker_size = ImMax(bars_width * 2, CalcItemWidth() - (alpha ? 2 : 1) * (bars_width + style.ItemInnerSpacing.x)); // Saturation/Value picking box + bool alpha = (flags & ImGuiColorEditFlags_NoAlpha) == 0; + ImVec2 picker_pos = window->DC.CursorPos; + float bars_width = ColorSquareSize(); // Arbitrary smallish width of Hue/Alpha picking bars float bars_line_extrude = ImMin(2.0f, style.ItemInnerSpacing.x * 0.5f); + float sv_picker_size = ImMax(bars_width * 1, CalcItemWidth() - (alpha ? 2 : 1) * (bars_width + style.ItemInnerSpacing.x)); // Saturation/Value picking box float bar0_pos_x = picker_pos.x + sv_picker_size + style.ItemInnerSpacing.x; float bar1_pos_x = bar0_pos_x + bars_width + style.ItemInnerSpacing.x; @@ -9270,11 +9295,14 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl } } - const char* label_display_end = FindRenderedTextEnd(label); - if (label != label_display_end) + if ((flags & ImGuiColorEditFlags_NoLabel) == 0) { - SameLine(0, style.ItemInnerSpacing.x); - TextUnformatted(label, label_display_end); + const char* label_display_end = FindRenderedTextEnd(label); + if (label != label_display_end) + { + SameLine(0, style.ItemInnerSpacing.x); + TextUnformatted(label, label_display_end); + } } // Convert back color to RGB @@ -9285,9 +9313,9 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl if (!(flags & ImGuiColorEditFlags_NoInputs)) { if ((flags & ImGuiColorEditFlags_ModeMask_) == 0) - ImGuiColorEditFlags sub_flags = (alpha ? ImGuiColorEditFlags_Alpha : 0) | ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_NoOptions | ImGuiColorEditFlags_NoColorSquare; flags |= ImGuiColorEditFlags_RGB | ImGuiColorEditFlags_HSV | ImGuiColorEditFlags_HEX; PushItemWidth((alpha ? bar1_pos_x : bar0_pos_x) + bars_width - picker_pos.x); + ImGuiColorEditFlags sub_flags = (flags & ImGuiColorEditFlags_NoAlpha) | ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_NoOptions | ImGuiColorEditFlags_NoTooltip; if (flags & ImGuiColorEditFlags_RGB) value_changed |= ColorEdit4("##rgb", col, sub_flags | ImGuiColorEditFlags_RGB); if (flags & ImGuiColorEditFlags_HSV) @@ -9814,14 +9842,14 @@ void ImGui::ValueColor(const char* prefix, const ImVec4& v) { Text("%s: (%.2f,%.2f,%.2f,%.2f)", prefix, v.x, v.y, v.z, v.w); SameLine(); - ColorButton(v, true); + ColorButton(prefix, v); } void ImGui::ValueColor(const char* prefix, ImU32 v) { Text("%s: %08X", prefix, v); SameLine(); - ColorButton(ColorConvertU32ToFloat4(v), true); + ColorButton(prefix, ColorConvertU32ToFloat4(v)); } //----------------------------------------------------------------------------- @@ -10023,6 +10051,7 @@ void ImGui::ShowMetricsWindow(bool* p_open) ImGui::BulletText("Pos: (%.1f,%.1f)", window->Pos.x, window->Pos.y); ImGui::BulletText("Size: (%.1f,%.1f), SizeContents (%.1f,%.1f)", window->Size.x, window->Size.y, window->SizeContents.x, window->SizeContents.y); ImGui::BulletText("Scroll: (%.2f,%.2f)", window->Scroll.x, window->Scroll.y); + ImGui::BulletText("Active: %d, Accessed: %d", window->Active, window->Accessed); if (window->RootWindow != window) NodeWindow(window->RootWindow, "RootWindow"); if (window->DC.ChildWindows.Size > 0) NodeWindows(window->DC.ChildWindows, "ChildWindows"); ImGui::BulletText("Storage: %d bytes", window->StateStorage.Data.Size * (int)sizeof(ImGuiStorage::Pair)); diff --git a/imgui.h b/imgui.h index b783700cc..f3612f119 100644 --- a/imgui.h +++ b/imgui.h @@ -70,7 +70,7 @@ typedef void* ImTextureID; // user data to identify a texture (this is typedef int ImGuiCol; // a color identifier for styling // enum ImGuiCol_ typedef int ImGuiStyleVar; // a variable identifier for styling // enum ImGuiStyleVar_ typedef int ImGuiKey; // a key identifier (ImGui-side enum) // enum ImGuiKey_ -typedef int ImGuiColorEditFlags; // color edit mode for ColorEdit*() // enum ImGuiColorEditFlags_ +typedef int ImGuiColorEditFlags; // color edit flags for Color*() // enum ImGuiColorEditFlags_ typedef int ImGuiMouseCursor; // a mouse cursor identifier // enum ImGuiMouseCursor_ typedef int ImGuiWindowFlags; // window flags for Begin*() // enum ImGuiWindowFlags_ typedef int ImGuiSetCond; // condition flags for Set*() // enum ImGuiSetCond_ @@ -275,11 +275,11 @@ namespace ImGui IMGUI_API bool Combo(const char* label, int* current_item, const char* const* items, int items_count, int height_in_items = -1); IMGUI_API bool Combo(const char* label, int* current_item, const char* items_separated_by_zeros, int height_in_items = -1); // separate items with \0, end item-list with \0\0 IMGUI_API bool Combo(const char* label, int* current_item, bool (*items_getter)(void* data, int idx, const char** out_text), void* data, int items_count, int height_in_items = -1); - IMGUI_API bool ColorButton(const ImVec4& col, bool small_height = false, bool outline_border = true); + IMGUI_API bool ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFlags flags = 0, ImVec2 size = ImVec2(0,0)); IMGUI_API bool ColorEdit3(const char* label, float col[3], ImGuiColorEditFlags flags = 0); // click on colored squared to open a color picker, right-click for options. Hint: 'float col[3]' function argument is same as 'float* col'. You can pass address of first element out of a contiguous set, e.g. &myvector.x - IMGUI_API bool ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flags = 0x01); // 0x01 = ImGuiColorEditFlags_Alpha = very dodgily backward compatible with 'bool show_alpha=true' + IMGUI_API bool ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flags = 0); IMGUI_API bool ColorPicker3(const char* label, float col[3], ImGuiColorEditFlags flags = 0); - IMGUI_API bool ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags flags = 0x01); + IMGUI_API bool ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags flags = 0); IMGUI_API void PlotLines(const char* label, const float* values, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0,0), int stride = sizeof(float)); IMGUI_API void PlotLines(const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0,0)); IMGUI_API void PlotHistogram(const char* label, const float* values, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0,0), int stride = sizeof(float)); @@ -663,14 +663,16 @@ enum ImGuiStyleVar_ // Enumeration for ColorEdit3() / ColorEdit4() / ColorPicker3() / ColorPicker4() enum ImGuiColorEditFlags_ { - ImGuiColorEditFlags_Alpha = 1 << 0, // ColorEdit/ColorPicker: show/edit Alpha component. Must be 0x01 for compatibility with old API taking bool - ImGuiColorEditFlags_RGB = 1 << 1, // ColorEdit: Choose one among RGB/HSV/HEX. User can still use the options menu to change. ColorPicker: Choose any combination or RGB/HSX/HEX. - ImGuiColorEditFlags_HSV = 1 << 2, - ImGuiColorEditFlags_HEX = 1 << 3, + ImGuiColorEditFlags_RGB = 1 << 0, // ColorEdit: Choose one among RGB/HSV/HEX. User can still use the options menu to change. ColorPicker: Choose any combination or RGB/HSX/HEX. (Default flag must be 0x01 for compatibility with old pre-1.51 API taking bool param). + ImGuiColorEditFlags_HSV = 1 << 1, + ImGuiColorEditFlags_HEX = 1 << 2, + ImGuiColorEditFlags_NoAlpha = 1 << 3, // ColorEdit/ColorPicker: show/edit Alpha component. ImGuiColorEditFlags_NoPicker = 1 << 4, // ColorEdit: Disable picker when clicking on colored square ImGuiColorEditFlags_NoOptions = 1 << 5, // ColorEdit: Disable toggling options menu when right-clicking colored square ImGuiColorEditFlags_NoColorSquare = 1 << 6, // ColorEdit: Disable colored square ImGuiColorEditFlags_NoInputs = 1 << 7, // ColorEdit: Disable inputs sliders/text edit, show only a button. ColorPicker: Disable all RGB/HSV/HEX sliders. + ImGuiColorEditFlags_NoTooltip = 1 << 8, // ColorEdit, ColorButton: Disable tooltip when hovering the color square. + ImGuiColorEditFlags_NoLabel = 1 << 9, // ColorEdit: Disable display of inline text label, however the label is still shown in tooltip and picker ImGuiColorEditFlags_ModeMask_ = ImGuiColorEditFlags_RGB|ImGuiColorEditFlags_HSV|ImGuiColorEditFlags_HEX }; diff --git a/imgui_internal.h b/imgui_internal.h index aad9c185f..f8f0a3828 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -755,6 +755,8 @@ namespace ImGui IMGUI_API bool InputScalarEx(const char* label, ImGuiDataType data_type, void* data_ptr, void* step_ptr, void* step_fast_ptr, const char* scalar_format, ImGuiInputTextFlags extra_flags); IMGUI_API bool InputScalarAsWidgetReplacement(const ImRect& aabb, const char* label, ImGuiDataType data_type, void* data_ptr, ImGuiID id, int decimal_precision); + IMGUI_API void ColorTooltip(const char* text, const float col[4], ImGuiColorEditFlags flags); + IMGUI_API bool TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* label, const char* label_end = NULL); IMGUI_API bool TreeNodeBehaviorIsOpen(ImGuiID id, ImGuiTreeNodeFlags flags = 0); // Consume previous SetNextTreeNodeOpened() data, if any. May return true when logging IMGUI_API void TreePushRawID(ImGuiID id); From 91bf8fd68911b32d11e35a4d4e2137567119723a Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 22 Jul 2017 18:01:29 +0800 Subject: [PATCH 109/921] ColorPicker,ColorEdit: Demo code (#346) --- imgui_demo.cpp | 42 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 7544f3387..f0f35438a 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -658,6 +658,44 @@ void ImGui::ShowTestWindow(bool* p_open) //ImGui::ListBox("##listbox2", &listbox_item_current2, listbox_items, IM_ARRAYSIZE(listbox_items), 4); //ImGui::PopItemWidth(); + if (ImGui::TreeNode("Color/Picker Widgets")) + { + static ImVec4 color = ImColor(114, 144, 154); + + ImGui::Text("Color widget:"); + ImGui::SameLine(); ShowHelpMarker("Click on the colored square to open a color picker.\nRight-click on the colored square to show options.\nCTRL+click on individual component to input value.\n"); + ImGui::ColorEdit3("MyColor##1", (float*)&color, ImGuiColorEditFlags_HSV); + + ImGui::Text("Color widget w/ Alpha:"); + ImGui::ColorEdit4("MyColor##2", (float*)&color); + + ImGui::Text("Color button only:"); + ImGui::ColorEdit4("MyColor##3", (float*)&color, ImGuiColorEditFlags_NoInputs|ImGuiColorEditFlags_NoLabel); + + ImGui::Text("Color picker:"); + static bool alpha = false; + static bool label = true; + static int inputs_mode = 0; + static float width = 200.0f; + ImGui::Checkbox("With Alpha", &alpha); + ImGui::Checkbox("With Label", &label); + ImGui::Combo("Mode", &inputs_mode, "All Inputs\0No Inputs\0RGB Input\0HSV Input\0HEX Input\0"); + ImGui::DragFloat("Width", &width, 1.0f, 1.0f, 999.0f); + ImGui::PushItemWidth(width); + ImGuiColorEditFlags flags = (label ? 0 : ImGuiColorEditFlags_NoLabel); + if (inputs_mode == 1) flags |= ImGuiColorEditFlags_NoInputs; + if (inputs_mode == 2) flags |= ImGuiColorEditFlags_RGB; + if (inputs_mode == 3) flags |= ImGuiColorEditFlags_HSV; + if (inputs_mode == 4) flags |= ImGuiColorEditFlags_HEX; + if (alpha) + ImGui::ColorPicker4("MyColor##4", (float*)&color, flags); + else + ImGui::ColorPicker3("MyColor##4", (float*)&color, flags); + ImGui::PopItemWidth(); + + ImGui::TreePop(); + } + if (ImGui::TreeNode("Range Widgets")) { ImGui::Unindent(); @@ -1280,7 +1318,7 @@ void ImGui::ShowTestWindow(bool* p_open) } static ImVec4 color = ImColor(0.8f, 0.5f, 1.0f, 1.0f); - ImGui::ColorButton(color); + ImGui::ColorButton("##color", color); if (ImGui::BeginPopupContextItem("color context menu")) { ImGui::Text("Edit color"); @@ -1719,7 +1757,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) if (!filter.PassFilter(name)) continue; ImGui::PushID(i); - ImGui::ColorEdit4(name, (float*)&style.Colors[i], color_edit_flags | ImGuiColorEditFlags_Alpha | ImGuiColorEditFlags_NoOptions); + ImGui::ColorEdit4(name, (float*)&style.Colors[i], color_edit_flags | ImGuiColorEditFlags_NoOptions); if (memcmp(&style.Colors[i], (ref ? &ref->Colors[i] : &default_style.Colors[i]), sizeof(ImVec4)) != 0) { ImGui::SameLine(); if (ImGui::Button("Revert")) style.Colors[i] = ref ? ref->Colors[i] : default_style.Colors[i]; From 4355b2e422a70cd79848027cff7d393a026c6eaf Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 22 Jul 2017 19:04:10 +0800 Subject: [PATCH 110/921] ColorPicker: Honor ImGuiColorEditFlags_NoColorSquare flag + comments (#346) --- imgui.cpp | 2 +- imgui.h | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 25239625b..7aa9f6deb 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9315,7 +9315,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl if ((flags & ImGuiColorEditFlags_ModeMask_) == 0) flags |= ImGuiColorEditFlags_RGB | ImGuiColorEditFlags_HSV | ImGuiColorEditFlags_HEX; PushItemWidth((alpha ? bar1_pos_x : bar0_pos_x) + bars_width - picker_pos.x); - ImGuiColorEditFlags sub_flags = (flags & ImGuiColorEditFlags_NoAlpha) | ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_NoOptions | ImGuiColorEditFlags_NoTooltip; + ImGuiColorEditFlags sub_flags = (flags & (ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoColorSquare)) | ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_NoOptions | ImGuiColorEditFlags_NoTooltip; if (flags & ImGuiColorEditFlags_RGB) value_changed |= ColorEdit4("##rgb", col, sub_flags | ImGuiColorEditFlags_RGB); if (flags & ImGuiColorEditFlags_HSV) diff --git a/imgui.h b/imgui.h index f3612f119..cd455194d 100644 --- a/imgui.h +++ b/imgui.h @@ -663,16 +663,16 @@ enum ImGuiStyleVar_ // Enumeration for ColorEdit3() / ColorEdit4() / ColorPicker3() / ColorPicker4() enum ImGuiColorEditFlags_ { - ImGuiColorEditFlags_RGB = 1 << 0, // ColorEdit: Choose one among RGB/HSV/HEX. User can still use the options menu to change. ColorPicker: Choose any combination or RGB/HSX/HEX. (Default flag must be 0x01 for compatibility with old pre-1.51 API taking bool param). - ImGuiColorEditFlags_HSV = 1 << 1, - ImGuiColorEditFlags_HEX = 1 << 2, - ImGuiColorEditFlags_NoAlpha = 1 << 3, // ColorEdit/ColorPicker: show/edit Alpha component. + ImGuiColorEditFlags_RGB = 1 << 0, // ColorEdit: Default to one among RGB/HSV/HEX. User can still use the options menu to change. ColorPicker: Choose any combination or RGB/HSX/HEX.. + ImGuiColorEditFlags_HSV = 1 << 1, // " + ImGuiColorEditFlags_HEX = 1 << 2, // " + ImGuiColorEditFlags_NoAlpha = 1 << 3, // ColorEdit, ColorPicker: show/edit Alpha component. ImGuiColorEditFlags_NoPicker = 1 << 4, // ColorEdit: Disable picker when clicking on colored square ImGuiColorEditFlags_NoOptions = 1 << 5, // ColorEdit: Disable toggling options menu when right-clicking colored square - ImGuiColorEditFlags_NoColorSquare = 1 << 6, // ColorEdit: Disable colored square - ImGuiColorEditFlags_NoInputs = 1 << 7, // ColorEdit: Disable inputs sliders/text edit, show only a button. ColorPicker: Disable all RGB/HSV/HEX sliders. - ImGuiColorEditFlags_NoTooltip = 1 << 8, // ColorEdit, ColorButton: Disable tooltip when hovering the color square. - ImGuiColorEditFlags_NoLabel = 1 << 9, // ColorEdit: Disable display of inline text label, however the label is still shown in tooltip and picker + ImGuiColorEditFlags_NoColorSquare = 1 << 6, // ColorEdit, ColorPicker: Disable colored square. + ImGuiColorEditFlags_NoInputs = 1 << 7, // ColorEdit, ColorPicker: Disable inputs sliders/text widgets, show only the colored square. + ImGuiColorEditFlags_NoTooltip = 1 << 8, // ColorEdit, ColorButton: Disable tooltip when hovering the colored square. + ImGuiColorEditFlags_NoLabel = 1 << 9, // ColorEdit: Disable display of inline text label (however the label is still used in tooltip and picker) ImGuiColorEditFlags_ModeMask_ = ImGuiColorEditFlags_RGB|ImGuiColorEditFlags_HSV|ImGuiColorEditFlags_HEX }; From 790d0eb5befa5073ce300302be2016eaa949e742 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 22 Jul 2017 19:24:39 +0800 Subject: [PATCH 111/921] ColorPicker: Added ImGuiColorEditFlags_AlphaBar option (#346) --- imgui.cpp | 14 +++++--------- imgui.h | 1 + imgui_demo.cpp | 4 +++- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 7aa9f6deb..c531b74c7 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9249,18 +9249,14 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl BeginGroup(); // Setup - bool alpha = (flags & ImGuiColorEditFlags_NoAlpha) == 0; + bool alpha_bar = (flags & ImGuiColorEditFlags_AlphaBar) && !(flags & ImGuiColorEditFlags_NoAlpha); ImVec2 picker_pos = window->DC.CursorPos; float bars_width = ColorSquareSize(); // Arbitrary smallish width of Hue/Alpha picking bars float bars_line_extrude = ImMin(2.0f, style.ItemInnerSpacing.x * 0.5f); - float sv_picker_size = ImMax(bars_width * 1, CalcItemWidth() - (alpha ? 2 : 1) * (bars_width + style.ItemInnerSpacing.x)); // Saturation/Value picking box + float sv_picker_size = ImMax(bars_width * 1, CalcItemWidth() - (alpha_bar ? 2 : 1) * (bars_width + style.ItemInnerSpacing.x)); // Saturation/Value picking box float bar0_pos_x = picker_pos.x + sv_picker_size + style.ItemInnerSpacing.x; float bar1_pos_x = bar0_pos_x + bars_width + style.ItemInnerSpacing.x; - // Recreate our own tooltip over's ColorButton() one because we want to display correct alpha here - //if (IsItemHovered()) - // ColorTooltip(col, flags); - float H,S,V; ColorConvertRGBtoHSV(col[0], col[1], col[2], H, S, V); @@ -9284,7 +9280,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl } // Alpha bar logic - if (alpha) + if (alpha_bar) { SetCursorScreenPos(ImVec2(bar1_pos_x, picker_pos.y)); InvisibleButton("alpha", ImVec2(bars_width, sv_picker_size)); @@ -9314,7 +9310,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl { if ((flags & ImGuiColorEditFlags_ModeMask_) == 0) flags |= ImGuiColorEditFlags_RGB | ImGuiColorEditFlags_HSV | ImGuiColorEditFlags_HEX; - PushItemWidth((alpha ? bar1_pos_x : bar0_pos_x) + bars_width - picker_pos.x); + PushItemWidth((alpha_bar ? bar1_pos_x : bar0_pos_x) + bars_width - picker_pos.x); ImGuiColorEditFlags sub_flags = (flags & (ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoColorSquare)) | ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_NoOptions | ImGuiColorEditFlags_NoTooltip; if (flags & ImGuiColorEditFlags_RGB) value_changed |= ColorEdit4("##rgb", col, sub_flags | ImGuiColorEditFlags_RGB); @@ -9354,7 +9350,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl draw_list->AddLine(ImVec2(bar0_pos_x - bars_line_extrude, bar0_line_y), ImVec2(bar0_pos_x + bars_width + bars_line_extrude, bar0_line_y), IM_COL32_WHITE); // Render alpha bar - if (alpha) + if (alpha_bar) { float alpha = ImSaturate(col[3]); float bar1_line_y = (float)(int)(picker_pos.y + (1.0f-alpha) * sv_picker_size + 0.5f); diff --git a/imgui.h b/imgui.h index cd455194d..52385f00d 100644 --- a/imgui.h +++ b/imgui.h @@ -673,6 +673,7 @@ enum ImGuiColorEditFlags_ ImGuiColorEditFlags_NoInputs = 1 << 7, // ColorEdit, ColorPicker: Disable inputs sliders/text widgets, show only the colored square. ImGuiColorEditFlags_NoTooltip = 1 << 8, // ColorEdit, ColorButton: Disable tooltip when hovering the colored square. ImGuiColorEditFlags_NoLabel = 1 << 9, // ColorEdit: Disable display of inline text label (however the label is still used in tooltip and picker) + ImGuiColorEditFlags_AlphaBar = 1 << 10, // ColorPicker: Show vertical alpha bar/gradient ImGuiColorEditFlags_ModeMask_ = ImGuiColorEditFlags_RGB|ImGuiColorEditFlags_HSV|ImGuiColorEditFlags_HEX }; diff --git a/imgui_demo.cpp b/imgui_demo.cpp index f0f35438a..a4108ed7b 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -674,15 +674,17 @@ void ImGui::ShowTestWindow(bool* p_open) ImGui::Text("Color picker:"); static bool alpha = false; + static bool alpha_bar = false; static bool label = true; static int inputs_mode = 0; static float width = 200.0f; ImGui::Checkbox("With Alpha", &alpha); + ImGui::Checkbox("With Alpha Bar", &alpha_bar); ImGui::Checkbox("With Label", &label); ImGui::Combo("Mode", &inputs_mode, "All Inputs\0No Inputs\0RGB Input\0HSV Input\0HEX Input\0"); ImGui::DragFloat("Width", &width, 1.0f, 1.0f, 999.0f); ImGui::PushItemWidth(width); - ImGuiColorEditFlags flags = (label ? 0 : ImGuiColorEditFlags_NoLabel); + ImGuiColorEditFlags flags = (label ? 0 : ImGuiColorEditFlags_NoLabel) | (alpha_bar ? ImGuiColorEditFlags_AlphaBar : 0); if (inputs_mode == 1) flags |= ImGuiColorEditFlags_NoInputs; if (inputs_mode == 2) flags |= ImGuiColorEditFlags_RGB; if (inputs_mode == 3) flags |= ImGuiColorEditFlags_HSV; From a8b202782f26fa1cc1dd18884ef972e394d8d396 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 22 Jul 2017 19:37:13 +0800 Subject: [PATCH 112/921] ColorPicker,ColorButton: Honor Border/Shadow style settings (#346) --- imgui.cpp | 21 +++++++++++++++++---- imgui_internal.h | 1 + 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index c531b74c7..e9aabe362 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2977,6 +2977,16 @@ void ImGui::RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool border, } } +void ImGui::RenderFrameBorder(ImVec2 p_min, ImVec2 p_max, float rounding) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->Flags & ImGuiWindowFlags_ShowBorders) + { + window->DrawList->AddRect(p_min+ImVec2(1,1), p_max+ImVec2(1,1), GetColorU32(ImGuiCol_BorderShadow), rounding); + window->DrawList->AddRect(p_min, p_max, GetColorU32(ImGuiCol_Border), rounding); + } +} + // Render a triangle to denote expanded/collapsed state void ImGui::RenderCollapseTriangle(ImVec2 p_min, bool is_open, float scale) { @@ -9033,8 +9043,7 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl bool hovered, held; bool pressed = ButtonBehavior(bb, id, &hovered, &held); - window->DrawList->AddRectFilled(bb.Min, bb.Max, GetColorU32(*(ImVec4*)&col), style.FrameRounding); - //window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(border_col), style.FrameRounding); + RenderFrame(bb.Min, bb.Max, GetColorU32(*(ImVec4*)&col), true, style.FrameRounding); if (hovered && !(flags & ImGuiColorEditFlags_NoTooltip)) ColorTooltip(desc_id, &col.x, flags & ImGuiColorEditFlags_NoAlpha); @@ -9347,14 +9356,17 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl hue_colors[i], hue_colors[i], hue_colors[i + 1], hue_colors[i + 1]); } float bar0_line_y = (float)(int)(picker_pos.y + H * sv_picker_size + 0.5f); + RenderFrameBorder(ImVec2(bar0_pos_x, picker_pos.y), ImVec2(bar0_pos_x + bars_width, picker_pos.y + sv_picker_size), 0.0f); draw_list->AddLine(ImVec2(bar0_pos_x - bars_line_extrude, bar0_line_y), ImVec2(bar0_pos_x + bars_width + bars_line_extrude, bar0_line_y), IM_COL32_WHITE); // Render alpha bar if (alpha_bar) { float alpha = ImSaturate(col[3]); - float bar1_line_y = (float)(int)(picker_pos.y + (1.0f-alpha) * sv_picker_size + 0.5f); - draw_list->AddRectFilledMultiColor(ImVec2(bar1_pos_x, picker_pos.y), ImVec2(bar1_pos_x + bars_width, picker_pos.y + sv_picker_size), IM_COL32_WHITE, IM_COL32_WHITE, IM_COL32_BLACK, IM_COL32_BLACK); + float bar1_line_y = (float)(int)(picker_pos.y + (1.0f - alpha) * sv_picker_size + 0.5f); + ImRect bar1_bb(bar1_pos_x, picker_pos.y, bar1_pos_x + bars_width, picker_pos.y + sv_picker_size); + draw_list->AddRectFilledMultiColor(bar1_bb.Min, bar1_bb.Max, IM_COL32_WHITE, IM_COL32_WHITE, IM_COL32_BLACK, IM_COL32_BLACK); + RenderFrameBorder(bar1_bb.Min, bar1_bb.Max, 0.0f); draw_list->AddLine(ImVec2(bar1_pos_x - bars_line_extrude, bar1_line_y), ImVec2(bar1_pos_x + bars_width + bars_line_extrude, bar1_line_y), IM_COL32_WHITE); } @@ -9362,6 +9374,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl ImU32 hue_color32 = ColorConvertFloat4ToU32(hue_color_f); draw_list->AddRectFilledMultiColor(picker_pos, picker_pos + ImVec2(sv_picker_size,sv_picker_size), IM_COL32_WHITE, hue_color32, hue_color32, IM_COL32_WHITE); draw_list->AddRectFilledMultiColor(picker_pos, picker_pos + ImVec2(sv_picker_size,sv_picker_size), IM_COL32_BLACK_TRANS, IM_COL32_BLACK_TRANS, IM_COL32_BLACK, IM_COL32_BLACK); + RenderFrameBorder(picker_pos, picker_pos + ImVec2(sv_picker_size,sv_picker_size), 0.0f); // Render cross-hair const float CROSSHAIR_SIZE = 7.0f; diff --git a/imgui_internal.h b/imgui_internal.h index f8f0a3828..58e8bd8e0 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -732,6 +732,7 @@ namespace ImGui IMGUI_API void RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end, float wrap_width); IMGUI_API void RenderTextClipped(const ImVec2& pos_min, const ImVec2& pos_max, const char* text, const char* text_end, const ImVec2* text_size_if_known, const ImVec2& align = ImVec2(0,0), const ImRect* clip_rect = NULL); IMGUI_API void RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool border = true, float rounding = 0.0f); + IMGUI_API void RenderFrameBorder(ImVec2 p_min, ImVec2 p_max, float rounding = 0.0f); IMGUI_API void RenderCollapseTriangle(ImVec2 pos, bool is_open, float scale = 1.0f); IMGUI_API void RenderBullet(ImVec2 pos); IMGUI_API void RenderCheckMark(ImVec2 pos, ImU32 col); From c8794c246e20167b111fda9ecf3adcc3da2532cb Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 23 Jul 2017 15:22:21 +0800 Subject: [PATCH 113/921] Examples: Vulkan: Batch file builds both debug and release --- examples/vulkan_example/build_win32.bat | 3 +++ examples/vulkan_example/build_win64.bat | 3 +++ 2 files changed, 6 insertions(+) diff --git a/examples/vulkan_example/build_win32.bat b/examples/vulkan_example/build_win32.bat index b76741ae6..bacb63943 100644 --- a/examples/vulkan_example/build_win32.bat +++ b/examples/vulkan_example/build_win32.bat @@ -1,4 +1,7 @@ @REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. + mkdir Debug cl /nologo /Zi /MD /I ..\.. /I ..\libs\glfw\include /I %VULKAN_SDK%\include *.cpp ..\..\*.cpp /FeDebug/vulkan_example.exe /FoDebug/ /link /LIBPATH:..\libs\glfw\lib-vc2010-32 /libpath:%VULKAN_SDK%\lib32 glfw3.lib opengl32.lib gdi32.lib shell32.lib vulkan-1.lib +mkdir Release +cl /nologo /Zi /MD /Ox /Oi /I ..\.. /I ..\libs\glfw\include /I %VULKAN_SDK%\include *.cpp ..\..\*.cpp /FeRelease/vulkan_example.exe /FoRelease/ /link /LIBPATH:..\libs\glfw\lib-vc2010-32 /libpath:%VULKAN_SDK%\lib32 glfw3.lib opengl32.lib gdi32.lib shell32.lib vulkan-1.lib diff --git a/examples/vulkan_example/build_win64.bat b/examples/vulkan_example/build_win64.bat index 83ecf5a1e..71e557b19 100644 --- a/examples/vulkan_example/build_win64.bat +++ b/examples/vulkan_example/build_win64.bat @@ -1,4 +1,7 @@ @REM Build for Visual Studio compiler. Run your copy of amd64/vcvars32.bat to setup 64-bit command-line compiler. + mkdir Debug cl /nologo /Zi /MD /I ..\.. /I ..\libs\glfw\include /I %VULKAN_SDK%\include *.cpp ..\..\*.cpp /FeDebug/vulkan_example.exe /FoDebug/ /link /LIBPATH:..\libs\glfw\lib-vc2010-64 /libpath:%VULKAN_SDK%\lib glfw3.lib opengl32.lib gdi32.lib shell32.lib vulkan-1.lib +mkdir Release +cl /nologo /Zi /MD /Ox /Oi /I ..\.. /I ..\libs\glfw\include /I %VULKAN_SDK%\include *.cpp ..\..\*.cpp /FeRelease/vulkan_example.exe /FoRelease/ /link /LIBPATH:..\libs\glfw\lib-vc2010-64 /libpath:%VULKAN_SDK%\lib glfw3.lib opengl32.lib gdi32.lib shell32.lib vulkan-1.lib From 166e8f62619fd6b3770e3b467820a43e2c4bdf06 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 23 Jul 2017 15:57:39 +0800 Subject: [PATCH 114/921] Examples: OpenGL2+GLFW/SDL: Added commented out glUseProgram(0) in main.cpp for visibility (#1116) --- examples/opengl2_example/imgui_impl_glfw.cpp | 2 +- examples/opengl2_example/main.cpp | 1 + examples/sdl_opengl2_example/imgui_impl_sdl.cpp | 2 +- examples/sdl_opengl2_example/main.cpp | 1 + 4 files changed, 4 insertions(+), 2 deletions(-) diff --git a/examples/opengl2_example/imgui_impl_glfw.cpp b/examples/opengl2_example/imgui_impl_glfw.cpp index f3bb0b2b8..435de7a81 100644 --- a/examples/opengl2_example/imgui_impl_glfw.cpp +++ b/examples/opengl2_example/imgui_impl_glfw.cpp @@ -58,7 +58,7 @@ void ImGui_ImplGlfw_RenderDrawLists(ImDrawData* draw_data) glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnableClientState(GL_COLOR_ARRAY); glEnable(GL_TEXTURE_2D); - //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context + //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context where shaders may be bound // Setup viewport, orthographic projection matrix glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); diff --git a/examples/opengl2_example/main.cpp b/examples/opengl2_example/main.cpp index a844db520..b60071490 100644 --- a/examples/opengl2_example/main.cpp +++ b/examples/opengl2_example/main.cpp @@ -77,6 +77,7 @@ int main(int, char**) glViewport(0, 0, display_w, display_h); glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); glClear(GL_COLOR_BUFFER_BIT); + //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context where shaders may be bound ImGui::Render(); glfwSwapBuffers(window); } diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl.cpp b/examples/sdl_opengl2_example/imgui_impl_sdl.cpp index f0758bdab..04b6a9a39 100644 --- a/examples/sdl_opengl2_example/imgui_impl_sdl.cpp +++ b/examples/sdl_opengl2_example/imgui_impl_sdl.cpp @@ -49,7 +49,7 @@ void ImGui_ImplSdl_RenderDrawLists(ImDrawData* draw_data) glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnableClientState(GL_COLOR_ARRAY); glEnable(GL_TEXTURE_2D); - //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context + //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context where shaders may be bound // Setup viewport, orthographic projection matrix glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); diff --git a/examples/sdl_opengl2_example/main.cpp b/examples/sdl_opengl2_example/main.cpp index f42e7faf4..72cf21a52 100644 --- a/examples/sdl_opengl2_example/main.cpp +++ b/examples/sdl_opengl2_example/main.cpp @@ -89,6 +89,7 @@ int main(int, char**) glViewport(0, 0, (int)ImGui::GetIO().DisplaySize.x, (int)ImGui::GetIO().DisplaySize.y); glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); glClear(GL_COLOR_BUFFER_BIT); + //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context where shaders may be bound ImGui::Render(); SDL_GL_SwapWindow(window); } From 645875a240db7336e9d10fa756d2ae16b7788bae Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 23 Jul 2017 16:13:17 +0800 Subject: [PATCH 115/921] Examples: Enable vsync by default in example applications (#1213, #1151) --- examples/directx10_example/main.cpp | 4 +++- examples/directx11_example/main.cpp | 4 +++- examples/directx9_example/main.cpp | 3 ++- examples/opengl2_example/main.cpp | 1 + examples/opengl3_example/main.cpp | 1 + 5 files changed, 10 insertions(+), 3 deletions(-) diff --git a/examples/directx10_example/main.cpp b/examples/directx10_example/main.cpp index fb98cad16..a7b282da4 100644 --- a/examples/directx10_example/main.cpp +++ b/examples/directx10_example/main.cpp @@ -183,7 +183,9 @@ int main(int, char**) // Rendering g_pd3dDevice->ClearRenderTargetView(g_mainRenderTargetView, (float*)&clear_col); ImGui::Render(); - g_pSwapChain->Present(0, 0); + + g_pSwapChain->Present(1, 0); // Present with vsync + //g_pSwapChain->Present(0, 0); // Present without vsync } ImGui_ImplDX10_Shutdown(); diff --git a/examples/directx11_example/main.cpp b/examples/directx11_example/main.cpp index e3fe5aa71..9e85d9e7c 100644 --- a/examples/directx11_example/main.cpp +++ b/examples/directx11_example/main.cpp @@ -186,7 +186,9 @@ int main(int, char**) // Rendering g_pd3dDeviceContext->ClearRenderTargetView(g_mainRenderTargetView, (float*)&clear_col); ImGui::Render(); - g_pSwapChain->Present(0, 0); + + g_pSwapChain->Present(1, 0); // Present with vsync + //g_pSwapChain->Present(0, 0); // Present without vsync } ImGui_ImplDX11_Shutdown(); diff --git a/examples/directx9_example/main.cpp b/examples/directx9_example/main.cpp index babee5fd4..ecc382a7b 100644 --- a/examples/directx9_example/main.cpp +++ b/examples/directx9_example/main.cpp @@ -63,7 +63,8 @@ int main(int, char**) g_d3dpp.BackBufferFormat = D3DFMT_UNKNOWN; g_d3dpp.EnableAutoDepthStencil = TRUE; g_d3dpp.AutoDepthStencilFormat = D3DFMT_D16; - g_d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; + g_d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE; // Present with vsync + //g_d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; // Present without vsync, maximum unthrottled framerate // Create the D3DDevice if (pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &g_d3dpp, &g_pd3dDevice) < 0) diff --git a/examples/opengl2_example/main.cpp b/examples/opengl2_example/main.cpp index b60071490..28cb90ff5 100644 --- a/examples/opengl2_example/main.cpp +++ b/examples/opengl2_example/main.cpp @@ -19,6 +19,7 @@ int main(int, char**) return 1; GLFWwindow* window = glfwCreateWindow(1280, 720, "ImGui OpenGL2 example", NULL, NULL); glfwMakeContextCurrent(window); + glfwSwapInterval(1); // Enable vsync // Setup ImGui binding ImGui_ImplGlfw_Init(window, true); diff --git a/examples/opengl3_example/main.cpp b/examples/opengl3_example/main.cpp index 074bab548..a1c45a535 100644 --- a/examples/opengl3_example/main.cpp +++ b/examples/opengl3_example/main.cpp @@ -26,6 +26,7 @@ int main(int, char**) #endif GLFWwindow* window = glfwCreateWindow(1280, 720, "ImGui OpenGL3 example", NULL, NULL); glfwMakeContextCurrent(window); + glfwSwapInterval(1); // Enable vsync gl3wInit(); // Setup ImGui binding From 4def2ce339ec9e04b0a02fa3e0a28c8cec5fbe2d Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 23 Jul 2017 17:55:39 +0800 Subject: [PATCH 116/921] ColorPicker: Demo tweaks (#346) --- imgui_demo.cpp | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index a4108ed7b..0a05e656f 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -666,33 +666,31 @@ void ImGui::ShowTestWindow(bool* p_open) ImGui::SameLine(); ShowHelpMarker("Click on the colored square to open a color picker.\nRight-click on the colored square to show options.\nCTRL+click on individual component to input value.\n"); ImGui::ColorEdit3("MyColor##1", (float*)&color, ImGuiColorEditFlags_HSV); - ImGui::Text("Color widget w/ Alpha:"); + ImGui::Text("Color widget with Alpha:"); ImGui::ColorEdit4("MyColor##2", (float*)&color); ImGui::Text("Color button only:"); + ImGui::SameLine(); ShowHelpMarker("With the ImGuiColorEditFlags_NoInputs flag you can hide all the slider/text inputs.\nWith the ImGuiColorEditFlags_NoLabel flag you can pass a non-empty label which will only be used for the tooltip and picker popup."); ImGui::ColorEdit4("MyColor##3", (float*)&color, ImGuiColorEditFlags_NoInputs|ImGuiColorEditFlags_NoLabel); ImGui::Text("Color picker:"); static bool alpha = false; static bool alpha_bar = false; - static bool label = true; static int inputs_mode = 0; static float width = 200.0f; ImGui::Checkbox("With Alpha", &alpha); ImGui::Checkbox("With Alpha Bar", &alpha_bar); - ImGui::Checkbox("With Label", &label); ImGui::Combo("Mode", &inputs_mode, "All Inputs\0No Inputs\0RGB Input\0HSV Input\0HEX Input\0"); ImGui::DragFloat("Width", &width, 1.0f, 1.0f, 999.0f); ImGui::PushItemWidth(width); - ImGuiColorEditFlags flags = (label ? 0 : ImGuiColorEditFlags_NoLabel) | (alpha_bar ? ImGuiColorEditFlags_AlphaBar : 0); + ImGuiColorEditFlags flags = 0; + if (!alpha) flags |= ImGuiColorEditFlags_NoAlpha; // This is by default if you call ColorPicker3() instead of ColorPicker4() + if (alpha_bar) flags |= ImGuiColorEditFlags_AlphaBar; if (inputs_mode == 1) flags |= ImGuiColorEditFlags_NoInputs; if (inputs_mode == 2) flags |= ImGuiColorEditFlags_RGB; if (inputs_mode == 3) flags |= ImGuiColorEditFlags_HSV; if (inputs_mode == 4) flags |= ImGuiColorEditFlags_HEX; - if (alpha) - ImGui::ColorPicker4("MyColor##4", (float*)&color, flags); - else - ImGui::ColorPicker3("MyColor##4", (float*)&color, flags); + ImGui::ColorPicker4("MyColor##4", (float*)&color, flags); ImGui::PopItemWidth(); ImGui::TreePop(); From 7b2d79cffd2177cfaac01e7a24da8744dc071845 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 23 Jul 2017 18:44:32 +0800 Subject: [PATCH 117/921] ColorEdit: Added ImGuiColorEditFlags_Float flag to display and edit drag values in 0.0..1.0 range instead of 0..255. (#346) --- imgui.cpp | 29 +++++++++++++++++++++-------- imgui.h | 1 + imgui_demo.cpp | 3 +++ 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index e9aabe362..b88ceafa4 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9097,6 +9097,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag int i[4] = { IM_F32_TO_INT8_UNBOUND(f[0]), IM_F32_TO_INT8_UNBOUND(f[1]), IM_F32_TO_INT8_UNBOUND(f[2]), IM_F32_TO_INT8_UNBOUND(f[3]) }; bool value_changed = false; + bool value_changed_as_float = false; BeginGroup(); PushID(label); @@ -9107,15 +9108,21 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag const float w_item_one = ImMax(1.0f, (float)(int)((w_items_all - (style.ItemInnerSpacing.x) * (components-1)) / (float)components)); const float w_item_last = ImMax(1.0f, (float)(int)(w_items_all - (w_item_one + style.ItemInnerSpacing.x) * (components-1))); - const bool hide_prefix = (w_item_one <= CalcTextSize("M:999").x); + const bool hide_prefix = (w_item_one <= CalcTextSize((flags & ImGuiColorEditFlags_Float) ? "M:1.000" : "M:999").x); const char* ids[4] = { "##X", "##Y", "##Z", "##W" }; - const char* fmt_table[3][4] = + const char* fmt_table_int[3][4] = { { "%3.0f", "%3.0f", "%3.0f", "%3.0f" }, // Short display { "R:%3.0f", "G:%3.0f", "B:%3.0f", "A:%3.0f" }, // Long display for RGBA - { "H:%3.0f", "S:%3.0f", "V:%3.0f", "A:%3.0f" } // Long display for HSVV + { "H:%3.0f", "S:%3.0f", "V:%3.0f", "A:%3.0f" } // Long display for HSVA }; - const char** fmt = hide_prefix ? fmt_table[0] : (flags & ImGuiColorEditFlags_HSV) ? fmt_table[2] : fmt_table[1]; + const char* fmt_table_float[3][4] = + { + { "%0.3f", "%0.3f", "%0.3f", "%0.3f" }, // Short display + { "R:%0.3f", "G:%0.3f", "B:%0.3f", "A:%0.3f" }, // Long display for RGBA + { "H:%0.3f", "S:%0.3f", "V:%0.3f", "A:%0.3f" } // Long display for HSVA + }; + const int fmt_idx = hide_prefix ? 0 : (flags & ImGuiColorEditFlags_HSV) ? 2 : 1; PushItemWidth(w_item_one); for (int n = 0; n < components; n++) @@ -9124,7 +9131,10 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag SameLine(0, style.ItemInnerSpacing.x); if (n + 1 == components) PushItemWidth(w_item_last); - value_changed |= DragInt(ids[n], &i[n], 1.0f, 0, 255, fmt[n]); + if (flags & ImGuiColorEditFlags_Float) + value_changed |= value_changed_as_float |= DragFloat(ids[n], &f[n], 1.0f/255.0f, 0.0f, 1.0f, fmt_table_float[fmt_idx][n]); + else + value_changed |= DragInt(ids[n], &i[n], 1.0f, 0, 255, fmt_table_int[fmt_idx][n]); } PopItemWidth(); PopItemWidth(); @@ -9183,8 +9193,10 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag TextUnformatted(label, label_display_end); Separator(); } - PushItemWidth(ColorSquareSize() * 12.0f); - value_changed |= ColorPicker4("##picker", col, (flags & ImGuiColorEditFlags_NoAlpha) | (ImGuiColorEditFlags_RGB | ImGuiColorEditFlags_HSV | ImGuiColorEditFlags_HEX)); + float square_sz = ColorSquareSize(); + ImGuiColorEditFlags picker_flags = (flags & (ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_Float)) | (ImGuiColorEditFlags_RGB | ImGuiColorEditFlags_HSV | ImGuiColorEditFlags_HEX) | ImGuiColorEditFlags_NoLabel; + PushItemWidth(square_sz * 12.0f); + value_changed |= ColorPicker4("##picker", col, picker_flags); PopItemWidth(); EndPopup(); } @@ -9211,6 +9223,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag // Convert back if (!picker_active) { + if (!value_changed_as_float) for (int n = 0; n < 4; n++) f[n] = i[n] / 255.0f; if (flags & ImGuiColorEditFlags_HSV) @@ -9320,7 +9333,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl if ((flags & ImGuiColorEditFlags_ModeMask_) == 0) flags |= ImGuiColorEditFlags_RGB | ImGuiColorEditFlags_HSV | ImGuiColorEditFlags_HEX; PushItemWidth((alpha_bar ? bar1_pos_x : bar0_pos_x) + bars_width - picker_pos.x); - ImGuiColorEditFlags sub_flags = (flags & (ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoColorSquare)) | ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_NoOptions | ImGuiColorEditFlags_NoTooltip; + ImGuiColorEditFlags sub_flags = (flags & (ImGuiColorEditFlags_Float | ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoColorSquare)) | ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_NoOptions | ImGuiColorEditFlags_NoTooltip; if (flags & ImGuiColorEditFlags_RGB) value_changed |= ColorEdit4("##rgb", col, sub_flags | ImGuiColorEditFlags_RGB); if (flags & ImGuiColorEditFlags_HSV) diff --git a/imgui.h b/imgui.h index 52385f00d..ea8eb083e 100644 --- a/imgui.h +++ b/imgui.h @@ -674,6 +674,7 @@ enum ImGuiColorEditFlags_ ImGuiColorEditFlags_NoTooltip = 1 << 8, // ColorEdit, ColorButton: Disable tooltip when hovering the colored square. ImGuiColorEditFlags_NoLabel = 1 << 9, // ColorEdit: Disable display of inline text label (however the label is still used in tooltip and picker) ImGuiColorEditFlags_AlphaBar = 1 << 10, // ColorPicker: Show vertical alpha bar/gradient + ImGuiColorEditFlags_Float = 1 << 11, // ColorEdit, ColorPicker: display values formatted as 0.0f..1.0f floats instead of 0..255 integers ImGuiColorEditFlags_ModeMask_ = ImGuiColorEditFlags_RGB|ImGuiColorEditFlags_HSV|ImGuiColorEditFlags_HEX }; diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 0a05e656f..83ac78b01 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -669,6 +669,9 @@ void ImGui::ShowTestWindow(bool* p_open) ImGui::Text("Color widget with Alpha:"); ImGui::ColorEdit4("MyColor##2", (float*)&color); + ImGui::Text("Color widget with Float Display:"); + ImGui::ColorEdit4("MyColor##2f", (float*)&color, ImGuiColorEditFlags_Float); + ImGui::Text("Color button only:"); ImGui::SameLine(); ShowHelpMarker("With the ImGuiColorEditFlags_NoInputs flag you can hide all the slider/text inputs.\nWith the ImGuiColorEditFlags_NoLabel flag you can pass a non-empty label which will only be used for the tooltip and picker popup."); ImGui::ColorEdit4("MyColor##3", (float*)&color, ImGuiColorEditFlags_NoInputs|ImGuiColorEditFlags_NoLabel); From 8d32e8dae6609a7ba373c680f16a42a52785145a Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 23 Jul 2017 18:48:45 +0800 Subject: [PATCH 118/921] ColorPicker: Handle out of 0..1 range colors when displaying the cross hair. (#346) --- imgui.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index b88ceafa4..5c935f945 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9389,9 +9389,9 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl draw_list->AddRectFilledMultiColor(picker_pos, picker_pos + ImVec2(sv_picker_size,sv_picker_size), IM_COL32_BLACK_TRANS, IM_COL32_BLACK_TRANS, IM_COL32_BLACK, IM_COL32_BLACK); RenderFrameBorder(picker_pos, picker_pos + ImVec2(sv_picker_size,sv_picker_size), 0.0f); - // Render cross-hair + // Render cross-hair (clamp S/V within 0..1 range because floating points colors may lead HSV values to be out of range) const float CROSSHAIR_SIZE = 7.0f; - ImVec2 p((float)(int)(picker_pos.x + S * sv_picker_size + 0.5f), (float)(int)(picker_pos.y + (1 - V) * sv_picker_size + 0.5f)); + ImVec2 p((float)(int)(picker_pos.x + ImSaturate(S) * sv_picker_size + 0.5f), (float)(int)(picker_pos.y + ImSaturate(1 - V) * sv_picker_size + 0.5f)); draw_list->AddLine(ImVec2(p.x - CROSSHAIR_SIZE, p.y), ImVec2(p.x - 2, p.y), IM_COL32_WHITE); draw_list->AddLine(ImVec2(p.x + CROSSHAIR_SIZE, p.y), ImVec2(p.x + 2, p.y), IM_COL32_WHITE); draw_list->AddLine(ImVec2(p.x, p.y + CROSSHAIR_SIZE), ImVec2(p.x, p.y + 2), IM_COL32_WHITE); From 4f1f251bd2b0b81498b6a3fbb569b40110e45acd Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 23 Jul 2017 19:02:26 +0800 Subject: [PATCH 119/921] ColorEdit, ColorPicker: Context / options menu allows to toggle between u8 and float display. Using short words to avoid localization. (#346) --- imgui.cpp | 16 +++++++++++----- imgui.h | 3 ++- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 5c935f945..3d84e83b6 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9085,7 +9085,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag // Read back edit mode from persistent storage if (!(flags & ImGuiColorEditFlags_NoOptions)) - flags = (flags & (~ImGuiColorEditFlags_ModeMask_)) | (g.ColorEditModeStorage.GetInt(id, (flags & ImGuiColorEditFlags_ModeMask_)) & ImGuiColorEditFlags_ModeMask_); + flags = (flags & (~ImGuiColorEditFlags_StoredMask_)) | (g.ColorEditModeStorage.GetInt(id, (flags & ImGuiColorEditFlags_StoredMask_)) & ImGuiColorEditFlags_StoredMask_); // Check that exactly one of RGB/HSV/HEX is set IM_ASSERT(ImIsPowerOfTwo((int)(flags & ImGuiColorEditFlags_ModeMask_))); // @@ -9202,10 +9202,16 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag } if (!(flags & ImGuiColorEditFlags_NoOptions) && BeginPopup("context")) { - // FIXME-LOCALIZATION - if (MenuItem("Edit as RGB", NULL, (flags & ImGuiColorEditFlags_RGB)?1:0)) g.ColorEditModeStorage.SetInt(id, (int)(ImGuiColorEditFlags_RGB)); - if (MenuItem("Edit as HSV", NULL, (flags & ImGuiColorEditFlags_HSV)?1:0)) g.ColorEditModeStorage.SetInt(id, (int)(ImGuiColorEditFlags_HSV)); - if (MenuItem("Edit as Hexadecimal", NULL, (flags & ImGuiColorEditFlags_HEX)?1:0)) g.ColorEditModeStorage.SetInt(id, (int)(ImGuiColorEditFlags_HEX)); + // Display and store options. Don't apply to 'flags' this frame. + ImGuiColorEditFlags new_flags = -1; + if (RadioButton("RGB", (flags & ImGuiColorEditFlags_RGB)?1:0)) new_flags = (flags & ~ImGuiColorEditFlags_ModeMask_) | ImGuiColorEditFlags_RGB; + if (RadioButton("HSV", (flags & ImGuiColorEditFlags_HSV)?1:0)) new_flags = (flags & ~ImGuiColorEditFlags_ModeMask_) | ImGuiColorEditFlags_HSV; + if (RadioButton("HEX", (flags & ImGuiColorEditFlags_HEX)?1:0)) new_flags = (flags & ~ImGuiColorEditFlags_ModeMask_) | ImGuiColorEditFlags_HEX; + Separator(); + if (RadioButton("0..255", (flags & ImGuiColorEditFlags_Float)?0:1)) new_flags = (flags & ~ImGuiColorEditFlags_Float); + if (RadioButton("0.00..1.00", (flags & ImGuiColorEditFlags_Float)?1:0)) new_flags = (flags | ImGuiColorEditFlags_Float); + if (new_flags != -1) + g.ColorEditModeStorage.SetInt(id, (int)(new_flags & ImGuiColorEditFlags_StoredMask_)); EndPopup(); } diff --git a/imgui.h b/imgui.h index ea8eb083e..d91da3966 100644 --- a/imgui.h +++ b/imgui.h @@ -675,7 +675,8 @@ enum ImGuiColorEditFlags_ ImGuiColorEditFlags_NoLabel = 1 << 9, // ColorEdit: Disable display of inline text label (however the label is still used in tooltip and picker) ImGuiColorEditFlags_AlphaBar = 1 << 10, // ColorPicker: Show vertical alpha bar/gradient ImGuiColorEditFlags_Float = 1 << 11, // ColorEdit, ColorPicker: display values formatted as 0.0f..1.0f floats instead of 0..255 integers - ImGuiColorEditFlags_ModeMask_ = ImGuiColorEditFlags_RGB|ImGuiColorEditFlags_HSV|ImGuiColorEditFlags_HEX + ImGuiColorEditFlags_ModeMask_ = ImGuiColorEditFlags_RGB|ImGuiColorEditFlags_HSV|ImGuiColorEditFlags_HEX, + ImGuiColorEditFlags_StoredMask_ = ImGuiColorEditFlags_RGB|ImGuiColorEditFlags_HSV|ImGuiColorEditFlags_HEX|ImGuiColorEditFlags_Float }; // Enumeration for GetMouseCursor() From f39cd61bf0f0c9eb631fdc13c9a7538e25a5a2e8 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 23 Jul 2017 19:08:58 +0800 Subject: [PATCH 120/921] Reorder ImGuiColorEditFlags_ (#346) --- imgui.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/imgui.h b/imgui.h index d91da3966..57ba915c0 100644 --- a/imgui.h +++ b/imgui.h @@ -663,18 +663,18 @@ enum ImGuiStyleVar_ // Enumeration for ColorEdit3() / ColorEdit4() / ColorPicker3() / ColorPicker4() enum ImGuiColorEditFlags_ { - ImGuiColorEditFlags_RGB = 1 << 0, // ColorEdit: Default to one among RGB/HSV/HEX. User can still use the options menu to change. ColorPicker: Choose any combination or RGB/HSX/HEX.. + ImGuiColorEditFlags_RGB = 1 << 0, // ColorEdit: Default to one among RGB/HSV/HEX. User can still use the options menu to change. ColorPicker: Choose any combination or RGB/HSV/HEX. ImGuiColorEditFlags_HSV = 1 << 1, // " ImGuiColorEditFlags_HEX = 1 << 2, // " - ImGuiColorEditFlags_NoAlpha = 1 << 3, // ColorEdit, ColorPicker: show/edit Alpha component. - ImGuiColorEditFlags_NoPicker = 1 << 4, // ColorEdit: Disable picker when clicking on colored square - ImGuiColorEditFlags_NoOptions = 1 << 5, // ColorEdit: Disable toggling options menu when right-clicking colored square - ImGuiColorEditFlags_NoColorSquare = 1 << 6, // ColorEdit, ColorPicker: Disable colored square. - ImGuiColorEditFlags_NoInputs = 1 << 7, // ColorEdit, ColorPicker: Disable inputs sliders/text widgets, show only the colored square. - ImGuiColorEditFlags_NoTooltip = 1 << 8, // ColorEdit, ColorButton: Disable tooltip when hovering the colored square. - ImGuiColorEditFlags_NoLabel = 1 << 9, // ColorEdit: Disable display of inline text label (however the label is still used in tooltip and picker) - ImGuiColorEditFlags_AlphaBar = 1 << 10, // ColorPicker: Show vertical alpha bar/gradient - ImGuiColorEditFlags_Float = 1 << 11, // ColorEdit, ColorPicker: display values formatted as 0.0f..1.0f floats instead of 0..255 integers + ImGuiColorEditFlags_Float = 1 << 3, // ColorEdit, ColorPicker: display values formatted as 0.0f..1.0f floats instead of 0..255 integers. No round-trip of value via integers. + ImGuiColorEditFlags_AlphaBar = 1 << 4, // ColorPicker: Show vertical alpha bar/gradient. + ImGuiColorEditFlags_NoAlpha = 1 << 5, // ColorEdit, ColorPicker: show/edit Alpha component. + ImGuiColorEditFlags_NoPicker = 1 << 6, // ColorEdit: Disable picker when clicking on colored square + ImGuiColorEditFlags_NoOptions = 1 << 7, // ColorEdit: Disable toggling options menu when right-clicking colored square + ImGuiColorEditFlags_NoColorSquare = 1 << 8, // ColorEdit, ColorPicker: Disable colored square. + ImGuiColorEditFlags_NoInputs = 1 << 9, // ColorEdit, ColorPicker: Disable inputs sliders/text widgets, show only the colored square. + ImGuiColorEditFlags_NoTooltip = 1 << 10, // ColorEdit, ColorButton: Disable tooltip when hovering the colored square. + ImGuiColorEditFlags_NoLabel = 1 << 11, // ColorEdit: Disable display of inline text label (the label is still used in tooltip and picker) ImGuiColorEditFlags_ModeMask_ = ImGuiColorEditFlags_RGB|ImGuiColorEditFlags_HSV|ImGuiColorEditFlags_HEX, ImGuiColorEditFlags_StoredMask_ = ImGuiColorEditFlags_RGB|ImGuiColorEditFlags_HSV|ImGuiColorEditFlags_HEX|ImGuiColorEditFlags_Float }; From 6e04cedd5f972ae00a5a6c8719eec5e4015849e8 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 25 Jul 2017 20:06:18 +0800 Subject: [PATCH 121/921] Updated link to binaries --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9cb17933f..48dd80dd0 100644 --- a/README.md +++ b/README.md @@ -44,8 +44,8 @@ ImGui allows you create elaborate tools as well as very short-lived ones. On the Binaries/Demo ------------- -You should be able to build the examples from sources (tested on Windows/Mac/Linux). If you don't, let me know! If you want to have a quick look at the features of ImGui, you can download Windows binaries of the demo app here. -- [imgui-demo-binaries-20161113.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20161113.zip) (Windows binaries, ImGui 1.49+ 2016/11/13, 5 executables, 588 KB) +You should be able to build the examples from sources (tested on Windows/Mac/Linux). If you don't, let me know! If you want to have a quick look at some ImGui features, you can download Windows binaries of the demo app here: +- [imgui-demo-binaries-20170723.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20170723.zip) (Windows binaries, ImGui 1.51+ 2017/07/23, 5 executables, 808 KB) Bindings -------- From 95fe11b5bf14f72fc70762347c583d089e619a65 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 26 Jul 2017 14:34:59 +0800 Subject: [PATCH 122/921] Added GetColorU32(u32) variant that does the style alpha multiply without a floating point round trip. Not 100% sure about that before the signature may seem ambiguous? But also make using imgui+drawlist more consistent in end-user extensions. --- imgui.cpp | 11 +++++++++++ imgui.h | 1 + 2 files changed, 12 insertions(+) diff --git a/imgui.cpp b/imgui.cpp index 3d84e83b6..e8a7a7f5f 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1253,6 +1253,16 @@ ImU32 ImGui::GetColorU32(const ImVec4& col) return ColorConvertFloat4ToU32(c); } +ImU32 ImGui::GetColorU32(ImU32 col) +{ + float style_alpha = GImGui->Style.Alpha; + if (style_alpha >= 1.0f) + return col; + int a = (col & IM_COL32_A_MASK) >> IM_COL32_A_SHIFT; + a = (int)(a * style_alpha); // We don't need to clamp 0..255 because Style.Alpha is in 0..1 range. + return (col & ~IM_COL32_A_MASK) | (a << IM_COL32_A_SHIFT); +} + // Convert rgb floats ([0-1],[0-1],[0-1]) to hsv floats ([0-1],[0-1],[0-1]), from Foley & van Dam p592 // Optimized http://lolengine.net/blog/2013/01/13/fast-rgb-to-hsv void ImGui::ColorConvertRGBtoHSV(float r, float g, float b, float& out_h, float& out_s, float& out_v) @@ -2143,6 +2153,7 @@ void ImGui::NewFrame() IM_ASSERT(g.IO.Fonts->Fonts.Size > 0); // Font Atlas not created. Did you call io.Fonts->GetTexDataAsRGBA32 / GetTexDataAsAlpha8 ? IM_ASSERT(g.IO.Fonts->Fonts[0]->IsLoaded()); // Font Atlas not created. Did you call io.Fonts->GetTexDataAsRGBA32 / GetTexDataAsAlpha8 ? IM_ASSERT(g.Style.CurveTessellationTol > 0.0f); // Invalid style setting + IM_ASSERT(g.Style.Alpha >= 0.0f && g.Style.Alpha <= 1.0f); // Invalid style setting. Alpha cannot be negative (allows us to avoid a few clamps in color computations) if (!g.Initialized) { diff --git a/imgui.h b/imgui.h index 57ba915c0..c6cf65153 100644 --- a/imgui.h +++ b/imgui.h @@ -190,6 +190,7 @@ namespace ImGui IMGUI_API ImVec2 GetFontTexUvWhitePixel(); // get UV coordinate for a while pixel, useful to draw custom shapes via the ImDrawList API IMGUI_API ImU32 GetColorU32(ImGuiCol idx, float alpha_mul = 1.0f); // retrieve given style color with style alpha applied and optional extra alpha multiplier IMGUI_API ImU32 GetColorU32(const ImVec4& col); // retrieve given color with style alpha applied + IMGUI_API ImU32 GetColorU32(ImU32 col); // retrieve given color with style alpha applied // Parameters stacks (current window) IMGUI_API void PushItemWidth(float item_width); // width of items for the common item+label case, pixels. 0.0f = default to ~2/3 of windows width, >0.0f: width in pixels, <0.0f align xx pixels to the right of window (so -1.0f always align width to the right side) From 9d0e5beaa7ac0e0e44feab7221797ac113c592f1 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 26 Jul 2017 14:35:50 +0800 Subject: [PATCH 123/921] GetColorU32(ImGuiCol): avoid using GImGui twice since some implementation make it a TLS-ish variable with non-trivial accessors. --- imgui.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index e8a7a7f5f..cf5b3238a 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1241,15 +1241,17 @@ ImU32 ImGui::ColorConvertFloat4ToU32(const ImVec4& in) ImU32 ImGui::GetColorU32(ImGuiCol idx, float alpha_mul) { - ImVec4 c = GImGui->Style.Colors[idx]; - c.w *= GImGui->Style.Alpha * alpha_mul; + ImGuiStyle& style = GImGui->Style; + ImVec4 c = style.Colors[idx]; + c.w *= style.Alpha * alpha_mul; return ColorConvertFloat4ToU32(c); } ImU32 ImGui::GetColorU32(const ImVec4& col) { + ImGuiStyle& style = GImGui->Style; ImVec4 c = col; - c.w *= GImGui->Style.Alpha; + c.w *= style.Alpha; return ColorConvertFloat4ToU32(c); } From df5687988326acab20c0dab7a3303f3606248762 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 26 Jul 2017 14:53:15 +0800 Subject: [PATCH 124/921] imDrawList::PathRect() uses ImGuiCorner_ enums. Should fully promote this to imgui.h at some point. --- imgui_draw.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index fa6838a6b..654e55369 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -774,9 +774,14 @@ void ImDrawList::PathBezierCurveTo(const ImVec2& p2, const ImVec2& p3, const ImV void ImDrawList::PathRect(const ImVec2& a, const ImVec2& b, float rounding, int rounding_corners) { + const int corners_top = ImGuiCorner_TopLeft | ImGuiCorner_TopRight; + const int corners_bottom = ImGuiCorner_BottomLeft | ImGuiCorner_BottomRight; + const int corners_left = ImGuiCorner_TopLeft | ImGuiCorner_BottomLeft; + const int corners_right = ImGuiCorner_TopRight | ImGuiCorner_BottomRight; + float r = rounding; - r = ImMin(r, fabsf(b.x-a.x) * ( ((rounding_corners&(1|2))==(1|2)) || ((rounding_corners&(4|8))==(4|8)) ? 0.5f : 1.0f ) - 1.0f); - r = ImMin(r, fabsf(b.y-a.y) * ( ((rounding_corners&(1|8))==(1|8)) || ((rounding_corners&(2|4))==(2|4)) ? 0.5f : 1.0f ) - 1.0f); + r = ImMin(r, fabsf(b.x-a.x) * ( ((rounding_corners & corners_top) == corners_top) || ((rounding_corners & corners_bottom) == corners_bottom) ? 0.5f : 1.0f ) - 1.0f); + r = ImMin(r, fabsf(b.y-a.y) * ( ((rounding_corners & corners_left) == corners_left) || ((rounding_corners & corners_right) == corners_right) ? 0.5f : 1.0f ) - 1.0f); if (r <= 0.0f || rounding_corners == 0) { @@ -787,10 +792,10 @@ void ImDrawList::PathRect(const ImVec2& a, const ImVec2& b, float rounding, int } else { - const float r0 = (rounding_corners & 1) ? r : 0.0f; - const float r1 = (rounding_corners & 2) ? r : 0.0f; - const float r2 = (rounding_corners & 4) ? r : 0.0f; - const float r3 = (rounding_corners & 8) ? r : 0.0f; + const float r0 = (rounding_corners & ImGuiCorner_TopLeft) ? r : 0.0f; + const float r1 = (rounding_corners & ImGuiCorner_TopRight) ? r : 0.0f; + const float r2 = (rounding_corners & ImGuiCorner_BottomRight) ? r : 0.0f; + const float r3 = (rounding_corners & ImGuiCorner_BottomLeft) ? r : 0.0f; PathArcToFast(ImVec2(a.x+r0,a.y+r0), r0, 6, 9); PathArcToFast(ImVec2(b.x-r1,a.y+r1), r1, 9, 12); PathArcToFast(ImVec2(b.x-r2,b.y-r2), r2, 0, 3); From 78a8f798c505ba659f14e4737cdef582ea073452 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 26 Jul 2017 15:24:09 +0800 Subject: [PATCH 125/921] ColorEdit, ColorPicker, ColorButton: Display grid under transparent colors (WIP) (#346) --- imgui.cpp | 32 +++++++++++++++++++++++++++----- imgui_internal.h | 1 + 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index cf5b3238a..728008b51 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9017,7 +9017,7 @@ void ImGui::ColorTooltip(const char* text, const float col[4], ImGuiColorEditFla } ImVec2 sz(g.FontSize * 3, g.FontSize * 3); - window->DrawList->AddRectFilled(window->DC.CursorPos, window->DC.CursorPos + sz, IM_COL32(cr,cg,cb,255)); + RenderColorRectWithAlphaGrid(window->DC.CursorPos, window->DC.CursorPos + sz, IM_COL32(cr,cg,cb,ca), g.FontSize, g.Style.FrameRounding); Dummy(sz); SameLine(); if (flags & ImGuiColorEditFlags_NoAlpha) @@ -9033,6 +9033,24 @@ static inline float ColorSquareSize() return g.FontSize + g.Style.FramePadding.y * 2.0f; } +void ImGui::RenderColorRectWithAlphaGrid(ImVec2 p_min, ImVec2 p_max, ImU32 col, float grid_step, float rounding) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (((col & IM_COL32_A_MASK) >> IM_COL32_A_SHIFT) < 0xFF) + { + ImU32 col_bg1 = GetColorU32(IM_COL32(204,204,204,255)); + ImU32 col_bg2 = GetColorU32(IM_COL32(128,128,128,255)); + window->DrawList->AddRectFilled(p_min, p_max, col_bg1, rounding); + int yi = 0; + for (float y = p_min.y; y < p_max.y; y += grid_step, yi++) + for (float x = p_min.x + ((yi & 1) ? grid_step : 0.0f); x < p_max.x; x += grid_step * 2) + { + window->DrawList->AddRectFilled(ImVec2(x,y), ImMin(ImVec2(x + grid_step, y + grid_step), p_max), col_bg2, 0.0f); + } + } + window->DrawList->AddRectFilled(p_min, p_max, col, rounding); +} + // A little colored square. Return true when clicked. // FIXME: May want to display/ignore the alpha component in the color display? Yet show it in the tooltip. // 'desc_id' is not called 'label' because we don't display it next to the button, but only in the tooltip. @@ -9045,10 +9063,11 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl ImGuiContext& g = *GImGui; const ImGuiStyle& style = g.Style; const ImGuiID id = window->GetID(desc_id); + float default_size = ColorSquareSize(); if (size.x == 0.0f) - size.x = ColorSquareSize(); + size.x = default_size; if (size.y == 0.0f) - size.y = ColorSquareSize(); + size.y = default_size; const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size); ItemSize(bb); if (!ItemAdd(bb, &id)) @@ -9056,7 +9075,9 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl bool hovered, held; bool pressed = ButtonBehavior(bb, id, &hovered, &held); - RenderFrame(bb.Min, bb.Max, GetColorU32(*(ImVec4*)&col), true, style.FrameRounding); + float grid_step = ImMin(g.FontSize, ImMin(size.x, size.y) * 0.5f); + RenderColorRectWithAlphaGrid(bb.Min, bb.Max, GetColorU32(col), grid_step, style.FrameRounding); + RenderFrameBorder(bb.Min, bb.Max, style.FrameRounding); if (hovered && !(flags & ImGuiColorEditFlags_NoTooltip)) ColorTooltip(desc_id, &col.x, flags & ImGuiColorEditFlags_NoAlpha); @@ -9184,11 +9205,12 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag if (!(flags & ImGuiColorEditFlags_NoInputs)) SameLine(0, style.ItemInnerSpacing.x); - const ImVec4 col_display(col[0], col[1], col[2], 1.0f); + const ImVec4 col_display(col[0], col[1], col[2], alpha ? col[3] : 1.0f); // 1.0f if (ColorButton("##ColorButton", col_display, flags)) { if (!(flags & ImGuiColorEditFlags_NoPicker)) { + g.ColorPickerRef = ImVec4(col[0], col[1], col[2], alpha ? col[3] : 1.0f); OpenPopup("picker"); SetNextWindowPos(window->DC.LastItemRect.GetBL() + ImVec2(-1,style.ItemSpacing.y)); } diff --git a/imgui_internal.h b/imgui_internal.h index 58e8bd8e0..191d50eac 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -733,6 +733,7 @@ namespace ImGui IMGUI_API void RenderTextClipped(const ImVec2& pos_min, const ImVec2& pos_max, const char* text, const char* text_end, const ImVec2* text_size_if_known, const ImVec2& align = ImVec2(0,0), const ImRect* clip_rect = NULL); IMGUI_API void RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool border = true, float rounding = 0.0f); IMGUI_API void RenderFrameBorder(ImVec2 p_min, ImVec2 p_max, float rounding = 0.0f); + IMGUI_API void RenderColorRectWithAlphaGrid(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, float grid_step, float rounding = 0.0f); IMGUI_API void RenderCollapseTriangle(ImVec2 pos, bool is_open, float scale = 1.0f); IMGUI_API void RenderBullet(ImVec2 pos); IMGUI_API void RenderCheckMark(ImVec2 pos, ImU32 col); From ce203f99f56a60333a9a80dfc5c41f06d25aa65e Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 26 Jul 2017 15:52:17 +0800 Subject: [PATCH 126/921] ColorButton: Push a text baseline offset if higher than g.FontSize. (#346) --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 728008b51..4538043ad 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9069,7 +9069,7 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl if (size.y == 0.0f) size.y = default_size; const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size); - ItemSize(bb); + ItemSize(bb, ImMin((size.y - g.FontSize) * 0.5f, style.FramePadding.y)); if (!ItemAdd(bb, &id)) return false; From c84acf3f568de57dc1599ff03f00a0da29ef7d77 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 26 Jul 2017 15:59:57 +0800 Subject: [PATCH 127/921] Comments --- imgui.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/imgui.h b/imgui.h index c6cf65153..7bd0d4fee 100644 --- a/imgui.h +++ b/imgui.h @@ -265,7 +265,7 @@ namespace ImGui IMGUI_API void BulletText(const char* fmt, ...) IM_PRINTFARGS(1); // shortcut for Bullet()+Text() IMGUI_API void BulletTextV(const char* fmt, va_list args); IMGUI_API bool Button(const char* label, const ImVec2& size = ImVec2(0,0)); // button - IMGUI_API bool SmallButton(const char* label); // button with FramePadding=(0,0) + IMGUI_API bool SmallButton(const char* label); // button with FramePadding=(0,0) to easily embed in text IMGUI_API bool InvisibleButton(const char* str_id, const ImVec2& size); IMGUI_API void Image(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0,0), const ImVec2& uv1 = ImVec2(1,1), const ImVec4& tint_col = ImVec4(1,1,1,1), const ImVec4& border_col = ImVec4(0,0,0,0)); IMGUI_API bool ImageButton(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0,0), const ImVec2& uv1 = ImVec2(1,1), int frame_padding = -1, const ImVec4& bg_col = ImVec4(0,0,0,0), const ImVec4& tint_col = ImVec4(1,1,1,1)); // <0 frame_padding uses default frame padding settings. 0 for no padding @@ -276,8 +276,8 @@ namespace ImGui IMGUI_API bool Combo(const char* label, int* current_item, const char* const* items, int items_count, int height_in_items = -1); IMGUI_API bool Combo(const char* label, int* current_item, const char* items_separated_by_zeros, int height_in_items = -1); // separate items with \0, end item-list with \0\0 IMGUI_API bool Combo(const char* label, int* current_item, bool (*items_getter)(void* data, int idx, const char** out_text), void* data, int items_count, int height_in_items = -1); - IMGUI_API bool ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFlags flags = 0, ImVec2 size = ImVec2(0,0)); - IMGUI_API bool ColorEdit3(const char* label, float col[3], ImGuiColorEditFlags flags = 0); // click on colored squared to open a color picker, right-click for options. Hint: 'float col[3]' function argument is same as 'float* col'. You can pass address of first element out of a contiguous set, e.g. &myvector.x + IMGUI_API bool ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFlags flags = 0, ImVec2 size = ImVec2(0,0)); // display a colored square/button, hover for details, return true when pressed. + IMGUI_API bool ColorEdit3(const char* label, float col[3], ImGuiColorEditFlags flags = 0); // 3-4 components color edition. click on colored squared to open a color picker, right-click for options. Hint: 'float col[3]' function argument is same as 'float* col'. You can pass address of first element out of a contiguous structure, e.g. &myvector.x IMGUI_API bool ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flags = 0); IMGUI_API bool ColorPicker3(const char* label, float col[3], ImGuiColorEditFlags flags = 0); IMGUI_API bool ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags flags = 0); From d29a4c5e5c879c703976c5332a2630c605084880 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 26 Jul 2017 16:00:47 +0800 Subject: [PATCH 128/921] Demo: Removed the color button from the context menu example because it is misleading now that our color widget have tooltip/context menus themselves. (#346) --- imgui_demo.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 83ac78b01..dbfc29692 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1317,15 +1317,17 @@ void ImGui::ShowTestWindow(bool* p_open) { if (ImGui::Selectable("Set to zero")) value = 0.0f; if (ImGui::Selectable("Set to PI")) value = 3.1415f; + ImGui::DragFloat("Value", &value, 0.1f, 0.0f, 0.0f); ImGui::EndPopup(); } - static ImVec4 color = ImColor(0.8f, 0.5f, 1.0f, 1.0f); - ImGui::ColorButton("##color", color); - if (ImGui::BeginPopupContextItem("color context menu")) + static char name[32] = "Label1"; + char buf[64]; sprintf(buf, "Button: %s###Button", name); // ### operator override ID ignoring the preceeding label + ImGui::Button(buf); + if (ImGui::BeginPopupContextItem("rename context menu")) { - ImGui::Text("Edit color"); - ImGui::ColorEdit3("##edit", (float*)&color); + ImGui::Text("Edit name:"); + ImGui::InputText("##edit", name, IM_ARRAYSIZE(name)); if (ImGui::Button("Close")) ImGui::CloseCurrentPopup(); ImGui::EndPopup(); From 6796e771fd61d02fa27f5aed657b12620c1ed64a Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 26 Jul 2017 16:28:01 +0800 Subject: [PATCH 129/921] ColorEdit, ColorPicker: added ImGuiColorEditFlags_NoAlphaPreview flag (#346). Reorder flags again. --- imgui.cpp | 6 +++--- imgui.h | 21 +++++++++++---------- imgui_demo.cpp | 16 +++++++++++----- 3 files changed, 25 insertions(+), 18 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 4538043ad..16a247ce7 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9005,7 +9005,7 @@ void ImGui::ColorTooltip(const char* text, const float col[4], ImGuiColorEditFla { ImGuiContext& g = *GImGui; - int cr = IM_F32_TO_INT8_SAT(col[0]), cg = IM_F32_TO_INT8_SAT(col[1]), cb = IM_F32_TO_INT8_SAT(col[2]), ca = (flags & ImGuiColorEditFlags_NoAlpha) ? 255 : IM_F32_TO_INT8_SAT(col[3]); + int cr = IM_F32_TO_INT8_SAT(col[0]), cg = IM_F32_TO_INT8_SAT(col[1]), cb = IM_F32_TO_INT8_SAT(col[2]), ca = (flags & (ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoAlphaPreview)) ? 255 : IM_F32_TO_INT8_SAT(col[3]); BeginTooltipEx(true); ImGuiWindow* window = GetCurrentWindow(); @@ -9076,11 +9076,11 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl bool hovered, held; bool pressed = ButtonBehavior(bb, id, &hovered, &held); float grid_step = ImMin(g.FontSize, ImMin(size.x, size.y) * 0.5f); - RenderColorRectWithAlphaGrid(bb.Min, bb.Max, GetColorU32(col), grid_step, style.FrameRounding); + RenderColorRectWithAlphaGrid(bb.Min, bb.Max, GetColorU32((flags & (ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoAlphaPreview)) ? ImVec4(col.x, col.y, col.z, 1.0f) : col), grid_step, style.FrameRounding); RenderFrameBorder(bb.Min, bb.Max, style.FrameRounding); if (hovered && !(flags & ImGuiColorEditFlags_NoTooltip)) - ColorTooltip(desc_id, &col.x, flags & ImGuiColorEditFlags_NoAlpha); + ColorTooltip(desc_id, &col.x, flags & (ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoAlphaPreview)); return pressed; } diff --git a/imgui.h b/imgui.h index 7bd0d4fee..0e8490173 100644 --- a/imgui.h +++ b/imgui.h @@ -274,7 +274,7 @@ namespace ImGui IMGUI_API bool RadioButton(const char* label, bool active); IMGUI_API bool RadioButton(const char* label, int* v, int v_button); IMGUI_API bool Combo(const char* label, int* current_item, const char* const* items, int items_count, int height_in_items = -1); - IMGUI_API bool Combo(const char* label, int* current_item, const char* items_separated_by_zeros, int height_in_items = -1); // separate items with \0, end item-list with \0\0 + IMGUI_API bool Combo(const char* label, int* current_item, const char* items_separated_by_zeros, int height_in_items = -1); // separate items with \0, end item-list with \0\0 IMGUI_API bool Combo(const char* label, int* current_item, bool (*items_getter)(void* data, int idx, const char** out_text), void* data, int items_count, int height_in_items = -1); IMGUI_API bool ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFlags flags = 0, ImVec2 size = ImVec2(0,0)); // display a colored square/button, hover for details, return true when pressed. IMGUI_API bool ColorEdit3(const char* label, float col[3], ImGuiColorEditFlags flags = 0); // 3-4 components color edition. click on colored squared to open a color picker, right-click for options. Hint: 'float col[3]' function argument is same as 'float* col'. You can pass address of first element out of a contiguous structure, e.g. &myvector.x @@ -661,21 +661,22 @@ enum ImGuiStyleVar_ ImGuiStyleVar_Count_ }; -// Enumeration for ColorEdit3() / ColorEdit4() / ColorPicker3() / ColorPicker4() +// Enumeration for ColorEdit3() / ColorEdit4() / ColorPicker3() / ColorPicker4() / ColorButton() enum ImGuiColorEditFlags_ { ImGuiColorEditFlags_RGB = 1 << 0, // ColorEdit: Default to one among RGB/HSV/HEX. User can still use the options menu to change. ColorPicker: Choose any combination or RGB/HSV/HEX. ImGuiColorEditFlags_HSV = 1 << 1, // " ImGuiColorEditFlags_HEX = 1 << 2, // " - ImGuiColorEditFlags_Float = 1 << 3, // ColorEdit, ColorPicker: display values formatted as 0.0f..1.0f floats instead of 0..255 integers. No round-trip of value via integers. + ImGuiColorEditFlags_Float = 1 << 3, // ColorEdit, ColorPicker, ColorButton: display values formatted as 0.0f..1.0f floats instead of 0..255 integers. No round-trip of value via integers. ImGuiColorEditFlags_AlphaBar = 1 << 4, // ColorPicker: Show vertical alpha bar/gradient. - ImGuiColorEditFlags_NoAlpha = 1 << 5, // ColorEdit, ColorPicker: show/edit Alpha component. - ImGuiColorEditFlags_NoPicker = 1 << 6, // ColorEdit: Disable picker when clicking on colored square - ImGuiColorEditFlags_NoOptions = 1 << 7, // ColorEdit: Disable toggling options menu when right-clicking colored square - ImGuiColorEditFlags_NoColorSquare = 1 << 8, // ColorEdit, ColorPicker: Disable colored square. - ImGuiColorEditFlags_NoInputs = 1 << 9, // ColorEdit, ColorPicker: Disable inputs sliders/text widgets, show only the colored square. - ImGuiColorEditFlags_NoTooltip = 1 << 10, // ColorEdit, ColorButton: Disable tooltip when hovering the colored square. - ImGuiColorEditFlags_NoLabel = 1 << 11, // ColorEdit: Disable display of inline text label (the label is still used in tooltip and picker) + ImGuiColorEditFlags_NoAlpha = 1 << 5, // ColorEdit, ColorPicker, ColorButton: completely ignore Alpha component (read 3 components). + ImGuiColorEditFlags_NoAlphaPreview = 1 << 6, // ColorEdit, ColorPicker, ColorButton: do not display transparent colors over a checkerboard, always display the preview as opaque. + ImGuiColorEditFlags_NoPicker = 1 << 7, // ColorEdit: disable picker when clicking on colored square. + ImGuiColorEditFlags_NoOptions = 1 << 8, // ColorEdit: disable toggling options menu when right-clicking on colored square. + ImGuiColorEditFlags_NoColorSquare = 1 << 9, // ColorEdit, ColorPicker: disable colored square. + ImGuiColorEditFlags_NoInputs = 1 << 10, // ColorEdit, ColorPicker: disable inputs sliders/text widgets, show only the colored square. + ImGuiColorEditFlags_NoTooltip = 1 << 11, // ColorEdit, ColorButton: disable tooltip when hovering the colored square. + ImGuiColorEditFlags_NoLabel = 1 << 12, // ColorEdit, ColorPicker: disable display of inline text label (the label is still used in tooltip and picker). ImGuiColorEditFlags_ModeMask_ = ImGuiColorEditFlags_RGB|ImGuiColorEditFlags_HSV|ImGuiColorEditFlags_HEX, ImGuiColorEditFlags_StoredMask_ = ImGuiColorEditFlags_RGB|ImGuiColorEditFlags_HSV|ImGuiColorEditFlags_HEX|ImGuiColorEditFlags_Float }; diff --git a/imgui_demo.cpp b/imgui_demo.cpp index dbfc29692..13079dc72 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -660,21 +660,27 @@ void ImGui::ShowTestWindow(bool* p_open) if (ImGui::TreeNode("Color/Picker Widgets")) { - static ImVec4 color = ImColor(114, 144, 154); + static ImVec4 color = ImColor(114, 144, 154, 200); + + static bool alpha_preview = true; + ImGui::Checkbox("With Alpha Preview", &alpha_preview); ImGui::Text("Color widget:"); ImGui::SameLine(); ShowHelpMarker("Click on the colored square to open a color picker.\nRight-click on the colored square to show options.\nCTRL+click on individual component to input value.\n"); ImGui::ColorEdit3("MyColor##1", (float*)&color, ImGuiColorEditFlags_HSV); ImGui::Text("Color widget with Alpha:"); - ImGui::ColorEdit4("MyColor##2", (float*)&color); + ImGui::ColorEdit4("MyColor##2", (float*)&color, (alpha_preview ? 0 : ImGuiColorEditFlags_NoAlphaPreview)); ImGui::Text("Color widget with Float Display:"); - ImGui::ColorEdit4("MyColor##2f", (float*)&color, ImGuiColorEditFlags_Float); + ImGui::ColorEdit4("MyColor##2f", (float*)&color, ImGuiColorEditFlags_Float | (alpha_preview ? 0 : ImGuiColorEditFlags_NoAlphaPreview)); + + ImGui::Text("Color button with Picker:"); + ImGui::SameLine(); ShowHelpMarker("With the ImGuiColorEditFlags_NoInputs flag you can hide all the slider/text inputs.\nWith the ImGuiColorEditFlags_NoLabel flag you can pass a non-empty label which will only be used for the tooltip and picker popup."); + ImGui::ColorEdit4("MyColor##3", (float*)&color, ImGuiColorEditFlags_NoInputs|ImGuiColorEditFlags_NoLabel|(alpha_preview ? 0 : ImGuiColorEditFlags_NoAlphaPreview)); ImGui::Text("Color button only:"); - ImGui::SameLine(); ShowHelpMarker("With the ImGuiColorEditFlags_NoInputs flag you can hide all the slider/text inputs.\nWith the ImGuiColorEditFlags_NoLabel flag you can pass a non-empty label which will only be used for the tooltip and picker popup."); - ImGui::ColorEdit4("MyColor##3", (float*)&color, ImGuiColorEditFlags_NoInputs|ImGuiColorEditFlags_NoLabel); + ImGui::ColorButton("MyColor##3b", *(ImVec4*)&color, (alpha_preview ? 0 : ImGuiColorEditFlags_NoAlphaPreview), ImVec2(80,80)); ImGui::Text("Color picker:"); static bool alpha = false; From 19c6a9c0e02423b9721e0a913babd0db6db9d243 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 26 Jul 2017 17:38:33 +0800 Subject: [PATCH 130/921] ColorButton, ColorPicker: painfully made RenderColorRectWithAlphaCheckerboard more friendly to using Rounding and Border in style, still not perfect :( (#346) + comments --- imgui.cpp | 34 +++++++++++++++++++++------------- imgui_internal.h | 2 +- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 16a247ce7..cf8d338e7 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9017,7 +9017,7 @@ void ImGui::ColorTooltip(const char* text, const float col[4], ImGuiColorEditFla } ImVec2 sz(g.FontSize * 3, g.FontSize * 3); - RenderColorRectWithAlphaGrid(window->DC.CursorPos, window->DC.CursorPos + sz, IM_COL32(cr,cg,cb,ca), g.FontSize, g.Style.FrameRounding); + RenderColorRectWithAlphaCheckerboard(window->DC.CursorPos, window->DC.CursorPos + sz, IM_COL32(cr,cg,cb,ca), g.FontSize, g.Style.FrameRounding); Dummy(sz); SameLine(); if (flags & ImGuiColorEditFlags_NoAlpha) @@ -9033,22 +9033,32 @@ static inline float ColorSquareSize() return g.FontSize + g.Style.FramePadding.y * 2.0f; } -void ImGui::RenderColorRectWithAlphaGrid(ImVec2 p_min, ImVec2 p_max, ImU32 col, float grid_step, float rounding) +void ImGui::RenderColorRectWithAlphaCheckerboard(ImVec2 p_min, ImVec2 p_max, ImU32 col, float grid_step, float rounding, int rounding_corners_flags_parent) { ImGuiWindow* window = GetCurrentWindow(); if (((col & IM_COL32_A_MASK) >> IM_COL32_A_SHIFT) < 0xFF) { + // We use rounding+1 here which is counterintuitive but it inhibit mosts of the edge artifacts with overlayed rounded shapes ImU32 col_bg1 = GetColorU32(IM_COL32(204,204,204,255)); ImU32 col_bg2 = GetColorU32(IM_COL32(128,128,128,255)); - window->DrawList->AddRectFilled(p_min, p_max, col_bg1, rounding); - int yi = 0; - for (float y = p_min.y; y < p_max.y; y += grid_step, yi++) - for (float x = p_min.x + ((yi & 1) ? grid_step : 0.0f); x < p_max.x; x += grid_step * 2) + window->DrawList->AddRectFilled(p_min, p_max, col_bg1, rounding+1, rounding_corners_flags_parent); + int x_count = (int)((p_max.x - p_min.x) / grid_step + 0.99f); + int y_count = (int)((p_max.y - p_min.y) / grid_step + 0.99f); + for (int y_i = 0; y_i < y_count; y_i++) { - window->DrawList->AddRectFilled(ImVec2(x,y), ImMin(ImVec2(x + grid_step, y + grid_step), p_max), col_bg2, 0.0f); + for (int x_i = (y_i & 1) ^ 1; x_i < x_count; x_i += 2) + { + int rounding_corners_flags = 0; + if (y_i == 0) rounding_corners_flags |= (x_i == 0) ? ImGuiCorner_TopLeft : (x_i == x_count-1) ? ImGuiCorner_TopRight : 0; + if (y_i == y_count-1) rounding_corners_flags |= (x_i == 0) ? ImGuiCorner_BottomLeft : (x_i == x_count-1) ? ImGuiCorner_BottomRight : 0; + rounding_corners_flags &= rounding_corners_flags_parent; + ImVec2 p1(p_min.x + x_i * grid_step, p_min.y + y_i * grid_step); + ImVec2 p2(ImMin(p1.x + grid_step, p_max.x), ImMin(p1.y + grid_step, p_max.y)); + window->DrawList->AddRectFilled(p1, p2, col_bg2, rounding_corners_flags ? rounding+1 : 0.0f, rounding_corners_flags); + } } } - window->DrawList->AddRectFilled(p_min, p_max, col, rounding); + window->DrawList->AddRectFilled(p_min, p_max, col, rounding, rounding_corners_flags_parent); } // A little colored square. Return true when clicked. @@ -9076,7 +9086,7 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl bool hovered, held; bool pressed = ButtonBehavior(bb, id, &hovered, &held); float grid_step = ImMin(g.FontSize, ImMin(size.x, size.y) * 0.5f); - RenderColorRectWithAlphaGrid(bb.Min, bb.Max, GetColorU32((flags & (ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoAlphaPreview)) ? ImVec4(col.x, col.y, col.z, 1.0f) : col), grid_step, style.FrameRounding); + RenderColorRectWithAlphaCheckerboard(bb.Min, bb.Max, GetColorU32((flags & (ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoAlphaPreview)) ? ImVec4(col.x, col.y, col.z, 1.0f) : col), grid_step, style.FrameRounding); RenderFrameBorder(bb.Min, bb.Max, style.FrameRounding); if (hovered && !(flags & ImGuiColorEditFlags_NoTooltip)) @@ -9294,11 +9304,9 @@ bool ImGui::ColorPicker3(const char* label, float col[3], ImGuiColorEditFlags fl return true; } -// ColorPicker v2.60 WIP -// see https://github.com/ocornut/imgui/issues/346 -// TODO: English strings in context menu (see FIXME-LOCALIZATION) -// Note: we adjust item height based on item widget, which may cause a flickering feedback loop (if automatic height makes a vertical scrollbar appears, affecting automatic width..) +// ColorPicker // Note: only access 3 floats if ImGuiColorEditFlags_NoAlpha flag is set. +// FIXME: we adjust the big color square height based on item width, which may cause a flickering feedback loop (if automatic height makes a vertical scrollbar appears, affecting automatic width..) bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags flags) { ImGuiContext& g = *GImGui; diff --git a/imgui_internal.h b/imgui_internal.h index 191d50eac..86ab1844d 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -733,7 +733,7 @@ namespace ImGui IMGUI_API void RenderTextClipped(const ImVec2& pos_min, const ImVec2& pos_max, const char* text, const char* text_end, const ImVec2* text_size_if_known, const ImVec2& align = ImVec2(0,0), const ImRect* clip_rect = NULL); IMGUI_API void RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool border = true, float rounding = 0.0f); IMGUI_API void RenderFrameBorder(ImVec2 p_min, ImVec2 p_max, float rounding = 0.0f); - IMGUI_API void RenderColorRectWithAlphaGrid(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, float grid_step, float rounding = 0.0f); + IMGUI_API void RenderColorRectWithAlphaCheckerboard(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, float grid_step, float rounding = 0.0f, int rounding_corners_flags = ~0); IMGUI_API void RenderCollapseTriangle(ImVec2 pos, bool is_open, float scale = 1.0f); IMGUI_API void RenderBullet(ImVec2 pos); IMGUI_API void RenderCheckMark(ImVec2 pos, ImU32 col); From 76bae2f015263a8ed86bfdf4f84e9015eb380921 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 26 Jul 2017 17:46:48 +0800 Subject: [PATCH 131/921] ColorEdit, ColorPicker: Fixed broken build due to commiting an undesirable change in 78a8f798c505ba659f14e4737cdef582ea073452 (#346) --- imgui.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index cf8d338e7..413f60f31 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9220,7 +9220,6 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag { if (!(flags & ImGuiColorEditFlags_NoPicker)) { - g.ColorPickerRef = ImVec4(col[0], col[1], col[2], alpha ? col[3] : 1.0f); OpenPopup("picker"); SetNextWindowPos(window->DC.LastItemRect.GetBL() + ImVec2(-1,style.ItemSpacing.y)); } From 69dd1ed5830c6b218d4770c6cb454b000e55fd32 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 26 Jul 2017 22:20:43 +0800 Subject: [PATCH 132/921] RenderColorRectWithAlphaCheckerboard() in one layer to shunt out anti-alasing artefacts when rounded. Added ImLerp(int,int,float). (#346) --- imgui.cpp | 31 ++++++++++++++++++++----------- imgui_internal.h | 1 + 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 413f60f31..9c7ce11a5 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9033,19 +9033,26 @@ static inline float ColorSquareSize() return g.FontSize + g.Style.FramePadding.y * 2.0f; } +static inline ImU32 ImAlphaBlendColor(ImU32 col_a, ImU32 col_b) +{ + float t = ((col_b >> IM_COL32_A_SHIFT) & 0xFF) / 255.f; + int r = ImLerp((int)(col_a >> IM_COL32_R_SHIFT) & 0xFF, (int)(col_b >> IM_COL32_R_SHIFT) & 0xFF, t); + int g = ImLerp((int)(col_a >> IM_COL32_G_SHIFT) & 0xFF, (int)(col_b >> IM_COL32_G_SHIFT) & 0xFF, t); + int b = ImLerp((int)(col_a >> IM_COL32_B_SHIFT) & 0xFF, (int)(col_b >> IM_COL32_B_SHIFT) & 0xFF, t); + return IM_COL32(r, g, b, 0xFF); +} + void ImGui::RenderColorRectWithAlphaCheckerboard(ImVec2 p_min, ImVec2 p_max, ImU32 col, float grid_step, float rounding, int rounding_corners_flags_parent) { ImGuiWindow* window = GetCurrentWindow(); if (((col & IM_COL32_A_MASK) >> IM_COL32_A_SHIFT) < 0xFF) { - // We use rounding+1 here which is counterintuitive but it inhibit mosts of the edge artifacts with overlayed rounded shapes - ImU32 col_bg1 = GetColorU32(IM_COL32(204,204,204,255)); - ImU32 col_bg2 = GetColorU32(IM_COL32(128,128,128,255)); - window->DrawList->AddRectFilled(p_min, p_max, col_bg1, rounding+1, rounding_corners_flags_parent); + ImU32 col_bg1 = GetColorU32(ImAlphaBlendColor(IM_COL32(204,204,204,255), col)); + ImU32 col_bg2 = GetColorU32(ImAlphaBlendColor(IM_COL32(128,128,128,255), col)); + window->DrawList->AddRectFilled(p_min, p_max, col_bg1, rounding, rounding_corners_flags_parent); int x_count = (int)((p_max.x - p_min.x) / grid_step + 0.99f); int y_count = (int)((p_max.y - p_min.y) / grid_step + 0.99f); for (int y_i = 0; y_i < y_count; y_i++) - { for (int x_i = (y_i & 1) ^ 1; x_i < x_count; x_i += 2) { int rounding_corners_flags = 0; @@ -9054,11 +9061,13 @@ void ImGui::RenderColorRectWithAlphaCheckerboard(ImVec2 p_min, ImVec2 p_max, ImU rounding_corners_flags &= rounding_corners_flags_parent; ImVec2 p1(p_min.x + x_i * grid_step, p_min.y + y_i * grid_step); ImVec2 p2(ImMin(p1.x + grid_step, p_max.x), ImMin(p1.y + grid_step, p_max.y)); - window->DrawList->AddRectFilled(p1, p2, col_bg2, rounding_corners_flags ? rounding+1 : 0.0f, rounding_corners_flags); - } + window->DrawList->AddRectFilled(p1, p2, col_bg2, rounding_corners_flags ? rounding : 0.0f, rounding_corners_flags); } } - window->DrawList->AddRectFilled(p_min, p_max, col, rounding, rounding_corners_flags_parent); + else + { + window->DrawList->AddRectFilled(p_min, p_max, col, rounding, rounding_corners_flags_parent); + } } // A little colored square. Return true when clicked. @@ -9238,7 +9247,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag Separator(); } float square_sz = ColorSquareSize(); - ImGuiColorEditFlags picker_flags = (flags & (ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_Float)) | (ImGuiColorEditFlags_RGB | ImGuiColorEditFlags_HSV | ImGuiColorEditFlags_HEX) | ImGuiColorEditFlags_NoLabel; + ImGuiColorEditFlags picker_flags = (flags & (ImGuiColorEditFlags_NoAlpha|ImGuiColorEditFlags_Float)) | (ImGuiColorEditFlags_RGB | ImGuiColorEditFlags_HSV | ImGuiColorEditFlags_HEX) | ImGuiColorEditFlags_NoLabel; PushItemWidth(square_sz * 12.0f); value_changed |= ColorPicker4("##picker", col, picker_flags); PopItemWidth(); @@ -9274,8 +9283,8 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag if (!picker_active) { if (!value_changed_as_float) - for (int n = 0; n < 4; n++) - f[n] = i[n] / 255.0f; + for (int n = 0; n < 4; n++) + f[n] = i[n] / 255.0f; if (flags & ImGuiColorEditFlags_HSV) ColorConvertHSVtoRGB(f[0], f[1], f[2], f[0], f[1], f[2]); if (value_changed) diff --git a/imgui_internal.h b/imgui_internal.h index 86ab1844d..3c4c005ba 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -131,6 +131,7 @@ static inline int ImClamp(int v, int mn, int mx) static inline float ImClamp(float v, float mn, float mx) { return (v < mn) ? mn : (v > mx) ? mx : v; } static inline ImVec2 ImClamp(const ImVec2& f, const ImVec2& mn, ImVec2 mx) { return ImVec2(ImClamp(f.x,mn.x,mx.x), ImClamp(f.y,mn.y,mx.y)); } static inline float ImSaturate(float f) { return (f < 0.0f) ? 0.0f : (f > 1.0f) ? 1.0f : f; } +static inline int ImLerp(int a, int b, float t) { return (int)(a + (b - a) * t); } static inline float ImLerp(float a, float b, float t) { return a + (b - a) * t; } static inline ImVec2 ImLerp(const ImVec2& a, const ImVec2& b, const ImVec2& t) { return ImVec2(a.x + (b.x - a.x) * t.x, a.y + (b.y - a.y) * t.y); } static inline float ImLengthSqr(const ImVec2& lhs) { return lhs.x*lhs.x + lhs.y*lhs.y; } From 27e5b09af160d32af3182d4c53773d721f16cfc6 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 26 Jul 2017 23:07:35 +0800 Subject: [PATCH 133/921] ColorButton: ImGuiColorEditFlags_HalfAlphaPreview flag to render both opaque and alpha-with-checkerboard versions of the peak preview (#346) --- imgui.cpp | 15 +++++++++++++-- imgui.h | 1 + 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 9c7ce11a5..1a38869b9 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9094,8 +9094,19 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl bool hovered, held; bool pressed = ButtonBehavior(bb, id, &hovered, &held); - float grid_step = ImMin(g.FontSize, ImMin(size.x, size.y) * 0.5f); - RenderColorRectWithAlphaCheckerboard(bb.Min, bb.Max, GetColorU32((flags & (ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoAlphaPreview)) ? ImVec4(col.x, col.y, col.z, 1.0f) : col), grid_step, style.FrameRounding); + + float mid_x = (float)(int)((bb.Min.x + bb.Max.x) * 0.5f); + float grid_step = ImMax((bb.Max.x - mid_x) * 0.50f, ImMin(size.x, size.y) * 0.50f); + ImVec4 col_without_alpha(col.x, col.y, col.z, 1.0f); + if ((flags & ImGuiColorEditFlags_HalfAlphaPreview) && (flags & (ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoAlphaPreview)) == 0 && col.w < 1.0f) + { + window->DrawList->AddRectFilled(bb.Min, ImVec2(mid_x, bb.Max.y), GetColorU32(col_without_alpha), style.FrameRounding, ImGuiCorner_TopLeft|ImGuiCorner_BottomLeft); + RenderColorRectWithAlphaCheckerboard(ImVec2(mid_x, bb.Min.y), bb.Max, GetColorU32(col), grid_step, style.FrameRounding, ImGuiCorner_TopRight|ImGuiCorner_BottomRight); + } + else + { + RenderColorRectWithAlphaCheckerboard(bb.Min, bb.Max, GetColorU32((flags & (ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoAlphaPreview)) ? col_without_alpha : col), grid_step, style.FrameRounding); + } RenderFrameBorder(bb.Min, bb.Max, style.FrameRounding); if (hovered && !(flags & ImGuiColorEditFlags_NoTooltip)) diff --git a/imgui.h b/imgui.h index 0e8490173..60dcd2d27 100644 --- a/imgui.h +++ b/imgui.h @@ -677,6 +677,7 @@ enum ImGuiColorEditFlags_ ImGuiColorEditFlags_NoInputs = 1 << 10, // ColorEdit, ColorPicker: disable inputs sliders/text widgets, show only the colored square. ImGuiColorEditFlags_NoTooltip = 1 << 11, // ColorEdit, ColorButton: disable tooltip when hovering the colored square. ImGuiColorEditFlags_NoLabel = 1 << 12, // ColorEdit, ColorPicker: disable display of inline text label (the label is still used in tooltip and picker). + ImGuiColorEditFlags_HalfAlphaPreview= 1 << 13, ImGuiColorEditFlags_ModeMask_ = ImGuiColorEditFlags_RGB|ImGuiColorEditFlags_HSV|ImGuiColorEditFlags_HEX, ImGuiColorEditFlags_StoredMask_ = ImGuiColorEditFlags_RGB|ImGuiColorEditFlags_HSV|ImGuiColorEditFlags_HEX|ImGuiColorEditFlags_Float }; From 2e37db9002af285ee138e908b0a5312a48e7814f Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 27 Jul 2017 10:49:01 +0800 Subject: [PATCH 134/921] ColorEdit4: Fix not forwarding ImGuiColorEditFlags_AlphaBar flag to ColorPicker4 (#346) --- imgui.cpp | 2 +- imgui_demo.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 1a38869b9..ea75603ca 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9258,7 +9258,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag Separator(); } float square_sz = ColorSquareSize(); - ImGuiColorEditFlags picker_flags = (flags & (ImGuiColorEditFlags_NoAlpha|ImGuiColorEditFlags_Float)) | (ImGuiColorEditFlags_RGB | ImGuiColorEditFlags_HSV | ImGuiColorEditFlags_HEX) | ImGuiColorEditFlags_NoLabel; + ImGuiColorEditFlags picker_flags = (flags & (ImGuiColorEditFlags_NoAlpha|ImGuiColorEditFlags_AlphaBar|ImGuiColorEditFlags_Float)) | (ImGuiColorEditFlags_RGB | ImGuiColorEditFlags_HSV | ImGuiColorEditFlags_HEX) | ImGuiColorEditFlags_NoLabel; PushItemWidth(square_sz * 12.0f); value_changed |= ColorPicker4("##picker", col, picker_flags); PopItemWidth(); diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 13079dc72..0a608b4a7 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1768,7 +1768,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) if (!filter.PassFilter(name)) continue; ImGui::PushID(i); - ImGui::ColorEdit4(name, (float*)&style.Colors[i], color_edit_flags | ImGuiColorEditFlags_NoOptions); + ImGui::ColorEdit4(name, (float*)&style.Colors[i], color_edit_flags | ImGuiColorEditFlags_NoOptions | ImGuiColorEditFlags_AlphaBar); if (memcmp(&style.Colors[i], (ref ? &ref->Colors[i] : &default_style.Colors[i]), sizeof(ImVec4)) != 0) { ImGui::SameLine(); if (ImGui::Button("Revert")) style.Colors[i] = ref ? ref->Colors[i] : default_style.Colors[i]; From c1c2b2400a2228bab821f50a50318686f750bdcc Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 27 Jul 2017 11:04:39 +0800 Subject: [PATCH 135/921] ColorButton: Undo ce203f99f56a60333a9a80dfc5c41f06d25aa65e --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index ea75603ca..aa4bf4085 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9088,7 +9088,7 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl if (size.y == 0.0f) size.y = default_size; const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size); - ItemSize(bb, ImMin((size.y - g.FontSize) * 0.5f, style.FramePadding.y)); + ItemSize(bb);//, ImMin((size.y - g.FontSize) * 0.5f, style.FramePadding.y)); if (!ItemAdd(bb, &id)) return false; From b7a563276d1844c509a9d81bd4c354bbd20e1a49 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 27 Jul 2017 11:07:46 +0800 Subject: [PATCH 136/921] ColorTooltip: Honor ImGuiColorEditFlags_HalfAlphaPreview flag by calling ColorButton(). Added HalfAlphaPreview to demo. (#346) --- imgui.cpp | 6 ++---- imgui_demo.cpp | 11 +++++++---- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index aa4bf4085..cefc3d997 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9007,7 +9007,6 @@ void ImGui::ColorTooltip(const char* text, const float col[4], ImGuiColorEditFla int cr = IM_F32_TO_INT8_SAT(col[0]), cg = IM_F32_TO_INT8_SAT(col[1]), cb = IM_F32_TO_INT8_SAT(col[2]), ca = (flags & (ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoAlphaPreview)) ? 255 : IM_F32_TO_INT8_SAT(col[3]); BeginTooltipEx(true); - ImGuiWindow* window = GetCurrentWindow(); const char* text_end = text ? FindRenderedTextEnd(text, NULL) : text; if (text_end > text) @@ -9017,8 +9016,7 @@ void ImGui::ColorTooltip(const char* text, const float col[4], ImGuiColorEditFla } ImVec2 sz(g.FontSize * 3, g.FontSize * 3); - RenderColorRectWithAlphaCheckerboard(window->DC.CursorPos, window->DC.CursorPos + sz, IM_COL32(cr,cg,cb,ca), g.FontSize, g.Style.FrameRounding); - Dummy(sz); + ColorButton("##preview", ImVec4(col[0], col[1], col[2], col[3]), (flags & (ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_HalfAlphaPreview)) | ImGuiColorEditFlags_NoTooltip, sz); SameLine(); if (flags & ImGuiColorEditFlags_NoAlpha) Text("#%02X%02X%02X\nR: %d, G: %d, B: %d\n(%.3f, %.3f, %.3f)", cr, cg, cb, cr, cg, cb, col[0], col[1], col[2]); @@ -9110,7 +9108,7 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl RenderFrameBorder(bb.Min, bb.Max, style.FrameRounding); if (hovered && !(flags & ImGuiColorEditFlags_NoTooltip)) - ColorTooltip(desc_id, &col.x, flags & (ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoAlphaPreview)); + ColorTooltip(desc_id, &col.x, flags & (ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoAlphaPreview | ImGuiColorEditFlags_HalfAlphaPreview)); return pressed; } diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 0a608b4a7..96f8bf261 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -663,24 +663,27 @@ void ImGui::ShowTestWindow(bool* p_open) static ImVec4 color = ImColor(114, 144, 154, 200); static bool alpha_preview = true; + static bool alpha_half_preview = false; ImGui::Checkbox("With Alpha Preview", &alpha_preview); + ImGui::Checkbox("With Half Alpha Preview", &alpha_half_preview); + int alpha_flags = alpha_half_preview ? ImGuiColorEditFlags_HalfAlphaPreview : (alpha_preview ? 0 : ImGuiColorEditFlags_NoAlphaPreview); ImGui::Text("Color widget:"); ImGui::SameLine(); ShowHelpMarker("Click on the colored square to open a color picker.\nRight-click on the colored square to show options.\nCTRL+click on individual component to input value.\n"); ImGui::ColorEdit3("MyColor##1", (float*)&color, ImGuiColorEditFlags_HSV); ImGui::Text("Color widget with Alpha:"); - ImGui::ColorEdit4("MyColor##2", (float*)&color, (alpha_preview ? 0 : ImGuiColorEditFlags_NoAlphaPreview)); + ImGui::ColorEdit4("MyColor##2", (float*)&color, alpha_flags); ImGui::Text("Color widget with Float Display:"); - ImGui::ColorEdit4("MyColor##2f", (float*)&color, ImGuiColorEditFlags_Float | (alpha_preview ? 0 : ImGuiColorEditFlags_NoAlphaPreview)); + ImGui::ColorEdit4("MyColor##2f", (float*)&color, ImGuiColorEditFlags_Float | alpha_flags); ImGui::Text("Color button with Picker:"); ImGui::SameLine(); ShowHelpMarker("With the ImGuiColorEditFlags_NoInputs flag you can hide all the slider/text inputs.\nWith the ImGuiColorEditFlags_NoLabel flag you can pass a non-empty label which will only be used for the tooltip and picker popup."); - ImGui::ColorEdit4("MyColor##3", (float*)&color, ImGuiColorEditFlags_NoInputs|ImGuiColorEditFlags_NoLabel|(alpha_preview ? 0 : ImGuiColorEditFlags_NoAlphaPreview)); + ImGui::ColorEdit4("MyColor##3", (float*)&color, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel | alpha_flags); ImGui::Text("Color button only:"); - ImGui::ColorButton("MyColor##3b", *(ImVec4*)&color, (alpha_preview ? 0 : ImGuiColorEditFlags_NoAlphaPreview), ImVec2(80,80)); + ImGui::ColorButton("MyColor##3b", *(ImVec4*)&color, alpha_flags, ImVec2(80,80)); ImGui::Text("Color picker:"); static bool alpha = false; From a9df6bfe86858d92f387bc40e9419ba30d7065c1 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 27 Jul 2017 14:04:58 +0800 Subject: [PATCH 137/921] ColorButton: Fixed rounding corners artefact when there is a single cell. --- imgui.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index cefc3d997..38aa33aa3 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9054,8 +9054,8 @@ void ImGui::RenderColorRectWithAlphaCheckerboard(ImVec2 p_min, ImVec2 p_max, ImU for (int x_i = (y_i & 1) ^ 1; x_i < x_count; x_i += 2) { int rounding_corners_flags = 0; - if (y_i == 0) rounding_corners_flags |= (x_i == 0) ? ImGuiCorner_TopLeft : (x_i == x_count-1) ? ImGuiCorner_TopRight : 0; - if (y_i == y_count-1) rounding_corners_flags |= (x_i == 0) ? ImGuiCorner_BottomLeft : (x_i == x_count-1) ? ImGuiCorner_BottomRight : 0; + if (y_i == 0) { if (x_i == 0) rounding_corners_flags |= ImGuiCorner_TopLeft; if (x_i == x_count-1) rounding_corners_flags |= ImGuiCorner_TopRight; } + if (y_i == y_count-1) { if (x_i == 0) rounding_corners_flags |= ImGuiCorner_BottomLeft; if (x_i == x_count-1) rounding_corners_flags |= ImGuiCorner_BottomRight; } rounding_corners_flags &= rounding_corners_flags_parent; ImVec2 p1(p_min.x + x_i * grid_step, p_min.y + y_i * grid_step); ImVec2 p2(ImMin(p1.x + grid_step, p_max.x), ImMin(p1.y + grid_step, p_max.y)); From bfec9c657e99c240b483777dd591d8f241b98490 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 27 Jul 2017 16:26:32 +0800 Subject: [PATCH 138/921] ColorButton: Pretty much gave up with getting the checkerboard + AA + rounding + blending + offset all working together with every combination under the sun. It works as long as you don't sneeze. (#346) --- imgui.cpp | 52 ++++++++++++++++++++++++++++-------------------- imgui_internal.h | 2 +- 2 files changed, 31 insertions(+), 23 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 38aa33aa3..d5b157596 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9040,31 +9040,39 @@ static inline ImU32 ImAlphaBlendColor(ImU32 col_a, ImU32 col_b) return IM_COL32(r, g, b, 0xFF); } -void ImGui::RenderColorRectWithAlphaCheckerboard(ImVec2 p_min, ImVec2 p_max, ImU32 col, float grid_step, float rounding, int rounding_corners_flags_parent) +// NB: This is rather brittle and will show artifact when rounding this enabled if rounded corners overlap multiple cells. Caller currently responsible for avoiding that. +// I spent a non reasonable amount of time trying to getting this right for ColorButton with rounding+anti-aliasing+ImGuiColorEditFlags_HalfAlphaPreview flag + various grid sizes and offsets, and eventually gave up... probably more reasonable to disable rounding alltogether. +void ImGui::RenderColorRectWithAlphaCheckerboard(ImVec2 p_min, ImVec2 p_max, ImU32 col, float grid_step, ImVec2 grid_off, float rounding, int rounding_corners_flags) { ImGuiWindow* window = GetCurrentWindow(); if (((col & IM_COL32_A_MASK) >> IM_COL32_A_SHIFT) < 0xFF) { ImU32 col_bg1 = GetColorU32(ImAlphaBlendColor(IM_COL32(204,204,204,255), col)); ImU32 col_bg2 = GetColorU32(ImAlphaBlendColor(IM_COL32(128,128,128,255), col)); - window->DrawList->AddRectFilled(p_min, p_max, col_bg1, rounding, rounding_corners_flags_parent); - int x_count = (int)((p_max.x - p_min.x) / grid_step + 0.99f); - int y_count = (int)((p_max.y - p_min.y) / grid_step + 0.99f); - for (int y_i = 0; y_i < y_count; y_i++) - for (int x_i = (y_i & 1) ^ 1; x_i < x_count; x_i += 2) + window->DrawList->AddRectFilled(p_min, p_max, col_bg1, rounding, rounding_corners_flags); + + int yi = 0; + for (float y = p_min.y + grid_off.y; y < p_max.y; y += grid_step, yi++) + { + float y1 = ImClamp(y, p_min.y, p_max.y), y2 = ImMin(y + grid_step, p_max.y); + if (y2 <= y1) + continue; + for (float x = p_min.x + grid_off.x + (yi & 1) * grid_step; x < p_max.x; x += grid_step * 2.0f) { - int rounding_corners_flags = 0; - if (y_i == 0) { if (x_i == 0) rounding_corners_flags |= ImGuiCorner_TopLeft; if (x_i == x_count-1) rounding_corners_flags |= ImGuiCorner_TopRight; } - if (y_i == y_count-1) { if (x_i == 0) rounding_corners_flags |= ImGuiCorner_BottomLeft; if (x_i == x_count-1) rounding_corners_flags |= ImGuiCorner_BottomRight; } - rounding_corners_flags &= rounding_corners_flags_parent; - ImVec2 p1(p_min.x + x_i * grid_step, p_min.y + y_i * grid_step); - ImVec2 p2(ImMin(p1.x + grid_step, p_max.x), ImMin(p1.y + grid_step, p_max.y)); - window->DrawList->AddRectFilled(p1, p2, col_bg2, rounding_corners_flags ? rounding : 0.0f, rounding_corners_flags); + float x1 = ImClamp(x, p_min.x, p_max.x), x2 = ImMin(x + grid_step, p_max.x); + if (x2 <= x1) + continue; + int rounding_corners_flags_cell = 0; + if (y1 <= p_min.y) { if (x1 <= p_min.x) rounding_corners_flags_cell |= ImGuiCorner_TopLeft; if (x2 >= p_max.x) rounding_corners_flags_cell |= ImGuiCorner_TopRight; } + if (y2 >= p_max.y) { if (x1 <= p_min.x) rounding_corners_flags_cell |= ImGuiCorner_BottomLeft; if (x2 >= p_max.x) rounding_corners_flags_cell |= ImGuiCorner_BottomRight; } + rounding_corners_flags_cell &= rounding_corners_flags; + window->DrawList->AddRectFilled(ImVec2(x1,y1), ImVec2(x2,y2), col_bg2, rounding_corners_flags_cell ? rounding : 0.0f, rounding_corners_flags_cell); + } } } else { - window->DrawList->AddRectFilled(p_min, p_max, col, rounding, rounding_corners_flags_parent); + window->DrawList->AddRectFilled(p_min, p_max, col, rounding, rounding_corners_flags); } } @@ -9078,7 +9086,6 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl return false; ImGuiContext& g = *GImGui; - const ImGuiStyle& style = g.Style; const ImGuiID id = window->GetID(desc_id); float default_size = ColorSquareSize(); if (size.x == 0.0f) @@ -9086,26 +9093,27 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl if (size.y == 0.0f) size.y = default_size; const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size); - ItemSize(bb);//, ImMin((size.y - g.FontSize) * 0.5f, style.FramePadding.y)); + ItemSize(bb); if (!ItemAdd(bb, &id)) return false; bool hovered, held; bool pressed = ButtonBehavior(bb, id, &hovered, &held); - float mid_x = (float)(int)((bb.Min.x + bb.Max.x) * 0.5f); - float grid_step = ImMax((bb.Max.x - mid_x) * 0.50f, ImMin(size.x, size.y) * 0.50f); ImVec4 col_without_alpha(col.x, col.y, col.z, 1.0f); + float grid_step = ImMin(size.x, size.y) / 2.0f; + float rounding = ImMin(g.Style.FrameRounding, grid_step * 0.5f); if ((flags & ImGuiColorEditFlags_HalfAlphaPreview) && (flags & (ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoAlphaPreview)) == 0 && col.w < 1.0f) { - window->DrawList->AddRectFilled(bb.Min, ImVec2(mid_x, bb.Max.y), GetColorU32(col_without_alpha), style.FrameRounding, ImGuiCorner_TopLeft|ImGuiCorner_BottomLeft); - RenderColorRectWithAlphaCheckerboard(ImVec2(mid_x, bb.Min.y), bb.Max, GetColorU32(col), grid_step, style.FrameRounding, ImGuiCorner_TopRight|ImGuiCorner_BottomRight); + float mid_x = (float)(int)((bb.Min.x + bb.Max.x) * 0.5f + 0.5f); + RenderColorRectWithAlphaCheckerboard(ImVec2(bb.Min.x + grid_step, bb.Min.y), bb.Max, GetColorU32(col), grid_step, ImVec2(-grid_step, 0.0f), rounding, ImGuiCorner_TopRight|ImGuiCorner_BottomRight); + window->DrawList->AddRectFilled(bb.Min, ImVec2(mid_x, bb.Max.y), GetColorU32(col_without_alpha), rounding, ImGuiCorner_TopLeft|ImGuiCorner_BottomLeft); } else { - RenderColorRectWithAlphaCheckerboard(bb.Min, bb.Max, GetColorU32((flags & (ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoAlphaPreview)) ? col_without_alpha : col), grid_step, style.FrameRounding); + RenderColorRectWithAlphaCheckerboard(bb.Min, bb.Max, GetColorU32((flags & (ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoAlphaPreview)) ? col_without_alpha : col), grid_step, ImVec2(0,0), rounding); } - RenderFrameBorder(bb.Min, bb.Max, style.FrameRounding); + RenderFrameBorder(bb.Min, bb.Max, rounding); if (hovered && !(flags & ImGuiColorEditFlags_NoTooltip)) ColorTooltip(desc_id, &col.x, flags & (ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoAlphaPreview | ImGuiColorEditFlags_HalfAlphaPreview)); diff --git a/imgui_internal.h b/imgui_internal.h index 3c4c005ba..b9d4780b9 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -734,7 +734,7 @@ namespace ImGui IMGUI_API void RenderTextClipped(const ImVec2& pos_min, const ImVec2& pos_max, const char* text, const char* text_end, const ImVec2* text_size_if_known, const ImVec2& align = ImVec2(0,0), const ImRect* clip_rect = NULL); IMGUI_API void RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool border = true, float rounding = 0.0f); IMGUI_API void RenderFrameBorder(ImVec2 p_min, ImVec2 p_max, float rounding = 0.0f); - IMGUI_API void RenderColorRectWithAlphaCheckerboard(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, float grid_step, float rounding = 0.0f, int rounding_corners_flags = ~0); + IMGUI_API void RenderColorRectWithAlphaCheckerboard(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, float grid_step, ImVec2 grid_off, float rounding = 0.0f, int rounding_corners_flags = ~0); IMGUI_API void RenderCollapseTriangle(ImVec2 pos, bool is_open, float scale = 1.0f); IMGUI_API void RenderBullet(ImVec2 pos); IMGUI_API void RenderCheckMark(ImVec2 pos, ImU32 col); From b1cbd87a9457b63c706410a4063897421b31966e Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 27 Jul 2017 16:49:57 +0800 Subject: [PATCH 139/921] ColorEdit4: Minor tidying up. (#346) --- imgui.cpp | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index d5b157596..0e7956a70 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9129,6 +9129,7 @@ bool ImGui::ColorEdit3(const char* label, float col[3], ImGuiColorEditFlags flag // Edit colors components (each component in 0.0f..1.0f range) // Click on colored square to open a color picker (unless ImGuiColorEditFlags_NoPicker is set). Use CTRL-Click to input value and TAB to go to next item. // Note: only access 3 floats if ImGuiColorEditFlags_NoAlpha flag is set. +// FIXME-OPT: Need to add coarse clipping for the entire widget. bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flags) { ImGuiWindow* window = GetCurrentWindow(); @@ -9138,9 +9139,9 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag ImGuiContext& g = *GImGui; const ImGuiStyle& style = g.Style; const ImGuiID id = window->GetID(label); - const float w_full = CalcItemWidth(); const float w_extra = (flags & ImGuiColorEditFlags_NoColorSquare) ? 0.0f : (ColorSquareSize() + style.ItemInnerSpacing.x); - const float w_items_all = w_full - w_extra; + const float w_items_all = CalcItemWidth() - w_extra; + const char* label_display_end = FindRenderedTextEnd(label); const bool alpha = (flags & ImGuiColorEditFlags_NoAlpha) == 0; const int components = alpha ? 4 : 3; @@ -9153,12 +9154,10 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag if (flags & ImGuiColorEditFlags_NoInputs) flags = (flags & (~ImGuiColorEditFlags_ModeMask_)) | ImGuiColorEditFlags_RGB | ImGuiColorEditFlags_NoOptions; - // Read back edit mode from persistent storage + // Read back edit mode from persistent storage, check that exactly one of RGB/HSV/HEX is set if (!(flags & ImGuiColorEditFlags_NoOptions)) flags = (flags & (~ImGuiColorEditFlags_StoredMask_)) | (g.ColorEditModeStorage.GetInt(id, (flags & ImGuiColorEditFlags_StoredMask_)) & ImGuiColorEditFlags_StoredMask_); - - // Check that exactly one of RGB/HSV/HEX is set - IM_ASSERT(ImIsPowerOfTwo((int)(flags & ImGuiColorEditFlags_ModeMask_))); // + IM_ASSERT(ImIsPowerOfTwo((int)(flags & ImGuiColorEditFlags_ModeMask_))); float f[4] = { col[0], col[1], col[2], alpha ? col[3] : 1.0f }; if (flags & ImGuiColorEditFlags_HSV) @@ -9233,8 +9232,6 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag PopItemWidth(); } - const char* label_display_end = FindRenderedTextEnd(label); - bool picker_active = false; if (!(flags & ImGuiColorEditFlags_NoColorSquare)) { From c36d59a42abbf8921d20c3e95e41c5f6291a1bcf Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 27 Jul 2017 17:16:46 +0800 Subject: [PATCH 140/921] ColorEdit, ColorPicker: AlphaPreview, AlphaPreviewHalf are explicit. Updated demo and using in style editor. 3x3 checkerboard more readable in half mode. (#346) --- imgui.cpp | 17 ++++++++++------- imgui.h | 21 +++++++++++---------- imgui_demo.cpp | 19 +++++++++++-------- 3 files changed, 32 insertions(+), 25 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 0e7956a70..964a6d312 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9005,7 +9005,7 @@ void ImGui::ColorTooltip(const char* text, const float col[4], ImGuiColorEditFla { ImGuiContext& g = *GImGui; - int cr = IM_F32_TO_INT8_SAT(col[0]), cg = IM_F32_TO_INT8_SAT(col[1]), cb = IM_F32_TO_INT8_SAT(col[2]), ca = (flags & (ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoAlphaPreview)) ? 255 : IM_F32_TO_INT8_SAT(col[3]); + int cr = IM_F32_TO_INT8_SAT(col[0]), cg = IM_F32_TO_INT8_SAT(col[1]), cb = IM_F32_TO_INT8_SAT(col[2]), ca = (flags & ImGuiColorEditFlags_NoAlpha) ? 255 : IM_F32_TO_INT8_SAT(col[3]); BeginTooltipEx(true); const char* text_end = text ? FindRenderedTextEnd(text, NULL) : text; @@ -9016,7 +9016,7 @@ void ImGui::ColorTooltip(const char* text, const float col[4], ImGuiColorEditFla } ImVec2 sz(g.FontSize * 3, g.FontSize * 3); - ColorButton("##preview", ImVec4(col[0], col[1], col[2], col[3]), (flags & (ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_HalfAlphaPreview)) | ImGuiColorEditFlags_NoTooltip, sz); + ColorButton("##preview", ImVec4(col[0], col[1], col[2], col[3]), (flags & (ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf)) | ImGuiColorEditFlags_NoTooltip, sz); SameLine(); if (flags & ImGuiColorEditFlags_NoAlpha) Text("#%02X%02X%02X\nR: %d, G: %d, B: %d\n(%.3f, %.3f, %.3f)", cr, cg, cb, cr, cg, cb, col[0], col[1], col[2]); @@ -9068,7 +9068,7 @@ void ImGui::RenderColorRectWithAlphaCheckerboard(ImVec2 p_min, ImVec2 p_max, ImU rounding_corners_flags_cell &= rounding_corners_flags; window->DrawList->AddRectFilled(ImVec2(x1,y1), ImVec2(x2,y2), col_bg2, rounding_corners_flags_cell ? rounding : 0.0f, rounding_corners_flags_cell); } - } + } } else { @@ -9099,11 +9099,14 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl bool hovered, held; bool pressed = ButtonBehavior(bb, id, &hovered, &held); + + if (flags & ImGuiColorEditFlags_NoAlpha) + flags &= ~(ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf); ImVec4 col_without_alpha(col.x, col.y, col.z, 1.0f); - float grid_step = ImMin(size.x, size.y) / 2.0f; + float grid_step = ImMin(size.x, size.y) / 2.99f; float rounding = ImMin(g.Style.FrameRounding, grid_step * 0.5f); - if ((flags & ImGuiColorEditFlags_HalfAlphaPreview) && (flags & (ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoAlphaPreview)) == 0 && col.w < 1.0f) + if ((flags & ImGuiColorEditFlags_AlphaPreviewHalf) && col.w < 1.0f) { float mid_x = (float)(int)((bb.Min.x + bb.Max.x) * 0.5f + 0.5f); RenderColorRectWithAlphaCheckerboard(ImVec2(bb.Min.x + grid_step, bb.Min.y), bb.Max, GetColorU32(col), grid_step, ImVec2(-grid_step, 0.0f), rounding, ImGuiCorner_TopRight|ImGuiCorner_BottomRight); @@ -9111,12 +9114,12 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl } else { - RenderColorRectWithAlphaCheckerboard(bb.Min, bb.Max, GetColorU32((flags & (ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoAlphaPreview)) ? col_without_alpha : col), grid_step, ImVec2(0,0), rounding); + RenderColorRectWithAlphaCheckerboard(bb.Min, bb.Max, GetColorU32((flags & ImGuiColorEditFlags_AlphaPreview) ? col : col_without_alpha), grid_step, ImVec2(0,0), rounding); } RenderFrameBorder(bb.Min, bb.Max, rounding); if (hovered && !(flags & ImGuiColorEditFlags_NoTooltip)) - ColorTooltip(desc_id, &col.x, flags & (ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoAlphaPreview | ImGuiColorEditFlags_HalfAlphaPreview)); + ColorTooltip(desc_id, &col.x, flags & (ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf)); return pressed; } diff --git a/imgui.h b/imgui.h index 60dcd2d27..55a553ba4 100644 --- a/imgui.h +++ b/imgui.h @@ -668,16 +668,17 @@ enum ImGuiColorEditFlags_ ImGuiColorEditFlags_HSV = 1 << 1, // " ImGuiColorEditFlags_HEX = 1 << 2, // " ImGuiColorEditFlags_Float = 1 << 3, // ColorEdit, ColorPicker, ColorButton: display values formatted as 0.0f..1.0f floats instead of 0..255 integers. No round-trip of value via integers. - ImGuiColorEditFlags_AlphaBar = 1 << 4, // ColorPicker: Show vertical alpha bar/gradient. - ImGuiColorEditFlags_NoAlpha = 1 << 5, // ColorEdit, ColorPicker, ColorButton: completely ignore Alpha component (read 3 components). - ImGuiColorEditFlags_NoAlphaPreview = 1 << 6, // ColorEdit, ColorPicker, ColorButton: do not display transparent colors over a checkerboard, always display the preview as opaque. - ImGuiColorEditFlags_NoPicker = 1 << 7, // ColorEdit: disable picker when clicking on colored square. - ImGuiColorEditFlags_NoOptions = 1 << 8, // ColorEdit: disable toggling options menu when right-clicking on colored square. - ImGuiColorEditFlags_NoColorSquare = 1 << 9, // ColorEdit, ColorPicker: disable colored square. - ImGuiColorEditFlags_NoInputs = 1 << 10, // ColorEdit, ColorPicker: disable inputs sliders/text widgets, show only the colored square. - ImGuiColorEditFlags_NoTooltip = 1 << 11, // ColorEdit, ColorButton: disable tooltip when hovering the colored square. - ImGuiColorEditFlags_NoLabel = 1 << 12, // ColorEdit, ColorPicker: disable display of inline text label (the label is still used in tooltip and picker). - ImGuiColorEditFlags_HalfAlphaPreview= 1 << 13, + ImGuiColorEditFlags_AlphaBar = 1 << 4, // ColorEdit, ColorPicker: show vertical alpha bar/gradient in picker. + ImGuiColorEditFlags_AlphaPreview = 1 << 5, // ColorEdit, ColorPicker, ColorButton: display preview as a transparent color over a checkerboard, instead of opaque. + ImGuiColorEditFlags_AlphaPreviewHalf= 1 << 6, // ColorEdit, ColorPicker, ColorButton: display half opaque / half checkerboard + ImGuiColorEditFlags_NoAlpha = 1 << 7, // ColorEdit, ColorPicker, ColorButton: completely ignore Alpha component (read 3 components). + ImGuiColorEditFlags_NoPicker = 1 << 8, // ColorEdit: disable picker when clicking on colored square. + ImGuiColorEditFlags_NoOptions = 1 << 9, // ColorEdit: disable toggling options menu when right-clicking on colored square. + ImGuiColorEditFlags_NoColorSquare = 1 << 10, // ColorEdit, ColorPicker: disable colored square. + ImGuiColorEditFlags_NoInputs = 1 << 12, // ColorEdit, ColorPicker: disable inputs sliders/text widgets, show only the colored square. + ImGuiColorEditFlags_NoTooltip = 1 << 13, // ColorEdit, ColorButton: disable tooltip when hovering the colored square. + ImGuiColorEditFlags_NoLabel = 1 << 14, // ColorEdit, ColorPicker: disable display of inline text label (the label is still used in tooltip and picker). + ImGuiColorEditFlags_NoRefColor = 1 << 15, ImGuiColorEditFlags_ModeMask_ = ImGuiColorEditFlags_RGB|ImGuiColorEditFlags_HSV|ImGuiColorEditFlags_HEX, ImGuiColorEditFlags_StoredMask_ = ImGuiColorEditFlags_RGB|ImGuiColorEditFlags_HSV|ImGuiColorEditFlags_HEX|ImGuiColorEditFlags_Float }; diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 96f8bf261..85b8861f1 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -666,7 +666,7 @@ void ImGui::ShowTestWindow(bool* p_open) static bool alpha_half_preview = false; ImGui::Checkbox("With Alpha Preview", &alpha_preview); ImGui::Checkbox("With Half Alpha Preview", &alpha_half_preview); - int alpha_flags = alpha_half_preview ? ImGuiColorEditFlags_HalfAlphaPreview : (alpha_preview ? 0 : ImGuiColorEditFlags_NoAlphaPreview); + int alpha_flags = alpha_half_preview ? ImGuiColorEditFlags_AlphaPreviewHalf : (alpha_preview ? ImGuiColorEditFlags_AlphaPreview : 0); ImGui::Text("Color widget:"); ImGui::SameLine(); ShowHelpMarker("Click on the colored square to open a color picker.\nRight-click on the colored square to show options.\nCTRL+click on individual component to input value.\n"); @@ -1752,14 +1752,17 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) ImGui::SameLine(); ImGui::PushItemWidth(120); ImGui::Combo("##output_type", &output_dest, "To Clipboard\0To TTY\0"); ImGui::PopItemWidth(); ImGui::SameLine(); ImGui::Checkbox("Only Modified Fields", &output_only_modified); - static ImGuiColorEditFlags color_edit_flags = ImGuiColorEditFlags_RGB; - ImGui::RadioButton("RGB", &color_edit_flags, ImGuiColorEditFlags_RGB); - ImGui::SameLine(); - ImGui::RadioButton("HSV", &color_edit_flags, ImGuiColorEditFlags_HSV); - ImGui::SameLine(); - ImGui::RadioButton("HEX", &color_edit_flags, ImGuiColorEditFlags_HEX); + static ImGuiColorEditFlags color_flags = ImGuiColorEditFlags_RGB; + ImGui::RadioButton("RGB", &color_flags, ImGuiColorEditFlags_RGB); ImGui::SameLine(); + ImGui::RadioButton("HSV", &color_flags, ImGuiColorEditFlags_HSV); ImGui::SameLine(); + ImGui::RadioButton("HEX", &color_flags, ImGuiColorEditFlags_HEX); //ImGui::Text("Tip: Click on colored square to change edit mode."); + static ImGuiColorEditFlags alpha_flags = 0; + ImGui::RadioButton("Opaque", &alpha_flags, 0); ImGui::SameLine(); + ImGui::RadioButton("Alpha", &alpha_flags, ImGuiColorEditFlags_AlphaPreview); ImGui::SameLine(); + ImGui::RadioButton("Half", &alpha_flags, ImGuiColorEditFlags_AlphaPreviewHalf); + static ImGuiTextFilter filter; filter.Draw("Filter colors", 200); @@ -1771,7 +1774,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) if (!filter.PassFilter(name)) continue; ImGui::PushID(i); - ImGui::ColorEdit4(name, (float*)&style.Colors[i], color_edit_flags | ImGuiColorEditFlags_NoOptions | ImGuiColorEditFlags_AlphaBar); + ImGui::ColorEdit4(name, (float*)&style.Colors[i], color_flags | ImGuiColorEditFlags_NoOptions | ImGuiColorEditFlags_AlphaBar | alpha_flags); if (memcmp(&style.Colors[i], (ref ? &ref->Colors[i] : &default_style.Colors[i]), sizeof(ImVec4)) != 0) { ImGui::SameLine(); if (ImGui::Button("Revert")) style.Colors[i] = ref ? ref->Colors[i] : default_style.Colors[i]; From cdcda9ff682665cb160b66de6fa25b5904c9f060 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 29 Jul 2017 14:01:05 +0800 Subject: [PATCH 141/921] ColorEdit4: Store edit options per window. Demo: Letting user change edit mode. (#346) --- imgui.cpp | 14 +++++++------- imgui_demo.cpp | 16 ++++++---------- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 964a6d312..e3164e0ee 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9141,7 +9141,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag ImGuiContext& g = *GImGui; const ImGuiStyle& style = g.Style; - const ImGuiID id = window->GetID(label); + const ImGuiID storage_id = window->ID; // Store options on a per window basis const float w_extra = (flags & ImGuiColorEditFlags_NoColorSquare) ? 0.0f : (ColorSquareSize() + style.ItemInnerSpacing.x); const float w_items_all = CalcItemWidth() - w_extra; const char* label_display_end = FindRenderedTextEnd(label); @@ -9149,17 +9149,17 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag const bool alpha = (flags & ImGuiColorEditFlags_NoAlpha) == 0; const int components = alpha ? 4 : 3; - // If no mode is specified, defaults to RGB - if (!(flags & ImGuiColorEditFlags_ModeMask_)) - flags |= ImGuiColorEditFlags_RGB; - // If we're not showing any slider there's no point in querying color mode, nor showing the options menu, nor doing any HSV conversions if (flags & ImGuiColorEditFlags_NoInputs) flags = (flags & (~ImGuiColorEditFlags_ModeMask_)) | ImGuiColorEditFlags_RGB | ImGuiColorEditFlags_NoOptions; + // If no mode is specified, defaults to RGB + if (!(flags & ImGuiColorEditFlags_ModeMask_)) + flags |= ImGuiColorEditFlags_RGB; + // Read back edit mode from persistent storage, check that exactly one of RGB/HSV/HEX is set if (!(flags & ImGuiColorEditFlags_NoOptions)) - flags = (flags & (~ImGuiColorEditFlags_StoredMask_)) | (g.ColorEditModeStorage.GetInt(id, (flags & ImGuiColorEditFlags_StoredMask_)) & ImGuiColorEditFlags_StoredMask_); + flags = (flags & (~ImGuiColorEditFlags_StoredMask_)) | (g.ColorEditModeStorage.GetInt(storage_id, (flags & ImGuiColorEditFlags_StoredMask_)) & ImGuiColorEditFlags_StoredMask_); IM_ASSERT(ImIsPowerOfTwo((int)(flags & ImGuiColorEditFlags_ModeMask_))); float f[4] = { col[0], col[1], col[2], alpha ? col[3] : 1.0f }; @@ -9281,7 +9281,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag if (RadioButton("0..255", (flags & ImGuiColorEditFlags_Float)?0:1)) new_flags = (flags & ~ImGuiColorEditFlags_Float); if (RadioButton("0.00..1.00", (flags & ImGuiColorEditFlags_Float)?1:0)) new_flags = (flags | ImGuiColorEditFlags_Float); if (new_flags != -1) - g.ColorEditModeStorage.SetInt(id, (int)(new_flags & ImGuiColorEditFlags_StoredMask_)); + g.ColorEditModeStorage.SetInt(storage_id, (int)(new_flags & ImGuiColorEditFlags_StoredMask_)); EndPopup(); } diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 85b8861f1..49532fa45 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1752,19 +1752,15 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) ImGui::SameLine(); ImGui::PushItemWidth(120); ImGui::Combo("##output_type", &output_dest, "To Clipboard\0To TTY\0"); ImGui::PopItemWidth(); ImGui::SameLine(); ImGui::Checkbox("Only Modified Fields", &output_only_modified); - static ImGuiColorEditFlags color_flags = ImGuiColorEditFlags_RGB; - ImGui::RadioButton("RGB", &color_flags, ImGuiColorEditFlags_RGB); ImGui::SameLine(); - ImGui::RadioButton("HSV", &color_flags, ImGuiColorEditFlags_HSV); ImGui::SameLine(); - ImGui::RadioButton("HEX", &color_flags, ImGuiColorEditFlags_HEX); - //ImGui::Text("Tip: Click on colored square to change edit mode."); + ImGui::Text("Tip: Left-click on colored square to open color picker,\nRight-click to open edit options menu."); + + static ImGuiTextFilter filter; + filter.Draw("Filter colors", 200); static ImGuiColorEditFlags alpha_flags = 0; ImGui::RadioButton("Opaque", &alpha_flags, 0); ImGui::SameLine(); ImGui::RadioButton("Alpha", &alpha_flags, ImGuiColorEditFlags_AlphaPreview); ImGui::SameLine(); - ImGui::RadioButton("Half", &alpha_flags, ImGuiColorEditFlags_AlphaPreviewHalf); - - static ImGuiTextFilter filter; - filter.Draw("Filter colors", 200); + ImGui::RadioButton("Both", &alpha_flags, ImGuiColorEditFlags_AlphaPreviewHalf); ImGui::BeginChild("#colors", ImVec2(0, 300), true, ImGuiWindowFlags_AlwaysVerticalScrollbar); ImGui::PushItemWidth(-160); @@ -1774,7 +1770,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) if (!filter.PassFilter(name)) continue; ImGui::PushID(i); - ImGui::ColorEdit4(name, (float*)&style.Colors[i], color_flags | ImGuiColorEditFlags_NoOptions | ImGuiColorEditFlags_AlphaBar | alpha_flags); + ImGui::ColorEdit4(name, (float*)&style.Colors[i], ImGuiColorEditFlags_AlphaBar | alpha_flags); if (memcmp(&style.Colors[i], (ref ? &ref->Colors[i] : &default_style.Colors[i]), sizeof(ImVec4)) != 0) { ImGui::SameLine(); if (ImGui::Button("Revert")) style.Colors[i] = ref ? ref->Colors[i] : default_style.Colors[i]; From 973d4a361b71df421b454fd6937a2d0d7b85a9a4 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 29 Jul 2017 14:32:41 +0800 Subject: [PATCH 142/921] ColorPicker: Forward AlphaPreview flag to its individual inputs/sliders. Split code into extra lines to make logic more readable. (#346) --- imgui.cpp | 9 ++++++--- imgui_demo.cpp | 14 +++++++------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index e3164e0ee..e2a38a51d 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9264,15 +9264,17 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag Separator(); } float square_sz = ColorSquareSize(); - ImGuiColorEditFlags picker_flags = (flags & (ImGuiColorEditFlags_NoAlpha|ImGuiColorEditFlags_AlphaBar|ImGuiColorEditFlags_Float)) | (ImGuiColorEditFlags_RGB | ImGuiColorEditFlags_HSV | ImGuiColorEditFlags_HEX) | ImGuiColorEditFlags_NoLabel; + ImGuiColorEditFlags picker_flags_to_forward = ImGuiColorEditFlags_Float | ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_AlphaBar | ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf; + ImGuiColorEditFlags picker_flags = (flags & picker_flags_to_forward) | (ImGuiColorEditFlags_RGB | ImGuiColorEditFlags_HSV | ImGuiColorEditFlags_HEX) | ImGuiColorEditFlags_NoLabel; PushItemWidth(square_sz * 12.0f); value_changed |= ColorPicker4("##picker", col, picker_flags); PopItemWidth(); EndPopup(); } + + // Context menu: display and store options. Don't apply to 'flags' this frame. if (!(flags & ImGuiColorEditFlags_NoOptions) && BeginPopup("context")) { - // Display and store options. Don't apply to 'flags' this frame. ImGuiColorEditFlags new_flags = -1; if (RadioButton("RGB", (flags & ImGuiColorEditFlags_RGB)?1:0)) new_flags = (flags & ~ImGuiColorEditFlags_ModeMask_) | ImGuiColorEditFlags_RGB; if (RadioButton("HSV", (flags & ImGuiColorEditFlags_HSV)?1:0)) new_flags = (flags & ~ImGuiColorEditFlags_ModeMask_) | ImGuiColorEditFlags_HSV; @@ -9407,7 +9409,8 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl if ((flags & ImGuiColorEditFlags_ModeMask_) == 0) flags |= ImGuiColorEditFlags_RGB | ImGuiColorEditFlags_HSV | ImGuiColorEditFlags_HEX; PushItemWidth((alpha_bar ? bar1_pos_x : bar0_pos_x) + bars_width - picker_pos.x); - ImGuiColorEditFlags sub_flags = (flags & (ImGuiColorEditFlags_Float | ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoColorSquare)) | ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_NoOptions | ImGuiColorEditFlags_NoTooltip; + ImGuiColorEditFlags sub_flags_to_forward = ImGuiColorEditFlags_Float | ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoColorSquare | ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf; + ImGuiColorEditFlags sub_flags = (flags & sub_flags_to_forward) | ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_NoOptions; if (flags & ImGuiColorEditFlags_RGB) value_changed |= ColorEdit4("##rgb", col, sub_flags | ImGuiColorEditFlags_RGB); if (flags & ImGuiColorEditFlags_HSV) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 49532fa45..e8d3d3c9d 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -666,36 +666,36 @@ void ImGui::ShowTestWindow(bool* p_open) static bool alpha_half_preview = false; ImGui::Checkbox("With Alpha Preview", &alpha_preview); ImGui::Checkbox("With Half Alpha Preview", &alpha_half_preview); - int alpha_flags = alpha_half_preview ? ImGuiColorEditFlags_AlphaPreviewHalf : (alpha_preview ? ImGuiColorEditFlags_AlphaPreview : 0); + int alpha_previw_flags = alpha_half_preview ? ImGuiColorEditFlags_AlphaPreviewHalf : (alpha_preview ? ImGuiColorEditFlags_AlphaPreview : 0); ImGui::Text("Color widget:"); ImGui::SameLine(); ShowHelpMarker("Click on the colored square to open a color picker.\nRight-click on the colored square to show options.\nCTRL+click on individual component to input value.\n"); ImGui::ColorEdit3("MyColor##1", (float*)&color, ImGuiColorEditFlags_HSV); ImGui::Text("Color widget with Alpha:"); - ImGui::ColorEdit4("MyColor##2", (float*)&color, alpha_flags); + ImGui::ColorEdit4("MyColor##2", (float*)&color, alpha_previw_flags); ImGui::Text("Color widget with Float Display:"); - ImGui::ColorEdit4("MyColor##2f", (float*)&color, ImGuiColorEditFlags_Float | alpha_flags); + ImGui::ColorEdit4("MyColor##2f", (float*)&color, ImGuiColorEditFlags_Float | alpha_previw_flags); ImGui::Text("Color button with Picker:"); ImGui::SameLine(); ShowHelpMarker("With the ImGuiColorEditFlags_NoInputs flag you can hide all the slider/text inputs.\nWith the ImGuiColorEditFlags_NoLabel flag you can pass a non-empty label which will only be used for the tooltip and picker popup."); - ImGui::ColorEdit4("MyColor##3", (float*)&color, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel | alpha_flags); + ImGui::ColorEdit4("MyColor##3", (float*)&color, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel | alpha_previw_flags); ImGui::Text("Color button only:"); - ImGui::ColorButton("MyColor##3b", *(ImVec4*)&color, alpha_flags, ImVec2(80,80)); + ImGui::ColorButton("MyColor##3b", *(ImVec4*)&color, alpha_previw_flags, ImVec2(80,80)); ImGui::Text("Color picker:"); static bool alpha = false; static bool alpha_bar = false; - static int inputs_mode = 0; + static int inputs_mode = 2; static float width = 200.0f; ImGui::Checkbox("With Alpha", &alpha); ImGui::Checkbox("With Alpha Bar", &alpha_bar); ImGui::Combo("Mode", &inputs_mode, "All Inputs\0No Inputs\0RGB Input\0HSV Input\0HEX Input\0"); ImGui::DragFloat("Width", &width, 1.0f, 1.0f, 999.0f); ImGui::PushItemWidth(width); - ImGuiColorEditFlags flags = 0; + ImGuiColorEditFlags flags = alpha_previw_flags; if (!alpha) flags |= ImGuiColorEditFlags_NoAlpha; // This is by default if you call ColorPicker3() instead of ColorPicker4() if (alpha_bar) flags |= ImGuiColorEditFlags_AlphaBar; if (inputs_mode == 1) flags |= ImGuiColorEditFlags_NoInputs; From 6bc1572d312eef3fa800c720b7211a4fd7426449 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 29 Jul 2017 15:50:24 +0800 Subject: [PATCH 143/921] ColorPicker: Comments. Single input value mode allow access to context-menu options. (#346) --- imgui.cpp | 18 +++++++++--------- imgui_demo.cpp | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index e2a38a51d..b6ef2bdbb 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -551,7 +551,6 @@ - tabs (#261, #351) - separator: separator on the initial position of a window is not visible (cursorpos.y <= clippos.y) !- color: the color helpers/typing is a mess and needs sorting out. - - color: add a better color picker (#346) - node/graph editor (#306) - pie menus patterns (#434) - drag'n drop, dragging helpers (carry dragging info, visualize drag source before clicking, drop target, etc.) (#143, #479) @@ -612,11 +611,11 @@ - drawlist: end-user probably can't call Clear() directly because we expect a texture to be pushed in the stack. - examples: directx9: save/restore device state more thoroughly. - examples: window minimize, maximize (#583) + - optimization: add clipping for multi-component widgets (SliderFloatX, ColorEditX, etc.). one problem is that nav branch can't easily clip parent group when there is a move request. - optimization: add a flag to disable most of rendering, for the case where the user expect to skip it (#335) - optimization: use another hash function than crc32, e.g. FNV1a - optimization/render: merge command-lists with same clip-rect into one even if they aren't sequential? (as long as in-between clip rectangle don't overlap)? - optimization: turn some the various stack vectors into statically-sized arrays - - optimization: better clipping for multi-component widgets */ #if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) @@ -9129,10 +9128,9 @@ bool ImGui::ColorEdit3(const char* label, float col[3], ImGuiColorEditFlags flag return ColorEdit4(label, col, flags | ImGuiColorEditFlags_NoAlpha); } -// Edit colors components (each component in 0.0f..1.0f range) -// Click on colored square to open a color picker (unless ImGuiColorEditFlags_NoPicker is set). Use CTRL-Click to input value and TAB to go to next item. -// Note: only access 3 floats if ImGuiColorEditFlags_NoAlpha flag is set. -// FIXME-OPT: Need to add coarse clipping for the entire widget. +// Edit colors components (each component in 0.0f..1.0f range). +// See enum ImGuiColorEditFlags_ for available options. e.g. Only access 3 floats if ImGuiColorEditFlags_NoAlpha flag is set. +// With typical options: Left-click on colored square to open color picker. Right-click to open option menu. CTRL-Click over input fields to edit them and TAB to go to next item. bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flags) { ImGuiWindow* window = GetCurrentWindow(); @@ -9406,11 +9404,13 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl // R,G,B and H,S,V slider color editor if (!(flags & ImGuiColorEditFlags_NoInputs)) { - if ((flags & ImGuiColorEditFlags_ModeMask_) == 0) - flags |= ImGuiColorEditFlags_RGB | ImGuiColorEditFlags_HSV | ImGuiColorEditFlags_HEX; PushItemWidth((alpha_bar ? bar1_pos_x : bar0_pos_x) + bars_width - picker_pos.x); ImGuiColorEditFlags sub_flags_to_forward = ImGuiColorEditFlags_Float | ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoColorSquare | ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf; - ImGuiColorEditFlags sub_flags = (flags & sub_flags_to_forward) | ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_NoOptions; + ImGuiColorEditFlags sub_flags = (flags & sub_flags_to_forward) | ImGuiColorEditFlags_NoPicker; + if ((flags & ImGuiColorEditFlags_ModeMask_) == 0) + flags |= ImGuiColorEditFlags_RGB | ImGuiColorEditFlags_HSV | ImGuiColorEditFlags_HEX; + if ((flags & ImGuiColorEditFlags_ModeMask_) == ImGuiColorEditFlags_ModeMask_) + sub_flags |= ImGuiColorEditFlags_NoOptions; if (flags & ImGuiColorEditFlags_RGB) value_changed |= ColorEdit4("##rgb", col, sub_flags | ImGuiColorEditFlags_RGB); if (flags & ImGuiColorEditFlags_HSV) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index e8d3d3c9d..30e5748d3 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -686,7 +686,7 @@ void ImGui::ShowTestWindow(bool* p_open) ImGui::ColorButton("MyColor##3b", *(ImVec4*)&color, alpha_previw_flags, ImVec2(80,80)); ImGui::Text("Color picker:"); - static bool alpha = false; + static bool alpha = true; static bool alpha_bar = false; static int inputs_mode = 2; static float width = 200.0f; From 7537dff8067df6d8b2c493e12f5d1058a24511d7 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 29 Jul 2017 15:54:45 +0800 Subject: [PATCH 144/921] ColorEdit4: Picker spawned from ColorEdit4 has a preview for original/previous color with revert button - WIP not really happy with it being in ColorEdit4 code (#346) --- imgui.cpp | 17 +++++++++++++++++ imgui_internal.h | 1 + 2 files changed, 18 insertions(+) diff --git a/imgui.cpp b/imgui.cpp index b6ef2bdbb..ca8666b1f 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9244,6 +9244,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag { if (!(flags & ImGuiColorEditFlags_NoPicker)) { + g.ColorPickerRef = ImVec4(col[0], col[1], col[2], alpha ? col[3] : 1.0f); OpenPopup("picker"); SetNextWindowPos(window->DC.LastItemRect.GetBL() + ImVec2(-1,style.ItemSpacing.y)); } @@ -9264,9 +9265,25 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag float square_sz = ColorSquareSize(); ImGuiColorEditFlags picker_flags_to_forward = ImGuiColorEditFlags_Float | ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_AlphaBar | ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf; ImGuiColorEditFlags picker_flags = (flags & picker_flags_to_forward) | (ImGuiColorEditFlags_RGB | ImGuiColorEditFlags_HSV | ImGuiColorEditFlags_HEX) | ImGuiColorEditFlags_NoLabel; + if ((flags & ImGuiColorEditFlags_NoRefColor) == 0) + picker_flags |= ImGuiColorEditFlags_NoColorSquare; PushItemWidth(square_sz * 12.0f); value_changed |= ColorPicker4("##picker", col, picker_flags); PopItemWidth(); + if ((flags & ImGuiColorEditFlags_NoRefColor) == 0) + { + SameLine(); + BeginGroup(); + Text("Current"); + ColorButton("##current", col_display, ImGuiColorEditFlags_NoTooltip|ImGuiColorEditFlags_AlphaPreviewHalf, ImVec2(square_sz * 3, square_sz * 2)); + Text("Original"); + if (ColorButton("##original", g.ColorPickerRef, ImGuiColorEditFlags_NoTooltip|ImGuiColorEditFlags_AlphaPreviewHalf, ImVec2(square_sz * 3, square_sz * 2))) + { + memcpy(col, &g.ColorPickerRef, (alpha ? 4 : 3) * sizeof(float)); + value_changed = 0; + } + EndGroup(); + } EndPopup(); } diff --git a/imgui_internal.h b/imgui_internal.h index b9d4780b9..e3295dc79 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -433,6 +433,7 @@ struct ImGuiContext ImFont InputTextPasswordFont; ImGuiID ScalarAsInputTextId; // Temporary text input when CTRL+clicking on a slider, etc. ImGuiStorage ColorEditModeStorage; // Store user selection of color edit mode + ImVec4 ColorPickerRef; float DragCurrentValue; // Currently dragged value, always float, not rounded by end-user precision settings ImVec2 DragLastMouseDelta; float DragSpeedDefaultRatio; // If speed == 0.0f, uses (max-min) * DragSpeedDefaultRatio From 6c82572a35017e98a54f0ffd5205dafe3a4a3dc7 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 29 Jul 2017 16:11:20 +0800 Subject: [PATCH 145/921] ColorEdit4: Fixed not returning true when clicking on the Original/Ref color in Picker spawned from ColorEdit4 + shallow tidying up (#346) --- imgui.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index ca8666b1f..d8d8995fb 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9239,12 +9239,13 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag if (!(flags & ImGuiColorEditFlags_NoInputs)) SameLine(0, style.ItemInnerSpacing.x); - const ImVec4 col_display(col[0], col[1], col[2], alpha ? col[3] : 1.0f); // 1.0f - if (ColorButton("##ColorButton", col_display, flags)) + const ImVec4 col_v4(col[0], col[1], col[2], alpha ? col[3] : 1.0f); + if (ColorButton("##ColorButton", col_v4, flags)) { if (!(flags & ImGuiColorEditFlags_NoPicker)) { - g.ColorPickerRef = ImVec4(col[0], col[1], col[2], alpha ? col[3] : 1.0f); + // Store current color and open a picker + g.ColorPickerRef = col_v4; OpenPopup("picker"); SetNextWindowPos(window->DC.LastItemRect.GetBL() + ImVec2(-1,style.ItemSpacing.y)); } @@ -9267,7 +9268,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag ImGuiColorEditFlags picker_flags = (flags & picker_flags_to_forward) | (ImGuiColorEditFlags_RGB | ImGuiColorEditFlags_HSV | ImGuiColorEditFlags_HEX) | ImGuiColorEditFlags_NoLabel; if ((flags & ImGuiColorEditFlags_NoRefColor) == 0) picker_flags |= ImGuiColorEditFlags_NoColorSquare; - PushItemWidth(square_sz * 12.0f); + PushItemWidth(square_sz * 12.0f); // Use 256 + bar sizes? value_changed |= ColorPicker4("##picker", col, picker_flags); PopItemWidth(); if ((flags & ImGuiColorEditFlags_NoRefColor) == 0) @@ -9275,12 +9276,12 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag SameLine(); BeginGroup(); Text("Current"); - ColorButton("##current", col_display, ImGuiColorEditFlags_NoTooltip|ImGuiColorEditFlags_AlphaPreviewHalf, ImVec2(square_sz * 3, square_sz * 2)); + ColorButton("##current", col_v4, ImGuiColorEditFlags_NoTooltip|ImGuiColorEditFlags_AlphaPreviewHalf, ImVec2(square_sz * 3, square_sz * 2)); Text("Original"); if (ColorButton("##original", g.ColorPickerRef, ImGuiColorEditFlags_NoTooltip|ImGuiColorEditFlags_AlphaPreviewHalf, ImVec2(square_sz * 3, square_sz * 2))) { - memcpy(col, &g.ColorPickerRef, (alpha ? 4 : 3) * sizeof(float)); - value_changed = 0; + memcpy(col, &g.ColorPickerRef, components * sizeof(float)); + value_changed = true; } EndGroup(); } From e84224bcd55913a374bca1c6825412c712ea086a Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 29 Jul 2017 17:00:56 +0800 Subject: [PATCH 146/921] ColorEdit4: Can open context menu from inputs/drags as well (#346) --- imgui.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index d8d8995fb..80031eddd 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9205,6 +9205,8 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag value_changed |= value_changed_as_float |= DragFloat(ids[n], &f[n], 1.0f/255.0f, 0.0f, 1.0f, fmt_table_float[fmt_idx][n]); else value_changed |= DragInt(ids[n], &i[n], 1.0f, 0, 255, fmt_table_int[fmt_idx][n]); + if (!(flags & ImGuiColorEditFlags_NoOptions) && IsItemHovered() && IsMouseClicked(1)) + OpenPopup("context"); } PopItemWidth(); PopItemWidth(); @@ -9230,6 +9232,8 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag else sscanf(p, "%02X%02X%02X", (unsigned int*)&i[0], (unsigned int*)&i[1], (unsigned int*)&i[2]); } + if (!(flags & ImGuiColorEditFlags_NoOptions) && IsItemHovered() && IsMouseClicked(1)) + OpenPopup("context"); PopItemWidth(); } @@ -9250,10 +9254,8 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag SetNextWindowPos(window->DC.LastItemRect.GetBL() + ImVec2(-1,style.ItemSpacing.y)); } } - else if (!(flags & ImGuiColorEditFlags_NoOptions) && IsItemHovered() && IsMouseClicked(1)) - { + if (!(flags & ImGuiColorEditFlags_NoOptions) && IsItemHovered() && IsMouseClicked(1)) OpenPopup("context"); - } if (BeginPopup("picker")) { From 3926bd08e17325b5408333ab53e9140a8227e555 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 29 Jul 2017 17:23:32 +0800 Subject: [PATCH 147/921] ColorPicker: Added ImGuiColorEditFlags_NoSidePreview flag + optional reference color. Added more demo code. (#346) --- imgui.cpp | 89 +++++++++++++++++++++++++++----------------------- imgui.h | 4 +-- imgui_demo.cpp | 34 +++++++++++++------ 3 files changed, 75 insertions(+), 52 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 80031eddd..3467c4b3e 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9266,48 +9266,28 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag Separator(); } float square_sz = ColorSquareSize(); - ImGuiColorEditFlags picker_flags_to_forward = ImGuiColorEditFlags_Float | ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_AlphaBar | ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf; - ImGuiColorEditFlags picker_flags = (flags & picker_flags_to_forward) | (ImGuiColorEditFlags_RGB | ImGuiColorEditFlags_HSV | ImGuiColorEditFlags_HEX) | ImGuiColorEditFlags_NoLabel; - if ((flags & ImGuiColorEditFlags_NoRefColor) == 0) - picker_flags |= ImGuiColorEditFlags_NoColorSquare; + ImGuiColorEditFlags picker_flags_to_forward = ImGuiColorEditFlags_Float | ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_AlphaBar;// | ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf; + ImGuiColorEditFlags picker_flags = (flags & picker_flags_to_forward) | (ImGuiColorEditFlags_RGB | ImGuiColorEditFlags_HSV | ImGuiColorEditFlags_HEX) | ImGuiColorEditFlags_NoLabel | ImGuiColorEditFlags_AlphaPreviewHalf; PushItemWidth(square_sz * 12.0f); // Use 256 + bar sizes? - value_changed |= ColorPicker4("##picker", col, picker_flags); + value_changed |= ColorPicker4("##picker", col, picker_flags, &g.ColorPickerRef.x); PopItemWidth(); - if ((flags & ImGuiColorEditFlags_NoRefColor) == 0) - { - SameLine(); - BeginGroup(); - Text("Current"); - ColorButton("##current", col_v4, ImGuiColorEditFlags_NoTooltip|ImGuiColorEditFlags_AlphaPreviewHalf, ImVec2(square_sz * 3, square_sz * 2)); - Text("Original"); - if (ColorButton("##original", g.ColorPickerRef, ImGuiColorEditFlags_NoTooltip|ImGuiColorEditFlags_AlphaPreviewHalf, ImVec2(square_sz * 3, square_sz * 2))) - { - memcpy(col, &g.ColorPickerRef, components * sizeof(float)); - value_changed = true; - } - EndGroup(); - } EndPopup(); } + } - // Context menu: display and store options. Don't apply to 'flags' this frame. - if (!(flags & ImGuiColorEditFlags_NoOptions) && BeginPopup("context")) - { - ImGuiColorEditFlags new_flags = -1; - if (RadioButton("RGB", (flags & ImGuiColorEditFlags_RGB)?1:0)) new_flags = (flags & ~ImGuiColorEditFlags_ModeMask_) | ImGuiColorEditFlags_RGB; - if (RadioButton("HSV", (flags & ImGuiColorEditFlags_HSV)?1:0)) new_flags = (flags & ~ImGuiColorEditFlags_ModeMask_) | ImGuiColorEditFlags_HSV; - if (RadioButton("HEX", (flags & ImGuiColorEditFlags_HEX)?1:0)) new_flags = (flags & ~ImGuiColorEditFlags_ModeMask_) | ImGuiColorEditFlags_HEX; - Separator(); - if (RadioButton("0..255", (flags & ImGuiColorEditFlags_Float)?0:1)) new_flags = (flags & ~ImGuiColorEditFlags_Float); - if (RadioButton("0.00..1.00", (flags & ImGuiColorEditFlags_Float)?1:0)) new_flags = (flags | ImGuiColorEditFlags_Float); - if (new_flags != -1) - g.ColorEditModeStorage.SetInt(storage_id, (int)(new_flags & ImGuiColorEditFlags_StoredMask_)); - EndPopup(); - } - - // Recreate our own tooltip over's ColorButton() one because we want to display correct alpha here - if (!(flags & ImGuiColorEditFlags_NoTooltip) && IsItemHovered()) - ColorTooltip(label, col, flags); + // Context menu: display and store options. Don't apply to 'flags' this frame. + if (!(flags & ImGuiColorEditFlags_NoOptions) && BeginPopup("context")) + { + ImGuiColorEditFlags new_flags = -1; + if (RadioButton("RGB", (flags & ImGuiColorEditFlags_RGB)?1:0)) new_flags = (flags & ~ImGuiColorEditFlags_ModeMask_) | ImGuiColorEditFlags_RGB; + if (RadioButton("HSV", (flags & ImGuiColorEditFlags_HSV)?1:0)) new_flags = (flags & ~ImGuiColorEditFlags_ModeMask_) | ImGuiColorEditFlags_HSV; + if (RadioButton("HEX", (flags & ImGuiColorEditFlags_HEX)?1:0)) new_flags = (flags & ~ImGuiColorEditFlags_ModeMask_) | ImGuiColorEditFlags_HEX; + Separator(); + if (RadioButton("0..255", (flags & ImGuiColorEditFlags_Float)?0:1)) new_flags = (flags & ~ImGuiColorEditFlags_Float); + if (RadioButton("0.00..1.00", (flags & ImGuiColorEditFlags_Float)?1:0)) new_flags = (flags | ImGuiColorEditFlags_Float); + if (new_flags != -1) + g.ColorEditModeStorage.SetInt(storage_id, (int)(new_flags & ImGuiColorEditFlags_StoredMask_)); + EndPopup(); } if (label != label_display_end && !(flags & ImGuiColorEditFlags_NoLabel)) @@ -9352,7 +9332,7 @@ bool ImGui::ColorPicker3(const char* label, float col[3], ImGuiColorEditFlags fl // ColorPicker // Note: only access 3 floats if ImGuiColorEditFlags_NoAlpha flag is set. // FIXME: we adjust the big color square height based on item width, which may cause a flickering feedback loop (if automatic height makes a vertical scrollbar appears, affecting automatic width..) -bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags flags) +bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags flags, const float* ref_col) { ImGuiContext& g = *GImGui; ImGuiWindow* window = GetCurrentWindow(); @@ -9364,6 +9344,9 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl PushID(label); BeginGroup(); + if ((flags & ImGuiColorEditFlags_NoSidePreview) == 0) + flags |= ImGuiColorEditFlags_NoColorSquare; + // Setup bool alpha_bar = (flags & ImGuiColorEditFlags_AlphaBar) && !(flags & ImGuiColorEditFlags_NoAlpha); ImVec2 picker_pos = window->DC.CursorPos; @@ -9407,15 +9390,41 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl } } - if ((flags & ImGuiColorEditFlags_NoLabel) == 0) + if (!(flags & ImGuiColorEditFlags_NoSidePreview)) + { + SameLine(0, style.ItemInnerSpacing.x); + BeginGroup(); + } + + if (!(flags & ImGuiColorEditFlags_NoLabel)) { const char* label_display_end = FindRenderedTextEnd(label); if (label != label_display_end) { - SameLine(0, style.ItemInnerSpacing.x); + if ((flags & ImGuiColorEditFlags_NoSidePreview)) + SameLine(0, style.ItemInnerSpacing.x); TextUnformatted(label, label_display_end); } } + if (!(flags & ImGuiColorEditFlags_NoSidePreview)) + { + ImVec4 col_v4(col[0], col[1], col[2], (flags & ImGuiColorEditFlags_NoAlpha) ? 1.0f : col[3]); + float square_sz = ColorSquareSize(); + if ((flags & ImGuiColorEditFlags_NoLabel)) + Text("Current"); + ColorButton("##current", col_v4, (flags & (ImGuiColorEditFlags_AlphaPreview|ImGuiColorEditFlags_AlphaPreviewHalf)), ImVec2(square_sz * 3, square_sz * 2)); + if (ref_col != NULL) + { + Text("Original"); + ImVec4 ref_col_v4(ref_col[0], ref_col[1], ref_col[2], (flags & ImGuiColorEditFlags_NoAlpha) ? 1.0f : ref_col[3]); + if (ColorButton("##original", ref_col_v4, (flags & (ImGuiColorEditFlags_AlphaPreview|ImGuiColorEditFlags_AlphaPreviewHalf)), ImVec2(square_sz * 3, square_sz * 2))) + { + memcpy(col, ref_col, ((flags & ImGuiColorEditFlags_NoAlpha) ? 3 : 4) * sizeof(float)); + value_changed = true; + } + } + EndGroup(); + } // Convert back color to RGB if (hsv_changed) diff --git a/imgui.h b/imgui.h index 55a553ba4..98be6611b 100644 --- a/imgui.h +++ b/imgui.h @@ -280,7 +280,7 @@ namespace ImGui IMGUI_API bool ColorEdit3(const char* label, float col[3], ImGuiColorEditFlags flags = 0); // 3-4 components color edition. click on colored squared to open a color picker, right-click for options. Hint: 'float col[3]' function argument is same as 'float* col'. You can pass address of first element out of a contiguous structure, e.g. &myvector.x IMGUI_API bool ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flags = 0); IMGUI_API bool ColorPicker3(const char* label, float col[3], ImGuiColorEditFlags flags = 0); - IMGUI_API bool ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags flags = 0); + IMGUI_API bool ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags flags = 0, const float* ref_col = NULL); IMGUI_API void PlotLines(const char* label, const float* values, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0,0), int stride = sizeof(float)); IMGUI_API void PlotLines(const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0,0)); IMGUI_API void PlotHistogram(const char* label, const float* values, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0,0), int stride = sizeof(float)); @@ -678,7 +678,7 @@ enum ImGuiColorEditFlags_ ImGuiColorEditFlags_NoInputs = 1 << 12, // ColorEdit, ColorPicker: disable inputs sliders/text widgets, show only the colored square. ImGuiColorEditFlags_NoTooltip = 1 << 13, // ColorEdit, ColorButton: disable tooltip when hovering the colored square. ImGuiColorEditFlags_NoLabel = 1 << 14, // ColorEdit, ColorPicker: disable display of inline text label (the label is still used in tooltip and picker). - ImGuiColorEditFlags_NoRefColor = 1 << 15, + ImGuiColorEditFlags_NoSidePreview = 1 << 15, // ColorPicker: disable bigger color preview on right side of the picker, use small colored square instead ImGuiColorEditFlags_ModeMask_ = ImGuiColorEditFlags_RGB|ImGuiColorEditFlags_HSV|ImGuiColorEditFlags_HEX, ImGuiColorEditFlags_StoredMask_ = ImGuiColorEditFlags_RGB|ImGuiColorEditFlags_HSV|ImGuiColorEditFlags_HEX|ImGuiColorEditFlags_Float }; diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 30e5748d3..fec43cdd2 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -666,44 +666,58 @@ void ImGui::ShowTestWindow(bool* p_open) static bool alpha_half_preview = false; ImGui::Checkbox("With Alpha Preview", &alpha_preview); ImGui::Checkbox("With Half Alpha Preview", &alpha_half_preview); - int alpha_previw_flags = alpha_half_preview ? ImGuiColorEditFlags_AlphaPreviewHalf : (alpha_preview ? ImGuiColorEditFlags_AlphaPreview : 0); + int alpha_preview_flags = alpha_half_preview ? ImGuiColorEditFlags_AlphaPreviewHalf : (alpha_preview ? ImGuiColorEditFlags_AlphaPreview : 0); ImGui::Text("Color widget:"); ImGui::SameLine(); ShowHelpMarker("Click on the colored square to open a color picker.\nRight-click on the colored square to show options.\nCTRL+click on individual component to input value.\n"); ImGui::ColorEdit3("MyColor##1", (float*)&color, ImGuiColorEditFlags_HSV); ImGui::Text("Color widget with Alpha:"); - ImGui::ColorEdit4("MyColor##2", (float*)&color, alpha_previw_flags); + ImGui::ColorEdit4("MyColor##2", (float*)&color, alpha_preview_flags); ImGui::Text("Color widget with Float Display:"); - ImGui::ColorEdit4("MyColor##2f", (float*)&color, ImGuiColorEditFlags_Float | alpha_previw_flags); + ImGui::ColorEdit4("MyColor##2f", (float*)&color, ImGuiColorEditFlags_Float | alpha_preview_flags); ImGui::Text("Color button with Picker:"); ImGui::SameLine(); ShowHelpMarker("With the ImGuiColorEditFlags_NoInputs flag you can hide all the slider/text inputs.\nWith the ImGuiColorEditFlags_NoLabel flag you can pass a non-empty label which will only be used for the tooltip and picker popup."); - ImGui::ColorEdit4("MyColor##3", (float*)&color, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel | alpha_previw_flags); + ImGui::ColorEdit4("MyColor##3", (float*)&color, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel | alpha_preview_flags); ImGui::Text("Color button only:"); - ImGui::ColorButton("MyColor##3b", *(ImVec4*)&color, alpha_previw_flags, ImVec2(80,80)); + ImGui::ColorButton("MyColor##3b", *(ImVec4*)&color, alpha_preview_flags, ImVec2(80,80)); ImGui::Text("Color picker:"); static bool alpha = true; static bool alpha_bar = false; + static bool side_preview = true; + static bool ref_color = false; + static ImVec4 ref_color_v(1.0f,0.0f,1.0f,0.5f); static int inputs_mode = 2; static float width = 200.0f; ImGui::Checkbox("With Alpha", &alpha); ImGui::Checkbox("With Alpha Bar", &alpha_bar); + ImGui::Checkbox("With Side Preview", &side_preview); + if (side_preview) + { + ImGui::Checkbox("With Ref Color", &ref_color); + if (ref_color) + { + ImGui::SameLine(); + ImGui::ColorEdit4("##RefColor", &ref_color_v.x, ImGuiColorEditFlags_NoInputs | alpha_preview_flags); + } + } ImGui::Combo("Mode", &inputs_mode, "All Inputs\0No Inputs\0RGB Input\0HSV Input\0HEX Input\0"); - ImGui::DragFloat("Width", &width, 1.0f, 1.0f, 999.0f); - ImGui::PushItemWidth(width); - ImGuiColorEditFlags flags = alpha_previw_flags; + //ImGui::DragFloat("Width", &width, 1.0f, 1.0f, 999.0f); + //ImGui::PushItemWidth(width); + ImGuiColorEditFlags flags = alpha_preview_flags; if (!alpha) flags |= ImGuiColorEditFlags_NoAlpha; // This is by default if you call ColorPicker3() instead of ColorPicker4() if (alpha_bar) flags |= ImGuiColorEditFlags_AlphaBar; + if (!side_preview) flags |= ImGuiColorEditFlags_NoSidePreview; if (inputs_mode == 1) flags |= ImGuiColorEditFlags_NoInputs; if (inputs_mode == 2) flags |= ImGuiColorEditFlags_RGB; if (inputs_mode == 3) flags |= ImGuiColorEditFlags_HSV; if (inputs_mode == 4) flags |= ImGuiColorEditFlags_HEX; - ImGui::ColorPicker4("MyColor##4", (float*)&color, flags); - ImGui::PopItemWidth(); + ImGui::ColorPicker4("MyColor##4", (float*)&color, flags, ref_color ? &ref_color_v.x : NULL); + //ImGui::PopItemWidth(); ImGui::TreePop(); } From 35186a11650a84efc52db2aa36128d15feac7b35 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 29 Jul 2017 17:35:24 +0800 Subject: [PATCH 148/921] Demo: Comments (#346) --- imgui_demo.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index fec43cdd2..ba4c7807b 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -706,6 +706,7 @@ void ImGui::ShowTestWindow(bool* p_open) } } ImGui::Combo("Mode", &inputs_mode, "All Inputs\0No Inputs\0RGB Input\0HSV Input\0HEX Input\0"); + ImGui::SameLine(); ShowHelpMarker("User can right-click the inputs and override edit mode."); //ImGui::DragFloat("Width", &width, 1.0f, 1.0f, 999.0f); //ImGui::PushItemWidth(width); ImGuiColorEditFlags flags = alpha_preview_flags; From fef8aac523c460d0646c5918aa427a539b40a82b Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 30 Jul 2017 16:15:52 +0800 Subject: [PATCH 149/921] ColorPicker4: hue/alpha bars draw arrows that would look right on all background. RenderArrow helper. (#346) --- imgui.cpp | 28 ++++++++++++++++++++++++---- imgui_demo.cpp | 2 +- imgui_internal.h | 9 +++++++++ 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 3467c4b3e..7fdb41d2e 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9329,6 +9329,26 @@ bool ImGui::ColorPicker3(const char* label, float col[3], ImGuiColorEditFlags fl return true; } +// 'pos' is position of the arrow tip. half_sz.x is length from base to tip. half_sz.y is length on each side. +static void RenderArrow(ImDrawList* draw_list, ImVec2 pos, ImVec2 half_sz, ImGuiDir direction, ImU32 col) +{ + switch (direction) + { + case ImGuiDir_Right: draw_list->AddTriangleFilled(ImVec2(pos.x - half_sz.x, pos.y + half_sz.y), ImVec2(pos.x - half_sz.x, pos.y - half_sz.y), pos, col); return; + case ImGuiDir_Left: draw_list->AddTriangleFilled(ImVec2(pos.x + half_sz.x, pos.y - half_sz.y), ImVec2(pos.x + half_sz.x, pos.y + half_sz.y), pos, col); return; + case ImGuiDir_Down: draw_list->AddTriangleFilled(ImVec2(pos.x - half_sz.x, pos.y - half_sz.y), ImVec2(pos.x + half_sz.x, pos.y - half_sz.y), pos, col); return; + case ImGuiDir_Up: draw_list->AddTriangleFilled(ImVec2(pos.x + half_sz.x, pos.y + half_sz.y), ImVec2(pos.x - half_sz.x, pos.y + half_sz.y), pos, col); return; + } +} + +static void RenderArrowsForVerticalBar(ImDrawList* draw_list, ImVec2 pos, ImVec2 half_sz, float bar_w) +{ + RenderArrow(draw_list, ImVec2(pos.x + half_sz.x + 1, pos.y), ImVec2(half_sz.x + 2, half_sz.y + 1), ImGuiDir_Right, IM_COL32_BLACK); + RenderArrow(draw_list, ImVec2(pos.x + half_sz.x, pos.y), half_sz, ImGuiDir_Right, IM_COL32_WHITE); + RenderArrow(draw_list, ImVec2(pos.x + bar_w - half_sz.x - 1, pos.y), ImVec2(half_sz.x + 2, half_sz.y + 1), ImGuiDir_Left, IM_COL32_BLACK); + RenderArrow(draw_list, ImVec2(pos.x + bar_w - half_sz.x, pos.y), half_sz, ImGuiDir_Left, IM_COL32_WHITE); +} + // ColorPicker // Note: only access 3 floats if ImGuiColorEditFlags_NoAlpha flag is set. // FIXME: we adjust the big color square height based on item width, which may cause a flickering feedback loop (if automatic height makes a vertical scrollbar appears, affecting automatic width..) @@ -9351,10 +9371,10 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl bool alpha_bar = (flags & ImGuiColorEditFlags_AlphaBar) && !(flags & ImGuiColorEditFlags_NoAlpha); ImVec2 picker_pos = window->DC.CursorPos; float bars_width = ColorSquareSize(); // Arbitrary smallish width of Hue/Alpha picking bars - float bars_line_extrude = ImMin(2.0f, style.ItemInnerSpacing.x * 0.5f); float sv_picker_size = ImMax(bars_width * 1, CalcItemWidth() - (alpha_bar ? 2 : 1) * (bars_width + style.ItemInnerSpacing.x)); // Saturation/Value picking box float bar0_pos_x = picker_pos.x + sv_picker_size + style.ItemInnerSpacing.x; float bar1_pos_x = bar0_pos_x + bars_width + style.ItemInnerSpacing.x; + float bars_triangles_half_sz = (float)(int)(bars_width * 0.20f); float H,S,V; ColorConvertRGBtoHSV(col[0], col[1], col[2], H, S, V); @@ -9476,17 +9496,17 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl } float bar0_line_y = (float)(int)(picker_pos.y + H * sv_picker_size + 0.5f); RenderFrameBorder(ImVec2(bar0_pos_x, picker_pos.y), ImVec2(bar0_pos_x + bars_width, picker_pos.y + sv_picker_size), 0.0f); - draw_list->AddLine(ImVec2(bar0_pos_x - bars_line_extrude, bar0_line_y), ImVec2(bar0_pos_x + bars_width + bars_line_extrude, bar0_line_y), IM_COL32_WHITE); + RenderArrowsForVerticalBar(draw_list, ImVec2(bar0_pos_x - 1, bar0_line_y), ImVec2(bars_triangles_half_sz + 1, bars_triangles_half_sz), bars_width + 2.0f); // Render alpha bar if (alpha_bar) { float alpha = ImSaturate(col[3]); - float bar1_line_y = (float)(int)(picker_pos.y + (1.0f - alpha) * sv_picker_size + 0.5f); ImRect bar1_bb(bar1_pos_x, picker_pos.y, bar1_pos_x + bars_width, picker_pos.y + sv_picker_size); draw_list->AddRectFilledMultiColor(bar1_bb.Min, bar1_bb.Max, IM_COL32_WHITE, IM_COL32_WHITE, IM_COL32_BLACK, IM_COL32_BLACK); + float bar1_line_y = (float)(int)(picker_pos.y + (1.0f - alpha) * sv_picker_size + 0.5f); RenderFrameBorder(bar1_bb.Min, bar1_bb.Max, 0.0f); - draw_list->AddLine(ImVec2(bar1_pos_x - bars_line_extrude, bar1_line_y), ImVec2(bar1_pos_x + bars_width + bars_line_extrude, bar1_line_y), IM_COL32_WHITE); + RenderArrowsForVerticalBar(draw_list, ImVec2(bar1_pos_x - 1, bar1_line_y), ImVec2(bars_triangles_half_sz + 1, bars_triangles_half_sz), bars_width + 2.0f); } // Render color matrix diff --git a/imgui_demo.cpp b/imgui_demo.cpp index ba4c7807b..dcf3664e9 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -687,7 +687,7 @@ void ImGui::ShowTestWindow(bool* p_open) ImGui::Text("Color picker:"); static bool alpha = true; - static bool alpha_bar = false; + static bool alpha_bar = true; static bool side_preview = true; static bool ref_color = false; static ImVec4 ref_color_v(1.0f,0.0f,1.0f,0.5f); diff --git a/imgui_internal.h b/imgui_internal.h index e3295dc79..8525544b5 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -202,6 +202,15 @@ enum ImGuiDataType ImGuiDataType_Float2, }; +enum ImGuiDir +{ + ImGuiDir_None = -1, + ImGuiDir_Left = 0, + ImGuiDir_Right = 1, + ImGuiDir_Up = 2, + ImGuiDir_Down = 3, +}; + enum ImGuiCorner { ImGuiCorner_TopLeft = 1 << 0, // 1 From 390188dfa9f416ea2b411017901fe102983034dd Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 30 Jul 2017 16:16:06 +0800 Subject: [PATCH 150/921] Comments about parts of imgui_internal.h that will self-destruct. --- imgui_internal.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/imgui_internal.h b/imgui_internal.h index 8525544b5..e8d930fae 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -736,9 +736,8 @@ namespace ImGui IMGUI_API void OpenPopupEx(const char* str_id, bool reopen_existing); - // NB: All position are in absolute pixels coordinates (not window coordinates) - // FIXME: All those functions are a mess and needs to be refactored into something decent. AVOID USING OUTSIDE OF IMGUI.CPP! NOT FOR PUBLIC CONSUMPTION. - // We need: a sort of symbol library, preferably baked into font atlas when possible + decent text rendering helpers. + // NB: All position are in absolute pixels coordinates (never using window coordinates internally) + // AVOID USING OUTSIDE OF IMGUI.CPP! NOT FOR PUBLIC CONSUMPTION. THOSE FUNCTIONS ARE A MESS. THEIR SIGNATURE AND BEHAVIOR WILL CHANGE, THEY NEED TO BE REFACTORED INTO SOMETHING DECENT. IMGUI_API void RenderText(ImVec2 pos, const char* text, const char* text_end = NULL, bool hide_text_after_hash = true); IMGUI_API void RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end, float wrap_width); IMGUI_API void RenderTextClipped(const ImVec2& pos_min, const ImVec2& pos_max, const char* text, const char* text_end, const ImVec2* text_size_if_known, const ImVec2& align = ImVec2(0,0), const ImRect* clip_rect = NULL); From 3ffcc72f98195dd3730c355a293081a3e53ed6b7 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 30 Jul 2017 16:57:44 +0800 Subject: [PATCH 151/921] ColorPicker: Better cursor/color preview over the color matrix. (#346) --- imgui.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 7fdb41d2e..17d231ac3 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9380,13 +9380,13 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl ColorConvertRGBtoHSV(col[0], col[1], col[2], H, S, V); // Color matrix logic - bool value_changed = false, hsv_changed = false; + bool value_changed = false, hsv_changed = false, value_changed_from_matrix = false; InvisibleButton("sv", ImVec2(sv_picker_size, sv_picker_size)); if (IsItemActive()) { S = ImSaturate((io.MousePos.x - picker_pos.x) / (sv_picker_size-1)); V = 1.0f - ImSaturate((io.MousePos.y - picker_pos.y) / (sv_picker_size-1)); - value_changed = hsv_changed = true; + value_changed = hsv_changed = value_changed_from_matrix = true; } // Hue bar logic @@ -9426,6 +9426,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl TextUnformatted(label, label_display_end); } } + if (!(flags & ImGuiColorEditFlags_NoSidePreview)) { ImVec4 col_v4(col[0], col[1], col[2], (flags & ImGuiColorEditFlags_NoAlpha) ? 1.0f : col[3]); @@ -9515,13 +9516,14 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl draw_list->AddRectFilledMultiColor(picker_pos, picker_pos + ImVec2(sv_picker_size,sv_picker_size), IM_COL32_BLACK_TRANS, IM_COL32_BLACK_TRANS, IM_COL32_BLACK, IM_COL32_BLACK); RenderFrameBorder(picker_pos, picker_pos + ImVec2(sv_picker_size,sv_picker_size), 0.0f); - // Render cross-hair (clamp S/V within 0..1 range because floating points colors may lead HSV values to be out of range) - const float CROSSHAIR_SIZE = 7.0f; + // Render cursor/preview circle (clamp S/V within 0..1 range because floating points colors may lead HSV values to be out of range) ImVec2 p((float)(int)(picker_pos.x + ImSaturate(S) * sv_picker_size + 0.5f), (float)(int)(picker_pos.y + ImSaturate(1 - V) * sv_picker_size + 0.5f)); - draw_list->AddLine(ImVec2(p.x - CROSSHAIR_SIZE, p.y), ImVec2(p.x - 2, p.y), IM_COL32_WHITE); - draw_list->AddLine(ImVec2(p.x + CROSSHAIR_SIZE, p.y), ImVec2(p.x + 2, p.y), IM_COL32_WHITE); - draw_list->AddLine(ImVec2(p.x, p.y + CROSSHAIR_SIZE), ImVec2(p.x, p.y + 2), IM_COL32_WHITE); - draw_list->AddLine(ImVec2(p.x, p.y - CROSSHAIR_SIZE), ImVec2(p.x, p.y - 2), IM_COL32_WHITE); + p.x = ImClamp(p.x, picker_pos.x + 2, picker_pos.x + sv_picker_size - 2); + p.y = ImClamp(p.y, picker_pos.y + 2, picker_pos.y + sv_picker_size - 2); + float r = value_changed_from_matrix ? 10.0f : 6.0f; + draw_list->AddCircleFilled(p, r, ColorConvertFloat4ToU32(ImVec4(col[0], col[1], col[2], 1.0f)), 12); + draw_list->AddCircle(p, r+1, IM_COL32(128,128,128,255), 12); + draw_list->AddCircle(p, r, IM_COL32_WHITE, 12); EndGroup(); PopID(); From f040547a5f174900439e607895bb9d38fb9d8c5a Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 30 Jul 2017 17:37:28 +0800 Subject: [PATCH 152/921] Demo: custom ColorPicker popup example (#346) --- imgui_demo.cpp | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index dcf3664e9..34bd635ee 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -682,6 +682,45 @@ void ImGui::ShowTestWindow(bool* p_open) ImGui::SameLine(); ShowHelpMarker("With the ImGuiColorEditFlags_NoInputs flag you can hide all the slider/text inputs.\nWith the ImGuiColorEditFlags_NoLabel flag you can pass a non-empty label which will only be used for the tooltip and picker popup."); ImGui::ColorEdit4("MyColor##3", (float*)&color, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel | alpha_preview_flags); + ImGui::Text("Color button with Custom Picker Popup:"); + bool open_popup = ImGui::ColorButton("MyColor##3b", color, alpha_preview_flags); + static ImVec4 backup_color; + ImGui::SameLine(); + open_popup |= ImGui::Button("Palette"); + if (open_popup) + { + ImGui::OpenPopup("mypicker"); + backup_color = color; + } + if (ImGui::BeginPopup("mypicker")) + { + ImGui::Text("MY FANCY COLOR PICKER!"); + ImGui::Separator(); + ImGui::ColorPicker4("##picker", (float*)&color, alpha_preview_flags | ImGuiColorEditFlags_NoSidePreview | ImGuiColorEditFlags_NoColorSquare); + ImGui::SameLine(); + ImGui::BeginGroup(); + ImGui::Text("Current"); + ImGui::ColorButton("##current", color, ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_AlphaBar | ImGuiColorEditFlags_AlphaPreview, ImVec2(60,40)); + ImGui::Text("Previous"); + if (ImGui::ColorButton("##previous", backup_color, ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_AlphaPreview, ImVec2(60,40))) + color = backup_color; + ImGui::Separator(); + ImGui::Text("Palette"); + for (int n = 0; n < 32; n++) + { + ImGui::PushID(n); + if ((n % 8) != 0) + ImGui::SameLine(0.0f, ImGui::GetStyle().ItemSpacing.y); + ImVec4 dummy_palette_col; + ImGui::ColorConvertHSVtoRGB(n / 31.0f, 0.8f, 0.8f, dummy_palette_col.x, dummy_palette_col.y, dummy_palette_col.z); + if (ImGui::ColorButton("##palette", dummy_palette_col, ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_NoTooltip, ImVec2(20,20))) + color = ImVec4(dummy_palette_col.x, dummy_palette_col.y, dummy_palette_col.z, color.w); // Preserve alpha! + ImGui::PopID(); + } + ImGui::EndGroup(); + ImGui::EndPopup(); + } + ImGui::Text("Color button only:"); ImGui::ColorButton("MyColor##3b", *(ImVec4*)&color, alpha_preview_flags, ImVec2(80,80)); From 4d844ffde17efefebbce3ab3a185fb9d642d83b2 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 30 Jul 2017 17:43:19 +0800 Subject: [PATCH 153/921] Demo: custom ColorPicker popup example tweaks (#346) --- imgui_demo.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 34bd635ee..4f45207d9 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -683,8 +683,13 @@ void ImGui::ShowTestWindow(bool* p_open) ImGui::ColorEdit4("MyColor##3", (float*)&color, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel | alpha_preview_flags); ImGui::Text("Color button with Custom Picker Popup:"); - bool open_popup = ImGui::ColorButton("MyColor##3b", color, alpha_preview_flags); + static bool saved_palette_inited = false; + static ImVec4 saved_palette[32]; static ImVec4 backup_color; + if (!saved_palette_inited) + for (int n = 0; n < IM_ARRAYSIZE(saved_palette); n++) + ImGui::ColorConvertHSVtoRGB(n / 31.0f, 0.8f, 0.8f, saved_palette[n].x, saved_palette[n].y, saved_palette[n].z); + bool open_popup = ImGui::ColorButton("MyColor##3b", color, alpha_preview_flags); ImGui::SameLine(); open_popup |= ImGui::Button("Palette"); if (open_popup) @@ -694,6 +699,7 @@ void ImGui::ShowTestWindow(bool* p_open) } if (ImGui::BeginPopup("mypicker")) { + // FIXME: Adding a drag and drop example here would be perfect! ImGui::Text("MY FANCY COLOR PICKER!"); ImGui::Separator(); ImGui::ColorPicker4("##picker", (float*)&color, alpha_preview_flags | ImGuiColorEditFlags_NoSidePreview | ImGuiColorEditFlags_NoColorSquare); @@ -706,15 +712,13 @@ void ImGui::ShowTestWindow(bool* p_open) color = backup_color; ImGui::Separator(); ImGui::Text("Palette"); - for (int n = 0; n < 32; n++) + for (int n = 0; n < IM_ARRAYSIZE(saved_palette); n++) { ImGui::PushID(n); if ((n % 8) != 0) ImGui::SameLine(0.0f, ImGui::GetStyle().ItemSpacing.y); - ImVec4 dummy_palette_col; - ImGui::ColorConvertHSVtoRGB(n / 31.0f, 0.8f, 0.8f, dummy_palette_col.x, dummy_palette_col.y, dummy_palette_col.z); - if (ImGui::ColorButton("##palette", dummy_palette_col, ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_NoTooltip, ImVec2(20,20))) - color = ImVec4(dummy_palette_col.x, dummy_palette_col.y, dummy_palette_col.z, color.w); // Preserve alpha! + if (ImGui::ColorButton("##palette", saved_palette[n], ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_NoTooltip, ImVec2(20,20))) + color = ImVec4(saved_palette[n].x, saved_palette[n].y, saved_palette[n].z, color.w); // Preserve alpha! ImGui::PopID(); } ImGui::EndGroup(); From 3fe7739b5de5abc86902de64f79d038c3a5e6bc3 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 30 Jul 2017 17:53:37 +0800 Subject: [PATCH 154/921] ColorPicker: Honor ImGuiColorEditFlags_NoTooltip if for some reason user wants that. (#346) --- imgui.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 17d231ac3..da9c6d8db 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9433,12 +9433,12 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl float square_sz = ColorSquareSize(); if ((flags & ImGuiColorEditFlags_NoLabel)) Text("Current"); - ColorButton("##current", col_v4, (flags & (ImGuiColorEditFlags_AlphaPreview|ImGuiColorEditFlags_AlphaPreviewHalf)), ImVec2(square_sz * 3, square_sz * 2)); + ColorButton("##current", col_v4, (flags & (ImGuiColorEditFlags_AlphaPreview|ImGuiColorEditFlags_AlphaPreviewHalf|ImGuiColorEditFlags_NoTooltip)), ImVec2(square_sz * 3, square_sz * 2)); if (ref_col != NULL) { Text("Original"); ImVec4 ref_col_v4(ref_col[0], ref_col[1], ref_col[2], (flags & ImGuiColorEditFlags_NoAlpha) ? 1.0f : ref_col[3]); - if (ColorButton("##original", ref_col_v4, (flags & (ImGuiColorEditFlags_AlphaPreview|ImGuiColorEditFlags_AlphaPreviewHalf)), ImVec2(square_sz * 3, square_sz * 2))) + if (ColorButton("##original", ref_col_v4, (flags & (ImGuiColorEditFlags_AlphaPreview|ImGuiColorEditFlags_AlphaPreviewHalf|ImGuiColorEditFlags_NoTooltip)), ImVec2(square_sz * 3, square_sz * 2))) { memcpy(col, ref_col, ((flags & ImGuiColorEditFlags_NoAlpha) ? 3 : 4) * sizeof(float)); value_changed = true; From 90fcd4a829c9280c467c4aa6406221e483c7d344 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 30 Jul 2017 17:55:42 +0800 Subject: [PATCH 155/921] Renamed ImGuiColorEditFlags_NoColorSquare to ImGuiColorEditFlags_NoSmallPreview (#346) --- imgui.cpp | 8 ++++---- imgui.h | 2 +- imgui_demo.cpp | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index da9c6d8db..03859500f 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9140,7 +9140,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag ImGuiContext& g = *GImGui; const ImGuiStyle& style = g.Style; const ImGuiID storage_id = window->ID; // Store options on a per window basis - const float w_extra = (flags & ImGuiColorEditFlags_NoColorSquare) ? 0.0f : (ColorSquareSize() + style.ItemInnerSpacing.x); + const float w_extra = (flags & ImGuiColorEditFlags_NoSmallPreview) ? 0.0f : (ColorSquareSize() + style.ItemInnerSpacing.x); const float w_items_all = CalcItemWidth() - w_extra; const char* label_display_end = FindRenderedTextEnd(label); @@ -9238,7 +9238,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag } bool picker_active = false; - if (!(flags & ImGuiColorEditFlags_NoColorSquare)) + if (!(flags & ImGuiColorEditFlags_NoSmallPreview)) { if (!(flags & ImGuiColorEditFlags_NoInputs)) SameLine(0, style.ItemInnerSpacing.x); @@ -9365,7 +9365,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl BeginGroup(); if ((flags & ImGuiColorEditFlags_NoSidePreview) == 0) - flags |= ImGuiColorEditFlags_NoColorSquare; + flags |= ImGuiColorEditFlags_NoSmallPreview; // Setup bool alpha_bar = (flags & ImGuiColorEditFlags_AlphaBar) && !(flags & ImGuiColorEditFlags_NoAlpha); @@ -9455,7 +9455,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl if (!(flags & ImGuiColorEditFlags_NoInputs)) { PushItemWidth((alpha_bar ? bar1_pos_x : bar0_pos_x) + bars_width - picker_pos.x); - ImGuiColorEditFlags sub_flags_to_forward = ImGuiColorEditFlags_Float | ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoColorSquare | ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf; + ImGuiColorEditFlags sub_flags_to_forward = ImGuiColorEditFlags_Float | ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoSmallPreview | ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf; ImGuiColorEditFlags sub_flags = (flags & sub_flags_to_forward) | ImGuiColorEditFlags_NoPicker; if ((flags & ImGuiColorEditFlags_ModeMask_) == 0) flags |= ImGuiColorEditFlags_RGB | ImGuiColorEditFlags_HSV | ImGuiColorEditFlags_HEX; diff --git a/imgui.h b/imgui.h index 98be6611b..db0866d1e 100644 --- a/imgui.h +++ b/imgui.h @@ -674,7 +674,7 @@ enum ImGuiColorEditFlags_ ImGuiColorEditFlags_NoAlpha = 1 << 7, // ColorEdit, ColorPicker, ColorButton: completely ignore Alpha component (read 3 components). ImGuiColorEditFlags_NoPicker = 1 << 8, // ColorEdit: disable picker when clicking on colored square. ImGuiColorEditFlags_NoOptions = 1 << 9, // ColorEdit: disable toggling options menu when right-clicking on colored square. - ImGuiColorEditFlags_NoColorSquare = 1 << 10, // ColorEdit, ColorPicker: disable colored square. + ImGuiColorEditFlags_NoSmallPreview = 1 << 10, // ColorEdit, ColorPicker: disable colored square. ImGuiColorEditFlags_NoInputs = 1 << 12, // ColorEdit, ColorPicker: disable inputs sliders/text widgets, show only the colored square. ImGuiColorEditFlags_NoTooltip = 1 << 13, // ColorEdit, ColorButton: disable tooltip when hovering the colored square. ImGuiColorEditFlags_NoLabel = 1 << 14, // ColorEdit, ColorPicker: disable display of inline text label (the label is still used in tooltip and picker). diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 4f45207d9..70f13c746 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -702,7 +702,7 @@ void ImGui::ShowTestWindow(bool* p_open) // FIXME: Adding a drag and drop example here would be perfect! ImGui::Text("MY FANCY COLOR PICKER!"); ImGui::Separator(); - ImGui::ColorPicker4("##picker", (float*)&color, alpha_preview_flags | ImGuiColorEditFlags_NoSidePreview | ImGuiColorEditFlags_NoColorSquare); + ImGui::ColorPicker4("##picker", (float*)&color, alpha_preview_flags | ImGuiColorEditFlags_NoSidePreview | ImGuiColorEditFlags_NoSmallPreview); ImGui::SameLine(); ImGui::BeginGroup(); ImGui::Text("Current"); From 65a27732d86f2a36f8930d50609b4fc680153c94 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 30 Jul 2017 17:57:38 +0800 Subject: [PATCH 156/921] ImGuiColorEditFlags: Made 0x01 unused for backward compatibility with old bool. Various comments tweaks. (#346) --- imgui.h | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/imgui.h b/imgui.h index db0866d1e..045d118ee 100644 --- a/imgui.h +++ b/imgui.h @@ -664,21 +664,21 @@ enum ImGuiStyleVar_ // Enumeration for ColorEdit3() / ColorEdit4() / ColorPicker3() / ColorPicker4() / ColorButton() enum ImGuiColorEditFlags_ { - ImGuiColorEditFlags_RGB = 1 << 0, // ColorEdit: Default to one among RGB/HSV/HEX. User can still use the options menu to change. ColorPicker: Choose any combination or RGB/HSV/HEX. - ImGuiColorEditFlags_HSV = 1 << 1, // " - ImGuiColorEditFlags_HEX = 1 << 2, // " - ImGuiColorEditFlags_Float = 1 << 3, // ColorEdit, ColorPicker, ColorButton: display values formatted as 0.0f..1.0f floats instead of 0..255 integers. No round-trip of value via integers. - ImGuiColorEditFlags_AlphaBar = 1 << 4, // ColorEdit, ColorPicker: show vertical alpha bar/gradient in picker. - ImGuiColorEditFlags_AlphaPreview = 1 << 5, // ColorEdit, ColorPicker, ColorButton: display preview as a transparent color over a checkerboard, instead of opaque. - ImGuiColorEditFlags_AlphaPreviewHalf= 1 << 6, // ColorEdit, ColorPicker, ColorButton: display half opaque / half checkerboard - ImGuiColorEditFlags_NoAlpha = 1 << 7, // ColorEdit, ColorPicker, ColorButton: completely ignore Alpha component (read 3 components). - ImGuiColorEditFlags_NoPicker = 1 << 8, // ColorEdit: disable picker when clicking on colored square. - ImGuiColorEditFlags_NoOptions = 1 << 9, // ColorEdit: disable toggling options menu when right-clicking on colored square. - ImGuiColorEditFlags_NoSmallPreview = 1 << 10, // ColorEdit, ColorPicker: disable colored square. - ImGuiColorEditFlags_NoInputs = 1 << 12, // ColorEdit, ColorPicker: disable inputs sliders/text widgets, show only the colored square. - ImGuiColorEditFlags_NoTooltip = 1 << 13, // ColorEdit, ColorButton: disable tooltip when hovering the colored square. - ImGuiColorEditFlags_NoLabel = 1 << 14, // ColorEdit, ColorPicker: disable display of inline text label (the label is still used in tooltip and picker). - ImGuiColorEditFlags_NoSidePreview = 1 << 15, // ColorPicker: disable bigger color preview on right side of the picker, use small colored square instead + ImGuiColorEditFlags_RGB = 1 << 1, // ColorEdit: default to one among RGB/HSV/HEX. User can still use the options menu to change. ColorPicker: Choose any combination or RGB/HSV/HEX. + ImGuiColorEditFlags_HSV = 1 << 2, // " + ImGuiColorEditFlags_HEX = 1 << 3, // " + ImGuiColorEditFlags_Float = 1 << 4, // ColorEdit, ColorPicker, ColorButton: display values formatted as 0.0f..1.0f floats instead of 0..255 integers. No round-trip of value via integers. + ImGuiColorEditFlags_AlphaBar = 1 << 5, // ColorEdit, ColorPicker: show vertical alpha bar/gradient in picker. + ImGuiColorEditFlags_AlphaPreview = 1 << 6, // ColorEdit, ColorPicker, ColorButton: display preview as a transparent color over a checkerboard, instead of opaque. + ImGuiColorEditFlags_AlphaPreviewHalf= 1 << 7, // ColorEdit, ColorPicker, ColorButton: display half opaque / half checkerboard, instead of opaque. + ImGuiColorEditFlags_NoAlpha = 1 << 8, // ColorEdit, ColorPicker, ColorButton: completely ignore Alpha component (read 3 components from the input pointer). + ImGuiColorEditFlags_NoPicker = 1 << 9, // ColorEdit: disable picker when clicking on colored square. + ImGuiColorEditFlags_NoOptions = 1 << 10, // ColorEdit: disable toggling options menu when right-clicking on inputs/small preview. + ImGuiColorEditFlags_NoSmallPreview = 1 << 11, // ColorEdit, ColorPicker: disable colored square preview next to the inputs. (e.g. to show only the inputs) + ImGuiColorEditFlags_NoInputs = 1 << 12, // ColorEdit, ColorPicker: disable inputs sliders/text widgets (e.g. to show only the small preview colored square). + ImGuiColorEditFlags_NoTooltip = 1 << 13, // ColorEdit, ColorPicker, ColorButton: disable tooltip when hovering the preview. + ImGuiColorEditFlags_NoLabel = 1 << 14, // ColorEdit, ColorPicker: disable display of inline text label (the label is still forwarded to the tooltip and picker). + ImGuiColorEditFlags_NoSidePreview = 1 << 15, // ColorPicker: disable bigger color preview on right side of the picker, use small colored square preview instead. ImGuiColorEditFlags_ModeMask_ = ImGuiColorEditFlags_RGB|ImGuiColorEditFlags_HSV|ImGuiColorEditFlags_HEX, ImGuiColorEditFlags_StoredMask_ = ImGuiColorEditFlags_RGB|ImGuiColorEditFlags_HSV|ImGuiColorEditFlags_HEX|ImGuiColorEditFlags_Float }; From e1a00c3d266642f726b574ac20758c52f30be7df Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 30 Jul 2017 18:09:34 +0800 Subject: [PATCH 157/921] ColorButton: Added frame border when style border are off. (#346) @jdumas --- imgui.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 03859500f..c5731b04c 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -152,8 +152,8 @@ Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. Also read releases logs https://github.com/ocornut/imgui/releases for more details. - - 2016/08/xx (1.XX) - removed ColorEditMode() and ImGuiColorEditMode in favor of ImGuiColorEditFlags and parameters to the various Color*() functions - - changed prototype of 'ColorEdit4(const char* label, float col[4], bool show_alpha = true)' to 'ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flags = 0)', where passing flags = 0x01 is a safe no-op (hello dodgy backward compatibility!) + - 2017/07/30 (1.51) - removed ColorEditMode() and ImGuiColorEditMode in favor of ImGuiColorEditFlags and parameters to the various Color*() functions + - changed prototype of 'ColorEdit4(const char* label, float col[4], bool show_alpha = true)' to 'ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flags = 0)', where passing flags = 0x01 is a safe no-op (hello dodgy backward compatibility!). - check and run the demo window, under "Color/Picker Widgets", to understand the various new options. - changed prototype of rarely used 'ColorButton(ImVec4 col, bool small_height = false, bool outline_border = true)' to 'ColorButton(const char* desc_id, ImVec4 col, ImGuiColorEditFlags flags = 0, ImVec2 size = ImVec2(0,0))' - 2017/07/20 (1.51) - removed IsPosHoveringAnyWindow(ImVec2), which was partly broken and misleading. ASSERT + redirect user to io.WantCaptureMouse - 2017/05/26 (1.50) - removed ImFontConfig::MergeGlyphCenterV in favor of a more multipurpose ImFontConfig::GlyphOffset. @@ -9115,7 +9115,10 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl { RenderColorRectWithAlphaCheckerboard(bb.Min, bb.Max, GetColorU32((flags & ImGuiColorEditFlags_AlphaPreview) ? col : col_without_alpha), grid_step, ImVec2(0,0), rounding); } - RenderFrameBorder(bb.Min, bb.Max, rounding); + if (window->Flags & ImGuiWindowFlags_ShowBorders) + RenderFrameBorder(bb.Min, bb.Max, rounding); + else + window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_FrameBg), rounding); // Color button are often in need of some sort of border if (hovered && !(flags & ImGuiColorEditFlags_NoTooltip)) ColorTooltip(desc_id, &col.x, flags & (ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf)); From 91a4f5df25d629c9a881555e88ec8481e712f931 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 30 Jul 2017 18:28:59 +0800 Subject: [PATCH 158/921] Demo: Tweaks --- imgui_demo.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 70f13c746..625f50c8f 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -700,15 +700,15 @@ void ImGui::ShowTestWindow(bool* p_open) if (ImGui::BeginPopup("mypicker")) { // FIXME: Adding a drag and drop example here would be perfect! - ImGui::Text("MY FANCY COLOR PICKER!"); + ImGui::Text("MY CUSTOM COLOR PICKER WITH AN AMAZING PALETTE!"); ImGui::Separator(); ImGui::ColorPicker4("##picker", (float*)&color, alpha_preview_flags | ImGuiColorEditFlags_NoSidePreview | ImGuiColorEditFlags_NoSmallPreview); ImGui::SameLine(); ImGui::BeginGroup(); ImGui::Text("Current"); - ImGui::ColorButton("##current", color, ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_AlphaBar | ImGuiColorEditFlags_AlphaPreview, ImVec2(60,40)); + ImGui::ColorButton("##current", color, ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_AlphaPreviewHalf, ImVec2(60,40)); ImGui::Text("Previous"); - if (ImGui::ColorButton("##previous", backup_color, ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_AlphaPreview, ImVec2(60,40))) + if (ImGui::ColorButton("##previous", backup_color, ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_AlphaPreviewHalf, ImVec2(60,40))) color = backup_color; ImGui::Separator(); ImGui::Text("Palette"); From f6a89779c8832931dd349c0d9aa9562f3575c22e Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 30 Jul 2017 23:06:07 +0800 Subject: [PATCH 159/921] ColorEdit4: Hex input clamps integer components to 0..255 range during printout (#346) --- imgui.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index c5731b04c..235630205 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9219,9 +9219,9 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag // RGB Hexadecimal Input char buf[64]; if (alpha) - ImFormatString(buf, IM_ARRAYSIZE(buf), "#%02X%02X%02X%02X", i[0], i[1], i[2], i[3]); + ImFormatString(buf, IM_ARRAYSIZE(buf), "#%02X%02X%02X%02X", ImClamp(i[0],0,255), ImClamp(i[1],0,255), ImClamp(i[2],0,255), ImClamp(i[3],0,255)); else - ImFormatString(buf, IM_ARRAYSIZE(buf), "#%02X%02X%02X", i[0], i[1], i[2]); + ImFormatString(buf, IM_ARRAYSIZE(buf), "#%02X%02X%02X", ImClamp(i[0],0,255), ImClamp(i[1],0,255), ImClamp(i[2],0,255)); PushItemWidth(w_items_all); if (InputText("##Text", buf, IM_ARRAYSIZE(buf), ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsUppercase)) { From 3075d8bcd427c303a9194b99a6470beedbe1fbc9 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 30 Jul 2017 23:08:43 +0800 Subject: [PATCH 160/921] ColorEdit4: Preliminary support for ImGuiColorEditFlags_HDR flag (currently only lift limits). (#346) --- imgui.cpp | 11 ++++++----- imgui.h | 23 ++++++++++++----------- imgui_demo.cpp | 20 +++++++++++--------- 3 files changed, 29 insertions(+), 25 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 235630205..d7dda115f 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9148,6 +9148,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag const char* label_display_end = FindRenderedTextEnd(label); const bool alpha = (flags & ImGuiColorEditFlags_NoAlpha) == 0; + const bool hdr = (flags & ImGuiColorEditFlags_HDR) != 0; const int components = alpha ? 4 : 3; // If we're not showing any slider there's no point in querying color mode, nor showing the options menu, nor doing any HSV conversions @@ -9205,9 +9206,9 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag if (n + 1 == components) PushItemWidth(w_item_last); if (flags & ImGuiColorEditFlags_Float) - value_changed |= value_changed_as_float |= DragFloat(ids[n], &f[n], 1.0f/255.0f, 0.0f, 1.0f, fmt_table_float[fmt_idx][n]); + value_changed |= value_changed_as_float |= DragFloat(ids[n], &f[n], 1.0f/255.0f, 0.0f, hdr ? 0.0f : 1.0f, fmt_table_float[fmt_idx][n]); else - value_changed |= DragInt(ids[n], &i[n], 1.0f, 0, 255, fmt_table_int[fmt_idx][n]); + value_changed |= DragInt(ids[n], &i[n], 1.0f, 0, hdr ? 0 : 255, fmt_table_int[fmt_idx][n]); if (!(flags & ImGuiColorEditFlags_NoOptions) && IsItemHovered() && IsMouseClicked(1)) OpenPopup("context"); } @@ -9269,7 +9270,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag Separator(); } float square_sz = ColorSquareSize(); - ImGuiColorEditFlags picker_flags_to_forward = ImGuiColorEditFlags_Float | ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_AlphaBar;// | ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf; + ImGuiColorEditFlags picker_flags_to_forward = ImGuiColorEditFlags_Float | ImGuiColorEditFlags_HDR | ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_AlphaBar;// | ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf; ImGuiColorEditFlags picker_flags = (flags & picker_flags_to_forward) | (ImGuiColorEditFlags_RGB | ImGuiColorEditFlags_HSV | ImGuiColorEditFlags_HEX) | ImGuiColorEditFlags_NoLabel | ImGuiColorEditFlags_AlphaPreviewHalf; PushItemWidth(square_sz * 12.0f); // Use 256 + bar sizes? value_changed |= ColorPicker4("##picker", col, picker_flags, &g.ColorPickerRef.x); @@ -9436,12 +9437,12 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl float square_sz = ColorSquareSize(); if ((flags & ImGuiColorEditFlags_NoLabel)) Text("Current"); - ColorButton("##current", col_v4, (flags & (ImGuiColorEditFlags_AlphaPreview|ImGuiColorEditFlags_AlphaPreviewHalf|ImGuiColorEditFlags_NoTooltip)), ImVec2(square_sz * 3, square_sz * 2)); + ColorButton("##current", col_v4, (flags & (ImGuiColorEditFlags_HDR|ImGuiColorEditFlags_AlphaPreview|ImGuiColorEditFlags_AlphaPreviewHalf|ImGuiColorEditFlags_NoTooltip)), ImVec2(square_sz * 3, square_sz * 2)); if (ref_col != NULL) { Text("Original"); ImVec4 ref_col_v4(ref_col[0], ref_col[1], ref_col[2], (flags & ImGuiColorEditFlags_NoAlpha) ? 1.0f : ref_col[3]); - if (ColorButton("##original", ref_col_v4, (flags & (ImGuiColorEditFlags_AlphaPreview|ImGuiColorEditFlags_AlphaPreviewHalf|ImGuiColorEditFlags_NoTooltip)), ImVec2(square_sz * 3, square_sz * 2))) + if (ColorButton("##original", ref_col_v4, (flags & (ImGuiColorEditFlags_HDR|ImGuiColorEditFlags_AlphaPreview|ImGuiColorEditFlags_AlphaPreviewHalf|ImGuiColorEditFlags_NoTooltip)), ImVec2(square_sz * 3, square_sz * 2))) { memcpy(col, ref_col, ((flags & ImGuiColorEditFlags_NoAlpha) ? 3 : 4) * sizeof(float)); value_changed = true; diff --git a/imgui.h b/imgui.h index 045d118ee..92b0a3a1b 100644 --- a/imgui.h +++ b/imgui.h @@ -668,17 +668,18 @@ enum ImGuiColorEditFlags_ ImGuiColorEditFlags_HSV = 1 << 2, // " ImGuiColorEditFlags_HEX = 1 << 3, // " ImGuiColorEditFlags_Float = 1 << 4, // ColorEdit, ColorPicker, ColorButton: display values formatted as 0.0f..1.0f floats instead of 0..255 integers. No round-trip of value via integers. - ImGuiColorEditFlags_AlphaBar = 1 << 5, // ColorEdit, ColorPicker: show vertical alpha bar/gradient in picker. - ImGuiColorEditFlags_AlphaPreview = 1 << 6, // ColorEdit, ColorPicker, ColorButton: display preview as a transparent color over a checkerboard, instead of opaque. - ImGuiColorEditFlags_AlphaPreviewHalf= 1 << 7, // ColorEdit, ColorPicker, ColorButton: display half opaque / half checkerboard, instead of opaque. - ImGuiColorEditFlags_NoAlpha = 1 << 8, // ColorEdit, ColorPicker, ColorButton: completely ignore Alpha component (read 3 components from the input pointer). - ImGuiColorEditFlags_NoPicker = 1 << 9, // ColorEdit: disable picker when clicking on colored square. - ImGuiColorEditFlags_NoOptions = 1 << 10, // ColorEdit: disable toggling options menu when right-clicking on inputs/small preview. - ImGuiColorEditFlags_NoSmallPreview = 1 << 11, // ColorEdit, ColorPicker: disable colored square preview next to the inputs. (e.g. to show only the inputs) - ImGuiColorEditFlags_NoInputs = 1 << 12, // ColorEdit, ColorPicker: disable inputs sliders/text widgets (e.g. to show only the small preview colored square). - ImGuiColorEditFlags_NoTooltip = 1 << 13, // ColorEdit, ColorPicker, ColorButton: disable tooltip when hovering the preview. - ImGuiColorEditFlags_NoLabel = 1 << 14, // ColorEdit, ColorPicker: disable display of inline text label (the label is still forwarded to the tooltip and picker). - ImGuiColorEditFlags_NoSidePreview = 1 << 15, // ColorPicker: disable bigger color preview on right side of the picker, use small colored square preview instead. + ImGuiColorEditFlags_HDR = 1 << 5, // ColorEdit: disable 0.0f..1.0f limits (note: you probably want to use ImGuiColorEditFlags_Float flag as well). + ImGuiColorEditFlags_AlphaBar = 1 << 6, // ColorEdit, ColorPicker: show vertical alpha bar/gradient in picker. + ImGuiColorEditFlags_AlphaPreview = 1 << 7, // ColorEdit, ColorPicker, ColorButton: display preview as a transparent color over a checkerboard, instead of opaque. + ImGuiColorEditFlags_AlphaPreviewHalf= 1 << 8, // ColorEdit, ColorPicker, ColorButton: display half opaque / half checkerboard, instead of opaque. + ImGuiColorEditFlags_NoAlpha = 1 << 9, // ColorEdit, ColorPicker, ColorButton: completely ignore Alpha component (read 3 components from the input pointer). + ImGuiColorEditFlags_NoPicker = 1 << 10, // ColorEdit: disable picker when clicking on colored square. + ImGuiColorEditFlags_NoOptions = 1 << 11, // ColorEdit: disable toggling options menu when right-clicking on inputs/small preview. + ImGuiColorEditFlags_NoSmallPreview = 1 << 12, // ColorEdit, ColorPicker: disable colored square preview next to the inputs. (e.g. to show only the inputs) + ImGuiColorEditFlags_NoInputs = 1 << 13, // ColorEdit, ColorPicker: disable inputs sliders/text widgets (e.g. to show only the small preview colored square). + ImGuiColorEditFlags_NoTooltip = 1 << 14, // ColorEdit, ColorPicker, ColorButton: disable tooltip when hovering the preview. + ImGuiColorEditFlags_NoLabel = 1 << 15, // ColorEdit, ColorPicker: disable display of inline text label (the label is still forwarded to the tooltip and picker). + ImGuiColorEditFlags_NoSidePreview = 1 << 16, // ColorPicker: disable bigger color preview on right side of the picker, use small colored square preview instead. ImGuiColorEditFlags_ModeMask_ = ImGuiColorEditFlags_RGB|ImGuiColorEditFlags_HSV|ImGuiColorEditFlags_HEX, ImGuiColorEditFlags_StoredMask_ = ImGuiColorEditFlags_RGB|ImGuiColorEditFlags_HSV|ImGuiColorEditFlags_HEX|ImGuiColorEditFlags_Float }; diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 625f50c8f..ddf30eeab 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -662,25 +662,27 @@ void ImGui::ShowTestWindow(bool* p_open) { static ImVec4 color = ImColor(114, 144, 154, 200); + static bool hdr = false; static bool alpha_preview = true; static bool alpha_half_preview = false; + ImGui::Checkbox("With HDR", &hdr); ImGui::SameLine(); ShowHelpMarker("Currently all this does is to lift the 0..1 limits on dragging widgets."); ImGui::Checkbox("With Alpha Preview", &alpha_preview); ImGui::Checkbox("With Half Alpha Preview", &alpha_half_preview); - int alpha_preview_flags = alpha_half_preview ? ImGuiColorEditFlags_AlphaPreviewHalf : (alpha_preview ? ImGuiColorEditFlags_AlphaPreview : 0); + int misc_flags = (hdr ? ImGuiColorEditFlags_HDR : 0) | (alpha_half_preview ? ImGuiColorEditFlags_AlphaPreviewHalf : (alpha_preview ? ImGuiColorEditFlags_AlphaPreview : 0)); ImGui::Text("Color widget:"); ImGui::SameLine(); ShowHelpMarker("Click on the colored square to open a color picker.\nRight-click on the colored square to show options.\nCTRL+click on individual component to input value.\n"); ImGui::ColorEdit3("MyColor##1", (float*)&color, ImGuiColorEditFlags_HSV); ImGui::Text("Color widget with Alpha:"); - ImGui::ColorEdit4("MyColor##2", (float*)&color, alpha_preview_flags); + ImGui::ColorEdit4("MyColor##2", (float*)&color, misc_flags); ImGui::Text("Color widget with Float Display:"); - ImGui::ColorEdit4("MyColor##2f", (float*)&color, ImGuiColorEditFlags_Float | alpha_preview_flags); + ImGui::ColorEdit4("MyColor##2f", (float*)&color, ImGuiColorEditFlags_Float | misc_flags); ImGui::Text("Color button with Picker:"); ImGui::SameLine(); ShowHelpMarker("With the ImGuiColorEditFlags_NoInputs flag you can hide all the slider/text inputs.\nWith the ImGuiColorEditFlags_NoLabel flag you can pass a non-empty label which will only be used for the tooltip and picker popup."); - ImGui::ColorEdit4("MyColor##3", (float*)&color, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel | alpha_preview_flags); + ImGui::ColorEdit4("MyColor##3", (float*)&color, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel | misc_flags); ImGui::Text("Color button with Custom Picker Popup:"); static bool saved_palette_inited = false; @@ -689,7 +691,7 @@ void ImGui::ShowTestWindow(bool* p_open) if (!saved_palette_inited) for (int n = 0; n < IM_ARRAYSIZE(saved_palette); n++) ImGui::ColorConvertHSVtoRGB(n / 31.0f, 0.8f, 0.8f, saved_palette[n].x, saved_palette[n].y, saved_palette[n].z); - bool open_popup = ImGui::ColorButton("MyColor##3b", color, alpha_preview_flags); + bool open_popup = ImGui::ColorButton("MyColor##3b", color, misc_flags); ImGui::SameLine(); open_popup |= ImGui::Button("Palette"); if (open_popup) @@ -702,7 +704,7 @@ void ImGui::ShowTestWindow(bool* p_open) // FIXME: Adding a drag and drop example here would be perfect! ImGui::Text("MY CUSTOM COLOR PICKER WITH AN AMAZING PALETTE!"); ImGui::Separator(); - ImGui::ColorPicker4("##picker", (float*)&color, alpha_preview_flags | ImGuiColorEditFlags_NoSidePreview | ImGuiColorEditFlags_NoSmallPreview); + ImGui::ColorPicker4("##picker", (float*)&color, misc_flags | ImGuiColorEditFlags_NoSidePreview | ImGuiColorEditFlags_NoSmallPreview); ImGui::SameLine(); ImGui::BeginGroup(); ImGui::Text("Current"); @@ -726,7 +728,7 @@ void ImGui::ShowTestWindow(bool* p_open) } ImGui::Text("Color button only:"); - ImGui::ColorButton("MyColor##3b", *(ImVec4*)&color, alpha_preview_flags, ImVec2(80,80)); + ImGui::ColorButton("MyColor##3b", *(ImVec4*)&color, misc_flags, ImVec2(80,80)); ImGui::Text("Color picker:"); static bool alpha = true; @@ -745,14 +747,14 @@ void ImGui::ShowTestWindow(bool* p_open) if (ref_color) { ImGui::SameLine(); - ImGui::ColorEdit4("##RefColor", &ref_color_v.x, ImGuiColorEditFlags_NoInputs | alpha_preview_flags); + ImGui::ColorEdit4("##RefColor", &ref_color_v.x, ImGuiColorEditFlags_NoInputs | misc_flags); } } ImGui::Combo("Mode", &inputs_mode, "All Inputs\0No Inputs\0RGB Input\0HSV Input\0HEX Input\0"); ImGui::SameLine(); ShowHelpMarker("User can right-click the inputs and override edit mode."); //ImGui::DragFloat("Width", &width, 1.0f, 1.0f, 999.0f); //ImGui::PushItemWidth(width); - ImGuiColorEditFlags flags = alpha_preview_flags; + ImGuiColorEditFlags flags = misc_flags; if (!alpha) flags |= ImGuiColorEditFlags_NoAlpha; // This is by default if you call ColorPicker3() instead of ColorPicker4() if (alpha_bar) flags |= ImGuiColorEditFlags_AlphaBar; if (!side_preview) flags |= ImGuiColorEditFlags_NoSidePreview; From 3ee969c3e3659ae50e9ef47e7c1c7fa6cf6e116f Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 30 Jul 2017 23:11:59 +0800 Subject: [PATCH 161/921] ColorPicker: Alpha bar using a checkerboard. (#346) --- imgui.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index d7dda115f..45206dfe6 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9504,11 +9504,13 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl RenderArrowsForVerticalBar(draw_list, ImVec2(bar0_pos_x - 1, bar0_line_y), ImVec2(bars_triangles_half_sz + 1, bars_triangles_half_sz), bars_width + 2.0f); // Render alpha bar + ImU32 col32_no_alpha = ColorConvertFloat4ToU32(ImVec4(col[0], col[1], col[2], 1.0f)); if (alpha_bar) { float alpha = ImSaturate(col[3]); ImRect bar1_bb(bar1_pos_x, picker_pos.y, bar1_pos_x + bars_width, picker_pos.y + sv_picker_size); - draw_list->AddRectFilledMultiColor(bar1_bb.Min, bar1_bb.Max, IM_COL32_WHITE, IM_COL32_WHITE, IM_COL32_BLACK, IM_COL32_BLACK); + RenderColorRectWithAlphaCheckerboard(bar1_bb.Min, bar1_bb.Max, IM_COL32(0,0,0,0), bar1_bb.GetWidth() / 2.0f, ImVec2(0,0)); + draw_list->AddRectFilledMultiColor(bar1_bb.Min, bar1_bb.Max, col32_no_alpha, col32_no_alpha, col32_no_alpha & ~IM_COL32_A_MASK, col32_no_alpha & ~IM_COL32_A_MASK); float bar1_line_y = (float)(int)(picker_pos.y + (1.0f - alpha) * sv_picker_size + 0.5f); RenderFrameBorder(bar1_bb.Min, bar1_bb.Max, 0.0f); RenderArrowsForVerticalBar(draw_list, ImVec2(bar1_pos_x - 1, bar1_line_y), ImVec2(bars_triangles_half_sz + 1, bars_triangles_half_sz), bars_width + 2.0f); @@ -9525,7 +9527,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl p.x = ImClamp(p.x, picker_pos.x + 2, picker_pos.x + sv_picker_size - 2); p.y = ImClamp(p.y, picker_pos.y + 2, picker_pos.y + sv_picker_size - 2); float r = value_changed_from_matrix ? 10.0f : 6.0f; - draw_list->AddCircleFilled(p, r, ColorConvertFloat4ToU32(ImVec4(col[0], col[1], col[2], 1.0f)), 12); + draw_list->AddCircleFilled(p, r, col32_no_alpha, 12); draw_list->AddCircle(p, r+1, IM_COL32(128,128,128,255), 12); draw_list->AddCircle(p, r, IM_COL32_WHITE, 12); From efbb1ae04e16d49bfc67f8e81c78a98ed95bdfb1 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 30 Jul 2017 23:22:48 +0800 Subject: [PATCH 162/921] ColorPicker4: Fixed forwarding _HDR flag from ColorPicker4 back to ColorEdit4 components. (#346) --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 45206dfe6..e796acfa5 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9459,7 +9459,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl if (!(flags & ImGuiColorEditFlags_NoInputs)) { PushItemWidth((alpha_bar ? bar1_pos_x : bar0_pos_x) + bars_width - picker_pos.x); - ImGuiColorEditFlags sub_flags_to_forward = ImGuiColorEditFlags_Float | ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoSmallPreview | ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf; + ImGuiColorEditFlags sub_flags_to_forward = ImGuiColorEditFlags_Float | ImGuiColorEditFlags_HDR | ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoSmallPreview | ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf; ImGuiColorEditFlags sub_flags = (flags & sub_flags_to_forward) | ImGuiColorEditFlags_NoPicker; if ((flags & ImGuiColorEditFlags_ModeMask_) == 0) flags |= ImGuiColorEditFlags_RGB | ImGuiColorEditFlags_HSV | ImGuiColorEditFlags_HEX; From 4b2f157fb11d41f663578d3043789f366f3837f4 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 31 Jul 2017 11:50:14 +0800 Subject: [PATCH 163/921] Renamed ImGuiColorEditFlags_ModeMask_ to ImGuiColorEditFlags_InputsModeMask_ (#346) --- imgui.cpp | 16 ++++++++-------- imgui.h | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index e796acfa5..a79a8e030 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9153,16 +9153,16 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag // If we're not showing any slider there's no point in querying color mode, nor showing the options menu, nor doing any HSV conversions if (flags & ImGuiColorEditFlags_NoInputs) - flags = (flags & (~ImGuiColorEditFlags_ModeMask_)) | ImGuiColorEditFlags_RGB | ImGuiColorEditFlags_NoOptions; + flags = (flags & (~ImGuiColorEditFlags_InputsModeMask_)) | ImGuiColorEditFlags_RGB | ImGuiColorEditFlags_NoOptions; // If no mode is specified, defaults to RGB - if (!(flags & ImGuiColorEditFlags_ModeMask_)) + if (!(flags & ImGuiColorEditFlags_InputsModeMask_)) flags |= ImGuiColorEditFlags_RGB; // Read back edit mode from persistent storage, check that exactly one of RGB/HSV/HEX is set if (!(flags & ImGuiColorEditFlags_NoOptions)) flags = (flags & (~ImGuiColorEditFlags_StoredMask_)) | (g.ColorEditModeStorage.GetInt(storage_id, (flags & ImGuiColorEditFlags_StoredMask_)) & ImGuiColorEditFlags_StoredMask_); - IM_ASSERT(ImIsPowerOfTwo((int)(flags & ImGuiColorEditFlags_ModeMask_))); + IM_ASSERT(ImIsPowerOfTwo((int)(flags & ImGuiColorEditFlags_InputsModeMask_))); float f[4] = { col[0], col[1], col[2], alpha ? col[3] : 1.0f }; if (flags & ImGuiColorEditFlags_HSV) @@ -9283,9 +9283,9 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag if (!(flags & ImGuiColorEditFlags_NoOptions) && BeginPopup("context")) { ImGuiColorEditFlags new_flags = -1; - if (RadioButton("RGB", (flags & ImGuiColorEditFlags_RGB)?1:0)) new_flags = (flags & ~ImGuiColorEditFlags_ModeMask_) | ImGuiColorEditFlags_RGB; - if (RadioButton("HSV", (flags & ImGuiColorEditFlags_HSV)?1:0)) new_flags = (flags & ~ImGuiColorEditFlags_ModeMask_) | ImGuiColorEditFlags_HSV; - if (RadioButton("HEX", (flags & ImGuiColorEditFlags_HEX)?1:0)) new_flags = (flags & ~ImGuiColorEditFlags_ModeMask_) | ImGuiColorEditFlags_HEX; + if (RadioButton("RGB", (flags & ImGuiColorEditFlags_RGB)?1:0)) new_flags = (flags & ~ImGuiColorEditFlags_InputsModeMask_) | ImGuiColorEditFlags_RGB; + if (RadioButton("HSV", (flags & ImGuiColorEditFlags_HSV)?1:0)) new_flags = (flags & ~ImGuiColorEditFlags_InputsModeMask_) | ImGuiColorEditFlags_HSV; + if (RadioButton("HEX", (flags & ImGuiColorEditFlags_HEX)?1:0)) new_flags = (flags & ~ImGuiColorEditFlags_InputsModeMask_) | ImGuiColorEditFlags_HEX; Separator(); if (RadioButton("0..255", (flags & ImGuiColorEditFlags_Float)?0:1)) new_flags = (flags & ~ImGuiColorEditFlags_Float); if (RadioButton("0.00..1.00", (flags & ImGuiColorEditFlags_Float)?1:0)) new_flags = (flags | ImGuiColorEditFlags_Float); @@ -9461,9 +9461,9 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl PushItemWidth((alpha_bar ? bar1_pos_x : bar0_pos_x) + bars_width - picker_pos.x); ImGuiColorEditFlags sub_flags_to_forward = ImGuiColorEditFlags_Float | ImGuiColorEditFlags_HDR | ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoSmallPreview | ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf; ImGuiColorEditFlags sub_flags = (flags & sub_flags_to_forward) | ImGuiColorEditFlags_NoPicker; - if ((flags & ImGuiColorEditFlags_ModeMask_) == 0) + if ((flags & ImGuiColorEditFlags_InputsModeMask_) == 0) flags |= ImGuiColorEditFlags_RGB | ImGuiColorEditFlags_HSV | ImGuiColorEditFlags_HEX; - if ((flags & ImGuiColorEditFlags_ModeMask_) == ImGuiColorEditFlags_ModeMask_) + if ((flags & ImGuiColorEditFlags_InputsModeMask_) == ImGuiColorEditFlags_InputsModeMask_) sub_flags |= ImGuiColorEditFlags_NoOptions; if (flags & ImGuiColorEditFlags_RGB) value_changed |= ColorEdit4("##rgb", col, sub_flags | ImGuiColorEditFlags_RGB); diff --git a/imgui.h b/imgui.h index 92b0a3a1b..c7c367fc3 100644 --- a/imgui.h +++ b/imgui.h @@ -680,7 +680,7 @@ enum ImGuiColorEditFlags_ ImGuiColorEditFlags_NoTooltip = 1 << 14, // ColorEdit, ColorPicker, ColorButton: disable tooltip when hovering the preview. ImGuiColorEditFlags_NoLabel = 1 << 15, // ColorEdit, ColorPicker: disable display of inline text label (the label is still forwarded to the tooltip and picker). ImGuiColorEditFlags_NoSidePreview = 1 << 16, // ColorPicker: disable bigger color preview on right side of the picker, use small colored square preview instead. - ImGuiColorEditFlags_ModeMask_ = ImGuiColorEditFlags_RGB|ImGuiColorEditFlags_HSV|ImGuiColorEditFlags_HEX, + ImGuiColorEditFlags_InputsModeMask_ = ImGuiColorEditFlags_RGB|ImGuiColorEditFlags_HSV|ImGuiColorEditFlags_HEX, ImGuiColorEditFlags_StoredMask_ = ImGuiColorEditFlags_RGB|ImGuiColorEditFlags_HSV|ImGuiColorEditFlags_HEX|ImGuiColorEditFlags_Float }; From 70ee41b8b36a56d838f816a8f771c29ac1dea746 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 31 Jul 2017 12:08:20 +0800 Subject: [PATCH 164/921] ColorPicker: Reordered drawing code to match left-to-right display. Extra comments. (#346) --- imgui.cpp | 51 +++++++++++++++++++++++---------------------------- 1 file changed, 23 insertions(+), 28 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index a79a8e030..236ca7a27 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9488,49 +9488,44 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl } } - // Render hue bar - ImVec4 hue_color_f(1, 1, 1, 1); - ColorConvertHSVtoRGB(H, 1, 1, hue_color_f.x, hue_color_f.y, hue_color_f.z); - ImU32 hue_colors[] = { IM_COL32(255,0,0,255), IM_COL32(255,255,0,255), IM_COL32(0,255,0,255), IM_COL32(0,255,255,255), IM_COL32(0,0,255,255), IM_COL32(255,0,255,255), IM_COL32(255,0,0,255) }; - for (int i = 0; i < 6; ++i) - { - draw_list->AddRectFilledMultiColor( - ImVec2(bar0_pos_x, picker_pos.y + i * (sv_picker_size / 6)), - ImVec2(bar0_pos_x + bars_width, picker_pos.y + (i + 1) * (sv_picker_size / 6)), - hue_colors[i], hue_colors[i], hue_colors[i + 1], hue_colors[i + 1]); - } - float bar0_line_y = (float)(int)(picker_pos.y + H * sv_picker_size + 0.5f); - RenderFrameBorder(ImVec2(bar0_pos_x, picker_pos.y), ImVec2(bar0_pos_x + bars_width, picker_pos.y + sv_picker_size), 0.0f); - RenderArrowsForVerticalBar(draw_list, ImVec2(bar0_pos_x - 1, bar0_line_y), ImVec2(bars_triangles_half_sz + 1, bars_triangles_half_sz), bars_width + 2.0f); - - // Render alpha bar + ImVec4 hue_color_f(1, 1, 1, 1); ColorConvertHSVtoRGB(H, 1, 1, hue_color_f.x, hue_color_f.y, hue_color_f.z); + ImU32 hue_color32 = ColorConvertFloat4ToU32(hue_color_f); ImU32 col32_no_alpha = ColorConvertFloat4ToU32(ImVec4(col[0], col[1], col[2], 1.0f)); - if (alpha_bar) - { - float alpha = ImSaturate(col[3]); - ImRect bar1_bb(bar1_pos_x, picker_pos.y, bar1_pos_x + bars_width, picker_pos.y + sv_picker_size); - RenderColorRectWithAlphaCheckerboard(bar1_bb.Min, bar1_bb.Max, IM_COL32(0,0,0,0), bar1_bb.GetWidth() / 2.0f, ImVec2(0,0)); - draw_list->AddRectFilledMultiColor(bar1_bb.Min, bar1_bb.Max, col32_no_alpha, col32_no_alpha, col32_no_alpha & ~IM_COL32_A_MASK, col32_no_alpha & ~IM_COL32_A_MASK); - float bar1_line_y = (float)(int)(picker_pos.y + (1.0f - alpha) * sv_picker_size + 0.5f); - RenderFrameBorder(bar1_bb.Min, bar1_bb.Max, 0.0f); - RenderArrowsForVerticalBar(draw_list, ImVec2(bar1_pos_x - 1, bar1_line_y), ImVec2(bars_triangles_half_sz + 1, bars_triangles_half_sz), bars_width + 2.0f); - } // Render color matrix - ImU32 hue_color32 = ColorConvertFloat4ToU32(hue_color_f); draw_list->AddRectFilledMultiColor(picker_pos, picker_pos + ImVec2(sv_picker_size,sv_picker_size), IM_COL32_WHITE, hue_color32, hue_color32, IM_COL32_WHITE); draw_list->AddRectFilledMultiColor(picker_pos, picker_pos + ImVec2(sv_picker_size,sv_picker_size), IM_COL32_BLACK_TRANS, IM_COL32_BLACK_TRANS, IM_COL32_BLACK, IM_COL32_BLACK); RenderFrameBorder(picker_pos, picker_pos + ImVec2(sv_picker_size,sv_picker_size), 0.0f); // Render cursor/preview circle (clamp S/V within 0..1 range because floating points colors may lead HSV values to be out of range) ImVec2 p((float)(int)(picker_pos.x + ImSaturate(S) * sv_picker_size + 0.5f), (float)(int)(picker_pos.y + ImSaturate(1 - V) * sv_picker_size + 0.5f)); - p.x = ImClamp(p.x, picker_pos.x + 2, picker_pos.x + sv_picker_size - 2); + p.x = ImClamp(p.x, picker_pos.x + 2, picker_pos.x + sv_picker_size - 2); // Sneakily prevent the circle to stick out too much p.y = ImClamp(p.y, picker_pos.y + 2, picker_pos.y + sv_picker_size - 2); float r = value_changed_from_matrix ? 10.0f : 6.0f; draw_list->AddCircleFilled(p, r, col32_no_alpha, 12); draw_list->AddCircle(p, r+1, IM_COL32(128,128,128,255), 12); draw_list->AddCircle(p, r, IM_COL32_WHITE, 12); + // Render hue bar + ImU32 hue_bar_colors[6+1] = { IM_COL32(255,0,0,255), IM_COL32(255,255,0,255), IM_COL32(0,255,0,255), IM_COL32(0,255,255,255), IM_COL32(0,0,255,255), IM_COL32(255,0,255,255), IM_COL32(255,0,0,255) }; + for (int i = 0; i < 6; ++i) + draw_list->AddRectFilledMultiColor(ImVec2(bar0_pos_x, picker_pos.y + i * (sv_picker_size / 6)), ImVec2(bar0_pos_x + bars_width, picker_pos.y + (i + 1) * (sv_picker_size / 6)), hue_bar_colors[i], hue_bar_colors[i], hue_bar_colors[i + 1], hue_bar_colors[i + 1]); + float bar0_line_y = (float)(int)(picker_pos.y + H * sv_picker_size + 0.5f); + RenderFrameBorder(ImVec2(bar0_pos_x, picker_pos.y), ImVec2(bar0_pos_x + bars_width, picker_pos.y + sv_picker_size), 0.0f); + RenderArrowsForVerticalBar(draw_list, ImVec2(bar0_pos_x - 1, bar0_line_y), ImVec2(bars_triangles_half_sz + 1, bars_triangles_half_sz), bars_width + 2.0f); + + // Render alpha bar + if (alpha_bar) + { + float alpha = ImSaturate(col[3]); + ImRect bar1_bb(bar1_pos_x, picker_pos.y, bar1_pos_x + bars_width, picker_pos.y + sv_picker_size); + RenderColorRectWithAlphaCheckerboard(bar1_bb.Min, bar1_bb.Max, IM_COL32(0,0,0,0), bar1_bb.GetWidth() / 2.0f, ImVec2(0.0f, 0.0f)); + draw_list->AddRectFilledMultiColor(bar1_bb.Min, bar1_bb.Max, col32_no_alpha, col32_no_alpha, col32_no_alpha & ~IM_COL32_A_MASK, col32_no_alpha & ~IM_COL32_A_MASK); + float bar1_line_y = (float)(int)(picker_pos.y + (1.0f - alpha) * sv_picker_size + 0.5f); + RenderFrameBorder(bar1_bb.Min, bar1_bb.Max, 0.0f); + RenderArrowsForVerticalBar(draw_list, ImVec2(bar1_pos_x - 1, bar1_line_y), ImVec2(bars_triangles_half_sz + 1, bars_triangles_half_sz), bars_width + 2.0f); + } + EndGroup(); PopID(); From e63ebd997ff7c1d341e5cffd940a64b506aed8ff Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 31 Jul 2017 12:25:27 +0800 Subject: [PATCH 165/921] Use ~IM_COL32_A_MASK instead of IM_COL32(255,255,255,0) --- imgui_draw.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 654e55369..42a87b47a 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -432,7 +432,7 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32 { // Anti-aliased stroke const float AA_SIZE = 1.0f; - const ImU32 col_trans = col & IM_COL32(255,255,255,0); + const ImU32 col_trans = col & ~IM_COL32_A_MASK; const int idx_count = thick_line ? count*18 : count*12; const int vtx_count = thick_line ? points_count*4 : points_count*3; @@ -605,7 +605,7 @@ void ImDrawList::AddConvexPolyFilled(const ImVec2* points, const int points_coun { // Anti-aliased Fill const float AA_SIZE = 1.0f; - const ImU32 col_trans = col & IM_COL32(255,255,255,0); + const ImU32 col_trans = col & ~IM_COL32_A_MASK; const int idx_count = (points_count-2)*3 + points_count*6; const int vtx_count = (points_count*2); PrimReserve(idx_count, vtx_count); From cc3cce7567e706d01391177dbdbdbeb8888e59b8 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 31 Jul 2017 16:48:45 +0800 Subject: [PATCH 166/921] Comments, minor tidying up. --- imgui.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 236ca7a27..c705146ef 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -5570,6 +5570,7 @@ void ImGui::LabelText(const char* label, const char* fmt, ...) static inline bool IsWindowContentHoverable(ImGuiWindow* window) { // An active popup disable hovering on other windows (apart from its own children) + // FIXME-OPT: This could be cached/stored within the window. ImGuiContext& g = *GImGui; if (ImGuiWindow* focused_window = g.FocusedWindow) if (ImGuiWindow* focused_root_window = focused_window->RootWindow) @@ -9846,7 +9847,8 @@ void ImGui::Columns(int columns_count, const char* id, bool border) { float x = window->Pos.x + GetColumnOffset(i); const ImGuiID column_id = window->DC.ColumnsSetId + ImGuiID(i); - const ImRect column_rect(ImVec2(x-4,y1),ImVec2(x+4,y2)); + const float column_w = 4.0f; + const ImRect column_rect(ImVec2(x - column_w, y1), ImVec2(x + column_w, y2)); if (IsClippedEx(column_rect, &column_id, false)) continue; @@ -9863,7 +9865,7 @@ void ImGui::Columns(int columns_count, const char* id, bool border) if (held) { if (g.ActiveIdIsJustActivated) - g.ActiveIdClickOffset.x -= 4; // Store from center of column line (we used a 8 wide rect for columns clicking) + g.ActiveIdClickOffset.x -= column_w; // Store from center of column line (we used a 8 wide rect for columns clicking) x = GetDraggedColumnOffset(i); SetColumnOffset(i, x); } From 10ef5a63f03f84ad12449cf49e46ec827a93a08b Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 31 Jul 2017 16:50:28 +0800 Subject: [PATCH 167/921] ColorPicker: Rearrange code to introduce alternate HSV picker/selector with simpler diff. (#346) --- imgui.cpp | 74 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 40 insertions(+), 34 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index c705146ef..45ea7e890 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9385,22 +9385,25 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl ColorConvertRGBtoHSV(col[0], col[1], col[2], H, S, V); // Color matrix logic - bool value_changed = false, hsv_changed = false, value_changed_from_matrix = false; - InvisibleButton("sv", ImVec2(sv_picker_size, sv_picker_size)); - if (IsItemActive()) - { - S = ImSaturate((io.MousePos.x - picker_pos.x) / (sv_picker_size-1)); - V = 1.0f - ImSaturate((io.MousePos.y - picker_pos.y) / (sv_picker_size-1)); - value_changed = hsv_changed = value_changed_from_matrix = true; - } + bool value_changed = false, value_changed_h = false, value_changed_sv = false; - // Hue bar logic - SetCursorScreenPos(ImVec2(bar0_pos_x, picker_pos.y)); - InvisibleButton("hue", ImVec2(bars_width, sv_picker_size)); - if (IsItemActive()) { - H = ImSaturate((io.MousePos.y - picker_pos.y) / (sv_picker_size-1)); - value_changed = hsv_changed = true; + InvisibleButton("sv", ImVec2(sv_picker_size, sv_picker_size)); + if (IsItemActive()) + { + S = ImSaturate((io.MousePos.x - picker_pos.x) / (sv_picker_size-1)); + V = 1.0f - ImSaturate((io.MousePos.y - picker_pos.y) / (sv_picker_size-1)); + value_changed = value_changed_sv = true; + } + + // Hue bar logic + SetCursorScreenPos(ImVec2(bar0_pos_x, picker_pos.y)); + InvisibleButton("hue", ImVec2(bars_width, sv_picker_size)); + if (IsItemActive()) + { + H = ImSaturate((io.MousePos.y - picker_pos.y) / (sv_picker_size-1)); + value_changed = value_changed_h = true; + } } // Alpha bar logic @@ -9453,7 +9456,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl } // Convert back color to RGB - if (hsv_changed) + if (value_changed_h || value_changed_sv) ColorConvertHSVtoRGB(H >= 1.0f ? H - 10 * 1e-6f : H, S > 0.0f ? S : 10*1e-6f, V > 0.0f ? V : 1e-6f, col[0], col[1], col[2]); // R,G,B and H,S,V slider color editor @@ -9493,27 +9496,30 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl ImU32 hue_color32 = ColorConvertFloat4ToU32(hue_color_f); ImU32 col32_no_alpha = ColorConvertFloat4ToU32(ImVec4(col[0], col[1], col[2], 1.0f)); - // Render color matrix - draw_list->AddRectFilledMultiColor(picker_pos, picker_pos + ImVec2(sv_picker_size,sv_picker_size), IM_COL32_WHITE, hue_color32, hue_color32, IM_COL32_WHITE); - draw_list->AddRectFilledMultiColor(picker_pos, picker_pos + ImVec2(sv_picker_size,sv_picker_size), IM_COL32_BLACK_TRANS, IM_COL32_BLACK_TRANS, IM_COL32_BLACK, IM_COL32_BLACK); - RenderFrameBorder(picker_pos, picker_pos + ImVec2(sv_picker_size,sv_picker_size), 0.0f); + const ImU32 hue_colors[6+1] = { IM_COL32(255,0,0,255), IM_COL32(255,255,0,255), IM_COL32(0,255,0,255), IM_COL32(0,255,255,255), IM_COL32(0,0,255,255), IM_COL32(255,0,255,255), IM_COL32(255,0,0,255) }; + ImVec2 sv_cursor_pos; + + { + // Render SV Square + draw_list->AddRectFilledMultiColor(picker_pos, picker_pos + ImVec2(sv_picker_size,sv_picker_size), IM_COL32_WHITE, hue_color32, hue_color32, IM_COL32_WHITE); + draw_list->AddRectFilledMultiColor(picker_pos, picker_pos + ImVec2(sv_picker_size,sv_picker_size), IM_COL32_BLACK_TRANS, IM_COL32_BLACK_TRANS, IM_COL32_BLACK, IM_COL32_BLACK); + RenderFrameBorder(picker_pos, picker_pos + ImVec2(sv_picker_size,sv_picker_size), 0.0f); + sv_cursor_pos.x = ImClamp((float)(int)(picker_pos.x + ImSaturate(S) * sv_picker_size + 0.5f), picker_pos.x + 2, picker_pos.x + sv_picker_size - 2); // Sneakily prevent the circle to stick out too much + sv_cursor_pos.y = ImClamp((float)(int)(picker_pos.y + ImSaturate(1 - V) * sv_picker_size + 0.5f), picker_pos.y + 2, picker_pos.y + sv_picker_size - 2); - // Render cursor/preview circle (clamp S/V within 0..1 range because floating points colors may lead HSV values to be out of range) - ImVec2 p((float)(int)(picker_pos.x + ImSaturate(S) * sv_picker_size + 0.5f), (float)(int)(picker_pos.y + ImSaturate(1 - V) * sv_picker_size + 0.5f)); - p.x = ImClamp(p.x, picker_pos.x + 2, picker_pos.x + sv_picker_size - 2); // Sneakily prevent the circle to stick out too much - p.y = ImClamp(p.y, picker_pos.y + 2, picker_pos.y + sv_picker_size - 2); - float r = value_changed_from_matrix ? 10.0f : 6.0f; - draw_list->AddCircleFilled(p, r, col32_no_alpha, 12); - draw_list->AddCircle(p, r+1, IM_COL32(128,128,128,255), 12); - draw_list->AddCircle(p, r, IM_COL32_WHITE, 12); + // Render Hue Bar + for (int i = 0; i < 6; ++i) + draw_list->AddRectFilledMultiColor(ImVec2(bar0_pos_x, picker_pos.y + i * (sv_picker_size / 6)), ImVec2(bar0_pos_x + bars_width, picker_pos.y + (i + 1) * (sv_picker_size / 6)), hue_colors[i], hue_colors[i], hue_colors[i + 1], hue_colors[i + 1]); + float bar0_line_y = (float)(int)(picker_pos.y + H * sv_picker_size + 0.5f); + RenderFrameBorder(ImVec2(bar0_pos_x, picker_pos.y), ImVec2(bar0_pos_x + bars_width, picker_pos.y + sv_picker_size), 0.0f); + RenderArrowsForVerticalBar(draw_list, ImVec2(bar0_pos_x - 1, bar0_line_y), ImVec2(bars_triangles_half_sz + 1, bars_triangles_half_sz), bars_width + 2.0f); + } - // Render hue bar - ImU32 hue_bar_colors[6+1] = { IM_COL32(255,0,0,255), IM_COL32(255,255,0,255), IM_COL32(0,255,0,255), IM_COL32(0,255,255,255), IM_COL32(0,0,255,255), IM_COL32(255,0,255,255), IM_COL32(255,0,0,255) }; - for (int i = 0; i < 6; ++i) - draw_list->AddRectFilledMultiColor(ImVec2(bar0_pos_x, picker_pos.y + i * (sv_picker_size / 6)), ImVec2(bar0_pos_x + bars_width, picker_pos.y + (i + 1) * (sv_picker_size / 6)), hue_bar_colors[i], hue_bar_colors[i], hue_bar_colors[i + 1], hue_bar_colors[i + 1]); - float bar0_line_y = (float)(int)(picker_pos.y + H * sv_picker_size + 0.5f); - RenderFrameBorder(ImVec2(bar0_pos_x, picker_pos.y), ImVec2(bar0_pos_x + bars_width, picker_pos.y + sv_picker_size), 0.0f); - RenderArrowsForVerticalBar(draw_list, ImVec2(bar0_pos_x - 1, bar0_line_y), ImVec2(bars_triangles_half_sz + 1, bars_triangles_half_sz), bars_width + 2.0f); + // Render cursor/preview circle (clamp S/V within 0..1 range because floating points colors may lead HSV values to be out of range) + float sv_cursor_rad = value_changed_sv ? 10.0f : 6.0f; + draw_list->AddCircleFilled(sv_cursor_pos, sv_cursor_rad, col32_no_alpha, 12); + draw_list->AddCircle(sv_cursor_pos, sv_cursor_rad+1, IM_COL32(128,128,128,255), 12); + draw_list->AddCircle(sv_cursor_pos, sv_cursor_rad, IM_COL32_WHITE, 12); // Render alpha bar if (alpha_bar) From 2f508c7073faa314739e205b4b244309daaeb2fc Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 31 Jul 2017 17:32:07 +0800 Subject: [PATCH 168/921] ColorEdit: Extract ColorOptionsPopup() function out of ColorEdit4(). (#346) --- imgui.cpp | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 45ea7e890..e36f1c65f 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9132,6 +9132,20 @@ bool ImGui::ColorEdit3(const char* label, float col[3], ImGuiColorEditFlags flag return ColorEdit4(label, col, flags | ImGuiColorEditFlags_NoAlpha); } +static void ColorOptionsPopup(ImGuiID storage_id, ImGuiColorEditFlags flags) +{ + ImGuiContext& g = *GImGui; + ImGuiColorEditFlags new_flags = -1; + if (ImGui::RadioButton("RGB", (flags & ImGuiColorEditFlags_RGB)?1:0)) new_flags = (flags & ~ImGuiColorEditFlags_InputsModeMask_) | ImGuiColorEditFlags_RGB; + if (ImGui::RadioButton("HSV", (flags & ImGuiColorEditFlags_HSV)?1:0)) new_flags = (flags & ~ImGuiColorEditFlags_InputsModeMask_) | ImGuiColorEditFlags_HSV; + if (ImGui::RadioButton("HEX", (flags & ImGuiColorEditFlags_HEX)?1:0)) new_flags = (flags & ~ImGuiColorEditFlags_InputsModeMask_) | ImGuiColorEditFlags_HEX; + ImGui::Separator(); + if (ImGui::RadioButton("0..255", (flags & ImGuiColorEditFlags_Float)?0:1)) new_flags = (flags & ~ImGuiColorEditFlags_Float); + if (ImGui::RadioButton("0.00..1.00", (flags & ImGuiColorEditFlags_Float)?1:0)) new_flags = (flags | ImGuiColorEditFlags_Float); + if (new_flags != -1) + g.ColorEditModeStorage.SetInt(storage_id, (int)(new_flags & ImGuiColorEditFlags_StoredMask_)); +} + // Edit colors components (each component in 0.0f..1.0f range). // See enum ImGuiColorEditFlags_ for available options. e.g. Only access 3 floats if ImGuiColorEditFlags_NoAlpha flag is set. // With typical options: Left-click on colored square to open color picker. Right-click to open option menu. CTRL-Click over input fields to edit them and TAB to go to next item. @@ -9283,15 +9297,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag // Context menu: display and store options. Don't apply to 'flags' this frame. if (!(flags & ImGuiColorEditFlags_NoOptions) && BeginPopup("context")) { - ImGuiColorEditFlags new_flags = -1; - if (RadioButton("RGB", (flags & ImGuiColorEditFlags_RGB)?1:0)) new_flags = (flags & ~ImGuiColorEditFlags_InputsModeMask_) | ImGuiColorEditFlags_RGB; - if (RadioButton("HSV", (flags & ImGuiColorEditFlags_HSV)?1:0)) new_flags = (flags & ~ImGuiColorEditFlags_InputsModeMask_) | ImGuiColorEditFlags_HSV; - if (RadioButton("HEX", (flags & ImGuiColorEditFlags_HEX)?1:0)) new_flags = (flags & ~ImGuiColorEditFlags_InputsModeMask_) | ImGuiColorEditFlags_HEX; - Separator(); - if (RadioButton("0..255", (flags & ImGuiColorEditFlags_Float)?0:1)) new_flags = (flags & ~ImGuiColorEditFlags_Float); - if (RadioButton("0.00..1.00", (flags & ImGuiColorEditFlags_Float)?1:0)) new_flags = (flags | ImGuiColorEditFlags_Float); - if (new_flags != -1) - g.ColorEditModeStorage.SetInt(storage_id, (int)(new_flags & ImGuiColorEditFlags_StoredMask_)); + ColorOptionsPopup(storage_id, flags); EndPopup(); } From 72da4081f89aae92be0071a5119ad07224423c9f Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 31 Jul 2017 17:54:40 +0800 Subject: [PATCH 169/921] Internals: Added ImTriangleBarycentricCoords() helper. Renamed ImIsPointInTriangle() to ImTriangleContainsPoint(), with different arg order. --- imgui.cpp | 15 +++++++++++++-- imgui_internal.h | 3 ++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index e36f1c65f..a9a799dbf 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -900,7 +900,7 @@ void ImGuiIO::AddInputCharactersUTF8(const char* utf8_chars) #define IM_NEWLINE "\n" #endif -bool ImIsPointInTriangle(const ImVec2& p, const ImVec2& a, const ImVec2& b, const ImVec2& c) +bool ImTriangleContainsPoint(ImVec2 a, ImVec2 b, ImVec2 c, ImVec2 p) { bool b1 = ((p.x - b.x) * (a.y - b.y) - (p.y - b.y) * (a.x - b.x)) < 0.0f; bool b2 = ((p.x - c.x) * (b.y - c.y) - (p.y - c.y) * (b.x - c.x)) < 0.0f; @@ -908,6 +908,17 @@ bool ImIsPointInTriangle(const ImVec2& p, const ImVec2& a, const ImVec2& b, cons return ((b1 == b2) && (b2 == b3)); } +void ImTriangleBarycentricCoords(ImVec2 a, ImVec2 b, ImVec2 c, ImVec2 p, float& out_u, float& out_v, float& out_w) +{ + ImVec2 v0 = b - a; + ImVec2 v1 = c - a; + ImVec2 v2 = p - a; + const float denom = v0.x * v1.y - v1.x * v0.y; + out_v = (v2.x * v1.y - v1.x * v2.y) / denom; + out_w = (v0.x * v2.y - v2.x * v0.y) / denom; + out_u = 1.0f - out_v - out_w; +} + int ImStricmp(const char* str1, const char* str2) { int d; @@ -8954,7 +8965,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled) ta.x += (window->Pos.x < next_window->Pos.x) ? -0.5f : +0.5f; // to avoid numerical issues tb.y = ta.y + ImMax((tb.y - extra) - ta.y, -100.0f); // triangle is maximum 200 high to limit the slope and the bias toward large sub-menus // FIXME: Multiply by fb_scale? tc.y = ta.y + ImMin((tc.y + extra) - ta.y, +100.0f); - moving_within_opened_triangle = ImIsPointInTriangle(g.IO.MousePos, ta, tb, tc); + moving_within_opened_triangle = ImTriangleContainsPoint(ta, tb, tc, g.IO.MousePos); //window->DrawList->PushClipRectFullScreen(); window->DrawList->AddTriangleFilled(ta, tb, tc, moving_within_opened_triangle ? IM_COL32(0,128,0,128) : IM_COL32(128,0,0,128)); window->DrawList->PopClipRect(); // Debug } } diff --git a/imgui_internal.h b/imgui_internal.h index e8d930fae..ff7285c98 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -90,7 +90,8 @@ IMGUI_API int ImTextCountUtf8BytesFromStr(const ImWchar* in_text, cons IMGUI_API ImU32 ImHash(const void* data, int data_size, ImU32 seed = 0); // Pass data_size==0 for zero-terminated strings IMGUI_API void* ImFileLoadToMemory(const char* filename, const char* file_open_mode, int* out_file_size = NULL, int padding_bytes = 0); IMGUI_API FILE* ImFileOpen(const char* filename, const char* file_open_mode); -IMGUI_API bool ImIsPointInTriangle(const ImVec2& p, const ImVec2& a, const ImVec2& b, const ImVec2& c); +IMGUI_API bool ImTriangleContainsPoint(ImVec2 a, ImVec2 b, ImVec2 c, ImVec2 p); +IMGUI_API void ImTriangleBarycentricCoords(ImVec2 a, ImVec2 b, ImVec2 c, ImVec2 p, float& out_u, float& out_v, float& out_w); static inline bool ImCharIsSpace(int c) { return c == ' ' || c == '\t' || c == 0x3000; } static inline bool ImIsPowerOfTwo(int v) { return v != 0 && (v & (v - 1)) == 0; } static inline int ImUpperPowerOfTwo(int v) { v--; v |= v >> 1; v |= v >> 2; v |= v >> 4; v |= v >> 8; v |= v >> 16; v++; return v; } From 1a26d0bc98e0a6a54d4e8f449fc9cf3facd47902 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 31 Jul 2017 18:56:51 +0800 Subject: [PATCH 170/921] Internals: Added ImDot(), ImRotate(), ImLerp(v2,v2,float) helpers. --- imgui_internal.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/imgui_internal.h b/imgui_internal.h index ff7285c98..4aeac0686 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -134,12 +134,15 @@ static inline ImVec2 ImClamp(const ImVec2& f, const ImVec2& mn, ImVec2 mx) static inline float ImSaturate(float f) { return (f < 0.0f) ? 0.0f : (f > 1.0f) ? 1.0f : f; } static inline int ImLerp(int a, int b, float t) { return (int)(a + (b - a) * t); } static inline float ImLerp(float a, float b, float t) { return a + (b - a) * t; } +static inline ImVec2 ImLerp(const ImVec2& a, const ImVec2& b, float t) { return ImVec2(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t); } static inline ImVec2 ImLerp(const ImVec2& a, const ImVec2& b, const ImVec2& t) { return ImVec2(a.x + (b.x - a.x) * t.x, a.y + (b.y - a.y) * t.y); } static inline float ImLengthSqr(const ImVec2& lhs) { return lhs.x*lhs.x + lhs.y*lhs.y; } static inline float ImLengthSqr(const ImVec4& lhs) { return lhs.x*lhs.x + lhs.y*lhs.y + lhs.z*lhs.z + lhs.w*lhs.w; } static inline float ImInvLength(const ImVec2& lhs, float fail_value) { float d = lhs.x*lhs.x + lhs.y*lhs.y; if (d > 0.0f) return 1.0f / sqrtf(d); return fail_value; } static inline float ImFloor(float f) { return (float)(int)f; } -static inline ImVec2 ImFloor(ImVec2 v) { return ImVec2((float)(int)v.x, (float)(int)v.y); } +static inline ImVec2 ImFloor(const ImVec2& v) { return ImVec2((float)(int)v.x, (float)(int)v.y); } +static inline float ImDot(const ImVec2& a, const ImVec2& b) { return a.x * b.x + a.y * b.y; } +static inline ImVec2 ImRotate(const ImVec2& v, float cos_a, float sin_a) { return ImVec2(v.x * cos_a - v.y * sin_a, v.x * sin_a + v.y * cos_a); } // We call C++ constructor on own allocated memory via the placement "new(ptr) Type()" syntax. // Defining a custom placement new() with a dummy parameter allows us to bypass including which on some platforms complains when user has disabled exceptions. From fb54dce71c4337009764a66afc6b44b2436d2463 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 31 Jul 2017 21:11:41 +0800 Subject: [PATCH 171/921] Internals: Added ImLineClosestPoint, ImTriangleClosestPoint helpers. Changing ImVec2 arg to const ImVec2& --- imgui.cpp | 34 ++++++++++++++++++++++++++++++++-- imgui_internal.h | 10 +++++++--- 2 files changed, 39 insertions(+), 5 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index a9a799dbf..3aa543918 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -900,7 +900,21 @@ void ImGuiIO::AddInputCharactersUTF8(const char* utf8_chars) #define IM_NEWLINE "\n" #endif -bool ImTriangleContainsPoint(ImVec2 a, ImVec2 b, ImVec2 c, ImVec2 p) +ImVec2 ImLineClosestPoint(const ImVec2& a, const ImVec2& b, const ImVec2& p) +{ + ImVec2 ap = p - a; + ImVec2 ab_dir = b - a; + float ab_len = sqrtf(ab_dir.x * ab_dir.x + ab_dir.y * ab_dir.y); + ab_dir *= 1.0f / ab_len; + float dot = ap.x * ab_dir.x + ap.y * ab_dir.y; + if (dot < 0.0f) + return a; + if (dot > ab_len) + return b; + return a + ab_dir * dot; +} + +bool ImTriangleContainsPoint(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p) { bool b1 = ((p.x - b.x) * (a.y - b.y) - (p.y - b.y) * (a.x - b.x)) < 0.0f; bool b2 = ((p.x - c.x) * (b.y - c.y) - (p.y - c.y) * (b.x - c.x)) < 0.0f; @@ -908,7 +922,7 @@ bool ImTriangleContainsPoint(ImVec2 a, ImVec2 b, ImVec2 c, ImVec2 p) return ((b1 == b2) && (b2 == b3)); } -void ImTriangleBarycentricCoords(ImVec2 a, ImVec2 b, ImVec2 c, ImVec2 p, float& out_u, float& out_v, float& out_w) +void ImTriangleBarycentricCoords(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p, float& out_u, float& out_v, float& out_w) { ImVec2 v0 = b - a; ImVec2 v1 = c - a; @@ -919,6 +933,22 @@ void ImTriangleBarycentricCoords(ImVec2 a, ImVec2 b, ImVec2 c, ImVec2 p, float& out_u = 1.0f - out_v - out_w; } +ImVec2 ImTriangleClosestPoint(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p) +{ + ImVec2 proj_ab = ImLineClosestPoint(a, b, p); + ImVec2 proj_bc = ImLineClosestPoint(b, c, p); + ImVec2 proj_ca = ImLineClosestPoint(c, a, p); + float dist2_ab = ImLengthSqr(p - proj_ab); + float dist2_bc = ImLengthSqr(p - proj_bc); + float dist2_ca = ImLengthSqr(p - proj_ca); + float m = ImMin(dist2_ab, ImMin(dist2_bc, dist2_ca)); + if (m == dist2_ab) + return proj_ab; + if (m == dist2_bc) + return proj_bc; + return proj_ca; +} + int ImStricmp(const char* str1, const char* str2) { int d; diff --git a/imgui_internal.h b/imgui_internal.h index 4aeac0686..080369158 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -89,13 +89,17 @@ IMGUI_API int ImTextCountUtf8BytesFromStr(const ImWchar* in_text, cons // Helpers: Misc IMGUI_API ImU32 ImHash(const void* data, int data_size, ImU32 seed = 0); // Pass data_size==0 for zero-terminated strings IMGUI_API void* ImFileLoadToMemory(const char* filename, const char* file_open_mode, int* out_file_size = NULL, int padding_bytes = 0); -IMGUI_API FILE* ImFileOpen(const char* filename, const char* file_open_mode); -IMGUI_API bool ImTriangleContainsPoint(ImVec2 a, ImVec2 b, ImVec2 c, ImVec2 p); -IMGUI_API void ImTriangleBarycentricCoords(ImVec2 a, ImVec2 b, ImVec2 c, ImVec2 p, float& out_u, float& out_v, float& out_w); +IMGUI_API FILE* ImFileOpen(const char* filename, const char* file_open_mode); static inline bool ImCharIsSpace(int c) { return c == ' ' || c == '\t' || c == 0x3000; } static inline bool ImIsPowerOfTwo(int v) { return v != 0 && (v & (v - 1)) == 0; } static inline int ImUpperPowerOfTwo(int v) { v--; v |= v >> 1; v |= v >> 2; v |= v >> 4; v |= v >> 8; v |= v >> 16; v++; return v; } +// Helpers: Geometry +IMGUI_API ImVec2 ImLineClosestPoint(const ImVec2& a, const ImVec2& b, const ImVec2& p); +IMGUI_API bool ImTriangleContainsPoint(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p); +IMGUI_API ImVec2 ImTriangleClosestPoint(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p); +IMGUI_API void ImTriangleBarycentricCoords(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p, float& out_u, float& out_v, float& out_w); + // Helpers: String IMGUI_API int ImStricmp(const char* str1, const char* str2); IMGUI_API int ImStrnicmp(const char* str1, const char* str2, int count); From f6460970c50ae359e68fe832aa49478b47cc123d Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 31 Jul 2017 21:20:42 +0800 Subject: [PATCH 172/921] ColorPicker: Hue wheel + SV triangle picker mode (mode selection flags still wip, missing context menu and persistent options). (#346) --- imgui.cpp | 113 ++++++++++++++++++++++++++++++++++++++++++++++++- imgui.h | 5 ++- imgui_demo.cpp | 10 ++--- 3 files changed, 120 insertions(+), 8 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 3aa543918..00bfe5572 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1013,7 +1013,6 @@ const char* ImStristr(const char* haystack, const char* haystack_end, const char return NULL; } - // MSVC version appears to return -1 on overflow, whereas glibc appears to return total count (which may be >= buf_size). // Ideally we would test for only one of those limits at runtime depending on the behavior the vsnprintf(), but trying to deduct it at compile time sounds like a pandora can of worm. int ImFormatString(char* buf, int buf_size, const char* fmt, ...) @@ -9401,6 +9400,21 @@ static void RenderArrowsForVerticalBar(ImDrawList* draw_list, ImVec2 pos, ImVec2 RenderArrow(draw_list, ImVec2(pos.x + bar_w - half_sz.x, pos.y), half_sz, ImGuiDir_Left, IM_COL32_WHITE); } +static void PaintVertsLinearGradientKeepAlpha(ImDrawVert* vert_start, ImDrawVert* vert_end, ImVec2 gradient_p0, ImVec2 gradient_p1, ImU32 col0, ImU32 col1) +{ + ImVec2 gradient_extent = gradient_p1 - gradient_p0; + float gradient_inv_length = ImInvLength(gradient_extent, 0.0f); + for (ImDrawVert* vert = vert_start; vert < vert_end; vert++) + { + float d = ImDot(vert->pos - gradient_p0, gradient_extent); + float t = ImMin(sqrtf(ImMax(d, 0.0f)) * gradient_inv_length, 1.0f); + int r = ImLerp((int)(col0 >> IM_COL32_R_SHIFT) & 0xFF, (int)(col1 >> IM_COL32_R_SHIFT) & 0xFF, t); + int g = ImLerp((int)(col0 >> IM_COL32_G_SHIFT) & 0xFF, (int)(col1 >> IM_COL32_G_SHIFT) & 0xFF, t); + int b = ImLerp((int)(col0 >> IM_COL32_B_SHIFT) & 0xFF, (int)(col1 >> IM_COL32_B_SHIFT) & 0xFF, t); + vert->col = (r << IM_COL32_R_SHIFT) | (g << IM_COL32_G_SHIFT) | (b << IM_COL32_B_SHIFT) | (vert->col & IM_COL32_A_MASK); + } +} + // ColorPicker // Note: only access 3 floats if ImGuiColorEditFlags_NoAlpha flag is set. // FIXME: we adjust the big color square height based on item width, which may cause a flickering feedback loop (if automatic height makes a vertical scrollbar appears, affecting automatic width..) @@ -9428,13 +9442,63 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl float bar1_pos_x = bar0_pos_x + bars_width + style.ItemInnerSpacing.x; float bars_triangles_half_sz = (float)(int)(bars_width * 0.20f); + float wheel_thickness = sv_picker_size * 0.08f; + float wheel_r_outer = sv_picker_size * 0.50f; + float wheel_r_inner = wheel_r_outer - wheel_thickness; + ImVec2 wheel_center(picker_pos.x + (sv_picker_size + bars_width)*0.5f, picker_pos.y + sv_picker_size*0.5f); + + // Note: the triangle is displayed rotated with triangle_pa pointing to Hue, but most coordinates stays unrotated for logic. + float triangle_r = wheel_r_inner - (int)(sv_picker_size * 0.027f); + ImVec2 triangle_pa = ImVec2(triangle_r, 0.0f); // Hue point. + ImVec2 triangle_pb = ImVec2(triangle_r * -0.5f, triangle_r * -0.866025f); // Black point. + ImVec2 triangle_pc = ImVec2(triangle_r * -0.5f, triangle_r * +0.866025f); // White point. + float H,S,V; ColorConvertRGBtoHSV(col[0], col[1], col[2], H, S, V); - // Color matrix logic + // Defaults to Hue bar + SV rectangle // FIXME-WIP + if ((flags & ImGuiColorEditFlags_PickerModeMask_) == 0) + flags |= ImGuiColorEditFlags_PickerHueBar; + IM_ASSERT(ImIsPowerOfTwo((int)(flags & ImGuiColorEditFlags_PickerModeMask_))); // Check that only 1 is selected + bool value_changed = false, value_changed_h = false, value_changed_sv = false; + if (flags & ImGuiColorEditFlags_PickerHueWheel) { + // Hue wheel + SV triangle logic + InvisibleButton("hsv", ImVec2(sv_picker_size + style.ItemInnerSpacing.x + bars_width, sv_picker_size)); + if (IsItemActive()) + { + ImVec2 initial_off = g.IO.MouseClickedPos[0] - wheel_center; + ImVec2 current_off = g.IO.MousePos - wheel_center; + float initial_dist2 = ImLengthSqr(initial_off); + if (initial_dist2 >= (wheel_r_inner-1)*(wheel_r_inner-1) && initial_dist2 <= (wheel_r_outer+1)*(wheel_r_outer+1)) + { + // Interactive with Hue wheel + H = atan2f(current_off.y, current_off.x) / IM_PI*0.5f; + if (H < 0.0f) + H += 1.0f; + value_changed = value_changed_h = true; + } + float cos_hue_angle = cosf(-H * 2.0f * IM_PI); + float sin_hue_angle = sinf(-H * 2.0f * IM_PI); + if (ImTriangleContainsPoint(triangle_pa, triangle_pb, triangle_pc, ImRotate(initial_off, cos_hue_angle, sin_hue_angle))) + { + // Interacting with SV triangle + ImVec2 current_off_unrotated = ImRotate(current_off, cos_hue_angle, sin_hue_angle); + if (!ImTriangleContainsPoint(triangle_pa, triangle_pb, triangle_pc, current_off_unrotated)) + current_off_unrotated = ImTriangleClosestPoint(triangle_pa, triangle_pb, triangle_pc, current_off_unrotated); + float uu, vv, ww; + ImTriangleBarycentricCoords(triangle_pa, triangle_pb, triangle_pc, current_off_unrotated, uu, vv, ww); + V = ImClamp(1.0f - vv, 0.0001f, 1.0f); + S = ImClamp(uu / V, 0.0001f, 1.0f); + value_changed = value_changed_sv = true; + } + } + } + else if (flags & ImGuiColorEditFlags_PickerHueBar) + { + // SV rectangle logic InvisibleButton("sv", ImVec2(sv_picker_size, sv_picker_size)); if (IsItemActive()) { @@ -9546,6 +9610,51 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl const ImU32 hue_colors[6+1] = { IM_COL32(255,0,0,255), IM_COL32(255,255,0,255), IM_COL32(0,255,0,255), IM_COL32(0,255,255,255), IM_COL32(0,0,255,255), IM_COL32(255,0,255,255), IM_COL32(255,0,0,255) }; ImVec2 sv_cursor_pos; + if (flags & ImGuiColorEditFlags_PickerHueWheel) + { + // Render Hue Wheel + const float aeps = 1.5f / wheel_r_outer; // Half a pixel arc length in radians (2pi cancels out). + const int segment_per_arc = ImMax(4, (int)wheel_r_outer / 12); + for (int n = 0; n < 6; n++) + { + const float a0 = (n) /6.0f * 2.0f * IM_PI - aeps; + const float a1 = (n+1.0f)/6.0f * 2.0f * IM_PI + aeps; + int vert_start_idx = draw_list->_VtxCurrentIdx; + draw_list->PathArcTo(wheel_center, (wheel_r_inner + wheel_r_outer)*0.5f, a0, a1, segment_per_arc); + draw_list->PathStroke(IM_COL32_WHITE, false, wheel_thickness); + + // Paint colors over existing vertices + ImVec2 gradient_p0(wheel_center.x + cosf(a0) * wheel_r_inner, wheel_center.y + sinf(a0) * wheel_r_inner); + ImVec2 gradient_p1(wheel_center.x + cosf(a1) * wheel_r_inner, wheel_center.y + sinf(a1) * wheel_r_inner); + PaintVertsLinearGradientKeepAlpha(draw_list->_VtxWritePtr - (draw_list->_VtxCurrentIdx - vert_start_idx), draw_list->_VtxWritePtr, gradient_p0, gradient_p1, hue_colors[n], hue_colors[n+1]); + } + + // Render Cursor + preview on Hue Wheel + float cos_hue_angle = cosf(H * 2.0f * IM_PI); + float sin_hue_angle = sinf(H * 2.0f * IM_PI); + ImVec2 hue_cursor_pos(wheel_center.x + cos_hue_angle * (wheel_r_inner+wheel_r_outer)*0.5f, wheel_center.y + sin_hue_angle * (wheel_r_inner+wheel_r_outer)*0.5f); + float hue_cursor_rad = value_changed_h ? wheel_thickness * 0.65f : wheel_thickness * 0.55f; + int hue_cursor_segments = ImClamp((int)(hue_cursor_rad / 1.4f), 9, 32); + draw_list->AddCircleFilled(hue_cursor_pos, hue_cursor_rad, hue_color32, hue_cursor_segments); + draw_list->AddCircle(hue_cursor_pos, hue_cursor_rad+1, IM_COL32(128,128,128,255), hue_cursor_segments); + draw_list->AddCircle(hue_cursor_pos, hue_cursor_rad, IM_COL32_WHITE, hue_cursor_segments); + + // Render SV triangle (rotated according to hue) + ImVec2 tra = wheel_center + ImRotate(triangle_pa, cos_hue_angle, sin_hue_angle); + ImVec2 trb = wheel_center + ImRotate(triangle_pb, cos_hue_angle, sin_hue_angle); + ImVec2 trc = wheel_center + ImRotate(triangle_pc, cos_hue_angle, sin_hue_angle); + ImVec2 uv_white = g.FontTexUvWhitePixel; + draw_list->PrimReserve(6, 6); + draw_list->PrimVtx(tra, uv_white, hue_color32); + draw_list->PrimVtx(trb, uv_white, hue_color32); + draw_list->PrimVtx(trc, uv_white, IM_COL32_WHITE); + draw_list->PrimVtx(tra, uv_white, IM_COL32_BLACK_TRANS); + draw_list->PrimVtx(trb, uv_white, IM_COL32_BLACK); + draw_list->PrimVtx(trc, uv_white, IM_COL32_BLACK_TRANS); + draw_list->AddTriangle(tra, trb, trc, IM_COL32(128,128,128,255), 1.5f); + sv_cursor_pos = ImLerp(ImLerp(trc, tra, ImSaturate(S)), trb, ImSaturate(1 - V)); + } + else if (flags & ImGuiColorEditFlags_PickerHueBar) { // Render SV Square draw_list->AddRectFilledMultiColor(picker_pos, picker_pos + ImVec2(sv_picker_size,sv_picker_size), IM_COL32_WHITE, hue_color32, hue_color32, IM_COL32_WHITE); diff --git a/imgui.h b/imgui.h index c7c367fc3..fd52468ba 100644 --- a/imgui.h +++ b/imgui.h @@ -673,14 +673,17 @@ enum ImGuiColorEditFlags_ ImGuiColorEditFlags_AlphaPreview = 1 << 7, // ColorEdit, ColorPicker, ColorButton: display preview as a transparent color over a checkerboard, instead of opaque. ImGuiColorEditFlags_AlphaPreviewHalf= 1 << 8, // ColorEdit, ColorPicker, ColorButton: display half opaque / half checkerboard, instead of opaque. ImGuiColorEditFlags_NoAlpha = 1 << 9, // ColorEdit, ColorPicker, ColorButton: completely ignore Alpha component (read 3 components from the input pointer). - ImGuiColorEditFlags_NoPicker = 1 << 10, // ColorEdit: disable picker when clicking on colored square. + ImGuiColorEditFlags_NoPicker = 1 << 10, // ColorEdit: disable picker when clicking on colored square. ImGuiColorEditFlags_NoOptions = 1 << 11, // ColorEdit: disable toggling options menu when right-clicking on inputs/small preview. ImGuiColorEditFlags_NoSmallPreview = 1 << 12, // ColorEdit, ColorPicker: disable colored square preview next to the inputs. (e.g. to show only the inputs) ImGuiColorEditFlags_NoInputs = 1 << 13, // ColorEdit, ColorPicker: disable inputs sliders/text widgets (e.g. to show only the small preview colored square). ImGuiColorEditFlags_NoTooltip = 1 << 14, // ColorEdit, ColorPicker, ColorButton: disable tooltip when hovering the preview. ImGuiColorEditFlags_NoLabel = 1 << 15, // ColorEdit, ColorPicker: disable display of inline text label (the label is still forwarded to the tooltip and picker). ImGuiColorEditFlags_NoSidePreview = 1 << 16, // ColorPicker: disable bigger color preview on right side of the picker, use small colored square preview instead. + ImGuiColorEditFlags_PickerHueWheel = 1 << 17, // [WIP] ColorPicker: wheel for Hue, triangle for SV + ImGuiColorEditFlags_PickerHueBar = 1 << 18, // [WIP] ColorPicker: bar for Hue, rectangle for SV ImGuiColorEditFlags_InputsModeMask_ = ImGuiColorEditFlags_RGB|ImGuiColorEditFlags_HSV|ImGuiColorEditFlags_HEX, + ImGuiColorEditFlags_PickerModeMask_ = ImGuiColorEditFlags_PickerHueWheel|ImGuiColorEditFlags_PickerHueBar, ImGuiColorEditFlags_StoredMask_ = ImGuiColorEditFlags_RGB|ImGuiColorEditFlags_HSV|ImGuiColorEditFlags_HEX|ImGuiColorEditFlags_Float }; diff --git a/imgui_demo.cpp b/imgui_demo.cpp index ddf30eeab..a3acd7856 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -737,7 +737,7 @@ void ImGui::ShowTestWindow(bool* p_open) static bool ref_color = false; static ImVec4 ref_color_v(1.0f,0.0f,1.0f,0.5f); static int inputs_mode = 2; - static float width = 200.0f; + static int picker_mode = 0; ImGui::Checkbox("With Alpha", &alpha); ImGui::Checkbox("With Alpha Bar", &alpha_bar); ImGui::Checkbox("With Side Preview", &side_preview); @@ -750,20 +750,20 @@ void ImGui::ShowTestWindow(bool* p_open) ImGui::ColorEdit4("##RefColor", &ref_color_v.x, ImGuiColorEditFlags_NoInputs | misc_flags); } } - ImGui::Combo("Mode", &inputs_mode, "All Inputs\0No Inputs\0RGB Input\0HSV Input\0HEX Input\0"); + ImGui::Combo("Inputs Mode", &inputs_mode, "All Inputs\0No Inputs\0RGB Input\0HSV Input\0HEX Input\0"); + ImGui::Combo("Picker Mode", &picker_mode, "Hue bar + SV rect\0Hue wheel + SV triangle\0"); ImGui::SameLine(); ShowHelpMarker("User can right-click the inputs and override edit mode."); - //ImGui::DragFloat("Width", &width, 1.0f, 1.0f, 999.0f); - //ImGui::PushItemWidth(width); ImGuiColorEditFlags flags = misc_flags; if (!alpha) flags |= ImGuiColorEditFlags_NoAlpha; // This is by default if you call ColorPicker3() instead of ColorPicker4() if (alpha_bar) flags |= ImGuiColorEditFlags_AlphaBar; if (!side_preview) flags |= ImGuiColorEditFlags_NoSidePreview; + if (picker_mode == 0) flags |= ImGuiColorEditFlags_PickerHueBar; + if (picker_mode == 1) flags |= ImGuiColorEditFlags_PickerHueWheel; if (inputs_mode == 1) flags |= ImGuiColorEditFlags_NoInputs; if (inputs_mode == 2) flags |= ImGuiColorEditFlags_RGB; if (inputs_mode == 3) flags |= ImGuiColorEditFlags_HSV; if (inputs_mode == 4) flags |= ImGuiColorEditFlags_HEX; ImGui::ColorPicker4("MyColor##4", (float*)&color, flags, ref_color ? &ref_color_v.x : NULL); - //ImGui::PopItemWidth(); ImGui::TreePop(); } From 40ac84d701abc57e57c36f4710779a8d8bf80fce Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 3 Aug 2017 16:41:29 +0800 Subject: [PATCH 173/921] DataTypeApplyOpFromText: renamed local variables + comments to avoid confusion about the fact that int and float paths are not totally symetrical. (#671) --- imgui.cpp | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 7ca66c79f..8db2b250c 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -6369,16 +6369,16 @@ static bool DataTypeApplyOpFromText(const char* buf, const char* initial_value_b scalar_format = "%d"; int* v = (int*)data_ptr; const int old_v = *v; - int arg0 = *v; - if (op && sscanf(initial_value_buf, scalar_format, &arg0) < 1) + int arg0i = *v; + if (op && sscanf(initial_value_buf, scalar_format, &arg0i) < 1) return false; // Store operand in a float so we can use fractional value for multipliers (*1.1), but constant always parsed as integer so we can fit big integers (e.g. 2000000003) past float precision - float arg1 = 0.0f; - if (op == '+') { if (sscanf(buf, "%f", &arg1) == 1) *v = (int)(arg0 + arg1); } // Add (use "+-" to subtract) - else if (op == '*') { if (sscanf(buf, "%f", &arg1) == 1) *v = (int)(arg0 * arg1); } // Multiply - else if (op == '/') { if (sscanf(buf, "%f", &arg1) == 1 && arg1 != 0.0f) *v = (int)(arg0 / arg1); }// Divide - else { if (sscanf(buf, scalar_format, &arg0) == 1) *v = arg0; } // Assign constant + float arg1f = 0.0f; + if (op == '+') { if (sscanf(buf, "%f", &arg1f) == 1) *v = (int)(arg0i + arg1f); } // Add (use "+-" to subtract) + else if (op == '*') { if (sscanf(buf, "%f", &arg1f) == 1) *v = (int)(arg0i * arg1f); } // Multiply + else if (op == '/') { if (sscanf(buf, "%f", &arg1f) == 1 && arg1f != 0.0f) *v = (int)(arg0i / arg1f); }// Divide + else { if (sscanf(buf, scalar_format, &arg0i) == 1) *v = arg0i; } // Assign constant (read as integer so big values are not lossy) return (old_v != *v); } else if (data_type == ImGuiDataType_Float) @@ -6387,17 +6387,17 @@ static bool DataTypeApplyOpFromText(const char* buf, const char* initial_value_b scalar_format = "%f"; float* v = (float*)data_ptr; const float old_v = *v; - float arg0 = *v; - if (op && sscanf(initial_value_buf, scalar_format, &arg0) < 1) + float arg0f = *v; + if (op && sscanf(initial_value_buf, scalar_format, &arg0f) < 1) return false; - float arg1 = 0.0f; - if (sscanf(buf, scalar_format, &arg1) < 1) + float arg1f = 0.0f; + if (sscanf(buf, scalar_format, &arg1f) < 1) return false; - if (op == '+') { *v = arg0 + arg1; } // Add (use "+-" to subtract) - else if (op == '*') { *v = arg0 * arg1; } // Multiply - else if (op == '/') { if (arg1 != 0.0f) *v = arg0 / arg1; } // Divide - else { *v = arg1; } // Assign constant + if (op == '+') { *v = arg0f + arg1f; } // Add (use "+-" to subtract) + else if (op == '*') { *v = arg0f * arg1f; } // Multiply + else if (op == '/') { if (arg1f != 0.0f) *v = arg0f / arg1f; } // Divide + else { *v = arg1f; } // Assign constant return (old_v != *v); } From 95f2706d1cc04ce9c1fbab3f171954762f755fff Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 5 Aug 2017 16:05:48 +0800 Subject: [PATCH 174/921] Clipboard: [windows] Fixed not closing win32 clipboard on early return. (#1264) --- imgui.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/imgui.cpp b/imgui.cpp index 8db2b250c..9d3cb1ba7 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9655,7 +9655,10 @@ static const char* GetClipboardTextFn_DefaultImpl(void*) return NULL; HANDLE wbuf_handle = GetClipboardData(CF_UNICODETEXT); if (wbuf_handle == NULL) + { + CloseClipboard(); return NULL; + } if (ImWchar* wbuf_global = (ImWchar*)GlobalLock(wbuf_handle)) { int buf_len = ImTextCountUtf8BytesFromStr(wbuf_global, NULL) + 1; From d762f1dbfb6faa72561c5069a4fc1b2685965ed4 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 5 Aug 2017 19:15:03 +0800 Subject: [PATCH 175/921] Comments, clarification about io.WantCaptureMouse, io.WantCaptureKeyboard flags timing and NewFrame(). (#1262) --- imgui.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 9d3cb1ba7..6eb9153c5 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -141,8 +141,9 @@ SwapBuffers(); } - - You can read back 'io.WantCaptureMouse', 'io.WantCaptureKeybord' etc. flags from the IO structure to tell how ImGui intends to use your - inputs and to know if you should share them or hide them from the rest of your application. Read the FAQ below for more information. + - When calling NewFrame(), the 'io.WantCaptureMouse'/'io.WantCaptureKeyboard'/'io.WantTextInput' flags are updated. + They tell you if ImGui intends to use your inputs. So for example, if 'io.WantCaptureMouse' is set you would typically want to hide + mouse inputs from the rest of your application. Read the FAQ below for more information about those flags. API BREAKING CHANGES @@ -397,11 +398,13 @@ 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 can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application? - A: You can read the 'io.WantCaptureXXX' flags in the ImGuiIO structure. Preferably read them after calling ImGui::NewFrame() to avoid those flags lagging by one frame, but either should be fine. - When 'io.WantCaptureMouse' or 'io.WantCaptureKeyboard' flags are set you may want to discard/hide the inputs from the rest of your application. - When 'io.WantInputsCharacters' is set to may want to notify your OS to popup an on-screen keyboard, if available. - ImGui is tracking dragging and widget activity that may occur outside the boundary of a window, so 'io.WantCaptureMouse' is a more accurate and complete than testing for ImGui::IsMouseHoveringAnyWindow(). - (Advanced note: text input releases focus on Return 'KeyDown', so the following Return 'KeyUp' event that your application receive will typically have 'io.WantcaptureKeyboard=false'. + A: You can read the 'io.WantCaptureMouse'/'io.WantCaptureKeyboard'/'ioWantTextInput' flags from the ImGuiIO structure. + - When 'io.WantCaptureMouse' or 'io.WantCaptureKeyboard' flags are set you may want to discard/hide the inputs from the rest of your application. + - When 'io.WantTextInput' is set to may want to notify your OS to popup an on-screen keyboard, if available (e.g. on a mobile phone, or console without a keyboard). + Preferably read the flags after calling ImGui::NewFrame() to avoid them lagging by one frame. But reading those flags before calling NewFrame() is also generally ok, + as the bool toggles fairly rarely and you don't generally expect to interact with either ImGui or your application during the same frame when that transition occurs. + ImGui is tracking dragging and widget activity that may occur outside the boundary of a window, so 'io.WantCaptureMouse' is more accurate and correct than checking if a window is hovered. + (Advanced note: text input releases focus on Return 'KeyDown', so the following Return 'KeyUp' event that your application receive will typically have 'io.WantCaptureKeyboard=false'. Depending on your application logic it may or not be inconvenient. You might want to track which key-downs were for ImGui (e.g. with an array of bool) and filter out the corresponding key-ups.) Q: How can I load a different font than the default? (default is an embedded version of ProggyClean.ttf, rendered at size 13) From 46c73cccff45ca60232c9578ab0182c0603dfb8d Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 5 Aug 2017 19:47:52 +0800 Subject: [PATCH 176/921] Popups window can be moved (if they don't have explicit positions provided by user, or e.g. sub-menu popup) (#1252) --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 6eb9153c5..2307e66a4 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3547,7 +3547,7 @@ static bool BeginPopupEx(const char* str_id, ImGuiWindowFlags extra_flags) } ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); - ImGuiWindowFlags flags = extra_flags|ImGuiWindowFlags_Popup|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_AlwaysAutoResize; + ImGuiWindowFlags flags = extra_flags|ImGuiWindowFlags_Popup|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_AlwaysAutoResize; char name[20]; if (flags & ImGuiWindowFlags_ChildMenu) From cdea8ca94fffbbc32fabfd1b0f8789b125384486 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 6 Aug 2017 11:07:52 +0800 Subject: [PATCH 177/921] Demo: Comment about 'static' and some tweaks (#1267) --- imgui_demo.cpp | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index f2d03396c..b248a6458 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -6,14 +6,18 @@ // Everything in this file will be stripped out by the linker if you don't call ImGui::ShowTestWindow(). // During development, you can call ImGui::ShowTestWindow() in your code to learn about various features of ImGui. Have it wired in a debug menu! // Removing this file from your project is hindering access to documentation for everyone in your team, likely leading you to poorer usage of the library. - // Note that you can #define IMGUI_DISABLE_TEST_WINDOWS in imconfig.h for the same effect. // If you want to link core ImGui in your public builds but not those test windows, #define IMGUI_DISABLE_TEST_WINDOWS in imconfig.h and those functions will be empty. // For any other case, if you have ImGui available you probably want this to be available for reference and execution. - // Thank you, // -Your beloved friend, imgui_demo.cpp (that you won't delete) +// Message to beginner C/C++ programmer about the meaning of 'static': in this demo code, we frequently we use 'static' variables inside functions. +// We do this as a way to gather code and data in the same place, make the demo code faster to read, faster to write, and smaller. A static variable persist across calls, +// so it is essentially like a global variable but declared inside the scope of the function. +// It also happens to be a convenient way of storing simple UI related information as long as your function doesn't need to be reentrant or used in threads. +// This may be a pattern you want to use in your code (simple is beautiful!), but most of the real data you would be editing is likely to be stored outside your function. + #if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) #define _CRT_SECURE_NO_WARNINGS #endif @@ -538,9 +542,13 @@ void ImGui::ShowTestWindow(bool* p_open) ImGui::TreePop(); } - static bool a=false; - if (ImGui::Button("Button")) { printf("Clicked\n"); a ^= 1; } - if (a) + static bool my_toggle = false; + if (ImGui::Button("Button")) + { + printf("Clicked\n"); + my_toggle = !my_toggle; + } + if (my_toggle) { ImGui::SameLine(); ImGui::Text("Thanks for clicking me!"); From f4c0134f9f62cd6ebbfec9690e98580d24559238 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 6 Aug 2017 18:08:58 +0800 Subject: [PATCH 178/921] Moved ColorEdit, ColorPicker declaration in their own section of imgui.h, minor comments adjustment (#346) --- imgui.h | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/imgui.h b/imgui.h index fd52468ba..cec6e26bd 100644 --- a/imgui.h +++ b/imgui.h @@ -245,7 +245,7 @@ namespace ImGui IMGUI_API void PushID(const void* ptr_id); IMGUI_API void PushID(int int_id); IMGUI_API void PopID(); - IMGUI_API ImGuiID GetID(const char* str_id); // calculate unique ID (hash of whole ID stack + given parameter). useful if you want to query into ImGuiStorage yourself. otherwise rarely needed + IMGUI_API ImGuiID GetID(const char* str_id); // calculate unique ID (hash of whole ID stack + given parameter). useful if you want to query into ImGuiStorage yourself IMGUI_API ImGuiID GetID(const char* str_id_begin, const char* str_id_end); IMGUI_API ImGuiID GetID(const void* ptr_id); @@ -276,11 +276,6 @@ namespace ImGui IMGUI_API bool Combo(const char* label, int* current_item, const char* const* items, int items_count, int height_in_items = -1); IMGUI_API bool Combo(const char* label, int* current_item, const char* items_separated_by_zeros, int height_in_items = -1); // separate items with \0, end item-list with \0\0 IMGUI_API bool Combo(const char* label, int* current_item, bool (*items_getter)(void* data, int idx, const char** out_text), void* data, int items_count, int height_in_items = -1); - IMGUI_API bool ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFlags flags = 0, ImVec2 size = ImVec2(0,0)); // display a colored square/button, hover for details, return true when pressed. - IMGUI_API bool ColorEdit3(const char* label, float col[3], ImGuiColorEditFlags flags = 0); // 3-4 components color edition. click on colored squared to open a color picker, right-click for options. Hint: 'float col[3]' function argument is same as 'float* col'. You can pass address of first element out of a contiguous structure, e.g. &myvector.x - IMGUI_API bool ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flags = 0); - IMGUI_API bool ColorPicker3(const char* label, float col[3], ImGuiColorEditFlags flags = 0); - IMGUI_API bool ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags flags = 0, const float* ref_col = NULL); IMGUI_API void PlotLines(const char* label, const float* values, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0,0), int stride = sizeof(float)); IMGUI_API void PlotLines(const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0,0)); IMGUI_API void PlotHistogram(const char* label, const float* values, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0,0), int stride = sizeof(float)); @@ -288,7 +283,7 @@ namespace ImGui IMGUI_API void ProgressBar(float fraction, const ImVec2& size_arg = ImVec2(-1,0), const char* overlay = NULL); // Widgets: Drags (tip: ctrl+click on a drag box to input with keyboard. manually input values aren't clamped, can go off-bounds) - // For all the Float2/Float3/Float4/Int2/Int3/Int4 versions of every functions, remember than a 'float v[3]' function argument is the same as 'float* v'. You can pass address of your first element out of a contiguous set, e.g. &myvector.x + // For all the Float2/Float3/Float4/Int2/Int3/Int4 versions of every functions, note that a 'float v[X]' function argument is the same as 'float* v', the array syntax is just a way to document the number of elements that are expected to be accessible. You can pass address of your first element out of a contiguous set, e.g. &myvector.x 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); @@ -313,7 +308,7 @@ namespace ImGui IMGUI_API bool InputInt4(const char* label, int v[4], ImGuiInputTextFlags extra_flags = 0); // Widgets: Sliders (tip: ctrl+click on a slider to input with keyboard. manually input values aren't clamped, can go off-bounds) - IMGUI_API bool SliderFloat(const char* label, float* v, float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f); // adjust display_format to decorate the value with a prefix or a suffix. Use power!=1.0 for logarithmic sliders + IMGUI_API bool SliderFloat(const char* label, float* v, float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f); // adjust display_format to decorate the value with a prefix or a suffix for in-slider labels or unit display. Use power!=1.0 for logarithmic sliders IMGUI_API bool SliderFloat2(const char* label, float v[2], float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f); IMGUI_API bool SliderFloat3(const char* label, float v[3], float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f); IMGUI_API bool SliderFloat4(const char* label, float v[4], float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f); @@ -325,6 +320,14 @@ namespace ImGui IMGUI_API bool VSliderFloat(const char* label, const ImVec2& size, float* v, float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f); IMGUI_API bool VSliderInt(const char* label, const ImVec2& size, int* v, int v_min, int v_max, const char* display_format = "%.0f"); + // Widgets: Color Editor/Picker (tip: the ColorEdit* functions have a little colored preview square that can be left-clicked to open a picker, and right-clicked to open an option menu.) + // Note that a 'float v[X]' function argument is the same as 'float* v', the array syntax is just a way to document the number of elements that are expected to be accessible. You can the pass the address of a first float element out of a contiguous structure, e.g. &myvector.x + IMGUI_API bool ColorEdit3(const char* label, float col[3], ImGuiColorEditFlags flags = 0); + IMGUI_API bool ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flags = 0); + IMGUI_API bool ColorPicker3(const char* label, float col[3], ImGuiColorEditFlags flags = 0); + IMGUI_API bool ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags flags = 0, const float* ref_col = NULL); + IMGUI_API bool ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFlags flags = 0, ImVec2 size = ImVec2(0,0)); // display a colored square/button, hover for details, return true when pressed. + // Widgets: Trees IMGUI_API bool TreeNode(const char* label); // if returning 'true' the node is open and the tree id is pushed into the id stack. user is responsible for calling TreePop(). IMGUI_API bool TreeNode(const char* str_id, const char* fmt, ...) IM_PRINTFARGS(2); // read the FAQ about why and how to use ID. to align arbitrary text at the same level as a TreeNode() you can use Bullet(). @@ -451,7 +454,7 @@ namespace ImGui IMGUI_API ImVec2 GetMousePosOnOpeningCurrentPopup(); // retrieve backup of mouse positioning at the time of opening popup we have BeginPopup() into IMGUI_API ImVec2 GetMouseDragDelta(int button = 0, float lock_threshold = -1.0f); // dragging amount since clicking. if lock_threshold < -1.0f uses io.MouseDraggingThreshold IMGUI_API void ResetMouseDragDelta(int button = 0); // - IMGUI_API ImGuiMouseCursor GetMouseCursor(); // get desired cursor type, reset in ImGui::NewFrame(), this updated during the frame. valid before Render(). If you use software rendering by setting io.MouseDrawCursor ImGui will render those for you + IMGUI_API ImGuiMouseCursor GetMouseCursor(); // get desired cursor type, reset in ImGui::NewFrame(), this is updated during the frame. valid before Render(). If you use software rendering by setting io.MouseDrawCursor ImGui will render those for you IMGUI_API void SetMouseCursor(ImGuiMouseCursor type); // set desired cursor type IMGUI_API void CaptureKeyboardFromApp(bool capture = true); // manually override io.WantCaptureKeyboard flag next frame (said flag is entirely left for your application handle). e.g. force capture keyboard when your widget is being hovered. IMGUI_API void CaptureMouseFromApp(bool capture = true); // manually override io.WantCaptureMouse flag next frame (said flag is entirely left for your application handle). From 6d60e0fc58a5adefc1ed0cfd3a54ce7eca6471c2 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 7 Aug 2017 15:21:21 +0800 Subject: [PATCH 179/921] Fonts readme tweaks, links --- extra_fonts/README.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/extra_fonts/README.txt b/extra_fonts/README.txt index 8df8340a8..82bc557a7 100644 --- a/extra_fonts/README.txt +++ b/extra_fonts/README.txt @@ -18,8 +18,9 @@ io.Fonts->AddFontDefault(); ImFontConfig config; config.MergeMode = true; - const ImWchar icon_ranges[] = { ICON_MIN_FA, ICON_MAX_FA, 0 }; + static const ImWchar icon_ranges[] = { ICON_MIN_FA, ICON_MAX_FA, 0 }; io.Fonts->AddFontFromFileTTF("fonts/fontawesome-webfont.ttf", 13.0f, &config, icon_ranges); + // Usage, e.g. ImGui::Text("%s Search", ICON_FA_SEARCH); @@ -153,6 +154,9 @@ https://github.com/SamBrishes/kenney-icon-font https://design.google.com/icons/ + IcoMoon - Custom Icon font builder + https://icomoon.io/app + Typefaces for source code beautification https://github.com/chrissimpkins/codeface From 233a6efeba627498ef1ff0150eb52a3a450caea4 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 7 Aug 2017 18:35:15 +0800 Subject: [PATCH 180/921] Fixed GetScrollMaxX(), GetScrollMaxY(). Tweak demo to display more data. Using functions in Begin(). (#1271) --- imgui.cpp | 9 ++++++--- imgui_demo.cpp | 16 ++++++++++------ 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 2307e66a4..a40b89ed9 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4205,7 +4205,10 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us } window->Scroll = ImMax(window->Scroll, ImVec2(0.0f, 0.0f)); if (!window->Collapsed && !window->SkipItems) - window->Scroll = ImMin(window->Scroll, ImMax(ImVec2(0.0f, 0.0f), window->SizeContents - window->SizeFull + window->ScrollbarSizes)); + { + window->Scroll.x = ImMin(window->Scroll.x, GetScrollMaxX()); + window->Scroll.y = ImMin(window->Scroll.y, GetScrollMaxY()); + } // Modal window darkens what is behind them if ((flags & ImGuiWindowFlags_Modal) != 0 && window == GetFrontMostModalRootWindow()) @@ -5267,13 +5270,13 @@ float ImGui::GetScrollY() float ImGui::GetScrollMaxX() { ImGuiWindow* window = GetCurrentWindowRead(); - return window->SizeContents.x - window->SizeFull.x - window->ScrollbarSizes.x; + return ImMax(0.0f, window->SizeContents.x - (window->SizeFull.x - window->ScrollbarSizes.x)); } float ImGui::GetScrollMaxY() { ImGuiWindow* window = GetCurrentWindowRead(); - return window->SizeContents.y - window->SizeFull.y - window->ScrollbarSizes.y; + return ImMax(0.0f, window->SizeContents.y - (window->SizeFull.y - window->ScrollbarSizes.y)); } void ImGui::SetScrollX(float scroll_x) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index b248a6458..72de7525f 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1097,9 +1097,9 @@ void ImGui::ShowTestWindow(bool* p_open) static int track_line = 50, scroll_to_px = 200; ImGui::Checkbox("Track", &track); ImGui::PushItemWidth(100); - ImGui::SameLine(130); track |= ImGui::DragInt("##line", &track_line, 0.25f, 0, 99, "Line %.0f"); - bool scroll_to = ImGui::Button("Scroll To"); - ImGui::SameLine(130); scroll_to |= ImGui::DragInt("##pos_y", &scroll_to_px, 1.00f, 0, 9999, "y = %.0f px"); + ImGui::SameLine(130); track |= ImGui::DragInt("##line", &track_line, 0.25f, 0, 99, "Line = %.0f"); + bool scroll_to = ImGui::Button("Scroll To Pos"); + ImGui::SameLine(130); scroll_to |= ImGui::DragInt("##pos_y", &scroll_to_px, 1.00f, 0, 9999, "Y = %.0f px"); ImGui::PopItemWidth(); if (scroll_to) track = false; @@ -1123,7 +1123,9 @@ void ImGui::ShowTestWindow(bool* p_open) ImGui::Text("Line %d", line); } } + float scroll_y = ImGui::GetScrollY(), scroll_max_y = ImGui::GetScrollMaxY(); ImGui::EndChild(); + ImGui::Text("%.0f/%0.f", scroll_y, scroll_max_y); ImGui::EndGroup(); } ImGui::TreePop(); @@ -1158,12 +1160,14 @@ void ImGui::ShowTestWindow(bool* p_open) ImGui::PopID(); } } + float scroll_x = ImGui::GetScrollX(), scroll_max_x = ImGui::GetScrollMaxX(); ImGui::EndChild(); ImGui::PopStyleVar(2); float scroll_x_delta = 0.0f; - ImGui::SmallButton("<<"); if (ImGui::IsItemActive()) scroll_x_delta = -ImGui::GetIO().DeltaTime * 1000.0f; - ImGui::SameLine(); ImGui::Text("Scroll from code"); ImGui::SameLine(); - ImGui::SmallButton(">>"); if (ImGui::IsItemActive()) scroll_x_delta = +ImGui::GetIO().DeltaTime * 1000.0f; + ImGui::SmallButton("<<"); if (ImGui::IsItemActive()) scroll_x_delta = -ImGui::GetIO().DeltaTime * 1000.0f; ImGui::SameLine(); + ImGui::Text("Scroll from code"); ImGui::SameLine(); + ImGui::SmallButton(">>"); if (ImGui::IsItemActive()) scroll_x_delta = +ImGui::GetIO().DeltaTime * 1000.0f; ImGui::SameLine(); + ImGui::Text("%.0f/%.0f", scroll_x, scroll_max_x); if (scroll_x_delta != 0.0f) { ImGui::BeginChild("scrolling"); // Demonstrate a trick: you can use Begin to set yourself in the context of another window (here we are already out of your child window) From 7096fd8500c87d777dbd70dc9c1cd381b35bae4d Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 7 Aug 2017 19:41:22 +0800 Subject: [PATCH 181/921] Fixes for Vertical Scrollbar not automatically getting enabled if enabled Horizontal Scrollbar straddle the vertical limit. (#1271, #246) --- imgui.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index a40b89ed9..694227e10 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4262,6 +4262,8 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us // Scrollbars window->ScrollbarY = (flags & ImGuiWindowFlags_AlwaysVerticalScrollbar) || ((window->SizeContents.y > window->Size.y + style.ItemSpacing.y) && !(flags & ImGuiWindowFlags_NoScrollbar)); window->ScrollbarX = (flags & ImGuiWindowFlags_AlwaysHorizontalScrollbar) || ((window->SizeContents.x > window->Size.x - (window->ScrollbarY ? style.ScrollbarSize : 0.0f) - window->WindowPadding.x) && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar)); + if (window->ScrollbarX && !window->ScrollbarY) + window->ScrollbarY = (window->SizeContents.y > window->Size.y + style.ItemSpacing.y - style.ScrollbarSize) && !(flags & ImGuiWindowFlags_NoScrollbar); window->ScrollbarSizes = ImVec2(window->ScrollbarY ? style.ScrollbarSize : 0.0f, window->ScrollbarX ? style.ScrollbarSize : 0.0f); window->BorderSize = (flags & ImGuiWindowFlags_ShowBorders) ? 1.0f : 0.0f; @@ -4510,10 +4512,10 @@ static void Scrollbar(ImGuiWindow* window, bool horizontal) // V denote the main axis of the scrollbar float scrollbar_size_v = horizontal ? bb.GetWidth() : bb.GetHeight(); float scroll_v = horizontal ? window->Scroll.x : window->Scroll.y; - float win_size_avail_v = (horizontal ? window->Size.x : window->Size.y) - other_scrollbar_size_w; + float win_size_avail_v = (horizontal ? window->SizeFull.x : window->SizeFull.y) - other_scrollbar_size_w; float win_size_contents_v = horizontal ? window->SizeContents.x : window->SizeContents.y; - // The grabable box size generally represent the amount visible (vs the total scrollable amount) + // The grabbable box size generally represent the amount visible (vs the total scrollable amount) // But we maintain a minimum size in pixel to allow for the user to still aim inside. const float grab_h_pixels = ImMin(ImMax(scrollbar_size_v * ImSaturate(win_size_avail_v / ImMax(win_size_contents_v, win_size_avail_v)), style.GrabMinSize), scrollbar_size_v); const float grab_h_norm = grab_h_pixels / scrollbar_size_v; @@ -5270,7 +5272,7 @@ float ImGui::GetScrollY() float ImGui::GetScrollMaxX() { ImGuiWindow* window = GetCurrentWindowRead(); - return ImMax(0.0f, window->SizeContents.x - (window->SizeFull.x - window->ScrollbarSizes.x)); + return ImMax(0.0f, window->SizeContents.x - (window->SizeFull.x - window->ScrollbarSizes.x) + 50); } float ImGui::GetScrollMaxY() From e36b41cbd0dc69c2bb4d6c3d1eb0d5fc3884652c Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 7 Aug 2017 21:53:57 +0800 Subject: [PATCH 182/921] Fixed Y scroll aiming when Horizontal Scrollbar is enabled (#665). Tweak log demo. --- imgui.cpp | 2 +- imgui_demo.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 694227e10..7d30e7887 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4200,7 +4200,7 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us if (window->ScrollTarget.y < FLT_MAX) { float center_ratio = window->ScrollTargetCenterRatio.y; - window->Scroll.y = window->ScrollTarget.y - ((1.0f - center_ratio) * (window->TitleBarHeight() + window->MenuBarHeight())) - (center_ratio * window->SizeFull.y); + window->Scroll.y = window->ScrollTarget.y - ((1.0f - center_ratio) * (window->TitleBarHeight() + window->MenuBarHeight())) - (center_ratio * (window->SizeFull.y - window->ScrollbarSizes.y)); window->ScrollTarget.y = FLT_MAX; } window->Scroll = ImMax(window->Scroll, ImVec2(0.0f, 0.0f)); diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 72de7525f..18697277e 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -2464,10 +2464,10 @@ static void ShowExampleAppLog(bool* p_open) { static ExampleAppLog log; - // Demo fill + // Demo: add random items (unless Ctrl is held) static float last_time = -1.0f; float time = ImGui::GetTime(); - if (time - last_time >= 0.3f) + if (time - last_time >= 0.20f && !ImGui::GetIO().KeyCtrl) { const char* random_words[] = { "system", "info", "warning", "error", "fatal", "notice", "log" }; log.AddLog("[%s] Hello, time is %.1f, rand() %d\n", random_words[rand() % IM_ARRAYSIZE(random_words)], time, (int)rand()); From d43c25d8f4ebb4413d24220dd28ebea75ab437bd Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 7 Aug 2017 21:54:41 +0800 Subject: [PATCH 183/921] SetScrollHere() tweak to make the code a little less confusing --- imgui.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 7d30e7887..174110262 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -5310,8 +5310,9 @@ void ImGui::SetScrollFromPosY(float pos_y, float center_y_ratio) void ImGui::SetScrollHere(float center_y_ratio) { ImGuiWindow* window = GetCurrentWindow(); - float target_y = window->DC.CursorPosPrevLine.y + (window->DC.PrevLineHeight * center_y_ratio) + (GImGui->Style.ItemSpacing.y * (center_y_ratio - 0.5f) * 2.0f); // Precisely aim above, in the middle or below the last line. - SetScrollFromPosY(target_y - window->Pos.y, center_y_ratio); + float target_y = window->DC.CursorPosPrevLine.y - window->Pos.y; // Top of last item, in window space + target_y += (window->DC.PrevLineHeight * center_y_ratio) + (GImGui->Style.ItemSpacing.y * (center_y_ratio - 0.5f) * 2.0f); // Precisely aim above, in the middle or below the last line. + SetScrollFromPosY(target_y, center_y_ratio); } void ImGui::SetKeyboardFocusHere(int offset) From 0ab722c3c5dceedd22eec58d6b43c4edb2991845 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 7 Aug 2017 22:28:09 +0800 Subject: [PATCH 184/921] Columns: First first column appearing wider than others (#1266) --- imgui.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 174110262..67412bef2 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9416,7 +9416,7 @@ float ImGui::GetColumnOffset(int column_index) IM_ASSERT(column_index < window->DC.ColumnsData.Size); const float t = window->DC.ColumnsData[column_index].OffsetNorm; - const float x_offset = window->DC.ColumnsMinX + t * (window->DC.ColumnsMaxX - window->DC.ColumnsMinX); + const float x_offset = ImLerp(window->DC.ColumnsMinX, window->DC.ColumnsMaxX, t); return (float)(int)x_offset; } @@ -9518,7 +9518,7 @@ void ImGui::Columns(int columns_count, const char* id, bool border) window->DC.ColumnsShowBorders = border; const float content_region_width = (window->SizeContentsExplicit.x != 0.0f) ? window->SizeContentsExplicit.x : window->Size.x; - window->DC.ColumnsMinX = window->DC.IndentX; // Lock our horizontal range + window->DC.ColumnsMinX = window->DC.IndentX - g.Style.ItemSpacing.x; // Lock our horizontal range window->DC.ColumnsMaxX = content_region_width - window->Scroll.x - ((window->Flags & ImGuiWindowFlags_NoScrollbar) ? 0 : g.Style.ScrollbarSize);// - window->WindowPadding().x; window->DC.ColumnsStartPosY = window->DC.CursorPos.y; window->DC.ColumnsCellMinY = window->DC.ColumnsCellMaxY = window->DC.CursorPos.y; From a1bcc8392eee7af8fa745018ccb9fdaae7ca25c0 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 8 Aug 2017 11:15:34 +0800 Subject: [PATCH 185/921] Fixed GetScrollMaxX() debug left-over from 7096fd8500c87d777dbd70dc9c1cd381b35bae4d (#1271) --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 67412bef2..79037c6ba 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -5272,7 +5272,7 @@ float ImGui::GetScrollY() float ImGui::GetScrollMaxX() { ImGuiWindow* window = GetCurrentWindowRead(); - return ImMax(0.0f, window->SizeContents.x - (window->SizeFull.x - window->ScrollbarSizes.x) + 50); + return ImMax(0.0f, window->SizeContents.x - (window->SizeFull.x - window->ScrollbarSizes.x)); } float ImGui::GetScrollMaxY() From b5ad88627dc00c3f216dbde2db1108b8a3d26891 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 8 Aug 2017 11:27:48 +0800 Subject: [PATCH 186/921] Merge various documentation tweaks, comments, todos from the Navigation Branch to reduce drift a little --- imgui.cpp | 152 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 80 insertions(+), 72 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 79037c6ba..aca9afe90 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -16,6 +16,8 @@ - MISSION STATEMENT - END-USER GUIDE - PROGRAMMER GUIDE (read me!) + - Read first + - Getting started with integrating imgui in your code/engine - API BREAKING CHANGES (read me when you update!) - FREQUENTLY ASKED QUESTIONS (FAQ), TIPS - How can I help? @@ -50,22 +52,21 @@ Designed for developers and content-creators, not the typical end-user! Some of the weaknesses includes: - doesn't look fancy, doesn't animate - limited layout features, intricate layouts are typically crafted in code - - occasionally uses statically sized buffers for string manipulations - won't crash, but some very long pieces of text may be clipped. functions like ImGui::TextUnformatted() don't have such restriction. END-USER GUIDE ============== - - double-click title bar to collapse window - - click upper right corner to close a window, available when 'bool* p_open' is passed to ImGui::Begin() - - click and drag on lower right corner to resize window - - click and drag on any empty space to move window - - double-click/double-tap on lower right corner grip to auto-fit to content + - Double-click title bar to collapse window + - Click upper right corner to close a window, available when 'bool* p_open' is passed to ImGui::Begin() + - Click and drag on lower right corner to resize window + - Click and drag on any empty space to move window + - Double-click/double-tap on lower right corner grip to auto-fit to content - TAB/SHIFT+TAB to cycle through keyboard editable fields - - use mouse wheel to scroll - - use CTRL+mouse wheel to zoom window contents (if IO.FontAllowScaling is true) + - Use mouse wheel to scroll + - Use CTRL+mouse wheel to zoom window contents (if io.FontAllowScaling is true) - CTRL+Click on a slider or drag box to input value as text - - text editor: + - Text editor: - Hold SHIFT or use mouse to select text. - CTRL+Left/Right to word jump - CTRL+Shift+Left/Right to select words @@ -74,76 +75,80 @@ - CTRL+Z,CTRL+Y to undo/redo - ESCAPE to revert text to its original value - You can apply arithmetic operators +,*,/ on numerical values. Use +- to subtract (because - would set a negative value!) + - Controls are automatically adjusted for OSX to match standard OSX text editing operations. PROGRAMMER GUIDE ================ - - read the FAQ below this section! - - your code creates the UI, if your code doesn't run the UI is gone! == very dynamic UI, no construction/destructions steps, less data retention on your side, no state duplication, less sync, less bugs. - - call and read ImGui::ShowTestWindow() for demo code demonstrating most features. - - see examples/ folder for standalone sample applications. Prefer reading examples/opengl2_example/ first as it is the simplest. - you may be able to grab and copy a ready made imgui_impl_*** file from the examples/. - - customization: PushStyleColor()/PushStyleVar() or the style editor to tweak the look of the interface (e.g. if you want a more compact UI or a different color scheme). + READ FIRST - - getting started: - - init: call ImGui::GetIO() to retrieve the ImGuiIO structure and fill the fields marked 'Settings'. - - init: call io.Fonts->GetTexDataAsRGBA32(...) and load the font texture pixels into graphics memory. - - every frame: - 1/ in your mainloop or right after you got your keyboard/mouse info, call ImGui::GetIO() and fill the fields marked 'Input' - 2/ call ImGui::NewFrame() as early as you can! - 3/ use any ImGui function you want between NewFrame() and Render() - 4/ call ImGui::Render() as late as you can to end the frame and finalize render data. it will call your RenderDrawListFn handler that you set in the IO structure. - (if you don't need to render, you still need to call Render() and ignore the callback, or call EndFrame() instead. if you call neither some aspects of windows focusing/moving will appear broken.) - - all rendering information are stored into command-lists until ImGui::Render() is called. - - ImGui never touches or know about your GPU state. the only function that knows about GPU is the RenderDrawListFn handler that you provide. - - effectively it means you can create widgets at any time in your code, regardless of considerations of being in "update" vs "render" phases of your own application. - - refer to the examples applications in the examples/ folder for instruction on how to setup your code. - - a typical application skeleton may be: + - Read the FAQ below this section! + - Your code creates the UI, if your code doesn't run the UI is gone! == very dynamic UI, no construction/destructions steps, less data retention on your side, no state duplication, less sync, less bugs. + - Call and read ImGui::ShowTestWindow() for demo code demonstrating most features. + - Customization: PushStyleColor()/PushStyleVar() or the style editor to tweak the look of the interface (e.g. if you want a more compact UI or a different color scheme). - // Application init - ImGuiIO& io = ImGui::GetIO(); - io.DisplaySize.x = 1920.0f; - io.DisplaySize.y = 1280.0f; - io.IniFilename = "imgui.ini"; - io.RenderDrawListsFn = my_render_function; // Setup a render function, or set to NULL and call GetDrawData() after Render() to access the render data. - // TODO: Fill others settings of the io structure + GETTING STARTED WITH INTEGRATING IMGUI IN YOUR CODE/ENGINE - // Load texture atlas - // There is a default font so you don't need to care about choosing a font yet - unsigned char* pixels; - int width, height; - io.Fonts->GetTexDataAsRGBA32(pixels, &width, &height); - // TODO: At this points you've got a texture pointed to by 'pixels' and you need to upload that your your graphic system - // TODO: Store your texture pointer/identifier (whatever your engine uses) in 'io.Fonts->TexID' + - See examples/ folder for standalone sample applications. Prefer reading examples/opengl_example/ first as it is the simplest. + You may be able to grab and copy a ready made imgui_impl_*** file from the examples/. + - Init: call ImGui::GetIO() to retrieve the ImGuiIO structure and fill the fields marked 'Settings'. + - Init: call io.Fonts->GetTexDataAsRGBA32(...) and load the font texture pixels into graphics memory. + - Every frame: + 1/ in your mainloop or right after you got your keyboard/mouse info, call ImGui::GetIO() and fill the fields marked 'Input' + 2/ call ImGui::NewFrame() as early as you can! + 3/ use any ImGui function you want between NewFrame() and Render() + 4/ call ImGui::Render() as late as you can to end the frame and finalize render data. it will call your RenderDrawListFn handler that you set in the IO structure. + (if you don't need to render, you still need to call Render() and ignore the callback, or call EndFrame() instead. if you call neither some aspects of windows focusing/moving will appear broken.) + - All rendering information are stored into command-lists until ImGui::Render() is called. + - ImGui never touches or knows about your GPU state. the only function that knows about GPU is the RenderDrawListFn handler that you provide. + - Effectively it means you can create widgets at any time in your code, regardless of considerations of being in "update" vs "render" phases of your own application. + - Refer to the examples applications in the examples/ folder for instruction on how to setup your code. + - A typical application skeleton may be: - // Application main loop - while (true) - { - // 1) get low-level inputs (e.g. on Win32, GetKeyboardState(), or poll your events, etc.) - // TODO: fill all fields of IO structure and call NewFrame - ImGuiIO& io = ImGui::GetIO(); - io.DeltaTime = 1.0f/60.0f; - io.MousePos = mouse_pos; - io.MouseDown[0] = mouse_button_0; - io.MouseDown[1] = mouse_button_1; - io.KeysDown[i] = ... + // Application init + ImGuiIO& io = ImGui::GetIO(); + io.DisplaySize.x = 1920.0f; + io.DisplaySize.y = 1280.0f; + io.IniFilename = "imgui.ini"; + io.RenderDrawListsFn = my_render_function; // Setup a render function, or set to NULL and call GetDrawData() after Render() to access the render data. + // TODO: Fill others settings of the io structure - // 2) call NewFrame(), after this point you can use ImGui::* functions anytime - ImGui::NewFrame(); + // Load texture atlas (there is a default font so you don't need to care about choosing a font yet) + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32(pixels, &width, &height); + // TODO: At this points you've got a texture pointed to by 'pixels' and you need to upload that your your graphic system + // TODO: Store your texture pointer/identifier (whatever your engine uses) in 'io.Fonts->TexID' - // 3) most of your application code here - MyGameUpdate(); // may use any ImGui functions, e.g. ImGui::Begin("My window"); ImGui::Text("Hello, world!"); ImGui::End(); - MyGameRender(); // may use any ImGui functions + // Application main loop + while (true) + { + // 1) get low-level inputs (e.g. on Win32, GetKeyboardState(), or poll your events, etc.) + // TODO: fill all fields of IO structure and call NewFrame + ImGuiIO& io = ImGui::GetIO(); + io.DeltaTime = 1.0f/60.0f; + io.MousePos = mouse_pos; + io.MouseDown[0] = mouse_button_0; + io.MouseDown[1] = mouse_button_1; + io.KeysDown[i] = ... - // 4) render & swap video buffers - ImGui::Render(); - SwapBuffers(); - } + // 2) call NewFrame(), after this point you can use ImGui::* functions anytime + ImGui::NewFrame(); + + // 3) most of your application code here + MyGameUpdate(); // may use any ImGui functions, e.g. ImGui::Begin("My window"); ImGui::Text("Hello, world!"); ImGui::End(); + MyGameRender(); // may use any ImGui functions + + // 4) render & swap video buffers + ImGui::Render(); + SwapBuffers(); + } + + - When calling NewFrame(), the 'io.WantCaptureMouse'/'io.WantCaptureKeyboard'/'io.WantTextInput' flags are updated. + They tell you if ImGui intends to use your inputs. So for example, if 'io.WantCaptureMouse' is set you would typically want to hide + mouse inputs from the rest of your application. Read the FAQ below for more information about those flags. - - When calling NewFrame(), the 'io.WantCaptureMouse'/'io.WantCaptureKeyboard'/'io.WantTextInput' flags are updated. - They tell you if ImGui intends to use your inputs. So for example, if 'io.WantCaptureMouse' is set you would typically want to hide - mouse inputs from the rest of your application. Read the FAQ below for more information about those flags. API BREAKING CHANGES @@ -269,7 +274,7 @@ Q: How can I help? A: - If you are experienced enough with ImGui and with C/C++, look at the todo list and see how you want/can help! - - Become a Patron/donate. Convince your company to become a Patron or provide serious funding for development time. + - Become a Patron/donate! Convince your company to become a Patron or provide serious funding for development time! See http://www.patreon.com/imgui Q: How do I update to a newer version of ImGui? A: Overwrite the following files: @@ -490,9 +495,9 @@ - window/tooltip: allow to set the width of a tooltip to allow TextWrapped() etc. while keeping the height automatic. - window: increase minimum size of a window with menus or fix the menu rendering so that it doesn't look odd. - draw-list: maintaining bounding box per command would allow to merge draw command when clipping isn't relied on (typical non-scrolling window or non-overflowing column would merge with previous command). -!- scrolling: allow immediately effective change of scroll if we haven't appended items yet +!- scrolling: allow immediately effective change of scroll after Begin() if we haven't appended items yet - splitter/separator: formalize the splitter idiom into an official api (we want to handle n-way split) (#319) - - widgets: display mode: widget-label, label-widget (aligned on column or using fixed size), label-newline-tab-widget etc. + - widgets: display mode: widget-label, label-widget (aligned on column or using fixed size), label-newline-tab-widget etc. (#395) - widgets: clean up widgets internal toward exposing everything. - widgets: add disabled and read-only modes (#211) - main: considering adding an Init() function? some constructs are awkward in the implementation because of the lack of them. @@ -575,13 +580,14 @@ - textwrapped: figure out better way to use TextWrapped() in an always auto-resize context (tooltip, etc.) (#249) - settings: write more decent code to allow saving/loading new fields - settings: api for per-tool simple persistent data (bool,int,float,columns sizes,etc.) in .ini file + - stb: add defines to disable stb implementations - style: add window shadows. - style/optimization: store rounded corners in texture to use 1 quad per corner (filled and wireframe) to lower the cost of rounding. - style: color-box not always square? - style: a concept of "compact style" that the end-user can easily rely on (e.g. PushStyleCompact()?) that maps to other settings? avoid implementing duplicate helpers such as SmallCheckbox(), etc. - style: try to make PushStyleVar() more robust to incorrect parameters (to be more friendly to edit & continues situation). - style: global scale setting. - - style: WindowPadding needs to be EVEN needs the 0.5 multiplier probably have a subtle effect on clip rectangle + - style: WindowPadding needs to be EVEN as the 0.5 multiplier used on this value probably have a subtle effect on clip rectangle - text: simple markup language for color change? - font: dynamic font atlas to avoid baking huge ranges into bitmap and make scaling easier. - font: small opt: for monospace font (like the defalt one) we can trim IndexXAdvance as long as trailing value is == FallbackXAdvance @@ -594,6 +600,7 @@ - log: let user copy any window content to clipboard easily (CTRL+C on windows? while moving it? context menu?). code is commented because it fails with multiple Begin/End pairs. - filters: set a current filter that tree node can automatically query to hide themselves - filters: handle wildcards (with implicit leading/trailing *), regexps + - filters: fuzzy matches (may use code at blog.forrestthewoods.com/4cffeed33fdb) - shortcuts: add a shortcut api, e.g. parse "&Save" and/or "Save (CTRL+S)", pass in to widgets or provide simple ways to use (button=activate, input=focus) !- keyboard: tooltip & combo boxes are messing up / not honoring keyboard tabbing - keyboard: full keyboard navigation and focus. (#323) @@ -6414,6 +6421,7 @@ static bool DataTypeApplyOpFromText(const char* buf, const char* initial_value_b } // Create text input in place of a slider (when CTRL+Clicking on slider) +// FIXME: Logic is messy and confusing. bool ImGui::InputScalarAsWidgetReplacement(const ImRect& aabb, const char* label, ImGuiDataType data_type, void* data_ptr, ImGuiID id, int decimal_precision) { ImGuiContext& g = *GImGui; @@ -6427,9 +6435,8 @@ bool ImGui::InputScalarAsWidgetReplacement(const ImRect& aabb, const char* label char buf[32]; DataTypeFormatString(data_type, data_ptr, decimal_precision, buf, IM_ARRAYSIZE(buf)); bool text_value_changed = InputTextEx(label, buf, IM_ARRAYSIZE(buf), aabb.GetSize(), ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_AutoSelectAll); - if (g.ScalarAsInputTextId == 0) + if (g.ScalarAsInputTextId == 0) // First frame we started displaying the InputText widget { - // First frame IM_ASSERT(g.ActiveId == id); // InputText ID expected to match the Slider ID (else we'd need to store them both, which is also possible) g.ScalarAsInputTextId = g.ActiveId; SetHoveredID(id); @@ -9872,6 +9879,7 @@ void ImGui::ShowMetricsWindow(bool* p_open) ImGui::Text("HoveredRootWindow: '%s'", g.HoveredRootWindow ? g.HoveredRootWindow->Name : "NULL"); ImGui::Text("HoveredID: 0x%08X/0x%08X", g.HoveredId, g.HoveredIdPreviousFrame); // Data is "in-flight" so depending on when the Metrics window is called we may see current frame information or not ImGui::Text("ActiveID: 0x%08X/0x%08X", g.ActiveId, g.ActiveIdPreviousFrame); + ImGui::Text("ActiveIdWindow: '%s", g.ActiveIdWindow ? g.ActiveIdWindow->Name : "NULL"); ImGui::TreePop(); } } From d952a8d3bf4f35b99f50ca497f62ad7ae94dcb28 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 8 Aug 2017 14:49:45 +0800 Subject: [PATCH 187/921] Demo: Color widget demo tweaks (#346) --- imgui_demo.cpp | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 58a115e68..b5e27ac1b 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -673,17 +673,19 @@ void ImGui::ShowTestWindow(bool* p_open) static bool hdr = false; static bool alpha_preview = true; static bool alpha_half_preview = false; + static bool options_menu = true; ImGui::Checkbox("With HDR", &hdr); ImGui::SameLine(); ShowHelpMarker("Currently all this does is to lift the 0..1 limits on dragging widgets."); ImGui::Checkbox("With Alpha Preview", &alpha_preview); ImGui::Checkbox("With Half Alpha Preview", &alpha_half_preview); - int misc_flags = (hdr ? ImGuiColorEditFlags_HDR : 0) | (alpha_half_preview ? ImGuiColorEditFlags_AlphaPreviewHalf : (alpha_preview ? ImGuiColorEditFlags_AlphaPreview : 0)); + ImGui::Checkbox("With Options Menu", &options_menu); ImGui::SameLine(); ShowHelpMarker("Right-click on the individual color widget to show options."); + int misc_flags = (hdr ? ImGuiColorEditFlags_HDR : 0) | (alpha_half_preview ? ImGuiColorEditFlags_AlphaPreviewHalf : (alpha_preview ? ImGuiColorEditFlags_AlphaPreview : 0)) | (options_menu ? 0 : ImGuiColorEditFlags_NoOptions); ImGui::Text("Color widget:"); - ImGui::SameLine(); ShowHelpMarker("Click on the colored square to open a color picker.\nRight-click on the colored square to show options.\nCTRL+click on individual component to input value.\n"); - ImGui::ColorEdit3("MyColor##1", (float*)&color, ImGuiColorEditFlags_HSV); + ImGui::SameLine(); ShowHelpMarker("Click on the colored square to open a color picker.\nCTRL+click on individual component to input value.\n"); + ImGui::ColorEdit3("MyColor##1", (float*)&color, misc_flags); - ImGui::Text("Color widget with Alpha:"); - ImGui::ColorEdit4("MyColor##2", (float*)&color, misc_flags); + ImGui::Text("Color widget HSV with Alpha:"); + ImGui::ColorEdit4("MyColor##2", (float*)&color, ImGuiColorEditFlags_HSV | misc_flags); ImGui::Text("Color widget with Float Display:"); ImGui::ColorEdit4("MyColor##2f", (float*)&color, ImGuiColorEditFlags_Float | misc_flags); @@ -751,6 +753,7 @@ void ImGui::ShowTestWindow(bool* p_open) ImGui::Checkbox("With Side Preview", &side_preview); if (side_preview) { + ImGui::SameLine(); ImGui::Checkbox("With Ref Color", &ref_color); if (ref_color) { @@ -759,14 +762,14 @@ void ImGui::ShowTestWindow(bool* p_open) } } ImGui::Combo("Inputs Mode", &inputs_mode, "All Inputs\0No Inputs\0RGB Input\0HSV Input\0HEX Input\0"); - ImGui::Combo("Picker Mode", &picker_mode, "Hue bar + SV rect\0Hue wheel + SV triangle\0"); - ImGui::SameLine(); ShowHelpMarker("User can right-click the inputs and override edit mode."); + ImGui::Combo("Picker Mode", &picker_mode, "Auto/Current\0Hue bar + SV rect\0Hue wheel + SV triangle\0"); + ImGui::SameLine(); ShowHelpMarker("User can right-click the picker to change mode."); ImGuiColorEditFlags flags = misc_flags; if (!alpha) flags |= ImGuiColorEditFlags_NoAlpha; // This is by default if you call ColorPicker3() instead of ColorPicker4() if (alpha_bar) flags |= ImGuiColorEditFlags_AlphaBar; if (!side_preview) flags |= ImGuiColorEditFlags_NoSidePreview; - if (picker_mode == 0) flags |= ImGuiColorEditFlags_PickerHueBar; - if (picker_mode == 1) flags |= ImGuiColorEditFlags_PickerHueWheel; + if (picker_mode == 1) flags |= ImGuiColorEditFlags_PickerHueBar; + if (picker_mode == 2) flags |= ImGuiColorEditFlags_PickerHueWheel; if (inputs_mode == 1) flags |= ImGuiColorEditFlags_NoInputs; if (inputs_mode == 2) flags |= ImGuiColorEditFlags_RGB; if (inputs_mode == 3) flags |= ImGuiColorEditFlags_HSV; From 942cb0e1f23a95b28f8220b85ed55bd488bc4716 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 8 Aug 2017 15:54:20 +0800 Subject: [PATCH 188/921] Added SetColorEditOptions(). ColorPicker4: context menu to select picker type and alpha bar. Reorganized flags (again!). (#346) --- imgui.cpp | 164 +++++++++++++++++++++++++++++++++-------------- imgui.h | 47 ++++++++------ imgui_demo.cpp | 8 +++ imgui_internal.h | 3 +- 4 files changed, 151 insertions(+), 71 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index c924d48d5..e7d56ad50 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2477,7 +2477,6 @@ void ImGui::Shutdown() for (int i = 0; i < IM_ARRAYSIZE(g.RenderDrawLists); i++) g.RenderDrawLists[i].clear(); g.OverlayDrawList.ClearFreeMemory(); - g.ColorEditModeStorage.Clear(); if (g.PrivateClipboard) { ImGui::MemFree(g.PrivateClipboard); @@ -9132,6 +9131,21 @@ void ImGui::RenderColorRectWithAlphaCheckerboard(ImVec2 p_min, ImVec2 p_max, ImU } } +void ImGui::SetColorEditOptions(ImGuiColorEditFlags flags) +{ + ImGuiContext& g = *GImGui; + if ((flags & ImGuiColorEditFlags__InputsMask) == 0) + flags |= ImGuiColorEditFlags__OptionsDefault & ImGuiColorEditFlags__InputsMask; + if ((flags & ImGuiColorEditFlags__DataTypeMask) == 0) + flags |= ImGuiColorEditFlags__OptionsDefault & ImGuiColorEditFlags__DataTypeMask; + if ((flags & ImGuiColorEditFlags__PickerMask) == 0) + flags |= ImGuiColorEditFlags__OptionsDefault & ImGuiColorEditFlags__PickerMask; + IM_ASSERT(ImIsPowerOfTwo((int)(flags & ImGuiColorEditFlags__InputsMask))); // Check only 1 option is selected + IM_ASSERT(ImIsPowerOfTwo((int)(flags & ImGuiColorEditFlags__DataTypeMask))); // Check only 1 option is selected + IM_ASSERT(ImIsPowerOfTwo((int)(flags & ImGuiColorEditFlags__PickerMask))); // Check only 1 option is selected + g.ColorEditOptions = flags; +} + // A little colored square. Return true when clicked. // FIXME: May want to display/ignore the alpha component in the color display? Yet show it in the tooltip. // 'desc_id' is not called 'label' because we don't display it next to the button, but only in the tooltip. @@ -9188,18 +9202,66 @@ bool ImGui::ColorEdit3(const char* label, float col[3], ImGuiColorEditFlags flag return ColorEdit4(label, col, flags | ImGuiColorEditFlags_NoAlpha); } -static void ColorOptionsPopup(ImGuiID storage_id, ImGuiColorEditFlags flags) +static void ColorEditOptionsPopup(ImGuiColorEditFlags flags) { + bool allow_opt_inputs = !(flags & ImGuiColorEditFlags__InputsMask); + bool allow_opt_datatype = !(flags & ImGuiColorEditFlags__DataTypeMask); + if ((!allow_opt_inputs && !allow_opt_datatype) || !ImGui::BeginPopup("context")) + return; ImGuiContext& g = *GImGui; - ImGuiColorEditFlags new_flags = -1; - if (ImGui::RadioButton("RGB", (flags & ImGuiColorEditFlags_RGB)?1:0)) new_flags = (flags & ~ImGuiColorEditFlags_InputsModeMask_) | ImGuiColorEditFlags_RGB; - if (ImGui::RadioButton("HSV", (flags & ImGuiColorEditFlags_HSV)?1:0)) new_flags = (flags & ~ImGuiColorEditFlags_InputsModeMask_) | ImGuiColorEditFlags_HSV; - if (ImGui::RadioButton("HEX", (flags & ImGuiColorEditFlags_HEX)?1:0)) new_flags = (flags & ~ImGuiColorEditFlags_InputsModeMask_) | ImGuiColorEditFlags_HEX; - ImGui::Separator(); - if (ImGui::RadioButton("0..255", (flags & ImGuiColorEditFlags_Float)?0:1)) new_flags = (flags & ~ImGuiColorEditFlags_Float); - if (ImGui::RadioButton("0.00..1.00", (flags & ImGuiColorEditFlags_Float)?1:0)) new_flags = (flags | ImGuiColorEditFlags_Float); - if (new_flags != -1) - g.ColorEditModeStorage.SetInt(storage_id, (int)(new_flags & ImGuiColorEditFlags_StoredMask_)); + ImGuiColorEditFlags opts = g.ColorEditOptions; + if (allow_opt_inputs) + { + if (ImGui::RadioButton("RGB", (opts & ImGuiColorEditFlags_RGB) ? 1 : 0)) opts = (opts & ~ImGuiColorEditFlags__InputsMask) | ImGuiColorEditFlags_RGB; + if (ImGui::RadioButton("HSV", (opts & ImGuiColorEditFlags_HSV) ? 1 : 0)) opts = (opts & ~ImGuiColorEditFlags__InputsMask) | ImGuiColorEditFlags_HSV; + if (ImGui::RadioButton("HEX", (opts & ImGuiColorEditFlags_HEX) ? 1 : 0)) opts = (opts & ~ImGuiColorEditFlags__InputsMask) | ImGuiColorEditFlags_HEX; + } + if (allow_opt_datatype) + { + if (allow_opt_inputs) ImGui::Separator(); + if (ImGui::RadioButton("0..255", (opts & ImGuiColorEditFlags_Uint8) ? 1 : 0)) opts = (opts & ~ImGuiColorEditFlags__DataTypeMask) | ImGuiColorEditFlags_Uint8; + if (ImGui::RadioButton("0.00..1.00", (opts & ImGuiColorEditFlags_Float) ? 1 : 0)) opts = (opts & ~ImGuiColorEditFlags__DataTypeMask) | ImGuiColorEditFlags_Float; + } + g.ColorEditOptions = opts; + ImGui::EndPopup(); +} + +static void ColorPickerOptionsPopup(ImGuiColorEditFlags flags, float* ref_col) +{ + bool allow_opt_picker = !(flags & ImGuiColorEditFlags__PickerMask); + bool allow_opt_alpha_bar = !(flags & ImGuiColorEditFlags_NoAlpha) && !(flags & ImGuiColorEditFlags_AlphaBar); + if ((!allow_opt_picker && !allow_opt_alpha_bar) || !ImGui::BeginPopup("context")) + return; + ImGuiContext& g = *GImGui; + if (allow_opt_picker) + { + ImVec2 picker_size(g.FontSize * 8, ImMax(g.FontSize * 8 - (ColorSquareSize() + g.Style.ItemInnerSpacing.x), 1.0f)); // FIXME: Picker size copied from main picker function + ImGui::PushItemWidth(picker_size.x); + for (int picker_type = 0; picker_type < 2; picker_type++) + { + // Draw small/thumbnail version of each picker type (over an invisible button for selection) + if (picker_type > 0) ImGui::Separator(); + ImGui::PushID(picker_type); + ImGuiColorEditFlags picker_flags = ImGuiColorEditFlags_NoInputs|ImGuiColorEditFlags_NoOptions|ImGuiColorEditFlags_NoLabel|ImGuiColorEditFlags_NoSidePreview|(flags & ImGuiColorEditFlags_NoAlpha); + if (picker_type == 0) picker_flags |= ImGuiColorEditFlags_PickerHueBar; + if (picker_type == 1) picker_flags |= ImGuiColorEditFlags_PickerHueWheel; + ImVec2 backup_pos = ImGui::GetCursorScreenPos(); + if (ImGui::Selectable("##selectable", false, 0, picker_size)) // By default, Selectable() is closing popup + g.ColorEditOptions = (g.ColorEditOptions & ~ImGuiColorEditFlags__PickerMask) | (picker_flags & ImGuiColorEditFlags__PickerMask); + ImGui::SetCursorScreenPos(backup_pos); + ImVec4 dummy_ref_col; + memcpy(&dummy_ref_col.x, ref_col, sizeof(float) * (ImGuiColorEditFlags_NoAlpha ? 3 : 4)); + ImGui::ColorPicker4("##dummypicker", &dummy_ref_col.x, picker_flags); + ImGui::PopID(); + } + ImGui::PopItemWidth(); + } + if (allow_opt_alpha_bar) + { + if (allow_opt_picker) ImGui::Separator(); + ImGui::CheckboxFlags("Alpha Bar", (unsigned int*)&g.ColorEditOptions, ImGuiColorEditFlags_AlphaBar); + } + ImGui::EndPopup(); } // Edit colors components (each component in 0.0f..1.0f range). @@ -9213,7 +9275,6 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag ImGuiContext& g = *GImGui; const ImGuiStyle& style = g.Style; - const ImGuiID storage_id = window->ID; // Store options on a per window basis const float w_extra = (flags & ImGuiColorEditFlags_NoSmallPreview) ? 0.0f : (ColorSquareSize() + style.ItemInnerSpacing.x); const float w_items_all = CalcItemWidth() - w_extra; const char* label_display_end = FindRenderedTextEnd(label); @@ -9221,39 +9282,44 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag const bool alpha = (flags & ImGuiColorEditFlags_NoAlpha) == 0; const bool hdr = (flags & ImGuiColorEditFlags_HDR) != 0; const int components = alpha ? 4 : 3; + const ImGuiColorEditFlags flags_untouched = flags; - // If we're not showing any slider there's no point in querying color mode, nor showing the options menu, nor doing any HSV conversions + BeginGroup(); + PushID(label); + + // If we're not showing any slider there's no point in doing any HSV conversions if (flags & ImGuiColorEditFlags_NoInputs) - flags = (flags & (~ImGuiColorEditFlags_InputsModeMask_)) | ImGuiColorEditFlags_RGB | ImGuiColorEditFlags_NoOptions; + flags = (flags & (~ImGuiColorEditFlags__InputsMask)) | ImGuiColorEditFlags_RGB | ImGuiColorEditFlags_NoOptions; - // If no mode is specified, defaults to RGB - if (!(flags & ImGuiColorEditFlags_InputsModeMask_)) - flags |= ImGuiColorEditFlags_RGB; - - // Read back edit mode from persistent storage, check that exactly one of RGB/HSV/HEX is set + // Context menu: display and modify options (before defaults are applied) if (!(flags & ImGuiColorEditFlags_NoOptions)) - flags = (flags & (~ImGuiColorEditFlags_StoredMask_)) | (g.ColorEditModeStorage.GetInt(storage_id, (flags & ImGuiColorEditFlags_StoredMask_)) & ImGuiColorEditFlags_StoredMask_); - IM_ASSERT(ImIsPowerOfTwo((int)(flags & ImGuiColorEditFlags_InputsModeMask_))); + ColorEditOptionsPopup(flags); + + // Read stored options + if (!(flags & ImGuiColorEditFlags__InputsMask)) + flags |= (g.ColorEditOptions & ImGuiColorEditFlags__InputsMask); + if (!(flags & ImGuiColorEditFlags__DataTypeMask)) + flags |= (g.ColorEditOptions & ImGuiColorEditFlags__DataTypeMask); + if (!(flags & ImGuiColorEditFlags__PickerMask)) + flags |= (g.ColorEditOptions & ImGuiColorEditFlags__PickerMask); + flags |= (g.ColorEditOptions & ~(ImGuiColorEditFlags__InputsMask | ImGuiColorEditFlags__DataTypeMask | ImGuiColorEditFlags__PickerMask)); + // Convert to the formats we need float f[4] = { col[0], col[1], col[2], alpha ? col[3] : 1.0f }; if (flags & ImGuiColorEditFlags_HSV) ColorConvertRGBtoHSV(f[0], f[1], f[2], f[0], f[1], f[2]); - int i[4] = { IM_F32_TO_INT8_UNBOUND(f[0]), IM_F32_TO_INT8_UNBOUND(f[1]), IM_F32_TO_INT8_UNBOUND(f[2]), IM_F32_TO_INT8_UNBOUND(f[3]) }; bool value_changed = false; bool value_changed_as_float = false; - BeginGroup(); - PushID(label); - if ((flags & (ImGuiColorEditFlags_RGB | ImGuiColorEditFlags_HSV)) != 0 && (flags & ImGuiColorEditFlags_NoInputs) == 0) { // RGB/HSV 0..255 Sliders const float w_item_one = ImMax(1.0f, (float)(int)((w_items_all - (style.ItemInnerSpacing.x) * (components-1)) / (float)components)); const float w_item_last = ImMax(1.0f, (float)(int)(w_items_all - (w_item_one + style.ItemInnerSpacing.x) * (components-1))); - const bool hide_prefix = (w_item_one <= CalcTextSize((flags & ImGuiColorEditFlags_Float) ? "M:1.000" : "M:999").x); + const bool hide_prefix = (w_item_one <= CalcTextSize((flags & ImGuiColorEditFlags_Float) ? "M:0.000" : "M:000").x); const char* ids[4] = { "##X", "##Y", "##Z", "##W" }; const char* fmt_table_int[3][4] = { @@ -9341,8 +9407,8 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag Separator(); } float square_sz = ColorSquareSize(); - ImGuiColorEditFlags picker_flags_to_forward = ImGuiColorEditFlags_Float | ImGuiColorEditFlags_HDR | ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_AlphaBar;// | ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf; - ImGuiColorEditFlags picker_flags = (flags & picker_flags_to_forward) | (ImGuiColorEditFlags_RGB | ImGuiColorEditFlags_HSV | ImGuiColorEditFlags_HEX) | ImGuiColorEditFlags_NoLabel | ImGuiColorEditFlags_AlphaPreviewHalf; + ImGuiColorEditFlags picker_flags_to_forward = ImGuiColorEditFlags__DataTypeMask | ImGuiColorEditFlags__PickerMask | ImGuiColorEditFlags_HDR | ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_AlphaBar; + ImGuiColorEditFlags picker_flags = (flags_untouched & picker_flags_to_forward) | ImGuiColorEditFlags__InputsMask | ImGuiColorEditFlags_NoLabel | ImGuiColorEditFlags_AlphaPreviewHalf; PushItemWidth(square_sz * 12.0f); // Use 256 + bar sizes? value_changed |= ColorPicker4("##picker", col, picker_flags, &g.ColorPickerRef.x); PopItemWidth(); @@ -9350,13 +9416,6 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag } } - // Context menu: display and store options. Don't apply to 'flags' this frame. - if (!(flags & ImGuiColorEditFlags_NoOptions) && BeginPopup("context")) - { - ColorOptionsPopup(storage_id, flags); - EndPopup(); - } - if (label != label_display_end && !(flags & ImGuiColorEditFlags_NoLabel)) { SameLine(0, style.ItemInnerSpacing.x); @@ -9449,6 +9508,18 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl if ((flags & ImGuiColorEditFlags_NoSidePreview) == 0) flags |= ImGuiColorEditFlags_NoSmallPreview; + if ((flags & ImGuiColorEditFlags_NoOptions) == 0) + { + // Context menu: display and store options. + ColorPickerOptionsPopup(flags, col); + + // Read stored options + if ((flags & ImGuiColorEditFlags__PickerMask) == 0) + flags |= ((g.ColorEditOptions & ImGuiColorEditFlags__PickerMask) ? g.ColorEditOptions : ImGuiColorEditFlags__OptionsDefault) & ImGuiColorEditFlags__PickerMask; + IM_ASSERT(ImIsPowerOfTwo((int)(flags & ImGuiColorEditFlags__PickerMask))); // Check that only 1 is selected + flags |= (g.ColorEditOptions & ImGuiColorEditFlags_AlphaBar); + } + // Setup bool alpha_bar = (flags & ImGuiColorEditFlags_AlphaBar) && !(flags & ImGuiColorEditFlags_NoAlpha); ImVec2 picker_pos = window->DC.CursorPos; @@ -9472,11 +9543,6 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl float H,S,V; ColorConvertRGBtoHSV(col[0], col[1], col[2], H, S, V); - // Defaults to Hue bar + SV rectangle // FIXME-WIP - if ((flags & ImGuiColorEditFlags_PickerModeMask_) == 0) - flags |= ImGuiColorEditFlags_PickerHueBar; - IM_ASSERT(ImIsPowerOfTwo((int)(flags & ImGuiColorEditFlags_PickerModeMask_))); // Check that only 1 is selected - bool value_changed = false, value_changed_h = false, value_changed_sv = false; if (flags & ImGuiColorEditFlags_PickerHueWheel) @@ -9511,6 +9577,8 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl value_changed = value_changed_sv = true; } } + if (!(flags & ImGuiColorEditFlags_NoOptions) && IsItemHovered() && IsMouseClicked(1)) + OpenPopup("context"); } else if (flags & ImGuiColorEditFlags_PickerHueBar) { @@ -9522,6 +9590,8 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl V = 1.0f - ImSaturate((io.MousePos.y - picker_pos.y) / (sv_picker_size-1)); value_changed = value_changed_sv = true; } + if (!(flags & ImGuiColorEditFlags_NoOptions) && IsItemHovered() && IsMouseClicked(1)) + OpenPopup("context"); // Hue bar logic SetCursorScreenPos(ImVec2(bar0_pos_x, picker_pos.y)); @@ -9587,20 +9657,16 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl ColorConvertHSVtoRGB(H >= 1.0f ? H - 10 * 1e-6f : H, S > 0.0f ? S : 10*1e-6f, V > 0.0f ? V : 1e-6f, col[0], col[1], col[2]); // R,G,B and H,S,V slider color editor - if (!(flags & ImGuiColorEditFlags_NoInputs)) + if ((flags & ImGuiColorEditFlags_NoInputs) == 0) { PushItemWidth((alpha_bar ? bar1_pos_x : bar0_pos_x) + bars_width - picker_pos.x); - ImGuiColorEditFlags sub_flags_to_forward = ImGuiColorEditFlags_Float | ImGuiColorEditFlags_HDR | ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoSmallPreview | ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf; + ImGuiColorEditFlags sub_flags_to_forward = ImGuiColorEditFlags__DataTypeMask | ImGuiColorEditFlags_HDR | ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoSmallPreview | ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf; ImGuiColorEditFlags sub_flags = (flags & sub_flags_to_forward) | ImGuiColorEditFlags_NoPicker; - if ((flags & ImGuiColorEditFlags_InputsModeMask_) == 0) - flags |= ImGuiColorEditFlags_RGB | ImGuiColorEditFlags_HSV | ImGuiColorEditFlags_HEX; - if ((flags & ImGuiColorEditFlags_InputsModeMask_) == ImGuiColorEditFlags_InputsModeMask_) - sub_flags |= ImGuiColorEditFlags_NoOptions; - if (flags & ImGuiColorEditFlags_RGB) + if (flags & ImGuiColorEditFlags_RGB || (flags & ImGuiColorEditFlags__InputsMask) == 0) value_changed |= ColorEdit4("##rgb", col, sub_flags | ImGuiColorEditFlags_RGB); - if (flags & ImGuiColorEditFlags_HSV) + if (flags & ImGuiColorEditFlags_HSV || (flags & ImGuiColorEditFlags__InputsMask) == 0) value_changed |= ColorEdit4("##hsv", col, sub_flags | ImGuiColorEditFlags_HSV); - if (flags & ImGuiColorEditFlags_HEX) + if (flags & ImGuiColorEditFlags_HEX || (flags & ImGuiColorEditFlags__InputsMask) == 0) value_changed |= ColorEdit4("##hex", col, sub_flags | ImGuiColorEditFlags_HEX); PopItemWidth(); } diff --git a/imgui.h b/imgui.h index cec6e26bd..851a20ceb 100644 --- a/imgui.h +++ b/imgui.h @@ -327,6 +327,7 @@ namespace ImGui IMGUI_API bool ColorPicker3(const char* label, float col[3], ImGuiColorEditFlags flags = 0); IMGUI_API bool ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags flags = 0, const float* ref_col = NULL); IMGUI_API bool ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFlags flags = 0, ImVec2 size = ImVec2(0,0)); // display a colored square/button, hover for details, return true when pressed. + IMGUI_API void SetColorEditOptions(ImGuiColorEditFlags flags); // initialize current options (generally on application startup) if you want to select a default format, picker type, etc. User will be able to change many settings, unless you pass the _NoOptions flag to your calls. // Widgets: Trees IMGUI_API bool TreeNode(const char* label); // if returning 'true' the node is open and the tree id is pushed into the id stack. user is responsible for calling TreePop(). @@ -667,27 +668,31 @@ enum ImGuiStyleVar_ // Enumeration for ColorEdit3() / ColorEdit4() / ColorPicker3() / ColorPicker4() / ColorButton() enum ImGuiColorEditFlags_ { - ImGuiColorEditFlags_RGB = 1 << 1, // ColorEdit: default to one among RGB/HSV/HEX. User can still use the options menu to change. ColorPicker: Choose any combination or RGB/HSV/HEX. - ImGuiColorEditFlags_HSV = 1 << 2, // " - ImGuiColorEditFlags_HEX = 1 << 3, // " - ImGuiColorEditFlags_Float = 1 << 4, // ColorEdit, ColorPicker, ColorButton: display values formatted as 0.0f..1.0f floats instead of 0..255 integers. No round-trip of value via integers. - ImGuiColorEditFlags_HDR = 1 << 5, // ColorEdit: disable 0.0f..1.0f limits (note: you probably want to use ImGuiColorEditFlags_Float flag as well). - ImGuiColorEditFlags_AlphaBar = 1 << 6, // ColorEdit, ColorPicker: show vertical alpha bar/gradient in picker. - ImGuiColorEditFlags_AlphaPreview = 1 << 7, // ColorEdit, ColorPicker, ColorButton: display preview as a transparent color over a checkerboard, instead of opaque. - ImGuiColorEditFlags_AlphaPreviewHalf= 1 << 8, // ColorEdit, ColorPicker, ColorButton: display half opaque / half checkerboard, instead of opaque. - ImGuiColorEditFlags_NoAlpha = 1 << 9, // ColorEdit, ColorPicker, ColorButton: completely ignore Alpha component (read 3 components from the input pointer). - ImGuiColorEditFlags_NoPicker = 1 << 10, // ColorEdit: disable picker when clicking on colored square. - ImGuiColorEditFlags_NoOptions = 1 << 11, // ColorEdit: disable toggling options menu when right-clicking on inputs/small preview. - ImGuiColorEditFlags_NoSmallPreview = 1 << 12, // ColorEdit, ColorPicker: disable colored square preview next to the inputs. (e.g. to show only the inputs) - ImGuiColorEditFlags_NoInputs = 1 << 13, // ColorEdit, ColorPicker: disable inputs sliders/text widgets (e.g. to show only the small preview colored square). - ImGuiColorEditFlags_NoTooltip = 1 << 14, // ColorEdit, ColorPicker, ColorButton: disable tooltip when hovering the preview. - ImGuiColorEditFlags_NoLabel = 1 << 15, // ColorEdit, ColorPicker: disable display of inline text label (the label is still forwarded to the tooltip and picker). - ImGuiColorEditFlags_NoSidePreview = 1 << 16, // ColorPicker: disable bigger color preview on right side of the picker, use small colored square preview instead. - ImGuiColorEditFlags_PickerHueWheel = 1 << 17, // [WIP] ColorPicker: wheel for Hue, triangle for SV - ImGuiColorEditFlags_PickerHueBar = 1 << 18, // [WIP] ColorPicker: bar for Hue, rectangle for SV - ImGuiColorEditFlags_InputsModeMask_ = ImGuiColorEditFlags_RGB|ImGuiColorEditFlags_HSV|ImGuiColorEditFlags_HEX, - ImGuiColorEditFlags_PickerModeMask_ = ImGuiColorEditFlags_PickerHueWheel|ImGuiColorEditFlags_PickerHueBar, - ImGuiColorEditFlags_StoredMask_ = ImGuiColorEditFlags_RGB|ImGuiColorEditFlags_HSV|ImGuiColorEditFlags_HEX|ImGuiColorEditFlags_Float + ImGuiColorEditFlags_NoAlpha = 1 << 1, // // ColorEdit, ColorPicker, ColorButton: ignore Alpha component (read 3 components from the input pointer). + ImGuiColorEditFlags_NoPicker = 1 << 2, // // ColorEdit: disable picker when clicking on colored square. + ImGuiColorEditFlags_NoOptions = 1 << 3, // // ColorEdit: disable toggling options menu when right-clicking on inputs/small preview. + ImGuiColorEditFlags_NoSmallPreview = 1 << 4, // // ColorEdit, ColorPicker: disable colored square preview next to the inputs. (e.g. to show only the inputs) + ImGuiColorEditFlags_NoInputs = 1 << 5, // // ColorEdit, ColorPicker: disable inputs sliders/text widgets (e.g. to show only the small preview colored square). + ImGuiColorEditFlags_NoTooltip = 1 << 6, // // ColorEdit, ColorPicker, ColorButton: disable tooltip when hovering the preview. + ImGuiColorEditFlags_NoLabel = 1 << 7, // // ColorEdit, ColorPicker: disable display of inline text label (the label is still forwarded to the tooltip and picker). + ImGuiColorEditFlags_NoSidePreview = 1 << 8, // // ColorPicker: disable bigger color preview on right side of the picker, use small colored square preview instead. + // User Options (right-click on widget to change some of them). You can set application defaults using SetColorEditOptions(). The idea is that you probably don't want to override them in most of your calls, let the user choose and/or call SetColorEditOptions() during startup. + ImGuiColorEditFlags_AlphaBar = 1 << 9, // // ColorEdit, ColorPicker: show vertical alpha bar/gradient in picker. + ImGuiColorEditFlags_AlphaPreview = 1 << 10, // // ColorEdit, ColorPicker, ColorButton: display preview as a transparent color over a checkerboard, instead of opaque. + ImGuiColorEditFlags_AlphaPreviewHalf= 1 << 11, // // ColorEdit, ColorPicker, ColorButton: display half opaque / half checkerboard, instead of opaque. + ImGuiColorEditFlags_HDR = 1 << 12, // // (WIP) ColorEdit: Currently only disable 0.0f..1.0f limits in RGBA edition (note: you probably want to use ImGuiColorEditFlags_Float flag as well). + ImGuiColorEditFlags_RGB = 1 << 13, // [Inputs] // ColorEdit: choose one among RGB/HSV/HEX. ColorPicker: choose any combination using RGB/HSV/HEX. + ImGuiColorEditFlags_HSV = 1 << 14, // [Inputs] // " + ImGuiColorEditFlags_HEX = 1 << 15, // [Inputs] // " + ImGuiColorEditFlags_Uint8 = 1 << 16, // [DataType] // ColorEdit, ColorPicker, ColorButton: _display_ values formatted as 0..255. + ImGuiColorEditFlags_Float = 1 << 17, // [DataType] // ColorEdit, ColorPicker, ColorButton: _display_ values formatted as 0.0f..1.0f floats instead of 0..255 integers. No round-trip of value via integers. + ImGuiColorEditFlags_PickerHueBar = 1 << 18, // [PickerMode] // ColorPicker: bar for Hue, rectangle for Sat/Value. + ImGuiColorEditFlags_PickerHueWheel = 1 << 19, // [PickerMode] // ColorPicker: wheel for Hue, triangle for Sat/Value. + // Internals/Masks + ImGuiColorEditFlags__InputsMask = ImGuiColorEditFlags_RGB|ImGuiColorEditFlags_HSV|ImGuiColorEditFlags_HEX, + ImGuiColorEditFlags__DataTypeMask = ImGuiColorEditFlags_Uint8|ImGuiColorEditFlags_Float, + ImGuiColorEditFlags__PickerMask = ImGuiColorEditFlags_PickerHueWheel|ImGuiColorEditFlags_PickerHueBar, + ImGuiColorEditFlags__OptionsDefault = ImGuiColorEditFlags_Uint8|ImGuiColorEditFlags_RGB|ImGuiColorEditFlags_PickerHueBar // Change application default using SetColorEditOptions() }; // Enumeration for GetMouseCursor() diff --git a/imgui_demo.cpp b/imgui_demo.cpp index b5e27ac1b..2fd17f4db 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -776,6 +776,14 @@ void ImGui::ShowTestWindow(bool* p_open) if (inputs_mode == 4) flags |= ImGuiColorEditFlags_HEX; ImGui::ColorPicker4("MyColor##4", (float*)&color, flags, ref_color ? &ref_color_v.x : NULL); + ImGui::Text("Programmatically set defaults/options:"); + ImGui::SameLine(); ShowHelpMarker("SetColorEditOptions() is designed to allow you to set boot-time default.\nWe don't have Push/Pop functions because you can force options on a per-widget basis if needed, and the user can change non-forced ones with the options menu.\nWe don't have a getter to avoid encouraging you to persistently save values that aren't forward-compatible."); + if (ImGui::Button("Uint8 + HSV")) + ImGui::SetColorEditOptions(ImGuiColorEditFlags_Uint8 | ImGuiColorEditFlags_HSV); + ImGui::SameLine(); + if (ImGui::Button("Float + HDR + NoClamp")) + ImGui::SetColorEditOptions(ImGuiColorEditFlags_Float | ImGuiColorEditFlags_RGB | ImGuiColorEditFlags_HDR); + ImGui::TreePop(); } diff --git a/imgui_internal.h b/imgui_internal.h index 080369158..166efadc1 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -449,7 +449,7 @@ struct ImGuiContext ImGuiTextEditState InputTextState; ImFont InputTextPasswordFont; ImGuiID ScalarAsInputTextId; // Temporary text input when CTRL+clicking on a slider, etc. - ImGuiStorage ColorEditModeStorage; // Store user selection of color edit mode + ImGuiColorEditFlags ColorEditOptions; // Store user options for color edit widgets ImVec4 ColorPickerRef; float DragCurrentValue; // Currently dragged value, always float, not rounded by end-user precision settings ImVec2 DragLastMouseDelta; @@ -520,6 +520,7 @@ struct ImGuiContext SetNextTreeNodeOpenCond = 0; ScalarAsInputTextId = 0; + ColorEditOptions = ImGuiColorEditFlags__OptionsDefault; DragCurrentValue = 0.0f; DragLastMouseDelta = ImVec2(0.0f, 0.0f); DragSpeedDefaultRatio = 1.0f / 100.0f; From a78ef7a369174dadf64678fcf4752ac79f74d546 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 8 Aug 2017 16:07:17 +0800 Subject: [PATCH 189/921] Comments --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index e7d56ad50..05a88f338 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -158,7 +158,7 @@ Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. Also read releases logs https://github.com/ocornut/imgui/releases for more details. - - 2017/07/30 (1.51) - removed ColorEditMode() and ImGuiColorEditMode in favor of ImGuiColorEditFlags and parameters to the various Color*() functions + - 2017/07/30 (1.51) - removed ColorEditMode() and ImGuiColorEditMode in favor of ImGuiColorEditFlags and parameters to the various Color*() functions. The SetColorEditOptions() allows to initialize default but the user can still change them with right-click context menu. - changed prototype of 'ColorEdit4(const char* label, float col[4], bool show_alpha = true)' to 'ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flags = 0)', where passing flags = 0x01 is a safe no-op (hello dodgy backward compatibility!). - check and run the demo window, under "Color/Picker Widgets", to understand the various new options. - changed prototype of rarely used 'ColorButton(ImVec4 col, bool small_height = false, bool outline_border = true)' to 'ColorButton(const char* desc_id, ImVec4 col, ImGuiColorEditFlags flags = 0, ImVec2 size = ImVec2(0,0))' - 2017/07/20 (1.51) - removed IsPosHoveringAnyWindow(ImVec2), which was partly broken and misleading. ASSERT + redirect user to io.WantCaptureMouse From d888de44838b510b9d920de5051d1756d1cd560e Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 8 Aug 2017 17:49:12 +0800 Subject: [PATCH 190/921] Demo: Merged a few demo tweaks from navigation branch to minimize drift. --- imgui_demo.cpp | 115 +++++++++++++++++++++++++------------------------ 1 file changed, 59 insertions(+), 56 deletions(-) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 2fd17f4db..ac40ae97c 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -542,13 +542,10 @@ void ImGui::ShowTestWindow(bool* p_open) ImGui::TreePop(); } - static bool my_toggle = false; + static int clicked = 0; if (ImGui::Button("Button")) - { - printf("Clicked\n"); - my_toggle = !my_toggle; - } - if (my_toggle) + clicked++; + if (clicked & 1) { ImGui::SameLine(); ImGui::Text("Thanks for clicking me!"); @@ -902,7 +899,7 @@ void ImGui::ShowTestWindow(bool* p_open) } } - if (ImGui::CollapsingHeader("Graphs widgets")) + if (ImGui::CollapsingHeader("Plots widgets")) { static bool animate = true; ImGui::Checkbox("Animate", &animate); @@ -914,16 +911,16 @@ void ImGui::ShowTestWindow(bool* p_open) // Tip: If your float aren't contiguous but part of a structure, you can pass a pointer to your first float and the sizeof() of your structure in the Stride parameter. static float values[90] = { 0 }; static int values_offset = 0; - if (animate) + static float refresh_time = 0.0f; + if (!animate || refresh_time == 0.0f) + refresh_time = ImGui::GetTime(); + while (refresh_time < ImGui::GetTime()) // Create dummy data at fixed 60 hz rate for the demo { - static float refresh_time = ImGui::GetTime(); // Create dummy data at fixed 60 hz rate for the demo - for (; ImGui::GetTime() > refresh_time + 1.0f/60.0f; refresh_time += 1.0f/60.0f) - { - static float phase = 0.0f; - values[values_offset] = cosf(phase); - values_offset = (values_offset+1) % IM_ARRAYSIZE(values); - phase += 0.10f*values_offset; - } + static float phase = 0.0f; + values[values_offset] = cosf(phase); + values_offset = (values_offset+1) % IM_ARRAYSIZE(values); + phase += 0.10f*values_offset; + refresh_time += 1.0f/60.0f; } ImGui::PlotLines("Lines", values, IM_ARRAYSIZE(values), values_offset, "avg 0.0", -1.0f, 1.0f, ImVec2(0,80)); ImGui::PlotHistogram("Histogram", arr, IM_ARRAYSIZE(arr), 0, NULL, 0.0f, 1.0f, ImVec2(0,80)); @@ -933,7 +930,7 @@ void ImGui::ShowTestWindow(bool* p_open) struct Funcs { static float Sin(void*, int i) { return sinf(i * 0.1f); } - static float Saw(void*, int i) { return (i & 1) ? 1.0f : 0.0f; } + static float Saw(void*, int i) { return (i & 1) ? 1.0f : -1.0f; } }; static int func_type = 0, display_count = 70; ImGui::Separator(); @@ -1458,9 +1455,11 @@ void ImGui::ShowTestWindow(bool* p_open) ImGui::OpenPopup("Stacked 1"); if (ImGui::BeginPopupModal("Stacked 1")) { - ImGui::Text("Hello from Stacked The First"); + ImGui::Text("Hello from Stacked The First\nUsing style.Colors[ImGuiCol_ModalWindowDarkening] for darkening."); + static int item = 1; + ImGui::Combo("Combo", &item, "aaaa\0bbbb\0cccc\0dddd\0eeee\0\0"); - if (ImGui::Button("Another one..")) + if (ImGui::Button("Add another modal..")) ImGui::OpenPopup("Stacked 2"); if (ImGui::BeginPopupModal("Stacked 2")) { @@ -1617,7 +1616,7 @@ void ImGui::ShowTestWindow(bool* p_open) } bool node_open = ImGui::TreeNode("Tree within single cell"); - ImGui::SameLine(); ShowHelpMarker("NB: Tree node must be poped before ending the cell.\nThere's no storage of state per-cell."); + ImGui::SameLine(); ShowHelpMarker("NB: Tree node must be poped before ending the cell. There's no storage of state per-cell."); if (node_open) { ImGui::Columns(2, "tree items"); @@ -1645,8 +1644,42 @@ void ImGui::ShowTestWindow(bool* p_open) ImGui::BulletText("%s", lines[i]); } - if (ImGui::CollapsingHeader("Keyboard, Mouse & Focus")) + if (ImGui::CollapsingHeader("Inputs & Focus")) { + ImGuiIO& io = ImGui::GetIO(); + ImGui::Checkbox("io.MouseDrawCursor", &io.MouseDrawCursor); + ImGui::SameLine(); ShowHelpMarker("Request ImGui to render a mouse cursor for you in software. Note that a mouse cursor rendered via regular GPU rendering will feel more laggy than hardware cursor, but will be more in sync with your other visuals."); + + ImGui::Text("WantCaptureMouse: %d", io.WantCaptureMouse); + ImGui::Text("WantCaptureKeyboard: %d", io.WantCaptureKeyboard); + ImGui::Text("WantTextInput: %d", io.WantTextInput); + + if (ImGui::TreeNode("Keyboard & Mouse State")) + { + ImGui::Text("Mouse pos: (%g, %g)", io.MousePos.x, io.MousePos.y); + ImGui::Text("Mouse down:"); for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) if (io.MouseDownDuration[i] >= 0.0f) { ImGui::SameLine(); ImGui::Text("b%d (%.02f secs)", i, io.MouseDownDuration[i]); } + ImGui::Text("Mouse clicked:"); for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) if (ImGui::IsMouseClicked(i)) { ImGui::SameLine(); ImGui::Text("b%d", i); } + ImGui::Text("Mouse dbl-clicked:"); for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) if (ImGui::IsMouseDoubleClicked(i)) { ImGui::SameLine(); ImGui::Text("b%d", i); } + ImGui::Text("Mouse released:"); for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) if (ImGui::IsMouseReleased(i)) { ImGui::SameLine(); ImGui::Text("b%d", i); } + ImGui::Text("Mouse wheel: %.1f", io.MouseWheel); + + ImGui::Text("Keys down:"); for (int i = 0; i < IM_ARRAYSIZE(io.KeysDown); i++) if (io.KeysDownDuration[i] >= 0.0f) { ImGui::SameLine(); ImGui::Text("%d (%.02f secs)", i, io.KeysDownDuration[i]); } + ImGui::Text("Keys pressed:"); for (int i = 0; i < IM_ARRAYSIZE(io.KeysDown); i++) if (ImGui::IsKeyPressed(i)) { ImGui::SameLine(); ImGui::Text("%d", i); } + ImGui::Text("Keys release:"); for (int i = 0; i < IM_ARRAYSIZE(io.KeysDown); i++) if (ImGui::IsKeyReleased(i)) { ImGui::SameLine(); ImGui::Text("%d", i); } + ImGui::Text("Keys mods: %s%s%s%s", io.KeyCtrl ? "CTRL " : "", io.KeyShift ? "SHIFT " : "", io.KeyAlt ? "ALT " : "", io.KeySuper ? "SUPER " : ""); + + + ImGui::Button("Hovering me sets the\nkeyboard capture flag"); + if (ImGui::IsItemHovered()) + ImGui::CaptureKeyboardFromApp(true); + ImGui::SameLine(); + ImGui::Button("Holding me clears the\nthe keyboard capture flag"); + if (ImGui::IsItemActive()) + ImGui::CaptureKeyboardFromApp(false); + + ImGui::TreePop(); + } + if (ImGui::TreeNode("Tabbing")) { ImGui::Text("Use TAB/SHIFT+TAB to cycle through keyboard editable fields."); @@ -1700,52 +1733,20 @@ void ImGui::ShowTestWindow(bool* p_open) // Draw a line between the button and the mouse cursor ImDrawList* draw_list = ImGui::GetWindowDrawList(); draw_list->PushClipRectFullScreen(); - draw_list->AddLine(ImGui::CalcItemRectClosestPoint(ImGui::GetIO().MousePos, true, -2.0f), ImGui::GetIO().MousePos, ImColor(ImGui::GetStyle().Colors[ImGuiCol_Button]), 4.0f); + draw_list->AddLine(ImGui::CalcItemRectClosestPoint(io.MousePos, true, -2.0f), io.MousePos, ImColor(ImGui::GetStyle().Colors[ImGuiCol_Button]), 4.0f); draw_list->PopClipRect(); ImVec2 value_raw = ImGui::GetMouseDragDelta(0, 0.0f); ImVec2 value_with_lock_threshold = ImGui::GetMouseDragDelta(0); - ImVec2 mouse_delta = ImGui::GetIO().MouseDelta; + ImVec2 mouse_delta = io.MouseDelta; ImGui::SameLine(); ImGui::Text("Raw (%.1f, %.1f), WithLockThresold (%.1f, %.1f), MouseDelta (%.1f, %.1f)", value_raw.x, value_raw.y, value_with_lock_threshold.x, value_with_lock_threshold.y, mouse_delta.x, mouse_delta.y); } ImGui::TreePop(); } - if (ImGui::TreeNode("Keyboard & Mouse State")) - { - ImGuiIO& io = ImGui::GetIO(); - - ImGui::Text("MousePos: (%g, %g)", io.MousePos.x, io.MousePos.y); - ImGui::Text("Mouse down:"); for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) if (io.MouseDownDuration[i] >= 0.0f) { ImGui::SameLine(); ImGui::Text("b%d (%.02f secs)", i, io.MouseDownDuration[i]); } - ImGui::Text("Mouse clicked:"); for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) if (ImGui::IsMouseClicked(i)) { ImGui::SameLine(); ImGui::Text("b%d", i); } - ImGui::Text("Mouse dbl-clicked:"); for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) if (ImGui::IsMouseDoubleClicked(i)) { ImGui::SameLine(); ImGui::Text("b%d", i); } - ImGui::Text("Mouse released:"); for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) if (ImGui::IsMouseReleased(i)) { ImGui::SameLine(); ImGui::Text("b%d", i); } - ImGui::Text("MouseWheel: %.1f", io.MouseWheel); - - ImGui::Text("Keys down:"); for (int i = 0; i < IM_ARRAYSIZE(io.KeysDown); i++) if (io.KeysDownDuration[i] >= 0.0f) { ImGui::SameLine(); ImGui::Text("%d (%.02f secs)", i, io.KeysDownDuration[i]); } - ImGui::Text("Keys pressed:"); for (int i = 0; i < IM_ARRAYSIZE(io.KeysDown); i++) if (ImGui::IsKeyPressed(i)) { ImGui::SameLine(); ImGui::Text("%d", i); } - ImGui::Text("Keys release:"); for (int i = 0; i < IM_ARRAYSIZE(io.KeysDown); i++) if (ImGui::IsKeyReleased(i)) { ImGui::SameLine(); ImGui::Text("%d", i); } - ImGui::Text("KeyMods: %s%s%s%s", io.KeyCtrl ? "CTRL " : "", io.KeyShift ? "SHIFT " : "", io.KeyAlt ? "ALT " : "", io.KeySuper ? "SUPER " : ""); - - ImGui::Text("WantCaptureMouse: %s", io.WantCaptureMouse ? "true" : "false"); - ImGui::Text("WantCaptureKeyboard: %s", io.WantCaptureKeyboard ? "true" : "false"); - ImGui::Text("WantTextInput: %s", io.WantTextInput ? "true" : "false"); - - ImGui::Button("Hovering me sets the\nkeyboard capture flag"); - if (ImGui::IsItemHovered()) - ImGui::CaptureKeyboardFromApp(true); - ImGui::SameLine(); - ImGui::Button("Holding me clears the\nthe keyboard capture flag"); - if (ImGui::IsItemActive()) - ImGui::CaptureKeyboardFromApp(false); - - ImGui::TreePop(); - } - if (ImGui::TreeNode("Mouse cursors")) { - ImGui::TextWrapped("Your application can render a different mouse cursor based on what ImGui::GetMouseCursor() returns. You can also set io.MouseDrawCursor to ask ImGui to render the cursor for you in software."); - ImGui::Checkbox("io.MouseDrawCursor", &ImGui::GetIO().MouseDrawCursor); ImGui::Text("Hover to see mouse cursors:"); + ImGui::SameLine(); ShowHelpMarker("Your application can render a different mouse cursor based on what ImGui::GetMouseCursor() returns. If software cursor rendering (io.MouseDrawCursor) is set ImGui will draw the right cursor for you, otherwise your backend needs to handle it."); for (int i = 0; i < ImGuiMouseCursor_Count_; i++) { char label[32]; @@ -2014,9 +2015,11 @@ static void ShowExampleMenuFile() ImGui::EndChild(); static float f = 0.5f; static int n = 0; + static bool b = true; ImGui::SliderFloat("Value", &f, 0.0f, 1.0f); ImGui::InputFloat("Input", &f, 0.1f); ImGui::Combo("Combo", &n, "Yes\0No\0Maybe\0\0"); + ImGui::Checkbox("Check", &b); ImGui::EndMenu(); } if (ImGui::BeginMenu("Colors")) From be9628494a95748d86757920d664961b7ce91646 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 8 Aug 2017 18:04:31 +0800 Subject: [PATCH 191/921] Demo: Rearranged everything under Widgets in a more consistent way. --- imgui_demo.cpp | 468 +++++++++++++++++++++++++------------------------ 1 file changed, 236 insertions(+), 232 deletions(-) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index ac40ae97c..69d878459 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -260,6 +260,133 @@ void ImGui::ShowTestWindow(bool* p_open) if (ImGui::CollapsingHeader("Widgets")) { + + if (ImGui::TreeNode("Basic")) + { + static int clicked = 0; + if (ImGui::Button("Button")) + clicked++; + if (clicked & 1) + { + ImGui::SameLine(); + ImGui::Text("Thanks for clicking me!"); + } + + static bool check = true; + ImGui::Checkbox("checkbox", &check); + + static int e = 0; + ImGui::RadioButton("radio a", &e, 0); ImGui::SameLine(); + ImGui::RadioButton("radio b", &e, 1); ImGui::SameLine(); + ImGui::RadioButton("radio c", &e, 2); + + // Color buttons, demonstrate using PushID() to add unique identifier in the ID stack, and changing style. + for (int i = 0; i < 7; i++) + { + if (i > 0) ImGui::SameLine(); + ImGui::PushID(i); + ImGui::PushStyleColor(ImGuiCol_Button, ImColor::HSV(i/7.0f, 0.6f, 0.6f)); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImColor::HSV(i/7.0f, 0.7f, 0.7f)); + ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImColor::HSV(i/7.0f, 0.8f, 0.8f)); + ImGui::Button("Click"); + ImGui::PopStyleColor(3); + ImGui::PopID(); + } + + ImGui::Text("Hover over me"); + if (ImGui::IsItemHovered()) + ImGui::SetTooltip("I am a tooltip"); + + ImGui::SameLine(); + ImGui::Text("- or me"); + if (ImGui::IsItemHovered()) + { + ImGui::BeginTooltip(); + ImGui::Text("I am a fancy tooltip"); + static float arr[] = { 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f }; + ImGui::PlotLines("Curve", arr, IM_ARRAYSIZE(arr)); + ImGui::EndTooltip(); + } + + // Testing IMGUI_ONCE_UPON_A_FRAME macro + //for (int i = 0; i < 5; i++) + //{ + // IMGUI_ONCE_UPON_A_FRAME + // { + // ImGui::Text("This will be displayed only once."); + // } + //} + + ImGui::Separator(); + + ImGui::LabelText("label", "Value"); + + static int item = 1; + ImGui::Combo("combo", &item, "aaaa\0bbbb\0cccc\0dddd\0eeee\0\0"); // Combo using values packed in a single constant string (for really quick combo) + + const char* items[] = { "AAAA", "BBBB", "CCCC", "DDDD", "EEEE", "FFFF", "GGGG", "HHHH", "IIII", "JJJJ", "KKKK" }; + static int item2 = -1; + ImGui::Combo("combo scroll", &item2, items, IM_ARRAYSIZE(items)); // Combo using proper array. You can also pass a callback to retrieve array value, no need to create/copy an array just for that. + + { + static char str0[128] = "Hello, world!"; + static int i0=123; + static float f0=0.001f; + ImGui::InputText("input text", str0, IM_ARRAYSIZE(str0)); + ImGui::SameLine(); ShowHelpMarker("Hold SHIFT or use mouse to select text.\n" "CTRL+Left/Right to word jump.\n" "CTRL+A or double-click to select all.\n" "CTRL+X,CTRL+C,CTRL+V clipboard.\n" "CTRL+Z,CTRL+Y undo/redo.\n" "ESCAPE to revert.\n"); + + ImGui::InputInt("input int", &i0); + ImGui::SameLine(); ShowHelpMarker("You can apply arithmetic operators +,*,/ on numerical values.\n e.g. [ 100 ], input \'*2\', result becomes [ 200 ]\nUse +- to subtract.\n"); + + ImGui::InputFloat("input float", &f0, 0.01f, 1.0f); + + static float vec4a[4] = { 0.10f, 0.20f, 0.30f, 0.44f }; + ImGui::InputFloat3("input float3", vec4a); + } + + { + static int i1=50, i2=42; + ImGui::DragInt("drag int", &i1, 1); + ImGui::SameLine(); ShowHelpMarker("Click and drag to edit value.\nHold SHIFT/ALT for faster/slower edit.\nDouble-click or CTRL+click to input value."); + + ImGui::DragInt("drag int 0..100", &i2, 1, 0, 100, "%.0f%%"); + + static float f1=1.00f, f2=0.0067f; + ImGui::DragFloat("drag float", &f1, 0.005f); + ImGui::DragFloat("drag small float", &f2, 0.0001f, 0.0f, 0.0f, "%.06f ns"); + } + + { + static int i1=0; + ImGui::SliderInt("slider int", &i1, -1, 3); + ImGui::SameLine(); ShowHelpMarker("CTRL+click to input value."); + + static float f1=0.123f, f2=0.0f; + ImGui::SliderFloat("slider float", &f1, 0.0f, 1.0f, "ratio = %.3f"); + ImGui::SliderFloat("slider log float", &f2, -10.0f, 10.0f, "%.4f", 3.0f); + static float angle = 0.0f; + ImGui::SliderAngle("slider angle", &angle); + } + + static float col1[3] = { 1.0f,0.0f,0.2f }; + static float col2[4] = { 0.4f,0.7f,0.0f,0.5f }; + ImGui::ColorEdit3("color 1", col1); + ImGui::SameLine(); ShowHelpMarker("Click on the colored square to open a color picker.\nRight-click on the colored square to show options.\nCTRL+click on individual component to input value.\n"); + + ImGui::ColorEdit4("color 2", col2); + + const char* listbox_items[] = { "Apple", "Banana", "Cherry", "Kiwi", "Mango", "Orange", "Pineapple", "Strawberry", "Watermelon" }; + static int listbox_item_current = 1; + ImGui::ListBox("listbox\n(single select)", &listbox_item_current, listbox_items, IM_ARRAYSIZE(listbox_items), 4); + + //static int listbox_item_current2 = 2; + //ImGui::PushItemWidth(-1); + //ImGui::ListBox("##listbox2", &listbox_item_current2, listbox_items, IM_ARRAYSIZE(listbox_items), 4); + //ImGui::PopItemWidth(); + + ImGui::TreePop(); + } + if (ImGui::TreeNode("Trees")) { if (ImGui::TreeNode("Basic trees")) @@ -353,56 +480,62 @@ void ImGui::ShowTestWindow(bool* p_open) ImGui::TreePop(); } - if (ImGui::TreeNode("Colored Text")) + if (ImGui::TreeNode("Text")) { - // Using shortcut. You can use PushStyleColor()/PopStyleColor() for more flexibility. - ImGui::TextColored(ImVec4(1.0f,0.0f,1.0f,1.0f), "Pink"); - ImGui::TextColored(ImVec4(1.0f,1.0f,0.0f,1.0f), "Yellow"); - ImGui::TextDisabled("Disabled"); - ImGui::TreePop(); - } + if (ImGui::TreeNode("Colored Text")) + { + // Using shortcut. You can use PushStyleColor()/PopStyleColor() for more flexibility. + ImGui::TextColored(ImVec4(1.0f,0.0f,1.0f,1.0f), "Pink"); + ImGui::TextColored(ImVec4(1.0f,1.0f,0.0f,1.0f), "Yellow"); + ImGui::TextDisabled("Disabled"); + ImGui::SameLine(); ShowHelpMarker("The TextDisabled color is stored in ImGuiStyle."); + ImGui::TreePop(); + } - if (ImGui::TreeNode("Word Wrapping")) - { - // Using shortcut. You can use PushTextWrapPos()/PopTextWrapPos() for more flexibility. - ImGui::TextWrapped("This text should automatically wrap on the edge of the window. The current implementation for text wrapping follows simple rules suitable for English and possibly other languages."); - ImGui::Spacing(); + if (ImGui::TreeNode("Word Wrapping")) + { + // Using shortcut. You can use PushTextWrapPos()/PopTextWrapPos() for more flexibility. + ImGui::TextWrapped("This text should automatically wrap on the edge of the window. The current implementation for text wrapping follows simple rules suitable for English and possibly other languages."); + ImGui::Spacing(); - static float wrap_width = 200.0f; - ImGui::SliderFloat("Wrap width", &wrap_width, -20, 600, "%.0f"); + static float wrap_width = 200.0f; + ImGui::SliderFloat("Wrap width", &wrap_width, -20, 600, "%.0f"); - ImGui::Text("Test paragraph 1:"); - ImVec2 pos = ImGui::GetCursorScreenPos(); - ImGui::GetWindowDrawList()->AddRectFilled(ImVec2(pos.x + wrap_width, pos.y), ImVec2(pos.x + wrap_width + 10, pos.y + ImGui::GetTextLineHeight()), IM_COL32(255,0,255,255)); - ImGui::PushTextWrapPos(ImGui::GetCursorPos().x + wrap_width); - ImGui::Text("The lazy dog is a good dog. This paragraph is made to fit within %.0f pixels. Testing a 1 character word. The quick brown fox jumps over the lazy dog.", wrap_width); - ImGui::GetWindowDrawList()->AddRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), IM_COL32(255,255,0,255)); - ImGui::PopTextWrapPos(); + ImGui::Text("Test paragraph 1:"); + ImVec2 pos = ImGui::GetCursorScreenPos(); + ImGui::GetWindowDrawList()->AddRectFilled(ImVec2(pos.x + wrap_width, pos.y), ImVec2(pos.x + wrap_width + 10, pos.y + ImGui::GetTextLineHeight()), IM_COL32(255,0,255,255)); + ImGui::PushTextWrapPos(ImGui::GetCursorPos().x + wrap_width); + ImGui::Text("The lazy dog is a good dog. This paragraph is made to fit within %.0f pixels. Testing a 1 character word. The quick brown fox jumps over the lazy dog.", wrap_width); + ImGui::GetWindowDrawList()->AddRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), IM_COL32(255,255,0,255)); + ImGui::PopTextWrapPos(); - ImGui::Text("Test paragraph 2:"); - pos = ImGui::GetCursorScreenPos(); - ImGui::GetWindowDrawList()->AddRectFilled(ImVec2(pos.x + wrap_width, pos.y), ImVec2(pos.x + wrap_width + 10, pos.y + ImGui::GetTextLineHeight()), IM_COL32(255,0,255,255)); - ImGui::PushTextWrapPos(ImGui::GetCursorPos().x + wrap_width); - ImGui::Text("aaaaaaaa bbbbbbbb, c cccccccc,dddddddd. d eeeeeeee ffffffff. gggggggg!hhhhhhhh"); - ImGui::GetWindowDrawList()->AddRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), IM_COL32(255,255,0,255)); - ImGui::PopTextWrapPos(); + ImGui::Text("Test paragraph 2:"); + pos = ImGui::GetCursorScreenPos(); + ImGui::GetWindowDrawList()->AddRectFilled(ImVec2(pos.x + wrap_width, pos.y), ImVec2(pos.x + wrap_width + 10, pos.y + ImGui::GetTextLineHeight()), IM_COL32(255,0,255,255)); + ImGui::PushTextWrapPos(ImGui::GetCursorPos().x + wrap_width); + ImGui::Text("aaaaaaaa bbbbbbbb, c cccccccc,dddddddd. d eeeeeeee ffffffff. gggggggg!hhhhhhhh"); + ImGui::GetWindowDrawList()->AddRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), IM_COL32(255,255,0,255)); + ImGui::PopTextWrapPos(); - ImGui::TreePop(); - } + ImGui::TreePop(); + } - if (ImGui::TreeNode("UTF-8 Text")) - { - // UTF-8 test with Japanese characters - // (needs a suitable font, try Arial Unicode or M+ fonts http://mplus-fonts.sourceforge.jp/mplus-outline-fonts/index-en.html) - // Most compiler appears to support UTF-8 in source code (with Visual Studio you need to save your file as 'UTF-8 without signature') - // However for the sake for maximum portability here we are *not* including raw UTF-8 character in this source file, instead we encode the string with hexadecimal constants. - // In your own application be reasonable and use UTF-8 in source or retrieve the data from file system! - // Note that characters values are preserved even if the font cannot be displayed, so you can safely copy & paste garbled characters into another application. - ImGui::TextWrapped("CJK text will only appears if the font was loaded with the appropriate CJK character ranges. Call io.Font->LoadFromFileTTF() manually to load extra character ranges."); - ImGui::Text("Hiragana: \xe3\x81\x8b\xe3\x81\x8d\xe3\x81\x8f\xe3\x81\x91\xe3\x81\x93 (kakikukeko)"); - ImGui::Text("Kanjis: \xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e (nihongo)"); - static char buf[32] = "\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e"; - ImGui::InputText("UTF-8 input", buf, IM_ARRAYSIZE(buf)); + if (ImGui::TreeNode("UTF-8 Text")) + { + // UTF-8 test with Japanese characters + // (needs a suitable font, try Arial Unicode or M+ fonts http://mplus-fonts.sourceforge.jp/mplus-outline-fonts/index-en.html) + // - From C++11 you can use the u8"my text" syntax to encode literal strings as UTF-8 + // - For earlier compiler, you may be able to encode your sources as UTF-8 (e.g. Visual Studio save your file as 'UTF-8 without signature') + // - HOWEVER, FOR THIS DEMO FILE, BECAUSE WE WANT TO SUPPORT COMPILER, WE ARE *NOT* INCLUDING RAW UTF-8 CHARACTERS IN THIS SOURCE FILE. + // Instead we are encoding a few string with hexadecimal constants. Don't do this in your application! + // Note that characters values are preserved even by InputText() if the font cannot be displayed, so you can safely copy & paste garbled characters into another application. + ImGui::TextWrapped("CJK text will only appears if the font was loaded with the appropriate CJK character ranges. Call io.Font->LoadFromFileTTF() manually to load extra character ranges."); + ImGui::Text("Hiragana: \xe3\x81\x8b\xe3\x81\x8d\xe3\x81\x8f\xe3\x81\x91\xe3\x81\x93 (kakikukeko)"); + ImGui::Text("Kanjis: \xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e (nihongo)"); + static char buf[32] = "\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e"; // "nihongo" + ImGui::InputText("UTF-8 input", buf, IM_ARRAYSIZE(buf)); + ImGui::TreePop(); + } ImGui::TreePop(); } @@ -542,127 +675,71 @@ void ImGui::ShowTestWindow(bool* p_open) ImGui::TreePop(); } - static int clicked = 0; - if (ImGui::Button("Button")) - clicked++; - if (clicked & 1) + + if (ImGui::TreeNode("Plots widgets")) { - ImGui::SameLine(); - ImGui::Text("Thanks for clicking me!"); - } + static bool animate = true; + ImGui::Checkbox("Animate", &animate); - static bool check = true; - ImGui::Checkbox("checkbox", &check); - - static int e = 0; - ImGui::RadioButton("radio a", &e, 0); ImGui::SameLine(); - ImGui::RadioButton("radio b", &e, 1); ImGui::SameLine(); - ImGui::RadioButton("radio c", &e, 2); - - // Color buttons, demonstrate using PushID() to add unique identifier in the ID stack, and changing style. - for (int i = 0; i < 7; i++) - { - if (i > 0) ImGui::SameLine(); - ImGui::PushID(i); - ImGui::PushStyleColor(ImGuiCol_Button, ImColor::HSV(i/7.0f, 0.6f, 0.6f)); - ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImColor::HSV(i/7.0f, 0.7f, 0.7f)); - ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImColor::HSV(i/7.0f, 0.8f, 0.8f)); - ImGui::Button("Click"); - ImGui::PopStyleColor(3); - ImGui::PopID(); - } - - ImGui::Text("Hover over me"); - if (ImGui::IsItemHovered()) - ImGui::SetTooltip("I am a tooltip"); - - ImGui::SameLine(); - ImGui::Text("- or me"); - if (ImGui::IsItemHovered()) - { - ImGui::BeginTooltip(); - ImGui::Text("I am a fancy tooltip"); static float arr[] = { 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f }; - ImGui::PlotLines("Curve", arr, IM_ARRAYSIZE(arr)); - ImGui::EndTooltip(); + ImGui::PlotLines("Frame Times", arr, IM_ARRAYSIZE(arr)); + + // Create a dummy array of contiguous float values to plot + // Tip: If your float aren't contiguous but part of a structure, you can pass a pointer to your first float and the sizeof() of your structure in the Stride parameter. + static float values[90] = { 0 }; + static int values_offset = 0; + static float refresh_time = 0.0f; + if (!animate || refresh_time == 0.0f) + refresh_time = ImGui::GetTime(); + while (refresh_time < ImGui::GetTime()) // Create dummy data at fixed 60 hz rate for the demo + { + static float phase = 0.0f; + values[values_offset] = cosf(phase); + values_offset = (values_offset+1) % IM_ARRAYSIZE(values); + phase += 0.10f*values_offset; + refresh_time += 1.0f/60.0f; + } + ImGui::PlotLines("Lines", values, IM_ARRAYSIZE(values), values_offset, "avg 0.0", -1.0f, 1.0f, ImVec2(0,80)); + ImGui::PlotHistogram("Histogram", arr, IM_ARRAYSIZE(arr), 0, NULL, 0.0f, 1.0f, ImVec2(0,80)); + + // Use functions to generate output + // FIXME: This is rather awkward because current plot API only pass in indices. We probably want an API passing floats and user provide sample rate/count. + struct Funcs + { + static float Sin(void*, int i) { return sinf(i * 0.1f); } + static float Saw(void*, int i) { return (i & 1) ? 1.0f : -1.0f; } + }; + static int func_type = 0, display_count = 70; + ImGui::Separator(); + ImGui::PushItemWidth(100); ImGui::Combo("func", &func_type, "Sin\0Saw\0"); ImGui::PopItemWidth(); + ImGui::SameLine(); + ImGui::SliderInt("Sample count", &display_count, 1, 400); + float (*func)(void*, int) = (func_type == 0) ? Funcs::Sin : Funcs::Saw; + ImGui::PlotLines("Lines", func, NULL, display_count, 0, NULL, -1.0f, 1.0f, ImVec2(0,80)); + ImGui::PlotHistogram("Histogram", func, NULL, display_count, 0, NULL, -1.0f, 1.0f, ImVec2(0,80)); + ImGui::Separator(); + + // Animate a simple progress bar + static float progress = 0.0f, progress_dir = 1.0f; + if (animate) + { + progress += progress_dir * 0.4f * ImGui::GetIO().DeltaTime; + if (progress >= +1.1f) { progress = +1.1f; progress_dir *= -1.0f; } + if (progress <= -0.1f) { progress = -0.1f; progress_dir *= -1.0f; } + } + + // Typically we would use ImVec2(-1.0f,0.0f) to use all available width, or ImVec2(width,0.0f) for a specified width. ImVec2(0.0f,0.0f) uses ItemWidth. + ImGui::ProgressBar(progress, ImVec2(0.0f,0.0f)); + ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); + ImGui::Text("Progress Bar"); + + float progress_saturated = (progress < 0.0f) ? 0.0f : (progress > 1.0f) ? 1.0f : progress; + char buf[32]; + sprintf(buf, "%d/%d", (int)(progress_saturated*1753), 1753); + ImGui::ProgressBar(progress, ImVec2(0.f,0.f), buf); + ImGui::TreePop(); } - // Testing IMGUI_ONCE_UPON_A_FRAME macro - //for (int i = 0; i < 5; i++) - //{ - // IMGUI_ONCE_UPON_A_FRAME - // { - // ImGui::Text("This will be displayed only once."); - // } - //} - - ImGui::Separator(); - - ImGui::LabelText("label", "Value"); - - static int item = 1; - ImGui::Combo("combo", &item, "aaaa\0bbbb\0cccc\0dddd\0eeee\0\0"); // Combo using values packed in a single constant string (for really quick combo) - - const char* items[] = { "AAAA", "BBBB", "CCCC", "DDDD", "EEEE", "FFFF", "GGGG", "HHHH", "IIII", "JJJJ", "KKKK" }; - static int item2 = -1; - ImGui::Combo("combo scroll", &item2, items, IM_ARRAYSIZE(items)); // Combo using proper array. You can also pass a callback to retrieve array value, no need to create/copy an array just for that. - - { - static char str0[128] = "Hello, world!"; - static int i0=123; - static float f0=0.001f; - ImGui::InputText("input text", str0, IM_ARRAYSIZE(str0)); - ImGui::SameLine(); ShowHelpMarker("Hold SHIFT or use mouse to select text.\n" "CTRL+Left/Right to word jump.\n" "CTRL+A or double-click to select all.\n" "CTRL+X,CTRL+C,CTRL+V clipboard.\n" "CTRL+Z,CTRL+Y undo/redo.\n" "ESCAPE to revert.\n"); - - ImGui::InputInt("input int", &i0); - ImGui::SameLine(); ShowHelpMarker("You can apply arithmetic operators +,*,/ on numerical values.\n e.g. [ 100 ], input \'*2\', result becomes [ 200 ]\nUse +- to subtract.\n"); - - ImGui::InputFloat("input float", &f0, 0.01f, 1.0f); - - static float vec4a[4] = { 0.10f, 0.20f, 0.30f, 0.44f }; - ImGui::InputFloat3("input float3", vec4a); - } - - { - static int i1=50, i2=42; - ImGui::DragInt("drag int", &i1, 1); - ImGui::SameLine(); ShowHelpMarker("Click and drag to edit value.\nHold SHIFT/ALT for faster/slower edit.\nDouble-click or CTRL+click to input value."); - - ImGui::DragInt("drag int 0..100", &i2, 1, 0, 100, "%.0f%%"); - - static float f1=1.00f, f2=0.0067f; - ImGui::DragFloat("drag float", &f1, 0.005f); - ImGui::DragFloat("drag small float", &f2, 0.0001f, 0.0f, 0.0f, "%.06f ns"); - } - - { - static int i1=0; - ImGui::SliderInt("slider int", &i1, -1, 3); - ImGui::SameLine(); ShowHelpMarker("CTRL+click to input value."); - - static float f1=0.123f, f2=0.0f; - ImGui::SliderFloat("slider float", &f1, 0.0f, 1.0f, "ratio = %.3f"); - ImGui::SliderFloat("slider log float", &f2, -10.0f, 10.0f, "%.4f", 3.0f); - static float angle = 0.0f; - ImGui::SliderAngle("slider angle", &angle); - } - - static float col1[3] = { 1.0f,0.0f,0.2f }; - static float col2[4] = { 0.4f,0.7f,0.0f,0.5f }; - ImGui::ColorEdit3("color 1", col1); - ImGui::SameLine(); ShowHelpMarker("Click on the colored square to open a color picker.\nRight-click on the colored square to show options.\nCTRL+click on individual component to input value.\n"); - - ImGui::ColorEdit4("color 2", col2); - - const char* listbox_items[] = { "Apple", "Banana", "Cherry", "Kiwi", "Mango", "Orange", "Pineapple", "Strawberry", "Watermelon" }; - static int listbox_item_current = 1; - ImGui::ListBox("listbox\n(single select)", &listbox_item_current, listbox_items, IM_ARRAYSIZE(listbox_items), 4); - - //static int listbox_item_current2 = 2; - //ImGui::PushItemWidth(-1); - //ImGui::ListBox("##listbox2", &listbox_item_current2, listbox_items, IM_ARRAYSIZE(listbox_items), 4); - //ImGui::PopItemWidth(); - if (ImGui::TreeNode("Color/Picker Widgets")) { static ImVec4 color = ImColor(114, 144, 154, 200); @@ -786,21 +863,15 @@ void ImGui::ShowTestWindow(bool* p_open) if (ImGui::TreeNode("Range Widgets")) { - ImGui::Unindent(); - static float begin = 10, end = 90; static int begin_i = 100, end_i = 1000; ImGui::DragFloatRange2("range", &begin, &end, 0.25f, 0.0f, 100.0f, "Min: %.1f %%", "Max: %.1f %%"); ImGui::DragIntRange2("range int (no bounds)", &begin_i, &end_i, 5, 0, 0, "Min: %.0f units", "Max: %.0f units"); - - ImGui::Indent(); ImGui::TreePop(); } if (ImGui::TreeNode("Multi-component Widgets")) { - ImGui::Unindent(); - static float vec4f[4] = { 0.10f, 0.20f, 0.30f, 0.44f }; static int vec4i[4] = { 1, 5, 100, 255 }; @@ -827,13 +898,11 @@ void ImGui::ShowTestWindow(bool* p_open) ImGui::DragInt4("drag int4", vec4i, 1, 0, 255); ImGui::SliderInt4("slider int4", vec4i, 0, 255); - ImGui::Indent(); ImGui::TreePop(); } if (ImGui::TreeNode("Vertical Sliders")) { - ImGui::Unindent(); const float spacing = 4; ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(spacing, spacing)); @@ -893,75 +962,10 @@ void ImGui::ShowTestWindow(bool* p_open) } ImGui::PopID(); ImGui::PopStyleVar(); - - ImGui::Indent(); ImGui::TreePop(); } } - if (ImGui::CollapsingHeader("Plots widgets")) - { - static bool animate = true; - ImGui::Checkbox("Animate", &animate); - - static float arr[] = { 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f }; - ImGui::PlotLines("Frame Times", arr, IM_ARRAYSIZE(arr)); - - // Create a dummy array of contiguous float values to plot - // Tip: If your float aren't contiguous but part of a structure, you can pass a pointer to your first float and the sizeof() of your structure in the Stride parameter. - static float values[90] = { 0 }; - static int values_offset = 0; - static float refresh_time = 0.0f; - if (!animate || refresh_time == 0.0f) - refresh_time = ImGui::GetTime(); - while (refresh_time < ImGui::GetTime()) // Create dummy data at fixed 60 hz rate for the demo - { - static float phase = 0.0f; - values[values_offset] = cosf(phase); - values_offset = (values_offset+1) % IM_ARRAYSIZE(values); - phase += 0.10f*values_offset; - refresh_time += 1.0f/60.0f; - } - ImGui::PlotLines("Lines", values, IM_ARRAYSIZE(values), values_offset, "avg 0.0", -1.0f, 1.0f, ImVec2(0,80)); - ImGui::PlotHistogram("Histogram", arr, IM_ARRAYSIZE(arr), 0, NULL, 0.0f, 1.0f, ImVec2(0,80)); - - // Use functions to generate output - // FIXME: This is rather awkward because current plot API only pass in indices. We probably want an API passing floats and user provide sample rate/count. - struct Funcs - { - static float Sin(void*, int i) { return sinf(i * 0.1f); } - static float Saw(void*, int i) { return (i & 1) ? 1.0f : -1.0f; } - }; - static int func_type = 0, display_count = 70; - ImGui::Separator(); - ImGui::PushItemWidth(100); ImGui::Combo("func", &func_type, "Sin\0Saw\0"); ImGui::PopItemWidth(); - ImGui::SameLine(); - ImGui::SliderInt("Sample count", &display_count, 1, 400); - float (*func)(void*, int) = (func_type == 0) ? Funcs::Sin : Funcs::Saw; - ImGui::PlotLines("Lines", func, NULL, display_count, 0, NULL, -1.0f, 1.0f, ImVec2(0,80)); - ImGui::PlotHistogram("Histogram", func, NULL, display_count, 0, NULL, -1.0f, 1.0f, ImVec2(0,80)); - ImGui::Separator(); - - // Animate a simple progress bar - static float progress = 0.0f, progress_dir = 1.0f; - if (animate) - { - progress += progress_dir * 0.4f * ImGui::GetIO().DeltaTime; - if (progress >= +1.1f) { progress = +1.1f; progress_dir *= -1.0f; } - if (progress <= -0.1f) { progress = -0.1f; progress_dir *= -1.0f; } - } - - // Typically we would use ImVec2(-1.0f,0.0f) to use all available width, or ImVec2(width,0.0f) for a specified width. ImVec2(0.0f,0.0f) uses ItemWidth. - ImGui::ProgressBar(progress, ImVec2(0.0f,0.0f)); - ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); - ImGui::Text("Progress Bar"); - - float progress_saturated = (progress < 0.0f) ? 0.0f : (progress > 1.0f) ? 1.0f : progress; - char buf[32]; - sprintf(buf, "%d/%d", (int)(progress_saturated*1753), 1753); - ImGui::ProgressBar(progress, ImVec2(0.f,0.f), buf); - } - if (ImGui::CollapsingHeader("Layout")) { if (ImGui::TreeNode("Child regions")) From 55b99d753c651d9f75d3285a6ac53e42a366b940 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 8 Aug 2017 23:12:23 +0800 Subject: [PATCH 192/921] Minor string typo --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 05a88f338..87bae6abd 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -10483,7 +10483,7 @@ void ImGui::ShowMetricsWindow(bool* p_open) ImGui::Text("HoveredRootWindow: '%s'", g.HoveredRootWindow ? g.HoveredRootWindow->Name : "NULL"); ImGui::Text("HoveredID: 0x%08X/0x%08X", g.HoveredId, g.HoveredIdPreviousFrame); // Data is "in-flight" so depending on when the Metrics window is called we may see current frame information or not ImGui::Text("ActiveID: 0x%08X/0x%08X", g.ActiveId, g.ActiveIdPreviousFrame); - ImGui::Text("ActiveIdWindow: '%s", g.ActiveIdWindow ? g.ActiveIdWindow->Name : "NULL"); + ImGui::Text("ActiveIdWindow: '%s'", g.ActiveIdWindow ? g.ActiveIdWindow->Name : "NULL"); ImGui::TreePop(); } } From 43e2abbee3409bf445f690462384bd217b7fd974 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 9 Aug 2017 20:27:59 +0800 Subject: [PATCH 193/921] Comments, FAQ entry (#586, #1105) --- README.md | 3 ++- imgui.cpp | 12 +++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 48dd80dd0..09ed595e4 100644 --- a/README.md +++ b/README.md @@ -144,11 +144,12 @@ The library started its life and is best known as "ImGui" only due to the fact t
I integrated ImGui in my engine and the text or lines are blurry..
I integrated ImGui in my engine and some elements are disappearing when I move windows around..
How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs. -
How can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application? +
How can I tell when ImGui wants my mouse/keyboard inputs VS when I can pass them to my application?
How can I load a different font than the default?
How can I easily use icons in my application?
How can I load multiple fonts?
How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic? +
How can I preserve my ImGui context across reloading a DLL? (loss of the global/static variables)
How can I use the drawing facilities without an ImGui window? (using ImDrawList API) See the FAQ in imgui.cpp for answers. diff --git a/imgui.cpp b/imgui.cpp index 87bae6abd..d8ed90975 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -26,11 +26,12 @@ - I integrated ImGui in my engine and the text or lines are blurry.. - I integrated ImGui in my engine and some elements are clipping or disappearing when I move windows around.. - How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs. - - How can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application? + - How can I tell when ImGui wants my mouse/keyboard inputs VS when I can pass them to my application? - How can I load a different font than the default? - How can I easily use icons in my application? - How can I load multiple fonts? - How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic? + - How can I preserve my ImGui context across reloading a DLL? (loss of the global/static variables) - How can I use the drawing facilities without an ImGui window? (using ImDrawList API) - ISSUES & TODO-LIST - CODE @@ -405,7 +406,7 @@ 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 can I tell when ImGui wants my mouse/keyboard inputs and when I can pass them to my application? + Q: How can I tell when ImGui wants my mouse/keyboard inputs VS when I can pass them to my application? A: You can read the 'io.WantCaptureMouse'/'io.WantCaptureKeyboard'/'ioWantTextInput' flags from the ImGuiIO structure. - When 'io.WantCaptureMouse' or 'io.WantCaptureKeyboard' flags are set you may want to discard/hide the inputs from the rest of your application. - When 'io.WantTextInput' is set to may want to notify your OS to popup an on-screen keyboard, if available (e.g. on a mobile phone, or console without a keyboard). @@ -466,9 +467,13 @@ As for text input, depends on you passing the right character code to io.AddInputCharacter(). The example applications do that. + Q: How can I preserve my ImGui context across reloading a DLL? (loss of the global/static variables) + A: Create your own context 'ctx = CreateContext()' + 'SetCurrentContext(ctx)' and your own font atlas 'ctx->GetIO().Fonts = new ImFontAtlas()' so you don't rely on the default globals. + Q: How can I use the drawing facilities without an ImGui window? (using ImDrawList API) A: The easiest way is to create a dummy window. Call Begin() with NoTitleBar|NoResize|NoMove|NoScrollbar|NoSavedSettings|NoInputs flag, zero background alpha, then retrieve the ImDrawList* via GetWindowDrawList() and draw to it in any way you like. + You can also perfectly create a standalone ImDrawList instance _but_ you need ImGui to be initialized because ImDrawList pulls from ImGui data to retrieve the coordinates of the white pixel. - tip: the construct 'IMGUI_ONCE_UPON_A_FRAME { ... }' will run the block of code only once a frame. You can use it to quickly add custom UI in the middle of a deep nested inner loop in your code. - tip: you can create widgets without a Begin()/End() block, they will go in an implicit window called "Debug" @@ -740,12 +745,13 @@ static void ImeSetInputScreenPosFn_DefaultImpl(int x, int y); // Context //----------------------------------------------------------------------------- -// Default font atlas storage . +// Default font atlas storage. // New contexts always point by default to this font atlas. It can be changed by reassigning the GetIO().Fonts variable. static ImFontAtlas GImDefaultFontAtlas; // Default context storage + current context pointer. // Implicitely used by all ImGui functions. Always assumed to be != NULL. Change to a different context by calling ImGui::SetCurrentContext() +// If you are hot-reloading this code in a DLL you will lose the static/global variables. Create your own context+font atlas instead of relying on those default (see FAQ entry "How can I preserve my ImGui context across reloading a DLL?"). // ImGui is currently not thread-safe because of this variable. If you want thread-safety to allow N threads to access N different contexts, you might work around it by: // - Having multiple instances of the ImGui code compiled inside different namespace (easiest/safest, if you have a finite number of contexts) // - or: Changing this variable to be TLS. You may #define GImGui in imconfig.h for further custom hackery. Future development aim to make this context pointer explicit to all calls. Also read https://github.com/ocornut/imgui/issues/586 From 4fd148f4f972037421229ba343861a1c7497445d Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 9 Aug 2017 22:42:03 +0800 Subject: [PATCH 194/921] Added ImFontAtlas::GlyphRangesBuilder helper + doc --- extra_fonts/README.txt | 22 +++++++++++++++++++++- imgui.cpp | 24 +++++++++++++++++------- imgui.h | 15 ++++++++++++++- imgui_draw.cpp | 38 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 90 insertions(+), 9 deletions(-) diff --git a/extra_fonts/README.txt b/extra_fonts/README.txt index 82bc557a7..9a3114590 100644 --- a/extra_fonts/README.txt +++ b/extra_fonts/README.txt @@ -24,6 +24,7 @@ // Usage, e.g. ImGui::Text("%s Search", ICON_FA_SEARCH); + --------------------------------- FONTS LOADING INSTRUCTIONS --------------------------------- @@ -84,11 +85,27 @@ font->DisplayOffset.y += 1; // Render 1 pixel down +--------------------------------- + BUILDING CUSTOM GLYPH RANGES +--------------------------------- + + You can use the ImFontAtlas::GlyphRangesBuilder helper to create glyph ranges based on text input. + For exemple: for a game where your script is known, if you can feed your entire script to it and only build the characters the game needs. + + ImVector ranges; + ImFontAtlas::GlyphRangesBuilder builder; + builder.AddText("Hello world"); // Add a string (here "Hello world" contains 7 unique characters) + builder.AddChar(0x7262); // Add a specific character + builder.AddRanges(io.Fonts->GetGlyphRangesJapanese()); // Add one of the default ranges + builder.BuildRanges(&ranges); // Build the final result (ordered ranges with all the unique characters submitted) + io.Fonts->AddFontFromFileTTF("myfontfile.ttf", size_in_pixels, NULL, ranges.Data); + + --------------------------------- REMAPPING CODEPOINTS --------------------------------- - All your strings needs to use UTF-8 encoding. Specifying literal in your source code using a local code page (such as CP-923 for Japanese CP-1251 for Cyrillic) will not work. + All your strings needs to use UTF-8 encoding. Specifying literal in your source code using a local code page (such as CP-923 for Japanese CP-1251 for Cyrillic) will NOT work! In C++11 you can encode a string literal in UTF-8 by using the u8"hello" syntax. Otherwise you can convert yourself to UTF-8 or load text data from file already saved as UTF-8. You can also try to remap your local codepage characters to their Unicode codepoint using font->AddRemapChar(), but international users may have problems reading/editing your source code. @@ -169,6 +186,9 @@ Inconsolata http://www.levien.com/type/myfonts/inconsolata.html + Google Noto Fonts (worldwide languages) + https://www.google.com/get/noto/ + Adobe Source Code Pro: Monospaced font family for user interface and coding environments https://github.com/adobe-fonts/source-code-pro diff --git a/imgui.cpp b/imgui.cpp index d8ed90975..5f937212a 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -457,15 +457,25 @@ Q: How can I display and input non-Latin characters such as Chinese, Japanese, Korean, Cyrillic? A: When loading a font, pass custom Unicode ranges to specify the glyphs to load. - All your strings needs to use UTF-8 encoding. Specifying literal in your source code using a local code page (such as CP-923 for Japanese or CP-1251 for Cyrillic) will not work. - In C++11 you can encode a string literal in UTF-8 by using the u8"hello" syntax. Otherwise you can convert yourself to UTF-8 or load text data from file already saved as UTF-8. - You can also try to remap your local codepage characters to their Unicode codepoint using font->AddRemapChar(), but international users may have problems reading/editing your source code. - io.Fonts->AddFontFromFileTTF("myfontfile.ttf", size_in_pixels, NULL, io.Fonts->GetGlyphRangesJapanese()); // Load Japanese characters - io.Fonts->GetTexDataAsRGBA32() or GetTexDataAsAlpha8() - io.ImeWindowHandle = MY_HWND; // To input using Microsoft IME, give ImGui the hwnd of your application + // Add default Japanese ranges + io.Fonts->AddFontFromFileTTF("myfontfile.ttf", size_in_pixels, NULL, io.Fonts->GetGlyphRangesJapanese()); + + // Or create your own custom ranges (e.g. for a game you can feed your entire game script and only build the characters the game need) + ImVector ranges; + ImFontAtlas::GlyphRangesBuilder builder; + builder.AddText("Hello world"); // Add a string (here "Hello world" contains 7 unique characters) + builder.AddChar(0x7262); // Add a specific character + builder.AddRanges(io.Fonts->GetGlyphRangesJapanese()); // Add one of the default ranges + builder.BuildRanges(&ranges); // Build the final result (ordered ranges with all the unique characters submitted) + io.Fonts->AddFontFromFileTTF("myfontfile.ttf", size_in_pixels, NULL, ranges.Data); - As for text input, depends on you passing the right character code to io.AddInputCharacter(). The example applications do that. + All your strings needs to use UTF-8 encoding. In C++11 you can encode a string literal in UTF-8 by using the u8"hello" syntax. + Specifying literal in your source code using a local code page (such as CP-923 for Japanese or CP-1251 for Cyrillic) will NOT work! + Otherwise you can convert yourself to UTF-8 or load text data from file already saved as UTF-8. + + Text input: it is up to your application to pass the right character code to io.AddInputCharacter(). The applications in examples/ are doing that. + For languages using IME, on Windows you can copy the Hwnd of your application to io.ImeWindowHandle. The default implementation of io.ImeSetInputScreenPosFn() on Windows will set your IME position correctly. Q: How can I preserve my ImGui context across reloading a DLL? (loss of the global/static variables) A: Create your own context 'ctx = CreateContext()' + 'SetCurrentContext(ctx)' and your own font atlas 'ctx->GetIO().Fonts = new ImFontAtlas()' so you don't rely on the default globals. diff --git a/imgui.h b/imgui.h index 851a20ceb..8552fea03 100644 --- a/imgui.h +++ b/imgui.h @@ -1350,7 +1350,7 @@ struct ImFontAtlas void SetTexID(ImTextureID id) { TexID = id; } // Helpers to retrieve list of common Unicode ranges (2 value per range, values are inclusive, zero-terminated list) - // NB: Make sure that your string are UTF-8 and NOT in your local code page. In C++11, you can create a UTF-8 string literally using the u8"Hello world" syntax. See FAQ for details. + // NB: Make sure that your string are UTF-8 and NOT in your local code page. In C++11, you can create UTF-8 string literal using the u8"Hello world" syntax. See FAQ for details. IMGUI_API const ImWchar* GetGlyphRangesDefault(); // Basic Latin, Extended Latin IMGUI_API const ImWchar* GetGlyphRangesKorean(); // Default + Korean characters IMGUI_API const ImWchar* GetGlyphRangesJapanese(); // Default + Hiragana, Katakana, Half-Width, Selection of 1946 Ideographs @@ -1358,6 +1358,19 @@ struct ImFontAtlas IMGUI_API const ImWchar* GetGlyphRangesCyrillic(); // Default + about 400 Cyrillic characters IMGUI_API const ImWchar* GetGlyphRangesThai(); // Default + Thai characters + // Helpers to build glyph ranges from text data. Feed all your application strings/characters to it then call BuildRanges(). + struct GlyphRangesBuilder + { + ImVector UsedChars; // Store 1-bit per Unicode code point (0=unused, 1=used) + GlyphRangesBuilder() { UsedChars.resize(0x10000 / 8); memset(UsedChars.Data, 0, 0x10000 / 8); } + bool GetBit(int n) { return (UsedChars[n >> 3] & (1 << (n & 7))) != 0; } + void SetBit(int n) { UsedChars[n >> 3] |= 1 << (n & 7); } // Set bit 'c' in the array + void AddChar(ImWchar c) { SetBit(c); } // Add character + IMGUI_API void AddText(const char* text, const char* text_end = NULL); // Add string (each character of the UTF-8 string are added) + IMGUI_API void AddRanges(const ImWchar* ranges); // Add ranges, e.g. builder.AddRanges(ImFontAtlas::GetGlyphRangesDefault) to force add all of ASCII/Latin+Ext + IMGUI_API void BuildRanges(ImVector* out_ranges); // Output new ranges + }; + // Members // (Access texture data via GetTexData*() calls which will setup a default font for you.) ImTextureID TexID; // User data to refer to the texture once it has been uploaded to user's graphic systems. It is passed back to you during rendering via the ImDrawCmd structure. diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 42a87b47a..876fd7df7 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1694,6 +1694,44 @@ const ImWchar* ImFontAtlas::GetGlyphRangesThai() return &ranges[0]; } +//----------------------------------------------------------------------------- +// ImFontAtlas::GlyphRangesBuilder +//----------------------------------------------------------------------------- + +void ImFontAtlas::GlyphRangesBuilder::AddText(const char* text, const char* text_end) +{ + while (text_end ? (text < text_end) : *text) + { + unsigned int c = 0; + int c_len = ImTextCharFromUtf8(&c, text, text_end); + text += c_len; + if (c_len == 0) + break; + if (c < 0x10000) + AddChar((ImWchar)c); + } +} + +void ImFontAtlas::GlyphRangesBuilder::AddRanges(const ImWchar* ranges) +{ + for (; ranges[0]; ranges += 2) + for (ImWchar c = ranges[0]; c <= ranges[1]; c++) + AddChar(c); +} + +void ImFontAtlas::GlyphRangesBuilder::BuildRanges(ImVector* out_ranges) +{ + for (int n = 0; n < 0x10000; n++) + if (GetBit(n)) + { + out_ranges->push_back((ImWchar)n); + while (n < 0x10000 && GetBit(n + 1)) + n++; + out_ranges->push_back((ImWchar)n); + } + out_ranges->push_back(0); +} + //----------------------------------------------------------------------------- // ImFont //----------------------------------------------------------------------------- From fc5ab0cb8dc57a30f577d7f7a33f67b9cb37b334 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 9 Aug 2017 22:56:01 +0800 Subject: [PATCH 195/921] RenderCheckMark() tidying up --- imgui.cpp | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 5f937212a..5a688f733 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3102,20 +3102,13 @@ void ImGui::RenderCheckMark(ImVec2 pos, ImU32 col) { ImGuiContext& g = *GImGui; ImGuiWindow* window = GetCurrentWindow(); - - ImVec2 a, b, c; float start_x = (float)(int)(g.FontSize * 0.307f + 0.5f); float rem_third = (float)(int)((g.FontSize - start_x) / 3.0f); - a.x = pos.x + 0.5f + start_x; - b.x = a.x + rem_third; - c.x = a.x + rem_third * 3.0f; - b.y = pos.y - 1.0f + (float)(int)(g.Font->Ascent * (g.FontSize / g.Font->FontSize) + 0.5f) + (float)(int)(g.Font->DisplayOffset.y); - a.y = b.y - rem_third; - c.y = b.y - rem_third * 2.0f; - - window->DrawList->PathLineTo(a); - window->DrawList->PathLineTo(b); - window->DrawList->PathLineTo(c); + float bx = pos.x + 0.5f + start_x + rem_third; + float by = pos.y - 1.0f + (float)(int)(g.Font->Ascent * (g.FontSize / g.Font->FontSize) + 0.5f) + (float)(int)(g.Font->DisplayOffset.y); + window->DrawList->PathLineTo(ImVec2(bx - rem_third, by - rem_third)); + window->DrawList->PathLineTo(ImVec2(bx, by)); + window->DrawList->PathLineTo(ImVec2(bx + rem_third*2, by - rem_third*2)); window->DrawList->PathStroke(col, false); } From fed18d3203ff5ee656c62338f6059bb63bf25590 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 9 Aug 2017 23:04:26 +0800 Subject: [PATCH 196/921] Removed old ValueColor() helpers. (#346) --- imgui.cpp | 18 ++---------------- imgui.h | 2 -- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 5a688f733..36588819c 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -159,7 +159,8 @@ Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. Also read releases logs https://github.com/ocornut/imgui/releases for more details. - - 2017/07/30 (1.51) - removed ColorEditMode() and ImGuiColorEditMode in favor of ImGuiColorEditFlags and parameters to the various Color*() functions. The SetColorEditOptions() allows to initialize default but the user can still change them with right-click context menu. + - 2017/08/09 (1.51) - removed ValueColor() helpers, they are equivalent to calling Text(label) + SameLine() + ColorButton(). + - 2017/08/08 (1.51) - removed ColorEditMode() and ImGuiColorEditMode in favor of ImGuiColorEditFlags and parameters to the various Color*() functions. The SetColorEditOptions() allows to initialize default but the user can still change them with right-click context menu. - changed prototype of 'ColorEdit4(const char* label, float col[4], bool show_alpha = true)' to 'ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flags = 0)', where passing flags = 0x01 is a safe no-op (hello dodgy backward compatibility!). - check and run the demo window, under "Color/Picker Widgets", to understand the various new options. - changed prototype of rarely used 'ColorButton(ImVec4 col, bool small_height = false, bool outline_border = true)' to 'ColorButton(const char* desc_id, ImVec4 col, ImGuiColorEditFlags flags = 0, ImVec2 size = ImVec2(0,0))' - 2017/07/20 (1.51) - removed IsPosHoveringAnyWindow(ImVec2), which was partly broken and misleading. ASSERT + redirect user to io.WantCaptureMouse @@ -10243,21 +10244,6 @@ void ImGui::Value(const char* prefix, float v, const char* float_format) } } -// FIXME: May want to remove those helpers? -void ImGui::ValueColor(const char* prefix, const ImVec4& v) -{ - Text("%s: (%.2f,%.2f,%.2f,%.2f)", prefix, v.x, v.y, v.z, v.w); - SameLine(); - ColorButton(prefix, v); -} - -void ImGui::ValueColor(const char* prefix, ImU32 v) -{ - Text("%s: %08X", prefix, v); - SameLine(); - ColorButton(prefix, ColorConvertU32ToFloat4(v)); -} - //----------------------------------------------------------------------------- // PLATFORM DEPENDENT HELPERS //----------------------------------------------------------------------------- diff --git a/imgui.h b/imgui.h index 8552fea03..b3419557b 100644 --- a/imgui.h +++ b/imgui.h @@ -363,8 +363,6 @@ namespace ImGui IMGUI_API void Value(const char* prefix, int v); IMGUI_API void Value(const char* prefix, unsigned int v); IMGUI_API void Value(const char* prefix, float v, const char* float_format = NULL); - IMGUI_API void ValueColor(const char* prefix, const ImVec4& v); - IMGUI_API void ValueColor(const char* prefix, ImU32 v); // Tooltips IMGUI_API void SetTooltip(const char* fmt, ...) IM_PRINTFARGS(1); // set text tooltip under mouse-cursor, typically use with ImGui::IsItemHovered(). overidde any previous call to SetTooltip(). From 53d1b1e9296a9c6743fa4c574ffdb2b0aa1a1a49 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 10 Aug 2017 10:25:50 +0800 Subject: [PATCH 197/921] ColorPicker: Fixes for when ImGuiColorEditFlags_NoOptions flag is set: always read a default picker type + forward flag to sub ColorEdit widgets. (#346) --- imgui.cpp | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 36588819c..ef7a7a8c3 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9515,20 +9515,19 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl PushID(label); BeginGroup(); - if ((flags & ImGuiColorEditFlags_NoSidePreview) == 0) + if (!(flags & ImGuiColorEditFlags_NoSidePreview)) flags |= ImGuiColorEditFlags_NoSmallPreview; - if ((flags & ImGuiColorEditFlags_NoOptions) == 0) - { - // Context menu: display and store options. + // Context menu: display and store options. + if (!(flags & ImGuiColorEditFlags_NoOptions)) ColorPickerOptionsPopup(flags, col); - // Read stored options - if ((flags & ImGuiColorEditFlags__PickerMask) == 0) - flags |= ((g.ColorEditOptions & ImGuiColorEditFlags__PickerMask) ? g.ColorEditOptions : ImGuiColorEditFlags__OptionsDefault) & ImGuiColorEditFlags__PickerMask; - IM_ASSERT(ImIsPowerOfTwo((int)(flags & ImGuiColorEditFlags__PickerMask))); // Check that only 1 is selected + // Read stored options + if (!(flags & ImGuiColorEditFlags__PickerMask)) + flags |= ((g.ColorEditOptions & ImGuiColorEditFlags__PickerMask) ? g.ColorEditOptions : ImGuiColorEditFlags__OptionsDefault) & ImGuiColorEditFlags__PickerMask; + IM_ASSERT(ImIsPowerOfTwo((int)(flags & ImGuiColorEditFlags__PickerMask))); // Check that only 1 is selected + if (!(flags & ImGuiColorEditFlags_NoOptions)) flags |= (g.ColorEditOptions & ImGuiColorEditFlags_AlphaBar); - } // Setup bool alpha_bar = (flags & ImGuiColorEditFlags_AlphaBar) && !(flags & ImGuiColorEditFlags_NoAlpha); @@ -9670,7 +9669,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl if ((flags & ImGuiColorEditFlags_NoInputs) == 0) { PushItemWidth((alpha_bar ? bar1_pos_x : bar0_pos_x) + bars_width - picker_pos.x); - ImGuiColorEditFlags sub_flags_to_forward = ImGuiColorEditFlags__DataTypeMask | ImGuiColorEditFlags_HDR | ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoSmallPreview | ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf; + ImGuiColorEditFlags sub_flags_to_forward = ImGuiColorEditFlags__DataTypeMask | ImGuiColorEditFlags_HDR | ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoOptions | ImGuiColorEditFlags_NoSmallPreview | ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf; ImGuiColorEditFlags sub_flags = (flags & sub_flags_to_forward) | ImGuiColorEditFlags_NoPicker; if (flags & ImGuiColorEditFlags_RGB || (flags & ImGuiColorEditFlags__InputsMask) == 0) value_changed |= ColorEdit4("##rgb", col, sub_flags | ImGuiColorEditFlags_RGB); From 7e452ec7379e56517d459152f3fde2f5fcb3c3d6 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 11 Aug 2017 13:36:28 +0800 Subject: [PATCH 198/921] Renamed ImGuiSetCond_XXX type and enums to ImGuiCond_XXX, kept old enums under #ifdef IMGUI_DISABLE_OBSOLETE_FUNCTIONS --- examples/allegro5_example/main.cpp | 4 +- .../apple_example/imguiex-ios/debug_hud.cpp | 9 +-- examples/directx10_example/main.cpp | 4 +- examples/directx11_example/main.cpp | 4 +- examples/directx9_example/main.cpp | 4 +- examples/marmalade_example/main.cpp | 4 +- examples/opengl2_example/main.cpp | 4 +- examples/opengl3_example/main.cpp | 4 +- examples/sdl_opengl2_example/main.cpp | 4 +- examples/sdl_opengl3_example/main.cpp | 4 +- examples/vulkan_example/main.cpp | 4 +- imgui.cpp | 81 ++++++++++--------- imgui.h | 43 +++++----- imgui_demo.cpp | 24 +++--- imgui_internal.h | 18 ++--- 15 files changed, 110 insertions(+), 105 deletions(-) diff --git a/examples/allegro5_example/main.cpp b/examples/allegro5_example/main.cpp index a8cd156ba..f99ff5e9e 100644 --- a/examples/allegro5_example/main.cpp +++ b/examples/allegro5_example/main.cpp @@ -72,7 +72,7 @@ int main(int, char**) // 2. Show another simple window, this time using an explicit Begin/End pair if (show_another_window) { - ImGui::SetNextWindowSize(ImVec2(200, 100), ImGuiSetCond_FirstUseEver); + ImGui::SetNextWindowSize(ImVec2(200, 100), ImGuiCond_FirstUseEver); ImGui::Begin("Another Window", &show_another_window); ImGui::Text("Hello"); ImGui::End(); @@ -81,7 +81,7 @@ int main(int, char**) // 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow() if (show_test_window) { - ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver); + ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); ImGui::ShowTestWindow(&show_test_window); } diff --git a/examples/apple_example/imguiex-ios/debug_hud.cpp b/examples/apple_example/imguiex-ios/debug_hud.cpp index c75938a39..63bec89ba 100644 --- a/examples/apple_example/imguiex-ios/debug_hud.cpp +++ b/examples/apple_example/imguiex-ios/debug_hud.cpp @@ -24,18 +24,17 @@ void DebugHUD_InitDefaults( DebugHUD *hud ) hud->cubeColor2[3] = 1.0f; } -void DebugHUD_DoInterface( DebugHUD *hud ) +void DebugHUD_DoInterface(DebugHUD *hud) { if (hud->show_test_window) { - ImGui::SetNextWindowPos( ImVec2( 400, 20 ), ImGuiSetCond_FirstUseEver ); - ImGui::ShowTestWindow( &hud->show_test_window ); + ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); + ImGui::ShowTestWindow(&hud->show_test_window ); } if (hud->show_example_window) { - ImGui::SetNextWindowPos( ImVec2( 20, 20 ), ImGuiSetCond_FirstUseEver ); - ImGui::SetNextWindowSize( ImVec2( 350, 200 ), ImGuiSetCond_FirstUseEver ); + ImGui::SetNextWindowSize(ImVec2(350, 200), ImGuiCond_FirstUseEver); ImGui::Begin("Another Window", &hud->show_example_window); ImGui::ColorEdit3("Cube 1 Color", hud->cubeColor1); ImGui::ColorEdit3("Cube 2 Color", hud->cubeColor2); diff --git a/examples/directx10_example/main.cpp b/examples/directx10_example/main.cpp index a7b282da4..6b89ba9e8 100644 --- a/examples/directx10_example/main.cpp +++ b/examples/directx10_example/main.cpp @@ -167,7 +167,7 @@ int main(int, char**) // 2. Show another simple window, this time using an explicit Begin/End pair if (show_another_window) { - ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver); + ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiCond_FirstUseEver); ImGui::Begin("Another Window", &show_another_window); ImGui::Text("Hello"); ImGui::End(); @@ -176,7 +176,7 @@ int main(int, char**) // 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow() if (show_test_window) { - ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver); // Normally user code doesn't need/want to call it because positions are saved in .ini file anyway. Here we just want to make the demo initial state a bit more friendly! + ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); // Normally user code doesn't need/want to call it because positions are saved in .ini file anyway. Here we just want to make the demo initial state a bit more friendly! ImGui::ShowTestWindow(&show_test_window); } diff --git a/examples/directx11_example/main.cpp b/examples/directx11_example/main.cpp index 9e85d9e7c..63b220957 100644 --- a/examples/directx11_example/main.cpp +++ b/examples/directx11_example/main.cpp @@ -170,7 +170,7 @@ int main(int, char**) // 2. Show another simple window, this time using an explicit Begin/End pair if (show_another_window) { - ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver); + ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiCond_FirstUseEver); ImGui::Begin("Another Window", &show_another_window); ImGui::Text("Hello"); ImGui::End(); @@ -179,7 +179,7 @@ int main(int, char**) // 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow() if (show_test_window) { - ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver); // Normally user code doesn't need/want to call it because positions are saved in .ini file anyway. Here we just want to make the demo initial state a bit more friendly! + ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); // Normally user code doesn't need/want to call it because positions are saved in .ini file anyway. Here we just want to make the demo initial state a bit more friendly! ImGui::ShowTestWindow(&show_test_window); } diff --git a/examples/directx9_example/main.cpp b/examples/directx9_example/main.cpp index ecc382a7b..036712c4b 100644 --- a/examples/directx9_example/main.cpp +++ b/examples/directx9_example/main.cpp @@ -121,7 +121,7 @@ int main(int, char**) // 2. Show another simple window, this time using an explicit Begin/End pair if (show_another_window) { - ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver); + ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiCond_FirstUseEver); ImGui::Begin("Another Window", &show_another_window); ImGui::Text("Hello"); ImGui::End(); @@ -130,7 +130,7 @@ int main(int, char**) // 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow() if (show_test_window) { - ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver); + ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); ImGui::ShowTestWindow(&show_test_window); } diff --git a/examples/marmalade_example/main.cpp b/examples/marmalade_example/main.cpp index c49aa844f..e08e306b6 100644 --- a/examples/marmalade_example/main.cpp +++ b/examples/marmalade_example/main.cpp @@ -56,7 +56,7 @@ int main(int, char**) // 2. Show another simple window, this time using an explicit Begin/End pair if (show_another_window) { - ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver); + ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiCond_FirstUseEver); ImGui::Begin("Another Window", &show_another_window); ImGui::Text("Hello"); ImGui::End(); @@ -65,7 +65,7 @@ int main(int, char**) // 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow() if (show_test_window) { - ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver); + ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); ImGui::ShowTestWindow(&show_test_window); } diff --git a/examples/opengl2_example/main.cpp b/examples/opengl2_example/main.cpp index 28cb90ff5..aa0816f91 100644 --- a/examples/opengl2_example/main.cpp +++ b/examples/opengl2_example/main.cpp @@ -59,7 +59,7 @@ int main(int, char**) // 2. Show another simple window, this time using an explicit Begin/End pair if (show_another_window) { - ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver); + ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiCond_FirstUseEver); ImGui::Begin("Another Window", &show_another_window); ImGui::Text("Hello"); ImGui::End(); @@ -68,7 +68,7 @@ int main(int, char**) // 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow() if (show_test_window) { - ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver); + ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); ImGui::ShowTestWindow(&show_test_window); } diff --git a/examples/opengl3_example/main.cpp b/examples/opengl3_example/main.cpp index a1c45a535..a11bc59d1 100644 --- a/examples/opengl3_example/main.cpp +++ b/examples/opengl3_example/main.cpp @@ -67,7 +67,7 @@ int main(int, char**) // 2. Show another simple window, this time using an explicit Begin/End pair if (show_another_window) { - ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver); + ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiCond_FirstUseEver); ImGui::Begin("Another Window", &show_another_window); ImGui::Text("Hello"); ImGui::End(); @@ -76,7 +76,7 @@ int main(int, char**) // 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow() if (show_test_window) { - ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver); + ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); ImGui::ShowTestWindow(&show_test_window); } diff --git a/examples/sdl_opengl2_example/main.cpp b/examples/sdl_opengl2_example/main.cpp index 72cf21a52..53e428ba3 100644 --- a/examples/sdl_opengl2_example/main.cpp +++ b/examples/sdl_opengl2_example/main.cpp @@ -72,7 +72,7 @@ int main(int, char**) // 2. Show another simple window, this time using an explicit Begin/End pair if (show_another_window) { - ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver); + ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiCond_FirstUseEver); ImGui::Begin("Another Window", &show_another_window); ImGui::Text("Hello"); ImGui::End(); @@ -81,7 +81,7 @@ int main(int, char**) // 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow() if (show_test_window) { - ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver); + ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); ImGui::ShowTestWindow(&show_test_window); } diff --git a/examples/sdl_opengl3_example/main.cpp b/examples/sdl_opengl3_example/main.cpp index c396405fb..56b790659 100644 --- a/examples/sdl_opengl3_example/main.cpp +++ b/examples/sdl_opengl3_example/main.cpp @@ -75,7 +75,7 @@ int main(int, char**) // 2. Show another simple window, this time using an explicit Begin/End pair if (show_another_window) { - ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver); + ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiCond_FirstUseEver); ImGui::Begin("Another Window", &show_another_window); ImGui::Text("Hello"); ImGui::End(); @@ -84,7 +84,7 @@ int main(int, char**) // 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow() if (show_test_window) { - ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver); + ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); ImGui::ShowTestWindow(&show_test_window); } diff --git a/examples/vulkan_example/main.cpp b/examples/vulkan_example/main.cpp index 265392699..a4922b092 100644 --- a/examples/vulkan_example/main.cpp +++ b/examples/vulkan_example/main.cpp @@ -698,7 +698,7 @@ int main(int, char**) // 2. Show another simple window, this time using an explicit Begin/End pair if (show_another_window) { - ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver); + ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiCond_FirstUseEver); ImGui::Begin("Another Window", &show_another_window); ImGui::Text("Hello"); ImGui::End(); @@ -707,7 +707,7 @@ int main(int, char**) // 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow() if (show_test_window) { - ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver); + ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); ImGui::ShowTestWindow(&show_test_window); } diff --git a/imgui.cpp b/imgui.cpp index ef7a7a8c3..e7a0be071 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -159,6 +159,7 @@ Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. Also read releases logs https://github.com/ocornut/imgui/releases for more details. + - 2017/08/11 (1.51) - renamed ImGuiSetCond_*** types and flags to ImGuiCond_***. Kept redirection enums (will obsolete). - 2017/08/09 (1.51) - removed ValueColor() helpers, they are equivalent to calling Text(label) + SameLine() + ColorButton(). - 2017/08/08 (1.51) - removed ColorEditMode() and ImGuiColorEditMode in favor of ImGuiColorEditFlags and parameters to the various Color*() functions. The SetColorEditOptions() allows to initialize default but the user can still change them with right-click context menu. - changed prototype of 'ColorEdit4(const char* label, float col[4], bool show_alpha = true)' to 'ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flags = 0)', where passing flags = 0x01 is a safe no-op (hello dodgy backward compatibility!). - check and run the demo window, under "Color/Picker Widgets", to understand the various new options. @@ -704,9 +705,9 @@ static ImFont* GetDefaultFont(); static void SetCurrentFont(ImFont* font); static void SetCurrentWindow(ImGuiWindow* window); static void SetWindowScrollY(ImGuiWindow* window, float new_scroll_y); -static void SetWindowPos(ImGuiWindow* window, const ImVec2& pos, ImGuiSetCond cond); -static void SetWindowSize(ImGuiWindow* window, const ImVec2& size, ImGuiSetCond cond); -static void SetWindowCollapsed(ImGuiWindow* window, bool collapsed, ImGuiSetCond cond); +static void SetWindowPos(ImGuiWindow* window, const ImVec2& pos, ImGuiCond cond); +static void SetWindowSize(ImGuiWindow* window, const ImVec2& size, ImGuiCond cond); +static void SetWindowCollapsed(ImGuiWindow* window, bool collapsed, ImGuiCond cond); static ImGuiWindow* FindHoveredWindow(ImVec2 pos, bool excluding_childs); static ImGuiWindow* CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFlags flags); static inline bool IsWindowContentHoverable(ImGuiWindow* window); @@ -1878,7 +1879,7 @@ ImGuiWindow::ImGuiWindow(const char* name) AutoFitOnlyGrows = false; AutoPosLastDirection = -1; HiddenFrames = 0; - SetWindowPosAllowFlags = SetWindowSizeAllowFlags = SetWindowCollapsedAllowFlags = ImGuiSetCond_Always | ImGuiSetCond_Once | ImGuiSetCond_FirstUseEver | ImGuiSetCond_Appearing; + SetWindowPosAllowFlags = SetWindowSizeAllowFlags = SetWindowCollapsedAllowFlags = ImGuiCond_Always | ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing; SetWindowPosCenterWanted = false; LastFrameActive = -1; @@ -2448,7 +2449,7 @@ void ImGui::NewFrame() CloseInactivePopups(); // Create implicit window - we will only render it if the user has added something to it. - ImGui::SetNextWindowSize(ImVec2(400,400), ImGuiSetCond_FirstUseEver); + ImGui::SetNextWindowSize(ImVec2(400,400), ImGuiCond_FirstUseEver); ImGui::Begin("Debug"); } @@ -3896,9 +3897,9 @@ static ImGuiWindow* CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFl } else { - window->SetWindowPosAllowFlags &= ~ImGuiSetCond_FirstUseEver; - window->SetWindowSizeAllowFlags &= ~ImGuiSetCond_FirstUseEver; - window->SetWindowCollapsedAllowFlags &= ~ImGuiSetCond_FirstUseEver; + window->SetWindowPosAllowFlags &= ~ImGuiCond_FirstUseEver; + window->SetWindowSizeAllowFlags &= ~ImGuiCond_FirstUseEver; + window->SetWindowCollapsedAllowFlags &= ~ImGuiCond_FirstUseEver; } if (settings->Pos.x != FLT_MAX) @@ -3967,7 +3968,7 @@ static void ApplySizeFullWithConstraint(ImGuiWindow* window, ImVec2 new_size) // You can use the "##" or "###" markers to use the same label with different id, or same id with different label. See documentation at the top of this file. // - Return false when window is collapsed, so you can early out in your code. You always need to call ImGui::End() even if false is returned. // - Passing 'bool* p_open' displays a Close button on the upper-right corner of the window, the pointed value will be set to false when the button is pressed. -// - Passing non-zero 'size' is roughly equivalent to calling SetNextWindowSize(size, ImGuiSetCond_FirstUseEver) prior to calling Begin(). +// - Passing non-zero 'size' is roughly equivalent to calling SetNextWindowSize(size, ImGuiCond_FirstUseEver) prior to calling Begin(). bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) { return ImGui::Begin(name, p_open, ImVec2(0.f, 0.f), -1.0f, flags); @@ -4025,12 +4026,12 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us if (g.SetNextWindowPosCond) { const ImVec2 backup_cursor_pos = window->DC.CursorPos; // FIXME: not sure of the exact reason of this saving/restore anymore :( need to look into that. - if (!window_was_active || window_appearing_after_being_hidden) window->SetWindowPosAllowFlags |= ImGuiSetCond_Appearing; + if (!window_was_active || window_appearing_after_being_hidden) window->SetWindowPosAllowFlags |= ImGuiCond_Appearing; window_pos_set_by_api = (window->SetWindowPosAllowFlags & g.SetNextWindowPosCond) != 0; if (window_pos_set_by_api && ImLengthSqr(g.SetNextWindowPosVal - ImVec2(-FLT_MAX,-FLT_MAX)) < 0.001f) { window->SetWindowPosCenterWanted = true; // May be processed on the next frame if this is our first frame and we are measuring size - window->SetWindowPosAllowFlags &= ~(ImGuiSetCond_Once | ImGuiSetCond_FirstUseEver | ImGuiSetCond_Appearing); + window->SetWindowPosAllowFlags &= ~(ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing); } else { @@ -4041,7 +4042,7 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us } if (g.SetNextWindowSizeCond) { - if (!window_was_active || window_appearing_after_being_hidden) window->SetWindowSizeAllowFlags |= ImGuiSetCond_Appearing; + if (!window_was_active || window_appearing_after_being_hidden) window->SetWindowSizeAllowFlags |= ImGuiCond_Appearing; window_size_set_by_api = (window->SetWindowSizeAllowFlags & g.SetNextWindowSizeCond) != 0; SetWindowSize(window, g.SetNextWindowSizeVal, g.SetNextWindowSizeCond); g.SetNextWindowSizeCond = 0; @@ -4057,7 +4058,7 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us } if (g.SetNextWindowCollapsedCond) { - if (!window_was_active || window_appearing_after_being_hidden) window->SetWindowCollapsedAllowFlags |= ImGuiSetCond_Appearing; + if (!window_was_active || window_appearing_after_being_hidden) window->SetWindowCollapsedAllowFlags |= ImGuiCond_Appearing; SetWindowCollapsed(window, g.SetNextWindowCollapsedVal, g.SetNextWindowCollapsedCond); g.SetNextWindowCollapsedCond = 0; } @@ -5013,12 +5014,12 @@ static void SetWindowScrollY(ImGuiWindow* window, float new_scroll_y) window->DC.CursorMaxPos.y -= window->Scroll.y; } -static void SetWindowPos(ImGuiWindow* window, const ImVec2& pos, ImGuiSetCond cond) +static void SetWindowPos(ImGuiWindow* window, const ImVec2& pos, ImGuiCond cond) { // Test condition (NB: bit 0 is always true) and clear flags for next time if (cond && (window->SetWindowPosAllowFlags & cond) == 0) return; - window->SetWindowPosAllowFlags &= ~(ImGuiSetCond_Once | ImGuiSetCond_FirstUseEver | ImGuiSetCond_Appearing); + window->SetWindowPosAllowFlags &= ~(ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing); window->SetWindowPosCenterWanted = false; // Set @@ -5029,13 +5030,13 @@ static void SetWindowPos(ImGuiWindow* window, const ImVec2& pos, ImGuiSetCond co window->DC.CursorMaxPos += (window->Pos - old_pos); // And more importantly we need to adjust this so size calculation doesn't get affected. } -void ImGui::SetWindowPos(const ImVec2& pos, ImGuiSetCond cond) +void ImGui::SetWindowPos(const ImVec2& pos, ImGuiCond cond) { ImGuiWindow* window = GetCurrentWindowRead(); SetWindowPos(window, pos, cond); } -void ImGui::SetWindowPos(const char* name, const ImVec2& pos, ImGuiSetCond cond) +void ImGui::SetWindowPos(const char* name, const ImVec2& pos, ImGuiCond cond) { if (ImGuiWindow* window = FindWindowByName(name)) SetWindowPos(window, pos, cond); @@ -5047,12 +5048,12 @@ ImVec2 ImGui::GetWindowSize() return window->Size; } -static void SetWindowSize(ImGuiWindow* window, const ImVec2& size, ImGuiSetCond cond) +static void SetWindowSize(ImGuiWindow* window, const ImVec2& size, ImGuiCond cond) { // Test condition (NB: bit 0 is always true) and clear flags for next time if (cond && (window->SetWindowSizeAllowFlags & cond) == 0) return; - window->SetWindowSizeAllowFlags &= ~(ImGuiSetCond_Once | ImGuiSetCond_FirstUseEver | ImGuiSetCond_Appearing); + window->SetWindowSizeAllowFlags &= ~(ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing); // Set if (size.x > 0.0f) @@ -5077,30 +5078,30 @@ static void SetWindowSize(ImGuiWindow* window, const ImVec2& size, ImGuiSetCond } } -void ImGui::SetWindowSize(const ImVec2& size, ImGuiSetCond cond) +void ImGui::SetWindowSize(const ImVec2& size, ImGuiCond cond) { SetWindowSize(GImGui->CurrentWindow, size, cond); } -void ImGui::SetWindowSize(const char* name, const ImVec2& size, ImGuiSetCond cond) +void ImGui::SetWindowSize(const char* name, const ImVec2& size, ImGuiCond cond) { ImGuiWindow* window = FindWindowByName(name); if (window) SetWindowSize(window, size, cond); } -static void SetWindowCollapsed(ImGuiWindow* window, bool collapsed, ImGuiSetCond cond) +static void SetWindowCollapsed(ImGuiWindow* window, bool collapsed, ImGuiCond cond) { // Test condition (NB: bit 0 is always true) and clear flags for next time if (cond && (window->SetWindowCollapsedAllowFlags & cond) == 0) return; - window->SetWindowCollapsedAllowFlags &= ~(ImGuiSetCond_Once | ImGuiSetCond_FirstUseEver | ImGuiSetCond_Appearing); + window->SetWindowCollapsedAllowFlags &= ~(ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing); // Set window->Collapsed = collapsed; } -void ImGui::SetWindowCollapsed(bool collapsed, ImGuiSetCond cond) +void ImGui::SetWindowCollapsed(bool collapsed, ImGuiCond cond) { SetWindowCollapsed(GImGui->CurrentWindow, collapsed, cond); } @@ -5110,7 +5111,7 @@ bool ImGui::IsWindowCollapsed() return GImGui->CurrentWindow->Collapsed; } -void ImGui::SetWindowCollapsed(const char* name, bool collapsed, ImGuiSetCond cond) +void ImGui::SetWindowCollapsed(const char* name, bool collapsed, ImGuiCond cond) { ImGuiWindow* window = FindWindowByName(name); if (window) @@ -5135,25 +5136,25 @@ void ImGui::SetWindowFocus(const char* name) } } -void ImGui::SetNextWindowPos(const ImVec2& pos, ImGuiSetCond cond) +void ImGui::SetNextWindowPos(const ImVec2& pos, ImGuiCond cond) { ImGuiContext& g = *GImGui; g.SetNextWindowPosVal = pos; - g.SetNextWindowPosCond = cond ? cond : ImGuiSetCond_Always; + g.SetNextWindowPosCond = cond ? cond : ImGuiCond_Always; } -void ImGui::SetNextWindowPosCenter(ImGuiSetCond cond) +void ImGui::SetNextWindowPosCenter(ImGuiCond cond) { ImGuiContext& g = *GImGui; g.SetNextWindowPosVal = ImVec2(-FLT_MAX, -FLT_MAX); - g.SetNextWindowPosCond = cond ? cond : ImGuiSetCond_Always; + g.SetNextWindowPosCond = cond ? cond : ImGuiCond_Always; } -void ImGui::SetNextWindowSize(const ImVec2& size, ImGuiSetCond cond) +void ImGui::SetNextWindowSize(const ImVec2& size, ImGuiCond cond) { ImGuiContext& g = *GImGui; g.SetNextWindowSizeVal = size; - g.SetNextWindowSizeCond = cond ? cond : ImGuiSetCond_Always; + g.SetNextWindowSizeCond = cond ? cond : ImGuiCond_Always; } void ImGui::SetNextWindowSizeConstraints(const ImVec2& size_min, const ImVec2& size_max, ImGuiSizeConstraintCallback custom_callback, void* custom_callback_user_data) @@ -5169,21 +5170,21 @@ void ImGui::SetNextWindowContentSize(const ImVec2& size) { ImGuiContext& g = *GImGui; g.SetNextWindowContentSizeVal = size; - g.SetNextWindowContentSizeCond = ImGuiSetCond_Always; + g.SetNextWindowContentSizeCond = ImGuiCond_Always; } void ImGui::SetNextWindowContentWidth(float width) { ImGuiContext& g = *GImGui; g.SetNextWindowContentSizeVal = ImVec2(width, g.SetNextWindowContentSizeCond ? g.SetNextWindowContentSizeVal.y : 0.0f); - g.SetNextWindowContentSizeCond = ImGuiSetCond_Always; + g.SetNextWindowContentSizeCond = ImGuiCond_Always; } -void ImGui::SetNextWindowCollapsed(bool collapsed, ImGuiSetCond cond) +void ImGui::SetNextWindowCollapsed(bool collapsed, ImGuiCond cond) { ImGuiContext& g = *GImGui; g.SetNextWindowCollapsedVal = collapsed; - g.SetNextWindowCollapsedCond = cond ? cond : ImGuiSetCond_Always; + g.SetNextWindowCollapsedCond = cond ? cond : ImGuiCond_Always; } void ImGui::SetNextWindowFocus() @@ -6005,14 +6006,14 @@ bool ImGui::TreeNodeBehaviorIsOpen(ImGuiID id, ImGuiTreeNodeFlags flags) bool is_open; if (g.SetNextTreeNodeOpenCond != 0) { - if (g.SetNextTreeNodeOpenCond & ImGuiSetCond_Always) + if (g.SetNextTreeNodeOpenCond & ImGuiCond_Always) { is_open = g.SetNextTreeNodeOpenVal; storage->SetInt(id, is_open); } else { - // We treat ImGuiSetCondition_Once and ImGuiSetCondition_FirstUseEver the same because tree node state are not saved persistently. + // We treat ImGuiCond_Once and ImGuiCond_FirstUseEver the same because tree node state are not saved persistently. const int stored_value = storage->GetInt(id, -1); if (stored_value == -1) { @@ -6279,11 +6280,11 @@ float ImGui::GetTreeNodeToLabelSpacing() return g.FontSize + (g.Style.FramePadding.x * 2.0f); } -void ImGui::SetNextTreeNodeOpen(bool is_open, ImGuiSetCond cond) +void ImGui::SetNextTreeNodeOpen(bool is_open, ImGuiCond cond) { ImGuiContext& g = *GImGui; g.SetNextTreeNodeOpenVal = is_open; - g.SetNextTreeNodeOpenCond = cond ? cond : ImGuiSetCond_Always; + g.SetNextTreeNodeOpenCond = cond ? cond : ImGuiCond_Always; } void ImGui::PushID(const char* str_id) @@ -9052,7 +9053,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled) if (menu_is_open) { - SetNextWindowPos(popup_pos, ImGuiSetCond_Always); + SetNextWindowPos(popup_pos, ImGuiCond_Always); ImGuiWindowFlags flags = ImGuiWindowFlags_ShowBorders | ((window->Flags & (ImGuiWindowFlags_Popup|ImGuiWindowFlags_ChildMenu)) ? ImGuiWindowFlags_ChildMenu|ImGuiWindowFlags_ChildWindow : ImGuiWindowFlags_ChildMenu); menu_is_open = BeginPopupEx(label, flags); // menu_is_open can be 'false' when the popup is completely clipped (e.g. zero size display) } diff --git a/imgui.h b/imgui.h index b3419557b..e6cde685b 100644 --- a/imgui.h +++ b/imgui.h @@ -73,7 +73,7 @@ typedef int ImGuiKey; // a key identifier (ImGui-side enum) // e typedef int ImGuiColorEditFlags; // color edit flags for Color*() // enum ImGuiColorEditFlags_ typedef int ImGuiMouseCursor; // a mouse cursor identifier // enum ImGuiMouseCursor_ typedef int ImGuiWindowFlags; // window flags for Begin*() // enum ImGuiWindowFlags_ -typedef int ImGuiSetCond; // condition flags for Set*() // enum ImGuiSetCond_ +typedef int ImGuiCond; // condition flags for Set*() // enum ImGuiCond_ typedef int ImGuiInputTextFlags; // flags for InputText*() // enum ImGuiInputTextFlags_ typedef int ImGuiSelectableFlags; // flags for Selectable() // enum ImGuiSelectableFlags_ typedef int ImGuiTreeNodeFlags; // flags for TreeNode*(), Collapsing*() // enum ImGuiTreeNodeFlags_ @@ -148,22 +148,22 @@ namespace ImGui IMGUI_API bool IsWindowCollapsed(); IMGUI_API void SetWindowFontScale(float scale); // per-window font scale. Adjust IO.FontGlobalScale if you want to scale all windows - IMGUI_API void SetNextWindowPos(const ImVec2& pos, ImGuiSetCond cond = 0); // set next window position. call before Begin() - IMGUI_API void SetNextWindowPosCenter(ImGuiSetCond cond = 0); // set next window position to be centered on screen. call before Begin() - IMGUI_API void SetNextWindowSize(const ImVec2& size, ImGuiSetCond cond = 0); // set next window size. set axis to 0.0f to force an auto-fit on this axis. call before Begin() + IMGUI_API void SetNextWindowPos(const ImVec2& pos, ImGuiCond cond = 0); // set next window position. call before Begin() + IMGUI_API void SetNextWindowPosCenter(ImGuiCond cond = 0); // set next window position to be centered on screen. call before Begin() + IMGUI_API void SetNextWindowSize(const ImVec2& size, ImGuiCond cond = 0); // set next window size. set axis to 0.0f to force an auto-fit on this axis. call before Begin() IMGUI_API void SetNextWindowSizeConstraints(const ImVec2& size_min, const ImVec2& size_max, ImGuiSizeConstraintCallback custom_callback = NULL, void* custom_callback_data = NULL); // set next window size limits. use -1,-1 on either X/Y axis to preserve the current size. Use callback to apply non-trivial programmatic constraints. IMGUI_API void SetNextWindowContentSize(const ImVec2& size); // set next window content size (enforce the range of scrollbars). set axis to 0.0f to leave it automatic. call before Begin() IMGUI_API void SetNextWindowContentWidth(float width); // set next window content width (enforce the range of horizontal scrollbar). call before Begin() - IMGUI_API void SetNextWindowCollapsed(bool collapsed, ImGuiSetCond cond = 0); // set next window collapsed state. call before Begin() + IMGUI_API void SetNextWindowCollapsed(bool collapsed, ImGuiCond cond = 0); // set next window collapsed state. call before Begin() IMGUI_API void SetNextWindowFocus(); // set next window to be focused / front-most. call before Begin() - IMGUI_API void SetWindowPos(const ImVec2& pos, ImGuiSetCond cond = 0); // (not recommended) set current window position - call within Begin()/End(). prefer using SetNextWindowPos(), as this may incur tearing and side-effects. - IMGUI_API void SetWindowSize(const ImVec2& size, ImGuiSetCond cond = 0); // (not recommended) set current window size - call within Begin()/End(). set to ImVec2(0,0) to force an auto-fit. prefer using SetNextWindowSize(), as this may incur tearing and minor side-effects. - IMGUI_API void SetWindowCollapsed(bool collapsed, ImGuiSetCond cond = 0); // (not recommended) set current window collapsed state. prefer using SetNextWindowCollapsed(). + IMGUI_API void SetWindowPos(const ImVec2& pos, ImGuiCond cond = 0); // (not recommended) set current window position - call within Begin()/End(). prefer using SetNextWindowPos(), as this may incur tearing and side-effects. + IMGUI_API void SetWindowSize(const ImVec2& size, ImGuiCond cond = 0); // (not recommended) set current window size - call within Begin()/End(). set to ImVec2(0,0) to force an auto-fit. prefer using SetNextWindowSize(), as this may incur tearing and minor side-effects. + IMGUI_API void SetWindowCollapsed(bool collapsed, ImGuiCond cond = 0); // (not recommended) set current window collapsed state. prefer using SetNextWindowCollapsed(). IMGUI_API void SetWindowFocus(); // (not recommended) set current window to be focused / front-most. prefer using SetNextWindowFocus(). - IMGUI_API void SetWindowPos(const char* name, const ImVec2& pos, ImGuiSetCond cond = 0); // set named window position. - IMGUI_API void SetWindowSize(const char* name, const ImVec2& size, ImGuiSetCond cond = 0); // set named window size. set axis to 0.0f to force an auto-fit on this axis. - IMGUI_API void SetWindowCollapsed(const char* name, bool collapsed, ImGuiSetCond cond = 0); // set named window collapsed state - IMGUI_API void SetWindowFocus(const char* name); // set named window to be focused / front-most. use NULL to remove focus. + IMGUI_API void SetWindowPos(const char* name, const ImVec2& pos, ImGuiCond cond = 0); // set named window position. + IMGUI_API void SetWindowSize(const char* name, const ImVec2& size, ImGuiCond cond = 0); // set named window size. set axis to 0.0f to force an auto-fit on this axis. + IMGUI_API void SetWindowCollapsed(const char* name, bool collapsed, ImGuiCond cond = 0); // set named window collapsed state + IMGUI_API void SetWindowFocus(const char* name); // set named window to be focused / front-most. use NULL to remove focus. IMGUI_API float GetScrollX(); // get scrolling amount [0..GetScrollMaxX()] IMGUI_API float GetScrollY(); // get scrolling amount [0..GetScrollMaxY()] @@ -345,7 +345,7 @@ namespace ImGui IMGUI_API void TreePop(); // ~ Unindent()+PopId() IMGUI_API void TreeAdvanceToLabelPos(); // advance cursor x position by GetTreeNodeToLabelSpacing() IMGUI_API float GetTreeNodeToLabelSpacing(); // horizontal distance preceding label when using TreeNode*() or Bullet() == (g.FontSize + style.FramePadding.x*2) for a regular unframed TreeNode - IMGUI_API void SetNextTreeNodeOpen(bool is_open, ImGuiSetCond cond = 0); // set next TreeNode/CollapsingHeader open state. + IMGUI_API void SetNextTreeNodeOpen(bool is_open, ImGuiCond cond = 0); // set next TreeNode/CollapsingHeader open state. IMGUI_API bool CollapsingHeader(const char* label, ImGuiTreeNodeFlags flags = 0); // if returning 'true' the header is open. doesn't indent nor push on ID stack. user doesn't have to call TreePop(). IMGUI_API bool CollapsingHeader(const char* label, bool* p_open, ImGuiTreeNodeFlags flags = 0); // when 'p_open' isn't NULL, display an additional small close button on upper right of the header @@ -708,13 +708,18 @@ enum ImGuiMouseCursor_ }; // Condition flags for ImGui::SetWindow***(), SetNextWindow***(), SetNextTreeNode***() functions -// All those functions treat 0 as a shortcut to ImGuiSetCond_Always -enum ImGuiSetCond_ +// All those functions treat 0 as a shortcut to ImGuiCond_Always +enum ImGuiCond_ { - ImGuiSetCond_Always = 1 << 0, // Set the variable - ImGuiSetCond_Once = 1 << 1, // Set the variable once per runtime session (only the first call with succeed) - ImGuiSetCond_FirstUseEver = 1 << 2, // Set the variable if the window has no saved data (if doesn't exist in the .ini file) - ImGuiSetCond_Appearing = 1 << 3 // Set the variable if the window is appearing after being hidden/inactive (or the first time) + ImGuiCond_Always = 1 << 0, // Set the variable + ImGuiCond_Once = 1 << 1, // Set the variable once per runtime session (only the first call with succeed) + ImGuiCond_FirstUseEver = 1 << 2, // Set the variable if the window has no saved data (if doesn't exist in the .ini file) + ImGuiCond_Appearing = 1 << 3 // Set the variable if the window is appearing after being hidden/inactive (or the first time) + +// Obsolete names (will be obsolete) +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS + , ImGuiSetCond_Always = ImGuiCond_Always, ImGuiSetCond_Once = ImGuiCond_Once, ImGuiSetCond_FirstUseEver = ImGuiCond_FirstUseEver, ImGuiSetCond_Appearing = ImGuiCond_Appearing +#endif }; struct ImGuiStyle diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 69d878459..52f728840 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -181,7 +181,7 @@ void ImGui::ShowTestWindow(bool* p_open) if (no_scrollbar) window_flags |= ImGuiWindowFlags_NoScrollbar; if (no_collapse) window_flags |= ImGuiWindowFlags_NoCollapse; if (!no_menu) window_flags |= ImGuiWindowFlags_MenuBar; - ImGui::SetNextWindowSize(ImVec2(550,680), ImGuiSetCond_FirstUseEver); + ImGui::SetNextWindowSize(ImVec2(550,680), ImGuiCond_FirstUseEver); if (!ImGui::Begin("ImGui Demo", p_open, window_flags)) { // Early out if the window is collapsed, as an optimization. @@ -855,8 +855,8 @@ void ImGui::ShowTestWindow(bool* p_open) if (ImGui::Button("Uint8 + HSV")) ImGui::SetColorEditOptions(ImGuiColorEditFlags_Uint8 | ImGuiColorEditFlags_HSV); ImGui::SameLine(); - if (ImGui::Button("Float + HDR + NoClamp")) - ImGui::SetColorEditOptions(ImGuiColorEditFlags_Float | ImGuiColorEditFlags_RGB | ImGuiColorEditFlags_HDR); + if (ImGui::Button("Float + HDR")) + ImGui::SetColorEditOptions(ImGuiColorEditFlags_Float | ImGuiColorEditFlags_RGB); ImGui::TreePop(); } @@ -2118,12 +2118,12 @@ static void ShowExampleAppManipulatingWindowTitle(bool*) // You can use the "##" and "###" markers to manipulate the display/ID. // Using "##" to display same title but have unique identifier. - ImGui::SetNextWindowPos(ImVec2(100,100), ImGuiSetCond_FirstUseEver); + ImGui::SetNextWindowPos(ImVec2(100,100), ImGuiCond_FirstUseEver); ImGui::Begin("Same title as another window##1"); ImGui::Text("This is window 1.\nMy title is the same as window 2, but my identifier is unique."); ImGui::End(); - ImGui::SetNextWindowPos(ImVec2(100,200), ImGuiSetCond_FirstUseEver); + ImGui::SetNextWindowPos(ImVec2(100,200), ImGuiCond_FirstUseEver); ImGui::Begin("Same title as another window##2"); ImGui::Text("This is window 2.\nMy title is the same as window 1, but my identifier is unique."); ImGui::End(); @@ -2131,7 +2131,7 @@ static void ShowExampleAppManipulatingWindowTitle(bool*) // Using "###" to display a changing title but keep a static identifier "AnimatedTitle" char buf[128]; sprintf(buf, "Animated title %c %d###AnimatedTitle", "|/-\\"[(int)(ImGui::GetTime()/0.25f)&3], rand()); - ImGui::SetNextWindowPos(ImVec2(100,300), ImGuiSetCond_FirstUseEver); + ImGui::SetNextWindowPos(ImVec2(100,300), ImGuiCond_FirstUseEver); ImGui::Begin(buf); ImGui::Text("This window has a changing title."); ImGui::End(); @@ -2140,7 +2140,7 @@ static void ShowExampleAppManipulatingWindowTitle(bool*) // Demonstrate using the low-level ImDrawList to draw custom shapes. static void ShowExampleAppCustomRendering(bool* p_open) { - ImGui::SetNextWindowSize(ImVec2(350,560), ImGuiSetCond_FirstUseEver); + ImGui::SetNextWindowSize(ImVec2(350,560), ImGuiCond_FirstUseEver); if (!ImGui::Begin("Example: Custom rendering", p_open)) { ImGui::End(); @@ -2293,7 +2293,7 @@ struct ExampleAppConsole void Draw(const char* title, bool* p_open) { - ImGui::SetNextWindowSize(ImVec2(520,600), ImGuiSetCond_FirstUseEver); + ImGui::SetNextWindowSize(ImVec2(520,600), ImGuiCond_FirstUseEver); if (!ImGui::Begin(title, p_open)) { ImGui::End(); @@ -2551,7 +2551,7 @@ struct ExampleAppLog void Draw(const char* title, bool* p_open = NULL) { - ImGui::SetNextWindowSize(ImVec2(500,400), ImGuiSetCond_FirstUseEver); + ImGui::SetNextWindowSize(ImVec2(500,400), ImGuiCond_FirstUseEver); ImGui::Begin(title, p_open); if (ImGui::Button("Clear")) Clear(); ImGui::SameLine(); @@ -2608,7 +2608,7 @@ static void ShowExampleAppLog(bool* p_open) // Demonstrate create a window with multiple child windows. static void ShowExampleAppLayout(bool* p_open) { - ImGui::SetNextWindowSize(ImVec2(500, 440), ImGuiSetCond_FirstUseEver); + ImGui::SetNextWindowSize(ImVec2(500, 440), ImGuiCond_FirstUseEver); if (ImGui::Begin("Example: Layout", p_open, ImGuiWindowFlags_MenuBar)) { if (ImGui::BeginMenuBar()) @@ -2654,7 +2654,7 @@ static void ShowExampleAppLayout(bool* p_open) // Demonstrate create a simple property editor. static void ShowExampleAppPropertyEditor(bool* p_open) { - ImGui::SetNextWindowSize(ImVec2(430,450), ImGuiSetCond_FirstUseEver); + ImGui::SetNextWindowSize(ImVec2(430,450), ImGuiCond_FirstUseEver); if (!ImGui::Begin("Example: Property editor", p_open)) { ImGui::End(); @@ -2727,7 +2727,7 @@ static void ShowExampleAppPropertyEditor(bool* p_open) // Demonstrate/test rendering huge amount of text, and the incidence of clipping. static void ShowExampleAppLongText(bool* p_open) { - ImGui::SetNextWindowSize(ImVec2(520,600), ImGuiSetCond_FirstUseEver); + ImGui::SetNextWindowSize(ImVec2(520,600), ImGuiCond_FirstUseEver); if (!ImGui::Begin("Example: Long text display", p_open)) { ImGui::End(); diff --git a/imgui_internal.h b/imgui_internal.h index 166efadc1..5afb368e7 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -425,17 +425,17 @@ struct ImGuiContext ImVec2 SetNextWindowSizeVal; ImVec2 SetNextWindowContentSizeVal; bool SetNextWindowCollapsedVal; - ImGuiSetCond SetNextWindowPosCond; - ImGuiSetCond SetNextWindowSizeCond; - ImGuiSetCond SetNextWindowContentSizeCond; - ImGuiSetCond SetNextWindowCollapsedCond; + ImGuiCond SetNextWindowPosCond; + ImGuiCond SetNextWindowSizeCond; + ImGuiCond SetNextWindowContentSizeCond; + ImGuiCond SetNextWindowCollapsedCond; ImRect SetNextWindowSizeConstraintRect; // Valid if 'SetNextWindowSizeConstraint' is true ImGuiSizeConstraintCallback SetNextWindowSizeConstraintCallback; - void* SetNextWindowSizeConstraintCallbackUserData; + void* SetNextWindowSizeConstraintCallbackUserData; bool SetNextWindowSizeConstraint; bool SetNextWindowFocus; bool SetNextTreeNodeOpenVal; - ImGuiSetCond SetNextTreeNodeOpenCond; + ImGuiCond SetNextTreeNodeOpenCond; // Render ImDrawData RenderDrawData; // Main ImDrawData instance to pass render information to the user @@ -666,9 +666,9 @@ struct IMGUI_API ImGuiWindow bool AutoFitOnlyGrows; int AutoPosLastDirection; int HiddenFrames; - int SetWindowPosAllowFlags; // bit ImGuiSetCond_*** specify if SetWindowPos() call will succeed with this particular flag. - int SetWindowSizeAllowFlags; // bit ImGuiSetCond_*** specify if SetWindowSize() call will succeed with this particular flag. - int SetWindowCollapsedAllowFlags; // bit ImGuiSetCond_*** specify if SetWindowCollapsed() call will succeed with this particular flag. + ImGuiCond SetWindowPosAllowFlags; // store condition flags for next SetWindowPos() call. + ImGuiCond SetWindowSizeAllowFlags; // store condition flags for next SetWindowSize() call. + ImGuiCond SetWindowCollapsedAllowFlags; // store condition flags for next SetWindowCollapsed() call. bool SetWindowPosCenterWanted; ImGuiDrawContext DC; // Temporary per-window data, reset at the beginning of the frame From d7cad903aa423576579a69bab86af725b5f9eb29 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 11 Aug 2017 14:29:27 +0800 Subject: [PATCH 199/921] Documentation tweaks --- README.md | 2 +- imgui.cpp | 147 ++++++++++++++++++++++++++++++++---------------------- imgui.h | 2 +- 3 files changed, 90 insertions(+), 61 deletions(-) diff --git a/README.md b/README.md index 09ed595e4..72bb4a64f 100644 --- a/README.md +++ b/README.md @@ -122,6 +122,7 @@ The Immediate Mode GUI paradigm may at first appear unusual to some users. This - [Jari Komppa's tutorial on building an ImGui library](http://iki.fi/sol/imgui/). - [Casey Muratori's original video that popularized the concept](https://mollyrocket.com/861). - [Nicolas Guillemot's CppCon'16 flashtalk about Dear ImGui](https://www.youtube.com/watch?v=LSRJ1jZq90k). +- [Thierry Excoffier's Zero Memory Widget](http://perso.univ-lyon1.fr/thierry.excoffier/ZMW/). See the [Links page](https://github.com/ocornut/imgui/wiki/Links) for third-party bindings to different languages and frameworks. @@ -139,7 +140,6 @@ Frequently Asked Question (FAQ) The library started its life and is best known as "ImGui" only due to the fact that I didn't give it a proper name when I released it. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations. It seemed confusing and unfair to hog the name. To reduce the ambiguity without affecting existing codebases, I have decided on an alternate, longer name "dear imgui" that people can use to refer to this specific library in ambiguous situations. -How do I update to a newer version of ImGui?
What is ImTextureID and how do I display an image?
I integrated ImGui in my engine and the text or lines are blurry..
I integrated ImGui in my engine and some elements are disappearing when I move windows around.. diff --git a/imgui.cpp b/imgui.cpp index e7a0be071..a59362406 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -17,11 +17,11 @@ - END-USER GUIDE - PROGRAMMER GUIDE (read me!) - Read first - - Getting started with integrating imgui in your code/engine + - How to update to a newer version of ImGui + - Getting started with integrating ImGui in your code/engine - API BREAKING CHANGES (read me when you update!) - FREQUENTLY ASKED QUESTIONS (FAQ), TIPS - How can I help? - - How do I update to a newer version of ImGui? - What is ImTextureID and how do I display an image? - I integrated ImGui in my engine and the text or lines are blurry.. - I integrated ImGui in my engine and some elements are clipping or disappearing when I move windows around.. @@ -40,19 +40,18 @@ MISSION STATEMENT ================= - - easy to use to create code-driven and data-driven tools - - easy to use to create ad hoc short-lived tools and long-lived, more elaborate tools - - easy to hack and improve - - minimize screen real-estate usage - - minimize setup and maintenance - - minimize state storage on user side - - portable, minimize dependencies, run on target (consoles, phones, etc.) - - efficient runtime (NB- we do allocate when "growing" content - creating a window / opening a tree node for the first time, etc. - but a typical frame won't allocate anything) - - read about immediate-mode gui principles @ http://mollyrocket.com/861, http://mollyrocket.com/forums/index.html + - Easy to use to create code-driven and data-driven tools + - Easy to use to create ad hoc short-lived tools and long-lived, more elaborate tools + - Easy to hack and improve + - Minimize screen real-estate usage + - Minimize setup and maintenance + - Minimize state storage on user side + - Portable, minimize dependencies, run on target (consoles, phones, etc.) + - Efficient runtime and memory consumption (NB- we do allocate when "growing" content - creating a window / opening a tree node for the first time, etc. - but a typical frame won't allocate anything) Designed for developers and content-creators, not the typical end-user! Some of the weaknesses includes: - - doesn't look fancy, doesn't animate - - limited layout features, intricate layouts are typically crafted in code + - Doesn't look fancy, doesn't animate + - Limited layout features, intricate layouts are typically crafted in code END-USER GUIDE @@ -87,65 +86,110 @@ - Read the FAQ below this section! - Your code creates the UI, if your code doesn't run the UI is gone! == very dynamic UI, no construction/destructions steps, less data retention on your side, no state duplication, less sync, less bugs. - Call and read ImGui::ShowTestWindow() for demo code demonstrating most features. - - Customization: PushStyleColor()/PushStyleVar() or the style editor to tweak the look of the interface (e.g. if you want a more compact UI or a different color scheme). + - You can learn about immediate-mode gui principles at http://www.johno.se/book/imgui.html or watch http://mollyrocket.com/861 + + HOW TO UPDATE TO A NEWER VERSION OF IMGUI + + - Overwrite all the sources files except for imconfig.h (if you have made modification to your copy of imconfig.h) + - Read the "API BREAKING CHANGES" section (below). This is where we list occasional API breaking changes. + If a function/type has been renamed / or marked obsolete, try to fix the name in your code before it is permanently removed from the public API. + If you have a problem with a missing function/symbols, search for its name in the code, there will likely be a comment about it. + Please report any issue to the GitHub page! + - Try to keep your copy of dear imgui reasonably up to date. GETTING STARTED WITH INTEGRATING IMGUI IN YOUR CODE/ENGINE - - See examples/ folder for standalone sample applications. Prefer reading examples/opengl_example/ first as it is the simplest. - You may be able to grab and copy a ready made imgui_impl_*** file from the examples/. - - Init: call ImGui::GetIO() to retrieve the ImGuiIO structure and fill the fields marked 'Settings'. - - Init: call io.Fonts->GetTexDataAsRGBA32(...) and load the font texture pixels into graphics memory. + - Add the ImGui source files to your projects, using your preferred build system. It is recommended you build the .cpp files as part of your project and not as a library. + - You can later customize the imconfig.h file to tweak some compilation time behavior, such as integrating imgui types with your own maths types. + - See examples/ folder for standalone sample applications. To understand the integration process, you can read examples/opengl2_example/ because it is short, + then switch to the one more appropriate to your use case. + - You may be able to grab and copy a ready made imgui_impl_*** file from the examples/. + - When using ImGui, your programming IDE if your friend: follow the declaration of variables, functions and types to find comments about them. + + - Init: retrieve the ImGuiIO structure with ImGui::GetIO() and fill the fields marked 'Settings': at minimum you need to set io.DisplaySize (application resolution). + Later on you will fill your keyboard mapping, clipboard handlers, and other advanced features but for a basic integration you don't need to worry about it all. + - Init: call io.Fonts->GetTexDataAsRGBA32(...), it will build the font atlas texture, then load the texture pixels into graphics memory. - Every frame: - 1/ in your mainloop or right after you got your keyboard/mouse info, call ImGui::GetIO() and fill the fields marked 'Input' - 2/ call ImGui::NewFrame() as early as you can! - 3/ use any ImGui function you want between NewFrame() and Render() - 4/ call ImGui::Render() as late as you can to end the frame and finalize render data. it will call your RenderDrawListFn handler that you set in the IO structure. + - In your main loop as early a possible, fill the IO fields marked 'Input' (e.g. mouse position, buttons, keyboard info, etc.) + - Call ImGui::NewFrame() to begin the imgui frame + - You can use any ImGui function you want between NewFrame() and Render() + - Call ImGui::Render() as late as you can to end the frame and finalize render data. it will call your io.RenderDrawListFn handler. (if you don't need to render, you still need to call Render() and ignore the callback, or call EndFrame() instead. if you call neither some aspects of windows focusing/moving will appear broken.) - All rendering information are stored into command-lists until ImGui::Render() is called. - ImGui never touches or knows about your GPU state. the only function that knows about GPU is the RenderDrawListFn handler that you provide. - Effectively it means you can create widgets at any time in your code, regardless of considerations of being in "update" vs "render" phases of your own application. - Refer to the examples applications in the examples/ folder for instruction on how to setup your code. - - A typical application skeleton may be: + - A minimal application skeleton may be: // Application init ImGuiIO& io = ImGui::GetIO(); io.DisplaySize.x = 1920.0f; io.DisplaySize.y = 1280.0f; - io.IniFilename = "imgui.ini"; - io.RenderDrawListsFn = my_render_function; // Setup a render function, or set to NULL and call GetDrawData() after Render() to access the render data. - // TODO: Fill others settings of the io structure + io.RenderDrawListsFn = MyRenderFunction; // Setup a render function, or set to NULL and call GetDrawData() after Render() to access the render data. + // TODO: Fill others settings of the io structure later. // Load texture atlas (there is a default font so you don't need to care about choosing a font yet) unsigned char* pixels; int width, height; io.Fonts->GetTexDataAsRGBA32(pixels, &width, &height); - // TODO: At this points you've got a texture pointed to by 'pixels' and you need to upload that your your graphic system - // TODO: Store your texture pointer/identifier (whatever your engine uses) in 'io.Fonts->TexID' + // TODO: At this points you've got the texture data and you need to upload that your your graphic system: + MyTexture* texture = MyEngine::CreateTextureFromMemoryPixels(pixels, width, height, TEXTURE_TYPE_RGBA) + // TODO: Store your texture pointer/identifier (whatever your engine uses) in 'io.Fonts->TexID'. This will be passed back to your via the renderer. + io.Fonts->TexID = (void*)texture; // Application main loop while (true) { - // 1) get low-level inputs (e.g. on Win32, GetKeyboardState(), or poll your events, etc.) - // TODO: fill all fields of IO structure and call NewFrame - ImGuiIO& io = ImGui::GetIO(); - io.DeltaTime = 1.0f/60.0f; - io.MousePos = mouse_pos; - io.MouseDown[0] = mouse_button_0; - io.MouseDown[1] = mouse_button_1; - io.KeysDown[i] = ... + // Setup low-level inputs (e.g. on Win32, GetKeyboardState(), or write to those fields from your Windows message loop handlers, etc.) + ImGuiIO& io = ImGui::GetIO(); + io.DeltaTime = 1.0f/60.0f; + io.MousePos = mouse_pos; + io.MouseDown[0] = mouse_button_0; + io.MouseDown[1] = mouse_button_1; - // 2) call NewFrame(), after this point you can use ImGui::* functions anytime - ImGui::NewFrame(); + // Call NewFrame(), after this point you can use ImGui::* functions anytime + ImGui::NewFrame(); - // 3) most of your application code here - MyGameUpdate(); // may use any ImGui functions, e.g. ImGui::Begin("My window"); ImGui::Text("Hello, world!"); ImGui::End(); - MyGameRender(); // may use any ImGui functions + // Most of your application code here + MyGameUpdate(); // may use any ImGui functions, e.g. ImGui::Begin("My window"); ImGui::Text("Hello, world!"); ImGui::End(); + MyGameRender(); // may use any ImGui functions as well! - // 4) render & swap video buffers - ImGui::Render(); - SwapBuffers(); + // Render & swap video buffers + ImGui::Render(); + SwapBuffers(); } + - A minimal render function skeleton may be: + + void void MyRenderFunction(ImDrawData* draw_data)(ImDrawData* draw_data) + { + // TODO: Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled + // TODO: Setup viewport, orthographic projection matrix + // TODO: Setup shader: vertex { float2 pos, float2 uv, u32 color }, fragment shader sample color from 1 texture, multiply by vertex color. + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawVert* vtx_buffer = cmd_list->VtxBuffer.Data; // vertex buffer generated by ImGui + const ImDrawIdx* idx_buffer = cmd_list->IdxBuffer.Data; // index buffer generated by ImGui + for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) + { + const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + // Render 'pcmd->ElemCount/3' texture triangles + MyEngineBindTexture(pcmd->TextureId); + MyEngineScissor((int)pcmd->ClipRect.x, (int)pcmd->ClipRect.y, (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); + MyEngineDrawIndexedTriangles(pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer, vtx_buffer); + } + idx_buffer += pcmd->ElemCount; + } + } + } + + - The examples/ folders contains many functional implementation of the pseudo-code above. - When calling NewFrame(), the 'io.WantCaptureMouse'/'io.WantCaptureKeyboard'/'io.WantTextInput' flags are updated. They tell you if ImGui intends to use your inputs. So for example, if 'io.WantCaptureMouse' is set you would typically want to hide mouse inputs from the rest of your application. Read the FAQ below for more information about those flags. @@ -282,21 +326,6 @@ A: - If you are experienced enough with ImGui and with C/C++, look at the todo list and see how you want/can help! - Become a Patron/donate! Convince your company to become a Patron or provide serious funding for development time! See http://www.patreon.com/imgui - Q: How do I update to a newer version of ImGui? - A: Overwrite the following files: - imgui.cpp - imgui.h - imgui_demo.cpp - imgui_draw.cpp - imgui_internal.h - stb_rect_pack.h - stb_textedit.h - stb_truetype.h - Don't overwrite imconfig.h if you have made modification to your copy. - If you have a problem with a missing function/symbols, search for its name in the code, there will likely be a comment about it. - Check the "API BREAKING CHANGES" sections for a list of occasional API breaking changes. - Please report any issue to the GitHub page! - Q: What is ImTextureID and how do I display an image? A: ImTextureID is a void* used to pass renderer-agnostic texture references around until it hits your render function. ImGui knows nothing about what those bits represent, it just passes them around. It is up to you to decide what you want the void* to carry! diff --git a/imgui.h b/imgui.h index e6cde685b..f8d5aae84 100644 --- a/imgui.h +++ b/imgui.h @@ -785,7 +785,7 @@ struct ImGuiIO bool OSXBehaviors; // = defined(__APPLE__) // OS X style: Text editing cursor movement using Alt instead of Ctrl, Shortcuts using Cmd/Super instead of Ctrl, Line/Text Start and End using Cmd+Arrows instead of Home/End, Double click selects by word instead of selecting whole text, Multi-selection in lists uses Cmd/Super instead of Ctrl //------------------------------------------------------------------ - // User Functions + // Settings (User Functions) //------------------------------------------------------------------ // Rendering function, will be called in Render(). From 08265bfbd93fd272da84c9bfe38b326a8dd0a272 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 11 Aug 2017 14:44:53 +0800 Subject: [PATCH 200/921] RenderArrow(): fix warning. re-orderer lines to match enum order. --- imgui.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index a59362406..42f85239e 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9500,10 +9500,11 @@ static void RenderArrow(ImDrawList* draw_list, ImVec2 pos, ImVec2 half_sz, ImGui { switch (direction) { - case ImGuiDir_Right: draw_list->AddTriangleFilled(ImVec2(pos.x - half_sz.x, pos.y + half_sz.y), ImVec2(pos.x - half_sz.x, pos.y - half_sz.y), pos, col); return; case ImGuiDir_Left: draw_list->AddTriangleFilled(ImVec2(pos.x + half_sz.x, pos.y - half_sz.y), ImVec2(pos.x + half_sz.x, pos.y + half_sz.y), pos, col); return; - case ImGuiDir_Down: draw_list->AddTriangleFilled(ImVec2(pos.x - half_sz.x, pos.y - half_sz.y), ImVec2(pos.x + half_sz.x, pos.y - half_sz.y), pos, col); return; + case ImGuiDir_Right: draw_list->AddTriangleFilled(ImVec2(pos.x - half_sz.x, pos.y + half_sz.y), ImVec2(pos.x - half_sz.x, pos.y - half_sz.y), pos, col); return; case ImGuiDir_Up: draw_list->AddTriangleFilled(ImVec2(pos.x + half_sz.x, pos.y + half_sz.y), ImVec2(pos.x - half_sz.x, pos.y + half_sz.y), pos, col); return; + case ImGuiDir_Down: draw_list->AddTriangleFilled(ImVec2(pos.x - half_sz.x, pos.y - half_sz.y), ImVec2(pos.x + half_sz.x, pos.y - half_sz.y), pos, col); return; + default: return; // Fix warning for ImGuiDir_None } } From 5eef7dd82fed09a6ffc8c8172022729450bd9ab1 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 12 Aug 2017 00:43:55 +0800 Subject: [PATCH 201/921] Demo: Consoles: Added "Copy" button to demonstrate LogToClipboard --- imgui_demo.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 52f728840..9fedba302 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -2308,6 +2308,7 @@ struct ExampleAppConsole if (ImGui::SmallButton("Add Dummy Text")) { AddLog("%d some text", Items.Size); AddLog("some more text"); AddLog("display very important message here!"); } ImGui::SameLine(); if (ImGui::SmallButton("Add Dummy Error")) AddLog("[error] something went wrong"); ImGui::SameLine(); if (ImGui::SmallButton("Clear")) ClearLog(); ImGui::SameLine(); + bool copy_to_clipboard = ImGui::SmallButton("Copy"); ImGui::SameLine(); if (ImGui::SmallButton("Scroll to bottom")) ScrollToBottom = true; //static float t = 0.0f; if (ImGui::GetTime() - t > 0.02f) { t = ImGui::GetTime(); AddLog("Spam %f", t); } @@ -2338,6 +2339,8 @@ struct ExampleAppConsole // and appending newly elements as they are inserted. This is left as a task to the user until we can manage to improve this example code! // If your items are of variable size you may want to implement code similar to what ImGuiListClipper does. Or split your data into fixed height items to allow random-seeking into your list. ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(4,1)); // Tighten spacing + if (copy_to_clipboard) + ImGui::LogToClipboard(); for (int i = 0; i < Items.Size; i++) { const char* item = Items[i]; @@ -2350,6 +2353,8 @@ struct ExampleAppConsole ImGui::TextUnformatted(item); ImGui::PopStyleColor(); } + if (copy_to_clipboard) + ImGui::LogFinish(); if (ScrollToBottom) ImGui::SetScrollHere(); ScrollToBottom = false; From b4fe5d36a4e7f0bee4db0da53a8b8cee52be8a68 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 12 Aug 2017 00:46:58 +0800 Subject: [PATCH 202/921] Examples: OpenGL3+SDL: Fix types to uses GlEnum (#1147) --- examples/opengl3_example/imgui_impl_glfw_gl3.cpp | 4 ++-- .../sdl_opengl3_example/imgui_impl_sdl_gl3.cpp | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp index ba321e81e..a9a45e105 100644 --- a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp +++ b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp @@ -51,14 +51,14 @@ void ImGui_ImplGlfwGL3_RenderDrawLists(ImDrawData* draw_data) GLint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); GLint last_element_array_buffer; glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &last_element_array_buffer); GLint last_vertex_array; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array); + GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); + GLint last_scissor_box[4]; glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box); GLenum last_blend_src_rgb; glGetIntegerv(GL_BLEND_SRC_RGB, (GLint*)&last_blend_src_rgb); GLenum last_blend_dst_rgb; glGetIntegerv(GL_BLEND_DST_RGB, (GLint*)&last_blend_dst_rgb); GLenum last_blend_src_alpha; glGetIntegerv(GL_BLEND_SRC_ALPHA, (GLint*)&last_blend_src_alpha); GLenum last_blend_dst_alpha; glGetIntegerv(GL_BLEND_DST_ALPHA, (GLint*)&last_blend_dst_alpha); GLenum last_blend_equation_rgb; glGetIntegerv(GL_BLEND_EQUATION_RGB, (GLint*)&last_blend_equation_rgb); GLenum last_blend_equation_alpha; glGetIntegerv(GL_BLEND_EQUATION_ALPHA, (GLint*)&last_blend_equation_alpha); - GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); - GLint last_scissor_box[4]; glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box); GLboolean last_enable_blend = glIsEnabled(GL_BLEND); GLboolean last_enable_cull_face = glIsEnabled(GL_CULL_FACE); GLboolean last_enable_depth_test = glIsEnabled(GL_DEPTH_TEST); diff --git a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp index 7b7dacaa4..59101e938 100644 --- a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp +++ b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp @@ -38,21 +38,21 @@ void ImGui_ImplSdlGL3_RenderDrawLists(ImDrawData* draw_data) draw_data->ScaleClipRects(io.DisplayFramebufferScale); // Backup GL state - GLint last_active_texture; glGetIntegerv(GL_ACTIVE_TEXTURE, &last_active_texture); + GLenum last_active_texture; glGetIntegerv(GL_ACTIVE_TEXTURE, (GLint*)&last_active_texture); glActiveTexture(GL_TEXTURE0); GLint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); GLint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); GLint last_element_array_buffer; glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &last_element_array_buffer); GLint last_vertex_array; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array); - GLint last_blend_src_rgb; glGetIntegerv(GL_BLEND_SRC_RGB, &last_blend_src_rgb); - GLint last_blend_dst_rgb; glGetIntegerv(GL_BLEND_DST_RGB, &last_blend_dst_rgb); - GLint last_blend_src_alpha; glGetIntegerv(GL_BLEND_SRC_ALPHA, &last_blend_src_alpha); - GLint last_blend_dst_alpha; glGetIntegerv(GL_BLEND_DST_ALPHA, &last_blend_dst_alpha); - GLint last_blend_equation_rgb; glGetIntegerv(GL_BLEND_EQUATION_RGB, &last_blend_equation_rgb); - GLint last_blend_equation_alpha; glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &last_blend_equation_alpha); GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); GLint last_scissor_box[4]; glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box); + GLenum last_blend_src_rgb; glGetIntegerv(GL_BLEND_SRC_RGB, (GLint*)&last_blend_src_rgb); + GLenum last_blend_dst_rgb; glGetIntegerv(GL_BLEND_DST_RGB, (GLint*)&last_blend_dst_rgb); + GLenum last_blend_src_alpha; glGetIntegerv(GL_BLEND_SRC_ALPHA, (GLint*)&last_blend_src_alpha); + GLenum last_blend_dst_alpha; glGetIntegerv(GL_BLEND_DST_ALPHA, (GLint*)&last_blend_dst_alpha); + GLenum last_blend_equation_rgb; glGetIntegerv(GL_BLEND_EQUATION_RGB, (GLint*)&last_blend_equation_rgb); + GLenum last_blend_equation_alpha; glGetIntegerv(GL_BLEND_EQUATION_ALPHA, (GLint*)&last_blend_equation_alpha); GLboolean last_enable_blend = glIsEnabled(GL_BLEND); GLboolean last_enable_cull_face = glIsEnabled(GL_CULL_FACE); GLboolean last_enable_depth_test = glIsEnabled(GL_DEPTH_TEST); From 0f126a5b07abcfde08bf07d86a996b88b6386f89 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 12 Aug 2017 01:05:24 +0800 Subject: [PATCH 203/921] Update README.md (small wording bits, inspired by #1093) --- README.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 72bb4a64f..bdbd85eb6 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ dear imgui, [![Build Status](https://travis-ci.org/ocornut/imgui.svg?branch=master)](https://travis-ci.org/ocornut/imgui) [![Coverity Status](https://scan.coverity.com/projects/4720/badge.svg)](https://scan.coverity.com/projects/4720) -(This library is free but needs your support to sustain its development. There are lots of desirable new features and maintenance to do. If you are an individual using dear imgui, please consider financial support via Patreon/PayPal. If your company is using dear imgui, please consider sponsorship (e.g. sponsoring a few weeks of development). I can invoice for private support, custom development etc. E-mail: omarcornut at gmail.) +(This library is free but needs your support to sustain its development. There are lots of desirable new features and maintenance to do. If you are an individual using dear imgui, please consider donating via Patreon or PayPal. If your company is using dear imgui, please consider financial support (e.g. sponsoring a few weeks/months of development). I can invoice for private support, custom development etc. E-mail: omarcornut at gmail.) Monthly donations via Patreon:
[![Patreon](https://cloud.githubusercontent.com/assets/8225057/5990484/70413560-a9ab-11e4-8942-1a63607c0b00.png)](http://www.patreon.com/imgui) @@ -143,7 +143,7 @@ The library started its life and is best known as "ImGui" only due to the fact t
What is ImTextureID and how do I display an image?
I integrated ImGui in my engine and the text or lines are blurry..
I integrated ImGui in my engine and some elements are disappearing when I move windows around.. -
How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs. +
How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on labels/IDs.
How can I tell when ImGui wants my mouse/keyboard inputs VS when I can pass them to my application?
How can I load a different font than the default?
How can I easily use icons in my application? @@ -190,18 +190,20 @@ ImGui takes advantage of a few C++ languages features for convenience but nothin There is an unofficial but reasonably maintained [c-api for ImGui](https://github.com/Extrawurst/cimgui) by Stephan Dilly. I would suggest using your target language functionality to try replicating the function overloading and default parameters used in C++ else the API may be harder to use. It was really designed with C++ in mind and may not make the same amount of sense with another language. Also see [Links](https://github.com/ocornut/imgui/wiki/Links) for third-party bindings to other languages. -Donate ------- +Support dear imgui +------------------ How can I help financing further development of Dear ImGui? +Your contributions are keeping the library alive. If you are an individual using dear imgui, please consider donating to enable me to spend more time improving the library. + Monthly donations via Patreon:
[![Patreon](https://cloud.githubusercontent.com/assets/8225057/5990484/70413560-a9ab-11e4-8942-1a63607c0b00.png)](http://www.patreon.com/imgui) One-off donations via PayPal:
[![PayPal](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5Q73FPZ9C526U) -Your contributions are keeping the library alive. For end-users, I have setup an [**ImGui Patreon page**](http://www.patreon.com/imgui) if you want to donate and enable me to spend more time improving the library. If your company uses ImGui please consider making a contribution. One-off donations are also greatly appreciated. I can invoice for private support, custom development or whatever makes more sense in a given context. I am available for hire to work on or with ImGui. Please e-mail omarcornut at gmail for details. Thanks! +If your company uses dear imgui, please consider financial support (e.g. sponsoring a few weeks/months of development). I can invoice for private support, custom development etc. E-mail: omarcornut at gmail. Thanks! Credits ------- @@ -216,7 +218,7 @@ Embeds [stb_textedit.h, stb_truetype.h, stb_rectpack.h](https://github.com/nothi Inspiration, feedback, and testing for early versions: Casey Muratori, Atman Binstock, Mikko Mononen, Emmanuel Briney, Stefan Kamoda, Anton Mikhailov, Matt Willis. And everybody posting feedback, questions and patches on the GitHub. -Ongoing ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui). +Ongoing dear imgui development is financially supported on [**Patreon**](http://www.patreon.com/imgui). Double-chocolate sponsors: - Media Molecule From 908b025c3c47afcab907386bc038e2bc1793f591 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 12 Aug 2017 01:23:39 +0800 Subject: [PATCH 204/921] Fixed (unlikely) Ini saving crash if the ImGuiWindowFlags_NoSavedSettings gets removed from a window after its creation (#1000) + minor FAQ tweaks --- imgui.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 42f85239e..f4048d20b 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -25,7 +25,7 @@ - What is ImTextureID and how do I display an image? - I integrated ImGui in my engine and the text or lines are blurry.. - I integrated ImGui in my engine and some elements are clipping or disappearing when I move windows around.. - - How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs. + - How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on labels/IDs. - How can I tell when ImGui wants my mouse/keyboard inputs VS when I can pass them to my application? - How can I load a different font than the default? - How can I easily use icons in my application? @@ -344,7 +344,7 @@ Q: I integrated ImGui in my engine and some elements are clipping or disappearing when I move windows around.. A: Most likely you are mishandling the clipping rectangles in your render function. Rectangles provided by ImGui are defined as (x1=left,y1=top,x2=right,y2=bottom) and NOT as (x1,y1,width,height). - Q: Can I have multiple widgets with the same label? Can I have widget without a label? (Yes) + Q: Can I have multiple widgets with the same label? Can I have widget without a label? A: Yes. A primer on the use of labels/IDs in ImGui.. - Elements that are not clickable, such as Text() items don't need an ID. @@ -2633,6 +2633,8 @@ static void SaveIniSettingsToDisk(const char* ini_filename) if (window->Flags & ImGuiWindowFlags_NoSavedSettings) continue; ImGuiIniData* settings = FindWindowSettings(window->Name); + if (!settings) // This will only return NULL in the rare instance where the window was first created with ImGuiWindowFlags_NoSavedSettings then had the flag disabled later on. We don't bind settings in this case (bug #1000). + continue; settings->Pos = window->Pos; settings->Size = window->SizeFull; settings->Collapsed = window->Collapsed; From 8352d43a0c318380053a88e313e62f733d7290d5 Mon Sep 17 00:00:00 2001 From: LuK1337 Date: Fri, 11 Aug 2017 22:52:33 +0200 Subject: [PATCH 205/921] Fix broken ImGuiColorEditFlags_NoAlpha flag check * Fixes warning: imgui.cpp:9295:98: warning: enum constant in boolean context [-Wint-in-bool-context] --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index f4048d20b..89fdc06e8 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9292,7 +9292,7 @@ static void ColorPickerOptionsPopup(ImGuiColorEditFlags flags, float* ref_col) g.ColorEditOptions = (g.ColorEditOptions & ~ImGuiColorEditFlags__PickerMask) | (picker_flags & ImGuiColorEditFlags__PickerMask); ImGui::SetCursorScreenPos(backup_pos); ImVec4 dummy_ref_col; - memcpy(&dummy_ref_col.x, ref_col, sizeof(float) * (ImGuiColorEditFlags_NoAlpha ? 3 : 4)); + memcpy(&dummy_ref_col.x, ref_col, sizeof(float) * (picker_flags & ImGuiColorEditFlags_NoAlpha ? 3 : 4)); ImGui::ColorPicker4("##dummypicker", &dummy_ref_col.x, picker_flags); ImGui::PopID(); } From 8c61a4eb4c8a62b2eb764db49b2c7cf3815afad7 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 14 Aug 2017 11:29:54 +0800 Subject: [PATCH 206/921] Fonts: Adding references to the fact that .OTF fonts are supported (but haven't renamed the entry points) --- README.md | 2 +- extra_fonts/README.txt | 5 +++-- imgui.cpp | 2 +- imgui.h | 18 +++++++++--------- 4 files changed, 14 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index bdbd85eb6..3bfb46edf 100644 --- a/README.md +++ b/README.md @@ -103,7 +103,7 @@ See the [Screenshots Thread](https://github.com/ocornut/imgui/issues/123) for so ![screenshot 6](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v143/skinning_sample_02.png) ![screenshot 7](https://cloud.githubusercontent.com/assets/8225057/7903336/96f0fb7c-07d0-11e5-95d6-41c6a1595e5a.png) -ImGui can load TTF fonts. UTF-8 is supported for text display and input. Here using Arial Unicode font to display Japanese. Initialize custom font with: +ImGui can load TTF/OTF fonts. UTF-8 is supported for text display and input. Here using Arial Unicode font to display Japanese. Initialize custom font with: ``` ImGuiIO& io = ImGui::GetIO(); io.Fonts->AddFontFromFileTTF("ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); diff --git a/extra_fonts/README.txt b/extra_fonts/README.txt index 9a3114590..77fdaa6c0 100644 --- a/extra_fonts/README.txt +++ b/extra_fonts/README.txt @@ -1,6 +1,7 @@ The code in imgui.cpp embeds a copy of 'ProggyClean.ttf' that you can use without any external files. - The files in this folder are only provided as a convenience, you can use any of your own .TTF files. + The files in this folder are only provided as a convenience, you can use any .TTF/.OTF. + (Note: .OTF support in stb_truetype.h currently doesn't appear to load every font) Fonts are rasterized in a single texture at the time of calling either of io.Fonts.GetTexDataAsAlpha8()/GetTexDataAsRGBA32()/Build(). @@ -34,7 +35,7 @@ ImGuiIO& io = ImGui::GetIO(); io.Fonts->AddFontDefault(); - Load .TTF file with: + Load .TTF/.OTF file with: ImGuiIO& io = ImGui::GetIO(); io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels); diff --git a/imgui.cpp b/imgui.cpp index 89fdc06e8..ef63b09cb 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -448,7 +448,7 @@ Depending on your application logic it may or not be inconvenient. You might want to track which key-downs were for ImGui (e.g. with an array of bool) and filter out the corresponding key-ups.) Q: How can I load a different font than the default? (default is an embedded version of ProggyClean.ttf, rendered at size 13) - A: Use the font atlas to load the TTF file you want: + A: Use the font atlas to load the TTF/OTF file you want: ImGuiIO& io = ImGui::GetIO(); io.Fonts->AddFontFromFileTTF("myfontfile.ttf", size_in_pixels); diff --git a/imgui.h b/imgui.h index f8d5aae84..1c5cce612 100644 --- a/imgui.h +++ b/imgui.h @@ -48,7 +48,7 @@ struct ImDrawData; // All draw command lists required to render struct ImDrawList; // A single draw command list (generally one per window) struct ImDrawVert; // A single vertex (20 bytes by default, override layout with IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT) struct ImFont; // Runtime data for a single font within a parent ImFontAtlas -struct ImFontAtlas; // Runtime data for multiple fonts, bake multiple fonts into a single texture, TTF font loader +struct ImFontAtlas; // Runtime data for multiple fonts, bake multiple fonts into a single texture, TTF/OTF font loader struct ImFontConfig; // Configuration data when adding a font or merging fonts struct ImColor; // Helper functions to create a color that can be converted to either u32 or float4 struct ImGuiIO; // Main configuration and I/O between your application and ImGui @@ -1301,10 +1301,10 @@ struct ImDrawData struct ImFontConfig { - void* FontData; // // TTF data - int FontDataSize; // // TTF data size - bool FontDataOwnedByAtlas; // true // TTF data ownership taken by the container ImFontAtlas (will delete memory itself). Set to true - int FontNo; // 0 // Index of font within TTF file + void* FontData; // // TTF/OTF data + int FontDataSize; // // TTF/OTF data size + bool FontDataOwnedByAtlas; // true // TTF/OTF data ownership taken by the container ImFontAtlas (will delete memory itself). Set to true + int FontNo; // 0 // Index of font within TTF/OTF file float SizePixels; // // Size in pixels for rasterizer int OversampleH, OversampleV; // 3, 1 // Rasterize at higher quality for sub-pixel positioning. We don't use sub-pixel positions on the Y axis. bool PixelSnapH; // false // Align every glyph to pixel boundary. Useful e.g. if you are merging a non-pixel aligned font with the default font. If enabled, you can set OversampleH/V to 1. @@ -1320,7 +1320,7 @@ struct ImFontConfig IMGUI_API ImFontConfig(); }; -// Load and rasterize multiple TTF fonts into a same texture. +// Load and rasterize multiple TTF/OTF fonts into a same texture. // Sharing a texture for multiple fonts allows us to reduce the number of draw calls during rendering. // We also add custom graphic data into the texture that serves for ImGui. // 1. (Optional) Call AddFont*** functions. If you don't call any, the default font will be loaded for you. @@ -1335,9 +1335,9 @@ struct ImFontAtlas IMGUI_API ImFont* AddFont(const ImFontConfig* font_cfg); IMGUI_API ImFont* AddFontDefault(const ImFontConfig* font_cfg = NULL); IMGUI_API ImFont* AddFontFromFileTTF(const char* filename, float size_pixels, const ImFontConfig* font_cfg = NULL, const ImWchar* glyph_ranges = NULL); - IMGUI_API ImFont* AddFontFromMemoryTTF(void* ttf_data, int ttf_size, float size_pixels, const ImFontConfig* font_cfg = NULL, const ImWchar* glyph_ranges = NULL); // 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 ImFontConfig* font_cfg = NULL, const ImWchar* glyph_ranges = NULL); // 'compressed_ttf_data' still owned by caller. Compress with binary_to_compressed_c.cpp - IMGUI_API ImFont* AddFontFromMemoryCompressedBase85TTF(const char* compressed_ttf_data_base85, float size_pixels, const ImFontConfig* font_cfg = NULL, const ImWchar* glyph_ranges = NULL); // 'compressed_ttf_data_base85' still owned by caller. Compress with binary_to_compressed_c.cpp with -base85 paramaeter + IMGUI_API ImFont* AddFontFromMemoryTTF(void* font_data, int font_size, float size_pixels, const ImFontConfig* font_cfg = NULL, const ImWchar* glyph_ranges = NULL); // Transfer ownership of 'ttf_data' to ImFontAtlas, will be deleted after Build() + IMGUI_API ImFont* AddFontFromMemoryCompressedTTF(const void* compressed_font_data, int compressed_font_size, float size_pixels, const ImFontConfig* font_cfg = NULL, const ImWchar* glyph_ranges = NULL); // 'compressed_font_data' still owned by caller. Compress with binary_to_compressed_c.cpp + IMGUI_API ImFont* AddFontFromMemoryCompressedBase85TTF(const char* compressed_font_data_base85, float size_pixels, const ImFontConfig* font_cfg = NULL, const ImWchar* glyph_ranges = NULL); // 'compressed_font_data_base85' still owned by caller. Compress with binary_to_compressed_c.cpp with -base85 paramaeter 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) From 6a4064e5f22e05dd7463e77a526359cb6a83243d Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 14 Aug 2017 12:25:35 +0800 Subject: [PATCH 207/921] PathArcToFast: Minor renaming for clarification. Comments. --- imgui.cpp | 2 +- imgui_draw.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index ef63b09cb..002f31403 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4388,7 +4388,7 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us bg_color_idx = ImGuiCol_PopupBg; else if ((flags & ImGuiWindowFlags_ChildWindow) != 0) bg_color_idx = ImGuiCol_ChildWindowBg; - ImVec4 bg_color = style.Colors[bg_color_idx]; + ImVec4 bg_color = style.Colors[bg_color_idx]; // We don't use GetColorU32() because bg_alpha is assigned (not multiplied) below if (bg_alpha >= 0.0f) bg_color.w = bg_alpha; bg_color.w *= style.Alpha; diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 876fd7df7..d1ee8cbdc 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -678,7 +678,7 @@ void ImDrawList::AddConvexPolyFilled(const ImVec2* points, const int points_coun } } -void ImDrawList::PathArcToFast(const ImVec2& centre, float radius, int amin, int amax) +void ImDrawList::PathArcToFast(const ImVec2& centre, float radius, int a_min_of_12, int a_max_of_12) { static ImVec2 circle_vtx[12]; static bool circle_vtx_builds = false; @@ -694,15 +694,15 @@ void ImDrawList::PathArcToFast(const ImVec2& centre, float radius, int amin, int circle_vtx_builds = true; } - if (amin > amax) return; + if (a_min_of_12 > a_max_of_12) return; if (radius == 0.0f) { _Path.push_back(centre); } else { - _Path.reserve(_Path.Size + (amax - amin + 1)); - for (int a = amin; a <= amax; a++) + _Path.reserve(_Path.Size + (a_max_of_12 - a_min_of_12 + 1)); + for (int a = a_min_of_12; a <= a_max_of_12; a++) { const ImVec2& c = circle_vtx[a % circle_vtx_count]; _Path.push_back(ImVec2(centre.x + c.x * radius, centre.y + c.y * radius)); From 648f75b2456f1e5b17be113908c0119ed9e5b071 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 14 Aug 2017 13:04:32 +0800 Subject: [PATCH 208/921] Style: renamed ImGuiCol_Columns_*** to ImGuiCol_Separator_*** (BREAKING), Separator() uses this color as well. (#707, #1019) --- imgui.cpp | 17 +++++++++-------- imgui.h | 6 +++--- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 002f31403..6c09b3976 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -203,6 +203,7 @@ Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. Also read releases logs https://github.com/ocornut/imgui/releases for more details. + - 2017/08/13 (1.51) - renamed ImGuiCol_Columns_*** to ImGuiCol_Separator_*** - 2017/08/11 (1.51) - renamed ImGuiSetCond_*** types and flags to ImGuiCond_***. Kept redirection enums (will obsolete). - 2017/08/09 (1.51) - removed ValueColor() helpers, they are equivalent to calling Text(label) + SameLine() + ColorButton(). - 2017/08/08 (1.51) - removed ColorEditMode() and ImGuiColorEditMode in favor of ImGuiColorEditFlags and parameters to the various Color*() functions. The SetColorEditOptions() allows to initialize default but the user can still change them with right-click context menu. @@ -859,9 +860,9 @@ ImGuiStyle::ImGuiStyle() Colors[ImGuiCol_Header] = ImVec4(0.40f, 0.40f, 0.90f, 0.45f); Colors[ImGuiCol_HeaderHovered] = ImVec4(0.45f, 0.45f, 0.90f, 0.80f); Colors[ImGuiCol_HeaderActive] = ImVec4(0.53f, 0.53f, 0.87f, 0.80f); - Colors[ImGuiCol_Column] = ImVec4(0.50f, 0.50f, 0.50f, 1.00f); - Colors[ImGuiCol_ColumnHovered] = ImVec4(0.70f, 0.60f, 0.60f, 1.00f); - Colors[ImGuiCol_ColumnActive] = ImVec4(0.90f, 0.70f, 0.70f, 1.00f); + Colors[ImGuiCol_Separator] = ImVec4(0.50f, 0.50f, 0.50f, 1.00f); + Colors[ImGuiCol_SeparatorHovered] = ImVec4(0.60f, 0.60f, 0.70f, 1.00f); + Colors[ImGuiCol_SeparatorActive] = ImVec4(0.70f, 0.70f, 0.90f, 1.00f); Colors[ImGuiCol_ResizeGrip] = ImVec4(1.00f, 1.00f, 1.00f, 0.30f); Colors[ImGuiCol_ResizeGripHovered] = ImVec4(1.00f, 1.00f, 1.00f, 0.60f); Colors[ImGuiCol_ResizeGripActive] = ImVec4(1.00f, 1.00f, 1.00f, 0.90f); @@ -4969,9 +4970,9 @@ const char* ImGui::GetStyleColName(ImGuiCol idx) case ImGuiCol_Header: return "Header"; case ImGuiCol_HeaderHovered: return "HeaderHovered"; case ImGuiCol_HeaderActive: return "HeaderActive"; - case ImGuiCol_Column: return "Column"; - case ImGuiCol_ColumnHovered: return "ColumnHovered"; - case ImGuiCol_ColumnActive: return "ColumnActive"; + case ImGuiCol_Separator: return "Separator"; + case ImGuiCol_SeparatorHovered: return "SeparatorHovered"; + case ImGuiCol_SeparatorActive: return "SeparatorActive"; case ImGuiCol_ResizeGrip: return "ResizeGrip"; case ImGuiCol_ResizeGripHovered: return "ResizeGripHovered"; case ImGuiCol_ResizeGripActive: return "ResizeGripActive"; @@ -9843,7 +9844,7 @@ void ImGui::Separator() return; } - window->DrawList->AddLine(bb.Min, ImVec2(bb.Max.x,bb.Min.y), GetColorU32(ImGuiCol_Border)); + window->DrawList->AddLine(bb.Min, ImVec2(bb.Max.x,bb.Min.y), GetColorU32(ImGuiCol_Separator)); ImGuiContext& g = *GImGui; if (g.LogEnabled) @@ -10144,7 +10145,7 @@ void ImGui::Columns(int columns_count, const char* id, bool border) g.MouseCursor = ImGuiMouseCursor_ResizeEW; // Draw before resize so our items positioning are in sync with the line being drawn - const ImU32 col = GetColorU32(held ? ImGuiCol_ColumnActive : hovered ? ImGuiCol_ColumnHovered : ImGuiCol_Column); + const ImU32 col = GetColorU32(held ? ImGuiCol_SeparatorActive : hovered ? ImGuiCol_SeparatorHovered : ImGuiCol_Separator); const float xi = (float)(int)x; window->DrawList->AddLine(ImVec2(xi, y1+1.0f), ImVec2(xi, y2), col); diff --git a/imgui.h b/imgui.h index 1c5cce612..195cdccba 100644 --- a/imgui.h +++ b/imgui.h @@ -624,9 +624,9 @@ enum ImGuiCol_ ImGuiCol_Header, ImGuiCol_HeaderHovered, ImGuiCol_HeaderActive, - ImGuiCol_Column, - ImGuiCol_ColumnHovered, - ImGuiCol_ColumnActive, + ImGuiCol_Separator, + ImGuiCol_SeparatorHovered, + ImGuiCol_SeparatorActive, ImGuiCol_ResizeGrip, ImGuiCol_ResizeGripHovered, ImGuiCol_ResizeGripActive, From 97fccbdb73044695b1afb45a03e9c99aa8cb3ac7 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 14 Aug 2017 13:05:03 +0800 Subject: [PATCH 209/921] Demo: Fixed conflicting id introduced in be9628494a95748d86757920d664961b7ce91646 . Added tooltip. --- imgui_demo.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 9fedba302..3a7691162 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1484,6 +1484,8 @@ void ImGui::ShowTestWindow(bool* p_open) if (ImGui::CollapsingHeader("Columns")) { + ImGui::PushID("Columns"); + // Basic columns if (ImGui::TreeNode("Basic")) { @@ -1631,6 +1633,7 @@ void ImGui::ShowTestWindow(bool* p_open) ImGui::Separator(); ImGui::TreePop(); } + ImGui::PopID(); } if (ImGui::CollapsingHeader("Filtering")) @@ -1786,7 +1789,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) if (ImGui::TreeNode("Rendering")) { - ImGui::Checkbox("Anti-aliased lines", &style.AntiAliasedLines); + ImGui::Checkbox("Anti-aliased lines", &style.AntiAliasedLines); ImGui::SameLine(); ShowHelpMarker("When disabling anti-aliasing lines, you'll probably want to disable borders in your style as well."); ImGui::Checkbox("Anti-aliased shapes", &style.AntiAliasedShapes); ImGui::PushItemWidth(100); ImGui::DragFloat("Curve Tessellation Tolerance", &style.CurveTessellationTol, 0.02f, 0.10f, FLT_MAX, NULL, 2.0f); From c1e1e015c4a81c68812113d85dfdedbc598ff413 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 14 Aug 2017 13:07:55 +0800 Subject: [PATCH 210/921] Style: Tweaked default border (which is off by default) to be less noticeable (#707, #1019) --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 6c09b3976..389198d93 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -837,7 +837,7 @@ ImGuiStyle::ImGuiStyle() Colors[ImGuiCol_WindowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.70f); Colors[ImGuiCol_ChildWindowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); Colors[ImGuiCol_PopupBg] = ImVec4(0.05f, 0.05f, 0.10f, 0.90f); - Colors[ImGuiCol_Border] = ImVec4(0.70f, 0.70f, 0.70f, 0.65f); + Colors[ImGuiCol_Border] = ImVec4(0.70f, 0.70f, 0.70f, 0.22f); Colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); Colors[ImGuiCol_FrameBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.30f); // Background of checkbox, radio button, plot, slider, text input Colors[ImGuiCol_FrameBgHovered] = ImVec4(0.90f, 0.80f, 0.80f, 0.40f); From 2b7fe73a08d8958641dbaff23e18c0e531a9523f Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 14 Aug 2017 13:27:19 +0800 Subject: [PATCH 211/921] Window size can be loaded from .ini data even if ImGuiWindowFlags_NoResize flag is set (#1048, #1056) --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 389198d93..ecd747d14 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3941,7 +3941,7 @@ static ImGuiWindow* CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFl window->Collapsed = settings->Collapsed; } - if (ImLengthSqr(settings->Size) > 0.00001f && !(flags & ImGuiWindowFlags_NoResize)) + if (ImLengthSqr(settings->Size) > 0.00001f) size = settings->Size; window->Size = window->SizeFull = size; } From c26b29b254e04a0293fc7f4231dcac51ac6def44 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 14 Aug 2017 15:14:46 +0800 Subject: [PATCH 212/921] Style: Moving code in a function to make incoming diff easier to parse. --- imgui.cpp | 94 ++++++++++++++++++++++++++++++------------------------- imgui.h | 3 ++ 2 files changed, 54 insertions(+), 43 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index ecd747d14..8588b27ab 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -832,49 +832,57 @@ ImGuiStyle::ImGuiStyle() AntiAliasedShapes = true; // Enable anti-aliasing on filled shapes (rounded rectangles, circles, etc.) CurveTessellationTol = 1.25f; // Tessellation tolerance. Decrease for highly tessellated curves (higher quality, more polygons), increase to reduce quality. - Colors[ImGuiCol_Text] = ImVec4(0.90f, 0.90f, 0.90f, 1.00f); - Colors[ImGuiCol_TextDisabled] = ImVec4(0.60f, 0.60f, 0.60f, 1.00f); - Colors[ImGuiCol_WindowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.70f); - Colors[ImGuiCol_ChildWindowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); - Colors[ImGuiCol_PopupBg] = ImVec4(0.05f, 0.05f, 0.10f, 0.90f); - Colors[ImGuiCol_Border] = ImVec4(0.70f, 0.70f, 0.70f, 0.22f); - Colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); - Colors[ImGuiCol_FrameBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.30f); // Background of checkbox, radio button, plot, slider, text input - Colors[ImGuiCol_FrameBgHovered] = ImVec4(0.90f, 0.80f, 0.80f, 0.40f); - Colors[ImGuiCol_FrameBgActive] = ImVec4(0.90f, 0.65f, 0.65f, 0.45f); - Colors[ImGuiCol_TitleBg] = ImVec4(0.27f, 0.27f, 0.54f, 0.83f); - Colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.40f, 0.40f, 0.80f, 0.20f); - Colors[ImGuiCol_TitleBgActive] = ImVec4(0.32f, 0.32f, 0.63f, 0.87f); - Colors[ImGuiCol_MenuBarBg] = ImVec4(0.40f, 0.40f, 0.55f, 0.80f); - Colors[ImGuiCol_ScrollbarBg] = ImVec4(0.20f, 0.25f, 0.30f, 0.60f); - Colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.40f, 0.40f, 0.80f, 0.30f); - Colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.40f, 0.40f, 0.80f, 0.40f); - Colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.80f, 0.50f, 0.50f, 0.40f); - Colors[ImGuiCol_ComboBg] = ImVec4(0.20f, 0.20f, 0.20f, 0.99f); - Colors[ImGuiCol_CheckMark] = ImVec4(0.90f, 0.90f, 0.90f, 0.50f); - Colors[ImGuiCol_SliderGrab] = ImVec4(1.00f, 1.00f, 1.00f, 0.30f); - Colors[ImGuiCol_SliderGrabActive] = ImVec4(0.80f, 0.50f, 0.50f, 1.00f); - Colors[ImGuiCol_Button] = ImVec4(0.67f, 0.40f, 0.40f, 0.60f); - Colors[ImGuiCol_ButtonHovered] = ImVec4(0.67f, 0.40f, 0.40f, 1.00f); - Colors[ImGuiCol_ButtonActive] = ImVec4(0.80f, 0.50f, 0.50f, 1.00f); - Colors[ImGuiCol_Header] = ImVec4(0.40f, 0.40f, 0.90f, 0.45f); - Colors[ImGuiCol_HeaderHovered] = ImVec4(0.45f, 0.45f, 0.90f, 0.80f); - Colors[ImGuiCol_HeaderActive] = ImVec4(0.53f, 0.53f, 0.87f, 0.80f); - Colors[ImGuiCol_Separator] = ImVec4(0.50f, 0.50f, 0.50f, 1.00f); - Colors[ImGuiCol_SeparatorHovered] = ImVec4(0.60f, 0.60f, 0.70f, 1.00f); - Colors[ImGuiCol_SeparatorActive] = ImVec4(0.70f, 0.70f, 0.90f, 1.00f); - Colors[ImGuiCol_ResizeGrip] = ImVec4(1.00f, 1.00f, 1.00f, 0.30f); - Colors[ImGuiCol_ResizeGripHovered] = ImVec4(1.00f, 1.00f, 1.00f, 0.60f); - Colors[ImGuiCol_ResizeGripActive] = ImVec4(1.00f, 1.00f, 1.00f, 0.90f); - Colors[ImGuiCol_CloseButton] = ImVec4(0.50f, 0.50f, 0.90f, 0.50f); - Colors[ImGuiCol_CloseButtonHovered] = ImVec4(0.70f, 0.70f, 0.90f, 0.60f); - Colors[ImGuiCol_CloseButtonActive] = ImVec4(0.70f, 0.70f, 0.70f, 1.00f); - Colors[ImGuiCol_PlotLines] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f); - Colors[ImGuiCol_PlotLinesHovered] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); - Colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); - Colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.60f, 0.00f, 1.00f); - Colors[ImGuiCol_TextSelectedBg] = ImVec4(0.00f, 0.00f, 1.00f, 0.35f); - Colors[ImGuiCol_ModalWindowDarkening] = ImVec4(0.20f, 0.20f, 0.20f, 0.35f); + ImGui::StyleColorsClassic(this); +} + +void ImGui::StyleColorsClassic(ImGuiStyle* dst) +{ + ImGuiStyle* style = dst ? dst : &ImGui::GetStyle(); + ImVec4* colors = style->Colors; + + colors[ImGuiCol_Text] = ImVec4(0.90f, 0.90f, 0.90f, 1.00f); + colors[ImGuiCol_TextDisabled] = ImVec4(0.60f, 0.60f, 0.60f, 1.00f); + colors[ImGuiCol_WindowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.70f); + colors[ImGuiCol_ChildWindowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); + colors[ImGuiCol_PopupBg] = ImVec4(0.05f, 0.05f, 0.10f, 0.90f); + colors[ImGuiCol_Border] = ImVec4(0.70f, 0.70f, 0.70f, 0.22f); + colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); + colors[ImGuiCol_FrameBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.30f); // Background of checkbox, radio button, plot, slider, text input + colors[ImGuiCol_FrameBgHovered] = ImVec4(0.90f, 0.80f, 0.80f, 0.40f); + colors[ImGuiCol_FrameBgActive] = ImVec4(0.90f, 0.65f, 0.65f, 0.45f); + colors[ImGuiCol_TitleBg] = ImVec4(0.27f, 0.27f, 0.54f, 0.83f); + colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.40f, 0.40f, 0.80f, 0.20f); + colors[ImGuiCol_TitleBgActive] = ImVec4(0.32f, 0.32f, 0.63f, 0.87f); + colors[ImGuiCol_MenuBarBg] = ImVec4(0.40f, 0.40f, 0.55f, 0.80f); + colors[ImGuiCol_ScrollbarBg] = ImVec4(0.20f, 0.25f, 0.30f, 0.60f); + colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.40f, 0.40f, 0.80f, 0.30f); + colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.40f, 0.40f, 0.80f, 0.40f); + colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.80f, 0.50f, 0.50f, 0.40f); + colors[ImGuiCol_ComboBg] = ImVec4(0.20f, 0.20f, 0.20f, 0.99f); + colors[ImGuiCol_CheckMark] = ImVec4(0.90f, 0.90f, 0.90f, 0.50f); + colors[ImGuiCol_SliderGrab] = ImVec4(1.00f, 1.00f, 1.00f, 0.30f); + colors[ImGuiCol_SliderGrabActive] = ImVec4(0.80f, 0.50f, 0.50f, 1.00f); + colors[ImGuiCol_Button] = ImVec4(0.67f, 0.40f, 0.40f, 0.60f); + colors[ImGuiCol_ButtonHovered] = ImVec4(0.67f, 0.40f, 0.40f, 1.00f); + colors[ImGuiCol_ButtonActive] = ImVec4(0.80f, 0.50f, 0.50f, 1.00f); + colors[ImGuiCol_Header] = ImVec4(0.40f, 0.40f, 0.90f, 0.45f); + colors[ImGuiCol_HeaderHovered] = ImVec4(0.45f, 0.45f, 0.90f, 0.80f); + colors[ImGuiCol_HeaderActive] = ImVec4(0.53f, 0.53f, 0.87f, 0.80f); + colors[ImGuiCol_Separator] = ImVec4(0.50f, 0.50f, 0.50f, 1.00f); + colors[ImGuiCol_SeparatorHovered] = ImVec4(0.60f, 0.60f, 0.70f, 1.00f); + colors[ImGuiCol_SeparatorActive] = ImVec4(0.70f, 0.70f, 0.90f, 1.00f); + colors[ImGuiCol_ResizeGrip] = ImVec4(1.00f, 1.00f, 1.00f, 0.30f); + colors[ImGuiCol_ResizeGripHovered] = ImVec4(1.00f, 1.00f, 1.00f, 0.60f); + colors[ImGuiCol_ResizeGripActive] = ImVec4(1.00f, 1.00f, 1.00f, 0.90f); + colors[ImGuiCol_CloseButton] = ImVec4(0.50f, 0.50f, 0.90f, 0.50f); + colors[ImGuiCol_CloseButtonHovered] = ImVec4(0.70f, 0.70f, 0.90f, 0.60f); + colors[ImGuiCol_CloseButtonActive] = ImVec4(0.70f, 0.70f, 0.70f, 1.00f); + colors[ImGuiCol_PlotLines] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f); + colors[ImGuiCol_PlotLinesHovered] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); + colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); + colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.60f, 0.00f, 1.00f); + colors[ImGuiCol_TextSelectedBg] = ImVec4(0.00f, 0.00f, 1.00f, 0.35f); + colors[ImGuiCol_ModalWindowDarkening] = ImVec4(0.20f, 0.20f, 0.20f, 0.35f); } ImGuiIO::ImGuiIO() diff --git a/imgui.h b/imgui.h index 195cdccba..98e05d9c7 100644 --- a/imgui.h +++ b/imgui.h @@ -402,6 +402,9 @@ namespace ImGui IMGUI_API void PushClipRect(const ImVec2& clip_rect_min, const ImVec2& clip_rect_max, bool intersect_with_current_clip_rect); IMGUI_API void PopClipRect(); + // Styles + IMGUI_API void StyleColorsClassic(ImGuiStyle* dst = NULL); + // Utilities IMGUI_API bool IsItemHovered(); // was the last item hovered by mouse? IMGUI_API bool IsItemHoveredRect(); // was the last item hovered by mouse? even if another item is active or window is blocked by popup while we are hovering this From bd3dfc0ebaab551ab7febc758d641da5e2087544 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 14 Aug 2017 15:34:04 +0800 Subject: [PATCH 213/921] Moved TODO list to TODO.txt --- TODO.txt | 150 +++++++++++++++++++++++++++++++++++++++++++++++++++ imgui.cpp | 156 +++--------------------------------------------------- 2 files changed, 156 insertions(+), 150 deletions(-) create mode 100644 TODO.txt diff --git a/TODO.txt b/TODO.txt new file mode 100644 index 000000000..96ab22c82 --- /dev/null +++ b/TODO.txt @@ -0,0 +1,150 @@ +dear imgui +ISSUES & TODO LIST + +Issue numbers (#) refer to github issues listed at https://github.com/ocornut/imgui/issues +The list below consist mostly of ideas noted down before they are requested/discussed by users (at which point it usually moves to the github) + + - doc: add a proper documentation+regression testing system (#435) + - window: add a way for very transient windows (non-saved, temporary overlay over hundreds of objects) to "clean" up from the global window list. perhaps a lightweight explicit cleanup pass. + - window: calling SetNextWindowSize() every frame with <= 0 doesn't do anything, may be useful to allow (particularly when used for a single axis). (#690) + - window: auto-fit feedback loop when user relies on any dynamic layout (window width multiplier, column) appears weird to end-user. clarify. + - window: allow resizing of child windows (possibly given min/max for each axis?.) + - window: background options for child windows, border option (disable rounding). + - window: add a way to clear an existing window instead of appending (e.g. for tooltip override using a consistent api rather than the deferred tooltip) > + - window: resizing from any sides? + mouse cursor directives for app. +!- window: begin with *p_open == false should return false. + - window: get size/pos helpers given names (see discussion in #249) + - window: a collapsed window can be stuck behind the main menu bar? + - window: when window is small, prioritize resize button over close button. + - window: detect extra End() call that pop the "Debug" window out and assert at call site instead of later. + - window/tooltip: allow to set the width of a tooltip to allow TextWrapped() etc. while keeping the height automatic. + - window: increase minimum size of a window with menus or fix the menu rendering so that it doesn't look odd. + - draw-list: maintaining bounding box per command would allow to merge draw command when clipping isn't relied on (typical non-scrolling window or non-overflowing column would merge with previous command). +!- scrolling: allow immediately effective change of scroll after Begin() if we haven't appended items yet + - splitter/separator: formalize the splitter idiom into an official api (we want to handle n-way split) (#319) + - widgets: display mode: widget-label, label-widget (aligned on column or using fixed size), label-newline-tab-widget etc. (#395) + - widgets: clean up widgets internal toward exposing everything. + - widgets: add disabled and read-only modes (#211) + - main: considering adding an Init() function? some constructs are awkward in the implementation because of the lack of them. +!- main: make it so that a frame with no window registered won't refocus every window on subsequent frames (~bump LastFrameActive of all windows). + - 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: clean up the mess caused by converting UTF-8 <> wchar. the code is rather inefficient right now and super fragile. + - input text: reorganize event handling, allow CharFilter to modify buffers, allow multiple events? (#541) + - input text: expose CursorPos in char filter event (#816) + - input text: flag to disable live update of the user buffer (also applies to float/int text input) + - input text: resize behavior - field could stretch when being edited? hover tooltip shows more text? + - input text: add ImGuiInputTextFlags_EnterToApply? (off #218) + - input text: add discard flag (e.g. ImGuiInputTextFlags_DiscardActiveBuffer) or make it easier to clear active focus for text replacement during edition (#725) + - input text multi-line: don't directly call AddText() which does an unnecessary vertex reserve for character count prior to clipping. and/or more line-based clipping to AddText(). and/or reorganize TextUnformatted/RenderText for more efficiency for large text (e.g TextUnformatted could clip and log separately, etc). + - input text multi-line: way to dynamically grow the buffer without forcing the user to initially allocate for worse case (follow up on #200) + - input text multi-line: line numbers? status bar? (follow up on #200) + - input text multi-line: behave better when user changes input buffer while editing is active (even though it is illegal behavior). namely, the change of buffer can create a scrollbar glitch (#725) + - input text multi-line: better horizontal scrolling support (#383, #1224) + - input text: allow centering/positioning text so that ctrl+clicking Drag or Slider keeps the textual value at the same pixel position. + - input number: optional range min/max for Input*() functions + - input number: holding [-]/[+] buttons could increase the step speed non-linearly (or user-controlled) + - input number: use mouse wheel to step up/down + - input number: applying arithmetics ops (+,-,*,/) messes up with text edit undo stack. + - button: provide a button that looks framed. + - text: proper alignment options + - image/image button: misalignment on padded/bordered button? + - image/image button: parameters are confusing, image() has tint_col,border_col whereas imagebutton() has bg_col/tint_col. Even thou they are different parameters ordering could be more consistent. can we fix that? + - layout: horizontal layout helper (#97) + - layout: horizontal flow until no space left (#404) + - layout: more generic alignment state (left/right/centered) for single items? + - layout: clean up the InputFloatN/SliderFloatN/ColorEdit4 layout code. item width should include frame padding. + - layout: BeginGroup() needs a border option. + - columns: declare column set (each column: fixed size, %, fill, distribute default size among fills) (#513, #125) + - columns: add a conditional parameter to SetColumnOffset() (#513, #125) + - columns: separator function or parameter that works within the column (currently Separator() bypass all columns) (#125) + - columns: columns header to act as button (~sort op) and allow resize/reorder (#513, #125) + - columns: user specify columns size (#513, #125) + - columns: flag to add horizontal separator above/below? + - columns/layout: setup minimum line height (equivalent of automatically calling AlignFirstTextHeightToWidgets) + - combo: sparse combo boxes (via function call?) / iterators + - 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 keyboard for custom listbox (pr #203) + - listbox: multiple selection + - listbox: user may want to initial scroll to focus on the one selected value? + - listbox: keyboard navigation. + - listbox: scrolling should track modified selection. +!- popups/menus: clarify usage of popups id, how MenuItem/Selectable closing parent popups affects the ID, etc. this is quite fishy needs improvement! (#331, #402) + - popups: add variant using global identifier similar to Begin/End (#402) + - popups: border options. richer api like BeginChild() perhaps? (#197) + - tooltip: tooltip that doesn't fit in entire screen seems to lose their "last preferred button" and may teleport when moving mouse + - menus: local shortcuts, global shortcuts (#456, #126) + - menus: icons + - menus: menubars: some sort of priority / effect of main menu-bar on desktop size? + - menus: calling BeginMenu() twice with a same name doesn't seem to append nicely + - statusbar: add a per-window status bar helper similar to what menubar does. + - tabs (#261, #351) + - separator: separator on the initial position of a window is not visible (cursorpos.y <= clippos.y) +!- color: the color helpers/typing is a mess and needs sorting out. + - node/graph editor (#306) + - pie menus patterns (#434) + - drag'n drop, dragging helpers (carry dragging info, visualize drag source before clicking, drop target, etc.) (#143, #479) + - plot: PlotLines() should use the polygon-stroke facilities (currently issues with averaging normals) + - plot: make it easier for user to draw extra stuff into the graph (e.g: draw basis, highlight certain points, 2d plots, multiple plots) + - plot: "smooth" automatic scale over time, user give an input 0.0(full user scale) 1.0(full derived from value) + - plot: add a helper e.g. Plot(char* label, float value, float time_span=2.0f) that stores values and Plot them for you - probably another function name. and/or automatically allow to plot ANY displayed value (more reliance on stable ID) + - slider: allow using the [-]/[+] buttons used by InputFloat()/InputInt() + - slider: initial absolute click is imprecise. change to relative movement slider (same as scrollbar). + - slider: add dragging-based widgets to edit values with mouse (on 2 axises), saving screen real-estate. + - slider: tint background based on value (e.g. v_min -> v_max, or use 0.0f either side of the sign) + - slider & drag: int data passing through a float + - drag float: up/down axis + - drag float: added leeway on edge (e.g. a few invisible steps past the clamp limits) + - tree node / optimization: avoid formatting when clipped. + - tree node: tree-node/header right-most side doesn't take account of horizontal scrolling. + - tree node: add treenode/treepush int variants? not there because (void*) cast from int warns on some platforms/settings? + - tree node: try to apply scrolling at time of TreePop() if node was just opened and end of node is past scrolling limits? + - tree node / selectable render mismatch which is visible if you use them both next to each other (e.g. cf. property viewer) + - tree node: tweak color scheme to distinguish headers from selected tree node (#581) + - textwrapped: figure out better way to use TextWrapped() in an always auto-resize context (tooltip, etc.) (#249) + - settings: write more decent code to allow saving/loading new fields + - settings: api for per-tool simple persistent data (bool,int,float,columns sizes,etc.) in .ini file + - stb: add defines to disable stb implementations + - style: add window shadows. + - style/optimization: store rounded corners in texture to use 1 quad per corner (filled and wireframe) to lower the cost of rounding. + - style: color-box not always square? + - style: a concept of "compact style" that the end-user can easily rely on (e.g. PushStyleCompact()?) that maps to other settings? avoid implementing duplicate helpers such as SmallCheckbox(), etc. + - style: try to make PushStyleVar() more robust to incorrect parameters (to be more friendly to edit & continues situation). + - style: global scale setting. + - style: WindowPadding needs to be EVEN as the 0.5 multiplier used on this value probably have a subtle effect on clip rectangle + - text: simple markup language for color change? + - font: dynamic font atlas to avoid baking huge ranges into bitmap and make scaling easier. + - font: small opt: for monospace font (like the defalt one) we can trim IndexXAdvance as long as trailing value is == FallbackXAdvance + - font: add support for kerning, probably optional. perhaps default to (32..128)^2 matrix ~ 36KB then hash fallback. + - font: add a simpler CalcTextSizeA() api? current one ok but not welcome if user needs to call it directly (without going through ImGui::CalcTextSize) + - font: fix AddRemapChar() to work before font has been built. + - log: LogButtons() options for specifying depth and/or hiding depth slider + - log: have more control over the log scope (e.g. stop logging when leaving current tree node scope) + - log: be able to log anything (e.g. right-click on a window/tree-node, shows context menu? log into tty/file/clipboard) + - log: let user copy any window content to clipboard easily (CTRL+C on windows? while moving it? context menu?). code is commented because it fails with multiple Begin/End pairs. + - filters: set a current filter that tree node can automatically query to hide themselves + - filters: handle wildcards (with implicit leading/trailing *), regexps + - filters: fuzzy matches (may use code at blog.forrestthewoods.com/4cffeed33fdb) + - shortcuts: add a shortcut api, e.g. parse "&Save" and/or "Save (CTRL+S)", pass in to widgets or provide simple ways to use (button=activate, input=focus) +!- keyboard: tooltip & combo boxes are messing up / not honoring keyboard tabbing + - keyboard: full keyboard navigation and focus. (#323) + - focus: preserve ActiveId/focus stack state, e.g. when opening a menu and close it, previously selected InputText() focus gets restored (#622) + - focus: SetKeyboardFocusHere() on with >= 0 offset could be done on same frame (else latch and modulate on beginning of next frame) + - input: rework IO system to be able to pass actual ordered/timestamped events. (~#335, #71) + - input: allow to decide and pass explicit double-clicks (e.g. for windows by the CS_DBLCLKS style). + - input: support track pad style scrolling & slider edit. + - misc: provide a way to compile out the entire implementation while providing a dummy API (e.g. #define IMGUI_DUMMY_IMPL) + - misc: double-clicking on title bar to minimize isn't consistent, perhaps move to single-click on left-most collapse icon? + - misc: provide HoveredTime and ActivatedTime to ease the creation of animations. + - style editor: have a more global HSV setter (e.g. alter hue on all elements). consider replacing active/hovered by offset in HSV space? (#438) + - style editor: color child window height expressed in multiple of line height. + - remote: make a system like RemoteImGui first-class citizen/project (#75) + - drawlist: move Font, FontSize, FontTexUvWhitePixel inside ImDrawList and make it self-contained (apart from drawing settings?) + - drawlist: end-user probably can't call Clear() directly because we expect a texture to be pushed in the stack. + - examples: directx9: save/restore device state more thoroughly. + - examples: window minimize, maximize (#583) + - optimization: add clipping for multi-component widgets (SliderFloatX, ColorEditX, etc.). one problem is that nav branch can't easily clip parent group when there is a move request. + - optimization: add a flag to disable most of rendering, for the case where the user expect to skip it (#335) + - optimization: use another hash function than crc32, e.g. FNV1a + - optimization/render: merge command-lists with same clip-rect into one even if they aren't sequential? (as long as in-between clip rectangle don't overlap)? + - optimization: turn some the various stack vectors into statically-sized arrays diff --git a/imgui.cpp b/imgui.cpp index ecd747d14..1940f0bf6 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -20,6 +20,7 @@ - How to update to a newer version of ImGui - Getting started with integrating ImGui in your code/engine - API BREAKING CHANGES (read me when you update!) + - ISSUES & TODO LIST - FREQUENTLY ASKED QUESTIONS (FAQ), TIPS - How can I help? - What is ImTextureID and how do I display an image? @@ -320,6 +321,11 @@ - 2014/08/28 (1.09) - changed the behavior of IO.PixelCenterOffset following various rendering fixes + ISSUES & TODO-LIST + ================== + See TODO.txt + + FREQUENTLY ASKED QUESTIONS (FAQ), TIPS ====================================== @@ -523,156 +529,6 @@ - tip: you can call Render() multiple times (e.g for VR renders). - tip: call and read the ShowTestWindow() code in imgui_demo.cpp for more example of how to use ImGui! - - ISSUES & TODO-LIST - ================== - Issue numbers (#) refer to github issues listed at https://github.com/ocornut/imgui/issues - The list below consist mostly of ideas noted down before they are requested/discussed by users (at which point it usually moves to the github) - - - doc: add a proper documentation+regression testing system (#435) - - window: add a way for very transient windows (non-saved, temporary overlay over hundreds of objects) to "clean" up from the global window list. perhaps a lightweight explicit cleanup pass. - - window: calling SetNextWindowSize() every frame with <= 0 doesn't do anything, may be useful to allow (particularly when used for a single axis) (#690) - - window: auto-fit feedback loop when user relies on any dynamic layout (window width multiplier, column) appears weird to end-user. clarify. - - window: allow resizing of child windows (possibly given min/max for each axis?) - - window: background options for child windows, border option (disable rounding) - - window: add a way to clear an existing window instead of appending (e.g. for tooltip override using a consistent api rather than the deferred tooltip) - - window: resizing from any sides? + mouse cursor directives for app. -!- window: begin with *p_open == false should return false. - - window: get size/pos helpers given names (see discussion in #249) - - window: a collapsed window can be stuck behind the main menu bar? - - window: when window is small, prioritize resize button over close button. - - window: detect extra End() call that pop the "Debug" window out and assert at call site instead of later. - - window/tooltip: allow to set the width of a tooltip to allow TextWrapped() etc. while keeping the height automatic. - - window: increase minimum size of a window with menus or fix the menu rendering so that it doesn't look odd. - - draw-list: maintaining bounding box per command would allow to merge draw command when clipping isn't relied on (typical non-scrolling window or non-overflowing column would merge with previous command). -!- scrolling: allow immediately effective change of scroll after Begin() if we haven't appended items yet - - splitter/separator: formalize the splitter idiom into an official api (we want to handle n-way split) (#319) - - widgets: display mode: widget-label, label-widget (aligned on column or using fixed size), label-newline-tab-widget etc. (#395) - - widgets: clean up widgets internal toward exposing everything. - - widgets: add disabled and read-only modes (#211) - - main: considering adding an Init() function? some constructs are awkward in the implementation because of the lack of them. -!- main: make it so that a frame with no window registered won't refocus every window on subsequent frames (~bump LastFrameActive of all windows). - - 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: clean up the mess caused by converting UTF-8 <> wchar. the code is rather inefficient right now and super fragile. - - input text: reorganize event handling, allow CharFilter to modify buffers, allow multiple events? (#541) - - input text: expose CursorPos in char filter event (#816) - - input text: flag to disable live update of the user buffer (also applies to float/int text input) - - input text: resize behavior - field could stretch when being edited? hover tooltip shows more text? - - input text: add ImGuiInputTextFlags_EnterToApply? (off #218) - - input text: add discard flag (e.g. ImGuiInputTextFlags_DiscardActiveBuffer) or make it easier to clear active focus for text replacement during edition (#725) - - input text multi-line: don't directly call AddText() which does an unnecessary vertex reserve for character count prior to clipping. and/or more line-based clipping to AddText(). and/or reorganize TextUnformatted/RenderText for more efficiency for large text (e.g TextUnformatted could clip and log separately, etc). - - input text multi-line: way to dynamically grow the buffer without forcing the user to initially allocate for worse case (follow up on #200) - - input text multi-line: line numbers? status bar? (follow up on #200) - - input text multi-line: behave better when user changes input buffer while editing is active (even though it is illegal behavior). namely, the change of buffer can create a scrollbar glitch (#725) - - input text multi-line: better horizontal scrolling support (#383, #1224) - - input text: allow centering/positioning text so that ctrl+clicking Drag or Slider keeps the textual value at the same pixel position. - - input number: optional range min/max for Input*() functions - - input number: holding [-]/[+] buttons could increase the step speed non-linearly (or user-controlled) - - input number: use mouse wheel to step up/down - - input number: applying arithmetics ops (+,-,*,/) messes up with text edit undo stack. - - button: provide a button that looks framed. - - text: proper alignment options - - image/image button: misalignment on padded/bordered button? - - image/image button: parameters are confusing, image() has tint_col,border_col whereas imagebutton() has bg_col/tint_col. Even thou they are different parameters ordering could be more consistent. can we fix that? - - layout: horizontal layout helper (#97) - - layout: horizontal flow until no space left (#404) - - layout: more generic alignment state (left/right/centered) for single items? - - layout: clean up the InputFloatN/SliderFloatN/ColorEdit4 layout code. item width should include frame padding. - - layout: BeginGroup() needs a border option. - - columns: declare column set (each column: fixed size, %, fill, distribute default size among fills) (#513, #125) - - columns: add a conditional parameter to SetColumnOffset() (#513, #125) - - columns: separator function or parameter that works within the column (currently Separator() bypass all columns) (#125) - - columns: columns header to act as button (~sort op) and allow resize/reorder (#513, #125) - - columns: user specify columns size (#513, #125) - - columns: flag to add horizontal separator above/below? - - columns/layout: setup minimum line height (equivalent of automatically calling AlignFirstTextHeightToWidgets) - - combo: sparse combo boxes (via function call?) / iterators - - 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 keyboard for custom listbox (pr #203) - - listbox: multiple selection - - listbox: user may want to initial scroll to focus on the one selected value? - - listbox: keyboard navigation. - - listbox: scrolling should track modified selection. -!- popups/menus: clarify usage of popups id, how MenuItem/Selectable closing parent popups affects the ID, etc. this is quite fishy needs improvement! (#331, #402) - - popups: add variant using global identifier similar to Begin/End (#402) - - popups: border options. richer api like BeginChild() perhaps? (#197) - - tooltip: tooltip that doesn't fit in entire screen seems to lose their "last preferred button" and may teleport when moving mouse - - menus: local shortcuts, global shortcuts (#456, #126) - - menus: icons - - menus: menubars: some sort of priority / effect of main menu-bar on desktop size? - - menus: calling BeginMenu() twice with a same name doesn't seem to append nicely - - statusbar: add a per-window status bar helper similar to what menubar does. - - tabs (#261, #351) - - separator: separator on the initial position of a window is not visible (cursorpos.y <= clippos.y) -!- color: the color helpers/typing is a mess and needs sorting out. - - node/graph editor (#306) - - pie menus patterns (#434) - - drag'n drop, dragging helpers (carry dragging info, visualize drag source before clicking, drop target, etc.) (#143, #479) - - plot: PlotLines() should use the polygon-stroke facilities (currently issues with averaging normals) - - plot: make it easier for user to draw extra stuff into the graph (e.g: draw basis, highlight certain points, 2d plots, multiple plots) - - plot: "smooth" automatic scale over time, user give an input 0.0(full user scale) 1.0(full derived from value) - - plot: add a helper e.g. Plot(char* label, float value, float time_span=2.0f) that stores values and Plot them for you - probably another function name. and/or automatically allow to plot ANY displayed value (more reliance on stable ID) - - slider: allow using the [-]/[+] buttons used by InputFloat()/InputInt() - - slider: initial absolute click is imprecise. change to relative movement slider (same as scrollbar). - - slider: add dragging-based widgets to edit values with mouse (on 2 axises), saving screen real-estate. - - slider: tint background based on value (e.g. v_min -> v_max, or use 0.0f either side of the sign) - - slider & drag: int data passing through a float - - drag float: up/down axis - - drag float: added leeway on edge (e.g. a few invisible steps past the clamp limits) - - tree node / optimization: avoid formatting when clipped. - - tree node: tree-node/header right-most side doesn't take account of horizontal scrolling. - - tree node: add treenode/treepush int variants? not there because (void*) cast from int warns on some platforms/settings? - - tree node: try to apply scrolling at time of TreePop() if node was just opened and end of node is past scrolling limits? - - tree node / selectable render mismatch which is visible if you use them both next to each other (e.g. cf. property viewer) - - tree node: tweak color scheme to distinguish headers from selected tree node (#581) - - textwrapped: figure out better way to use TextWrapped() in an always auto-resize context (tooltip, etc.) (#249) - - settings: write more decent code to allow saving/loading new fields - - settings: api for per-tool simple persistent data (bool,int,float,columns sizes,etc.) in .ini file - - stb: add defines to disable stb implementations - - style: add window shadows. - - style/optimization: store rounded corners in texture to use 1 quad per corner (filled and wireframe) to lower the cost of rounding. - - style: color-box not always square? - - style: a concept of "compact style" that the end-user can easily rely on (e.g. PushStyleCompact()?) that maps to other settings? avoid implementing duplicate helpers such as SmallCheckbox(), etc. - - style: try to make PushStyleVar() more robust to incorrect parameters (to be more friendly to edit & continues situation). - - style: global scale setting. - - style: WindowPadding needs to be EVEN as the 0.5 multiplier used on this value probably have a subtle effect on clip rectangle - - text: simple markup language for color change? - - font: dynamic font atlas to avoid baking huge ranges into bitmap and make scaling easier. - - font: small opt: for monospace font (like the defalt one) we can trim IndexXAdvance as long as trailing value is == FallbackXAdvance - - font: add support for kerning, probably optional. perhaps default to (32..128)^2 matrix ~ 36KB then hash fallback. - - font: add a simpler CalcTextSizeA() api? current one ok but not welcome if user needs to call it directly (without going through ImGui::CalcTextSize) - - font: fix AddRemapChar() to work before font has been built. - - log: LogButtons() options for specifying depth and/or hiding depth slider - - log: have more control over the log scope (e.g. stop logging when leaving current tree node scope) - - log: be able to log anything (e.g. right-click on a window/tree-node, shows context menu? log into tty/file/clipboard) - - log: let user copy any window content to clipboard easily (CTRL+C on windows? while moving it? context menu?). code is commented because it fails with multiple Begin/End pairs. - - filters: set a current filter that tree node can automatically query to hide themselves - - filters: handle wildcards (with implicit leading/trailing *), regexps - - filters: fuzzy matches (may use code at blog.forrestthewoods.com/4cffeed33fdb) - - shortcuts: add a shortcut api, e.g. parse "&Save" and/or "Save (CTRL+S)", pass in to widgets or provide simple ways to use (button=activate, input=focus) -!- keyboard: tooltip & combo boxes are messing up / not honoring keyboard tabbing - - keyboard: full keyboard navigation and focus. (#323) - - focus: preserve ActiveId/focus stack state, e.g. when opening a menu and close it, previously selected InputText() focus gets restored (#622) - - focus: SetKeyboardFocusHere() on with >= 0 offset could be done on same frame (else latch and modulate on beginning of next frame) - - input: rework IO system to be able to pass actual ordered/timestamped events. (~#335, #71) - - input: allow to decide and pass explicit double-clicks (e.g. for windows by the CS_DBLCLKS style). - - input: support track pad style scrolling & slider edit. - - misc: provide a way to compile out the entire implementation while providing a dummy API (e.g. #define IMGUI_DUMMY_IMPL) - - misc: double-clicking on title bar to minimize isn't consistent, perhaps move to single-click on left-most collapse icon? - - misc: provide HoveredTime and ActivatedTime to ease the creation of animations. - - style editor: have a more global HSV setter (e.g. alter hue on all elements). consider replacing active/hovered by offset in HSV space? (#438) - - style editor: color child window height expressed in multiple of line height. - - remote: make a system like RemoteImGui first-class citizen/project (#75) - - drawlist: move Font, FontSize, FontTexUvWhitePixel inside ImDrawList and make it self-contained (apart from drawing settings?) - - drawlist: end-user probably can't call Clear() directly because we expect a texture to be pushed in the stack. - - examples: directx9: save/restore device state more thoroughly. - - examples: window minimize, maximize (#583) - - optimization: add clipping for multi-component widgets (SliderFloatX, ColorEditX, etc.). one problem is that nav branch can't easily clip parent group when there is a move request. - - optimization: add a flag to disable most of rendering, for the case where the user expect to skip it (#335) - - optimization: use another hash function than crc32, e.g. FNV1a - - optimization/render: merge command-lists with same clip-rect into one even if they aren't sequential? (as long as in-between clip rectangle don't overlap)? - - optimization: turn some the various stack vectors into statically-sized arrays */ #if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) From 3d6e037c23cf118c333eb225ebcc5870d25623bc Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 14 Aug 2017 16:27:22 +0800 Subject: [PATCH 214/921] Comments (#1034) --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 1940f0bf6..0ada9c045 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -7287,7 +7287,7 @@ bool ImGui::Checkbox(const char* label, bool* v) const ImGuiID id = window->GetID(label); const ImVec2 label_size = CalcTextSize(label, NULL, true); - const ImRect check_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(label_size.y + style.FramePadding.y*2, label_size.y + style.FramePadding.y*2)); + const ImRect check_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(label_size.y + style.FramePadding.y*2, label_size.y + style.FramePadding.y*2)); // We want a square shape to we use Y twice ItemSize(check_bb, style.FramePadding.y); ImRect total_bb = check_bb; From d258287c9287a3c909b84bc160708f3c3f65629d Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 14 Aug 2017 16:53:38 +0800 Subject: [PATCH 215/921] Revert d2c219d #826 + tidying up ImFont::RenderChar() --- imgui.h | 1 - imgui_draw.cpp | 13 +------------ 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/imgui.h b/imgui.h index bdcf10f20..195cdccba 100644 --- a/imgui.h +++ b/imgui.h @@ -1435,7 +1435,6 @@ struct ImFont // 'wrap_width' enable automatic word-wrapping across multiple lines to fit into given width. 0.0f to disable. IMGUI_API ImVec2 CalcTextSizeA(float size, float max_width, float wrap_width, const char* text_begin, const char* text_end = NULL, const char** remaining = NULL) const; // utf8 IMGUI_API const char* CalcWordWrapPositionA(float scale, const char* text, const char* text_end, float wrap_width) const; - IMGUI_API void RenderGlyph(ImDrawList* draw_list, ImVec2 pos, ImU32 col, const ImFont::Glyph* glyph) const; IMGUI_API void RenderChar(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, unsigned short c) const; IMGUI_API void RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width = 0.0f, bool cpu_fine_clip = false) const; diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 0de4f49ad..9a79ffbf0 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -2050,15 +2050,6 @@ ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, cons return text_size; } -void ImFont::RenderGlyph(ImDrawList* draw_list, ImVec2 pos, ImU32 col, const ImFont::Glyph* glyph) const { - pos.x = (float)(int)pos.x + DisplayOffset.x; - pos.y = (float)(int)pos.y + DisplayOffset.y; - ImVec2 pos_tl(pos.x + glyph->X0, pos.y + glyph->Y0); - ImVec2 pos_br(pos.x + glyph->X1, pos.y + glyph->Y1); - draw_list->PrimReserve(6, 4); - draw_list->PrimRectUV(pos_tl, pos_br, ImVec2(glyph->U0, glyph->V0), ImVec2(glyph->U1, glyph->V1), col); -} - void ImFont::RenderChar(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, unsigned short c) const { if (c == ' ' || c == '\t' || c == '\n' || c == '\r') // Match behavior of RenderText(), those 4 codepoints are hard-coded. @@ -2068,10 +2059,8 @@ void ImFont::RenderChar(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col float scale = (size >= 0.0f) ? (size / FontSize) : 1.0f; pos.x = (float)(int)pos.x + DisplayOffset.x; pos.y = (float)(int)pos.y + DisplayOffset.y; - ImVec2 pos_tl(pos.x + glyph->X0 * scale, pos.y + glyph->Y0 * scale); - ImVec2 pos_br(pos.x + glyph->X1 * scale, pos.y + glyph->Y1 * scale); draw_list->PrimReserve(6, 4); - draw_list->PrimRectUV(pos_tl, pos_br, ImVec2(glyph->U0, glyph->V0), ImVec2(glyph->U1, glyph->V1), col); + draw_list->PrimRectUV(ImVec2(pos.x + glyph->X0 * scale, pos.y + glyph->Y0 * scale), ImVec2(pos.x + glyph->X1 * scale, pos.y + glyph->Y1 * scale), ImVec2(glyph->U0, glyph->V0), ImVec2(glyph->U1, glyph->V1), col); } } From a6d69f04c0c83966b629c031dede7bb739c6e0bd Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 14 Aug 2017 17:20:05 +0800 Subject: [PATCH 216/921] PlotHistogram: bars are drawn based on the position of zero (#828) --- imgui.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 0ada9c045..acd69588a 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -7163,7 +7163,8 @@ void ImGui::PlotEx(ImGuiPlotType plot_type, const char* label, float (*values_ge float v0 = values_getter(data, (0 + values_offset) % values_count); float t0 = 0.0f; - ImVec2 tp0 = ImVec2( t0, 1.0f - ImSaturate((v0 - scale_min) / (scale_max - scale_min)) ); // Point in the normalized space of our target rectangle + ImVec2 tp0 = ImVec2( t0, 1.0f - ImSaturate((v0 - scale_min) / (scale_max - scale_min)) ); // Point in the normalized space of our target rectangle + float histogram_zero_line_t = (scale_min * scale_max < 0.0f) ? (-scale_min / (scale_max - scale_min)) : (scale_min < 0.0f ? 0.0f : 1.0f); // Where does the zero line stands const ImU32 col_base = GetColorU32((plot_type == ImGuiPlotType_Lines) ? ImGuiCol_PlotLines : ImGuiCol_PlotHistogram); const ImU32 col_hovered = GetColorU32((plot_type == ImGuiPlotType_Lines) ? ImGuiCol_PlotLinesHovered : ImGuiCol_PlotHistogramHovered); @@ -7178,7 +7179,7 @@ void ImGui::PlotEx(ImGuiPlotType plot_type, const char* label, float (*values_ge // NB: Draw calls are merged together by the DrawList system. Still, we should render our batch are lower level to save a bit of CPU. ImVec2 pos0 = ImLerp(inner_bb.Min, inner_bb.Max, tp0); - ImVec2 pos1 = ImLerp(inner_bb.Min, inner_bb.Max, (plot_type == ImGuiPlotType_Lines) ? tp1 : ImVec2(tp1.x, 1.0f)); + ImVec2 pos1 = ImLerp(inner_bb.Min, inner_bb.Max, (plot_type == ImGuiPlotType_Lines) ? tp1 : ImVec2(tp1.x, histogram_zero_line_t)); if (plot_type == ImGuiPlotType_Lines) { window->DrawList->AddLine(pos0, pos1, v_hovered == v1_idx ? col_hovered : col_base); From 7b7845d76472c61f62a4975bcf35eb7efc905c15 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 14 Aug 2017 21:00:44 +0800 Subject: [PATCH 217/921] ImFont::CalcWordWrapPositionA: minor optimization --- imgui_draw.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 9a79ffbf0..3eb8eea6f 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1878,6 +1878,7 @@ const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, const c float line_width = 0.0f; float word_width = 0.0f; float blank_width = 0.0f; + wrap_width /= scale; // We work with unscaled widths to avoid scaling every characters const char* word_end = text; const char* prev_word_end = NULL; @@ -1911,7 +1912,7 @@ const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, const c } } - const float char_width = ((int)c < IndexXAdvance.Size ? IndexXAdvance[(int)c] : FallbackXAdvance) * scale; + const float char_width = ((int)c < IndexXAdvance.Size ? IndexXAdvance[(int)c] : FallbackXAdvance); if (ImCharIsSpace(c)) { if (inside_word) From 03aae93f3e106200c7229ee54b4454bb6ce90e33 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 14 Aug 2017 21:14:42 +0800 Subject: [PATCH 218/921] TODO list update (merging a first batch of things I had laying around, +60 entries) --- TODO.txt | 185 +++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 126 insertions(+), 59 deletions(-) diff --git a/TODO.txt b/TODO.txt index 96ab22c82..fd8a303d1 100644 --- a/TODO.txt +++ b/TODO.txt @@ -4,40 +4,55 @@ ISSUES & TODO LIST Issue numbers (#) refer to github issues listed at https://github.com/ocornut/imgui/issues The list below consist mostly of ideas noted down before they are requested/discussed by users (at which point it usually moves to the github) - - doc: add a proper documentation+regression testing system (#435) - - window: add a way for very transient windows (non-saved, temporary overlay over hundreds of objects) to "clean" up from the global window list. perhaps a lightweight explicit cleanup pass. + - doc/test: add a proper documentation+regression testing system (#435) + - doc/test: checklist app to verify binding/integration of imgui (test inputs, rendering, callback, etc.). + - project: folder or separate repository with maintained helpers (e.g. imgui_memory_editor.h, imgui_stl.h, maybe imgui_dock would be there?) + - window: calling SetNextWindowSize() every frame with <= 0 doesn't do anything, may be useful to allow (particularly when used for a single axis). (#690) + - window: add a way for very transient windows (non-saved, temporary overlay over hundreds of objects) to "clean" up from the global window list. perhaps a lightweight explicit cleanup pass. - window: auto-fit feedback loop when user relies on any dynamic layout (window width multiplier, column) appears weird to end-user. clarify. - window: allow resizing of child windows (possibly given min/max for each axis?.) - window: background options for child windows, border option (disable rounding). - - window: add a way to clear an existing window instead of appending (e.g. for tooltip override using a consistent api rather than the deferred tooltip) > - - window: resizing from any sides? + mouse cursor directives for app. + - window: resizing from any sides? + mouse cursor directives for app. (#822) !- window: begin with *p_open == false should return false. - window: get size/pos helpers given names (see discussion in #249) - window: a collapsed window can be stuck behind the main menu bar? - - window: when window is small, prioritize resize button over close button. - - window: detect extra End() call that pop the "Debug" window out and assert at call site instead of later. + - window: when window is very small, prioritize resize button over close button. + - window: detect extra End() call that pop the "Debug" window out and assert at End() call site instead of at end of frame. - window/tooltip: allow to set the width of a tooltip to allow TextWrapped() etc. while keeping the height automatic. - window: increase minimum size of a window with menus or fix the menu rendering so that it doesn't look odd. - - draw-list: maintaining bounding box per command would allow to merge draw command when clipping isn't relied on (typical non-scrolling window or non-overflowing column would merge with previous command). -!- scrolling: allow immediately effective change of scroll after Begin() if we haven't appended items yet - - splitter/separator: formalize the splitter idiom into an official api (we want to handle n-way split) (#319) - - widgets: display mode: widget-label, label-widget (aligned on column or using fixed size), label-newline-tab-widget etc. (#395) - - widgets: clean up widgets internal toward exposing everything. - - widgets: add disabled and read-only modes (#211) + - window: double-clicking on title bar to minimize isn't consistent, perhaps move to single-click on left-most collapse icon? +!- scrolling: allow immediately effective change of scroll after Begin() if we haven't appended items yet. + - scrolling/clipping: separator on the initial position of a window is not visible (cursorpos.y <= clippos.y) + + - drawlist: move Font, FontSize, FontTexUvWhitePixel inside ImDrawList and make it self-contained (apart from drawing settings?) + - drawlist: end-user probably can't call Clear() directly because we expect a texture to be pushed in the stack. + - drawlist: maintaining bounding box per command would allow to merge draw command when clipping isn't relied on (typical non-scrolling window or non-overflowing column would merge with previous command). + - main: considering adding an Init() function? some constructs are awkward in the implementation because of the lack of them. -!- main: make it so that a frame with no window registered won't refocus every window on subsequent frames (~bump LastFrameActive of all windows). + - main: find a way to preserve relative orders of multiple reappearing windows (so an app toggling between "modes" e.g. fullscreen vs all tools) won't lose relative ordering. - 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: clean up the mess caused by converting UTF-8 <> wchar. the code is rather inefficient right now and super fragile. + - main: rename the main "Debug" window to avoid ID collision with user who may want to use "Debug" with specific flags + + - widgets: display mode: widget-label, label-widget (aligned on column or using fixed size), label-newline-tab-widget etc. (#395) + - widgets: clean up widgets internal toward exposing everything and stabilizing imgui_internals.h. + - widgets: add disabled and read-only modes (#211) + - widgets: alignment options in style (e.g. center Selectable, Right-Align within Button, etc.) #1260 + - widgets: activate by identifier (trigger button, focus given id) + + - input text: clean up the mess caused by converting UTF-8 <> wchar. the code is rather inefficient right now and super fragile. - input text: reorganize event handling, allow CharFilter to modify buffers, allow multiple events? (#541) - input text: expose CursorPos in char filter event (#816) - - input text: flag to disable live update of the user buffer (also applies to float/int text input) - - input text: resize behavior - field could stretch when being edited? hover tooltip shows more text? + - input text: access public fields via a non-callback API e.g. InputTextGetState("xxx") that may return NULL if not active. + - input text: flag to disable live update of the user buffer (also applies to float/int text input) (#701) + - input text: way to dynamically grow the buffer without forcing the user to initially allocate for worse case, e.g. more natural std::string (follow up on #200) + - input text: hover tooltip could show unclamped text - input text: add ImGuiInputTextFlags_EnterToApply? (off #218) + - input text: easier ways to update buffer (from source char*) while owned. preserve some sort of cursor position for multi-line text. - input text: add discard flag (e.g. ImGuiInputTextFlags_DiscardActiveBuffer) or make it easier to clear active focus for text replacement during edition (#725) + - input text: display bug when clicking a drag/slider after an input text in a different window has all-selected text (order dependant). actually a very old bug but no one appears to have noticed it. - input text multi-line: don't directly call AddText() which does an unnecessary vertex reserve for character count prior to clipping. and/or more line-based clipping to AddText(). and/or reorganize TextUnformatted/RenderText for more efficiency for large text (e.g TextUnformatted could clip and log separately, etc). - - input text multi-line: way to dynamically grow the buffer without forcing the user to initially allocate for worse case (follow up on #200) - input text multi-line: line numbers? status bar? (follow up on #200) - input text multi-line: behave better when user changes input buffer while editing is active (even though it is illegal behavior). namely, the change of buffer can create a scrollbar glitch (#725) - input text multi-line: better horizontal scrolling support (#383, #1224) @@ -46,10 +61,7 @@ The list below consist mostly of ideas noted down before they are requested/disc - input number: holding [-]/[+] buttons could increase the step speed non-linearly (or user-controlled) - input number: use mouse wheel to step up/down - input number: applying arithmetics ops (+,-,*,/) messes up with text edit undo stack. - - button: provide a button that looks framed. - - text: proper alignment options - - image/image button: misalignment on padded/bordered button? - - image/image button: parameters are confusing, image() has tint_col,border_col whereas imagebutton() has bg_col/tint_col. Even thou they are different parameters ordering could be more consistent. can we fix that? + - layout: horizontal layout helper (#97) - layout: horizontal flow until no space left (#404) - layout: more generic alignment state (left/right/centered) for single items? @@ -62,87 +74,142 @@ The list below consist mostly of ideas noted down before they are requested/disc - columns: user specify columns size (#513, #125) - columns: flag to add horizontal separator above/below? - columns/layout: setup minimum line height (equivalent of automatically calling AlignFirstTextHeightToWidgets) - - combo: sparse combo boxes (via function call?) / iterators - - 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 keyboard for custom listbox (pr #203) - - listbox: multiple selection - - listbox: user may want to initial scroll to focus on the one selected value? - - listbox: keyboard navigation. - - listbox: scrolling should track modified selection. -!- popups/menus: clarify usage of popups id, how MenuItem/Selectable closing parent popups affects the ID, etc. this is quite fishy needs improvement! (#331, #402) - - popups: add variant using global identifier similar to Begin/End (#402) - - popups: border options. richer api like BeginChild() perhaps? (#197) - - tooltip: tooltip that doesn't fit in entire screen seems to lose their "last preferred button" and may teleport when moving mouse - - menus: local shortcuts, global shortcuts (#456, #126) - - menus: icons - - menus: menubars: some sort of priority / effect of main menu-bar on desktop size? - - menus: calling BeginMenu() twice with a same name doesn't seem to append nicely - - statusbar: add a per-window status bar helper similar to what menubar does. - - tabs (#261, #351) - - separator: separator on the initial position of a window is not visible (cursorpos.y <= clippos.y) -!- color: the color helpers/typing is a mess and needs sorting out. - - node/graph editor (#306) - - pie menus patterns (#434) - - drag'n drop, dragging helpers (carry dragging info, visualize drag source before clicking, drop target, etc.) (#143, #479) - - plot: PlotLines() should use the polygon-stroke facilities (currently issues with averaging normals) + +!- color: the color helpers/types are a mess and needs sorting out. + - color: (api break) ImGui::ColorConvertXXX functions should be loose ImColorConvertXX to match imgui_internals.h + + - plot: full featured plot/graph api w/ scrolling, zooming etc. all bell & whistle. why not! + - plot: PlotLines() should use the polygon-stroke facilities, less verticles (currently issues with averaging normals) - plot: make it easier for user to draw extra stuff into the graph (e.g: draw basis, highlight certain points, 2d plots, multiple plots) - plot: "smooth" automatic scale over time, user give an input 0.0(full user scale) 1.0(full derived from value) + - plot: option/feature: draw the zero line + - plot: option/feature: draw grid, vertical markers + - plot: option/feature: draw unit - plot: add a helper e.g. Plot(char* label, float value, float time_span=2.0f) that stores values and Plot them for you - probably another function name. and/or automatically allow to plot ANY displayed value (more reliance on stable ID) + + - clipper: ability to force display 1 item in the list would be convenient. + + - splitter/separator: formalize the splitter idiom into an official api (we want to handle n-way split) (#319) + - tabs (#261, #351) + + - dock: docking extension + - dock: dock out from a collapsing header? would work nicely but need emitting window to keep submitting the code. + + - ext: stl-ish friendly extension (imgui_stl.h) that has wrapped for std::string, std::vector etc. + + - button: provide a button that looks framed. + - image/image button: misalignment on padded/bordered button? + - image/image button: parameters are confusing, image() has tint_col,border_col whereas imagebutton() has bg_col/tint_col. Even thou they are different parameters ordering could be more consistent. can we fix that? + - image button: not taking an explicit id is odd. - slider: allow using the [-]/[+] buttons used by InputFloat()/InputInt() - slider: initial absolute click is imprecise. change to relative movement slider (same as scrollbar). - slider: add dragging-based widgets to edit values with mouse (on 2 axises), saving screen real-estate. - slider: tint background based on value (e.g. v_min -> v_max, or use 0.0f either side of the sign) + - slider: precision dragging + - slider: step option (#1183) + - knob: rotating knob widget (#942) - slider & drag: int data passing through a float - drag float: up/down axis - drag float: added leeway on edge (e.g. a few invisible steps past the clamp limits) + + - combo: sparse combo boxes (via function call?) / iterators + - combo: active item type could be anything else e.g. void* + - combo: use clipper + - combo: contents should extends to fit label if combo widget is small + - combo: option for ComboEx to not return true when unchanged (#1182) + - combo/listbox: keyboard control. need InputText-like non-active focus + key handling. considering keyboard for custom listbox (pr #203) + - listbox: multiple selection. + - listbox: unselect (#1208) + - listbox: make it easier/more natural to implement range-select (need some sort of info/ref about the last clicked/focused item that user can translate to an index?) + - listbox: user may want to initial scroll to focus on the one selected value? + - listbox: expose hovered item for a basic ListBox + - listbox: keyboard navigation. + - listbox: scrolling should track modified selection. + +!- popups/menus: clarify usage of popups id, how MenuItem/Selectable closing parent popups affects the ID, etc. this is quite fishy needs improvement! (#331, #402) + - popups: if the popup functions took explicit ImGuiID it would allow the user to manage the scope of those ID. (#331) + - popups: clicking outside (to close popup) and holding shouldn't drag window below. + - popups: add variant using global identifier similar to Begin/End (#402) + - popups: border options. richer api like BeginChild() perhaps? (#197) + - tooltip: tooltip that doesn't fit in entire screen seems to lose their "last preferred direction" and may teleport when moving mouse. + + - menus: local shortcuts, global shortcuts (#456, #126) + - menus: menubars: some sort of priority / effect of main menu-bar on desktop size? + - menus: calling BeginMenu() twice with a same name doesn't append as Begin() does for regular windows (#1207) + - statusbar: add a per-window status bar helper similar to what menubar does. + - shortcuts: local-style shortcut api, e.g. parse "&Save" + - shortcuts: global-style shortcut api e.g. "Save (CTRL+S)" -> explicit flag for recursing into closed menu + - shortcuts: programmatically access shortcuts "Focus("&Save")) + + - text: proper alignment options in imgui_internal.h + - text wrapped: figure out better way to use TextWrapped() in an always auto-resize context (tooltip, etc.) (#249) + - tree node / optimization: avoid formatting when clipped. - tree node: tree-node/header right-most side doesn't take account of horizontal scrolling. - tree node: add treenode/treepush int variants? not there because (void*) cast from int warns on some platforms/settings? - tree node: try to apply scrolling at time of TreePop() if node was just opened and end of node is past scrolling limits? - tree node / selectable render mismatch which is visible if you use them both next to each other (e.g. cf. property viewer) - tree node: tweak color scheme to distinguish headers from selected tree node (#581) - - textwrapped: figure out better way to use TextWrapped() in an always auto-resize context (tooltip, etc.) (#249) + +!- settings: expose enough to save/load .ini from RAM instead of fopen - settings: write more decent code to allow saving/loading new fields - settings: api for per-tool simple persistent data (bool,int,float,columns sizes,etc.) in .ini file - stb: add defines to disable stb implementations - - style: add window shadows. + +!- style: better default styles. +!- style: move border to style structure, remove _ShowBorder flag. - style/optimization: store rounded corners in texture to use 1 quad per corner (filled and wireframe) to lower the cost of rounding. + - style: add window shadow (fading away from the window. Paint-style calculation of vertices alpha after drawlist would be easier) - style: color-box not always square? - style: a concept of "compact style" that the end-user can easily rely on (e.g. PushStyleCompact()?) that maps to other settings? avoid implementing duplicate helpers such as SmallCheckbox(), etc. - style: try to make PushStyleVar() more robust to incorrect parameters (to be more friendly to edit & continues situation). - style: global scale setting. - style: WindowPadding needs to be EVEN as the 0.5 multiplier used on this value probably have a subtle effect on clip rectangle - - text: simple markup language for color change? - - font: dynamic font atlas to avoid baking huge ranges into bitmap and make scaling easier. - - font: small opt: for monospace font (like the defalt one) we can trim IndexXAdvance as long as trailing value is == FallbackXAdvance - - font: add support for kerning, probably optional. perhaps default to (32..128)^2 matrix ~ 36KB then hash fallback. - - font: add a simpler CalcTextSizeA() api? current one ok but not welcome if user needs to call it directly (without going through ImGui::CalcTextSize) - - font: fix AddRemapChar() to work before font has been built. + - style: have a more global HSV setter (e.g. alter hue on all elements). consider replacing active/hovered by offset in HSV space? (#438, #707, #1223) + - style editor: color child window height expressed in multiple of line height. + - log: LogButtons() options for specifying depth and/or hiding depth slider - log: have more control over the log scope (e.g. stop logging when leaving current tree node scope) - log: be able to log anything (e.g. right-click on a window/tree-node, shows context menu? log into tty/file/clipboard) - log: let user copy any window content to clipboard easily (CTRL+C on windows? while moving it? context menu?). code is commented because it fails with multiple Begin/End pairs. + - filters: set a current filter that tree node can automatically query to hide themselves - filters: handle wildcards (with implicit leading/trailing *), regexps - filters: fuzzy matches (may use code at blog.forrestthewoods.com/4cffeed33fdb) - - shortcuts: add a shortcut api, e.g. parse "&Save" and/or "Save (CTRL+S)", pass in to widgets or provide simple ways to use (button=activate, input=focus) -!- keyboard: tooltip & combo boxes are messing up / not honoring keyboard tabbing + + - drag'n drop, dragging helpers, demo (carry dragging info, visualize drag source before clicking, drop target, etc.) (#143, #479) + - node/graph editor (#306) + - pie menus patterns (#434) + - markup: simple markup language for color change? + +!- font: better CalcTextSizeA() API, at least for simple use cases. current one is horrible (perhaps have simple vs extended versions). + - font: PushFontSize API (#1018) + - font/atlas: incremental updates + - font/atlas: dynamic font atlas to avoid baking huge ranges into bitmap and make scaling easier. + - font/atlas: allow user to submit its own primitive to be rectpacked, and allow to map them on a Unicode point. + - font: MemoryTTF taking ownership confusing/not obvious, maybe default should be opposite? + - font/text: vertical and/or rotated text renderer (#705) - vertical is easier clipping wise + - font: imgui_freetype.h alternative renderer (#618) + - font: optimization: for monospace font (like the default one) we can trim IndexXAdvance as long as trailing value is == FallbackXAdvance (need to make sure TAB is still correct). + - font: add support for kerning, probably optional. A) perhaps default to (32..128)^2 matrix ~ 9K entries = 36KB, then hash for non-ascii?. B) or sparse lookup into per-char list? + - font: add a simpler CalcTextSizeA() api? current one ok but not welcome if user needs to call it directly (without going through ImGui::CalcTextSize) + - font: fix AddRemapChar() to work before font has been built. + +!- keyboard: tooltip & combo boxes are messing up / not honoring keyboard tabbing. - keyboard: full keyboard navigation and focus. (#323) - focus: preserve ActiveId/focus stack state, e.g. when opening a menu and close it, previously selected InputText() focus gets restored (#622) - focus: SetKeyboardFocusHere() on with >= 0 offset could be done on same frame (else latch and modulate on beginning of next frame) - input: rework IO system to be able to pass actual ordered/timestamped events. (~#335, #71) - input: allow to decide and pass explicit double-clicks (e.g. for windows by the CS_DBLCLKS style). - input: support track pad style scrolling & slider edit. + - misc: provide a way to compile out the entire implementation while providing a dummy API (e.g. #define IMGUI_DUMMY_IMPL) - - misc: double-clicking on title bar to minimize isn't consistent, perhaps move to single-click on left-most collapse icon? - misc: provide HoveredTime and ActivatedTime to ease the creation of animations. - - style editor: have a more global HSV setter (e.g. alter hue on all elements). consider replacing active/hovered by offset in HSV space? (#438) - - style editor: color child window height expressed in multiple of line height. - remote: make a system like RemoteImGui first-class citizen/project (#75) - - drawlist: move Font, FontSize, FontTexUvWhitePixel inside ImDrawList and make it self-contained (apart from drawing settings?) - - drawlist: end-user probably can't call Clear() directly because we expect a texture to be pushed in the stack. - examples: directx9: save/restore device state more thoroughly. - examples: window minimize, maximize (#583) + - examples: provide a zero-framerate/idle example. + - optimization: replace vsnprintf with stb_printf? or enable the defines/infrastructure to allow it (#1038) - optimization: add clipping for multi-component widgets (SliderFloatX, ColorEditX, etc.). one problem is that nav branch can't easily clip parent group when there is a move request. - optimization: add a flag to disable most of rendering, for the case where the user expect to skip it (#335) - optimization: use another hash function than crc32, e.g. FNV1a From cd17af0d3390de6ce3a17580c4e6a9d795b8c2cc Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 15 Aug 2017 00:09:03 +0800 Subject: [PATCH 219/921] Renamed --- LICENSE => LICENSE.txt | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename LICENSE => LICENSE.txt (100%) diff --git a/LICENSE b/LICENSE.txt similarity index 100% rename from LICENSE rename to LICENSE.txt From 01b99bbe093ea4199a6215880b0e2896ec83377a Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 15 Aug 2017 00:36:15 +0800 Subject: [PATCH 220/921] TODO list update --- TODO.txt | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/TODO.txt b/TODO.txt index fd8a303d1..67a9250eb 100644 --- a/TODO.txt +++ b/TODO.txt @@ -1,8 +1,9 @@ dear imgui ISSUES & TODO LIST -Issue numbers (#) refer to github issues listed at https://github.com/ocornut/imgui/issues -The list below consist mostly of ideas noted down before they are requested/discussed by users (at which point it usually moves to the github) +Issue numbers (#) refer to github issues listed at https://github.com/ocornut/imgui/issues/XXXX +The list below consist mostly of ideas noted down before they are requested/discussed by users (at which point they usually exist on the github issue tracker). +It's mostly a bunch of personal notes, probably incomplete. Feel free to query if you have any questions. - doc/test: add a proper documentation+regression testing system (#435) - doc/test: checklist app to verify binding/integration of imgui (test inputs, rendering, callback, etc.). @@ -28,6 +29,7 @@ The list below consist mostly of ideas noted down before they are requested/disc - drawlist: move Font, FontSize, FontTexUvWhitePixel inside ImDrawList and make it self-contained (apart from drawing settings?) - drawlist: end-user probably can't call Clear() directly because we expect a texture to be pushed in the stack. - drawlist: maintaining bounding box per command would allow to merge draw command when clipping isn't relied on (typical non-scrolling window or non-overflowing column would merge with previous command). + - drawlist: avoid passing null (-9999,+9999) rectangle to end-user, instead perhaps pass rectangle based on io.DisplaySize? - main: considering adding an Init() function? some constructs are awkward in the implementation because of the lack of them. - main: find a way to preserve relative orders of multiple reappearing windows (so an app toggling between "modes" e.g. fullscreen vs all tools) won't lose relative ordering. @@ -67,16 +69,17 @@ The list below consist mostly of ideas noted down before they are requested/disc - layout: more generic alignment state (left/right/centered) for single items? - layout: clean up the InputFloatN/SliderFloatN/ColorEdit4 layout code. item width should include frame padding. - layout: BeginGroup() needs a border option. - - columns: declare column set (each column: fixed size, %, fill, distribute default size among fills) (#513, #125) + + - columns: sizing policy (e.g. for each column: fixed size, %, fill, distribute default size among fills) (#513, #125) - columns: add a conditional parameter to SetColumnOffset() (#513, #125) + - columns: headers. with sort op/button. reorderable. (#513, #125) + - columns: allow columns to recurse. - columns: separator function or parameter that works within the column (currently Separator() bypass all columns) (#125) - - columns: columns header to act as button (~sort op) and allow resize/reorder (#513, #125) - - columns: user specify columns size (#513, #125) - columns: flag to add horizontal separator above/below? - columns/layout: setup minimum line height (equivalent of automatically calling AlignFirstTextHeightToWidgets) !- color: the color helpers/types are a mess and needs sorting out. - - color: (api break) ImGui::ColorConvertXXX functions should be loose ImColorConvertXX to match imgui_internals.h + - color: (api breaking) ImGui::ColorConvertXXX functions should be loose ImColorConvertXX to match imgui_internals.h - plot: full featured plot/graph api w/ scrolling, zooming etc. all bell & whistle. why not! - plot: PlotLines() should use the polygon-stroke facilities, less verticles (currently issues with averaging normals) @@ -90,11 +93,12 @@ The list below consist mostly of ideas noted down before they are requested/disc - clipper: ability to force display 1 item in the list would be convenient. - splitter/separator: formalize the splitter idiom into an official api (we want to handle n-way split) (#319) - - tabs (#261, #351) - dock: docking extension - dock: dock out from a collapsing header? would work nicely but need emitting window to keep submitting the code. + - tabs: re-ordering, close buttons, context menu, persistent order (#261, #351) + - ext: stl-ish friendly extension (imgui_stl.h) that has wrapped for std::string, std::vector etc. - button: provide a button that looks framed. @@ -127,19 +131,20 @@ The list below consist mostly of ideas noted down before they are requested/disc - listbox: scrolling should track modified selection. !- popups/menus: clarify usage of popups id, how MenuItem/Selectable closing parent popups affects the ID, etc. this is quite fishy needs improvement! (#331, #402) + - popups/nav: esc/enter default behavior for popups. + - popups: reopening context menu at new position should be the behavior by default? (equivalent to internal OpenPopupEx() with reopen_existing=true) - popups: if the popup functions took explicit ImGuiID it would allow the user to manage the scope of those ID. (#331) - popups: clicking outside (to close popup) and holding shouldn't drag window below. - popups: add variant using global identifier similar to Begin/End (#402) - popups: border options. richer api like BeginChild() perhaps? (#197) - tooltip: tooltip that doesn't fit in entire screen seems to lose their "last preferred direction" and may teleport when moving mouse. - - menus: local shortcuts, global shortcuts (#456, #126) - - menus: menubars: some sort of priority / effect of main menu-bar on desktop size? - menus: calling BeginMenu() twice with a same name doesn't append as Begin() does for regular windows (#1207) - statusbar: add a per-window status bar helper similar to what menubar does. - shortcuts: local-style shortcut api, e.g. parse "&Save" - - shortcuts: global-style shortcut api e.g. "Save (CTRL+S)" -> explicit flag for recursing into closed menu + - shortcuts,menus: global-style shortcut api e.g. "Save (CTRL+S)" -> explicit flag for recursing into closed menu - shortcuts: programmatically access shortcuts "Focus("&Save")) + - menus: menubars: main menu-bar could affect clamping of windows position (~ akin to modifying DisplayMin) - text: proper alignment options in imgui_internal.h - text wrapped: figure out better way to use TextWrapped() in an always auto-resize context (tooltip, etc.) (#249) @@ -194,6 +199,7 @@ The list below consist mostly of ideas noted down before they are requested/disc - font: add support for kerning, probably optional. A) perhaps default to (32..128)^2 matrix ~ 9K entries = 36KB, then hash for non-ascii?. B) or sparse lookup into per-char list? - font: add a simpler CalcTextSizeA() api? current one ok but not welcome if user needs to call it directly (without going through ImGui::CalcTextSize) - font: fix AddRemapChar() to work before font has been built. + - font: (api breaking) removed "TTF" from symbol names. also because it now supports OTF. !- keyboard: tooltip & combo boxes are messing up / not honoring keyboard tabbing. - keyboard: full keyboard navigation and focus. (#323) @@ -206,9 +212,12 @@ The list below consist mostly of ideas noted down before they are requested/disc - misc: provide a way to compile out the entire implementation while providing a dummy API (e.g. #define IMGUI_DUMMY_IMPL) - misc: provide HoveredTime and ActivatedTime to ease the creation of animations. - remote: make a system like RemoteImGui first-class citizen/project (#75) + + - demo: demo: add a virtual scrolling example? - examples: directx9: save/restore device state more thoroughly. - examples: window minimize, maximize (#583) - examples: provide a zero-framerate/idle example. + - examples: document WantCaptureKeyboard, WantCaptureMouse in example apps. (#446) - optimization: replace vsnprintf with stb_printf? or enable the defines/infrastructure to allow it (#1038) - optimization: add clipping for multi-component widgets (SliderFloatX, ColorEditX, etc.). one problem is that nav branch can't easily clip parent group when there is a move request. - optimization: add a flag to disable most of rendering, for the case where the user expect to skip it (#335) From f8f382221c846081c4fcfb6668f2b361f0547f60 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 15 Aug 2017 11:41:00 +0800 Subject: [PATCH 221/921] ImVector: added resize() variant with initialization value --- imgui.h | 5 +++-- imgui_draw.cpp | 12 +++--------- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/imgui.h b/imgui.h index 98e05d9c7..8d0336cc2 100644 --- a/imgui.h +++ b/imgui.h @@ -908,12 +908,13 @@ public: inline int _grow_capacity(int new_size) { int new_capacity = Capacity ? (Capacity + Capacity/2) : 8; return new_capacity > new_size ? new_capacity : new_size; } inline void resize(int new_size) { if (new_size > Capacity) reserve(_grow_capacity(new_size)); Size = new_size; } + inline void resize(int new_size, const T& v){ if (new_size > Capacity) reserve(_grow_capacity(new_size)); if (new_size > Size) for (int n = Size; n < new_size; n++) Data[n] = v; Size = new_size; } inline void reserve(int new_capacity) { if (new_capacity <= Capacity) return; - T* new_data = (value_type*)ImGui::MemAlloc((size_t)new_capacity * sizeof(value_type)); + T* new_data = (value_type*)ImGui::MemAlloc((size_t)new_capacity * sizeof(T)); if (Data) - memcpy(new_data, Data, (size_t)Size * sizeof(value_type)); + memcpy(new_data, Data, (size_t)Size * sizeof(T)); ImGui::MemFree(Data); Data = new_data; Capacity = new_capacity; diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 3eb8eea6f..b2f599d8d 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1820,16 +1820,10 @@ void ImFont::SetFallbackChar(ImWchar c) void ImFont::GrowIndex(int new_size) { IM_ASSERT(IndexXAdvance.Size == IndexLookup.Size); - int old_size = IndexLookup.Size; - if (new_size <= old_size) + if (new_size <= IndexLookup.Size) return; - IndexXAdvance.resize(new_size); - IndexLookup.resize(new_size); - for (int i = old_size; i < new_size; i++) - { - IndexXAdvance[i] = -1.0f; - IndexLookup[i] = (unsigned short)-1; - } + IndexXAdvance.resize(new_size, -1.0f); + IndexLookup.resize(new_size, (unsigned short)-1); } void ImFont::AddRemapChar(ImWchar dst, ImWchar src, bool overwrite_dst) From 18b50f8ebacceff6908bb9f69994357ceabb4500 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 15 Aug 2017 11:41:36 +0800 Subject: [PATCH 222/921] Comments --- imgui_demo.cpp | 1 - imgui_draw.cpp | 7 +++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 3a7691162..df67b6f47 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -260,7 +260,6 @@ void ImGui::ShowTestWindow(bool* p_open) if (ImGui::CollapsingHeader("Widgets")) { - if (ImGui::TreeNode("Basic")) { static int clicked = 0; diff --git a/imgui_draw.cpp b/imgui_draw.cpp index b2f599d8d..850f48807 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1237,7 +1237,7 @@ ImFont* ImFontAtlas::AddFontFromFileTTF(const char* filename, float size_pixels, return AddFontFromMemoryTTF(data, data_size, size_pixels, &font_cfg, glyph_ranges); } -// NBM Transfer ownership of 'ttf_data' to ImFontAtlas, unless font_cfg_template->FontDataOwnedByAtlas == false. Owned TTF buffer will be deleted after Build(). +// NB: Transfer ownership of 'ttf_data' to ImFontAtlas, unless font_cfg_template->FontDataOwnedByAtlas == false. Owned TTF buffer will be deleted after Build(). ImFont* ImFontAtlas::AddFontFromMemoryTTF(void* ttf_data, int ttf_size, float size_pixels, const ImFontConfig* font_cfg_template, const ImWchar* glyph_ranges) { ImFontConfig font_cfg = font_cfg_template ? *font_cfg_template : ImFontConfig(); @@ -1611,7 +1611,10 @@ const ImWchar* ImFontAtlas::GetGlyphRangesChinese() const ImWchar* ImFontAtlas::GetGlyphRangesJapanese() { // Store the 1946 ideograms code points as successive offsets from the initial unicode codepoint 0x4E00. Each offset has an implicit +1. - // This encoding helps us reduce the source code size. + // This encoding is designed to helps us reduce the source code size. + // FIXME: Source a list of the revised 2136 joyo kanji list from 2010 and rebuild this. + // The current list was sourced from http://theinstructionlimit.com/author/renaudbedardrenaudbedard/page/3 + // Note that you may use ImFontAtlas::GlyphRangesBuilder to create your own ranges, by merging existing ranges or adding new characters. static const short offsets_from_0x4E00[] = { -1,0,1,3,0,0,0,0,1,0,5,1,1,0,7,4,6,10,0,1,9,9,7,1,3,19,1,10,7,1,0,1,0,5,1,0,6,4,2,6,0,0,12,6,8,0,3,5,0,1,0,9,0,0,8,1,1,3,4,5,13,0,0,8,2,17, From 0f935248e3a687af1383d8f45402db540f9f5b2d Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 15 Aug 2017 17:46:11 +0800 Subject: [PATCH 223/921] Combo, Inputint, InputFloat, ColorEdit4 all use the small size for little square --- imgui.cpp | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index e7c97bdb7..1bac8fa91 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -8253,6 +8253,12 @@ bool ImGui::InputTextMultiline(const char* label, char* buf, size_t buf_size, co return InputTextEx(label, buf, (int)buf_size, size, flags | ImGuiInputTextFlags_Multiline, callback, user_data); } +static inline float SmallSquareSize() +{ + ImGuiContext& g = *GImGui; + return g.FontSize + g.Style.FramePadding.y * 2.0f; +} + // NB: scalar_format here must be a simple "%xx" format string with no prefix/suffix (unlike the Drag/Slider functions "display_format" argument) bool ImGui::InputScalarEx(const char* label, ImGuiDataType data_type, void* data_ptr, void* step_ptr, void* step_fast_ptr, const char* scalar_format, ImGuiInputTextFlags extra_flags) { @@ -8266,7 +8272,7 @@ bool ImGui::InputScalarEx(const char* label, ImGuiDataType data_type, void* data BeginGroup(); PushID(label); - const ImVec2 button_sz = ImVec2(g.FontSize, g.FontSize) + style.FramePadding*2.0f; + const ImVec2 button_sz = ImVec2(SmallSquareSize(), SmallSquareSize()); if (step_ptr) PushItemWidth(ImMax(1.0f, CalcItemWidth() - (button_sz.x + style.ItemInnerSpacing.x)*2)); @@ -8481,7 +8487,7 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi if (!ItemAdd(total_bb, &id)) return false; - const float arrow_size = (g.FontSize + style.FramePadding.x * 2.0f); + const float arrow_size = SmallSquareSize(); const bool hovered = IsHovered(frame_bb, id); bool popup_open = IsPopupOpen(id); bool popup_opened_now = false; @@ -8489,7 +8495,7 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi const ImRect value_bb(frame_bb.Min, frame_bb.Max - ImVec2(arrow_size, 0.0f)); RenderFrame(frame_bb.Min, frame_bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding); RenderFrame(ImVec2(frame_bb.Max.x-arrow_size, frame_bb.Min.y), frame_bb.Max, GetColorU32(popup_open || hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button), true, style.FrameRounding); // FIXME-ROUNDING - RenderCollapseTriangle(ImVec2(frame_bb.Max.x-arrow_size, frame_bb.Min.y) + style.FramePadding, true); + RenderCollapseTriangle(ImVec2(frame_bb.Max.x - arrow_size + style.FramePadding.y, frame_bb.Min.y + style.FramePadding.y), true); if (*current_item >= 0 && *current_item < items_count) { @@ -8988,12 +8994,6 @@ void ImGui::ColorTooltip(const char* text, const float col[4], ImGuiColorEditFla EndTooltip(); } -static inline float ColorSquareSize() -{ - ImGuiContext& g = *GImGui; - return g.FontSize + g.Style.FramePadding.y * 2.0f; -} - static inline ImU32 ImAlphaBlendColor(ImU32 col_a, ImU32 col_b) { float t = ((col_b >> IM_COL32_A_SHIFT) & 0xFF) / 255.f; @@ -9065,7 +9065,7 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl ImGuiContext& g = *GImGui; const ImGuiID id = window->GetID(desc_id); - float default_size = ColorSquareSize(); + float default_size = SmallSquareSize(); if (size.x == 0.0f) size.x = default_size; if (size.y == 0.0f) @@ -9143,7 +9143,7 @@ static void ColorPickerOptionsPopup(ImGuiColorEditFlags flags, float* ref_col) ImGuiContext& g = *GImGui; if (allow_opt_picker) { - ImVec2 picker_size(g.FontSize * 8, ImMax(g.FontSize * 8 - (ColorSquareSize() + g.Style.ItemInnerSpacing.x), 1.0f)); // FIXME: Picker size copied from main picker function + ImVec2 picker_size(g.FontSize * 8, ImMax(g.FontSize * 8 - (SmallSquareSize() + g.Style.ItemInnerSpacing.x), 1.0f)); // FIXME: Picker size copied from main picker function ImGui::PushItemWidth(picker_size.x); for (int picker_type = 0; picker_type < 2; picker_type++) { @@ -9183,7 +9183,8 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag ImGuiContext& g = *GImGui; const ImGuiStyle& style = g.Style; - const float w_extra = (flags & ImGuiColorEditFlags_NoSmallPreview) ? 0.0f : (ColorSquareSize() + style.ItemInnerSpacing.x); + const float square_sz = SmallSquareSize(); + const float w_extra = (flags & ImGuiColorEditFlags_NoSmallPreview) ? 0.0f : (square_sz + style.ItemInnerSpacing.x); const float w_items_all = CalcItemWidth() - w_extra; const char* label_display_end = FindRenderedTextEnd(label); @@ -9314,7 +9315,6 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag TextUnformatted(label, label_display_end); Separator(); } - float square_sz = ColorSquareSize(); ImGuiColorEditFlags picker_flags_to_forward = ImGuiColorEditFlags__DataTypeMask | ImGuiColorEditFlags__PickerMask | ImGuiColorEditFlags_HDR | ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_AlphaBar; ImGuiColorEditFlags picker_flags = (flags_untouched & picker_flags_to_forward) | ImGuiColorEditFlags__InputsMask | ImGuiColorEditFlags_NoLabel | ImGuiColorEditFlags_AlphaPreviewHalf; PushItemWidth(square_sz * 12.0f); // Use 256 + bar sizes? @@ -9431,7 +9431,8 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl // Setup bool alpha_bar = (flags & ImGuiColorEditFlags_AlphaBar) && !(flags & ImGuiColorEditFlags_NoAlpha); ImVec2 picker_pos = window->DC.CursorPos; - float bars_width = ColorSquareSize(); // Arbitrary smallish width of Hue/Alpha picking bars + float square_sz = SmallSquareSize(); + float bars_width = square_sz; // Arbitrary smallish width of Hue/Alpha picking bars float sv_picker_size = ImMax(bars_width * 1, CalcItemWidth() - (alpha_bar ? 2 : 1) * (bars_width + style.ItemInnerSpacing.x)); // Saturation/Value picking box float bar0_pos_x = picker_pos.x + sv_picker_size + style.ItemInnerSpacing.x; float bar1_pos_x = bar0_pos_x + bars_width + style.ItemInnerSpacing.x; @@ -9543,7 +9544,6 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl if (!(flags & ImGuiColorEditFlags_NoSidePreview)) { ImVec4 col_v4(col[0], col[1], col[2], (flags & ImGuiColorEditFlags_NoAlpha) ? 1.0f : col[3]); - float square_sz = ColorSquareSize(); if ((flags & ImGuiColorEditFlags_NoLabel)) Text("Current"); ColorButton("##current", col_v4, (flags & (ImGuiColorEditFlags_HDR|ImGuiColorEditFlags_AlphaPreview|ImGuiColorEditFlags_AlphaPreviewHalf|ImGuiColorEditFlags_NoTooltip)), ImVec2(square_sz * 3, square_sz * 2)); From 668a4bf1bcedb282bad22dc36c166b911c40c101 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 15 Aug 2017 17:48:41 +0800 Subject: [PATCH 224/921] Demo: style editor output tweak so it is easier to modify the output code.. + TODO list update --- TODO.txt | 5 ++++- imgui_demo.cpp | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/TODO.txt b/TODO.txt index 67a9250eb..56eb873c9 100644 --- a/TODO.txt +++ b/TODO.txt @@ -30,6 +30,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - drawlist: end-user probably can't call Clear() directly because we expect a texture to be pushed in the stack. - drawlist: maintaining bounding box per command would allow to merge draw command when clipping isn't relied on (typical non-scrolling window or non-overflowing column would merge with previous command). - drawlist: avoid passing null (-9999,+9999) rectangle to end-user, instead perhaps pass rectangle based on io.DisplaySize? + - drawlist: primtiives/helpers to manipulate vertices post submission, so e.g. a quad/rect can be resized to fit later submitted content, _without_ using the ChannelSplit api - main: considering adding an Init() function? some constructs are awkward in the implementation because of the lack of them. - main: find a way to preserve relative orders of multiple reappearing windows (so an app toggling between "modes" e.g. fullscreen vs all tools) won't lose relative ordering. @@ -64,6 +65,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - input number: use mouse wheel to step up/down - input number: applying arithmetics ops (+,-,*,/) messes up with text edit undo stack. + - layout: helper or a way to express ImGui::SameLine(ImGui::GetCursorStartPos().x + ImGui::CalcItemWidth() + ImGui::GetStyle().ItemInnerSpacing.x); in a simpler manner. - layout: horizontal layout helper (#97) - layout: horizontal flow until no space left (#404) - layout: more generic alignment state (left/right/centered) for single items? @@ -78,8 +80,9 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - columns: flag to add horizontal separator above/below? - columns/layout: setup minimum line height (equivalent of automatically calling AlignFirstTextHeightToWidgets) -!- color: the color helpers/types are a mess and needs sorting out. +!- color: the color conversion helpers/types are a mess and needs sorting out. - color: (api breaking) ImGui::ColorConvertXXX functions should be loose ImColorConvertXX to match imgui_internals.h + - coloredit: it is still somehow awkward to copy colors around (unless going through Hex mode). - plot: full featured plot/graph api w/ scrolling, zooming etc. all bell & whistle. why not! - plot: PlotLines() should use the polygon-stroke facilities, less verticles (currently issues with averaging normals) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index df67b6f47..ab417a019 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1829,13 +1829,13 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) ImGui::LogToClipboard(); else ImGui::LogToTTY(); - ImGui::LogText("ImGuiStyle& style = ImGui::GetStyle();" IM_NEWLINE); + ImGui::LogText("ImVec4* colors = ImGui::GetStyle().Colors;" IM_NEWLINE); for (int i = 0; i < ImGuiCol_COUNT; i++) { const ImVec4& col = style.Colors[i]; const char* name = ImGui::GetStyleColName(i); if (!output_only_modified || memcmp(&col, (ref ? &ref->Colors[i] : &default_style.Colors[i]), sizeof(ImVec4)) != 0) - ImGui::LogText("style.Colors[ImGuiCol_%s]%*s= ImVec4(%.2ff, %.2ff, %.2ff, %.2ff);" IM_NEWLINE, name, 22 - (int)strlen(name), "", col.x, col.y, col.z, col.w); + ImGui::LogText("colors[ImGuiCol_%s]%*s= ImVec4(%.2ff, %.2ff, %.2ff, %.2ff);" IM_NEWLINE, name, 23-(int)strlen(name), "", col.x, col.y, col.z, col.w); } ImGui::LogFinish(); } From 5429bd892e1150d45fca1cd86778911a42e60313 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 15 Aug 2017 18:30:52 +0800 Subject: [PATCH 225/921] ColorEdit4: Added "Copy as..." option in context menu (#346) --- imgui.cpp | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 1bac8fa91..e7645facf 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9110,7 +9110,7 @@ bool ImGui::ColorEdit3(const char* label, float col[3], ImGuiColorEditFlags flag return ColorEdit4(label, col, flags | ImGuiColorEditFlags_NoAlpha); } -static void ColorEditOptionsPopup(ImGuiColorEditFlags flags) +static void ColorEditOptionsPopup(ImGuiColorEditFlags flags, float* col) { bool allow_opt_inputs = !(flags & ImGuiColorEditFlags__InputsMask); bool allow_opt_datatype = !(flags & ImGuiColorEditFlags__DataTypeMask); @@ -9130,6 +9130,26 @@ static void ColorEditOptionsPopup(ImGuiColorEditFlags flags) if (ImGui::RadioButton("0..255", (opts & ImGuiColorEditFlags_Uint8) ? 1 : 0)) opts = (opts & ~ImGuiColorEditFlags__DataTypeMask) | ImGuiColorEditFlags_Uint8; if (ImGui::RadioButton("0.00..1.00", (opts & ImGuiColorEditFlags_Float) ? 1 : 0)) opts = (opts & ~ImGuiColorEditFlags__DataTypeMask) | ImGuiColorEditFlags_Float; } + + if (allow_opt_inputs || allow_opt_datatype) ImGui::Separator(); + if (ImGui::Button("Copy as..", ImVec2(-1,0))) + ImGui::OpenPopup("Copy"); + if (ImGui::BeginPopup("Copy")) + { + int cr = IM_F32_TO_INT8_SAT(col[0]), cg = IM_F32_TO_INT8_SAT(col[1]), cb = IM_F32_TO_INT8_SAT(col[2]), ca = (flags & ImGuiColorEditFlags_NoAlpha) ? 255 : IM_F32_TO_INT8_SAT(col[3]); + char buf[64]; + sprintf(buf, "(%.3ff, %.3ff, %.3ff, %.3ff)", col[0], col[1], col[2], (flags & ImGuiColorEditFlags_NoAlpha) ? 1.0f : col[3]); + if (ImGui::Selectable(buf)) + ImGui::SetClipboardText(buf); + sprintf(buf, "(%d,%d,%d,%d)", cr, cg, cb, ca); + if (ImGui::Selectable(buf)) + ImGui::SetClipboardText(buf); + sprintf(buf, (flags & ImGuiColorEditFlags_NoAlpha) ? "0x%02X%02X%02X" : "0x%02X%02X%02X%02X", cr, cg, cb, ca); + if (ImGui::Selectable(buf)) + ImGui::SetClipboardText(buf); + ImGui::EndPopup(); + } + g.ColorEditOptions = opts; ImGui::EndPopup(); } @@ -9202,7 +9222,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag // Context menu: display and modify options (before defaults are applied) if (!(flags & ImGuiColorEditFlags_NoOptions)) - ColorEditOptionsPopup(flags); + ColorEditOptionsPopup(flags, col); // Read stored options if (!(flags & ImGuiColorEditFlags__InputsMask)) From 18f217e63189ce6c71755d1ab52f69a7b49bb08a Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 15 Aug 2017 19:06:02 +0800 Subject: [PATCH 226/921] Style: Moved position of ImGuiCol_TitleBgCollapsed --- imgui.cpp | 2 +- imgui.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index e7645facf..3dc6cbcf5 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4817,8 +4817,8 @@ const char* ImGui::GetStyleColName(ImGuiCol idx) case ImGuiCol_FrameBgHovered: return "FrameBgHovered"; case ImGuiCol_FrameBgActive: return "FrameBgActive"; case ImGuiCol_TitleBg: return "TitleBg"; - case ImGuiCol_TitleBgCollapsed: return "TitleBgCollapsed"; case ImGuiCol_TitleBgActive: return "TitleBgActive"; + case ImGuiCol_TitleBgCollapsed: return "TitleBgCollapsed"; case ImGuiCol_MenuBarBg: return "MenuBarBg"; case ImGuiCol_ScrollbarBg: return "ScrollbarBg"; case ImGuiCol_ScrollbarGrab: return "ScrollbarGrab"; diff --git a/imgui.h b/imgui.h index 8d0336cc2..9fc13dc5b 100644 --- a/imgui.h +++ b/imgui.h @@ -610,8 +610,8 @@ enum ImGuiCol_ ImGuiCol_FrameBgHovered, ImGuiCol_FrameBgActive, ImGuiCol_TitleBg, - ImGuiCol_TitleBgCollapsed, ImGuiCol_TitleBgActive, + ImGuiCol_TitleBgCollapsed, ImGuiCol_MenuBarBg, ImGuiCol_ScrollbarBg, ImGuiCol_ScrollbarGrab, From 1e162dfc74a958efc81d10ce446a0218c5816e91 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 15 Aug 2017 19:19:00 +0800 Subject: [PATCH 227/921] PushStyleVar/PopStyleVar: internal tweaks --- imgui.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 3dc6cbcf5..2b83f2107 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4735,7 +4735,7 @@ struct ImGuiStyleVarInfo { ImGuiDataType Type; ImU32 Offset; - void* GetVarPtr() const { return (void*)((unsigned char*)&GImGui->Style + Offset); } + void* GetVarPtr(ImGuiStyle* style) const { return (void*)((unsigned char*)style + Offset); } }; static const ImGuiStyleVarInfo GStyleVarInfo[ImGuiStyleVar_Count_] = @@ -4765,8 +4765,9 @@ void ImGui::PushStyleVar(ImGuiStyleVar idx, float val) const ImGuiStyleVarInfo* var_info = GetStyleVarInfo(idx); if (var_info->Type == ImGuiDataType_Float) { - float* pvar = (float*)var_info->GetVarPtr(); - GImGui->StyleModifiers.push_back(ImGuiStyleMod(idx, *pvar)); + ImGuiContext& g = *GImGui; + float* pvar = (float*)var_info->GetVarPtr(&g.Style); + g.StyleModifiers.push_back(ImGuiStyleMod(idx, *pvar)); *pvar = val; return; } @@ -4778,8 +4779,9 @@ void ImGui::PushStyleVar(ImGuiStyleVar idx, const ImVec2& val) const ImGuiStyleVarInfo* var_info = GetStyleVarInfo(idx); if (var_info->Type == ImGuiDataType_Float2) { - ImVec2* pvar = (ImVec2*)var_info->GetVarPtr(); - GImGui->StyleModifiers.push_back(ImGuiStyleMod(idx, *pvar)); + ImGuiContext& g = *GImGui; + ImVec2* pvar = (ImVec2*)var_info->GetVarPtr(&g.Style); + g.StyleModifiers.push_back(ImGuiStyleMod(idx, *pvar)); *pvar = val; return; } @@ -4793,9 +4795,9 @@ void ImGui::PopStyleVar(int count) { ImGuiStyleMod& backup = g.StyleModifiers.back(); const ImGuiStyleVarInfo* info = GetStyleVarInfo(backup.VarIdx); - if (info->Type == ImGuiDataType_Float) (*(float*)info->GetVarPtr()) = backup.BackupFloat[0]; - else if (info->Type == ImGuiDataType_Float2) (*(ImVec2*)info->GetVarPtr()) = ImVec2(backup.BackupFloat[0], backup.BackupFloat[1]); - else if (info->Type == ImGuiDataType_Int) (*(int*)info->GetVarPtr()) = backup.BackupInt[0]; + if (info->Type == ImGuiDataType_Float) (*(float*)info->GetVarPtr(&g.Style)) = backup.BackupFloat[0]; + else if (info->Type == ImGuiDataType_Float2) (*(ImVec2*)info->GetVarPtr(&g.Style)) = ImVec2(backup.BackupFloat[0], backup.BackupFloat[1]); + else if (info->Type == ImGuiDataType_Int) (*(int*)info->GetVarPtr(&g.Style)) = backup.BackupInt[0]; g.StyleModifiers.pop_back(); count--; } From 718f00d6519a3b0f4bca209749c3a46d6d86451f Mon Sep 17 00:00:00 2001 From: James Wallis <31036241+jadwallis@users.noreply.github.com> Date: Tue, 15 Aug 2017 14:11:04 +0100 Subject: [PATCH 228/921] Make font atlas packing padding configurable --- imgui.h | 1 + imgui_draw.cpp | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/imgui.h b/imgui.h index 195cdccba..e5f8a6149 100644 --- a/imgui.h +++ b/imgui.h @@ -1382,6 +1382,7 @@ struct ImFontAtlas int TexWidth; // Texture width calculated during Build(). int TexHeight; // Texture height calculated during Build(). int TexDesiredWidth; // Texture width desired by user before Build(). Must be a power-of-two. If have many glyphs your graphics API have texture size restrictions you may want to increase texture width to decrease height. + int TexGlyphPadding; // Padding between glyphs within texture in pixels. Defaults to 1. ImVec2 TexUvWhitePixel; // Texture coordinates to a white pixel ImVector Fonts; // Hold all the fonts returned by AddFont*. Fonts[0] is the default font upon calling ImGui::NewFrame(), use ImGui::PushFont()/PopFont() to change the current font. diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 3eb8eea6f..acae0e208 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1061,6 +1061,7 @@ ImFontAtlas::ImFontAtlas() TexPixelsAlpha8 = NULL; TexPixelsRGBA32 = NULL; TexWidth = TexHeight = TexDesiredWidth = 0; + TexGlyphPadding = 1; TexUvWhitePixel = ImVec2(0, 0); } @@ -1314,13 +1315,13 @@ bool ImFontAtlas::Build() } } - // Start packing. We need a known width for the skyline algorithm. Using a cheap heuristic here to decide of width. User can override TexDesiredWidth if they wish. + // Start packing. We need a known width for the skyline algorithm. Using a cheap heuristic here to decide of width. User can override TexDesiredWidth and TexGlyphPadding if they wish. // After packing is done, width shouldn't matter much, but some API/GPU have texture size limitations and increasing width can decrease height. TexWidth = (TexDesiredWidth > 0) ? TexDesiredWidth : (total_glyph_count > 4000) ? 4096 : (total_glyph_count > 2000) ? 2048 : (total_glyph_count > 1000) ? 1024 : 512; TexHeight = 0; const int max_tex_height = 1024*32; stbtt_pack_context spc; - stbtt_PackBegin(&spc, NULL, TexWidth, max_tex_height, 0, 1, NULL); + stbtt_PackBegin(&spc, NULL, TexWidth, max_tex_height, 0, TexGlyphPadding, NULL); // Pack our extra data rectangles first, so it will be on the upper-left corner of our texture (UV will have small values). ImVector extra_rects; From 9239e91dc9133fa0fa681d0b67db2741de76f17f Mon Sep 17 00:00:00 2001 From: James Wallis <31036241+jadwallis@users.noreply.github.com> Date: Tue, 15 Aug 2017 14:12:32 +0100 Subject: [PATCH 229/921] Whitespace fix to previous --- imgui.h | 2 +- imgui_draw.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/imgui.h b/imgui.h index e5f8a6149..1f13882f7 100644 --- a/imgui.h +++ b/imgui.h @@ -1382,7 +1382,7 @@ struct ImFontAtlas int TexWidth; // Texture width calculated during Build(). int TexHeight; // Texture height calculated during Build(). int TexDesiredWidth; // Texture width desired by user before Build(). Must be a power-of-two. If have many glyphs your graphics API have texture size restrictions you may want to increase texture width to decrease height. - int TexGlyphPadding; // Padding between glyphs within texture in pixels. Defaults to 1. + int TexGlyphPadding; // Padding between glyphs within texture in pixels. Defaults to 1. ImVec2 TexUvWhitePixel; // Texture coordinates to a white pixel ImVector Fonts; // Hold all the fonts returned by AddFont*. Fonts[0] is the default font upon calling ImGui::NewFrame(), use ImGui::PushFont()/PopFont() to change the current font. diff --git a/imgui_draw.cpp b/imgui_draw.cpp index acae0e208..6e94cfb6b 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1061,7 +1061,7 @@ ImFontAtlas::ImFontAtlas() TexPixelsAlpha8 = NULL; TexPixelsRGBA32 = NULL; TexWidth = TexHeight = TexDesiredWidth = 0; - TexGlyphPadding = 1; + TexGlyphPadding = 1; TexUvWhitePixel = ImVec2(0, 0); } From e682362f35c0ce859933fbbdd8e0b4e8fa5f2792 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 16 Aug 2017 12:54:51 +0800 Subject: [PATCH 230/921] TODO list update, comments --- TODO.txt | 21 +++++++++++++++------ imgui_internal.h | 2 ++ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/TODO.txt b/TODO.txt index 67a9250eb..61d9e048d 100644 --- a/TODO.txt +++ b/TODO.txt @@ -23,19 +23,22 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - window/tooltip: allow to set the width of a tooltip to allow TextWrapped() etc. while keeping the height automatic. - window: increase minimum size of a window with menus or fix the menu rendering so that it doesn't look odd. - window: double-clicking on title bar to minimize isn't consistent, perhaps move to single-click on left-most collapse icon? + - window: expose contents size. (#1045) !- scrolling: allow immediately effective change of scroll after Begin() if we haven't appended items yet. - scrolling/clipping: separator on the initial position of a window is not visible (cursorpos.y <= clippos.y) - drawlist: move Font, FontSize, FontTexUvWhitePixel inside ImDrawList and make it self-contained (apart from drawing settings?) + - drawlist: make it easier to toggle AA per primitive, so we can use e.g. non-AA fill + AA borders more naturally - drawlist: end-user probably can't call Clear() directly because we expect a texture to be pushed in the stack. - drawlist: maintaining bounding box per command would allow to merge draw command when clipping isn't relied on (typical non-scrolling window or non-overflowing column would merge with previous command). - drawlist: avoid passing null (-9999,+9999) rectangle to end-user, instead perhaps pass rectangle based on io.DisplaySize? + - drawlist: primtiives/helpers to manipulate vertices post submission, so e.g. a quad/rect can be resized to fit later submitted content, _without_ using the ChannelSplit api - main: considering adding an Init() function? some constructs are awkward in the implementation because of the lack of them. - main: find a way to preserve relative orders of multiple reappearing windows (so an app toggling between "modes" e.g. fullscreen vs all tools) won't lose relative ordering. - 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? - - main: rename the main "Debug" window to avoid ID collision with user who may want to use "Debug" with specific flags + - main: rename the main "Debug" window to avoid ID collision with user who may want to use "Debug" with specific flags. - widgets: display mode: widget-label, label-widget (aligned on column or using fixed size), label-newline-tab-widget etc. (#395) - widgets: clean up widgets internal toward exposing everything and stabilizing imgui_internals.h. @@ -64,6 +67,8 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - input number: use mouse wheel to step up/down - input number: applying arithmetics ops (+,-,*,/) messes up with text edit undo stack. + - layout: helper or a way to express ImGui::SameLine(ImGui::GetCursorStartPos().x + ImGui::CalcItemWidth() + ImGui::GetStyle().ItemInnerSpacing.x); in a simpler manner. + - layout: generalization of the above: a concept equivalent to word processor ruler tab stop ~ mini columns (position in X, no clipping implied) (vaguely relate to #267, #395, also what is used internally for menu items) - layout: horizontal layout helper (#97) - layout: horizontal flow until no space left (#404) - layout: more generic alignment state (left/right/centered) for single items? @@ -78,8 +83,9 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - columns: flag to add horizontal separator above/below? - columns/layout: setup minimum line height (equivalent of automatically calling AlignFirstTextHeightToWidgets) -!- color: the color helpers/types are a mess and needs sorting out. +!- color: the color conversion helpers/types are a mess and needs sorting out. - color: (api breaking) ImGui::ColorConvertXXX functions should be loose ImColorConvertXX to match imgui_internals.h + - coloredit: it is still somehow awkward to copy colors around (unless going through Hex mode). - plot: full featured plot/graph api w/ scrolling, zooming etc. all bell & whistle. why not! - plot: PlotLines() should use the polygon-stroke facilities, less verticles (currently issues with averaging normals) @@ -158,11 +164,12 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i !- settings: expose enough to save/load .ini from RAM instead of fopen - settings: write more decent code to allow saving/loading new fields - - settings: api for per-tool simple persistent data (bool,int,float,columns sizes,etc.) in .ini file + - settings: api for per-tool simple persistent data (bool,int,float,columns sizes,etc.) in .ini file (#437) - stb: add defines to disable stb implementations !- style: better default styles. !- style: move border to style structure, remove _ShowBorder flag. + - style: border types: out-screen, in-screen, etc. - style/optimization: store rounded corners in texture to use 1 quad per corner (filled and wireframe) to lower the cost of rounding. - style: add window shadow (fading away from the window. Paint-style calculation of vertices alpha after drawlist would be easier) - style: color-box not always square? @@ -171,6 +178,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - style: global scale setting. - style: WindowPadding needs to be EVEN as the 0.5 multiplier used on this value probably have a subtle effect on clip rectangle - style: have a more global HSV setter (e.g. alter hue on all elements). consider replacing active/hovered by offset in HSV space? (#438, #707, #1223) + - style: gradients fill (#1223) ~ 2 bg colors for each fill? tricky with rounded shapes and using textures for corners. - style editor: color child window height expressed in multiple of line height. - log: LogButtons() options for specifying depth and/or hiding depth slider @@ -205,12 +213,13 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - keyboard: full keyboard navigation and focus. (#323) - focus: preserve ActiveId/focus stack state, e.g. when opening a menu and close it, previously selected InputText() focus gets restored (#622) - focus: SetKeyboardFocusHere() on with >= 0 offset could be done on same frame (else latch and modulate on beginning of next frame) - - input: rework IO system to be able to pass actual ordered/timestamped events. (~#335, #71) - - input: allow to decide and pass explicit double-clicks (e.g. for windows by the CS_DBLCLKS style). - - input: support track pad style scrolling & slider edit. + - inputs: rework IO system to be able to pass actual ordered/timestamped events. use an event queue? (~#335, #71) + - inputs: allow to decide and pass explicit double-clicks (e.g. for windows by the CS_DBLCLKS style). + - inputs: support track pad style scrolling & slider edit. - misc: provide a way to compile out the entire implementation while providing a dummy API (e.g. #define IMGUI_DUMMY_IMPL) - misc: provide HoveredTime and ActivatedTime to ease the creation of animations. + - misc: fix for compilation settings where stdcall isn't the default (e.g. vectorcall) (#1230) - remote: make a system like RemoteImGui first-class citizen/project (#75) - demo: demo: add a virtual scrolling example? diff --git a/imgui_internal.h b/imgui_internal.h index 5afb368e7..2803e3509 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -4,6 +4,8 @@ // You may use this file to debug, understand or extend ImGui features but we don't provide any guarantee of forward compatibility! // Implement maths operators for ImVec2 (disabled by default to not collide with using IM_VEC2_CLASS_EXTRA along with your own math types+operators) // #define IMGUI_DEFINE_MATH_OPERATORS +// Define IM_PLACEMENT_NEW() macro helper. +// #define IMGUI_DEFINE_PLACEMENT_NEW #pragma once From a83f7083ed23aadbe8cb595cd53619b174ab0c5d Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 16 Aug 2017 13:06:14 +0800 Subject: [PATCH 231/921] BeginPopupEx() uses ImGuiID internally --- imgui.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index acd69588a..b5518e937 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -614,7 +614,7 @@ static void MarkIniSettingsDirty(); static void PushColumnClipRect(int column_index = -1); static ImRect GetVisibleRect(); -static bool BeginPopupEx(const char* str_id, ImGuiWindowFlags extra_flags); +static bool BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_flags); static void CloseInactivePopups(); static void ClosePopupToLevel(int remaining); static void ClosePopup(ImGuiID id); @@ -3505,11 +3505,10 @@ static inline void ClearSetNextWindowData() g.SetNextWindowSizeConstraint = g.SetNextWindowFocus = false; } -static bool BeginPopupEx(const char* str_id, ImGuiWindowFlags extra_flags) +static bool BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_flags) { ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; - const ImGuiID id = window->GetID(str_id); if (!IsPopupOpen(id)) { ClearSetNextWindowData(); // We behave like Begin() and need to consume those values @@ -3536,12 +3535,13 @@ static bool BeginPopupEx(const char* str_id, ImGuiWindowFlags extra_flags) bool ImGui::BeginPopup(const char* str_id) { - if (GImGui->OpenPopupStack.Size <= GImGui->CurrentPopupStack.Size) // Early out for performance + ImGuiContext& g = *GImGui; + if (g.OpenPopupStack.Size <= g.CurrentPopupStack.Size) // Early out for performance { ClearSetNextWindowData(); // We behave like Begin() and need to consume those values return false; } - return BeginPopupEx(str_id, ImGuiWindowFlags_ShowBorders); + return BeginPopupEx(g.CurrentWindow->GetID(str_id), ImGuiWindowFlags_ShowBorders); } bool ImGui::BeginPopupModal(const char* name, bool* p_open, ImGuiWindowFlags extra_flags) @@ -8534,7 +8534,7 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi PushStyleVar(ImGuiStyleVar_WindowPadding, style.FramePadding); const ImGuiWindowFlags flags = ImGuiWindowFlags_ComboBox | ((window->Flags & ImGuiWindowFlags_ShowBorders) ? ImGuiWindowFlags_ShowBorders : 0); - if (BeginPopupEx(label, flags)) + if (BeginPopupEx(id, flags)) { // Display items Spacing(); @@ -8944,7 +8944,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled) { SetNextWindowPos(popup_pos, ImGuiCond_Always); ImGuiWindowFlags flags = ImGuiWindowFlags_ShowBorders | ((window->Flags & (ImGuiWindowFlags_Popup|ImGuiWindowFlags_ChildMenu)) ? ImGuiWindowFlags_ChildMenu|ImGuiWindowFlags_ChildWindow : ImGuiWindowFlags_ChildMenu); - menu_is_open = BeginPopupEx(label, flags); // menu_is_open can be 'false' when the popup is completely clipped (e.g. zero size display) + menu_is_open = BeginPopupEx(id, flags); // menu_is_open can be 'false' when the popup is completely clipped (e.g. zero size display) } return menu_is_open; From d2259f65e51df44c79cfc93a491ca0b871355fc2 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 16 Aug 2017 13:42:41 +0800 Subject: [PATCH 232/921] Undo part of 32dbe836d0cde14891d47ed054535283d0f567e2 to keep the same name for both overloads (#891, #799) --- imgui.cpp | 33 +++++++++++++++------------------ imgui_internal.h | 1 + 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 404989239..958e07013 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -618,7 +618,6 @@ static bool BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_flags); static void CloseInactivePopups(); static void ClosePopupToLevel(int remaining); static void ClosePopup(ImGuiID id); -static bool IsPopupIdOpen(ImGuiID id); static ImGuiWindow* GetFrontMostModalRootWindow(); static ImVec2 FindBestPopupWindowPos(const ImVec2& base_pos, const ImVec2& size, int* last_dir, const ImRect& rect_to_avoid); @@ -3396,12 +3395,6 @@ void ImGui::EndTooltip() ImGui::End(); } -static bool IsPopupIdOpen(ImGuiID id) -{ - ImGuiContext& g = *GImGui; - return g.OpenPopupStack.Size > g.CurrentPopupStack.Size && g.OpenPopupStack[g.CurrentPopupStack.Size].PopupId == id; -} - // Mark popup as open (toggle toward open state). // Popups are closed when user click outside, or activate a pressable item, or CloseCurrentPopup() is called within a BeginPopup()/EndPopup() block. // Popup identifiers are relative to the current ID-stack (so OpenPopup and BeginPopup needs to be at the same level). @@ -3480,7 +3473,7 @@ static void ClosePopupToLevel(int remaining) static void ClosePopup(ImGuiID id) { - if (!IsPopupIdOpen(id)) + if (!ImGui::IsPopupOpen(id)) return; ImGuiContext& g = *GImGui; ClosePopupToLevel(g.OpenPopupStack.Size - 1); @@ -3509,7 +3502,7 @@ static bool BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_flags) { ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; - if (!IsPopupIdOpen(id)) + if (!ImGui::IsPopupOpen(id)) { ClearSetNextWindowData(); // We behave like Begin() and need to consume those values return false; @@ -3544,12 +3537,16 @@ bool ImGui::BeginPopup(const char* str_id) return BeginPopupEx(g.CurrentWindow->GetID(str_id), ImGuiWindowFlags_ShowBorders); } +bool ImGui::IsPopupOpen(ImGuiID id) +{ + ImGuiContext& g = *GImGui; + return g.OpenPopupStack.Size > g.CurrentPopupStack.Size && g.OpenPopupStack[g.CurrentPopupStack.Size].PopupId == id; +} + bool ImGui::IsPopupOpen(const char* str_id) { ImGuiContext& g = *GImGui; - ImGuiWindow* window = g.CurrentWindow; - const ImGuiID id = window->GetID(str_id); - return IsPopupIdOpen(id); + return g.OpenPopupStack.Size > g.CurrentPopupStack.Size && g.OpenPopupStack[g.CurrentPopupStack.Size].PopupId == g.CurrentWindow->GetID(str_id); } bool ImGui::BeginPopupModal(const char* name, bool* p_open, ImGuiWindowFlags extra_flags) @@ -3557,7 +3554,7 @@ bool ImGui::BeginPopupModal(const char* name, bool* p_open, ImGuiWindowFlags ext ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; const ImGuiID id = window->GetID(name); - if (!IsPopupIdOpen(id)) + if (!IsPopupOpen(id)) { ClearSetNextWindowData(); // We behave like Begin() and need to consume those values return false; @@ -8483,7 +8480,7 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi const float arrow_size = (g.FontSize + style.FramePadding.x * 2.0f); const bool hovered = IsHovered(frame_bb, id); - bool popup_open = IsPopupIdOpen(id); + bool popup_open = IsPopupOpen(id); bool popup_opened_now = false; const ImRect value_bb(frame_bb.Min, frame_bb.Max - ImVec2(arrow_size, 0.0f)); @@ -8507,7 +8504,7 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi if (g.IO.MouseClicked[0]) { ClearActiveID(); - if (IsPopupIdOpen(id)) + if (IsPopupOpen(id)) { ClosePopup(id); } @@ -8521,7 +8518,7 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi } bool value_changed = false; - if (IsPopupIdOpen(id)) + if (IsPopupOpen(id)) { // Size default to hold ~7 items if (height_in_items < 0) @@ -8867,7 +8864,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled) ImGuiWindow* backed_focused_window = g.FocusedWindow; bool pressed; - bool menu_is_open = IsPopupIdOpen(id); + bool menu_is_open = IsPopupOpen(id); bool menuset_is_open = !(window->Flags & ImGuiWindowFlags_Popup) && (g.OpenPopupStack.Size > g.CurrentPopupStack.Size && g.OpenPopupStack[g.CurrentPopupStack.Size].ParentMenuSet == window->GetID("##menus")); if (menuset_is_open) g.FocusedWindow = window; @@ -8934,7 +8931,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled) want_open = true; if (!enabled) // explicitly close if an open menu becomes disabled, facilitate users code a lot in pattern such as 'if (BeginMenu("options", has_object)) { ..use object.. }' want_close = true; - if (want_close && IsPopupIdOpen(id)) + if (want_close && IsPopupOpen(id)) ClosePopupToLevel(GImGui->CurrentPopupStack.Size); if (!menu_is_open && want_open && g.OpenPopupStack.Size > g.CurrentPopupStack.Size) diff --git a/imgui_internal.h b/imgui_internal.h index 2803e3509..170eb4598 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -746,6 +746,7 @@ namespace ImGui IMGUI_API float CalcWrapWidthForPos(const ImVec2& pos, float wrap_pos_x); IMGUI_API void OpenPopupEx(const char* str_id, bool reopen_existing); + IMGUI_API bool IsPopupOpen(ImGuiID id); // NB: All position are in absolute pixels coordinates (never using window coordinates internally) // AVOID USING OUTSIDE OF IMGUI.CPP! NOT FOR PUBLIC CONSUMPTION. THOSE FUNCTIONS ARE A MESS. THEIR SIGNATURE AND BEHAVIOR WILL CHANGE, THEY NEED TO BE REFACTORED INTO SOMETHING DECENT. From 638d77c682ba504a219a2a9d6a0a7f28dd9dd410 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 16 Aug 2017 14:19:48 +0800 Subject: [PATCH 233/921] Comments (#402) --- imgui.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.h b/imgui.h index 3e901a1d0..4a014fed4 100644 --- a/imgui.h +++ b/imgui.h @@ -381,7 +381,7 @@ namespace ImGui IMGUI_API bool MenuItem(const char* label, const char* shortcut, bool* p_selected, bool enabled = true); // return true when activated + toggle (*p_selected) if p_selected != NULL // Popups - IMGUI_API void OpenPopup(const char* str_id); // mark popup as open. popups are closed when user click outside, or activate a pressable item, or CloseCurrentPopup() is called within a BeginPopup()/EndPopup() block. popup identifiers are relative to the current ID-stack (so OpenPopup and BeginPopup needs to be at the same level). + IMGUI_API void OpenPopup(const char* str_id); // call to mark popup as open (don't call every frame!). popups are closed when user click outside, or if CloseCurrentPopup() is called within a BeginPopup()/EndPopup() block. By default, Selectable()/MenuItem() are calling CloseCurrentPopup(). Popup identifiers are relative to the current ID-stack (so OpenPopup and BeginPopup needs to be at the same level). IMGUI_API bool IsPopupOpen(const char* str_id); // return true if the popup is open IMGUI_API bool BeginPopup(const char* str_id); // return true if the popup is open, and you can start outputting to it. only call EndPopup() if BeginPopup() returned true! IMGUI_API bool BeginPopupModal(const char* name, bool* p_open = NULL, ImGuiWindowFlags extra_flags = 0); // modal dialog (block interactions behind the modal window, can't close the modal window by clicking outside) From 5ea1865fdb2151e5fcdbbb273ba9b6b3513a5015 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 16 Aug 2017 14:24:41 +0800 Subject: [PATCH 234/921] (api breaking) changed parameter order for BeginPopupContextWindow(), note that most uses relied on default parameters completely. --- imgui.cpp | 9 ++++++--- imgui.h | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 958e07013..1562290a0 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -204,6 +204,7 @@ Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. Also read releases logs https://github.com/ocornut/imgui/releases for more details. + - 2017/08/15 (1.51) - changed parameter order for BeginPopupContextWindow(), note that most uses relied on default parameters completely. - 2017/08/13 (1.51) - renamed ImGuiCol_Columns_*** to ImGuiCol_Separator_*** - 2017/08/11 (1.51) - renamed ImGuiSetCond_*** types and flags to ImGuiCond_***. Kept redirection enums (will obsolete). - 2017/08/09 (1.51) - removed ValueColor() helpers, they are equivalent to calling Text(label) + SameLine() + ColorButton(). @@ -3598,9 +3599,10 @@ bool ImGui::BeginPopupContextItem(const char* str_id, int mouse_button) return BeginPopup(str_id); } -bool ImGui::BeginPopupContextWindow(bool also_over_items, const char* str_id, int mouse_button) +bool ImGui::BeginPopupContextWindow(const char* str_id, int mouse_button, bool also_over_items) { - if (!str_id) str_id = "window_context_menu"; + if (!str_id) + str_id = "window_context_menu"; if (IsMouseHoveringWindow() && IsMouseClicked(mouse_button)) if (also_over_items || !IsAnyItemHovered()) OpenPopupEx(str_id, true); @@ -3609,7 +3611,8 @@ bool ImGui::BeginPopupContextWindow(bool also_over_items, const char* str_id, in bool ImGui::BeginPopupContextVoid(const char* str_id, int mouse_button) { - if (!str_id) str_id = "void_context_menu"; + if (!str_id) + str_id = "void_context_menu"; if (!IsMouseHoveringAnyWindow() && IsMouseClicked(mouse_button)) OpenPopupEx(str_id, true); return BeginPopup(str_id); diff --git a/imgui.h b/imgui.h index 4a014fed4..bbc66a337 100644 --- a/imgui.h +++ b/imgui.h @@ -386,7 +386,7 @@ namespace ImGui IMGUI_API bool BeginPopup(const char* str_id); // return true if the popup is open, and you can start outputting to it. only call EndPopup() if BeginPopup() returned true! IMGUI_API bool BeginPopupModal(const char* name, bool* p_open = NULL, ImGuiWindowFlags extra_flags = 0); // modal dialog (block interactions behind the modal window, can't close the modal window by clicking outside) IMGUI_API bool BeginPopupContextItem(const char* str_id, int mouse_button = 1); // helper to open and begin popup when clicked on last item. read comments in .cpp! - IMGUI_API bool BeginPopupContextWindow(bool also_over_items = true, const char* str_id = NULL, int mouse_button = 1); // helper to open and begin popup when clicked on current window. + IMGUI_API bool BeginPopupContextWindow(const char* str_id = NULL, int mouse_button = 1, bool also_over_items = true); // helper to open and begin popup when clicked on current window. IMGUI_API bool BeginPopupContextVoid(const char* str_id = NULL, int mouse_button = 1); // helper to open and begin popup when clicked in void (no window). IMGUI_API void EndPopup(); IMGUI_API void CloseCurrentPopup(); // close the popup we have begin-ed into. clicking on a MenuItem or Selectable automatically close the current popup. From a9915681eb354096b62362d0d799ccf7cbe83080 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 16 Aug 2017 14:37:54 +0800 Subject: [PATCH 235/921] PushID()/PopID() to not need to mark parent window as Accessed (needlessly waking up the root "Debug" window) (#747) --- imgui.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 1562290a0..dc7081bbb 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -6185,32 +6185,32 @@ void ImGui::SetNextTreeNodeOpen(bool is_open, ImGuiCond cond) void ImGui::PushID(const char* str_id) { - ImGuiWindow* window = GetCurrentWindow(); + ImGuiWindow* window = GetCurrentWindowRead(); window->IDStack.push_back(window->GetID(str_id)); } void ImGui::PushID(const char* str_id_begin, const char* str_id_end) { - ImGuiWindow* window = GetCurrentWindow(); + ImGuiWindow* window = GetCurrentWindowRead(); window->IDStack.push_back(window->GetID(str_id_begin, str_id_end)); } void ImGui::PushID(const void* ptr_id) { - ImGuiWindow* window = GetCurrentWindow(); + ImGuiWindow* window = GetCurrentWindowRead(); window->IDStack.push_back(window->GetID(ptr_id)); } void ImGui::PushID(int int_id) { const void* ptr_id = (void*)(intptr_t)int_id; - ImGuiWindow* window = GetCurrentWindow(); + ImGuiWindow* window = GetCurrentWindowRead(); window->IDStack.push_back(window->GetID(ptr_id)); } void ImGui::PopID() { - ImGuiWindow* window = GetCurrentWindow(); + ImGuiWindow* window = GetCurrentWindowRead(); window->IDStack.pop_back(); } From a85a14370bf58accafb262486045ba1557df659c Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 16 Aug 2017 15:47:10 +0800 Subject: [PATCH 236/921] OpenPopupEx() internal tweaks to receive an ImGuiID, BeginPopupContextXXX shortening unnecessarily long identifier. --- imgui.cpp | 20 +++++++++++--------- imgui.h | 2 +- imgui_internal.h | 2 +- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index dc7081bbb..13a7ca0ad 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3400,11 +3400,10 @@ void ImGui::EndTooltip() // Popups are closed when user click outside, or activate a pressable item, or CloseCurrentPopup() is called within a BeginPopup()/EndPopup() block. // Popup identifiers are relative to the current ID-stack (so OpenPopup and BeginPopup needs to be at the same level). // One open popup per level of the popup hierarchy (NB: when assigning we reset the Window member of ImGuiPopupRef to NULL) -void ImGui::OpenPopupEx(const char* str_id, bool reopen_existing) +void ImGui::OpenPopupEx(ImGuiID id, bool reopen_existing) { ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; - ImGuiID id = window->GetID(str_id); int current_stack_size = g.CurrentPopupStack.Size; ImGuiPopupRef popup_ref = ImGuiPopupRef(id, window, window->GetID("##menus"), g.IO.MousePos); // Tagged as new ref because constructor sets Window to NULL (we are passing the ParentWindow info here) if (g.OpenPopupStack.Size < current_stack_size + 1) @@ -3418,7 +3417,8 @@ void ImGui::OpenPopupEx(const char* str_id, bool reopen_existing) void ImGui::OpenPopup(const char* str_id) { - ImGui::OpenPopupEx(str_id, false); + ImGuiContext& g = *GImGui; + OpenPopupEx(g.CurrentWindow->GetID(str_id), false); } static void CloseInactivePopups() @@ -3494,6 +3494,7 @@ void ImGui::CloseCurrentPopup() static inline void ClearSetNextWindowData() { + // FIXME-OPT ImGuiContext& g = *GImGui; g.SetNextWindowPosCond = g.SetNextWindowSizeCond = g.SetNextWindowContentSizeCond = g.SetNextWindowCollapsedCond = 0; g.SetNextWindowSizeConstraint = g.SetNextWindowFocus = false; @@ -3538,6 +3539,7 @@ bool ImGui::BeginPopup(const char* str_id) return BeginPopupEx(g.CurrentWindow->GetID(str_id), ImGuiWindowFlags_ShowBorders); } +// FIXME bool ImGui::IsPopupOpen(ImGuiID id) { ImGuiContext& g = *GImGui; @@ -3590,31 +3592,31 @@ void ImGui::EndPopup() // 2. If you want right-clicking on the same item to reopen the popup at new location, use the same code replacing IsItemHovered() with IsItemHoveredRect() // and passing true to the OpenPopupEx(). // Because: hovering an item in a window below the popup won't normally trigger is hovering behavior/coloring. The pattern of ignoring the fact that -// the item isn't interactable (because it is blocked by the active popup) may useful in some situation when e.g. large canvas as one item, content of menu +// the item can be interacted with (because it is blocked by the active popup) may useful in some situation when e.g. large canvas as one item, content of menu // driven by click position. bool ImGui::BeginPopupContextItem(const char* str_id, int mouse_button) { if (IsItemHovered() && IsMouseClicked(mouse_button)) - OpenPopupEx(str_id, false); + OpenPopupEx(GImGui->CurrentWindow->GetID(str_id), false); return BeginPopup(str_id); } bool ImGui::BeginPopupContextWindow(const char* str_id, int mouse_button, bool also_over_items) { if (!str_id) - str_id = "window_context_menu"; + str_id = "window_context"; if (IsMouseHoveringWindow() && IsMouseClicked(mouse_button)) if (also_over_items || !IsAnyItemHovered()) - OpenPopupEx(str_id, true); + OpenPopupEx(GImGui->CurrentWindow->GetID(str_id), true); return BeginPopup(str_id); } bool ImGui::BeginPopupContextVoid(const char* str_id, int mouse_button) { if (!str_id) - str_id = "void_context_menu"; + str_id = "void_context"; if (!IsMouseHoveringAnyWindow() && IsMouseClicked(mouse_button)) - OpenPopupEx(str_id, true); + OpenPopupEx(GImGui->CurrentWindow->GetID(str_id), true); return BeginPopup(str_id); } diff --git a/imgui.h b/imgui.h index bbc66a337..907d415de 100644 --- a/imgui.h +++ b/imgui.h @@ -382,13 +382,13 @@ namespace ImGui // Popups IMGUI_API void OpenPopup(const char* str_id); // call to mark popup as open (don't call every frame!). popups are closed when user click outside, or if CloseCurrentPopup() is called within a BeginPopup()/EndPopup() block. By default, Selectable()/MenuItem() are calling CloseCurrentPopup(). Popup identifiers are relative to the current ID-stack (so OpenPopup and BeginPopup needs to be at the same level). - IMGUI_API bool IsPopupOpen(const char* str_id); // return true if the popup is open IMGUI_API bool BeginPopup(const char* str_id); // return true if the popup is open, and you can start outputting to it. only call EndPopup() if BeginPopup() returned true! IMGUI_API bool BeginPopupModal(const char* name, bool* p_open = NULL, ImGuiWindowFlags extra_flags = 0); // modal dialog (block interactions behind the modal window, can't close the modal window by clicking outside) IMGUI_API bool BeginPopupContextItem(const char* str_id, int mouse_button = 1); // helper to open and begin popup when clicked on last item. read comments in .cpp! IMGUI_API bool BeginPopupContextWindow(const char* str_id = NULL, int mouse_button = 1, bool also_over_items = true); // helper to open and begin popup when clicked on current window. IMGUI_API bool BeginPopupContextVoid(const char* str_id = NULL, int mouse_button = 1); // helper to open and begin popup when clicked in void (no window). IMGUI_API void EndPopup(); + IMGUI_API bool IsPopupOpen(const char* str_id); // return true if the popup is open IMGUI_API void CloseCurrentPopup(); // close the popup we have begin-ed into. clicking on a MenuItem or Selectable automatically close the current popup. // Logging: all text output from interface is redirected to tty/file/clipboard. By default, tree nodes are automatically opened during logging. diff --git a/imgui_internal.h b/imgui_internal.h index 170eb4598..0d8981278 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -745,7 +745,7 @@ namespace ImGui IMGUI_API ImVec2 CalcItemSize(ImVec2 size, float default_x, float default_y); IMGUI_API float CalcWrapWidthForPos(const ImVec2& pos, float wrap_pos_x); - IMGUI_API void OpenPopupEx(const char* str_id, bool reopen_existing); + IMGUI_API void OpenPopupEx(ImGuiID id, bool reopen_existing); IMGUI_API bool IsPopupOpen(ImGuiID id); // NB: All position are in absolute pixels coordinates (never using window coordinates internally) From 68bf5ecbc1148d4dd61bdca0e7a8871b492a8e84 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 16 Aug 2017 17:51:44 +0800 Subject: [PATCH 237/921] Marked the weird IMGUI_ONCE_UPON_A_FRAME helper macro as obsolete. prefer using the more explicit ImGuiOnceUponAFrame. Removed the broken __LINE__ from IMGUI_ONCE_UPON_A_FRAME --- imgui.cpp | 1 + imgui.h | 17 +++++++++-------- imgui_demo.cpp | 11 ++++------- 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 13a7ca0ad..5a935aac7 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -204,6 +204,7 @@ Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. Also read releases logs https://github.com/ocornut/imgui/releases for more details. + - 2017/08/15 (1.51) - marked the weird IMGUI_ONCE_UPON_A_FRAME helper macro as obsolete. prefer using the more explicit ImGuiOnceUponAFrame. - 2017/08/15 (1.51) - changed parameter order for BeginPopupContextWindow(), note that most uses relied on default parameters completely. - 2017/08/13 (1.51) - renamed ImGuiCol_Columns_*** to ImGuiCol_Separator_*** - 2017/08/11 (1.51) - renamed ImGuiSetCond_*** types and flags to ImGuiCond_***. Kept redirection enums (will obsolete). diff --git a/imgui.h b/imgui.h index 907d415de..f5c7dcc23 100644 --- a/imgui.h +++ b/imgui.h @@ -924,15 +924,11 @@ public: inline iterator insert(const_iterator it, const value_type& v) { IM_ASSERT(it >= Data && it <= Data+Size); const ptrdiff_t off = it - Data; if (Size == Capacity) reserve(Capacity ? Capacity * 2 : 4); if (off < (int)Size) memmove(Data + off + 1, Data + off, ((size_t)Size - (size_t)off) * sizeof(value_type)); Data[off] = v; Size++; return Data + off; } }; -// Helper: execute a block of code at maximum once a frame -// Convenient if you want to quickly create an UI within deep-nested code that runs multiple times every frame. +// Helper: execute a block of code at maximum once a frame. Convenient if you want to quickly create an UI within deep-nested code that runs multiple times every frame. // Usage: -// IMGUI_ONCE_UPON_A_FRAME -// { -// // code block will be executed one per frame -// } -// Attention! the macro expands into 2 statement so make sure you don't use it within e.g. an if() statement without curly braces. -#define IMGUI_ONCE_UPON_A_FRAME static ImGuiOnceUponAFrame imgui_oaf##__LINE__; if (imgui_oaf##__LINE__) +// static ImGuiOnceUponAFrame oaf; +// if (oaf) +// ImGui::Text("This will be called only once per frame"); struct ImGuiOnceUponAFrame { ImGuiOnceUponAFrame() { RefFrame = -1; } @@ -940,6 +936,11 @@ struct ImGuiOnceUponAFrame operator bool() const { int current_frame = ImGui::GetFrameCount(); if (RefFrame == current_frame) return false; RefFrame = current_frame; return true; } }; +// Helper macro for ImGuiOnceUponAFrame. Attention: The macro expands into 2 statement so make sure you don't use it within e.g. an if() statement without curly braces. +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS // Will obsolete +#define IMGUI_ONCE_UPON_A_FRAME static ImGuiOnceUponAFrame imgui_oaf; if (imgui_oaf) +#endif + // Helper: Parse and apply text filters. In format "aaaaa[,bbbb][,ccccc]" struct ImGuiTextFilter { diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 3a7691162..8e9eaebf9 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -308,14 +308,11 @@ void ImGui::ShowTestWindow(bool* p_open) ImGui::EndTooltip(); } - // Testing IMGUI_ONCE_UPON_A_FRAME macro + // Testing ImGuiOnceUponAFrame helper. + //static ImGuiOnceUponAFrame once; //for (int i = 0; i < 5; i++) - //{ - // IMGUI_ONCE_UPON_A_FRAME - // { - // ImGui::Text("This will be displayed only once."); - // } - //} + // if (once) + // ImGui::Text("This will be displayed only once."); ImGui::Separator(); From fd9460a0877601ff3ed4a43fb2b92ce8fbef6fbb Mon Sep 17 00:00:00 2001 From: Viktor Kirilov Date: Wed, 16 Aug 2017 17:52:11 +0300 Subject: [PATCH 238/921] added missing IMGUI_API to ImGuiTextFilter methods implemented in imgui.cpp --- imgui.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/imgui.h b/imgui.h index f5c7dcc23..0e287fb1e 100644 --- a/imgui.h +++ b/imgui.h @@ -964,11 +964,11 @@ struct ImGuiTextFilter ImVector Filters; int CountGrep; - ImGuiTextFilter(const char* default_filter = ""); - ~ImGuiTextFilter() {} + IMGUI_API ImGuiTextFilter(const char* default_filter = ""); + ~ImGuiTextFilter() {} void Clear() { InputBuf[0] = 0; Build(); } - bool Draw(const char* label = "Filter (inc,-exc)", float width = 0.0f); // Helper calling InputText+Build - bool PassFilter(const char* text, const char* text_end = NULL) const; + IMGUI_API bool Draw(const char* label = "Filter (inc,-exc)", float width = 0.0f); // Helper calling InputText+Build + IMGUI_API bool PassFilter(const char* text, const char* text_end = NULL) const; bool IsActive() const { return !Filters.empty(); } IMGUI_API void Build(); }; From 0be4f66d89a1130c04262844dcbef600e91dcb88 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 16 Aug 2017 18:56:26 +0800 Subject: [PATCH 239/921] ImFontAtlas: Shuffling some code inside Build() to make upcoming diffs less confusing (nb: we might break compat with forks of Build() like #618) --- TODO.txt | 1 + imgui_draw.cpp | 60 +++++++++++++++++++++++++------------------------- 2 files changed, 31 insertions(+), 30 deletions(-) diff --git a/TODO.txt b/TODO.txt index 61d9e048d..5f70cc960 100644 --- a/TODO.txt +++ b/TODO.txt @@ -24,6 +24,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - window: increase minimum size of a window with menus or fix the menu rendering so that it doesn't look odd. - window: double-clicking on title bar to minimize isn't consistent, perhaps move to single-click on left-most collapse icon? - window: expose contents size. (#1045) + - window: GetWindowSize() returns (0,0) when not calculated? (#1045) !- scrolling: allow immediately effective change of scroll after Begin() if we haven't appended items yet. - scrolling/clipping: separator on the initial position of a window is not visible (cursorpos.y <= clippos.y) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 6e94cfb6b..2c6d88e5a 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1034,7 +1034,7 @@ void ImDrawData::ScaleClipRects(const ImVec2& scale) } //----------------------------------------------------------------------------- -// ImFontAtlas +// ImFontConfig //----------------------------------------------------------------------------- ImFontConfig::ImFontConfig() @@ -1055,6 +1055,10 @@ ImFontConfig::ImFontConfig() memset(Name, 0, sizeof(Name)); } +//----------------------------------------------------------------------------- +// ImFontAtlas +//----------------------------------------------------------------------------- + ImFontAtlas::ImFontAtlas() { TexID = NULL; @@ -1282,40 +1286,19 @@ bool ImFontAtlas::Build() TexUvWhitePixel = ImVec2(0, 0); ClearTexData(); - struct ImFontTempBuildData - { - stbtt_fontinfo FontInfo; - stbrp_rect* Rects; - stbtt_pack_range* Ranges; - int RangesCount; - }; - ImFontTempBuildData* tmp_array = (ImFontTempBuildData*)ImGui::MemAlloc((size_t)ConfigData.Size * sizeof(ImFontTempBuildData)); - - // Initialize font information early (so we can error without any cleanup) + count glyphs + // Count glyphs/ranges int total_glyph_count = 0; int total_glyph_range_count = 0; for (int input_i = 0; input_i < ConfigData.Size; input_i++) { ImFontConfig& cfg = ConfigData[input_i]; - ImFontTempBuildData& tmp = tmp_array[input_i]; - - IM_ASSERT(cfg.DstFont && (!cfg.DstFont->IsLoaded() || cfg.DstFont->ContainerAtlas == this)); - const int font_offset = stbtt_GetFontOffsetForIndex((unsigned char*)cfg.FontData, cfg.FontNo); - IM_ASSERT(font_offset >= 0); - if (!stbtt_InitFont(&tmp.FontInfo, (unsigned char*)cfg.FontData, font_offset)) - return false; - - // Count glyphs if (!cfg.GlyphRanges) cfg.GlyphRanges = GetGlyphRangesDefault(); - for (const ImWchar* in_range = cfg.GlyphRanges; in_range[0] && in_range[1]; in_range += 2) - { + for (const ImWchar* in_range = cfg.GlyphRanges; in_range[0] && in_range[1]; in_range += 2, total_glyph_range_count++) total_glyph_count += (in_range[1] - in_range[0]) + 1; - total_glyph_range_count++; - } } - // Start packing. We need a known width for the skyline algorithm. Using a cheap heuristic here to decide of width. User can override TexDesiredWidth and TexGlyphPadding if they wish. + // Start packing. We need a known width for the skyline algorithm. Using a dumb heuristic here to decide of width. User can override TexDesiredWidth and TexGlyphPadding if they wish. // After packing is done, width shouldn't matter much, but some API/GPU have texture size limitations and increasing width can decrease height. TexWidth = (TexDesiredWidth > 0) ? TexDesiredWidth : (total_glyph_count > 4000) ? 4096 : (total_glyph_count > 2000) ? 2048 : (total_glyph_count > 1000) ? 1024 : 512; TexHeight = 0; @@ -1332,6 +1315,26 @@ bool ImFontAtlas::Build() if (extra_rects[i].was_packed) TexHeight = ImMax(TexHeight, extra_rects[i].y + extra_rects[i].h); + // Initialize font information (so we can error without any cleanup) + struct ImFontTempBuildData + { + stbtt_fontinfo FontInfo; + stbrp_rect* Rects; + stbtt_pack_range* Ranges; + int RangesCount; + }; + ImFontTempBuildData* tmp_array = (ImFontTempBuildData*)ImGui::MemAlloc((size_t)ConfigData.Size * sizeof(ImFontTempBuildData)); + for (int input_i = 0; input_i < ConfigData.Size; input_i++) + { + ImFontConfig& cfg = ConfigData[input_i]; + ImFontTempBuildData& tmp = tmp_array[input_i]; + IM_ASSERT(cfg.DstFont && (!cfg.DstFont->IsLoaded() || cfg.DstFont->ContainerAtlas == this)); + const int font_offset = stbtt_GetFontOffsetForIndex((unsigned char*)cfg.FontData, cfg.FontNo); + IM_ASSERT(font_offset >= 0); + if (!stbtt_InitFont(&tmp.FontInfo, (unsigned char*)cfg.FontData, font_offset)) + return false; + } + // Allocate packing character data and flag packed characters buffer as non-packed (x0=y0=x1=y1=0) int buf_packedchars_n = 0, buf_rects_n = 0, buf_ranges_n = 0; stbtt_packedchar* buf_packedchars = (stbtt_packedchar*)ImGui::MemAlloc(total_glyph_count * sizeof(stbtt_packedchar)); @@ -1350,11 +1353,8 @@ bool ImFontAtlas::Build() // Setup ranges int glyph_count = 0; int glyph_ranges_count = 0; - for (const ImWchar* in_range = cfg.GlyphRanges; in_range[0] && in_range[1]; in_range += 2) - { + for (const ImWchar* in_range = cfg.GlyphRanges; in_range[0] && in_range[1]; in_range += 2, glyph_ranges_count++) glyph_count += (in_range[1] - in_range[0]) + 1; - glyph_ranges_count++; - } tmp.Ranges = buf_ranges + buf_ranges_n; tmp.RangesCount = glyph_ranges_count; buf_ranges_n += glyph_ranges_count; @@ -1392,7 +1392,7 @@ bool ImFontAtlas::Build() spc.pixels = TexPixelsAlpha8; spc.height = TexHeight; - // Second pass: render characters + // Second pass: render font characters for (int input_i = 0; input_i < ConfigData.Size; input_i++) { ImFontConfig& cfg = ConfigData[input_i]; From c569676a7b58014fabf113e5a517012261748f76 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 17 Aug 2017 11:37:07 +0800 Subject: [PATCH 240/921] ImVector: Added a const --- TODO.txt | 1 + imgui.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/TODO.txt b/TODO.txt index 5f70cc960..eac6d7473 100644 --- a/TODO.txt +++ b/TODO.txt @@ -75,6 +75,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - layout: more generic alignment state (left/right/centered) for single items? - layout: clean up the InputFloatN/SliderFloatN/ColorEdit4 layout code. item width should include frame padding. - layout: BeginGroup() needs a border option. + - layout: vertical alignement of mixed height items (e.g. buttons) within a same line (#1284) - columns: sizing policy (e.g. for each column: fixed size, %, fill, distribute default size among fills) (#513, #125) - columns: add a conditional parameter to SetColumnOffset() (#513, #125) diff --git a/imgui.h b/imgui.h index 0e287fb1e..681ad9be5 100644 --- a/imgui.h +++ b/imgui.h @@ -903,7 +903,7 @@ public: inline const value_type& back() const { IM_ASSERT(Size > 0); return Data[Size-1]; } inline void swap(ImVector& rhs) { int rhs_size = rhs.Size; rhs.Size = Size; Size = rhs_size; int rhs_cap = rhs.Capacity; rhs.Capacity = Capacity; Capacity = rhs_cap; value_type* rhs_data = rhs.Data; rhs.Data = Data; Data = rhs_data; } - inline int _grow_capacity(int new_size) { int new_capacity = Capacity ? (Capacity + Capacity/2) : 8; return new_capacity > new_size ? new_capacity : new_size; } + inline int _grow_capacity(int size) const { int new_capacity = Capacity ? (Capacity + Capacity/2) : 8; return new_capacity > size ? new_capacity : size; } inline void resize(int new_size) { if (new_size > Capacity) reserve(_grow_capacity(new_size)); Size = new_size; } inline void reserve(int new_capacity) From 52f1a4124c1a3f104e1ee82bf62b469cddbcaccf Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 17 Aug 2017 13:56:16 +0800 Subject: [PATCH 241/921] Demo: Tweaked Fonts section. --- imgui_demo.cpp | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 8e9eaebf9..78e527f7a 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1872,9 +1872,10 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) ImGui::TreePop(); } - if (ImGui::TreeNode("Fonts", "Fonts (%d)", ImGui::GetIO().Fonts->Fonts.Size)) + bool fonts_opened = ImGui::TreeNode("Fonts", "Fonts (%d)", ImGui::GetIO().Fonts->Fonts.Size); + ImGui::SameLine(); ShowHelpMarker("Tip: Load fonts with io.Fonts->AddFontFromFileTTF()\nbefore calling io.Fonts->GetTex* functions."); + if (fonts_opened) { - ImGui::SameLine(); ShowHelpMarker("Tip: Load fonts with io.Fonts->AddFontFromFileTTF()\nbefore calling io.Fonts->GetTex* functions."); ImFontAtlas* atlas = ImGui::GetIO().Fonts; if (ImGui::TreeNode("Atlas texture", "Atlas texture (%dx%d pixels)", atlas->TexWidth, atlas->TexHeight)) { @@ -1885,14 +1886,13 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) for (int i = 0; i < atlas->Fonts.Size; i++) { ImFont* font = atlas->Fonts[i]; - ImGui::BulletText("Font %d: \'%s\', %.2f px, %d glyphs", i, font->ConfigData ? font->ConfigData[0].Name : "", font->FontSize, font->Glyphs.Size); - ImGui::TreePush((void*)(intptr_t)i); + bool font_details_opened = ImGui::TreeNode(font, "Font %d: \'%s\', %.2f px, %d glyphs", i, font->ConfigData ? font->ConfigData[0].Name : "", font->FontSize, font->Glyphs.Size); ImGui::SameLine(); if (ImGui::SmallButton("Set as default")) ImGui::GetIO().FontDefault = font; - ImGui::PushFont(font); - ImGui::Text("The quick brown fox jumps over the lazy dog"); - ImGui::PopFont(); - if (ImGui::TreeNode("Details")) + if (font_details_opened) { + ImGui::PushFont(font); + ImGui::Text("The quick brown fox jumps over the lazy dog"); + ImGui::PopFont(); ImGui::DragFloat("Font scale", &font->Scale, 0.005f, 0.3f, 2.0f, "%.1f"); // Scale only this font ImGui::SameLine(); ShowHelpMarker("Note than the default embedded font is NOT meant to be scaled.\n\nFont are currently rendered into bitmaps at a given size at the time of building the atlas. You may oversample them to get some flexibility with scaling. You can also render at multiple sizes and select which one to use at runtime.\n\n(Glimmer of hope: the atlas system should hopefully be rewritten in the future to make scaling more natural and automatic.)"); ImGui::Text("Ascent: %f, Descent: %f, Height: %f", font->Ascent, font->Descent, font->Ascent - font->Descent); @@ -1946,7 +1946,6 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) } ImGui::TreePop(); } - ImGui::TreePop(); } static float window_scale = 1.0f; ImGui::DragFloat("this window scale", &window_scale, 0.005f, 0.3f, 2.0f, "%.1f"); // scale only this window From 4a7e1ff4d4f3b43bf510f40c3772e7adef5a3b82 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 17 Aug 2017 15:35:59 +0800 Subject: [PATCH 242/921] ImFontAtlas: Some shallow renaming + added an assert for clarification --- imgui_draw.cpp | 45 +++++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 2c6d88e5a..6f817db1b 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1287,20 +1287,20 @@ bool ImFontAtlas::Build() ClearTexData(); // Count glyphs/ranges - int total_glyph_count = 0; - int total_glyph_range_count = 0; + int total_glyphs_count = 0; + int total_ranges_count = 0; for (int input_i = 0; input_i < ConfigData.Size; input_i++) { ImFontConfig& cfg = ConfigData[input_i]; if (!cfg.GlyphRanges) cfg.GlyphRanges = GetGlyphRangesDefault(); - for (const ImWchar* in_range = cfg.GlyphRanges; in_range[0] && in_range[1]; in_range += 2, total_glyph_range_count++) - total_glyph_count += (in_range[1] - in_range[0]) + 1; + for (const ImWchar* in_range = cfg.GlyphRanges; in_range[0] && in_range[1]; in_range += 2, total_ranges_count++) + total_glyphs_count += (in_range[1] - in_range[0]) + 1; } // Start packing. We need a known width for the skyline algorithm. Using a dumb heuristic here to decide of width. User can override TexDesiredWidth and TexGlyphPadding if they wish. // After packing is done, width shouldn't matter much, but some API/GPU have texture size limitations and increasing width can decrease height. - TexWidth = (TexDesiredWidth > 0) ? TexDesiredWidth : (total_glyph_count > 4000) ? 4096 : (total_glyph_count > 2000) ? 2048 : (total_glyph_count > 1000) ? 1024 : 512; + TexWidth = (TexDesiredWidth > 0) ? TexDesiredWidth : (total_glyphs_count > 4000) ? 4096 : (total_glyphs_count > 2000) ? 2048 : (total_glyphs_count > 1000) ? 1024 : 512; TexHeight = 0; const int max_tex_height = 1024*32; stbtt_pack_context spc; @@ -1337,12 +1337,12 @@ bool ImFontAtlas::Build() // Allocate packing character data and flag packed characters buffer as non-packed (x0=y0=x1=y1=0) int buf_packedchars_n = 0, buf_rects_n = 0, buf_ranges_n = 0; - stbtt_packedchar* buf_packedchars = (stbtt_packedchar*)ImGui::MemAlloc(total_glyph_count * sizeof(stbtt_packedchar)); - stbrp_rect* buf_rects = (stbrp_rect*)ImGui::MemAlloc(total_glyph_count * sizeof(stbrp_rect)); - stbtt_pack_range* buf_ranges = (stbtt_pack_range*)ImGui::MemAlloc(total_glyph_range_count * sizeof(stbtt_pack_range)); - memset(buf_packedchars, 0, total_glyph_count * sizeof(stbtt_packedchar)); - memset(buf_rects, 0, total_glyph_count * sizeof(stbrp_rect)); // Unnecessary but let's clear this for the sake of sanity. - memset(buf_ranges, 0, total_glyph_range_count * sizeof(stbtt_pack_range)); + stbtt_packedchar* buf_packedchars = (stbtt_packedchar*)ImGui::MemAlloc(total_glyphs_count * sizeof(stbtt_packedchar)); + stbrp_rect* buf_rects = (stbrp_rect*)ImGui::MemAlloc(total_glyphs_count * sizeof(stbrp_rect)); + stbtt_pack_range* buf_ranges = (stbtt_pack_range*)ImGui::MemAlloc(total_ranges_count * sizeof(stbtt_pack_range)); + memset(buf_packedchars, 0, total_glyphs_count * sizeof(stbtt_packedchar)); + memset(buf_rects, 0, total_glyphs_count * sizeof(stbrp_rect)); // Unnecessary but let's clear this for the sake of sanity. + memset(buf_ranges, 0, total_ranges_count * sizeof(stbtt_pack_range)); // First font pass: pack all glyphs (no rendering at this point, we are working with rectangles in an infinitely tall texture at this point) for (int input_i = 0; input_i < ConfigData.Size; input_i++) @@ -1351,14 +1351,14 @@ bool ImFontAtlas::Build() ImFontTempBuildData& tmp = tmp_array[input_i]; // Setup ranges - int glyph_count = 0; - int glyph_ranges_count = 0; - for (const ImWchar* in_range = cfg.GlyphRanges; in_range[0] && in_range[1]; in_range += 2, glyph_ranges_count++) - glyph_count += (in_range[1] - in_range[0]) + 1; + int font_glyphs_count = 0; + int font_ranges_count = 0; + for (const ImWchar* in_range = cfg.GlyphRanges; in_range[0] && in_range[1]; in_range += 2, font_ranges_count++) + font_glyphs_count += (in_range[1] - in_range[0]) + 1; tmp.Ranges = buf_ranges + buf_ranges_n; - tmp.RangesCount = glyph_ranges_count; - buf_ranges_n += glyph_ranges_count; - for (int i = 0; i < glyph_ranges_count; i++) + tmp.RangesCount = font_ranges_count; + buf_ranges_n += font_ranges_count; + for (int i = 0; i < font_ranges_count; i++) { const ImWchar* in_range = &cfg.GlyphRanges[i * 2]; stbtt_pack_range& range = tmp.Ranges[i]; @@ -1371,9 +1371,10 @@ bool ImFontAtlas::Build() // Pack tmp.Rects = buf_rects + buf_rects_n; - buf_rects_n += glyph_count; + buf_rects_n += font_glyphs_count; stbtt_PackSetOversampling(&spc, cfg.OversampleH, cfg.OversampleV); int n = stbtt_PackFontRangesGatherRects(&spc, &tmp.FontInfo, tmp.Ranges, tmp.RangesCount, tmp.Rects); + IM_ASSERT(n == font_glyphs_count); stbrp_pack_rects((stbrp_context*)spc.pack_info, tmp.Rects, n); // Extend texture height @@ -1381,9 +1382,9 @@ bool ImFontAtlas::Build() if (tmp.Rects[i].was_packed) TexHeight = ImMax(TexHeight, tmp.Rects[i].y + tmp.Rects[i].h); } - IM_ASSERT(buf_rects_n == total_glyph_count); - IM_ASSERT(buf_packedchars_n == total_glyph_count); - IM_ASSERT(buf_ranges_n == total_glyph_range_count); + IM_ASSERT(buf_rects_n == total_glyphs_count); + IM_ASSERT(buf_packedchars_n == total_glyphs_count); + IM_ASSERT(buf_ranges_n == total_ranges_count); // Create texture TexHeight = ImUpperPowerOfTwo(TexHeight); From d970957e2de0780bec50ed05c9f412df6db08dad Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 17 Aug 2017 19:36:48 +0800 Subject: [PATCH 243/921] ImFontAtlas: Draft of an api to submit custom rectangle (not exposed). Atlas default texture chunk using it. (WIP: we are still storing mouse UV outside in GImGui) --- imgui.h | 16 +++- imgui_draw.cpp | 224 +++++++++++++++++++++++++++++-------------------- 2 files changed, 145 insertions(+), 95 deletions(-) diff --git a/imgui.h b/imgui.h index 681ad9be5..19f01c85f 100644 --- a/imgui.h +++ b/imgui.h @@ -1388,10 +1388,22 @@ struct ImFontAtlas ImVec2 TexUvWhitePixel; // Texture coordinates to a white pixel ImVector Fonts; // Hold all the fonts returned by AddFont*. Fonts[0] is the default font upon calling ImGui::NewFrame(), use ImGui::PushFont()/PopFont() to change the current font. - // Private + // [Private] User rectangle for packing custom texture data into the atlas. + struct CustomRect + { + unsigned int ID; // Input // User ID. <0x10000 for font mapped data (WIP/UNSUPPORTED), >=0x10000 for other texture data + unsigned short Width, Height; // Input // Desired rectangle dimension + unsigned short X, Y; // Output // Packed position in Atlas + CustomRect() { ID = 0xFFFFFFFF; Width = Height = 0; X = Y = 0xFFFF; } + bool IsPacked() const { return X != 0xFFFF; } + }; + + // [Private] Members + ImVector CustomRects; // Rectangles for packing custom texture data into the atlas. ImVector ConfigData; // Internal data IMGUI_API bool Build(); // Build pixels data. This is automatically for you by the GetTexData*** functions. - IMGUI_API void RenderCustomTexData(int pass, void* rects); + IMGUI_API int CustomRectRegister(unsigned int id, int width, int height); + IMGUI_API void CustomRectCalcUV(const CustomRect* rect, ImVec2* out_uv_min, ImVec2* out_uv_max); }; // Font runtime data and rendering diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 6f817db1b..579fe6f0f 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1059,6 +1059,42 @@ ImFontConfig::ImFontConfig() // ImFontAtlas //----------------------------------------------------------------------------- +// A work of art lies ahead! (. = white layer, X = black layer, others are blank) +// The white texels on the top left are the ones we'll use everywhere in ImGui to render filled shapes. +const int FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF = 90; +const int FONT_ATLAS_DEFAULT_TEX_DATA_H = 27; +const int FONT_ATLAS_DEFAULT_TEX_DATA_ID = 0xF0000; +const char FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS[FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF * FONT_ATLAS_DEFAULT_TEX_DATA_H + 1] = +{ + "..- -XXXXXXX- X - X -XXXXXXX - XXXXXXX" + "..- -X.....X- X.X - X.X -X.....X - X.....X" + "--- -XXX.XXX- X...X - X...X -X....X - X....X" + "X - X.X - X.....X - X.....X -X...X - X...X" + "XX - X.X -X.......X- X.......X -X..X.X - X.X..X" + "X.X - X.X -XXXX.XXXX- XXXX.XXXX -X.X X.X - X.X X.X" + "X..X - X.X - X.X - X.X -XX X.X - X.X XX" + "X...X - X.X - X.X - XX X.X XX - X.X - X.X " + "X....X - X.X - X.X - X.X X.X X.X - X.X - X.X " + "X.....X - X.X - X.X - X..X X.X X..X - X.X - X.X " + "X......X - X.X - X.X - X...XXXXXX.XXXXXX...X - X.X XX-XX X.X " + "X.......X - X.X - X.X -X.....................X- X.X X.X-X.X X.X " + "X........X - X.X - X.X - X...XXXXXX.XXXXXX...X - X.X..X-X..X.X " + "X.........X -XXX.XXX- X.X - X..X X.X X..X - X...X-X...X " + "X..........X-X.....X- X.X - X.X X.X X.X - X....X-X....X " + "X......XXXXX-XXXXXXX- X.X - XX X.X XX - X.....X-X.....X " + "X...X..X --------- X.X - X.X - XXXXXXX-XXXXXXX " + "X..X X..X - -XXXX.XXXX- XXXX.XXXX ------------------------------------" + "X.X X..X - -X.......X- X.......X - XX XX - " + "XX X..X - - X.....X - X.....X - X.X X.X - " + " X..X - X...X - X...X - X..X X..X - " + " XX - X.X - X.X - X...XXXXXXXXXXXXX...X - " + "------------ - X - X -X.....................X- " + " ----------------------------------- X...XXXXXXXXXXXXX...X - " + " - X..X X..X - " + " - X.X X.X - " + " - XX XX - " +}; + ImFontAtlas::ImFontAtlas() { TexID = NULL; @@ -1091,6 +1127,7 @@ void ImFontAtlas::ClearInputData() Fonts[i]->ConfigDataCount = 0; } ConfigData.clear(); + CustomRects.clear(); } void ImFontAtlas::ClearTexData() @@ -1277,6 +1314,29 @@ ImFont* ImFontAtlas::AddFontFromMemoryCompressedBase85TTF(const char* compressed return font; } +int ImFontAtlas::CustomRectRegister(unsigned int id, int width, int height) +{ + IM_ASSERT(width > 0 && width <= 0xFFFF); + IM_ASSERT(height > 0 && height <= 0xFFFF); + CustomRect r; + r.ID = id; + r.Width = (unsigned short)width; + r.Height = (unsigned short)height; + CustomRects.push_back(r); + return CustomRects.Size - 1; // Return index +} + +void ImFontAtlas::CustomRectCalcUV(const CustomRect* rect, ImVec2* out_uv_min, ImVec2* out_uv_max) +{ + IM_ASSERT(TexWidth > 0 && TexHeight > 0); // Font atlas needs to be built before we can calculate UV coordinates + IM_ASSERT(rect->IsPacked()); // Make sure the rectangle has been packed + *out_uv_min = ImVec2((float)rect->X / TexWidth, (float)rect->Y / TexHeight); + *out_uv_max = ImVec2((float)(rect->X + rect->Width) / TexWidth, (float)(rect->Y + rect->Height) / TexHeight); +} + +static void BuildPackCustomRects(ImFontAtlas* atlas, stbtt_pack_context* spc); +static void BuildRenderDefaultTexData(ImFontAtlas* atlas); + bool ImFontAtlas::Build() { IM_ASSERT(ConfigData.Size > 0); @@ -1299,7 +1359,7 @@ bool ImFontAtlas::Build() } // Start packing. We need a known width for the skyline algorithm. Using a dumb heuristic here to decide of width. User can override TexDesiredWidth and TexGlyphPadding if they wish. - // After packing is done, width shouldn't matter much, but some API/GPU have texture size limitations and increasing width can decrease height. + // Width doesn't really matter much, but some API/GPU have texture size limitations and increasing width can decrease height. TexWidth = (TexDesiredWidth > 0) ? TexDesiredWidth : (total_glyphs_count > 4000) ? 4096 : (total_glyphs_count > 2000) ? 2048 : (total_glyphs_count > 1000) ? 1024 : 512; TexHeight = 0; const int max_tex_height = 1024*32; @@ -1307,13 +1367,10 @@ bool ImFontAtlas::Build() stbtt_PackBegin(&spc, NULL, TexWidth, max_tex_height, 0, TexGlyphPadding, NULL); // Pack our extra data rectangles first, so it will be on the upper-left corner of our texture (UV will have small values). - ImVector extra_rects; - RenderCustomTexData(0, &extra_rects); - stbtt_PackSetOversampling(&spc, 1, 1); - stbrp_pack_rects((stbrp_context*)spc.pack_info, &extra_rects[0], extra_rects.Size); - for (int i = 0; i < extra_rects.Size; i++) - if (extra_rects[i].was_packed) - TexHeight = ImMax(TexHeight, extra_rects[i].y + extra_rects[i].h); + // FIXME-WIP: We should register in the constructor (but cannot because our static instances may not have allocator ready by the time they initialize). This needs to be fixed because we can expose CustomRects. + if (CustomRects.empty()) + CustomRectRegister(FONT_ATLAS_DEFAULT_TEX_DATA_ID, FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF*2+1, FONT_ATLAS_DEFAULT_TEX_DATA_H); + BuildPackCustomRects(this, &spc); // Initialize font information (so we can error without any cleanup) struct ImFontTempBuildData @@ -1476,100 +1533,81 @@ bool ImFontAtlas::Build() ImGui::MemFree(tmp_array); // Render into our custom data block - RenderCustomTexData(1, &extra_rects); + BuildRenderDefaultTexData(this); return true; } -void ImFontAtlas::RenderCustomTexData(int pass, void* p_rects) +static void BuildPackCustomRects(ImFontAtlas* atlas, stbtt_pack_context* spc) { - // A work of art lies ahead! (. = white layer, X = black layer, others are blank) - // The white texels on the top left are the ones we'll use everywhere in ImGui to render filled shapes. - const int TEX_DATA_W = 90; - const int TEX_DATA_H = 27; - const char texture_data[TEX_DATA_W*TEX_DATA_H+1] = + ImVector& user_rects = atlas->CustomRects; + ImVector pack_rects; + pack_rects.resize(user_rects.Size); + memset(pack_rects.Data, 0, sizeof(stbrp_rect) * user_rects.Size); + for (int i = 0; i < user_rects.Size; i++) { - "..- -XXXXXXX- X - X -XXXXXXX - XXXXXXX" - "..- -X.....X- X.X - X.X -X.....X - X.....X" - "--- -XXX.XXX- X...X - X...X -X....X - X....X" - "X - X.X - X.....X - X.....X -X...X - X...X" - "XX - X.X -X.......X- X.......X -X..X.X - X.X..X" - "X.X - X.X -XXXX.XXXX- XXXX.XXXX -X.X X.X - X.X X.X" - "X..X - X.X - X.X - X.X -XX X.X - X.X XX" - "X...X - X.X - X.X - XX X.X XX - X.X - X.X " - "X....X - X.X - X.X - X.X X.X X.X - X.X - X.X " - "X.....X - X.X - X.X - X..X X.X X..X - X.X - X.X " - "X......X - X.X - X.X - X...XXXXXX.XXXXXX...X - X.X XX-XX X.X " - "X.......X - X.X - X.X -X.....................X- X.X X.X-X.X X.X " - "X........X - X.X - X.X - X...XXXXXX.XXXXXX...X - X.X..X-X..X.X " - "X.........X -XXX.XXX- X.X - X..X X.X X..X - X...X-X...X " - "X..........X-X.....X- X.X - X.X X.X X.X - X....X-X....X " - "X......XXXXX-XXXXXXX- X.X - XX X.X XX - X.....X-X.....X " - "X...X..X --------- X.X - X.X - XXXXXXX-XXXXXXX " - "X..X X..X - -XXXX.XXXX- XXXX.XXXX ------------------------------------" - "X.X X..X - -X.......X- X.......X - XX XX - " - "XX X..X - - X.....X - X.....X - X.X X.X - " - " X..X - X...X - X...X - X..X X..X - " - " XX - X.X - X.X - X...XXXXXXXXXXXXX...X - " - "------------ - X - X -X.....................X- " - " ----------------------------------- X...XXXXXXXXXXXXX...X - " - " - X..X X..X - " - " - X.X X.X - " - " - XX XX - " + pack_rects[i].w = user_rects[i].Width; + pack_rects[i].h = user_rects[i].Height; + } + stbtt_PackSetOversampling(spc, 1, 1); + stbrp_pack_rects((stbrp_context*)spc->pack_info, &pack_rects[0], pack_rects.Size); + for (int i = 0; i < pack_rects.Size; i++) + if (pack_rects[i].was_packed) + { + user_rects[i].X = pack_rects[i].x; + user_rects[i].Y = pack_rects[i].y; + IM_ASSERT(pack_rects[i].w == user_rects[i].Width && pack_rects[i].h == user_rects[i].Height); + atlas->TexHeight = ImMax(atlas->TexHeight, pack_rects[i].y + pack_rects[i].h); + } +} + +static void BuildRenderDefaultTexData(ImFontAtlas* atlas) +{ + ImFontAtlas::CustomRect& r = atlas->CustomRects[0]; + IM_ASSERT(r.ID == FONT_ATLAS_DEFAULT_TEX_DATA_ID); + IM_ASSERT(r.Width == FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF*2+1); + IM_ASSERT(r.Height == FONT_ATLAS_DEFAULT_TEX_DATA_H); + IM_ASSERT(r.IsPacked()); + IM_ASSERT(atlas->TexPixelsAlpha8 != NULL); + + // Render/copy pixels + for (int y = 0, n = 0; y < FONT_ATLAS_DEFAULT_TEX_DATA_H; y++) + for (int x = 0; x < FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF; x++, n++) + { + const int offset0 = (int)(r.X + x) + (int)(r.Y + y) * atlas->TexWidth; + const int offset1 = offset0 + FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF + 1; + atlas->TexPixelsAlpha8[offset0] = FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS[n] == '.' ? 0xFF : 0x00; + atlas->TexPixelsAlpha8[offset1] = FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS[n] == 'X' ? 0xFF : 0x00; + } + const ImVec2 tex_uv_scale(1.0f / atlas->TexWidth, 1.0f / atlas->TexHeight); + atlas->TexUvWhitePixel = ImVec2((r.X + 0.5f) * tex_uv_scale.x, (r.Y + 0.5f) * tex_uv_scale.y); + + // Setup mouse cursors + const ImVec2 cursor_datas[ImGuiMouseCursor_Count_][3] = + { + // Pos ........ Size ......... Offset ...... + { ImVec2(0,3), ImVec2(12,19), ImVec2( 0, 0) }, // ImGuiMouseCursor_Arrow + { ImVec2(13,0), ImVec2(7,16), ImVec2( 4, 8) }, // ImGuiMouseCursor_TextInput + { ImVec2(31,0), ImVec2(23,23), ImVec2(11,11) }, // ImGuiMouseCursor_Move + { ImVec2(21,0), ImVec2( 9,23), ImVec2( 5,11) }, // ImGuiMouseCursor_ResizeNS + { ImVec2(55,18),ImVec2(23, 9), ImVec2(11, 5) }, // ImGuiMouseCursor_ResizeEW + { ImVec2(73,0), ImVec2(17,17), ImVec2( 9, 9) }, // ImGuiMouseCursor_ResizeNESW + { ImVec2(55,0), ImVec2(17,17), ImVec2( 9, 9) }, // ImGuiMouseCursor_ResizeNWSE }; - ImVector& rects = *(ImVector*)p_rects; - if (pass == 0) + for (int type = 0; type < ImGuiMouseCursor_Count_; type++) { - // Request rectangles - stbrp_rect r; - memset(&r, 0, sizeof(r)); - r.w = (TEX_DATA_W*2)+1; - r.h = TEX_DATA_H+1; - rects.push_back(r); - } - else if (pass == 1) - { - // Render/copy pixels - const stbrp_rect& r = rects[0]; - for (int y = 0, n = 0; y < TEX_DATA_H; y++) - for (int x = 0; x < TEX_DATA_W; x++, n++) - { - const int offset0 = (int)(r.x + x) + (int)(r.y + y) * TexWidth; - const int offset1 = offset0 + 1 + TEX_DATA_W; - TexPixelsAlpha8[offset0] = texture_data[n] == '.' ? 0xFF : 0x00; - TexPixelsAlpha8[offset1] = texture_data[n] == 'X' ? 0xFF : 0x00; - } - const ImVec2 tex_uv_scale(1.0f / TexWidth, 1.0f / TexHeight); - TexUvWhitePixel = ImVec2((r.x + 0.5f) * tex_uv_scale.x, (r.y + 0.5f) * tex_uv_scale.y); - - // Setup mouse cursors - const ImVec2 cursor_datas[ImGuiMouseCursor_Count_][3] = - { - // Pos ........ Size ......... Offset ...... - { ImVec2(0,3), ImVec2(12,19), ImVec2( 0, 0) }, // ImGuiMouseCursor_Arrow - { ImVec2(13,0), ImVec2(7,16), ImVec2( 4, 8) }, // ImGuiMouseCursor_TextInput - { ImVec2(31,0), ImVec2(23,23), ImVec2(11,11) }, // ImGuiMouseCursor_Move - { ImVec2(21,0), ImVec2( 9,23), ImVec2( 5,11) }, // ImGuiMouseCursor_ResizeNS - { ImVec2(55,18),ImVec2(23, 9), ImVec2(11, 5) }, // ImGuiMouseCursor_ResizeEW - { ImVec2(73,0), ImVec2(17,17), ImVec2( 9, 9) }, // ImGuiMouseCursor_ResizeNESW - { ImVec2(55,0), ImVec2(17,17), ImVec2( 9, 9) }, // ImGuiMouseCursor_ResizeNWSE - }; - - for (int type = 0; type < ImGuiMouseCursor_Count_; type++) - { - ImGuiMouseCursorData& cursor_data = GImGui->MouseCursorData[type]; - ImVec2 pos = cursor_datas[type][0] + ImVec2((float)r.x, (float)r.y); - const ImVec2 size = cursor_datas[type][1]; - cursor_data.Type = type; - cursor_data.Size = size; - cursor_data.HotOffset = cursor_datas[type][2]; - cursor_data.TexUvMin[0] = (pos) * tex_uv_scale; - cursor_data.TexUvMax[0] = (pos + size) * tex_uv_scale; - pos.x += TEX_DATA_W+1; - cursor_data.TexUvMin[1] = (pos) * tex_uv_scale; - cursor_data.TexUvMax[1] = (pos + size) * tex_uv_scale; - } + ImGuiMouseCursorData& cursor_data = GImGui->MouseCursorData[type]; + ImVec2 pos = cursor_datas[type][0] + ImVec2((float)r.X, (float)r.Y); + const ImVec2 size = cursor_datas[type][1]; + cursor_data.Type = type; + cursor_data.Size = size; + cursor_data.HotOffset = cursor_datas[type][2]; + cursor_data.TexUvMin[0] = (pos) * tex_uv_scale; + cursor_data.TexUvMax[0] = (pos + size) * tex_uv_scale; + pos.x += FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF + 1; + cursor_data.TexUvMin[1] = (pos) * tex_uv_scale; + cursor_data.TexUvMax[1] = (pos + size) * tex_uv_scale; } } From 4075cc58e9e2ee53b69fc8a2ad8286b01c63811a Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 17 Aug 2017 20:44:44 +0800 Subject: [PATCH 244/921] ImFontAtlas; Re-arranging code to simplify implementation of imgui_freetype (#618) --- imgui_draw.cpp | 33 ++++++++++++++++++++------------- imgui_internal.h | 5 +++++ 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 579fe6f0f..96f258c00 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1334,13 +1334,12 @@ void ImFontAtlas::CustomRectCalcUV(const CustomRect* rect, ImVec2* out_uv_min, I *out_uv_max = ImVec2((float)(rect->X + rect->Width) / TexWidth, (float)(rect->Y + rect->Height) / TexHeight); } -static void BuildPackCustomRects(ImFontAtlas* atlas, stbtt_pack_context* spc); -static void BuildRenderDefaultTexData(ImFontAtlas* atlas); - bool ImFontAtlas::Build() { IM_ASSERT(ConfigData.Size > 0); + ImFontAtlasBuildRegisterDefaultCustomRects(this); + TexID = NULL; TexWidth = TexHeight = 0; TexUvWhitePixel = ImVec2(0, 0); @@ -1358,19 +1357,19 @@ bool ImFontAtlas::Build() total_glyphs_count += (in_range[1] - in_range[0]) + 1; } - // Start packing. We need a known width for the skyline algorithm. Using a dumb heuristic here to decide of width. User can override TexDesiredWidth and TexGlyphPadding if they wish. + // We need a width for the skyline algorithm. Using a dumb heuristic here to decide of width. User can override TexDesiredWidth and TexGlyphPadding if they wish. // Width doesn't really matter much, but some API/GPU have texture size limitations and increasing width can decrease height. TexWidth = (TexDesiredWidth > 0) ? TexDesiredWidth : (total_glyphs_count > 4000) ? 4096 : (total_glyphs_count > 2000) ? 2048 : (total_glyphs_count > 1000) ? 1024 : 512; TexHeight = 0; + + // Start packing const int max_tex_height = 1024*32; stbtt_pack_context spc; stbtt_PackBegin(&spc, NULL, TexWidth, max_tex_height, 0, TexGlyphPadding, NULL); + stbtt_PackSetOversampling(&spc, 1, 1); // Pack our extra data rectangles first, so it will be on the upper-left corner of our texture (UV will have small values). - // FIXME-WIP: We should register in the constructor (but cannot because our static instances may not have allocator ready by the time they initialize). This needs to be fixed because we can expose CustomRects. - if (CustomRects.empty()) - CustomRectRegister(FONT_ATLAS_DEFAULT_TEX_DATA_ID, FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF*2+1, FONT_ATLAS_DEFAULT_TEX_DATA_H); - BuildPackCustomRects(this, &spc); + ImFontAtlasBuildPackCustomRects(this, spc.pack_info); // Initialize font information (so we can error without any cleanup) struct ImFontTempBuildData @@ -1533,13 +1532,22 @@ bool ImFontAtlas::Build() ImGui::MemFree(tmp_array); // Render into our custom data block - BuildRenderDefaultTexData(this); + ImFontAtlasBuildRenderDefaultTexData(this); return true; } -static void BuildPackCustomRects(ImFontAtlas* atlas, stbtt_pack_context* spc) +void ImFontAtlasBuildRegisterDefaultCustomRects(ImFontAtlas* atlas) { + // FIXME-WIP: We should register in the constructor (but cannot because our static instances may not have allocator ready by the time they initialize). This needs to be fixed because we can expose CustomRects. + if (atlas->CustomRects.empty()) + atlas->CustomRectRegister(FONT_ATLAS_DEFAULT_TEX_DATA_ID, FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF*2+1, FONT_ATLAS_DEFAULT_TEX_DATA_H); +} + +void ImFontAtlasBuildPackCustomRects(ImFontAtlas* atlas, void* pack_context_opaque) +{ + stbrp_context* pack_context = (stbrp_context*)pack_context_opaque; + ImVector& user_rects = atlas->CustomRects; ImVector pack_rects; pack_rects.resize(user_rects.Size); @@ -1549,8 +1557,7 @@ static void BuildPackCustomRects(ImFontAtlas* atlas, stbtt_pack_context* spc) pack_rects[i].w = user_rects[i].Width; pack_rects[i].h = user_rects[i].Height; } - stbtt_PackSetOversampling(spc, 1, 1); - stbrp_pack_rects((stbrp_context*)spc->pack_info, &pack_rects[0], pack_rects.Size); + stbrp_pack_rects(pack_context, &pack_rects[0], pack_rects.Size); for (int i = 0; i < pack_rects.Size; i++) if (pack_rects[i].was_packed) { @@ -1561,7 +1568,7 @@ static void BuildPackCustomRects(ImFontAtlas* atlas, stbtt_pack_context* spc) } } -static void BuildRenderDefaultTexData(ImFontAtlas* atlas) +void ImFontAtlasBuildRenderDefaultTexData(ImFontAtlas* atlas) { ImFontAtlas::CustomRect& r = atlas->CustomRects[0]; IM_ASSERT(r.ID == FONT_ATLAS_DEFAULT_TEX_DATA_ID); diff --git a/imgui_internal.h b/imgui_internal.h index 0d8981278..310878049 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -792,6 +792,11 @@ namespace ImGui } // namespace ImGui +// ImFontAtlas +IMGUI_API void ImFontAtlasBuildRegisterDefaultCustomRects(ImFontAtlas* atlas); +IMGUI_API void ImFontAtlasBuildPackCustomRects(ImFontAtlas* atlas, void* spc); +IMGUI_API void ImFontAtlasBuildRenderDefaultTexData(ImFontAtlas* atlas); + #ifdef __clang__ #pragma clang diagnostic pop #endif From 1086c877671eabd394fbb178de88b446bfd04528 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 17 Aug 2017 21:13:14 +0800 Subject: [PATCH 245/921] ImFontAtlas: Re-arranging code to simplify implementation of imgui_freetype. (#618) --- imgui_draw.cpp | 44 +++++++++++++++++++++++++++----------------- imgui_internal.h | 3 ++- 2 files changed, 29 insertions(+), 18 deletions(-) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 96f258c00..7f9ff56ec 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1477,20 +1477,9 @@ bool ImFontAtlas::Build() float ascent = unscaled_ascent * font_scale; float descent = unscaled_descent * font_scale; - if (!cfg.MergeMode) - { - dst_font->ContainerAtlas = this; - dst_font->ConfigData = &cfg; - dst_font->ConfigDataCount = 0; - dst_font->FontSize = cfg.SizePixels; - dst_font->Ascent = ascent; - dst_font->Descent = descent; - dst_font->Glyphs.resize(0); - dst_font->MetricsTotalSurface = 0; - } - dst_font->ConfigDataCount++; + ImFontAtlasBuildSetupFont(this, dst_font, &cfg, ascent, descent); float off_x = cfg.GlyphOffset.x; - float off_y = cfg.GlyphOffset.y; + float off_y = cfg.GlyphOffset.y + (float)(int)(dst_font->Ascent + 0.5f); dst_font->FallbackGlyph = NULL; // Always clear fallback so FindGlyph can return NULL. It will be set again in BuildLookupTable() for (int i = 0; i < tmp.RangesCount; i++) @@ -1513,11 +1502,16 @@ bool ImFontAtlas::Build() dst_font->Glyphs.resize(dst_font->Glyphs.Size + 1); ImFont::Glyph& glyph = dst_font->Glyphs.back(); glyph.Codepoint = (ImWchar)codepoint; - glyph.X0 = q.x0 + off_x; glyph.Y0 = q.y0 + off_y; glyph.X1 = q.x1 + off_x; glyph.Y1 = q.y1 + off_y; - glyph.U0 = q.s0; glyph.V0 = q.t0; glyph.U1 = q.s1; glyph.V1 = q.t1; - glyph.Y0 += (float)(int)(dst_font->Ascent + 0.5f); - glyph.Y1 += (float)(int)(dst_font->Ascent + 0.5f); + glyph.X0 = q.x0 + off_x; + glyph.Y0 = q.y0 + off_y; + glyph.X1 = q.x1 + off_x; + glyph.Y1 = q.y1 + off_y; + glyph.U0 = q.s0; + glyph.V0 = q.t0; + glyph.U1 = q.s1; + glyph.V1 = q.t1; glyph.XAdvance = (pc.xadvance + cfg.GlyphExtraSpacing.x); // Bake spacing into XAdvance + if (cfg.PixelSnapH) glyph.XAdvance = (float)(int)(glyph.XAdvance + 0.5f); dst_font->MetricsTotalSurface += (int)((glyph.U1 - glyph.U0) * TexWidth + 1.99f) * (int)((glyph.V1 - glyph.V0) * TexHeight + 1.99f); // +1 to account for average padding, +0.99 to round @@ -1544,6 +1538,22 @@ void ImFontAtlasBuildRegisterDefaultCustomRects(ImFontAtlas* atlas) atlas->CustomRectRegister(FONT_ATLAS_DEFAULT_TEX_DATA_ID, FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF*2+1, FONT_ATLAS_DEFAULT_TEX_DATA_H); } +void ImFontAtlasBuildSetupFont(ImFontAtlas* atlas, ImFont* font, ImFontConfig* font_config, float ascent, float descent) +{ + if (!font_config->MergeMode) + { + font->ContainerAtlas = atlas; + font->ConfigData = font_config; + font->ConfigDataCount = 0; + font->FontSize = font_config->SizePixels; + font->Ascent = ascent; + font->Descent = descent; + font->Glyphs.resize(0); + font->MetricsTotalSurface = 0; + } + font->ConfigDataCount++; +} + void ImFontAtlasBuildPackCustomRects(ImFontAtlas* atlas, void* pack_context_opaque) { stbrp_context* pack_context = (stbrp_context*)pack_context_opaque; diff --git a/imgui_internal.h b/imgui_internal.h index 310878049..09f696282 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -792,8 +792,9 @@ namespace ImGui } // namespace ImGui -// ImFontAtlas +// ImFontAtlas internals IMGUI_API void ImFontAtlasBuildRegisterDefaultCustomRects(ImFontAtlas* atlas); +IMGUI_API void ImFontAtlasBuildSetupFont(ImFontAtlas* atlas, ImFont* font, ImFontConfig* font_config, float ascent, float descent); IMGUI_API void ImFontAtlasBuildPackCustomRects(ImFontAtlas* atlas, void* spc); IMGUI_API void ImFontAtlasBuildRenderDefaultTexData(ImFontAtlas* atlas); From 8be7a60f206899ab66a280582d45505176d18945 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 17 Aug 2017 21:19:54 +0800 Subject: [PATCH 246/921] ImFontAtlas: Re-arranging code to simplify implementation of imgui_freetype. (#618) --- imgui_draw.cpp | 72 ++++++++++++++++++++++++++---------------------- imgui_internal.h | 1 + 2 files changed, 40 insertions(+), 33 deletions(-) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 7f9ff56ec..bacbd7f5d 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1336,40 +1336,45 @@ void ImFontAtlas::CustomRectCalcUV(const CustomRect* rect, ImVec2* out_uv_min, I bool ImFontAtlas::Build() { - IM_ASSERT(ConfigData.Size > 0); + return ImFontAtlasBuildWithStbTruetype(this); +} - ImFontAtlasBuildRegisterDefaultCustomRects(this); +bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas) +{ + IM_ASSERT(atlas->ConfigData.Size > 0); - TexID = NULL; - TexWidth = TexHeight = 0; - TexUvWhitePixel = ImVec2(0, 0); - ClearTexData(); + ImFontAtlasBuildRegisterDefaultCustomRects(atlas); + + atlas->TexID = NULL; + atlas->TexWidth = atlas->TexHeight = 0; + atlas->TexUvWhitePixel = ImVec2(0, 0); + atlas->ClearTexData(); // Count glyphs/ranges int total_glyphs_count = 0; int total_ranges_count = 0; - for (int input_i = 0; input_i < ConfigData.Size; input_i++) + for (int input_i = 0; input_i < atlas->ConfigData.Size; input_i++) { - ImFontConfig& cfg = ConfigData[input_i]; + ImFontConfig& cfg = atlas->ConfigData[input_i]; if (!cfg.GlyphRanges) - cfg.GlyphRanges = GetGlyphRangesDefault(); + cfg.GlyphRanges = atlas->GetGlyphRangesDefault(); for (const ImWchar* in_range = cfg.GlyphRanges; in_range[0] && in_range[1]; in_range += 2, total_ranges_count++) total_glyphs_count += (in_range[1] - in_range[0]) + 1; } // We need a width for the skyline algorithm. Using a dumb heuristic here to decide of width. User can override TexDesiredWidth and TexGlyphPadding if they wish. // Width doesn't really matter much, but some API/GPU have texture size limitations and increasing width can decrease height. - TexWidth = (TexDesiredWidth > 0) ? TexDesiredWidth : (total_glyphs_count > 4000) ? 4096 : (total_glyphs_count > 2000) ? 2048 : (total_glyphs_count > 1000) ? 1024 : 512; - TexHeight = 0; + atlas->TexWidth = (atlas->TexDesiredWidth > 0) ? atlas->TexDesiredWidth : (total_glyphs_count > 4000) ? 4096 : (total_glyphs_count > 2000) ? 2048 : (total_glyphs_count > 1000) ? 1024 : 512; + atlas->TexHeight = 0; // Start packing const int max_tex_height = 1024*32; stbtt_pack_context spc; - stbtt_PackBegin(&spc, NULL, TexWidth, max_tex_height, 0, TexGlyphPadding, NULL); + stbtt_PackBegin(&spc, NULL, atlas->TexWidth, max_tex_height, 0, atlas->TexGlyphPadding, NULL); stbtt_PackSetOversampling(&spc, 1, 1); // Pack our extra data rectangles first, so it will be on the upper-left corner of our texture (UV will have small values). - ImFontAtlasBuildPackCustomRects(this, spc.pack_info); + ImFontAtlasBuildPackCustomRects(atlas, spc.pack_info); // Initialize font information (so we can error without any cleanup) struct ImFontTempBuildData @@ -1379,12 +1384,13 @@ bool ImFontAtlas::Build() stbtt_pack_range* Ranges; int RangesCount; }; - ImFontTempBuildData* tmp_array = (ImFontTempBuildData*)ImGui::MemAlloc((size_t)ConfigData.Size * sizeof(ImFontTempBuildData)); - for (int input_i = 0; input_i < ConfigData.Size; input_i++) + ImFontTempBuildData* tmp_array = (ImFontTempBuildData*)ImGui::MemAlloc((size_t)atlas->ConfigData.Size * sizeof(ImFontTempBuildData)); + for (int input_i = 0; input_i < atlas->ConfigData.Size; input_i++) { - ImFontConfig& cfg = ConfigData[input_i]; + ImFontConfig& cfg = atlas->ConfigData[input_i]; ImFontTempBuildData& tmp = tmp_array[input_i]; - IM_ASSERT(cfg.DstFont && (!cfg.DstFont->IsLoaded() || cfg.DstFont->ContainerAtlas == this)); + IM_ASSERT(cfg.DstFont && (!cfg.DstFont->IsLoaded() || cfg.DstFont->ContainerAtlas == atlas)); + const int font_offset = stbtt_GetFontOffsetForIndex((unsigned char*)cfg.FontData, cfg.FontNo); IM_ASSERT(font_offset >= 0); if (!stbtt_InitFont(&tmp.FontInfo, (unsigned char*)cfg.FontData, font_offset)) @@ -1401,9 +1407,9 @@ bool ImFontAtlas::Build() memset(buf_ranges, 0, total_ranges_count * sizeof(stbtt_pack_range)); // First font pass: pack all glyphs (no rendering at this point, we are working with rectangles in an infinitely tall texture at this point) - for (int input_i = 0; input_i < ConfigData.Size; input_i++) + for (int input_i = 0; input_i < atlas->ConfigData.Size; input_i++) { - ImFontConfig& cfg = ConfigData[input_i]; + ImFontConfig& cfg = atlas->ConfigData[input_i]; ImFontTempBuildData& tmp = tmp_array[input_i]; // Setup ranges @@ -1436,23 +1442,23 @@ bool ImFontAtlas::Build() // Extend texture height for (int i = 0; i < n; i++) if (tmp.Rects[i].was_packed) - TexHeight = ImMax(TexHeight, tmp.Rects[i].y + tmp.Rects[i].h); + atlas->TexHeight = ImMax(atlas->TexHeight, tmp.Rects[i].y + tmp.Rects[i].h); } IM_ASSERT(buf_rects_n == total_glyphs_count); IM_ASSERT(buf_packedchars_n == total_glyphs_count); IM_ASSERT(buf_ranges_n == total_ranges_count); // Create texture - TexHeight = ImUpperPowerOfTwo(TexHeight); - TexPixelsAlpha8 = (unsigned char*)ImGui::MemAlloc(TexWidth * TexHeight); - memset(TexPixelsAlpha8, 0, TexWidth * TexHeight); - spc.pixels = TexPixelsAlpha8; - spc.height = TexHeight; + atlas->TexHeight = ImUpperPowerOfTwo(atlas->TexHeight); + atlas->TexPixelsAlpha8 = (unsigned char*)ImGui::MemAlloc(atlas->TexWidth * atlas->TexHeight); + memset(atlas->TexPixelsAlpha8, 0, atlas->TexWidth * atlas->TexHeight); + spc.pixels = atlas->TexPixelsAlpha8; + spc.height = atlas->TexHeight; // Second pass: render font characters - for (int input_i = 0; input_i < ConfigData.Size; input_i++) + for (int input_i = 0; input_i < atlas->ConfigData.Size; input_i++) { - ImFontConfig& cfg = ConfigData[input_i]; + ImFontConfig& cfg = atlas->ConfigData[input_i]; ImFontTempBuildData& tmp = tmp_array[input_i]; stbtt_PackSetOversampling(&spc, cfg.OversampleH, cfg.OversampleV); stbtt_PackFontRangesRenderIntoRects(&spc, &tmp.FontInfo, tmp.Ranges, tmp.RangesCount, tmp.Rects); @@ -1465,9 +1471,9 @@ bool ImFontAtlas::Build() buf_rects = NULL; // Third pass: setup ImFont and glyphs for runtime - for (int input_i = 0; input_i < ConfigData.Size; input_i++) + for (int input_i = 0; input_i < atlas->ConfigData.Size; input_i++) { - ImFontConfig& cfg = ConfigData[input_i]; + ImFontConfig& cfg = atlas->ConfigData[input_i]; ImFontTempBuildData& tmp = tmp_array[input_i]; ImFont* dst_font = cfg.DstFont; // We can have multiple input fonts writing into a same destination font (when using MergeMode=true) @@ -1477,7 +1483,7 @@ bool ImFontAtlas::Build() float ascent = unscaled_ascent * font_scale; float descent = unscaled_descent * font_scale; - ImFontAtlasBuildSetupFont(this, dst_font, &cfg, ascent, descent); + ImFontAtlasBuildSetupFont(atlas, dst_font, &cfg, ascent, descent); float off_x = cfg.GlyphOffset.x; float off_y = cfg.GlyphOffset.y + (float)(int)(dst_font->Ascent + 0.5f); @@ -1497,7 +1503,7 @@ bool ImFontAtlas::Build() stbtt_aligned_quad q; float dummy_x = 0.0f, dummy_y = 0.0f; - stbtt_GetPackedQuad(range.chardata_for_range, TexWidth, TexHeight, char_idx, &dummy_x, &dummy_y, &q, 0); + stbtt_GetPackedQuad(range.chardata_for_range, atlas->TexWidth, atlas->TexHeight, char_idx, &dummy_x, &dummy_y, &q, 0); dst_font->Glyphs.resize(dst_font->Glyphs.Size + 1); ImFont::Glyph& glyph = dst_font->Glyphs.back(); @@ -1514,7 +1520,7 @@ bool ImFontAtlas::Build() if (cfg.PixelSnapH) glyph.XAdvance = (float)(int)(glyph.XAdvance + 0.5f); - dst_font->MetricsTotalSurface += (int)((glyph.U1 - glyph.U0) * TexWidth + 1.99f) * (int)((glyph.V1 - glyph.V0) * TexHeight + 1.99f); // +1 to account for average padding, +0.99 to round + dst_font->MetricsTotalSurface += (int)((glyph.U1 - glyph.U0) * atlas->TexWidth + 1.99f) * (int)((glyph.V1 - glyph.V0) * atlas->TexHeight + 1.99f); // +1 to account for average padding, +0.99 to round } } cfg.DstFont->BuildLookupTable(); @@ -1526,7 +1532,7 @@ bool ImFontAtlas::Build() ImGui::MemFree(tmp_array); // Render into our custom data block - ImFontAtlasBuildRenderDefaultTexData(this); + ImFontAtlasBuildRenderDefaultTexData(atlas); return true; } diff --git a/imgui_internal.h b/imgui_internal.h index 09f696282..31ae2613c 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -793,6 +793,7 @@ namespace ImGui } // namespace ImGui // ImFontAtlas internals +IMGUI_API bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas); IMGUI_API void ImFontAtlasBuildRegisterDefaultCustomRects(ImFontAtlas* atlas); IMGUI_API void ImFontAtlasBuildSetupFont(ImFontAtlas* atlas, ImFont* font, ImFontConfig* font_config, float ascent, float descent); IMGUI_API void ImFontAtlasBuildPackCustomRects(ImFontAtlas* atlas, void* spc); From 3b11e73333e5e2356a454d4c661d4776fc6770d5 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 20 Aug 2017 15:17:37 +0800 Subject: [PATCH 247/921] Examples: gitignore added patterns for modern MSVC versions --- examples/.gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/.gitignore b/examples/.gitignore index 4a3d57c08..9516dc7f6 100644 --- a/examples/.gitignore +++ b/examples/.gitignore @@ -42,6 +42,8 @@ sdl_opengl3_example/x64/* *.exe *.pdb *.ilk +*.VC.db +*.VC.VC.opendb ## Ini files imgui.ini From 91d841dd5f0d5f5c7452f20f353539f2b3cb9efa Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 20 Aug 2017 15:28:12 +0800 Subject: [PATCH 248/921] Added PushStyleColor(ImGuiCol idx, ImU32 col) overload. (Which _might_ cause an "ambiguous call" compilation error if you are using ImColor() with implicit cast. Cast to ImU32 or ImVec4 explicily to fix.) --- imgui.cpp | 12 ++++++++++++ imgui.h | 7 ++++--- imgui_demo.cpp | 20 ++++++++++---------- 3 files changed, 26 insertions(+), 13 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 5a935aac7..c3721cdfb 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -204,6 +204,7 @@ Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. Also read releases logs https://github.com/ocornut/imgui/releases for more details. + - 2016/08/20 (1.51) - added PushStyleColor(ImGuiCol idx, ImU32 col) overload, which _might_ cause an "ambiguous call" compilation error if you are using ImColor() with implicit cast. Cast to ImU32 or ImVec4 explicily to fix. - 2017/08/15 (1.51) - marked the weird IMGUI_ONCE_UPON_A_FRAME helper macro as obsolete. prefer using the more explicit ImGuiOnceUponAFrame. - 2017/08/15 (1.51) - changed parameter order for BeginPopupContextWindow(), note that most uses relied on default parameters completely. - 2017/08/13 (1.51) - renamed ImGuiCol_Columns_*** to ImGuiCol_Separator_*** @@ -4712,6 +4713,17 @@ void ImGui::PopTextWrapPos() window->DC.TextWrapPos = window->DC.TextWrapPosStack.empty() ? -1.0f : window->DC.TextWrapPosStack.back(); } +// FIXME: This may incur a round-trip (if the end user got their data from a float4) but eventually we aim to store the in-flight colors as ImU32 +void ImGui::PushStyleColor(ImGuiCol idx, ImU32 col) +{ + ImGuiContext& g = *GImGui; + ImGuiColMod backup; + backup.Col = idx; + backup.BackupValue = g.Style.Colors[idx]; + g.ColorModifiers.push_back(backup); + g.Style.Colors[idx] = ColorConvertU32ToFloat4(col); +} + void ImGui::PushStyleColor(ImGuiCol idx, const ImVec4& col) { ImGuiContext& g = *GImGui; diff --git a/imgui.h b/imgui.h index 19f01c85f..1c36d89f4 100644 --- a/imgui.h +++ b/imgui.h @@ -180,6 +180,7 @@ namespace ImGui // Parameters stacks (shared) IMGUI_API void PushFont(ImFont* font); // use NULL as a shortcut to push default font IMGUI_API void PopFont(); + IMGUI_API void PushStyleColor(ImGuiCol idx, ImU32 col); IMGUI_API void PushStyleColor(ImGuiCol idx, const ImVec4& col); IMGUI_API void PopStyleColor(int count = 1); IMGUI_API void PushStyleVar(ImGuiStyleVar idx, float val); @@ -1095,8 +1096,8 @@ struct ImGuiSizeConstraintCallbackData // ImColor() helper to implicity converts colors to either ImU32 (packed 4x1 byte) or ImVec4 (4x1 float) // Prefer using IM_COL32() macros if you want a guaranteed compile-time ImU32 for usage with ImDrawList API. -// **Avoid storing ImColor! Store either u32 of ImVec4. This is not a full-featured color class. -// **None of the ImGui API are using ImColor directly but you can use it as a convenience to pass colors in either ImU32 or ImVec4 formats. +// **Avoid storing ImColor! Store either u32 of ImVec4. This is not a full-featured color class. MAY OBSOLETE. +// **None of the ImGui API are using ImColor directly but you can use it as a convenience to pass colors in either ImU32 or ImVec4 formats. Explicitly cast to ImU32 or ImVec4 if needed. struct ImColor { ImVec4 Value; @@ -1109,8 +1110,8 @@ struct ImColor inline operator ImU32() const { return ImGui::ColorConvertFloat4ToU32(Value); } inline operator ImVec4() const { return Value; } + // FIXME-OBSOLETE: May need to obsolete/cleanup those helpers. inline void SetHSV(float h, float s, float v, float a = 1.0f){ ImGui::ColorConvertHSVtoRGB(h, s, v, Value.x, Value.y, Value.z); Value.w = a; } - static ImColor HSV(float h, float s, float v, float a = 1.0f) { float r,g,b; ImGui::ColorConvertHSVtoRGB(h, s, v, r, g, b); return ImColor(r,g,b,a); } }; diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 78e527f7a..70ac68133 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -285,9 +285,9 @@ void ImGui::ShowTestWindow(bool* p_open) { if (i > 0) ImGui::SameLine(); ImGui::PushID(i); - ImGui::PushStyleColor(ImGuiCol_Button, ImColor::HSV(i/7.0f, 0.6f, 0.6f)); - ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImColor::HSV(i/7.0f, 0.7f, 0.7f)); - ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImColor::HSV(i/7.0f, 0.8f, 0.8f)); + ImGui::PushStyleColor(ImGuiCol_Button, (ImVec4)ImColor::HSV(i/7.0f, 0.6f, 0.6f)); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, (ImVec4)ImColor::HSV(i/7.0f, 0.7f, 0.7f)); + ImGui::PushStyleColor(ImGuiCol_ButtonActive, (ImVec4)ImColor::HSV(i/7.0f, 0.8f, 0.8f)); ImGui::Button("Click"); ImGui::PopStyleColor(3); ImGui::PopID(); @@ -913,10 +913,10 @@ void ImGui::ShowTestWindow(bool* p_open) { if (i > 0) ImGui::SameLine(); ImGui::PushID(i); - ImGui::PushStyleColor(ImGuiCol_FrameBg, ImColor::HSV(i/7.0f, 0.5f, 0.5f)); - ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, ImColor::HSV(i/7.0f, 0.6f, 0.5f)); - ImGui::PushStyleColor(ImGuiCol_FrameBgActive, ImColor::HSV(i/7.0f, 0.7f, 0.5f)); - ImGui::PushStyleColor(ImGuiCol_SliderGrab, ImColor::HSV(i/7.0f, 0.9f, 0.9f)); + ImGui::PushStyleColor(ImGuiCol_FrameBg, (ImVec4)ImColor::HSV(i/7.0f, 0.5f, 0.5f)); + ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, (ImVec4)ImColor::HSV(i/7.0f, 0.6f, 0.5f)); + ImGui::PushStyleColor(ImGuiCol_FrameBgActive, (ImVec4)ImColor::HSV(i/7.0f, 0.7f, 0.5f)); + ImGui::PushStyleColor(ImGuiCol_SliderGrab, (ImVec4)ImColor::HSV(i/7.0f, 0.9f, 0.9f)); ImGui::VSliderFloat("##v", ImVec2(18,160), &values[i], 0.0f, 1.0f, ""); if (ImGui::IsItemActive() || ImGui::IsItemHovered()) ImGui::SetTooltip("%.3f", values[i]); @@ -1271,9 +1271,9 @@ void ImGui::ShowTestWindow(bool* p_open) char num_buf[16]; const char* label = (!(n%15)) ? "FizzBuzz" : (!(n%3)) ? "Fizz" : (!(n%5)) ? "Buzz" : (sprintf(num_buf, "%d", n), num_buf); float hue = n*0.05f; - ImGui::PushStyleColor(ImGuiCol_Button, ImColor::HSV(hue, 0.6f, 0.6f)); - ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImColor::HSV(hue, 0.7f, 0.7f)); - ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImColor::HSV(hue, 0.8f, 0.8f)); + ImGui::PushStyleColor(ImGuiCol_Button, (ImVec4)ImColor::HSV(hue, 0.6f, 0.6f)); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, (ImVec4)ImColor::HSV(hue, 0.7f, 0.7f)); + ImGui::PushStyleColor(ImGuiCol_ButtonActive, (ImVec4)ImColor::HSV(hue, 0.8f, 0.8f)); ImGui::Button(label, ImVec2(40.0f + sinf((float)(line + n)) * 20.0f, 0.0f)); ImGui::PopStyleColor(3); ImGui::PopID(); From 1065a7b95b6ca4e0b69ca83fe56b4f729ad7320f Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 20 Aug 2017 15:38:05 +0800 Subject: [PATCH 249/921] ImFontAtlas::AddFontDefault: Made it possible to override size (even if it isn't really recommended) --- imgui_draw.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index bacbd7f5d..85ef6a927 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1253,9 +1253,10 @@ ImFont* ImFontAtlas::AddFontDefault(const ImFontConfig* font_cfg_template) font_cfg.PixelSnapH = true; } if (font_cfg.Name[0] == '\0') strcpy(font_cfg.Name, "ProggyClean.ttf, 13px"); + if (font_cfg.SizePixels <= 0.0f) font_cfg.SizePixels = 13.0f; const char* ttf_compressed_base85 = GetDefaultCompressedFontDataTTFBase85(); - ImFont* font = AddFontFromMemoryCompressedBase85TTF(ttf_compressed_base85, 13.0f, &font_cfg, GetGlyphRangesDefault()); + ImFont* font = AddFontFromMemoryCompressedBase85TTF(ttf_compressed_base85, font_cfg.SizePixels, &font_cfg, GetGlyphRangesDefault()); return font; } From fd394e1e95474bb658c48086ac7edf0719aa7c7e Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 20 Aug 2017 16:39:11 +0800 Subject: [PATCH 250/921] Scrollbar: Comments. Fixed potential div-by-zero error which I can repro now, so added an assert to notify us if it's actually ever useful or not. --- imgui.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index c3721cdfb..ab4ad2b80 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4490,15 +4490,17 @@ static void Scrollbar(ImGuiWindow* window, bool horizontal) window->DrawList->AddRectFilled(bb.Min, bb.Max, ImGui::GetColorU32(ImGuiCol_ScrollbarBg), window_rounding, window_rounding_corners); bb.Reduce(ImVec2(ImClamp((float)(int)((bb.Max.x - bb.Min.x - 2.0f) * 0.5f), 0.0f, 3.0f), ImClamp((float)(int)((bb.Max.y - bb.Min.y - 2.0f) * 0.5f), 0.0f, 3.0f))); - // V denote the main axis of the scrollbar + // V denote the main, longer axis of the scrollbar (= height for a vertical scrollbar) float scrollbar_size_v = horizontal ? bb.GetWidth() : bb.GetHeight(); float scroll_v = horizontal ? window->Scroll.x : window->Scroll.y; float win_size_avail_v = (horizontal ? window->SizeFull.x : window->SizeFull.y) - other_scrollbar_size_w; float win_size_contents_v = horizontal ? window->SizeContents.x : window->SizeContents.y; - // The grabbable box size generally represent the amount visible (vs the total scrollable amount) + // Calculate the height of our grabbable box. It generally represent the amount visible (vs the total scrollable amount) // But we maintain a minimum size in pixel to allow for the user to still aim inside. - const float grab_h_pixels = ImMin(ImMax(scrollbar_size_v * ImSaturate(win_size_avail_v / ImMax(win_size_contents_v, win_size_avail_v)), style.GrabMinSize), scrollbar_size_v); + IM_ASSERT(ImMax(win_size_contents_v, win_size_avail_v) > 0.0f); // Adding this assert to check if the ImMax(XXX,1.0f) is still needed. PLEASE CONTACT ME if this triggers. + const float win_size_v = ImMax(ImMax(win_size_contents_v, win_size_avail_v), 1.0f); + const float grab_h_pixels = ImClamp(scrollbar_size_v * (win_size_avail_v / win_size_v), style.GrabMinSize, scrollbar_size_v); const float grab_h_norm = grab_h_pixels / scrollbar_size_v; // Handle input right away. None of the code of Begin() is relying on scrolling position before calling Scrollbar(). From cf84650ee8443a56ff02d044879a83a3feeca9ff Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 20 Aug 2017 16:39:43 +0800 Subject: [PATCH 251/921] GCC warnings fixes --- imgui.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/imgui.cpp b/imgui.cpp index ab4ad2b80..982624694 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -577,6 +577,8 @@ #pragma GCC diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function #pragma GCC diagnostic ignored "-Wconversion" // warning: conversion to 'xxxx' from 'xxxx' may alter its value #pragma GCC diagnostic ignored "-Wcast-qual" // warning: cast from type 'xxxx' to type 'xxxx' casts away qualifiers +#pragma GCC diagnostic ignored "-Wformat-nonliteral" // warning: format not a string literal, format string not checked +#pragma GCC diagnostic ignored "-Wsuggest-attribute=format" #endif //------------------------------------------------------------------------- From af2db53780d45da88c3a1e9b1ae8f36ce67a954a Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 20 Aug 2017 17:50:25 +0800 Subject: [PATCH 252/921] Added GetStyleColorVec4() --- imgui.cpp | 6 ++++++ imgui.h | 1 + 2 files changed, 7 insertions(+) diff --git a/imgui.cpp b/imgui.cpp index 982624694..ca38cc8ea 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1212,6 +1212,12 @@ ImU32 ImGui::GetColorU32(const ImVec4& col) return ColorConvertFloat4ToU32(c); } +const ImVec4& ImGui::GetStyleColorVec4(ImGuiCol idx) +{ + ImGuiStyle& style = GImGui->Style; + return style.Colors[idx]; +} + ImU32 ImGui::GetColorU32(ImU32 col) { float style_alpha = GImGui->Style.Alpha; diff --git a/imgui.h b/imgui.h index 1c36d89f4..de4a913f4 100644 --- a/imgui.h +++ b/imgui.h @@ -186,6 +186,7 @@ namespace ImGui IMGUI_API void PushStyleVar(ImGuiStyleVar idx, float val); IMGUI_API void PushStyleVar(ImGuiStyleVar idx, const ImVec2& val); IMGUI_API void PopStyleVar(int count = 1); + IMGUI_API const ImVec4& GetStyleColorVec4(ImGuiCol idx); // retrieve style color as stored in ImGuiStyle structure. use to feed back into PushStyleColor(), otherwhise use GetColorU32() to get style color + style alpha. IMGUI_API ImFont* GetFont(); // get current font IMGUI_API float GetFontSize(); // get current font size (= height in pixels) of current font with current scale applied IMGUI_API ImVec2 GetFontTexUvWhitePixel(); // get UV coordinate for a while pixel, useful to draw custom shapes via the ImDrawList API From b4eeb4aa8d5a102daf9bf8a5f6ce9b5cb1fdd33f Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 20 Aug 2017 17:53:09 +0800 Subject: [PATCH 253/921] Renamed GetStyleColName() to GetStyleColorName() for consistency. Extra comments in Api Breaking Changes section. --- imgui.cpp | 5 +++-- imgui.h | 2 +- imgui_demo.cpp | 6 +++--- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index ca38cc8ea..b21228275 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -204,9 +204,10 @@ Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. Also read releases logs https://github.com/ocornut/imgui/releases for more details. + - 2016/08/20 (1.51) - renamed GetStyleColName() to GetStyleColorName() for consistency. - 2016/08/20 (1.51) - added PushStyleColor(ImGuiCol idx, ImU32 col) overload, which _might_ cause an "ambiguous call" compilation error if you are using ImColor() with implicit cast. Cast to ImU32 or ImVec4 explicily to fix. - 2017/08/15 (1.51) - marked the weird IMGUI_ONCE_UPON_A_FRAME helper macro as obsolete. prefer using the more explicit ImGuiOnceUponAFrame. - - 2017/08/15 (1.51) - changed parameter order for BeginPopupContextWindow(), note that most uses relied on default parameters completely. + - 2017/08/15 (1.51) - changed parameter order for BeginPopupContextWindow() from (const char*,int buttons,bool also_over_items) to (const char*,int buttons,bool also_over_items). Note that most calls relied on default parameters completely. - 2017/08/13 (1.51) - renamed ImGuiCol_Columns_*** to ImGuiCol_Separator_*** - 2017/08/11 (1.51) - renamed ImGuiSetCond_*** types and flags to ImGuiCond_***. Kept redirection enums (will obsolete). - 2017/08/09 (1.51) - removed ValueColor() helpers, they are equivalent to calling Text(label) + SameLine() + ColorButton(). @@ -4826,7 +4827,7 @@ void ImGui::PopStyleVar(int count) } } -const char* ImGui::GetStyleColName(ImGuiCol idx) +const char* ImGui::GetStyleColorName(ImGuiCol idx) { // Create switch-case from enum with regexp: ImGuiCol_{.*}, --> case ImGuiCol_\1: return "\1"; switch (idx) diff --git a/imgui.h b/imgui.h index de4a913f4..5c8737c22 100644 --- a/imgui.h +++ b/imgui.h @@ -426,7 +426,7 @@ namespace ImGui IMGUI_API bool IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max); // test if rectangle (in screen space) is visible / not clipped. to perform coarse clipping on user's side. IMGUI_API float GetTime(); IMGUI_API int GetFrameCount(); - IMGUI_API const char* GetStyleColName(ImGuiCol idx); + IMGUI_API const char* GetStyleColorName(ImGuiCol idx); IMGUI_API ImVec2 CalcItemRectClosestPoint(const ImVec2& pos, bool on_edge = false, float outward = +0.0f); // utility to find the closest point the last item bounding rectangle edge. useful to visually link items IMGUI_API ImVec2 CalcTextSize(const char* text, const char* text_end = NULL, bool hide_text_after_double_hash = false, float wrap_width = -1.0f); IMGUI_API void CalcListClipping(int items_count, float items_height, int* out_items_display_start, int* out_items_display_end); // calculate coarse clipping for large list of evenly sized items. Prefer using the ImGuiListClipper higher-level helper if you can. diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 70ac68133..4b901acfc 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1831,7 +1831,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) for (int i = 0; i < ImGuiCol_COUNT; i++) { const ImVec4& col = style.Colors[i]; - const char* name = ImGui::GetStyleColName(i); + const char* name = ImGui::GetStyleColorName(i); if (!output_only_modified || memcmp(&col, (ref ? &ref->Colors[i] : &default_style.Colors[i]), sizeof(ImVec4)) != 0) ImGui::LogText("style.Colors[ImGuiCol_%s]%*s= ImVec4(%.2ff, %.2ff, %.2ff, %.2ff);" IM_NEWLINE, name, 22 - (int)strlen(name), "", col.x, col.y, col.z, col.w); } @@ -1854,7 +1854,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) ImGui::PushItemWidth(-160); for (int i = 0; i < ImGuiCol_COUNT; i++) { - const char* name = ImGui::GetStyleColName(i); + const char* name = ImGui::GetStyleColorName(i); if (!filter.PassFilter(name)) continue; ImGui::PushID(i); @@ -2028,7 +2028,7 @@ static void ShowExampleMenuFile() if (ImGui::BeginMenu("Colors")) { for (int i = 0; i < ImGuiCol_COUNT; i++) - ImGui::MenuItem(ImGui::GetStyleColName((ImGuiCol)i)); + ImGui::MenuItem(ImGui::GetStyleColorName((ImGuiCol)i)); ImGui::EndMenu(); } if (ImGui::BeginMenu("Disabled", false)) // Disabled From 19a42cb2fd864291419250e8c258a94761d620f2 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 20 Aug 2017 18:44:48 +0800 Subject: [PATCH 254/921] Columns: Moved BeginColumns/EndColumns/flags from #913 to imgui_internals.h + minor shallow tweaks. Removed demo code temporarily. (#125) --- imgui.cpp | 26 ++++++++++++-------------- imgui.h | 15 ++------------- imgui_demo.cpp | 43 ------------------------------------------- imgui_internal.h | 14 +++++++++++++- 4 files changed, 27 insertions(+), 71 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 8e774ab69..fbaf08013 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9928,15 +9928,13 @@ int ImGui::GetColumnsCount() return window->DC.ColumnsCount; } -static float OffsetNormToPixels(float offsetNorm) +static float OffsetNormToPixels(ImGuiWindow* window, float offset_norm) { - ImGuiWindow* window = ImGui::GetCurrentWindowRead(); - return offsetNorm * (window->DC.ColumnsMaxX - window->DC.ColumnsMinX); + return offset_norm * (window->DC.ColumnsMaxX - window->DC.ColumnsMinX); } -static float PixelsToOffsetNorm(float offset) +static float PixelsToOffsetNorm(ImGuiWindow* window, float offset) { - ImGuiWindow* window = ImGui::GetCurrentWindowRead(); return (offset - window->DC.ColumnsMinX) / (window->DC.ColumnsMaxX - window->DC.ColumnsMinX); } @@ -9986,18 +9984,18 @@ void ImGui::SetColumnOffset(int column_index, float offset) IM_ASSERT(column_index < window->DC.ColumnsData.Size); - const bool preserveWidth = !(window->DC.ColumnsFlags & ImGuiColumnsFlags_NoPreserveWidths) && (column_index < window->DC.ColumnsCount-1); - const float width = preserveWidth ? GetColumnWidth(column_index) : 0.0f; + const bool preserve_width = !(window->DC.ColumnsFlags & ImGuiColumnsFlags_NoPreserveWidths) && (column_index < window->DC.ColumnsCount-1); + const float width = preserve_width ? GetColumnWidth(column_index) : 0.0f; if (!(window->DC.ColumnsFlags & ImGuiColumnsFlags_NoForceWithinWindow)) offset = ImMin((float)(int)offset, window->DC.ColumnsMaxX - g.Style.ColumnsMinSpacing * (window->DC.ColumnsCount - column_index)); - const float offsetNorm = PixelsToOffsetNorm(offset); + const float offset_norm = PixelsToOffsetNorm(window, offset); const ImGuiID column_id = window->DC.ColumnsSetId + ImGuiID(column_index); - window->DC.StateStorage->SetFloat(column_id, offsetNorm); - window->DC.ColumnsData[column_index].OffsetNorm = offsetNorm; + window->DC.StateStorage->SetFloat(column_id, offset_norm); + window->DC.ColumnsData[column_index].OffsetNorm = offset_norm; - if (preserveWidth) + if (preserve_width) SetColumnOffset(column_index+1, offset + ImMax(g.Style.ColumnsMinSpacing, width)); } @@ -10007,7 +10005,7 @@ float ImGui::GetColumnWidth(int column_index) if (column_index < 0) column_index = window->DC.ColumnsCurrent; - return OffsetNormToPixels(window->DC.ColumnsData[column_index+1].OffsetNorm - window->DC.ColumnsData[column_index].OffsetNorm); + return OffsetNormToPixels(window, window->DC.ColumnsData[column_index+1].OffsetNorm - window->DC.ColumnsData[column_index].OffsetNorm); } void ImGui::SetColumnWidth(int column_index, float width) @@ -10066,7 +10064,7 @@ void ImGui::BeginColumns(const char* id, int columns_count, ImGuiColumnsFlags fl const float default_t = column_index / (float)window->DC.ColumnsCount; float t = window->DC.StateStorage->GetFloat(column_id, default_t); // Cheaply store our floating point value inside the integer (could store a union into the map?) if (!(window->DC.ColumnsFlags & ImGuiColumnsFlags_NoForceWithinWindow)) - t = ImMin(t, PixelsToOffsetNorm(window->DC.ColumnsMaxX - g.Style.ColumnsMinSpacing * (window->DC.ColumnsCount - column_index))); + t = ImMin(t, PixelsToOffsetNorm(window, window->DC.ColumnsMaxX - g.Style.ColumnsMinSpacing * (window->DC.ColumnsCount - column_index))); window->DC.ColumnsData[column_index].OffsetNorm = t; } window->DrawList->ChannelsSplit(window->DC.ColumnsCount); @@ -10098,7 +10096,7 @@ void ImGui::EndColumns() { float x = window->Pos.x + GetColumnOffset(i); const ImGuiID column_id = window->DC.ColumnsSetId + ImGuiID(i); - const float column_w = 4.0f; + const float column_w = 4.0f; // Width for interaction const ImRect column_rect(ImVec2(x - column_w, y1), ImVec2(x + column_w, y2)); if (IsClippedEx(column_rect, &column_id, false)) continue; diff --git a/imgui.h b/imgui.h index 8c6687a29..4fc0a9f98 100644 --- a/imgui.h +++ b/imgui.h @@ -231,9 +231,8 @@ namespace ImGui IMGUI_API float GetItemsLineHeightWithSpacing(); // distance (in pixels) between 2 consecutive lines of standard height widgets == GetWindowFontSize() + GetStyle().FramePadding.y*2 + GetStyle().ItemSpacing.y // Columns - // You can also use SameLine(pos_x) for simplified columning. The columns API is still work-in-progress and rather lacking. - IMGUI_API void BeginColumns(const char* id, int count, ImGuiColumnsFlags flags = 0); // setup number of columns. use an identifier to distinguish multiple column sets. close with EndColumns(). - IMGUI_API void EndColumns(); // close columns + // You can also use SameLine(pos_x) for simplified columns. The columns API is still work-in-progress and rather lacking. + IMGUI_API void Columns(int count = 1, const char* id = NULL, bool border = true); IMGUI_API void NextColumn(); // next column, defaults to current row or next row if the current row is finished IMGUI_API int GetColumnIndex(); // get current column index IMGUI_API float GetColumnWidth(int column_index = -1); // get column width (in pixels). pass -1 to use current column @@ -241,7 +240,6 @@ namespace ImGui IMGUI_API float GetColumnOffset(int column_index = -1); // get position of column line (in pixels, from the left side of the contents region). pass -1 to use current column, otherwise 0..GetColumnsCount() inclusive. column 0 is usually 0.0f and not resizable unless you call this IMGUI_API void SetColumnOffset(int column_index, float offset_x); // set position of column line (in pixels, from the left side of the contents region). pass -1 to use current column IMGUI_API int GetColumnsCount(); - IMGUI_API void Columns(int count = 1, const char* id = NULL, bool border = true); // ID scopes // If you are creating widgets in a loop you most likely want to push a unique identifier so ImGui can differentiate them. @@ -524,15 +522,6 @@ enum ImGuiWindowFlags_ ImGuiWindowFlags_ChildMenu = 1 << 27 // Don't use! For internal use by BeginMenu() }; -// Flags for ImGui::Columns() -enum ImGuiColumnsFlags_ -{ - // Default: 0 - ImGuiColumnsFlags_NoBorder = 1 << 0, // Disable column dividers - ImGuiColumnsFlags_NoPreserveWidths = 1 << 1, // Disable column width preservation when adjusting columns - ImGuiColumnsFlags_NoForceWithinWindow = 1 << 2 // Disable forcing columns to fit within window -}; - // Flags for ImGui::InputText() enum ImGuiInputTextFlags_ { diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 862e55333..4b901acfc 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1553,49 +1553,6 @@ void ImGui::ShowTestWindow(bool* p_open) } */ - if (ImGui::TreeNode("Advanced settings")) - { - static bool border = true; - static bool preserveWidths = true; - static bool forceWithinWindow = true; - - ImGui::Checkbox("Border", &border); - ImGui::SameLine(); - ImGui::Checkbox("Preserve widths", &preserveWidths); - ImGui::SameLine(); - ImGui::Checkbox("Force within window", &forceWithinWindow); - - ImGuiColumnsFlags flags = 0; - flags |= (border ? 0 : ImGuiColumnsFlags_NoBorder); - flags |= (preserveWidths ? 0 : ImGuiColumnsFlags_NoPreserveWidths); - flags |= (forceWithinWindow ? 0 : ImGuiColumnsFlags_NoForceWithinWindow); - - ImGui::BeginColumns("AdvancedColumns", 4, flags); - ImGui::Separator(); - ImGui::Text("ID"); ImGui::NextColumn(); - ImGui::Text("Name"); ImGui::NextColumn(); - ImGui::Text("Path"); ImGui::NextColumn(); - ImGui::Text("Flags"); ImGui::NextColumn(); - ImGui::Separator(); - const char* names[3] = { "One", "Two", "Three" }; - const char* paths[3] = { "/path/one", "/path/two", "/path/three" }; - static int selected = -1; - for (int i = 0; i < 3; i++) - { - char label[32]; - sprintf(label, "%04d", i); - if (ImGui::Selectable(label, selected == i, ImGuiSelectableFlags_SpanAllColumns)) - selected = i; - ImGui::NextColumn(); - ImGui::Text(names[i]); ImGui::NextColumn(); - ImGui::Text(paths[i]); ImGui::NextColumn(); - ImGui::Text("...."); ImGui::NextColumn(); - } - ImGui::EndColumns(); - ImGui::Separator(); - ImGui::TreePop(); - } - // Create multiple items in a same cell before switching to next column if (ImGui::TreeNode("Mixed items")) { diff --git a/imgui_internal.h b/imgui_internal.h index e83ebbe5d..7d7f3fa87 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -183,6 +183,14 @@ enum ImGuiSliderFlags_ ImGuiSliderFlags_Vertical = 1 << 0 }; +enum ImGuiColumnsFlags_ +{ + // Default: 0 + ImGuiColumnsFlags_NoBorder = 1 << 0, // Disable column dividers + ImGuiColumnsFlags_NoPreserveWidths = 1 << 1, // Disable column width preservation when adjusting columns + ImGuiColumnsFlags_NoForceWithinWindow = 1 << 2 // Disable forcing columns to fit within window +}; + enum ImGuiSelectableFlagsPrivate_ { // NB: need to be in sync with last value of ImGuiSelectableFlags_ @@ -598,7 +606,7 @@ struct IMGUI_API ImGuiDrawContext float ColumnsStartPosY; float ColumnsCellMinY; float ColumnsCellMaxY; - ImGuiColumnsFlags ColumnsFlags; + ImGuiColumnsFlags ColumnsFlags; ImGuiID ColumnsSetId; ImVector ColumnsData; @@ -748,6 +756,10 @@ namespace ImGui IMGUI_API void OpenPopupEx(ImGuiID id, bool reopen_existing); IMGUI_API bool IsPopupOpen(ImGuiID id); + // New Columns API + IMGUI_API void BeginColumns(const char* id, int count, ImGuiColumnsFlags flags = 0); // setup number of columns. use an identifier to distinguish multiple column sets. close with EndColumns(). + IMGUI_API void EndColumns(); // close columns + // NB: All position are in absolute pixels coordinates (never using window coordinates internally) // AVOID USING OUTSIDE OF IMGUI.CPP! NOT FOR PUBLIC CONSUMPTION. THOSE FUNCTIONS ARE A MESS. THEIR SIGNATURE AND BEHAVIOR WILL CHANGE, THEY NEED TO BE REFACTORED INTO SOMETHING DECENT. IMGUI_API void RenderText(ImVec2 pos, const char* text, const char* text_end = NULL, bool hide_text_after_hash = true); From 3bf2af23e641909890a568850e5dac8ebf8930f8 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 20 Aug 2017 18:44:54 +0800 Subject: [PATCH 255/921] Columns: Fixed EndColumns() not repositioning the cursor. (#913) --- imgui.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/imgui.cpp b/imgui.cpp index fbaf08013..0837b93dd 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -10126,6 +10126,8 @@ void ImGui::EndColumns() window->DC.ColumnsCount = 1; window->DC.ColumnsFlags = 0; window->DC.ColumnsData.resize(0); + window->DC.ColumnsOffsetX = 0.0f; + window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.IndentX + window->DC.ColumnsOffsetX); } // [2017/08: This is currently the only public API, while we are working on making BeginColumns/EndColumns user-facing] From a511b00226c31654b4cf99e027d6d51baf19d710 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 20 Aug 2017 19:19:31 +0800 Subject: [PATCH 256/921] Columns: Fixed offset rounding leading to SetColumnOffset() being destructive when ImGuiColumnsFlags_NoPreserveWidths flag is not set. (#913, #125) --- imgui.cpp | 6 +++--- imgui.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 0837b93dd..08d63a8f5 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9952,7 +9952,7 @@ static float GetDraggedColumnOffset(int column_index) if ((window->DC.ColumnsFlags & ImGuiColumnsFlags_NoPreserveWidths)) x = ImMin(x, ImGui::GetColumnOffset(column_index+1) - g.Style.ColumnsMinSpacing); - return (float)(int)x; + return x; } float ImGui::GetColumnOffset(int column_index) @@ -9972,7 +9972,7 @@ float ImGui::GetColumnOffset(int column_index) IM_ASSERT(column_index < window->DC.ColumnsData.Size); const float t = window->DC.ColumnsData[column_index].OffsetNorm; const float x_offset = ImLerp(window->DC.ColumnsMinX, window->DC.ColumnsMaxX, t); - return (float)(int)x_offset; + return x_offset; } void ImGui::SetColumnOffset(int column_index, float offset) @@ -9988,7 +9988,7 @@ void ImGui::SetColumnOffset(int column_index, float offset) const float width = preserve_width ? GetColumnWidth(column_index) : 0.0f; if (!(window->DC.ColumnsFlags & ImGuiColumnsFlags_NoForceWithinWindow)) - offset = ImMin((float)(int)offset, window->DC.ColumnsMaxX - g.Style.ColumnsMinSpacing * (window->DC.ColumnsCount - column_index)); + offset = ImMin(offset, window->DC.ColumnsMaxX - g.Style.ColumnsMinSpacing * (window->DC.ColumnsCount - column_index)); const float offset_norm = PixelsToOffsetNorm(window, offset); const ImGuiID column_id = window->DC.ColumnsSetId + ImGuiID(column_index); diff --git a/imgui.h b/imgui.h index 4fc0a9f98..7c102f7d5 100644 --- a/imgui.h +++ b/imgui.h @@ -237,7 +237,7 @@ namespace ImGui IMGUI_API int GetColumnIndex(); // get current column index IMGUI_API float GetColumnWidth(int column_index = -1); // get column width (in pixels). pass -1 to use current column IMGUI_API void SetColumnWidth(int column_index, float width); // set column width (in pixels). pass -1 to use current column - IMGUI_API float GetColumnOffset(int column_index = -1); // get position of column line (in pixels, from the left side of the contents region). pass -1 to use current column, otherwise 0..GetColumnsCount() inclusive. column 0 is usually 0.0f and not resizable unless you call this + IMGUI_API float GetColumnOffset(int column_index = -1); // get position of column line (in pixels, from the left side of the contents region). pass -1 to use current column, otherwise 0..GetColumnsCount() inclusive. column 0 is typically 0.0f IMGUI_API void SetColumnOffset(int column_index, float offset_x); // set position of column line (in pixels, from the left side of the contents region). pass -1 to use current column IMGUI_API int GetColumnsCount(); From 9307631c901aae10601dd669a98c9793064004fe Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 20 Aug 2017 19:25:29 +0800 Subject: [PATCH 257/921] Columns: Removed unnecessary/misleading dummy ItemSize(). Was fixed already before, and fixed again in this branch by 3bf2af23e641909890a568850e5dac8ebf8930f8. (#913, #125). End() calls EndColumns() directly. --- imgui.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 08d63a8f5..fb43a4e60 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4450,7 +4450,7 @@ void ImGui::End() ImGuiWindow* window = g.CurrentWindow; if (window->DC.ColumnsCount != 1) // close columns set if any is open - Columns(1, "#CLOSECOLUMNS"); + EndColumns(); PopClipRect(); // inner window clip rectangle // Stop logging @@ -10078,8 +10078,6 @@ void ImGui::EndColumns() ImGuiWindow* window = GetCurrentWindow(); IM_ASSERT(window->DC.ColumnsCount > 1); - if (window->DC.ColumnsCurrent != 0) - ItemSize(ImVec2(0, 0)); // Advance to column 0 PopItemWidth(); PopClipRect(); window->DrawList->ChannelsMerge(); From e70d49ba1f32b9a39550c32656468cb62f5bc964 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 20 Aug 2017 19:30:57 +0800 Subject: [PATCH 258/921] Columns: Fixed one form of shearing during resizing columns with PreserveWidth enabled (there's another issue still). (#913, #125) --- imgui.cpp | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index fb43a4e60..f32523cfe 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9996,7 +9996,7 @@ void ImGui::SetColumnOffset(int column_index, float offset) window->DC.ColumnsData[column_index].OffsetNorm = offset_norm; if (preserve_width) - SetColumnOffset(column_index+1, offset + ImMax(g.Style.ColumnsMinSpacing, width)); + SetColumnOffset(column_index + 1, offset + ImMax(g.Style.ColumnsMinSpacing, width)); } float ImGui::GetColumnWidth(int column_index) @@ -10090,6 +10090,7 @@ void ImGui::EndColumns() { const float y1 = window->DC.ColumnsStartPosY; const float y2 = window->DC.CursorPos.y; + int dragging_column = -1; for (int i = 1; i < window->DC.ColumnsCount; i++) { float x = window->Pos.x + GetColumnOffset(i); @@ -10098,25 +10099,28 @@ void ImGui::EndColumns() const ImRect column_rect(ImVec2(x - column_w, y1), ImVec2(x + column_w, y2)); if (IsClippedEx(column_rect, &column_id, false)) continue; - - bool hovered, held; + + bool hovered, held; ButtonBehavior(column_rect, column_id, &hovered, &held); if (hovered || held) g.MouseCursor = ImGuiMouseCursor_ResizeEW; + if (held && g.ActiveIdIsJustActivated) + g.ActiveIdClickOffset.x -= column_w; // Store from center of column line (we used a 8 wide rect for columns clicking). This is used by GetDraggedColumnOffset(). + if (held) + dragging_column = i; - // Draw before resize so our items positioning are in sync with the line being drawn - const ImU32 col = GetColorU32(held ? ImGuiCol_SeparatorActive : hovered ? ImGuiCol_SeparatorHovered : ImGuiCol_Separator); - const float xi = (float)(int)x; - window->DrawList->AddLine(ImVec2(xi, y1 + 1.0f), ImVec2(xi, y2), col); + // Draw column + const ImU32 col = GetColorU32(held ? ImGuiCol_SeparatorActive : hovered ? ImGuiCol_SeparatorHovered : ImGuiCol_Separator); + const float xi = (float)(int)x; + window->DrawList->AddLine(ImVec2(xi, y1 + 1.0f), ImVec2(xi, y2), col); + } - if (held) - { - if (g.ActiveIdIsJustActivated) - g.ActiveIdClickOffset.x -= column_w; // Store from center of column line (we used a 8 wide rect for columns clicking) - x = GetDraggedColumnOffset(i); - SetColumnOffset(i, x); - } - } + // Apply dragging after drawing the column lines, so our rendered lines are in sync with how items were displayed during the frame. + if (dragging_column != -1) + { + float x = GetDraggedColumnOffset(dragging_column); + SetColumnOffset(dragging_column, x); + } } window->DC.ColumnsSetId = 0; From 7f0063f85849ae51eb3d291426cfc3e9da1b1507 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 20 Aug 2017 19:32:18 +0800 Subject: [PATCH 259/921] Columns: Added ImGuiColumnsFlags_NoResize flag (internal). (#913, #125) --- imgui.cpp | 19 +++++++++++-------- imgui_internal.h | 5 +++-- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index f32523cfe..7c7a76369 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -10100,14 +10100,17 @@ void ImGui::EndColumns() if (IsClippedEx(column_rect, &column_id, false)) continue; - bool hovered, held; - ButtonBehavior(column_rect, column_id, &hovered, &held); - if (hovered || held) - g.MouseCursor = ImGuiMouseCursor_ResizeEW; - if (held && g.ActiveIdIsJustActivated) - g.ActiveIdClickOffset.x -= column_w; // Store from center of column line (we used a 8 wide rect for columns clicking). This is used by GetDraggedColumnOffset(). - if (held) - dragging_column = i; + bool hovered = false, held = false; + if (!(window->DC.ColumnsFlags & ImGuiColumnsFlags_NoResize)) + { + ButtonBehavior(column_rect, column_id, &hovered, &held); + if (hovered || held) + g.MouseCursor = ImGuiMouseCursor_ResizeEW; + if (held && g.ActiveIdIsJustActivated) + g.ActiveIdClickOffset.x -= column_w; // Store from center of column line (we used a 8 wide rect for columns clicking). This is used by GetDraggedColumnOffset(). + if (held) + dragging_column = i; + } // Draw column const ImU32 col = GetColorU32(held ? ImGuiCol_SeparatorActive : hovered ? ImGuiCol_SeparatorHovered : ImGuiCol_Separator); diff --git a/imgui_internal.h b/imgui_internal.h index 7d7f3fa87..f73cdcc88 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -187,8 +187,9 @@ enum ImGuiColumnsFlags_ { // Default: 0 ImGuiColumnsFlags_NoBorder = 1 << 0, // Disable column dividers - ImGuiColumnsFlags_NoPreserveWidths = 1 << 1, // Disable column width preservation when adjusting columns - ImGuiColumnsFlags_NoForceWithinWindow = 1 << 2 // Disable forcing columns to fit within window + ImGuiColumnsFlags_NoResize = 1 << 1, // Disable resizing columns when clicking on the dividers + ImGuiColumnsFlags_NoPreserveWidths = 1 << 2, // Disable column width preservation when adjusting columns + ImGuiColumnsFlags_NoForceWithinWindow = 1 << 3 // Disable forcing columns to fit within window }; enum ImGuiSelectableFlagsPrivate_ From 1c83b073c66341ea7b22d7dd42916094c9a0fdeb Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 20 Aug 2017 20:37:04 +0800 Subject: [PATCH 260/921] Columns: A set of column (and most importantly the right-most column) do not register its content to the parent, not affecting the window contents size. (#519, #125, #913) --- imgui.cpp | 3 +++ imgui_internal.h | 2 ++ 2 files changed, 5 insertions(+) diff --git a/imgui.cpp b/imgui.cpp index 7c7a76369..f20646e82 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4345,6 +4345,7 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us window->DC.ColumnsCurrent = 0; window->DC.ColumnsCount = 1; window->DC.ColumnsStartPosY = window->DC.CursorPos.y; + window->DC.ColumnsStartMaxPosX = window->DC.CursorMaxPos.x; window->DC.ColumnsCellMinY = window->DC.ColumnsCellMaxY = window->DC.ColumnsStartPosY; window->DC.TreeDepth = 0; window->DC.StateStorage = &window->StateStorage; @@ -10051,6 +10052,7 @@ void ImGui::BeginColumns(const char* id, int columns_count, ImGuiColumnsFlags fl window->DC.ColumnsMinX = window->DC.IndentX - g.Style.ItemSpacing.x; // Lock our horizontal range window->DC.ColumnsMaxX = content_region_width - window->Scroll.x - ((window->Flags & ImGuiWindowFlags_NoScrollbar) ? 0 : g.Style.ScrollbarSize);// - window->WindowPadding().x; window->DC.ColumnsStartPosY = window->DC.CursorPos.y; + window->DC.ColumnsStartMaxPosX = window->DC.CursorMaxPos.x; window->DC.ColumnsCellMinY = window->DC.ColumnsCellMaxY = window->DC.CursorPos.y; window->DC.ColumnsOffsetX = 0.0f; window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.IndentX + window->DC.ColumnsOffsetX); @@ -10084,6 +10086,7 @@ void ImGui::EndColumns() window->DC.ColumnsCellMaxY = ImMax(window->DC.ColumnsCellMaxY, window->DC.CursorPos.y); window->DC.CursorPos.y = window->DC.ColumnsCellMaxY; + window->DC.CursorMaxPos.x = ImMax(window->DC.ColumnsStartMaxPosX, window->DC.ColumnsMaxX); // Columns don't grow parent // Draw columns borders and handle resize if (!(window->DC.ColumnsFlags & ImGuiColumnsFlags_NoBorder) && !window->SkipItems) diff --git a/imgui_internal.h b/imgui_internal.h index f73cdcc88..d47c77025 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -605,6 +605,7 @@ struct IMGUI_API ImGuiDrawContext float ColumnsMinX; float ColumnsMaxX; float ColumnsStartPosY; + float ColumnsStartMaxPosX; // Backup of CursorMaxPos float ColumnsCellMinY; float ColumnsCellMaxY; ImGuiColumnsFlags ColumnsFlags; @@ -638,6 +639,7 @@ struct IMGUI_API ImGuiDrawContext ColumnsCount = 1; ColumnsMinX = ColumnsMaxX = 0.0f; ColumnsStartPosY = 0.0f; + ColumnsStartMaxPosX = 0.0f; ColumnsCellMinY = ColumnsCellMaxY = 0.0f; ColumnsFlags = 0; ColumnsSetId = 0; From 7ff1c149b5657ee83c9146b6a467040ca0bbe921 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 20 Aug 2017 20:40:25 +0800 Subject: [PATCH 261/921] Columns: Fixed another form of shearing made visible by the PreserveWidth option. The code was initially added in c46d5634d43c9f0296d845478c07b04f2c40d339 to fix because we've fixed in e42aaede42eb6d8a47cf104f3afd6057b13a61ee. (#913, #125) --- imgui.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index f20646e82..a7ff91224 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9958,17 +9958,19 @@ static float GetDraggedColumnOffset(int column_index) float ImGui::GetColumnOffset(int column_index) { - ImGuiContext& g = *GImGui; ImGuiWindow* window = GetCurrentWindowRead(); if (column_index < 0) column_index = window->DC.ColumnsCurrent; + /* if (g.ActiveId) { + ImGuiContext& g = *GImGui; const ImGuiID column_id = window->DC.ColumnsSetId + ImGuiID(column_index); if (g.ActiveId == column_id) return GetDraggedColumnOffset(column_index); } + */ IM_ASSERT(column_index < window->DC.ColumnsData.Size); const float t = window->DC.ColumnsData[column_index].OffsetNorm; @@ -10148,6 +10150,7 @@ void ImGui::Columns(int columns_count, const char* id, bool border) EndColumns(); ImGuiColumnsFlags flags = (border ? 0 : ImGuiColumnsFlags_NoBorder); + //flags |= ImGuiColumnsFlags_NoPreserveWidths | ImGuiColumnsFlags_NoForceWithinWindow; // NB: Legacy behavior if (columns_count != 1) BeginColumns(id, columns_count, flags); } From 1ebd7ec0494a1b97ee5ce06ad0ffb4d0964d7bff Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 20 Aug 2017 20:56:11 +0800 Subject: [PATCH 262/921] Demo: Columns: Added Horizontal Scrolling demo. Tweaked another Columns demo. (#519, #125, #913) --- imgui.cpp | 2 +- imgui_demo.cpp | 79 +++++++++++++++++++++++++++++++------------------- 2 files changed, 50 insertions(+), 31 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index a7ff91224..33b9178fe 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -10150,7 +10150,7 @@ void ImGui::Columns(int columns_count, const char* id, bool border) EndColumns(); ImGuiColumnsFlags flags = (border ? 0 : ImGuiColumnsFlags_NoBorder); - //flags |= ImGuiColumnsFlags_NoPreserveWidths | ImGuiColumnsFlags_NoForceWithinWindow; // NB: Legacy behavior + //flags |= ImGuiColumnsFlags_NoPreserveWidths; // NB: Legacy behavior if (columns_count != 1) BeginColumns(id, columns_count, flags); } diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 4b901acfc..73a658086 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1527,32 +1527,6 @@ void ImGui::ShowTestWindow(bool* p_open) ImGui::TreePop(); } - // Scrolling columns - /* - if (ImGui::TreeNode("Scrolling")) - { - ImGui::BeginChild("##header", ImVec2(0, ImGui::GetTextLineHeightWithSpacing()+ImGui::GetStyle().ItemSpacing.y)); - ImGui::Columns(3); - ImGui::Text("ID"); ImGui::NextColumn(); - ImGui::Text("Name"); ImGui::NextColumn(); - ImGui::Text("Path"); ImGui::NextColumn(); - ImGui::Columns(1); - ImGui::Separator(); - ImGui::EndChild(); - ImGui::BeginChild("##scrollingregion", ImVec2(0, 60)); - ImGui::Columns(3); - for (int i = 0; i < 10; i++) - { - ImGui::Text("%04d", i); ImGui::NextColumn(); - ImGui::Text("Foobar"); ImGui::NextColumn(); - ImGui::Text("/path/foobar/%04d/", i); ImGui::NextColumn(); - } - ImGui::Columns(1); - ImGui::EndChild(); - ImGui::TreePop(); - } - */ - // Create multiple items in a same cell before switching to next column if (ImGui::TreeNode("Mixed items")) { @@ -1570,7 +1544,7 @@ void ImGui::ShowTestWindow(bool* p_open) ImGui::Text("An extra line here."); ImGui::NextColumn(); - ImGui::Text("Sailor"); + ImGui::Text("Sailor"); ImGui::Button("Corniflower"); static float bar = 1.0f; ImGui::InputFloat("blue", &bar, 0.05f, 0, 3); @@ -1607,14 +1581,59 @@ void ImGui::ShowTestWindow(bool* p_open) ImGui::SameLine(); ImGui::Checkbox("vertical", &v_borders); ImGui::Columns(4, NULL, v_borders); - if (h_borders) ImGui::Separator(); - for (int i = 0; i < 8; i++) + for (int i = 0; i < 4*3; i++) { + if (h_borders && ImGui::GetColumnIndex() == 0) + ImGui::Separator(); ImGui::Text("%c%c%c", 'a'+i, 'a'+i, 'a'+i); + ImGui::Text("Width %.2f\nOffset %.2f", ImGui::GetColumnWidth(), ImGui::GetColumnOffset()); ImGui::NextColumn(); } ImGui::Columns(1); - if (h_borders) ImGui::Separator(); + if (h_borders) + ImGui::Separator(); + ImGui::TreePop(); + } + + // Scrolling columns + /* + if (ImGui::TreeNode("Vertical Scrolling")) + { + ImGui::BeginChild("##header", ImVec2(0, ImGui::GetTextLineHeightWithSpacing()+ImGui::GetStyle().ItemSpacing.y)); + ImGui::Columns(3); + ImGui::Text("ID"); ImGui::NextColumn(); + ImGui::Text("Name"); ImGui::NextColumn(); + ImGui::Text("Path"); ImGui::NextColumn(); + ImGui::Columns(1); + ImGui::Separator(); + ImGui::EndChild(); + ImGui::BeginChild("##scrollingregion", ImVec2(0, 60)); + ImGui::Columns(3); + for (int i = 0; i < 10; i++) + { + ImGui::Text("%04d", i); ImGui::NextColumn(); + ImGui::Text("Foobar"); ImGui::NextColumn(); + ImGui::Text("/path/foobar/%04d/", i); ImGui::NextColumn(); + } + ImGui::Columns(1); + ImGui::EndChild(); + ImGui::TreePop(); + } + */ + + if (ImGui::TreeNode("Horizontal Scrolling")) + { + ImGui::SetNextWindowContentWidth(2000); + ImGui::BeginChild("##scrollingregion", ImVec2(0, 120), false, ImGuiWindowFlags_HorizontalScrollbar); + ImGui::Columns(10); + for (int i = 0; i < 20; i++) + for (int j = 0; j < 10; j++) + { + ImGui::Text("Line %d Column %d", i, j); + ImGui::NextColumn(); + } + ImGui::Columns(1); + ImGui::EndChild(); ImGui::TreePop(); } From 83e8d10fabc1b8a9cf069c64edeba53b65e6be63 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 20 Aug 2017 21:08:07 +0800 Subject: [PATCH 263/921] Columns: Columns set resize based on the presence of vertical scrollbar. Not 100% sure about that but it looks like we've fixed enough bugs that this may not cause troubles anymore. (#125, #913, #893, #1138) --- imgui.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 33b9178fe..c677e79d5 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -10052,7 +10052,8 @@ void ImGui::BeginColumns(const char* id, int columns_count, ImGuiColumnsFlags fl const float content_region_width = (window->SizeContentsExplicit.x != 0.0f) ? window->SizeContentsExplicit.x : window->Size.x; window->DC.ColumnsMinX = window->DC.IndentX - g.Style.ItemSpacing.x; // Lock our horizontal range - window->DC.ColumnsMaxX = content_region_width - window->Scroll.x - ((window->Flags & ImGuiWindowFlags_NoScrollbar) ? 0 : g.Style.ScrollbarSize);// - window->WindowPadding().x; + //window->DC.ColumnsMaxX = content_region_width - window->Scroll.x -((window->Flags & ImGuiWindowFlags_NoScrollbar) ? 0 : g.Style.ScrollbarSize);// - window->WindowPadding().x; + window->DC.ColumnsMaxX = content_region_width - window->Scroll.x - window->ScrollbarSizes.x; window->DC.ColumnsStartPosY = window->DC.CursorPos.y; window->DC.ColumnsStartMaxPosX = window->DC.CursorMaxPos.x; window->DC.ColumnsCellMinY = window->DC.ColumnsCellMaxY = window->DC.CursorPos.y; From 54bdd00df752008d01c50e9847564ef2357c5d56 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 20 Aug 2017 21:32:18 +0800 Subject: [PATCH 264/921] Columns: Fix for explicit content width and scrollbar. (#519, #125) --- imgui.cpp | 4 ++-- imgui_demo.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index c677e79d5..2f05901bb 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -10050,10 +10050,10 @@ void ImGui::BeginColumns(const char* id, int columns_count, ImGuiColumnsFlags fl window->DC.ColumnsCount = columns_count; window->DC.ColumnsFlags = flags; - const float content_region_width = (window->SizeContentsExplicit.x != 0.0f) ? window->SizeContentsExplicit.x : window->Size.x; + const float content_region_width = (window->SizeContentsExplicit.x != 0.0f) ? (window->SizeContentsExplicit.x) : (window->Size.x -window->ScrollbarSizes.x); window->DC.ColumnsMinX = window->DC.IndentX - g.Style.ItemSpacing.x; // Lock our horizontal range //window->DC.ColumnsMaxX = content_region_width - window->Scroll.x -((window->Flags & ImGuiWindowFlags_NoScrollbar) ? 0 : g.Style.ScrollbarSize);// - window->WindowPadding().x; - window->DC.ColumnsMaxX = content_region_width - window->Scroll.x - window->ScrollbarSizes.x; + window->DC.ColumnsMaxX = content_region_width - window->Scroll.x; window->DC.ColumnsStartPosY = window->DC.CursorPos.y; window->DC.ColumnsStartMaxPosX = window->DC.CursorMaxPos.x; window->DC.ColumnsCellMinY = window->DC.ColumnsCellMaxY = window->DC.CursorPos.y; diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 73a658086..8911bcf2a 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1623,13 +1623,13 @@ void ImGui::ShowTestWindow(bool* p_open) if (ImGui::TreeNode("Horizontal Scrolling")) { - ImGui::SetNextWindowContentWidth(2000); + ImGui::SetNextWindowContentWidth(1500); ImGui::BeginChild("##scrollingregion", ImVec2(0, 120), false, ImGuiWindowFlags_HorizontalScrollbar); ImGui::Columns(10); for (int i = 0; i < 20; i++) for (int j = 0; j < 10; j++) { - ImGui::Text("Line %d Column %d", i, j); + ImGui::Text("Line %d Column %d...", i, j); ImGui::NextColumn(); } ImGui::Columns(1); From adeaf1cd72163646e523e1365f542a6dcad37791 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 20 Aug 2017 23:09:43 +0800 Subject: [PATCH 265/921] Columns: Moved PushColumnClipRect() to imgui_internal.h --- imgui.cpp | 3 +-- imgui_internal.h | 1 + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 2f05901bb..2fa316b29 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -617,7 +617,6 @@ static void LoadIniSettingsFromDisk(const char* ini_filename); static void SaveIniSettingsToDisk(const char* ini_filename); static void MarkIniSettingsDirty(); -static void PushColumnClipRect(int column_index = -1); static ImRect GetVisibleRect(); static bool BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_flags); @@ -10020,7 +10019,7 @@ void ImGui::SetColumnWidth(int column_index, float width) SetColumnOffset(column_index+1, GetColumnOffset(column_index) + width); } -static void PushColumnClipRect(int column_index) +void ImGui::PushColumnClipRect(int column_index) { ImGuiWindow* window = ImGui::GetCurrentWindow(); if (column_index < 0) diff --git a/imgui_internal.h b/imgui_internal.h index d47c77025..23a6db845 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -762,6 +762,7 @@ namespace ImGui // New Columns API IMGUI_API void BeginColumns(const char* id, int count, ImGuiColumnsFlags flags = 0); // setup number of columns. use an identifier to distinguish multiple column sets. close with EndColumns(). IMGUI_API void EndColumns(); // close columns + IMGUI_API void PushColumnClipRect(int column_index = -1); // NB: All position are in absolute pixels coordinates (never using window coordinates internally) // AVOID USING OUTSIDE OF IMGUI.CPP! NOT FOR PUBLIC CONSUMPTION. THOSE FUNCTIONS ARE A MESS. THEIR SIGNATURE AND BEHAVIOR WILL CHANGE, THEY NEED TO BE REFACTORED INTO SOMETHING DECENT. From 067127f11351fa68bdb76f6c3664f9bd40e757b9 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 20 Aug 2017 23:17:59 +0800 Subject: [PATCH 266/921] Columns: Caching columns clipping rectangles (#125) --- imgui.cpp | 20 ++++++++++++++------ imgui_internal.h | 1 + 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 2fa316b29..e62af2fa9 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -8607,7 +8607,7 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl ImGuiContext& g = *GImGui; const ImGuiStyle& style = g.Style; - if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.ColumnsCount > 1) + if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.ColumnsCount > 1) // FIXME-OPT: Avoid if vertically clipped. PopClipRect(); ImGuiID id = window->GetID(label); @@ -10021,13 +10021,11 @@ void ImGui::SetColumnWidth(int column_index, float width) void ImGui::PushColumnClipRect(int column_index) { - ImGuiWindow* window = ImGui::GetCurrentWindow(); + ImGuiWindow* window = GetCurrentWindowRead(); if (column_index < 0) column_index = window->DC.ColumnsCurrent; - float x1 = ImFloor(0.5f + window->Pos.x + ImGui::GetColumnOffset(column_index) - 1.0f); - float x2 = ImFloor(0.5f + window->Pos.x + ImGui::GetColumnOffset(column_index+1) - 1.0f); - ImGui::PushClipRect(ImVec2(x1,-FLT_MAX), ImVec2(x2,+FLT_MAX), true); + PushClipRect(window->DC.ColumnsData[column_index].ClipRect.Min, window->DC.ColumnsData[column_index].ClipRect.Max, false); } void ImGui::BeginColumns(const char* id, int columns_count, ImGuiColumnsFlags flags) @@ -10066,11 +10064,21 @@ void ImGui::BeginColumns(const char* id, int columns_count, ImGuiColumnsFlags fl const ImGuiID column_id = window->DC.ColumnsSetId + ImGuiID(column_index); KeepAliveID(column_id); const float default_t = column_index / (float)window->DC.ColumnsCount; - float t = window->DC.StateStorage->GetFloat(column_id, default_t); // Cheaply store our floating point value inside the integer (could store a union into the map?) + float t = window->DC.StateStorage->GetFloat(column_id, default_t); if (!(window->DC.ColumnsFlags & ImGuiColumnsFlags_NoForceWithinWindow)) t = ImMin(t, PixelsToOffsetNorm(window, window->DC.ColumnsMaxX - g.Style.ColumnsMinSpacing * (window->DC.ColumnsCount - column_index))); window->DC.ColumnsData[column_index].OffsetNorm = t; } + + // Cache clipping rectangles + for (int column_index = 0; column_index < columns_count; column_index++) + { + float clip_x1 = ImFloor(0.5f + window->Pos.x + GetColumnOffset(column_index) - 1.0f); + float clip_x2 = ImFloor(0.5f + window->Pos.x + GetColumnOffset(column_index + 1) - 1.0f); + window->DC.ColumnsData[column_index].ClipRect = ImRect(clip_x1, -FLT_MAX, clip_x2, +FLT_MAX); + window->DC.ColumnsData[column_index].ClipRect.Clip(window->ClipRect); + } + window->DrawList->ChannelsSplit(window->DC.ColumnsCount); PushColumnClipRect(); PushItemWidth(GetColumnWidth() * 0.65f); diff --git a/imgui_internal.h b/imgui_internal.h index 23a6db845..c3fdb7e49 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -316,6 +316,7 @@ struct ImGuiGroupData struct ImGuiColumnData { float OffsetNorm; // Column start offset, normalized 0.0 (far left) -> 1.0 (far right) + ImRect ClipRect; //float IndentX; }; From 9b484d24cd048afa746ecb479bb7ed466db218f9 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 20 Aug 2017 23:45:02 +0800 Subject: [PATCH 267/921] ImDrawList: Added GetClipRectMin(), GetClipRectMax() helpers. Comments. --- TODO.txt | 2 +- imgui.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/TODO.txt b/TODO.txt index eac6d7473..944df651b 100644 --- a/TODO.txt +++ b/TODO.txt @@ -26,7 +26,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - window: expose contents size. (#1045) - window: GetWindowSize() returns (0,0) when not calculated? (#1045) !- scrolling: allow immediately effective change of scroll after Begin() if we haven't appended items yet. - - scrolling/clipping: separator on the initial position of a window is not visible (cursorpos.y <= clippos.y) + - scrolling/clipping: separator on the initial position of a window is not visible (cursorpos.y <= clippos.y). (2017-08-20: can't repro) - drawlist: move Font, FontSize, FontTexUvWhitePixel inside ImDrawList and make it self-contained (apart from drawing settings?) - drawlist: make it easier to toggle AA per primitive, so we can use e.g. non-AA fill + AA borders more naturally diff --git a/imgui.h b/imgui.h index 7c102f7d5..249183a92 100644 --- a/imgui.h +++ b/imgui.h @@ -1233,6 +1233,8 @@ struct ImDrawList IMGUI_API void PopClipRect(); IMGUI_API void PushTextureID(const ImTextureID& texture_id); IMGUI_API void PopTextureID(); + inline ImVec2 GetClipRectMin() const { const ImVec4& cr = _ClipRectStack.back(); return ImVec2(cr.x, cr.y); } + inline ImVec2 GetClipRectMax() const { const ImVec4& cr = _ClipRectStack.back(); return ImVec2(cr.z, cr.w); } // Primitives IMGUI_API void AddLine(const ImVec2& a, const ImVec2& b, ImU32 col, float thickness = 1.0f); From 530baee1a7f2901d86adedfa8990c726f66b154c Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 21 Aug 2017 00:03:37 +0800 Subject: [PATCH 268/921] Removed tabs that slipped through the cracks --- imgui.cpp | 52 ++++++++++++++++++++++++------------------------ imgui_internal.h | 2 +- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index e62af2fa9..d40553f13 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -10086,32 +10086,32 @@ void ImGui::BeginColumns(const char* id, int columns_count, ImGuiColumnsFlags fl void ImGui::EndColumns() { - ImGuiContext& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - IM_ASSERT(window->DC.ColumnsCount > 1); + ImGuiContext& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + IM_ASSERT(window->DC.ColumnsCount > 1); - PopItemWidth(); - PopClipRect(); - window->DrawList->ChannelsMerge(); + PopItemWidth(); + PopClipRect(); + window->DrawList->ChannelsMerge(); - window->DC.ColumnsCellMaxY = ImMax(window->DC.ColumnsCellMaxY, window->DC.CursorPos.y); - window->DC.CursorPos.y = window->DC.ColumnsCellMaxY; + window->DC.ColumnsCellMaxY = ImMax(window->DC.ColumnsCellMaxY, window->DC.CursorPos.y); + window->DC.CursorPos.y = window->DC.ColumnsCellMaxY; window->DC.CursorMaxPos.x = ImMax(window->DC.ColumnsStartMaxPosX, window->DC.ColumnsMaxX); // Columns don't grow parent - // Draw columns borders and handle resize - if (!(window->DC.ColumnsFlags & ImGuiColumnsFlags_NoBorder) && !window->SkipItems) - { - const float y1 = window->DC.ColumnsStartPosY; - const float y2 = window->DC.CursorPos.y; + // Draw columns borders and handle resize + if (!(window->DC.ColumnsFlags & ImGuiColumnsFlags_NoBorder) && !window->SkipItems) + { + const float y1 = window->DC.ColumnsStartPosY; + const float y2 = window->DC.CursorPos.y; int dragging_column = -1; - for (int i = 1; i < window->DC.ColumnsCount; i++) - { - float x = window->Pos.x + GetColumnOffset(i); - const ImGuiID column_id = window->DC.ColumnsSetId + ImGuiID(i); + for (int i = 1; i < window->DC.ColumnsCount; i++) + { + float x = window->Pos.x + GetColumnOffset(i); + const ImGuiID column_id = window->DC.ColumnsSetId + ImGuiID(i); const float column_w = 4.0f; // Width for interaction const ImRect column_rect(ImVec2(x - column_w, y1), ImVec2(x + column_w, y2)); - if (IsClippedEx(column_rect, &column_id, false)) - continue; + if (IsClippedEx(column_rect, &column_id, false)) + continue; bool hovered = false, held = false; if (!(window->DC.ColumnsFlags & ImGuiColumnsFlags_NoResize)) @@ -10137,13 +10137,13 @@ void ImGui::EndColumns() float x = GetDraggedColumnOffset(dragging_column); SetColumnOffset(dragging_column, x); } - } + } - window->DC.ColumnsSetId = 0; - window->DC.ColumnsCurrent = 0; - window->DC.ColumnsCount = 1; - window->DC.ColumnsFlags = 0; - window->DC.ColumnsData.resize(0); + window->DC.ColumnsSetId = 0; + window->DC.ColumnsCurrent = 0; + window->DC.ColumnsCount = 1; + window->DC.ColumnsFlags = 0; + window->DC.ColumnsData.resize(0); window->DC.ColumnsOffsetX = 0.0f; window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.IndentX + window->DC.ColumnsOffsetX); } @@ -10155,7 +10155,7 @@ void ImGui::Columns(int columns_count, const char* id, bool border) IM_ASSERT(columns_count >= 1); if (window->DC.ColumnsCount != columns_count && window->DC.ColumnsCount != 1) - EndColumns(); + EndColumns(); ImGuiColumnsFlags flags = (border ? 0 : ImGuiColumnsFlags_NoBorder); //flags |= ImGuiColumnsFlags_NoPreserveWidths; // NB: Legacy behavior diff --git a/imgui_internal.h b/imgui_internal.h index c3fdb7e49..99372b17b 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -743,7 +743,7 @@ namespace ImGui IMGUI_API void EndFrame(); // Ends the ImGui frame. Automatically called by Render()! you most likely don't need to ever call that yourself directly. If you don't need to render you can call EndFrame() but you'll have wasted CPU already. If you don't need to render, don't create any windows instead! IMGUI_API void SetActiveID(ImGuiID id, ImGuiWindow* window); - IMGUI_API void ClearActiveID(); + IMGUI_API void ClearActiveID(); IMGUI_API void SetHoveredID(ImGuiID id); IMGUI_API void KeepAliveID(ImGuiID id); From 543dc2817f7dfd5ecbf790d9ebe5ac930e20e885 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 21 Aug 2017 22:54:20 +0800 Subject: [PATCH 269/921] Fixed an assert when calling CloseCurrentPopup() twice in a row. --- imgui.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index d40553f13..59de6793a 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3495,7 +3495,7 @@ void ImGui::CloseCurrentPopup() { ImGuiContext& g = *GImGui; int popup_idx = g.CurrentPopupStack.Size - 1; - if (popup_idx < 0 || popup_idx > g.OpenPopupStack.Size || g.CurrentPopupStack[popup_idx].PopupId != g.OpenPopupStack[popup_idx].PopupId) + if (popup_idx < 0 || popup_idx >= g.OpenPopupStack.Size || g.CurrentPopupStack[popup_idx].PopupId != g.OpenPopupStack[popup_idx].PopupId) return; while (popup_idx > 0 && g.OpenPopupStack[popup_idx].Window && (g.OpenPopupStack[popup_idx].Window->Flags & ImGuiWindowFlags_ChildMenu)) popup_idx--; @@ -3549,7 +3549,6 @@ bool ImGui::BeginPopup(const char* str_id) return BeginPopupEx(g.CurrentWindow->GetID(str_id), ImGuiWindowFlags_ShowBorders); } -// FIXME bool ImGui::IsPopupOpen(ImGuiID id) { ImGuiContext& g = *GImGui; From 6ee317d26d782ece9828f906a45c068d45a459b2 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 22 Aug 2017 17:46:50 +0800 Subject: [PATCH 270/921] ImRect::Clip() -> ClipWith() to clarify meaning, going to undo the change in Nav branch. --- imgui.cpp | 8 ++++---- imgui_internal.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 59de6793a..0396108a7 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3103,7 +3103,7 @@ bool ImGui::IsMouseHoveringRect(const ImVec2& r_min, const ImVec2& r_max, bool c // Clip ImRect rect_clipped(r_min, r_max); if (clip) - rect_clipped.Clip(window->ClipRect); + rect_clipped.ClipWith(window->ClipRect); // Expand for touch input const ImRect rect_for_touch(rect_clipped.Min - g.Style.TouchExtraPadding, rect_clipped.Max + g.Style.TouchExtraPadding); @@ -4390,7 +4390,7 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us // Save clipped aabb so we can access it in constant-time in FindHoveredWindow() window->WindowRectClipped = window->Rect(); - window->WindowRectClipped.Clip(window->ClipRect); + window->WindowRectClipped.ClipWith(window->ClipRect); // Pressing CTRL+C while holding on a window copy its content to the clipboard // This works but 1. doesn't handle multiple Begin/End pairs, 2. recursing into another Begin/End pair - so we need to work that out and add better logging scope. @@ -8213,7 +8213,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 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 ImRect rect(rect_pos + ImVec2(0.0f, bg_offy_up - g.FontSize), rect_pos +ImVec2(rect_size.x, bg_offy_dn)); - rect.Clip(clip_rect); + rect.ClipWith(clip_rect); if (rect.Overlaps(clip_rect)) draw_window->DrawList->AddRectFilled(rect.Min, rect.Max, bg_color); } @@ -10075,7 +10075,7 @@ void ImGui::BeginColumns(const char* id, int columns_count, ImGuiColumnsFlags fl float clip_x1 = ImFloor(0.5f + window->Pos.x + GetColumnOffset(column_index) - 1.0f); float clip_x2 = ImFloor(0.5f + window->Pos.x + GetColumnOffset(column_index + 1) - 1.0f); window->DC.ColumnsData[column_index].ClipRect = ImRect(clip_x1, -FLT_MAX, clip_x2, +FLT_MAX); - window->DC.ColumnsData[column_index].ClipRect.Clip(window->ClipRect); + window->DC.ColumnsData[column_index].ClipRect.ClipWith(window->ClipRect); } window->DrawList->ChannelsSplit(window->DC.ColumnsCount); diff --git a/imgui_internal.h b/imgui_internal.h index 99372b17b..2bfef8420 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -267,7 +267,7 @@ struct IMGUI_API ImRect void Expand(const float amount) { Min.x -= amount; Min.y -= amount; Max.x += amount; Max.y += amount; } void Expand(const ImVec2& amount) { Min.x -= amount.x; Min.y -= amount.y; Max.x += amount.x; Max.y += amount.y; } void Reduce(const ImVec2& amount) { Min.x += amount.x; Min.y += amount.y; Max.x -= amount.x; Max.y -= amount.y; } - void Clip(const ImRect& clip) { if (Min.x < clip.Min.x) Min.x = clip.Min.x; if (Min.y < clip.Min.y) Min.y = clip.Min.y; if (Max.x > clip.Max.x) Max.x = clip.Max.x; if (Max.y > clip.Max.y) Max.y = clip.Max.y; } + void ClipWith(const ImRect& clip) { if (Min.x < clip.Min.x) Min.x = clip.Min.x; if (Min.y < clip.Min.y) Min.y = clip.Min.y; if (Max.x > clip.Max.x) Max.x = clip.Max.x; if (Max.y > clip.Max.y) Max.y = clip.Max.y; } void Floor() { Min.x = (float)(int)Min.x; Min.y = (float)(int)Min.y; Max.x = (float)(int)Max.x; Max.y = (float)(int)Max.y; } ImVec2 GetClosestPoint(ImVec2 p, bool on_edge) const { From d5b0d51274d59417a5a3dfcb81c58a37c04cffde Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 22 Aug 2017 18:13:10 +0800 Subject: [PATCH 271/921] Minor miscellaneous merges from Navigation branch to reduce divergence a little bit --- imgui.cpp | 104 ++++++++++++++++++++++++----------------------- imgui_internal.h | 13 +++--- 2 files changed, 60 insertions(+), 57 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 0396108a7..c76a6db7b 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -615,7 +615,7 @@ static ImGuiIniData* FindWindowSettings(const char* name); static ImGuiIniData* AddWindowSettings(const char* name); static void LoadIniSettingsFromDisk(const char* ini_filename); static void SaveIniSettingsToDisk(const char* ini_filename); -static void MarkIniSettingsDirty(); +static void MarkIniSettingsDirty(ImGuiWindow* window); static ImRect GetVisibleRect(); @@ -742,6 +742,7 @@ ImGuiIO::ImGuiIO() // Most fields are initialized with zero memset(this, 0, sizeof(*this)); + // Settings DisplaySize = ImVec2(-1.0f, -1.0f); DeltaTime = 1.0f/60.0f; IniSavingRate = 5.0f; @@ -774,6 +775,7 @@ ImGuiIO::ImGuiIO() SetClipboardTextFn = SetClipboardTextFn_DefaultImpl; ClipboardUserData = NULL; ImeSetInputScreenPosFn = ImeSetInputScreenPosFn_DefaultImpl; + ImeWindowHandle = NULL; // Set OS X style defaults based on __APPLE__ compile time flag #ifdef __APPLE__ @@ -1934,7 +1936,6 @@ bool ImGui::IsClippedEx(const ImRect& bb, const ImGuiID* id, bool clip_even_when { ImGuiContext& g = *GImGui; ImGuiWindow* window = GetCurrentWindowRead(); - if (!bb.Overlaps(window->ClipRect)) if (!id || *id != GImGui->ActiveId) if (clip_even_when_logged || !g.LogEnabled) @@ -2146,7 +2147,8 @@ void ImGui::NewFrame() g.RenderDrawData.CmdLists = NULL; g.RenderDrawData.CmdListsCount = g.RenderDrawData.TotalVtxCount = g.RenderDrawData.TotalIdxCount = 0; - // Update inputs state + + // Update mouse input state if (g.IO.MousePos.x < 0 && g.IO.MousePos.y < 0) g.IO.MousePos = ImVec2(-9999.0f, -9999.0f); if ((g.IO.MousePos.x < 0 && g.IO.MousePos.y < 0) || (g.IO.MousePosPrev.x < 0 && g.IO.MousePosPrev.y < 0)) // if mouse just appeared or disappeared (negative coordinate) we cancel out movement in MouseDelta @@ -2213,7 +2215,7 @@ void ImGui::NewFrame() { g.MovedWindow->PosFloat += g.IO.MouseDelta; if (!(g.MovedWindow->Flags & ImGuiWindowFlags_NoSavedSettings) && (g.IO.MouseDelta.x != 0.0f || g.IO.MouseDelta.y != 0.0f)) - MarkIniSettingsDirty(); + MarkIniSettingsDirty(g.MovedWindow); } FocusWindow(g.MovedWindow); } @@ -2291,23 +2293,20 @@ void ImGui::NewFrame() if (g.HoveredWindow && g.IO.MouseWheel != 0.0f && !g.HoveredWindow->Collapsed) { ImGuiWindow* window = g.HoveredWindow; - if (g.IO.KeyCtrl) + if (g.IO.KeyCtrl && g.IO.FontAllowUserScaling) { - if (g.IO.FontAllowUserScaling) - { - // Zoom / Scale window - float new_font_scale = ImClamp(window->FontWindowScale + g.IO.MouseWheel * 0.10f, 0.50f, 2.50f); - float scale = new_font_scale / window->FontWindowScale; - window->FontWindowScale = new_font_scale; + // Zoom / Scale window + const float new_font_scale = ImClamp(window->FontWindowScale + g.IO.MouseWheel * 0.10f, 0.50f, 2.50f); + const float scale = new_font_scale / window->FontWindowScale; + window->FontWindowScale = new_font_scale; - const ImVec2 offset = window->Size * (1.0f - scale) * (g.IO.MousePos - window->Pos) / window->Size; - window->Pos += offset; - window->PosFloat += offset; - window->Size *= scale; - window->SizeFull *= scale; - } + const ImVec2 offset = window->Size * (1.0f - scale) * (g.IO.MousePos - window->Pos) / window->Size; + window->Pos += offset; + window->PosFloat += offset; + window->Size *= scale; + window->SizeFull *= scale; } - else if (!(window->Flags & ImGuiWindowFlags_NoScrollWithMouse)) + else if (!g.IO.KeyCtrl && !(window->Flags & ImGuiWindowFlags_NoScrollWithMouse)) { // Scroll const int scroll_lines = (window->Flags & ImGuiWindowFlags_ComboBox) ? 3 : 5; @@ -2530,11 +2529,12 @@ static void SaveIniSettingsToDisk(const char* ini_filename) fclose(f); } -static void MarkIniSettingsDirty() +static void MarkIniSettingsDirty(ImGuiWindow* window) { ImGuiContext& g = *GImGui; - if (g.SettingsDirtyTimer <= 0.0f) - g.SettingsDirtyTimer = g.IO.IniSavingRate; + if (!(window->Flags & ImGuiWindowFlags_NoSavedSettings)) + if (g.SettingsDirtyTimer <= 0.0f) + g.SettingsDirtyTimer = g.IO.IniSavingRate; } // FIXME: Add a more explicit sort order in the window structure. @@ -2684,6 +2684,7 @@ void ImGui::EndFrame() continue; AddWindowToSortedBuffer(g.WindowsSortBuffer, window); } + IM_ASSERT(g.Windows.Size == g.WindowsSortBuffer.Size); // we done something wrong g.Windows.swap(g.WindowsSortBuffer); @@ -3315,8 +3316,7 @@ bool ImGui::IsAnyItemActive() bool ImGui::IsItemVisible() { ImGuiWindow* window = GetCurrentWindowRead(); - ImRect r(window->ClipRect); - return r.Overlaps(window->DC.LastItemRect); + return window->ClipRect.Overlaps(window->DC.LastItemRect); } // Allow last item to be overlapped by a subsequent item. Both may be activated during the same frame before the later one takes priority. @@ -3631,7 +3631,7 @@ bool ImGui::BeginPopupContextVoid(const char* str_id, int mouse_button) static bool BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, bool border, ImGuiWindowFlags extra_flags) { - ImGuiWindow* window = ImGui::GetCurrentWindow(); + ImGuiWindow* parent_window = ImGui::GetCurrentWindow(); ImGuiWindowFlags flags = ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_ChildWindow; const ImVec2 content_avail = ImGui::GetContentRegionAvail(); @@ -3654,14 +3654,14 @@ static bool BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, b char title[256]; if (name) - ImFormatString(title, IM_ARRAYSIZE(title), "%s.%s.%08X", window->Name, name, id); + ImFormatString(title, IM_ARRAYSIZE(title), "%s.%s.%08X", parent_window->Name, name, id); else - ImFormatString(title, IM_ARRAYSIZE(title), "%s.%08X", window->Name, id); + ImFormatString(title, IM_ARRAYSIZE(title), "%s.%08X", parent_window->Name, id); bool ret = ImGui::Begin(title, NULL, size, -1.0f, flags); - - if (!(window->Flags & ImGuiWindowFlags_ShowBorders)) - ImGui::GetCurrentWindow()->Flags &= ~ImGuiWindowFlags_ShowBorders; + ImGuiWindow* child_window = ImGui::GetCurrentWindow(); + if (!(parent_window->Flags & ImGuiWindowFlags_ShowBorders)) + child_window->Flags &= ~ImGuiWindowFlags_ShowBorders; return ret; } @@ -3697,8 +3697,8 @@ void ImGui::EndChild() ImGui::End(); - window = GetCurrentWindow(); - ImRect bb(window->DC.CursorPos, window->DC.CursorPos + sz); + ImGuiWindow* parent_window = GetCurrentWindow(); + ImRect bb(parent_window->DC.CursorPos, parent_window->DC.CursorPos + sz); ItemSize(sz); ItemAdd(bb, NULL); } @@ -3744,7 +3744,7 @@ static ImVec2 FindBestPopupWindowPos(const ImVec2& base_pos, const ImVec2& size, // Clamp into visible area while not overlapping the cursor. Safety padding is optional if our popup size won't fit without it. ImVec2 safe_padding = style.DisplaySafeAreaPadding; ImRect r_outer(GetVisibleRect()); - r_outer.Reduce(ImVec2((size.x - r_outer.GetWidth() > safe_padding.x*2) ? safe_padding.x : 0.0f, (size.y - r_outer.GetHeight() > safe_padding.y*2) ? safe_padding.y : 0.0f)); + r_outer.Expand(ImVec2((size.x - r_outer.GetWidth() > safe_padding.x*2) ? -safe_padding.x : 0.0f, (size.y - r_outer.GetHeight() > safe_padding.y*2) ? -safe_padding.y : 0.0f)); ImVec2 base_pos_clamped = ImClamp(base_pos, r_outer.Min, r_outer.Max - size); for (int n = (*last_dir != -1) ? -1 : 0; n < 4; n++) // Last, Right, down, up, left. (Favor last used direction). @@ -4022,8 +4022,7 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us if (g.HoveredWindow == window && IsMouseHoveringRect(title_bar_rect.Min, title_bar_rect.Max) && g.IO.MouseDoubleClicked[0]) { window->Collapsed = !window->Collapsed; - if (!(flags & ImGuiWindowFlags_NoSavedSettings)) - MarkIniSettingsDirty(); + MarkIniSettingsDirty(window); FocusWindow(window); } } @@ -4097,8 +4096,7 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us window->SizeFull.x = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.x, size_auto_fit.x) : size_auto_fit.x; if (window->AutoFitFramesY > 0) window->SizeFull.y = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.y, size_auto_fit.y) : size_auto_fit.y; - if (!(flags & ImGuiWindowFlags_NoSavedSettings)) - MarkIniSettingsDirty(); + MarkIniSettingsDirty(window); } } @@ -4232,16 +4230,14 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us { // Manual auto-fit when double-clicking ApplySizeFullWithConstraint(window, size_auto_fit); - if (!(flags & ImGuiWindowFlags_NoSavedSettings)) - MarkIniSettingsDirty(); + MarkIniSettingsDirty(window); ClearActiveID(); } else if (held) { // We don't use an incremental MouseDelta but rather compute an absolute target size based on mouse position ApplySizeFullWithConstraint(window, (g.IO.MousePos - g.ActiveIdClickOffset + resize_rect.GetSize()) - window->Pos); - if (!(flags & ImGuiWindowFlags_NoSavedSettings)) - MarkIniSettingsDirty(); + MarkIniSettingsDirty(window); } window->Size = window->SizeFull; @@ -4407,7 +4403,8 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us // Note that if our window is collapsed we will end up with a null clipping rectangle which is the correct behavior. const ImRect title_bar_rect = window->TitleBarRect(); const float border_size = window->BorderSize; - ImRect clip_rect; // Force round to ensure that e.g. (int)(max.x-min.x) in user's render code produce correct result. + // Force round to ensure that e.g. (int)(max.x-min.x) in user's render code produce correct result. + ImRect clip_rect; clip_rect.Min.x = ImFloor(0.5f + title_bar_rect.Min.x + ImMax(border_size, ImFloor(window->WindowPadding.x*0.5f))); clip_rect.Min.y = ImFloor(0.5f + title_bar_rect.Max.y + window->MenuBarHeight() + border_size); clip_rect.Max.x = ImFloor(0.5f + window->Pos.x + window->Size.x - window->ScrollbarSizes.x - ImMax(border_size, ImFloor(window->WindowPadding.x*0.5f))); @@ -4496,7 +4493,7 @@ static void Scrollbar(ImGuiWindow* window, bool horizontal) else window_rounding_corners = (((window->Flags & ImGuiWindowFlags_NoTitleBar) && !(window->Flags & ImGuiWindowFlags_MenuBar)) ? ImGuiCorner_TopRight : 0) | (other_scrollbar ? 0 : ImGuiCorner_BottomRight); window->DrawList->AddRectFilled(bb.Min, bb.Max, ImGui::GetColorU32(ImGuiCol_ScrollbarBg), window_rounding, window_rounding_corners); - bb.Reduce(ImVec2(ImClamp((float)(int)((bb.Max.x - bb.Min.x - 2.0f) * 0.5f), 0.0f, 3.0f), ImClamp((float)(int)((bb.Max.y - bb.Min.y - 2.0f) * 0.5f), 0.0f, 3.0f))); + bb.Expand(ImVec2(-ImClamp((float)(int)((bb.Max.x - bb.Min.x - 2.0f) * 0.5f), 0.0f, 3.0f), -ImClamp((float)(int)((bb.Max.y - bb.Min.y - 2.0f) * 0.5f), 0.0f, 3.0f))); // V denote the main, longer axis of the scrollbar (= height for a vertical scrollbar) float scrollbar_size_v = horizontal ? bb.GetWidth() : bb.GetHeight(); @@ -5580,6 +5577,7 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool return false; } + // Default behavior requires click+release on same spot if ((flags & (ImGuiButtonFlags_PressedOnClickRelease | ImGuiButtonFlags_PressedOnClick | ImGuiButtonFlags_PressedOnRelease | ImGuiButtonFlags_PressedOnDoubleClick)) == 0) flags |= ImGuiButtonFlags_PressedOnClickRelease; @@ -6468,13 +6466,18 @@ int ImGui::ParseFormatPrecision(const char* fmt, int default_precision) return precision; } +static float GetMinimumStepAtDecimalPrecision(int decimal_precision) +{ + static const float min_steps[10] = { 1.0f, 0.1f, 0.01f, 0.001f, 0.0001f, 0.00001f, 0.000001f, 0.0000001f, 0.00000001f, 0.000000001f }; + return (decimal_precision >= 0 && decimal_precision < 10) ? min_steps[decimal_precision] : powf(10.0f, (float)-decimal_precision); +} + float ImGui::RoundScalar(float value, int decimal_precision) { // Round past decimal precision // So when our value is 1.99999 with a precision of 0.001 we'll end up rounding to 2.0 // FIXME: Investigate better rounding methods - static const float min_steps[10] = { 1.0f, 0.1f, 0.01f, 0.001f, 0.0001f, 0.00001f, 0.000001f, 0.0000001f, 0.00000001f, 0.000000001f }; - float min_step = (decimal_precision >= 0 && decimal_precision < 10) ? min_steps[decimal_precision] : powf(10.0f, (float)-decimal_precision); + const float min_step = GetMinimumStepAtDecimalPrecision(decimal_precision); bool negative = value < 0.0f; value = fabsf(value); float remainder = fmodf(value, min_step); @@ -6602,10 +6605,8 @@ bool ImGui::SliderBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v } } - // Calculate slider grab positioning - float grab_t = SliderBehaviorCalcRatioFromValue(*v, v_min, v_max, power, linear_zero_pos); - // Draw + float grab_t = SliderBehaviorCalcRatioFromValue(*v, v_min, v_max, power, linear_zero_pos); if (!is_horizontal) grab_t = 1.0f - grab_t; const float grab_pos = ImLerp(slider_usable_pos_min, slider_usable_pos_max, grab_t); @@ -7293,7 +7294,7 @@ void ImGui::ProgressBar(float fraction, const ImVec2& size_arg, const char* over // Render fraction = ImSaturate(fraction); RenderFrame(bb.Min, bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding); - bb.Reduce(ImVec2(window->BorderSize, window->BorderSize)); + bb.Expand(ImVec2(-window->BorderSize, -window->BorderSize)); const ImVec2 fill_br = ImVec2(ImLerp(bb.Min.x, bb.Max.x, fraction), bb.Max.y); RenderFrame(bb.Min, fill_br, GetColorU32(ImGuiCol_PlotHistogram), false, style.FrameRounding); @@ -8570,6 +8571,7 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi if (BeginPopupEx(id, flags)) { // Display items + // FIXME-OPT: Use clipper Spacing(); for (int i = 0; i < items_count; i++) { @@ -8757,7 +8759,7 @@ bool ImGui::ListBox(const char* label, int* current_item, bool (*items_getter)(v // Assume all items have even height (= 1 line of text). If you need items of different or variable sizes you can create a custom version of ListBox() in your code without using the clipper. bool value_changed = false; - ImGuiListClipper clipper(items_count, GetTextLineHeightWithSpacing()); + ImGuiListClipper clipper(items_count, GetTextLineHeightWithSpacing()); // We know exactly our line height here so we pass it as a minor optimization, but generally you don't need to. while (clipper.Step()) for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) { @@ -10471,8 +10473,8 @@ void ImGui::ShowMetricsWindow(bool* p_open) ImGui::Text("FocusedWindow: '%s'", g.FocusedWindow ? g.FocusedWindow->Name : "NULL"); ImGui::Text("HoveredWindow: '%s'", g.HoveredWindow ? g.HoveredWindow->Name : "NULL"); ImGui::Text("HoveredRootWindow: '%s'", g.HoveredRootWindow ? g.HoveredRootWindow->Name : "NULL"); - ImGui::Text("HoveredID: 0x%08X/0x%08X", g.HoveredId, g.HoveredIdPreviousFrame); // Data is "in-flight" so depending on when the Metrics window is called we may see current frame information or not - ImGui::Text("ActiveID: 0x%08X/0x%08X", g.ActiveId, g.ActiveIdPreviousFrame); + ImGui::Text("HoveredId: 0x%08X/0x%08X", g.HoveredId, g.HoveredIdPreviousFrame); // Data is "in-flight" so depending on when the Metrics window is called we may see current frame information or not + ImGui::Text("ActiveId: 0x%08X/0x%08X", g.ActiveId, g.ActiveIdPreviousFrame); ImGui::Text("ActiveIdWindow: '%s'", g.ActiveIdWindow ? g.ActiveIdWindow->Name : "NULL"); ImGui::TreePop(); } diff --git a/imgui_internal.h b/imgui_internal.h index 2bfef8420..d98d2cb48 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -266,7 +266,7 @@ struct IMGUI_API ImRect void Add(const ImRect& rhs) { if (Min.x > rhs.Min.x) Min.x = rhs.Min.x; if (Min.y > rhs.Min.y) Min.y = rhs.Min.y; if (Max.x < rhs.Max.x) Max.x = rhs.Max.x; if (Max.y < rhs.Max.y) Max.y = rhs.Max.y; } void Expand(const float amount) { Min.x -= amount; Min.y -= amount; Max.x += amount; Max.y += amount; } void Expand(const ImVec2& amount) { Min.x -= amount.x; Min.y -= amount.y; Max.x += amount.x; Max.y += amount.y; } - void Reduce(const ImVec2& amount) { Min.x += amount.x; Min.y += amount.y; Max.x -= amount.x; Max.y -= amount.y; } + void Translate(const ImVec2& v) { Min.x += v.x; Min.y += v.y; Max.x += v.x; Max.y += v.y; } void ClipWith(const ImRect& clip) { if (Min.x < clip.Min.x) Min.x = clip.Min.x; if (Min.y < clip.Min.y) Min.y = clip.Min.y; if (Max.x > clip.Max.x) Max.x = clip.Max.x; if (Max.y > clip.Max.y) Max.y = clip.Max.y; } void Floor() { Min.x = (float)(int)Min.x; Min.y = (float)(int)Min.y; Max.x = (float)(int)Max.x; Max.y = (float)(int)Max.y; } ImVec2 GetClosestPoint(ImVec2 p, bool on_edge) const @@ -397,8 +397,8 @@ struct ImGuiContext ImGuiIO IO; ImGuiStyle Style; ImFont* Font; // (Shortcut) == FontStack.empty() ? IO.Font : FontStack.back() - float FontSize; // (Shortcut) == FontBaseSize * g.CurrentWindow->FontWindowScale == window->FontSize() - float FontBaseSize; // (Shortcut) == IO.FontGlobalScale * Font->Scale * Font->FontSize. Size of characters. + float FontSize; // (Shortcut) == FontBaseSize * g.CurrentWindow->FontWindowScale == window->FontSize(). Text height for current window. + float FontBaseSize; // (Shortcut) == IO.FontGlobalScale * Font->Scale * Font->FontSize. Base text height. ImVec2 FontTexUvWhitePixel; // (Shortcut) == Font->TexUvWhitePixel float Time; @@ -407,8 +407,8 @@ struct ImGuiContext int FrameCountRendered; ImVector Windows; ImVector WindowsSortBuffer; - ImGuiWindow* CurrentWindow; // Being drawn into ImVector CurrentWindowStack; + ImGuiWindow* CurrentWindow; // Being drawn into ImGuiWindow* FocusedWindow; // Will catch keyboard inputs ImGuiWindow* HoveredWindow; // Will catch mouse inputs ImGuiWindow* HoveredRootWindow; // Will catch mouse inputs (for focus/move only) @@ -417,9 +417,10 @@ struct ImGuiContext ImGuiID HoveredIdPreviousFrame; ImGuiID ActiveId; // Active widget ImGuiID ActiveIdPreviousFrame; - bool ActiveIdIsAlive; + bool ActiveIdIsAlive; // Active widget has been seen this frame bool ActiveIdIsJustActivated; // Set at the time of activation for one frame - bool ActiveIdAllowOverlap; // Set only by active widget + bool ActiveIdAllowOverlap; // Active widget allows another widget to steal active id (generally for overlapping widgets, but not always) + ImVec2 ActiveIdClickOffset; // Clicked offset from upper-left corner, if applicable (currently only set by ButtonBehavior) ImGuiWindow* ActiveIdWindow; ImGuiWindow* MovedWindow; // Track the child window we clicked on to move a window. From 50b3a14d0ab430d30c2c9c961ce305684b5f2e64 Mon Sep 17 00:00:00 2001 From: ocornut Date: Sun, 31 Jul 2016 13:05:13 +0200 Subject: [PATCH 272/921] Merge 2545d75c3b978638329ac65cc1851f3f5998bb5b from Nav - Tidying up, removed two unnecessary window flags from being exposed in imgui.h --- imgui.cpp | 15 +++++---------- imgui.h | 4 +--- imgui_internal.h | 1 + 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index c76a6db7b..6a5973fc1 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1775,6 +1775,7 @@ ImGuiWindow::ImGuiWindow(const char* name) PopupId = 0; AutoFitFramesX = AutoFitFramesY = -1; AutoFitOnlyGrows = false; + AutoFitChildAxises = 0x00; AutoPosLastDirection = -1; HiddenFrames = 0; SetWindowPosAllowFlags = SetWindowSizeAllowFlags = SetWindowCollapsedAllowFlags = ImGuiCond_Always | ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing; @@ -3636,18 +3637,11 @@ static bool BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, b const ImVec2 content_avail = ImGui::GetContentRegionAvail(); ImVec2 size = ImFloor(size_arg); + const int auto_fit_axises = ((size.x == 0.0f) ? 0x01 : 0x00) | ((size.y == 0.0f) ? 0x02 : 0x00); if (size.x <= 0.0f) - { - if (size.x == 0.0f) - flags |= ImGuiWindowFlags_ChildWindowAutoFitX; size.x = ImMax(content_avail.x, 4.0f) - fabsf(size.x); // Arbitrary minimum zero-ish child size of 4.0f (0.0f causing too much issues) - } if (size.y <= 0.0f) - { - if (size.y == 0.0f) - flags |= ImGuiWindowFlags_ChildWindowAutoFitY; size.y = ImMax(content_avail.y, 4.0f) - fabsf(size.y); - } if (border) flags |= ImGuiWindowFlags_ShowBorders; flags |= extra_flags; @@ -3660,6 +3654,7 @@ static bool BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, b bool ret = ImGui::Begin(title, NULL, size, -1.0f, flags); ImGuiWindow* child_window = ImGui::GetCurrentWindow(); + child_window->AutoFitChildAxises = auto_fit_axises; if (!(parent_window->Flags & ImGuiWindowFlags_ShowBorders)) child_window->Flags &= ~ImGuiWindowFlags_ShowBorders; @@ -3690,9 +3685,9 @@ void ImGui::EndChild() { // When using auto-filling child window, we don't provide full width/height to ItemSize so that it doesn't feed back into automatic size-fitting. ImVec2 sz = GetWindowSize(); - if (window->Flags & ImGuiWindowFlags_ChildWindowAutoFitX) // Arbitrary minimum zero-ish child size of 4.0f causes less trouble than a 0.0f + if (window->AutoFitChildAxises & 0x01) // Arbitrary minimum zero-ish child size of 4.0f causes less trouble than a 0.0f sz.x = ImMax(4.0f, sz.x); - if (window->Flags & ImGuiWindowFlags_ChildWindowAutoFitY) + if (window->AutoFitChildAxises & 0x02) sz.y = ImMax(4.0f, sz.y); ImGui::End(); diff --git a/imgui.h b/imgui.h index 249183a92..5cf8b5a4b 100644 --- a/imgui.h +++ b/imgui.h @@ -512,9 +512,7 @@ enum ImGuiWindowFlags_ ImGuiWindowFlags_AlwaysHorizontalScrollbar=1<< 15, // Always show horizontal scrollbar (even if ContentSize.x < Size.x) ImGuiWindowFlags_AlwaysUseWindowPadding = 1 << 16, // Ensure child windows without border uses style.WindowPadding (ignored by default for non-bordered child windows, because more convenient) // [Internal] - ImGuiWindowFlags_ChildWindow = 1 << 20, // Don't use! For internal use by BeginChild() - ImGuiWindowFlags_ChildWindowAutoFitX = 1 << 21, // Don't use! For internal use by BeginChild() - ImGuiWindowFlags_ChildWindowAutoFitY = 1 << 22, // Don't use! For internal use by BeginChild() + ImGuiWindowFlags_ChildWindow = 1 << 22, // Don't use! For internal use by BeginChild() ImGuiWindowFlags_ComboBox = 1 << 23, // Don't use! For internal use by ComboBox() ImGuiWindowFlags_Tooltip = 1 << 24, // Don't use! For internal use by BeginTooltip() ImGuiWindowFlags_Popup = 1 << 25, // Don't use! For internal use by BeginPopup() diff --git a/imgui_internal.h b/imgui_internal.h index d98d2cb48..31effe442 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -679,6 +679,7 @@ struct IMGUI_API ImGuiWindow ImGuiID PopupId; // ID in the popup stack when this window is used as a popup/menu (because we use generic Name/ID for recycling) int AutoFitFramesX, AutoFitFramesY; bool AutoFitOnlyGrows; + int AutoFitChildAxises; int AutoPosLastDirection; int HiddenFrames; ImGuiCond SetWindowPosAllowFlags; // store condition flags for next SetWindowPos() call. From 2ad2190d478dfc670bacc9376ff658ed4c5f0d59 Mon Sep 17 00:00:00 2001 From: ocornut Date: Sat, 30 Jul 2016 10:02:46 +0200 Subject: [PATCH 273/921] Merge 20a0fde0124c08a7ead82357c9346acec0bafda6 Tidying up default clipboard handler for non Windows-OS (from Nav branch) --- imgui.cpp | 19 ++++++------------- imgui_internal.h | 3 +-- 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 6a5973fc1..9e0512799 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2391,11 +2391,7 @@ void ImGui::Shutdown() for (int i = 0; i < IM_ARRAYSIZE(g.RenderDrawLists); i++) g.RenderDrawLists[i].clear(); g.OverlayDrawList.ClearFreeMemory(); - if (g.PrivateClipboard) - { - ImGui::MemFree(g.PrivateClipboard); - g.PrivateClipboard = NULL; - } + g.PrivateClipboard.clear(); g.InputTextState.Text.clear(); g.InputTextState.InitialText.clear(); g.InputTextState.TempTextBuffer.clear(); @@ -10297,21 +10293,18 @@ static void SetClipboardTextFn_DefaultImpl(void*, const char* text) // Local ImGui-only clipboard implementation, if user hasn't defined better clipboard handlers static const char* GetClipboardTextFn_DefaultImpl(void*) { - return GImGui->PrivateClipboard; + ImGuiContext& g = *GImGui; + return g.PrivateClipboard.empty() ? NULL : g.PrivateClipboard.begin(); } // Local ImGui-only clipboard implementation, if user hasn't defined better clipboard handlers static void SetClipboardTextFn_DefaultImpl(void*, const char* text) { ImGuiContext& g = *GImGui; - if (g.PrivateClipboard) - { - ImGui::MemFree(g.PrivateClipboard); - g.PrivateClipboard = NULL; - } + g.PrivateClipboard.clear(); const char* text_end = text + strlen(text); - g.PrivateClipboard = (char*)ImGui::MemAlloc((size_t)(text_end - text) + 1); - memcpy(g.PrivateClipboard, text, (size_t)(text_end - text)); + g.PrivateClipboard.resize((size_t)(text_end - text) + 1); + memcpy(&g.PrivateClipboard[0], text, (size_t)(text_end - text)); g.PrivateClipboard[(int)(text_end - text)] = 0; } diff --git a/imgui_internal.h b/imgui_internal.h index 31effe442..416789dda 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -471,7 +471,7 @@ struct ImGuiContext float DragSpeedScaleFast; ImVec2 ScrollbarClickDeltaToGrabCenter; // Distance between mouse and center of grab box, normalized in parent space. Use storage? int TooltipOverrideCount; - char* PrivateClipboard; // If no custom clipboard handler is defined + ImVector PrivateClipboard; // If no custom clipboard handler is defined ImVec2 OsImePosRequest, OsImePosSet; // Cursor position request & last passed to the OS Input Method Editor // Logging @@ -541,7 +541,6 @@ struct ImGuiContext DragSpeedScaleFast = 10.0f; ScrollbarClickDeltaToGrabCenter = ImVec2(0.0f, 0.0f); TooltipOverrideCount = 0; - PrivateClipboard = NULL; OsImePosRequest = OsImePosSet = ImVec2(-1.0f, -1.0f); ModalWindowDarkeningRatio = 0.0f; From 141339e4b756e996a7eec5948ae69e3d4f0f1e3b Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 22 Aug 2017 19:51:12 +0800 Subject: [PATCH 274/921] (internals) Renamed FocusedWindow to NavWindow to match terminology of navigation branch --- imgui.cpp | 36 ++++++++++++++++++------------------ imgui_internal.h | 4 ++-- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 9e0512799..3b8e84ef8 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2317,8 +2317,8 @@ void ImGui::NewFrame() // Pressing TAB activate widget focus // NB: Don't discard FocusedWindow if it isn't active, so that a window that go on/off programatically won't lose its keyboard focus. - if (g.ActiveId == 0 && g.FocusedWindow != NULL && g.FocusedWindow->Active && IsKeyPressedMap(ImGuiKey_Tab, false)) - g.FocusedWindow->FocusIdxTabRequestNext = 0; + if (g.ActiveId == 0 && g.NavWindow != NULL && g.NavWindow->Active && IsKeyPressedMap(ImGuiKey_Tab, false)) + g.NavWindow->FocusIdxTabRequestNext = 0; // Mark all windows as not visible for (int i = 0; i != g.Windows.Size; i++) @@ -2330,7 +2330,7 @@ void ImGui::NewFrame() } // Closing the focused window restore focus to the first active root window in descending z-order - if (g.FocusedWindow && !g.FocusedWindow->WasActive) + if (g.NavWindow && !g.NavWindow->WasActive) for (int i = g.Windows.Size-1; i >= 0; i--) if (g.Windows[i]->WasActive && !(g.Windows[i]->Flags & ImGuiWindowFlags_ChildWindow)) { @@ -2373,7 +2373,7 @@ void ImGui::Shutdown() g.WindowsSortBuffer.clear(); g.CurrentWindow = NULL; g.CurrentWindowStack.clear(); - g.FocusedWindow = NULL; + g.NavWindow = NULL; g.HoveredWindow = NULL; g.HoveredRootWindow = NULL; g.ActiveIdWindow = NULL; @@ -2650,7 +2650,7 @@ void ImGui::EndFrame() // Click to focus window and start moving (after we're done with all our widgets) if (g.ActiveId == 0 && g.HoveredId == 0 && g.IO.MouseClicked[0]) { - if (!(g.FocusedWindow && !g.FocusedWindow->WasActive && g.FocusedWindow->Active)) // Unless we just made a popup appear + if (!(g.NavWindow && !g.NavWindow->WasActive && g.NavWindow->Active)) // Unless we just made a popup appear { if (g.HoveredRootWindow != NULL) { @@ -2662,7 +2662,7 @@ void ImGui::EndFrame() SetActiveID(g.MovedWindowMoveId, g.HoveredRootWindow); } } - else if (g.FocusedWindow != NULL && GetFrontMostModalRootWindow() == NULL) + else if (g.NavWindow != NULL && GetFrontMostModalRootWindow() == NULL) { // Clicking on void disable focus FocusWindow(NULL); @@ -3437,7 +3437,7 @@ static void CloseInactivePopups() // When popups are stacked, clicking on a lower level popups puts focus back to it and close popups above it. // Don't close our own child popup windows int n = 0; - if (g.FocusedWindow) + if (g.NavWindow) { for (n = 0; n < g.OpenPopupStack.Size; n++) { @@ -3450,7 +3450,7 @@ static void CloseInactivePopups() bool has_focus = false; for (int m = n; m < g.OpenPopupStack.Size && !has_focus; m++) - has_focus = (g.OpenPopupStack[m].Window && g.OpenPopupStack[m].Window->RootWindow == g.FocusedWindow->RootWindow); + has_focus = (g.OpenPopupStack[m].Window && g.OpenPopupStack[m].Window->RootWindow == g.NavWindow->RootWindow); if (!has_focus) break; } @@ -4260,7 +4260,7 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us // Title bar if (!(flags & ImGuiWindowFlags_NoTitleBar)) - window->DrawList->AddRectFilled(title_bar_rect.GetTL(), title_bar_rect.GetBR(), GetColorU32((g.FocusedWindow && window->RootNonPopupWindow == g.FocusedWindow->RootNonPopupWindow) ? ImGuiCol_TitleBgActive : ImGuiCol_TitleBg), window_rounding, ImGuiCorner_TopLeft|ImGuiCorner_TopRight); + window->DrawList->AddRectFilled(title_bar_rect.GetTL(), title_bar_rect.GetBR(), GetColorU32((g.NavWindow && window->RootNonPopupWindow == g.NavWindow->RootNonPopupWindow) ? ImGuiCol_TitleBgActive : ImGuiCol_TitleBg), window_rounding, ImGuiCorner_TopLeft|ImGuiCorner_TopRight); // Menu bar if (flags & ImGuiWindowFlags_MenuBar) @@ -4565,7 +4565,7 @@ void ImGui::FocusWindow(ImGuiWindow* window) ImGuiContext& g = *GImGui; // Always mark the window we passed as focused. This is used for keyboard interactions such as tabbing. - g.FocusedWindow = window; + g.NavWindow = window; // Passing NULL allow to disable keyboard focus if (!window) @@ -4876,19 +4876,19 @@ bool ImGui::IsWindowHovered() bool ImGui::IsWindowFocused() { ImGuiContext& g = *GImGui; - return g.FocusedWindow == g.CurrentWindow; + return g.NavWindow == g.CurrentWindow; } bool ImGui::IsRootWindowFocused() { ImGuiContext& g = *GImGui; - return g.FocusedWindow == g.CurrentWindow->RootWindow; + return g.NavWindow == g.CurrentWindow->RootWindow; } bool ImGui::IsRootWindowOrAnyChildFocused() { ImGuiContext& g = *GImGui; - return g.FocusedWindow && g.FocusedWindow->RootWindow == g.CurrentWindow->RootWindow; + return g.NavWindow && g.NavWindow->RootWindow == g.CurrentWindow->RootWindow; } bool ImGui::IsRootWindowOrAnyChildHovered() @@ -5547,7 +5547,7 @@ static inline bool IsWindowContentHoverable(ImGuiWindow* window) // An active popup disable hovering on other windows (apart from its own children) // FIXME-OPT: This could be cached/stored within the window. ImGuiContext& g = *GImGui; - if (ImGuiWindow* focused_window = g.FocusedWindow) + if (ImGuiWindow* focused_window = g.NavWindow) if (ImGuiWindow* focused_root_window = focused_window->RootWindow) if ((focused_root_window->Flags & ImGuiWindowFlags_Popup) != 0 && focused_root_window->WasActive && focused_root_window != window->RootWindow) return false; @@ -8882,13 +8882,13 @@ bool ImGui::BeginMenu(const char* label, bool enabled) const ImGuiID id = window->GetID(label); ImVec2 label_size = CalcTextSize(label, NULL, true); - ImGuiWindow* backed_focused_window = g.FocusedWindow; + ImGuiWindow* backed_focused_window = g.NavWindow; bool pressed; bool menu_is_open = IsPopupOpen(id); bool menuset_is_open = !(window->Flags & ImGuiWindowFlags_Popup) && (g.OpenPopupStack.Size > g.CurrentPopupStack.Size && g.OpenPopupStack[g.CurrentPopupStack.Size].ParentMenuSet == window->GetID("##menus")); if (menuset_is_open) - g.FocusedWindow = window; + g.NavWindow = window; // The reference position stored in popup_pos will be used by Begin() to find a suitable position for the child menu (using FindBestPopupWindowPos). ImVec2 popup_pos, pos = window->DC.CursorPos; @@ -8916,7 +8916,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled) bool hovered = enabled && IsHovered(window->DC.LastItemRect, id); if (menuset_is_open) - g.FocusedWindow = backed_focused_window; + g.NavWindow = backed_focused_window; bool want_open = false, want_close = false; if (window->Flags & (ImGuiWindowFlags_Popup|ImGuiWindowFlags_ChildMenu)) @@ -10458,7 +10458,7 @@ void ImGui::ShowMetricsWindow(bool* p_open) } if (ImGui::TreeNode("Basic state")) { - ImGui::Text("FocusedWindow: '%s'", g.FocusedWindow ? g.FocusedWindow->Name : "NULL"); + ImGui::Text("FocusedWindow: '%s'", g.NavWindow ? g.NavWindow->Name : "NULL"); ImGui::Text("HoveredWindow: '%s'", g.HoveredWindow ? g.HoveredWindow->Name : "NULL"); ImGui::Text("HoveredRootWindow: '%s'", g.HoveredRootWindow ? g.HoveredRootWindow->Name : "NULL"); ImGui::Text("HoveredId: 0x%08X/0x%08X", g.HoveredId, g.HoveredIdPreviousFrame); // Data is "in-flight" so depending on when the Metrics window is called we may see current frame information or not diff --git a/imgui_internal.h b/imgui_internal.h index 416789dda..e59a27edb 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -409,7 +409,7 @@ struct ImGuiContext ImVector WindowsSortBuffer; ImVector CurrentWindowStack; ImGuiWindow* CurrentWindow; // Being drawn into - ImGuiWindow* FocusedWindow; // Will catch keyboard inputs + ImGuiWindow* NavWindow; // Nav/focused window for navigation ImGuiWindow* HoveredWindow; // Will catch mouse inputs ImGuiWindow* HoveredRootWindow; // Will catch mouse inputs (for focus/move only) ImGuiID HoveredId; // Hovered widget @@ -500,7 +500,7 @@ struct ImGuiContext FrameCount = 0; FrameCountEnded = FrameCountRendered = -1; CurrentWindow = NULL; - FocusedWindow = NULL; + NavWindow = NULL; HoveredWindow = NULL; HoveredRootWindow = NULL; HoveredId = 0; From 6be7d4904e1dd67810087f6986d683efe10dcbf9 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 22 Aug 2017 20:10:02 +0800 Subject: [PATCH 275/921] Merge part of 88c1966629fff80f49bc6ffa0deb205f4856f3a3 from Nav branch. Renamed IsMouseHoveringAnyWindow() -> IsAnyWindowHovered(), IsMouseHoveringWindow() -> IsWindowHoveredRect() for consistency. Kept inline rediection function. --- imgui.cpp | 10 ++++++---- imgui.h | 10 ++++++---- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 3b8e84ef8..ea7d4e52b 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -204,8 +204,10 @@ Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. Also read releases logs https://github.com/ocornut/imgui/releases for more details. - - 2016/08/20 (1.51) - renamed GetStyleColName() to GetStyleColorName() for consistency. - - 2016/08/20 (1.51) - added PushStyleColor(ImGuiCol idx, ImU32 col) overload, which _might_ cause an "ambiguous call" compilation error if you are using ImColor() with implicit cast. Cast to ImU32 or ImVec4 explicily to fix. + - 2017/08/22 (1.51) - renamed IsMouseHoveringAnyWindow() to IsAnyWindowHovered() for consistency. Kept inline redirection function (will obsolete). + - renamed IsMouseHoveringWindow() to IsWindowHoveredRect() for consistency. Kept inline redirection function (will obsolete). + - 2017/08/20 (1.51) - renamed GetStyleColName() to GetStyleColorName() for consistency. + - 2017/08/20 (1.51) - added PushStyleColor(ImGuiCol idx, ImU32 col) overload, which _might_ cause an "ambiguous call" compilation error if you are using ImColor() with implicit cast. Cast to ImU32 or ImVec4 explicily to fix. - 2017/08/15 (1.51) - marked the weird IMGUI_ONCE_UPON_A_FRAME helper macro as obsolete. prefer using the more explicit ImGuiOnceUponAFrame. - 2017/08/15 (1.51) - changed parameter order for BeginPopupContextWindow() from (const char*,int buttons,bool also_over_items) to (const char*,int buttons,bool also_over_items). Note that most calls relied on default parameters completely. - 2017/08/13 (1.51) - renamed ImGuiCol_Columns_*** to ImGuiCol_Separator_*** @@ -3108,13 +3110,13 @@ bool ImGui::IsMouseHoveringRect(const ImVec2& r_min, const ImVec2& r_max, bool c return rect_for_touch.Contains(g.IO.MousePos); } -bool ImGui::IsMouseHoveringWindow() +bool ImGui::IsWindowHoveredRect() { ImGuiContext& g = *GImGui; return g.HoveredWindow == g.CurrentWindow; } -bool ImGui::IsMouseHoveringAnyWindow() +bool ImGui::IsAnyWindowHovered() { ImGuiContext& g = *GImGui; return g.HoveredWindow != NULL; diff --git a/imgui.h b/imgui.h index 5cf8b5a4b..d5be3a7b2 100644 --- a/imgui.h +++ b/imgui.h @@ -419,11 +419,13 @@ namespace ImGui IMGUI_API ImVec2 GetItemRectMax(); // " IMGUI_API ImVec2 GetItemRectSize(); // " IMGUI_API void SetItemAllowOverlap(); // allow last item to be overlapped by a subsequent item. sometimes useful with invisible buttons, selectables, etc. to catch unused area. - IMGUI_API bool IsWindowHovered(); // is current window hovered and hoverable (not blocked by a popup) (differentiate child windows from each others) IMGUI_API bool IsWindowFocused(); // is current window focused + IMGUI_API bool IsWindowHovered(); // is current window hovered and hoverable (not blocked by a popup) (differentiate child windows from each others) + IMGUI_API bool IsWindowHoveredRect(); // is current window hovered, disregarding of any consideration of being blocked by a popup. (unlike IsWindowHovered() this will return true even if the window is blocked because of a popup) IMGUI_API bool IsRootWindowFocused(); // is current root window focused (root = top-most parent of a child, otherwise self) IMGUI_API bool IsRootWindowOrAnyChildFocused(); // is current root window or any of its child (including current window) focused IMGUI_API bool IsRootWindowOrAnyChildHovered(); // is current root window or any of its child (including current window) hovered and hoverable (not blocked by a popup) + IMGUI_API bool IsAnyWindowHovered(); // is mouse hovering any visible window IMGUI_API bool IsRectVisible(const ImVec2& size); // test if rectangle (of given size, starting from cursor position) is visible / not clipped. IMGUI_API bool IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max); // test if rectangle (in screen space) is visible / not clipped. to perform coarse clipping on user's side. IMGUI_API float GetTime(); @@ -450,10 +452,8 @@ namespace ImGui IMGUI_API bool IsMouseClicked(int button, bool repeat = false); // did mouse button clicked (went from !Down to Down) IMGUI_API bool IsMouseDoubleClicked(int button); // did mouse button double-clicked. a double-click returns false in IsMouseClicked(). uses io.MouseDoubleClickTime. IMGUI_API bool IsMouseReleased(int button); // did mouse button released (went from Down to !Down) - IMGUI_API bool IsMouseHoveringWindow(); // is mouse hovering current window ("window" in API names always refer to current window). disregarding of any consideration of being blocked by a popup. (unlike IsWindowHovered() this will return true even if the window is blocked because of a popup) - IMGUI_API bool IsMouseHoveringAnyWindow(); // is mouse hovering any visible window - IMGUI_API bool IsMouseHoveringRect(const ImVec2& r_min, const ImVec2& r_max, bool clip = true); // is mouse hovering given bounding rect (in screen space). clipped by current clipping settings. disregarding of consideration of focus/window ordering/blocked by a popup. IMGUI_API bool IsMouseDragging(int button = 0, float lock_threshold = -1.0f); // is mouse dragging. if lock_threshold < -1.0f uses io.MouseDraggingThreshold + IMGUI_API bool IsMouseHoveringRect(const ImVec2& r_min, const ImVec2& r_max, bool clip = true); // is mouse hovering given bounding rect (in screen space). clipped by current clipping settings. disregarding of consideration of focus/window ordering/blocked by a popup. IMGUI_API ImVec2 GetMousePos(); // shortcut to ImGui::GetIO().MousePos provided by user, to be consistent with other calls IMGUI_API ImVec2 GetMousePosOnOpeningCurrentPopup(); // retrieve backup of mouse positioning at the time of opening popup we have BeginPopup() into IMGUI_API ImVec2 GetMouseDragDelta(int button = 0, float lock_threshold = -1.0f); // dragging amount since clicking. if lock_threshold < -1.0f uses io.MouseDraggingThreshold @@ -480,6 +480,8 @@ namespace ImGui // Obsolete functions (Will be removed! Also see 'API BREAKING CHANGES' section in imgui.cpp) #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS static inline bool IsPosHoveringAnyWindow(const ImVec2&) { IM_ASSERT(0); return false; } // OBSOLETE 1.51+. This was partly broken. You probably wanted to use ImGui::GetIO().WantCaptureMouse instead. + static inline bool IsMouseHoveringAnyWindow() { return IsAnyWindowHovered(); } // OBSOLETE 1.51+ + static inline bool IsMouseHoveringWindow() { return IsWindowHoveredRect(); } // OBSOLETE 1.51+ static inline bool CollapsingHeader(const char* label, const char* str_id, bool framed = true, bool default_open = false) { (void)str_id; (void)framed; ImGuiTreeNodeFlags default_open_flags = 1<<5; return CollapsingHeader(label, (default_open ? default_open_flags : 0)); } // OBSOLETE 1.49+ static inline ImFont* GetWindowFont() { return GetFont(); } // OBSOLETE 1.48+ static inline float GetWindowFontSize() { return GetFontSize(); } // OBSOLETE 1.48+ From 52b39af0a0fdc71a09a8e0e198ef61e94a4a6964 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 22 Aug 2017 20:23:46 +0800 Subject: [PATCH 276/921] Style: Added obsolete redirects for ImGuiCol_Columns*** fields. (ref 648f75b2456f1e5b17be113908c0119ed9e5b071) --- imgui.cpp | 2 +- imgui.h | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index ea7d4e52b..b4b52263d 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -210,7 +210,7 @@ - 2017/08/20 (1.51) - added PushStyleColor(ImGuiCol idx, ImU32 col) overload, which _might_ cause an "ambiguous call" compilation error if you are using ImColor() with implicit cast. Cast to ImU32 or ImVec4 explicily to fix. - 2017/08/15 (1.51) - marked the weird IMGUI_ONCE_UPON_A_FRAME helper macro as obsolete. prefer using the more explicit ImGuiOnceUponAFrame. - 2017/08/15 (1.51) - changed parameter order for BeginPopupContextWindow() from (const char*,int buttons,bool also_over_items) to (const char*,int buttons,bool also_over_items). Note that most calls relied on default parameters completely. - - 2017/08/13 (1.51) - renamed ImGuiCol_Columns_*** to ImGuiCol_Separator_*** + - 2017/08/13 (1.51) - renamed ImGuiCol_Columns*** to ImGuiCol_Separator***. Kept redirection enums (will obsolete). - 2017/08/11 (1.51) - renamed ImGuiSetCond_*** types and flags to ImGuiCond_***. Kept redirection enums (will obsolete). - 2017/08/09 (1.51) - removed ValueColor() helpers, they are equivalent to calling Text(label) + SameLine() + ColorButton(). - 2017/08/08 (1.51) - removed ColorEditMode() and ImGuiColorEditMode in favor of ImGuiColorEditFlags and parameters to the various Color*() functions. The SetColorEditOptions() allows to initialize default but the user can still change them with right-click context menu. diff --git a/imgui.h b/imgui.h index d5be3a7b2..84bb32e48 100644 --- a/imgui.h +++ b/imgui.h @@ -645,6 +645,11 @@ enum ImGuiCol_ ImGuiCol_TextSelectedBg, ImGuiCol_ModalWindowDarkening, // darken entire screen when a modal window is active ImGuiCol_COUNT + + // Obsolete names (will be removed) +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS + , ImGuiCol_Column = ImGuiCol_Separator, ImGuiCol_ColumnHovered = ImGuiCol_SeparatorHovered, ImGuiCol_ColumnActive = ImGuiCol_SeparatorActive +#endif }; // Enumeration for PushStyleVar() / PopStyleVar() to temporarily modify the ImGuiStyle structure. @@ -721,7 +726,7 @@ enum ImGuiCond_ ImGuiCond_FirstUseEver = 1 << 2, // Set the variable if the window has no saved data (if doesn't exist in the .ini file) ImGuiCond_Appearing = 1 << 3 // Set the variable if the window is appearing after being hidden/inactive (or the first time) -// Obsolete names (will be obsolete) + // Obsolete names (will be removed) #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS , ImGuiSetCond_Always = ImGuiCond_Always, ImGuiSetCond_Once = ImGuiCond_Once, ImGuiSetCond_FirstUseEver = ImGuiCond_FirstUseEver, ImGuiSetCond_Appearing = ImGuiCond_Appearing #endif From eb2bbf6f29a1b007fe9ddfdf66457823328f7c8e Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 22 Aug 2017 20:25:27 +0800 Subject: [PATCH 277/921] Renamed IsItemHoveredRect() to IsItemRectHovered(). Renamed IsMouseHoveringWindow() to IsWindowRectHovered() - follow up to previous commit 6be7d4904e1dd67810087f6986d683efe10dcbf9 merged from Nav. --- imconfig.h | 2 +- imgui.cpp | 11 ++++++----- imgui.h | 7 ++++--- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/imconfig.h b/imconfig.h index 19911acce..e557fa065 100644 --- a/imconfig.h +++ b/imconfig.h @@ -24,7 +24,7 @@ //---- It is very strongly recommended to NOT disable the test windows. Please read the comment at the top of imgui_demo.cpp to learn why. //#define IMGUI_DISABLE_TEST_WINDOWS -//---- Don't define obsolete functions names +//---- Don't define obsolete functions names. Consider enabling from time to time or when updating to reduce like hood of using already obsolete function/names //#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS //---- Pack colors to BGRA instead of RGBA (remove need to post process vertex buffer in back ends) diff --git a/imgui.cpp b/imgui.cpp index b4b52263d..ae182d851 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -204,8 +204,9 @@ Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. Also read releases logs https://github.com/ocornut/imgui/releases for more details. - - 2017/08/22 (1.51) - renamed IsMouseHoveringAnyWindow() to IsAnyWindowHovered() for consistency. Kept inline redirection function (will obsolete). - - renamed IsMouseHoveringWindow() to IsWindowHoveredRect() for consistency. Kept inline redirection function (will obsolete). + - 2017/08/22 (1.51) - renamed IsItemHoveredRect() to IsItemRectHovered(). Kept inline redirection function (will obsolete). + - renamed IsMouseHoveringAnyWindow() to IsAnyWindowHovered() for consistency. Kept inline redirection function (will obsolete). + - renamed IsMouseHoveringWindow() to IsWindowRectHovered() for consistency. Kept inline redirection function (will obsolete). - 2017/08/20 (1.51) - renamed GetStyleColName() to GetStyleColorName() for consistency. - 2017/08/20 (1.51) - added PushStyleColor(ImGuiCol idx, ImU32 col) overload, which _might_ cause an "ambiguous call" compilation error if you are using ImColor() with implicit cast. Cast to ImU32 or ImVec4 explicily to fix. - 2017/08/15 (1.51) - marked the weird IMGUI_ONCE_UPON_A_FRAME helper macro as obsolete. prefer using the more explicit ImGuiOnceUponAFrame. @@ -3110,7 +3111,7 @@ bool ImGui::IsMouseHoveringRect(const ImVec2& r_min, const ImVec2& r_max, bool c return rect_for_touch.Contains(g.IO.MousePos); } -bool ImGui::IsWindowHoveredRect() +bool ImGui::IsWindowRectHovered() { ImGuiContext& g = *GImGui; return g.HoveredWindow == g.CurrentWindow; @@ -3280,7 +3281,7 @@ bool ImGui::IsItemHovered() return window->DC.LastItemHoveredAndUsable; } -bool ImGui::IsItemHoveredRect() +bool ImGui::IsItemRectHovered() { ImGuiWindow* window = GetCurrentWindowRead(); return window->DC.LastItemHoveredRect; @@ -3597,7 +3598,7 @@ void ImGui::EndPopup() // This is a helper to handle the most simple case of associating one named popup to one given widget. // 1. If you have many possible popups (for different "instances" of a same widget, or for wholly different widgets), you may be better off handling // this yourself so you can store data relative to the widget that opened the popup instead of choosing different popup identifiers. -// 2. If you want right-clicking on the same item to reopen the popup at new location, use the same code replacing IsItemHovered() with IsItemHoveredRect() +// 2. If you want right-clicking on the same item to reopen the popup at new location, use the same code replacing IsItemHovered() with IsItemRectHovered() // and passing true to the OpenPopupEx(). // Because: hovering an item in a window below the popup won't normally trigger is hovering behavior/coloring. The pattern of ignoring the fact that // the item can be interacted with (because it is blocked by the active popup) may useful in some situation when e.g. large canvas as one item, content of menu diff --git a/imgui.h b/imgui.h index 84bb32e48..a6738b53c 100644 --- a/imgui.h +++ b/imgui.h @@ -409,7 +409,7 @@ namespace ImGui // Utilities IMGUI_API bool IsItemHovered(); // was the last item hovered by mouse? - IMGUI_API bool IsItemHoveredRect(); // was the last item hovered by mouse? even if another item is active or window is blocked by popup while we are hovering this + IMGUI_API bool IsItemRectHovered(); // was the last item hovered by mouse? even if another item is active or window is blocked by popup while we are hovering this IMGUI_API bool IsItemActive(); // was the last item active? (e.g. button being held, text field being edited- items that don't interact will always return false) IMGUI_API bool IsItemClicked(int mouse_button = 0); // was the last item clicked? (e.g. button/node just clicked on) IMGUI_API bool IsItemVisible(); // was the last item visible? (aka not out of sight due to clipping/scrolling.) @@ -421,7 +421,7 @@ namespace ImGui IMGUI_API void SetItemAllowOverlap(); // allow last item to be overlapped by a subsequent item. sometimes useful with invisible buttons, selectables, etc. to catch unused area. IMGUI_API bool IsWindowFocused(); // is current window focused IMGUI_API bool IsWindowHovered(); // is current window hovered and hoverable (not blocked by a popup) (differentiate child windows from each others) - IMGUI_API bool IsWindowHoveredRect(); // is current window hovered, disregarding of any consideration of being blocked by a popup. (unlike IsWindowHovered() this will return true even if the window is blocked because of a popup) + IMGUI_API bool IsWindowRectHovered(); // is current window rectnagle hovered, disregarding of any consideration of being blocked by a popup. (unlike IsWindowHovered() this will return true even if the window is blocked because of a popup) IMGUI_API bool IsRootWindowFocused(); // is current root window focused (root = top-most parent of a child, otherwise self) IMGUI_API bool IsRootWindowOrAnyChildFocused(); // is current root window or any of its child (including current window) focused IMGUI_API bool IsRootWindowOrAnyChildHovered(); // is current root window or any of its child (including current window) hovered and hoverable (not blocked by a popup) @@ -479,9 +479,10 @@ namespace ImGui // Obsolete functions (Will be removed! Also see 'API BREAKING CHANGES' section in imgui.cpp) #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS + static inline bool IsItemHoveredRect() { return IsItemRectHovered(); } // OBSOLETE 1.51+ static inline bool IsPosHoveringAnyWindow(const ImVec2&) { IM_ASSERT(0); return false; } // OBSOLETE 1.51+. This was partly broken. You probably wanted to use ImGui::GetIO().WantCaptureMouse instead. static inline bool IsMouseHoveringAnyWindow() { return IsAnyWindowHovered(); } // OBSOLETE 1.51+ - static inline bool IsMouseHoveringWindow() { return IsWindowHoveredRect(); } // OBSOLETE 1.51+ + static inline bool IsMouseHoveringWindow() { return IsWindowRectHovered(); } // OBSOLETE 1.51+ static inline bool CollapsingHeader(const char* label, const char* str_id, bool framed = true, bool default_open = false) { (void)str_id; (void)framed; ImGuiTreeNodeFlags default_open_flags = 1<<5; return CollapsingHeader(label, (default_open ? default_open_flags : 0)); } // OBSOLETE 1.49+ static inline ImFont* GetWindowFont() { return GetFont(); } // OBSOLETE 1.48+ static inline float GetWindowFontSize() { return GetFontSize(); } // OBSOLETE 1.48+ From 92efa00bc995d3e0b5d1c88600b9ec3d0ec3cb92 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 22 Aug 2017 20:44:39 +0800 Subject: [PATCH 278/921] Minor miscellaneous merges from Navigation branch to reduce divergence a little bit --- imgui.cpp | 82 +++++++++++++++++++++++++++++++------------------------ 1 file changed, 46 insertions(+), 36 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index ae182d851..2ed147df6 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3111,12 +3111,6 @@ bool ImGui::IsMouseHoveringRect(const ImVec2& r_min, const ImVec2& r_max, bool c return rect_for_touch.Contains(g.IO.MousePos); } -bool ImGui::IsWindowRectHovered() -{ - ImGuiContext& g = *GImGui; - return g.HoveredWindow == g.CurrentWindow; -} - bool ImGui::IsAnyWindowHovered() { ImGuiContext& g = *GImGui; @@ -4876,6 +4870,12 @@ bool ImGui::IsWindowHovered() return g.HoveredWindow == g.CurrentWindow && IsWindowContentHoverable(g.HoveredRootWindow); } +bool ImGui::IsWindowRectHovered() +{ + ImGuiContext& g = *GImGui; + return g.HoveredWindow == g.CurrentWindow; +} + bool ImGui::IsWindowFocused() { ImGuiContext& g = *GImGui; @@ -4921,7 +4921,7 @@ ImVec2 ImGui::GetWindowPos() static void SetWindowScrollY(ImGuiWindow* window, float new_scroll_y) { - window->DC.CursorMaxPos.y += window->Scroll.y; + window->DC.CursorMaxPos.y += window->Scroll.y; // SizeContents is generally computed based on CursorMaxPos which is affected by scroll position, so we need to apply our change to it. window->Scroll.y = new_scroll_y; window->DC.CursorMaxPos.y -= window->Scroll.y; } @@ -5550,8 +5550,8 @@ static inline bool IsWindowContentHoverable(ImGuiWindow* window) // An active popup disable hovering on other windows (apart from its own children) // FIXME-OPT: This could be cached/stored within the window. ImGuiContext& g = *GImGui; - if (ImGuiWindow* focused_window = g.NavWindow) - if (ImGuiWindow* focused_root_window = focused_window->RootWindow) + if (g.NavWindow) + if (ImGuiWindow* focused_root_window = g.NavWindow->RootWindow) if ((focused_root_window->Flags & ImGuiWindowFlags_Popup) != 0 && focused_root_window->WasActive && focused_root_window != window->RootWindow) return false; @@ -6549,13 +6549,23 @@ bool ImGui::SliderBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v bool value_changed = false; if (g.ActiveId == id) { + bool set_new_value = false; + float clicked_t = 0.0f; if (g.IO.MouseDown[0]) { const float mouse_abs_pos = is_horizontal ? g.IO.MousePos.x : g.IO.MousePos.y; - float clicked_t = (slider_usable_sz > 0.0f) ? ImClamp((mouse_abs_pos - slider_usable_pos_min) / slider_usable_sz, 0.0f, 1.0f) : 0.0f; + clicked_t = (slider_usable_sz > 0.0f) ? ImClamp((mouse_abs_pos - slider_usable_pos_min) / slider_usable_sz, 0.0f, 1.0f) : 0.0f; if (!is_horizontal) clicked_t = 1.0f - clicked_t; + set_new_value = true; + } + else + { + ClearActiveID(); + } + if (set_new_value) + { float new_value; if (is_non_linear) { @@ -6593,10 +6603,6 @@ bool ImGui::SliderBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v value_changed = true; } } - else - { - ClearActiveID(); - } } // Draw @@ -6864,32 +6870,32 @@ bool ImGui::DragBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v_s g.DragLastMouseDelta = ImVec2(0.f, 0.f); } + if (v_speed == 0.0f && (v_max - v_min) != 0.0f && (v_max - v_min) < FLT_MAX) + v_speed = (v_max - v_min) * g.DragSpeedDefaultRatio; float v_cur = g.DragCurrentValue; const ImVec2 mouse_drag_delta = GetMouseDragDelta(0, 1.0f); if (fabsf(mouse_drag_delta.x - g.DragLastMouseDelta.x) > 0.0f) { float speed = v_speed; - if (speed == 0.0f && (v_max - v_min) != 0.0f && (v_max - v_min) < FLT_MAX) - speed = (v_max - v_min) * g.DragSpeedDefaultRatio; if (g.IO.KeyShift && g.DragSpeedScaleFast >= 0.0f) speed = speed * g.DragSpeedScaleFast; if (g.IO.KeyAlt && g.DragSpeedScaleSlow >= 0.0f) speed = speed * g.DragSpeedScaleSlow; - float delta = (mouse_drag_delta.x - g.DragLastMouseDelta.x) * speed; + float adjust_delta = (mouse_drag_delta.x - g.DragLastMouseDelta.x) * speed; if (fabsf(power - 1.0f) > 0.001f) { // Logarithmic curve on both side of 0.0 float v0_abs = v_cur >= 0.0f ? v_cur : -v_cur; float v0_sign = v_cur >= 0.0f ? 1.0f : -1.0f; - float v1 = powf(v0_abs, 1.0f / power) + (delta * v0_sign); + float v1 = powf(v0_abs, 1.0f / power) + (adjust_delta * v0_sign); float v1_abs = v1 >= 0.0f ? v1 : -v1; float v1_sign = v1 >= 0.0f ? 1.0f : -1.0f; // Crossed sign line v_cur = powf(v1_abs, power) * v0_sign * v1_sign; // Reapply sign } else { - v_cur += delta; + v_cur += adjust_delta; } g.DragLastMouseDelta.x = mouse_drag_delta.x; @@ -8504,7 +8510,6 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi const float arrow_size = (g.FontSize + style.FramePadding.x * 2.0f); const bool hovered = IsHovered(frame_bb, id); bool popup_open = IsPopupOpen(id); - bool popup_opened_now = false; const ImRect value_bb(frame_bb.Min, frame_bb.Max - ImVec2(arrow_size, 0.0f)); RenderFrame(frame_bb.Min, frame_bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding); @@ -8521,22 +8526,27 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi if (label_size.x > 0) RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label); + bool popup_toggled = false; if (hovered) { SetHoveredID(id); if (g.IO.MouseClicked[0]) { ClearActiveID(); - if (IsPopupOpen(id)) - { - ClosePopup(id); - } - else - { - FocusWindow(window); - OpenPopup(label); - popup_open = popup_opened_now = true; - } + popup_toggled = true; + } + } + if (popup_toggled) + { + if (IsPopupOpen(id)) + { + ClosePopup(id); + } + else + { + FocusWindow(window); + OpenPopup(label); + popup_open = true; } } @@ -8580,7 +8590,7 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi value_changed = true; *current_item = i; } - if (item_selected && popup_opened_now) + if (item_selected && popup_toggled) SetScrollHere(); PopID(); } @@ -8885,13 +8895,13 @@ bool ImGui::BeginMenu(const char* label, bool enabled) const ImGuiID id = window->GetID(label); ImVec2 label_size = CalcTextSize(label, NULL, true); - ImGuiWindow* backed_focused_window = g.NavWindow; bool pressed; bool menu_is_open = IsPopupOpen(id); bool menuset_is_open = !(window->Flags & ImGuiWindowFlags_Popup) && (g.OpenPopupStack.Size > g.CurrentPopupStack.Size && g.OpenPopupStack[g.CurrentPopupStack.Size].ParentMenuSet == window->GetID("##menus")); + ImGuiWindow* backed_nav_window = g.NavWindow; if (menuset_is_open) - g.NavWindow = window; + g.NavWindow = window; // Odd hack to allow hovering across menus of a same menu-set (otherwise we wouldn't be able to hover parent) // The reference position stored in popup_pos will be used by Begin() to find a suitable position for the child menu (using FindBestPopupWindowPos). ImVec2 popup_pos, pos = window->DC.CursorPos; @@ -8919,7 +8929,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled) bool hovered = enabled && IsHovered(window->DC.LastItemRect, id); if (menuset_is_open) - g.NavWindow = backed_focused_window; + g.NavWindow = backed_nav_window; bool want_open = false, want_close = false; if (window->Flags & (ImGuiWindowFlags_Popup|ImGuiWindowFlags_ChildMenu)) @@ -8946,7 +8956,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled) want_close = (menu_is_open && !hovered && g.HoveredWindow == window && g.HoveredIdPreviousFrame != 0 && g.HoveredIdPreviousFrame != id && !moving_within_opened_triangle); want_open = (!menu_is_open && hovered && !moving_within_opened_triangle) || (!menu_is_open && hovered && pressed); } - else if (menu_is_open && pressed && menuset_is_open) // menu-bar: click open menu to close + else if (menu_is_open && pressed && menuset_is_open) // Menu bar: click an open menu again to close it { want_close = true; want_open = menu_is_open = false; @@ -10461,12 +10471,12 @@ void ImGui::ShowMetricsWindow(bool* p_open) } if (ImGui::TreeNode("Basic state")) { - ImGui::Text("FocusedWindow: '%s'", g.NavWindow ? g.NavWindow->Name : "NULL"); ImGui::Text("HoveredWindow: '%s'", g.HoveredWindow ? g.HoveredWindow->Name : "NULL"); ImGui::Text("HoveredRootWindow: '%s'", g.HoveredRootWindow ? g.HoveredRootWindow->Name : "NULL"); ImGui::Text("HoveredId: 0x%08X/0x%08X", g.HoveredId, g.HoveredIdPreviousFrame); // Data is "in-flight" so depending on when the Metrics window is called we may see current frame information or not ImGui::Text("ActiveId: 0x%08X/0x%08X", g.ActiveId, g.ActiveIdPreviousFrame); ImGui::Text("ActiveIdWindow: '%s'", g.ActiveIdWindow ? g.ActiveIdWindow->Name : "NULL"); + ImGui::Text("NavWindow: '%s'", g.NavWindow ? g.NavWindow->Name : "NULL"); ImGui::TreePop(); } } From d213c0eb7e3e934e36d72294f8e916543687b5ae Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 24 Aug 2017 17:30:10 +0800 Subject: [PATCH 279/921] Style: Tweaked default border (undo half-way from original c1e1e015c4a81c68812113d85dfdedbc598ff413) (#707) --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 2ed147df6..2640ebc64 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -700,7 +700,7 @@ ImGuiStyle::ImGuiStyle() Colors[ImGuiCol_WindowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.70f); Colors[ImGuiCol_ChildWindowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); Colors[ImGuiCol_PopupBg] = ImVec4(0.05f, 0.05f, 0.10f, 0.90f); - Colors[ImGuiCol_Border] = ImVec4(0.70f, 0.70f, 0.70f, 0.22f); + Colors[ImGuiCol_Border] = ImVec4(0.70f, 0.70f, 0.70f, 0.40f); Colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); Colors[ImGuiCol_FrameBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.30f); // Background of checkbox, radio button, plot, slider, text input Colors[ImGuiCol_FrameBgHovered] = ImVec4(0.90f, 0.80f, 0.80f, 0.40f); From 82c3116b4f2dc41be7bf66105a376666b8136ff9 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 24 Aug 2017 17:32:03 +0800 Subject: [PATCH 280/921] Demo: Displaying version number in test window. --- imgui_demo.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 8911bcf2a..8e20c6731 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -192,7 +192,7 @@ void ImGui::ShowTestWindow(bool* p_open) //ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.65f); // 2/3 of the space for widget and 1/3 for labels ImGui::PushItemWidth(-140); // Right align, keep 140 pixels for labels - ImGui::Text("Dear ImGui says hello."); + ImGui::Text("dear imgui says hello. (%s)", IMGUI_VERSION); // Menu if (ImGui::BeginMenuBar()) @@ -1575,6 +1575,7 @@ void ImGui::ShowTestWindow(bool* p_open) if (ImGui::TreeNode("Borders")) { + // NB: Future columns API should allow automatic horizontal borders. static bool h_borders = true; static bool v_borders = true; ImGui::Checkbox("horizontal", &h_borders); From 55a6209931a145dd012e85e6673e5ef6575948c9 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 25 Aug 2017 00:29:59 +0800 Subject: [PATCH 281/921] Version 1.51 --- imgui.cpp | 2 +- imgui.h | 4 ++-- imgui_demo.cpp | 2 +- imgui_draw.cpp | 2 +- imgui_internal.h | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 2640ebc64..26ed18260 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.51 WIP +// dear imgui, v1.51 // (main code and documentation) // See ImGui::ShowTestWindow() in imgui_demo.cpp for demo code. diff --git a/imgui.h b/imgui.h index a6738b53c..27a11fcfc 100644 --- a/imgui.h +++ b/imgui.h @@ -1,4 +1,4 @@ -// dear imgui, v1.51 WIP +// dear imgui, v1.51 // (headers) // See imgui.cpp file for documentation. @@ -16,7 +16,7 @@ #include // ptrdiff_t, NULL #include // memset, memmove, memcpy, strlen, strchr, strcpy, strcmp -#define IMGUI_VERSION "1.51 WIP" +#define IMGUI_VERSION "1.51" // Define attributes of all API symbols declarations, e.g. for DLL under Windows. #ifndef IMGUI_API diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 8e20c6731..8cdb5f2fb 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.51 WIP +// dear imgui, v1.51 // (demo code) // Message to the person tempted to delete this file when integrating ImGui into their code base: diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 8442bdd16..d01aa52d6 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.51 WIP +// dear imgui, v1.51 // (drawing and font code) // Contains implementation for diff --git a/imgui_internal.h b/imgui_internal.h index e59a27edb..cee3f7333 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1,4 +1,4 @@ -// dear imgui, v1.51 WIP +// dear imgui, v1.51 // (internals) // You may use this file to debug, understand or extend ImGui features but we don't provide any guarantee of forward compatibility! From 40f608ce9ba0530b7a504fa096f9b2a361589960 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 25 Aug 2017 15:12:12 +0800 Subject: [PATCH 282/921] Version 1.52 WIP --- imgui.cpp | 3 +-- imgui.h | 4 ++-- imgui_demo.cpp | 2 +- imgui_draw.cpp | 2 +- imgui_internal.h | 2 +- 5 files changed, 6 insertions(+), 7 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 26ed18260..a6eaea45a 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.51 +// dear imgui, v1.52 WIP // (main code and documentation) // See ImGui::ShowTestWindow() in imgui_demo.cpp for demo code. @@ -2151,7 +2151,6 @@ void ImGui::NewFrame() g.RenderDrawData.CmdLists = NULL; g.RenderDrawData.CmdListsCount = g.RenderDrawData.TotalVtxCount = g.RenderDrawData.TotalIdxCount = 0; - // Update mouse input state if (g.IO.MousePos.x < 0 && g.IO.MousePos.y < 0) g.IO.MousePos = ImVec2(-9999.0f, -9999.0f); diff --git a/imgui.h b/imgui.h index 27a11fcfc..8ec9a0fa7 100644 --- a/imgui.h +++ b/imgui.h @@ -1,4 +1,4 @@ -// dear imgui, v1.51 +// dear imgui, v1.52 WIP // (headers) // See imgui.cpp file for documentation. @@ -16,7 +16,7 @@ #include // ptrdiff_t, NULL #include // memset, memmove, memcpy, strlen, strchr, strcpy, strcmp -#define IMGUI_VERSION "1.51" +#define IMGUI_VERSION "1.52 WIP" // Define attributes of all API symbols declarations, e.g. for DLL under Windows. #ifndef IMGUI_API diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 8cdb5f2fb..6f7bd4db1 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.51 +// dear imgui, v1.52 WIP // (demo code) // Message to the person tempted to delete this file when integrating ImGui into their code base: diff --git a/imgui_draw.cpp b/imgui_draw.cpp index d01aa52d6..0f2345f5b 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.51 +// dear imgui, v1.52 WIP // (drawing and font code) // Contains implementation for diff --git a/imgui_internal.h b/imgui_internal.h index cee3f7333..df7357977 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1,4 +1,4 @@ -// dear imgui, v1.51 +// dear imgui, v1.52 WIP // (internals) // You may use this file to debug, understand or extend ImGui features but we don't provide any guarantee of forward compatibility! From 37f3a718c63e14f30cfa51a3050b35eba9b02f6f Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 25 Aug 2017 16:10:14 +0800 Subject: [PATCH 283/921] Marked all fmt + va_list functions with format attribute so GCC/Clang can warn about them. Not ignoring -Wsuggest-attribute=format anymore for GCC/Clang. --- imgui.cpp | 1 - imgui.h | 84 +++++++++++++++++++++++++----------------------- imgui_demo.cpp | 4 +-- imgui_internal.h | 4 +-- 4 files changed, 48 insertions(+), 45 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index a6eaea45a..5ce1e7237 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -582,7 +582,6 @@ #pragma GCC diagnostic ignored "-Wconversion" // warning: conversion to 'xxxx' from 'xxxx' may alter its value #pragma GCC diagnostic ignored "-Wcast-qual" // warning: cast from type 'xxxx' to type 'xxxx' casts away qualifiers #pragma GCC diagnostic ignored "-Wformat-nonliteral" // warning: format not a string literal, format string not checked -#pragma GCC diagnostic ignored "-Wsuggest-attribute=format" #endif //------------------------------------------------------------------------- diff --git a/imgui.h b/imgui.h index 8ec9a0fa7..d9fd8c83b 100644 --- a/imgui.h +++ b/imgui.h @@ -31,9 +31,11 @@ // Some compilers support applying printf-style warnings to user functions. #if defined(__clang__) || defined(__GNUC__) -#define IM_PRINTFARGS(FMT) __attribute__((format(printf, FMT, (FMT+1)))) +#define IM_FMTARGS(FMT) __attribute__((format(printf, FMT, FMT+1))) +#define IM_FMTLIST(FMT) __attribute__((format(printf, FMT, 0))) #else -#define IM_PRINTFARGS(FMT) +#define IM_FMTARGS(FMT) +#define IM_FMTLIST(FMT) #endif #if defined(__clang__) @@ -233,43 +235,45 @@ namespace ImGui // Columns // You can also use SameLine(pos_x) for simplified columns. The columns API is still work-in-progress and rather lacking. IMGUI_API void Columns(int count = 1, const char* id = NULL, bool border = true); - IMGUI_API void NextColumn(); // next column, defaults to current row or next row if the current row is finished - IMGUI_API int GetColumnIndex(); // get current column index - IMGUI_API float GetColumnWidth(int column_index = -1); // get column width (in pixels). pass -1 to use current column - IMGUI_API void SetColumnWidth(int column_index, float width); // set column width (in pixels). pass -1 to use current column - IMGUI_API float GetColumnOffset(int column_index = -1); // get position of column line (in pixels, from the left side of the contents region). pass -1 to use current column, otherwise 0..GetColumnsCount() inclusive. column 0 is typically 0.0f - IMGUI_API void SetColumnOffset(int column_index, float offset_x); // set position of column line (in pixels, from the left side of the contents region). pass -1 to use current column + IMGUI_API void NextColumn(); // next column, defaults to current row or next row if the current row is finished + IMGUI_API int GetColumnIndex(); // get current column index + IMGUI_API float GetColumnWidth(int column_index = -1); // get column width (in pixels). pass -1 to use current column + IMGUI_API void SetColumnWidth(int column_index, float width); // set column width (in pixels). pass -1 to use current column + IMGUI_API float GetColumnOffset(int column_index = -1); // get position of column line (in pixels, from the left side of the contents region). pass -1 to use current column, otherwise 0..GetColumnsCount() inclusive. column 0 is typically 0.0f + IMGUI_API void SetColumnOffset(int column_index, float offset_x); // set position of column line (in pixels, from the left side of the contents region). pass -1 to use current column IMGUI_API int GetColumnsCount(); // ID scopes - // If you are creating widgets in a loop you most likely want to push a unique identifier so ImGui can differentiate them. + // If you are creating widgets in a loop you most likely want to push a unique identifier (e.g. object pointer, loop index) so ImGui can differentiate them. // You can also use the "##foobar" syntax within widget label to distinguish them from each others. Read "A primer on the use of labels/IDs" in the FAQ for more details. - IMGUI_API void PushID(const char* str_id); // push identifier into the ID stack. IDs are hash of the *entire* stack! + IMGUI_API void PushID(const char* str_id); // push identifier into the ID stack. IDs are hash of the entire stack! IMGUI_API void PushID(const char* str_id_begin, const char* str_id_end); IMGUI_API void PushID(const void* ptr_id); IMGUI_API void PushID(int int_id); IMGUI_API void PopID(); - IMGUI_API ImGuiID GetID(const char* str_id); // calculate unique ID (hash of whole ID stack + given parameter). useful if you want to query into ImGuiStorage yourself + IMGUI_API ImGuiID GetID(const char* str_id); // calculate unique ID (hash of whole ID stack + given parameter). e.g. if you want to query into ImGuiStorage yourself IMGUI_API ImGuiID GetID(const char* str_id_begin, const char* str_id_end); IMGUI_API ImGuiID GetID(const void* ptr_id); - // Widgets - IMGUI_API void Text(const char* fmt, ...) IM_PRINTFARGS(1); - IMGUI_API void TextV(const char* fmt, va_list args); - IMGUI_API void TextColored(const ImVec4& col, const char* fmt, ...) IM_PRINTFARGS(2); // shortcut for PushStyleColor(ImGuiCol_Text, col); Text(fmt, ...); PopStyleColor(); - IMGUI_API void TextColoredV(const ImVec4& col, const char* fmt, va_list args); - IMGUI_API void TextDisabled(const char* fmt, ...) IM_PRINTFARGS(1); // shortcut for PushStyleColor(ImGuiCol_Text, style.Colors[ImGuiCol_TextDisabled]); Text(fmt, ...); PopStyleColor(); - IMGUI_API void TextDisabledV(const char* fmt, va_list args); - IMGUI_API void TextWrapped(const char* fmt, ...) IM_PRINTFARGS(1); // shortcut for PushTextWrapPos(0.0f); Text(fmt, ...); PopTextWrapPos();. Note that this won't work on an auto-resizing window if there's no other widgets to extend the window width, yoy may need to set a size using SetNextWindowSize(). - IMGUI_API void TextWrappedV(const char* fmt, va_list args); - IMGUI_API void TextUnformatted(const char* text, const char* text_end = NULL); // doesn't require null terminated string if 'text_end' is specified. no copy done to any bounded stack buffer, recommended for long chunks of text - IMGUI_API void LabelText(const char* label, const char* fmt, ...) IM_PRINTFARGS(2); // display text+label aligned the same way as value+label widgets - IMGUI_API void LabelTextV(const char* label, const char* fmt, va_list args); - IMGUI_API void Bullet(); // draw a small circle and keep the cursor on the same line. advance cursor x position by GetTreeNodeToLabelSpacing(), same distance that TreeNode() uses - IMGUI_API void BulletText(const char* fmt, ...) IM_PRINTFARGS(1); // shortcut for Bullet()+Text() - IMGUI_API void BulletTextV(const char* fmt, va_list args); + // Widgets: Text + IMGUI_API void TextUnformatted(const char* text, const char* text_end = NULL); // doesn't require null terminated string if 'text_end' is specified. no copy done, no limits, recommended for long chunks of text + IMGUI_API void Text(const char* fmt, ...) IM_FMTARGS(1); // simple formatted text + IMGUI_API void TextV(const char* fmt, va_list args) IM_FMTLIST(1); + IMGUI_API void TextColored(const ImVec4& col, const char* fmt, ...) IM_FMTARGS(2); // shortcut for PushStyleColor(ImGuiCol_Text, col); Text(fmt, ...); PopStyleColor(); + IMGUI_API void TextColoredV(const ImVec4& col, const char* fmt, va_list args) IM_FMTLIST(2); + IMGUI_API void TextDisabled(const char* fmt, ...) IM_FMTARGS(1); // shortcut for PushStyleColor(ImGuiCol_Text, style.Colors[ImGuiCol_TextDisabled]); Text(fmt, ...); PopStyleColor(); + IMGUI_API void TextDisabledV(const char* fmt, va_list args) IM_FMTLIST(1); + IMGUI_API void TextWrapped(const char* fmt, ...) IM_FMTARGS(1); // shortcut for PushTextWrapPos(0.0f); Text(fmt, ...); PopTextWrapPos();. Note that this won't work on an auto-resizing window if there's no other widgets to extend the window width, yoy may need to set a size using SetNextWindowSize(). + IMGUI_API void TextWrappedV(const char* fmt, va_list args) IM_FMTLIST(1); + IMGUI_API void LabelText(const char* label, const char* fmt, ...) IM_FMTARGS(2); // display text+label aligned the same way as value+label widgets + IMGUI_API void LabelTextV(const char* label, const char* fmt, va_list args) IM_FMTLIST(2); + IMGUI_API void BulletText(const char* fmt, ...) IM_FMTARGS(1); // shortcut for Bullet()+Text() + IMGUI_API void BulletTextV(const char* fmt, va_list args) IM_FMTLIST(1); + IMGUI_API void Bullet(); // draw a small circle and keep the cursor on the same line. advance cursor x position by GetTreeNodeToLabelSpacing(), same distance that TreeNode() uses + + // Widgets: Main IMGUI_API bool Button(const char* label, const ImVec2& size = ImVec2(0,0)); // button - IMGUI_API bool SmallButton(const char* label); // button with FramePadding=(0,0) to easily embed in text + IMGUI_API bool SmallButton(const char* label); // button with FramePadding=(0,0) to easily embed within text IMGUI_API bool InvisibleButton(const char* str_id, const ImVec2& size); IMGUI_API void Image(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0,0), const ImVec2& uv1 = ImVec2(1,1), const ImVec4& tint_col = ImVec4(1,1,1,1), const ImVec4& border_col = ImVec4(0,0,0,0)); IMGUI_API bool ImageButton(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0,0), const ImVec2& uv1 = ImVec2(1,1), int frame_padding = -1, const ImVec4& bg_col = ImVec4(0,0,0,0), const ImVec4& tint_col = ImVec4(1,1,1,1)); // <0 frame_padding uses default frame padding settings. 0 for no padding @@ -335,15 +339,15 @@ namespace ImGui // Widgets: Trees IMGUI_API bool TreeNode(const char* label); // if returning 'true' the node is open and the tree id is pushed into the id stack. user is responsible for calling TreePop(). - IMGUI_API bool TreeNode(const char* str_id, const char* fmt, ...) IM_PRINTFARGS(2); // read the FAQ about why and how to use ID. to align arbitrary text at the same level as a TreeNode() you can use Bullet(). - IMGUI_API bool TreeNode(const void* ptr_id, const char* fmt, ...) IM_PRINTFARGS(2); // " - IMGUI_API bool TreeNodeV(const char* str_id, const char* fmt, va_list args); // " - IMGUI_API bool TreeNodeV(const void* ptr_id, const char* fmt, va_list args); // " + IMGUI_API bool TreeNode(const char* str_id, const char* fmt, ...) IM_FMTARGS(2); // read the FAQ about why and how to use ID. to align arbitrary text at the same level as a TreeNode() you can use Bullet(). + IMGUI_API bool TreeNode(const void* ptr_id, const char* fmt, ...) IM_FMTARGS(2); // " + IMGUI_API bool TreeNodeV(const char* str_id, const char* fmt, va_list args) IM_FMTLIST(2); + IMGUI_API bool TreeNodeV(const void* ptr_id, const char* fmt, va_list args) IM_FMTLIST(2); IMGUI_API bool TreeNodeEx(const char* label, ImGuiTreeNodeFlags flags = 0); - IMGUI_API bool TreeNodeEx(const char* str_id, ImGuiTreeNodeFlags flags, const char* fmt, ...) IM_PRINTFARGS(3); - IMGUI_API bool TreeNodeEx(const void* ptr_id, ImGuiTreeNodeFlags flags, const char* fmt, ...) IM_PRINTFARGS(3); - IMGUI_API bool TreeNodeExV(const char* str_id, ImGuiTreeNodeFlags flags, const char* fmt, va_list args); - IMGUI_API bool TreeNodeExV(const void* ptr_id, ImGuiTreeNodeFlags flags, const char* fmt, va_list args); + IMGUI_API bool TreeNodeEx(const char* str_id, ImGuiTreeNodeFlags flags, const char* fmt, ...) IM_FMTARGS(3); + IMGUI_API bool TreeNodeEx(const void* ptr_id, ImGuiTreeNodeFlags flags, const char* fmt, ...) IM_FMTARGS(3); + IMGUI_API bool TreeNodeExV(const char* str_id, ImGuiTreeNodeFlags flags, const char* fmt, va_list args) IM_FMTLIST(3); + IMGUI_API bool TreeNodeExV(const void* ptr_id, ImGuiTreeNodeFlags flags, const char* fmt, va_list args) IM_FMTLIST(3); IMGUI_API void TreePush(const char* str_id = NULL); // ~ Indent()+PushId(). Already called by TreeNode() when returning true, but you can call Push/Pop yourself for layout purpose IMGUI_API void TreePush(const void* ptr_id = NULL); // " IMGUI_API void TreePop(); // ~ Unindent()+PopId() @@ -369,8 +373,8 @@ namespace ImGui IMGUI_API void Value(const char* prefix, float v, const char* float_format = NULL); // Tooltips - IMGUI_API void SetTooltip(const char* fmt, ...) IM_PRINTFARGS(1); // set text tooltip under mouse-cursor, typically use with ImGui::IsItemHovered(). overidde any previous call to SetTooltip(). - IMGUI_API void SetTooltipV(const char* fmt, va_list args); + IMGUI_API void SetTooltip(const char* fmt, ...) IM_FMTARGS(1); // set text tooltip under mouse-cursor, typically use with ImGui::IsItemHovered(). overidde any previous call to SetTooltip(). + IMGUI_API void SetTooltipV(const char* fmt, va_list args) IM_FMTLIST(1); IMGUI_API void BeginTooltip(); // begin/append a tooltip window. to create full-featured tooltip (with any kind of contents). IMGUI_API void EndTooltip(); @@ -401,7 +405,7 @@ namespace ImGui IMGUI_API void LogToClipboard(int max_depth = -1); // start logging to OS clipboard IMGUI_API void LogFinish(); // stop logging (close file, etc.) IMGUI_API void LogButtons(); // helper to display buttons for logging to tty/file/clipboard - IMGUI_API void LogText(const char* fmt, ...) IM_PRINTFARGS(1); // pass text data straight to log (without being displayed) + IMGUI_API void LogText(const char* fmt, ...) IM_FMTARGS(1); // pass text data straight to log (without being displayed) // Clipping IMGUI_API void PushClipRect(const ImVec2& clip_rect_min, const ImVec2& clip_rect_max, bool intersect_with_current_clip_rect); @@ -996,8 +1000,8 @@ struct ImGuiTextBuffer bool empty() { return Buf.Size <= 1; } void clear() { Buf.clear(); Buf.push_back(0); } const char* c_str() const { return Buf.Data; } - IMGUI_API void append(const char* fmt, ...) IM_PRINTFARGS(2); - IMGUI_API void appendv(const char* fmt, va_list args); + IMGUI_API void append(const char* fmt, ...) IM_FMTARGS(2); + IMGUI_API void appendv(const char* fmt, va_list args) IM_FMTLIST(2); }; // Helper: Simple Key->value storage diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 6f7bd4db1..abf89f349 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -2298,7 +2298,7 @@ struct ExampleAppConsole ScrollToBottom = true; } - void AddLog(const char* fmt, ...) IM_PRINTFARGS(2) + void AddLog(const char* fmt, ...) IM_FMTARGS(2) { char buf[1024]; va_list args; @@ -2560,7 +2560,7 @@ struct ExampleAppLog void Clear() { Buf.clear(); LineOffsets.clear(); } - void AddLog(const char* fmt, ...) IM_PRINTFARGS(2) + void AddLog(const char* fmt, ...) IM_FMTARGS(2) { int old_size = Buf.size(); va_list args; diff --git a/imgui_internal.h b/imgui_internal.h index df7357977..b38101876 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -109,8 +109,8 @@ IMGUI_API char* ImStrdup(const char* str); IMGUI_API int ImStrlenW(const ImWchar* str); IMGUI_API const ImWchar*ImStrbolW(const ImWchar* buf_mid_line, const ImWchar* buf_begin); // Find beginning-of-line IMGUI_API const char* ImStristr(const char* haystack, const char* haystack_end, const char* needle, const char* needle_end); -IMGUI_API int ImFormatString(char* buf, int buf_size, const char* fmt, ...) IM_PRINTFARGS(3); -IMGUI_API int ImFormatStringV(char* buf, int buf_size, const char* fmt, va_list args); +IMGUI_API int ImFormatString(char* buf, int buf_size, const char* fmt, ...) IM_FMTARGS(3); +IMGUI_API int ImFormatStringV(char* buf, int buf_size, const char* fmt, va_list args) IM_FMTLIST(3); // Helpers: Math // We are keeping those not leaking to the user by default, in the case the user has implicit cast operators between ImVec2 and its own types (when IM_VEC2_CLASS_EXTRA is defined) From 92a6faca6f5a5abce8c4671fb0e55ed2e422eda2 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 25 Aug 2017 16:43:25 +0800 Subject: [PATCH 284/921] IO: io.MousePos needs to be set to ImVec2(-FLT_MAX,-FLT_MAX) when mouse is unavailable/missing. Previously ImVec2(-1,-1) was enough but we'll now accept negative mouse coordinates. --- examples/allegro5_example/imgui_impl_a5.cpp | 2 +- examples/opengl2_example/imgui_impl_glfw.cpp | 2 +- examples/opengl3_example/imgui_impl_glfw_gl3.cpp | 2 +- examples/sdl_opengl2_example/imgui_impl_sdl.cpp | 2 +- examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp | 2 +- examples/vulkan_example/imgui_impl_glfw_vulkan.cpp | 2 +- imgui.cpp | 11 ++++++----- imgui.h | 2 +- 8 files changed, 13 insertions(+), 12 deletions(-) diff --git a/examples/allegro5_example/imgui_impl_a5.cpp b/examples/allegro5_example/imgui_impl_a5.cpp index 9a04ff9c1..6f5b7b061 100644 --- a/examples/allegro5_example/imgui_impl_a5.cpp +++ b/examples/allegro5_example/imgui_impl_a5.cpp @@ -262,7 +262,7 @@ void ImGui_ImplA5_NewFrame() } else { - io.MousePos = ImVec2(-1, -1); + io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); } al_get_mouse_state(&mouse); diff --git a/examples/opengl2_example/imgui_impl_glfw.cpp b/examples/opengl2_example/imgui_impl_glfw.cpp index 435de7a81..f85fb5c4c 100644 --- a/examples/opengl2_example/imgui_impl_glfw.cpp +++ b/examples/opengl2_example/imgui_impl_glfw.cpp @@ -272,7 +272,7 @@ void ImGui_ImplGlfw_NewFrame() } else { - io.MousePos = ImVec2(-1,-1); + io.MousePos = ImVec2(-FLT_MAX,-FLT_MAX); } for (int i = 0; i < 3; i++) diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp index a9a45e105..ff96b88a2 100644 --- a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp +++ b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp @@ -383,7 +383,7 @@ void ImGui_ImplGlfwGL3_NewFrame() } else { - io.MousePos = ImVec2(-1,-1); + io.MousePos = ImVec2(-FLT_MAX,-FLT_MAX); } for (int i = 0; i < 3; i++) diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl.cpp b/examples/sdl_opengl2_example/imgui_impl_sdl.cpp index 04b6a9a39..a8338cecc 100644 --- a/examples/sdl_opengl2_example/imgui_impl_sdl.cpp +++ b/examples/sdl_opengl2_example/imgui_impl_sdl.cpp @@ -265,7 +265,7 @@ void ImGui_ImplSdl_NewFrame(SDL_Window *window) if (SDL_GetWindowFlags(window) & SDL_WINDOW_MOUSE_FOCUS) io.MousePos = ImVec2((float)mx, (float)my); // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.) else - io.MousePos = ImVec2(-1,-1); + io.MousePos = ImVec2(-FLT_MAX,-FLT_MAX); io.MouseDown[0] = g_MousePressed[0] || (mouseMask & SDL_BUTTON(SDL_BUTTON_LEFT)) != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. io.MouseDown[1] = g_MousePressed[1] || (mouseMask & SDL_BUTTON(SDL_BUTTON_RIGHT)) != 0; diff --git a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp index 59101e938..1861edae0 100644 --- a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp +++ b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp @@ -377,7 +377,7 @@ void ImGui_ImplSdlGL3_NewFrame(SDL_Window* window) if (SDL_GetWindowFlags(window) & SDL_WINDOW_MOUSE_FOCUS) io.MousePos = ImVec2((float)mx, (float)my); // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.) else - io.MousePos = ImVec2(-1, -1); + io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); io.MouseDown[0] = g_MousePressed[0] || (mouseMask & SDL_BUTTON(SDL_BUTTON_LEFT)) != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. io.MouseDown[1] = g_MousePressed[1] || (mouseMask & SDL_BUTTON(SDL_BUTTON_RIGHT)) != 0; diff --git a/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp b/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp index d43929f6a..90f783278 100644 --- a/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp +++ b/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp @@ -815,7 +815,7 @@ void ImGui_ImplGlfwVulkan_NewFrame() } else { - io.MousePos = ImVec2(-1,-1); + io.MousePos = ImVec2(-FLT_MAX,-FLT_MAX); } for (int i = 0; i < 3; i++) diff --git a/imgui.cpp b/imgui.cpp index 5ce1e7237..be7b018d5 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -204,6 +204,7 @@ Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. Also read releases logs https://github.com/ocornut/imgui/releases for more details. + - 2017/08/25 (1.52) - io.MousePos needs to be set to ImVec2(-FLT_MAX,-FLT_MAX) when mouse is unavailable/missing. Previously ImVec2(-1,-1) was enough but we now accept negative mouse coordinates. In your binding if you need to support unavailable mouse, make sure to replace "io.MousePos = ImVec2(-1,-1)" with "io.MousePos = ImVec2(-FLT_MAX,-FLT_MAX)". - 2017/08/22 (1.51) - renamed IsItemHoveredRect() to IsItemRectHovered(). Kept inline redirection function (will obsolete). - renamed IsMouseHoveringAnyWindow() to IsAnyWindowHovered() for consistency. Kept inline redirection function (will obsolete). - renamed IsMouseHoveringWindow() to IsWindowRectHovered() for consistency. Kept inline redirection function (will obsolete). @@ -754,8 +755,8 @@ ImGuiIO::ImGuiIO() FontGlobalScale = 1.0f; FontDefault = NULL; DisplayFramebufferScale = ImVec2(1.0f, 1.0f); - MousePos = ImVec2(-1,-1); - MousePosPrev = ImVec2(-1,-1); + MousePos = ImVec2(-FLT_MAX, -FLT_MAX); + MousePosPrev = ImVec2(-FLT_MAX, -FLT_MAX); MouseDoubleClickTime = 0.30f; MouseDoubleClickMaxDist = 6.0f; MouseDragThreshold = 6.0f; @@ -2151,9 +2152,9 @@ void ImGui::NewFrame() g.RenderDrawData.CmdListsCount = g.RenderDrawData.TotalVtxCount = g.RenderDrawData.TotalIdxCount = 0; // Update mouse input state - if (g.IO.MousePos.x < 0 && g.IO.MousePos.y < 0) - g.IO.MousePos = ImVec2(-9999.0f, -9999.0f); - if ((g.IO.MousePos.x < 0 && g.IO.MousePos.y < 0) || (g.IO.MousePosPrev.x < 0 && g.IO.MousePosPrev.y < 0)) // if mouse just appeared or disappeared (negative coordinate) we cancel out movement in MouseDelta + // If mouse just appeared or disappeared (usually denoted by -FLT_MAX component, but in reality we test for -256000.0f) we cancel out movement in MouseDelta + const float MOUSE_INVALID = -256000.0f; + if ((g.IO.MousePos.x < MOUSE_INVALID && g.IO.MousePos.y < MOUSE_INVALID) || (g.IO.MousePosPrev.x < MOUSE_INVALID && g.IO.MousePosPrev.y < MOUSE_INVALID)) g.IO.MouseDelta = ImVec2(0.0f, 0.0f); else g.IO.MouseDelta = g.IO.MousePos - g.IO.MousePosPrev; diff --git a/imgui.h b/imgui.h index d9fd8c83b..61227e020 100644 --- a/imgui.h +++ b/imgui.h @@ -828,7 +828,7 @@ struct ImGuiIO // Input - Fill before calling NewFrame() //------------------------------------------------------------------ - ImVec2 MousePos; // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.) + ImVec2 MousePos; // Mouse position, in pixels. Set to ImVec2(-FLT_MAX,-FLT_MAX) if mouse is unavailable (on another screen, etc.) bool MouseDown[5]; // Mouse buttons: left, right, middle + extras. ImGui itself mostly only uses left button (BeginPopupContext** are using right button). Others buttons allows us to track if the mouse is being used by your application + available to user as a convenience via IsMouse** API. float MouseWheel; // Mouse wheel: 1 unit scrolls about 5 lines text. bool MouseDrawCursor; // Request ImGui to draw a mouse cursor for you (if you are on a platform without a mouse cursor). From a02210a455b2899f3fc01d7f57a3c6bdd77ef38a Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 26 Aug 2017 00:31:17 +0800 Subject: [PATCH 285/921] Fixed compilation with IMGUI_DISABLE_OBSOLETE_FUNCTIONS defined --- imgui.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index be7b018d5..9f8a0c5fc 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3607,7 +3607,7 @@ bool ImGui::BeginPopupContextWindow(const char* str_id, int mouse_button, bool a { if (!str_id) str_id = "window_context"; - if (IsMouseHoveringWindow() && IsMouseClicked(mouse_button)) + if (IsWindowRectHovered() && IsMouseClicked(mouse_button)) if (also_over_items || !IsAnyItemHovered()) OpenPopupEx(GImGui->CurrentWindow->GetID(str_id), true); return BeginPopup(str_id); @@ -3617,7 +3617,7 @@ bool ImGui::BeginPopupContextVoid(const char* str_id, int mouse_button) { if (!str_id) str_id = "void_context"; - if (!IsMouseHoveringAnyWindow() && IsMouseClicked(mouse_button)) + if (!IsAnyWindowHovered() && IsMouseClicked(mouse_button)) OpenPopupEx(GImGui->CurrentWindow->GetID(str_id), true); return BeginPopup(str_id); } From 304de0ee1b8727d13edbfff088bebdd55b888de6 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 26 Aug 2017 14:11:41 +0800 Subject: [PATCH 286/921] ImFontConfig: Comments, const. --- imgui.h | 8 ++++---- imgui_draw.cpp | 12 ++++++------ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/imgui.h b/imgui.h index 61227e020..e82d778b7 100644 --- a/imgui.h +++ b/imgui.h @@ -1321,14 +1321,14 @@ struct ImFontConfig { void* FontData; // // TTF/OTF data int FontDataSize; // // TTF/OTF data size - bool FontDataOwnedByAtlas; // true // TTF/OTF data ownership taken by the container ImFontAtlas (will delete memory itself). Set to true + bool FontDataOwnedByAtlas; // true // TTF/OTF data ownership taken by the container ImFontAtlas (will delete memory itself). int FontNo; // 0 // Index of font within TTF/OTF file - float SizePixels; // // Size in pixels for rasterizer + float SizePixels; // // Size in pixels for rasterizer. int OversampleH, OversampleV; // 3, 1 // Rasterize at higher quality for sub-pixel positioning. We don't use sub-pixel positions on the Y axis. bool PixelSnapH; // false // Align every glyph to pixel boundary. Useful e.g. if you are merging a non-pixel aligned font with the default font. If enabled, you can set OversampleH/V to 1. ImVec2 GlyphExtraSpacing; // 0, 0 // Extra spacing (in pixels) between glyphs. Only X axis is supported for now. - ImVec2 GlyphOffset; // 0, 0 // Offset all glyphs from this font input - const ImWchar* GlyphRanges; // // Pointer to a user-provided list of Unicode range (2 value per range, values are inclusive, zero-terminated list). THE ARRAY DATA NEEDS TO PERSIST AS LONG AS THE FONT IS ALIVE. + ImVec2 GlyphOffset; // 0, 0 // Offset all glyphs from this font input. + const ImWchar* GlyphRanges; // NULL // Pointer to a user-provided list of Unicode range (2 value per range, values are inclusive, zero-terminated list). THE ARRAY DATA NEEDS TO PERSIST AS LONG AS THE FONT IS ALIVE. bool MergeMode; // false // Merge into previous ImFont, so you can combine multiple inputs font into one ImFont (e.g. ASCII font + icons + Japanese glyphs). You may want to use GlyphOffset.y when merge font of different heights. // [Internal] diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 0f2345f5b..0eb1e5989 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1051,8 +1051,8 @@ ImFontConfig::ImFontConfig() GlyphOffset = ImVec2(0.0f, 0.0f); GlyphRanges = NULL; MergeMode = false; - DstFont = NULL; memset(Name, 0, sizeof(Name)); + DstFont = NULL; } //----------------------------------------------------------------------------- @@ -1478,15 +1478,15 @@ bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas) ImFontTempBuildData& tmp = tmp_array[input_i]; ImFont* dst_font = cfg.DstFont; // We can have multiple input fonts writing into a same destination font (when using MergeMode=true) - float font_scale = stbtt_ScaleForPixelHeight(&tmp.FontInfo, cfg.SizePixels); + const float font_scale = stbtt_ScaleForPixelHeight(&tmp.FontInfo, cfg.SizePixels); int unscaled_ascent, unscaled_descent, unscaled_line_gap; stbtt_GetFontVMetrics(&tmp.FontInfo, &unscaled_ascent, &unscaled_descent, &unscaled_line_gap); - float ascent = unscaled_ascent * font_scale; - float descent = unscaled_descent * font_scale; + const float ascent = unscaled_ascent * font_scale; + const float descent = unscaled_descent * font_scale; ImFontAtlasBuildSetupFont(atlas, dst_font, &cfg, ascent, descent); - float off_x = cfg.GlyphOffset.x; - float off_y = cfg.GlyphOffset.y + (float)(int)(dst_font->Ascent + 0.5f); + const float off_x = cfg.GlyphOffset.x; + const float off_y = cfg.GlyphOffset.y + (float)(int)(dst_font->Ascent + 0.5f); dst_font->FallbackGlyph = NULL; // Always clear fallback so FindGlyph can return NULL. It will be set again in BuildLookupTable() for (int i = 0; i < tmp.RangesCount; i++) From f72ca6d22ccbe14f3ec8734136a3644c8dd9cfa8 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 26 Aug 2017 14:11:56 +0800 Subject: [PATCH 287/921] ImFontConfig: Added RasterizerMultiply option to alter the brightness of individual fonts at rasterization time, which may help increasing readability for some. Added RasterizerFlags for custom rasterizer flags (aka imgui_freetype) --- imgui.h | 2 ++ imgui_draw.cpp | 29 +++++++++++++++++++++++++++++ imgui_internal.h | 2 ++ 3 files changed, 33 insertions(+) diff --git a/imgui.h b/imgui.h index e82d778b7..7d0721b04 100644 --- a/imgui.h +++ b/imgui.h @@ -1330,6 +1330,8 @@ struct ImFontConfig ImVec2 GlyphOffset; // 0, 0 // Offset all glyphs from this font input. const ImWchar* GlyphRanges; // NULL // Pointer to a user-provided list of Unicode range (2 value per range, values are inclusive, zero-terminated list). THE ARRAY DATA NEEDS TO PERSIST AS LONG AS THE FONT IS ALIVE. bool MergeMode; // false // Merge into previous ImFont, so you can combine multiple inputs font into one ImFont (e.g. ASCII font + icons + Japanese glyphs). You may want to use GlyphOffset.y when merge font of different heights. + unsigned int RasterizerFlags; // 0x00 // Settings for custom font rasterizer (e.g. ImGuiFreeType). Leave as zero if you aren't using one. + float RasterizerMultiply; // 1.0f // Brighten (>1.0f) or darken (<1.0f) font output. Brightening small fonts may be a good workaround to make them more readable. // [Internal] char Name[32]; // Name (strictly to ease debugging) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 0eb1e5989..cd8325393 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1051,6 +1051,8 @@ ImFontConfig::ImFontConfig() GlyphOffset = ImVec2(0.0f, 0.0f); GlyphRanges = NULL; MergeMode = false; + RasterizerFlags = 0x00; + RasterizerMultiply = 1.0f; memset(Name, 0, sizeof(Name)); DstFont = NULL; } @@ -1340,6 +1342,23 @@ bool ImFontAtlas::Build() return ImFontAtlasBuildWithStbTruetype(this); } +void ImFontAtlasBuildMultiplyCalcLookupTable(unsigned char out_table[256], float in_brighten_factor) +{ + for (unsigned int i = 0; i < 256; i++) + { + unsigned int value = (unsigned int)(i * in_brighten_factor); + out_table[i] = value > 255 ? 255 : (value & 0xFF); + } +} + +void ImFontAtlasBuildMultiplyRectAlpha8(const unsigned char table[256], unsigned char* pixels, int x, int y, int w, int h, int stride) +{ + unsigned char* data = pixels + x + y * stride; + for (int j = h; j > 0; j--, data += stride) + for (int i = 0; i < w; i++) + data[i] = table[data[i]]; +} + bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas) { IM_ASSERT(atlas->ConfigData.Size > 0); @@ -1382,6 +1401,7 @@ bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas) { stbtt_fontinfo FontInfo; stbrp_rect* Rects; + int RectsCount; stbtt_pack_range* Ranges; int RangesCount; }; @@ -1434,6 +1454,7 @@ bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas) // Pack tmp.Rects = buf_rects + buf_rects_n; + tmp.RectsCount = font_glyphs_count; buf_rects_n += font_glyphs_count; stbtt_PackSetOversampling(&spc, cfg.OversampleH, cfg.OversampleV); int n = stbtt_PackFontRangesGatherRects(&spc, &tmp.FontInfo, tmp.Ranges, tmp.RangesCount, tmp.Rects); @@ -1463,6 +1484,14 @@ bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas) ImFontTempBuildData& tmp = tmp_array[input_i]; stbtt_PackSetOversampling(&spc, cfg.OversampleH, cfg.OversampleV); stbtt_PackFontRangesRenderIntoRects(&spc, &tmp.FontInfo, tmp.Ranges, tmp.RangesCount, tmp.Rects); + if (cfg.RasterizerMultiply != 1.0f) + { + unsigned char multiply_table[256]; + ImFontAtlasBuildMultiplyCalcLookupTable(multiply_table, cfg.RasterizerMultiply); + for (const stbrp_rect* r = tmp.Rects; r != tmp.Rects + tmp.RectsCount; r++) + if (r->was_packed) + ImFontAtlasBuildMultiplyRectAlpha8(multiply_table, spc.pixels, r->x, r->y, r->w, r->h, spc.stride_in_bytes); + } tmp.Rects = NULL; } diff --git a/imgui_internal.h b/imgui_internal.h index b38101876..40af8ca47 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -816,6 +816,8 @@ IMGUI_API void ImFontAtlasBuildRegisterDefaultCustomRects(ImFontAtl IMGUI_API void ImFontAtlasBuildSetupFont(ImFontAtlas* atlas, ImFont* font, ImFontConfig* font_config, float ascent, float descent); IMGUI_API void ImFontAtlasBuildPackCustomRects(ImFontAtlas* atlas, void* spc); IMGUI_API void ImFontAtlasBuildRenderDefaultTexData(ImFontAtlas* atlas); +IMGUI_API void ImFontAtlasBuildMultiplyCalcLookupTable(unsigned char out_table[256], float in_multiply_factor); +IMGUI_API void ImFontAtlasBuildMultiplyRectAlpha8(const unsigned char table[256], unsigned char* pixels, int x, int y, int w, int h, int stride); #ifdef __clang__ #pragma clang diagnostic pop From 5938f1ba61cd08b723e777b2739cc21456831f02 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 26 Aug 2017 15:18:06 +0800 Subject: [PATCH 288/921] Added IsMousePosValid() helper. --- imgui.cpp | 16 ++++++++++++---- imgui.h | 1 + 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 9f8a0c5fc..384078d96 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2153,11 +2153,10 @@ void ImGui::NewFrame() // Update mouse input state // If mouse just appeared or disappeared (usually denoted by -FLT_MAX component, but in reality we test for -256000.0f) we cancel out movement in MouseDelta - const float MOUSE_INVALID = -256000.0f; - if ((g.IO.MousePos.x < MOUSE_INVALID && g.IO.MousePos.y < MOUSE_INVALID) || (g.IO.MousePosPrev.x < MOUSE_INVALID && g.IO.MousePosPrev.y < MOUSE_INVALID)) - g.IO.MouseDelta = ImVec2(0.0f, 0.0f); - else + if (IsMousePosValid(&g.IO.MousePos) && IsMousePosValid(&g.IO.MousePosPrev)) g.IO.MouseDelta = g.IO.MousePos - g.IO.MousePosPrev; + else + g.IO.MouseDelta = ImVec2(0.0f, 0.0f); g.IO.MousePosPrev = g.IO.MousePos; for (int i = 0; i < IM_ARRAYSIZE(g.IO.MouseDown); i++) { @@ -3228,6 +3227,15 @@ ImVec2 ImGui::GetMousePosOnOpeningCurrentPopup() return g.IO.MousePos; } +// We typically use ImVec2(-FLT_MAX,-FLT_MAX) to denote an invalid mouse position +bool ImGui::IsMousePosValid(const ImVec2* mouse_pos) +{ + if (mouse_pos == NULL) + mouse_pos = &GImGui->IO.MousePos; + const float MOUSE_INVALID = -256000.0f; + return mouse_pos->x >= MOUSE_INVALID && mouse_pos->y >= MOUSE_INVALID; +} + ImVec2 ImGui::GetMouseDragDelta(int button, float lock_threshold) { ImGuiContext& g = *GImGui; diff --git a/imgui.h b/imgui.h index 7d0721b04..7100fb24d 100644 --- a/imgui.h +++ b/imgui.h @@ -458,6 +458,7 @@ namespace ImGui IMGUI_API bool IsMouseReleased(int button); // did mouse button released (went from Down to !Down) IMGUI_API bool IsMouseDragging(int button = 0, float lock_threshold = -1.0f); // is mouse dragging. if lock_threshold < -1.0f uses io.MouseDraggingThreshold IMGUI_API bool IsMouseHoveringRect(const ImVec2& r_min, const ImVec2& r_max, bool clip = true); // is mouse hovering given bounding rect (in screen space). clipped by current clipping settings. disregarding of consideration of focus/window ordering/blocked by a popup. + IMGUI_API bool IsMousePosValid(const ImVec2* mouse_pos = NULL); // IMGUI_API ImVec2 GetMousePos(); // shortcut to ImGui::GetIO().MousePos provided by user, to be consistent with other calls IMGUI_API ImVec2 GetMousePosOnOpeningCurrentPopup(); // retrieve backup of mouse positioning at the time of opening popup we have BeginPopup() into IMGUI_API ImVec2 GetMouseDragDelta(int button = 0, float lock_threshold = -1.0f); // dragging amount since clicking. if lock_threshold < -1.0f uses io.MouseDraggingThreshold From 419b22a4871119625b441566dd4c27cbb15f20cd Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 26 Aug 2017 16:35:39 +0800 Subject: [PATCH 289/921] Internals: Split some code out of NewFrame() into an Initialize() function. --- imgui.cpp | 26 +++++++++++++++----------- imgui_internal.h | 1 + 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 384078d96..bff649188 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2125,16 +2125,9 @@ void ImGui::NewFrame() IM_ASSERT(g.Style.CurveTessellationTol > 0.0f); // Invalid style setting IM_ASSERT(g.Style.Alpha >= 0.0f && g.Style.Alpha <= 1.0f); // Invalid style setting. Alpha cannot be negative (allows us to avoid a few clamps in color computations) + // Initialize on first frame if (!g.Initialized) - { - // Initialize on first frame - g.LogClipboard = (ImGuiTextBuffer*)ImGui::MemAlloc(sizeof(ImGuiTextBuffer)); - IM_PLACEMENT_NEW(g.LogClipboard) ImGuiTextBuffer(); - - IM_ASSERT(g.Settings.empty()); - LoadIniSettingsFromDisk(g.IO.IniFilename); - g.Initialized = true; - } + ImGui::Initialize(); SetCurrentFont(GetDefaultFont()); IM_ASSERT(g.Font->IsLoaded()); @@ -2350,7 +2343,18 @@ void ImGui::NewFrame() ImGui::Begin("Debug"); } -// NB: behavior of ImGui after Shutdown() is not tested/guaranteed at the moment. This function is merely here to free heap allocations. +void ImGui::Initialize() +{ + ImGuiContext& g = *GImGui; + g.LogClipboard = (ImGuiTextBuffer*)ImGui::MemAlloc(sizeof(ImGuiTextBuffer)); + IM_PLACEMENT_NEW(g.LogClipboard) ImGuiTextBuffer(); + + IM_ASSERT(g.Settings.empty()); + LoadIniSettingsFromDisk(g.IO.IniFilename); + g.Initialized = true; +} + +// This function is merely here to free heap allocations. void ImGui::Shutdown() { ImGuiContext& g = *GImGui; @@ -2359,7 +2363,7 @@ void ImGui::Shutdown() if (g.IO.Fonts) // Testing for NULL to allow user to NULLify in case of running Shutdown() on multiple contexts. Bit hacky. g.IO.Fonts->Clear(); - // Cleanup of other data are conditional on actually having used ImGui. + // Cleanup of other data are conditional on actually having initialize ImGui. if (!g.Initialized) return; diff --git a/imgui_internal.h b/imgui_internal.h index 40af8ca47..7feaa176e 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -741,6 +741,7 @@ namespace ImGui IMGUI_API ImGuiWindow* FindWindowByName(const char* name); IMGUI_API void FocusWindow(ImGuiWindow* window); + IMGUI_API void Initialize(); IMGUI_API void EndFrame(); // Ends the ImGui frame. Automatically called by Render()! you most likely don't need to ever call that yourself directly. If you don't need to render you can call EndFrame() but you'll have wasted CPU already. If you don't need to render, don't create any windows instead! IMGUI_API void SetActiveID(ImGuiID id, ImGuiWindow* window); From b295e185ffae72e2f3edea83526b0324484f9f5b Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 26 Aug 2017 16:42:40 +0800 Subject: [PATCH 290/921] Updated copyright date for 2017, updated Gallery link --- LICENSE.txt | 2 +- imgui.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/LICENSE.txt b/LICENSE.txt index b28ef2253..5a9b98b83 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2014-2015 Omar Cornut and ImGui contributors +Copyright (c) 2014-2017 Omar Cornut and ImGui contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/imgui.cpp b/imgui.cpp index bff649188..ef3987ace 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -5,7 +5,7 @@ // Newcomers, read 'Programmer guide' below for notes on how to setup ImGui in your codebase. // Get latest version at https://github.com/ocornut/imgui // Releases change-log at https://github.com/ocornut/imgui/releases -// Gallery (please post your screenshots/video there!): https://github.com/ocornut/imgui/issues/772 +// Gallery (please post your screenshots/video there!): https://github.com/ocornut/imgui/issues/1269 // Developed by Omar Cornut and every direct or indirect contributors to the GitHub. // This library is free but I need your support to sustain development and maintenance. // If you work for a company, please consider financial support, e.g: https://www.patreon.com/imgui From 0d4b08a851e8c16cbf16916124e1811e34ab875d Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 28 Aug 2017 12:14:29 +0800 Subject: [PATCH 291/921] Added Go binding link --- README.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 3bfb46edf..44233311c 100644 --- a/README.md +++ b/README.md @@ -55,14 +55,15 @@ _NB: those third-party bindings may be more or less maintained, more or less clo _Integrating Dear ImGui within your custom engine is a matter of wiring mouse/keyboard inputs and providing a render function that can bind a texture and render simple textured triangles. The examples/ folder is populated with applications doing just that. If you are an experienced programmer it should take you less than an hour to integrate Dear ImGui in your custom engine, but make sure to spend time reading the FAQ, the comments and other documentation!_ Languages: -- cimgui: thin c-api wrapper for ImGui https://github.com/Extrawurst/cimgui -- ImGui.NET: An ImGui wrapper for .NET Core https://github.com/mellinoe/ImGui.NET -- imgui-rs: Rust bindings for dear imgui https://github.com/Gekkio/imgui-rs -- DerelictImgui: Dynamic bindings for the D programming language: https://github.com/Extrawurst/DerelictImgui -- CyImGui: Python bindings for dear imgui using Cython: https://github.com/chromy/cyimgui -- pyimgui: Another Python bindings for dear imgui: https://github.com/swistakm/pyimgui -- LUA: https://github.com/patrickriordan/imgui_lua_bindings -- imgui-pas: P ascal bindings for imgui https://github.com/dpethes/imgui-pas +- C - cimgui: thin c-api wrapper for ImGui https://github.com/Extrawurst/cimgui +- C#/.Net - ImGui.NET: An ImGui wrapper for .NET Core https://github.com/mellinoe/ImGui.NET +- D - DerelictImgui: Dynamic bindings for the D programming language: https://github.com/Extrawurst/DerelictImgui +- Go - go-imgui https://github.com/Armored-Dragon/go-imgui +- Lua - https://github.com/patrickriordan/imgui_lua_bindings +- Pascal - imgui-pas https://github.com/dpethes/imgui-pas +- Python - CyImGui: Python bindings for dear imgui using Cython: https://github.com/chromy/cyimgui +- Python - pyimgui: Another Python bindings for dear imgui: https://github.com/swistakm/pyimgui +- Rust - imgui-rs: Rust bindings for dear imgui https://github.com/Gekkio/imgui-rs Frameworks: - Main ImGui repository include examples for DirectX9, DirectX10, DirectX11, OpenGL2/3, Vulkan, Allegro 5, SDL+GL2/3, iOS and Marmalade: https://github.com/ocornut/imgui/tree/master/examples From 7a7327addec8cde30c13d6224a121033043874ba Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 28 Aug 2017 13:19:20 +0800 Subject: [PATCH 292/921] ParseFormatPrecision() returns -1 for scientific noation 'e'/'E', RoundScalar() doesn't alter those. --- imgui.cpp | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index ef3987ace..024d2aaa3 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -936,6 +936,18 @@ const char* ImStristr(const char* haystack, const char* haystack_end, const char return NULL; } +static const char* ImAtoi(const char* src, int* output) +{ + int negative = 0; + if (*src == '-') { negative = 1; src++; } + if (*src == '+') { src++; } + int v = 0; + while (*src >= '0' && *src <= '9') + v = (v * 10) + (*src++ - '0'); + *output = negative ? -v : v; + return src; +} + // MSVC version appears to return -1 on overflow, whereas glibc appears to return total count (which may be >= buf_size). // Ideally we would test for only one of those limits at runtime depending on the behavior the vsnprintf(), but trying to deduct it at compile time sounds like a pandora can of worm. int ImFormatString(char* buf, int buf_size, const char* fmt, ...) @@ -6462,10 +6474,12 @@ int ImGui::ParseFormatPrecision(const char* fmt, int default_precision) fmt++; if (*fmt == '.') { - precision = atoi(fmt + 1); + fmt = ImAtoi(fmt + 1, &precision); if (precision < 0 || precision > 10) precision = default_precision; } + if (*fmt == 'e' || *fmt == 'E') // Maximum precision with scientific notation + precision = -1; break; } return precision; @@ -6482,6 +6496,8 @@ float ImGui::RoundScalar(float value, int decimal_precision) // Round past decimal precision // So when our value is 1.99999 with a precision of 0.001 we'll end up rounding to 2.0 // FIXME: Investigate better rounding methods + if (decimal_precision < 0) + return value; const float min_step = GetMinimumStepAtDecimalPrecision(decimal_precision); bool negative = value < 0.0f; value = fabsf(value); @@ -6533,7 +6549,7 @@ bool ImGui::SliderBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v const float grab_padding = 2.0f; const float slider_sz = is_horizontal ? (frame_bb.GetWidth() - grab_padding * 2.0f) : (frame_bb.GetHeight() - grab_padding * 2.0f); float grab_sz; - if (decimal_precision > 0) + if (decimal_precision != 0) grab_sz = ImMin(style.GrabMinSize, slider_sz); else grab_sz = ImMin(ImMax(1.0f * (slider_sz / ((v_min < v_max ? v_max - v_min : v_min - v_max) + 1.0f)), style.GrabMinSize), slider_sz); // Integer sliders, if possible have the grab size represent 1 unit From 1f51e8f39d69e45d32e59f274b0b0760710b0603 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 28 Aug 2017 14:11:11 +0800 Subject: [PATCH 293/921] Internals: Renamed some ImGuiCorner enums. --- imgui.cpp | 12 ++++++------ imgui_draw.cpp | 10 +++++----- imgui_internal.h | 4 ++-- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 024d2aaa3..59acbb2b5 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4276,7 +4276,7 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us bg_color.w = bg_alpha; bg_color.w *= style.Alpha; if (bg_color.w > 0.0f) - window->DrawList->AddRectFilled(window->Pos+ImVec2(0,window->TitleBarHeight()), window->Pos+window->Size, ColorConvertFloat4ToU32(bg_color), window_rounding, (flags & ImGuiWindowFlags_NoTitleBar) ? ImGuiCorner_All : ImGuiCorner_BottomLeft|ImGuiCorner_BottomRight); + window->DrawList->AddRectFilled(window->Pos+ImVec2(0,window->TitleBarHeight()), window->Pos+window->Size, ColorConvertFloat4ToU32(bg_color), window_rounding, (flags & ImGuiWindowFlags_NoTitleBar) ? ImGuiCorner_All : ImGuiCorner_BotLeft|ImGuiCorner_BotRight); // Title bar if (!(flags & ImGuiWindowFlags_NoTitleBar)) @@ -4500,9 +4500,9 @@ static void Scrollbar(ImGuiWindow* window, bool horizontal) float window_rounding = (window->Flags & ImGuiWindowFlags_ChildWindow) ? style.ChildWindowRounding : style.WindowRounding; int window_rounding_corners; if (horizontal) - window_rounding_corners = ImGuiCorner_BottomLeft | (other_scrollbar ? 0 : ImGuiCorner_BottomRight); + window_rounding_corners = ImGuiCorner_BotLeft | (other_scrollbar ? 0 : ImGuiCorner_BotRight); else - window_rounding_corners = (((window->Flags & ImGuiWindowFlags_NoTitleBar) && !(window->Flags & ImGuiWindowFlags_MenuBar)) ? ImGuiCorner_TopRight : 0) | (other_scrollbar ? 0 : ImGuiCorner_BottomRight); + window_rounding_corners = (((window->Flags & ImGuiWindowFlags_NoTitleBar) && !(window->Flags & ImGuiWindowFlags_MenuBar)) ? ImGuiCorner_TopRight : 0) | (other_scrollbar ? 0 : ImGuiCorner_BotRight); window->DrawList->AddRectFilled(bb.Min, bb.Max, ImGui::GetColorU32(ImGuiCol_ScrollbarBg), window_rounding, window_rounding_corners); bb.Expand(ImVec2(-ImClamp((float)(int)((bb.Max.x - bb.Min.x - 2.0f) * 0.5f), 0.0f, 3.0f), -ImClamp((float)(int)((bb.Max.y - bb.Min.y - 2.0f) * 0.5f), 0.0f, 3.0f))); @@ -9085,7 +9085,7 @@ void ImGui::RenderColorRectWithAlphaCheckerboard(ImVec2 p_min, ImVec2 p_max, ImU continue; int rounding_corners_flags_cell = 0; if (y1 <= p_min.y) { if (x1 <= p_min.x) rounding_corners_flags_cell |= ImGuiCorner_TopLeft; if (x2 >= p_max.x) rounding_corners_flags_cell |= ImGuiCorner_TopRight; } - if (y2 >= p_max.y) { if (x1 <= p_min.x) rounding_corners_flags_cell |= ImGuiCorner_BottomLeft; if (x2 >= p_max.x) rounding_corners_flags_cell |= ImGuiCorner_BottomRight; } + if (y2 >= p_max.y) { if (x1 <= p_min.x) rounding_corners_flags_cell |= ImGuiCorner_BotLeft; if (x2 >= p_max.x) rounding_corners_flags_cell |= ImGuiCorner_BotRight; } rounding_corners_flags_cell &= rounding_corners_flags; window->DrawList->AddRectFilled(ImVec2(x1,y1), ImVec2(x2,y2), col_bg2, rounding_corners_flags_cell ? rounding : 0.0f, rounding_corners_flags_cell); } @@ -9145,8 +9145,8 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl if ((flags & ImGuiColorEditFlags_AlphaPreviewHalf) && col.w < 1.0f) { float mid_x = (float)(int)((bb.Min.x + bb.Max.x) * 0.5f + 0.5f); - RenderColorRectWithAlphaCheckerboard(ImVec2(bb.Min.x + grid_step, bb.Min.y), bb.Max, GetColorU32(col), grid_step, ImVec2(-grid_step, 0.0f), rounding, ImGuiCorner_TopRight|ImGuiCorner_BottomRight); - window->DrawList->AddRectFilled(bb.Min, ImVec2(mid_x, bb.Max.y), GetColorU32(col_without_alpha), rounding, ImGuiCorner_TopLeft|ImGuiCorner_BottomLeft); + RenderColorRectWithAlphaCheckerboard(ImVec2(bb.Min.x + grid_step, bb.Min.y), bb.Max, GetColorU32(col), grid_step, ImVec2(-grid_step, 0.0f), rounding, ImGuiCorner_TopRight|ImGuiCorner_BotRight); + window->DrawList->AddRectFilled(bb.Min, ImVec2(mid_x, bb.Max.y), GetColorU32(col_without_alpha), rounding, ImGuiCorner_TopLeft|ImGuiCorner_BotLeft); } else { diff --git a/imgui_draw.cpp b/imgui_draw.cpp index cd8325393..4e15ea0c0 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -775,9 +775,9 @@ void ImDrawList::PathBezierCurveTo(const ImVec2& p2, const ImVec2& p3, const ImV void ImDrawList::PathRect(const ImVec2& a, const ImVec2& b, float rounding, int rounding_corners) { const int corners_top = ImGuiCorner_TopLeft | ImGuiCorner_TopRight; - const int corners_bottom = ImGuiCorner_BottomLeft | ImGuiCorner_BottomRight; - const int corners_left = ImGuiCorner_TopLeft | ImGuiCorner_BottomLeft; - const int corners_right = ImGuiCorner_TopRight | ImGuiCorner_BottomRight; + const int corners_bottom = ImGuiCorner_BotLeft | ImGuiCorner_BotRight; + const int corners_left = ImGuiCorner_TopLeft | ImGuiCorner_BotLeft; + const int corners_right = ImGuiCorner_TopRight | ImGuiCorner_BotRight; float r = rounding; r = ImMin(r, fabsf(b.x-a.x) * ( ((rounding_corners & corners_top) == corners_top) || ((rounding_corners & corners_bottom) == corners_bottom) ? 0.5f : 1.0f ) - 1.0f); @@ -794,8 +794,8 @@ void ImDrawList::PathRect(const ImVec2& a, const ImVec2& b, float rounding, int { const float r0 = (rounding_corners & ImGuiCorner_TopLeft) ? r : 0.0f; const float r1 = (rounding_corners & ImGuiCorner_TopRight) ? r : 0.0f; - const float r2 = (rounding_corners & ImGuiCorner_BottomRight) ? r : 0.0f; - const float r3 = (rounding_corners & ImGuiCorner_BottomLeft) ? r : 0.0f; + const float r2 = (rounding_corners & ImGuiCorner_BotRight) ? r : 0.0f; + const float r3 = (rounding_corners & ImGuiCorner_BotLeft) ? r : 0.0f; PathArcToFast(ImVec2(a.x+r0,a.y+r0), r0, 6, 9); PathArcToFast(ImVec2(b.x-r1,a.y+r1), r1, 9, 12); PathArcToFast(ImVec2(b.x-r2,b.y-r2), r2, 0, 3); diff --git a/imgui_internal.h b/imgui_internal.h index 7feaa176e..d0ac0cf84 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -234,8 +234,8 @@ enum ImGuiCorner { ImGuiCorner_TopLeft = 1 << 0, // 1 ImGuiCorner_TopRight = 1 << 1, // 2 - ImGuiCorner_BottomRight = 1 << 2, // 4 - ImGuiCorner_BottomLeft = 1 << 3, // 8 + ImGuiCorner_BotRight = 1 << 2, // 4 + ImGuiCorner_BotLeft = 1 << 3, // 8 ImGuiCorner_All = 0x0F }; From e1d81f4dc5c62f4bf76adb8da044a475949b4b83 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 28 Aug 2017 14:12:55 +0800 Subject: [PATCH 294/921] ImDrawList: Minor tidying up. --- imgui_draw.cpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 4e15ea0c0..aad5bbb6c 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -694,7 +694,8 @@ void ImDrawList::PathArcToFast(const ImVec2& centre, float radius, int a_min_of_ circle_vtx_builds = true; } - if (a_min_of_12 > a_max_of_12) return; + if (a_min_of_12 > a_max_of_12) + return; if (radius == 0.0f) { _Path.push_back(centre); @@ -779,11 +780,10 @@ void ImDrawList::PathRect(const ImVec2& a, const ImVec2& b, float rounding, int const int corners_left = ImGuiCorner_TopLeft | ImGuiCorner_BotLeft; const int corners_right = ImGuiCorner_TopRight | ImGuiCorner_BotRight; - float r = rounding; - r = ImMin(r, fabsf(b.x-a.x) * ( ((rounding_corners & corners_top) == corners_top) || ((rounding_corners & corners_bottom) == corners_bottom) ? 0.5f : 1.0f ) - 1.0f); - r = ImMin(r, fabsf(b.y-a.y) * ( ((rounding_corners & corners_left) == corners_left) || ((rounding_corners & corners_right) == corners_right) ? 0.5f : 1.0f ) - 1.0f); + rounding = ImMin(rounding, fabsf(b.x - a.x) * ( ((rounding_corners & corners_top) == corners_top) || ((rounding_corners & corners_bottom) == corners_bottom) ? 0.5f : 1.0f ) - 1.0f); + rounding = ImMin(rounding, fabsf(b.y - a.y) * ( ((rounding_corners & corners_left) == corners_left) || ((rounding_corners & corners_right) == corners_right) ? 0.5f : 1.0f ) - 1.0f); - if (r <= 0.0f || rounding_corners == 0) + if (rounding <= 0.0f || rounding_corners == 0) { PathLineTo(a); PathLineTo(ImVec2(b.x,a.y)); @@ -792,14 +792,14 @@ void ImDrawList::PathRect(const ImVec2& a, const ImVec2& b, float rounding, int } else { - const float r0 = (rounding_corners & ImGuiCorner_TopLeft) ? r : 0.0f; - const float r1 = (rounding_corners & ImGuiCorner_TopRight) ? r : 0.0f; - const float r2 = (rounding_corners & ImGuiCorner_BotRight) ? r : 0.0f; - const float r3 = (rounding_corners & ImGuiCorner_BotLeft) ? r : 0.0f; - PathArcToFast(ImVec2(a.x+r0,a.y+r0), r0, 6, 9); - PathArcToFast(ImVec2(b.x-r1,a.y+r1), r1, 9, 12); - PathArcToFast(ImVec2(b.x-r2,b.y-r2), r2, 0, 3); - PathArcToFast(ImVec2(a.x+r3,b.y-r3), r3, 3, 6); + const float rounding_tl = (rounding_corners & ImGuiCorner_TopLeft) ? rounding : 0.0f; + const float rounding_tr = (rounding_corners & ImGuiCorner_TopRight) ? rounding : 0.0f; + const float rounding_br = (rounding_corners & ImGuiCorner_BotRight) ? rounding : 0.0f; + const float rounding_bl = (rounding_corners & ImGuiCorner_BotLeft) ? rounding : 0.0f; + PathArcToFast(ImVec2(a.x + rounding_tl, a.y + rounding_tl), rounding_tl, 6, 9); + PathArcToFast(ImVec2(b.x - rounding_tr, a.y + rounding_tr), rounding_tr, 9, 12); + PathArcToFast(ImVec2(b.x - rounding_br, b.y - rounding_br), rounding_br, 0, 3); + PathArcToFast(ImVec2(a.x + rounding_bl, b.y - rounding_bl), rounding_bl, 3, 6); } } From 808d631e35c3825f0ba9a4d7c0201be81ce879be Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 28 Aug 2017 16:02:25 +0800 Subject: [PATCH 295/921] imDrawList: PathArcTo() returns when passed zero radius. --- imgui_draw.cpp | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index aad5bbb6c..27f3965a4 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -694,27 +694,26 @@ void ImDrawList::PathArcToFast(const ImVec2& centre, float radius, int a_min_of_ circle_vtx_builds = true; } - if (a_min_of_12 > a_max_of_12) - return; - if (radius == 0.0f) + if (radius == 0.0f || a_min_of_12 > a_max_of_12) { _Path.push_back(centre); + return; } - else + _Path.reserve(_Path.Size + (a_max_of_12 - a_min_of_12 + 1)); + for (int a = a_min_of_12; a <= a_max_of_12; a++) { - _Path.reserve(_Path.Size + (a_max_of_12 - a_min_of_12 + 1)); - for (int a = a_min_of_12; a <= a_max_of_12; a++) - { - const ImVec2& c = circle_vtx[a % circle_vtx_count]; - _Path.push_back(ImVec2(centre.x + c.x * radius, centre.y + c.y * radius)); - } + const ImVec2& c = circle_vtx[a % circle_vtx_count]; + _Path.push_back(ImVec2(centre.x + c.x * radius, centre.y + c.y * radius)); } } void ImDrawList::PathArcTo(const ImVec2& centre, float radius, float amin, float amax, int num_segments) { if (radius == 0.0f) + { _Path.push_back(centre); + return; + } _Path.reserve(_Path.Size + (num_segments + 1)); for (int i = 0; i <= num_segments; i++) { @@ -786,9 +785,9 @@ void ImDrawList::PathRect(const ImVec2& a, const ImVec2& b, float rounding, int if (rounding <= 0.0f || rounding_corners == 0) { PathLineTo(a); - PathLineTo(ImVec2(b.x,a.y)); + PathLineTo(ImVec2(b.x, a.y)); PathLineTo(b); - PathLineTo(ImVec2(a.x,b.y)); + PathLineTo(ImVec2(a.x, b.y)); } else { From 7a9ea281bed18383b302815f3efcf9bb2a1e9b30 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 28 Aug 2017 19:27:12 +0800 Subject: [PATCH 296/921] ImSwap() helper. --- imgui.cpp | 4 ++-- imgui_internal.h | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 59acbb2b5..837a20038 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1252,12 +1252,12 @@ void ImGui::ColorConvertRGBtoHSV(float r, float g, float b, float& out_h, float& float K = 0.f; if (g < b) { - const float tmp = g; g = b; b = tmp; + ImSwap(g, b); K = -1.f; } if (r < g) { - const float tmp = r; r = g; g = tmp; + ImSwap(r, g); K = -2.f / 6.f - K; } diff --git a/imgui_internal.h b/imgui_internal.h index d0ac0cf84..130733e87 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -138,6 +138,7 @@ static inline int ImClamp(int v, int mn, int mx) static inline float ImClamp(float v, float mn, float mx) { return (v < mn) ? mn : (v > mx) ? mx : v; } static inline ImVec2 ImClamp(const ImVec2& f, const ImVec2& mn, ImVec2 mx) { return ImVec2(ImClamp(f.x,mn.x,mx.x), ImClamp(f.y,mn.y,mx.y)); } static inline float ImSaturate(float f) { return (f < 0.0f) ? 0.0f : (f > 1.0f) ? 1.0f : f; } +static inline void ImSwap(float& a, float& b) { float tmp = a; a = b; b = tmp; } static inline int ImLerp(int a, int b, float t) { return (int)(a + (b - a) * t); } static inline float ImLerp(float a, float b, float t) { return a + (b - a) * t; } static inline ImVec2 ImLerp(const ImVec2& a, const ImVec2& b, float t) { return ImVec2(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t); } From f0fa17b5e064e87de6dfe9bbf6afc9af3f75120f Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 29 Aug 2017 15:10:03 +0800 Subject: [PATCH 297/921] ImDrawList: Minor renaming --- imgui_draw.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 27f3965a4..b27da94bf 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -707,7 +707,7 @@ void ImDrawList::PathArcToFast(const ImVec2& centre, float radius, int a_min_of_ } } -void ImDrawList::PathArcTo(const ImVec2& centre, float radius, float amin, float amax, int num_segments) +void ImDrawList::PathArcTo(const ImVec2& centre, float radius, float a_min, float a_max, int num_segments) { if (radius == 0.0f) { @@ -717,7 +717,7 @@ void ImDrawList::PathArcTo(const ImVec2& centre, float radius, float amin, float _Path.reserve(_Path.Size + (num_segments + 1)); for (int i = 0; i <= num_segments; i++) { - const float a = amin + ((float)i / (float)num_segments) * (amax - amin); + const float a = a_min + ((float)i / (float)num_segments) * (a_max - a_min); _Path.push_back(ImVec2(centre.x + cosf(a) * radius, centre.y + sinf(a) * radius)); } } From 01d4bf299ae660a4b3da548965b07d02bf9ba087 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 29 Aug 2017 15:22:30 +0800 Subject: [PATCH 298/921] Added overcomplicated RenderRectFilledRangeH() to fix rounded progress bar, which will also help for range widgets and perhaps sliders grabs over rounded areas. (#1296, #76) --- imgui_draw.cpp | 71 ++++++++++++++++++++++++++++++++++++++++++++++++ imgui_internal.h | 1 + 2 files changed, 72 insertions(+) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index b27da94bf..4a090c355 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -2329,6 +2329,77 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col draw_list->_VtxCurrentIdx = (unsigned int)draw_list->VtxBuffer.Size; } +//----------------------------------------------------------------------------- +// Internals Drawing Helpers +//----------------------------------------------------------------------------- + +static inline float ImAcos01(float x) +{ + if (x <= 0.0f) return IM_PI * 0.5f; + if (x >= 1.0f) return 0.0f; + return (-0.69813170079773212f * x * x - 0.87266462599716477f) * x + 1.5707963267948966f; // Cheap approximation, enough for what we do. +} + +// FIXME: Cleanup and move code to ImDrawList. +void ImGui::RenderRectFilledRangeH(ImDrawList* draw_list, const ImRect& rect, ImU32 col, float x_start_norm, float x_end_norm, float rounding) +{ + if (x_end_norm == x_start_norm) + return; + if (x_start_norm > x_end_norm) + ImSwap(x_start_norm, x_end_norm); + + ImVec2 p0 = ImVec2(ImLerp(rect.Min.x, rect.Max.x, x_start_norm), rect.Min.y); + ImVec2 p1 = ImVec2(ImLerp(rect.Min.x, rect.Max.x, x_end_norm), rect.Max.y); + if (rounding == 0.0f) + { + draw_list->AddRectFilled(p0, p1, col, 0.0f); + return; + } + + rounding = ImClamp(ImMin((rect.Max.x - rect.Min.x) * 0.5f, (rect.Max.y - rect.Min.y) * 0.5f) - 1.0f, 0.0f, rounding); + const float inv_rounding = 1.0f / rounding; + const float arc0_b = ImAcos01(1.0f - (p0.x - rect.Min.x) * inv_rounding); + const float arc0_e = ImAcos01(1.0f - (p1.x - rect.Min.x) * inv_rounding); + const float x0 = ImMax(p0.x, rect.Min.x + rounding); + if (arc0_b == arc0_e) + { + draw_list->PathLineTo(ImVec2(x0, p1.y)); + draw_list->PathLineTo(ImVec2(x0, p0.y)); + } + else if (arc0_b == 0.0f && arc0_e == IM_PI*0.5f) + { + draw_list->PathArcToFast(ImVec2(x0, p1.y - rounding), rounding, 3, 6); // BL + draw_list->PathArcToFast(ImVec2(x0, p0.y + rounding), rounding, 6, 9); // TR + } + else + { + draw_list->PathArcTo(ImVec2(x0, p1.y - rounding), rounding, IM_PI - arc0_e, IM_PI - arc0_b, 3); // BL + draw_list->PathArcTo(ImVec2(x0, p0.y + rounding), rounding, IM_PI + arc0_b, IM_PI + arc0_e, 3); // TR + } + if (p1.x > rect.Min.x + rounding) + { + const float arc1_b = ImAcos01(1.0f - (rect.Max.x - p1.x) * inv_rounding); + const float arc1_e = ImAcos01(1.0f - (rect.Max.x - p0.x) * inv_rounding); + const float x1 = ImMin(p1.x, rect.Max.x - rounding); + if (arc1_b == arc1_e) + { + draw_list->PathLineTo(ImVec2(x1, p0.y)); + draw_list->PathLineTo(ImVec2(x1, p1.y)); + } + else if (arc1_b == 0.0f && arc1_e == IM_PI*0.5f) + { + draw_list->PathArcToFast(ImVec2(x1, p0.y + rounding), rounding, 9, 12); // TR + draw_list->PathArcToFast(ImVec2(x1, p1.y - rounding), rounding, 0, 3); // BR + } + else + { + draw_list->PathArcTo(ImVec2(x1, p0.y + rounding), rounding, -arc1_e, -arc1_b, 3); // TR + draw_list->PathArcTo(ImVec2(x1, p1.y - rounding), rounding, +arc1_b, +arc1_e, 3); // BR + } + } + draw_list->PathFillConvex(col); +} + //----------------------------------------------------------------------------- // DEFAULT FONT DATA //----------------------------------------------------------------------------- diff --git a/imgui_internal.h b/imgui_internal.h index 130733e87..d0fdd063d 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -779,6 +779,7 @@ namespace ImGui IMGUI_API void RenderCollapseTriangle(ImVec2 pos, bool is_open, float scale = 1.0f); IMGUI_API void RenderBullet(ImVec2 pos); IMGUI_API void RenderCheckMark(ImVec2 pos, ImU32 col); + IMGUI_API void RenderRectFilledRangeH(ImDrawList* draw_list, const ImRect& rect, ImU32 col, float x_start_norm, float x_end_norm, float rounding); IMGUI_API const char* FindRenderedTextEnd(const char* text, const char* text_end = NULL); // Find the optional ## from which we stop displaying text. IMGUI_API bool ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool* out_held, ImGuiButtonFlags flags = 0); From f8eef4957589f98781432ce72f517a1ffb43ae51 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 29 Aug 2017 15:23:07 +0800 Subject: [PATCH 299/921] ProgressBar() fixed rendering when straddling rounded area. (#1296) --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 837a20038..880b1f543 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -7323,7 +7323,7 @@ void ImGui::ProgressBar(float fraction, const ImVec2& size_arg, const char* over RenderFrame(bb.Min, bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding); bb.Expand(ImVec2(-window->BorderSize, -window->BorderSize)); const ImVec2 fill_br = ImVec2(ImLerp(bb.Min.x, bb.Max.x, fraction), bb.Max.y); - RenderFrame(bb.Min, fill_br, GetColorU32(ImGuiCol_PlotHistogram), false, style.FrameRounding); + RenderRectFilledRangeH(window->DrawList, bb, GetColorU32(ImGuiCol_PlotHistogram), 0.0f, fraction, style.FrameRounding); // Default displaying the fraction as percentage string, but user can override it char overlay_buf[32]; From 0ba3cadb887058ce6b86ce2a9048cf2bb1dc85b0 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 29 Aug 2017 15:25:05 +0800 Subject: [PATCH 300/921] RenderRectFilledRangeH() can't use cheap acosf() approximation for now. (#1296) --- imgui_draw.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 4a090c355..0a23ac0e5 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -2337,7 +2337,8 @@ static inline float ImAcos01(float x) { if (x <= 0.0f) return IM_PI * 0.5f; if (x >= 1.0f) return 0.0f; - return (-0.69813170079773212f * x * x - 0.87266462599716477f) * x + 1.5707963267948966f; // Cheap approximation, enough for what we do. + return acosf(x); + //return (-0.69813170079773212f * x * x - 0.87266462599716477f) * x + 1.5707963267948966f; // Cheap approximation, may be enough for what we do. } // FIXME: Cleanup and move code to ImDrawList. From ee42fae4683ea75f51faa156cf91304ef2d2bf3d Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 29 Aug 2017 16:05:12 +0800 Subject: [PATCH 301/921] Merge various minor things (supposedly harmless) from Navigation branch into Master to reduce differences. (#787) --- imgui.cpp | 20 ++++++++++---------- imgui.h | 14 +++++++------- imgui_internal.h | 9 +++++---- 3 files changed, 22 insertions(+), 21 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 880b1f543..cb9a7fa1f 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1803,9 +1803,9 @@ ImGuiWindow::ImGuiWindow(const char* name) DrawList = (ImDrawList*)ImGui::MemAlloc(sizeof(ImDrawList)); IM_PLACEMENT_NEW(DrawList) ImDrawList(); DrawList->_OwnerName = Name; + ParentWindow = NULL; RootWindow = NULL; RootNonPopupWindow = NULL; - ParentWindow = NULL; FocusIdxAllCounter = FocusIdxTabCounter = -1; FocusIdxAllRequestCurrent = FocusIdxTabRequestCurrent = INT_MAX; @@ -1925,7 +1925,8 @@ void ImGui::ItemSize(const ImRect& bb, float text_offset_y) // declares their minimum size requirement to ItemSize() and then use a larger region for drawing/interaction, which is passed to ItemAdd(). bool ImGui::ItemAdd(const ImRect& bb, const ImGuiID* id) { - ImGuiWindow* window = GetCurrentWindow(); + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; window->DC.LastItemId = id ? *id : 0; window->DC.LastItemRect = bb; window->DC.LastItemHoveredAndUsable = window->DC.LastItemHoveredRect = false; @@ -1933,7 +1934,6 @@ bool ImGui::ItemAdd(const ImRect& bb, const ImGuiID* id) return false; // This is a sensible default, but widgets are free to override it after calling ItemAdd() - ImGuiContext& g = *GImGui; if (IsMouseHoveringRect(bb.Min, bb.Max)) { // Matching the behavior of IsHovered() but allow if ActiveId==window->MoveID (we clicked on the window background) @@ -2210,7 +2210,7 @@ void ImGui::NewFrame() g.ActiveIdIsAlive = false; g.ActiveIdIsJustActivated = false; - // Handle user moving window (at the beginning of the frame to avoid input lag or sheering). Only valid for root windows. + // Handle user moving window with mouse (at the beginning of the frame to avoid input lag or sheering). Only valid for root windows. if (g.MovedWindowMoveId && g.MovedWindowMoveId == g.ActiveId) { KeepAliveID(g.MovedWindowMoveId); @@ -2221,7 +2221,7 @@ void ImGui::NewFrame() if (!(g.MovedWindow->Flags & ImGuiWindowFlags_NoMove)) { g.MovedWindow->PosFloat += g.IO.MouseDelta; - if (!(g.MovedWindow->Flags & ImGuiWindowFlags_NoSavedSettings) && (g.IO.MouseDelta.x != 0.0f || g.IO.MouseDelta.y != 0.0f)) + if (g.IO.MouseDelta.x != 0.0f || g.IO.MouseDelta.y != 0.0f) MarkIniSettingsDirty(g.MovedWindow); } FocusWindow(g.MovedWindow); @@ -3705,7 +3705,6 @@ void ImGui::EndChild() sz.x = ImMax(4.0f, sz.x); if (window->AutoFitChildAxises & 0x02) sz.y = ImMax(4.0f, sz.y); - ImGui::End(); ImGuiWindow* parent_window = GetCurrentWindow(); @@ -4159,10 +4158,11 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us // Position tooltip (always follows mouse) if ((flags & ImGuiWindowFlags_Tooltip) != 0 && !window_pos_set_by_api) { - ImRect rect_to_avoid(g.IO.MousePos.x - 16, g.IO.MousePos.y - 8, g.IO.MousePos.x + 24, g.IO.MousePos.y + 24); // FIXME: Completely hard-coded. Perhaps center on cursor hit-point instead? - window->PosFloat = FindBestPopupWindowPos(g.IO.MousePos, window->Size, &window->AutoPosLastDirection, rect_to_avoid); + ImVec2 ref_pos = g.IO.MousePos; + ImRect rect_to_avoid(ref_pos.x - 16, ref_pos.y - 8, ref_pos.x + 24, ref_pos.y + 24); // FIXME: Completely hard-coded. Perhaps center on cursor hit-point instead? + window->PosFloat = FindBestPopupWindowPos(ref_pos, window->Size, &window->AutoPosLastDirection, rect_to_avoid); if (window->AutoPosLastDirection == -1) - window->PosFloat = g.IO.MousePos + ImVec2(2,2); // If there's not enough room, for tooltip we prefer avoiding the cursor at all cost even if it means that part of the tooltip won't be visible. + window->PosFloat = ref_pos + ImVec2(2,2); // If there's not enough room, for tooltip we prefer avoiding the cursor at all cost even if it means that part of the tooltip won't be visible. } // Clamp position so it stays visible @@ -4217,7 +4217,7 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us const float window_rounding = (flags & ImGuiWindowFlags_ChildWindow) ? style.ChildWindowRounding : style.WindowRounding; if (window->Collapsed) { - // Draw title bar only + // Title bar only RenderFrame(title_bar_rect.GetTL(), title_bar_rect.GetBR(), GetColorU32(ImGuiCol_TitleBgCollapsed), true, window_rounding); } else diff --git a/imgui.h b/imgui.h index 7100fb24d..14fd4d9d5 100644 --- a/imgui.h +++ b/imgui.h @@ -412,11 +412,11 @@ namespace ImGui IMGUI_API void PopClipRect(); // Utilities - IMGUI_API bool IsItemHovered(); // was the last item hovered by mouse? - IMGUI_API bool IsItemRectHovered(); // was the last item hovered by mouse? even if another item is active or window is blocked by popup while we are hovering this - IMGUI_API bool IsItemActive(); // was the last item active? (e.g. button being held, text field being edited- items that don't interact will always return false) - IMGUI_API bool IsItemClicked(int mouse_button = 0); // was the last item clicked? (e.g. button/node just clicked on) - IMGUI_API bool IsItemVisible(); // was the last item visible? (aka not out of sight due to clipping/scrolling.) + IMGUI_API bool IsItemHovered(); // is the last item hovered by mouse (and usable)? + IMGUI_API bool IsItemRectHovered(); // is the last item hovered by mouse? even if another item is active or window is blocked by popup while we are hovering this + IMGUI_API bool IsItemActive(); // is the last item active? (e.g. button being held, text field being edited- items that don't interact will always return false) + IMGUI_API bool IsItemClicked(int mouse_button = 0); // is the last item clicked? (e.g. button/node just clicked on) + IMGUI_API bool IsItemVisible(); // is the last item visible? (aka not out of sight due to clipping/scrolling.) IMGUI_API bool IsAnyItemHovered(); IMGUI_API bool IsAnyItemActive(); IMGUI_API ImVec2 GetItemRectMin(); // get bounding rect of last item in screen space @@ -425,7 +425,7 @@ namespace ImGui IMGUI_API void SetItemAllowOverlap(); // allow last item to be overlapped by a subsequent item. sometimes useful with invisible buttons, selectables, etc. to catch unused area. IMGUI_API bool IsWindowFocused(); // is current window focused IMGUI_API bool IsWindowHovered(); // is current window hovered and hoverable (not blocked by a popup) (differentiate child windows from each others) - IMGUI_API bool IsWindowRectHovered(); // is current window rectnagle hovered, disregarding of any consideration of being blocked by a popup. (unlike IsWindowHovered() this will return true even if the window is blocked because of a popup) + IMGUI_API bool IsWindowRectHovered(); // is current window rectangle hovered, disregarding of any consideration of being blocked by a popup. (unlike IsWindowHovered() this will return true even if the window is blocked because of a popup) IMGUI_API bool IsRootWindowFocused(); // is current root window focused (root = top-most parent of a child, otherwise self) IMGUI_API bool IsRootWindowOrAnyChildFocused(); // is current root window or any of its child (including current window) focused IMGUI_API bool IsRootWindowOrAnyChildHovered(); // is current root window or any of its child (including current window) hovered and hoverable (not blocked by a popup) @@ -786,7 +786,7 @@ struct ImGuiIO float MouseDragThreshold; // = 6.0f // Distance threshold before considering we are dragging int KeyMap[ImGuiKey_COUNT]; // // Map of indices into the KeysDown[512] entries array float KeyRepeatDelay; // = 0.250f // When holding a key/button, time before it starts repeating, in seconds (for buttons in Repeat mode, etc.). - float KeyRepeatRate; // = 0.020f // When holding a key/button, rate at which it repeats, in seconds. + float KeyRepeatRate; // = 0.050f // When holding a key/button, rate at which it repeats, in seconds. void* UserData; // = NULL // Store your own data for retrieval by callbacks. ImFontAtlas* Fonts; // // Load and assemble one or more fonts into a single tightly packed texture. Output to Fonts array. diff --git a/imgui_internal.h b/imgui_internal.h index d0fdd063d..10598ac6f 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -538,7 +538,7 @@ struct ImGuiContext DragCurrentValue = 0.0f; DragLastMouseDelta = ImVec2(0.0f, 0.0f); DragSpeedDefaultRatio = 1.0f / 100.0f; - DragSpeedScaleSlow = 0.01f; + DragSpeedScaleSlow = 1.0f / 100.0f; DragSpeedScaleFast = 10.0f; ScrollbarClickDeltaToGrabCenter = ImVec2(0.0f, 0.0f); TooltipOverrideCount = 0; @@ -697,9 +697,10 @@ struct IMGUI_API ImGuiWindow ImGuiStorage StateStorage; float FontWindowScale; // Scale multiplier per-window ImDrawList* DrawList; - ImGuiWindow* RootWindow; // If we are a child window, this is pointing to the first non-child parent window. Else point to ourself. - ImGuiWindow* RootNonPopupWindow; // If we are a child window, this is pointing to the first non-child non-popup parent window. Else point to ourself. - ImGuiWindow* ParentWindow; // If we are a child window, this is pointing to our parent window. Else point to NULL. + ImGuiWindow* ParentWindow; // Immediate parent in the window stack *regardless* of whether this window is a child window or not) + ImGuiWindow* RootWindow; // Generally point to ourself. If we are a child window, this is pointing to the first non-child parent window. + ImGuiWindow* RootNonPopupWindow; // Generally point to ourself. Used to display TitleBgActive color and for selecting which window to use for NavWindowing + // Navigation / Focus int FocusIdxAllCounter; // Start at -1 and increase as assigned via FocusItemRegister() From 1f1e63f705f90ef51c4b5205cf8c4517d1e8f6c2 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 29 Aug 2017 16:06:52 +0800 Subject: [PATCH 302/921] Merge various minor things (supposedly harmless) from Navigation branch into Master to reduce differences. Some code in NewFrame() has been moved around. (#787) --- imgui.cpp | 55 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 29 insertions(+), 26 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index cb9a7fa1f..ed69170f5 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -751,25 +751,21 @@ ImGuiIO::ImGuiIO() IniSavingRate = 5.0f; IniFilename = "imgui.ini"; LogFilename = "imgui_log.txt"; - Fonts = &GImDefaultFontAtlas; - FontGlobalScale = 1.0f; - FontDefault = NULL; - DisplayFramebufferScale = ImVec2(1.0f, 1.0f); - MousePos = ImVec2(-FLT_MAX, -FLT_MAX); - MousePosPrev = ImVec2(-FLT_MAX, -FLT_MAX); MouseDoubleClickTime = 0.30f; MouseDoubleClickMaxDist = 6.0f; - MouseDragThreshold = 6.0f; - for (int i = 0; i < IM_ARRAYSIZE(MouseDownDuration); i++) - MouseDownDuration[i] = MouseDownDurationPrev[i] = -1.0f; - for (int i = 0; i < IM_ARRAYSIZE(KeysDownDuration); i++) - KeysDownDuration[i] = KeysDownDurationPrev[i] = -1.0f; for (int i = 0; i < ImGuiKey_COUNT; i++) KeyMap[i] = -1; KeyRepeatDelay = 0.250f; KeyRepeatRate = 0.050f; UserData = NULL; + Fonts = &GImDefaultFontAtlas; + FontGlobalScale = 1.0f; + FontDefault = NULL; + FontAllowUserScaling = false; + DisplayFramebufferScale = ImVec2(1.0f, 1.0f); + DisplayVisibleMin = DisplayVisibleMax = ImVec2(0.0f, 0.0f); + // User functions RenderDrawListsFn = NULL; MemAllocFn = malloc; @@ -780,6 +776,13 @@ ImGuiIO::ImGuiIO() ImeSetInputScreenPosFn = ImeSetInputScreenPosFn_DefaultImpl; ImeWindowHandle = NULL; + // Input (NB: we already have memset zero the entire structure) + MousePos = ImVec2(-FLT_MAX, -FLT_MAX); + MousePosPrev = ImVec2(-FLT_MAX, -FLT_MAX); + MouseDragThreshold = 6.0f; + for (int i = 0; i < IM_ARRAYSIZE(MouseDownDuration); i++) MouseDownDuration[i] = MouseDownDurationPrev[i] = -1.0f; + for (int i = 0; i < IM_ARRAYSIZE(KeysDownDuration); i++) KeysDownDuration[i] = KeysDownDurationPrev[i] = -1.0f; + // Set OS X style defaults based on __APPLE__ compile time flag #ifdef __APPLE__ OSXBehaviors = true; @@ -1768,14 +1771,13 @@ ImGuiWindow::ImGuiWindow(const char* name) Name = ImStrdup(name); ID = ImHash(name, 0); IDStack.push_back(ID); - MoveId = GetID("#MOVE"); - Flags = 0; OrderWithinParent = 0; PosFloat = Pos = ImVec2(0.0f, 0.0f); Size = SizeFull = ImVec2(0.0f, 0.0f); SizeContents = SizeContentsExplicit = ImVec2(0.0f, 0.0f); WindowPadding = ImVec2(0.0f, 0.0f); + MoveId = GetID("#MOVE"); Scroll = ImVec2(0.0f, 0.0f); ScrollTarget = ImVec2(FLT_MAX, FLT_MAX); ScrollTargetCenterRatio = ImVec2(0.5f, 0.5f); @@ -2156,6 +2158,20 @@ void ImGui::NewFrame() g.RenderDrawData.CmdLists = NULL; g.RenderDrawData.CmdListsCount = g.RenderDrawData.TotalVtxCount = g.RenderDrawData.TotalIdxCount = 0; + // Clear reference to active widget if the widget isn't alive anymore + g.HoveredIdPreviousFrame = g.HoveredId; + g.HoveredId = 0; + g.HoveredIdAllowOverlap = false; + if (!g.ActiveIdIsAlive && g.ActiveIdPreviousFrame == g.ActiveId && g.ActiveId != 0) + ClearActiveID(); + g.ActiveIdPreviousFrame = g.ActiveId; + g.ActiveIdIsAlive = false; + g.ActiveIdIsJustActivated = false; + // Update keyboard input state + memcpy(g.IO.KeysDownDurationPrev, g.IO.KeysDownDuration, sizeof(g.IO.KeysDownDuration)); + for (int i = 0; i < IM_ARRAYSIZE(g.IO.KeysDown); i++) + g.IO.KeysDownDuration[i] = g.IO.KeysDown[i] ? (g.IO.KeysDownDuration[i] < 0.0f ? 0.0f : g.IO.KeysDownDuration[i] + g.IO.DeltaTime) : -1.0f; + // Update mouse input state // If mouse just appeared or disappeared (usually denoted by -FLT_MAX component, but in reality we test for -256000.0f) we cancel out movement in MouseDelta if (IsMousePosValid(&g.IO.MousePos) && IsMousePosValid(&g.IO.MousePosPrev)) @@ -2190,9 +2206,6 @@ void ImGui::NewFrame() g.IO.MouseDragMaxDistanceSqr[i] = ImMax(g.IO.MouseDragMaxDistanceSqr[i], ImLengthSqr(g.IO.MousePos - g.IO.MouseClickedPos[i])); } } - memcpy(g.IO.KeysDownDurationPrev, g.IO.KeysDownDuration, sizeof(g.IO.KeysDownDuration)); - for (int i = 0; i < IM_ARRAYSIZE(g.IO.KeysDown); i++) - g.IO.KeysDownDuration[i] = g.IO.KeysDown[i] ? (g.IO.KeysDownDuration[i] < 0.0f ? 0.0f : g.IO.KeysDownDuration[i] + g.IO.DeltaTime) : -1.0f; // Calculate frame-rate for the user, as a purely luxurious feature g.FramerateSecPerFrameAccum += g.IO.DeltaTime - g.FramerateSecPerFrame[g.FramerateSecPerFrameIdx]; @@ -2200,16 +2213,6 @@ void ImGui::NewFrame() g.FramerateSecPerFrameIdx = (g.FramerateSecPerFrameIdx + 1) % IM_ARRAYSIZE(g.FramerateSecPerFrame); g.IO.Framerate = 1.0f / (g.FramerateSecPerFrameAccum / (float)IM_ARRAYSIZE(g.FramerateSecPerFrame)); - // Clear reference to active widget if the widget isn't alive anymore - g.HoveredIdPreviousFrame = g.HoveredId; - g.HoveredId = 0; - g.HoveredIdAllowOverlap = false; - if (!g.ActiveIdIsAlive && g.ActiveIdPreviousFrame == g.ActiveId && g.ActiveId != 0) - ClearActiveID(); - g.ActiveIdPreviousFrame = g.ActiveId; - g.ActiveIdIsAlive = false; - g.ActiveIdIsJustActivated = false; - // Handle user moving window with mouse (at the beginning of the frame to avoid input lag or sheering). Only valid for root windows. if (g.MovedWindowMoveId && g.MovedWindowMoveId == g.ActiveId) { From 358e7a194e0c5f86abdbd5ce5934561202a0cd50 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 29 Aug 2017 16:13:17 +0800 Subject: [PATCH 303/921] Added GetKeyPressedAmount() (from Nav branch) to be able to measure fast repeat rate accurately. Added internal CalcTypematicPressedRepeatAmount() function. --- imgui.cpp | 26 ++++++++++++++++++++------ imgui.h | 1 + imgui_internal.h | 2 ++ 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index ed69170f5..80da34185 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3154,6 +3154,25 @@ bool ImGui::IsKeyDown(int user_key_index) return GImGui->IO.KeysDown[user_key_index]; } +int ImGui::CalcTypematicPressedRepeatAmount(float t, float t_prev, float repeat_delay, float repeat_rate) +{ + if (t == 0.0f) + return 1; + if (t <= repeat_delay || repeat_rate <= 0.0f) + return 0; + const int count = (int)((t - repeat_delay) / repeat_rate) - (int)((t_prev - repeat_delay) / repeat_rate); + return (count > 0) ? count : 0; +} + +int ImGui::GetKeyPressedAmount(int key_index, float repeat_delay, float repeat_rate) +{ + ImGuiContext& g = *GImGui; + if (key_index < 0) return false; + IM_ASSERT(key_index >= 0 && key_index < IM_ARRAYSIZE(g.IO.KeysDown)); + const float t = g.IO.KeysDownDuration[key_index]; + return CalcTypematicPressedRepeatAmount(t, t - g.IO.DeltaTime, repeat_delay, repeat_rate); +} + bool ImGui::IsKeyPressed(int user_key_index, bool repeat) { ImGuiContext& g = *GImGui; @@ -3162,13 +3181,8 @@ bool ImGui::IsKeyPressed(int user_key_index, bool repeat) const float t = g.IO.KeysDownDuration[user_key_index]; if (t == 0.0f) return true; - if (repeat && t > g.IO.KeyRepeatDelay) - { - float delay = g.IO.KeyRepeatDelay, rate = g.IO.KeyRepeatRate; - if ((fmodf(t - delay, rate) > rate*0.5f) != (fmodf(t - delay - g.IO.DeltaTime, rate) > rate*0.5f)) - return true; - } + return GetKeyPressedAmount(user_key_index, g.IO.KeyRepeatDelay, g.IO.KeyRepeatRate) > 0; return false; } diff --git a/imgui.h b/imgui.h index 14fd4d9d5..f40c7db97 100644 --- a/imgui.h +++ b/imgui.h @@ -452,6 +452,7 @@ namespace ImGui IMGUI_API bool IsKeyDown(int user_key_index); // is key being held. == io.KeysDown[user_key_index]. note that imgui doesn't know the semantic of each entry of io.KeyDown[]. Use your own indices/enums according to how your backend/engine stored them into KeyDown[]! IMGUI_API bool IsKeyPressed(int user_key_index, bool repeat = true); // was key pressed (went from !Down to Down). if repeat=true, uses io.KeyRepeatDelay / KeyRepeatRate IMGUI_API bool IsKeyReleased(int user_key_index); // was key released (went from Down to !Down).. + IMGUI_API int GetKeyPressedAmount(int key_index, float repeat_delay, float rate); // uses provided repeat rate/delay. return a count, most often 0 or 1 but might be >1 if RepeatRate is small enough that DeltaTime > RepeatRate IMGUI_API bool IsMouseDown(int button); // is mouse button held IMGUI_API bool IsMouseClicked(int button, bool repeat = false); // did mouse button clicked (went from !Down to Down) IMGUI_API bool IsMouseDoubleClicked(int button); // did mouse button double-clicked. a double-click returns false in IsMouseClicked(). uses io.MouseDoubleClickTime. diff --git a/imgui_internal.h b/imgui_internal.h index 10598ac6f..80b2f4ded 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -764,6 +764,8 @@ namespace ImGui IMGUI_API void OpenPopupEx(ImGuiID id, bool reopen_existing); IMGUI_API bool IsPopupOpen(ImGuiID id); + IMGUI_API int CalcTypematicPressedRepeatAmount(float t, float t_prev, float repeat_delay, float repeat_rate); + // New Columns API IMGUI_API void BeginColumns(const char* id, int count, ImGuiColumnsFlags flags = 0); // setup number of columns. use an identifier to distinguish multiple column sets. close with EndColumns(). IMGUI_API void EndColumns(); // close columns From 287a4b6b38d1f28ffcb06b8c58957034a0cd0b6f Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 29 Aug 2017 16:52:37 +0800 Subject: [PATCH 304/921] Merged from Navigation branch: https://github.com/ocornut/imgui/commit/5cac4926c82a41253bd3540ce1bb4f50b0cfc146 fix title bar color of window under a modal window. --- imgui.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 80da34185..766116333 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1935,7 +1935,7 @@ bool ImGui::ItemAdd(const ImRect& bb, const ImGuiID* id) if (IsClippedEx(bb, id, false)) return false; - // This is a sensible default, but widgets are free to override it after calling ItemAdd() + // Setting LastItemHoveredAndUsable for IsItemHovered(). This is a sensible default, but widgets are free to override it. if (IsMouseHoveringRect(bb.Min, bb.Max)) { // Matching the behavior of IsHovered() but allow if ActiveId==window->MoveID (we clicked on the window background) @@ -4008,11 +4008,12 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us if (!(g.CurrentWindowStack[root_idx]->Flags & ImGuiWindowFlags_ChildWindow)) break; for (root_non_popup_idx = root_idx; root_non_popup_idx > 0; root_non_popup_idx--) - if (!(g.CurrentWindowStack[root_non_popup_idx]->Flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_Popup))) + if (!(g.CurrentWindowStack[root_non_popup_idx]->Flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_Popup)) || (g.CurrentWindowStack[root_non_popup_idx]->Flags & ImGuiWindowFlags_Modal)) break; window->ParentWindow = parent_window; window->RootWindow = g.CurrentWindowStack[root_idx]; - window->RootNonPopupWindow = g.CurrentWindowStack[root_non_popup_idx]; // This is merely for displaying the TitleBgActive color. + window->RootNonPopupWindow = g.CurrentWindowStack[root_non_popup_idx]; // Used to display TitleBgActive color and for selecting which window to use for NavWindowing + // When reusing window again multiple times a frame, just append content (don't need to setup again) if (first_begin_of_the_frame) @@ -4235,7 +4236,7 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us if (window->Collapsed) { // Title bar only - RenderFrame(title_bar_rect.GetTL(), title_bar_rect.GetBR(), GetColorU32(ImGuiCol_TitleBgCollapsed), true, window_rounding); + RenderFrame(title_bar_rect.GetTL(), title_bar_rect.GetBR(), GetColorU32(ImGuiCol_TitleBgCollapsed), true, window_rounding); } else { @@ -4296,8 +4297,9 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us window->DrawList->AddRectFilled(window->Pos+ImVec2(0,window->TitleBarHeight()), window->Pos+window->Size, ColorConvertFloat4ToU32(bg_color), window_rounding, (flags & ImGuiWindowFlags_NoTitleBar) ? ImGuiCorner_All : ImGuiCorner_BotLeft|ImGuiCorner_BotRight); // Title bar + const bool is_focused = g.NavWindow && window->RootNonPopupWindow == g.NavWindow->RootNonPopupWindow; if (!(flags & ImGuiWindowFlags_NoTitleBar)) - window->DrawList->AddRectFilled(title_bar_rect.GetTL(), title_bar_rect.GetBR(), GetColorU32((g.NavWindow && window->RootNonPopupWindow == g.NavWindow->RootNonPopupWindow) ? ImGuiCol_TitleBgActive : ImGuiCol_TitleBg), window_rounding, ImGuiCorner_TopLeft|ImGuiCorner_TopRight); + window->DrawList->AddRectFilled(title_bar_rect.GetTL(), title_bar_rect.GetBR(), GetColorU32(is_focused ? ImGuiCol_TitleBgActive : ImGuiCol_TitleBg), window_rounding, ImGuiCorner_TopLeft|ImGuiCorner_TopRight); // Menu bar if (flags & ImGuiWindowFlags_MenuBar) @@ -4387,11 +4389,12 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us // Title bar if (!(flags & ImGuiWindowFlags_NoTitleBar)) { + // Close button if (p_open != NULL) { - const float pad = 2.0f; - const float rad = (window->TitleBarHeight() - pad*2.0f) * 0.5f; - if (CloseButton(window->GetID("#CLOSE"), window->Rect().GetTR() + ImVec2(-pad - rad, pad + rad), rad)) + const float PAD = 2.0f; + const float rad = (window->TitleBarHeight() - PAD*2.0f) * 0.5f; + if (CloseButton(window->GetID("#CLOSE"), window->Rect().GetTR() + ImVec2(-PAD - rad, PAD + rad), rad)) *p_open = false; } From c9298c26571ab244957e871482a46e7696266b89 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 29 Aug 2017 17:09:44 +0800 Subject: [PATCH 305/921] Merged from Navigation branch: f71cdd13b71895c1d7f10b7eaa9d0fdc2849f626 Internal tidying up, moved code to CalcNextScrollFromScrollTargetAndClamp() so it can be reused by upcoming nav code. c816e6c74250b8946333682663dc9365e4b14e13 Fixed SetScrollX() handling of center ratio (which actually wasn't exposed publicly). (#323, #246) --- imgui.cpp | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 766116333..913bd9dde 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -609,6 +609,7 @@ static inline bool IsWindowContentHoverable(ImGuiWindow* window); static void ClearSetNextWindowData(); static void CheckStacksSize(ImGuiWindow* window, bool write); static void Scrollbar(ImGuiWindow* window, bool horizontal); +static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window); static void AddDrawListToRenderList(ImVector& out_render_list, ImDrawList* draw_list); static void AddWindowToRenderList(ImVector& out_render_list, ImGuiWindow* window); @@ -3894,6 +3895,24 @@ static void ApplySizeFullWithConstraint(ImGuiWindow* window, ImVec2 new_size) window->SizeFull = new_size; } +static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window) +{ + ImVec2 scroll = window->Scroll; + float cr_x = window->ScrollTargetCenterRatio.x; + float cr_y = window->ScrollTargetCenterRatio.y; + if (window->ScrollTarget.x < FLT_MAX) + scroll.x = window->ScrollTarget.x - cr_x * (window->SizeFull.x - window->ScrollbarSizes.x); + if (window->ScrollTarget.y < FLT_MAX) + scroll.y = window->ScrollTarget.y - (1.0f - cr_y) * (window->TitleBarHeight() + window->MenuBarHeight()) - cr_y * (window->SizeFull.y - window->ScrollbarSizes.y); + scroll = ImMax(scroll, ImVec2(0.0f, 0.0f)); + if (!window->Collapsed && !window->SkipItems) + { + scroll.x = ImMin(scroll.x, ImMax(0.0f, window->SizeContents.x - (window->SizeFull.x - window->ScrollbarSizes.x))); // == GetScrollMaxX for that window + scroll.y = ImMin(scroll.y, ImMax(0.0f, window->SizeContents.y - (window->SizeFull.y - window->ScrollbarSizes.y))); // == GetScrollMaxY for that window + } + return scroll; +} + // Push a new ImGui window to add widgets to. // - A default window called "Debug" is automatically stacked at the beginning of every frame so you can use widgets without explicitly calling a Begin/End pair. // - Begin/End can be called multiple times during the frame with the same window name to append content. @@ -4208,23 +4227,8 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us window->FocusIdxAllRequestNext = window->FocusIdxTabRequestNext = INT_MAX; // Apply scrolling - if (window->ScrollTarget.x < FLT_MAX) - { - window->Scroll.x = window->ScrollTarget.x; - window->ScrollTarget.x = FLT_MAX; - } - if (window->ScrollTarget.y < FLT_MAX) - { - float center_ratio = window->ScrollTargetCenterRatio.y; - window->Scroll.y = window->ScrollTarget.y - ((1.0f - center_ratio) * (window->TitleBarHeight() + window->MenuBarHeight())) - (center_ratio * (window->SizeFull.y - window->ScrollbarSizes.y)); - window->ScrollTarget.y = FLT_MAX; - } - window->Scroll = ImMax(window->Scroll, ImVec2(0.0f, 0.0f)); - if (!window->Collapsed && !window->SkipItems) - { - window->Scroll.x = ImMin(window->Scroll.x, GetScrollMaxX()); - window->Scroll.y = ImMin(window->Scroll.y, GetScrollMaxY()); - } + window->Scroll = CalcNextScrollFromScrollTargetAndClamp(window); + window->ScrollTarget = ImVec2(FLT_MAX, FLT_MAX); // Modal window darkens what is behind them if ((flags & ImGuiWindowFlags_Modal) != 0 && window == GetFrontMostModalRootWindow()) From aef041f94884cb30b4da59fdbab1c85f4b3b2575 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 29 Aug 2017 17:09:56 +0800 Subject: [PATCH 306/921] Merged from Navigation branch --- imgui.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 913bd9dde..532c67648 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4255,24 +4255,27 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us bool hovered, held; ButtonBehavior(resize_rect, resize_id, &hovered, &held, ImGuiButtonFlags_FlattenChilds); resize_col = GetColorU32(held ? ImGuiCol_ResizeGripActive : hovered ? ImGuiCol_ResizeGripHovered : ImGuiCol_ResizeGrip); - if (hovered || held) g.MouseCursor = ImGuiMouseCursor_ResizeNWSE; + ImVec2 size_target(FLT_MAX,FLT_MAX); if (g.HoveredWindow == window && held && g.IO.MouseDoubleClicked[0]) { // Manual auto-fit when double-clicking - ApplySizeFullWithConstraint(window, size_auto_fit); - MarkIniSettingsDirty(window); + size_target = size_auto_fit; ClearActiveID(); } else if (held) { // We don't use an incremental MouseDelta but rather compute an absolute target size based on mouse position - ApplySizeFullWithConstraint(window, (g.IO.MousePos - g.ActiveIdClickOffset + resize_rect.GetSize()) - window->Pos); - MarkIniSettingsDirty(window); + size_target = (g.IO.MousePos - g.ActiveIdClickOffset + resize_rect.GetSize()) - window->Pos; } + if (size_target.x != FLT_MAX && size_target.y != FLT_MAX) + { + ApplySizeFullWithConstraint(window, size_target); + MarkIniSettingsDirty(window); + } window->Size = window->SizeFull; title_bar_rect = window->TitleBarRect(); } From 550dc0999826379f0f79f7c30860df74bef8ce5d Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 29 Aug 2017 17:12:18 +0800 Subject: [PATCH 307/921] Merged from Navigation branch (misc) --- imgui.cpp | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 532c67648..590329cb3 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2633,6 +2633,19 @@ static void AddWindowToRenderList(ImVector& out_render_list, ImGuiW } } +static void AddWindowToRenderListSelectLayer(ImGuiWindow* window) +{ + // FIXME: Generalize this with a proper layering system so e.g. user can draw in specific layers, below text, .. + ImGuiContext& g = *GImGui; + g.IO.MetricsActiveWindows++; + if (window->Flags & ImGuiWindowFlags_Popup) + AddWindowToRenderList(g.RenderDrawLists[1], window); + else if (window->Flags & ImGuiWindowFlags_Tooltip) + AddWindowToRenderList(g.RenderDrawLists[2], window); + else + AddWindowToRenderList(g.RenderDrawLists[0], window); +} + // When using this function it is sane to ensure that float are perfectly rounded to integer values, to that e.g. (int)(max.x-min.x) in user's render produce correct result. void ImGui::PushClipRect(const ImVec2& clip_rect_min, const ImVec2& clip_rect_max, bool intersect_with_current_clip_rect) { @@ -2734,16 +2747,7 @@ void ImGui::Render() { ImGuiWindow* window = g.Windows[i]; if (window->Active && window->HiddenFrames <= 0 && (window->Flags & (ImGuiWindowFlags_ChildWindow)) == 0) - { - // FIXME: Generalize this with a proper layering system so e.g. user can draw in specific layers, below text, .. - g.IO.MetricsActiveWindows++; - if (window->Flags & ImGuiWindowFlags_Popup) - AddWindowToRenderList(g.RenderDrawLists[1], window); - else if (window->Flags & ImGuiWindowFlags_Tooltip) - AddWindowToRenderList(g.RenderDrawLists[2], window); - else - AddWindowToRenderList(g.RenderDrawLists[0], window); - } + AddWindowToRenderListSelectLayer(window); } // Flatten layers @@ -3138,7 +3142,7 @@ bool ImGui::IsAnyWindowHovered() static bool IsKeyPressedMap(ImGuiKey key, bool repeat) { const int key_index = GImGui->IO.KeyMap[key]; - return ImGui::IsKeyPressed(key_index, repeat); + return (key_index >= 0) ? ImGui::IsKeyPressed(key_index, repeat) : false; } int ImGui::GetKeyIndex(ImGuiKey imgui_key) From ddf41b039805983d9501d31a98aeccd3c6dbec30 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 29 Aug 2017 17:27:19 +0800 Subject: [PATCH 308/921] Merged from Navigation branch. TAB/Alt-TAB processing now deactivate if holding Ctrl. --- imgui.cpp | 19 ++++++++----------- imgui_internal.h | 2 +- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 590329cb3..56f3ee536 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1977,7 +1977,7 @@ bool ImGui::IsHovered(const ImRect& bb, ImGuiID id, bool flatten_childs) return false; } -bool ImGui::FocusableItemRegister(ImGuiWindow* window, bool is_active, bool tab_stop) +bool ImGui::FocusableItemRegister(ImGuiWindow* window, ImGuiID id, bool tab_stop) { ImGuiContext& g = *GImGui; @@ -1986,13 +1986,10 @@ bool ImGui::FocusableItemRegister(ImGuiWindow* window, bool is_active, bool tab_ if (allow_keyboard_focus) window->FocusIdxTabCounter++; - // Process keyboard input at this point: TAB, Shift-TAB switch focus - // We can always TAB out of a widget that doesn't allow tabbing in. - if (tab_stop && window->FocusIdxAllRequestNext == INT_MAX && window->FocusIdxTabRequestNext == INT_MAX && is_active && IsKeyPressedMap(ImGuiKey_Tab)) - { - // Modulo on index will be applied at the end of frame once we've got the total counter of items. - window->FocusIdxTabRequestNext = window->FocusIdxTabCounter + (g.IO.KeyShift ? (allow_keyboard_focus ? -1 : 0) : +1); - } + // Process keyboard input at this point: TAB/Shift-TAB to tab out of the currently focused item. + // Note that we can always TAB out of a widget that doesn't allow tabbing in. + if (tab_stop && (g.ActiveId == id) && window->FocusIdxAllRequestNext == INT_MAX && window->FocusIdxTabRequestNext == INT_MAX && !g.IO.KeyCtrl && IsKeyPressedMap(ImGuiKey_Tab)) + window->FocusIdxTabRequestNext = window->FocusIdxTabCounter + (g.IO.KeyShift ? (allow_keyboard_focus ? -1 : 0) : +1); // Modulo on index will be applied at the end of frame once we've got the total counter of items. if (window->FocusIdxAllCounter == window->FocusIdxAllRequestCurrent) return true; @@ -6715,7 +6712,7 @@ bool ImGui::SliderFloat(const char* label, float* v, float v_min, float v_max, c // Tabbing or CTRL-clicking on Slider turns it into an input box bool start_text_input = false; - const bool tab_focus_requested = FocusableItemRegister(window, g.ActiveId == id); + const bool tab_focus_requested = FocusableItemRegister(window, id); if (tab_focus_requested || (hovered && g.IO.MouseClicked[0])) { SetActiveID(id, window); @@ -7013,7 +7010,7 @@ bool ImGui::DragFloat(const char* label, float* v, float v_speed, float v_min, f // Tabbing or CTRL-clicking on Drag turns it into an input box bool start_text_input = false; - const bool tab_focus_requested = FocusableItemRegister(window, g.ActiveId == id); + const bool tab_focus_requested = FocusableItemRegister(window, id); if (tab_focus_requested || (hovered && (g.IO.MouseClicked[0] | g.IO.MouseDoubleClicked[0]))) { SetActiveID(id, window); @@ -7818,7 +7815,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 // NB: we are only allowed to access 'edit_state' if we are the active widget. ImGuiTextEditState& edit_state = g.InputTextState; - const bool focus_requested = FocusableItemRegister(window, g.ActiveId == id, (flags & (ImGuiInputTextFlags_CallbackCompletion|ImGuiInputTextFlags_AllowTabInput)) == 0); // Using completion callback disable keyboard tabbing + const bool focus_requested = FocusableItemRegister(window, id, (flags & (ImGuiInputTextFlags_CallbackCompletion|ImGuiInputTextFlags_AllowTabInput)) == 0); // Using completion callback disable keyboard tabbing const bool focus_requested_by_code = focus_requested && (window->FocusIdxAllCounter == window->FocusIdxAllRequestCurrent); const bool focus_requested_by_tab = focus_requested && !focus_requested_by_code; diff --git a/imgui_internal.h b/imgui_internal.h index 80b2f4ded..1a02473a0 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -756,7 +756,7 @@ namespace ImGui IMGUI_API bool ItemAdd(const ImRect& bb, const ImGuiID* id); IMGUI_API bool IsClippedEx(const ImRect& bb, const ImGuiID* id, bool clip_even_when_logged); IMGUI_API bool IsHovered(const ImRect& bb, ImGuiID id, bool flatten_childs = false); - IMGUI_API bool FocusableItemRegister(ImGuiWindow* window, bool is_active, bool tab_stop = true); // Return true if focus is requested + IMGUI_API bool FocusableItemRegister(ImGuiWindow* window, ImGuiID id, bool tab_stop = true); // Return true if focus is requested IMGUI_API void FocusableItemUnregister(ImGuiWindow* window); IMGUI_API ImVec2 CalcItemSize(ImVec2 size, float default_x, float default_y); IMGUI_API float CalcWrapWidthForPos(const ImVec2& pos, float wrap_pos_x); From 6cca4025eea4bb2eefe3f7af84a164ea9cc96335 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 29 Aug 2017 17:56:53 +0800 Subject: [PATCH 309/921] Merge from Navigation branch: 6aa80197633f23bb0c7d72ac4731d6895766c613 --- imgui.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 56f3ee536..39ee504c5 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2165,6 +2165,9 @@ void ImGui::NewFrame() g.ActiveIdPreviousFrame = g.ActiveId; g.ActiveIdIsAlive = false; g.ActiveIdIsJustActivated = false; + if (g.ScalarAsInputTextId && g.ActiveId != g.ScalarAsInputTextId) + g.ScalarAsInputTextId = 0; + // Update keyboard input state memcpy(g.IO.KeysDownDurationPrev, g.IO.KeysDownDuration, sizeof(g.IO.KeysDownDuration)); for (int i = 0; i < IM_ARRAYSIZE(g.IO.KeysDown); i++) @@ -6480,11 +6483,6 @@ bool ImGui::InputScalarAsWidgetReplacement(const ImRect& aabb, const char* label g.ScalarAsInputTextId = g.ActiveId; SetHoveredID(id); } - else if (g.ActiveId != g.ScalarAsInputTextId) - { - // Release - g.ScalarAsInputTextId = 0; - } if (text_value_changed) return DataTypeApplyOpFromText(buf, GImGui->InputTextState.InitialText.begin(), data_type, data_ptr, NULL); return false; @@ -6727,9 +6725,8 @@ bool ImGui::SliderFloat(const char* label, float* v, float v_min, float v_max, c if (start_text_input || (g.ActiveId == id && g.ScalarAsInputTextId == id)) return InputScalarAsWidgetReplacement(frame_bb, label, ImGuiDataType_Float, v, id, decimal_precision); - ItemSize(total_bb, style.FramePadding.y); - // Actual slider behavior + render grab + ItemSize(total_bb, style.FramePadding.y); const bool value_changed = SliderBehavior(frame_bb, id, v, v_min, v_max, power, decimal_precision); // Display value using user-provided display format so user can add prefix/suffix/decorations to the value. @@ -8983,6 +8980,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled) } bool hovered = enabled && IsHovered(window->DC.LastItemRect, id); + if (menuset_is_open) g.NavWindow = backed_nav_window; From 35e4fa7b851fb273c7e4f9bfae469072a93b6dee Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 29 Aug 2017 18:21:36 +0800 Subject: [PATCH 310/921] Merged from Navigation branch (DragBehavior) --- imgui.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 39ee504c5..4004a6285 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -6926,15 +6926,20 @@ bool ImGui::DragBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v_s v_speed = (v_max - v_min) * g.DragSpeedDefaultRatio; float v_cur = g.DragCurrentValue; const ImVec2 mouse_drag_delta = GetMouseDragDelta(0, 1.0f); - if (fabsf(mouse_drag_delta.x - g.DragLastMouseDelta.x) > 0.0f) + float adjust_delta = 0.0f; + //if (g.ActiveIdSource == ImGuiInputSource_Mouse) { - float speed = v_speed; + adjust_delta = mouse_drag_delta.x - g.DragLastMouseDelta.x; if (g.IO.KeyShift && g.DragSpeedScaleFast >= 0.0f) - speed = speed * g.DragSpeedScaleFast; + adjust_delta *= g.DragSpeedScaleFast; if (g.IO.KeyAlt && g.DragSpeedScaleSlow >= 0.0f) - speed = speed * g.DragSpeedScaleSlow; + adjust_delta *= g.DragSpeedScaleSlow; + } + adjust_delta *= v_speed; + g.DragLastMouseDelta.x = mouse_drag_delta.x; - float adjust_delta = (mouse_drag_delta.x - g.DragLastMouseDelta.x) * speed; + if (fabsf(adjust_delta) > 0.0f) + { if (fabsf(power - 1.0f) > 0.001f) { // Logarithmic curve on both side of 0.0 @@ -6949,7 +6954,6 @@ bool ImGui::DragBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v_s { v_cur += adjust_delta; } - g.DragLastMouseDelta.x = mouse_drag_delta.x; // Clamp if (v_min < v_max) From 96d2942373c650dcd40979c60ec53a795497d648 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 29 Aug 2017 18:40:14 +0800 Subject: [PATCH 311/921] InputText: Merged bits from Navigation branch (inc. g.ActiveIdIsJustActivated is only set on the toggle). --- imgui.cpp | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 4004a6285..a94546e04 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1868,11 +1868,10 @@ ImGuiWindow* ImGui::GetParentWindow() void ImGui::SetActiveID(ImGuiID id, ImGuiWindow* window) { ImGuiContext& g = *GImGui; + g.ActiveIdIsJustActivated = (g.ActiveId != id); g.ActiveId = id; g.ActiveIdAllowOverlap = false; - g.ActiveIdIsJustActivated = true; - if (id) - g.ActiveIdIsAlive = true; + g.ActiveIdIsAlive |= (id != 0); g.ActiveIdWindow = window; } @@ -7829,6 +7828,8 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 const bool user_clicked = hovered && io.MouseClicked[0]; const bool user_scrolled = is_multiline && g.ActiveId == 0 && edit_state.Id == id && g.ActiveIdPreviousFrame == draw_window->GetIDNoKeepAlive("#SCROLLY"); + bool clear_active_id = false; + bool select_all = (g.ActiveId != id) && (flags & ImGuiInputTextFlags_AutoSelectAll) != 0; if (focus_requested || user_clicked || user_scrolled) { @@ -7874,8 +7875,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 else if (io.MouseClicked[0]) { // Release focus when we click outside - if (g.ActiveId == id) - ClearActiveID(); + clear_active_id = true; } bool value_changed = false; @@ -7948,9 +7948,12 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 // Consume characters memset(g.IO.InputCharacters, 0, sizeof(g.IO.InputCharacters)); } + } - // Handle various key-presses - bool cancel_edit = false; + bool cancel_edit = false; + if (g.ActiveId == id && !g.ActiveIdIsJustActivated && !clear_active_id) + { + // Handle key-presses const int k_mask = (io.KeyShift ? STB_TEXTEDIT_K_SHIFT : 0); const bool is_shortcut_key_only = (io.OSXBehaviors ? (io.KeySuper && !io.KeyCtrl) : (io.KeyCtrl && !io.KeySuper)) && !io.KeyAlt && !io.KeyShift; // OS X style: Shortcuts using Cmd/Super instead of Ctrl const bool is_wordmove_key_down = io.OSXBehaviors ? io.KeyAlt : io.KeyCtrl; // OS X style: Text editing cursor movement using Alt instead of Ctrl @@ -7977,8 +7980,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 bool ctrl_enter_for_new_line = (flags & ImGuiInputTextFlags_CtrlEnterForNewLine) != 0; if (!is_multiline || (ctrl_enter_for_new_line && !io.KeyCtrl) || (!ctrl_enter_for_new_line && io.KeyCtrl)) { - ClearActiveID(); - enter_pressed = true; + enter_pressed = clear_active_id = true; } else if (is_editable) { @@ -7993,7 +7995,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 if (InputTextFilterCharacter(&c, flags, callback, user_data)) edit_state.OnKeyPressed((int)c); } - else if (IsKeyPressedMap(ImGuiKey_Escape)) { ClearActiveID(); cancel_edit = true; } + else if (IsKeyPressedMap(ImGuiKey_Escape)) { clear_active_id = cancel_edit = true; } else if (is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_Z) && is_editable) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_UNDO); edit_state.ClearSelection(); } else if (is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_Y) && is_editable) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_REDO); edit_state.ClearSelection(); } else if (is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_A)) { edit_state.SelectAll(); edit_state.CursorFollow = true; } @@ -8047,7 +8049,10 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 ImGui::MemFree(clipboard_filtered); } } + } + if (g.ActiveId == id) + { if (cancel_edit) { // Restore initial value @@ -8057,7 +8062,11 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 value_changed = true; } } - else + + // When using 'ImGuiInputTextFlags_EnterReturnsTrue' as a special case we reapply the live buffer back to the input buffer before clearing ActiveId, even though strictly speaking it wasn't modified on this frame. + // If we didn't do that, code like InputInt() with ImGuiInputTextFlags_EnterReturnsTrue would fail. Also this allows the user to use InputText() with ImGuiInputTextFlags_EnterReturnsTrue without maintaining any user-side storage. + bool apply_edit_back_to_user_buffer = !cancel_edit || (enter_pressed && (flags & ImGuiInputTextFlags_EnterReturnsTrue) != 0); + if (apply_edit_back_to_user_buffer) { // Apply new value immediately - copy modified buffer back // Note that as soon as the input box is active, the in-widget value gets priority over any underlying modification of the input buffer @@ -8145,6 +8154,10 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 } } + // Release active ID at the end of the function (so e.g. pressing Return still does a final application of the value) + if (clear_active_id && g.ActiveId == id) + ClearActiveID(); + // Render // Select which buffer we are going to display. When ImGuiInputTextFlags_NoLiveEdit is set 'buf' might still be the old value. We set buf to NULL to prevent accidental usage from now on. const char* buf_display = (g.ActiveId == id && is_editable) ? edit_state.TempTextBuffer.Data : buf; buf = NULL; From 6a1ba317c7b14fd0e024d329493b165a176512c5 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 29 Aug 2017 19:05:56 +0800 Subject: [PATCH 312/921] Demo: Minor coding style tweaks so bgfx copy needs less patching. --- imgui.cpp | 6 +++--- imgui_demo.cpp | 21 +++++++++++---------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index a94546e04..355108449 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -7996,9 +7996,9 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 edit_state.OnKeyPressed((int)c); } else if (IsKeyPressedMap(ImGuiKey_Escape)) { clear_active_id = cancel_edit = true; } - else if (is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_Z) && is_editable) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_UNDO); edit_state.ClearSelection(); } - else if (is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_Y) && is_editable) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_REDO); edit_state.ClearSelection(); } - else if (is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_A)) { edit_state.SelectAll(); edit_state.CursorFollow = true; } + else if (is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_Z) && is_editable) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_UNDO); edit_state.ClearSelection(); } + else if (is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_Y) && is_editable) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_REDO); edit_state.ClearSelection(); } + else if (is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_A)) { edit_state.SelectAll(); edit_state.CursorFollow = true; } else if (is_shortcut_key_only && !is_password && ((IsKeyPressedMap(ImGuiKey_X) && is_editable) || IsKeyPressedMap(ImGuiKey_C)) && (!is_multiline || edit_state.HasSelection())) { // Cut, Copy diff --git a/imgui_demo.cpp b/imgui_demo.cpp index abf89f349..b114520ba 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1550,9 +1550,9 @@ void ImGui::ShowTestWindow(bool* p_open) ImGui::InputFloat("blue", &bar, 0.05f, 0, 3); ImGui::NextColumn(); - if (ImGui::CollapsingHeader("Category A")) ImGui::Text("Blah blah blah"); ImGui::NextColumn(); - if (ImGui::CollapsingHeader("Category B")) ImGui::Text("Blah blah blah"); ImGui::NextColumn(); - if (ImGui::CollapsingHeader("Category C")) ImGui::Text("Blah blah blah"); ImGui::NextColumn(); + if (ImGui::CollapsingHeader("Category A")) { ImGui::Text("Blah blah blah"); } ImGui::NextColumn(); + if (ImGui::CollapsingHeader("Category B")) { ImGui::Text("Blah blah blah"); } ImGui::NextColumn(); + if (ImGui::CollapsingHeader("Category C")) { ImGui::Text("Blah blah blah"); } ImGui::NextColumn(); ImGui::Columns(1); ImGui::Separator(); ImGui::TreePop(); @@ -2105,9 +2105,9 @@ static void ShowExampleAppConstrainedResize(bool* p_open) "Custom: Fixed Steps (100)", }; ImGui::Combo("Constraint", &type, desc, IM_ARRAYSIZE(desc)); - if (ImGui::Button("200x200")) ImGui::SetWindowSize(ImVec2(200,200)); ImGui::SameLine(); - if (ImGui::Button("500x500")) ImGui::SetWindowSize(ImVec2(500,500)); ImGui::SameLine(); - if (ImGui::Button("800x200")) ImGui::SetWindowSize(ImVec2(800,200)); + if (ImGui::Button("200x200")) { ImGui::SetWindowSize(ImVec2(200,200)); } ImGui::SameLine(); + if (ImGui::Button("500x500")) { ImGui::SetWindowSize(ImVec2(500,500)); } ImGui::SameLine(); + if (ImGui::Button("800x200")) { ImGui::SetWindowSize(ImVec2(800,200)); } for (int i = 0; i < 10; i++) ImGui::Text("Hello, sailor! Making this line long enough for the example."); } @@ -2325,8 +2325,8 @@ struct ExampleAppConsole // TODO: display items starting from the bottom if (ImGui::SmallButton("Add Dummy Text")) { AddLog("%d some text", Items.Size); AddLog("some more text"); AddLog("display very important message here!"); } ImGui::SameLine(); - if (ImGui::SmallButton("Add Dummy Error")) AddLog("[error] something went wrong"); ImGui::SameLine(); - if (ImGui::SmallButton("Clear")) ClearLog(); ImGui::SameLine(); + if (ImGui::SmallButton("Add Dummy Error")) { AddLog("[error] something went wrong"); } ImGui::SameLine(); + if (ImGui::SmallButton("Clear")) { ClearLog(); } ImGui::SameLine(); bool copy_to_clipboard = ImGui::SmallButton("Copy"); ImGui::SameLine(); if (ImGui::SmallButton("Scroll to bottom")) ScrollToBottom = true; //static float t = 0.0f; if (ImGui::GetTime() - t > 0.02f) { t = ImGui::GetTime(); AddLog("Spam %f", t); } @@ -2385,7 +2385,7 @@ struct ExampleAppConsole if (ImGui::InputText("Input", InputBuf, IM_ARRAYSIZE(InputBuf), ImGuiInputTextFlags_EnterReturnsTrue|ImGuiInputTextFlags_CallbackCompletion|ImGuiInputTextFlags_CallbackHistory, &TextEditCallbackStub, (void*)this)) { char* input_end = InputBuf+strlen(InputBuf); - while (input_end > InputBuf && input_end[-1] == ' ') input_end--; *input_end = 0; + while (input_end > InputBuf && input_end[-1] == ' ') { input_end--; } *input_end = 0; if (InputBuf[0]) ExecCommand(InputBuf); strcpy(InputBuf, ""); @@ -2426,7 +2426,8 @@ struct ExampleAppConsole } else if (Stricmp(command_line, "HISTORY") == 0) { - for (int i = History.Size >= 10 ? History.Size - 10 : 0; i < History.Size; i++) + int first = History.Size - 10; + for (int i = first > 0 ? first : 0; i < History.Size; i++) AddLog("%3d: %s\n", i, History[i]); } else From 670d40642f726759b422b37784ef5f59c1cbbcb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Branimir=20Karad=C5=BEi=C4=87?= Date: Thu, 31 Aug 2017 13:04:40 -0700 Subject: [PATCH 313/921] Fixed C4267 conversion from size_t to int. --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 355108449..ae1787283 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -10386,7 +10386,7 @@ static void SetClipboardTextFn_DefaultImpl(void*, const char* text) ImGuiContext& g = *GImGui; g.PrivateClipboard.clear(); const char* text_end = text + strlen(text); - g.PrivateClipboard.resize((size_t)(text_end - text) + 1); + g.PrivateClipboard.resize((int)(text_end - text) + 1); memcpy(&g.PrivateClipboard[0], text, (size_t)(text_end - text)); g.PrivateClipboard[(int)(text_end - text)] = 0; } From cf48e28932e5d920567c61c04b97fdc954cabb8b Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 1 Sep 2017 20:39:12 +1200 Subject: [PATCH 314/921] Backup polygon mode, draw with filled polygons, restore state, for clients running opengl with glPolygonMode. closes #798 --- examples/opengl2_example/imgui_impl_glfw.cpp | 5 ++++- examples/opengl3_example/imgui_impl_glfw_gl3.cpp | 5 ++++- examples/sdl_opengl2_example/imgui_impl_sdl.cpp | 5 ++++- examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp | 5 ++++- 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/examples/opengl2_example/imgui_impl_glfw.cpp b/examples/opengl2_example/imgui_impl_glfw.cpp index f85fb5c4c..4fe957cba 100644 --- a/examples/opengl2_example/imgui_impl_glfw.cpp +++ b/examples/opengl2_example/imgui_impl_glfw.cpp @@ -44,8 +44,9 @@ void ImGui_ImplGlfw_RenderDrawLists(ImDrawData* draw_data) draw_data->ScaleClipRects(io.DisplayFramebufferScale); // We are using the OpenGL fixed pipeline to make the example code simpler to read! - // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers, polygon fill. GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + GLint last_polygon_mode[2]; glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode); GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); GLint last_scissor_box[4]; glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box); glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); @@ -58,6 +59,7 @@ void ImGui_ImplGlfw_RenderDrawLists(ImDrawData* draw_data) glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnableClientState(GL_COLOR_ARRAY); glEnable(GL_TEXTURE_2D); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context where shaders may be bound // Setup viewport, orthographic projection matrix @@ -109,6 +111,7 @@ void ImGui_ImplGlfw_RenderDrawLists(ImDrawData* draw_data) glMatrixMode(GL_PROJECTION); glPopMatrix(); glPopAttrib(); + glPolygonMode(GL_FRONT, last_polygon_mode[0]); glPolygonMode(GL_BACK, last_polygon_mode[1]); glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], (GLsizei)last_scissor_box[3]); } diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp index ff96b88a2..4c91961d8 100644 --- a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp +++ b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp @@ -51,6 +51,7 @@ void ImGui_ImplGlfwGL3_RenderDrawLists(ImDrawData* draw_data) GLint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); GLint last_element_array_buffer; glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &last_element_array_buffer); GLint last_vertex_array; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array); + GLint last_polygon_mode[2]; glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode); GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); GLint last_scissor_box[4]; glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box); GLenum last_blend_src_rgb; glGetIntegerv(GL_BLEND_SRC_RGB, (GLint*)&last_blend_src_rgb); @@ -64,13 +65,14 @@ void ImGui_ImplGlfwGL3_RenderDrawLists(ImDrawData* draw_data) GLboolean last_enable_depth_test = glIsEnabled(GL_DEPTH_TEST); GLboolean last_enable_scissor_test = glIsEnabled(GL_SCISSOR_TEST); - // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, polygon fill glEnable(GL_BLEND); glBlendEquation(GL_FUNC_ADD); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDisable(GL_CULL_FACE); glDisable(GL_DEPTH_TEST); glEnable(GL_SCISSOR_TEST); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); // Setup viewport, orthographic projection matrix glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); @@ -127,6 +129,7 @@ void ImGui_ImplGlfwGL3_RenderDrawLists(ImDrawData* draw_data) if (last_enable_cull_face) glEnable(GL_CULL_FACE); else glDisable(GL_CULL_FACE); if (last_enable_depth_test) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST); if (last_enable_scissor_test) glEnable(GL_SCISSOR_TEST); else glDisable(GL_SCISSOR_TEST); + glPolygonMode(GL_FRONT_AND_BACK, last_polygon_mode[0]); glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], (GLsizei)last_scissor_box[3]); } diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl.cpp b/examples/sdl_opengl2_example/imgui_impl_sdl.cpp index a8338cecc..cef10e729 100644 --- a/examples/sdl_opengl2_example/imgui_impl_sdl.cpp +++ b/examples/sdl_opengl2_example/imgui_impl_sdl.cpp @@ -35,8 +35,9 @@ void ImGui_ImplSdl_RenderDrawLists(ImDrawData* draw_data) draw_data->ScaleClipRects(io.DisplayFramebufferScale); // We are using the OpenGL fixed pipeline to make the example code simpler to read! - // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers, polygon fill. GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + GLint last_polygon_mode[2]; glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode); GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); GLint last_scissor_box[4]; glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box); glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); @@ -49,6 +50,7 @@ void ImGui_ImplSdl_RenderDrawLists(ImDrawData* draw_data) glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnableClientState(GL_COLOR_ARRAY); glEnable(GL_TEXTURE_2D); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context where shaders may be bound // Setup viewport, orthographic projection matrix @@ -100,6 +102,7 @@ void ImGui_ImplSdl_RenderDrawLists(ImDrawData* draw_data) glMatrixMode(GL_PROJECTION); glPopMatrix(); glPopAttrib(); + glPolygonMode(GL_FRONT, last_polygon_mode[0]); glPolygonMode(GL_BACK, last_polygon_mode[1]); glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], (GLsizei)last_scissor_box[3]); } diff --git a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp index 1861edae0..1829ac95a 100644 --- a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp +++ b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp @@ -45,6 +45,7 @@ void ImGui_ImplSdlGL3_RenderDrawLists(ImDrawData* draw_data) GLint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); GLint last_element_array_buffer; glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &last_element_array_buffer); GLint last_vertex_array; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array); + GLint last_polygon_mode[2]; glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode); GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); GLint last_scissor_box[4]; glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box); GLenum last_blend_src_rgb; glGetIntegerv(GL_BLEND_SRC_RGB, (GLint*)&last_blend_src_rgb); @@ -58,13 +59,14 @@ void ImGui_ImplSdlGL3_RenderDrawLists(ImDrawData* draw_data) GLboolean last_enable_depth_test = glIsEnabled(GL_DEPTH_TEST); GLboolean last_enable_scissor_test = glIsEnabled(GL_SCISSOR_TEST); - // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, polygon fill glEnable(GL_BLEND); glBlendEquation(GL_FUNC_ADD); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDisable(GL_CULL_FACE); glDisable(GL_DEPTH_TEST); glEnable(GL_SCISSOR_TEST); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); // Setup viewport, orthographic projection matrix glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); @@ -121,6 +123,7 @@ void ImGui_ImplSdlGL3_RenderDrawLists(ImDrawData* draw_data) if (last_enable_cull_face) glEnable(GL_CULL_FACE); else glDisable(GL_CULL_FACE); if (last_enable_depth_test) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST); if (last_enable_scissor_test) glEnable(GL_SCISSOR_TEST); else glDisable(GL_SCISSOR_TEST); + glPolygonMode(GL_FRONT_AND_BACK, last_polygon_mode[0]); glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], (GLsizei)last_scissor_box[3]); } From 7d1f2c0dc55c1cdce6cf3580a395ca4dd9357d18 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 1 Sep 2017 16:45:31 +0200 Subject: [PATCH 315/921] Examples: GL2: rename functions to include GL2 in name --- examples/opengl2_example/imgui_impl_glfw.cpp | 34 +++++++++---------- examples/opengl2_example/imgui_impl_glfw.h | 23 ++++++------- examples/opengl2_example/main.cpp | 6 ++-- .../sdl_opengl2_example/imgui_impl_sdl.cpp | 16 ++++----- examples/sdl_opengl2_example/imgui_impl_sdl.h | 12 +++---- examples/sdl_opengl2_example/main.cpp | 8 ++--- 6 files changed, 49 insertions(+), 50 deletions(-) diff --git a/examples/opengl2_example/imgui_impl_glfw.cpp b/examples/opengl2_example/imgui_impl_glfw.cpp index 4fe957cba..a1129d484 100644 --- a/examples/opengl2_example/imgui_impl_glfw.cpp +++ b/examples/opengl2_example/imgui_impl_glfw.cpp @@ -33,7 +33,7 @@ static GLuint g_FontTexture = 0; // This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) // If text or lines are blurry when integrating ImGui in your engine: // - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) -void ImGui_ImplGlfw_RenderDrawLists(ImDrawData* draw_data) +void ImGui_ImplGlfwGL2_RenderDrawLists(ImDrawData* draw_data) { // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) ImGuiIO& io = ImGui::GetIO(); @@ -126,18 +126,18 @@ static void ImGui_ImplGlfw_SetClipboardText(void* user_data, const char* text) glfwSetClipboardString((GLFWwindow*)user_data, text); } -void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/) +void ImGui_ImplGlfwGL2_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/) { if (action == GLFW_PRESS && button >= 0 && button < 3) g_MousePressed[button] = true; } -void ImGui_ImplGlfw_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset) +void ImGui_ImplGlfwGL2_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset) { g_MouseWheel += (float)yoffset; // Use fractional mouse wheel, 1.0 unit 5 lines. } -void ImGui_ImplGlFw_KeyCallback(GLFWwindow*, int key, int, int action, int mods) +void ImGui_ImplGlfwGL2_KeyCallback(GLFWwindow*, int key, int, int action, int mods) { ImGuiIO& io = ImGui::GetIO(); if (action == GLFW_PRESS) @@ -152,14 +152,14 @@ void ImGui_ImplGlFw_KeyCallback(GLFWwindow*, int key, int, int action, int mods) io.KeySuper = io.KeysDown[GLFW_KEY_LEFT_SUPER] || io.KeysDown[GLFW_KEY_RIGHT_SUPER]; } -void ImGui_ImplGlfw_CharCallback(GLFWwindow*, unsigned int c) +void ImGui_ImplGlfwGL2_CharCallback(GLFWwindow*, unsigned int c) { ImGuiIO& io = ImGui::GetIO(); if (c > 0 && c < 0x10000) io.AddInputCharacter((unsigned short)c); } -bool ImGui_ImplGlfw_CreateDeviceObjects() +bool ImGui_ImplGlfwGL2_CreateDeviceObjects() { // Build texture atlas ImGuiIO& io = ImGui::GetIO(); @@ -185,7 +185,7 @@ bool ImGui_ImplGlfw_CreateDeviceObjects() return true; } -void ImGui_ImplGlfw_InvalidateDeviceObjects() +void ImGui_ImplGlfwGL2_InvalidateDeviceObjects() { if (g_FontTexture) { @@ -195,7 +195,7 @@ void ImGui_ImplGlfw_InvalidateDeviceObjects() } } -bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks) +bool ImGui_ImplGlfwGL2_Init(GLFWwindow* window, bool install_callbacks) { g_Window = window; @@ -220,7 +220,7 @@ bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks) io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y; io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z; - io.RenderDrawListsFn = ImGui_ImplGlfw_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. + io.RenderDrawListsFn = ImGui_ImplGlfwGL2_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. io.SetClipboardTextFn = ImGui_ImplGlfw_SetClipboardText; io.GetClipboardTextFn = ImGui_ImplGlfw_GetClipboardText; io.ClipboardUserData = g_Window; @@ -230,25 +230,25 @@ bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks) if (install_callbacks) { - glfwSetMouseButtonCallback(window, ImGui_ImplGlfw_MouseButtonCallback); - glfwSetScrollCallback(window, ImGui_ImplGlfw_ScrollCallback); - glfwSetKeyCallback(window, ImGui_ImplGlFw_KeyCallback); - glfwSetCharCallback(window, ImGui_ImplGlfw_CharCallback); + glfwSetMouseButtonCallback(window, ImGui_ImplGlfwGL2_MouseButtonCallback); + glfwSetScrollCallback(window, ImGui_ImplGlfwGL2_ScrollCallback); + glfwSetKeyCallback(window, ImGui_ImplGlfwGL2_KeyCallback); + glfwSetCharCallback(window, ImGui_ImplGlfwGL2_CharCallback); } return true; } -void ImGui_ImplGlfw_Shutdown() +void ImGui_ImplGlfwGL2_Shutdown() { - ImGui_ImplGlfw_InvalidateDeviceObjects(); + ImGui_ImplGlfwGL2_InvalidateDeviceObjects(); ImGui::Shutdown(); } -void ImGui_ImplGlfw_NewFrame() +void ImGui_ImplGlfwGL2_NewFrame() { if (!g_FontTexture) - ImGui_ImplGlfw_CreateDeviceObjects(); + ImGui_ImplGlfwGL2_CreateDeviceObjects(); ImGuiIO& io = ImGui::GetIO(); diff --git a/examples/opengl2_example/imgui_impl_glfw.h b/examples/opengl2_example/imgui_impl_glfw.h index 07dd96f04..470863af3 100644 --- a/examples/opengl2_example/imgui_impl_glfw.h +++ b/examples/opengl2_example/imgui_impl_glfw.h @@ -12,18 +12,17 @@ struct GLFWwindow; -IMGUI_API bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks); -IMGUI_API void ImGui_ImplGlfw_Shutdown(); -IMGUI_API void ImGui_ImplGlfw_NewFrame(); +IMGUI_API bool ImGui_ImplGlfwGL2_Init(GLFWwindow* window, bool install_callbacks); +IMGUI_API void ImGui_ImplGlfwGL2_Shutdown(); +IMGUI_API void ImGui_ImplGlfwGL2_NewFrame(); // Use if you want to reset your rendering device without losing ImGui state. -IMGUI_API void ImGui_ImplGlfw_InvalidateDeviceObjects(); -IMGUI_API bool ImGui_ImplGlfw_CreateDeviceObjects(); +IMGUI_API void ImGui_ImplGlfwGL2_InvalidateDeviceObjects(); +IMGUI_API bool ImGui_ImplGlfwGL2_CreateDeviceObjects(); -// GLFW callbacks (installed by default if you enable 'install_callbacks' during initialization) -// Provided here if you want to chain callbacks. -// You can also handle inputs yourself and use those as a reference. -IMGUI_API void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods); -IMGUI_API void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset); -IMGUI_API void ImGui_ImplGlFw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); -IMGUI_API void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c); +// GLFW callbacks (registered by default to GLFW if you enable 'install_callbacks' during initialization) +// Provided here if you want to chain callbacks yourself. You may also handle inputs yourself and use those as a reference. +IMGUI_API void ImGui_ImplGlfwGL2_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods); +IMGUI_API void ImGui_ImplGlfwGL2_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset); +IMGUI_API void ImGui_ImplGlfwGL2_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); +IMGUI_API void ImGui_ImplGlfwGL2_CharCallback(GLFWwindow* window, unsigned int c); diff --git a/examples/opengl2_example/main.cpp b/examples/opengl2_example/main.cpp index aa0816f91..2c5bd5694 100644 --- a/examples/opengl2_example/main.cpp +++ b/examples/opengl2_example/main.cpp @@ -22,7 +22,7 @@ int main(int, char**) glfwSwapInterval(1); // Enable vsync // Setup ImGui binding - ImGui_ImplGlfw_Init(window, true); + ImGui_ImplGlfwGL2_Init(window, true); // Load Fonts // (there is a default font, this is only if you want to change it. see extra_fonts/README.txt for more details) @@ -42,7 +42,7 @@ int main(int, char**) while (!glfwWindowShouldClose(window)) { glfwPollEvents(); - ImGui_ImplGlfw_NewFrame(); + ImGui_ImplGlfwGL2_NewFrame(); // 1. Show a simple window // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug" @@ -84,7 +84,7 @@ int main(int, char**) } // Cleanup - ImGui_ImplGlfw_Shutdown(); + ImGui_ImplGlfwGL2_Shutdown(); glfwTerminate(); return 0; diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl.cpp b/examples/sdl_opengl2_example/imgui_impl_sdl.cpp index cef10e729..784d90aec 100644 --- a/examples/sdl_opengl2_example/imgui_impl_sdl.cpp +++ b/examples/sdl_opengl2_example/imgui_impl_sdl.cpp @@ -117,7 +117,7 @@ static void ImGui_ImplSdl_SetClipboardText(void*, const char* text) SDL_SetClipboardText(text); } -bool ImGui_ImplSdl_ProcessEvent(SDL_Event* event) +bool ImGui_ImplSdlGL2_ProcessEvent(SDL_Event* event) { ImGuiIO& io = ImGui::GetIO(); switch (event->type) @@ -157,7 +157,7 @@ bool ImGui_ImplSdl_ProcessEvent(SDL_Event* event) return false; } -bool ImGui_ImplSdl_CreateDeviceObjects() +bool ImGui_ImplSdlGL2_CreateDeviceObjects() { // Build texture atlas ImGuiIO& io = ImGui::GetIO(); @@ -184,7 +184,7 @@ bool ImGui_ImplSdl_CreateDeviceObjects() return true; } -void ImGui_ImplSdl_InvalidateDeviceObjects() +void ImGui_ImplSdlGL2_InvalidateDeviceObjects() { if (g_FontTexture) { @@ -194,7 +194,7 @@ void ImGui_ImplSdl_InvalidateDeviceObjects() } } -bool ImGui_ImplSdl_Init(SDL_Window* window) +bool ImGui_ImplSdlGL2_Init(SDL_Window* window) { ImGuiIO& io = ImGui::GetIO(); io.KeyMap[ImGuiKey_Tab] = SDLK_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array. @@ -234,16 +234,16 @@ bool ImGui_ImplSdl_Init(SDL_Window* window) return true; } -void ImGui_ImplSdl_Shutdown() +void ImGui_ImplSdlGL2_Shutdown() { - ImGui_ImplSdl_InvalidateDeviceObjects(); + ImGui_ImplSdlGL2_InvalidateDeviceObjects(); ImGui::Shutdown(); } -void ImGui_ImplSdl_NewFrame(SDL_Window *window) +void ImGui_ImplSdlGL2_NewFrame(SDL_Window *window) { if (!g_FontTexture) - ImGui_ImplSdl_CreateDeviceObjects(); + ImGui_ImplSdlGL2_CreateDeviceObjects(); ImGuiIO& io = ImGui::GetIO(); diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl.h b/examples/sdl_opengl2_example/imgui_impl_sdl.h index a322bf2d9..65b2bd996 100644 --- a/examples/sdl_opengl2_example/imgui_impl_sdl.h +++ b/examples/sdl_opengl2_example/imgui_impl_sdl.h @@ -9,11 +9,11 @@ struct SDL_Window; typedef union SDL_Event SDL_Event; -IMGUI_API bool ImGui_ImplSdl_Init(SDL_Window* window); -IMGUI_API void ImGui_ImplSdl_Shutdown(); -IMGUI_API void ImGui_ImplSdl_NewFrame(SDL_Window* window); -IMGUI_API bool ImGui_ImplSdl_ProcessEvent(SDL_Event* event); +IMGUI_API bool ImGui_ImplSdlGL2_Init(SDL_Window* window); +IMGUI_API void ImGui_ImplSdlGL2_Shutdown(); +IMGUI_API void ImGui_ImplSdlGL2_NewFrame(SDL_Window* window); +IMGUI_API bool ImGui_ImplSdlGL2_ProcessEvent(SDL_Event* event); // Use if you want to reset your rendering device without losing ImGui state. -IMGUI_API void ImGui_ImplSdl_InvalidateDeviceObjects(); -IMGUI_API bool ImGui_ImplSdl_CreateDeviceObjects(); +IMGUI_API void ImGui_ImplSdlGL2_InvalidateDeviceObjects(); +IMGUI_API bool ImGui_ImplSdlGL2_CreateDeviceObjects(); diff --git a/examples/sdl_opengl2_example/main.cpp b/examples/sdl_opengl2_example/main.cpp index 53e428ba3..d6f31845a 100644 --- a/examples/sdl_opengl2_example/main.cpp +++ b/examples/sdl_opengl2_example/main.cpp @@ -28,7 +28,7 @@ int main(int, char**) SDL_GLContext glcontext = SDL_GL_CreateContext(window); // Setup ImGui binding - ImGui_ImplSdl_Init(window); + ImGui_ImplSdlGL2_Init(window); // Load Fonts // (there is a default font, this is only if you want to change it. see extra_fonts/README.txt for more details) @@ -51,11 +51,11 @@ int main(int, char**) SDL_Event event; while (SDL_PollEvent(&event)) { - ImGui_ImplSdl_ProcessEvent(&event); + ImGui_ImplSdlGL2_ProcessEvent(&event); if (event.type == SDL_QUIT) done = true; } - ImGui_ImplSdl_NewFrame(window); + ImGui_ImplSdlGL2_NewFrame(window); // 1. Show a simple window // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug" @@ -95,7 +95,7 @@ int main(int, char**) } // Cleanup - ImGui_ImplSdl_Shutdown(); + ImGui_ImplSdlGL2_Shutdown(); SDL_GL_DeleteContext(glcontext); SDL_DestroyWindow(window); SDL_Quit(); From d9016964ada251c72b0dc2186e485fdec8fb7d6b Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 1 Sep 2017 16:55:04 +0200 Subject: [PATCH 316/921] Examples: GL3: Comments, tweaks (#1145) --- examples/opengl3_example/imgui_impl_glfw_gl3.cpp | 6 +++--- examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp index 173b3835c..1cf35c653 100644 --- a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp +++ b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp @@ -31,8 +31,8 @@ static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_Attr static unsigned int g_VboHandle = 0, g_VaoHandle = 0, g_ElementsHandle = 0; // This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) -// If text or lines are blurry when integrating ImGui in your engine: -// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) +// Note that this implementation is little overcomplicated because we are saving/setting up/restoring every OpenGL state explicitly, in order to be able to run within any OpenGL engine that doesn't do so. +// If text or lines are blurry when integrating ImGui in your engine: in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) void ImGui_ImplGlfwGL3_RenderDrawLists(ImDrawData* draw_data) { // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) @@ -88,6 +88,7 @@ void ImGui_ImplGlfwGL3_RenderDrawLists(ImDrawData* draw_data) glUniform1i(g_AttribLocationTex, 0); glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); glBindVertexArray(g_VaoHandle); + glBindSampler(0, 0); // Rely on combined texture/sampler state. for (int n = 0; n < draw_data->CmdListsCount; n++) { @@ -110,7 +111,6 @@ void ImGui_ImplGlfwGL3_RenderDrawLists(ImDrawData* draw_data) else { glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); - glBindSampler(0, 0); // rely on combined texture/sampler state. glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer_offset); } diff --git a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp index 1ad750fcf..0301d31bc 100644 --- a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp +++ b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp @@ -25,8 +25,8 @@ static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_Attr static unsigned int g_VboHandle = 0, g_VaoHandle = 0, g_ElementsHandle = 0; // This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) -// If text or lines are blurry when integrating ImGui in your engine: -// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) +// Note that this implementation is little overcomplicated because we are saving/setting up/restoring every OpenGL state explicitly, in order to be able to run within any OpenGL engine that doesn't do so. +// If text or lines are blurry when integrating ImGui in your engine: in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) void ImGui_ImplSdlGL3_RenderDrawLists(ImDrawData* draw_data) { // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) @@ -82,6 +82,7 @@ void ImGui_ImplSdlGL3_RenderDrawLists(ImDrawData* draw_data) glUniform1i(g_AttribLocationTex, 0); glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); glBindVertexArray(g_VaoHandle); + glBindSampler(0, 0); // Rely on combined texture/sampler state. for (int n = 0; n < draw_data->CmdListsCount; n++) { @@ -104,7 +105,6 @@ void ImGui_ImplSdlGL3_RenderDrawLists(ImDrawData* draw_data) else { glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); - glBindSampler(0, 0); // rely on combined texture/sampler state. glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer_offset); } From 4abce8af58e5e45d2578ab6ec612bcc76fe168e4 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 1 Sep 2017 16:58:07 +0200 Subject: [PATCH 317/921] Examples: GL2: Renaming, comments. --- examples/opengl2_example/imgui_impl_glfw.cpp | 12 ++++++------ examples/sdl_opengl2_example/imgui_impl_sdl.cpp | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/examples/opengl2_example/imgui_impl_glfw.cpp b/examples/opengl2_example/imgui_impl_glfw.cpp index a1129d484..624085fd7 100644 --- a/examples/opengl2_example/imgui_impl_glfw.cpp +++ b/examples/opengl2_example/imgui_impl_glfw.cpp @@ -31,9 +31,9 @@ static float g_MouseWheel = 0.0f; static GLuint g_FontTexture = 0; // This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) -// If text or lines are blurry when integrating ImGui in your engine: -// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) void ImGui_ImplGlfwGL2_RenderDrawLists(ImDrawData* draw_data) +// Note that this implementation is little overcomplicated because we are saving/setting up/restoring every OpenGL state explicitly, in order to be able to run within any OpenGL engine that doesn't do so. +// If text or lines are blurry when integrating ImGui in your engine: in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) { // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) ImGuiIO& io = ImGui::GetIO(); @@ -116,12 +116,12 @@ void ImGui_ImplGlfwGL2_RenderDrawLists(ImDrawData* draw_data) glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], (GLsizei)last_scissor_box[3]); } -static const char* ImGui_ImplGlfw_GetClipboardText(void* user_data) +static const char* ImGui_ImplGlfwGL2_GetClipboardText(void* user_data) { return glfwGetClipboardString((GLFWwindow*)user_data); } -static void ImGui_ImplGlfw_SetClipboardText(void* user_data, const char* text) +static void ImGui_ImplGlfwGL2_SetClipboardText(void* user_data, const char* text) { glfwSetClipboardString((GLFWwindow*)user_data, text); } @@ -221,8 +221,8 @@ bool ImGui_ImplGlfwGL2_Init(GLFWwindow* window, bool install_callbacks) io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z; io.RenderDrawListsFn = ImGui_ImplGlfwGL2_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. - io.SetClipboardTextFn = ImGui_ImplGlfw_SetClipboardText; - io.GetClipboardTextFn = ImGui_ImplGlfw_GetClipboardText; + io.SetClipboardTextFn = ImGui_ImplGlfwGL2_SetClipboardText; + io.GetClipboardTextFn = ImGui_ImplGlfwGL2_GetClipboardText; io.ClipboardUserData = g_Window; #ifdef _WIN32 io.ImeWindowHandle = glfwGetWin32Window(g_Window); diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl.cpp b/examples/sdl_opengl2_example/imgui_impl_sdl.cpp index 784d90aec..78ce40357 100644 --- a/examples/sdl_opengl2_example/imgui_impl_sdl.cpp +++ b/examples/sdl_opengl2_example/imgui_impl_sdl.cpp @@ -22,8 +22,8 @@ static float g_MouseWheel = 0.0f; static GLuint g_FontTexture = 0; // This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) -// If text or lines are blurry when integrating ImGui in your engine: -// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) +// Note that this implementation is little overcomplicated because we are saving/setting up/restoring every OpenGL state explicitly, in order to be able to run within any OpenGL engine that doesn't do so. +// If text or lines are blurry when integrating ImGui in your engine: in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) void ImGui_ImplSdl_RenderDrawLists(ImDrawData* draw_data) { // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) From b8ade0b94f7ea39f3b62a89e9473e18893e5644c Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 1 Sep 2017 17:06:26 +0200 Subject: [PATCH 318/921] Examples: Main: Removed call to SetNextWindowSize() --- examples/allegro5_example/main.cpp | 3 +-- examples/apple_example/imguiex-ios/debug_hud.cpp | 2 +- examples/directx10_example/main.cpp | 3 +-- examples/directx11_example/main.cpp | 3 +-- examples/directx9_example/main.cpp | 3 +-- examples/marmalade_example/main.cpp | 3 +-- examples/opengl2_example/main.cpp | 3 +-- examples/opengl3_example/main.cpp | 3 +-- examples/sdl_opengl2_example/main.cpp | 3 +-- examples/sdl_opengl3_example/main.cpp | 3 +-- examples/vulkan_example/main.cpp | 3 +-- 11 files changed, 11 insertions(+), 21 deletions(-) diff --git a/examples/allegro5_example/main.cpp b/examples/allegro5_example/main.cpp index f99ff5e9e..9f8a6c359 100644 --- a/examples/allegro5_example/main.cpp +++ b/examples/allegro5_example/main.cpp @@ -72,9 +72,8 @@ int main(int, char**) // 2. Show another simple window, this time using an explicit Begin/End pair if (show_another_window) { - ImGui::SetNextWindowSize(ImVec2(200, 100), ImGuiCond_FirstUseEver); ImGui::Begin("Another Window", &show_another_window); - ImGui::Text("Hello"); + ImGui::Text("Hello from another window!"); ImGui::End(); } diff --git a/examples/apple_example/imguiex-ios/debug_hud.cpp b/examples/apple_example/imguiex-ios/debug_hud.cpp index 63bec89ba..fff26eee9 100644 --- a/examples/apple_example/imguiex-ios/debug_hud.cpp +++ b/examples/apple_example/imguiex-ios/debug_hud.cpp @@ -34,8 +34,8 @@ void DebugHUD_DoInterface(DebugHUD *hud) if (hud->show_example_window) { - ImGui::SetNextWindowSize(ImVec2(350, 200), ImGuiCond_FirstUseEver); ImGui::Begin("Another Window", &hud->show_example_window); + ImGui::Text("Hello from another window!"); ImGui::ColorEdit3("Cube 1 Color", hud->cubeColor1); ImGui::ColorEdit3("Cube 2 Color", hud->cubeColor2); ImGui::SliderFloat("Rotation Speed", &hud->rotation_speed, 0.0f, 200.0f); diff --git a/examples/directx10_example/main.cpp b/examples/directx10_example/main.cpp index 6b89ba9e8..90add0364 100644 --- a/examples/directx10_example/main.cpp +++ b/examples/directx10_example/main.cpp @@ -167,9 +167,8 @@ int main(int, char**) // 2. Show another simple window, this time using an explicit Begin/End pair if (show_another_window) { - ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiCond_FirstUseEver); ImGui::Begin("Another Window", &show_another_window); - ImGui::Text("Hello"); + ImGui::Text("Hello from another window!"); ImGui::End(); } diff --git a/examples/directx11_example/main.cpp b/examples/directx11_example/main.cpp index 63b220957..c8d566bfc 100644 --- a/examples/directx11_example/main.cpp +++ b/examples/directx11_example/main.cpp @@ -170,9 +170,8 @@ int main(int, char**) // 2. Show another simple window, this time using an explicit Begin/End pair if (show_another_window) { - ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiCond_FirstUseEver); ImGui::Begin("Another Window", &show_another_window); - ImGui::Text("Hello"); + ImGui::Text("Hello from another window!"); ImGui::End(); } diff --git a/examples/directx9_example/main.cpp b/examples/directx9_example/main.cpp index 036712c4b..f9791b733 100644 --- a/examples/directx9_example/main.cpp +++ b/examples/directx9_example/main.cpp @@ -121,9 +121,8 @@ int main(int, char**) // 2. Show another simple window, this time using an explicit Begin/End pair if (show_another_window) { - ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiCond_FirstUseEver); ImGui::Begin("Another Window", &show_another_window); - ImGui::Text("Hello"); + ImGui::Text("Hello from another window!"); ImGui::End(); } diff --git a/examples/marmalade_example/main.cpp b/examples/marmalade_example/main.cpp index e08e306b6..57b7f0b69 100644 --- a/examples/marmalade_example/main.cpp +++ b/examples/marmalade_example/main.cpp @@ -56,9 +56,8 @@ int main(int, char**) // 2. Show another simple window, this time using an explicit Begin/End pair if (show_another_window) { - ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiCond_FirstUseEver); ImGui::Begin("Another Window", &show_another_window); - ImGui::Text("Hello"); + ImGui::Text("Hello from another window!"); ImGui::End(); } diff --git a/examples/opengl2_example/main.cpp b/examples/opengl2_example/main.cpp index 2c5bd5694..5674a4bcb 100644 --- a/examples/opengl2_example/main.cpp +++ b/examples/opengl2_example/main.cpp @@ -59,9 +59,8 @@ int main(int, char**) // 2. Show another simple window, this time using an explicit Begin/End pair if (show_another_window) { - ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiCond_FirstUseEver); ImGui::Begin("Another Window", &show_another_window); - ImGui::Text("Hello"); + ImGui::Text("Hello from another window!"); ImGui::End(); } diff --git a/examples/opengl3_example/main.cpp b/examples/opengl3_example/main.cpp index a11bc59d1..0de9b0a0e 100644 --- a/examples/opengl3_example/main.cpp +++ b/examples/opengl3_example/main.cpp @@ -67,9 +67,8 @@ int main(int, char**) // 2. Show another simple window, this time using an explicit Begin/End pair if (show_another_window) { - ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiCond_FirstUseEver); ImGui::Begin("Another Window", &show_another_window); - ImGui::Text("Hello"); + ImGui::Text("Hello from another window!"); ImGui::End(); } diff --git a/examples/sdl_opengl2_example/main.cpp b/examples/sdl_opengl2_example/main.cpp index d6f31845a..4db6f0f9c 100644 --- a/examples/sdl_opengl2_example/main.cpp +++ b/examples/sdl_opengl2_example/main.cpp @@ -72,9 +72,8 @@ int main(int, char**) // 2. Show another simple window, this time using an explicit Begin/End pair if (show_another_window) { - ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiCond_FirstUseEver); ImGui::Begin("Another Window", &show_another_window); - ImGui::Text("Hello"); + ImGui::Text("Hello from another window!"); ImGui::End(); } diff --git a/examples/sdl_opengl3_example/main.cpp b/examples/sdl_opengl3_example/main.cpp index 56b790659..30b14e72b 100644 --- a/examples/sdl_opengl3_example/main.cpp +++ b/examples/sdl_opengl3_example/main.cpp @@ -75,9 +75,8 @@ int main(int, char**) // 2. Show another simple window, this time using an explicit Begin/End pair if (show_another_window) { - ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiCond_FirstUseEver); ImGui::Begin("Another Window", &show_another_window); - ImGui::Text("Hello"); + ImGui::Text("Hello from another window!"); ImGui::End(); } diff --git a/examples/vulkan_example/main.cpp b/examples/vulkan_example/main.cpp index a4922b092..7ed9ea12d 100644 --- a/examples/vulkan_example/main.cpp +++ b/examples/vulkan_example/main.cpp @@ -698,9 +698,8 @@ int main(int, char**) // 2. Show another simple window, this time using an explicit Begin/End pair if (show_another_window) { - ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiCond_FirstUseEver); ImGui::Begin("Another Window", &show_another_window); - ImGui::Text("Hello"); + ImGui::Text("Hello from another window!"); ImGui::End(); } From fd684ba974fbebf7c89fc9c21a6591feafd01f87 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 1 Sep 2017 17:43:56 +0200 Subject: [PATCH 319/921] Removed 2 obsolete redirection functions (obsoleted 26+ months ago). --- imgui.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/imgui.h b/imgui.h index f40c7db97..27c11307e 100644 --- a/imgui.h +++ b/imgui.h @@ -493,8 +493,6 @@ namespace ImGui static inline ImFont* GetWindowFont() { return GetFont(); } // OBSOLETE 1.48+ static inline float GetWindowFontSize() { return GetFontSize(); } // OBSOLETE 1.48+ static inline void SetScrollPosHere() { SetScrollHere(); } // OBSOLETE 1.42+ - static inline bool GetWindowCollapsed() { return ImGui::IsWindowCollapsed(); } // OBSOLETE 1.39+ - static inline bool IsRectClipped(const ImVec2& size) { return !IsRectVisible(size); } // OBSOLETE 1.39+ #endif } // namespace ImGui From 804ee78731c092801612453688cefc54817eef6d Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 1 Sep 2017 21:55:59 +0200 Subject: [PATCH 320/921] Added IsWindowAppearing(). --- imgui.cpp | 22 +++++++++++++++++----- imgui.h | 1 + imgui_internal.h | 4 ++-- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index ae1787283..2a0df774f 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1789,6 +1789,7 @@ ImGuiWindow::ImGuiWindow(const char* name) Accessed = false; Collapsed = false; SkipItems = false; + Appearing = false; BeginCount = 0; PopupId = 0; AutoFitFramesX = AutoFitFramesY = -1; @@ -3976,13 +3977,15 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us } const bool window_appearing_after_being_hidden = (window->HiddenFrames == 1); + window->Appearing = (!window_was_active || window_appearing_after_being_hidden); // Process SetNextWindow***() calls bool window_pos_set_by_api = false, window_size_set_by_api = false; if (g.SetNextWindowPosCond) { const ImVec2 backup_cursor_pos = window->DC.CursorPos; // FIXME: not sure of the exact reason of this saving/restore anymore :( need to look into that. - if (!window_was_active || window_appearing_after_being_hidden) window->SetWindowPosAllowFlags |= ImGuiCond_Appearing; + if (window->Appearing) + window->SetWindowPosAllowFlags |= ImGuiCond_Appearing; window_pos_set_by_api = (window->SetWindowPosAllowFlags & g.SetNextWindowPosCond) != 0; if (window_pos_set_by_api && ImLengthSqr(g.SetNextWindowPosVal - ImVec2(-FLT_MAX,-FLT_MAX)) < 0.001f) { @@ -3998,7 +4001,8 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us } if (g.SetNextWindowSizeCond) { - if (!window_was_active || window_appearing_after_being_hidden) window->SetWindowSizeAllowFlags |= ImGuiCond_Appearing; + if (window->Appearing) + window->SetWindowSizeAllowFlags |= ImGuiCond_Appearing; window_size_set_by_api = (window->SetWindowSizeAllowFlags & g.SetNextWindowSizeCond) != 0; SetWindowSize(window, g.SetNextWindowSizeVal, g.SetNextWindowSizeCond); g.SetNextWindowSizeCond = 0; @@ -4014,13 +4018,14 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us } if (g.SetNextWindowCollapsedCond) { - if (!window_was_active || window_appearing_after_being_hidden) window->SetWindowCollapsedAllowFlags |= ImGuiCond_Appearing; + if (window->Appearing) + window->SetWindowCollapsedAllowFlags |= ImGuiCond_Appearing; SetWindowCollapsed(window, g.SetNextWindowCollapsedVal, g.SetNextWindowCollapsedCond); g.SetNextWindowCollapsedCond = 0; } if (g.SetNextWindowFocus) { - ImGui::SetWindowFocus(); + SetWindowFocus(); g.SetNextWindowFocus = false; } @@ -5073,7 +5078,14 @@ void ImGui::SetWindowCollapsed(bool collapsed, ImGuiCond cond) bool ImGui::IsWindowCollapsed() { - return GImGui->CurrentWindow->Collapsed; + ImGuiWindow* window = GetCurrentWindowRead(); + return window->Collapsed; +} + +bool ImGui::IsWindowAppearing() +{ + ImGuiWindow* window = GetCurrentWindowRead(); + return window->Appearing; } void ImGui::SetWindowCollapsed(const char* name, bool collapsed, ImGuiCond cond) diff --git a/imgui.h b/imgui.h index 27c11307e..be4b74a62 100644 --- a/imgui.h +++ b/imgui.h @@ -149,6 +149,7 @@ namespace ImGui IMGUI_API float GetWindowWidth(); IMGUI_API float GetWindowHeight(); IMGUI_API bool IsWindowCollapsed(); + IMGUI_API bool IsWindowAppearing(); IMGUI_API void SetWindowFontScale(float scale); // per-window font scale. Adjust IO.FontGlobalScale if you want to scale all windows IMGUI_API void SetNextWindowPos(const ImVec2& pos, ImGuiCond cond = 0); // set next window position. call before Begin() diff --git a/imgui_internal.h b/imgui_internal.h index 1a02473a0..f9d67d04b 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -674,7 +674,8 @@ struct IMGUI_API ImGuiWindow bool WasActive; bool Accessed; // Set to true when any widget access the current window bool Collapsed; // Set when collapsing window to become only title-bar - bool SkipItems; // == Visible && !Collapsed + bool SkipItems; // Set when items can safely be all clipped (e.g. window not visible or collapsed) + bool Appearing; // Set during the frame where the window is appearing (or re-appearing) int BeginCount; // Number of Begin() during the current frame (generally 0 or 1, 1+ if appending via multiple Begin/End pairs) ImGuiID PopupId; // ID in the popup stack when this window is used as a popup/menu (because we use generic Name/ID for recycling) int AutoFitFramesX, AutoFitFramesY; @@ -701,7 +702,6 @@ struct IMGUI_API ImGuiWindow ImGuiWindow* RootWindow; // Generally point to ourself. If we are a child window, this is pointing to the first non-child parent window. ImGuiWindow* RootNonPopupWindow; // Generally point to ourself. Used to display TitleBgActive color and for selecting which window to use for NavWindowing - // Navigation / Focus int FocusIdxAllCounter; // Start at -1 and increase as assigned via FocusItemRegister() int FocusIdxTabCounter; // (same, but only count widgets which you can Tab through) From 5658675e9db5ddd065dee63dba9e785563edd026 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 1 Sep 2017 21:58:58 +0200 Subject: [PATCH 321/921] Combo: Removed unnecessary ClearActiveId() call (from era where active combo stored an id, now we just use popup functionality) --- imgui.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 2a0df774f..6c400748c 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -8667,7 +8667,6 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi item_text = "*Unknown item*"; if (Selectable(item_text, item_selected)) { - ClearActiveID(); value_changed = true; *current_item = i; } From e8dbf1c7954060bd4e2700ab297fdd1a2ef0bf55 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 1 Sep 2017 22:10:13 +0200 Subject: [PATCH 322/921] Combo: Internally split into BeginCombo(), EndCombo(), toward a more flexible combo api. --- imgui.cpp | 152 ++++++++++++++++++++++++++--------------------- imgui_internal.h | 6 +- 2 files changed, 88 insertions(+), 70 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 6c400748c..962e07fbd 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -8569,8 +8569,7 @@ bool ImGui::Combo(const char* label, int* current_item, const char* items_separa return value_changed; } -// Combo box function. -bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(void*, int, const char**), void* data, int items_count, int height_in_items) +bool ImGui::BeginCombo(const char* label, const char* preview_value, float popup_opened_height) { ImGuiWindow* window = GetCurrentWindow(); if (window->SkipItems) @@ -8597,87 +8596,102 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi RenderFrame(ImVec2(frame_bb.Max.x-arrow_size, frame_bb.Min.y), frame_bb.Max, GetColorU32(popup_open || hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button), true, style.FrameRounding); // FIXME-ROUNDING RenderCollapseTriangle(ImVec2(frame_bb.Max.x-arrow_size, frame_bb.Min.y) + style.FramePadding, true); - if (*current_item >= 0 && *current_item < items_count) - { - const char* item_text; - if (items_getter(data, *current_item, &item_text)) - RenderTextClipped(frame_bb.Min + style.FramePadding, value_bb.Max, item_text, NULL, NULL, ImVec2(0.0f,0.0f)); - } + if (preview_value != NULL) + RenderTextClipped(frame_bb.Min + style.FramePadding, value_bb.Max, preview_value, NULL, NULL, ImVec2(0.0f,0.0f)); if (label_size.x > 0) RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label); - bool popup_toggled = false; if (hovered) { SetHoveredID(id); if (g.IO.MouseClicked[0]) { ClearActiveID(); - popup_toggled = true; - } - } - if (popup_toggled) - { - if (IsPopupOpen(id)) - { - ClosePopup(id); - } - else - { - FocusWindow(window); - OpenPopup(label); - popup_open = true; - } - } - - bool value_changed = false; - if (IsPopupOpen(id)) - { - // Size default to hold ~7 items - if (height_in_items < 0) - height_in_items = 7; - - float popup_height = (label_size.y + style.ItemSpacing.y) * ImMin(items_count, height_in_items) + (style.FramePadding.y * 3); - float popup_y1 = frame_bb.Max.y; - float popup_y2 = ImClamp(popup_y1 + popup_height, popup_y1, g.IO.DisplaySize.y - style.DisplaySafeAreaPadding.y); - if ((popup_y2 - popup_y1) < ImMin(popup_height, frame_bb.Min.y - style.DisplaySafeAreaPadding.y)) - { - // Position our combo ABOVE because there's more space to fit! (FIXME: Handle in Begin() or use a shared helper. We have similar code in Begin() for popup placement) - popup_y1 = ImClamp(frame_bb.Min.y - popup_height, style.DisplaySafeAreaPadding.y, frame_bb.Min.y); - popup_y2 = frame_bb.Min.y; - } - ImRect popup_rect(ImVec2(frame_bb.Min.x, popup_y1), ImVec2(frame_bb.Max.x, popup_y2)); - SetNextWindowPos(popup_rect.Min); - SetNextWindowSize(popup_rect.GetSize()); - PushStyleVar(ImGuiStyleVar_WindowPadding, style.FramePadding); - - const ImGuiWindowFlags flags = ImGuiWindowFlags_ComboBox | ((window->Flags & ImGuiWindowFlags_ShowBorders) ? ImGuiWindowFlags_ShowBorders : 0); - if (BeginPopupEx(id, flags)) - { - // Display items - // FIXME-OPT: Use clipper - Spacing(); - for (int i = 0; i < items_count; i++) + if (IsPopupOpen(id)) { - PushID((void*)(intptr_t)i); - const bool item_selected = (i == *current_item); - const char* item_text; - if (!items_getter(data, i, &item_text)) - item_text = "*Unknown item*"; - if (Selectable(item_text, item_selected)) - { - value_changed = true; - *current_item = i; - } - if (item_selected && popup_toggled) - SetScrollHere(); - PopID(); + ClosePopup(id); + } + else + { + FocusWindow(window); + OpenPopup(label); } - EndPopup(); } - PopStyleVar(); } + + if (!IsPopupOpen(id)) + return false; + + float popup_y1 = frame_bb.Max.y; + float popup_y2 = ImClamp(popup_y1 + popup_opened_height, popup_y1, g.IO.DisplaySize.y - style.DisplaySafeAreaPadding.y); + if ((popup_y2 - popup_y1) < ImMin(popup_opened_height, frame_bb.Min.y - style.DisplaySafeAreaPadding.y)) + { + // Position our combo ABOVE because there's more space to fit! (FIXME: Handle in Begin() or use a shared helper. We have similar code in Begin() for popup placement) + popup_y1 = ImClamp(frame_bb.Min.y - popup_opened_height, style.DisplaySafeAreaPadding.y, frame_bb.Min.y); + popup_y2 = frame_bb.Min.y; + } + ImRect popup_rect(ImVec2(frame_bb.Min.x, popup_y1), ImVec2(frame_bb.Max.x, popup_y2)); + SetNextWindowPos(popup_rect.Min); + SetNextWindowSize(popup_rect.GetSize()); + PushStyleVar(ImGuiStyleVar_WindowPadding, style.FramePadding); + + const ImGuiWindowFlags flags = ImGuiWindowFlags_ComboBox | ((window->Flags & ImGuiWindowFlags_ShowBorders) ? ImGuiWindowFlags_ShowBorders : 0); + if (!BeginPopupEx(id, flags)) + { + IM_ASSERT(0); // This should never happen as we tested for IsPopupOpen() above + return false; + } + Spacing(); + + return true; +} + +void ImGui::EndCombo() +{ + EndPopup(); + PopStyleVar(); +} + +// Combo box function. +bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(void*, int, const char**), void* data, int items_count, int height_in_items) +{ + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; + + const char* preview_text = NULL; + if (*current_item >= 0 && *current_item < items_count) + items_getter(data, *current_item, &preview_text); + + // Size default to hold ~7 items + if (height_in_items < 0) + height_in_items = 7; + float popup_opened_height = (g.FontSize + style.ItemSpacing.y) * ImMin(items_count, height_in_items) + (style.FramePadding.y * 3); + + if (!BeginCombo(label, preview_text, popup_opened_height)) + return false; + + // Display items + // FIXME-OPT: Use clipper + bool value_changed = false; + for (int i = 0; i < items_count; i++) + { + PushID((void*)(intptr_t)i); + const bool item_selected = (i == *current_item); + const char* item_text; + if (!items_getter(data, i, &item_text)) + item_text = "*Unknown item*"; + if (Selectable(item_text, item_selected)) + { + value_changed = true; + *current_item = i; + } + if (item_selected && IsWindowAppearing()) + SetScrollHere(); + PopID(); + } + + EndCombo(); return value_changed; } diff --git a/imgui_internal.h b/imgui_internal.h index f9d67d04b..209c3a26a 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -766,11 +766,15 @@ namespace ImGui IMGUI_API int CalcTypematicPressedRepeatAmount(float t, float t_prev, float repeat_delay, float repeat_rate); - // New Columns API + // FIXME-WIP: New Columns API IMGUI_API void BeginColumns(const char* id, int count, ImGuiColumnsFlags flags = 0); // setup number of columns. use an identifier to distinguish multiple column sets. close with EndColumns(). IMGUI_API void EndColumns(); // close columns IMGUI_API void PushColumnClipRect(int column_index = -1); + // FIXME-WIP: New Combo API + IMGUI_API bool BeginCombo(const char* label, const char* preview_value, float popup_opened_height); + IMGUI_API void EndCombo(); + // NB: All position are in absolute pixels coordinates (never using window coordinates internally) // AVOID USING OUTSIDE OF IMGUI.CPP! NOT FOR PUBLIC CONSUMPTION. THOSE FUNCTIONS ARE A MESS. THEIR SIGNATURE AND BEHAVIOR WILL CHANGE, THEY NEED TO BE REFACTORED INTO SOMETHING DECENT. IMGUI_API void RenderText(ImVec2 pos, const char* text, const char* text_end = NULL, bool hide_text_after_hash = true); From 8fbe8709f9a3a6ec7b99c02f01b91e49bb2a0f63 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 4 Sep 2017 13:03:04 +0200 Subject: [PATCH 323/921] TODO, minor tweak --- TODO.txt | 3 +++ imgui.cpp | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/TODO.txt b/TODO.txt index 944df651b..9c7b3a2a4 100644 --- a/TODO.txt +++ b/TODO.txt @@ -99,6 +99,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - plot: add a helper e.g. Plot(char* label, float value, float time_span=2.0f) that stores values and Plot them for you - probably another function name. and/or automatically allow to plot ANY displayed value (more reliance on stable ID) - clipper: ability to force display 1 item in the list would be convenient. + - clipper: ability to run without knowing full count in advance. - splitter/separator: formalize the splitter idiom into an official api (we want to handle n-way split) (#319) @@ -156,6 +157,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - text: proper alignment options in imgui_internal.h - text wrapped: figure out better way to use TextWrapped() in an always auto-resize context (tooltip, etc.) (#249) + - text: it's currently impossible to have a window title with "##". perhaps an official workaround would be nice. \ style inhibitor? non-visible ascii code to insert between #? - tree node / optimization: avoid formatting when clipped. - tree node: tree-node/header right-most side doesn't take account of horizontal scrolling. @@ -215,6 +217,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - keyboard: full keyboard navigation and focus. (#323) - focus: preserve ActiveId/focus stack state, e.g. when opening a menu and close it, previously selected InputText() focus gets restored (#622) - focus: SetKeyboardFocusHere() on with >= 0 offset could be done on same frame (else latch and modulate on beginning of next frame) + - focus: unable to use SetKeyboardFocusHere() on clipped widgets. (#343) - inputs: rework IO system to be able to pass actual ordered/timestamped events. use an event queue? (~#335, #71) - inputs: allow to decide and pass explicit double-clicks (e.g. for windows by the CS_DBLCLKS style). - inputs: support track pad style scrolling & slider edit. diff --git a/imgui.cpp b/imgui.cpp index 962e07fbd..40c15f642 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1956,7 +1956,7 @@ bool ImGui::IsClippedEx(const ImRect& bb, const ImGuiID* id, bool clip_even_when ImGuiContext& g = *GImGui; ImGuiWindow* window = GetCurrentWindowRead(); if (!bb.Overlaps(window->ClipRect)) - if (!id || *id != GImGui->ActiveId) + if (!id || *id != g.ActiveId) if (clip_even_when_logged || !g.LogEnabled) return true; return false; From 89cae37b496ce14dbf3c4bcc59493dd9ff159e97 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 4 Sep 2017 13:05:20 +0200 Subject: [PATCH 324/921] Begin(): Tidying up some code, should be a no-op. --- imgui.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 40c15f642..5e61cee06 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3965,19 +3965,20 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us CheckStacksSize(window, true); IM_ASSERT(parent_window != NULL || !(flags & ImGuiWindowFlags_ChildWindow)); - bool window_was_active = (window->LastFrameActive == current_frame - 1); // Not using !WasActive because the implicit "Debug" window would always toggle off->on + // FIXME: This is currently true if we call Begin() multiple times in a row on a same window. + bool window_activated = (window->LastFrameActive != current_frame - 1); // Not using !WasActive because the implicit "Debug" window would always toggle off->on if (flags & ImGuiWindowFlags_Popup) { ImGuiPopupRef& popup_ref = g.OpenPopupStack[g.CurrentPopupStack.Size]; - window_was_active &= (window->PopupId == popup_ref.PopupId); - window_was_active &= (window == popup_ref.Window); + window_activated |= (window->PopupId != popup_ref.PopupId); // We recycle popups so treat window as activated if popup id changed + window_activated |= (window != popup_ref.Window); popup_ref.Window = window; g.CurrentPopupStack.push_back(popup_ref); window->PopupId = popup_ref.PopupId; } const bool window_appearing_after_being_hidden = (window->HiddenFrames == 1); - window->Appearing = (!window_was_active || window_appearing_after_being_hidden); + window->Appearing = (window_activated || window_appearing_after_being_hidden); // Process SetNextWindow***() calls bool window_pos_set_by_api = false, window_size_set_by_api = false; @@ -4061,7 +4062,7 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us else PushClipRect(fullscreen_rect.Min, fullscreen_rect.Max, true); - if (!window_was_active) + if (window_activated) { // Popup first latch mouse position, will position itself when it appears next frame window->AutoPosLastDirection = -1; @@ -4095,7 +4096,7 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us // Hide popup/tooltip window when first appearing while we measure size (because we recycle them) if (window->HiddenFrames > 0) window->HiddenFrames--; - if ((flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_Tooltip)) != 0 && !window_was_active) + if ((flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_Tooltip)) != 0 && window_activated) { window->HiddenFrames = 1; if (flags & ImGuiWindowFlags_AlwaysAutoResize) @@ -4389,7 +4390,7 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us window->DC.TreeDepth = 0; window->DC.StateStorage = &window->StateStorage; window->DC.GroupStack.resize(0); - window->MenuColumns.Update(3, style.ItemSpacing.x, !window_was_active); + window->MenuColumns.Update(3, style.ItemSpacing.x, window_activated); if (window->AutoFitFramesX > 0) window->AutoFitFramesX--; @@ -4397,7 +4398,7 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us window->AutoFitFramesY--; // New windows appears in front (we need to do that AFTER setting DC.CursorStartPos so our initial navigation reference rectangle can start around there) - if (!window_was_active && !(flags & ImGuiWindowFlags_NoFocusOnAppearing)) + if (window_activated && !(flags & ImGuiWindowFlags_NoFocusOnAppearing)) if (!(flags & (ImGuiWindowFlags_ChildWindow|ImGuiWindowFlags_Tooltip)) || (flags & ImGuiWindowFlags_Popup)) FocusWindow(window); From a9c6a0f6ecb1395c78369bc7cf2d9754750a36be Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 4 Sep 2017 13:24:45 +0200 Subject: [PATCH 325/921] Begin(): Removed unnecessary code (at the time of 1.18 commit e9e0e36f988a12e0719b1e3b109dafac9fb4471f, CursorPos was used to compute SizeContentsFit and this was necessary) --- imgui.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 5e61cee06..7d2f773f1 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3984,7 +3984,6 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us bool window_pos_set_by_api = false, window_size_set_by_api = false; if (g.SetNextWindowPosCond) { - const ImVec2 backup_cursor_pos = window->DC.CursorPos; // FIXME: not sure of the exact reason of this saving/restore anymore :( need to look into that. if (window->Appearing) window->SetWindowPosAllowFlags |= ImGuiCond_Appearing; window_pos_set_by_api = (window->SetWindowPosAllowFlags & g.SetNextWindowPosCond) != 0; @@ -3997,7 +3996,6 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us { SetWindowPos(window, g.SetNextWindowPosVal, g.SetNextWindowPosCond); } - window->DC.CursorPos = backup_cursor_pos; g.SetNextWindowPosCond = 0; } if (g.SetNextWindowSizeCond) @@ -4042,7 +4040,6 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us window->RootWindow = g.CurrentWindowStack[root_idx]; window->RootNonPopupWindow = g.CurrentWindowStack[root_non_popup_idx]; // Used to display TitleBgActive color and for selecting which window to use for NavWindowing - // When reusing window again multiple times a frame, just append content (don't need to setup again) if (first_begin_of_the_frame) { From 6400f2900a32c6f28f849ac1a2711fb9aaa2f88e Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 4 Sep 2017 13:26:46 +0200 Subject: [PATCH 326/921] Begin(): renamed locals. --- imgui.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 7d2f773f1..7413dc466 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3966,19 +3966,19 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us IM_ASSERT(parent_window != NULL || !(flags & ImGuiWindowFlags_ChildWindow)); // FIXME: This is currently true if we call Begin() multiple times in a row on a same window. - bool window_activated = (window->LastFrameActive != current_frame - 1); // Not using !WasActive because the implicit "Debug" window would always toggle off->on + bool window_just_activated_by_user = (window->LastFrameActive != current_frame - 1); // Not using !WasActive because the implicit "Debug" window would always toggle off->on if (flags & ImGuiWindowFlags_Popup) { ImGuiPopupRef& popup_ref = g.OpenPopupStack[g.CurrentPopupStack.Size]; - window_activated |= (window->PopupId != popup_ref.PopupId); // We recycle popups so treat window as activated if popup id changed - window_activated |= (window != popup_ref.Window); + window_just_activated_by_user |= (window->PopupId != popup_ref.PopupId); // We recycle popups so treat window as activated if popup id changed + window_just_activated_by_user |= (window != popup_ref.Window); popup_ref.Window = window; g.CurrentPopupStack.push_back(popup_ref); window->PopupId = popup_ref.PopupId; } - const bool window_appearing_after_being_hidden = (window->HiddenFrames == 1); - window->Appearing = (window_activated || window_appearing_after_being_hidden); + const bool window_just_appearing_after_hidden_for_resize = (window->HiddenFrames == 1); + window->Appearing = (window_just_activated_by_user || window_just_appearing_after_hidden_for_resize); // Process SetNextWindow***() calls bool window_pos_set_by_api = false, window_size_set_by_api = false; @@ -4059,7 +4059,7 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us else PushClipRect(fullscreen_rect.Min, fullscreen_rect.Max, true); - if (window_activated) + if (window_just_activated_by_user) { // Popup first latch mouse position, will position itself when it appears next frame window->AutoPosLastDirection = -1; @@ -4093,7 +4093,7 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us // Hide popup/tooltip window when first appearing while we measure size (because we recycle them) if (window->HiddenFrames > 0) window->HiddenFrames--; - if ((flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_Tooltip)) != 0 && window_activated) + if ((flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_Tooltip)) != 0 && window_just_activated_by_user) { window->HiddenFrames = 1; if (flags & ImGuiWindowFlags_AlwaysAutoResize) @@ -4173,7 +4173,7 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us bool window_pos_center = false; window_pos_center |= (window->SetWindowPosCenterWanted && window->HiddenFrames == 0); - window_pos_center |= ((flags & ImGuiWindowFlags_Modal) && !window_pos_set_by_api && window_appearing_after_being_hidden); + window_pos_center |= ((flags & ImGuiWindowFlags_Modal) && !window_pos_set_by_api && window_just_appearing_after_hidden_for_resize); if (window_pos_center) { // Center (any sort of window) @@ -4192,7 +4192,7 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us rect_to_avoid = ImRect(parent_window->Pos.x + horizontal_overlap, -FLT_MAX, parent_window->Pos.x + parent_window->Size.x - horizontal_overlap - parent_window->ScrollbarSizes.x, FLT_MAX); window->PosFloat = FindBestPopupWindowPos(window->PosFloat, window->Size, &window->AutoPosLastDirection, rect_to_avoid); } - else if ((flags & ImGuiWindowFlags_Popup) != 0 && !window_pos_set_by_api && window_appearing_after_being_hidden) + else if ((flags & ImGuiWindowFlags_Popup) != 0 && !window_pos_set_by_api && window_just_appearing_after_hidden_for_resize) { ImRect rect_to_avoid(window->PosFloat.x - 1, window->PosFloat.y - 1, window->PosFloat.x + 1, window->PosFloat.y + 1); window->PosFloat = FindBestPopupWindowPos(window->PosFloat, window->Size, &window->AutoPosLastDirection, rect_to_avoid); @@ -4387,7 +4387,7 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us window->DC.TreeDepth = 0; window->DC.StateStorage = &window->StateStorage; window->DC.GroupStack.resize(0); - window->MenuColumns.Update(3, style.ItemSpacing.x, window_activated); + window->MenuColumns.Update(3, style.ItemSpacing.x, window_just_activated_by_user); if (window->AutoFitFramesX > 0) window->AutoFitFramesX--; @@ -4395,7 +4395,7 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us window->AutoFitFramesY--; // New windows appears in front (we need to do that AFTER setting DC.CursorStartPos so our initial navigation reference rectangle can start around there) - if (window_activated && !(flags & ImGuiWindowFlags_NoFocusOnAppearing)) + if (window_just_activated_by_user && !(flags & ImGuiWindowFlags_NoFocusOnAppearing)) if (!(flags & (ImGuiWindowFlags_ChildWindow|ImGuiWindowFlags_Tooltip)) || (flags & ImGuiWindowFlags_Popup)) FocusWindow(window); From 2600b28f5d6321683078ace5ab2102d2dde8c7d4 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 4 Sep 2017 13:29:57 +0200 Subject: [PATCH 327/921] Begin(): fixed calling Begin() more than once per frame setting `window_just_activated_by_user` which in turn would set Appearing to true for that frame. --- imgui.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 7413dc466..2b9f50dba 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3951,7 +3951,7 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us window_is_new = true; } - const int current_frame = ImGui::GetFrameCount(); + const int current_frame = g.FrameCount; const bool first_begin_of_the_frame = (window->LastFrameActive != current_frame); if (first_begin_of_the_frame) window->Flags = (ImGuiWindowFlags)flags; @@ -3965,8 +3965,7 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us CheckStacksSize(window, true); IM_ASSERT(parent_window != NULL || !(flags & ImGuiWindowFlags_ChildWindow)); - // FIXME: This is currently true if we call Begin() multiple times in a row on a same window. - bool window_just_activated_by_user = (window->LastFrameActive != current_frame - 1); // Not using !WasActive because the implicit "Debug" window would always toggle off->on + bool window_just_activated_by_user = (window->LastFrameActive < current_frame - 1); // Not using !WasActive because the implicit "Debug" window would always toggle off->on if (flags & ImGuiWindowFlags_Popup) { ImGuiPopupRef& popup_ref = g.OpenPopupStack[g.CurrentPopupStack.Size]; From e1a7aa41cb827f55e621cf1974beddd51e92e25f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=A1clav=20Patejdl?= Date: Tue, 5 Sep 2017 16:31:54 +0200 Subject: [PATCH 328/921] Improved ColorPicker hue wheel color interpolation --- imgui.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 2b9f50dba..b33cb5c4e 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9510,11 +9510,11 @@ static void RenderArrowsForVerticalBar(ImDrawList* draw_list, ImVec2 pos, ImVec2 static void PaintVertsLinearGradientKeepAlpha(ImDrawVert* vert_start, ImDrawVert* vert_end, ImVec2 gradient_p0, ImVec2 gradient_p1, ImU32 col0, ImU32 col1) { ImVec2 gradient_extent = gradient_p1 - gradient_p0; - float gradient_inv_length = ImInvLength(gradient_extent, 0.0f); + float gradient_inv_length2 = 1.0f / ImLengthSqr(gradient_extent); for (ImDrawVert* vert = vert_start; vert < vert_end; vert++) { float d = ImDot(vert->pos - gradient_p0, gradient_extent); - float t = ImMin(sqrtf(ImMax(d, 0.0f)) * gradient_inv_length, 1.0f); + float t = ImClamp(d * gradient_inv_length2, 0.0f, 1.0f); int r = ImLerp((int)(col0 >> IM_COL32_R_SHIFT) & 0xFF, (int)(col1 >> IM_COL32_R_SHIFT) & 0xFF, t); int g = ImLerp((int)(col0 >> IM_COL32_G_SHIFT) & 0xFF, (int)(col1 >> IM_COL32_G_SHIFT) & 0xFF, t); int b = ImLerp((int)(col0 >> IM_COL32_B_SHIFT) & 0xFF, (int)(col1 >> IM_COL32_B_SHIFT) & 0xFF, t); From 790605e359843acb5eb3d2940385516536f37898 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 6 Sep 2017 17:20:54 +0200 Subject: [PATCH 329/921] Minor comments + renaming internal fields --- imgui.cpp | 15 +++++++-------- imgui_internal.h | 6 +++--- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index b33cb5c4e..51d03154a 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2286,14 +2286,14 @@ void ImGui::NewFrame() mouse_earliest_button_down = i; } bool mouse_avail_to_imgui = (mouse_earliest_button_down == -1) || g.IO.MouseDownOwned[mouse_earliest_button_down]; - if (g.CaptureMouseNextFrame != -1) - g.IO.WantCaptureMouse = (g.CaptureMouseNextFrame != 0); + if (g.WantCaptureMouseNextFrame != -1) + g.IO.WantCaptureMouse = (g.WantCaptureMouseNextFrame != 0); else g.IO.WantCaptureMouse = (mouse_avail_to_imgui && (g.HoveredWindow != NULL || mouse_any_down)) || (g.ActiveId != 0) || (!g.OpenPopupStack.empty()); - g.IO.WantCaptureKeyboard = (g.CaptureKeyboardNextFrame != -1) ? (g.CaptureKeyboardNextFrame != 0) : (g.ActiveId != 0); + g.IO.WantCaptureKeyboard = (g.WantCaptureKeyboardNextFrame != -1) ? (g.WantCaptureKeyboardNextFrame != 0) : (g.ActiveId != 0); g.IO.WantTextInput = (g.ActiveId != 0 && g.InputTextState.Id == g.ActiveId); g.MouseCursor = ImGuiMouseCursor_Arrow; - g.CaptureMouseNextFrame = g.CaptureKeyboardNextFrame = -1; + g.WantCaptureMouseNextFrame = g.WantCaptureKeyboardNextFrame = -1; g.OsImePosRequest = ImVec2(1.0f, 1.0f); // OS Input Method Editor showing on top-left of our window by default // If mouse was first clicked outside of ImGui bounds we also cancel out hovering. @@ -3306,12 +3306,12 @@ void ImGui::SetMouseCursor(ImGuiMouseCursor cursor_type) void ImGui::CaptureKeyboardFromApp(bool capture) { - GImGui->CaptureKeyboardNextFrame = capture ? 1 : 0; + GImGui->WantCaptureKeyboardNextFrame = capture ? 1 : 0; } void ImGui::CaptureMouseFromApp(bool capture) { - GImGui->CaptureMouseNextFrame = capture ? 1 : 0; + GImGui->WantCaptureMouseNextFrame = capture ? 1 : 0; } bool ImGui::IsItemHovered() @@ -6478,6 +6478,7 @@ bool ImGui::InputScalarAsWidgetReplacement(const ImRect& aabb, const char* label ImGuiWindow* window = GetCurrentWindow(); // Our replacement widget will override the focus ID (registered previously to allow for a TAB focus to happen) + // On the first frame, g.ScalarAsInputTextId == 0, then on subsequent frames it becomes == id SetActiveID(g.ScalarAsInputTextId, window); SetHoveredID(0); FocusableItemUnregister(window); @@ -6723,7 +6724,6 @@ bool ImGui::SliderFloat(const char* label, float* v, float v_min, float v_max, c { SetActiveID(id, window); FocusWindow(window); - if (tab_focus_requested || g.IO.KeyCtrl) { start_text_input = true; @@ -7024,7 +7024,6 @@ bool ImGui::DragFloat(const char* label, float* v, float v_speed, float v_min, f { SetActiveID(id, window); FocusWindow(window); - if (tab_focus_requested || g.IO.KeyCtrl || g.IO.MouseDoubleClicked[0]) { start_text_input = true; diff --git a/imgui_internal.h b/imgui_internal.h index 209c3a26a..bebdcb2a7 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -486,8 +486,8 @@ struct ImGuiContext float FramerateSecPerFrame[120]; // calculate estimate of framerate for user int FramerateSecPerFrameIdx; float FramerateSecPerFrameAccum; - int CaptureMouseNextFrame; // explicit capture via CaptureInputs() sets those flags - int CaptureKeyboardNextFrame; + int WantCaptureMouseNextFrame; // explicit capture via CaptureInputs() sets those flags + int WantCaptureKeyboardNextFrame; char TempBuffer[1024*3+1]; // temporary text buffer ImGuiContext() @@ -558,7 +558,7 @@ struct ImGuiContext memset(FramerateSecPerFrame, 0, sizeof(FramerateSecPerFrame)); FramerateSecPerFrameIdx = 0; FramerateSecPerFrameAccum = 0.0f; - CaptureMouseNextFrame = CaptureKeyboardNextFrame = -1; + WantCaptureMouseNextFrame = WantCaptureKeyboardNextFrame = -1; memset(TempBuffer, 0, sizeof(TempBuffer)); } }; From 2169bf6895fd9175ef74545c2c7bebf6441f04db Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 6 Sep 2017 17:25:36 +0200 Subject: [PATCH 330/921] Fixed WantTextInput from being true when an activated Drag or Slider was previously turned into an InputText(). (#1317) --- imgui.cpp | 5 +++-- imgui_internal.h | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 51d03154a..bb313abb6 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2291,9 +2291,9 @@ void ImGui::NewFrame() else g.IO.WantCaptureMouse = (mouse_avail_to_imgui && (g.HoveredWindow != NULL || mouse_any_down)) || (g.ActiveId != 0) || (!g.OpenPopupStack.empty()); g.IO.WantCaptureKeyboard = (g.WantCaptureKeyboardNextFrame != -1) ? (g.WantCaptureKeyboardNextFrame != 0) : (g.ActiveId != 0); - g.IO.WantTextInput = (g.ActiveId != 0 && g.InputTextState.Id == g.ActiveId); + g.IO.WantTextInput = (g.WantTextInputNextFrame != -1) ? (g.WantTextInputNextFrame != 0) : 0; g.MouseCursor = ImGuiMouseCursor_Arrow; - g.WantCaptureMouseNextFrame = g.WantCaptureKeyboardNextFrame = -1; + g.WantCaptureMouseNextFrame = g.WantCaptureKeyboardNextFrame = g.WantTextInputNextFrame = -1; g.OsImePosRequest = ImVec2(1.0f, 1.0f); // OS Input Method Editor showing on top-left of our window by default // If mouse was first clicked outside of ImGui bounds we also cancel out hovering. @@ -7906,6 +7906,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 // Although we are active we don't prevent mouse from hovering other elements unless we are interacting right now with the widget. // Down the line we should have a cleaner library-wide concept of Selected vs Active. g.ActiveIdAllowOverlap = !io.MouseDown[0]; + g.WantTextInputNextFrame = 1; // Edit in progress const float mouse_x = (io.MousePos.x - frame_bb.Min.x - style.FramePadding.x) + edit_state.ScrollX; diff --git a/imgui_internal.h b/imgui_internal.h index bebdcb2a7..7716357bc 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -488,6 +488,7 @@ struct ImGuiContext float FramerateSecPerFrameAccum; int WantCaptureMouseNextFrame; // explicit capture via CaptureInputs() sets those flags int WantCaptureKeyboardNextFrame; + int WantTextInputNextFrame; char TempBuffer[1024*3+1]; // temporary text buffer ImGuiContext() @@ -558,7 +559,7 @@ struct ImGuiContext memset(FramerateSecPerFrame, 0, sizeof(FramerateSecPerFrame)); FramerateSecPerFrameIdx = 0; FramerateSecPerFrameAccum = 0.0f; - WantCaptureMouseNextFrame = WantCaptureKeyboardNextFrame = -1; + WantCaptureMouseNextFrame = WantCaptureKeyboardNextFrame = WantTextInputNextFrame = -1; memset(TempBuffer, 0, sizeof(TempBuffer)); } }; From 9e2f202f05e92294c14629eb5856f588d1709ac1 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 6 Sep 2017 19:24:08 +0200 Subject: [PATCH 331/921] Demo: Not using the undesirable Begin() overload. --- imgui_demo.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index b114520ba..45a845d6c 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -2118,7 +2118,8 @@ static void ShowExampleAppConstrainedResize(bool* p_open) static void ShowExampleAppFixedOverlay(bool* p_open) { ImGui::SetNextWindowPos(ImVec2(10,10)); - if (!ImGui::Begin("Example: Fixed Overlay", p_open, ImVec2(0,0), 0.3f, ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoSavedSettings)) + ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(0.0f, 0.0f, 0.0f, 0.3f)); + if (!ImGui::Begin("Example: Fixed Overlay", p_open, ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoSavedSettings)) { ImGui::End(); return; @@ -2127,6 +2128,7 @@ static void ShowExampleAppFixedOverlay(bool* p_open) ImGui::Separator(); ImGui::Text("Mouse Position: (%.1f,%.1f)", ImGui::GetIO().MousePos.x, ImGui::GetIO().MousePos.y); ImGui::End(); + ImGui::PopStyleColor(); } // Demonstrate using "##" and "###" in identifiers to manipulate ID generation. From 51fcef0c21b9c05547370d02513406a196a739d6 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 6 Sep 2017 19:31:50 +0200 Subject: [PATCH 332/921] BeginCombo() tweaks, merged from Navigation branch. --- imgui.cpp | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index bb313abb6..acca6ed0d 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -7020,7 +7020,7 @@ bool ImGui::DragFloat(const char* label, float* v, float v_speed, float v_min, f // Tabbing or CTRL-clicking on Drag turns it into an input box bool start_text_input = false; const bool tab_focus_requested = FocusableItemRegister(window, id); - if (tab_focus_requested || (hovered && (g.IO.MouseClicked[0] | g.IO.MouseDoubleClicked[0]))) + if (tab_focus_requested || (hovered && (g.IO.MouseClicked[0] || g.IO.MouseDoubleClicked[0]))) { SetActiveID(id, window); FocusWindow(window); @@ -8599,25 +8599,31 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, float popup if (label_size.x > 0) RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label); + bool popup_toggled = false; if (hovered) { SetHoveredID(id); if (g.IO.MouseClicked[0]) { ClearActiveID(); - if (IsPopupOpen(id)) - { - ClosePopup(id); - } - else - { - FocusWindow(window); - OpenPopup(label); - } + popup_toggled = true; } } + if (popup_toggled) + { + if (popup_open) + { + ClosePopup(id); + } + else + { + FocusWindow(window); + OpenPopupEx(id, false); + } + popup_open = !popup_open; + } - if (!IsPopupOpen(id)) + if (!popup_open) return false; float popup_y1 = frame_bb.Max.y; @@ -9054,7 +9060,10 @@ bool ImGui::BeginMenu(const char* label, bool enabled) want_open = menu_is_open = false; } else if (pressed || (hovered && menuset_is_open && !menu_is_open)) // menu-bar: first click to open, then hover to open others + { want_open = true; + } + if (!enabled) // explicitly close if an open menu becomes disabled, facilitate users code a lot in pattern such as 'if (BeginMenu("options", has_object)) { ..use object.. }' want_close = true; if (want_close && IsPopupOpen(id)) From f63c03c46485c758712d0e6500137288622223d6 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 6 Sep 2017 20:28:36 +0200 Subject: [PATCH 333/921] Internals: moved ButtonRepeat and AllowKeyboardFocus bools/stacks to a generic ItemFlags stack. Merged from Navigation branch. --- imgui.cpp | 49 ++++++++++++++++++++++++++++++------------------ imgui.h | 4 ++-- imgui_internal.h | 20 ++++++++++++++------ 3 files changed, 47 insertions(+), 26 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index acca6ed0d..26ad6a192 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1981,7 +1981,7 @@ bool ImGui::FocusableItemRegister(ImGuiWindow* window, ImGuiID id, bool tab_stop { ImGuiContext& g = *GImGui; - const bool allow_keyboard_focus = window->DC.AllowKeyboardFocus; + const bool allow_keyboard_focus = (window->DC.ItemFlags & ImGuiItemFlags_AllowKeyboardFocus) != 0; window->FocusIdxAllCounter++; if (allow_keyboard_focus) window->FocusIdxTabCounter++; @@ -4370,13 +4370,11 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us window->DC.LogLinePosY = window->DC.CursorPos.y - 9999.0f; window->DC.ChildWindows.resize(0); window->DC.LayoutType = ImGuiLayoutType_Vertical; + window->DC.ItemFlags = ImGuiItemFlags_Default_; window->DC.ItemWidth = window->ItemWidthDefault; window->DC.TextWrapPos = -1.0f; // disabled - window->DC.AllowKeyboardFocus = true; - window->DC.ButtonRepeat = false; + window->DC.ItemFlagsStack.resize(0); window->DC.ItemWidthStack.resize(0); - window->DC.AllowKeyboardFocusStack.resize(0); - window->DC.ButtonRepeatStack.resize(0); window->DC.TextWrapPosStack.resize(0); window->DC.ColumnsCurrent = 0; window->DC.ColumnsCount = 1; @@ -4388,6 +4386,12 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us window->DC.GroupStack.resize(0); window->MenuColumns.Update(3, style.ItemSpacing.x, window_just_activated_by_user); + if ((flags & ImGuiWindowFlags_ChildWindow) && (window->DC.ItemFlags != parent_window->DC.ItemFlags)) + { + window->DC.ItemFlags = parent_window->DC.ItemFlags; + window->DC.ItemFlagsStack.push_back(window->DC.ItemFlags); + } + if (window->AutoFitFramesX > 0) window->AutoFitFramesX--; if (window->AutoFitFramesY > 0) @@ -4721,32 +4725,41 @@ void ImGui::PopFont() SetCurrentFont(g.FontStack.empty() ? GetDefaultFont() : g.FontStack.back()); } -void ImGui::PushAllowKeyboardFocus(bool allow_keyboard_focus) +void ImGui::PushItemFlag(ImGuiItemFlags option, bool enabled) { ImGuiWindow* window = GetCurrentWindow(); - window->DC.AllowKeyboardFocus = allow_keyboard_focus; - window->DC.AllowKeyboardFocusStack.push_back(allow_keyboard_focus); + if (enabled) + window->DC.ItemFlags |= option; + else + window->DC.ItemFlags &= ~option; + window->DC.ItemFlagsStack.push_back(window->DC.ItemFlags); +} + +void ImGui::PopItemFlag() +{ + ImGuiWindow* window = GetCurrentWindow(); + window->DC.ItemFlagsStack.pop_back(); + window->DC.ItemFlags = window->DC.ItemFlagsStack.empty() ? ImGuiItemFlags_Default_ : window->DC.ItemFlagsStack.back(); +} + +void ImGui::PushAllowKeyboardFocus(bool allow_keyboard_focus) +{ + PushItemFlag(ImGuiItemFlags_AllowKeyboardFocus, allow_keyboard_focus); } void ImGui::PopAllowKeyboardFocus() { - ImGuiWindow* window = GetCurrentWindow(); - window->DC.AllowKeyboardFocusStack.pop_back(); - window->DC.AllowKeyboardFocus = window->DC.AllowKeyboardFocusStack.empty() ? true : window->DC.AllowKeyboardFocusStack.back(); + PopItemFlag(); } void ImGui::PushButtonRepeat(bool repeat) { - ImGuiWindow* window = GetCurrentWindow(); - window->DC.ButtonRepeat = repeat; - window->DC.ButtonRepeatStack.push_back(repeat); + PushItemFlag(ImGuiItemFlags_ButtonRepeat, repeat); } void ImGui::PopButtonRepeat() { - ImGuiWindow* window = GetCurrentWindow(); - window->DC.ButtonRepeatStack.pop_back(); - window->DC.ButtonRepeat = window->DC.ButtonRepeatStack.empty() ? false : window->DC.ButtonRepeatStack.back(); + PopItemFlag(); } void ImGui::PushTextWrapPos(float wrap_pos_x) @@ -5722,7 +5735,7 @@ bool ImGui::ButtonEx(const char* label, const ImVec2& size_arg, ImGuiButtonFlags if (!ItemAdd(bb, &id)) return false; - if (window->DC.ButtonRepeat) flags |= ImGuiButtonFlags_Repeat; + if (window->DC.ItemFlags & ImGuiItemFlags_ButtonRepeat) flags |= ImGuiButtonFlags_Repeat; bool hovered, held; bool pressed = ButtonBehavior(bb, id, &hovered, &held, flags); diff --git a/imgui.h b/imgui.h index be4b74a62..0cf364955 100644 --- a/imgui.h +++ b/imgui.h @@ -204,9 +204,9 @@ namespace ImGui IMGUI_API float CalcItemWidth(); // width of item given pushed settings and current cursor position IMGUI_API void PushTextWrapPos(float wrap_pos_x = 0.0f); // word-wrapping for Text*() commands. < 0.0f: no wrapping; 0.0f: wrap to end of window (or column); > 0.0f: wrap at 'wrap_pos_x' position in window local space IMGUI_API void PopTextWrapPos(); - IMGUI_API void PushAllowKeyboardFocus(bool v); // allow focusing using TAB/Shift-TAB, enabled by default but you can disable it for certain widgets + IMGUI_API void PushAllowKeyboardFocus(bool allow_keyboard_focus); // allow focusing using TAB/Shift-TAB, enabled by default but you can disable it for certain widgets IMGUI_API void PopAllowKeyboardFocus(); - IMGUI_API void PushButtonRepeat(bool repeat); // in 'repeat' mode, Button*() functions return repeated true in a typematic manner (uses io.KeyRepeatDelay/io.KeyRepeatRate for now). Note that you can call IsItemActive() after any Button() to tell if the button is held in the current frame. + IMGUI_API void PushButtonRepeat(bool repeat); // in 'repeat' mode, Button*() functions return repeated true in a typematic manner (using io.KeyRepeatDelay/io.KeyRepeatRate setting). Note that you can call IsItemActive() after any Button() to tell if the button is held in the current frame. IMGUI_API void PopButtonRepeat(); // Cursor / Layout diff --git a/imgui_internal.h b/imgui_internal.h index 7716357bc..d882661f6 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -48,6 +48,7 @@ typedef int ImGuiLayoutType; // enum ImGuiLayoutType_ typedef int ImGuiButtonFlags; // enum ImGuiButtonFlags_ typedef int ImGuiTreeNodeFlags; // enum ImGuiTreeNodeFlags_ typedef int ImGuiSliderFlags; // enum ImGuiSliderFlags_ +typedef int ImGuiItemFlags; // enum ImGuiItemFlags_ //------------------------------------------------------------------------- // STB libraries @@ -564,6 +565,14 @@ struct ImGuiContext } }; +// Transient per-window flags, reset at the beginning of the frame. For child window, inherited from parent on first Begin(). +enum ImGuiItemFlags_ +{ + ImGuiItemFlags_AllowKeyboardFocus = 1 << 0, // default: true + ImGuiItemFlags_ButtonRepeat = 1 << 1, // default: false // Button() will return true multiple times based on io.KeyRepeatDelay and io.KeyRepeatRate settings. + ImGuiItemFlags_Default_ = ImGuiItemFlags_AllowKeyboardFocus +}; + // Transient per-window data, reset at the beginning of the frame // FIXME: That's theory, in practice the delimitation between ImGuiWindow and ImGuiDrawContext is quite tenuous and could be reconsidered. struct IMGUI_API ImGuiDrawContext @@ -589,14 +598,12 @@ struct IMGUI_API ImGuiDrawContext ImGuiLayoutType LayoutType; // We store the current settings outside of the vectors to increase memory locality (reduce cache misses). The vectors are rarely modified. Also it allows us to not heap allocate for short-lived windows which are not using those settings. + ImGuiItemFlags ItemFlags; // == ItemFlagsStack.back() [empty == ImGuiItemFlags_Default] float ItemWidth; // == ItemWidthStack.back(). 0.0: default, >0.0: width in pixels, <0.0: align xx pixels to the right of window float TextWrapPos; // == TextWrapPosStack.back() [empty == -1.0f] - bool AllowKeyboardFocus; // == AllowKeyboardFocusStack.back() [empty == true] - bool ButtonRepeat; // == ButtonRepeatStack.back() [empty == false] + ImVectorItemFlagsStack; ImVector ItemWidthStack; ImVector TextWrapPosStack; - ImVector AllowKeyboardFocusStack; - ImVector ButtonRepeatStack; ImVectorGroupStack; int StackSizesBackup[6]; // Store size of various stacks for asserting @@ -630,8 +637,7 @@ struct IMGUI_API ImGuiDrawContext StateStorage = NULL; LayoutType = ImGuiLayoutType_Vertical; ItemWidth = 0.0f; - ButtonRepeat = false; - AllowKeyboardFocus = true; + ItemFlags = ImGuiItemFlags_Default_; TextWrapPos = -1.0f; memset(StackSizesBackup, 0, sizeof(StackSizesBackup)); @@ -761,6 +767,8 @@ namespace ImGui IMGUI_API void FocusableItemUnregister(ImGuiWindow* window); IMGUI_API ImVec2 CalcItemSize(ImVec2 size, float default_x, float default_y); IMGUI_API float CalcWrapWidthForPos(const ImVec2& pos, float wrap_pos_x); + IMGUI_API void PushItemFlag(ImGuiItemFlags option, bool enabled); + IMGUI_API void PopItemFlag(); IMGUI_API void OpenPopupEx(ImGuiID id, bool reopen_existing); IMGUI_API bool IsPopupOpen(ImGuiID id); From cb2775ae54d1052a54fb6511292af6a3df245fda Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 6 Sep 2017 20:36:36 +0200 Subject: [PATCH 334/921] Internals: ImGuiItemFlags comments --- imgui_internal.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/imgui_internal.h b/imgui_internal.h index d882661f6..2d8b8457a 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -568,8 +568,11 @@ struct ImGuiContext // Transient per-window flags, reset at the beginning of the frame. For child window, inherited from parent on first Begin(). enum ImGuiItemFlags_ { - ImGuiItemFlags_AllowKeyboardFocus = 1 << 0, // default: true - ImGuiItemFlags_ButtonRepeat = 1 << 1, // default: false // Button() will return true multiple times based on io.KeyRepeatDelay and io.KeyRepeatRate settings. + ImGuiItemFlags_AllowKeyboardFocus = 1 << 0, // true + ImGuiItemFlags_ButtonRepeat = 1 << 1, // false // Button() will return true multiple times based on io.KeyRepeatDelay and io.KeyRepeatRate settings. + //ImGuiItemFlags_Disabled = 1 << 2, // false // All widgets appears are disabled + //ImGuiItemFlags_AllowNavDefaultFocus = 1 << 3, // true + //ImGuiItemFlags_SelectableDontClosePopup = 1 << 4, // false // MenuItem/Selectable() automatically closes current Popup window ImGuiItemFlags_Default_ = ImGuiItemFlags_AllowKeyboardFocus }; From cf6ba9dd2dda9151450c0f7a3ef0689ccbc53756 Mon Sep 17 00:00:00 2001 From: Daniel Loffgren Date: Sun, 10 Sep 2017 23:58:18 -0700 Subject: [PATCH 335/921] Don't do a bunch of OS gymnastics. alloca.h is only for glibc, everyone else uses stdlib.h --- imgui_draw.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 0a23ac0e5..e0d4016ff 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -21,10 +21,10 @@ #if !defined(alloca) #ifdef _WIN32 #include // alloca -#elif (defined(__FreeBSD__) || defined(FreeBSD_kernel) || defined(__DragonFly__)) && !defined(__GLIBC__) -#include // alloca. FreeBSD uses stdlib.h unless GLIBC +#elif !defined(__GLIBC__) +#include // alloca #else -#include // alloca +#include // alloca. glibc has an alloca specific header #endif #endif From 65632d268217ef8592ca478be7dc526398c1950f Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 12 Sep 2017 11:55:13 +0200 Subject: [PATCH 336/921] Fixed alloca include for SunOS (#1319) --- imgui_draw.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index e0d4016ff..b4b7f5648 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -21,10 +21,10 @@ #if !defined(alloca) #ifdef _WIN32 #include // alloca -#elif !defined(__GLIBC__) -#include // alloca +#elif defined(__GLIBC__) || defined(__sun) +#include // alloca #else -#include // alloca. glibc has an alloca specific header +#include // alloca #endif #endif From 54d30d758feaee651d3f791d450e204c2160ee63 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 12 Sep 2017 13:16:27 +0200 Subject: [PATCH 337/921] Implicit "Debug" window uses a "Debug##Default" identifier to allow the user creating such window with custom flags --- imgui.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 26ad6a192..42a3989fd 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2355,8 +2355,9 @@ void ImGui::NewFrame() CloseInactivePopups(); // Create implicit window - we will only render it if the user has added something to it. + // We don't use "Debug" to avoid colliding with user trying to create a "Debug" window with custom flags. ImGui::SetNextWindowSize(ImVec2(400,400), ImGuiCond_FirstUseEver); - ImGui::Begin("Debug"); + ImGui::Begin("Debug##Default"); } void ImGui::Initialize() From 4c794be41d1833178825306da28b6ce01d919da7 Mon Sep 17 00:00:00 2001 From: Bruce Mitchener Date: Thu, 14 Sep 2017 10:28:18 +0700 Subject: [PATCH 338/921] Improve warning configuration for clang. Clang 4.0 introduced -Wdouble-promotion, so check for and disable that on clang as we do on gcc. The old style casts warning is already disabled globally in this file for clang, so it doesn't need to be re-disabled within this scope. --- imgui_draw.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index b4b7f5648..7f7985b92 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -42,6 +42,9 @@ #if __has_warning("-Wreserved-id-macro") #pragma clang diagnostic ignored "-Wreserved-id-macro" // warning : macro name is a reserved identifier // #endif +#if __has_warning("-Wdouble-promotion") +#pragma clang diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function +#endif #elif defined(__GNUC__) #pragma GCC diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used #pragma GCC diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function @@ -69,7 +72,6 @@ namespace IMGUI_STB_NAMESPACE #ifdef __clang__ #pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wold-style-cast" // warning : use of old-style cast // yes, they are more terse. #pragma clang diagnostic ignored "-Wunused-function" #pragma clang diagnostic ignored "-Wmissing-prototypes" #endif From 2fcdeb7f1263d699b68b543f63b32f24c8dc7b73 Mon Sep 17 00:00:00 2001 From: Bruce Mitchener Date: Thu, 14 Sep 2017 10:35:30 +0700 Subject: [PATCH 339/921] Remove commas after last item in enumeration. This brings these enums to match the rest of the code and fixes 2 warnings under clang about using C++11 extensions. --- imgui_internal.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/imgui_internal.h b/imgui_internal.h index 2d8b8457a..fcced1ac9 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -220,7 +220,7 @@ enum ImGuiDataType { ImGuiDataType_Int, ImGuiDataType_Float, - ImGuiDataType_Float2, + ImGuiDataType_Float2 }; enum ImGuiDir @@ -229,7 +229,7 @@ enum ImGuiDir ImGuiDir_Left = 0, ImGuiDir_Right = 1, ImGuiDir_Up = 2, - ImGuiDir_Down = 3, + ImGuiDir_Down = 3 }; enum ImGuiCorner From 83645aa5938e9fa518cf26a1d2a027f84bf4b1a3 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 15 Sep 2017 01:28:30 +0200 Subject: [PATCH 340/921] More consistently uses "Dear ImGui" --- README.md | 54 +++++++++++++++++++++++++++--------------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index 44233311c..5aae9d67d 100644 --- a/README.md +++ b/README.md @@ -11,13 +11,13 @@ Monthly donations via Patreon: One-off donations via PayPal:
[![PayPal](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5Q73FPZ9C526U) -dear imgui (AKA ImGui), is a bloat-free graphical user interface library for C++. It outputs optimized vertex buffers that you can render anytime in your 3D-pipeline enabled application. It is fast, portable, renderer agnostic and self-contained (no external dependencies). +Dear ImGui, is a bloat-free graphical user interface library for C++. It outputs optimized vertex buffers that you can render anytime in your 3D-pipeline enabled application. It is fast, portable, renderer agnostic and self-contained (no external dependencies). -ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/ debug tools (as opposed to UI for the average end-user). It favors simplicity and productivity toward this goal, and thus lacks certain features normally found in more high-level libraries. +Dear ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/ debug tools (as opposed to UI for the average end-user). It favors simplicity and productivity toward this goal, and thus lacks certain features normally found in more high-level libraries. -ImGui is particularly suited to integration in realtime 3D applications, fullscreen applications, embedded applications, games, or any applications on consoles platforms where operating system features are non-standard. +Dear ImGui is particularly suited to integration in realtime 3D applications, fullscreen applications, embedded applications, games, or any applications on consoles platforms where operating system features are non-standard. -ImGui is self-contained within a few files that you can easily copy and compile into your application/engine: +Dear ImGui is self-contained within a few files that you can easily copy and compile into your application/engine: - imgui.cpp - imgui.h @@ -31,26 +31,26 @@ ImGui is self-contained within a few files that you can easily copy and compile No specific build process is required. You can add the .cpp files to your project or #include them from an existing file. -Your code passes mouse/keyboard inputs and settings to ImGui (see example applications for more details). After ImGui is setup, you can use it like in this example: +Your code passes mouse/keyboard inputs and settings to Dear ImGui (see example applications for more details). After Dear ImGui is setup, you can use it like in this example: -![screenshot of sample code alongside its output with ImGui](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/code_sample_01.png) +![screenshot of sample code alongside its output with dear imgui](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/code_sample_01.png) -ImGui outputs vertex buffers and simple command-lists that you can render in your application. The number of draw calls and state changes is typically very small. Because it doesn't know or touch graphics state directly, you can call ImGui commands anywhere in your code (e.g. in the middle of a running algorithm, or in the middle of your own rendering process). Refer to the sample applications in the examples/ folder for instructions on how to integrate ImGui with your existing codebase. +Dear ImGui outputs vertex buffers and simple command-lists that you can render in your application. The number of draw calls and state changes is typically very small. Because it doesn't know or touch graphics state directly, you can call ImGui commands anywhere in your code (e.g. in the middle of a running algorithm, or in the middle of your own rendering process). Refer to the sample applications in the examples/ folder for instructions on how to integrate dear imgui with your existing codebase. _A common misunderstanding is to think that immediate mode gui == immediate mode rendering, which usually implies hammering your driver/GPU with a bunch of inefficient draw calls and state changes, as the gui functions are called by the user. This is NOT what Dear ImGui does. Dear ImGui outputs vertex buffers and a small list of draw calls batches. It never touches your GPU directly. The draw call batches are decently optimal and you can render them later, in your app or even remotely._ -ImGui allows you create elaborate tools as well as very short-lived ones. On the extreme side of short-liveness: using the Edit&Continue feature of modern compilers you can add a few widgets to tweaks variables while your application is running, and remove the code a minute later! ImGui is not just for tweaking values. You can use it to trace a running algorithm by just emitting text commands. You can use it along with your own reflection data to browse your dataset live. You can use it to expose the internals of a subsystem in your engine, to create a logger, an inspection tool, a profiler, a debugger, an entire game making editor/framework, etc. +Dear ImGui allows you create elaborate tools as well as very short-lived ones. On the extreme side of short-liveness: using the Edit&Continue feature of modern compilers you can add a few widgets to tweaks variables while your application is running, and remove the code a minute later! Dear ImGui is not just for tweaking values. You can use it to trace a running algorithm by just emitting text commands. You can use it along with your own reflection data to browse your dataset live. You can use it to expose the internals of a subsystem in your engine, to create a logger, an inspection tool, a profiler, a debugger, an entire game making editor/framework, etc. Binaries/Demo ------------- -You should be able to build the examples from sources (tested on Windows/Mac/Linux). If you don't, let me know! If you want to have a quick look at some ImGui features, you can download Windows binaries of the demo app here: -- [imgui-demo-binaries-20170723.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20170723.zip) (Windows binaries, ImGui 1.51+ 2017/07/23, 5 executables, 808 KB) +You should be able to build the examples from sources (tested on Windows/Mac/Linux). If you don't, let me know! If you want to have a quick look at some Dear ImGui features, you can download Windows binaries of the demo app here: +- [imgui-demo-binaries-20170723.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20170723.zip) (Windows binaries, Dear ImGui 1.51+ 2017/07/23, 5 executables, 808 KB) Bindings -------- -_NB: those third-party bindings may be more or less maintained, more or less close to the spirit of original API and therefore I cannot give much guarantee about them. People who create language bindings sometimes haven't used the C++ API themselves (for the good reason that they aren't C++ users). ImGui was designed with C++ in mind and some of the subtleties may be lost in translation with other languages. If your language supports it, I would suggest replicating the function overloading and default parameters used in the original, else the API may be harder to use. In doubt, please check the original C++ version first!_ +_NB: those third-party bindings may be more or less maintained, more or less close to the spirit of original API and therefore I cannot give much guarantee about them. People who create language bindings sometimes haven't used the C++ API themselves (for the good reason that they aren't C++ users). Dear ImGui was designed with C++ in mind and some of the subtleties may be lost in translation with other languages. If your language supports it, I would suggest replicating the function overloading and default parameters used in the original, else the API may be harder to use. In doubt, please check the original C++ version first!_ _Integrating Dear ImGui within your custom engine is a matter of wiring mouse/keyboard inputs and providing a render function that can bind a texture and render simple textured triangles. The examples/ folder is populated with applications doing just that. If you are an experienced programmer it should take you less than an hour to integrate Dear ImGui in your custom engine, but make sure to spend time reading the FAQ, the comments and other documentation!_ @@ -104,7 +104,7 @@ See the [Screenshots Thread](https://github.com/ocornut/imgui/issues/123) for so ![screenshot 6](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v143/skinning_sample_02.png) ![screenshot 7](https://cloud.githubusercontent.com/assets/8225057/7903336/96f0fb7c-07d0-11e5-95d6-41c6a1595e5a.png) -ImGui can load TTF/OTF fonts. UTF-8 is supported for text display and input. Here using Arial Unicode font to display Japanese. Initialize custom font with: +Dear ImGui can load TTF/OTF fonts. UTF-8 is supported for text display and input. Here using Arial Unicode font to display Japanese. Initialize custom font with: ``` ImGuiIO& io = ImGui::GetIO(); io.Fonts->AddFontFromFileTTF("ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); @@ -142,32 +142,32 @@ Frequently Asked Question (FAQ) The library started its life and is best known as "ImGui" only due to the fact that I didn't give it a proper name when I released it. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations. It seemed confusing and unfair to hog the name. To reduce the ambiguity without affecting existing codebases, I have decided on an alternate, longer name "dear imgui" that people can use to refer to this specific library in ambiguous situations.
What is ImTextureID and how do I display an image? -
I integrated ImGui in my engine and the text or lines are blurry.. -
I integrated ImGui in my engine and some elements are disappearing when I move windows around.. +
I integrated Dear ImGui in my engine and the text or lines are blurry.. +
I integrated Dear ImGui in my engine and some elements are disappearing when I move windows around..
How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on labels/IDs. -
How can I tell when ImGui wants my mouse/keyboard inputs VS when I can pass them to my application? +
How can I tell when Dear ImGui wants my mouse/keyboard inputs VS when I can pass them to my application?
How can I load a different font than the default?
How can I easily use icons in my application?
How can I load multiple fonts?
How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic? -
How can I preserve my ImGui context across reloading a DLL? (loss of the global/static variables) -
How can I use the drawing facilities without an ImGui window? (using ImDrawList API) +
How can I preserve my Dear ImGui context across reloading a DLL? (loss of the global/static variables) +
How can I use the drawing facilities without an Dear ImGui window? (using ImDrawList API) See the FAQ in imgui.cpp for answers. -How do you use ImGui on a platform that may not have a mouse or keyboard? +How do you use Dear ImGui on a platform that may not have a mouse or keyboard? -I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/symless/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate. +I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/symless/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. Dear ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate. -Can you create elaborate/serious tools with ImGui? +Can you create elaborate/serious tools with Dear ImGui? Yes. I have written data browsers, debuggers, profilers and all sort of non-trivial tools with the library. In my experience the simplicity of the API is very empowering. Your UI runs close to your live data. Make the tools always-on and everybody in the team will be inclined to create new tools (as opposed to more "offline" UI toolkits where only a fraction of your team effectively creates tools). -ImGui is very programmer centric and the immediate-mode GUI paradigm might requires you to readjust some habits before you can realize its full potential. Many programmers have unfortunately been taught by their environment to make unnecessarily complicated things. ImGui is about making things that are simple, efficient and powerful. +Dear ImGui is very programmer centric and the immediate-mode GUI paradigm might requires you to readjust some habits before you can realize its full potential. Many programmers have unfortunately been taught by their environment to make unnecessarily complicated things. Dear ImGui is about making things that are simple, efficient and powerful. -Is ImGui fast? +Is Dear ImGui fast? -Probably fast enough for most uses. Down to the foundation of its visual design, ImGui is engineered to be fairly performant both in term of CPU and GPU usage. Running elaborate code and creating elaborate UI will of course have a cost but ImGui aims to minimize it. +Probably fast enough for most uses. Down to the foundation of its visual design, Dear ImGui is engineered to be fairly performant both in term of CPU and GPU usage. Running elaborate code and creating elaborate UI will of course have a cost but Dear ImGui aims to minimize it. Mileage may vary but the following screenshot can give you a rough idea of the cost of running and rendering UI code (In the case of a trivial demo application like this one, your driver/os setup are likely to be the bottleneck. Testing performance as part of a real application is recommended). @@ -175,11 +175,11 @@ Mileage may vary but the following screenshot can give you a rough idea of the c This is showing framerate for the full application loop on my 2011 iMac running Windows 7, OpenGL, AMD Radeon HD 6700M with an optimized executable. In contrast, librairies featuring higher-quality rendering and layouting techniques may have a higher resources footprint. -If you intend to display large lists of items (say, 1000+) it can be beneficial for your code to perform clipping manually - one way is using helpers such as ImGuiListClipper - in order to avoid submitting them to ImGui in the first place. Even though ImGui will discard your clipped items it still needs to calculate their size and that overhead will add up if you have thousands of items. If you can handle clipping and height positionning yourself then browsing a list with millions of items isn't a problem. +If you intend to display large lists of items (say, 1000+) it can be beneficial for your code to perform clipping manually - one way is using helpers such as ImGuiListClipper - in order to avoid submitting them to Dear ImGui in the first place. Even though ImGui will discard your clipped items it still needs to calculate their size and that overhead will add up if you have thousands of items. If you can handle clipping and height positionning yourself then browsing a list with millions of items isn't a problem. -Can you reskin the look of ImGui? +Can you reskin the look of Dear ImGui? -You can alter the look of the interface to some degree: changing colors, sizes, padding, rounding, fonts. However, as ImGui is designed and optimised to create debug tools, the amount of skinning you can apply is limited. There is only so much you can stray away from the default look and feel of the interface. +You can alter the look of the interface to some degree: changing colors, sizes, padding, rounding, fonts. However, as Dear ImGui is designed and optimised to create debug tools, the amount of skinning you can apply is limited. There is only so much you can stray away from the default look and feel of the interface. This is [LumixEngine](https://github.com/nem0/LumixEngine) with a minor skinning hack + a docking/tabs extension (both of which you can find in the Issues section and will eventually be merged). @@ -187,7 +187,7 @@ This is [LumixEngine](https://github.com/nem0/LumixEngine) with a minor skinning Why using C++ (as opposed to C)? -ImGui takes advantage of a few C++ languages features for convenience but nothing anywhere Boost-insanity/quagmire. ImGui doesn't use any C++ header file. Language-wise, function overloading and default parameters are used to make the API easier to use and code more terse. Doing so I believe the API is sitting on a sweet spot and giving up on those features would make the API more cumbersome. Other features such as namespace, constructors and templates (in the case of the ImVector<> class) are also relied on as a convenience. +Dear ImGui takes advantage of a few C++ languages features for convenience but nothing anywhere Boost-insanity/quagmire. Dear ImGui doesn't use any C++ header file. Language-wise, function overloading and default parameters are used to make the API easier to use and code more terse. Doing so I believe the API is sitting on a sweet spot and giving up on those features would make the API more cumbersome. Other features such as namespace, constructors and templates (in the case of the ImVector<> class) are also relied on as a convenience. There is an unofficial but reasonably maintained [c-api for ImGui](https://github.com/Extrawurst/cimgui) by Stephan Dilly. I would suggest using your target language functionality to try replicating the function overloading and default parameters used in C++ else the API may be harder to use. It was really designed with C++ in mind and may not make the same amount of sense with another language. Also see [Links](https://github.com/ocornut/imgui/wiki/Links) for third-party bindings to other languages. From 052999a6ab0ccc7e26981b0912140e6cc47d1374 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 15 Sep 2017 01:31:41 +0200 Subject: [PATCH 341/921] More consistently uses "Dear ImGui" --- imgui.cpp | 50 +++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 42a3989fd..f98cd6801 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2,7 +2,7 @@ // (main code and documentation) // See ImGui::ShowTestWindow() in imgui_demo.cpp for demo code. -// Newcomers, read 'Programmer guide' below for notes on how to setup ImGui in your codebase. +// Newcomers, read 'Programmer guide' below for notes on how to setup Dear ImGui in your codebase. // Get latest version at https://github.com/ocornut/imgui // Releases change-log at https://github.com/ocornut/imgui/releases // Gallery (please post your screenshots/video there!): https://github.com/ocornut/imgui/issues/1269 @@ -17,22 +17,22 @@ - END-USER GUIDE - PROGRAMMER GUIDE (read me!) - Read first - - How to update to a newer version of ImGui - - Getting started with integrating ImGui in your code/engine + - How to update to a newer version of Dear ImGui + - Getting started with integrating Dear ImGui in your code/engine - API BREAKING CHANGES (read me when you update!) - ISSUES & TODO LIST - FREQUENTLY ASKED QUESTIONS (FAQ), TIPS - How can I help? - What is ImTextureID and how do I display an image? - - I integrated ImGui in my engine and the text or lines are blurry.. - - I integrated ImGui in my engine and some elements are clipping or disappearing when I move windows around.. + - I integrated Dear ImGui in my engine and the text or lines are blurry.. + - I integrated Dear ImGui in my engine and some elements are clipping or disappearing when I move windows around.. - How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on labels/IDs. - - How can I tell when ImGui wants my mouse/keyboard inputs VS when I can pass them to my application? + - How can I tell when Dear ImGui wants my mouse/keyboard inputs VS when I can pass them to my application? - How can I load a different font than the default? - How can I easily use icons in my application? - How can I load multiple fonts? - How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic? - - How can I preserve my ImGui context across reloading a DLL? (loss of the global/static variables) + - How can I preserve my Dear ImGui context across reloading a DLL? (loss of the global/static variables) - How can I use the drawing facilities without an ImGui window? (using ImDrawList API) - ISSUES & TODO-LIST - CODE @@ -89,7 +89,7 @@ - Call and read ImGui::ShowTestWindow() for demo code demonstrating most features. - You can learn about immediate-mode gui principles at http://www.johno.se/book/imgui.html or watch http://mollyrocket.com/861 - HOW TO UPDATE TO A NEWER VERSION OF IMGUI + HOW TO UPDATE TO A NEWER VERSION OF DEAR IMGUI - Overwrite all the sources files except for imconfig.h (if you have made modification to your copy of imconfig.h) - Read the "API BREAKING CHANGES" section (below). This is where we list occasional API breaking changes. @@ -98,26 +98,26 @@ Please report any issue to the GitHub page! - Try to keep your copy of dear imgui reasonably up to date. - GETTING STARTED WITH INTEGRATING IMGUI IN YOUR CODE/ENGINE + GETTING STARTED WITH INTEGRATING DEAR IMGUI IN YOUR CODE/ENGINE - - Add the ImGui source files to your projects, using your preferred build system. It is recommended you build the .cpp files as part of your project and not as a library. + - Add the Dear ImGui source files to your projects, using your preferred build system. It is recommended you build the .cpp files as part of your project and not as a library. - You can later customize the imconfig.h file to tweak some compilation time behavior, such as integrating imgui types with your own maths types. - See examples/ folder for standalone sample applications. To understand the integration process, you can read examples/opengl2_example/ because it is short, then switch to the one more appropriate to your use case. - You may be able to grab and copy a ready made imgui_impl_*** file from the examples/. - - When using ImGui, your programming IDE if your friend: follow the declaration of variables, functions and types to find comments about them. + - When using Dear ImGui, your programming IDE if your friend: follow the declaration of variables, functions and types to find comments about them. - Init: retrieve the ImGuiIO structure with ImGui::GetIO() and fill the fields marked 'Settings': at minimum you need to set io.DisplaySize (application resolution). Later on you will fill your keyboard mapping, clipboard handlers, and other advanced features but for a basic integration you don't need to worry about it all. - Init: call io.Fonts->GetTexDataAsRGBA32(...), it will build the font atlas texture, then load the texture pixels into graphics memory. - Every frame: - In your main loop as early a possible, fill the IO fields marked 'Input' (e.g. mouse position, buttons, keyboard info, etc.) - - Call ImGui::NewFrame() to begin the imgui frame + - Call ImGui::NewFrame() to begin the frame - You can use any ImGui function you want between NewFrame() and Render() - Call ImGui::Render() as late as you can to end the frame and finalize render data. it will call your io.RenderDrawListFn handler. (if you don't need to render, you still need to call Render() and ignore the callback, or call EndFrame() instead. if you call neither some aspects of windows focusing/moving will appear broken.) - All rendering information are stored into command-lists until ImGui::Render() is called. - - ImGui never touches or knows about your GPU state. the only function that knows about GPU is the RenderDrawListFn handler that you provide. + - Dear ImGui never touches or knows about your GPU state. the only function that knows about GPU is the RenderDrawListFn handler that you provide. - Effectively it means you can create widgets at any time in your code, regardless of considerations of being in "update" vs "render" phases of your own application. - Refer to the examples applications in the examples/ folder for instruction on how to setup your code. - A minimal application skeleton may be: @@ -338,33 +338,33 @@ ====================================== Q: How can I help? - A: - If you are experienced enough with ImGui and with C/C++, look at the todo list and see how you want/can help! + A: - If you are experienced enough with Dear ImGui and with C/C++, look at the todo list and see how you want/can help! - Become a Patron/donate! Convince your company to become a Patron or provide serious funding for development time! See http://www.patreon.com/imgui Q: What is ImTextureID and how do I display an image? A: ImTextureID is a void* used to pass renderer-agnostic texture references around until it hits your render function. - ImGui knows nothing about what those bits represent, it just passes them around. It is up to you to decide what you want the void* to carry! + Dear ImGui knows nothing about what those bits represent, it just passes them around. It is up to you to decide what you want the void* to carry! It could be an identifier to your OpenGL texture (cast GLuint to void*), a pointer to your custom engine material (cast MyMaterial* to void*), etc. At the end of the chain, your renderer takes this void* to cast it back into whatever it needs to select a current texture to render. Refer to examples applications, where each renderer (in a imgui_impl_xxxx.cpp file) is treating ImTextureID as a different thing. (c++ tip: OpenGL uses integers to identify textures. You can safely store an integer into a void*, just cast it to void*, don't take it's address!) To display a custom image/texture within an ImGui window, you may use ImGui::Image(), ImGui::ImageButton(), ImDrawList::AddImage() functions. - ImGui will generate the geometry and draw calls using the ImTextureID that you passed and which your renderer can use. + Dear ImGui will generate the geometry and draw calls using the ImTextureID that you passed and which your renderer can use. It is your responsibility to get textures uploaded to your GPU. - Q: I integrated ImGui in my engine and the text or lines are blurry.. + Q: I integrated Dear ImGui in my engine and the text or lines are blurry.. A: In your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f). Also make sure your orthographic projection matrix and io.DisplaySize matches your actual framebuffer dimension. - Q: I integrated ImGui in my engine and some elements are clipping or disappearing when I move windows around.. + Q: I integrated Dear ImGui in my engine and some elements are clipping or disappearing when I move windows around.. A: Most likely you are mishandling the clipping rectangles in your render function. Rectangles provided by ImGui are defined as (x1=left,y1=top,x2=right,y2=bottom) and NOT as (x1,y1,width,height). Q: Can I have multiple widgets with the same label? Can I have widget without a label? - A: Yes. A primer on the use of labels/IDs in ImGui.. + A: Yes. A primer on the use of labels/IDs in Dear ImGui.. - Elements that are not clickable, such as Text() items don't need an ID. - - Interactive widgets require state to be carried over multiple frames (most typically ImGui often needs to remember what is the "active" widget). + - Interactive widgets require state to be carried over multiple frames (most typically Dear ImGui often needs to remember what is the "active" widget). to do so they need a unique ID. unique ID are typically derived from a string label, an integer index or a pointer. Button("OK"); // Label = "OK", ID = hash of "OK" @@ -452,15 +452,15 @@ 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 can I tell when ImGui wants my mouse/keyboard inputs VS when I can pass them to my application? + Q: How can I tell when Dear ImGui wants my mouse/keyboard inputs VS when I can pass them to my application? A: You can read the 'io.WantCaptureMouse'/'io.WantCaptureKeyboard'/'ioWantTextInput' flags from the ImGuiIO structure. - When 'io.WantCaptureMouse' or 'io.WantCaptureKeyboard' flags are set you may want to discard/hide the inputs from the rest of your application. - When 'io.WantTextInput' is set to may want to notify your OS to popup an on-screen keyboard, if available (e.g. on a mobile phone, or console without a keyboard). Preferably read the flags after calling ImGui::NewFrame() to avoid them lagging by one frame. But reading those flags before calling NewFrame() is also generally ok, - as the bool toggles fairly rarely and you don't generally expect to interact with either ImGui or your application during the same frame when that transition occurs. - ImGui is tracking dragging and widget activity that may occur outside the boundary of a window, so 'io.WantCaptureMouse' is more accurate and correct than checking if a window is hovered. + as the bool toggles fairly rarely and you don't generally expect to interact with either Dear ImGui or your application during the same frame when that transition occurs. + Dear ImGui is tracking dragging and widget activity that may occur outside the boundary of a window, so 'io.WantCaptureMouse' is more accurate and correct than checking if a window is hovered. (Advanced note: text input releases focus on Return 'KeyDown', so the following Return 'KeyUp' event that your application receive will typically have 'io.WantCaptureKeyboard=false'. - Depending on your application logic it may or not be inconvenient. You might want to track which key-downs were for ImGui (e.g. with an array of bool) and filter out the corresponding key-ups.) + Depending on your application logic it may or not be inconvenient. You might want to track which key-downs were for Dear ImGui (e.g. with an array of bool) and filter out the corresponding key-ups.) Q: How can I load a different font than the default? (default is an embedded version of ProggyClean.ttf, rendered at size 13) A: Use the font atlas to load the TTF/OTF file you want: @@ -523,7 +523,7 @@ Text input: it is up to your application to pass the right character code to io.AddInputCharacter(). The applications in examples/ are doing that. For languages using IME, on Windows you can copy the Hwnd of your application to io.ImeWindowHandle. The default implementation of io.ImeSetInputScreenPosFn() on Windows will set your IME position correctly. - Q: How can I preserve my ImGui context across reloading a DLL? (loss of the global/static variables) + Q: How can I preserve my Dear ImGui context across reloading a DLL? (loss of the global/static variables) A: Create your own context 'ctx = CreateContext()' + 'SetCurrentContext(ctx)' and your own font atlas 'ctx->GetIO().Fonts = new ImFontAtlas()' so you don't rely on the default globals. Q: How can I use the drawing facilities without an ImGui window? (using ImDrawList API) From c4c042bcec31821f65f44589d2743353e76ad4db Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 15 Sep 2017 01:32:29 +0200 Subject: [PATCH 342/921] Typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5aae9d67d..31b101567 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ Monthly donations via Patreon: One-off donations via PayPal:
[![PayPal](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5Q73FPZ9C526U) -Dear ImGui, is a bloat-free graphical user interface library for C++. It outputs optimized vertex buffers that you can render anytime in your 3D-pipeline enabled application. It is fast, portable, renderer agnostic and self-contained (no external dependencies). +Dear ImGui is a bloat-free graphical user interface library for C++. It outputs optimized vertex buffers that you can render anytime in your 3D-pipeline enabled application. It is fast, portable, renderer agnostic and self-contained (no external dependencies). Dear ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/ debug tools (as opposed to UI for the average end-user). It favors simplicity and productivity toward this goal, and thus lacks certain features normally found in more high-level libraries. From 7c9e38f60acf06eed69d3552c01742bd0a5f9124 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 14 Aug 2017 15:14:46 +0800 Subject: [PATCH 343/921] Style: Moving code in a function to make incoming diff easier to parse. --- imgui.cpp | 94 ++++++++++++++++++++++++++++++------------------------- imgui.h | 3 ++ 2 files changed, 54 insertions(+), 43 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index f98cd6801..8480785bc 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -696,49 +696,57 @@ ImGuiStyle::ImGuiStyle() AntiAliasedShapes = true; // Enable anti-aliasing on filled shapes (rounded rectangles, circles, etc.) CurveTessellationTol = 1.25f; // Tessellation tolerance. Decrease for highly tessellated curves (higher quality, more polygons), increase to reduce quality. - Colors[ImGuiCol_Text] = ImVec4(0.90f, 0.90f, 0.90f, 1.00f); - Colors[ImGuiCol_TextDisabled] = ImVec4(0.60f, 0.60f, 0.60f, 1.00f); - Colors[ImGuiCol_WindowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.70f); - Colors[ImGuiCol_ChildWindowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); - Colors[ImGuiCol_PopupBg] = ImVec4(0.05f, 0.05f, 0.10f, 0.90f); - Colors[ImGuiCol_Border] = ImVec4(0.70f, 0.70f, 0.70f, 0.40f); - Colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); - Colors[ImGuiCol_FrameBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.30f); // Background of checkbox, radio button, plot, slider, text input - Colors[ImGuiCol_FrameBgHovered] = ImVec4(0.90f, 0.80f, 0.80f, 0.40f); - Colors[ImGuiCol_FrameBgActive] = ImVec4(0.90f, 0.65f, 0.65f, 0.45f); - Colors[ImGuiCol_TitleBg] = ImVec4(0.27f, 0.27f, 0.54f, 0.83f); - Colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.40f, 0.40f, 0.80f, 0.20f); - Colors[ImGuiCol_TitleBgActive] = ImVec4(0.32f, 0.32f, 0.63f, 0.87f); - Colors[ImGuiCol_MenuBarBg] = ImVec4(0.40f, 0.40f, 0.55f, 0.80f); - Colors[ImGuiCol_ScrollbarBg] = ImVec4(0.20f, 0.25f, 0.30f, 0.60f); - Colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.40f, 0.40f, 0.80f, 0.30f); - Colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.40f, 0.40f, 0.80f, 0.40f); - Colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.80f, 0.50f, 0.50f, 0.40f); - Colors[ImGuiCol_ComboBg] = ImVec4(0.20f, 0.20f, 0.20f, 0.99f); - Colors[ImGuiCol_CheckMark] = ImVec4(0.90f, 0.90f, 0.90f, 0.50f); - Colors[ImGuiCol_SliderGrab] = ImVec4(1.00f, 1.00f, 1.00f, 0.30f); - Colors[ImGuiCol_SliderGrabActive] = ImVec4(0.80f, 0.50f, 0.50f, 1.00f); - Colors[ImGuiCol_Button] = ImVec4(0.67f, 0.40f, 0.40f, 0.60f); - Colors[ImGuiCol_ButtonHovered] = ImVec4(0.67f, 0.40f, 0.40f, 1.00f); - Colors[ImGuiCol_ButtonActive] = ImVec4(0.80f, 0.50f, 0.50f, 1.00f); - Colors[ImGuiCol_Header] = ImVec4(0.40f, 0.40f, 0.90f, 0.45f); - Colors[ImGuiCol_HeaderHovered] = ImVec4(0.45f, 0.45f, 0.90f, 0.80f); - Colors[ImGuiCol_HeaderActive] = ImVec4(0.53f, 0.53f, 0.87f, 0.80f); - Colors[ImGuiCol_Separator] = ImVec4(0.50f, 0.50f, 0.50f, 1.00f); - Colors[ImGuiCol_SeparatorHovered] = ImVec4(0.60f, 0.60f, 0.70f, 1.00f); - Colors[ImGuiCol_SeparatorActive] = ImVec4(0.70f, 0.70f, 0.90f, 1.00f); - Colors[ImGuiCol_ResizeGrip] = ImVec4(1.00f, 1.00f, 1.00f, 0.30f); - Colors[ImGuiCol_ResizeGripHovered] = ImVec4(1.00f, 1.00f, 1.00f, 0.60f); - Colors[ImGuiCol_ResizeGripActive] = ImVec4(1.00f, 1.00f, 1.00f, 0.90f); - Colors[ImGuiCol_CloseButton] = ImVec4(0.50f, 0.50f, 0.90f, 0.50f); - Colors[ImGuiCol_CloseButtonHovered] = ImVec4(0.70f, 0.70f, 0.90f, 0.60f); - Colors[ImGuiCol_CloseButtonActive] = ImVec4(0.70f, 0.70f, 0.70f, 1.00f); - Colors[ImGuiCol_PlotLines] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f); - Colors[ImGuiCol_PlotLinesHovered] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); - Colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); - Colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.60f, 0.00f, 1.00f); - Colors[ImGuiCol_TextSelectedBg] = ImVec4(0.00f, 0.00f, 1.00f, 0.35f); - Colors[ImGuiCol_ModalWindowDarkening] = ImVec4(0.20f, 0.20f, 0.20f, 0.35f); + ImGui::StyleColorsClassic(this); +} + +void ImGui::StyleColorsClassic(ImGuiStyle* dst) +{ + ImGuiStyle* style = dst ? dst : &ImGui::GetStyle(); + ImVec4* colors = style->Colors; + + colors[ImGuiCol_Text] = ImVec4(0.90f, 0.90f, 0.90f, 1.00f); + colors[ImGuiCol_TextDisabled] = ImVec4(0.60f, 0.60f, 0.60f, 1.00f); + colors[ImGuiCol_WindowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.70f); + colors[ImGuiCol_ChildWindowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); + colors[ImGuiCol_PopupBg] = ImVec4(0.05f, 0.05f, 0.10f, 0.90f); + colors[ImGuiCol_Border] = ImVec4(0.70f, 0.70f, 0.70f, 0.40f); + colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); + colors[ImGuiCol_FrameBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.30f); // Background of checkbox, radio button, plot, slider, text input + colors[ImGuiCol_FrameBgHovered] = ImVec4(0.90f, 0.80f, 0.80f, 0.40f); + colors[ImGuiCol_FrameBgActive] = ImVec4(0.90f, 0.65f, 0.65f, 0.45f); + colors[ImGuiCol_TitleBg] = ImVec4(0.27f, 0.27f, 0.54f, 0.83f); + colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.40f, 0.40f, 0.80f, 0.20f); + colors[ImGuiCol_TitleBgActive] = ImVec4(0.32f, 0.32f, 0.63f, 0.87f); + colors[ImGuiCol_MenuBarBg] = ImVec4(0.40f, 0.40f, 0.55f, 0.80f); + colors[ImGuiCol_ScrollbarBg] = ImVec4(0.20f, 0.25f, 0.30f, 0.60f); + colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.40f, 0.40f, 0.80f, 0.30f); + colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.40f, 0.40f, 0.80f, 0.40f); + colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.80f, 0.50f, 0.50f, 0.40f); + colors[ImGuiCol_ComboBg] = ImVec4(0.20f, 0.20f, 0.20f, 0.99f); + colors[ImGuiCol_CheckMark] = ImVec4(0.90f, 0.90f, 0.90f, 0.50f); + colors[ImGuiCol_SliderGrab] = ImVec4(1.00f, 1.00f, 1.00f, 0.30f); + colors[ImGuiCol_SliderGrabActive] = ImVec4(0.80f, 0.50f, 0.50f, 1.00f); + colors[ImGuiCol_Button] = ImVec4(0.67f, 0.40f, 0.40f, 0.60f); + colors[ImGuiCol_ButtonHovered] = ImVec4(0.67f, 0.40f, 0.40f, 1.00f); + colors[ImGuiCol_ButtonActive] = ImVec4(0.80f, 0.50f, 0.50f, 1.00f); + colors[ImGuiCol_Header] = ImVec4(0.40f, 0.40f, 0.90f, 0.45f); + colors[ImGuiCol_HeaderHovered] = ImVec4(0.45f, 0.45f, 0.90f, 0.80f); + colors[ImGuiCol_HeaderActive] = ImVec4(0.53f, 0.53f, 0.87f, 0.80f); + colors[ImGuiCol_Separator] = ImVec4(0.50f, 0.50f, 0.50f, 1.00f); + colors[ImGuiCol_SeparatorHovered] = ImVec4(0.60f, 0.60f, 0.70f, 1.00f); + colors[ImGuiCol_SeparatorActive] = ImVec4(0.70f, 0.70f, 0.90f, 1.00f); + colors[ImGuiCol_ResizeGrip] = ImVec4(1.00f, 1.00f, 1.00f, 0.30f); + colors[ImGuiCol_ResizeGripHovered] = ImVec4(1.00f, 1.00f, 1.00f, 0.60f); + colors[ImGuiCol_ResizeGripActive] = ImVec4(1.00f, 1.00f, 1.00f, 0.90f); + colors[ImGuiCol_CloseButton] = ImVec4(0.50f, 0.50f, 0.90f, 0.50f); + colors[ImGuiCol_CloseButtonHovered] = ImVec4(0.70f, 0.70f, 0.90f, 0.60f); + colors[ImGuiCol_CloseButtonActive] = ImVec4(0.70f, 0.70f, 0.70f, 1.00f); + colors[ImGuiCol_PlotLines] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f); + colors[ImGuiCol_PlotLinesHovered] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); + colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); + colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.60f, 0.00f, 1.00f); + colors[ImGuiCol_TextSelectedBg] = ImVec4(0.00f, 0.00f, 1.00f, 0.35f); + colors[ImGuiCol_ModalWindowDarkening] = ImVec4(0.20f, 0.20f, 0.20f, 0.35f); } ImGuiIO::ImGuiIO() diff --git a/imgui.h b/imgui.h index 0cf364955..d7eefa7a0 100644 --- a/imgui.h +++ b/imgui.h @@ -412,6 +412,9 @@ namespace ImGui IMGUI_API void PushClipRect(const ImVec2& clip_rect_min, const ImVec2& clip_rect_max, bool intersect_with_current_clip_rect); IMGUI_API void PopClipRect(); + // Styles + IMGUI_API void StyleColorsClassic(ImGuiStyle* dst = NULL); + // Utilities IMGUI_API bool IsItemHovered(); // is the last item hovered by mouse (and usable)? IMGUI_API bool IsItemRectHovered(); // is the last item hovered by mouse? even if another item is active or window is blocked by popup while we are hovering this From 9693fd5351be5f79f114c1e7d659d2e07dcad9fd Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 15 Aug 2017 19:19:00 +0800 Subject: [PATCH 344/921] PushStyleVar/PopStyleVar: internal tweaks --- imgui.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 8480785bc..f35c0522c 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4822,7 +4822,7 @@ struct ImGuiStyleVarInfo { ImGuiDataType Type; ImU32 Offset; - void* GetVarPtr() const { return (void*)((unsigned char*)&GImGui->Style + Offset); } + void* GetVarPtr(ImGuiStyle* style) const { return (void*)((unsigned char*)style + Offset); } }; static const ImGuiStyleVarInfo GStyleVarInfo[ImGuiStyleVar_Count_] = @@ -4852,8 +4852,9 @@ void ImGui::PushStyleVar(ImGuiStyleVar idx, float val) const ImGuiStyleVarInfo* var_info = GetStyleVarInfo(idx); if (var_info->Type == ImGuiDataType_Float) { - float* pvar = (float*)var_info->GetVarPtr(); - GImGui->StyleModifiers.push_back(ImGuiStyleMod(idx, *pvar)); + ImGuiContext& g = *GImGui; + float* pvar = (float*)var_info->GetVarPtr(&g.Style); + g.StyleModifiers.push_back(ImGuiStyleMod(idx, *pvar)); *pvar = val; return; } @@ -4865,8 +4866,9 @@ void ImGui::PushStyleVar(ImGuiStyleVar idx, const ImVec2& val) const ImGuiStyleVarInfo* var_info = GetStyleVarInfo(idx); if (var_info->Type == ImGuiDataType_Float2) { - ImVec2* pvar = (ImVec2*)var_info->GetVarPtr(); - GImGui->StyleModifiers.push_back(ImGuiStyleMod(idx, *pvar)); + ImGuiContext& g = *GImGui; + ImVec2* pvar = (ImVec2*)var_info->GetVarPtr(&g.Style); + g.StyleModifiers.push_back(ImGuiStyleMod(idx, *pvar)); *pvar = val; return; } @@ -4880,9 +4882,9 @@ void ImGui::PopStyleVar(int count) { ImGuiStyleMod& backup = g.StyleModifiers.back(); const ImGuiStyleVarInfo* info = GetStyleVarInfo(backup.VarIdx); - if (info->Type == ImGuiDataType_Float) (*(float*)info->GetVarPtr()) = backup.BackupFloat[0]; - else if (info->Type == ImGuiDataType_Float2) (*(ImVec2*)info->GetVarPtr()) = ImVec2(backup.BackupFloat[0], backup.BackupFloat[1]); - else if (info->Type == ImGuiDataType_Int) (*(int*)info->GetVarPtr()) = backup.BackupInt[0]; + if (info->Type == ImGuiDataType_Float) (*(float*)info->GetVarPtr(&g.Style)) = backup.BackupFloat[0]; + else if (info->Type == ImGuiDataType_Float2) (*(ImVec2*)info->GetVarPtr(&g.Style)) = ImVec2(backup.BackupFloat[0], backup.BackupFloat[1]); + else if (info->Type == ImGuiDataType_Int) (*(int*)info->GetVarPtr(&g.Style)) = backup.BackupInt[0]; g.StyleModifiers.pop_back(); count--; } From b409d399c82e0269f2725d9a33a9a0ef5ae36235 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 15 Aug 2017 17:48:41 +0800 Subject: [PATCH 345/921] Demo: style editor output tweak so it is easier to modify the output code.. + TODO list update --- imgui_demo.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 45a845d6c..099e808a1 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1847,13 +1847,13 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) ImGui::LogToClipboard(); else ImGui::LogToTTY(); - ImGui::LogText("ImGuiStyle& style = ImGui::GetStyle();" IM_NEWLINE); + ImGui::LogText("ImVec4* colors = ImGui::GetStyle().Colors;" IM_NEWLINE); for (int i = 0; i < ImGuiCol_COUNT; i++) { const ImVec4& col = style.Colors[i]; const char* name = ImGui::GetStyleColorName(i); if (!output_only_modified || memcmp(&col, (ref ? &ref->Colors[i] : &default_style.Colors[i]), sizeof(ImVec4)) != 0) - ImGui::LogText("style.Colors[ImGuiCol_%s]%*s= ImVec4(%.2ff, %.2ff, %.2ff, %.2ff);" IM_NEWLINE, name, 22 - (int)strlen(name), "", col.x, col.y, col.z, col.w); + ImGui::LogText("colors[ImGuiCol_%s]%*s= ImVec4(%.2ff, %.2ff, %.2ff, %.2ff);" IM_NEWLINE, name, 23-(int)strlen(name), "", col.x, col.y, col.z, col.w); } ImGui::LogFinish(); } From f0f86213dbbe269e6bb0005e9d7e662320d097c6 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 15 Aug 2017 11:41:00 +0800 Subject: [PATCH 346/921] ImVector: added resize() variant with initialization value --- imgui.h | 5 +++-- imgui_draw.cpp | 12 +++--------- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/imgui.h b/imgui.h index d7eefa7a0..7809a323d 100644 --- a/imgui.h +++ b/imgui.h @@ -924,12 +924,13 @@ public: inline int _grow_capacity(int size) const { int new_capacity = Capacity ? (Capacity + Capacity/2) : 8; return new_capacity > size ? new_capacity : size; } inline void resize(int new_size) { if (new_size > Capacity) reserve(_grow_capacity(new_size)); Size = new_size; } + inline void resize(int new_size, const T& v){ if (new_size > Capacity) reserve(_grow_capacity(new_size)); if (new_size > Size) for (int n = Size; n < new_size; n++) Data[n] = v; Size = new_size; } inline void reserve(int new_capacity) { if (new_capacity <= Capacity) return; - T* new_data = (value_type*)ImGui::MemAlloc((size_t)new_capacity * sizeof(value_type)); + T* new_data = (value_type*)ImGui::MemAlloc((size_t)new_capacity * sizeof(T)); if (Data) - memcpy(new_data, Data, (size_t)Size * sizeof(value_type)); + memcpy(new_data, Data, (size_t)Size * sizeof(T)); ImGui::MemFree(Data); Data = new_data; Capacity = new_capacity; diff --git a/imgui_draw.cpp b/imgui_draw.cpp index b4b7f5648..84759c422 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1912,16 +1912,10 @@ void ImFont::SetFallbackChar(ImWchar c) void ImFont::GrowIndex(int new_size) { IM_ASSERT(IndexXAdvance.Size == IndexLookup.Size); - int old_size = IndexLookup.Size; - if (new_size <= old_size) + if (new_size <= IndexLookup.Size) return; - IndexXAdvance.resize(new_size); - IndexLookup.resize(new_size); - for (int i = old_size; i < new_size; i++) - { - IndexXAdvance[i] = -1.0f; - IndexLookup[i] = (unsigned short)-1; - } + IndexXAdvance.resize(new_size, -1.0f); + IndexLookup.resize(new_size, (unsigned short)-1); } void ImFont::AddRemapChar(ImWchar dst, ImWchar src, bool overwrite_dst) From 564c97b87ee08410ecf5b80bf6b31250f222342f Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 15 Aug 2017 11:41:36 +0800 Subject: [PATCH 347/921] Comments --- imgui_demo.cpp | 1 - imgui_draw.cpp | 7 +++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 099e808a1..24691abef 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -260,7 +260,6 @@ void ImGui::ShowTestWindow(bool* p_open) if (ImGui::CollapsingHeader("Widgets")) { - if (ImGui::TreeNode("Basic")) { static int clicked = 0; diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 84759c422..31abe84ae 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1281,7 +1281,7 @@ ImFont* ImFontAtlas::AddFontFromFileTTF(const char* filename, float size_pixels, return AddFontFromMemoryTTF(data, data_size, size_pixels, &font_cfg, glyph_ranges); } -// NBM Transfer ownership of 'ttf_data' to ImFontAtlas, unless font_cfg_template->FontDataOwnedByAtlas == false. Owned TTF buffer will be deleted after Build(). +// NB: Transfer ownership of 'ttf_data' to ImFontAtlas, unless font_cfg_template->FontDataOwnedByAtlas == false. Owned TTF buffer will be deleted after Build(). ImFont* ImFontAtlas::AddFontFromMemoryTTF(void* ttf_data, int ttf_size, float size_pixels, const ImFontConfig* font_cfg_template, const ImWchar* glyph_ranges) { ImFontConfig font_cfg = font_cfg_template ? *font_cfg_template : ImFontConfig(); @@ -1703,7 +1703,10 @@ const ImWchar* ImFontAtlas::GetGlyphRangesChinese() const ImWchar* ImFontAtlas::GetGlyphRangesJapanese() { // Store the 1946 ideograms code points as successive offsets from the initial unicode codepoint 0x4E00. Each offset has an implicit +1. - // This encoding helps us reduce the source code size. + // This encoding is designed to helps us reduce the source code size. + // FIXME: Source a list of the revised 2136 joyo kanji list from 2010 and rebuild this. + // The current list was sourced from http://theinstructionlimit.com/author/renaudbedardrenaudbedard/page/3 + // Note that you may use ImFontAtlas::GlyphRangesBuilder to create your own ranges, by merging existing ranges or adding new characters. static const short offsets_from_0x4E00[] = { -1,0,1,3,0,0,0,0,1,0,5,1,1,0,7,4,6,10,0,1,9,9,7,1,3,19,1,10,7,1,0,1,0,5,1,0,6,4,2,6,0,0,12,6,8,0,3,5,0,1,0,9,0,0,8,1,1,3,4,5,13,0,0,8,2,17, From 79ce9b74d5a4c2657062508d49242734a8fef8ba Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 18 Sep 2017 15:35:00 +0200 Subject: [PATCH 348/921] BeginTooltipEx() internal tweaks --- imgui.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index f7a96e3a3..a048e64f2 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3412,7 +3412,7 @@ static ImRect GetVisibleRect() } // Not exposed publicly as BeginTooltip() because bool parameters are evil. Let's see if other needs arise first. -static void BeginTooltipEx(bool override_previous_tooltip) +static void BeginTooltipEx(ImGuiWindowFlags extra_flags, bool override_previous_tooltip) { ImGuiContext& g = *GImGui; char window_name[16]; @@ -3425,12 +3425,13 @@ static void BeginTooltipEx(bool override_previous_tooltip) window->HiddenFrames = 1; ImFormatString(window_name, IM_ARRAYSIZE(window_name), "##Tooltip%02d", ++g.TooltipOverrideCount); } - ImGui::Begin(window_name, NULL, ImGuiWindowFlags_Tooltip|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_AlwaysAutoResize); + ImGuiWindowFlags flags = ImGuiWindowFlags_Tooltip|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_AlwaysAutoResize; + ImGui::Begin(window_name, NULL, flags | extra_flags); } void ImGui::SetTooltipV(const char* fmt, va_list args) { - BeginTooltipEx(true); + BeginTooltipEx(0, true); TextV(fmt, args); EndTooltip(); } @@ -3445,7 +3446,7 @@ void ImGui::SetTooltip(const char* fmt, ...) void ImGui::BeginTooltip() { - BeginTooltipEx(false); + BeginTooltipEx(0, false); } void ImGui::EndTooltip() @@ -9131,7 +9132,7 @@ void ImGui::ColorTooltip(const char* text, const float col[4], ImGuiColorEditFla ImGuiContext& g = *GImGui; int cr = IM_F32_TO_INT8_SAT(col[0]), cg = IM_F32_TO_INT8_SAT(col[1]), cb = IM_F32_TO_INT8_SAT(col[2]), ca = (flags & ImGuiColorEditFlags_NoAlpha) ? 255 : IM_F32_TO_INT8_SAT(col[3]); - BeginTooltipEx(true); + BeginTooltipEx(0, true); const char* text_end = text ? FindRenderedTextEnd(text, NULL) : text; if (text_end > text) From 1ff27d7db8c30dd317f85b38e5be936c103a1d37 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 18 Sep 2017 16:04:28 +0200 Subject: [PATCH 349/921] Added io.WantMoveMouse flags from Nav branch so Examples/Binding can already implement it. (#787) --- imgui.h | 1 + imgui_demo.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/imgui.h b/imgui.h index 7d8baf775..238ff89d8 100644 --- a/imgui.h +++ b/imgui.h @@ -855,6 +855,7 @@ struct ImGuiIO bool WantCaptureMouse; // Mouse is hovering a window or widget is active (= ImGui will use your mouse input). Use to hide mouse from the rest of your application bool WantCaptureKeyboard; // Widget is active (= ImGui will use your keyboard input). Use to hide keyboard from the rest of your application bool WantTextInput; // Some text input widget is active, which will read input characters from the InputCharacters array. Use to activate on screen keyboard if your system needs one + bool WantMoveMouse; // [BETA-NAV] MousePos has been altered. back-end should reposition mouse on next frame. used only if 'NavMovesMouse=true'. float Framerate; // Application framerate estimation, in frame per second. Solely for convenience. Rolling average estimation based on IO.DeltaTime over 120 frames int MetricsAllocs; // Number of active memory allocations int MetricsRenderVertices; // Vertices output during last call to Render() diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 24691abef..543172b28 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1676,6 +1676,7 @@ void ImGui::ShowTestWindow(bool* p_open) ImGui::Text("WantCaptureMouse: %d", io.WantCaptureMouse); ImGui::Text("WantCaptureKeyboard: %d", io.WantCaptureKeyboard); ImGui::Text("WantTextInput: %d", io.WantTextInput); + ImGui::Text("WantMoveMouse: %d", io.WantMoveMouse); if (ImGui::TreeNode("Keyboard & Mouse State")) { From d5d825debbc30423f32cf2710e39db1731c647af Mon Sep 17 00:00:00 2001 From: ocornut Date: Sat, 30 Jul 2016 23:17:11 +0200 Subject: [PATCH 350/921] Nav/Examples: honoring the io.WantMoveMouse flag in most common examples (#323) Missing support Vulkan (#549), Apple (#575, #247), SDL (#58, #356), Allegro, Marmalade (#368, #375) --- examples/README.txt | 1 + examples/directx10_example/imgui_impl_dx10.cpp | 8 ++++++++ examples/directx11_example/imgui_impl_dx11.cpp | 8 ++++++++ examples/directx9_example/imgui_impl_dx9.cpp | 8 ++++++++ examples/opengl2_example/imgui_impl_glfw.cpp | 13 ++++++++++--- examples/opengl3_example/imgui_impl_glfw_gl3.cpp | 13 ++++++++++--- 6 files changed, 45 insertions(+), 6 deletions(-) diff --git a/examples/README.txt b/examples/README.txt index 9491ff1a4..2769c1bf4 100644 --- a/examples/README.txt +++ b/examples/README.txt @@ -89,3 +89,4 @@ vulkan_example/ Vulkan example. This is quite long and tedious, because: Vulkan. +TODO: Apple, SDL GL/GL3, Allegro, Marmalade, Vulkan examples do not honor the io.WantMoveMouse flag. diff --git a/examples/directx10_example/imgui_impl_dx10.cpp b/examples/directx10_example/imgui_impl_dx10.cpp index 3c0f2d577..f85edf9b5 100644 --- a/examples/directx10_example/imgui_impl_dx10.cpp +++ b/examples/directx10_example/imgui_impl_dx10.cpp @@ -572,6 +572,14 @@ void ImGui_ImplDX10_NewFrame() // io.MouseDown : filled by WM_*BUTTON* events // io.MouseWheel : filled by WM_MOUSEWHEEL events + // Set OS mouse position if requested last frame by io.WantMoveMouse flag (used when io.NavMovesTrue is enabled by user and using directional navigation) + if (io.WantMoveMouse) + { + POINT pos = { (int)io.MousePos.x, (int)io.MousePos.y }; + ClientToScreen(g_hWnd, &pos); + SetCursorPos(pos.x, pos.y); + } + // Hide OS mouse cursor if ImGui is drawing it if (io.MouseDrawCursor) SetCursor(NULL); diff --git a/examples/directx11_example/imgui_impl_dx11.cpp b/examples/directx11_example/imgui_impl_dx11.cpp index 0442d785f..49a4aa481 100644 --- a/examples/directx11_example/imgui_impl_dx11.cpp +++ b/examples/directx11_example/imgui_impl_dx11.cpp @@ -575,6 +575,14 @@ void ImGui_ImplDX11_NewFrame() // io.MouseDown : filled by WM_*BUTTON* events // io.MouseWheel : filled by WM_MOUSEWHEEL events + // Set OS mouse position if requested last frame by io.WantMoveMouse flag (used when io.NavMovesTrue is enabled by user and using directional navigation) + if (io.WantMoveMouse) + { + POINT pos = { (int)io.MousePos.x, (int)io.MousePos.y }; + ClientToScreen(g_hWnd, &pos); + SetCursorPos(pos.x, pos.y); + } + // Hide OS mouse cursor if ImGui is drawing it if (io.MouseDrawCursor) SetCursor(NULL); diff --git a/examples/directx9_example/imgui_impl_dx9.cpp b/examples/directx9_example/imgui_impl_dx9.cpp index 664983ac8..490120126 100644 --- a/examples/directx9_example/imgui_impl_dx9.cpp +++ b/examples/directx9_example/imgui_impl_dx9.cpp @@ -349,6 +349,14 @@ void ImGui_ImplDX9_NewFrame() // io.MouseDown : filled by WM_*BUTTON* events // io.MouseWheel : filled by WM_MOUSEWHEEL events + // Set OS mouse position if requested last frame by io.WantMoveMouse flag (used when io.NavMovesTrue is enabled by user and using directional navigation) + if (io.WantMoveMouse) + { + POINT pos = { (int)io.MousePos.x, (int)io.MousePos.y }; + ClientToScreen(g_hWnd, &pos); + SetCursorPos(pos.x, pos.y); + } + // Hide OS mouse cursor if ImGui is drawing it if (io.MouseDrawCursor) SetCursor(NULL); diff --git a/examples/opengl2_example/imgui_impl_glfw.cpp b/examples/opengl2_example/imgui_impl_glfw.cpp index 624085fd7..236a2d101 100644 --- a/examples/opengl2_example/imgui_impl_glfw.cpp +++ b/examples/opengl2_example/imgui_impl_glfw.cpp @@ -269,9 +269,16 @@ void ImGui_ImplGlfwGL2_NewFrame() // (we already got mouse wheel, keyboard keys & characters from glfw callbacks polled in glfwPollEvents()) if (glfwGetWindowAttrib(g_Window, GLFW_FOCUSED)) { - double mouse_x, mouse_y; - glfwGetCursorPos(g_Window, &mouse_x, &mouse_y); - io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position in screen coordinates (set to -1,-1 if no mouse / on another screen, etc.) + if (io.WantMoveMouse) + { + glfwSetCursorPos(g_Window, (double)io.MousePos.x, (double)io.MousePos.y); // Set mouse position if requested by io.WantMoveMouse flag (used when io.NavMovesTrue is enabled by user and using directional navigation) + } + else + { + double mouse_x, mouse_y; + glfwGetCursorPos(g_Window, &mouse_x, &mouse_y); + io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Get mouse position in screen coordinates (set to -1,-1 if no mouse / on another screen, etc.) + } } else { diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp index 1cf35c653..ac711b91e 100644 --- a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp +++ b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp @@ -383,9 +383,16 @@ void ImGui_ImplGlfwGL3_NewFrame() // (we already got mouse wheel, keyboard keys & characters from glfw callbacks polled in glfwPollEvents()) if (glfwGetWindowAttrib(g_Window, GLFW_FOCUSED)) { - double mouse_x, mouse_y; - glfwGetCursorPos(g_Window, &mouse_x, &mouse_y); - io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position in screen coordinates (set to -1,-1 if no mouse / on another screen, etc.) + if (io.WantMoveMouse) + { + glfwSetCursorPos(g_Window, (double)io.MousePos.x, (double)io.MousePos.y); // Set mouse position if requested by io.WantMoveMouse flag (used when io.NavMovesTrue is enabled by user and using directional navigation) + } + else + { + double mouse_x, mouse_y; + glfwGetCursorPos(g_Window, &mouse_x, &mouse_y); + io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Get mouse position in screen coordinates (set to -1,-1 if no mouse / on another screen, etc.) + } } else { From 479e532f184061fee6af9a295a84bc6f5f263852 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 18 Sep 2017 21:41:49 +0200 Subject: [PATCH 351/921] ColorEdit: fixed weird ternary pattern that makes some compiler warning (fair) --- imgui.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index a048e64f2..0b316c1cd 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9301,7 +9301,10 @@ static void ColorEditOptionsPopup(ImGuiColorEditFlags flags, float* col) sprintf(buf, "(%d,%d,%d,%d)", cr, cg, cb, ca); if (ImGui::Selectable(buf)) ImGui::SetClipboardText(buf); - sprintf(buf, (flags & ImGuiColorEditFlags_NoAlpha) ? "0x%02X%02X%02X" : "0x%02X%02X%02X%02X", cr, cg, cb, ca); + if (flags & ImGuiColorEditFlags_NoAlpha) + sprintf(buf, "0x%02X%02X%02X", cr, cg, cb); + else + sprintf(buf, "0x%02X%02X%02X%02X", cr, cg, cb, ca); if (ImGui::Selectable(buf)) ImGui::SetClipboardText(buf); ImGui::EndPopup(); From 2fc07c1b7d95c09f5f230ded1b64b662d5943e8e Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 19 Sep 2017 18:32:09 +0200 Subject: [PATCH 352/921] Update README.md --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 31b101567..6fcac1e28 100644 --- a/README.md +++ b/README.md @@ -226,12 +226,14 @@ Double-chocolate sponsors: - Mobigame - Insomniac Games (sponsored the gamepad/keyboard navigation branch) - Aras Pranckevičius +- Lizardcube +- Greggman Salty caramel supporters: -- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Recognition Robotics, Chris Genova, ikrima, Glenn Fiedler, Geoffrey Evans, Dakko Dakko. +- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Recognition Robotics, Chris Genova, ikrima, Glenn Fiedler, Geoffrey Evans, Dakko Dakko, Mercury Labs, Singularity Demo Group, Mischa Alff, Sebastien Ronsse. Caramel supporters: -- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm, Farhan Wali, Jeff Roberts, Matt Reyer, Colin Riley, Victor Martins, Josh Simmons, Garrett Hoofman, Sergio Gonzales, Andrew Berridge, Roy Eltham, Game Preservation Society, [Kit framework](http://svkonsult.se/kit), Josh Faust, Martin Donlon, Quinton, Felix. +- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm, Farhan Wali, Jeff Roberts, Matt Reyer, Colin Riley, Victor Martins, Josh Simmons, Garrett Hoofman, Sergio Gonzales, Andrew Berridge, Roy Eltham, Game Preservation Society, [Kit framework](http://svkonsult.se/kit), Josh Faust, Martin Donlon, Quinton, Felix, Andrew Belt, Codecat, Cort Stratton, Claudio Canepa, Doug McNabb, Emmanuel Julien, Guillaume Chereau, Jeffrey Slutter, Jeremiah Deckard, r-lyeh, Roger Clark, Nekith, Joshua Fisher, Malte Hoffmann, Mustafa Karaalioglu, Merlyn Morgan-Graham, Per Vognsen, Fabian Giesen, Jan Staubach, Matt Hargett, John Shearer, Jesse Chounard, kingcoopa, Miloš Tošić. And other supporters; thanks! From 9b2672a99fa4be849d5f471b988deebf92836965 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 19 Sep 2017 18:33:04 +0200 Subject: [PATCH 353/921] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 6fcac1e28..c25d53450 100644 --- a/README.md +++ b/README.md @@ -233,9 +233,10 @@ Salty caramel supporters: - Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Recognition Robotics, Chris Genova, ikrima, Glenn Fiedler, Geoffrey Evans, Dakko Dakko, Mercury Labs, Singularity Demo Group, Mischa Alff, Sebastien Ronsse. Caramel supporters: -- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm, Farhan Wali, Jeff Roberts, Matt Reyer, Colin Riley, Victor Martins, Josh Simmons, Garrett Hoofman, Sergio Gonzales, Andrew Berridge, Roy Eltham, Game Preservation Society, [Kit framework](http://svkonsult.se/kit), Josh Faust, Martin Donlon, Quinton, Felix, Andrew Belt, Codecat, Cort Stratton, Claudio Canepa, Doug McNabb, Emmanuel Julien, Guillaume Chereau, Jeffrey Slutter, Jeremiah Deckard, r-lyeh, Roger Clark, Nekith, Joshua Fisher, Malte Hoffmann, Mustafa Karaalioglu, Merlyn Morgan-Graham, Per Vognsen, Fabian Giesen, Jan Staubach, Matt Hargett, John Shearer, Jesse Chounard, kingcoopa, Miloš Tošić. +- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm, Farhan Wali, Jeff Roberts, Matt Reyer, Colin Riley, Victor Martins, Josh Simmons, Garrett Hoofman, Sergio Gonzales, Andrew Berridge, Roy Eltham, Game Preservation Society, Kit framework, Josh Faust, Martin Donlon, Quinton, Felix, Andrew Belt, Codecat, Cort Stratton, Claudio Canepa, Doug McNabb, Emmanuel Julien, Guillaume Chereau, Jeffrey Slutter, Jeremiah Deckard, r-lyeh, Roger Clark, Nekith, Joshua Fisher, Malte Hoffmann, Mustafa Karaalioglu, Merlyn Morgan-Graham, Per Vognsen, Fabian Giesen, Jan Staubach, Matt Hargett, John Shearer, Jesse Chounard, kingcoopa, Miloš Tošić. And other supporters; thanks! +(Please contact me or PR if you would like to be added or removed from this list) License ------- From 229921541b5b10acc41baefe122da924e40562b5 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 20 Sep 2017 18:51:33 +0200 Subject: [PATCH 354/921] TODO list --- TODO.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/TODO.txt b/TODO.txt index 9c7b3a2a4..bddf473c5 100644 --- a/TODO.txt +++ b/TODO.txt @@ -44,6 +44,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - widgets: display mode: widget-label, label-widget (aligned on column or using fixed size), label-newline-tab-widget etc. (#395) - widgets: clean up widgets internal toward exposing everything and stabilizing imgui_internals.h. - widgets: add disabled and read-only modes (#211) + - widgets: add always-allow-overlap mode. - widgets: alignment options in style (e.g. center Selectable, Right-Align within Button, etc.) #1260 - widgets: activate by identifier (trigger button, focus given id) @@ -173,7 +174,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i !- style: better default styles. !- style: move border to style structure, remove _ShowBorder flag. - - style: border types: out-screen, in-screen, etc. + - style: border types: out-screen, in-screen, etc. (#447) - style/optimization: store rounded corners in texture to use 1 quad per corner (filled and wireframe) to lower the cost of rounding. - style: add window shadow (fading away from the window. Paint-style calculation of vertices alpha after drawlist would be easier) - style: color-box not always square? @@ -200,6 +201,8 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - markup: simple markup language for color change? !- font: better CalcTextSizeA() API, at least for simple use cases. current one is horrible (perhaps have simple vs extended versions). + - font: enforce monospace through ImFontConfig (for icons?) + - font: finish CustomRectRegister() to allow mapping unicode codepoint to custom texture data - font: PushFontSize API (#1018) - font/atlas: incremental updates - font/atlas: dynamic font atlas to avoid baking huge ranges into bitmap and make scaling easier. @@ -232,6 +235,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - examples: window minimize, maximize (#583) - examples: provide a zero-framerate/idle example. - examples: document WantCaptureKeyboard, WantCaptureMouse in example apps. (#446) + - examples: glfw: could go idle when minimized? if (glfwGetWindowAttrib(window, GLFW_ICONIFIED)) { glfwWaitEvents(); continue; } // the problem is that DeltaTime will be super high on resume, perhaps provide a way to let impl know (#440) - optimization: replace vsnprintf with stb_printf? or enable the defines/infrastructure to allow it (#1038) - optimization: add clipping for multi-component widgets (SliderFloatX, ColorEditX, etc.). one problem is that nav branch can't easily clip parent group when there is a move request. - optimization: add a flag to disable most of rendering, for the case where the user expect to skip it (#335) From 3dd3d0b2489dcb37601c8b989c5f719f849e0897 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 24 Sep 2017 12:54:49 +0200 Subject: [PATCH 355/921] Examples: DirectX11: allow creating device with feature level 10 sinec we don't really need much for that example. (#1333) --- examples/directx11_example/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/directx11_example/main.cpp b/examples/directx11_example/main.cpp index c8d566bfc..76bab9518 100644 --- a/examples/directx11_example/main.cpp +++ b/examples/directx11_example/main.cpp @@ -60,8 +60,8 @@ HRESULT CreateDeviceD3D(HWND hWnd) UINT createDeviceFlags = 0; //createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; D3D_FEATURE_LEVEL featureLevel; - const D3D_FEATURE_LEVEL featureLevelArray[1] = { D3D_FEATURE_LEVEL_11_0, }; - if (D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, featureLevelArray, 1, D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &featureLevel, &g_pd3dDeviceContext) != S_OK) + const D3D_FEATURE_LEVEL featureLevelArray[2] = { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_0, }; + if (D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, featureLevelArray, 2, D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &featureLevel, &g_pd3dDeviceContext) != S_OK) return E_FAIL; CreateRenderTarget(); From 0a5fb24f10caf49ec627a0e1b9ef0cc5e8b1bc93 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 25 Sep 2017 12:52:06 +0200 Subject: [PATCH 356/921] Popups: Exposing a little more of popups internals in imgui_internals.h --- imgui.cpp | 16 +++++++--------- imgui_internal.h | 2 ++ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 0b316c1cd..d3a3d2567 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -623,10 +623,8 @@ static void MarkIniSettingsDirty(ImGuiWindow* window); static ImRect GetVisibleRect(); -static bool BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_flags); static void CloseInactivePopups(); static void ClosePopupToLevel(int remaining); -static void ClosePopup(ImGuiID id); static ImGuiWindow* GetFrontMostModalRootWindow(); static ImVec2 FindBestPopupWindowPos(const ImVec2& base_pos, const ImVec2& size, int* last_dir, const ImRect& rect_to_avoid); @@ -3531,9 +3529,9 @@ static void ClosePopupToLevel(int remaining) g.OpenPopupStack.resize(remaining); } -static void ClosePopup(ImGuiID id) +void ImGui::ClosePopup(ImGuiID id) { - if (!ImGui::IsPopupOpen(id)) + if (!IsPopupOpen(id)) return; ImGuiContext& g = *GImGui; ClosePopupToLevel(g.OpenPopupStack.Size - 1); @@ -3559,17 +3557,17 @@ static inline void ClearSetNextWindowData() g.SetNextWindowSizeConstraint = g.SetNextWindowFocus = false; } -static bool BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_flags) +bool ImGui::BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_flags) { ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; - if (!ImGui::IsPopupOpen(id)) + if (!IsPopupOpen(id)) { ClearSetNextWindowData(); // We behave like Begin() and need to consume those values return false; } - ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); + PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); ImGuiWindowFlags flags = extra_flags|ImGuiWindowFlags_Popup|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_AlwaysAutoResize; char name[20]; @@ -3578,11 +3576,11 @@ static bool BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_flags) else ImFormatString(name, IM_ARRAYSIZE(name), "##popup_%08x", id); // Not recycling, so we can close/open during the same frame - bool is_open = ImGui::Begin(name, NULL, flags); + bool is_open = Begin(name, NULL, flags); if (!(window->Flags & ImGuiWindowFlags_ShowBorders)) g.CurrentWindow->Flags &= ~ImGuiWindowFlags_ShowBorders; if (!is_open) // NB: is_open can be 'false' when the popup is completely clipped (e.g. zero size display) - ImGui::EndPopup(); + EndPopup(); return is_open; } diff --git a/imgui_internal.h b/imgui_internal.h index fcced1ac9..056dccfa6 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -774,7 +774,9 @@ namespace ImGui IMGUI_API void PopItemFlag(); IMGUI_API void OpenPopupEx(ImGuiID id, bool reopen_existing); + IMGUI_API void ClosePopup(ImGuiID id); IMGUI_API bool IsPopupOpen(ImGuiID id); + IMGUI_API bool BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_flags); IMGUI_API int CalcTypematicPressedRepeatAmount(float t, float t_prev, float repeat_delay, float repeat_rate); From 9f34925b2aa656d1897be50dcd6aed395f401455 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 25 Sep 2017 13:23:25 +0200 Subject: [PATCH 357/921] Window: Tweaked ApplySizeFullWithConstraint() -> CalcSizeFullWithConstraint() so it can be used without side-effect --- imgui.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index d3a3d2567..5de150028 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3882,7 +3882,7 @@ static ImGuiWindow* CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFl return window; } -static void ApplySizeFullWithConstraint(ImGuiWindow* window, ImVec2 new_size) +static ImVec2 CalcSizeFullWithConstraint(ImGuiWindow* window, ImVec2 new_size) { ImGuiContext& g = *GImGui; if (g.SetNextWindowSizeConstraint) @@ -3904,7 +3904,7 @@ static void ApplySizeFullWithConstraint(ImGuiWindow* window, ImVec2 new_size) } if (!(window->Flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_AlwaysAutoResize))) new_size = ImMax(new_size, g.Style.WindowMinSize); - window->SizeFull = new_size; + return new_size; } static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window) @@ -4161,7 +4161,7 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us } // Apply minimum/maximum window size constraints and final size - ApplySizeFullWithConstraint(window, window->SizeFull); + window->SizeFull = CalcSizeFullWithConstraint(window, window->SizeFull); window->Size = window->Collapsed ? window->TitleBarRect().GetSize() : window->SizeFull; // POSITION @@ -4286,7 +4286,7 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us if (size_target.x != FLT_MAX && size_target.y != FLT_MAX) { - ApplySizeFullWithConstraint(window, size_target); + window->SizeFull = CalcSizeFullWithConstraint(window, size_target); MarkIniSettingsDirty(window); } window->Size = window->SizeFull; From 0a5557328868bb331804ebb8e114d58ec6a28d37 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 25 Sep 2017 15:48:52 +0200 Subject: [PATCH 358/921] Begin(): Minor tidying up of flow --- imgui.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 5de150028..310cfe2c0 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4143,13 +4143,13 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us if (window->AutoFitFramesY > 0) window->SizeFull.y = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.y, size_auto_fit.y) : size_auto_fit.y; } - else + else if (!window_size_set_by_api) { - if ((flags & ImGuiWindowFlags_AlwaysAutoResize) && !window_size_set_by_api) + if (flags & ImGuiWindowFlags_AlwaysAutoResize) { window->SizeFull = size_auto_fit; } - else if ((window->AutoFitFramesX > 0 || window->AutoFitFramesY > 0) && !window_size_set_by_api) + else if (window->AutoFitFramesX > 0 || window->AutoFitFramesY > 0) { // Auto-fit only grows during the first few frames if (window->AutoFitFramesX > 0) From 4b82759598e34aed179177ecaa00e774c0d23484 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 25 Sep 2017 18:25:43 +0200 Subject: [PATCH 359/921] SetNextWindowPos: added a ImVec2 pivot parameter for positioning a given a center, bottom-right position, etc. As a generalization of SetNextWindowPosCenter() which is now obsolete. This will be useful for combo-like popups as well. Demo: Simple-overlay window uses the SetWindowPos pivot to select a corner to position itself at. --- imgui.cpp | 37 ++++++++++++++++++++++--------------- imgui.h | 4 ++-- imgui_demo.cpp | 28 +++++++++++++++++++--------- imgui_internal.h | 4 +++- 4 files changed, 46 insertions(+), 27 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 310cfe2c0..f7cda6712 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -204,6 +204,7 @@ Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. Also read releases logs https://github.com/ocornut/imgui/releases for more details. + - 2017/09/25 (1.52) - removed SetNextWindowPosCenter() because SetNextWindowPos() now has the optional pivot information to do the same and more. Kept redirection function (will obsolete). - 2017/08/25 (1.52) - io.MousePos needs to be set to ImVec2(-FLT_MAX,-FLT_MAX) when mouse is unavailable/missing. Previously ImVec2(-1,-1) was enough but we now accept negative mouse coordinates. In your binding if you need to support unavailable mouse, make sure to replace "io.MousePos = ImVec2(-1,-1)" with "io.MousePos = ImVec2(-FLT_MAX,-FLT_MAX)". - 2017/08/22 (1.51) - renamed IsItemHoveredRect() to IsItemRectHovered(). Kept inline redirection function (will obsolete). - renamed IsMouseHoveringAnyWindow() to IsAnyWindowHovered() for consistency. Kept inline redirection function (will obsolete). @@ -1804,7 +1805,7 @@ ImGuiWindow::ImGuiWindow(const char* name) AutoPosLastDirection = -1; HiddenFrames = 0; SetWindowPosAllowFlags = SetWindowSizeAllowFlags = SetWindowCollapsedAllowFlags = ImGuiCond_Always | ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing; - SetWindowPosCenterWanted = false; + SetWindowPosVal = SetWindowPosPivot = ImVec2(FLT_MAX, FLT_MAX); LastFrameActive = -1; ItemWidthDefault = 0.0f; @@ -3619,11 +3620,15 @@ bool ImGui::BeginPopupModal(const char* name, bool* p_open, ImGuiWindowFlags ext return false; } + // Center modal windows by default + if ((window->SetWindowPosAllowFlags & g.SetNextWindowPosCond) == 0) + SetNextWindowPos(g.IO.DisplaySize * 0.5f, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f)); + ImGuiWindowFlags flags = extra_flags|ImGuiWindowFlags_Popup|ImGuiWindowFlags_Modal|ImGuiWindowFlags_NoCollapse|ImGuiWindowFlags_NoSavedSettings; bool is_open = ImGui::Begin(name, p_open, flags); if (!is_open || (p_open && !*p_open)) // NB: is_open can be 'false' when the popup is completely clipped (e.g. zero size display) { - ImGui::EndPopup(); + EndPopup(); if (is_open) ClosePopup(id); return false; @@ -3994,9 +3999,12 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us if (window->Appearing) window->SetWindowPosAllowFlags |= ImGuiCond_Appearing; window_pos_set_by_api = (window->SetWindowPosAllowFlags & g.SetNextWindowPosCond) != 0; - if (window_pos_set_by_api && ImLengthSqr(g.SetNextWindowPosVal - ImVec2(-FLT_MAX,-FLT_MAX)) < 0.001f) + if (window_pos_set_by_api && ImLengthSqr(g.SetNextWindowPosPivot) > 0.00001f) { - window->SetWindowPosCenterWanted = true; // May be processed on the next frame if this is our first frame and we are measuring size + // May be processed on the next frame if this is our first frame and we are measuring size + // FIXME: Look into removing the branch so everything can go through this same codepath for consistency. + window->SetWindowPosVal = g.SetNextWindowPosVal; + window->SetWindowPosPivot = g.SetNextWindowPosPivot; window->SetWindowPosAllowFlags &= ~(ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing); } else @@ -4178,13 +4186,11 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us window->Size = window->SizeFull = size_on_first_use; // NB: argument name 'size_on_first_use' misleading here, it's really just 'size' as provided by user passed via BeginChild()->Begin(). } - bool window_pos_center = false; - window_pos_center |= (window->SetWindowPosCenterWanted && window->HiddenFrames == 0); - window_pos_center |= ((flags & ImGuiWindowFlags_Modal) && !window_pos_set_by_api && window_just_appearing_after_hidden_for_resize); - if (window_pos_center) + const bool window_pos_with_pivot = (window->SetWindowPosVal.x != FLT_MAX && window->HiddenFrames == 0); + if (window_pos_with_pivot) { - // Center (any sort of window) - SetWindowPos(window, ImMax(style.DisplaySafeAreaPadding, fullscreen_rect.GetCenter() - window->SizeFull * 0.5f), 0); + // Position given a pivot (e.g. for centering) + SetWindowPos(window, ImMax(style.DisplaySafeAreaPadding, window->SetWindowPosVal - window->SizeFull * window->SetWindowPosPivot), 0); } else if (flags & ImGuiWindowFlags_ChildMenu) { @@ -5010,7 +5016,7 @@ static void SetWindowPos(ImGuiWindow* window, const ImVec2& pos, ImGuiCond cond) if (cond && (window->SetWindowPosAllowFlags & cond) == 0) return; window->SetWindowPosAllowFlags &= ~(ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing); - window->SetWindowPosCenterWanted = false; + window->SetWindowPosVal = ImVec2(FLT_MAX, FLT_MAX); // Set const ImVec2 old_pos = window->Pos; @@ -5133,19 +5139,20 @@ void ImGui::SetWindowFocus(const char* name) } } -void ImGui::SetNextWindowPos(const ImVec2& pos, ImGuiCond cond) +void ImGui::SetNextWindowPos(const ImVec2& pos, ImGuiCond cond, const ImVec2& pivot) { ImGuiContext& g = *GImGui; g.SetNextWindowPosVal = pos; + g.SetNextWindowPosPivot = pivot; g.SetNextWindowPosCond = cond ? cond : ImGuiCond_Always; } +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS void ImGui::SetNextWindowPosCenter(ImGuiCond cond) { - ImGuiContext& g = *GImGui; - g.SetNextWindowPosVal = ImVec2(-FLT_MAX, -FLT_MAX); - g.SetNextWindowPosCond = cond ? cond : ImGuiCond_Always; + SetNextWindowPos(ImGui::GetIO().DisplaySize * 0.5f, cond, ImVec2(0.5f, 0.5f)); } +#endif void ImGui::SetNextWindowSize(const ImVec2& size, ImGuiCond cond) { diff --git a/imgui.h b/imgui.h index 238ff89d8..4bfa9430d 100644 --- a/imgui.h +++ b/imgui.h @@ -152,8 +152,7 @@ namespace ImGui IMGUI_API bool IsWindowAppearing(); IMGUI_API void SetWindowFontScale(float scale); // per-window font scale. Adjust IO.FontGlobalScale if you want to scale all windows - IMGUI_API void SetNextWindowPos(const ImVec2& pos, ImGuiCond cond = 0); // set next window position. call before Begin() - IMGUI_API void SetNextWindowPosCenter(ImGuiCond cond = 0); // set next window position to be centered on screen. call before Begin() + IMGUI_API void SetNextWindowPos(const ImVec2& pos, ImGuiCond cond = 0, const ImVec2& pivot = ImVec2(0,0)); // set next window position. call before Begin(). use pivot=(0.5f,0.5f) to center on given point, etc. IMGUI_API void SetNextWindowSize(const ImVec2& size, ImGuiCond cond = 0); // set next window size. set axis to 0.0f to force an auto-fit on this axis. call before Begin() IMGUI_API void SetNextWindowSizeConstraints(const ImVec2& size_min, const ImVec2& size_max, ImGuiSizeConstraintCallback custom_callback = NULL, void* custom_callback_data = NULL); // set next window size limits. use -1,-1 on either X/Y axis to preserve the current size. Use callback to apply non-trivial programmatic constraints. IMGUI_API void SetNextWindowContentSize(const ImVec2& size); // set next window content size (enforce the range of scrollbars). set axis to 0.0f to leave it automatic. call before Begin() @@ -489,6 +488,7 @@ namespace ImGui // Obsolete functions (Will be removed! Also see 'API BREAKING CHANGES' section in imgui.cpp) #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS + static void SetNextWindowPosCenter(ImGuiCond cond = 0); // OBSOLETE 1.52+ static inline bool IsItemHoveredRect() { return IsItemRectHovered(); } // OBSOLETE 1.51+ static inline bool IsPosHoveringAnyWindow(const ImVec2&) { IM_ASSERT(0); return false; } // OBSOLETE 1.51+. This was partly broken. You probably wanted to use ImGui::GetIO().WantCaptureMouse instead. static inline bool IsMouseHoveringAnyWindow() { return IsAnyWindowHovered(); } // OBSOLETE 1.51+ diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 543172b28..9542b8830 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1434,7 +1434,7 @@ void ImGui::ShowTestWindow(bool* p_open) ImGui::OpenPopup("Delete?"); if (ImGui::BeginPopupModal("Delete?", NULL, ImGuiWindowFlags_AlwaysAutoResize)) { - ImGui::Text("All those beautiful files will be deleted.\nThis operation cannot be undone!\n\n"); + ImGui::Text("All those beautiful files will be deleted.\nThis operation cannot be undone!\n\n"); ImGui::Separator(); //static int dummy_i = 0; @@ -2114,20 +2114,30 @@ static void ShowExampleAppConstrainedResize(bool* p_open) ImGui::End(); } -// Demonstrate creating a simple static window with no decoration. +// Demonstrate creating a simple static window with no decoration + a context-menu to choose which corner of the screen to use. static void ShowExampleAppFixedOverlay(bool* p_open) { - ImGui::SetNextWindowPos(ImVec2(10,10)); + const float DISTANCE = 10.0f; + static int corner = 0; + ImVec2 window_pos = ImVec2((corner & 1) ? ImGui::GetIO().DisplaySize.x - DISTANCE : DISTANCE, (corner & 2) ? ImGui::GetIO().DisplaySize.y - DISTANCE : DISTANCE); + ImVec2 window_pos_pivot = ImVec2((corner & 1) ? 1.0f : 0.0f, (corner & 2) ? 1.0f : 0.0f); + ImGui::SetNextWindowPos(window_pos, ImGuiCond_Always, window_pos_pivot); ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(0.0f, 0.0f, 0.0f, 0.3f)); - if (!ImGui::Begin("Example: Fixed Overlay", p_open, ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoSavedSettings)) + if (ImGui::Begin("Example: Fixed Overlay", p_open, ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoSavedSettings)) { + ImGui::Text("Simple overlay\nin the corner of the screen.\n(right-click to change position)"); + ImGui::Separator(); + ImGui::Text("Mouse Position: (%.1f,%.1f)", ImGui::GetIO().MousePos.x, ImGui::GetIO().MousePos.y); + if (ImGui::BeginPopupContextWindow()) + { + if (ImGui::MenuItem("Top-left", NULL, corner == 0)) corner = 0; + if (ImGui::MenuItem("Top-right", NULL, corner == 1)) corner = 1; + if (ImGui::MenuItem("Bottom-left", NULL, corner == 2)) corner = 2; + if (ImGui::MenuItem("Bottom-right", NULL, corner == 3)) corner = 3; + ImGui::EndPopup(); + } ImGui::End(); - return; } - ImGui::Text("Simple overlay\non the top-left side of the screen."); - ImGui::Separator(); - ImGui::Text("Mouse Position: (%.1f,%.1f)", ImGui::GetIO().MousePos.x, ImGui::GetIO().MousePos.y); - ImGui::End(); ImGui::PopStyleColor(); } diff --git a/imgui_internal.h b/imgui_internal.h index 056dccfa6..8f6762bde 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -437,6 +437,7 @@ struct ImGuiContext // Storage for SetNexWindow** and SetNextTreeNode*** functions ImVec2 SetNextWindowPosVal; + ImVec2 SetNextWindowPosPivot; ImVec2 SetNextWindowSizeVal; ImVec2 SetNextWindowContentSizeVal; bool SetNextWindowCollapsedVal; @@ -696,7 +697,8 @@ struct IMGUI_API ImGuiWindow ImGuiCond SetWindowPosAllowFlags; // store condition flags for next SetWindowPos() call. ImGuiCond SetWindowSizeAllowFlags; // store condition flags for next SetWindowSize() call. ImGuiCond SetWindowCollapsedAllowFlags; // store condition flags for next SetWindowCollapsed() call. - bool SetWindowPosCenterWanted; + ImVec2 SetWindowPosVal; // store window position when using a non-zero Pivot (position set needs to be processed when we know the window size) + ImVec2 SetWindowPosPivot; // store window pivot for positioning. ImVec2(0,0) when positioning from top-left corner; ImVec2(0.5f,0.5f) for centering; ImVec2(1,1) for bottom right. ImGuiDrawContext DC; // Temporary per-window data, reset at the beginning of the frame ImVector IDStack; // ID stack. ID are hashes seeded with the value at the top of the stack From a34edb810e8136f46f03dc9fd757fa772660e318 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 25 Sep 2017 21:12:07 +0200 Subject: [PATCH 360/921] Demo: Fixed overlay demo keeps resizing (in case, e.g.: font changes) --- imgui_demo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 9542b8830..6773840f8 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -2123,7 +2123,7 @@ static void ShowExampleAppFixedOverlay(bool* p_open) ImVec2 window_pos_pivot = ImVec2((corner & 1) ? 1.0f : 0.0f, (corner & 2) ? 1.0f : 0.0f); ImGui::SetNextWindowPos(window_pos, ImGuiCond_Always, window_pos_pivot); ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(0.0f, 0.0f, 0.0f, 0.3f)); - if (ImGui::Begin("Example: Fixed Overlay", p_open, ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoSavedSettings)) + if (ImGui::Begin("Example: Fixed Overlay", p_open, ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoSavedSettings)) { ImGui::Text("Simple overlay\nin the corner of the screen.\n(right-click to change position)"); ImGui::Separator(); From 0d56140b4a71f3e68643d1af9139c8d61a8857c1 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 25 Sep 2017 21:45:34 +0200 Subject: [PATCH 361/921] BeginCombo(): rework internals a little to make it easier to provide custom combo-like elements relying in BeginCombo(). BeginPopupEx() doesn't enforce AlwaysAutoResize flag anymore. --- TODO.txt | 3 ++- imgui.cpp | 31 +++++++++++++++++++------------ imgui_internal.h | 2 +- 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/TODO.txt b/TODO.txt index bddf473c5..0369c6374 100644 --- a/TODO.txt +++ b/TODO.txt @@ -99,7 +99,8 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - plot: option/feature: draw unit - plot: add a helper e.g. Plot(char* label, float value, float time_span=2.0f) that stores values and Plot them for you - probably another function name. and/or automatically allow to plot ANY displayed value (more reliance on stable ID) - - clipper: ability to force display 1 item in the list would be convenient. + - clipper: ability to force display 1 item in the list would be convenient (for patterns where we need to set active id etc.) + - clipper: ability to disable the clipping through a simple flag/bool. - clipper: ability to run without knowing full count in advance. - splitter/separator: formalize the splitter idiom into an official api (we want to handle n-way split) (#319) diff --git a/imgui.cpp b/imgui.cpp index f7cda6712..88d0fcbbd 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3569,7 +3569,7 @@ bool ImGui::BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_flags) } PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); - ImGuiWindowFlags flags = extra_flags|ImGuiWindowFlags_Popup|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_AlwaysAutoResize; + ImGuiWindowFlags flags = extra_flags|ImGuiWindowFlags_Popup|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings; char name[20]; if (flags & ImGuiWindowFlags_ChildMenu) @@ -3594,7 +3594,7 @@ bool ImGui::BeginPopup(const char* str_id) ClearSetNextWindowData(); // We behave like Begin() and need to consume those values return false; } - return BeginPopupEx(g.CurrentWindow->GetID(str_id), ImGuiWindowFlags_ShowBorders); + return BeginPopupEx(g.CurrentWindow->GetID(str_id), ImGuiWindowFlags_ShowBorders | ImGuiWindowFlags_AlwaysAutoResize); } bool ImGui::IsPopupOpen(ImGuiID id) @@ -8602,7 +8602,7 @@ bool ImGui::Combo(const char* label, int* current_item, const char* items_separa return value_changed; } -bool ImGui::BeginCombo(const char* label, const char* preview_value, float popup_opened_height) +bool ImGui::BeginCombo(const char* label, const char* preview_value, ImVec2 popup_size) { ImGuiWindow* window = GetCurrentWindow(); if (window->SkipItems) @@ -8662,17 +8662,24 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, float popup if (!popup_open) return false; + if (popup_size.x == 0.0f) + popup_size.x = w; + float popup_y1 = frame_bb.Max.y; - float popup_y2 = ImClamp(popup_y1 + popup_opened_height, popup_y1, g.IO.DisplaySize.y - style.DisplaySafeAreaPadding.y); - if ((popup_y2 - popup_y1) < ImMin(popup_opened_height, frame_bb.Min.y - style.DisplaySafeAreaPadding.y)) + float popup_y2 = ImClamp(popup_y1 + popup_size.y, popup_y1, g.IO.DisplaySize.y - style.DisplaySafeAreaPadding.y); + if ((popup_y2 - popup_y1) < ImMin(popup_size.y, frame_bb.Min.y - style.DisplaySafeAreaPadding.y)) { // Position our combo ABOVE because there's more space to fit! (FIXME: Handle in Begin() or use a shared helper. We have similar code in Begin() for popup placement) - popup_y1 = ImClamp(frame_bb.Min.y - popup_opened_height, style.DisplaySafeAreaPadding.y, frame_bb.Min.y); + popup_y1 = ImClamp(frame_bb.Min.y - popup_size.y, style.DisplaySafeAreaPadding.y, frame_bb.Min.y); popup_y2 = frame_bb.Min.y; + SetNextWindowPos(ImVec2(frame_bb.Min.x, frame_bb.Min.y), ImGuiCond_Always, ImVec2(0.0f, 1.0f)); } - ImRect popup_rect(ImVec2(frame_bb.Min.x, popup_y1), ImVec2(frame_bb.Max.x, popup_y2)); - SetNextWindowPos(popup_rect.Min); - SetNextWindowSize(popup_rect.GetSize()); + else + { + // Position our combo below + SetNextWindowPos(ImVec2(frame_bb.Min.x, frame_bb.Max.y), ImGuiCond_Always, ImVec2(0.0f, 0.0f)); + } + SetNextWindowSize(ImVec2(popup_size.x, popup_y2 - popup_y1), ImGuiCond_Appearing); PushStyleVar(ImGuiStyleVar_WindowPadding, style.FramePadding); const ImGuiWindowFlags flags = ImGuiWindowFlags_ComboBox | ((window->Flags & ImGuiWindowFlags_ShowBorders) ? ImGuiWindowFlags_ShowBorders : 0); @@ -8705,9 +8712,9 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi // Size default to hold ~7 items if (height_in_items < 0) height_in_items = 7; - float popup_opened_height = (g.FontSize + style.ItemSpacing.y) * ImMin(items_count, height_in_items) + (style.FramePadding.y * 3); + float popup_height = (g.FontSize + style.ItemSpacing.y) * ImMin(items_count, height_in_items) + (style.FramePadding.y * 3); - if (!BeginCombo(label, preview_text, popup_opened_height)) + if (!BeginCombo(label, preview_text, ImVec2(0.0f, popup_height))) return false; // Display items @@ -9119,7 +9126,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled) if (menu_is_open) { SetNextWindowPos(popup_pos, ImGuiCond_Always); - ImGuiWindowFlags flags = ImGuiWindowFlags_ShowBorders | ((window->Flags & (ImGuiWindowFlags_Popup|ImGuiWindowFlags_ChildMenu)) ? ImGuiWindowFlags_ChildMenu|ImGuiWindowFlags_ChildWindow : ImGuiWindowFlags_ChildMenu); + ImGuiWindowFlags flags = ImGuiWindowFlags_ShowBorders | ImGuiWindowFlags_AlwaysAutoResize | ((window->Flags & (ImGuiWindowFlags_Popup|ImGuiWindowFlags_ChildMenu)) ? ImGuiWindowFlags_ChildMenu|ImGuiWindowFlags_ChildWindow : ImGuiWindowFlags_ChildMenu); menu_is_open = BeginPopupEx(id, flags); // menu_is_open can be 'false' when the popup is completely clipped (e.g. zero size display) } diff --git a/imgui_internal.h b/imgui_internal.h index 8f6762bde..63bbb0437 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -788,7 +788,7 @@ namespace ImGui IMGUI_API void PushColumnClipRect(int column_index = -1); // FIXME-WIP: New Combo API - IMGUI_API bool BeginCombo(const char* label, const char* preview_value, float popup_opened_height); + IMGUI_API bool BeginCombo(const char* label, const char* preview_value, ImVec2 popup_size = ImVec2(0.0f,0.0f)); IMGUI_API void EndCombo(); // NB: All position are in absolute pixels coordinates (never using window coordinates internally) From 4b2781fe8761aa63d2f2625263de4560c4b5f00d Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 25 Sep 2017 21:57:42 +0200 Subject: [PATCH 362/921] Begin: Moving some code into a CalcSizeAutoFit() function. --- imgui.cpp | 48 +++++++++++++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 88d0fcbbd..ae9d74377 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3912,6 +3912,30 @@ static ImVec2 CalcSizeFullWithConstraint(ImGuiWindow* window, ImVec2 new_size) return new_size; } +static ImVec2 CalcSizeAutoFit(ImGuiWindow* window) +{ + ImGuiContext& g = *GImGui; + ImGuiStyle& style = g.Style; + ImGuiWindowFlags flags = window->Flags; + ImVec2 size_auto_fit; + if ((flags & ImGuiWindowFlags_Tooltip) != 0) + { + // Tooltip always resize. We keep the spacing symmetric on both axises for aesthetic purpose. + size_auto_fit = window->SizeContents + window->WindowPadding - ImVec2(0.0f, style.ItemSpacing.y); + } + else + { + // Handling case of auto fit window not fitting in screen on one axis, we are growing auto fit size on the other axis to compensate for expected scrollbar. FIXME: Might turn bigger than DisplaySize-WindowPadding. + size_auto_fit = ImClamp(window->SizeContents + window->WindowPadding, style.WindowMinSize, ImMax(style.WindowMinSize, g.IO.DisplaySize - g.Style.DisplaySafeAreaPadding)); + if (size_auto_fit.x < window->SizeContents.x && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar)) + size_auto_fit.y += style.ScrollbarSize; + if (size_auto_fit.y < window->SizeContents.y && !(flags & ImGuiWindowFlags_NoScrollbar)) + size_auto_fit.x += style.ScrollbarSize; + size_auto_fit.y = ImMax(size_auto_fit.y - style.ItemSpacing.y, 0.0f); + } + return size_auto_fit; +} + static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window) { ImVec2 scroll = window->Scroll; @@ -4002,7 +4026,7 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us if (window_pos_set_by_api && ImLengthSqr(g.SetNextWindowPosPivot) > 0.00001f) { // May be processed on the next frame if this is our first frame and we are measuring size - // FIXME: Look into removing the branch so everything can go through this same codepath for consistency. + // FIXME: Look into removing the branch so everything can go through this same code path for consistency. window->SetWindowPosVal = g.SetNextWindowPosVal; window->SetWindowPosPivot = g.SetNextWindowPosPivot; window->SetWindowPosAllowFlags &= ~(ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing); @@ -4122,26 +4146,8 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us // Lock window padding so that altering the ShowBorders flag for children doesn't have side-effects. window->WindowPadding = ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & (ImGuiWindowFlags_AlwaysUseWindowPadding | ImGuiWindowFlags_ShowBorders | ImGuiWindowFlags_ComboBox | ImGuiWindowFlags_Popup))) ? ImVec2(0,0) : style.WindowPadding; - // Calculate auto-fit size - ImVec2 size_auto_fit; - if ((flags & ImGuiWindowFlags_Tooltip) != 0) - { - // Tooltip always resize. We keep the spacing symmetric on both axises for aesthetic purpose. - size_auto_fit = window->SizeContents + window->WindowPadding - ImVec2(0.0f, style.ItemSpacing.y); - } - else - { - size_auto_fit = ImClamp(window->SizeContents + window->WindowPadding, style.WindowMinSize, ImMax(style.WindowMinSize, g.IO.DisplaySize - g.Style.DisplaySafeAreaPadding)); - - // Handling case of auto fit window not fitting in screen on one axis, we are growing auto fit size on the other axis to compensate for expected scrollbar. FIXME: Might turn bigger than DisplaySize-WindowPadding. - if (size_auto_fit.x < window->SizeContents.x && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar)) - size_auto_fit.y += style.ScrollbarSize; - if (size_auto_fit.y < window->SizeContents.y && !(flags & ImGuiWindowFlags_NoScrollbar)) - size_auto_fit.x += style.ScrollbarSize; - size_auto_fit.y = ImMax(size_auto_fit.y - style.ItemSpacing.y, 0.0f); - } - - // Handle automatic resize + // Calculate auto-fit size, handle automatic resize + const ImVec2 size_auto_fit = CalcSizeAutoFit(window); if (window->Collapsed) { // We still process initial auto-fit on collapsed windows to get a window width, From c0547d358d746699f8d46a4996e49fdac8c55748 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 25 Sep 2017 22:04:39 +0200 Subject: [PATCH 363/921] Begin: Fixed auto-fit calculation code that predict the presence of ascrollbar so it works in the case size constraints are used. I actually don't need this fix now, but earlier experiment with BeginCombo() required this fix. --- imgui.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index ae9d74377..8eb3319ff 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3925,12 +3925,13 @@ static ImVec2 CalcSizeAutoFit(ImGuiWindow* window) } else { - // Handling case of auto fit window not fitting in screen on one axis, we are growing auto fit size on the other axis to compensate for expected scrollbar. FIXME: Might turn bigger than DisplaySize-WindowPadding. + // Handling case of auto fit window not fitting on the screen (on either axis): we are growing the size on the other axis to compensate for expected scrollbar. FIXME: Might turn bigger than DisplaySize-WindowPadding. size_auto_fit = ImClamp(window->SizeContents + window->WindowPadding, style.WindowMinSize, ImMax(style.WindowMinSize, g.IO.DisplaySize - g.Style.DisplaySafeAreaPadding)); - if (size_auto_fit.x < window->SizeContents.x && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar)) + ImVec2 size_auto_fit_after_constraint = CalcSizeFullWithConstraint(window, size_auto_fit); + if (size_auto_fit_after_constraint.x < window->SizeContents.x && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar)) size_auto_fit.y += style.ScrollbarSize; - if (size_auto_fit.y < window->SizeContents.y && !(flags & ImGuiWindowFlags_NoScrollbar)) - size_auto_fit.x += style.ScrollbarSize; + if (size_auto_fit_after_constraint.y < window->SizeContents.y && !(flags & ImGuiWindowFlags_NoScrollbar)) + size_auto_fit.x += style.ScrollbarSize * 2.0f; size_auto_fit.y = ImMax(size_auto_fit.y - style.ItemSpacing.y, 0.0f); } return size_auto_fit; From 69d0d3345107ee0e26d767a236825465338a8310 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 25 Sep 2017 22:45:10 +0200 Subject: [PATCH 364/921] Exposed PushMultiItemsWidths() to imgui_internal.h --- imgui.cpp | 7 +++---- imgui_internal.h | 1 + 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 1e5f9c166..f392fc1cc 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -592,7 +592,6 @@ static void LogRenderedText(const ImVec2& ref_pos, const char* text, const char* text_end = NULL); -static void PushMultiItemsWidths(int components, float w_full = 0.0f); static float GetDraggedColumnOffset(int column_index); static bool IsKeyPressedMap(ImGuiKey key, bool repeat = true); @@ -4676,12 +4675,12 @@ void ImGui::PushItemWidth(float item_width) window->DC.ItemWidthStack.push_back(window->DC.ItemWidth); } -static void PushMultiItemsWidths(int components, float w_full) +void ImGui::PushMultiItemsWidths(int components, float w_full) { - ImGuiWindow* window = ImGui::GetCurrentWindow(); + ImGuiWindow* window = GetCurrentWindow(); const ImGuiStyle& style = GImGui->Style; if (w_full <= 0.0f) - w_full = ImGui::CalcItemWidth(); + w_full = CalcItemWidth(); const float w_item_one = ImMax(1.0f, (float)(int)((w_full - (style.ItemInnerSpacing.x) * (components-1)) / (float)components)); const float w_item_last = ImMax(1.0f, (float)(int)(w_full - (w_item_one + style.ItemInnerSpacing.x) * (components-1))); window->DC.ItemWidthStack.push_back(w_item_last); diff --git a/imgui_internal.h b/imgui_internal.h index 63bbb0437..cd78dbbdf 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -772,6 +772,7 @@ namespace ImGui IMGUI_API void FocusableItemUnregister(ImGuiWindow* window); IMGUI_API ImVec2 CalcItemSize(ImVec2 size, float default_x, float default_y); IMGUI_API float CalcWrapWidthForPos(const ImVec2& pos, float wrap_pos_x); + IMGUI_API void PushMultiItemsWidths(int components, float width_full = 0.0f); IMGUI_API void PushItemFlag(ImGuiItemFlags option, bool enabled); IMGUI_API void PopItemFlag(); From 82748df71af117605768c121652da90406e052bb Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 26 Sep 2017 01:12:09 +0200 Subject: [PATCH 365/921] WantCaptureMouse: Tweaked logic so WantCaptureMouse can stay false when e.g. hovering over void while an InputText() is active. (#621) --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index f392fc1cc..f212e76e8 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2295,7 +2295,7 @@ void ImGui::NewFrame() if (g.WantCaptureMouseNextFrame != -1) g.IO.WantCaptureMouse = (g.WantCaptureMouseNextFrame != 0); else - g.IO.WantCaptureMouse = (mouse_avail_to_imgui && (g.HoveredWindow != NULL || mouse_any_down)) || (g.ActiveId != 0) || (!g.OpenPopupStack.empty()); + g.IO.WantCaptureMouse = (mouse_avail_to_imgui && (g.HoveredWindow != NULL || mouse_any_down)) || (!g.OpenPopupStack.empty()); g.IO.WantCaptureKeyboard = (g.WantCaptureKeyboardNextFrame != -1) ? (g.WantCaptureKeyboardNextFrame != 0) : (g.ActiveId != 0); g.IO.WantTextInput = (g.WantTextInputNextFrame != -1) ? (g.WantTextInputNextFrame != 0) : 0; g.MouseCursor = ImGuiMouseCursor_Arrow; From 99b9f1c93c4fd8ae6edb707bd8e22c7ca58e3d7a Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 26 Sep 2017 11:23:06 +0200 Subject: [PATCH 366/921] Fix static misusage error with decent compilers. Error introduced in 4b82759598e34aed179177ecaa00e774c0d23484 --- imgui.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.h b/imgui.h index 4bfa9430d..c6008ff64 100644 --- a/imgui.h +++ b/imgui.h @@ -488,7 +488,7 @@ namespace ImGui // Obsolete functions (Will be removed! Also see 'API BREAKING CHANGES' section in imgui.cpp) #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS - static void SetNextWindowPosCenter(ImGuiCond cond = 0); // OBSOLETE 1.52+ + void SetNextWindowPosCenter(ImGuiCond cond = 0); // OBSOLETE 1.52+ static inline bool IsItemHoveredRect() { return IsItemRectHovered(); } // OBSOLETE 1.51+ static inline bool IsPosHoveringAnyWindow(const ImVec2&) { IM_ASSERT(0); return false; } // OBSOLETE 1.51+. This was partly broken. You probably wanted to use ImGui::GetIO().WantCaptureMouse instead. static inline bool IsMouseHoveringAnyWindow() { return IsAnyWindowHovered(); } // OBSOLETE 1.51+ From 728deff56c68baf06125bd0074bcda2095b92a00 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 26 Sep 2017 15:33:57 +0200 Subject: [PATCH 367/921] Comments, debug code (commented), todo list --- TODO.txt | 5 +++-- imgui.cpp | 8 ++++++-- imgui.h | 2 +- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/TODO.txt b/TODO.txt index 0369c6374..92535d08d 100644 --- a/TODO.txt +++ b/TODO.txt @@ -169,7 +169,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - tree node: tweak color scheme to distinguish headers from selected tree node (#581) !- settings: expose enough to save/load .ini from RAM instead of fopen - - settings: write more decent code to allow saving/loading new fields + - settings: write more decent code to allow saving/loading new fields: columns, selected tree nodes? - settings: api for per-tool simple persistent data (bool,int,float,columns sizes,etc.) in .ini file (#437) - stb: add defines to disable stb implementations @@ -231,7 +231,8 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - misc: fix for compilation settings where stdcall isn't the default (e.g. vectorcall) (#1230) - remote: make a system like RemoteImGui first-class citizen/project (#75) - - demo: demo: add a virtual scrolling example? + - demo: add vertical separator demo + - demo: add a virtual scrolling example? - examples: directx9: save/restore device state more thoroughly. - examples: window minimize, maximize (#583) - examples: provide a zero-framerate/idle example. diff --git a/imgui.cpp b/imgui.cpp index f212e76e8..621f763aa 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1912,12 +1912,12 @@ void ImGui::ItemSize(const ImVec2& size, float text_offset_y) ImGuiContext& g = *GImGui; const float line_height = ImMax(window->DC.CurrentLineHeight, size.y); const float text_base_offset = ImMax(window->DC.CurrentLineTextBaseOffset, text_offset_y); + //if (g.IO.KeyAlt) window->DrawList->AddRect(window->DC.CursorPos, window->DC.CursorPos + ImVec2(size.x, line_height), IM_COL32(255,0,0,200)); // [DEBUG] window->DC.CursorPosPrevLine = ImVec2(window->DC.CursorPos.x + size.x, window->DC.CursorPos.y); window->DC.CursorPos = ImVec2((float)(int)(window->Pos.x + window->DC.IndentX + window->DC.ColumnsOffsetX), (float)(int)(window->DC.CursorPos.y + line_height + g.Style.ItemSpacing.y)); window->DC.CursorMaxPos.x = ImMax(window->DC.CursorMaxPos.x, window->DC.CursorPosPrevLine.x); window->DC.CursorMaxPos.y = ImMax(window->DC.CursorMaxPos.y, window->DC.CursorPos.y); - - //window->DrawList->AddCircle(window->DC.CursorMaxPos, 3.0f, IM_COL32(255,0,0,255), 4); // Debug + //if (g.IO.KeyAlt) window->DrawList->AddCircle(window->DC.CursorMaxPos, 3.0f, IM_COL32(255,0,0,255), 4); // [DEBUG] window->DC.PrevLineHeight = line_height; window->DC.PrevLineTextBaseOffset = text_base_offset; @@ -1941,6 +1941,7 @@ bool ImGui::ItemAdd(const ImRect& bb, const ImGuiID* id) window->DC.LastItemHoveredAndUsable = window->DC.LastItemHoveredRect = false; if (IsClippedEx(bb, id, false)) return false; + //if (g.IO.KeyAlt) window->DrawList->AddRect(bb.Min, bb.Max, IM_COL32(255,255,0,120)); // [DEBUG] // Setting LastItemHoveredAndUsable for IsItemHovered(). This is a sensible default, but widgets are free to override it. if (IsMouseHoveringRect(bb.Min, bb.Max)) @@ -9053,6 +9054,8 @@ bool ImGui::BeginMenu(const char* label, bool enabled) ImVec2 popup_pos, pos = window->DC.CursorPos; if (window->DC.LayoutType == ImGuiLayoutType_Horizontal) { + // Menu inside an horizontal menu bar + // Selectable extend their highlight by half ItemSpacing in each direction. popup_pos = ImVec2(pos.x - window->WindowPadding.x, pos.y - style.FramePadding.y + window->MenuBarHeight()); window->DC.CursorPos.x += (float)(int)(style.ItemSpacing.x * 0.5f); PushStyleVar(ImGuiStyleVar_ItemSpacing, style.ItemSpacing * 2.0f); @@ -9064,6 +9067,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled) } else { + // Menu inside a menu popup_pos = ImVec2(pos.x, pos.y - style.WindowPadding.y); float w = window->MenuColumns.DeclColumns(label_size.x, 0.0f, (float)(int)(g.FontSize * 1.20f)); // Feedback to next frame float extra_w = ImMax(0.0f, GetContentRegionAvail().x - w); diff --git a/imgui.h b/imgui.h index c6008ff64..081cf8e49 100644 --- a/imgui.h +++ b/imgui.h @@ -381,7 +381,7 @@ namespace ImGui // Menus IMGUI_API bool BeginMainMenuBar(); // create and append to a full screen menu-bar. only call EndMainMenuBar() if this returns true! IMGUI_API void EndMainMenuBar(); - IMGUI_API bool BeginMenuBar(); // append to menu-bar of current window (requires ImGuiWindowFlags_MenuBar flag set). only call EndMenuBar() if this returns true! + IMGUI_API bool BeginMenuBar(); // append to menu-bar of current window (requires ImGuiWindowFlags_MenuBar flag set on parent window). only call EndMenuBar() if this returns true! IMGUI_API void EndMenuBar(); IMGUI_API bool BeginMenu(const char* label, bool enabled = true); // create a sub-menu entry. only call EndMenu() if this returns true! IMGUI_API void EndMenu(); From c7a606ab7ee67f01f49ee93084d03ea72d3d52b3 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 26 Sep 2017 15:42:55 +0200 Subject: [PATCH 368/921] Horizontal layout does the minimum job to be usable internally - not exposed (#97) --- imgui.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 621f763aa..7668c88a2 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1922,6 +1922,10 @@ void ImGui::ItemSize(const ImVec2& size, float text_offset_y) window->DC.PrevLineHeight = line_height; window->DC.PrevLineTextBaseOffset = text_base_offset; window->DC.CurrentLineHeight = window->DC.CurrentLineTextBaseOffset = 0.0f; + + // Horizontal layout mode + if (window->DC.LayoutType == ImGuiLayoutType_Horizontal) + SameLine(); } void ImGui::ItemSize(const ImRect& bb, float text_offset_y) @@ -9062,8 +9066,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled) float w = label_size.x; pressed = Selectable(label, menu_is_open, ImGuiSelectableFlags_Menu | ImGuiSelectableFlags_DontClosePopups | (!enabled ? ImGuiSelectableFlags_Disabled : 0), ImVec2(w, 0.0f)); PopStyleVar(); - SameLine(); - window->DC.CursorPos.x += (float)(int)(style.ItemSpacing.x * 0.5f); + window->DC.CursorPos.x += (float)(int)(style.ItemSpacing.x * (-1.0f + 0.5f)); // -1 spacing to compensate the spacing added when Selectable() did a SameLine(). It would also work to call SameLine() ourselves after the PopStyleVar(). } else { @@ -10053,10 +10056,15 @@ void ImGui::NewLine() ImGuiWindow* window = GetCurrentWindow(); if (window->SkipItems) return; + + ImGuiContext& g = *GImGui; + const ImGuiLayoutType backup_layout_type = window->DC.LayoutType; + window->DC.LayoutType = ImGuiLayoutType_Vertical; if (window->DC.CurrentLineHeight > 0.0f) // In the event that we are on a line with items that is smaller that FontSize high, we will preserve its height. ItemSize(ImVec2(0,0)); else - ItemSize(ImVec2(0.0f, GImGui->FontSize)); + ItemSize(ImVec2(0.0f, g.FontSize)); + window->DC.LayoutType = backup_layout_type; } void ImGui::NextColumn() From be03882a15b0a785dffba08a95fb265db23ffc14 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 26 Sep 2017 15:43:48 +0200 Subject: [PATCH 369/921] Separator(): output vertical separator when used in horizontal layout mode, so it works in menu bars. --- imgui.cpp | 67 +++++++++++++++++++++++++++++++++--------------- imgui_internal.h | 7 +++++ 2 files changed, 53 insertions(+), 21 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 7668c88a2..4aafd8845 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9893,37 +9893,62 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl // Horizontal separating line. void ImGui::Separator() { + ImGuiContext& g = *GImGui; ImGuiWindow* window = GetCurrentWindow(); if (window->SkipItems) return; - if (window->DC.ColumnsCount > 1) - PopClipRect(); + ImGuiWindowFlags flags = 0; + if ((flags & (ImGuiSeparatorFlags_Horizontal | ImGuiSeparatorFlags_Vertical)) == 0) + { + if (window->DC.LayoutType == ImGuiLayoutType_Horizontal) + flags |= ImGuiSeparatorFlags_Vertical; + else + flags |= ImGuiSeparatorFlags_Horizontal; + } + IM_ASSERT(ImIsPowerOfTwo((int)(flags & (ImGuiSeparatorFlags_Horizontal | ImGuiSeparatorFlags_Vertical)))); // Check that only 1 option is selected - float x1 = window->Pos.x; - float x2 = window->Pos.x + window->Size.x; - if (!window->DC.GroupStack.empty()) - x1 += window->DC.IndentX; - - const ImRect bb(ImVec2(x1, window->DC.CursorPos.y), ImVec2(x2, window->DC.CursorPos.y+1.0f)); - ItemSize(ImVec2(0.0f, 0.0f)); // NB: we don't provide our width so that it doesn't get feed back into AutoFit, we don't provide height to not alter layout. - if (!ItemAdd(bb, NULL)) + if (flags & ImGuiSeparatorFlags_Horizontal) { if (window->DC.ColumnsCount > 1) + PopClipRect(); + + float x1 = window->Pos.x; + float x2 = window->Pos.x + window->Size.x; + if (!window->DC.GroupStack.empty()) + x1 += window->DC.IndentX; + + const ImRect bb(ImVec2(x1, window->DC.CursorPos.y), ImVec2(x2, window->DC.CursorPos.y+1.0f)); + ItemSize(ImVec2(0.0f, 0.0f)); // NB: we don't provide our width so that it doesn't get feed back into AutoFit, we don't provide height to not alter layout. + if (!ItemAdd(bb, NULL)) + { + if (window->DC.ColumnsCount > 1) + PushColumnClipRect(); + return; + } + + window->DrawList->AddLine(bb.Min, ImVec2(bb.Max.x,bb.Min.y), GetColorU32(ImGuiCol_Separator)); + + if (g.LogEnabled) + LogText(IM_NEWLINE "--------------------------------"); + + if (window->DC.ColumnsCount > 1) + { PushColumnClipRect(); - return; + window->DC.ColumnsCellMinY = window->DC.CursorPos.y; + } } - - window->DrawList->AddLine(bb.Min, ImVec2(bb.Max.x,bb.Min.y), GetColorU32(ImGuiCol_Separator)); - - ImGuiContext& g = *GImGui; - if (g.LogEnabled) - LogText(IM_NEWLINE "--------------------------------"); - - if (window->DC.ColumnsCount > 1) + else if (flags & ImGuiSeparatorFlags_Vertical) { - PushColumnClipRect(); - window->DC.ColumnsCellMinY = window->DC.CursorPos.y; + const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(1.0f, window->DC.CurrentLineHeight)); + ItemSize(ImVec2(bb.GetWidth(), 0.0f)); + if (!ItemAdd(bb, NULL)) + return; + + window->DrawList->AddLine(ImVec2(bb.Min.x, bb.Min.y), ImVec2(bb.Min.x, bb.Max.y), GetColorU32(ImGuiCol_Separator)); + + if (g.LogEnabled) + LogText("|"); } } diff --git a/imgui_internal.h b/imgui_internal.h index cd78dbbdf..0e779a2a8 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -48,6 +48,7 @@ typedef int ImGuiLayoutType; // enum ImGuiLayoutType_ typedef int ImGuiButtonFlags; // enum ImGuiButtonFlags_ typedef int ImGuiTreeNodeFlags; // enum ImGuiTreeNodeFlags_ typedef int ImGuiSliderFlags; // enum ImGuiSliderFlags_ +typedef int ImGuiSeparatorFlags; // enum ImGuiSeparatorFlags_ typedef int ImGuiItemFlags; // enum ImGuiItemFlags_ //------------------------------------------------------------------------- @@ -203,6 +204,12 @@ enum ImGuiSelectableFlagsPrivate_ ImGuiSelectableFlags_DrawFillAvailWidth = 1 << 6 }; +enum ImGuiSeparatorFlags_ +{ + ImGuiSeparatorFlags_Horizontal = 1 << 0, // Axis default to current layout type, so generally Horizontal unless e.g. in a menu bar + ImGuiSeparatorFlags_Vertical = 1 << 1 +}; + // FIXME: this is in development, not exposed/functional as a generic feature yet. enum ImGuiLayoutType_ { From 529ca279a47bcc829e5ba9f14fa6bfb4a10d706a Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 26 Sep 2017 18:41:21 +0200 Subject: [PATCH 370/921] ImFont: Split some building code into a AddGlyph() helper (that custom rect code and imgui_freetype can use) --- imgui.h | 5 +++-- imgui_draw.cpp | 40 +++++++++++++++++++++++----------------- 2 files changed, 26 insertions(+), 19 deletions(-) diff --git a/imgui.h b/imgui.h index 081cf8e49..f655a1667 100644 --- a/imgui.h +++ b/imgui.h @@ -1387,7 +1387,7 @@ struct ImFontAtlas IMGUI_API const ImWchar* GetGlyphRangesCyrillic(); // Default + about 400 Cyrillic characters IMGUI_API const ImWchar* GetGlyphRangesThai(); // Default + Thai characters - // Helpers to build glyph ranges from text data. Feed all your application strings/characters to it then call BuildRanges(). + // Helpers to build glyph ranges from text data. Feed your application strings/characters to it then call BuildRanges(). struct GlyphRangesBuilder { ImVector UsedChars; // Store 1-bit per Unicode code point (0=unused, 1=used) @@ -1477,8 +1477,9 @@ struct ImFont IMGUI_API void RenderChar(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, unsigned short c) const; IMGUI_API void RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width = 0.0f, bool cpu_fine_clip = false) const; - // Private + // [Private] IMGUI_API void GrowIndex(int new_size); + IMGUI_API void AddGlyph(ImWchar c, float x0, float y0, float x1, float y1, float u0, float v0, float u1, float v1, float x_advance); IMGUI_API void AddRemapChar(ImWchar dst, ImWchar src, bool overwrite_dst = true); // Makes 'dst' character/glyph points to 'src' character/glyph. Currently needs to be called AFTER fonts have been built. }; diff --git a/imgui_draw.cpp b/imgui_draw.cpp index a28063975..3291c31ae 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1535,23 +1535,7 @@ bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas) stbtt_aligned_quad q; float dummy_x = 0.0f, dummy_y = 0.0f; stbtt_GetPackedQuad(range.chardata_for_range, atlas->TexWidth, atlas->TexHeight, char_idx, &dummy_x, &dummy_y, &q, 0); - - dst_font->Glyphs.resize(dst_font->Glyphs.Size + 1); - ImFont::Glyph& glyph = dst_font->Glyphs.back(); - glyph.Codepoint = (ImWchar)codepoint; - glyph.X0 = q.x0 + off_x; - glyph.Y0 = q.y0 + off_y; - glyph.X1 = q.x1 + off_x; - glyph.Y1 = q.y1 + off_y; - glyph.U0 = q.s0; - glyph.V0 = q.t0; - glyph.U1 = q.s1; - glyph.V1 = q.t1; - glyph.XAdvance = (pc.xadvance + cfg.GlyphExtraSpacing.x); // Bake spacing into XAdvance - - if (cfg.PixelSnapH) - glyph.XAdvance = (float)(int)(glyph.XAdvance + 0.5f); - dst_font->MetricsTotalSurface += (int)((glyph.U1 - glyph.U0) * atlas->TexWidth + 1.99f) * (int)((glyph.V1 - glyph.V0) * atlas->TexHeight + 1.99f); // +1 to account for average padding, +0.99 to round + dst_font->AddGlyph((ImWchar)codepoint, q.x0 + off_x, q.y0 + off_y, q.x1 + off_x, q.y1 + off_y, q.s0, q.t0, q.s1, q.t1, pc.xadvance); } } cfg.DstFont->BuildLookupTable(); @@ -1923,6 +1907,28 @@ void ImFont::GrowIndex(int new_size) IndexLookup.resize(new_size, (unsigned short)-1); } +void ImFont::AddGlyph(ImWchar codepoint, float x0, float y0, float x1, float y1, float u0, float v0, float u1, float v1, float x_advance) +{ + Glyphs.resize(Glyphs.Size + 1); + ImFont::Glyph& glyph = Glyphs.back(); + glyph.Codepoint = (ImWchar)codepoint; + glyph.X0 = x0; + glyph.Y0 = y0; + glyph.X1 = x1; + glyph.Y1 = y1; + glyph.U0 = u0; + glyph.V0 = v0; + glyph.U1 = u1; + glyph.V1 = v1; + glyph.XAdvance = (x_advance + ConfigData->GlyphExtraSpacing.x); // Bake spacing into XAdvance + + if (ConfigData->PixelSnapH) + glyph.XAdvance = (float)(int)(glyph.XAdvance + 0.5f); + + // Compute rough surface usage metrics (+1 to account for average padding, +0.99 to round) + MetricsTotalSurface += (int)((glyph.U1 - glyph.U0) * ContainerAtlas->TexWidth + 1.99f) * (int)((glyph.V1 - glyph.V0) * ContainerAtlas->TexHeight + 1.99f); +} + void ImFont::AddRemapChar(ImWchar dst, ImWchar src, bool overwrite_dst) { IM_ASSERT(IndexLookup.Size > 0); // Currently this can only be called AFTER the font has been built, aka after calling ImFontAtlas::GetTexDataAs*() function. From 2170b0b2789a71b3f45d87b8940830f50312f60d Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 26 Sep 2017 19:10:29 +0200 Subject: [PATCH 371/921] ImFontAtlas: Comments and minor reorganization of declaration in header file. --- imgui.h | 46 ++++++++++++++++++++++++++++------------------ imgui_draw.cpp | 5 +++-- 2 files changed, 31 insertions(+), 20 deletions(-) diff --git a/imgui.h b/imgui.h index f655a1667..1a221c0d0 100644 --- a/imgui.h +++ b/imgui.h @@ -1369,21 +1369,25 @@ struct ImFontAtlas 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() - // After loading the texture into your graphic system, store your texture handle in 'TexID' (ignore if you aren't using multiple fonts nor images) + // Build atlas, retrieve pixel data. + // User is in charge of copying the pixels into graphics memory (e.g. create a texture with your engine). Then store your texture handle with SetTexID(). // RGBA32 format is provided for convenience and high compatibility, but note that all RGB pixels are white, so 75% of the memory is wasted. // Pitch = Width * BytesPerPixels + IMGUI_API bool Build(); // Build pixels data. This is called automatically for you by the GetTexData*** functions. IMGUI_API void GetTexDataAsAlpha8(unsigned char** out_pixels, int* out_width, int* out_height, int* out_bytes_per_pixel = NULL); // 1 byte per-pixel IMGUI_API void GetTexDataAsRGBA32(unsigned char** out_pixels, int* out_width, int* out_height, int* out_bytes_per_pixel = NULL); // 4 bytes-per-pixel void SetTexID(ImTextureID id) { TexID = id; } + //------------------------------------------- + // Glyph Ranges + //------------------------------------------- + // Helpers to retrieve list of common Unicode ranges (2 value per range, values are inclusive, zero-terminated list) // NB: Make sure that your string are UTF-8 and NOT in your local code page. In C++11, you can create UTF-8 string literal using the u8"Hello world" syntax. See FAQ for details. IMGUI_API const ImWchar* GetGlyphRangesDefault(); // Basic Latin, Extended Latin IMGUI_API const ImWchar* GetGlyphRangesKorean(); // Default + Korean characters IMGUI_API const ImWchar* GetGlyphRangesJapanese(); // Default + Hiragana, Katakana, Half-Width, Selection of 1946 Ideographs - IMGUI_API const ImWchar* GetGlyphRangesChinese(); // Japanese + full set of about 21000 CJK Unified Ideographs + IMGUI_API const ImWchar* GetGlyphRangesChinese(); // Default + Japanese + full set of about 21000 CJK Unified Ideographs IMGUI_API const ImWchar* GetGlyphRangesCyrillic(); // Default + about 400 Cyrillic characters IMGUI_API const ImWchar* GetGlyphRangesThai(); // Default + Thai characters @@ -1400,17 +1404,9 @@ struct ImFontAtlas IMGUI_API void BuildRanges(ImVector* out_ranges); // Output new ranges }; - // Members - // (Access texture data via GetTexData*() calls which will setup a default font for you.) - ImTextureID TexID; // User data to refer to the texture once it has been uploaded to user's graphic systems. It is passed back to you during rendering via the ImDrawCmd structure. - unsigned char* TexPixelsAlpha8; // 1 component per pixel, each component is unsigned 8-bit. Total size = TexWidth * TexHeight - unsigned int* TexPixelsRGBA32; // 4 component per pixel, each component is unsigned 8-bit. Total size = TexWidth * TexHeight * 4 - int TexWidth; // Texture width calculated during Build(). - int TexHeight; // Texture height calculated during Build(). - int TexDesiredWidth; // Texture width desired by user before Build(). Must be a power-of-two. If have many glyphs your graphics API have texture size restrictions you may want to increase texture width to decrease height. - int TexGlyphPadding; // Padding between glyphs within texture in pixels. Defaults to 1. - ImVec2 TexUvWhitePixel; // Texture coordinates to a white pixel - ImVector Fonts; // Hold all the fonts returned by AddFont*. Fonts[0] is the default font upon calling ImGui::NewFrame(), use ImGui::PushFont()/PopFont() to change the current font. + //------------------------------------------- + // Custom Rectangles + //------------------------------------------- // [Private] User rectangle for packing custom texture data into the atlas. struct CustomRect @@ -1422,10 +1418,24 @@ struct ImFontAtlas bool IsPacked() const { return X != 0xFFFF; } }; - // [Private] Members + //------------------------------------------- + // Members + //------------------------------------------- + + ImTextureID TexID; // User data to refer to the texture once it has been uploaded to user's graphic systems. It is passed back to you during rendering via the ImDrawCmd structure. + int TexDesiredWidth; // Texture width desired by user before Build(). Must be a power-of-two. If have many glyphs your graphics API have texture size restrictions you may want to increase texture width to decrease height. + int TexGlyphPadding; // Padding between glyphs within texture in pixels. Defaults to 1. + + // [Private] + // NB: Access texture data via GetTexData*() calls! Which will setup a default font for you. + unsigned char* TexPixelsAlpha8; // 1 component per pixel, each component is unsigned 8-bit. Total size = TexWidth * TexHeight + unsigned int* TexPixelsRGBA32; // 4 component per pixel, each component is unsigned 8-bit. Total size = TexWidth * TexHeight * 4 + int TexWidth; // Texture width calculated during Build(). + int TexHeight; // Texture height calculated during Build(). + ImVec2 TexUvWhitePixel; // Texture coordinates to a white pixel + ImVector Fonts; // Hold all the fonts returned by AddFont*. Fonts[0] is the default font upon calling ImGui::NewFrame(), use ImGui::PushFont()/PopFont() to change the current font. ImVector CustomRects; // Rectangles for packing custom texture data into the atlas. ImVector ConfigData; // Internal data - IMGUI_API bool Build(); // Build pixels data. This is automatically for you by the GetTexData*** functions. IMGUI_API int CustomRectRegister(unsigned int id, int width, int height); IMGUI_API void CustomRectCalcUV(const CustomRect* rect, ImVec2* out_uv_min, ImVec2* out_uv_max); }; @@ -1438,7 +1448,7 @@ struct ImFont { ImWchar Codepoint; float XAdvance; - float X0, Y0, X1, Y1; + float X0, Y0, X1, Y1; // Glyph corners float U0, V0, U1, V1; // Texture coordinates }; diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 3291c31ae..f08259b11 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1101,10 +1101,11 @@ const char FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS[FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF ImFontAtlas::ImFontAtlas() { TexID = NULL; + TexDesiredWidth = 0; + TexGlyphPadding = 1; TexPixelsAlpha8 = NULL; TexPixelsRGBA32 = NULL; - TexWidth = TexHeight = TexDesiredWidth = 0; - TexGlyphPadding = 1; + TexWidth = TexHeight = 0; TexUvWhitePixel = ImVec2(0, 0); } From 072d6d8cb5a8bb66318ae5db7d23b3be74bf5ffe Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 26 Sep 2017 19:26:16 +0200 Subject: [PATCH 372/921] ImFontAtlas: Refactored internals API to 1) avoid building lookup table multiple times for merged fonts + 2) allow the mapping of custom icons inside fonts (wip, uncommited) --- imgui_draw.cpp | 16 ++++++++++++---- imgui_internal.h | 2 +- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index f08259b11..10627bfc8 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1539,7 +1539,6 @@ bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas) dst_font->AddGlyph((ImWchar)codepoint, q.x0 + off_x, q.y0 + off_y, q.x1 + off_x, q.y1 + off_y, q.s0, q.t0, q.s1, q.t1, pc.xadvance); } } - cfg.DstFont->BuildLookupTable(); } // Cleanup temporaries @@ -1547,8 +1546,7 @@ bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas) ImGui::MemFree(buf_ranges); ImGui::MemFree(tmp_array); - // Render into our custom data block - ImFontAtlasBuildRenderDefaultTexData(atlas); + ImFontAtlasBuildFinish(atlas); return true; } @@ -1600,7 +1598,7 @@ void ImFontAtlasBuildPackCustomRects(ImFontAtlas* atlas, void* pack_context_opaq } } -void ImFontAtlasBuildRenderDefaultTexData(ImFontAtlas* atlas) +static void ImFontAtlasBuildRenderDefaultTexData(ImFontAtlas* atlas) { ImFontAtlas::CustomRect& r = atlas->CustomRects[0]; IM_ASSERT(r.ID == FONT_ATLAS_DEFAULT_TEX_DATA_ID); @@ -1650,6 +1648,16 @@ void ImFontAtlasBuildRenderDefaultTexData(ImFontAtlas* atlas) } } +void ImFontAtlasBuildFinish(ImFontAtlas* atlas) +{ + // Render into our custom data block + ImFontAtlasBuildRenderDefaultTexData(atlas); + + // Build all fonts lookup tables + for (int i = 0; i < atlas->Fonts.Size; i++) + atlas->Fonts[i]->BuildLookupTable(); +} + // Retrieve list of range (2 int per range, values are inclusive) const ImWchar* ImFontAtlas::GetGlyphRangesDefault() { diff --git a/imgui_internal.h b/imgui_internal.h index 0e779a2a8..99b0f3afa 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -849,7 +849,7 @@ IMGUI_API bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas); IMGUI_API void ImFontAtlasBuildRegisterDefaultCustomRects(ImFontAtlas* atlas); IMGUI_API void ImFontAtlasBuildSetupFont(ImFontAtlas* atlas, ImFont* font, ImFontConfig* font_config, float ascent, float descent); IMGUI_API void ImFontAtlasBuildPackCustomRects(ImFontAtlas* atlas, void* spc); -IMGUI_API void ImFontAtlasBuildRenderDefaultTexData(ImFontAtlas* atlas); +IMGUI_API void ImFontAtlasBuildFinish(ImFontAtlas* atlas); IMGUI_API void ImFontAtlasBuildMultiplyCalcLookupTable(unsigned char out_table[256], float in_multiply_factor); IMGUI_API void ImFontAtlasBuildMultiplyRectAlpha8(const unsigned char table[256], unsigned char* pixels, int x, int y, int w, int h, int stride); From 10bb9524eb99ede4b86a3a0da72fc1fb92ebaaf0 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 26 Sep 2017 19:54:30 +0200 Subject: [PATCH 373/921] ImFont: Renamed ImFont::Glyph to ImFontGlyph (for consistency and so ImFontAtlas types can use it without ordering half of the file). Left a redirection type. --- imgui.cpp | 2 +- imgui.h | 28 ++++++++++++++++------------ imgui_demo.cpp | 4 ++-- imgui_draw.cpp | 10 +++++----- 4 files changed, 24 insertions(+), 20 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 4aafd8845..2409b9140 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -7847,7 +7847,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 // Password pushes a temporary font with only a fallback glyph if (is_password) { - const ImFont::Glyph* glyph = g.Font->FindGlyph('*'); + const ImFontGlyph* glyph = g.Font->FindGlyph('*'); ImFont* password_font = &g.InputTextPasswordFont; password_font->FontSize = g.Font->FontSize; password_font->Scale = g.Font->Scale; diff --git a/imgui.h b/imgui.h index 1a221c0d0..dd1d6b9f8 100644 --- a/imgui.h +++ b/imgui.h @@ -1332,7 +1332,7 @@ struct ImFontConfig float SizePixels; // // Size in pixels for rasterizer. int OversampleH, OversampleV; // 3, 1 // Rasterize at higher quality for sub-pixel positioning. We don't use sub-pixel positions on the Y axis. bool PixelSnapH; // false // Align every glyph to pixel boundary. Useful e.g. if you are merging a non-pixel aligned font with the default font. If enabled, you can set OversampleH/V to 1. - ImVec2 GlyphExtraSpacing; // 0, 0 // Extra spacing (in pixels) between glyphs. Only X axis is supported for now. + ImVec2 GlyphExtraSpacing; // 1, 0 // Extra spacing (in pixels) between glyphs. Only X axis is supported for now. ImVec2 GlyphOffset; // 0, 0 // Offset all glyphs from this font input. const ImWchar* GlyphRanges; // NULL // Pointer to a user-provided list of Unicode range (2 value per range, values are inclusive, zero-terminated list). THE ARRAY DATA NEEDS TO PERSIST AS LONG AS THE FONT IS ALIVE. bool MergeMode; // false // Merge into previous ImFont, so you can combine multiple inputs font into one ImFont (e.g. ASCII font + icons + Japanese glyphs). You may want to use GlyphOffset.y when merge font of different heights. @@ -1346,6 +1346,14 @@ struct ImFontConfig IMGUI_API ImFontConfig(); }; +struct ImFontGlyph +{ + ImWchar Codepoint; // 0x0000..0xFFFF + float XAdvance; // Distance to next character (= data from font + ImFontConfig::GlyphExtraSpacing.x baked in) + float X0, Y0, X1, Y1; // Glyph corners + float U0, V0, U1, V1; // Texture coordinates +}; + // Load and rasterize multiple TTF/OTF fonts into a same texture. // Sharing a texture for multiple fonts allows us to reduce the number of draw calls during rendering. // We also add custom graphic data into the texture that serves for ImGui. @@ -1444,22 +1452,14 @@ struct ImFontAtlas // ImFontAtlas automatically loads a default embedded font for you when you call GetTexDataAsAlpha8() or GetTexDataAsRGBA32(). struct ImFont { - struct Glyph - { - ImWchar Codepoint; - float XAdvance; - float X0, Y0, X1, Y1; // Glyph corners - float U0, V0, U1, V1; // Texture coordinates - }; - // Members: Hot ~62/78 bytes float FontSize; // // Height of characters, set during loading (don't change after loading) float Scale; // = 1.f // Base font scale, multiplied by the per-window font scale which you can adjust with SetFontScale() ImVec2 DisplayOffset; // = (0.f,1.f) // Offset font rendering by xx pixels - ImVector Glyphs; // // All glyphs. + ImVector Glyphs; // // All glyphs. ImVector IndexXAdvance; // // Sparse. Glyphs->XAdvance in a directly indexable way (more cache-friendly, for CalcTextSize functions which are often bottleneck in large UI). ImVector IndexLookup; // // Sparse. Index glyphs by Unicode code-point. - const Glyph* FallbackGlyph; // == FindGlyph(FontFallbackChar) + const ImFontGlyph* FallbackGlyph; // == FindGlyph(FontFallbackChar) float FallbackXAdvance; // == FallbackGlyph->XAdvance ImWchar FallbackChar; // = '?' // Replacement glyph if one isn't found. Only set via SetFallbackChar() @@ -1475,7 +1475,7 @@ struct ImFont IMGUI_API ~ImFont(); IMGUI_API void Clear(); IMGUI_API void BuildLookupTable(); - IMGUI_API const Glyph* FindGlyph(ImWchar c) const; + IMGUI_API const ImFontGlyph*FindGlyph(ImWchar c) const; IMGUI_API void SetFallbackChar(ImWchar c); float GetCharAdvance(ImWchar c) const { return ((int)c < IndexXAdvance.Size) ? IndexXAdvance[(int)c] : FallbackXAdvance; } bool IsLoaded() const { return ContainerAtlas != NULL; } @@ -1491,6 +1491,10 @@ struct ImFont IMGUI_API void GrowIndex(int new_size); IMGUI_API void AddGlyph(ImWchar c, float x0, float y0, float x1, float y1, float u0, float v0, float u1, float v1, float x_advance); IMGUI_API void AddRemapChar(ImWchar dst, ImWchar src, bool overwrite_dst = true); // Makes 'dst' character/glyph points to 'src' character/glyph. Currently needs to be called AFTER fonts have been built. + +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS + typedef ImFontGlyph Glyph; // OBSOLETE 1.52+ +#endif }; #if defined(__clang__) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 6773840f8..f52dcbfdc 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1926,7 +1926,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) if (ImGui::TreeNode("Glyphs", "Glyphs (%d)", font->Glyphs.Size)) { // Display all glyphs of the fonts in separate pages of 256 characters - const ImFont::Glyph* glyph_fallback = font->FallbackGlyph; // Forcefully/dodgily make FindGlyph() return NULL on fallback, which isn't the default behavior. + const ImFontGlyph* glyph_fallback = font->FallbackGlyph; // Forcefully/dodgily make FindGlyph() return NULL on fallback, which isn't the default behavior. font->FallbackGlyph = NULL; for (int base = 0; base < 0x10000; base += 256) { @@ -1943,7 +1943,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) { ImVec2 cell_p1(base_pos.x + (n % 16) * (cell_size.x + cell_spacing), base_pos.y + (n / 16) * (cell_size.y + cell_spacing)); ImVec2 cell_p2(cell_p1.x + cell_size.x, cell_p1.y + cell_size.y); - const ImFont::Glyph* glyph = font->FindGlyph((ImWchar)(base+n));; + const ImFontGlyph* glyph = font->FindGlyph((ImWchar)(base+n));; draw_list->AddRect(cell_p1, cell_p2, glyph ? IM_COL32(255,255,255,100) : IM_COL32(255,255,255,50)); font->RenderChar(draw_list, cell_size.x, cell_p1, ImGui::GetColorU32(ImGuiCol_Text), (ImWchar)(base+n)); // We use ImFont::RenderChar as a shortcut because we don't have UTF-8 conversion functions available to generate a string. if (glyph && ImGui::IsMouseHoveringRect(cell_p1, cell_p2)) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 10627bfc8..f02e56262 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1885,7 +1885,7 @@ void ImFont::BuildLookupTable() { if (Glyphs.back().Codepoint != '\t') // So we can call this function multiple times Glyphs.resize(Glyphs.Size + 1); - ImFont::Glyph& tab_glyph = Glyphs.back(); + ImFontGlyph& tab_glyph = Glyphs.back(); tab_glyph = *FindGlyph((unsigned short)' '); tab_glyph.Codepoint = '\t'; tab_glyph.XAdvance *= 4; @@ -1919,7 +1919,7 @@ void ImFont::GrowIndex(int new_size) void ImFont::AddGlyph(ImWchar codepoint, float x0, float y0, float x1, float y1, float u0, float v0, float u1, float v1, float x_advance) { Glyphs.resize(Glyphs.Size + 1); - ImFont::Glyph& glyph = Glyphs.back(); + ImFontGlyph& glyph = Glyphs.back(); glyph.Codepoint = (ImWchar)codepoint; glyph.X0 = x0; glyph.Y0 = y0; @@ -1953,7 +1953,7 @@ void ImFont::AddRemapChar(ImWchar dst, ImWchar src, bool overwrite_dst) IndexXAdvance[dst] = (src < index_size) ? IndexXAdvance.Data[src] : 1.0f; } -const ImFont::Glyph* ImFont::FindGlyph(unsigned short c) const +const ImFontGlyph* ImFont::FindGlyph(unsigned short c) const { if (c < IndexLookup.Size) { @@ -2161,7 +2161,7 @@ void ImFont::RenderChar(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col { if (c == ' ' || c == '\t' || c == '\n' || c == '\r') // Match behavior of RenderText(), those 4 codepoints are hard-coded. return; - if (const Glyph* glyph = FindGlyph(c)) + if (const ImFontGlyph* glyph = FindGlyph(c)) { float scale = (size >= 0.0f) ? (size / FontSize) : 1.0f; pos.x = (float)(int)pos.x + DisplayOffset.x; @@ -2265,7 +2265,7 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col } float char_width = 0.0f; - if (const Glyph* glyph = FindGlyph((unsigned short)c)) + if (const ImFontGlyph* glyph = FindGlyph((unsigned short)c)) { char_width = glyph->XAdvance * scale; From 9e1ad7295f34a749e1337e2ffff0a2f60dada591 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 26 Sep 2017 20:05:16 +0200 Subject: [PATCH 374/921] ImFont: Renamed (supposedly internal) fields (e.g. XAdvance to AdvanceX). Custom text renderers might be affected if they didn't use the GetCharAdvance() helper function. --- imgui.cpp | 6 +++--- imgui.h | 10 +++++----- imgui_demo.cpp | 2 +- imgui_draw.cpp | 36 ++++++++++++++++++------------------ 4 files changed, 27 insertions(+), 27 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 2409b9140..5faff4f56 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3065,7 +3065,7 @@ ImVec2 ImGui::CalcTextSize(const char* text, const char* text_end, bool hide_tex return ImVec2(0.0f, font_size); ImVec2 text_size = font->CalcTextSizeA(font_size, FLT_MAX, wrap_width, text, text_display_end, NULL); - // Cancel out character spacing for the last character of a line (it is baked into glyph->XAdvance field) + // Cancel out character spacing for the last character of a line (it is baked into glyph->AdvanceX field) const float font_scale = font_size / font->FontSize; const float character_spacing_x = 1.0f * font_scale; if (text_size.x > 0.0f) @@ -7856,8 +7856,8 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 password_font->Descent = g.Font->Descent; password_font->ContainerAtlas = g.Font->ContainerAtlas; password_font->FallbackGlyph = glyph; - password_font->FallbackXAdvance = glyph->XAdvance; - IM_ASSERT(password_font->Glyphs.empty() && password_font->IndexXAdvance.empty() && password_font->IndexLookup.empty()); + password_font->FallbackAdvanceX = glyph->AdvanceX; + IM_ASSERT(password_font->Glyphs.empty() && password_font->IndexAdvanceX.empty() && password_font->IndexLookup.empty()); PushFont(password_font); } diff --git a/imgui.h b/imgui.h index dd1d6b9f8..a4b0273eb 100644 --- a/imgui.h +++ b/imgui.h @@ -1349,7 +1349,7 @@ struct ImFontConfig struct ImFontGlyph { ImWchar Codepoint; // 0x0000..0xFFFF - float XAdvance; // Distance to next character (= data from font + ImFontConfig::GlyphExtraSpacing.x baked in) + float AdvanceX; // Distance to next character (= data from font + ImFontConfig::GlyphExtraSpacing.x baked in) float X0, Y0, X1, Y1; // Glyph corners float U0, V0, U1, V1; // Texture coordinates }; @@ -1457,10 +1457,10 @@ struct ImFont float Scale; // = 1.f // Base font scale, multiplied by the per-window font scale which you can adjust with SetFontScale() ImVec2 DisplayOffset; // = (0.f,1.f) // Offset font rendering by xx pixels ImVector Glyphs; // // All glyphs. - ImVector IndexXAdvance; // // Sparse. Glyphs->XAdvance in a directly indexable way (more cache-friendly, for CalcTextSize functions which are often bottleneck in large UI). + ImVector IndexAdvanceX; // // Sparse. Glyphs->AdvanceX in a directly indexable way (more cache-friendly, for CalcTextSize functions which are often bottleneck in large UI). ImVector IndexLookup; // // Sparse. Index glyphs by Unicode code-point. const ImFontGlyph* FallbackGlyph; // == FindGlyph(FontFallbackChar) - float FallbackXAdvance; // == FallbackGlyph->XAdvance + float FallbackAdvanceX; // == FallbackGlyph->AdvanceX ImWchar FallbackChar; // = '?' // Replacement glyph if one isn't found. Only set via SetFallbackChar() // Members: Cold ~18/26 bytes @@ -1477,7 +1477,7 @@ struct ImFont IMGUI_API void BuildLookupTable(); IMGUI_API const ImFontGlyph*FindGlyph(ImWchar c) const; IMGUI_API void SetFallbackChar(ImWchar c); - float GetCharAdvance(ImWchar c) const { return ((int)c < IndexXAdvance.Size) ? IndexXAdvance[(int)c] : FallbackXAdvance; } + float GetCharAdvance(ImWchar c) const { return ((int)c < IndexAdvanceX.Size) ? IndexAdvanceX[(int)c] : FallbackAdvanceX; } bool IsLoaded() const { return ContainerAtlas != NULL; } // 'max_width' stops rendering after a certain width (could be turned into a 2d size). FLT_MAX to disable. @@ -1489,7 +1489,7 @@ struct ImFont // [Private] IMGUI_API void GrowIndex(int new_size); - IMGUI_API void AddGlyph(ImWchar c, float x0, float y0, float x1, float y1, float u0, float v0, float u1, float v1, float x_advance); + IMGUI_API void AddGlyph(ImWchar c, float x0, float y0, float x1, float y1, float u0, float v0, float u1, float v1, float advance_x); IMGUI_API void AddRemapChar(ImWchar dst, ImWchar src, bool overwrite_dst = true); // Makes 'dst' character/glyph points to 'src' character/glyph. Currently needs to be called AFTER fonts have been built. #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS diff --git a/imgui_demo.cpp b/imgui_demo.cpp index f52dcbfdc..81e89db50 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1951,7 +1951,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) ImGui::BeginTooltip(); ImGui::Text("Codepoint: U+%04X", base+n); ImGui::Separator(); - ImGui::Text("XAdvance+1: %.1f", glyph->XAdvance); + ImGui::Text("AdvanceX: %.1f", glyph->AdvanceX); ImGui::Text("Pos: (%.2f,%.2f)->(%.2f,%.2f)", glyph->X0, glyph->Y0, glyph->X1, glyph->Y1); ImGui::Text("UV: (%.3f,%.3f)->(%.3f,%.3f)", glyph->U0, glyph->V0, glyph->U1, glyph->V1); ImGui::EndTooltip(); diff --git a/imgui_draw.cpp b/imgui_draw.cpp index f02e56262..f2e1a2b81 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1851,10 +1851,10 @@ void ImFont::Clear() FontSize = 0.0f; DisplayOffset = ImVec2(0.0f, 1.0f); Glyphs.clear(); - IndexXAdvance.clear(); + IndexAdvanceX.clear(); IndexLookup.clear(); FallbackGlyph = NULL; - FallbackXAdvance = 0.0f; + FallbackAdvanceX = 0.0f; ConfigDataCount = 0; ConfigData = NULL; ContainerAtlas = NULL; @@ -1869,13 +1869,13 @@ void ImFont::BuildLookupTable() max_codepoint = ImMax(max_codepoint, (int)Glyphs[i].Codepoint); IM_ASSERT(Glyphs.Size < 0xFFFF); // -1 is reserved - IndexXAdvance.clear(); + IndexAdvanceX.clear(); IndexLookup.clear(); GrowIndex(max_codepoint + 1); for (int i = 0; i < Glyphs.Size; i++) { int codepoint = (int)Glyphs[i].Codepoint; - IndexXAdvance[codepoint] = Glyphs[i].XAdvance; + IndexAdvanceX[codepoint] = Glyphs[i].AdvanceX; IndexLookup[codepoint] = (unsigned short)i; } @@ -1888,17 +1888,17 @@ void ImFont::BuildLookupTable() ImFontGlyph& tab_glyph = Glyphs.back(); tab_glyph = *FindGlyph((unsigned short)' '); tab_glyph.Codepoint = '\t'; - tab_glyph.XAdvance *= 4; - IndexXAdvance[(int)tab_glyph.Codepoint] = (float)tab_glyph.XAdvance; + tab_glyph.AdvanceX *= 4; + IndexAdvanceX[(int)tab_glyph.Codepoint] = (float)tab_glyph.AdvanceX; IndexLookup[(int)tab_glyph.Codepoint] = (unsigned short)(Glyphs.Size-1); } FallbackGlyph = NULL; FallbackGlyph = FindGlyph(FallbackChar); - FallbackXAdvance = FallbackGlyph ? FallbackGlyph->XAdvance : 0.0f; + FallbackAdvanceX = FallbackGlyph ? FallbackGlyph->AdvanceX : 0.0f; for (int i = 0; i < max_codepoint + 1; i++) - if (IndexXAdvance[i] < 0.0f) - IndexXAdvance[i] = FallbackXAdvance; + if (IndexAdvanceX[i] < 0.0f) + IndexAdvanceX[i] = FallbackAdvanceX; } void ImFont::SetFallbackChar(ImWchar c) @@ -1909,14 +1909,14 @@ void ImFont::SetFallbackChar(ImWchar c) void ImFont::GrowIndex(int new_size) { - IM_ASSERT(IndexXAdvance.Size == IndexLookup.Size); + IM_ASSERT(IndexAdvanceX.Size == IndexLookup.Size); if (new_size <= IndexLookup.Size) return; - IndexXAdvance.resize(new_size, -1.0f); + IndexAdvanceX.resize(new_size, -1.0f); IndexLookup.resize(new_size, (unsigned short)-1); } -void ImFont::AddGlyph(ImWchar codepoint, float x0, float y0, float x1, float y1, float u0, float v0, float u1, float v1, float x_advance) +void ImFont::AddGlyph(ImWchar codepoint, float x0, float y0, float x1, float y1, float u0, float v0, float u1, float v1, float advance_x) { Glyphs.resize(Glyphs.Size + 1); ImFontGlyph& glyph = Glyphs.back(); @@ -1929,10 +1929,10 @@ void ImFont::AddGlyph(ImWchar codepoint, float x0, float y0, float x1, float y1, glyph.V0 = v0; glyph.U1 = u1; glyph.V1 = v1; - glyph.XAdvance = (x_advance + ConfigData->GlyphExtraSpacing.x); // Bake spacing into XAdvance + glyph.AdvanceX = (advance_x + ConfigData->GlyphExtraSpacing.x); // Bake spacing into AdvanceX if (ConfigData->PixelSnapH) - glyph.XAdvance = (float)(int)(glyph.XAdvance + 0.5f); + glyph.AdvanceX = (float)(int)(glyph.AdvanceX + 0.5f); // Compute rough surface usage metrics (+1 to account for average padding, +0.99 to round) MetricsTotalSurface += (int)((glyph.U1 - glyph.U0) * ContainerAtlas->TexWidth + 1.99f) * (int)((glyph.V1 - glyph.V0) * ContainerAtlas->TexHeight + 1.99f); @@ -1950,7 +1950,7 @@ void ImFont::AddRemapChar(ImWchar dst, ImWchar src, bool overwrite_dst) GrowIndex(dst + 1); IndexLookup[dst] = (src < index_size) ? IndexLookup.Data[src] : (unsigned short)-1; - IndexXAdvance[dst] = (src < index_size) ? IndexXAdvance.Data[src] : 1.0f; + IndexAdvanceX[dst] = (src < index_size) ? IndexAdvanceX.Data[src] : 1.0f; } const ImFontGlyph* ImFont::FindGlyph(unsigned short c) const @@ -2018,7 +2018,7 @@ const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, const c } } - const float char_width = ((int)c < IndexXAdvance.Size ? IndexXAdvance[(int)c] : FallbackXAdvance); + const float char_width = ((int)c < IndexAdvanceX.Size ? IndexAdvanceX[(int)c] : FallbackAdvanceX); if (ImCharIsSpace(c)) { if (inside_word) @@ -2135,7 +2135,7 @@ ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, cons continue; } - const float char_width = ((int)c < IndexXAdvance.Size ? IndexXAdvance[(int)c] : FallbackXAdvance) * scale; + const float char_width = ((int)c < IndexAdvanceX.Size ? IndexAdvanceX[(int)c] : FallbackAdvanceX) * scale; if (line_width + char_width >= max_width) { s = prev_s; @@ -2267,7 +2267,7 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col float char_width = 0.0f; if (const ImFontGlyph* glyph = FindGlyph((unsigned short)c)) { - char_width = glyph->XAdvance * scale; + char_width = glyph->AdvanceX * scale; // Arbitrarily assume that both space and tabs are empty glyphs as an optimization if (c != ' ' && c != '\t') From 501e73feedf603b22e3e4ea428f745d6992930eb Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 26 Sep 2017 20:18:14 +0200 Subject: [PATCH 375/921] Minor comments --- imgui.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/imgui.h b/imgui.h index a4b0273eb..8d5b13ebc 100644 --- a/imgui.h +++ b/imgui.h @@ -864,7 +864,7 @@ struct ImGuiIO ImVec2 MouseDelta; // Mouse delta. Note that this is zero if either current or previous position are negative, so a disappearing/reappearing mouse won't have a huge delta for one frame. //------------------------------------------------------------------ - // [Private] ImGui will maintain those fields. Forward compatibility not guaranteed! + // [Internal] ImGui will maintain those fields. Forward compatibility not guaranteed! //------------------------------------------------------------------ ImVec2 MousePosPrev; // Previous mouse position temporary storage (nb: not for public use, set to MousePos in NewFrame()) @@ -1379,12 +1379,12 @@ struct ImFontAtlas // Build atlas, retrieve pixel data. // User is in charge of copying the pixels into graphics memory (e.g. create a texture with your engine). Then store your texture handle with SetTexID(). - // RGBA32 format is provided for convenience and high compatibility, but note that all RGB pixels are white, so 75% of the memory is wasted. + // RGBA32 format is provided for convenience and compatibility, but note that unless you use CustomRect to draw color data, the RGB pixels emitted from Fonts will all be white (~75% of waste). // Pitch = Width * BytesPerPixels IMGUI_API bool Build(); // Build pixels data. This is called automatically for you by the GetTexData*** functions. IMGUI_API void GetTexDataAsAlpha8(unsigned char** out_pixels, int* out_width, int* out_height, int* out_bytes_per_pixel = NULL); // 1 byte per-pixel IMGUI_API void GetTexDataAsRGBA32(unsigned char** out_pixels, int* out_width, int* out_height, int* out_bytes_per_pixel = NULL); // 4 bytes-per-pixel - void SetTexID(ImTextureID id) { TexID = id; } + void SetTexID(ImTextureID id) { TexID = id; } //------------------------------------------- // Glyph Ranges @@ -1434,7 +1434,7 @@ struct ImFontAtlas int TexDesiredWidth; // Texture width desired by user before Build(). Must be a power-of-two. If have many glyphs your graphics API have texture size restrictions you may want to increase texture width to decrease height. int TexGlyphPadding; // Padding between glyphs within texture in pixels. Defaults to 1. - // [Private] + // [Internal] // NB: Access texture data via GetTexData*() calls! Which will setup a default font for you. unsigned char* TexPixelsAlpha8; // 1 component per pixel, each component is unsigned 8-bit. Total size = TexWidth * TexHeight unsigned int* TexPixelsRGBA32; // 4 component per pixel, each component is unsigned 8-bit. Total size = TexWidth * TexHeight * 4 @@ -1487,7 +1487,7 @@ struct ImFont IMGUI_API void RenderChar(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, unsigned short c) const; IMGUI_API void RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width = 0.0f, bool cpu_fine_clip = false) const; - // [Private] + // [Internal] IMGUI_API void GrowIndex(int new_size); IMGUI_API void AddGlyph(ImWchar c, float x0, float y0, float x1, float y1, float u0, float v0, float u1, float v1, float advance_x); IMGUI_API void AddRemapChar(ImWchar dst, ImWchar src, bool overwrite_dst = true); // Makes 'dst' character/glyph points to 'src' character/glyph. Currently needs to be called AFTER fonts have been built. From 3fe2ecfd4cd34367b505fba38941217a3cc89f1d Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 26 Sep 2017 20:24:27 +0200 Subject: [PATCH 376/921] ImFontAtlas: Added support for CustomRect API to submit custom rectangles to be packed into the atlas / and map them as font glyphs --- imgui.h | 21 +++++++++++++++------ imgui_draw.cpp | 50 +++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 56 insertions(+), 15 deletions(-) diff --git a/imgui.h b/imgui.h index 8d5b13ebc..185a31355 100644 --- a/imgui.h +++ b/imgui.h @@ -1413,19 +1413,29 @@ struct ImFontAtlas }; //------------------------------------------- - // Custom Rectangles + // Custom Rectangles/Glyphs API //------------------------------------------- - // [Private] User rectangle for packing custom texture data into the atlas. + // You can request arbitrary rectangles to be packed into the atlas, for your own purposes. After calling Build(), you can query the rectangle position and render your pixels. + // You can also request your rectangles to be mapped as font glyph (given a font + Unicode point), so you can render e.g. custom colorful icons and use them as regular glyphs. struct CustomRect { - unsigned int ID; // Input // User ID. <0x10000 for font mapped data (WIP/UNSUPPORTED), >=0x10000 for other texture data + unsigned int ID; // Input // User ID. Use <0x10000 to map into a font glyph, >=0x10000 for other/internal/custom texture data. unsigned short Width, Height; // Input // Desired rectangle dimension unsigned short X, Y; // Output // Packed position in Atlas - CustomRect() { ID = 0xFFFFFFFF; Width = Height = 0; X = Y = 0xFFFF; } + float GlyphAdvanceX; // Input // For custom font glyphs only (ID<0x10000): glyph xadvance + ImVec2 GlyphOffset; // Input // For custom font glyphs only (ID<0x10000): glyph display offset + ImFont* Font; // Input // For custom font glyphs only (ID<0x10000): target font + CustomRect() { ID = 0xFFFFFFFF; Width = Height = 0; X = Y = 0xFFFF; GlyphAdvanceX = 0.0f; GlyphOffset = ImVec2(0,0); Font = NULL; } bool IsPacked() const { return X != 0xFFFF; } }; + IMGUI_API int AddCustomRectRegular(unsigned int id, int width, int height); // Id needs to be >= 0x10000. Id >= 0x80000000 are reserved for ImGui and ImDrawList + IMGUI_API int AddCustomRectFontGlyph(ImFont* font, ImWchar id, int width, int height, float advance_x, const ImVec2& offset = ImVec2(0,0)); // Id needs to be < 0x10000 to register a rectangle to map into a specific font. + IMGUI_API void ClearCustomRects(); + IMGUI_API void CalcCustomRectUV(const CustomRect* rect, ImVec2* out_uv_min, ImVec2* out_uv_max); + const CustomRect* GetCustomRectByIndex(int index) const { if (index < 0) return NULL; return &CustomRects[index]; } + //------------------------------------------- // Members //------------------------------------------- @@ -1444,8 +1454,7 @@ struct ImFontAtlas ImVector Fonts; // Hold all the fonts returned by AddFont*. Fonts[0] is the default font upon calling ImGui::NewFrame(), use ImGui::PushFont()/PopFont() to change the current font. ImVector CustomRects; // Rectangles for packing custom texture data into the atlas. ImVector ConfigData; // Internal data - IMGUI_API int CustomRectRegister(unsigned int id, int width, int height); - IMGUI_API void CustomRectCalcUV(const CustomRect* rect, ImVec2* out_uv_min, ImVec2* out_uv_max); + int CustomRectIds[1]; // Identifiers of custom texture rectangle used by ImFontAtlas/ImDrawList }; // Font runtime data and rendering diff --git a/imgui_draw.cpp b/imgui_draw.cpp index f2e1a2b81..aee9374d5 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1066,7 +1066,7 @@ ImFontConfig::ImFontConfig() // The white texels on the top left are the ones we'll use everywhere in ImGui to render filled shapes. const int FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF = 90; const int FONT_ATLAS_DEFAULT_TEX_DATA_H = 27; -const int FONT_ATLAS_DEFAULT_TEX_DATA_ID = 0xF0000; +const unsigned int FONT_ATLAS_DEFAULT_TEX_DATA_ID = 0x80000000; const char FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS[FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF * FONT_ATLAS_DEFAULT_TEX_DATA_H + 1] = { "..- -XXXXXXX- X - X -XXXXXXX - XXXXXXX" @@ -1107,6 +1107,8 @@ ImFontAtlas::ImFontAtlas() TexPixelsRGBA32 = NULL; TexWidth = TexHeight = 0; TexUvWhitePixel = ImVec2(0, 0); + for (int n = 0; n < IM_ARRAYSIZE(CustomRectIds); n++) + CustomRectIds[n] = -1; } ImFontAtlas::~ImFontAtlas() @@ -1123,7 +1125,7 @@ void ImFontAtlas::ClearInputData() ConfigData[i].FontData = NULL; } - // When clearing this we lose access to the font name and other information used to build the font. + // When clearing this we lose access to the font name and other information used to build the font. for (int i = 0; i < Fonts.Size; i++) if (Fonts[i]->ConfigData >= ConfigData.Data && Fonts[i]->ConfigData < ConfigData.Data + ConfigData.Size) { @@ -1319,8 +1321,9 @@ ImFont* ImFontAtlas::AddFontFromMemoryCompressedBase85TTF(const char* compressed return font; } -int ImFontAtlas::CustomRectRegister(unsigned int id, int width, int height) +int ImFontAtlas::AddCustomRectRegular(unsigned int id, int width, int height) { + IM_ASSERT(id >= 0x10000); IM_ASSERT(width > 0 && width <= 0xFFFF); IM_ASSERT(height > 0 && height <= 0xFFFF); CustomRect r; @@ -1331,7 +1334,23 @@ int ImFontAtlas::CustomRectRegister(unsigned int id, int width, int height) return CustomRects.Size - 1; // Return index } -void ImFontAtlas::CustomRectCalcUV(const CustomRect* rect, ImVec2* out_uv_min, ImVec2* out_uv_max) +int ImFontAtlas::AddCustomRectFontGlyph(ImFont* font, ImWchar id, int width, int height, float advance_x, const ImVec2& offset) +{ + IM_ASSERT(font != NULL); + IM_ASSERT(width > 0 && width <= 0xFFFF); + IM_ASSERT(height > 0 && height <= 0xFFFF); + CustomRect r; + r.ID = id; + r.Width = (unsigned short)width; + r.Height = (unsigned short)height; + r.GlyphAdvanceX = advance_x; + r.GlyphOffset = offset; + r.Font = font; + CustomRects.push_back(r); + return CustomRects.Size - 1; // Return index +} + +void ImFontAtlas::CalcCustomRectUV(const CustomRect* rect, ImVec2* out_uv_min, ImVec2* out_uv_max) { IM_ASSERT(TexWidth > 0 && TexHeight > 0); // Font atlas needs to be built before we can calculate UV coordinates IM_ASSERT(rect->IsPacked()); // Make sure the rectangle has been packed @@ -1553,9 +1572,8 @@ bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas) void ImFontAtlasBuildRegisterDefaultCustomRects(ImFontAtlas* atlas) { - // FIXME-WIP: We should register in the constructor (but cannot because our static instances may not have allocator ready by the time they initialize). This needs to be fixed because we can expose CustomRects. - if (atlas->CustomRects.empty()) - atlas->CustomRectRegister(FONT_ATLAS_DEFAULT_TEX_DATA_ID, FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF*2+1, FONT_ATLAS_DEFAULT_TEX_DATA_H); + if (atlas->CustomRectIds[0] < 0) + atlas->CustomRectIds[0] = atlas->AddCustomRectRegular(FONT_ATLAS_DEFAULT_TEX_DATA_ID, FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF*2+1, FONT_ATLAS_DEFAULT_TEX_DATA_H); } void ImFontAtlasBuildSetupFont(ImFontAtlas* atlas, ImFont* font, ImFontConfig* font_config, float ascent, float descent) @@ -1600,7 +1618,8 @@ void ImFontAtlasBuildPackCustomRects(ImFontAtlas* atlas, void* pack_context_opaq static void ImFontAtlasBuildRenderDefaultTexData(ImFontAtlas* atlas) { - ImFontAtlas::CustomRect& r = atlas->CustomRects[0]; + IM_ASSERT(atlas->CustomRectIds[0] >= 0); + ImFontAtlas::CustomRect& r = atlas->CustomRects[atlas->CustomRectIds[0]]; IM_ASSERT(r.ID == FONT_ATLAS_DEFAULT_TEX_DATA_ID); IM_ASSERT(r.Width == FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF*2+1); IM_ASSERT(r.Height == FONT_ATLAS_DEFAULT_TEX_DATA_H); @@ -1653,6 +1672,19 @@ void ImFontAtlasBuildFinish(ImFontAtlas* atlas) // Render into our custom data block ImFontAtlasBuildRenderDefaultTexData(atlas); + // Register custom rectangle glyphs + for (int i = 0; i < atlas->CustomRects.Size; i++) + { + const ImFontAtlas::CustomRect& r = atlas->CustomRects[i]; + if (r.Font == NULL || r.ID > 0x10000) + continue; + + IM_ASSERT(r.Font->ContainerAtlas == atlas); + ImVec2 uv0, uv1; + atlas->CalcCustomRectUV(&r, &uv0, &uv1); + r.Font->AddGlyph((ImWchar)r.ID, r.GlyphOffset.x, r.GlyphOffset.y, r.GlyphOffset.x + r.Width, r.GlyphOffset.y + r.Height, uv0.x, uv0.y, uv1.x, uv1.y, r.GlyphAdvanceX); + } + // Build all fonts lookup tables for (int i = 0; i < atlas->Fonts.Size; i++) atlas->Fonts[i]->BuildLookupTable(); @@ -1929,7 +1961,7 @@ void ImFont::AddGlyph(ImWchar codepoint, float x0, float y0, float x1, float y1, glyph.V0 = v0; glyph.U1 = u1; glyph.V1 = v1; - glyph.AdvanceX = (advance_x + ConfigData->GlyphExtraSpacing.x); // Bake spacing into AdvanceX + glyph.AdvanceX = advance_x + ConfigData->GlyphExtraSpacing.x; // Bake spacing into AdvanceX if (ConfigData->PixelSnapH) glyph.AdvanceX = (float)(int)(glyph.AdvanceX + 0.5f); From bbd6d5d5b55363437dc2528b4bd23b7a00aba1e3 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 27 Sep 2017 00:20:09 +0200 Subject: [PATCH 377/921] Combo: Cleaned up, removed unnecessary code (looks like this part went untouched for a long time!). --- imgui.cpp | 29 +++++++---------------------- 1 file changed, 7 insertions(+), 22 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 5faff4f56..2ac7d20c5 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -8632,7 +8632,10 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImVec2 popu return false; const float arrow_size = SmallSquareSize(); - const bool hovered = IsHovered(frame_bb, id); + + bool hovered, held; + bool pressed = ButtonBehavior(frame_bb, id, &hovered, &held); + bool popup_open = IsPopupOpen(id); const ImRect value_bb(frame_bb.Min, frame_bb.Max - ImVec2(arrow_size, 0.0f)); @@ -8646,28 +8649,10 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImVec2 popu if (label_size.x > 0) RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label); - bool popup_toggled = false; - if (hovered) + if (pressed && !popup_open) { - SetHoveredID(id); - if (g.IO.MouseClicked[0]) - { - ClearActiveID(); - popup_toggled = true; - } - } - if (popup_toggled) - { - if (popup_open) - { - ClosePopup(id); - } - else - { - FocusWindow(window); - OpenPopupEx(id, false); - } - popup_open = !popup_open; + OpenPopupEx(id, false); + popup_open = true; } if (!popup_open) From 09f6f564d91ae061bfe35763c8e738e9f7255774 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 27 Sep 2017 11:21:42 +0200 Subject: [PATCH 378/921] ImFontAtlas: Fixed calling Clear() and rebuilding (broken in 3fe2ecfd4cd34367b505fba38941217a3cc89f1d) thanks @pdoane @mikesart --- imgui.h | 1 - imgui_draw.cpp | 4 ++++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/imgui.h b/imgui.h index 185a31355..48eda19c8 100644 --- a/imgui.h +++ b/imgui.h @@ -1432,7 +1432,6 @@ struct ImFontAtlas IMGUI_API int AddCustomRectRegular(unsigned int id, int width, int height); // Id needs to be >= 0x10000. Id >= 0x80000000 are reserved for ImGui and ImDrawList IMGUI_API int AddCustomRectFontGlyph(ImFont* font, ImWchar id, int width, int height, float advance_x, const ImVec2& offset = ImVec2(0,0)); // Id needs to be < 0x10000 to register a rectangle to map into a specific font. - IMGUI_API void ClearCustomRects(); IMGUI_API void CalcCustomRectUV(const CustomRect* rect, ImVec2* out_uv_min, ImVec2* out_uv_max); const CustomRect* GetCustomRectByIndex(int index) const { if (index < 0) return NULL; return &CustomRects[index]; } diff --git a/imgui_draw.cpp b/imgui_draw.cpp index aee9374d5..736476891 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1134,6 +1134,8 @@ void ImFontAtlas::ClearInputData() } ConfigData.clear(); CustomRects.clear(); + for (int n = 0; n < IM_ARRAYSIZE(CustomRectIds); n++) + CustomRectIds[n] = -1; } void ImFontAtlas::ClearTexData() @@ -1597,6 +1599,8 @@ void ImFontAtlasBuildPackCustomRects(ImFontAtlas* atlas, void* pack_context_opaq stbrp_context* pack_context = (stbrp_context*)pack_context_opaque; ImVector& user_rects = atlas->CustomRects; + IM_ASSERT(user_rects.Size >= 1); // We expect at least the default custom rects to be registered, else something went wrong. + ImVector pack_rects; pack_rects.resize(user_rects.Size); memset(pack_rects.Data, 0, sizeof(stbrp_rect) * user_rects.Size); From 8374a454daf5588386dbb374f8616b6d4329eec2 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 27 Sep 2017 11:39:13 +0200 Subject: [PATCH 379/921] Removed extraneous ImGui:: prefixes. Declared ColorEditOptionsPopup in imgui_internals.h. Tweaked internal signatures. --- imgui.cpp | 67 ++++++++++++++++++++++++------------------------ imgui_internal.h | 3 ++- 2 files changed, 36 insertions(+), 34 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 2ac7d20c5..a3d66b25c 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3629,7 +3629,7 @@ bool ImGui::BeginPopupModal(const char* name, bool* p_open, ImGuiWindowFlags ext SetNextWindowPos(g.IO.DisplaySize * 0.5f, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f)); ImGuiWindowFlags flags = extra_flags|ImGuiWindowFlags_Popup|ImGuiWindowFlags_Modal|ImGuiWindowFlags_NoCollapse|ImGuiWindowFlags_NoSavedSettings; - bool is_open = ImGui::Begin(name, p_open, flags); + bool is_open = Begin(name, p_open, flags); if (!is_open || (p_open && !*p_open)) // NB: is_open can be 'false' when the popup is completely clipped (e.g. zero size display) { EndPopup(); @@ -3646,9 +3646,9 @@ void ImGui::EndPopup() ImGuiWindow* window = GetCurrentWindow(); IM_ASSERT(window->Flags & ImGuiWindowFlags_Popup); // Mismatched BeginPopup()/EndPopup() calls IM_ASSERT(GImGui->CurrentPopupStack.Size > 0); - ImGui::End(); + End(); if (!(window->Flags & ImGuiWindowFlags_Modal)) - ImGui::PopStyleVar(); + PopStyleVar(); } // This is a helper to handle the most simple case of associating one named popup to one given widget. @@ -3758,17 +3758,17 @@ bool ImGui::BeginChildFrame(ImGuiID id, const ImVec2& size, ImGuiWindowFlags ext { ImGuiContext& g = *GImGui; const ImGuiStyle& style = g.Style; - ImGui::PushStyleColor(ImGuiCol_ChildWindowBg, style.Colors[ImGuiCol_FrameBg]); - ImGui::PushStyleVar(ImGuiStyleVar_ChildWindowRounding, style.FrameRounding); - ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, style.FramePadding); - return ImGui::BeginChild(id, size, (g.CurrentWindow->Flags & ImGuiWindowFlags_ShowBorders) ? true : false, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysUseWindowPadding | extra_flags); + PushStyleColor(ImGuiCol_ChildWindowBg, style.Colors[ImGuiCol_FrameBg]); + PushStyleVar(ImGuiStyleVar_ChildWindowRounding, style.FrameRounding); + PushStyleVar(ImGuiStyleVar_WindowPadding, style.FramePadding); + return BeginChild(id, size, (g.CurrentWindow->Flags & ImGuiWindowFlags_ShowBorders) ? true : false, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysUseWindowPadding | extra_flags); } void ImGui::EndChildFrame() { - ImGui::EndChild(); - ImGui::PopStyleVar(2); - ImGui::PopStyleColor(); + EndChild(); + PopStyleVar(2); + PopStyleColor(); } // Save and compare stack sizes on Begin()/End() to detect usage errors @@ -5161,7 +5161,7 @@ void ImGui::SetNextWindowPos(const ImVec2& pos, ImGuiCond cond, const ImVec2& pi #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS void ImGui::SetNextWindowPosCenter(ImGuiCond cond) { - SetNextWindowPos(ImGui::GetIO().DisplaySize * 0.5f, cond, ImVec2(0.5f, 0.5f)); + SetNextWindowPos(GetIO().DisplaySize * 0.5f, cond, ImVec2(0.5f, 0.5f)); } #endif @@ -9137,7 +9137,7 @@ void ImGui::EndMenu() } // Note: only access 3 floats if ImGuiColorEditFlags_NoAlpha flag is set. -void ImGui::ColorTooltip(const char* text, const float col[4], ImGuiColorEditFlags flags) +void ImGui::ColorTooltip(const char* text, const float* col, ImGuiColorEditFlags flags) { ImGuiContext& g = *GImGui; @@ -9277,51 +9277,52 @@ bool ImGui::ColorEdit3(const char* label, float col[3], ImGuiColorEditFlags flag return ColorEdit4(label, col, flags | ImGuiColorEditFlags_NoAlpha); } -static void ColorEditOptionsPopup(ImGuiColorEditFlags flags, float* col) +void ImGui::ColorEditOptionsPopup(const float* col, ImGuiColorEditFlags flags) { bool allow_opt_inputs = !(flags & ImGuiColorEditFlags__InputsMask); bool allow_opt_datatype = !(flags & ImGuiColorEditFlags__DataTypeMask); - if ((!allow_opt_inputs && !allow_opt_datatype) || !ImGui::BeginPopup("context")) + if ((!allow_opt_inputs && !allow_opt_datatype) || !BeginPopup("context")) return; ImGuiContext& g = *GImGui; ImGuiColorEditFlags opts = g.ColorEditOptions; if (allow_opt_inputs) { - if (ImGui::RadioButton("RGB", (opts & ImGuiColorEditFlags_RGB) ? 1 : 0)) opts = (opts & ~ImGuiColorEditFlags__InputsMask) | ImGuiColorEditFlags_RGB; - if (ImGui::RadioButton("HSV", (opts & ImGuiColorEditFlags_HSV) ? 1 : 0)) opts = (opts & ~ImGuiColorEditFlags__InputsMask) | ImGuiColorEditFlags_HSV; - if (ImGui::RadioButton("HEX", (opts & ImGuiColorEditFlags_HEX) ? 1 : 0)) opts = (opts & ~ImGuiColorEditFlags__InputsMask) | ImGuiColorEditFlags_HEX; + if (RadioButton("RGB", (opts & ImGuiColorEditFlags_RGB) ? 1 : 0)) opts = (opts & ~ImGuiColorEditFlags__InputsMask) | ImGuiColorEditFlags_RGB; + if (RadioButton("HSV", (opts & ImGuiColorEditFlags_HSV) ? 1 : 0)) opts = (opts & ~ImGuiColorEditFlags__InputsMask) | ImGuiColorEditFlags_HSV; + if (RadioButton("HEX", (opts & ImGuiColorEditFlags_HEX) ? 1 : 0)) opts = (opts & ~ImGuiColorEditFlags__InputsMask) | ImGuiColorEditFlags_HEX; } if (allow_opt_datatype) { - if (allow_opt_inputs) ImGui::Separator(); - if (ImGui::RadioButton("0..255", (opts & ImGuiColorEditFlags_Uint8) ? 1 : 0)) opts = (opts & ~ImGuiColorEditFlags__DataTypeMask) | ImGuiColorEditFlags_Uint8; - if (ImGui::RadioButton("0.00..1.00", (opts & ImGuiColorEditFlags_Float) ? 1 : 0)) opts = (opts & ~ImGuiColorEditFlags__DataTypeMask) | ImGuiColorEditFlags_Float; + if (allow_opt_inputs) Separator(); + if (RadioButton("0..255", (opts & ImGuiColorEditFlags_Uint8) ? 1 : 0)) opts = (opts & ~ImGuiColorEditFlags__DataTypeMask) | ImGuiColorEditFlags_Uint8; + if (RadioButton("0.00..1.00", (opts & ImGuiColorEditFlags_Float) ? 1 : 0)) opts = (opts & ~ImGuiColorEditFlags__DataTypeMask) | ImGuiColorEditFlags_Float; } - if (allow_opt_inputs || allow_opt_datatype) ImGui::Separator(); - if (ImGui::Button("Copy as..", ImVec2(-1,0))) - ImGui::OpenPopup("Copy"); - if (ImGui::BeginPopup("Copy")) + if (allow_opt_inputs || allow_opt_datatype) + Separator(); + if (Button("Copy as..", ImVec2(-1,0))) + OpenPopup("Copy"); + if (BeginPopup("Copy")) { int cr = IM_F32_TO_INT8_SAT(col[0]), cg = IM_F32_TO_INT8_SAT(col[1]), cb = IM_F32_TO_INT8_SAT(col[2]), ca = (flags & ImGuiColorEditFlags_NoAlpha) ? 255 : IM_F32_TO_INT8_SAT(col[3]); char buf[64]; sprintf(buf, "(%.3ff, %.3ff, %.3ff, %.3ff)", col[0], col[1], col[2], (flags & ImGuiColorEditFlags_NoAlpha) ? 1.0f : col[3]); - if (ImGui::Selectable(buf)) - ImGui::SetClipboardText(buf); + if (Selectable(buf)) + SetClipboardText(buf); sprintf(buf, "(%d,%d,%d,%d)", cr, cg, cb, ca); - if (ImGui::Selectable(buf)) - ImGui::SetClipboardText(buf); + if (Selectable(buf)) + SetClipboardText(buf); if (flags & ImGuiColorEditFlags_NoAlpha) sprintf(buf, "0x%02X%02X%02X", cr, cg, cb); else sprintf(buf, "0x%02X%02X%02X%02X", cr, cg, cb, ca); - if (ImGui::Selectable(buf)) - ImGui::SetClipboardText(buf); - ImGui::EndPopup(); + if (Selectable(buf)) + SetClipboardText(buf); + EndPopup(); } g.ColorEditOptions = opts; - ImGui::EndPopup(); + EndPopup(); } static void ColorPickerOptionsPopup(ImGuiColorEditFlags flags, float* ref_col) @@ -9392,7 +9393,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag // Context menu: display and modify options (before defaults are applied) if (!(flags & ImGuiColorEditFlags_NoOptions)) - ColorEditOptionsPopup(flags, col); + ColorEditOptionsPopup(col, flags); // Read stored options if (!(flags & ImGuiColorEditFlags__InputsMask)) diff --git a/imgui_internal.h b/imgui_internal.h index 99b0f3afa..b12b3c05c 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -831,7 +831,8 @@ namespace ImGui IMGUI_API bool InputScalarEx(const char* label, ImGuiDataType data_type, void* data_ptr, void* step_ptr, void* step_fast_ptr, const char* scalar_format, ImGuiInputTextFlags extra_flags); IMGUI_API bool InputScalarAsWidgetReplacement(const ImRect& aabb, const char* label, ImGuiDataType data_type, void* data_ptr, ImGuiID id, int decimal_precision); - IMGUI_API void ColorTooltip(const char* text, const float col[4], ImGuiColorEditFlags flags); + IMGUI_API void ColorTooltip(const char* text, const float* col, ImGuiColorEditFlags flags); + IMGUI_API void ColorEditOptionsPopup(const float* col, ImGuiColorEditFlags flags); IMGUI_API bool TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* label, const char* label_end = NULL); IMGUI_API bool TreeNodeBehaviorIsOpen(ImGuiID id, ImGuiTreeNodeFlags flags = 0); // Consume previous SetNextTreeNodeOpened() data, if any. May return true when logging From e56eba44fe0724a64f88f041fddad2eac3661cc3 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 27 Sep 2017 12:25:40 +0200 Subject: [PATCH 380/921] Fixed not being able to move a window by clicking on one of its child window (#1337, #635), broken by https://github.com/ocornut/imgui/commit/313d388bba42e0634a02b976dcdbae238d25eddc --- imgui.cpp | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index a3d66b25c..d8a308bd3 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2230,15 +2230,12 @@ void ImGui::NewFrame() { KeepAliveID(g.MovedWindowMoveId); IM_ASSERT(g.MovedWindow && g.MovedWindow->RootWindow); - IM_ASSERT(g.MovedWindow->RootWindow->MoveId == g.MovedWindowMoveId); + IM_ASSERT(g.MovedWindow->MoveId == g.MovedWindowMoveId); if (g.IO.MouseDown[0]) { - if (!(g.MovedWindow->Flags & ImGuiWindowFlags_NoMove)) - { - g.MovedWindow->PosFloat += g.IO.MouseDelta; - if (g.IO.MouseDelta.x != 0.0f || g.IO.MouseDelta.y != 0.0f) - MarkIniSettingsDirty(g.MovedWindow); - } + g.MovedWindow->RootWindow->PosFloat += g.IO.MouseDelta; + if (g.IO.MouseDelta.x != 0.0f || g.IO.MouseDelta.y != 0.0f) + MarkIniSettingsDirty(g.MovedWindow->RootWindow); FocusWindow(g.MovedWindow); } else @@ -2704,7 +2701,7 @@ void ImGui::EndFrame() if (!(g.HoveredWindow->Flags & ImGuiWindowFlags_NoMove)) { g.MovedWindow = g.HoveredWindow; - g.MovedWindowMoveId = g.HoveredRootWindow->MoveId; + g.MovedWindowMoveId = g.HoveredWindow->MoveId; SetActiveID(g.MovedWindowMoveId, g.HoveredRootWindow); } } From 842e88a8e3dcbd775390732fe5a0c7f65a7b62a3 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 27 Sep 2017 15:47:08 +0200 Subject: [PATCH 381/921] Examples: Avoid using ImColor() to not tempt newcomers into looking at it --- examples/allegro5_example/main.cpp | 2 +- examples/directx10_example/main.cpp | 6 +++--- examples/directx11_example/main.cpp | 6 +++--- examples/directx9_example/main.cpp | 6 +++--- examples/marmalade_example/main.cpp | 2 +- examples/opengl2_example/main.cpp | 2 +- examples/opengl3_example/main.cpp | 2 +- examples/sdl_opengl2_example/main.cpp | 2 +- examples/sdl_opengl3_example/main.cpp | 2 +- examples/vulkan_example/main.cpp | 2 +- 10 files changed, 16 insertions(+), 16 deletions(-) diff --git a/examples/allegro5_example/main.cpp b/examples/allegro5_example/main.cpp index 9f8a6c359..2b161d370 100644 --- a/examples/allegro5_example/main.cpp +++ b/examples/allegro5_example/main.cpp @@ -37,7 +37,7 @@ int main(int, char**) bool show_test_window = true; bool show_another_window = false; - ImVec4 clear_color = ImColor(114, 144, 154); + ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); // Main loop bool running = true; diff --git a/examples/directx10_example/main.cpp b/examples/directx10_example/main.cpp index 90add0364..88472e5ba 100644 --- a/examples/directx10_example/main.cpp +++ b/examples/directx10_example/main.cpp @@ -137,7 +137,7 @@ int main(int, char**) bool show_test_window = true; bool show_another_window = false; - ImVec4 clear_col = ImColor(114, 144, 154); + ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); // Main loop MSG msg; @@ -158,7 +158,7 @@ int main(int, char**) static float f = 0.0f; ImGui::Text("Hello, world!"); ImGui::SliderFloat("float", &f, 0.0f, 1.0f); - ImGui::ColorEdit3("clear color", (float*)&clear_col); + ImGui::ColorEdit3("clear color", (float*)&clear_color); if (ImGui::Button("Test Window")) show_test_window ^= 1; if (ImGui::Button("Another Window")) show_another_window ^= 1; ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); @@ -180,7 +180,7 @@ int main(int, char**) } // Rendering - g_pd3dDevice->ClearRenderTargetView(g_mainRenderTargetView, (float*)&clear_col); + g_pd3dDevice->ClearRenderTargetView(g_mainRenderTargetView, (float*)&clear_color); ImGui::Render(); g_pSwapChain->Present(1, 0); // Present with vsync diff --git a/examples/directx11_example/main.cpp b/examples/directx11_example/main.cpp index 76bab9518..ab563403e 100644 --- a/examples/directx11_example/main.cpp +++ b/examples/directx11_example/main.cpp @@ -140,7 +140,7 @@ int main(int, char**) bool show_test_window = true; bool show_another_window = false; - ImVec4 clear_col = ImColor(114, 144, 154); + ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); // Main loop MSG msg; @@ -161,7 +161,7 @@ int main(int, char**) static float f = 0.0f; ImGui::Text("Hello, world!"); ImGui::SliderFloat("float", &f, 0.0f, 1.0f); - ImGui::ColorEdit3("clear color", (float*)&clear_col); + ImGui::ColorEdit3("clear color", (float*)&clear_color); if (ImGui::Button("Test Window")) show_test_window ^= 1; if (ImGui::Button("Another Window")) show_another_window ^= 1; ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); @@ -183,7 +183,7 @@ int main(int, char**) } // Rendering - g_pd3dDeviceContext->ClearRenderTargetView(g_mainRenderTargetView, (float*)&clear_col); + g_pd3dDeviceContext->ClearRenderTargetView(g_mainRenderTargetView, (float*)&clear_color); ImGui::Render(); g_pSwapChain->Present(1, 0); // Present with vsync diff --git a/examples/directx9_example/main.cpp b/examples/directx9_example/main.cpp index f9791b733..85f34eee7 100644 --- a/examples/directx9_example/main.cpp +++ b/examples/directx9_example/main.cpp @@ -89,7 +89,7 @@ int main(int, char**) bool show_test_window = true; bool show_another_window = false; - ImVec4 clear_col = ImColor(114, 144, 154); + ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); // Main loop MSG msg; @@ -112,7 +112,7 @@ int main(int, char**) static float f = 0.0f; ImGui::Text("Hello, world!"); ImGui::SliderFloat("float", &f, 0.0f, 1.0f); - ImGui::ColorEdit3("clear color", (float*)&clear_col); + ImGui::ColorEdit3("clear color", (float*)&clear_color); if (ImGui::Button("Test Window")) show_test_window ^= 1; if (ImGui::Button("Another Window")) show_another_window ^= 1; ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); @@ -137,7 +137,7 @@ int main(int, char**) g_pd3dDevice->SetRenderState(D3DRS_ZENABLE, false); g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, false); g_pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, false); - D3DCOLOR clear_col_dx = D3DCOLOR_RGBA((int)(clear_col.x*255.0f), (int)(clear_col.y*255.0f), (int)(clear_col.z*255.0f), (int)(clear_col.w*255.0f)); + D3DCOLOR clear_col_dx = D3DCOLOR_RGBA((int)(clear_color.x*255.0f), (int)(clear_color.y*255.0f), (int)(clear_color.z*255.0f), (int)(clear_color.w*255.0f)); g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, clear_col_dx, 1.0f, 0); if (g_pd3dDevice->BeginScene() >= 0) { diff --git a/examples/marmalade_example/main.cpp b/examples/marmalade_example/main.cpp index 57b7f0b69..ebc812f19 100644 --- a/examples/marmalade_example/main.cpp +++ b/examples/marmalade_example/main.cpp @@ -29,7 +29,7 @@ int main(int, char**) bool show_test_window = true; bool show_another_window = false; - ImVec4 clear_color = ImColor(114, 144, 154); + ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); // Main loop while (true) diff --git a/examples/opengl2_example/main.cpp b/examples/opengl2_example/main.cpp index 5674a4bcb..c676953f2 100644 --- a/examples/opengl2_example/main.cpp +++ b/examples/opengl2_example/main.cpp @@ -36,7 +36,7 @@ int main(int, char**) bool show_test_window = true; bool show_another_window = false; - ImVec4 clear_color = ImColor(114, 144, 154); + ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); // Main loop while (!glfwWindowShouldClose(window)) diff --git a/examples/opengl3_example/main.cpp b/examples/opengl3_example/main.cpp index 0de9b0a0e..d3ac2cc27 100644 --- a/examples/opengl3_example/main.cpp +++ b/examples/opengl3_example/main.cpp @@ -44,7 +44,7 @@ int main(int, char**) bool show_test_window = true; bool show_another_window = false; - ImVec4 clear_color = ImColor(114, 144, 154); + ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); // Main loop while (!glfwWindowShouldClose(window)) diff --git a/examples/sdl_opengl2_example/main.cpp b/examples/sdl_opengl2_example/main.cpp index 4db6f0f9c..fb5f3fb53 100644 --- a/examples/sdl_opengl2_example/main.cpp +++ b/examples/sdl_opengl2_example/main.cpp @@ -42,7 +42,7 @@ int main(int, char**) bool show_test_window = true; bool show_another_window = false; - ImVec4 clear_color = ImColor(114, 144, 154); + ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); // Main loop bool done = false; diff --git a/examples/sdl_opengl3_example/main.cpp b/examples/sdl_opengl3_example/main.cpp index 30b14e72b..19e3f8617 100644 --- a/examples/sdl_opengl3_example/main.cpp +++ b/examples/sdl_opengl3_example/main.cpp @@ -45,7 +45,7 @@ int main(int, char**) bool show_test_window = true; bool show_another_window = false; - ImVec4 clear_color = ImColor(114, 144, 154); + ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); // Main loop bool done = false; diff --git a/examples/vulkan_example/main.cpp b/examples/vulkan_example/main.cpp index 7ed9ea12d..64c0f08c6 100644 --- a/examples/vulkan_example/main.cpp +++ b/examples/vulkan_example/main.cpp @@ -664,7 +664,7 @@ int main(int, char**) bool show_test_window = true; bool show_another_window = false; - ImVec4 clear_color = ImColor(114, 144, 154); + ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); // When IMGUI_UNLIMITED_FRAME_RATE is defined we render into latest image acquired from the swapchain but we display the image which was rendered before. // Hence we must render once and increase the g_FrameIndex without presenting, which we do before entering the render loop. From e87ad328e4a43b880693e3ccdaf3cf4bf6aa106c Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 27 Sep 2017 16:07:47 +0200 Subject: [PATCH 382/921] Moved implementation of Hovered-related functions next to each others + comments, before I attempt to work on them. No functional change here. --- imgui.cpp | 48 +++++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index d8a308bd3..99abdf973 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1947,11 +1947,13 @@ bool ImGui::ItemAdd(const ImRect& bb, const ImGuiID* id) return false; //if (g.IO.KeyAlt) window->DrawList->AddRect(bb.Min, bb.Max, IM_COL32(255,255,0,120)); // [DEBUG] - // Setting LastItemHoveredAndUsable for IsItemHovered(). This is a sensible default, but widgets are free to override it. + // Setting LastItemHoveredAndUsable for public facing IsItemHovered(). This is a sensible default, but widgets are free to override it. + // FIXME: Consider moving this code to IsItemHovered() so it's only evaluated if users needs it. if (IsMouseHoveringRect(bb.Min, bb.Max)) { - // Matching the behavior of IsHovered() but allow if ActiveId==window->MoveID (we clicked on the window background) - // So that clicking on items with no active id such as Text() still returns true with IsItemHovered() + // Matching the behavior of internal IsHovered() but: + // - we are always setting LastItemHoveredRect, which is returned by IsItemRectHovered(), so the order of tests is tweaked to be different. + // - we allow hovering to be true when ActiveId==window->MoveID, so that clicking on non-interactive items such as a Text() item still returns true with IsItemHovered()) window->DC.LastItemHoveredRect = true; if (g.HoveredRootWindow == window->RootWindow) if (g.ActiveId == 0 || (id && g.ActiveId == *id) || g.ActiveIdAllowOverlap || (g.ActiveId == window->MoveId)) @@ -1962,18 +1964,19 @@ bool ImGui::ItemAdd(const ImRect& bb, const ImGuiID* id) return true; } -bool ImGui::IsClippedEx(const ImRect& bb, const ImGuiID* id, bool clip_even_when_logged) +bool ImGui::IsItemHovered() { - ImGuiContext& g = *GImGui; ImGuiWindow* window = GetCurrentWindowRead(); - if (!bb.Overlaps(window->ClipRect)) - if (!id || *id != g.ActiveId) - if (clip_even_when_logged || !g.LogEnabled) - return true; - return false; + return window->DC.LastItemHoveredAndUsable; } -// NB: This is an internal helper. The user-facing IsItemHovered() is using data emitted from ItemAdd(), with a slightly different logic. +bool ImGui::IsItemRectHovered() +{ + ImGuiWindow* window = GetCurrentWindowRead(); + return window->DC.LastItemHoveredRect; +} + +// [Internal] The user-facing IsItemHovered() is using data emitted from ItemAdd(), with a slightly different logic. bool ImGui::IsHovered(const ImRect& bb, ImGuiID id, bool flatten_childs) { ImGuiContext& g = *GImGui; @@ -1988,6 +1991,17 @@ bool ImGui::IsHovered(const ImRect& bb, ImGuiID id, bool flatten_childs) return false; } +bool ImGui::IsClippedEx(const ImRect& bb, const ImGuiID* id, bool clip_even_when_logged) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = GetCurrentWindowRead(); + if (!bb.Overlaps(window->ClipRect)) + if (!id || *id != g.ActiveId) + if (clip_even_when_logged || !g.LogEnabled) + return true; + return false; +} + bool ImGui::FocusableItemRegister(ImGuiWindow* window, ImGuiID id, bool tab_stop) { ImGuiContext& g = *GImGui; @@ -3323,18 +3337,6 @@ void ImGui::CaptureMouseFromApp(bool capture) GImGui->WantCaptureMouseNextFrame = capture ? 1 : 0; } -bool ImGui::IsItemHovered() -{ - ImGuiWindow* window = GetCurrentWindowRead(); - return window->DC.LastItemHoveredAndUsable; -} - -bool ImGui::IsItemRectHovered() -{ - ImGuiWindow* window = GetCurrentWindowRead(); - return window->DC.LastItemHoveredRect; -} - bool ImGui::IsItemActive() { ImGuiContext& g = *GImGui; From 99c7622a1bd747b068db97a6e1c8e2cd06e39037 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 27 Sep 2017 16:20:53 +0200 Subject: [PATCH 383/921] ItemAdd(), not performing computation for IsItemRectHovered() which does them itself, allowing us in the next commit to optimize ItemAdd() and make its logic more consistent with IsHovered(). --- imgui.cpp | 15 ++++++++------- imgui_demo.cpp | 4 ++-- imgui_internal.h | 3 +-- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 99abdf973..555cea14c 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1942,19 +1942,17 @@ bool ImGui::ItemAdd(const ImRect& bb, const ImGuiID* id) ImGuiWindow* window = g.CurrentWindow; window->DC.LastItemId = id ? *id : 0; window->DC.LastItemRect = bb; - window->DC.LastItemHoveredAndUsable = window->DC.LastItemHoveredRect = false; + window->DC.LastItemHoveredAndUsable = false; if (IsClippedEx(bb, id, false)) return false; //if (g.IO.KeyAlt) window->DrawList->AddRect(bb.Min, bb.Max, IM_COL32(255,255,0,120)); // [DEBUG] // Setting LastItemHoveredAndUsable for public facing IsItemHovered(). This is a sensible default, but widgets are free to override it. - // FIXME: Consider moving this code to IsItemHovered() so it's only evaluated if users needs it. + // FIXME-OPT: Consider moving this code to IsItemHovered() so it's only evaluated if users needs it. if (IsMouseHoveringRect(bb.Min, bb.Max)) { // Matching the behavior of internal IsHovered() but: - // - we are always setting LastItemHoveredRect, which is returned by IsItemRectHovered(), so the order of tests is tweaked to be different. // - we allow hovering to be true when ActiveId==window->MoveID, so that clicking on non-interactive items such as a Text() item still returns true with IsItemHovered()) - window->DC.LastItemHoveredRect = true; if (g.HoveredRootWindow == window->RootWindow) if (g.ActiveId == 0 || (id && g.ActiveId == *id) || g.ActiveIdAllowOverlap || (g.ActiveId == window->MoveId)) if (IsWindowContentHoverable(window)) @@ -1973,7 +1971,7 @@ bool ImGui::IsItemHovered() bool ImGui::IsItemRectHovered() { ImGuiWindow* window = GetCurrentWindowRead(); - return window->DC.LastItemHoveredRect; + return IsMouseHoveringRect(window->DC.LastItemRect.Min, window->DC.LastItemRect.Max); } // [Internal] The user-facing IsItemHovered() is using data emitted from ItemAdd(), with a slightly different logic. @@ -10020,13 +10018,16 @@ void ImGui::EndGroup() ItemAdd(group_bb, NULL); } - // If the current ActiveId was declared within the boundary of our group, we copy it to LastItemId so IsItemActive() will function on the entire group. + // If the current ActiveId was declared within the boundary of our group, we copy it to LastItemId so IsItemActive() will be functional on the entire group. // It would be be neater if we replaced window.DC.LastItemId by e.g. 'bool LastItemIsActive', but if you search for LastItemId you'll notice it is only used in that context. const bool active_id_within_group = (!group_data.BackupActiveIdIsAlive && g.ActiveIdIsAlive && g.ActiveId && g.ActiveIdWindow->RootWindow == window->RootWindow); if (active_id_within_group) window->DC.LastItemId = g.ActiveId; if (active_id_within_group && g.HoveredId == g.ActiveId) - window->DC.LastItemHoveredAndUsable = window->DC.LastItemHoveredRect = true; + { + window->DC.LastItemHoveredAndUsable = true; + window->DC.LastItemRect = group_bb; + } window->DC.GroupStack.pop_back(); diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 81e89db50..d846faa1b 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1126,11 +1126,11 @@ void ImGui::ShowTestWindow(bool* p_open) ImGui::Button("CCC"); ImGui::Button("DDD"); ImGui::EndGroup(); - if (ImGui::IsItemHovered()) - ImGui::SetTooltip("Group hovered"); ImGui::SameLine(); ImGui::Button("EEE"); ImGui::EndGroup(); + if (ImGui::IsItemHovered()) + ImGui::SetTooltip("First group hovered"); } // Capture the group size and create widgets using the same size ImVec2 size = ImGui::GetItemRectSize(); diff --git a/imgui_internal.h b/imgui_internal.h index b12b3c05c..b204b602f 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -601,7 +601,6 @@ struct IMGUI_API ImGuiDrawContext ImGuiID LastItemId; ImRect LastItemRect; bool LastItemHoveredAndUsable; // Item rectangle is hovered, and its window is currently interactable with (not blocked by a popup preventing access to the window) - bool LastItemHoveredRect; // Item rectangle is hovered, but its window may or not be currently interactable with (might be blocked by a popup preventing access to the window) bool MenuBarAppending; float MenuBarOffsetX; ImVector ChildWindows; @@ -642,7 +641,7 @@ struct IMGUI_API ImGuiDrawContext TreeDepth = 0; LastItemId = 0; LastItemRect = ImRect(0.0f,0.0f,0.0f,0.0f); - LastItemHoveredAndUsable = LastItemHoveredRect = false; + LastItemHoveredAndUsable = false; MenuBarAppending = false; MenuBarOffsetX = 0.0f; StateStorage = NULL; From c075786d8b7e682f26d11b5b4a629fdf608fe28d Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 27 Sep 2017 16:29:46 +0200 Subject: [PATCH 384/921] ItemAdd(): re-ordering the tests, submission should now be faster. --- imgui.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 555cea14c..25d463fd8 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1947,13 +1947,13 @@ bool ImGui::ItemAdd(const ImRect& bb, const ImGuiID* id) return false; //if (g.IO.KeyAlt) window->DrawList->AddRect(bb.Min, bb.Max, IM_COL32(255,255,0,120)); // [DEBUG] - // Setting LastItemHoveredAndUsable for public facing IsItemHovered(). This is a sensible default, but widgets are free to override it. + // Set up for public-facing IsItemHovered(). We store the result in DC.LastItemHoveredAndUsable. + // This is roughly matching the behavior of internal IsHovered() + // - we allow hovering to be true when ActiveId==window->MoveID, so that clicking on non-interactive items such as a Text() item still returns true with IsItemHovered()) // FIXME-OPT: Consider moving this code to IsItemHovered() so it's only evaluated if users needs it. - if (IsMouseHoveringRect(bb.Min, bb.Max)) + if (g.HoveredRootWindow == window->RootWindow) { - // Matching the behavior of internal IsHovered() but: - // - we allow hovering to be true when ActiveId==window->MoveID, so that clicking on non-interactive items such as a Text() item still returns true with IsItemHovered()) - if (g.HoveredRootWindow == window->RootWindow) + if (IsMouseHoveringRect(bb.Min, bb.Max)) if (g.ActiveId == 0 || (id && g.ActiveId == *id) || g.ActiveIdAllowOverlap || (g.ActiveId == window->MoveId)) if (IsWindowContentHoverable(window)) window->DC.LastItemHoveredAndUsable = true; From 344d48be31e1fae98c9f7cb6d96b6d77d29abec0 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 27 Sep 2017 16:49:25 +0200 Subject: [PATCH 385/921] IsItemHovered(), ItemAdd(): Fixed seemingly unnecessary comparaison of root windows, makes IsItemHovered() more consistent with internal IsHovered(). Original test was added in 6e99688fa74b3de5694a8e021619cc1ade51ee03 should not have been using RootWindow in the first place. The difference between public-facing and internal versions would only be noticeable with overlapped child windows, which doesn't really happen anyway --- imgui.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 25d463fd8..2bce31de0 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1948,16 +1948,14 @@ bool ImGui::ItemAdd(const ImRect& bb, const ImGuiID* id) //if (g.IO.KeyAlt) window->DrawList->AddRect(bb.Min, bb.Max, IM_COL32(255,255,0,120)); // [DEBUG] // Set up for public-facing IsItemHovered(). We store the result in DC.LastItemHoveredAndUsable. - // This is roughly matching the behavior of internal IsHovered() + // This is roughly matching the behavior of internal-facing IsHovered() // - we allow hovering to be true when ActiveId==window->MoveID, so that clicking on non-interactive items such as a Text() item still returns true with IsItemHovered()) // FIXME-OPT: Consider moving this code to IsItemHovered() so it's only evaluated if users needs it. - if (g.HoveredRootWindow == window->RootWindow) - { + if (g.HoveredWindow == window) if (IsMouseHoveringRect(bb.Min, bb.Max)) if (g.ActiveId == 0 || (id && g.ActiveId == *id) || g.ActiveIdAllowOverlap || (g.ActiveId == window->MoveId)) if (IsWindowContentHoverable(window)) window->DC.LastItemHoveredAndUsable = true; - } return true; } @@ -1982,9 +1980,10 @@ bool ImGui::IsHovered(const ImRect& bb, ImGuiID id, bool flatten_childs) { ImGuiWindow* window = GetCurrentWindowRead(); if (g.HoveredWindow == window || (flatten_childs && g.HoveredRootWindow == window->RootWindow)) - if ((g.ActiveId == 0 || g.ActiveId == id || g.ActiveIdAllowOverlap) && IsMouseHoveringRect(bb.Min, bb.Max)) - if (IsWindowContentHoverable(g.HoveredRootWindow)) - return true; + if (g.ActiveId == 0 || g.ActiveId == id || g.ActiveIdAllowOverlap) + if (IsMouseHoveringRect(bb.Min, bb.Max)) + if (IsWindowContentHoverable(g.HoveredRootWindow)) + return true; } return false; } From 19e22baa065dab7c99694d14fc46d713e5c4f449 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 27 Sep 2017 17:06:07 +0200 Subject: [PATCH 386/921] ItemAdd(): more re-ordering of tests to match IsHovered() + comments --- imgui.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 2bce31de0..25dd1ce53 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1950,10 +1950,11 @@ bool ImGui::ItemAdd(const ImRect& bb, const ImGuiID* id) // Set up for public-facing IsItemHovered(). We store the result in DC.LastItemHoveredAndUsable. // This is roughly matching the behavior of internal-facing IsHovered() // - we allow hovering to be true when ActiveId==window->MoveID, so that clicking on non-interactive items such as a Text() item still returns true with IsItemHovered()) + // - we don't expose the flatten_child feature that IsHovered() has, which is only used by the window resizing widget (may rework this) // FIXME-OPT: Consider moving this code to IsItemHovered() so it's only evaluated if users needs it. if (g.HoveredWindow == window) - if (IsMouseHoveringRect(bb.Min, bb.Max)) - if (g.ActiveId == 0 || (id && g.ActiveId == *id) || g.ActiveIdAllowOverlap || (g.ActiveId == window->MoveId)) + if (g.ActiveId == 0 || (id && g.ActiveId == *id) || g.ActiveIdAllowOverlap || (g.ActiveId == window->MoveId)) + if (IsMouseHoveringRect(bb.Min, bb.Max)) if (IsWindowContentHoverable(window)) window->DC.LastItemHoveredAndUsable = true; From 0adcddac39ab6aad6f2c745f2d51c767c5673191 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 27 Sep 2017 17:21:50 +0200 Subject: [PATCH 387/921] IsItemHovered(), ItemAdd(): finishing cleaning up, moved the code to IsItemHovered() so ItemAdd() is more lightweight and the two IsXXXHovered functions are now very similar, making their differences less confusing. --- imgui.cpp | 36 +++++++++++++++--------------------- imgui_internal.h | 2 -- 2 files changed, 15 insertions(+), 23 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 25dd1ce53..c9b7031fa 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1942,29 +1942,27 @@ bool ImGui::ItemAdd(const ImRect& bb, const ImGuiID* id) ImGuiWindow* window = g.CurrentWindow; window->DC.LastItemId = id ? *id : 0; window->DC.LastItemRect = bb; - window->DC.LastItemHoveredAndUsable = false; if (IsClippedEx(bb, id, false)) return false; //if (g.IO.KeyAlt) window->DrawList->AddRect(bb.Min, bb.Max, IM_COL32(255,255,0,120)); // [DEBUG] - // Set up for public-facing IsItemHovered(). We store the result in DC.LastItemHoveredAndUsable. - // This is roughly matching the behavior of internal-facing IsHovered() - // - we allow hovering to be true when ActiveId==window->MoveID, so that clicking on non-interactive items such as a Text() item still returns true with IsItemHovered()) - // - we don't expose the flatten_child feature that IsHovered() has, which is only used by the window resizing widget (may rework this) - // FIXME-OPT: Consider moving this code to IsItemHovered() so it's only evaluated if users needs it. - if (g.HoveredWindow == window) - if (g.ActiveId == 0 || (id && g.ActiveId == *id) || g.ActiveIdAllowOverlap || (g.ActiveId == window->MoveId)) - if (IsMouseHoveringRect(bb.Min, bb.Max)) - if (IsWindowContentHoverable(window)) - window->DC.LastItemHoveredAndUsable = true; - return true; } +// This is roughly matching the behavior of internal-facing IsHovered() +// - we allow hovering to be true when ActiveId==window->MoveID, so that clicking on non-interactive items such as a Text() item still returns true with IsItemHovered()) +// - we don't expose the flatten_child feature that IsHovered() has, which is only used by the window resizing widget (may rework this) bool ImGui::IsItemHovered() { - ImGuiWindow* window = GetCurrentWindowRead(); - return window->DC.LastItemHoveredAndUsable; + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + if (g.HoveredWindow == window) + if (g.ActiveId == 0 || g.ActiveId == window->DC.LastItemId || g.ActiveIdAllowOverlap || g.ActiveId == window->MoveId) + if (IsMouseHoveringRect(window->DC.LastItemRect.Min, window->DC.LastItemRect.Max)) + if (IsWindowContentHoverable(window)) + return true; + + return false; } bool ImGui::IsItemRectHovered() @@ -1973,13 +1971,13 @@ bool ImGui::IsItemRectHovered() return IsMouseHoveringRect(window->DC.LastItemRect.Min, window->DC.LastItemRect.Max); } -// [Internal] The user-facing IsItemHovered() is using data emitted from ItemAdd(), with a slightly different logic. +// Internal facing IsHovered() differs slightly from IsItemHovered(). bool ImGui::IsHovered(const ImRect& bb, ImGuiID id, bool flatten_childs) { ImGuiContext& g = *GImGui; if (g.HoveredId == 0 || g.HoveredId == id || g.HoveredIdAllowOverlap) { - ImGuiWindow* window = GetCurrentWindowRead(); + ImGuiWindow* window = g.CurrentWindow; if (g.HoveredWindow == window || (flatten_childs && g.HoveredRootWindow == window->RootWindow)) if (g.ActiveId == 0 || g.ActiveId == id || g.ActiveIdAllowOverlap) if (IsMouseHoveringRect(bb.Min, bb.Max)) @@ -10023,11 +10021,7 @@ void ImGui::EndGroup() const bool active_id_within_group = (!group_data.BackupActiveIdIsAlive && g.ActiveIdIsAlive && g.ActiveId && g.ActiveIdWindow->RootWindow == window->RootWindow); if (active_id_within_group) window->DC.LastItemId = g.ActiveId; - if (active_id_within_group && g.HoveredId == g.ActiveId) - { - window->DC.LastItemHoveredAndUsable = true; - window->DC.LastItemRect = group_bb; - } + window->DC.LastItemRect = group_bb; window->DC.GroupStack.pop_back(); diff --git a/imgui_internal.h b/imgui_internal.h index b204b602f..a1192be9c 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -600,7 +600,6 @@ struct IMGUI_API ImGuiDrawContext int TreeDepth; ImGuiID LastItemId; ImRect LastItemRect; - bool LastItemHoveredAndUsable; // Item rectangle is hovered, and its window is currently interactable with (not blocked by a popup preventing access to the window) bool MenuBarAppending; float MenuBarOffsetX; ImVector ChildWindows; @@ -641,7 +640,6 @@ struct IMGUI_API ImGuiDrawContext TreeDepth = 0; LastItemId = 0; LastItemRect = ImRect(0.0f,0.0f,0.0f,0.0f); - LastItemHoveredAndUsable = false; MenuBarAppending = false; MenuBarOffsetX = 0.0f; StateStorage = NULL; From 7bcb1d3816cf0eea13a0f716a9779151ef203f76 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 27 Sep 2017 22:59:40 +0200 Subject: [PATCH 388/921] Internals: ButtonBehavior(), IsHovered() moved the responsability of flatten_child higher level to ButtonBehavior() - not super sure about the elegance of this --- imgui.cpp | 16 ++++++++++++---- imgui_internal.h | 2 +- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index c9b7031fa..747fcba51 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1951,7 +1951,6 @@ bool ImGui::ItemAdd(const ImRect& bb, const ImGuiID* id) // This is roughly matching the behavior of internal-facing IsHovered() // - we allow hovering to be true when ActiveId==window->MoveID, so that clicking on non-interactive items such as a Text() item still returns true with IsItemHovered()) -// - we don't expose the flatten_child feature that IsHovered() has, which is only used by the window resizing widget (may rework this) bool ImGui::IsItemHovered() { ImGuiContext& g = *GImGui; @@ -1972,13 +1971,13 @@ bool ImGui::IsItemRectHovered() } // Internal facing IsHovered() differs slightly from IsItemHovered(). -bool ImGui::IsHovered(const ImRect& bb, ImGuiID id, bool flatten_childs) +bool ImGui::IsHovered(const ImRect& bb, ImGuiID id) { ImGuiContext& g = *GImGui; if (g.HoveredId == 0 || g.HoveredId == id || g.HoveredIdAllowOverlap) { ImGuiWindow* window = g.CurrentWindow; - if (g.HoveredWindow == window || (flatten_childs && g.HoveredRootWindow == window->RootWindow)) + if (g.HoveredWindow == window) if (g.ActiveId == 0 || g.ActiveId == id || g.ActiveIdAllowOverlap) if (IsMouseHoveringRect(bb.Min, bb.Max)) if (IsWindowContentHoverable(g.HoveredRootWindow)) @@ -4274,6 +4273,7 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us if (!(flags & ImGuiWindowFlags_AlwaysAutoResize) && window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0 && !(flags & ImGuiWindowFlags_NoResize)) { // Manual resize + // Using the FlattenChilds button flag, we make the resize button accessible even if we are hovering over a child window const ImVec2 br = window->Rect().GetBR(); const ImRect resize_rect(br - ImVec2(resize_corner_size * 0.75f, resize_corner_size * 0.75f), br); const ImGuiID resize_id = window->GetID("#RESIZE"); @@ -5673,8 +5673,16 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool if ((flags & (ImGuiButtonFlags_PressedOnClickRelease | ImGuiButtonFlags_PressedOnClick | ImGuiButtonFlags_PressedOnRelease | ImGuiButtonFlags_PressedOnDoubleClick)) == 0) flags |= ImGuiButtonFlags_PressedOnClickRelease; + ImGuiWindow* backup_hovered_window = g.HoveredWindow; + if ((flags & ImGuiButtonFlags_FlattenChilds) && g.HoveredRootWindow == window) + g.HoveredWindow = window; + bool pressed = false; - bool hovered = IsHovered(bb, id, (flags & ImGuiButtonFlags_FlattenChilds) != 0); + bool hovered = IsHovered(bb, id); + + if ((flags & ImGuiButtonFlags_FlattenChilds) && g.HoveredRootWindow == window) + g.HoveredWindow = backup_hovered_window; + if (hovered) { SetHoveredID(id); diff --git a/imgui_internal.h b/imgui_internal.h index a1192be9c..9329e4615 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -771,7 +771,7 @@ namespace ImGui IMGUI_API void ItemSize(const ImRect& bb, float text_offset_y = 0.0f); IMGUI_API bool ItemAdd(const ImRect& bb, const ImGuiID* id); IMGUI_API bool IsClippedEx(const ImRect& bb, const ImGuiID* id, bool clip_even_when_logged); - IMGUI_API bool IsHovered(const ImRect& bb, ImGuiID id, bool flatten_childs = false); + IMGUI_API bool IsHovered(const ImRect& bb, ImGuiID id); IMGUI_API bool FocusableItemRegister(ImGuiWindow* window, ImGuiID id, bool tab_stop = true); // Return true if focus is requested IMGUI_API void FocusableItemUnregister(ImGuiWindow* window); IMGUI_API ImVec2 CalcItemSize(ImVec2 size, float default_x, float default_y); From c5a79deb38774c76ff416e8f673bf080650f1b52 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 27 Sep 2017 23:10:46 +0200 Subject: [PATCH 389/921] IsItemHovered(), IsHovered(): Shallow tweaks to make them more symetrical. Removed one set of braces. --- imgui.cpp | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 747fcba51..1f1c4f64c 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1954,12 +1954,14 @@ bool ImGui::ItemAdd(const ImRect& bb, const ImGuiID* id) bool ImGui::IsItemHovered() { ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; - if (g.HoveredWindow == window) - if (g.ActiveId == 0 || g.ActiveId == window->DC.LastItemId || g.ActiveIdAllowOverlap || g.ActiveId == window->MoveId) - if (IsMouseHoveringRect(window->DC.LastItemRect.Min, window->DC.LastItemRect.Max)) - if (IsWindowContentHoverable(window)) - return true; + if (g.HoveredWindow != window) + return false; + if (g.ActiveId == 0 || g.ActiveId == window->DC.LastItemId || g.ActiveIdAllowOverlap || g.ActiveId == window->MoveId) + if (IsMouseHoveringRect(window->DC.LastItemRect.Min, window->DC.LastItemRect.Max)) + if (IsWindowContentHoverable(window)) + return true; return false; } @@ -1974,15 +1976,17 @@ bool ImGui::IsItemRectHovered() bool ImGui::IsHovered(const ImRect& bb, ImGuiID id) { ImGuiContext& g = *GImGui; - if (g.HoveredId == 0 || g.HoveredId == id || g.HoveredIdAllowOverlap) - { - ImGuiWindow* window = g.CurrentWindow; - if (g.HoveredWindow == window) - if (g.ActiveId == 0 || g.ActiveId == id || g.ActiveIdAllowOverlap) - if (IsMouseHoveringRect(bb.Min, bb.Max)) - if (IsWindowContentHoverable(g.HoveredRootWindow)) - return true; - } + if (g.HoveredId != 0 && g.HoveredId != id && !g.HoveredIdAllowOverlap) + return false; + + ImGuiWindow* window = g.CurrentWindow; + if (g.HoveredWindow != window) + return false; + if (g.ActiveId == 0 || g.ActiveId == id || g.ActiveIdAllowOverlap) + if (IsMouseHoveringRect(bb.Min, bb.Max)) + if (IsWindowContentHoverable(g.HoveredRootWindow)) + return true; + return false; } From 2b7d4c713e9982ea7b668b38cbdeba344c0ca5d1 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 27 Sep 2017 23:31:03 +0200 Subject: [PATCH 390/921] Internals: Moved IsWindowContentHoverable() in the file --- imgui.cpp | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 1f1c4f64c..4d53b8b34 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -605,7 +605,6 @@ static void SetWindowSize(ImGuiWindow* window, const ImVec2& size, I static void SetWindowCollapsed(ImGuiWindow* window, bool collapsed, ImGuiCond cond); static ImGuiWindow* FindHoveredWindow(ImVec2 pos, bool excluding_childs); static ImGuiWindow* CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFlags flags); -static inline bool IsWindowContentHoverable(ImGuiWindow* window); static void ClearSetNextWindowData(); static void CheckStacksSize(ImGuiWindow* window, bool write); static void Scrollbar(ImGuiWindow* window, bool horizontal); @@ -1901,6 +1900,19 @@ void ImGui::KeepAliveID(ImGuiID id) g.ActiveIdIsAlive = true; } +static inline bool IsWindowContentHoverable(ImGuiWindow* window) +{ + // An active popup disable hovering on other windows (apart from its own children) + // FIXME-OPT: This could be cached/stored within the window. + ImGuiContext& g = *GImGui; + if (g.NavWindow) + if (ImGuiWindow* focused_root_window = g.NavWindow->RootWindow) + if ((focused_root_window->Flags & ImGuiWindowFlags_Popup) != 0 && focused_root_window->WasActive && focused_root_window != window->RootWindow) + return false; + + return true; +} + // Advance cursor given item size for layout. void ImGui::ItemSize(const ImVec2& size, float text_offset_y) { @@ -5647,19 +5659,6 @@ void ImGui::LabelText(const char* label, const char* fmt, ...) va_end(args); } -static inline bool IsWindowContentHoverable(ImGuiWindow* window) -{ - // An active popup disable hovering on other windows (apart from its own children) - // FIXME-OPT: This could be cached/stored within the window. - ImGuiContext& g = *GImGui; - if (g.NavWindow) - if (ImGuiWindow* focused_root_window = g.NavWindow->RootWindow) - if ((focused_root_window->Flags & ImGuiWindowFlags_Popup) != 0 && focused_root_window->WasActive && focused_root_window != window->RootWindow) - return false; - - return true; -} - bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool* out_held, ImGuiButtonFlags flags) { ImGuiContext& g = *GImGui; From eca74d55c729ca3007e47ddebec83697a9434911 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 28 Sep 2017 00:05:18 +0200 Subject: [PATCH 391/921] IsItemHovered(), IsHovered(): Shallow tweaks, eventually removed all the braces. --- imgui.cpp | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 4d53b8b34..fcf947b30 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1970,12 +1970,13 @@ bool ImGui::IsItemHovered() ImGuiWindow* window = g.CurrentWindow; if (g.HoveredWindow != window) return false; - if (g.ActiveId == 0 || g.ActiveId == window->DC.LastItemId || g.ActiveIdAllowOverlap || g.ActiveId == window->MoveId) - if (IsMouseHoveringRect(window->DC.LastItemRect.Min, window->DC.LastItemRect.Max)) - if (IsWindowContentHoverable(window)) - return true; - - return false; + if (g.ActiveId != 0 && g.ActiveId != window->DC.LastItemId && !g.ActiveIdAllowOverlap && g.ActiveId != window->MoveId) + return false; + if (!IsMouseHoveringRect(window->DC.LastItemRect.Min, window->DC.LastItemRect.Max)) + return false; + if (!IsWindowContentHoverable(window)) + return false; + return true; } bool ImGui::IsItemRectHovered() @@ -1994,12 +1995,13 @@ bool ImGui::IsHovered(const ImRect& bb, ImGuiID id) ImGuiWindow* window = g.CurrentWindow; if (g.HoveredWindow != window) return false; - if (g.ActiveId == 0 || g.ActiveId == id || g.ActiveIdAllowOverlap) - if (IsMouseHoveringRect(bb.Min, bb.Max)) - if (IsWindowContentHoverable(g.HoveredRootWindow)) - return true; - - return false; + if (g.ActiveId != 0 && g.ActiveId != id && !g.ActiveIdAllowOverlap) + return false; + if (!IsMouseHoveringRect(bb.Min, bb.Max)) + return false; + if (!IsWindowContentHoverable(g.HoveredRootWindow)) + return false; + return true; } bool ImGui::IsClippedEx(const ImRect& bb, const ImGuiID* id, bool clip_even_when_logged) From 2159629e9ee20cfbf2d814761edb95ef76bd333b Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 28 Sep 2017 00:05:35 +0200 Subject: [PATCH 392/921] Removed another msileading difference between the hovered functions (IsWindowContentHoverable() uses the root window already). Sorry for the commit spam! (making small commit to easily be able to Bisect those in case I make a mistake) --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index fcf947b30..150ebf62b 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1999,7 +1999,7 @@ bool ImGui::IsHovered(const ImRect& bb, ImGuiID id) return false; if (!IsMouseHoveringRect(bb.Min, bb.Max)) return false; - if (!IsWindowContentHoverable(g.HoveredRootWindow)) + if (!IsWindowContentHoverable(window)) return false; return true; } From fafe65a8fcb003bb9140bd9624ef5f218f631f93 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 28 Sep 2017 00:21:47 +0200 Subject: [PATCH 393/921] Refactor to move the responsability of SetHovered() to ItemHoverable() - previously IsHovered(). Simpler and the parallel to ItemAdd is clearer with the new name. --- imgui.cpp | 41 +++++++++++++++-------------------------- imgui_internal.h | 2 +- 2 files changed, 16 insertions(+), 27 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 150ebf62b..59b4c2759 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1961,7 +1961,7 @@ bool ImGui::ItemAdd(const ImRect& bb, const ImGuiID* id) return true; } -// This is roughly matching the behavior of internal-facing IsHovered() +// This is roughly matching the behavior of internal-facing ItemHoverable() which is // - we allow hovering to be true when ActiveId==window->MoveID, so that clicking on non-interactive items such as a Text() item still returns true with IsItemHovered()) bool ImGui::IsItemHovered() { @@ -1985,8 +1985,8 @@ bool ImGui::IsItemRectHovered() return IsMouseHoveringRect(window->DC.LastItemRect.Min, window->DC.LastItemRect.Max); } -// Internal facing IsHovered() differs slightly from IsItemHovered(). -bool ImGui::IsHovered(const ImRect& bb, ImGuiID id) +// Internal facing ItemHoverable() used when submitting widgets. Differs slightly from IsItemHovered(). +bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id) { ImGuiContext& g = *GImGui; if (g.HoveredId != 0 && g.HoveredId != id && !g.HoveredIdAllowOverlap) @@ -2001,6 +2001,8 @@ bool ImGui::IsHovered(const ImRect& bb, ImGuiID id) return false; if (!IsWindowContentHoverable(window)) return false; + + SetHoveredID(id); return true; } @@ -5683,14 +5685,13 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool g.HoveredWindow = window; bool pressed = false; - bool hovered = IsHovered(bb, id); + bool hovered = ItemHoverable(bb, id); if ((flags & ImGuiButtonFlags_FlattenChilds) && g.HoveredRootWindow == window) g.HoveredWindow = backup_hovered_window; if (hovered) { - SetHoveredID(id); if (!(flags & ImGuiButtonFlags_NoKeyModifiers) || (!g.IO.KeyCtrl && !g.IO.KeyShift && !g.IO.KeyAlt)) { // | CLICKING | HOLDING with ImGuiButtonFlags_Repeat @@ -6757,10 +6758,7 @@ bool ImGui::SliderFloat(const char* label, float* v, float v_min, float v_max, c ItemSize(total_bb, style.FramePadding.y); return false; } - - const bool hovered = IsHovered(frame_bb, id); - if (hovered) - SetHoveredID(id); + const bool hovered = ItemHoverable(frame_bb, id); if (!display_format) display_format = "%.3f"; @@ -6814,10 +6812,7 @@ bool ImGui::VSliderFloat(const char* label, const ImVec2& size, float* v, float ItemSize(bb, style.FramePadding.y); if (!ItemAdd(frame_bb, &id)) return false; - - const bool hovered = IsHovered(frame_bb, id); - if (hovered) - SetHoveredID(id); + const bool hovered = ItemHoverable(frame_bb, id); if (!display_format) display_format = "%.3f"; @@ -7057,10 +7052,7 @@ bool ImGui::DragFloat(const char* label, float* v, float v_speed, float v_min, f ItemSize(total_bb, style.FramePadding.y); return false; } - - const bool hovered = IsHovered(frame_bb, id); - if (hovered) - SetHoveredID(id); + const bool hovered = ItemHoverable(frame_bb, id); if (!display_format) display_format = "%.3f"; @@ -7263,6 +7255,7 @@ void ImGui::PlotEx(ImGuiPlotType plot_type, const char* label, float (*values_ge ItemSize(total_bb, style.FramePadding.y); if (!ItemAdd(total_bb, NULL)) return; + const bool hovered = ItemHoverable(inner_bb, 0); // Determine scale from values if not specified if (scale_min == FLT_MAX || scale_max == FLT_MAX) @@ -7290,7 +7283,7 @@ void ImGui::PlotEx(ImGuiPlotType plot_type, const char* label, float (*values_ge // Tooltip on hover int v_hovered = -1; - if (IsHovered(inner_bb, 0)) + if (hovered) { const float t = ImClamp((g.IO.MousePos.x - inner_bb.Min.x) / (inner_bb.Max.x - inner_bb.Min.x), 0.0f, 0.9999f); const int v_idx = (int)(t * item_count); @@ -7851,6 +7844,9 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 if (!ItemAdd(total_bb, &id)) return false; } + const bool hovered = ItemHoverable(frame_bb, id); + if (hovered) + g.MouseCursor = ImGuiMouseCursor_TextInput; // Password pushes a temporary font with only a fallback glyph if (is_password) @@ -7876,12 +7872,6 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 const bool focus_requested_by_code = focus_requested && (window->FocusIdxAllCounter == window->FocusIdxAllRequestCurrent); const bool focus_requested_by_tab = focus_requested && !focus_requested_by_code; - const bool hovered = IsHovered(frame_bb, id); - if (hovered) - { - SetHoveredID(id); - g.MouseCursor = ImGuiMouseCursor_TextInput; - } const bool user_clicked = hovered && io.MouseClicked[0]; const bool user_scrolled = is_multiline && g.ActiveId == 0 && edit_state.Id == id && g.ActiveIdPreviousFrame == draw_window->GetIDNoKeepAlive("#SCROLLY"); @@ -9073,8 +9063,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled) if (!enabled) PopStyleColor(); } - bool hovered = enabled && IsHovered(window->DC.LastItemRect, id); - + const bool hovered = enabled && ItemHoverable(window->DC.LastItemRect, id); if (menuset_is_open) g.NavWindow = backed_nav_window; diff --git a/imgui_internal.h b/imgui_internal.h index 9329e4615..67ccf4ebe 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -771,7 +771,7 @@ namespace ImGui IMGUI_API void ItemSize(const ImRect& bb, float text_offset_y = 0.0f); IMGUI_API bool ItemAdd(const ImRect& bb, const ImGuiID* id); IMGUI_API bool IsClippedEx(const ImRect& bb, const ImGuiID* id, bool clip_even_when_logged); - IMGUI_API bool IsHovered(const ImRect& bb, ImGuiID id); + IMGUI_API bool ItemHoverable(const ImRect& bb, ImGuiID id); IMGUI_API bool FocusableItemRegister(ImGuiWindow* window, ImGuiID id, bool tab_stop = true); // Return true if focus is requested IMGUI_API void FocusableItemUnregister(ImGuiWindow* window); IMGUI_API ImVec2 CalcItemSize(ImVec2 size, float default_x, float default_y); From 0106dcbd0253df387d929b60c4edafee1254d173 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 28 Sep 2017 15:43:26 +0200 Subject: [PATCH 394/921] Fixed IsItemHovered() - part of the processing has to be done in ItemAdd() because the widget may alter clipping rectangle temporarily. --- imgui.cpp | 12 ++++++++---- imgui_demo.cpp | 5 +++-- imgui_internal.h | 4 +++- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 59b4c2759..4a1f49fc0 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1952,12 +1952,16 @@ bool ImGui::ItemAdd(const ImRect& bb, const ImGuiID* id) { ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; + const bool is_clipped = IsClippedEx(bb, id, false); window->DC.LastItemId = id ? *id : 0; window->DC.LastItemRect = bb; - if (IsClippedEx(bb, id, false)) + window->DC.LastItemRectHoveredRect = false; + if (is_clipped) return false; //if (g.IO.KeyAlt) window->DrawList->AddRect(bb.Min, bb.Max, IM_COL32(255,255,0,120)); // [DEBUG] + // We need to calculate this now to take account of the current clipping rectangle (as items like Selectable may change them) + window->DC.LastItemRectHoveredRect = IsMouseHoveringRect(bb.Min, bb.Max); return true; } @@ -1968,12 +1972,12 @@ bool ImGui::IsItemHovered() ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; + if (!window->DC.LastItemRectHoveredRect) + return false; if (g.HoveredWindow != window) return false; if (g.ActiveId != 0 && g.ActiveId != window->DC.LastItemId && !g.ActiveIdAllowOverlap && g.ActiveId != window->MoveId) return false; - if (!IsMouseHoveringRect(window->DC.LastItemRect.Min, window->DC.LastItemRect.Max)) - return false; if (!IsWindowContentHoverable(window)) return false; return true; @@ -1982,7 +1986,7 @@ bool ImGui::IsItemHovered() bool ImGui::IsItemRectHovered() { ImGuiWindow* window = GetCurrentWindowRead(); - return IsMouseHoveringRect(window->DC.LastItemRect.Min, window->DC.LastItemRect.Max); + return window->DC.LastItemRectHoveredRect; } // Internal facing ItemHoverable() used when submitting widgets. Differs slightly from IsItemHovered(). diff --git a/imgui_demo.cpp b/imgui_demo.cpp index d846faa1b..bc75508a0 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1505,7 +1505,7 @@ void ImGui::ShowTestWindow(bool* p_open) ImGui::Text("ID"); ImGui::NextColumn(); ImGui::Text("Name"); ImGui::NextColumn(); ImGui::Text("Path"); ImGui::NextColumn(); - ImGui::Text("Flags"); ImGui::NextColumn(); + ImGui::Text("Hovered"); ImGui::NextColumn(); ImGui::Separator(); const char* names[3] = { "One", "Two", "Three" }; const char* paths[3] = { "/path/one", "/path/two", "/path/three" }; @@ -1516,10 +1516,11 @@ void ImGui::ShowTestWindow(bool* p_open) sprintf(label, "%04d", i); if (ImGui::Selectable(label, selected == i, ImGuiSelectableFlags_SpanAllColumns)) selected = i; + bool hovered = ImGui::IsItemHovered(); ImGui::NextColumn(); ImGui::Text(names[i]); ImGui::NextColumn(); ImGui::Text(paths[i]); ImGui::NextColumn(); - ImGui::Text("...."); ImGui::NextColumn(); + ImGui::Text("%d", hovered); ImGui::NextColumn(); } ImGui::Columns(1); ImGui::Separator(); diff --git a/imgui_internal.h b/imgui_internal.h index 67ccf4ebe..29d8ca7cc 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -600,6 +600,7 @@ struct IMGUI_API ImGuiDrawContext int TreeDepth; ImGuiID LastItemId; ImRect LastItemRect; + bool LastItemRectHoveredRect; bool MenuBarAppending; float MenuBarOffsetX; ImVector ChildWindows; @@ -639,7 +640,8 @@ struct IMGUI_API ImGuiDrawContext LogLinePosY = -1.0f; TreeDepth = 0; LastItemId = 0; - LastItemRect = ImRect(0.0f,0.0f,0.0f,0.0f); + LastItemRect = ImRect(); + LastItemRectHoveredRect = false; MenuBarAppending = false; MenuBarOffsetX = 0.0f; StateStorage = NULL; From 914200212187d9d2e30b56420af256642ee63e07 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 28 Sep 2017 16:40:28 +0200 Subject: [PATCH 395/921] Separator(): Tweak Logging so that the separator text is aligned according to tree padding. --- imgui.cpp | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 4a1f49fc0..496b677b9 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -590,8 +590,6 @@ // Forward Declarations //------------------------------------------------------------------------- -static void LogRenderedText(const ImVec2& ref_pos, const char* text, const char* text_end = NULL); - static float GetDraggedColumnOffset(int column_index); static bool IsKeyPressedMap(ImGuiKey key, bool repeat = true); @@ -2870,7 +2868,7 @@ void ImGui::LogText(const char* fmt, ...) // Internal version that takes a position to decide on newline placement and pad items according to their depth. // We split text into individual lines to add current tree level padding -static void LogRenderedText(const ImVec2& ref_pos, const char* text, const char* text_end) +static void LogRenderedText(const ImVec2* ref_pos, const char* text, const char* text_end = NULL) { ImGuiContext& g = *GImGui; ImGuiWindow* window = ImGui::GetCurrentWindowRead(); @@ -2878,8 +2876,9 @@ static void LogRenderedText(const ImVec2& ref_pos, const char* text, const char* if (!text_end) text_end = ImGui::FindRenderedTextEnd(text, text_end); - const bool log_new_line = ref_pos.y > window->DC.LogLinePosY+1; - window->DC.LogLinePosY = ref_pos.y; + const bool log_new_line = ref_pos && (ref_pos->y > window->DC.LogLinePosY + 1); + if (ref_pos) + window->DC.LogLinePosY = ref_pos->y; const char* text_remaining = text; if (g.LogStartDepth > window->DC.TreeDepth) // Re-adjust padding if we have popped out of our starting depth @@ -2944,7 +2943,7 @@ void ImGui::RenderText(ImVec2 pos, const char* text, const char* text_end, bool { window->DrawList->AddText(g.Font, g.FontSize, pos, GetColorU32(ImGuiCol_Text), text, text_display_end); if (g.LogEnabled) - LogRenderedText(pos, text, text_display_end); + LogRenderedText(&pos, text, text_display_end); } } @@ -2961,7 +2960,7 @@ void ImGui::RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end { window->DrawList->AddText(g.Font, g.FontSize, pos, GetColorU32(ImGuiCol_Text), text, text_end, wrap_width); if (g.LogEnabled) - LogRenderedText(pos, text, text_end); + LogRenderedText(&pos, text, text_end); } } @@ -3003,7 +3002,7 @@ void ImGui::RenderTextClipped(const ImVec2& pos_min, const ImVec2& pos_max, cons window->DrawList->AddText(g.Font, g.FontSize, pos, GetColorU32(ImGuiCol_Text), text, text_display_end, 0.0f, NULL); } if (g.LogEnabled) - LogRenderedText(pos, text, text_display_end); + LogRenderedText(&pos, text, text_display_end); } // Render a rectangle shaped with optional rounding and borders @@ -4288,7 +4287,7 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us if (window->Collapsed) { // Title bar only - RenderFrame(title_bar_rect.GetTL(), title_bar_rect.GetBR(), GetColorU32(ImGuiCol_TitleBgCollapsed), true, window_rounding); + RenderFrame(title_bar_rect.Min, title_bar_rect.Max, GetColorU32(ImGuiCol_TitleBgCollapsed), true, window_rounding); } else { @@ -6148,9 +6147,9 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l // NB: '##' is normally used to hide text (as a library-wide feature), so we need to specify the text range to make sure the ## aren't stripped out here. const char log_prefix[] = "\n##"; const char log_suffix[] = "##"; - LogRenderedText(text_pos, log_prefix, log_prefix+3); + LogRenderedText(&text_pos, log_prefix, log_prefix+3); RenderTextClipped(text_pos, bb.Max, label, label_end, &label_size); - LogRenderedText(text_pos, log_suffix+1, log_suffix+3); + LogRenderedText(&text_pos, log_suffix+1, log_suffix+3); } else { @@ -6168,7 +6167,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l else if (!(flags & ImGuiTreeNodeFlags_Leaf)) RenderCollapseTriangle(bb.Min + ImVec2(padding.x, g.FontSize*0.15f + text_base_offset_y), is_open, 0.70f); if (g.LogEnabled) - LogRenderedText(text_pos, ">"); + LogRenderedText(&text_pos, ">"); RenderText(text_pos, label, label_end, false); } @@ -7461,9 +7460,9 @@ bool ImGui::Checkbox(const char* label, bool* v) } if (g.LogEnabled) - LogRenderedText(text_bb.GetTL(), *v ? "[x]" : "[ ]"); + LogRenderedText(&text_bb.Min, *v ? "[x]" : "[ ]"); if (label_size.x > 0.0f) - RenderText(text_bb.GetTL(), label); + RenderText(text_bb.Min, label); return pressed; } @@ -7533,9 +7532,9 @@ bool ImGui::RadioButton(const char* label, bool active) } if (g.LogEnabled) - LogRenderedText(text_bb.GetTL(), active ? "(x)" : "( )"); + LogRenderedText(&text_bb.Min, active ? "(x)" : "( )"); if (label_size.x > 0.0f) - RenderText(text_bb.GetTL(), label); + RenderText(text_bb.Min, label); return pressed; } @@ -8378,7 +8377,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 // Log as text if (g.LogEnabled && !is_password) - LogRenderedText(render_pos, buf_display, NULL); + LogRenderedText(&render_pos, buf_display, NULL); if (label_size.x > 0) RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label); @@ -9917,7 +9916,7 @@ void ImGui::Separator() window->DrawList->AddLine(bb.Min, ImVec2(bb.Max.x,bb.Min.y), GetColorU32(ImGuiCol_Separator)); if (g.LogEnabled) - LogText(IM_NEWLINE "--------------------------------"); + LogRenderedText(NULL, IM_NEWLINE "--------------------------------"); if (window->DC.ColumnsCount > 1) { From f99348711bb85047ebd3fce743090af3f5df2e9a Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 28 Sep 2017 16:41:01 +0200 Subject: [PATCH 396/921] Added VerticalSeparator() entry point in imgui_internal. Seperator() in an horizontal layout context still does that. --- imgui.cpp | 87 +++++++++++++++++++++++++----------------------- imgui.h | 2 +- imgui_internal.h | 2 ++ 3 files changed, 49 insertions(+), 42 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 496b677b9..c791da66b 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9879,65 +9879,70 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl // Horizontal separating line. void ImGui::Separator() { - ImGuiContext& g = *GImGui; ImGuiWindow* window = GetCurrentWindow(); if (window->SkipItems) return; + ImGuiContext& g = *GImGui; ImGuiWindowFlags flags = 0; if ((flags & (ImGuiSeparatorFlags_Horizontal | ImGuiSeparatorFlags_Vertical)) == 0) - { - if (window->DC.LayoutType == ImGuiLayoutType_Horizontal) - flags |= ImGuiSeparatorFlags_Vertical; - else - flags |= ImGuiSeparatorFlags_Horizontal; - } + flags |= (window->DC.LayoutType == ImGuiLayoutType_Horizontal) ? ImGuiSeparatorFlags_Vertical : ImGuiSeparatorFlags_Horizontal; IM_ASSERT(ImIsPowerOfTwo((int)(flags & (ImGuiSeparatorFlags_Horizontal | ImGuiSeparatorFlags_Vertical)))); // Check that only 1 option is selected + if (flags & ImGuiSeparatorFlags_Vertical) + { + VerticalSeparator(); + return; + } - if (flags & ImGuiSeparatorFlags_Horizontal) + // Horizontal Separator + if (window->DC.ColumnsCount > 1) + PopClipRect(); + + float x1 = window->Pos.x; + float x2 = window->Pos.x + window->Size.x; + if (!window->DC.GroupStack.empty()) + x1 += window->DC.IndentX; + + const ImRect bb(ImVec2(x1, window->DC.CursorPos.y), ImVec2(x2, window->DC.CursorPos.y+1.0f)); + ItemSize(ImVec2(0.0f, 0.0f)); // NB: we don't provide our width so that it doesn't get feed back into AutoFit, we don't provide height to not alter layout. + if (!ItemAdd(bb, NULL)) { if (window->DC.ColumnsCount > 1) - PopClipRect(); + PushColumnClipRect(); + return; + } - float x1 = window->Pos.x; - float x2 = window->Pos.x + window->Size.x; - if (!window->DC.GroupStack.empty()) - x1 += window->DC.IndentX; + window->DrawList->AddLine(bb.Min, ImVec2(bb.Max.x,bb.Min.y), GetColorU32(ImGuiCol_Separator)); - const ImRect bb(ImVec2(x1, window->DC.CursorPos.y), ImVec2(x2, window->DC.CursorPos.y+1.0f)); - ItemSize(ImVec2(0.0f, 0.0f)); // NB: we don't provide our width so that it doesn't get feed back into AutoFit, we don't provide height to not alter layout. - if (!ItemAdd(bb, NULL)) - { - if (window->DC.ColumnsCount > 1) - PushColumnClipRect(); - return; - } - - window->DrawList->AddLine(bb.Min, ImVec2(bb.Max.x,bb.Min.y), GetColorU32(ImGuiCol_Separator)); - - if (g.LogEnabled) + if (g.LogEnabled) LogRenderedText(NULL, IM_NEWLINE "--------------------------------"); - if (window->DC.ColumnsCount > 1) - { - PushColumnClipRect(); - window->DC.ColumnsCellMinY = window->DC.CursorPos.y; - } - } - else if (flags & ImGuiSeparatorFlags_Vertical) + if (window->DC.ColumnsCount > 1) { - const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(1.0f, window->DC.CurrentLineHeight)); - ItemSize(ImVec2(bb.GetWidth(), 0.0f)); - if (!ItemAdd(bb, NULL)) - return; - - window->DrawList->AddLine(ImVec2(bb.Min.x, bb.Min.y), ImVec2(bb.Min.x, bb.Max.y), GetColorU32(ImGuiCol_Separator)); - - if (g.LogEnabled) - LogText("|"); + PushColumnClipRect(); + window->DC.ColumnsCellMinY = window->DC.CursorPos.y; } } +void ImGui::VerticalSeparator() +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return; + ImGuiContext& g = *GImGui; + + float y1 = window->DC.CursorPos.y; + float y2 = window->DC.CursorPos.y + window->DC.CurrentLineHeight; + const ImRect bb(ImVec2(window->DC.CursorPos.x, y1), ImVec2(window->DC.CursorPos.x + 1.0f, y2)); + ItemSize(ImVec2(bb.GetWidth(), 0.0f)); + if (!ItemAdd(bb, NULL)) + return; + + window->DrawList->AddLine(ImVec2(bb.Min.x, bb.Min.y), ImVec2(bb.Min.x, bb.Max.y), GetColorU32(ImGuiCol_Separator)); + if (g.LogEnabled) + LogText(" |"); +} + void ImGui::Spacing() { ImGuiWindow* window = GetCurrentWindow(); diff --git a/imgui.h b/imgui.h index 48eda19c8..0740592f1 100644 --- a/imgui.h +++ b/imgui.h @@ -209,7 +209,7 @@ namespace ImGui IMGUI_API void PopButtonRepeat(); // Cursor / Layout - IMGUI_API void Separator(); // horizontal line + IMGUI_API void Separator(); // separator, generally horizontal. inside a menu bar or in horizontal layout mode, this becomes a vertical separator. IMGUI_API void SameLine(float pos_x = 0.0f, float spacing_w = -1.0f); // call between widgets or groups to layout them horizontally IMGUI_API void NewLine(); // undo a SameLine() IMGUI_API void Spacing(); // add vertical spacing diff --git a/imgui_internal.h b/imgui_internal.h index 29d8ca7cc..7687c393d 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -789,6 +789,8 @@ namespace ImGui IMGUI_API int CalcTypematicPressedRepeatAmount(float t, float t_prev, float repeat_delay, float repeat_rate); + IMGUI_API void VerticalSeparator(); // Vertical separator, for menu bars (use current line height). not exposed because it is misleading what it doesn't have an effect on regular layout. + // FIXME-WIP: New Columns API IMGUI_API void BeginColumns(const char* id, int count, ImGuiColumnsFlags flags = 0); // setup number of columns. use an identifier to distinguish multiple column sets. close with EndColumns(). IMGUI_API void EndColumns(); // close columns From 926c1cf9a43f739d3a6ab7c9144d15917dfac2be Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 28 Sep 2017 17:02:28 +0200 Subject: [PATCH 397/921] Merged from Navigation branch: ImGuiItemFlags_SelectableDontClosePopup flag --- imgui.cpp | 2 +- imgui_internal.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index c791da66b..49282a40d 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -8813,7 +8813,7 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl if (flags & ImGuiSelectableFlags_Disabled) PopStyleColor(); // Automatically close popups - if (pressed && !(flags & ImGuiSelectableFlags_DontClosePopups) && (window->Flags & ImGuiWindowFlags_Popup)) + if (pressed && (window->Flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiSelectableFlags_DontClosePopups) && !(window->DC.ItemFlags & ImGuiItemFlags_SelectableDontClosePopup)) CloseCurrentPopup(); return pressed; } diff --git a/imgui_internal.h b/imgui_internal.h index 7687c393d..84eec71d1 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -580,8 +580,8 @@ enum ImGuiItemFlags_ ImGuiItemFlags_ButtonRepeat = 1 << 1, // false // Button() will return true multiple times based on io.KeyRepeatDelay and io.KeyRepeatRate settings. //ImGuiItemFlags_Disabled = 1 << 2, // false // All widgets appears are disabled //ImGuiItemFlags_AllowNavDefaultFocus = 1 << 3, // true - //ImGuiItemFlags_SelectableDontClosePopup = 1 << 4, // false // MenuItem/Selectable() automatically closes current Popup window - ImGuiItemFlags_Default_ = ImGuiItemFlags_AllowKeyboardFocus + ImGuiItemFlags_SelectableDontClosePopup = 1 << 4, // false // MenuItem/Selectable() automatically closes current Popup window + ImGuiItemFlags_Default_ = ImGuiItemFlags_AllowKeyboardFocus }; // Transient per-window data, reset at the beginning of the frame From e8f7c83138bfcd5f4bab6d15ed9fc8eeded7b063 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 28 Sep 2017 17:37:55 +0200 Subject: [PATCH 398/921] Begin: Shallow tweak to minimize diff with nav branch --- imgui.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 49282a40d..85840bfb0 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4448,6 +4448,12 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us // Title bar if (!(flags & ImGuiWindowFlags_NoTitleBar)) { + // Collapse button + if (!(flags & ImGuiWindowFlags_NoCollapse)) + { + RenderCollapseTriangle(window->Pos + style.FramePadding, !window->Collapsed, 1.0f); + } + // Close button if (p_open != NULL) { @@ -4457,10 +4463,8 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us *p_open = false; } + // Title text (FIXME: refactor text alignment facilities along with RenderText helpers) const ImVec2 text_size = CalcTextSize(name, NULL, true); - if (!(flags & ImGuiWindowFlags_NoCollapse)) - RenderCollapseTriangle(window->Pos + style.FramePadding, !window->Collapsed, 1.0f); - ImVec2 text_min = window->Pos; ImVec2 text_max = window->Pos + ImVec2(window->Size.x, style.FramePadding.y*2 + text_size.y); ImRect clip_rect; @@ -6979,6 +6983,7 @@ bool ImGui::DragBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v_s if (v_speed == 0.0f && (v_max - v_min) != 0.0f && (v_max - v_min) < FLT_MAX) v_speed = (v_max - v_min) * g.DragSpeedDefaultRatio; + float v_cur = g.DragCurrentValue; const ImVec2 mouse_drag_delta = GetMouseDragDelta(0, 1.0f); float adjust_delta = 0.0f; From c0cf123e0b84bda9cb73bd90bec8282a34ed26e1 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 28 Sep 2017 20:39:36 +0200 Subject: [PATCH 399/921] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index c25d53450..5e1174b09 100644 --- a/README.md +++ b/README.md @@ -98,9 +98,9 @@ See the [Screenshots Thread](https://github.com/ocornut/imgui/issues/123) for so [![screenshot profiler](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v148/profiler-880.jpg)](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v148/profiler.png) -![screenshot 3](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v143/test_window_01.png) -![screenshot 4](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v143/test_window_03.png) -![screenshot 5](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v140/test_window_05_menus.png) +![screenshot picker](https://user-images.githubusercontent.com/8225057/29062188-471e95ba-7c53-11e7-9618-c4484c0b75fe.PNG) + +![screenshot 5](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v151/menus.png) ![screenshot 6](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v143/skinning_sample_02.png) ![screenshot 7](https://cloud.githubusercontent.com/assets/8225057/7903336/96f0fb7c-07d0-11e5-95d6-41c6a1595e5a.png) From 164f22d5b7e5d6e4356d616d64ea428e648470d2 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 28 Sep 2017 19:35:10 +0200 Subject: [PATCH 400/921] Comments --- imgui_internal.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/imgui_internal.h b/imgui_internal.h index 84eec71d1..392de3eaf 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -169,13 +169,13 @@ inline void operator delete(void*, ImPlacementNewDummy, void*) {} enum ImGuiButtonFlags_ { ImGuiButtonFlags_Repeat = 1 << 0, // hold to repeat - ImGuiButtonFlags_PressedOnClickRelease = 1 << 1, // (default) return pressed on click+release on same item (default if no PressedOn** flag is set) - ImGuiButtonFlags_PressedOnClick = 1 << 2, // return pressed on click (default requires click+release) - ImGuiButtonFlags_PressedOnRelease = 1 << 3, // return pressed on release (default requires click+release) - ImGuiButtonFlags_PressedOnDoubleClick = 1 << 4, // return pressed on double-click (default requires click+release) - ImGuiButtonFlags_FlattenChilds = 1 << 5, // allow interaction even if a child window is overlapping - ImGuiButtonFlags_DontClosePopups = 1 << 6, // disable automatically closing parent popup on press - ImGuiButtonFlags_Disabled = 1 << 7, // disable interaction + ImGuiButtonFlags_PressedOnClickRelease = 1 << 1, // return true on click + release on same item [DEFAULT if no PressedOn* flag is set] + ImGuiButtonFlags_PressedOnClick = 1 << 2, // return true on click (default requires click+release) + ImGuiButtonFlags_PressedOnRelease = 1 << 3, // return true on release (default requires click+release) + ImGuiButtonFlags_PressedOnDoubleClick = 1 << 4, // return true on double-click (default requires click+release) + ImGuiButtonFlags_FlattenChilds = 1 << 5, // allow interactions even if a child window is overlapping + ImGuiButtonFlags_DontClosePopups = 1 << 6, // disable automatically closing parent popup on press // [UNUSED] + ImGuiButtonFlags_Disabled = 1 << 7, // disable interactions ImGuiButtonFlags_AlignTextBaseLine = 1 << 8, // vertically align button to match text baseline - ButtonEx() only ImGuiButtonFlags_NoKeyModifiers = 1 << 9, // disable interaction if a key modifier is held ImGuiButtonFlags_AllowOverlapMode = 1 << 10 // require previous frame HoveredId to either match id or be null before being usable From 3b85a8b6a0f0063a3fc7d1dbc18a0dff7a1d17e9 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 28 Sep 2017 20:15:32 +0200 Subject: [PATCH 401/921] Demo: Added an extra test related to baseline and fixed an id collision. --- imgui_demo.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index bc75508a0..781ef121a 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -808,7 +808,7 @@ void ImGui::ShowTestWindow(bool* p_open) } ImGui::Text("Color button only:"); - ImGui::ColorButton("MyColor##3b", *(ImVec4*)&color, misc_flags, ImVec2(80,80)); + ImGui::ColorButton("MyColor##3c", *(ImVec4*)&color, misc_flags, ImVec2(80,80)); ImGui::Text("Color picker:"); static bool alpha = true; @@ -1183,7 +1183,8 @@ void ImGui::ShowTestWindow(bool* p_open) ImGui::Text("Text aligned to Widget"); ImGui::SameLine(); ImGui::Button("Widget##1"); ImGui::SameLine(); ImGui::Text("Widget"); ImGui::SameLine(); - ImGui::SmallButton("Widget##2"); + ImGui::SmallButton("Widget##2"); ImGui::SameLine(); + ImGui::Button("Widget##3"); // Tree const float spacing = ImGui::GetStyle().ItemInnerSpacing.x; From fba9353c603e787c4b6752c8f1efb1cab2d143fc Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 29 Sep 2017 16:29:00 +0200 Subject: [PATCH 402/921] BeginMenu: Shuffling braces around to clarify flow --- imgui.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 85840bfb0..3d00e84bf 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9100,14 +9100,18 @@ bool ImGui::BeginMenu(const char* label, bool enabled) want_close = (menu_is_open && !hovered && g.HoveredWindow == window && g.HoveredIdPreviousFrame != 0 && g.HoveredIdPreviousFrame != id && !moving_within_opened_triangle); want_open = (!menu_is_open && hovered && !moving_within_opened_triangle) || (!menu_is_open && hovered && pressed); } - else if (menu_is_open && pressed && menuset_is_open) // Menu bar: click an open menu again to close it + else { - want_close = true; - want_open = menu_is_open = false; - } - else if (pressed || (hovered && menuset_is_open && !menu_is_open)) // menu-bar: first click to open, then hover to open others - { - want_open = true; + // Menu bar + if (menu_is_open && pressed && menuset_is_open) // Click an open menu again to close it + { + want_close = true; + want_open = menu_is_open = false; + } + else if (pressed || (hovered && menuset_is_open && !menu_is_open)) // First click to open, then hover to open others + { + want_open = true; + } } if (!enabled) // explicitly close if an open menu becomes disabled, facilitate users code a lot in pattern such as 'if (BeginMenu("options", has_object)) { ..use object.. }' From 9912f7eef80a7f8fda21a5c92eb4fcc4e32ee4dd Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 29 Sep 2017 22:19:53 +0200 Subject: [PATCH 403/921] BeginMenu(): fixed logic to distinguish vertical menu from one layed out in a menu bar. Makes MenuItem() in a regular window behave more consistently, and this will be also needed by upcoming menu-navigation changes in the nav branch. (#126, #787) --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 3d00e84bf..849a05f4d 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9076,7 +9076,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled) g.NavWindow = backed_nav_window; bool want_open = false, want_close = false; - if (window->Flags & (ImGuiWindowFlags_Popup|ImGuiWindowFlags_ChildMenu)) + if (window->DC.LayoutType != ImGuiLayoutType_Horizontal) // (window->Flags & (ImGuiWindowFlags_Popup|ImGuiWindowFlags_ChildMenu)) { // Implement http://bjk5.com/post/44698559168/breaking-down-amazons-mega-dropdown to avoid using timers, so menus feels more reactive. bool moving_within_opened_triangle = false; From c38526d14b38eff269032ac2b00a748ee16964c6 Mon Sep 17 00:00:00 2001 From: Anthony Pesch Date: Sun, 1 Oct 2017 23:40:29 -0400 Subject: [PATCH 404/921] Completely clear font when rebuilding atlas. Previously, IndexLookup was not cleared on each font, causing FindGlyph to return old glyphs when using MergeMode. --- imgui_draw.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 736476891..b45cc1ffd 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1540,7 +1540,6 @@ bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas) const float off_x = cfg.GlyphOffset.x; const float off_y = cfg.GlyphOffset.y + (float)(int)(dst_font->Ascent + 0.5f); - dst_font->FallbackGlyph = NULL; // Always clear fallback so FindGlyph can return NULL. It will be set again in BuildLookupTable() for (int i = 0; i < tmp.RangesCount; i++) { stbtt_pack_range& range = tmp.Ranges[i]; @@ -1582,14 +1581,16 @@ void ImFontAtlasBuildSetupFont(ImFontAtlas* atlas, ImFont* font, ImFontConfig* f { if (!font_config->MergeMode) { - font->ContainerAtlas = atlas; - font->ConfigData = font_config; - font->ConfigDataCount = 0; + ImVec2 display_offset = font->DisplayOffset; + + font->Clear(); + font->FontSize = font_config->SizePixels; + font->DisplayOffset = display_offset; + font->ConfigData = font_config; + font->ContainerAtlas = atlas; font->Ascent = ascent; font->Descent = descent; - font->Glyphs.resize(0); - font->MetricsTotalSurface = 0; } font->ConfigDataCount++; } From cbc9730798b9971794d3c63480aca918f72f857e Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 2 Oct 2017 15:36:52 -0700 Subject: [PATCH 405/921] Metrics: Draw window bounding boxes when hovering Pos/Size. List all draw layers, trimming empty commands like Render() does. --- imgui.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 849a05f4d..75c018353 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -10590,6 +10590,8 @@ void ImGui::ShowMetricsWindow(bool* p_open) int elem_offset = 0; for (const ImDrawCmd* pcmd = draw_list->CmdBuffer.begin(); pcmd < draw_list->CmdBuffer.end(); elem_offset += pcmd->ElemCount, pcmd++) { + if (pcmd->UserCallback == NULL && pcmd->ElemCount == 0) + continue; if (pcmd->UserCallback) { ImGui::BulletText("Callback %p, user_data %p", pcmd->UserCallback, pcmd->UserCallbackData); @@ -10644,8 +10646,9 @@ void ImGui::ShowMetricsWindow(bool* p_open) if (!ImGui::TreeNode(window, "%s '%s', %d @ 0x%p", label, window->Name, window->Active || window->WasActive, window)) return; NodeDrawList(window->DrawList, "DrawList"); - ImGui::BulletText("Pos: (%.1f,%.1f)", window->Pos.x, window->Pos.y); - ImGui::BulletText("Size: (%.1f,%.1f), SizeContents (%.1f,%.1f)", window->Size.x, window->Size.y, window->SizeContents.x, window->SizeContents.y); + ImGui::BulletText("Pos: (%.1f,%.1f), Size: (%.1f,%.1f), SizeContents (%.1f,%.1f)", window->Pos.x, window->Pos.y, window->Size.x, window->Size.y, window->SizeContents.x, window->SizeContents.y); + if (ImGui::IsItemHovered()) + GImGui->OverlayDrawList.AddRect(window->Pos, window->Pos + window->Size, IM_COL32(255,255,0,255)); ImGui::BulletText("Scroll: (%.2f,%.2f)", window->Scroll.x, window->Scroll.y); ImGui::BulletText("Active: %d, Accessed: %d", window->Active, window->Accessed); if (window->RootWindow != window) NodeWindow(window->RootWindow, "RootWindow"); @@ -10659,8 +10662,9 @@ void ImGui::ShowMetricsWindow(bool* p_open) Funcs::NodeWindows(g.Windows, "Windows"); if (ImGui::TreeNode("DrawList", "Active DrawLists (%d)", g.RenderDrawLists[0].Size)) { - for (int i = 0; i < g.RenderDrawLists[0].Size; i++) - Funcs::NodeDrawList(g.RenderDrawLists[0][i], "DrawList"); + for (int layer = 0; layer < IM_ARRAYSIZE(g.RenderDrawLists); layer++) + for (int i = 0; i < g.RenderDrawLists[layer].Size; i++) + Funcs::NodeDrawList(g.RenderDrawLists[0][i], "DrawList"); ImGui::TreePop(); } if (ImGui::TreeNode("Popups", "Open Popups Stack (%d)", g.OpenPopupStack.Size)) From 7f58bb03c145227ead5e2bfd03ab5f3022fab529 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 2 Oct 2017 15:46:00 -0700 Subject: [PATCH 406/921] Changed the internal name formatting of child windows to use slashes as separator, more readable. --- imgui.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 75c018353..4761a542b 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3720,9 +3720,9 @@ static bool BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, b char title[256]; if (name) - ImFormatString(title, IM_ARRAYSIZE(title), "%s.%s.%08X", parent_window->Name, name, id); + ImFormatString(title, IM_ARRAYSIZE(title), "%s/%s_%08X", parent_window->Name, name, id); else - ImFormatString(title, IM_ARRAYSIZE(title), "%s.%08X", parent_window->Name, id); + ImFormatString(title, IM_ARRAYSIZE(title), "%s/%08X", parent_window->Name, id); bool ret = ImGui::Begin(title, NULL, size, -1.0f, flags); ImGuiWindow* child_window = ImGui::GetCurrentWindow(); From 6ec50d6bf5f9e4f853a664dcb13357958d9f7f19 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Tue, 3 Oct 2017 11:45:25 -0700 Subject: [PATCH 407/921] Fix binary_to_compressed_c tool to return 0 when successful Returning 1 is seen as an error by many tools, making it tricky to integrate this into build systems as-is. --- extra_fonts/binary_to_compressed_c.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/extra_fonts/binary_to_compressed_c.cpp b/extra_fonts/binary_to_compressed_c.cpp index ee160a42a..e373e69c6 100644 --- a/extra_fonts/binary_to_compressed_c.cpp +++ b/extra_fonts/binary_to_compressed_c.cpp @@ -53,8 +53,7 @@ int main(int argc, char** argv) } } - binary_to_compressed_c(argv[argn], argv[argn+1], use_base85_encoding, use_compression); - return 1; + return binary_to_compressed_c(argv[argn], argv[argn+1], use_base85_encoding, use_compression) ? 0 : 1; } char Encode85Byte(unsigned int x) From b36a043bbfc7c812024a0a02d63b15b134389cbb Mon Sep 17 00:00:00 2001 From: matiTechno Date: Wed, 4 Oct 2017 11:09:21 +0200 Subject: [PATCH 408/921] typo --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 4761a542b..f1fdb508f 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -105,7 +105,7 @@ - See examples/ folder for standalone sample applications. To understand the integration process, you can read examples/opengl2_example/ because it is short, then switch to the one more appropriate to your use case. - You may be able to grab and copy a ready made imgui_impl_*** file from the examples/. - - When using Dear ImGui, your programming IDE if your friend: follow the declaration of variables, functions and types to find comments about them. + - When using Dear ImGui, your programming IDE is your friend: follow the declaration of variables, functions and types to find comments about them. - Init: retrieve the ImGuiIO structure with ImGui::GetIO() and fill the fields marked 'Settings': at minimum you need to set io.DisplaySize (application resolution). Later on you will fill your keyboard mapping, clipboard handlers, and other advanced features but for a basic integration you don't need to worry about it all. From 89ab4b5e07d53104917e18929e1e18c1af3d47da Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 4 Oct 2017 11:56:03 -0700 Subject: [PATCH 409/921] TODO update --- TODO.txt | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/TODO.txt b/TODO.txt index 92535d08d..d2820c75d 100644 --- a/TODO.txt +++ b/TODO.txt @@ -25,6 +25,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - window: double-clicking on title bar to minimize isn't consistent, perhaps move to single-click on left-most collapse icon? - window: expose contents size. (#1045) - window: GetWindowSize() returns (0,0) when not calculated? (#1045) + - window: freeze window flag: if not focused/hovered, return false, render with previous ImDrawList. and/or reduce refresh rate. !- scrolling: allow immediately effective change of scroll after Begin() if we haven't appended items yet. - scrolling/clipping: separator on the initial position of a window is not visible (cursorpos.y <= clippos.y). (2017-08-20: can't repro) @@ -55,6 +56,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - input text: flag to disable live update of the user buffer (also applies to float/int text input) (#701) - input text: way to dynamically grow the buffer without forcing the user to initially allocate for worse case, e.g. more natural std::string (follow up on #200) - input text: hover tooltip could show unclamped text + - input text: option to Tab after an Enter validation. - input text: add ImGuiInputTextFlags_EnterToApply? (off #218) - input text: easier ways to update buffer (from source char*) while owned. preserve some sort of cursor position for multi-line text. - input text: add discard flag (e.g. ImGuiInputTextFlags_DiscardActiveBuffer) or make it easier to clear active focus for text replacement during edition (#725) @@ -80,7 +82,9 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - columns: sizing policy (e.g. for each column: fixed size, %, fill, distribute default size among fills) (#513, #125) - columns: add a conditional parameter to SetColumnOffset() (#513, #125) - - columns: headers. with sort op/button. reorderable. (#513, #125) + - columns: headers. reorderable. (#513, #125) + - columns: optional sorting modifiers (up/down), sort list so sorting can be done multi-critera. notify user when sort order changed. + - columns: option to alternate background colors on odd/even scanlines. - columns: allow columns to recurse. - columns: separator function or parameter that works within the column (currently Separator() bypass all columns) (#125) - columns: flag to add horizontal separator above/below? @@ -134,7 +138,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - combo: option for ComboEx to not return true when unchanged (#1182) - combo/listbox: keyboard control. need InputText-like non-active focus + key handling. considering keyboard for custom listbox (pr #203) - listbox: multiple selection. - - listbox: unselect (#1208) + - listbox: unselect option (#1208) - listbox: make it easier/more natural to implement range-select (need some sort of info/ref about the last clicked/focused item that user can translate to an index?) - listbox: user may want to initial scroll to focus on the one selected value? - listbox: expose hovered item for a basic ListBox @@ -142,7 +146,6 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - listbox: scrolling should track modified selection. !- popups/menus: clarify usage of popups id, how MenuItem/Selectable closing parent popups affects the ID, etc. this is quite fishy needs improvement! (#331, #402) - - popups/nav: esc/enter default behavior for popups. - popups: reopening context menu at new position should be the behavior by default? (equivalent to internal OpenPopupEx() with reopen_existing=true) - popups: if the popup functions took explicit ImGuiID it would allow the user to manage the scope of those ID. (#331) - popups: clicking outside (to close popup) and holding shouldn't drag window below. @@ -217,13 +220,16 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - font: fix AddRemapChar() to work before font has been built. - font: (api breaking) removed "TTF" from symbol names. also because it now supports OTF. -!- keyboard: tooltip & combo boxes are messing up / not honoring keyboard tabbing. - - keyboard: full keyboard navigation and focus. (#323) +!- nav/keyboard: tooltip & combo boxes are messing up / not honoring keyboard tabbing. + - nav: integrate navigation branch into master. (#787) + - nav: integrate/design keyboard controls. + - nav: once tab should go through most/all widgets (in submission order?) + - nav: esc/enter default behavior for popups, e.g. be able to mark an "ok" or "cancel" button that would get triggered by those keys. - focus: preserve ActiveId/focus stack state, e.g. when opening a menu and close it, previously selected InputText() focus gets restored (#622) - focus: SetKeyboardFocusHere() on with >= 0 offset could be done on same frame (else latch and modulate on beginning of next frame) - - focus: unable to use SetKeyboardFocusHere() on clipped widgets. (#343) + - focus: unable to use SetKeyboardFocusHere() on clipped widgets. (#787) - inputs: rework IO system to be able to pass actual ordered/timestamped events. use an event queue? (~#335, #71) - - inputs: allow to decide and pass explicit double-clicks (e.g. for windows by the CS_DBLCLKS style). + - inputs: allow to pass explicit double-clicks if that's the only thing the user's backend can get them. (e.g. for windows by the CS_DBLCLKS style). - inputs: support track pad style scrolling & slider edit. - misc: provide a way to compile out the entire implementation while providing a dummy API (e.g. #define IMGUI_DUMMY_IMPL) From 67ac7da30f2372dbd9c7371ef42114a436f6659d Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 4 Oct 2017 18:13:57 -0700 Subject: [PATCH 410/921] Styles: Added ImGuiStyle::ScaleAllSizes(float) helper to make it easier to have application transition to e.g. High DPI with a matching style. --- imgui.cpp | 23 +++++++++++++++++++++++ imgui.h | 1 + 2 files changed, 24 insertions(+) diff --git a/imgui.cpp b/imgui.cpp index f1fdb508f..21aba4ebc 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -744,6 +744,29 @@ void ImGui::StyleColorsClassic(ImGuiStyle* dst) colors[ImGuiCol_ModalWindowDarkening] = ImVec4(0.20f, 0.20f, 0.20f, 0.35f); } +// To scale your entire UI (e.g. if you want your app to use High DPI or generally be DPI aware) you may use this helper function. Scaling the fonts is done separately and is up to you. +// Tips: if you need to change your scale multiple times, prefer calling this on a freshly initialized ImGuiStyle structure rather than scaling multiple times (because floating point multiplications are lossy). +void ImGuiStyle::ScaleAllSizes(float scale_factor) +{ + WindowPadding *= scale_factor; + WindowMinSize *= scale_factor; + WindowRounding *= scale_factor; + ChildWindowRounding *= scale_factor; + FramePadding *= scale_factor; + FrameRounding *= scale_factor; + ItemSpacing *= scale_factor; + ItemInnerSpacing *= scale_factor; + TouchExtraPadding *= scale_factor; + IndentSpacing *= scale_factor; + ColumnsMinSpacing *= scale_factor; + ScrollbarSize *= scale_factor; + ScrollbarRounding *= scale_factor; + GrabMinSize *= scale_factor; + GrabRounding *= scale_factor; + DisplayWindowPadding *= scale_factor; + DisplaySafeAreaPadding *= scale_factor; +} + ImGuiIO::ImGuiIO() { // Most fields are initialized with zero diff --git a/imgui.h b/imgui.h index 0740592f1..654e83fcb 100644 --- a/imgui.h +++ b/imgui.h @@ -769,6 +769,7 @@ struct ImGuiStyle ImVec4 Colors[ImGuiCol_COUNT]; IMGUI_API ImGuiStyle(); + IMGUI_API void ScaleAllSizes(float scale_factor); }; // This is where your app communicate with ImGui. Access via ImGui::GetIO(). From b3099d650c2ee73683e85a0be0b6761ee741aa1d Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 4 Oct 2017 19:28:04 -0700 Subject: [PATCH 411/921] Examples: Adding Roboto to the commented-out font list, and removing the unnecessary ProggyClean from there. --- examples/allegro5_example/main.cpp | 2 +- examples/directx10_example/main.cpp | 2 +- examples/directx11_example/main.cpp | 2 +- examples/directx9_example/main.cpp | 2 +- examples/marmalade_example/main.cpp | 2 +- examples/opengl2_example/main.cpp | 2 +- examples/opengl3_example/main.cpp | 2 +- examples/sdl_opengl2_example/main.cpp | 2 +- examples/sdl_opengl3_example/main.cpp | 2 +- examples/vulkan_example/main.cpp | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/examples/allegro5_example/main.cpp b/examples/allegro5_example/main.cpp index 2b161d370..cfff74ea4 100644 --- a/examples/allegro5_example/main.cpp +++ b/examples/allegro5_example/main.cpp @@ -31,7 +31,7 @@ int main(int, char**) //io.Fonts->AddFontDefault(); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyClean.ttf", 13.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Roboto-Medium.ttf", 16.0f); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); diff --git a/examples/directx10_example/main.cpp b/examples/directx10_example/main.cpp index 88472e5ba..4675a21da 100644 --- a/examples/directx10_example/main.cpp +++ b/examples/directx10_example/main.cpp @@ -131,7 +131,7 @@ int main(int, char**) //io.Fonts->AddFontDefault(); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyClean.ttf", 13.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Roboto-Medium.ttf", 16.0f); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); diff --git a/examples/directx11_example/main.cpp b/examples/directx11_example/main.cpp index ab563403e..04321610e 100644 --- a/examples/directx11_example/main.cpp +++ b/examples/directx11_example/main.cpp @@ -134,7 +134,7 @@ int main(int, char**) //io.Fonts->AddFontDefault(); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyClean.ttf", 13.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Roboto-Medium.ttf", 16.0f); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); diff --git a/examples/directx9_example/main.cpp b/examples/directx9_example/main.cpp index 85f34eee7..b8e5907c8 100644 --- a/examples/directx9_example/main.cpp +++ b/examples/directx9_example/main.cpp @@ -83,7 +83,7 @@ int main(int, char**) //io.Fonts->AddFontDefault(); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyClean.ttf", 13.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Roboto-Medium.ttf", 16.0f); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); diff --git a/examples/marmalade_example/main.cpp b/examples/marmalade_example/main.cpp index ebc812f19..eb0938ab7 100644 --- a/examples/marmalade_example/main.cpp +++ b/examples/marmalade_example/main.cpp @@ -23,7 +23,7 @@ int main(int, char**) //io.Fonts->AddFontDefault(); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyClean.ttf", 13.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Roboto-Medium.ttf", 16.0f); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); diff --git a/examples/opengl2_example/main.cpp b/examples/opengl2_example/main.cpp index c676953f2..bb688c687 100644 --- a/examples/opengl2_example/main.cpp +++ b/examples/opengl2_example/main.cpp @@ -30,7 +30,7 @@ int main(int, char**) //io.Fonts->AddFontDefault(); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyClean.ttf", 13.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Roboto-Medium.ttf", 16.0f); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); diff --git a/examples/opengl3_example/main.cpp b/examples/opengl3_example/main.cpp index d3ac2cc27..6b20f8ce7 100644 --- a/examples/opengl3_example/main.cpp +++ b/examples/opengl3_example/main.cpp @@ -38,7 +38,7 @@ int main(int, char**) //io.Fonts->AddFontDefault(); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyClean.ttf", 13.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Roboto-Medium.ttf", 16.0f); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); diff --git a/examples/sdl_opengl2_example/main.cpp b/examples/sdl_opengl2_example/main.cpp index fb5f3fb53..9d8a8622c 100644 --- a/examples/sdl_opengl2_example/main.cpp +++ b/examples/sdl_opengl2_example/main.cpp @@ -36,7 +36,7 @@ int main(int, char**) //io.Fonts->AddFontDefault(); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyClean.ttf", 13.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Roboto-Medium.ttf", 16.0f); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); diff --git a/examples/sdl_opengl3_example/main.cpp b/examples/sdl_opengl3_example/main.cpp index 19e3f8617..afd9fe58d 100644 --- a/examples/sdl_opengl3_example/main.cpp +++ b/examples/sdl_opengl3_example/main.cpp @@ -39,7 +39,7 @@ int main(int, char**) //io.Fonts->AddFontDefault(); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyClean.ttf", 13.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Roboto-Medium.ttf", 16.0f); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); diff --git a/examples/vulkan_example/main.cpp b/examples/vulkan_example/main.cpp index 64c0f08c6..379901749 100644 --- a/examples/vulkan_example/main.cpp +++ b/examples/vulkan_example/main.cpp @@ -631,7 +631,7 @@ int main(int, char**) //io.Fonts->AddFontDefault(); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyClean.ttf", 13.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Roboto-Medium.ttf", 16.0f); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); From 63cd2bf9b14ba754ccf5ea2c7d2eb532ac6b242b Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 5 Oct 2017 09:40:06 -0700 Subject: [PATCH 412/921] Removed obsolete comment. --- imgui.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 21aba4ebc..1e5d128e5 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2388,7 +2388,6 @@ void ImGui::NewFrame() } // Pressing TAB activate widget focus - // NB: Don't discard FocusedWindow if it isn't active, so that a window that go on/off programatically won't lose its keyboard focus. if (g.ActiveId == 0 && g.NavWindow != NULL && g.NavWindow->Active && IsKeyPressedMap(ImGuiKey_Tab, false)) g.NavWindow->FocusIdxTabRequestNext = 0; From a8788e51a792e42ba8c2c589044fac3291d0069e Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 5 Oct 2017 09:53:07 -0700 Subject: [PATCH 413/921] SetKeyboardFocusHere() added assert to prevent passing values smaller than -1 as we may have to outlaw them (I think nobody was using that) --- imgui.cpp | 1 + imgui.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 1e5d128e5..ad9735915 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -5457,6 +5457,7 @@ void ImGui::SetScrollHere(float center_y_ratio) void ImGui::SetKeyboardFocusHere(int offset) { + IM_ASSERT(offset >= -1); // -1 is allowed but not below ImGuiWindow* window = GetCurrentWindow(); window->FocusIdxAllRequestNext = window->FocusIdxAllCounter + 1 + offset; window->FocusIdxTabRequestNext = INT_MAX; diff --git a/imgui.h b/imgui.h index 654e83fcb..e47b6e9ef 100644 --- a/imgui.h +++ b/imgui.h @@ -176,7 +176,7 @@ namespace ImGui IMGUI_API void SetScrollY(float scroll_y); // set scrolling amount [0..GetScrollMaxY()] IMGUI_API void SetScrollHere(float center_y_ratio = 0.5f); // adjust scrolling amount to make current cursor position visible. center_y_ratio=0.0: top, 0.5: center, 1.0: bottom. IMGUI_API void SetScrollFromPosY(float pos_y, float center_y_ratio = 0.5f); // adjust scrolling amount to make given position valid. use GetCursorPos() or GetCursorStartPos()+offset to get valid positions. - IMGUI_API void SetKeyboardFocusHere(int offset = 0); // focus keyboard on the next widget. Use positive 'offset' to access sub components of a multiple component widget. Use negative 'offset' to access previous widgets. + IMGUI_API void SetKeyboardFocusHere(int offset = 0); // focus keyboard on the next widget. Use positive 'offset' to access sub components of a multiple component widget. Use -1 to access previous widget. IMGUI_API void SetStateStorage(ImGuiStorage* tree); // replace tree state storage with our own (if you want to manipulate it yourself, typically clear subsection of it) IMGUI_API ImGuiStorage* GetStateStorage(); From a0d724b45079389073e9ae7e42b87ae90aafae7c Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 5 Oct 2017 11:02:23 -0700 Subject: [PATCH 414/921] Made AlignFirstTextHeightToWidgets() saner and faster (still disliking its name very much!) --- imgui.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index ad9735915..6423c5a67 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -5653,10 +5653,9 @@ void ImGui::AlignFirstTextHeightToWidgets() if (window->SkipItems) return; - // Declare a dummy item size to that upcoming items that are smaller will center-align on the newly expanded line height. ImGuiContext& g = *GImGui; - ItemSize(ImVec2(0, g.FontSize + g.Style.FramePadding.y*2), g.Style.FramePadding.y); - SameLine(0, 0); + window->DC.CurrentLineHeight = ImMax(window->DC.CurrentLineHeight, g.FontSize + g.Style.FramePadding.y * 2); + window->DC.CurrentLineTextBaseOffset = ImMax(window->DC.CurrentLineTextBaseOffset, g.Style.FramePadding.y); } // Add a label+text combo aligned to other label+value widgets From 726dcf0dd240dc0f332449b0244759fc21f0fd90 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 5 Oct 2017 11:03:38 -0700 Subject: [PATCH 415/921] TextUnformatted(): minor tweak --- imgui.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 6423c5a67..43a2ee1bf 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -5552,6 +5552,7 @@ void ImGui::TextUnformatted(const char* text, const char* text_end) if (text_end == NULL) text_end = text + strlen(text); // FIXME-OPT + const ImVec2 text_pos(window->DC.CursorPos.x, window->DC.CursorPos.y + window->DC.CurrentLineTextBaseOffset); const float wrap_pos_x = window->DC.TextWrapPos; const bool wrap_enabled = wrap_pos_x >= 0.0f; if (text_end - text > 2000 && !wrap_enabled) @@ -5562,7 +5563,6 @@ void ImGui::TextUnformatted(const char* text, const char* text_end) // We also don't vertically center the text within the line full height, which is unlikely to matter because we are likely the biggest and only item on the line. const char* line = text; const float line_height = GetTextLineHeight(); - const ImVec2 text_pos = window->DC.CursorPos + ImVec2(0.0f, window->DC.CurrentLineTextBaseOffset); const ImRect clip_rect = window->ClipRect; ImVec2 text_size(0,0); @@ -5636,7 +5636,6 @@ void ImGui::TextUnformatted(const char* text, const char* text_end) const ImVec2 text_size = CalcTextSize(text_begin, text_end, false, wrap_width); // Account of baseline offset - ImVec2 text_pos(window->DC.CursorPos.x, window->DC.CursorPos.y + window->DC.CurrentLineTextBaseOffset); ImRect bb(text_pos, text_pos + text_size); ItemSize(text_size); if (!ItemAdd(bb, NULL)) From d851775c80aac7312369739aae6afa25ac31e4ad Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 5 Oct 2017 17:55:27 -0700 Subject: [PATCH 416/921] ColorButton: Reduced bordering artefact that would be particularly visible with opaque Col_FrameBg and FrameRounding enabled. --- imgui.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 43a2ee1bf..ef698db70 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9281,15 +9281,18 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl ImVec4 col_without_alpha(col.x, col.y, col.z, 1.0f); float grid_step = ImMin(size.x, size.y) / 2.99f; float rounding = ImMin(g.Style.FrameRounding, grid_step * 0.5f); + ImRect bb_inner = bb; + float off = -0.75f; // The border (using Col_FrameBg) tends to look off when color is near-opaque and rounding is enabled. This offset seemed like a good middleground to reduce those artefacts. + bb_inner.Expand(off); if ((flags & ImGuiColorEditFlags_AlphaPreviewHalf) && col.w < 1.0f) { - float mid_x = (float)(int)((bb.Min.x + bb.Max.x) * 0.5f + 0.5f); - RenderColorRectWithAlphaCheckerboard(ImVec2(bb.Min.x + grid_step, bb.Min.y), bb.Max, GetColorU32(col), grid_step, ImVec2(-grid_step, 0.0f), rounding, ImGuiCorner_TopRight|ImGuiCorner_BotRight); - window->DrawList->AddRectFilled(bb.Min, ImVec2(mid_x, bb.Max.y), GetColorU32(col_without_alpha), rounding, ImGuiCorner_TopLeft|ImGuiCorner_BotLeft); + float mid_x = (float)(int)((bb_inner.Min.x + bb_inner.Max.x) * 0.5f + 0.5f); + RenderColorRectWithAlphaCheckerboard(ImVec2(bb_inner.Min.x + grid_step, bb_inner.Min.y), bb_inner.Max, GetColorU32(col), grid_step, ImVec2(-grid_step + off, off), rounding, ImGuiCorner_TopRight|ImGuiCorner_BotRight); + window->DrawList->AddRectFilled(bb_inner.Min, ImVec2(mid_x, bb_inner.Max.y), GetColorU32(col_without_alpha), rounding, ImGuiCorner_TopLeft|ImGuiCorner_BotLeft); } else { - RenderColorRectWithAlphaCheckerboard(bb.Min, bb.Max, GetColorU32((flags & ImGuiColorEditFlags_AlphaPreview) ? col : col_without_alpha), grid_step, ImVec2(0,0), rounding); + RenderColorRectWithAlphaCheckerboard(bb_inner.Min, bb_inner.Max, GetColorU32((flags & ImGuiColorEditFlags_AlphaPreview) ? col : col_without_alpha), grid_step, ImVec2(off, off), rounding); } if (window->Flags & ImGuiWindowFlags_ShowBorders) RenderFrameBorder(bb.Min, bb.Max, rounding); From 335c8dd159701853bb34d6d5a6b04dc797fb8062 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 6 Oct 2017 11:23:08 -0700 Subject: [PATCH 417/921] Comments (clarifying whether types are to be considered as flags or regular, non combinable enums) --- TODO.txt | 1 + imgui.h | 34 +++++++++++++++++----------------- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/TODO.txt b/TODO.txt index d2820c75d..04e795fa0 100644 --- a/TODO.txt +++ b/TODO.txt @@ -232,6 +232,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - inputs: allow to pass explicit double-clicks if that's the only thing the user's backend can get them. (e.g. for windows by the CS_DBLCLKS style). - inputs: support track pad style scrolling & slider edit. + - misc: make the ImGuiCond values linear (non-power-of-two). internal storage for ImGuiWindow can use integers to combine into flags. - misc: provide a way to compile out the entire implementation while providing a dummy API (e.g. #define IMGUI_DUMMY_IMPL) - misc: provide HoveredTime and ActivatedTime to ease the creation of animations. - misc: fix for compilation settings where stdcall isn't the default (e.g. vectorcall) (#1230) diff --git a/imgui.h b/imgui.h index e47b6e9ef..bdc7d507e 100644 --- a/imgui.h +++ b/imgui.h @@ -69,17 +69,17 @@ typedef unsigned int ImU32; // 32-bit unsigned integer (typically used t typedef unsigned int ImGuiID; // unique ID used by widgets (typically hashed from a stack of string) typedef unsigned short ImWchar; // character for keyboard input/display typedef void* ImTextureID; // user data to identify a texture (this is whatever to you want it to be! read the FAQ about ImTextureID in imgui.cpp) -typedef int ImGuiCol; // a color identifier for styling // enum ImGuiCol_ -typedef int ImGuiStyleVar; // a variable identifier for styling // enum ImGuiStyleVar_ -typedef int ImGuiKey; // a key identifier (ImGui-side enum) // enum ImGuiKey_ -typedef int ImGuiColorEditFlags; // color edit flags for Color*() // enum ImGuiColorEditFlags_ -typedef int ImGuiMouseCursor; // a mouse cursor identifier // enum ImGuiMouseCursor_ -typedef int ImGuiWindowFlags; // window flags for Begin*() // enum ImGuiWindowFlags_ -typedef int ImGuiCond; // condition flags for Set*() // enum ImGuiCond_ -typedef int ImGuiColumnsFlags; // flags for *Columns*() // enum ImGuiColumnsFlags_ -typedef int ImGuiInputTextFlags; // flags for InputText*() // enum ImGuiInputTextFlags_ -typedef int ImGuiSelectableFlags; // flags for Selectable() // enum ImGuiSelectableFlags_ -typedef int ImGuiTreeNodeFlags; // flags for TreeNode*(), Collapsing*() // enum ImGuiTreeNodeFlags_ +typedef int ImGuiCol; // enum: a color identifier for styling // enum ImGuiCol_ +typedef int ImGuiStyleVar; // enum: a variable identifier for styling // enum ImGuiStyleVar_ +typedef int ImGuiKey; // enum: a key identifier (ImGui-side enum) // enum ImGuiKey_ +typedef int ImGuiMouseCursor; // enum: a mouse cursor identifier // enum ImGuiMouseCursor_ +typedef int ImGuiCond; // enum: a condition for Set*() // enum ImGuiCond_ +typedef int ImGuiColorEditFlags; // flags: color edit flags for Color*() // enum ImGuiColorEditFlags_ +typedef int ImGuiWindowFlags; // flags: window flags for Begin*() // enum ImGuiWindowFlags_ +typedef int ImGuiColumnsFlags; // flags: for *Columns*() // enum ImGuiColumnsFlags_ +typedef int ImGuiInputTextFlags; // flags: for InputText*() // enum ImGuiInputTextFlags_ +typedef int ImGuiSelectableFlags; // flags: for Selectable() // enum ImGuiSelectableFlags_ +typedef int ImGuiTreeNodeFlags; // flags: for TreeNode*(), Collapsing*() // enum ImGuiTreeNodeFlags_ typedef int (*ImGuiTextEditCallback)(ImGuiTextEditCallbackData *data); typedef void (*ImGuiSizeConstraintCallback)(ImGuiSizeConstraintCallbackData* data); #ifdef _MSC_VER @@ -726,14 +726,14 @@ enum ImGuiMouseCursor_ ImGuiMouseCursor_Count_ }; -// Condition flags for ImGui::SetWindow***(), SetNextWindow***(), SetNextTreeNode***() functions -// All those functions treat 0 as a shortcut to ImGuiCond_Always +// Condition for ImGui::SetWindow***(), SetNextWindow***(), SetNextTreeNode***() functions +// All those functions treat 0 as a shortcut to ImGuiCond_Always. From the point of view of the user use this as an enum (don't combine multiple values into flags). enum ImGuiCond_ { - ImGuiCond_Always = 1 << 0, // Set the variable - ImGuiCond_Once = 1 << 1, // Set the variable once per runtime session (only the first call with succeed) - ImGuiCond_FirstUseEver = 1 << 2, // Set the variable if the window has no saved data (if doesn't exist in the .ini file) - ImGuiCond_Appearing = 1 << 3 // Set the variable if the window is appearing after being hidden/inactive (or the first time) + ImGuiCond_Always = 1 << 0, // Set the variable + ImGuiCond_Once = 1 << 1, // Set the variable once per runtime session (only the first call with succeed) + ImGuiCond_FirstUseEver = 1 << 2, // Set the variable if the window has no saved data (if doesn't exist in the .ini file) + ImGuiCond_Appearing = 1 << 3 // Set the variable if the window is appearing after being hidden/inactive (or the first time) // Obsolete names (will be removed) #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS From acb6f12d2cb14ab359c64ff1a9fd42582371b174 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 6 Oct 2017 11:48:07 -0700 Subject: [PATCH 418/921] Removed extraneous calls to GetCurrentWindowRead() when we already have a ImGuiContext. Internal RenderXXX functions also don't need to write into the Accessed field at all. --- imgui.cpp | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index ef698db70..bc2f458ce 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1937,12 +1937,12 @@ static inline bool IsWindowContentHoverable(ImGuiWindow* window) // Advance cursor given item size for layout. void ImGui::ItemSize(const ImVec2& size, float text_offset_y) { - ImGuiWindow* window = GetCurrentWindow(); + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; if (window->SkipItems) return; // Always align ourselves on pixel boundaries - ImGuiContext& g = *GImGui; const float line_height = ImMax(window->DC.CurrentLineHeight, size.y); const float text_base_offset = ImMax(window->DC.CurrentLineTextBaseOffset, text_offset_y); //if (g.IO.KeyAlt) window->DrawList->AddRect(window->DC.CursorPos, window->DC.CursorPos + ImVec2(size.x, line_height), IM_COL32(255,0,0,200)); // [DEBUG] @@ -2034,7 +2034,7 @@ bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id) bool ImGui::IsClippedEx(const ImRect& bb, const ImGuiID* id, bool clip_even_when_logged) { ImGuiContext& g = *GImGui; - ImGuiWindow* window = GetCurrentWindowRead(); + ImGuiWindow* window = g.CurrentWindow; if (!bb.Overlaps(window->ClipRect)) if (!id || *id != g.ActiveId) if (clip_even_when_logged || !g.LogEnabled) @@ -2893,7 +2893,7 @@ void ImGui::LogText(const char* fmt, ...) static void LogRenderedText(const ImVec2* ref_pos, const char* text, const char* text_end = NULL) { ImGuiContext& g = *GImGui; - ImGuiWindow* window = ImGui::GetCurrentWindowRead(); + ImGuiWindow* window = g.CurrentWindow; if (!text_end) text_end = ImGui::FindRenderedTextEnd(text, text_end); @@ -2945,7 +2945,7 @@ static void LogRenderedText(const ImVec2* ref_pos, const char* text, const char* void ImGui::RenderText(ImVec2 pos, const char* text, const char* text_end, bool hide_text_after_hash) { ImGuiContext& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); + ImGuiWindow* window = g.CurrentWindow; // Hide anything after a '##' string const char* text_display_end; @@ -2972,7 +2972,7 @@ void ImGui::RenderText(ImVec2 pos, const char* text, const char* text_end, bool void ImGui::RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end, float wrap_width) { ImGuiContext& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); + ImGuiWindow* window = g.CurrentWindow; if (!text_end) text_end = text + strlen(text); // FIXME-OPT @@ -2997,7 +2997,7 @@ void ImGui::RenderTextClipped(const ImVec2& pos_min, const ImVec2& pos_max, cons return; ImGuiContext& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); + ImGuiWindow* window = g.CurrentWindow; // Perform CPU side clipping for single clipped element to avoid using scissor state ImVec2 pos = pos_min; @@ -3030,8 +3030,8 @@ void ImGui::RenderTextClipped(const ImVec2& pos_min, const ImVec2& pos_max, cons // Render a rectangle shaped with optional rounding and borders void ImGui::RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool border, float rounding) { - ImGuiWindow* window = GetCurrentWindow(); - + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; window->DrawList->AddRectFilled(p_min, p_max, fill_col, rounding); if (border && (window->Flags & ImGuiWindowFlags_ShowBorders)) { @@ -3042,7 +3042,8 @@ void ImGui::RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool border, void ImGui::RenderFrameBorder(ImVec2 p_min, ImVec2 p_max, float rounding) { - ImGuiWindow* window = GetCurrentWindow(); + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; if (window->Flags & ImGuiWindowFlags_ShowBorders) { window->DrawList->AddRect(p_min+ImVec2(1,1), p_max+ImVec2(1,1), GetColorU32(ImGuiCol_BorderShadow), rounding); @@ -3054,7 +3055,7 @@ void ImGui::RenderFrameBorder(ImVec2 p_min, ImVec2 p_max, float rounding) void ImGui::RenderCollapseTriangle(ImVec2 p_min, bool is_open, float scale) { ImGuiContext& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); + ImGuiWindow* window = g.CurrentWindow; const float h = g.FontSize * 1.00f; const float r = h * 0.40f * scale; @@ -3080,14 +3081,15 @@ void ImGui::RenderCollapseTriangle(ImVec2 p_min, bool is_open, float scale) void ImGui::RenderBullet(ImVec2 pos) { - ImGuiWindow* window = GetCurrentWindow(); + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; window->DrawList->AddCircleFilled(pos, GImGui->FontSize*0.20f, GetColorU32(ImGuiCol_Text), 8); } void ImGui::RenderCheckMark(ImVec2 pos, ImU32 col) { ImGuiContext& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); + ImGuiWindow* window = g.CurrentWindow; float start_x = (float)(int)(g.FontSize * 0.307f + 0.5f); float rem_third = (float)(int)((g.FontSize - start_x) / 3.0f); float bx = pos.x + 0.5f + start_x + rem_third; @@ -3132,7 +3134,7 @@ ImVec2 ImGui::CalcTextSize(const char* text, const char* text_end, bool hide_tex void ImGui::CalcListClipping(int items_count, float items_height, int* out_items_display_start, int* out_items_display_end) { ImGuiContext& g = *GImGui; - ImGuiWindow* window = GetCurrentWindowRead(); + ImGuiWindow* window = g.CurrentWindow; if (g.LogEnabled) { // If logging is active, do not perform any clipping @@ -3184,7 +3186,7 @@ static ImGuiWindow* FindHoveredWindow(ImVec2 pos, bool excluding_childs) bool ImGui::IsMouseHoveringRect(const ImVec2& r_min, const ImVec2& r_max, bool clip) { ImGuiContext& g = *GImGui; - ImGuiWindow* window = GetCurrentWindowRead(); + ImGuiWindow* window = g.CurrentWindow; // Clip ImRect rect_clipped(r_min, r_max); @@ -3382,7 +3384,7 @@ bool ImGui::IsItemActive() ImGuiContext& g = *GImGui; if (g.ActiveId) { - ImGuiWindow* window = GetCurrentWindowRead(); + ImGuiWindow* window = g.CurrentWindow; return g.ActiveId == window->DC.LastItemId; } return false; @@ -5947,7 +5949,7 @@ void ImGui::LogToTTY(int max_depth) ImGuiContext& g = *GImGui; if (g.LogEnabled) return; - ImGuiWindow* window = GetCurrentWindowRead(); + ImGuiWindow* window = g.CurrentWindow; g.LogEnabled = true; g.LogFile = stdout; @@ -5962,7 +5964,7 @@ void ImGui::LogToFile(int max_depth, const char* filename) ImGuiContext& g = *GImGui; if (g.LogEnabled) return; - ImGuiWindow* window = GetCurrentWindowRead(); + ImGuiWindow* window = g.CurrentWindow; if (!filename) { @@ -5989,7 +5991,7 @@ void ImGui::LogToClipboard(int max_depth) ImGuiContext& g = *GImGui; if (g.LogEnabled) return; - ImGuiWindow* window = GetCurrentWindowRead(); + ImGuiWindow* window = g.CurrentWindow; g.LogEnabled = true; g.LogFile = NULL; @@ -10175,7 +10177,7 @@ static float GetDraggedColumnOffset(int column_index) // Active (dragged) column always follow mouse. The reason we need this is that dragging a column to the right edge of an auto-resizing // window creates a feedback loop because we store normalized positions. So while dragging we enforce absolute positioning. ImGuiContext& g = *GImGui; - ImGuiWindow* window = ImGui::GetCurrentWindowRead(); + ImGuiWindow* window = g.CurrentWindow; IM_ASSERT(column_index > 0); // We cannot drag column 0. If you get this assert you may have a conflict between the ID of your columns and another widgets. IM_ASSERT(g.ActiveId == window->DC.ColumnsSetId + ImGuiID(column_index)); From 042153d2548c4d1861d6b41ded655a17f36809fd Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 6 Oct 2017 14:23:18 -0700 Subject: [PATCH 419/921] Internal: ItemAdd(), IsClippedEx(): removed unnecessary indirection for ID parameter --- imgui.cpp | 64 ++++++++++++++++++++++++------------------------ imgui_internal.h | 4 +-- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index bc2f458ce..57539a9c7 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1969,12 +1969,12 @@ void ImGui::ItemSize(const ImRect& bb, float text_offset_y) // Declare item bounding box for clipping and interaction. // Note that the size can be different than the one provided to ItemSize(). Typically, widgets that spread over available surface // declares their minimum size requirement to ItemSize() and then use a larger region for drawing/interaction, which is passed to ItemAdd(). -bool ImGui::ItemAdd(const ImRect& bb, const ImGuiID* id) +bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id) { ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; const bool is_clipped = IsClippedEx(bb, id, false); - window->DC.LastItemId = id ? *id : 0; + window->DC.LastItemId = id; window->DC.LastItemRect = bb; window->DC.LastItemRectHoveredRect = false; if (is_clipped) @@ -2031,12 +2031,12 @@ bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id) return true; } -bool ImGui::IsClippedEx(const ImRect& bb, const ImGuiID* id, bool clip_even_when_logged) +bool ImGui::IsClippedEx(const ImRect& bb, ImGuiID id, bool clip_even_when_logged) { ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; if (!bb.Overlaps(window->ClipRect)) - if (!id || *id != g.ActiveId) + if (id == 0 || id != g.ActiveId) if (clip_even_when_logged || !g.LogEnabled) return true; return false; @@ -3790,7 +3790,7 @@ void ImGui::EndChild() ImGuiWindow* parent_window = GetCurrentWindow(); ImRect bb(parent_window->DC.CursorPos, parent_window->DC.CursorPos + sz); ItemSize(sz); - ItemAdd(bb, NULL); + ItemAdd(bb, 0); } } @@ -5598,7 +5598,7 @@ void ImGui::TextUnformatted(const char* text, const char* text_end) while (line < text_end) { const char* line_end = strchr(line, '\n'); - if (IsClippedEx(line_rect, NULL, false)) + if (IsClippedEx(line_rect, 0, false)) break; const ImVec2 line_size = CalcTextSize(line, line_end, false); @@ -5630,7 +5630,7 @@ void ImGui::TextUnformatted(const char* text, const char* text_end) ImRect bb(text_pos, text_pos + text_size); ItemSize(bb); - ItemAdd(bb, NULL); + ItemAdd(bb, 0); } else { @@ -5640,7 +5640,7 @@ void ImGui::TextUnformatted(const char* text, const char* text_end) // Account of baseline offset ImRect bb(text_pos, text_pos + text_size); ItemSize(text_size); - if (!ItemAdd(bb, NULL)) + if (!ItemAdd(bb, 0)) return; // Render (we don't hide text after ## in this end-user function) @@ -5674,7 +5674,7 @@ void ImGui::LabelTextV(const char* label, const char* fmt, va_list args) const ImRect value_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y + style.FramePadding.y*2)); const ImRect total_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w + (label_size.x > 0.0f ? style.ItemInnerSpacing.x : 0.0f), style.FramePadding.y*2) + label_size); ItemSize(total_bb, style.FramePadding.y); - if (!ItemAdd(total_bb, NULL)) + if (!ItemAdd(total_bb, 0)) return; // Render @@ -5799,7 +5799,7 @@ bool ImGui::ButtonEx(const char* label, const ImVec2& size_arg, ImGuiButtonFlags const ImRect bb(pos, pos + size); ItemSize(bb, style.FramePadding.y); - if (!ItemAdd(bb, &id)) + if (!ItemAdd(bb, id)) return false; if (window->DC.ItemFlags & ImGuiItemFlags_ButtonRepeat) flags |= ImGuiButtonFlags_Repeat; @@ -5846,7 +5846,7 @@ bool ImGui::InvisibleButton(const char* str_id, const ImVec2& size_arg) ImVec2 size = CalcItemSize(size_arg, 0.0f, 0.0f); const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size); ItemSize(bb); - if (!ItemAdd(bb, &id)) + if (!ItemAdd(bb, id)) return false; bool hovered, held; @@ -5890,7 +5890,7 @@ void ImGui::Image(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& if (border_col.w > 0.0f) bb.Max += ImVec2(2,2); ItemSize(bb); - if (!ItemAdd(bb, NULL)) + if (!ItemAdd(bb, 0)) return; if (border_col.w > 0.0f) @@ -5927,7 +5927,7 @@ bool ImGui::ImageButton(ImTextureID user_texture_id, const ImVec2& size, const I const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size + padding*2); const ImRect image_bb(window->DC.CursorPos + padding, window->DC.CursorPos + padding + size); ItemSize(bb); - if (!ItemAdd(bb, &id)) + if (!ItemAdd(bb, id)) return false; bool hovered, held; @@ -6129,7 +6129,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l // (Ideally we'd want to add a flag for the user to specify we want want the hit test to be done up to the right side of the content or not) const ImRect interact_bb = display_frame ? bb : ImRect(bb.Min.x, bb.Min.y, bb.Min.x + text_width + style.ItemSpacing.x*2, bb.Max.y); bool is_open = TreeNodeBehaviorIsOpen(id, flags); - if (!ItemAdd(interact_bb, &id)) + if (!ItemAdd(interact_bb, id)) { if (is_open && !(flags & ImGuiTreeNodeFlags_NoTreePushOnOpen)) TreePushRawID(id); @@ -6399,7 +6399,7 @@ void ImGui::Bullet() const float line_height = ImMax(ImMin(window->DC.CurrentLineHeight, g.FontSize + g.Style.FramePadding.y*2), g.FontSize); const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(g.FontSize, line_height)); ItemSize(bb); - if (!ItemAdd(bb, NULL)) + if (!ItemAdd(bb, 0)) { SameLine(0, style.FramePadding.x*2); return; @@ -6427,7 +6427,7 @@ void ImGui::BulletTextV(const char* fmt, va_list args) const float line_height = ImMax(ImMin(window->DC.CurrentLineHeight, g.FontSize + g.Style.FramePadding.y*2), g.FontSize); const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(g.FontSize + (label_size.x > 0.0f ? (label_size.x + style.FramePadding.x*2) : 0.0f), ImMax(line_height, label_size.y))); // Empty text doesn't add padding ItemSize(bb); - if (!ItemAdd(bb, NULL)) + if (!ItemAdd(bb, 0)) return; // Render @@ -6783,7 +6783,7 @@ bool ImGui::SliderFloat(const char* label, float* v, float v_min, float v_max, c const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f)); // NB- we don't call ItemSize() yet because we may turn into a text edit box below - if (!ItemAdd(total_bb, &id)) + if (!ItemAdd(total_bb, id)) { ItemSize(total_bb, style.FramePadding.y); return false; @@ -6840,7 +6840,7 @@ bool ImGui::VSliderFloat(const char* label, const ImVec2& size, float* v, float const ImRect bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f)); ItemSize(bb, style.FramePadding.y); - if (!ItemAdd(frame_bb, &id)) + if (!ItemAdd(frame_bb, id)) return false; const bool hovered = ItemHoverable(frame_bb, id); @@ -7078,7 +7078,7 @@ bool ImGui::DragFloat(const char* label, float* v, float v_speed, float v_min, f const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f)); // NB- we don't call ItemSize() yet because we may turn into a text edit box below - if (!ItemAdd(total_bb, &id)) + if (!ItemAdd(total_bb, id)) { ItemSize(total_bb, style.FramePadding.y); return false; @@ -7284,7 +7284,7 @@ void ImGui::PlotEx(ImGuiPlotType plot_type, const char* label, float (*values_ge const ImRect inner_bb(frame_bb.Min + style.FramePadding, frame_bb.Max - style.FramePadding); const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0)); ItemSize(total_bb, style.FramePadding.y); - if (!ItemAdd(total_bb, NULL)) + if (!ItemAdd(total_bb, 0)) return; const bool hovered = ItemHoverable(inner_bb, 0); @@ -7424,7 +7424,7 @@ void ImGui::ProgressBar(float fraction, const ImVec2& size_arg, const char* over ImVec2 pos = window->DC.CursorPos; ImRect bb(pos, pos + CalcItemSize(size_arg, CalcItemWidth(), g.FontSize + style.FramePadding.y*2.0f)); ItemSize(bb, style.FramePadding.y); - if (!ItemAdd(bb, NULL)) + if (!ItemAdd(bb, 0)) return; // Render @@ -7471,7 +7471,7 @@ bool ImGui::Checkbox(const char* label, bool* v) total_bb = ImRect(ImMin(check_bb.Min, text_bb.Min), ImMax(check_bb.Max, text_bb.Max)); } - if (!ItemAdd(total_bb, &id)) + if (!ItemAdd(total_bb, id)) return false; bool hovered, held; @@ -7534,7 +7534,7 @@ bool ImGui::RadioButton(const char* label, bool active) total_bb.Add(text_bb); } - if (!ItemAdd(total_bb, &id)) + if (!ItemAdd(total_bb, id)) return false; ImVec2 center = check_bb.GetCenter(); @@ -7872,7 +7872,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 else { ItemSize(total_bb, style.FramePadding.y); - if (!ItemAdd(total_bb, &id)) + if (!ItemAdd(total_bb, id)) return false; } const bool hovered = ItemHoverable(frame_bb, id); @@ -8657,7 +8657,7 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImVec2 popu const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y + style.FramePadding.y*2.0f)); const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f)); ItemSize(total_bb, style.FramePadding.y); - if (!ItemAdd(total_bb, &id)) + if (!ItemAdd(total_bb, id)) return false; const float arrow_size = SmallSquareSize(); @@ -8806,7 +8806,7 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl bb_with_spacing.Min.y -= spacing_U; bb_with_spacing.Max.x += spacing_R; bb_with_spacing.Max.y += spacing_D; - if (!ItemAdd(bb_with_spacing, &id)) + if (!ItemAdd(bb_with_spacing, id)) { if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.ColumnsCount > 1) PushColumnClipRect(); @@ -9271,7 +9271,7 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl size.y = default_size; const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size); ItemSize(bb); - if (!ItemAdd(bb, &id)) + if (!ItemAdd(bb, id)) return false; bool hovered, held; @@ -9940,7 +9940,7 @@ void ImGui::Separator() const ImRect bb(ImVec2(x1, window->DC.CursorPos.y), ImVec2(x2, window->DC.CursorPos.y+1.0f)); ItemSize(ImVec2(0.0f, 0.0f)); // NB: we don't provide our width so that it doesn't get feed back into AutoFit, we don't provide height to not alter layout. - if (!ItemAdd(bb, NULL)) + if (!ItemAdd(bb, 0)) { if (window->DC.ColumnsCount > 1) PushColumnClipRect(); @@ -9970,7 +9970,7 @@ void ImGui::VerticalSeparator() float y2 = window->DC.CursorPos.y + window->DC.CurrentLineHeight; const ImRect bb(ImVec2(window->DC.CursorPos.x, y1), ImVec2(window->DC.CursorPos.x + 1.0f, y2)); ItemSize(ImVec2(bb.GetWidth(), 0.0f)); - if (!ItemAdd(bb, NULL)) + if (!ItemAdd(bb, 0)) return; window->DrawList->AddLine(ImVec2(bb.Min.x, bb.Min.y), ImVec2(bb.Min.x, bb.Max.y), GetColorU32(ImGuiCol_Separator)); @@ -9994,7 +9994,7 @@ void ImGui::Dummy(const ImVec2& size) const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size); ItemSize(bb); - ItemAdd(bb, NULL); + ItemAdd(bb, 0); } bool ImGui::IsRectVisible(const ImVec2& size) @@ -10058,7 +10058,7 @@ void ImGui::EndGroup() { window->DC.CurrentLineTextBaseOffset = ImMax(window->DC.PrevLineTextBaseOffset, group_data.BackupCurrentLineTextBaseOffset); // FIXME: Incorrect, we should grab the base offset from the *first line* of the group but it is hard to obtain now. ItemSize(group_bb.GetSize(), group_data.BackupCurrentLineTextBaseOffset); - ItemAdd(group_bb, NULL); + ItemAdd(group_bb, 0); } // If the current ActiveId was declared within the boundary of our group, we copy it to LastItemId so IsItemActive() will be functional on the entire group. @@ -10344,7 +10344,7 @@ void ImGui::EndColumns() const ImGuiID column_id = window->DC.ColumnsSetId + ImGuiID(i); const float column_w = 4.0f; // Width for interaction const ImRect column_rect(ImVec2(x - column_w, y1), ImVec2(x + column_w, y2)); - if (IsClippedEx(column_rect, &column_id, false)) + if (IsClippedEx(column_rect, column_id, false)) continue; bool hovered = false, held = false; diff --git a/imgui_internal.h b/imgui_internal.h index 392de3eaf..5b5c5d44f 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -771,9 +771,9 @@ namespace ImGui IMGUI_API void ItemSize(const ImVec2& size, float text_offset_y = 0.0f); IMGUI_API void ItemSize(const ImRect& bb, float text_offset_y = 0.0f); - IMGUI_API bool ItemAdd(const ImRect& bb, const ImGuiID* id); - IMGUI_API bool IsClippedEx(const ImRect& bb, const ImGuiID* id, bool clip_even_when_logged); + IMGUI_API bool ItemAdd(const ImRect& bb, ImGuiID id); IMGUI_API bool ItemHoverable(const ImRect& bb, ImGuiID id); + IMGUI_API bool IsClippedEx(const ImRect& bb, ImGuiID id, bool clip_even_when_logged); IMGUI_API bool FocusableItemRegister(ImGuiWindow* window, ImGuiID id, bool tab_stop = true); // Return true if focus is requested IMGUI_API void FocusableItemUnregister(ImGuiWindow* window); IMGUI_API ImVec2 CalcItemSize(ImVec2 size, float default_x, float default_y); From c6e370a77a2dd03c9ce5ac1b9df2ccc399c1611a Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 11 Oct 2017 15:16:11 +0200 Subject: [PATCH 420/921] TreeNode: Added ImGuiTreeNodeFlags_FramePadding flag --- imgui.cpp | 10 +++++----- imgui.h | 5 +++-- imgui_demo.cpp | 3 ++- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 57539a9c7..463eb25bb 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -6104,14 +6104,14 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l ImGuiContext& g = *GImGui; const ImGuiStyle& style = g.Style; const bool display_frame = (flags & ImGuiTreeNodeFlags_Framed) != 0; - const ImVec2 padding = display_frame ? style.FramePadding : ImVec2(style.FramePadding.x, 0.0f); + const ImVec2 padding = (display_frame || (flags & ImGuiTreeNodeFlags_FramePadding)) ? style.FramePadding : ImVec2(style.FramePadding.x, 0.0f); if (!label_end) label_end = FindRenderedTextEnd(label); const ImVec2 label_size = CalcTextSize(label, label_end, false); // We vertically grow up to current line height up the typical widget height. - const float text_base_offset_y = ImMax(0.0f, window->DC.CurrentLineTextBaseOffset - padding.y); // Latch before ItemSize changes it + const float text_base_offset_y = ImMax(padding.y, window->DC.CurrentLineTextBaseOffset); // Latch before ItemSize changes it const float frame_height = ImMax(ImMin(window->DC.CurrentLineHeight, g.FontSize + style.FramePadding.y*2), label_size.y + padding.y*2); ImRect bb = ImRect(window->DC.CursorPos, ImVec2(window->Pos.x + GetContentRegionMax().x, window->DC.CursorPos.y + frame_height)); if (display_frame) @@ -6126,7 +6126,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l ItemSize(ImVec2(text_width, frame_height), text_base_offset_y); // For regular tree nodes, we arbitrary allow to click past 2 worth of ItemSpacing - // (Ideally we'd want to add a flag for the user to specify we want want the hit test to be done up to the right side of the content or not) + // (Ideally we'd want to add a flag for the user to specify if we want the hit test to be done up to the right side of the content or not) const ImRect interact_bb = display_frame ? bb : ImRect(bb.Min.x, bb.Min.y, bb.Min.x + text_width + style.ItemSpacing.x*2, bb.Max.y); bool is_open = TreeNodeBehaviorIsOpen(id, flags); if (!ItemAdd(interact_bb, id)) @@ -6163,12 +6163,12 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l // Render const ImU32 col = GetColorU32((held && hovered) ? ImGuiCol_HeaderActive : hovered ? ImGuiCol_HeaderHovered : ImGuiCol_Header); - const ImVec2 text_pos = bb.Min + ImVec2(text_offset_x, padding.y + text_base_offset_y); + const ImVec2 text_pos = bb.Min + ImVec2(text_offset_x, text_base_offset_y); if (display_frame) { // Framed type RenderFrame(bb.Min, bb.Max, col, true, style.FrameRounding); - RenderCollapseTriangle(bb.Min + padding + ImVec2(0.0f, text_base_offset_y), is_open, 1.0f); + RenderCollapseTriangle(bb.Min + ImVec2(padding.x, text_base_offset_y), is_open, 1.0f); if (g.LogEnabled) { // NB: '##' is normally used to hide text (as a library-wide feature), so we need to specify the text range to make sure the ## aren't stripped out here. diff --git a/imgui.h b/imgui.h index bdc7d507e..fbdaf4752 100644 --- a/imgui.h +++ b/imgui.h @@ -568,8 +568,9 @@ enum ImGuiTreeNodeFlags_ ImGuiTreeNodeFlags_OpenOnArrow = 1 << 7, // Only open when clicking on the arrow part. If ImGuiTreeNodeFlags_OpenOnDoubleClick is also set, single-click arrow or double-click all box to open. ImGuiTreeNodeFlags_Leaf = 1 << 8, // No collapsing, no arrow (use as a convenience for leaf nodes). ImGuiTreeNodeFlags_Bullet = 1 << 9, // Display a bullet instead of arrow - //ImGuITreeNodeFlags_SpanAllAvailWidth = 1 << 10, // FIXME: TODO: Extend hit box horizontally even if not framed - //ImGuiTreeNodeFlags_NoScrollOnOpen = 1 << 11, // FIXME: TODO: Disable automatic scroll on TreePop() if node got just open and contents is not visible + ImGuiTreeNodeFlags_FramePadding = 1 << 10, // Use FramePadding (even for an unframed text node) to vertically align text baseline to regular widget height. Equivalent to calling AlignFirstTextHeightToWidgets(). + //ImGuITreeNodeFlags_SpanAllAvailWidth = 1 << 11, // FIXME: TODO: Extend hit box horizontally even if not framed + //ImGuiTreeNodeFlags_NoScrollOnOpen = 1 << 12, // FIXME: TODO: Disable automatic scroll on TreePop() if node got just open and contents is not visible ImGuiTreeNodeFlags_CollapsingHeader = ImGuiTreeNodeFlags_Framed | ImGuiTreeNodeFlags_NoAutoOpenOnLog }; diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 781ef121a..07e2cd794 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -429,7 +429,8 @@ void ImGui::ShowTestWindow(bool* p_open) else { // Leaf: The only reason we have a TreeNode at all is to allow selection of the leaf. Otherwise we can use BulletText() or TreeAdvanceToLabelPos()+Text(). - ImGui::TreeNodeEx((void*)(intptr_t)i, node_flags | ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen, "Selectable Leaf %d", i); + node_flags |= ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen; // ImGuiTreeNodeFlags_Bullet + ImGui::TreeNodeEx((void*)(intptr_t)i, node_flags, "Selectable Leaf %d", i); if (ImGui::IsItemClicked()) node_clicked = i; } From 4cfec4813e20871ffbb310490459182acd851d54 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 11 Oct 2017 15:24:54 +0200 Subject: [PATCH 421/921] Links --- README.md | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 5e1174b09..c4d129307 100644 --- a/README.md +++ b/README.md @@ -67,22 +67,21 @@ Languages: Frameworks: - Main ImGui repository include examples for DirectX9, DirectX10, DirectX11, OpenGL2/3, Vulkan, Allegro 5, SDL+GL2/3, iOS and Marmalade: https://github.com/ocornut/imgui/tree/master/examples -- Unmerged PR: DirectX12 example (with issues) https://github.com/ocornut/imgui/pull/301 -- Unmerged PR: SDL2 + OpenGLES + Emscripten example https://github.com/ocornut/imgui/pull/336 -- Unmerged PR: FreeGlut + OpenGL2 example https://github.com/ocornut/imgui/pull/801 -- Unmerged PR: Native Win32 and OSX example https://github.com/ocornut/imgui/pull/281 -- Unmerged PR: Android Example https://github.com/ocornut/imgui/pull/421 -- Cinder backend for dear imgui https://github.com/simongeilfus/Cinder-ImGui -- FlexGUI: Flexium/SFML backend for dear imgui https://github.com/DXsmiley/FlexGUI -- IrrIMGUI: Irrlicht backend for dear imgui https://github.com/ZahlGraf/IrrIMGUI -- UnrealEngine_ImGui: Unreal Engine 4 backend for dear imgui https://github.com/sronsse/UnrealEngine_ImGui -- LÖVE backend for dear imgui https://github.com/slages/love-imgui -- Ogre backend for dear imgui https://bitbucket.org/LMCrashy/ogreimgui/src -- ofxImGui: openFrameworks backend for dear imgui https://github.com/jvcleave/ofxImGui -- SFML backend for dear imgui https://github.com/EliasD/imgui-sfml -- SFML backend for dear imgui https://github.com/Mischa-Alff/imgui-backends -- cocos2d-x with imgui https://github.com/c0i/imguix https://github.com/ocornut/imgui/issues/551 -- NanoRT: software raytraced version https://github.com/syoyo/imgui/tree/nanort/examples/raytrace_example +- Unmerged PR: DirectX12: https://github.com/ocornut/imgui/pull/301 +- Unmerged PR: SDL2 + OpenGLES + Emscripten: https://github.com/ocornut/imgui/pull/336 +- Unmerged PR: FreeGlut + OpenGL2: https://github.com/ocornut/imgui/pull/801 +- Unmerged PR: Native Win32 and OSX: https://github.com/ocornut/imgui/pull/281 +- Unmerged PR: Android: https://github.com/ocornut/imgui/pull/421 +- Cinder: https://github.com/simongeilfus/Cinder-ImGui +- cocos2d-x: https://github.com/c0i/imguix https://github.com/ocornut/imgui/issues/551 +- Flexium/SFML (FlexGUI): https://github.com/DXsmiley/FlexGUI +- Irrlicht (IrrIMGUI): https://github.com/ZahlGraf/IrrIMGUI +- Ogre: https://bitbucket.org/LMCrashy/ogreimgui/src +- openFrameworks (ofxImGui): https://github.com/jvcleave/ofxImGui +- LÖVE: https://github.com/slages/love-imgui +- NanoRT (software raytraced) https://github.com/syoyo/imgui/tree/nanort/examples/raytrace_example +- Unreal Engine 4: https://github.com/segross/UnrealImGui or https://github.com/sronsse/UnrealEngine_ImGui +- SFML: https://github.com/EliasD/imgui-sfml or https://github.com/Mischa-Alff/imgui-backends For other bindings: see [this page](https://github.com/ocornut/imgui/wiki/Links/). Please contact me with the Issues tracker or Twitter to fix/update this list. From 578a588c1d85d6aa45bc9752a080cb54a5157b3c Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 11 Oct 2017 15:26:35 +0200 Subject: [PATCH 422/921] Links --- README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index c4d129307..3e78bfc76 100644 --- a/README.md +++ b/README.md @@ -55,15 +55,15 @@ _NB: those third-party bindings may be more or less maintained, more or less clo _Integrating Dear ImGui within your custom engine is a matter of wiring mouse/keyboard inputs and providing a render function that can bind a texture and render simple textured triangles. The examples/ folder is populated with applications doing just that. If you are an experienced programmer it should take you less than an hour to integrate Dear ImGui in your custom engine, but make sure to spend time reading the FAQ, the comments and other documentation!_ Languages: -- C - cimgui: thin c-api wrapper for ImGui https://github.com/Extrawurst/cimgui -- C#/.Net - ImGui.NET: An ImGui wrapper for .NET Core https://github.com/mellinoe/ImGui.NET -- D - DerelictImgui: Dynamic bindings for the D programming language: https://github.com/Extrawurst/DerelictImgui -- Go - go-imgui https://github.com/Armored-Dragon/go-imgui -- Lua - https://github.com/patrickriordan/imgui_lua_bindings -- Pascal - imgui-pas https://github.com/dpethes/imgui-pas -- Python - CyImGui: Python bindings for dear imgui using Cython: https://github.com/chromy/cyimgui -- Python - pyimgui: Another Python bindings for dear imgui: https://github.com/swistakm/pyimgui -- Rust - imgui-rs: Rust bindings for dear imgui https://github.com/Gekkio/imgui-rs +- C (cimgui): thin c-api wrapper for ImGui https://github.com/Extrawurst/cimgui +- C#/.Net (ImGui.NET): An ImGui wrapper for .NET Core https://github.com/mellinoe/ImGui.NET +- D (DerelictImgui): Dynamic bindings for the D programming language: https://github.com/Extrawurst/DerelictImgui +- Go (go-imgui): https://github.com/Armored-Dragon/go-imgui +- Lua: https://github.com/patrickriordan/imgui_lua_bindings +- Pascal (imgui-pas) https://github.com/dpethes/imgui-pas +- Python (CyImGui): Python bindings for dear imgui using Cython: https://github.com/chromy/cyimgui +- Python (pyimgui): Another Python bindings for dear imgui: https://github.com/swistakm/pyimgui +- Rust (imgui-rs): Rust bindings for dear imgui https://github.com/Gekkio/imgui-rs Frameworks: - Main ImGui repository include examples for DirectX9, DirectX10, DirectX11, OpenGL2/3, Vulkan, Allegro 5, SDL+GL2/3, iOS and Marmalade: https://github.com/ocornut/imgui/tree/master/examples From 43b4a81b3e3a1895851457533830501bba212058 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 11 Oct 2017 15:36:57 +0200 Subject: [PATCH 423/921] Rnamed AlignFirstTextHeightToWidgets() to AlignTextToFramePadding(). Kept inline redirection function (will obsolete). --- imgui.cpp | 5 +++-- imgui.h | 5 +++-- imgui_demo.cpp | 14 +++++++------- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 463eb25bb..38b35fb9e 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -204,6 +204,7 @@ Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. Also read releases logs https://github.com/ocornut/imgui/releases for more details. + - 2017/10/11 (1.52) - renamed AlignFirstTextHeightToWidgets() to AlignTextToFramePadding(). Kept inline redirection function (will obsolete). - 2017/09/25 (1.52) - removed SetNextWindowPosCenter() because SetNextWindowPos() now has the optional pivot information to do the same and more. Kept redirection function (will obsolete). - 2017/08/25 (1.52) - io.MousePos needs to be set to ImVec2(-FLT_MAX,-FLT_MAX) when mouse is unavailable/missing. Previously ImVec2(-1,-1) was enough but we now accept negative mouse coordinates. In your binding if you need to support unavailable mouse, make sure to replace "io.MousePos = ImVec2(-1,-1)" with "io.MousePos = ImVec2(-FLT_MAX,-FLT_MAX)". - 2017/08/22 (1.51) - renamed IsItemHoveredRect() to IsItemRectHovered(). Kept inline redirection function (will obsolete). @@ -5648,7 +5649,7 @@ void ImGui::TextUnformatted(const char* text, const char* text_end) } } -void ImGui::AlignFirstTextHeightToWidgets() +void ImGui::AlignTextToFramePadding() { ImGuiWindow* window = GetCurrentWindow(); if (window->SkipItems) @@ -9028,7 +9029,7 @@ bool ImGui::BeginMenuBar() window->DC.CursorPos = ImVec2(rect.Min.x + window->DC.MenuBarOffsetX, rect.Min.y);// + g.Style.FramePadding.y); window->DC.LayoutType = ImGuiLayoutType_Horizontal; window->DC.MenuBarAppending = true; - AlignFirstTextHeightToWidgets(); + AlignTextToFramePadding(); return true; } diff --git a/imgui.h b/imgui.h index fbdaf4752..a5a5972e1 100644 --- a/imgui.h +++ b/imgui.h @@ -227,7 +227,7 @@ namespace ImGui IMGUI_API ImVec2 GetCursorStartPos(); // initial cursor position IMGUI_API ImVec2 GetCursorScreenPos(); // cursor position in absolute screen coordinates [0..io.DisplaySize] (useful to work with ImDrawList API) IMGUI_API void SetCursorScreenPos(const ImVec2& pos); // cursor position in absolute screen coordinates [0..io.DisplaySize] - IMGUI_API void AlignFirstTextHeightToWidgets(); // call once if the first item on the line is a Text() item and you want to vertically lower it to match subsequent (bigger) widgets + IMGUI_API void AlignTextToFramePadding(); // vertically align/lower upcoming text to FramePadding.y so that it will aligns to upcoming widgets (call if you have text on a line before regular widgets) IMGUI_API float GetTextLineHeight(); // height of font == GetWindowFontSize() IMGUI_API float GetTextLineHeightWithSpacing(); // distance (in pixels) between 2 consecutive lines of text == GetWindowFontSize() + GetStyle().ItemSpacing.y IMGUI_API float GetItemsLineHeightWithSpacing(); // distance (in pixels) between 2 consecutive lines of standard height widgets == GetWindowFontSize() + GetStyle().FramePadding.y*2 + GetStyle().ItemSpacing.y @@ -488,6 +488,7 @@ namespace ImGui // Obsolete functions (Will be removed! Also see 'API BREAKING CHANGES' section in imgui.cpp) #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS + static inline void AlignFirstTextHeightToWidgets() { AlignTextToFramePadding(); } // OBSOLETE 1.52+ void SetNextWindowPosCenter(ImGuiCond cond = 0); // OBSOLETE 1.52+ static inline bool IsItemHoveredRect() { return IsItemRectHovered(); } // OBSOLETE 1.51+ static inline bool IsPosHoveringAnyWindow(const ImVec2&) { IM_ASSERT(0); return false; } // OBSOLETE 1.51+. This was partly broken. You probably wanted to use ImGui::GetIO().WantCaptureMouse instead. @@ -568,7 +569,7 @@ enum ImGuiTreeNodeFlags_ ImGuiTreeNodeFlags_OpenOnArrow = 1 << 7, // Only open when clicking on the arrow part. If ImGuiTreeNodeFlags_OpenOnDoubleClick is also set, single-click arrow or double-click all box to open. ImGuiTreeNodeFlags_Leaf = 1 << 8, // No collapsing, no arrow (use as a convenience for leaf nodes). ImGuiTreeNodeFlags_Bullet = 1 << 9, // Display a bullet instead of arrow - ImGuiTreeNodeFlags_FramePadding = 1 << 10, // Use FramePadding (even for an unframed text node) to vertically align text baseline to regular widget height. Equivalent to calling AlignFirstTextHeightToWidgets(). + ImGuiTreeNodeFlags_FramePadding = 1 << 10, // Use FramePadding (even for an unframed text node) to vertically align text baseline to regular widget height. Equivalent to calling AlignTextToFramePadding(). //ImGuITreeNodeFlags_SpanAllAvailWidth = 1 << 11, // FIXME: TODO: Extend hit box horizontally even if not framed //ImGuiTreeNodeFlags_NoScrollOnOpen = 1 << 12, // FIXME: TODO: Disable automatic scroll on TreePop() if node got just open and contents is not visible ImGuiTreeNodeFlags_CollapsingHeader = ImGuiTreeNodeFlags_Framed | ImGuiTreeNodeFlags_NoAutoOpenOnLog diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 07e2cd794..3f7d5feea 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1054,7 +1054,7 @@ void ImGui::ShowTestWindow(bool* p_open) ImGui::TextColored(ImVec4(1,1,0,1), "Sailor"); // Button - ImGui::AlignFirstTextHeightToWidgets(); + ImGui::AlignTextToFramePadding(); ImGui::Text("Normal buttons"); ImGui::SameLine(); ImGui::Button("Banana"); ImGui::SameLine(); ImGui::Button("Apple"); ImGui::SameLine(); @@ -1180,7 +1180,7 @@ void ImGui::ShowTestWindow(bool* p_open) ImGui::Text("TEST"); ImGui::SameLine(); ImGui::SmallButton("TEST##2"); - ImGui::AlignFirstTextHeightToWidgets(); // If your line starts with text, call this to align it to upcoming widgets. + ImGui::AlignTextToFramePadding(); // If your line starts with text, call this to align it to upcoming widgets. ImGui::Text("Text aligned to Widget"); ImGui::SameLine(); ImGui::Button("Widget##1"); ImGui::SameLine(); ImGui::Text("Widget"); ImGui::SameLine(); @@ -1193,7 +1193,7 @@ void ImGui::ShowTestWindow(bool* p_open) ImGui::SameLine(0.0f, spacing); if (ImGui::TreeNode("Node##1")) { for (int i = 0; i < 6; i++) ImGui::BulletText("Item %d..", i); ImGui::TreePop(); } // Dummy tree data - ImGui::AlignFirstTextHeightToWidgets(); // Vertically align text node a bit lower so it'll be vertically centered with upcoming widget. Otherwise you can use SmallButton (smaller fit). + ImGui::AlignTextToFramePadding(); // Vertically align text node a bit lower so it'll be vertically centered with upcoming widget. Otherwise you can use SmallButton (smaller fit). bool node_open = ImGui::TreeNode("Node##2"); // Common mistake to avoid: if we want to SameLine after TreeNode we need to do it before we add child content. ImGui::SameLine(0.0f, spacing); ImGui::Button("Button##2"); if (node_open) { for (int i = 0; i < 6; i++) ImGui::BulletText("Item %d..", i); ImGui::TreePop(); } // Dummy tree data @@ -1203,7 +1203,7 @@ void ImGui::ShowTestWindow(bool* p_open) ImGui::SameLine(0.0f, spacing); ImGui::BulletText("Bullet text"); - ImGui::AlignFirstTextHeightToWidgets(); + ImGui::AlignTextToFramePadding(); ImGui::BulletText("Node"); ImGui::SameLine(0.0f, spacing); ImGui::Button("Button##4"); @@ -2712,10 +2712,10 @@ static void ShowExampleAppPropertyEditor(bool* p_open) static void ShowDummyObject(const char* prefix, int uid) { ImGui::PushID(uid); // Use object uid as identifier. Most commonly you could also use the object pointer as a base ID. - ImGui::AlignFirstTextHeightToWidgets(); // Text and Tree nodes are less high than regular widgets, here we add vertical spacing to make the tree lines equal high. + ImGui::AlignTextToFramePadding(); // Text and Tree nodes are less high than regular widgets, here we add vertical spacing to make the tree lines equal high. bool node_open = ImGui::TreeNode("Object", "%s_%u", prefix, uid); ImGui::NextColumn(); - ImGui::AlignFirstTextHeightToWidgets(); + ImGui::AlignTextToFramePadding(); ImGui::Text("my sailor is rich"); ImGui::NextColumn(); if (node_open) @@ -2730,7 +2730,7 @@ static void ShowExampleAppPropertyEditor(bool* p_open) } else { - ImGui::AlignFirstTextHeightToWidgets(); + ImGui::AlignTextToFramePadding(); // Here we use a Selectable (instead of Text) to highlight on hover //ImGui::Text("Field_%d", i); char label[32]; From 4be967823fb72c799f3b3d5f2204a2e287476af9 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 13 Oct 2017 13:29:42 +0200 Subject: [PATCH 424/921] Exposed Scrollbar() in imgui_internal.h and removed a bool arg --- imgui.cpp | 18 ++++++++++-------- imgui_internal.h | 1 + 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 38b35fb9e..2657fa2c4 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -606,7 +606,6 @@ static ImGuiWindow* FindHoveredWindow(ImVec2 pos, bool excluding_childs); static ImGuiWindow* CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFlags flags); static void ClearSetNextWindowData(); static void CheckStacksSize(ImGuiWindow* window, bool write); -static void Scrollbar(ImGuiWindow* window, bool horizontal); static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window); static void AddDrawListToRenderList(ImVector& out_render_list, ImDrawList* draw_list); @@ -4392,9 +4391,9 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us // Scrollbars if (window->ScrollbarX) - Scrollbar(window, true); + Scrollbar(ImGuiLayoutType_Horizontal); if (window->ScrollbarY) - Scrollbar(window, false); + Scrollbar(ImGuiLayoutType_Vertical); // Render resize grip // (after the input handling so we don't have a frame of latency) @@ -4586,9 +4585,12 @@ void ImGui::End() // - We handle absolute seeking (when first clicking outside the grab) and relative manipulation (afterward or when clicking inside the grab) // - We store values as normalized ratio and in a form that allows the window content to change while we are holding on a scrollbar // - We handle both horizontal and vertical scrollbars, which makes the terminology not ideal. -static void Scrollbar(ImGuiWindow* window, bool horizontal) +void ImGui::Scrollbar(ImGuiLayoutType direction) { ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + + const bool horizontal = (direction == ImGuiLayoutType_Horizontal); const ImGuiStyle& style = g.Style; const ImGuiID id = window->GetID(horizontal ? "#SCROLLX" : "#SCROLLY"); @@ -4611,7 +4613,7 @@ static void Scrollbar(ImGuiWindow* window, bool horizontal) window_rounding_corners = ImGuiCorner_BotLeft | (other_scrollbar ? 0 : ImGuiCorner_BotRight); else window_rounding_corners = (((window->Flags & ImGuiWindowFlags_NoTitleBar) && !(window->Flags & ImGuiWindowFlags_MenuBar)) ? ImGuiCorner_TopRight : 0) | (other_scrollbar ? 0 : ImGuiCorner_BotRight); - window->DrawList->AddRectFilled(bb.Min, bb.Max, ImGui::GetColorU32(ImGuiCol_ScrollbarBg), window_rounding, window_rounding_corners); + window->DrawList->AddRectFilled(bb.Min, bb.Max, GetColorU32(ImGuiCol_ScrollbarBg), window_rounding, window_rounding_corners); bb.Expand(ImVec2(-ImClamp((float)(int)((bb.Max.x - bb.Min.x - 2.0f) * 0.5f), 0.0f, 3.0f), -ImClamp((float)(int)((bb.Max.y - bb.Min.y - 2.0f) * 0.5f), 0.0f, 3.0f))); // V denote the main, longer axis of the scrollbar (= height for a vertical scrollbar) @@ -4631,7 +4633,7 @@ static void Scrollbar(ImGuiWindow* window, bool horizontal) bool held = false; bool hovered = false; const bool previously_held = (g.ActiveId == id); - ImGui::ButtonBehavior(bb, id, &hovered, &held); + ButtonBehavior(bb, id, &hovered, &held); float scroll_max = ImMax(1.0f, win_size_contents_v - win_size_avail_v); float scroll_ratio = ImSaturate(scroll_v / scroll_max); @@ -4644,7 +4646,7 @@ static void Scrollbar(ImGuiWindow* window, bool horizontal) // Click position in scrollbar normalized space (0.0f->1.0f) const float clicked_v_norm = ImSaturate((mouse_pos_v - scrollbar_pos_v) / scrollbar_size_v); - ImGui::SetHoveredID(id); + SetHoveredID(id); bool seek_absolute = false; if (!previously_held) @@ -4680,7 +4682,7 @@ static void Scrollbar(ImGuiWindow* window, bool horizontal) } // Render - const ImU32 grab_col = ImGui::GetColorU32(held ? ImGuiCol_ScrollbarGrabActive : hovered ? ImGuiCol_ScrollbarGrabHovered : ImGuiCol_ScrollbarGrab); + const ImU32 grab_col = GetColorU32(held ? ImGuiCol_ScrollbarGrabActive : hovered ? ImGuiCol_ScrollbarGrabHovered : ImGuiCol_ScrollbarGrab); if (horizontal) window->DrawList->AddRectFilled(ImVec2(ImLerp(bb.Min.x, bb.Max.x, grab_v_norm), bb.Min.y), ImVec2(ImLerp(bb.Min.x, bb.Max.x, grab_v_norm) + grab_h_pixels, bb.Max.y), grab_col, style.ScrollbarRounding); else diff --git a/imgui_internal.h b/imgui_internal.h index 5b5c5d44f..6c4f8db5e 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -789,6 +789,7 @@ namespace ImGui IMGUI_API int CalcTypematicPressedRepeatAmount(float t, float t_prev, float repeat_delay, float repeat_rate); + IMGUI_API void Scrollbar(ImGuiLayoutType direction); IMGUI_API void VerticalSeparator(); // Vertical separator, for menu bars (use current line height). not exposed because it is misleading what it doesn't have an effect on regular layout. // FIXME-WIP: New Columns API From dbab9b248abfe64bfa2a469de1c9357277b4043a Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 13 Oct 2017 20:03:56 +0200 Subject: [PATCH 425/921] Update README.md --- README.md | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 3e78bfc76..48e011c3a 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ Binaries/Demo ------------- You should be able to build the examples from sources (tested on Windows/Mac/Linux). If you don't, let me know! If you want to have a quick look at some Dear ImGui features, you can download Windows binaries of the demo app here: -- [imgui-demo-binaries-20170723.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20170723.zip) (Windows binaries, Dear ImGui 1.51+ 2017/07/23, 5 executables, 808 KB) +- [imgui-demo-binaries-20171013.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20171013.zip) (Windows binaries, Dear ImGui 1.52 WIP built 2017/10/13, 5 executables) Bindings -------- @@ -136,11 +136,15 @@ Frequently Asked Question (FAQ) - Standalone example applications using e.g. OpenGL/DirectX are provided in the examples/ folder. - We obviously needs better documentation! Consider contributing or becoming a [Patron](http://www.patreon.com/imgui) to promote this effort. +Which version should I get? + +I occasionally tag [Releases](https://github.com/ocornut/imgui/releases) but it is generally safe and recommended to sync to master. The library is pretty stable and regression tend to fixed very fast when reported. You may also want to checkout the [navigation branch](https://github.com/ocornut/imgui/tree/navigation) if you want to use imgui with a gamepad (it is also possible to map keyboard inputs to some degree). The Navigation branch is being kept up to date with Master. + Why the odd dual naming, "dear imgui" vs "ImGui"? The library started its life and is best known as "ImGui" only due to the fact that I didn't give it a proper name when I released it. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations. It seemed confusing and unfair to hog the name. To reduce the ambiguity without affecting existing codebases, I have decided on an alternate, longer name "dear imgui" that people can use to refer to this specific library in ambiguous situations. -
What is ImTextureID and how do I display an image? +What is ImTextureID and how do I display an image?
I integrated Dear ImGui in my engine and the text or lines are blurry..
I integrated Dear ImGui in my engine and some elements are disappearing when I move windows around..
How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on labels/IDs. @@ -180,15 +184,15 @@ If you intend to display large lists of items (say, 1000+) it can be beneficial You can alter the look of the interface to some degree: changing colors, sizes, padding, rounding, fonts. However, as Dear ImGui is designed and optimised to create debug tools, the amount of skinning you can apply is limited. There is only so much you can stray away from the default look and feel of the interface. -This is [LumixEngine](https://github.com/nem0/LumixEngine) with a minor skinning hack + a docking/tabs extension (both of which you can find in the Issues section and will eventually be merged). +This is [LumixEngine](https://github.com/nem0/LumixEngine) with custom colors + a docking/tabs extension (both of which you can find in the Issues section and will eventually be merged). -[![Skinning in LumixEngine](https://cloud.githubusercontent.com/assets/8225057/13198792/92808c5c-d812-11e5-9507-16b63918b05b.jpg)](https://cloud.githubusercontent.com/assets/8225057/13044612/59f07aec-d3cf-11e5-8ccb-39adf2e13e69.png) +![LumixEngine](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v151/lumix-201710-rearranged.png) Why using C++ (as opposed to C)? -Dear ImGui takes advantage of a few C++ languages features for convenience but nothing anywhere Boost-insanity/quagmire. Dear ImGui doesn't use any C++ header file. Language-wise, function overloading and default parameters are used to make the API easier to use and code more terse. Doing so I believe the API is sitting on a sweet spot and giving up on those features would make the API more cumbersome. Other features such as namespace, constructors and templates (in the case of the ImVector<> class) are also relied on as a convenience. +Dear ImGui takes advantage of a few C++ languages features for convenience but nothing anywhere Boost-insanity/quagmire. Dear ImGui does NOT require C++11 so it can be used with most old C++ compilers. Dear ImGui doesn't use any C++ header file. Language-wise, function overloading and default parameters are used to make the API easier to use and code more terse. Doing so I believe the API is sitting on a sweet spot and giving up on those features would make the API more cumbersome. Other features such as namespace, constructors and templates (in the case of the ImVector<> class) are also relied on as a convenience. -There is an unofficial but reasonably maintained [c-api for ImGui](https://github.com/Extrawurst/cimgui) by Stephan Dilly. I would suggest using your target language functionality to try replicating the function overloading and default parameters used in C++ else the API may be harder to use. It was really designed with C++ in mind and may not make the same amount of sense with another language. Also see [Links](https://github.com/ocornut/imgui/wiki/Links) for third-party bindings to other languages. +There is an reasonably maintained [c-api for ImGui](https://github.com/Extrawurst/cimgui) by Stephan Dilly designed for binding in other languages. I would suggest using your target language functionalities to try replicating the function overloading and default parameters used in C++ else the API may be harder to use. Also see [Links](https://github.com/ocornut/imgui/wiki/Links) for third-party bindings to other languages. Support dear imgui ------------------ From b498856c9d2c8270481e7e1ef25ed57142ce7ca3 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 13 Oct 2017 20:05:50 +0200 Subject: [PATCH 426/921] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 48e011c3a..71b1f37be 100644 --- a/README.md +++ b/README.md @@ -138,7 +138,7 @@ Frequently Asked Question (FAQ) Which version should I get? -I occasionally tag [Releases](https://github.com/ocornut/imgui/releases) but it is generally safe and recommended to sync to master. The library is pretty stable and regression tend to fixed very fast when reported. You may also want to checkout the [navigation branch](https://github.com/ocornut/imgui/tree/navigation) if you want to use imgui with a gamepad (it is also possible to map keyboard inputs to some degree). The Navigation branch is being kept up to date with Master. +I occasionally tag [Releases](https://github.com/ocornut/imgui/releases) but it is generally safe and recommended to sync to master. The library is fairly stable and regressions tend to fixed fast when reported. You may also want to checkout the [navigation branch](https://github.com/ocornut/imgui/tree/navigation) if you want to use Dear ImGui with a gamepad (it is also possible to map keyboard inputs to some degree). The Navigation branch is being kept up to date with Master. Why the odd dual naming, "dear imgui" vs "ImGui"? From 251bc6c22ce886f36b779136ed652f7ac1ed1368 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 13 Oct 2017 21:29:31 +0200 Subject: [PATCH 427/921] Update README.md --- README.md | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 71b1f37be..3cc4d2c67 100644 --- a/README.md +++ b/README.md @@ -50,9 +50,9 @@ You should be able to build the examples from sources (tested on Windows/Mac/Lin Bindings -------- -_NB: those third-party bindings may be more or less maintained, more or less close to the spirit of original API and therefore I cannot give much guarantee about them. People who create language bindings sometimes haven't used the C++ API themselves (for the good reason that they aren't C++ users). Dear ImGui was designed with C++ in mind and some of the subtleties may be lost in translation with other languages. If your language supports it, I would suggest replicating the function overloading and default parameters used in the original, else the API may be harder to use. In doubt, please check the original C++ version first!_ +Integrating Dear ImGui within your custom engine is a matter of wiring mouse/keyboard inputs and providing a render function that can bind a texture and render simple textured triangles. The examples/ folder is populated with applications doing just that. If you are an experienced programmer it should take you less than an hour to integrate Dear ImGui in your custom engine, but make sure to spend time reading the FAQ, the comments and other documentation! -_Integrating Dear ImGui within your custom engine is a matter of wiring mouse/keyboard inputs and providing a render function that can bind a texture and render simple textured triangles. The examples/ folder is populated with applications doing just that. If you are an experienced programmer it should take you less than an hour to integrate Dear ImGui in your custom engine, but make sure to spend time reading the FAQ, the comments and other documentation!_ +_NB: those third-party bindings may be more or less maintained, more or less close to the spirit of original API and therefore I cannot give much guarantee about them. People who create language bindings sometimes haven't used the C++ API themselves (for the good reason that they aren't C++ users). Dear ImGui was designed with C++ in mind and some of the subtleties may be lost in translation with other languages. If your language supports it, I would suggest replicating the function overloading and default parameters used in the original, else the API may be harder to use. In doubt, please check the original C++ version first!_ Languages: - C (cimgui): thin c-api wrapper for ImGui https://github.com/Extrawurst/cimgui @@ -90,6 +90,7 @@ Gallery ------- See the [Screenshots Thread](https://github.com/ocornut/imgui/issues/123) for some user creations. +Also see the [Mega screenshots](https://github.com/ocornut/imgui/issues/1273) for an idea of the available features. ![screenshot 1](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v148/examples_01.png) [![screenshot game](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v149/gallery_TheDragonsTrap-01-thumb.jpg)](https://cloud.githubusercontent.com/assets/8225057/20628927/33e14cac-b329-11e6-80f6-9524e93b048a.png) @@ -138,7 +139,7 @@ Frequently Asked Question (FAQ) Which version should I get? -I occasionally tag [Releases](https://github.com/ocornut/imgui/releases) but it is generally safe and recommended to sync to master. The library is fairly stable and regressions tend to fixed fast when reported. You may also want to checkout the [navigation branch](https://github.com/ocornut/imgui/tree/navigation) if you want to use Dear ImGui with a gamepad (it is also possible to map keyboard inputs to some degree). The Navigation branch is being kept up to date with Master. +I occasionally tag [Releases](https://github.com/ocornut/imgui/releases) but it is generally safe and recommended to sync to master. The library is fairly stable and regressions tend to be fixed fast when reported. You may also want to checkout the [navigation branch](https://github.com/ocornut/imgui/tree/navigation) if you want to use Dear ImGui with a gamepad (it is also possible to map keyboard inputs to some degree). The Navigation branch is being kept up to date with Master. Why the odd dual naming, "dear imgui" vs "ImGui"? @@ -160,13 +161,13 @@ See the FAQ in imgui.cpp for answers. How do you use Dear ImGui on a platform that may not have a mouse or keyboard? -I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/symless/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. Dear ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate. +I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/symless/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. Dear ImGui allows to increase the hit box of widgets (via the _style.TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate. You can also checkout the beta [navigation branch](https://github.com/ocornut/imgui/tree/navigation) which provides support for using Dear ImGui with a game controller. Can you create elaborate/serious tools with Dear ImGui? -Yes. I have written data browsers, debuggers, profilers and all sort of non-trivial tools with the library. In my experience the simplicity of the API is very empowering. Your UI runs close to your live data. Make the tools always-on and everybody in the team will be inclined to create new tools (as opposed to more "offline" UI toolkits where only a fraction of your team effectively creates tools). +Yes. People have written game editors, data browsers, debuggers, profilers and all sort of non-trivial tools with the library. In my experience the simplicity of the API is very empowering. Your UI runs close to your live data. Make the tools always-on and everybody in the team will be inclined to create new tools (as opposed to more "offline" UI toolkits where only a fraction of your team effectively creates tools). -Dear ImGui is very programmer centric and the immediate-mode GUI paradigm might requires you to readjust some habits before you can realize its full potential. Many programmers have unfortunately been taught by their environment to make unnecessarily complicated things. Dear ImGui is about making things that are simple, efficient and powerful. +Dear ImGui is very programmer centric and the immediate-mode GUI paradigm might requires you to readjust some habits before you can realize its full potential. Dear ImGui is about making things that are simple, efficient and powerful. Is Dear ImGui fast? @@ -182,9 +183,7 @@ If you intend to display large lists of items (say, 1000+) it can be beneficial Can you reskin the look of Dear ImGui? -You can alter the look of the interface to some degree: changing colors, sizes, padding, rounding, fonts. However, as Dear ImGui is designed and optimised to create debug tools, the amount of skinning you can apply is limited. There is only so much you can stray away from the default look and feel of the interface. - -This is [LumixEngine](https://github.com/nem0/LumixEngine) with custom colors + a docking/tabs extension (both of which you can find in the Issues section and will eventually be merged). +You can alter the look of the interface to some degree: changing colors, sizes, padding, rounding, fonts. However, as Dear ImGui is designed and optimised to create debug tools, the amount of skinning you can apply is limited. There is only so much you can stray away from the default look and feel of the interface. Below is a screenshot from [LumixEngine](https://github.com/nem0/LumixEngine) with custom colors + a docking/tabs extension (both of which you can find in the Issues section and will eventually be merged): ![LumixEngine](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v151/lumix-201710-rearranged.png) From ce7b04e8b97d451f4888168ec76f95bc35a5de09 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 13 Oct 2017 23:59:17 +0200 Subject: [PATCH 428/921] Removed apparently unncessary code in InputFloatN() and InputInt(). --- imgui.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 2657fa2c4..015906670 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -8531,7 +8531,6 @@ bool ImGui::InputFloatN(const char* label, float* v, int components, int decimal } PopID(); - window->DC.CurrentLineTextBaseOffset = ImMax(window->DC.CurrentLineTextBaseOffset, g.Style.FramePadding.y); TextUnformatted(label, FindRenderedTextEnd(label)); EndGroup(); @@ -8574,7 +8573,6 @@ bool ImGui::InputIntN(const char* label, int* v, int components, ImGuiInputTextF } PopID(); - window->DC.CurrentLineTextBaseOffset = ImMax(window->DC.CurrentLineTextBaseOffset, g.Style.FramePadding.y); TextUnformatted(label, FindRenderedTextEnd(label)); EndGroup(); From 7a8eb5bdc971d3f1b82ae8683a9df9b4c1437a78 Mon Sep 17 00:00:00 2001 From: Dominik Tugend Date: Sun, 15 Oct 2017 19:27:53 +0200 Subject: [PATCH 429/921] Rendering issue fix Fixes ocornut/imgui#1172 --- imgui_draw.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 736476891..f5923641c 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -222,7 +222,7 @@ void ImDrawList::UpdateTextureID() // Try to merge with previous command if it matches, else use current command ImDrawCmd* prev_cmd = CmdBuffer.Size > 1 ? curr_cmd - 1 : NULL; - if (prev_cmd && prev_cmd->TextureId == curr_texture_id && memcmp(&prev_cmd->ClipRect, &GetCurrentClipRect(), sizeof(ImVec4)) == 0 && prev_cmd->UserCallback == NULL) + if (curr_cmd->ElemCount == 0 && prev_cmd && prev_cmd->TextureId == curr_texture_id && memcmp(&prev_cmd->ClipRect, &GetCurrentClipRect(), sizeof(ImVec4)) == 0 && prev_cmd->UserCallback == NULL) CmdBuffer.pop_back(); else curr_cmd->TextureId = curr_texture_id; From e32569dd5aa008448b10d9be11e5193502f5368b Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 15 Oct 2017 21:06:33 +0200 Subject: [PATCH 430/921] ImDrawList: Fixed a bug in ChannelsMerge() leading to an extraneous draw call being created, which unexpectly led to more dramatic condition but to faulty draw command merging code. (#1172, #1368) --- imgui_draw.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index f5923641c..9da0ad1c2 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -339,7 +339,7 @@ void ImDrawList::ChannelsMerge() if (int sz = ch.CmdBuffer.Size) { memcpy(cmd_write, ch.CmdBuffer.Data, sz * sizeof(ImDrawCmd)); cmd_write += sz; } if (int sz = ch.IdxBuffer.Size) { memcpy(_IdxWritePtr, ch.IdxBuffer.Data, sz * sizeof(ImDrawIdx)); _IdxWritePtr += sz; } } - AddDrawCmd(); + UpdateClipRect(); // We call this instead of AddDrawCmd(), so that empty channels won't produce an extra draw call. _ChannelsCount = 1; } From 633f60cdb2a33dbc396ee9bc8c6452b099d3b7b1 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 15 Oct 2017 21:30:06 +0200 Subject: [PATCH 431/921] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 3cc4d2c67..306a8e542 100644 --- a/README.md +++ b/README.md @@ -80,6 +80,7 @@ Frameworks: - openFrameworks (ofxImGui): https://github.com/jvcleave/ofxImGui - LÖVE: https://github.com/slages/love-imgui - NanoRT (software raytraced) https://github.com/syoyo/imgui/tree/nanort/examples/raytrace_example +- Qt3d https://github.com/alpqr/imgui-qt3d - Unreal Engine 4: https://github.com/segross/UnrealImGui or https://github.com/sronsse/UnrealEngine_ImGui - SFML: https://github.com/EliasD/imgui-sfml or https://github.com/Mischa-Alff/imgui-backends From c76f0142927db9b9585380713a4829336d1c0b24 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 16 Oct 2017 16:41:09 +0200 Subject: [PATCH 432/921] Fix IsItemHovered() issue on child by temporarily reverting 344d48be31e1fae98c9f7cb6d96b6d77d29abec0. This is not the ideal solution. (Fix #1370) --- imgui.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 015906670..c2d6aa013 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1986,8 +1986,9 @@ bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id) return true; } -// This is roughly matching the behavior of internal-facing ItemHoverable() which is +// This is roughly matching the behavior of internal-facing ItemHoverable() // - we allow hovering to be true when ActiveId==window->MoveID, so that clicking on non-interactive items such as a Text() item still returns true with IsItemHovered()) +// - this should work even for non-interactive items that have no ID, so we cannot use LastItemId bool ImGui::IsItemHovered() { ImGuiContext& g = *GImGui; @@ -1995,7 +1996,11 @@ bool ImGui::IsItemHovered() ImGuiWindow* window = g.CurrentWindow; if (!window->DC.LastItemRectHoveredRect) return false; - if (g.HoveredWindow != window) + // [2017/10/16] Reverted commit 344d48be3 and testing RootWindow instead. I believe it is correct to NOT test for RootWindow but this leaves us unable to use IsItemHovered() after EndChild() itself. + // Until a solution is found I believe reverting to the test from 2017/09/27 is safe since this was the test that has been running for a long while. + //if (g.HoveredWindow != window) + // return false; + if (g.HoveredRootWindow != window->RootWindow) return false; if (g.ActiveId != 0 && g.ActiveId != window->DC.LastItemId && !g.ActiveIdAllowOverlap && g.ActiveId != window->MoveId) return false; From 1a35766356032a77bed1e9f16bdfcd60b93784cf Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 16 Oct 2017 23:36:34 +0200 Subject: [PATCH 433/921] BeginPopupContextItem() now supports a NULL string identifier and uses the last item ID if available. For interactive items (that have an ID) this works! For non interactive items we assert. --- imgui.cpp | 25 +++++++++++++++---------- imgui.h | 2 +- imgui_demo.cpp | 9 +++++++-- 3 files changed, 23 insertions(+), 13 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index c2d6aa013..9e969385e 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3697,38 +3697,43 @@ void ImGui::EndPopup() PopStyleVar(); } -// This is a helper to handle the most simple case of associating one named popup to one given widget. +// This is a helper to handle the simplest case of associating one named popup to one given widget. // 1. If you have many possible popups (for different "instances" of a same widget, or for wholly different widgets), you may be better off handling // this yourself so you can store data relative to the widget that opened the popup instead of choosing different popup identifiers. // 2. If you want right-clicking on the same item to reopen the popup at new location, use the same code replacing IsItemHovered() with IsItemRectHovered() // and passing true to the OpenPopupEx(). -// Because: hovering an item in a window below the popup won't normally trigger is hovering behavior/coloring. The pattern of ignoring the fact that -// the item can be interacted with (because it is blocked by the active popup) may useful in some situation when e.g. large canvas as one item, content of menu -// driven by click position. +// This is because hovering an item in a window below the popup won't work. IsItemRectHovered() skips this test. +// The pattern of ignoring the fact that the item can be interacted with (because it is blocked by the active popup) may useful in some situation +// when e.g. large canvas where the content of menu driven by click position. bool ImGui::BeginPopupContextItem(const char* str_id, int mouse_button) { + ImGuiWindow* window = GImGui->CurrentWindow; + ImGuiID id = str_id ? window->GetID(str_id) : window->DC.LastItemId; // If user hasn't passed an ID, we can use the LastItemID. Using LastItemID as a Popup ID won't conflict! + IM_ASSERT(id != 0); // However, you cannot pass a NULL str_id if the last item has no identifier (e.g. a Text() item) if (IsItemHovered() && IsMouseClicked(mouse_button)) - OpenPopupEx(GImGui->CurrentWindow->GetID(str_id), false); - return BeginPopup(str_id); + OpenPopupEx(id, false); + return BeginPopupEx(id, 0); } bool ImGui::BeginPopupContextWindow(const char* str_id, int mouse_button, bool also_over_items) { if (!str_id) str_id = "window_context"; + ImGuiID id = GImGui->CurrentWindow->GetID(str_id); if (IsWindowRectHovered() && IsMouseClicked(mouse_button)) if (also_over_items || !IsAnyItemHovered()) - OpenPopupEx(GImGui->CurrentWindow->GetID(str_id), true); - return BeginPopup(str_id); + OpenPopupEx(id, true); + return BeginPopupEx(id, 0); } bool ImGui::BeginPopupContextVoid(const char* str_id, int mouse_button) { if (!str_id) str_id = "void_context"; + ImGuiID id = GImGui->CurrentWindow->GetID(str_id); if (!IsAnyWindowHovered() && IsMouseClicked(mouse_button)) - OpenPopupEx(GImGui->CurrentWindow->GetID(str_id), true); - return BeginPopup(str_id); + OpenPopupEx(id, true); + return BeginPopupEx(id, 0); } static bool BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, bool border, ImGuiWindowFlags extra_flags) diff --git a/imgui.h b/imgui.h index a5a5972e1..8984f9910 100644 --- a/imgui.h +++ b/imgui.h @@ -392,7 +392,7 @@ namespace ImGui IMGUI_API void OpenPopup(const char* str_id); // call to mark popup as open (don't call every frame!). popups are closed when user click outside, or if CloseCurrentPopup() is called within a BeginPopup()/EndPopup() block. By default, Selectable()/MenuItem() are calling CloseCurrentPopup(). Popup identifiers are relative to the current ID-stack (so OpenPopup and BeginPopup needs to be at the same level). IMGUI_API bool BeginPopup(const char* str_id); // return true if the popup is open, and you can start outputting to it. only call EndPopup() if BeginPopup() returned true! IMGUI_API bool BeginPopupModal(const char* name, bool* p_open = NULL, ImGuiWindowFlags extra_flags = 0); // modal dialog (block interactions behind the modal window, can't close the modal window by clicking outside) - IMGUI_API bool BeginPopupContextItem(const char* str_id, int mouse_button = 1); // helper to open and begin popup when clicked on last item. read comments in .cpp! + IMGUI_API bool BeginPopupContextItem(const char* str_id = NULL, int mouse_button = 1); // helper to open and begin popup when clicked on last item. if you can pass a NULL str_id only if the previous item had an id. If you want to use that on a non-interactive item such as Text() you need to pass in an explicit ID here. read comments in .cpp! IMGUI_API bool BeginPopupContextWindow(const char* str_id = NULL, int mouse_button = 1, bool also_over_items = true); // helper to open and begin popup when clicked on current window. IMGUI_API bool BeginPopupContextVoid(const char* str_id = NULL, int mouse_button = 1); // helper to open and begin popup when clicked in void (no window). IMGUI_API void EndPopup(); diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 3f7d5feea..107c4b86d 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1402,6 +1402,11 @@ void ImGui::ShowTestWindow(bool* p_open) if (ImGui::TreeNode("Context menus")) { + // BeginPopupContextItem() is a helper to provide common/simple popup behavior of essentially doing: + // if (IsItemHovered() && IsMouseClicked(0)) + // OpenPopup(id); + // return BeginPopup(id); + // For more advanced uses you may want to replicate and cuztomize this code. This the comments inside BeginPopupContextItem() implementation. static float value = 0.5f; ImGui::Text("Value = %.3f (<-- right-click here)", value); if (ImGui::BeginPopupContextItem("item context menu")) @@ -1413,9 +1418,9 @@ void ImGui::ShowTestWindow(bool* p_open) } static char name[32] = "Label1"; - char buf[64]; sprintf(buf, "Button: %s###Button", name); // ### operator override ID ignoring the preceeding label + char buf[64]; sprintf(buf, "Button: %s###Button", name); // ### operator override ID ignoring the preceding label ImGui::Button(buf); - if (ImGui::BeginPopupContextItem("rename context menu")) + if (ImGui::BeginPopupContextItem()) // When used after an item that has an ID (here the Button), we can skip providing an ID to BeginPopupContextItem(). { ImGui::Text("Edit name:"); ImGui::InputText("##edit", name, IM_ARRAYSIZE(name)); From 839067fda9e2ffa34c2e8bfc36be2c94fddcab53 Mon Sep 17 00:00:00 2001 From: Gargaj Date: Tue, 17 Oct 2017 12:37:21 +0200 Subject: [PATCH 434/921] Capture/release window in DX9 implementation This helps a lot when the user drags a slider but carries the cursor offscreen before releasing the button - without the capturing, the slider will "stick" to the mouse cursor even after the button has been released. (This should generally be added to all Windows implementations - I won't mind doing it if you think it's a good idea.) --- examples/directx9_example/imgui_impl_dx9.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/examples/directx9_example/imgui_impl_dx9.cpp b/examples/directx9_example/imgui_impl_dx9.cpp index 490120126..d1062560b 100644 --- a/examples/directx9_example/imgui_impl_dx9.cpp +++ b/examples/directx9_example/imgui_impl_dx9.cpp @@ -177,21 +177,27 @@ IMGUI_API LRESULT ImGui_ImplDX9_WndProcHandler(HWND, UINT msg, WPARAM wParam, LP switch (msg) { case WM_LBUTTONDOWN: + SetCapture( hWnd ); io.MouseDown[0] = true; return true; case WM_LBUTTONUP: + ReleaseCapture(); io.MouseDown[0] = false; return true; case WM_RBUTTONDOWN: + SetCapture( hWnd ); io.MouseDown[1] = true; return true; case WM_RBUTTONUP: + ReleaseCapture(); io.MouseDown[1] = false; return true; case WM_MBUTTONDOWN: + SetCapture( hWnd ); io.MouseDown[2] = true; return true; case WM_MBUTTONUP: + ReleaseCapture(); io.MouseDown[2] = false; return true; case WM_MOUSEWHEEL: From 55d873875e62d952f1b26ac87ba3bd95de2f29bc Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 17 Oct 2017 15:47:55 +0200 Subject: [PATCH 435/921] Begin: Work toward obsoleting the 5-arguments Begin() overload. (1) --- imgui.cpp | 29 +++++++++++++++++++---------- imgui_internal.h | 2 ++ 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 9e969385e..dcd92148b 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4010,6 +4010,17 @@ static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window) return scroll; } +static ImGuiCol GetWindowBgColorIdxFromFlags(ImGuiWindowFlags flags) +{ + if (flags & ImGuiWindowFlags_ComboBox) + return ImGuiCol_ComboBg; + if (flags & (ImGuiWindowFlags_Tooltip | ImGuiWindowFlags_Popup)) + return ImGuiCol_PopupBg; + if (flags & ImGuiWindowFlags_ChildWindow) + return ImGuiCol_ChildWindowBg; + return ImGuiCol_WindowBg; +} + // Push a new ImGui window to add widgets to. // - A default window called "Debug" is automatically stacked at the beginning of every frame so you can use widgets without explicitly calling a Begin/End pair. // - Begin/End can be called multiple times during the frame with the same window name to append content. @@ -4021,10 +4032,15 @@ static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window) // - Passing non-zero 'size' is roughly equivalent to calling SetNextWindowSize(size, ImGuiCond_FirstUseEver) prior to calling Begin(). bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) { - return ImGui::Begin(name, p_open, ImVec2(0.f, 0.f), -1.0f, flags); + return BeginEx(name, p_open, ImVec2(0.f, 0.f), -1.0f, flags); } bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_use, float bg_alpha, ImGuiWindowFlags flags) +{ + return BeginEx(name, p_open, size_on_first_use, bg_alpha, flags); +} + +bool ImGui::BeginEx(const char* name, bool* p_open, const ImVec2& size_on_first_use, float bg_alpha, ImGuiWindowFlags flags) { ImGuiContext& g = *GImGui; const ImGuiStyle& style = g.Style; @@ -4371,13 +4387,7 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us window->BorderSize = (flags & ImGuiWindowFlags_ShowBorders) ? 1.0f : 0.0f; // Window background, Default Alpha - ImGuiCol bg_color_idx = ImGuiCol_WindowBg; - if ((flags & ImGuiWindowFlags_ComboBox) != 0) - bg_color_idx = ImGuiCol_ComboBg; - else if ((flags & ImGuiWindowFlags_Tooltip) != 0 || (flags & ImGuiWindowFlags_Popup) != 0) - bg_color_idx = ImGuiCol_PopupBg; - else if ((flags & ImGuiWindowFlags_ChildWindow) != 0) - bg_color_idx = ImGuiCol_ChildWindowBg; + ImGuiCol bg_color_idx = GetWindowBgColorIdxFromFlags(flags); ImVec4 bg_color = style.Colors[bg_color_idx]; // We don't use GetColorU32() because bg_alpha is assigned (not multiplied) below if (bg_alpha >= 0.0f) bg_color.w = bg_alpha; @@ -5151,8 +5161,7 @@ void ImGui::SetWindowSize(const ImVec2& size, ImGuiCond cond) void ImGui::SetWindowSize(const char* name, const ImVec2& size, ImGuiCond cond) { - ImGuiWindow* window = FindWindowByName(name); - if (window) + if (ImGuiWindow* window = FindWindowByName(name)) SetWindowSize(window, size, cond); } diff --git a/imgui_internal.h b/imgui_internal.h index 6c4f8db5e..ea67e9dfd 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -782,6 +782,8 @@ namespace ImGui IMGUI_API void PushItemFlag(ImGuiItemFlags option, bool enabled); IMGUI_API void PopItemFlag(); + IMGUI_API bool BeginEx(const char* name, bool* p_open, const ImVec2& size_on_first_use, float bg_alpha, ImGuiWindowFlags flags); + IMGUI_API void OpenPopupEx(ImGuiID id, bool reopen_existing); IMGUI_API void ClosePopup(ImGuiID id); IMGUI_API bool IsPopupOpen(ImGuiID id); From 4aa9d2089dbdfb55e13d0f1a164d124a07e36880 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 17 Oct 2017 15:51:20 +0200 Subject: [PATCH 436/921] Begin: Work toward obsoleting the 5-arguments Begin() overload. Removed size_on_first_use from internal BeginEx(). (2) --- imgui.cpp | 15 ++++++++++----- imgui_internal.h | 2 +- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index dcd92148b..c165c1eac 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3758,7 +3758,8 @@ static bool BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, b else ImFormatString(title, IM_ARRAYSIZE(title), "%s/%08X", parent_window->Name, id); - bool ret = ImGui::Begin(title, NULL, size, -1.0f, flags); + ImGui::SetNextWindowSize(size); + bool ret = ImGui::Begin(title, NULL, flags); ImGuiWindow* child_window = ImGui::GetCurrentWindow(); child_window->AutoFitChildAxises = auto_fit_axises; if (!(parent_window->Flags & ImGuiWindowFlags_ShowBorders)) @@ -4032,15 +4033,17 @@ static ImGuiCol GetWindowBgColorIdxFromFlags(ImGuiWindowFlags flags) // - Passing non-zero 'size' is roughly equivalent to calling SetNextWindowSize(size, ImGuiCond_FirstUseEver) prior to calling Begin(). bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) { - return BeginEx(name, p_open, ImVec2(0.f, 0.f), -1.0f, flags); + return BeginEx(name, p_open, -1.0f, flags); } bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_use, float bg_alpha, ImGuiWindowFlags flags) { - return BeginEx(name, p_open, size_on_first_use, bg_alpha, flags); + if (size_on_first_use.x != 0.0f || size_on_first_use.y != 0.0f) + SetNextWindowSize(size_on_first_use, ImGuiCond_FirstUseEver); + return BeginEx(name, p_open, bg_alpha, flags); } -bool ImGui::BeginEx(const char* name, bool* p_open, const ImVec2& size_on_first_use, float bg_alpha, ImGuiWindowFlags flags) +bool ImGui::BeginEx(const char* name, bool* p_open, float bg_alpha, ImGuiWindowFlags flags) { ImGuiContext& g = *GImGui; const ImGuiStyle& style = g.Style; @@ -4056,6 +4059,7 @@ bool ImGui::BeginEx(const char* name, bool* p_open, const ImVec2& size_on_first_ ImGuiWindow* window = FindWindowByName(name); if (!window) { + ImVec2 size_on_first_use = (g.SetNextWindowSizeCond != 0) ? g.SetNextWindowSizeVal : ImVec2(0.0f, 0.0f); // Any condition flag will do since we are creating a new window here. window = CreateNewWindow(name, size_on_first_use, flags); window_is_new = true; } @@ -4260,8 +4264,9 @@ bool ImGui::BeginEx(const char* name, bool* p_open, const ImVec2& size_on_first_ } if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Popup)) { + IM_ASSERT(window_size_set_by_api); // Submitted by BeginChild() window->Pos = window->PosFloat = parent_window->DC.CursorPos; - window->Size = window->SizeFull = size_on_first_use; // NB: argument name 'size_on_first_use' misleading here, it's really just 'size' as provided by user passed via BeginChild()->Begin(). + window->Size = window->SizeFull; } const bool window_pos_with_pivot = (window->SetWindowPosVal.x != FLT_MAX && window->HiddenFrames == 0); diff --git a/imgui_internal.h b/imgui_internal.h index ea67e9dfd..945650dac 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -782,7 +782,7 @@ namespace ImGui IMGUI_API void PushItemFlag(ImGuiItemFlags option, bool enabled); IMGUI_API void PopItemFlag(); - IMGUI_API bool BeginEx(const char* name, bool* p_open, const ImVec2& size_on_first_use, float bg_alpha, ImGuiWindowFlags flags); + IMGUI_API bool BeginEx(const char* name, bool* p_open, float bg_alpha, ImGuiWindowFlags flags); IMGUI_API void OpenPopupEx(ImGuiID id, bool reopen_existing); IMGUI_API void ClosePopup(ImGuiID id); From 2739b6ebcde4772bb51efe961a72fd4864eafa42 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 17 Oct 2017 16:14:20 +0200 Subject: [PATCH 437/921] Begin: Work toward obsoleting the 5-arguments Begin() overload. Removed bg_alpha from internal BeginEx(). (3) --- imgui.cpp | 37 ++++++++++++++++++++++++------------- imgui_demo.cpp | 2 +- imgui_internal.h | 2 +- 3 files changed, 26 insertions(+), 15 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index c165c1eac..b38060a0b 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4025,25 +4025,41 @@ static ImGuiCol GetWindowBgColorIdxFromFlags(ImGuiWindowFlags flags) // Push a new ImGui window to add widgets to. // - A default window called "Debug" is automatically stacked at the beginning of every frame so you can use widgets without explicitly calling a Begin/End pair. // - Begin/End can be called multiple times during the frame with the same window name to append content. -// - 'size_on_first_use' for a regular window denote the initial size for first-time creation (no saved data) and isn't that useful. Use SetNextWindowSize() prior to calling Begin() for more flexible window manipulation. // - The window name is used as a unique identifier to preserve window information across frames (and save rudimentary information to the .ini file). // You can use the "##" or "###" markers to use the same label with different id, or same id with different label. See documentation at the top of this file. // - Return false when window is collapsed, so you can early out in your code. You always need to call ImGui::End() even if false is returned. // - Passing 'bool* p_open' displays a Close button on the upper-right corner of the window, the pointed value will be set to false when the button is pressed. -// - Passing non-zero 'size' is roughly equivalent to calling SetNextWindowSize(size, ImGuiCond_FirstUseEver) prior to calling Begin(). bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) { - return BeginEx(name, p_open, -1.0f, flags); + return BeginEx(name, p_open, flags); } -bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_use, float bg_alpha, ImGuiWindowFlags flags) +// FIXME-OBSOLETE: Old Begin() API, avoid calling this version directly! +bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_use, float bg_alpha_override, ImGuiWindowFlags flags) { + ImGuiContext& g = *GImGui; + + // Old API feature: we could pass the initial window size as a parameter, however this was very misleading because in most cases it would only affect the window when it didn't have storage in the .ini file. if (size_on_first_use.x != 0.0f || size_on_first_use.y != 0.0f) SetNextWindowSize(size_on_first_use, ImGuiCond_FirstUseEver); - return BeginEx(name, p_open, bg_alpha, flags); + + // Old API feature: we could override the window background alpha with a parameter. This is actually tricky to reproduce manually because: + // (1) there are multiple variants of WindowBg (popup, tooltip, etc.) and (2) you can't call PushStyleColor before Begin and PopStyleColor just after Begin() because of how CheckStackSizes() behave. + // The user-side solution is to do backup = GetStyleColorVec4(ImGuiCol_xxxBG), PushStyleColor(ImGuiCol_xxxBg), Begin, PushStyleColor(ImGuiCol_xxxBg, backup), [...], PopStyleColor(), End(); PopStyleColor() - which is super awkward. + // The alpha override was rarely used but for now we'll leave the Begin() variant around for a bit. We may either lift the constraint on CheckStackSizes() either add a SetNextWindowBgAlpha() helper that does it magically. + const ImGuiCol bg_color_idx = GetWindowBgColorIdxFromFlags(flags); + const ImVec4 bg_color_backup = g.Style.Colors[bg_color_idx]; + if (bg_alpha_override >= 0.0f) + g.Style.Colors[bg_color_idx].w = bg_alpha_override; + + bool ret = BeginEx(name, p_open, flags); + + if (bg_alpha_override >= 0.0f) + g.Style.Colors[bg_color_idx] = bg_color_backup; + return ret; } -bool ImGui::BeginEx(const char* name, bool* p_open, float bg_alpha, ImGuiWindowFlags flags) +bool ImGui::BeginEx(const char* name, bool* p_open, ImGuiWindowFlags flags) { ImGuiContext& g = *GImGui; const ImGuiStyle& style = g.Style; @@ -4392,13 +4408,8 @@ bool ImGui::BeginEx(const char* name, bool* p_open, float bg_alpha, ImGuiWindowF window->BorderSize = (flags & ImGuiWindowFlags_ShowBorders) ? 1.0f : 0.0f; // Window background, Default Alpha - ImGuiCol bg_color_idx = GetWindowBgColorIdxFromFlags(flags); - ImVec4 bg_color = style.Colors[bg_color_idx]; // We don't use GetColorU32() because bg_alpha is assigned (not multiplied) below - if (bg_alpha >= 0.0f) - bg_color.w = bg_alpha; - bg_color.w *= style.Alpha; - if (bg_color.w > 0.0f) - window->DrawList->AddRectFilled(window->Pos+ImVec2(0,window->TitleBarHeight()), window->Pos+window->Size, ColorConvertFloat4ToU32(bg_color), window_rounding, (flags & ImGuiWindowFlags_NoTitleBar) ? ImGuiCorner_All : ImGuiCorner_BotLeft|ImGuiCorner_BotRight); + ImU32 bg_col = GetColorU32(GetWindowBgColorIdxFromFlags(flags)); + window->DrawList->AddRectFilled(window->Pos+ImVec2(0,window->TitleBarHeight()), window->Pos+window->Size, bg_col, window_rounding, (flags & ImGuiWindowFlags_NoTitleBar) ? ImGuiCorner_All : ImGuiCorner_BotLeft|ImGuiCorner_BotRight); // Title bar const bool is_focused = g.NavWindow && window->RootNonPopupWindow == g.NavWindow->RootNonPopupWindow; diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 107c4b86d..c0f96d750 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -2130,7 +2130,7 @@ static void ShowExampleAppFixedOverlay(bool* p_open) ImVec2 window_pos = ImVec2((corner & 1) ? ImGui::GetIO().DisplaySize.x - DISTANCE : DISTANCE, (corner & 2) ? ImGui::GetIO().DisplaySize.y - DISTANCE : DISTANCE); ImVec2 window_pos_pivot = ImVec2((corner & 1) ? 1.0f : 0.0f, (corner & 2) ? 1.0f : 0.0f); ImGui::SetNextWindowPos(window_pos, ImGuiCond_Always, window_pos_pivot); - ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(0.0f, 0.0f, 0.0f, 0.3f)); + ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(0.0f, 0.0f, 0.0f, 0.3f)); // Transparent background if (ImGui::Begin("Example: Fixed Overlay", p_open, ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoSavedSettings)) { ImGui::Text("Simple overlay\nin the corner of the screen.\n(right-click to change position)"); diff --git a/imgui_internal.h b/imgui_internal.h index 945650dac..972b5afd7 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -782,7 +782,7 @@ namespace ImGui IMGUI_API void PushItemFlag(ImGuiItemFlags option, bool enabled); IMGUI_API void PopItemFlag(); - IMGUI_API bool BeginEx(const char* name, bool* p_open, float bg_alpha, ImGuiWindowFlags flags); + IMGUI_API bool BeginEx(const char* name, bool* p_open, ImGuiWindowFlags flags); IMGUI_API void OpenPopupEx(ImGuiID id, bool reopen_existing); IMGUI_API void ClosePopup(ImGuiID id); From 78a85ba3fecd931cbc7f8c37c6a5e519dc101c23 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 17 Oct 2017 16:15:46 +0200 Subject: [PATCH 438/921] Begin: Work toward obsoleting the 5-arguments Begin() overload. Internal BeginEx() becomes the normal public Begin() again! (4) --- imgui.cpp | 23 +++++++++-------------- imgui_internal.h | 2 -- 2 files changed, 9 insertions(+), 16 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index b38060a0b..2254b9b08 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4022,18 +4022,6 @@ static ImGuiCol GetWindowBgColorIdxFromFlags(ImGuiWindowFlags flags) return ImGuiCol_WindowBg; } -// Push a new ImGui window to add widgets to. -// - A default window called "Debug" is automatically stacked at the beginning of every frame so you can use widgets without explicitly calling a Begin/End pair. -// - Begin/End can be called multiple times during the frame with the same window name to append content. -// - The window name is used as a unique identifier to preserve window information across frames (and save rudimentary information to the .ini file). -// You can use the "##" or "###" markers to use the same label with different id, or same id with different label. See documentation at the top of this file. -// - Return false when window is collapsed, so you can early out in your code. You always need to call ImGui::End() even if false is returned. -// - Passing 'bool* p_open' displays a Close button on the upper-right corner of the window, the pointed value will be set to false when the button is pressed. -bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) -{ - return BeginEx(name, p_open, flags); -} - // FIXME-OBSOLETE: Old Begin() API, avoid calling this version directly! bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_use, float bg_alpha_override, ImGuiWindowFlags flags) { @@ -4052,14 +4040,21 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us if (bg_alpha_override >= 0.0f) g.Style.Colors[bg_color_idx].w = bg_alpha_override; - bool ret = BeginEx(name, p_open, flags); + bool ret = Begin(name, p_open, flags); if (bg_alpha_override >= 0.0f) g.Style.Colors[bg_color_idx] = bg_color_backup; return ret; } -bool ImGui::BeginEx(const char* name, bool* p_open, ImGuiWindowFlags flags) +// Push a new ImGui window to add widgets to. +// - A default window called "Debug" is automatically stacked at the beginning of every frame so you can use widgets without explicitly calling a Begin/End pair. +// - Begin/End can be called multiple times during the frame with the same window name to append content. +// - The window name is used as a unique identifier to preserve window information across frames (and save rudimentary information to the .ini file). +// You can use the "##" or "###" markers to use the same label with different id, or same id with different label. See documentation at the top of this file. +// - Return false when window is collapsed, so you can early out in your code. You always need to call ImGui::End() even if false is returned. +// - Passing 'bool* p_open' displays a Close button on the upper-right corner of the window, the pointed value will be set to false when the button is pressed. +bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) { ImGuiContext& g = *GImGui; const ImGuiStyle& style = g.Style; diff --git a/imgui_internal.h b/imgui_internal.h index 972b5afd7..6c4f8db5e 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -782,8 +782,6 @@ namespace ImGui IMGUI_API void PushItemFlag(ImGuiItemFlags option, bool enabled); IMGUI_API void PopItemFlag(); - IMGUI_API bool BeginEx(const char* name, bool* p_open, ImGuiWindowFlags flags); - IMGUI_API void OpenPopupEx(ImGuiID id, bool reopen_existing); IMGUI_API void ClosePopup(ImGuiID id); IMGUI_API bool IsPopupOpen(ImGuiID id); From 03b76bf05b3b33718773383265db417c1b9dc7a7 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 17 Oct 2017 16:19:21 +0200 Subject: [PATCH 439/921] Begin: Marked 5 parameters version of Begin() as obsolete. Now waiting for a riot to happen! --- imgui.cpp | 52 +++++++++++++++++++++++++++------------------------- imgui.h | 2 +- 2 files changed, 28 insertions(+), 26 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 2254b9b08..f2be79bc4 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -204,6 +204,7 @@ Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. Also read releases logs https://github.com/ocornut/imgui/releases for more details. + - 2017/10/17 (1.52) - marked the old 5-parameters version of Begin() as obsolete (still available). Use SetNextWindowSize()+Begin() instead! - 2017/10/11 (1.52) - renamed AlignFirstTextHeightToWidgets() to AlignTextToFramePadding(). Kept inline redirection function (will obsolete). - 2017/09/25 (1.52) - removed SetNextWindowPosCenter() because SetNextWindowPos() now has the optional pivot information to do the same and more. Kept redirection function (will obsolete). - 2017/08/25 (1.52) - io.MousePos needs to be set to ImVec2(-FLT_MAX,-FLT_MAX) when mouse is unavailable/missing. Previously ImVec2(-1,-1) was enough but we now accept negative mouse coordinates. In your binding if you need to support unavailable mouse, make sure to replace "io.MousePos = ImVec2(-1,-1)" with "io.MousePos = ImVec2(-FLT_MAX,-FLT_MAX)". @@ -4022,31 +4023,6 @@ static ImGuiCol GetWindowBgColorIdxFromFlags(ImGuiWindowFlags flags) return ImGuiCol_WindowBg; } -// FIXME-OBSOLETE: Old Begin() API, avoid calling this version directly! -bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_use, float bg_alpha_override, ImGuiWindowFlags flags) -{ - ImGuiContext& g = *GImGui; - - // Old API feature: we could pass the initial window size as a parameter, however this was very misleading because in most cases it would only affect the window when it didn't have storage in the .ini file. - if (size_on_first_use.x != 0.0f || size_on_first_use.y != 0.0f) - SetNextWindowSize(size_on_first_use, ImGuiCond_FirstUseEver); - - // Old API feature: we could override the window background alpha with a parameter. This is actually tricky to reproduce manually because: - // (1) there are multiple variants of WindowBg (popup, tooltip, etc.) and (2) you can't call PushStyleColor before Begin and PopStyleColor just after Begin() because of how CheckStackSizes() behave. - // The user-side solution is to do backup = GetStyleColorVec4(ImGuiCol_xxxBG), PushStyleColor(ImGuiCol_xxxBg), Begin, PushStyleColor(ImGuiCol_xxxBg, backup), [...], PopStyleColor(), End(); PopStyleColor() - which is super awkward. - // The alpha override was rarely used but for now we'll leave the Begin() variant around for a bit. We may either lift the constraint on CheckStackSizes() either add a SetNextWindowBgAlpha() helper that does it magically. - const ImGuiCol bg_color_idx = GetWindowBgColorIdxFromFlags(flags); - const ImVec4 bg_color_backup = g.Style.Colors[bg_color_idx]; - if (bg_alpha_override >= 0.0f) - g.Style.Colors[bg_color_idx].w = bg_alpha_override; - - bool ret = Begin(name, p_open, flags); - - if (bg_alpha_override >= 0.0f) - g.Style.Colors[bg_color_idx] = bg_color_backup; - return ret; -} - // Push a new ImGui window to add widgets to. // - A default window called "Debug" is automatically stacked at the beginning of every frame so you can use widgets without explicitly calling a Begin/End pair. // - Begin/End can be called multiple times during the frame with the same window name to append content. @@ -4589,6 +4565,32 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) return !window->SkipItems; } +// Old Begin() API with 5 parameters, avoid calling this version directly! Use SetNextWindowSize()+Begin() instead. +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS +bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_use, float bg_alpha_override, ImGuiWindowFlags flags) +{ + // Old API feature: we could pass the initial window size as a parameter, however this was very misleading because in most cases it would only affect the window when it didn't have storage in the .ini file. + if (size_on_first_use.x != 0.0f || size_on_first_use.y != 0.0f) + SetNextWindowSize(size_on_first_use, ImGuiCond_FirstUseEver); + + // Old API feature: we could override the window background alpha with a parameter. This is actually tricky to reproduce manually because: + // (1) there are multiple variants of WindowBg (popup, tooltip, etc.) and (2) you can't call PushStyleColor before Begin and PopStyleColor just after Begin() because of how CheckStackSizes() behave. + // The user-side solution is to do backup = GetStyleColorVec4(ImGuiCol_xxxBG), PushStyleColor(ImGuiCol_xxxBg), Begin, PushStyleColor(ImGuiCol_xxxBg, backup), [...], PopStyleColor(), End(); PopStyleColor() - which is super awkward. + // The alpha override was rarely used but for now we'll leave the Begin() variant around for a bit. We may either lift the constraint on CheckStackSizes() either add a SetNextWindowBgAlpha() helper that does it magically. + ImGuiContext& g = *GImGui; + const ImGuiCol bg_color_idx = GetWindowBgColorIdxFromFlags(flags); + const ImVec4 bg_color_backup = g.Style.Colors[bg_color_idx]; + if (bg_alpha_override >= 0.0f) + g.Style.Colors[bg_color_idx].w = bg_alpha_override; + + bool ret = Begin(name, p_open, flags); + + if (bg_alpha_override >= 0.0f) + g.Style.Colors[bg_color_idx] = bg_color_backup; + return ret; +} +#endif // IMGUI_DISABLE_OBSOLETE_FUNCTIONS + void ImGui::End() { ImGuiContext& g = *GImGui; diff --git a/imgui.h b/imgui.h index 8984f9910..17c39f5ea 100644 --- a/imgui.h +++ b/imgui.h @@ -132,7 +132,6 @@ namespace ImGui // Window IMGUI_API bool Begin(const char* name, bool* p_open = NULL, ImGuiWindowFlags flags = 0); // push window to the stack and start appending to it. see .cpp for details. return false when window is collapsed, so you can early out in your code. 'bool* p_open' creates a widget on the upper-right to close the window (which sets your bool to false). - IMGUI_API bool Begin(const char* name, bool* p_open, const ImVec2& size_on_first_use, float bg_alpha = -1.0f, ImGuiWindowFlags flags = 0); // OBSOLETE. this is the older/longer API. the extra parameters aren't very relevant. call SetNextWindowSize() instead if you want to set a window size. For regular windows, 'size_on_first_use' only applies to the first time EVER the window is created and probably not what you want! might obsolete this API eventually. IMGUI_API void End(); // finish appending to current window, pop it off the window stack. IMGUI_API bool BeginChild(const char* str_id, const ImVec2& size = ImVec2(0,0), bool border = false, ImGuiWindowFlags extra_flags = 0); // begin a scrolling region. size==0.0f: use remaining window size, size<0.0f: use remaining window size minus abs(size). size>0.0f: fixed size. each axis can use a different mode, e.g. ImVec2(0,400). IMGUI_API bool BeginChild(ImGuiID id, const ImVec2& size = ImVec2(0,0), bool border = false, ImGuiWindowFlags extra_flags = 0); // " @@ -488,6 +487,7 @@ namespace ImGui // Obsolete functions (Will be removed! Also see 'API BREAKING CHANGES' section in imgui.cpp) #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS + bool Begin(const char* name, bool* p_open, const ImVec2& size_on_first_use, float bg_alpha_override = -1.0f, ImGuiWindowFlags flags = 0); // OBSOLETE 1.52+. use SetNextWindowSize() instead if you want to set a window size. static inline void AlignFirstTextHeightToWidgets() { AlignTextToFramePadding(); } // OBSOLETE 1.52+ void SetNextWindowPosCenter(ImGuiCond cond = 0); // OBSOLETE 1.52+ static inline bool IsItemHoveredRect() { return IsItemRectHovered(); } // OBSOLETE 1.51+ From bf778ebb7edd73176c76469eb7869e56854c16d3 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 18 Oct 2017 13:06:49 +0200 Subject: [PATCH 440/921] Checkbox: Using checkmark. MenuItem: Tweaked checkmark, thicker. --- imgui.cpp | 24 ++++++++++++++---------- imgui_internal.h | 2 +- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index f2be79bc4..445bba37b 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3092,18 +3092,22 @@ void ImGui::RenderBullet(ImVec2 pos) window->DrawList->AddCircleFilled(pos, GImGui->FontSize*0.20f, GetColorU32(ImGuiCol_Text), 8); } -void ImGui::RenderCheckMark(ImVec2 pos, ImU32 col) +void ImGui::RenderCheckMark(ImVec2 pos, ImU32 col, float sz) { ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; - float start_x = (float)(int)(g.FontSize * 0.307f + 0.5f); - float rem_third = (float)(int)((g.FontSize - start_x) / 3.0f); - float bx = pos.x + 0.5f + start_x + rem_third; - float by = pos.y - 1.0f + (float)(int)(g.Font->Ascent * (g.FontSize / g.Font->FontSize) + 0.5f) + (float)(int)(g.Font->DisplayOffset.y); - window->DrawList->PathLineTo(ImVec2(bx - rem_third, by - rem_third)); + + float thickness = ImMax(sz / 5.0f, 1.0f); + sz -= thickness*0.5f; + pos += ImVec2(thickness*0.25f, thickness*0.25f); + + float third = sz / 3.0f; + float bx = pos.x + third; + float by = pos.y + sz - third*0.5f; + window->DrawList->PathLineTo(ImVec2(bx - third, by - third)); window->DrawList->PathLineTo(ImVec2(bx, by)); - window->DrawList->PathLineTo(ImVec2(bx + rem_third*2, by - rem_third*2)); - window->DrawList->PathStroke(col, false); + window->DrawList->PathLineTo(ImVec2(bx + third*2, by - third*2)); + window->DrawList->PathStroke(col, false, thickness); } // Calculate text size. Text can be multi-line. Optionally ignore text after a ## marker. @@ -7519,7 +7523,7 @@ bool ImGui::Checkbox(const char* label, bool* v) { const float check_sz = ImMin(check_bb.GetWidth(), check_bb.GetHeight()); const float pad = ImMax(1.0f, (float)(int)(check_sz / 6.0f)); - window->DrawList->AddRectFilled(check_bb.Min+ImVec2(pad,pad), check_bb.Max-ImVec2(pad,pad), GetColorU32(ImGuiCol_CheckMark), style.FrameRounding); + RenderCheckMark(check_bb.Min + ImVec2(pad,pad), GetColorU32(ImGuiCol_CheckMark), check_bb.GetWidth() - pad*2.0f); } if (g.LogEnabled) @@ -9004,7 +9008,7 @@ bool ImGui::MenuItem(const char* label, const char* shortcut, bool selected, boo } if (selected) - RenderCheckMark(pos + ImVec2(window->MenuColumns.Pos[2] + extra_w + g.FontSize * 0.20f, 0.0f), GetColorU32(enabled ? ImGuiCol_Text : ImGuiCol_TextDisabled)); + RenderCheckMark(pos + ImVec2(window->MenuColumns.Pos[2] + extra_w + g.FontSize * (0.20f+0.200f), g.FontSize * 0.134f * 0.5f), GetColorU32(enabled ? ImGuiCol_Text : ImGuiCol_TextDisabled), g.FontSize * 0.866f); return pressed; } diff --git a/imgui_internal.h b/imgui_internal.h index 6c4f8db5e..9880a9ae8 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -811,7 +811,7 @@ namespace ImGui IMGUI_API void RenderColorRectWithAlphaCheckerboard(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, float grid_step, ImVec2 grid_off, float rounding = 0.0f, int rounding_corners_flags = ~0); IMGUI_API void RenderCollapseTriangle(ImVec2 pos, bool is_open, float scale = 1.0f); IMGUI_API void RenderBullet(ImVec2 pos); - IMGUI_API void RenderCheckMark(ImVec2 pos, ImU32 col); + IMGUI_API void RenderCheckMark(ImVec2 pos, ImU32 col, float sz); IMGUI_API void RenderRectFilledRangeH(ImDrawList* draw_list, const ImRect& rect, ImU32 col, float x_start_norm, float x_end_norm, float rounding); IMGUI_API const char* FindRenderedTextEnd(const char* text, const char* text_end = NULL); // Find the optional ## from which we stop displaying text. From 1c4af303bfc7387d36d95132d32ea40d95f8f4d4 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 17 Oct 2017 23:18:20 +0200 Subject: [PATCH 441/921] Internals:Helpers: Added ImSwap(int,int), exposed ImStrncpy(). --- imgui_internal.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/imgui_internal.h b/imgui_internal.h index 9880a9ae8..2d3b37391 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -107,6 +107,7 @@ IMGUI_API void ImTriangleBarycentricCoords(const ImVec2& a, const ImVec // Helpers: String IMGUI_API int ImStricmp(const char* str1, const char* str2); IMGUI_API int ImStrnicmp(const char* str1, const char* str2, int count); +IMGUI_API void ImStrncpy(char* dst, const char* src, int count); IMGUI_API char* ImStrdup(const char* str); IMGUI_API int ImStrlenW(const ImWchar* str); IMGUI_API const ImWchar*ImStrbolW(const ImWchar* buf_mid_line, const ImWchar* buf_begin); // Find beginning-of-line @@ -140,6 +141,7 @@ static inline int ImClamp(int v, int mn, int mx) static inline float ImClamp(float v, float mn, float mx) { return (v < mn) ? mn : (v > mx) ? mx : v; } static inline ImVec2 ImClamp(const ImVec2& f, const ImVec2& mn, ImVec2 mx) { return ImVec2(ImClamp(f.x,mn.x,mx.x), ImClamp(f.y,mn.y,mx.y)); } static inline float ImSaturate(float f) { return (f < 0.0f) ? 0.0f : (f > 1.0f) ? 1.0f : f; } +static inline void ImSwap(int& a, int& b) { int tmp = a; a = b; b = tmp; } static inline void ImSwap(float& a, float& b) { float tmp = a; a = b; b = tmp; } static inline int ImLerp(int a, int b, float t) { return (int)(a + (b - a) * t); } static inline float ImLerp(float a, float b, float t) { return a + (b - a) * t; } From ef3f87eec587179c0a82634f481412e25c707d15 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 17 Oct 2017 23:31:17 +0200 Subject: [PATCH 442/921] Internals: ButtonBehavior: made ImGuiButtonFlags_PressedOnClick and ImGuiButtonFlags_PressedOnDoubleClick set the click offset correctly + hold on g.ActiveId so Held state can be reported. Added ImGuiButtonFlags_NoHoldingActiveId flag to disable the later. --- imgui.cpp | 8 ++++++-- imgui_internal.h | 5 +++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 445bba37b..51f7f3f5e 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -5777,8 +5777,12 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool if (((flags & ImGuiButtonFlags_PressedOnClick) && g.IO.MouseClicked[0]) || ((flags & ImGuiButtonFlags_PressedOnDoubleClick) && g.IO.MouseDoubleClicked[0])) { pressed = true; - ClearActiveID(); + if (flags & ImGuiButtonFlags_NoHoldingActiveID) + ClearActiveID(); + else + SetActiveID(id, window); // Hold on ID FocusWindow(window); + g.ActiveIdClickOffset = g.IO.MousePos - bb.Min; } if ((flags & ImGuiButtonFlags_PressedOnRelease) && g.IO.MouseReleased[0]) { @@ -8851,7 +8855,7 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl } ImGuiButtonFlags button_flags = 0; - if (flags & ImGuiSelectableFlags_Menu) button_flags |= ImGuiButtonFlags_PressedOnClick; + if (flags & ImGuiSelectableFlags_Menu) button_flags |= ImGuiButtonFlags_PressedOnClick | ImGuiButtonFlags_NoHoldingActiveID; if (flags & ImGuiSelectableFlags_MenuItem) button_flags |= ImGuiButtonFlags_PressedOnRelease; if (flags & ImGuiSelectableFlags_Disabled) button_flags |= ImGuiButtonFlags_Disabled; if (flags & ImGuiSelectableFlags_AllowDoubleClick) button_flags |= ImGuiButtonFlags_PressedOnClickRelease | ImGuiButtonFlags_PressedOnDoubleClick; diff --git a/imgui_internal.h b/imgui_internal.h index 2d3b37391..7edcd9028 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -178,9 +178,10 @@ enum ImGuiButtonFlags_ ImGuiButtonFlags_FlattenChilds = 1 << 5, // allow interactions even if a child window is overlapping ImGuiButtonFlags_DontClosePopups = 1 << 6, // disable automatically closing parent popup on press // [UNUSED] ImGuiButtonFlags_Disabled = 1 << 7, // disable interactions - ImGuiButtonFlags_AlignTextBaseLine = 1 << 8, // vertically align button to match text baseline - ButtonEx() only + ImGuiButtonFlags_AlignTextBaseLine = 1 << 8, // vertically align button to match text baseline (ButtonEx() only) ImGuiButtonFlags_NoKeyModifiers = 1 << 9, // disable interaction if a key modifier is held - ImGuiButtonFlags_AllowOverlapMode = 1 << 10 // require previous frame HoveredId to either match id or be null before being usable + ImGuiButtonFlags_AllowOverlapMode = 1 << 10, // require previous frame HoveredId to either match id or be null before being usable + ImGuiButtonFlags_NoHoldingActiveID = 1 << 11 // don't set ActiveId while holding the mouse (ImGuiButtonFlags_PressedOnClick only) }; enum ImGuiSliderFlags_ From a03093b2d44f978d432fb81a85fd61e8cd9eb18d Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 18 Oct 2017 19:51:32 +0200 Subject: [PATCH 443/921] CollapsingHeader(bool*) variant: fixed for IsItemHovered() to work properly in the nav branch.Basically the close button now has to use ItemAdd() to be navable into, which overwrite the IsItemHovered data. (#600, #787) --- imgui.cpp | 3 +++ imgui_demo.cpp | 4 +++- imgui_internal.h | 11 +++++++++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 51f7f3f5e..d92817187 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -6273,8 +6273,11 @@ bool ImGui::CollapsingHeader(const char* label, bool* p_open, ImGuiTreeNodeFlags // Create a small overlapping close button // FIXME: We can evolve this into user accessible helpers to add extra buttons on title bars, headers, etc. ImGuiContext& g = *GImGui; float button_sz = g.FontSize * 0.5f; + ImGuiItemHoveredDataBackup last_item_backup; + last_item_backup.Backup(); if (CloseButton(window->GetID((void*)(intptr_t)(id+1)), ImVec2(ImMin(window->DC.LastItemRect.Max.x, window->ClipRect.Max.x) - g.Style.FramePadding.x - button_sz, window->DC.LastItemRect.Min.y + g.Style.FramePadding.y + button_sz), button_sz)) *p_open = false; + last_item_backup.Restore(); } return is_open; diff --git a/imgui_demo.cpp b/imgui_demo.cpp index c0f96d750..2a3ce928e 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -454,14 +454,16 @@ void ImGui::ShowTestWindow(bool* p_open) if (ImGui::TreeNode("Collapsing Headers")) { static bool closable_group = true; + ImGui::Checkbox("Enable extra group", &closable_group); if (ImGui::CollapsingHeader("Header")) { - ImGui::Checkbox("Enable extra group", &closable_group); + ImGui::Text("IsItemHovered: %d", IsItemHovered()); for (int i = 0; i < 5; i++) ImGui::Text("Some content %d", i); } if (ImGui::CollapsingHeader("Header with a close button", &closable_group)) { + ImGui::Text("IsItemHovered: %d", IsItemHovered()); for (int i = 0; i < 5; i++) ImGui::Text("More content %d", i); } diff --git a/imgui_internal.h b/imgui_internal.h index 7edcd9028..58aceec18 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -747,6 +747,17 @@ public: ImRect MenuBarRect() const { float y1 = Pos.y + TitleBarHeight(); return ImRect(Pos.x, y1, Pos.x + SizeFull.x, y1 + MenuBarHeight()); } }; +// Backup and restore just enough data to be able to use IsItemHovered() on item A after another B in the same window has overwritten the data. +struct ImGuiItemHoveredDataBackup +{ + ImGuiID LastItemId; + ImRect LastItemRect; + bool LastItemRectHoveredRect; + + void Backup() { ImGuiWindow* window = GImGui->CurrentWindow; LastItemId = window->DC.LastItemId; LastItemRect = window->DC.LastItemRect; LastItemRectHoveredRect = window->DC.LastItemRectHoveredRect; } + void Restore() { ImGuiWindow* window = GImGui->CurrentWindow; window->DC.LastItemId = LastItemId; window->DC.LastItemRect = LastItemRect; window->DC.LastItemRectHoveredRect = LastItemRectHoveredRect; } +}; + //----------------------------------------------------------------------------- // Internal API // No guarantee of forward compatibility here. From 370a48c10bbda08cbf0ba63ade49f64f843b8bd4 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 18 Oct 2017 23:46:16 +0200 Subject: [PATCH 444/921] Internals: RenderCollapseTriangle() -> RenderTriangle(), takes a ImGuiDir --- imgui.cpp | 48 ++++++++++++++++++++++++++++-------------------- imgui_internal.h | 2 +- 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index d92817187..34b577efc 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3058,31 +3058,39 @@ void ImGui::RenderFrameBorder(ImVec2 p_min, ImVec2 p_max, float rounding) } // Render a triangle to denote expanded/collapsed state -void ImGui::RenderCollapseTriangle(ImVec2 p_min, bool is_open, float scale) +void ImGui::RenderTriangle(ImVec2 p_min, ImGuiDir dir, float scale) { ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; const float h = g.FontSize * 1.00f; - const float r = h * 0.40f * scale; - ImVec2 center = p_min + ImVec2(h*0.50f, h*0.50f*scale); + float r = h * 0.40f * scale; + ImVec2 center = p_min + ImVec2(h * 0.50f, h * 0.50f * scale); ImVec2 a, b, c; - if (is_open) + switch (dir) { - center.y -= r*0.25f; - a = center + ImVec2(0,1)*r; - b = center + ImVec2(-0.866f,-0.5f)*r; - c = center + ImVec2(0.866f,-0.5f)*r; - } - else - { - a = center + ImVec2(1,0)*r; - b = center + ImVec2(-0.500f,0.866f)*r; - c = center + ImVec2(-0.500f,-0.866f)*r; + case ImGuiDir_Up: + r = -r; // ...fall through, no break! + case ImGuiDir_Down: + center.y -= r * 0.25f; + a = ImVec2(0,1) * r; + b = ImVec2(-0.866f,-0.5f) * r; + c = ImVec2(+0.866f,-0.5f) * r; + break; + case ImGuiDir_Left: + r = -r; // ...fall through, no break! + case ImGuiDir_Right: + a = ImVec2(1,0) * r; + b = ImVec2(-0.500f,+0.866f) * r; + c = ImVec2(-0.500f,-0.866f) * r; + break; + default: + IM_ASSERT(0); + break; } - window->DrawList->AddTriangleFilled(a, b, c, GetColorU32(ImGuiCol_Text)); + window->DrawList->AddTriangleFilled(center + a, center + b, center + c, GetColorU32(ImGuiCol_Text)); } void ImGui::RenderBullet(ImVec2 pos) @@ -4486,7 +4494,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // Collapse button if (!(flags & ImGuiWindowFlags_NoCollapse)) { - RenderCollapseTriangle(window->Pos + style.FramePadding, !window->Collapsed, 1.0f); + RenderTriangle(window->Pos + style.FramePadding, window->Collapsed ? ImGuiDir_Right : ImGuiDir_Down, 1.0f); } // Close button @@ -6211,7 +6219,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l { // Framed type RenderFrame(bb.Min, bb.Max, col, true, style.FrameRounding); - RenderCollapseTriangle(bb.Min + ImVec2(padding.x, text_base_offset_y), is_open, 1.0f); + RenderTriangle(bb.Min + ImVec2(padding.x, text_base_offset_y), is_open ? ImGuiDir_Down : ImGuiDir_Right, 1.0f); if (g.LogEnabled) { // NB: '##' is normally used to hide text (as a library-wide feature), so we need to specify the text range to make sure the ## aren't stripped out here. @@ -6235,7 +6243,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l if (flags & ImGuiTreeNodeFlags_Bullet) RenderBullet(bb.Min + ImVec2(text_offset_x * 0.5f, g.FontSize*0.50f + text_base_offset_y)); else if (!(flags & ImGuiTreeNodeFlags_Leaf)) - RenderCollapseTriangle(bb.Min + ImVec2(padding.x, g.FontSize*0.15f + text_base_offset_y), is_open, 0.70f); + RenderTriangle(bb.Min + ImVec2(padding.x, g.FontSize*0.15f + text_base_offset_y), is_open ? ImGuiDir_Down : ImGuiDir_Right, 0.70f); if (g.LogEnabled) LogRenderedText(&text_pos, ">"); RenderText(text_pos, label, label_end, false); @@ -8714,7 +8722,7 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImVec2 popu const ImRect value_bb(frame_bb.Min, frame_bb.Max - ImVec2(arrow_size, 0.0f)); RenderFrame(frame_bb.Min, frame_bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding); RenderFrame(ImVec2(frame_bb.Max.x-arrow_size, frame_bb.Min.y), frame_bb.Max, GetColorU32(popup_open || hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button), true, style.FrameRounding); // FIXME-ROUNDING - RenderCollapseTriangle(ImVec2(frame_bb.Max.x - arrow_size + style.FramePadding.y, frame_bb.Min.y + style.FramePadding.y), true); + RenderTriangle(ImVec2(frame_bb.Max.x - arrow_size + style.FramePadding.y, frame_bb.Min.y + style.FramePadding.y), ImGuiDir_Down); if (preview_value != NULL) RenderTextClipped(frame_bb.Min + style.FramePadding, value_bb.Max, preview_value, NULL, NULL, ImVec2(0.0f,0.0f)); @@ -9134,7 +9142,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled) float extra_w = ImMax(0.0f, GetContentRegionAvail().x - w); pressed = Selectable(label, menu_is_open, ImGuiSelectableFlags_Menu | ImGuiSelectableFlags_DontClosePopups | ImGuiSelectableFlags_DrawFillAvailWidth | (!enabled ? ImGuiSelectableFlags_Disabled : 0), ImVec2(w, 0.0f)); if (!enabled) PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]); - RenderCollapseTriangle(pos + ImVec2(window->MenuColumns.Pos[2] + extra_w + g.FontSize * 0.20f, 0.0f), false); + RenderTriangle(pos + ImVec2(window->MenuColumns.Pos[2] + extra_w + g.FontSize * 0.20f, 0.0f), ImGuiDir_Right); if (!enabled) PopStyleColor(); } diff --git a/imgui_internal.h b/imgui_internal.h index 58aceec18..4e34b8b87 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -823,7 +823,7 @@ namespace ImGui IMGUI_API void RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool border = true, float rounding = 0.0f); IMGUI_API void RenderFrameBorder(ImVec2 p_min, ImVec2 p_max, float rounding = 0.0f); IMGUI_API void RenderColorRectWithAlphaCheckerboard(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, float grid_step, ImVec2 grid_off, float rounding = 0.0f, int rounding_corners_flags = ~0); - IMGUI_API void RenderCollapseTriangle(ImVec2 pos, bool is_open, float scale = 1.0f); + IMGUI_API void RenderTriangle(ImVec2 pos, ImGuiDir dir, float scale = 1.0f); IMGUI_API void RenderBullet(ImVec2 pos); IMGUI_API void RenderCheckMark(ImVec2 pos, ImU32 col, float sz); IMGUI_API void RenderRectFilledRangeH(ImDrawList* draw_list, const ImRect& rect, ImU32 col, float x_start_norm, float x_end_norm, float rounding); From d3c2e904d8e3b7310fb4e2a8a3984caf3f94171d Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 19 Oct 2017 19:29:59 +0200 Subject: [PATCH 445/921] Internals: Added ImLinearSweep() helper. --- TODO.txt | 1 + imgui_internal.h | 1 + 2 files changed, 2 insertions(+) diff --git a/TODO.txt b/TODO.txt index 04e795fa0..f1976f2fb 100644 --- a/TODO.txt +++ b/TODO.txt @@ -236,6 +236,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - misc: provide a way to compile out the entire implementation while providing a dummy API (e.g. #define IMGUI_DUMMY_IMPL) - misc: provide HoveredTime and ActivatedTime to ease the creation of animations. - misc: fix for compilation settings where stdcall isn't the default (e.g. vectorcall) (#1230) + - misc: detect user not calling Render() and suggest to call EndFrame()? - remote: make a system like RemoteImGui first-class citizen/project (#75) - demo: add vertical separator demo diff --git a/imgui_internal.h b/imgui_internal.h index 4e34b8b87..c9d522e67 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -154,6 +154,7 @@ static inline float ImFloor(float f) static inline ImVec2 ImFloor(const ImVec2& v) { return ImVec2((float)(int)v.x, (float)(int)v.y); } static inline float ImDot(const ImVec2& a, const ImVec2& b) { return a.x * b.x + a.y * b.y; } static inline ImVec2 ImRotate(const ImVec2& v, float cos_a, float sin_a) { return ImVec2(v.x * cos_a - v.y * sin_a, v.x * sin_a + v.y * cos_a); } +static inline float ImLinearSweep(float current, float target, float speed) { if (current < target) return ImMin(current + speed, target); if (current > target) return ImMax(current - speed, target); return current; } // We call C++ constructor on own allocated memory via the placement "new(ptr) Type()" syntax. // Defining a custom placement new() with a dummy parameter allows us to bypass including which on some platforms complains when user has disabled exceptions. From 22977ffedb0b6bc701521fd11d0c610d3e991bf2 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 19 Oct 2017 19:30:46 +0200 Subject: [PATCH 446/921] Documentation: Extra comments + tweaks to make usage of long-line more bearable. --- imgui.cpp | 94 ++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 58 insertions(+), 36 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 34b577efc..0b5e03856 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -48,7 +48,8 @@ - Minimize setup and maintenance - Minimize state storage on user side - Portable, minimize dependencies, run on target (consoles, phones, etc.) - - Efficient runtime and memory consumption (NB- we do allocate when "growing" content - creating a window / opening a tree node for the first time, etc. - but a typical frame won't allocate anything) + - Efficient runtime and memory consumption (NB- we do allocate when "growing" content e.g. creating a window, opening a tree node + for the first time, etc. but a typical frame won't allocate anything) Designed for developers and content-creators, not the typical end-user! Some of the weaknesses includes: - Doesn't look fancy, doesn't animate @@ -85,7 +86,8 @@ READ FIRST - Read the FAQ below this section! - - Your code creates the UI, if your code doesn't run the UI is gone! == very dynamic UI, no construction/destructions steps, less data retention on your side, no state duplication, less sync, less bugs. + - Your code creates the UI, if your code doesn't run the UI is gone! == very dynamic UI, no construction/destructions steps, less data retention + on your side, no state duplication, less sync, less bugs. - Call and read ImGui::ShowTestWindow() for demo code demonstrating most features. - You can learn about immediate-mode gui principles at http://www.johno.se/book/imgui.html or watch http://mollyrocket.com/861 @@ -100,25 +102,28 @@ GETTING STARTED WITH INTEGRATING DEAR IMGUI IN YOUR CODE/ENGINE - - Add the Dear ImGui source files to your projects, using your preferred build system. It is recommended you build the .cpp files as part of your project and not as a library. + - Add the Dear ImGui source files to your projects, using your preferred build system. + It is recommended you build the .cpp files as part of your project and not as a library. - You can later customize the imconfig.h file to tweak some compilation time behavior, such as integrating imgui types with your own maths types. - - See examples/ folder for standalone sample applications. To understand the integration process, you can read examples/opengl2_example/ because it is short, - then switch to the one more appropriate to your use case. + - See examples/ folder for standalone sample applications. To understand the integration process, you can read examples/opengl2_example/ because + it is short, then switch to the one more appropriate to your use case. - You may be able to grab and copy a ready made imgui_impl_*** file from the examples/. - When using Dear ImGui, your programming IDE is your friend: follow the declaration of variables, functions and types to find comments about them. - - Init: retrieve the ImGuiIO structure with ImGui::GetIO() and fill the fields marked 'Settings': at minimum you need to set io.DisplaySize (application resolution). - Later on you will fill your keyboard mapping, clipboard handlers, and other advanced features but for a basic integration you don't need to worry about it all. + - Init: retrieve the ImGuiIO structure with ImGui::GetIO() and fill the fields marked 'Settings': at minimum you need to set io.DisplaySize + (application resolution). Later on you will fill your keyboard mapping, clipboard handlers, and other advanced features but for a basic + integration you don't need to worry about it all. - Init: call io.Fonts->GetTexDataAsRGBA32(...), it will build the font atlas texture, then load the texture pixels into graphics memory. - Every frame: - In your main loop as early a possible, fill the IO fields marked 'Input' (e.g. mouse position, buttons, keyboard info, etc.) - Call ImGui::NewFrame() to begin the frame - You can use any ImGui function you want between NewFrame() and Render() - Call ImGui::Render() as late as you can to end the frame and finalize render data. it will call your io.RenderDrawListFn handler. - (if you don't need to render, you still need to call Render() and ignore the callback, or call EndFrame() instead. if you call neither some aspects of windows focusing/moving will appear broken.) + (Even if you don't render, call Render() and ignore the callback, or call EndFrame() instead. Otherwhise some features will break) - All rendering information are stored into command-lists until ImGui::Render() is called. - Dear ImGui never touches or knows about your GPU state. the only function that knows about GPU is the RenderDrawListFn handler that you provide. - - Effectively it means you can create widgets at any time in your code, regardless of considerations of being in "update" vs "render" phases of your own application. + - Effectively it means you can create widgets at any time in your code, regardless of considerations of being in "update" vs "render" phases + of your own application. - Refer to the examples applications in the examples/ folder for instruction on how to setup your code. - A minimal application skeleton may be: @@ -126,7 +131,7 @@ ImGuiIO& io = ImGui::GetIO(); io.DisplaySize.x = 1920.0f; io.DisplaySize.y = 1280.0f; - io.RenderDrawListsFn = MyRenderFunction; // Setup a render function, or set to NULL and call GetDrawData() after Render() to access the render data. + io.RenderDrawListsFn = MyRenderFunction; // Setup a render function, or set to NULL and call GetDrawData() after Render() to access render data. // TODO: Fill others settings of the io structure later. // Load texture atlas (there is a default font so you don't need to care about choosing a font yet) @@ -180,9 +185,16 @@ } else { - // Render 'pcmd->ElemCount/3' texture triangles + // The texture for the draw call is specified by pcmd->TextureId. + // The vast majority of draw calls with use the imgui texture atlas, which value you have set yourself during initialization. MyEngineBindTexture(pcmd->TextureId); + + // We are using scissoring to clip some objects. All low-level graphics API supports it. + // If your engine doesn't support scissoring yet, you will get some small glitches (some elements outside their bounds) which you can fix later. MyEngineScissor((int)pcmd->ClipRect.x, (int)pcmd->ClipRect.y, (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); + + // Render 'pcmd->ElemCount/3' indexed triangles. + // By default the indices ImDrawIdx are 16-bits, you can change them to 32-bits if your engine doesn't support 16-bits indices. MyEngineDrawIndexedTriangles(pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer, vtx_buffer); } idx_buffer += pcmd->ElemCount; @@ -360,21 +372,22 @@ Also make sure your orthographic projection matrix and io.DisplaySize matches your actual framebuffer dimension. Q: I integrated Dear ImGui in my engine and some elements are clipping or disappearing when I move windows around.. - A: Most likely you are mishandling the clipping rectangles in your render function. Rectangles provided by ImGui are defined as (x1=left,y1=top,x2=right,y2=bottom) and NOT as (x1,y1,width,height). + A: You are probably mishandling the clipping rectangles in your render function. + Rectangles provided by ImGui are defined as (x1=left,y1=top,x2=right,y2=bottom) and NOT as (x1,y1,width,height). Q: Can I have multiple widgets with the same label? Can I have widget without a label? A: Yes. A primer on the use of labels/IDs in Dear ImGui.. - Elements that are not clickable, such as Text() items don't need an ID. - - Interactive widgets require state to be carried over multiple frames (most typically Dear ImGui often needs to remember what is the "active" widget). - to do so they need a unique ID. unique ID are typically derived from a string label, an integer index or a pointer. + - Interactive widgets require state to be carried over multiple frames (most typically Dear ImGui often needs to remember what is + the "active" widget). to do so they need a unique ID. unique ID are typically derived from a string label, an integer index or a pointer. Button("OK"); // Label = "OK", ID = hash of "OK" Button("Cancel"); // Label = "Cancel", ID = hash of "Cancel" - - ID are uniquely scoped within windows, tree nodes, etc. so no conflict can happen if you have two buttons called "OK" in two different windows - or in two different locations of a tree. + - ID are uniquely scoped within windows, tree nodes, etc. so no conflict can happen if you have two buttons called "OK" + in two different windows or in two different locations of a tree. - If you have a same ID twice in the same location, you'll have a conflict: @@ -383,8 +396,8 @@ Fear not! this is easy to solve and there are many ways to solve it! - - When passing a label you can optionally specify extra unique ID information within string itself. This helps solving the simpler collision cases. - use "##" to pass a complement to the ID that won't be visible to the end-user: + - When passing a label you can optionally specify extra unique ID information within string itself. + This helps solving the simpler collision cases. Use "##" to pass a complement to the ID that won't be visible to the end-user: Button("Play"); // Label = "Play", ID = hash of "Play" Button("Play##foo1"); // Label = "Play", ID = hash of "Play##foo1" (different from above) @@ -452,18 +465,22 @@ - When working with trees, ID are used to preserve the open/close state of each tree node. Depending on your use cases you may want to use strings, indices or pointers as ID. - 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! + e.g. when displaying a single object that may change over time (dynamic 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 can I tell when Dear ImGui wants my mouse/keyboard inputs VS when I can pass them to my application? A: You can read the 'io.WantCaptureMouse'/'io.WantCaptureKeyboard'/'ioWantTextInput' flags from the ImGuiIO structure. - When 'io.WantCaptureMouse' or 'io.WantCaptureKeyboard' flags are set you may want to discard/hide the inputs from the rest of your application. - - When 'io.WantTextInput' is set to may want to notify your OS to popup an on-screen keyboard, if available (e.g. on a mobile phone, or console without a keyboard). - Preferably read the flags after calling ImGui::NewFrame() to avoid them lagging by one frame. But reading those flags before calling NewFrame() is also generally ok, - as the bool toggles fairly rarely and you don't generally expect to interact with either Dear ImGui or your application during the same frame when that transition occurs. - Dear ImGui is tracking dragging and widget activity that may occur outside the boundary of a window, so 'io.WantCaptureMouse' is more accurate and correct than checking if a window is hovered. - (Advanced note: text input releases focus on Return 'KeyDown', so the following Return 'KeyUp' event that your application receive will typically have 'io.WantCaptureKeyboard=false'. - Depending on your application logic it may or not be inconvenient. You might want to track which key-downs were for Dear ImGui (e.g. with an array of bool) and filter out the corresponding key-ups.) + - When 'io.WantTextInput' is set to may want to notify your OS to popup an on-screen keyboard, if available (e.g. on a mobile phone, or console OS). + Preferably read the flags after calling ImGui::NewFrame() to avoid them lagging by one frame. But reading those flags before calling NewFrame() is + also generally ok, as the bool toggles fairly rarely and you don't generally expect to interact with either Dear ImGui or your application during + the same frame when that transition occurs. Dear ImGui is tracking dragging and widget activity that may occur outside the boundary of a window, + so 'io.WantCaptureMouse' is more accurate and correct than checking if a window is hovered. + (Advanced note: text input releases focus on Return 'KeyDown', so the following Return 'KeyUp' event that your application receive will typically + have 'io.WantCaptureKeyboard=false'. Depending on your application logic it may or not be inconvenient. You might want to track which key-downs + were for Dear ImGui, e.g. with an array of bool, and filter out the corresponding key-ups.) Q: How can I load a different font than the default? (default is an embedded version of ProggyClean.ttf, rendered at size 13) A: Use the font atlas to load the TTF/OTF file you want: @@ -473,8 +490,8 @@ io.Fonts->GetTexDataAsRGBA32() or GetTexDataAsAlpha8() Q: How can I easily use icons in my application? - A: The most convenient and practical way is to merge an icon font such as FontAwesome inside you main font. Then you can refer to icons within your strings. - Read 'How can I load multiple fonts?' and the file 'extra_fonts/README.txt' for instructions. + A: The most convenient and practical way is to merge an icon font such as FontAwesome inside you main font. Then you can refer to icons within your + strings. Read 'How can I load multiple fonts?' and the file 'extra_fonts/README.txt' for instructions and useful header files. Q: How can I load multiple fonts? A: Use the font atlas to pack them into a single texture: @@ -524,19 +541,24 @@ Otherwise you can convert yourself to UTF-8 or load text data from file already saved as UTF-8. Text input: it is up to your application to pass the right character code to io.AddInputCharacter(). The applications in examples/ are doing that. - For languages using IME, on Windows you can copy the Hwnd of your application to io.ImeWindowHandle. The default implementation of io.ImeSetInputScreenPosFn() on Windows will set your IME position correctly. + For languages using IME, on Windows you can copy the Hwnd of your application to io.ImeWindowHandle. + The default implementation of io.ImeSetInputScreenPosFn() on Windows will set your IME position correctly. Q: How can I preserve my Dear ImGui context across reloading a DLL? (loss of the global/static variables) - A: Create your own context 'ctx = CreateContext()' + 'SetCurrentContext(ctx)' and your own font atlas 'ctx->GetIO().Fonts = new ImFontAtlas()' so you don't rely on the default globals. + A: Create your own context 'ctx = CreateContext()' + 'SetCurrentContext(ctx)' and your own font atlas 'ctx->GetIO().Fonts = new ImFontAtlas()' + so you don't rely on the default globals. Q: How can I use the drawing facilities without an ImGui window? (using ImDrawList API) - A: The easiest way is to create a dummy window. Call Begin() with NoTitleBar|NoResize|NoMove|NoScrollbar|NoSavedSettings|NoInputs flag, zero background alpha, - then retrieve the ImDrawList* via GetWindowDrawList() and draw to it in any way you like. - You can also perfectly create a standalone ImDrawList instance _but_ you need ImGui to be initialized because ImDrawList pulls from ImGui data to retrieve the coordinates of the white pixel. + A: The easiest way is to create a dummy window. Call Begin() with NoTitleBar|NoResize|NoMove|NoScrollbar|NoSavedSettings|NoInputs flag, + zero background alpha, then retrieve the ImDrawList* via GetWindowDrawList() and draw to it in any way you like. + You can also perfectly create a standalone ImDrawList instance _but_ you need ImGui to be initialized because ImDrawList pulls from ImGui + data to retrieve the coordinates of the white pixel. - - tip: the construct 'IMGUI_ONCE_UPON_A_FRAME { ... }' will run the block of code only once a frame. You can use it to quickly add custom UI in the middle of a deep nested inner loop in your code. - - tip: you can create widgets without a Begin()/End() block, they will go in an implicit window called "Debug" - - tip: you can call Begin() multiple times with the same name during the same frame, it will keep appending to the same window. this is also useful to set yourself in the context of another window (to get/set other settings) + - tip: you can call Begin() multiple times with the same name during the same frame, it will keep appending to the same window. + this is also useful to set yourself in the context of another window (to get/set other settings) + - tip: you can create widgets without a Begin()/End() block, they will go in an implicit window called "Debug". + - tip: the ImGuiOnceUponAFrame helper will allow run the block of code only once a frame. You can use it to quickly add custom UI in the middle + of a deep nested inner loop in your code. - tip: you can call Render() multiple times (e.g for VR renders). - tip: call and read the ShowTestWindow() code in imgui_demo.cpp for more example of how to use ImGui! From 5b699517d43b6998fa6f432edb9d991497bad690 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 19 Oct 2017 19:33:03 +0200 Subject: [PATCH 447/921] Internals: PaintVerts** renamed to ShadeVerts**, moved to imgui_draw.cpp and exposed in imgui_internal.h (+1 squashed commits) --- imgui.cpp | 17 +---------------- imgui_draw.cpp | 37 +++++++++++++++++++++++++++++++++++++ imgui_internal.h | 4 ++++ 3 files changed, 42 insertions(+), 16 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 0b5e03856..4f14032c9 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9684,21 +9684,6 @@ static void RenderArrowsForVerticalBar(ImDrawList* draw_list, ImVec2 pos, ImVec2 RenderArrow(draw_list, ImVec2(pos.x + bar_w - half_sz.x, pos.y), half_sz, ImGuiDir_Left, IM_COL32_WHITE); } -static void PaintVertsLinearGradientKeepAlpha(ImDrawVert* vert_start, ImDrawVert* vert_end, ImVec2 gradient_p0, ImVec2 gradient_p1, ImU32 col0, ImU32 col1) -{ - ImVec2 gradient_extent = gradient_p1 - gradient_p0; - float gradient_inv_length2 = 1.0f / ImLengthSqr(gradient_extent); - for (ImDrawVert* vert = vert_start; vert < vert_end; vert++) - { - float d = ImDot(vert->pos - gradient_p0, gradient_extent); - float t = ImClamp(d * gradient_inv_length2, 0.0f, 1.0f); - int r = ImLerp((int)(col0 >> IM_COL32_R_SHIFT) & 0xFF, (int)(col1 >> IM_COL32_R_SHIFT) & 0xFF, t); - int g = ImLerp((int)(col0 >> IM_COL32_G_SHIFT) & 0xFF, (int)(col1 >> IM_COL32_G_SHIFT) & 0xFF, t); - int b = ImLerp((int)(col0 >> IM_COL32_B_SHIFT) & 0xFF, (int)(col1 >> IM_COL32_B_SHIFT) & 0xFF, t); - vert->col = (r << IM_COL32_R_SHIFT) | (g << IM_COL32_G_SHIFT) | (b << IM_COL32_B_SHIFT) | (vert->col & IM_COL32_A_MASK); - } -} - // ColorPicker // Note: only access 3 floats if ImGuiColorEditFlags_NoAlpha flag is set. // FIXME: we adjust the big color square height based on item width, which may cause a flickering feedback loop (if automatic height makes a vertical scrollbar appears, affecting automatic width..) @@ -9916,7 +9901,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl // Paint colors over existing vertices ImVec2 gradient_p0(wheel_center.x + cosf(a0) * wheel_r_inner, wheel_center.y + sinf(a0) * wheel_r_inner); ImVec2 gradient_p1(wheel_center.x + cosf(a1) * wheel_r_inner, wheel_center.y + sinf(a1) * wheel_r_inner); - PaintVertsLinearGradientKeepAlpha(draw_list->_VtxWritePtr - (draw_list->_VtxCurrentIdx - vert_start_idx), draw_list->_VtxWritePtr, gradient_p0, gradient_p1, hue_colors[n], hue_colors[n+1]); + ShadeVertsLinearColorGradientKeepAlpha(draw_list->_VtxWritePtr - (draw_list->_VtxCurrentIdx - vert_start_idx), draw_list->_VtxWritePtr, gradient_p0, gradient_p1, hue_colors[n], hue_colors[n+1]); } // Render Cursor + preview on Hue Wheel diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 9da0ad1c2..384da73e9 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1034,6 +1034,43 @@ void ImDrawData::ScaleClipRects(const ImVec2& scale) } } +//----------------------------------------------------------------------------- +// Shade functions +//----------------------------------------------------------------------------- + +// Generic linear color gradient, write to RGB fields, leave A untouched. +void ImGui::ShadeVertsLinearColorGradientKeepAlpha(ImDrawVert* vert_start, ImDrawVert* vert_end, ImVec2 gradient_p0, ImVec2 gradient_p1, ImU32 col0, ImU32 col1) +{ + ImVec2 gradient_extent = gradient_p1 - gradient_p0; + float gradient_inv_length2 = 1.0f / ImLengthSqr(gradient_extent); + for (ImDrawVert* vert = vert_start; vert < vert_end; vert++) + { + float d = ImDot(vert->pos - gradient_p0, gradient_extent); + float t = ImClamp(d * gradient_inv_length2, 0.0f, 1.0f); + int r = ImLerp((int)(col0 >> IM_COL32_R_SHIFT) & 0xFF, (int)(col1 >> IM_COL32_R_SHIFT) & 0xFF, t); + int g = ImLerp((int)(col0 >> IM_COL32_G_SHIFT) & 0xFF, (int)(col1 >> IM_COL32_G_SHIFT) & 0xFF, t); + int b = ImLerp((int)(col0 >> IM_COL32_B_SHIFT) & 0xFF, (int)(col1 >> IM_COL32_B_SHIFT) & 0xFF, t); + vert->col = (r << IM_COL32_R_SHIFT) | (g << IM_COL32_G_SHIFT) | (b << IM_COL32_B_SHIFT) | (vert->col & IM_COL32_A_MASK); + } +} + +// Scan and shade backward from the end of given vertices. Assume vertices are text only (= vert_start..vert_end going left to right) so we can break as soon as we are out the gradient bounds. +void ImGui::ShadeVertsLinearAlphaGradientForLeftToRightText(ImDrawVert* vert_start, ImDrawVert* vert_end, float gradient_p0_x, float gradient_p1_x) +{ + float gradient_extent_x = gradient_p1_x - gradient_p0_x; + float gradient_inv_length2 = 1.0f / (gradient_extent_x * gradient_extent_x); + int full_alpha_count = 0; + for (ImDrawVert* vert = vert_end - 1; vert >= vert_start; vert--) + { + float d = (vert->pos.x - gradient_p0_x) * (gradient_extent_x); + float alpha_mul = 1.0f - ImClamp(d * gradient_inv_length2, 0.0f, 1.0f); + if (alpha_mul >= 1.0f && ++full_alpha_count > 2) + return; // Early out + int a = (int)(((vert->col >> IM_COL32_A_SHIFT) & 0xFF) * alpha_mul); + vert->col = (vert->col & ~IM_COL32_A_MASK) | (a << IM_COL32_A_SHIFT); + } +} + //----------------------------------------------------------------------------- // ImFontConfig //----------------------------------------------------------------------------- diff --git a/imgui_internal.h b/imgui_internal.h index c9d522e67..ec6d4e518 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -860,6 +860,10 @@ namespace ImGui IMGUI_API int ParseFormatPrecision(const char* fmt, int default_value); IMGUI_API float RoundScalar(float value, int decimal_precision); + // Shade functions + IMGUI_API void ShadeVertsLinearColorGradientKeepAlpha(ImDrawVert* vert_start, ImDrawVert* vert_end, ImVec2 gradient_p0, ImVec2 gradient_p1, ImU32 col0, ImU32 col1); + IMGUI_API void ShadeVertsLinearAlphaGradientForLeftToRightText(ImDrawVert* vert_start, ImDrawVert* vert_end, float gradient_p0_x, float gradient_p1_x); + } // namespace ImGui // ImFontAtlas internals From e384078d7aad79607f32a5db87ebc004cc6b5c56 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 19 Oct 2017 22:49:36 +0200 Subject: [PATCH 448/921] IO: reordering some supposedly private fields. --- imgui.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.h b/imgui.h index 17c39f5ea..a6b1116c3 100644 --- a/imgui.h +++ b/imgui.h @@ -871,9 +871,9 @@ struct ImGuiIO //------------------------------------------------------------------ ImVec2 MousePosPrev; // Previous mouse position temporary storage (nb: not for public use, set to MousePos in NewFrame()) - bool MouseClicked[5]; // Mouse button went from !Down to Down ImVec2 MouseClickedPos[5]; // Position at time of clicking float MouseClickedTime[5]; // Time of last click (used to figure out double-click) + bool MouseClicked[5]; // Mouse button went from !Down to Down bool MouseDoubleClicked[5]; // Has mouse button been double-clicked? bool MouseReleased[5]; // Mouse button went from Down to !Down bool MouseDownOwned[5]; // Track if button was clicked inside a window. We don't request mouse capture from the application if click started outside ImGui bounds. From 2a32a2e66297a2a3c0bd73f87c0aa991d4c15707 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 20 Oct 2017 12:38:48 +0200 Subject: [PATCH 449/921] Demos: Tweaks of popups/context/menus section. --- imgui_demo.cpp | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 2a3ce928e..7fafd9ef2 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1383,22 +1383,6 @@ void ImGui::ShowTestWindow(bool* p_open) ImGui::EndPopup(); } - ImGui::Spacing(); - ImGui::TextWrapped("Below we are testing adding menu items to a regular window. It's rather unusual but should work!"); - ImGui::Separator(); - // NB: As a quirk in this very specific example, we want to differentiate the parent of this menu from the parent of the various popup menus above. - // To do so we are encloding the items in a PushID()/PopID() block to make them two different menusets. If we don't, opening any popup above and hovering our menu here - // would open it. This is because once a menu is active, we allow to switch to a sibling menu by just hovering on it, which is the desired behavior for regular menus. - ImGui::PushID("foo"); - ImGui::MenuItem("Menu item", "CTRL+M"); - if (ImGui::BeginMenu("Menu inside a regular window")) - { - ShowExampleMenuFile(); - ImGui::EndMenu(); - } - ImGui::PopID(); - ImGui::Separator(); - ImGui::TreePop(); } @@ -1415,7 +1399,9 @@ void ImGui::ShowTestWindow(bool* p_open) { if (ImGui::Selectable("Set to zero")) value = 0.0f; if (ImGui::Selectable("Set to PI")) value = 3.1415f; - ImGui::DragFloat("Value", &value, 0.1f, 0.0f, 0.0f); + ImGui::PushItemWidth(-1); + ImGui::DragFloat("##Value", &value, 0.1f, 0.0f, 0.0f); + ImGui::PopItemWidth(); ImGui::EndPopup(); } @@ -1485,6 +1471,25 @@ void ImGui::ShowTestWindow(bool* p_open) ImGui::TreePop(); } + + if (ImGui::TreeNode("Menus inside a regular window")) + { + ImGui::TextWrapped("Below we are testing adding menu items to a regular window. It's rather unusual but should work!"); + ImGui::Separator(); + // NB: As a quirk in this very specific example, we want to differentiate the parent of this menu from the parent of the various popup menus above. + // To do so we are encloding the items in a PushID()/PopID() block to make them two different menusets. If we don't, opening any popup above and hovering our menu here + // would open it. This is because once a menu is active, we allow to switch to a sibling menu by just hovering on it, which is the desired behavior for regular menus. + ImGui::PushID("foo"); + ImGui::MenuItem("Menu item", "CTRL+M"); + if (ImGui::BeginMenu("Menu inside a regular window")) + { + ShowExampleMenuFile(); + ImGui::EndMenu(); + } + ImGui::PopID(); + ImGui::Separator(); + ImGui::TreePop(); + } } if (ImGui::CollapsingHeader("Columns")) From 5f7299e15a28fbadc693bdc90184e23c367b488e Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 20 Oct 2017 13:07:57 +0200 Subject: [PATCH 450/921] Refactor EndFrame() code that process focusing window with left mouse button. This commit should be no-op. --- imgui.cpp | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 4f14032c9..a7de91f3b 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2771,25 +2771,28 @@ void ImGui::EndFrame() g.CurrentWindow->Active = false; ImGui::End(); - // Click to focus window and start moving (after we're done with all our widgets) - if (g.ActiveId == 0 && g.HoveredId == 0 && g.IO.MouseClicked[0]) + if (g.ActiveId == 0 && g.HoveredId == 0) { - if (!(g.NavWindow && !g.NavWindow->WasActive && g.NavWindow->Active)) // Unless we just made a popup appear + if (!g.NavWindow || g.NavWindow->WasActive || !g.NavWindow->Active) // Unless we just made a popup appear { - if (g.HoveredRootWindow != NULL) + // Click to focus window and start moving (after we're done with all our widgets) + if (g.IO.MouseClicked[0]) { - FocusWindow(g.HoveredWindow); - if (!(g.HoveredWindow->Flags & ImGuiWindowFlags_NoMove)) + if (g.HoveredRootWindow != NULL) { - g.MovedWindow = g.HoveredWindow; - g.MovedWindowMoveId = g.HoveredWindow->MoveId; - SetActiveID(g.MovedWindowMoveId, g.HoveredRootWindow); + FocusWindow(g.HoveredWindow); + if (!(g.HoveredWindow->Flags & ImGuiWindowFlags_NoMove)) + { + g.MovedWindow = g.HoveredWindow; + g.MovedWindowMoveId = g.HoveredWindow->MoveId; + SetActiveID(g.MovedWindowMoveId, g.HoveredRootWindow); + } + } + else if (g.NavWindow != NULL && GetFrontMostModalRootWindow() == NULL) + { + // Clicking on void disable focus + FocusWindow(NULL); } - } - else if (g.NavWindow != NULL && GetFrontMostModalRootWindow() == NULL) - { - // Clicking on void disable focus - FocusWindow(NULL); } } } From 853018dd4dff37ffeb32f89980a52c300e84dc35 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 20 Oct 2017 13:21:42 +0200 Subject: [PATCH 451/921] Popups: Fixed a bug introduced in 1a35766356032a77bed1e9f16bdfcd60b93784cf which made the BeginPopupContextXXX functions create popups without border. (nb: all that border mess is going away in styling clean up) --- imgui.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index a7de91f3b..b05ad6c7b 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3750,7 +3750,7 @@ bool ImGui::BeginPopupContextItem(const char* str_id, int mouse_button) IM_ASSERT(id != 0); // However, you cannot pass a NULL str_id if the last item has no identifier (e.g. a Text() item) if (IsItemHovered() && IsMouseClicked(mouse_button)) OpenPopupEx(id, false); - return BeginPopupEx(id, 0); + return BeginPopupEx(id, ImGuiWindowFlags_ShowBorders | ImGuiWindowFlags_AlwaysAutoResize); } bool ImGui::BeginPopupContextWindow(const char* str_id, int mouse_button, bool also_over_items) @@ -3761,7 +3761,7 @@ bool ImGui::BeginPopupContextWindow(const char* str_id, int mouse_button, bool a if (IsWindowRectHovered() && IsMouseClicked(mouse_button)) if (also_over_items || !IsAnyItemHovered()) OpenPopupEx(id, true); - return BeginPopupEx(id, 0); + return BeginPopupEx(id, ImGuiWindowFlags_ShowBorders | ImGuiWindowFlags_AlwaysAutoResize); } bool ImGui::BeginPopupContextVoid(const char* str_id, int mouse_button) @@ -3771,7 +3771,7 @@ bool ImGui::BeginPopupContextVoid(const char* str_id, int mouse_button) ImGuiID id = GImGui->CurrentWindow->GetID(str_id); if (!IsAnyWindowHovered() && IsMouseClicked(mouse_button)) OpenPopupEx(id, true); - return BeginPopupEx(id, 0); + return BeginPopupEx(id, ImGuiWindowFlags_ShowBorders | ImGuiWindowFlags_AlwaysAutoResize); } static bool BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, bool border, ImGuiWindowFlags extra_flags) From 87ae40843c0b5c526edd9cdb62b072cd0bcc49ff Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 20 Oct 2017 13:26:39 +0200 Subject: [PATCH 452/921] Popups: popups can be closed with a right-click anywhere, without altering focus under the popup.(~#439) --- imgui.cpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index b05ad6c7b..933859893 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -643,7 +643,7 @@ static void MarkIniSettingsDirty(ImGuiWindow* window); static ImRect GetVisibleRect(); -static void CloseInactivePopups(); +static void CloseInactivePopups(ImGuiWindow* ref_window); static void ClosePopupToLevel(int remaining); static ImGuiWindow* GetFrontMostModalRootWindow(); static ImVec2 FindBestPopupWindowPos(const ImVec2& base_pos, const ImVec2& size, int* last_dir, const ImRect& rect_to_avoid); @@ -2441,7 +2441,7 @@ void ImGui::NewFrame() // But in order to allow the user to call NewFrame() multiple times without calling Render(), we are doing an explicit clear. g.CurrentWindowStack.resize(0); g.CurrentPopupStack.resize(0); - CloseInactivePopups(); + CloseInactivePopups(g.NavWindow); // Create implicit window - we will only render it if the user has added something to it. // We don't use "Debug" to avoid colliding with user trying to create a "Debug" window with custom flags. @@ -2773,7 +2773,7 @@ void ImGui::EndFrame() if (g.ActiveId == 0 && g.HoveredId == 0) { - if (!g.NavWindow || g.NavWindow->WasActive || !g.NavWindow->Active) // Unless we just made a popup appear + if (!g.NavWindow || !g.NavWindow->Appearing) // Unless we just made a window/popup appear { // Click to focus window and start moving (after we're done with all our widgets) if (g.IO.MouseClicked[0]) @@ -2794,6 +2794,13 @@ void ImGui::EndFrame() FocusWindow(NULL); } } + + // With right mouse button we close popups without changing focus + // (The left mouse button path calls FocusWindow which will lead NewFrame->CloseInactivePopups to trigger) + if (g.IO.MouseClicked[1]) + { + CloseInactivePopups(g.HoveredWindow); + } } } @@ -3567,7 +3574,7 @@ void ImGui::OpenPopup(const char* str_id) OpenPopupEx(g.CurrentWindow->GetID(str_id), false); } -static void CloseInactivePopups() +static void CloseInactivePopups(ImGuiWindow* ref_window) { ImGuiContext& g = *GImGui; if (g.OpenPopupStack.empty()) @@ -3576,7 +3583,7 @@ static void CloseInactivePopups() // When popups are stacked, clicking on a lower level popups puts focus back to it and close popups above it. // Don't close our own child popup windows int n = 0; - if (g.NavWindow) + if (ref_window) { for (n = 0; n < g.OpenPopupStack.Size; n++) { @@ -3589,7 +3596,7 @@ static void CloseInactivePopups() bool has_focus = false; for (int m = n; m < g.OpenPopupStack.Size && !has_focus; m++) - has_focus = (g.OpenPopupStack[m].Window && g.OpenPopupStack[m].Window->RootWindow == g.NavWindow->RootWindow); + has_focus = (g.OpenPopupStack[m].Window && g.OpenPopupStack[m].Window->RootWindow == ref_window->RootWindow); if (!has_focus) break; } From 3b485cda51807b9a29cb0ba3a3e22c2b500f7cdc Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 20 Oct 2017 16:09:24 +0200 Subject: [PATCH 453/921] Fixed a bug allowing to move a _NoMove window from a child that doesn't have the flag. (#1381) broken by e56eba44fe0724a64f88f041fddad2eac3661cc3 (#1337) --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 933859893..e9619bac1 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2781,7 +2781,7 @@ void ImGui::EndFrame() if (g.HoveredRootWindow != NULL) { FocusWindow(g.HoveredWindow); - if (!(g.HoveredWindow->Flags & ImGuiWindowFlags_NoMove)) + if (!(g.HoveredWindow->Flags & ImGuiWindowFlags_NoMove) && !(g.HoveredRootWindow->Flags & ImGuiWindowFlags_NoMove)) { g.MovedWindow = g.HoveredWindow; g.MovedWindowMoveId = g.HoveredWindow->MoveId; From e6f06627e9cc7b47b4b428f15dc6d4c1910e7a18 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 20 Oct 2017 16:13:13 +0200 Subject: [PATCH 454/921] Made the ImGuiWindowFlags_NoMove flag inherited from parent to child, so in a setup with RootWindow (no flag) -> Child (NoMove flag) -> SubChild (no flag) user won't be able to move the root window by clicking on SubChild. (#1381) --- imgui.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/imgui.cpp b/imgui.cpp index e9619bac1..a65cf90c2 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3785,6 +3785,7 @@ static bool BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, b { ImGuiWindow* parent_window = ImGui::GetCurrentWindow(); ImGuiWindowFlags flags = ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_ChildWindow; + flags |= (parent_window->Flags & ImGuiWindowFlags_NoMove); // Inherit the NoMove flag const ImVec2 content_avail = ImGui::GetContentRegionAvail(); ImVec2 size = ImFloor(size_arg); From d29a6a5a5a22cd114557854c918b3d3c1a8262b6 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 20 Oct 2017 16:40:10 +0200 Subject: [PATCH 455/921] Moved IMGUI_DISABLE_OBSOLETE_FUNCTIONS block lower in the imgui.h file so obsolete functions can use flags. Also sane to quarantine them outside of the respectable area. --- imgui.cpp | 7 ------- imgui.h | 36 +++++++++++++++++++++--------------- imgui_internal.h | 1 - 3 files changed, 21 insertions(+), 23 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index a65cf90c2..463065033 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -5284,13 +5284,6 @@ void ImGui::SetNextWindowPos(const ImVec2& pos, ImGuiCond cond, const ImVec2& pi g.SetNextWindowPosCond = cond ? cond : ImGuiCond_Always; } -#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS -void ImGui::SetNextWindowPosCenter(ImGuiCond cond) -{ - SetNextWindowPos(GetIO().DisplaySize * 0.5f, cond, ImVec2(0.5f, 0.5f)); -} -#endif - void ImGui::SetNextWindowSize(const ImVec2& size, ImGuiCond cond) { ImGuiContext& g = *GImGui; diff --git a/imgui.h b/imgui.h index a6b1116c3..4771175e5 100644 --- a/imgui.h +++ b/imgui.h @@ -485,21 +485,6 @@ namespace ImGui IMGUI_API ImGuiContext* GetCurrentContext(); IMGUI_API void SetCurrentContext(ImGuiContext* ctx); - // Obsolete functions (Will be removed! Also see 'API BREAKING CHANGES' section in imgui.cpp) -#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS - bool Begin(const char* name, bool* p_open, const ImVec2& size_on_first_use, float bg_alpha_override = -1.0f, ImGuiWindowFlags flags = 0); // OBSOLETE 1.52+. use SetNextWindowSize() instead if you want to set a window size. - static inline void AlignFirstTextHeightToWidgets() { AlignTextToFramePadding(); } // OBSOLETE 1.52+ - void SetNextWindowPosCenter(ImGuiCond cond = 0); // OBSOLETE 1.52+ - static inline bool IsItemHoveredRect() { return IsItemRectHovered(); } // OBSOLETE 1.51+ - static inline bool IsPosHoveringAnyWindow(const ImVec2&) { IM_ASSERT(0); return false; } // OBSOLETE 1.51+. This was partly broken. You probably wanted to use ImGui::GetIO().WantCaptureMouse instead. - static inline bool IsMouseHoveringAnyWindow() { return IsAnyWindowHovered(); } // OBSOLETE 1.51+ - static inline bool IsMouseHoveringWindow() { return IsWindowRectHovered(); } // OBSOLETE 1.51+ - static inline bool CollapsingHeader(const char* label, const char* str_id, bool framed = true, bool default_open = false) { (void)str_id; (void)framed; ImGuiTreeNodeFlags default_open_flags = 1<<5; return CollapsingHeader(label, (default_open ? default_open_flags : 0)); } // OBSOLETE 1.49+ - static inline ImFont* GetWindowFont() { return GetFont(); } // OBSOLETE 1.48+ - static inline float GetWindowFontSize() { return GetFontSize(); } // OBSOLETE 1.48+ - static inline void SetScrollPosHere() { SetScrollHere(); } // OBSOLETE 1.42+ -#endif - } // namespace ImGui // Flags for ImGui::Begin() @@ -886,6 +871,27 @@ struct ImGuiIO IMGUI_API ImGuiIO(); }; +//----------------------------------------------------------------------------- +// Obsolete functions (Will be removed! Also see 'API BREAKING CHANGES' section in imgui.cpp) +//----------------------------------------------------------------------------- + +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS +namespace ImGui +{ + bool Begin(const char* name, bool* p_open, const ImVec2& size_on_first_use, float bg_alpha_override = -1.0f, ImGuiWindowFlags flags = 0); // OBSOLETE 1.52+. use SetNextWindowSize() instead if you want to set a window size. + static inline void AlignFirstTextHeightToWidgets() { AlignTextToFramePadding(); } // OBSOLETE 1.52+ + static inline void SetNextWindowPosCenter(ImGuiCond cond = 0) { SetNextWindowPos(ImVec2(GetIO().DisplaySize.x * 0.5f, GetIO().DisplaySize.y * 0.5f), cond, ImVec2(0.5f, 0.5f)); } // OBSOLETE 1.52+ + static inline bool IsItemHoveredRect() { return IsItemRectHovered(); } // OBSOLETE 1.51+ + static inline bool IsPosHoveringAnyWindow(const ImVec2&) { IM_ASSERT(0); return false; } // OBSOLETE 1.51+. This was partly broken. You probably wanted to use ImGui::GetIO().WantCaptureMouse instead. + static inline bool IsMouseHoveringAnyWindow() { return IsAnyWindowHovered(); } // OBSOLETE 1.51+ + static inline bool IsMouseHoveringWindow() { return IsWindowRectHovered(); } // OBSOLETE 1.51+ + static inline bool CollapsingHeader(const char* label, const char* str_id, bool framed = true, bool default_open = false) { (void)str_id; (void)framed; ImGuiTreeNodeFlags default_open_flags = 1 << 5; return CollapsingHeader(label, (default_open ? default_open_flags : 0)); } // OBSOLETE 1.49+ + static inline ImFont* GetWindowFont() { return GetFont(); } // OBSOLETE 1.48+ + static inline float GetWindowFontSize() { return GetFontSize(); } // OBSOLETE 1.48+ + static inline void SetScrollPosHere() { SetScrollHere(); } // OBSOLETE 1.42+ +} +#endif + //----------------------------------------------------------------------------- // Helpers //----------------------------------------------------------------------------- diff --git a/imgui_internal.h b/imgui_internal.h index ec6d4e518..8f8dcc6c7 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -433,7 +433,6 @@ struct ImGuiContext bool ActiveIdIsAlive; // Active widget has been seen this frame bool ActiveIdIsJustActivated; // Set at the time of activation for one frame bool ActiveIdAllowOverlap; // Active widget allows another widget to steal active id (generally for overlapping widgets, but not always) - ImVec2 ActiveIdClickOffset; // Clicked offset from upper-left corner, if applicable (currently only set by ButtonBehavior) ImGuiWindow* ActiveIdWindow; ImGuiWindow* MovedWindow; // Track the child window we clicked on to move a window. From 564ff2dfd379d40568879a5bc89e8cfea7e51d2f Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 20 Oct 2017 17:52:22 +0200 Subject: [PATCH 456/921] IsItemHovered(), IsWindowHovered(): added flags to enable various and more specific behavior. Will enable improvements for popups/context menus and drag'n drop. (relate ~#439, #1013, #143, #925) The legacy confusing IsItemRectHovered(), IsWindowRectHovered() can be completely removed now. Changed IsWindowHovered() behavior with default parameter: it now return false is the window is blocked by a popup. Demo: Added tests for those two functions. --- imgui.cpp | 51 +++++++++++++++++++++++++------------------------- imgui.h | 23 ++++++++++++++++------- imgui_demo.cpp | 28 +++++++++++++++++++++++++++ 3 files changed, 69 insertions(+), 33 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 463065033..efb234f0f 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -216,11 +216,12 @@ Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. Also read releases logs https://github.com/ocornut/imgui/releases for more details. + - 2017/10/20 (1.52) - removed the IsItemRectHovered()/IsWindowRectHovered() names introduced in 1.51, the new flags available for IsItemHovered() and IsWindowHovered() are providing much more details/options, and those legacy entry points were confusing/misleading. - 2017/10/17 (1.52) - marked the old 5-parameters version of Begin() as obsolete (still available). Use SetNextWindowSize()+Begin() instead! - 2017/10/11 (1.52) - renamed AlignFirstTextHeightToWidgets() to AlignTextToFramePadding(). Kept inline redirection function (will obsolete). - 2017/09/25 (1.52) - removed SetNextWindowPosCenter() because SetNextWindowPos() now has the optional pivot information to do the same and more. Kept redirection function (will obsolete). - 2017/08/25 (1.52) - io.MousePos needs to be set to ImVec2(-FLT_MAX,-FLT_MAX) when mouse is unavailable/missing. Previously ImVec2(-1,-1) was enough but we now accept negative mouse coordinates. In your binding if you need to support unavailable mouse, make sure to replace "io.MousePos = ImVec2(-1,-1)" with "io.MousePos = ImVec2(-FLT_MAX,-FLT_MAX)". - - 2017/08/22 (1.51) - renamed IsItemHoveredRect() to IsItemRectHovered(). Kept inline redirection function (will obsolete). + - 2017/08/22 (1.51) - renamed IsItemHoveredRect() to IsItemRectHovered(). Kept inline redirection function (will obsolete). -> (1.52) use IsItemHovered(ImGuiHoveredFlags_RectOnly)! - renamed IsMouseHoveringAnyWindow() to IsAnyWindowHovered() for consistency. Kept inline redirection function (will obsolete). - renamed IsMouseHoveringWindow() to IsWindowRectHovered() for consistency. Kept inline redirection function (will obsolete). - 2017/08/20 (1.51) - renamed GetStyleColName() to GetStyleColorName() for consistency. @@ -1944,15 +1945,22 @@ void ImGui::KeepAliveID(ImGuiID id) g.ActiveIdIsAlive = true; } -static inline bool IsWindowContentHoverable(ImGuiWindow* window) +static inline bool IsWindowContentHoverable(ImGuiWindow* window, ImGuiHoveredFlags flags) { // An active popup disable hovering on other windows (apart from its own children) // FIXME-OPT: This could be cached/stored within the window. ImGuiContext& g = *GImGui; if (g.NavWindow) if (ImGuiWindow* focused_root_window = g.NavWindow->RootWindow) - if ((focused_root_window->Flags & ImGuiWindowFlags_Popup) != 0 && focused_root_window->WasActive && focused_root_window != window->RootWindow) - return false; + if (focused_root_window->WasActive && focused_root_window != window->RootWindow) + { + // For the purpose of those flags we differentiate "standard popup" from "modal popup" + // NB: The order of those two tests is important because Modal windows are also Popups. + if (focused_root_window->Flags & ImGuiWindowFlags_Modal) + return false; + if ((focused_root_window->Flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiHoveredFlags_AllowWhenBlockedByPopup)) + return false; + } return true; } @@ -2012,7 +2020,7 @@ bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id) // This is roughly matching the behavior of internal-facing ItemHoverable() // - we allow hovering to be true when ActiveId==window->MoveID, so that clicking on non-interactive items such as a Text() item still returns true with IsItemHovered()) // - this should work even for non-interactive items that have no ID, so we cannot use LastItemId -bool ImGui::IsItemHovered() +bool ImGui::IsItemHovered(ImGuiHoveredFlags flags) { ImGuiContext& g = *GImGui; @@ -2023,21 +2031,16 @@ bool ImGui::IsItemHovered() // Until a solution is found I believe reverting to the test from 2017/09/27 is safe since this was the test that has been running for a long while. //if (g.HoveredWindow != window) // return false; - if (g.HoveredRootWindow != window->RootWindow) + if (g.HoveredRootWindow != window->RootWindow && !(flags & ImGuiHoveredFlags_AllowWhenOverlapped)) return false; - if (g.ActiveId != 0 && g.ActiveId != window->DC.LastItemId && !g.ActiveIdAllowOverlap && g.ActiveId != window->MoveId) - return false; - if (!IsWindowContentHoverable(window)) + if (!(flags & ImGuiHoveredFlags_AllowWhenBlockedByActiveItem)) + if (g.ActiveId != 0 && g.ActiveId != window->DC.LastItemId && !g.ActiveIdAllowOverlap && g.ActiveId != window->MoveId) + return false; + if (!IsWindowContentHoverable(window, flags)) return false; return true; } -bool ImGui::IsItemRectHovered() -{ - ImGuiWindow* window = GetCurrentWindowRead(); - return window->DC.LastItemRectHoveredRect; -} - // Internal facing ItemHoverable() used when submitting widgets. Differs slightly from IsItemHovered(). bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id) { @@ -2052,7 +2055,7 @@ bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id) return false; if (!IsMouseHoveringRect(bb.Min, bb.Max)) return false; - if (!IsWindowContentHoverable(window)) + if (!IsWindowContentHoverable(window, ImGuiHoveredFlags_Default)) return false; SetHoveredID(id); @@ -5086,16 +5089,11 @@ const char* ImGui::GetStyleColorName(ImGuiCol idx) return "Unknown"; } -bool ImGui::IsWindowHovered() +bool ImGui::IsWindowHovered(ImGuiHoveredFlags flags) { + IM_ASSERT((flags & (ImGuiHoveredFlags_AllowWhenOverlapped | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem)) == 0); // Flags not supported by this function ImGuiContext& g = *GImGui; - return g.HoveredWindow == g.CurrentWindow && IsWindowContentHoverable(g.HoveredRootWindow); -} - -bool ImGui::IsWindowRectHovered() -{ - ImGuiContext& g = *GImGui; - return g.HoveredWindow == g.CurrentWindow; + return g.HoveredWindow == g.CurrentWindow && IsWindowContentHoverable(g.HoveredRootWindow, flags); } bool ImGui::IsWindowFocused() @@ -5116,10 +5114,11 @@ bool ImGui::IsRootWindowOrAnyChildFocused() return g.NavWindow && g.NavWindow->RootWindow == g.CurrentWindow->RootWindow; } -bool ImGui::IsRootWindowOrAnyChildHovered() +bool ImGui::IsRootWindowOrAnyChildHovered(ImGuiHoveredFlags flags) { + IM_ASSERT((flags & (ImGuiHoveredFlags_AllowWhenOverlapped | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem)) == 0); // Flags not supported by this function ImGuiContext& g = *GImGui; - return g.HoveredRootWindow && (g.HoveredRootWindow == g.CurrentWindow->RootWindow) && IsWindowContentHoverable(g.HoveredRootWindow); + return g.HoveredRootWindow && (g.HoveredRootWindow == g.CurrentWindow->RootWindow) && IsWindowContentHoverable(g.HoveredRootWindow, flags); } float ImGui::GetWindowWidth() diff --git a/imgui.h b/imgui.h index 4771175e5..3b72401d9 100644 --- a/imgui.h +++ b/imgui.h @@ -80,6 +80,7 @@ typedef int ImGuiColumnsFlags; // flags: for *Columns*() typedef int ImGuiInputTextFlags; // flags: for InputText*() // enum ImGuiInputTextFlags_ typedef int ImGuiSelectableFlags; // flags: for Selectable() // enum ImGuiSelectableFlags_ typedef int ImGuiTreeNodeFlags; // flags: for TreeNode*(), Collapsing*() // enum ImGuiTreeNodeFlags_ +typedef int ImGuiHoveredFlags; // flags: for IsItemHovered() // enum ImGuiHoveredFlags_ typedef int (*ImGuiTextEditCallback)(ImGuiTextEditCallbackData *data); typedef void (*ImGuiSizeConstraintCallback)(ImGuiSizeConstraintCallbackData* data); #ifdef _MSC_VER @@ -414,8 +415,7 @@ namespace ImGui IMGUI_API void StyleColorsClassic(ImGuiStyle* dst = NULL); // Utilities - IMGUI_API bool IsItemHovered(); // is the last item hovered by mouse (and usable)? - IMGUI_API bool IsItemRectHovered(); // is the last item hovered by mouse? even if another item is active or window is blocked by popup while we are hovering this + IMGUI_API bool IsItemHovered(ImGuiHoveredFlags flags = 0); // is the last item hovered by mouse (and usable)? IMGUI_API bool IsItemActive(); // is the last item active? (e.g. button being held, text field being edited- items that don't interact will always return false) IMGUI_API bool IsItemClicked(int mouse_button = 0); // is the last item clicked? (e.g. button/node just clicked on) IMGUI_API bool IsItemVisible(); // is the last item visible? (aka not out of sight due to clipping/scrolling.) @@ -426,11 +426,10 @@ namespace ImGui IMGUI_API ImVec2 GetItemRectSize(); // " IMGUI_API void SetItemAllowOverlap(); // allow last item to be overlapped by a subsequent item. sometimes useful with invisible buttons, selectables, etc. to catch unused area. IMGUI_API bool IsWindowFocused(); // is current window focused - IMGUI_API bool IsWindowHovered(); // is current window hovered and hoverable (not blocked by a popup) (differentiate child windows from each others) - IMGUI_API bool IsWindowRectHovered(); // is current window rectangle hovered, disregarding of any consideration of being blocked by a popup. (unlike IsWindowHovered() this will return true even if the window is blocked because of a popup) + IMGUI_API bool IsWindowHovered(ImGuiHoveredFlags flags = 0); // is current window hovered (and typically: not blocked by a popup/modal) IMGUI_API bool IsRootWindowFocused(); // is current root window focused (root = top-most parent of a child, otherwise self) IMGUI_API bool IsRootWindowOrAnyChildFocused(); // is current root window or any of its child (including current window) focused - IMGUI_API bool IsRootWindowOrAnyChildHovered(); // is current root window or any of its child (including current window) hovered and hoverable (not blocked by a popup) + IMGUI_API bool IsRootWindowOrAnyChildHovered(ImGuiHoveredFlags flags = 0); // is current root window or any of its child (including current window) hovered and hoverable (not blocked by a popup) IMGUI_API bool IsAnyWindowHovered(); // is mouse hovering any visible window IMGUI_API bool IsRectVisible(const ImVec2& size); // test if rectangle (of given size, starting from cursor position) is visible / not clipped. IMGUI_API bool IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max); // test if rectangle (in screen space) is visible / not clipped. to perform coarse clipping on user's side. @@ -569,6 +568,16 @@ enum ImGuiSelectableFlags_ ImGuiSelectableFlags_AllowDoubleClick = 1 << 2 // Generate press events on double clicks too }; +enum ImGuiHoveredFlags_ +{ + ImGuiHoveredFlags_Default = 0, // Return true if directly over the item/window, not obstructed by another window, not obstructed by an active popup or modal blocking inputs under them. + ImGuiHoveredFlags_AllowWhenBlockedByPopup = 1 << 0, // Return true even if a popup window is normally blocking access to this item/window + //ImGuiHoveredFlags_AllowWhenBlockedByModal = 1 << 1, // Return true even if a modal popup window is normally blocking access to this item/window. FIXME-TODO: Unavailable yet. + ImGuiHoveredFlags_AllowWhenBlockedByActiveItem = 1 << 2, // Return true even if an active item is blocking access to this item/window + ImGuiHoveredFlags_AllowWhenOverlapped = 1 << 3, // Return true even if the position is overlapped by another window + ImGuiHoveredFlags_RectOnly = ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem | ImGuiHoveredFlags_AllowWhenOverlapped +}; + // User fill ImGuiIO.KeyMap[] array with indices into the ImGuiIO.KeysDown[512] array enum ImGuiKey_ { @@ -881,10 +890,10 @@ namespace ImGui bool Begin(const char* name, bool* p_open, const ImVec2& size_on_first_use, float bg_alpha_override = -1.0f, ImGuiWindowFlags flags = 0); // OBSOLETE 1.52+. use SetNextWindowSize() instead if you want to set a window size. static inline void AlignFirstTextHeightToWidgets() { AlignTextToFramePadding(); } // OBSOLETE 1.52+ static inline void SetNextWindowPosCenter(ImGuiCond cond = 0) { SetNextWindowPos(ImVec2(GetIO().DisplaySize.x * 0.5f, GetIO().DisplaySize.y * 0.5f), cond, ImVec2(0.5f, 0.5f)); } // OBSOLETE 1.52+ - static inline bool IsItemHoveredRect() { return IsItemRectHovered(); } // OBSOLETE 1.51+ + static inline bool IsItemHoveredRect() { return IsItemHovered(ImGuiHoveredFlags_RectOnly); } // OBSOLETE 1.51+ static inline bool IsPosHoveringAnyWindow(const ImVec2&) { IM_ASSERT(0); return false; } // OBSOLETE 1.51+. This was partly broken. You probably wanted to use ImGui::GetIO().WantCaptureMouse instead. static inline bool IsMouseHoveringAnyWindow() { return IsAnyWindowHovered(); } // OBSOLETE 1.51+ - static inline bool IsMouseHoveringWindow() { return IsWindowRectHovered(); } // OBSOLETE 1.51+ + static inline bool IsMouseHoveringWindow() { return IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem); } // OBSOLETE 1.51+ static inline bool CollapsingHeader(const char* label, const char* str_id, bool framed = true, bool default_open = false) { (void)str_id; (void)framed; ImGuiTreeNodeFlags default_open_flags = 1 << 5; return CollapsingHeader(label, (default_open ? default_open_flags : 0)); } // OBSOLETE 1.49+ static inline ImFont* GetWindowFont() { return GetFont(); } // OBSOLETE 1.48+ static inline float GetWindowFontSize() { return GetFontSize(); } // OBSOLETE 1.48+ diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 7fafd9ef2..d923dffeb 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1763,6 +1763,34 @@ void ImGui::ShowTestWindow(bool* p_open) ImGui::TreePop(); } + if (ImGui::TreeNode("Hovering")) + { + // Testing IsWindowHovered() function + ImGui::BulletText( + "IsWindowHovered() = %d\n" + "IsWindowHovered(_AllowWhenBlockedByPopup) = %d\n", + //"IsWindowHovered(_AllowWhenBlockedByActiveItem) = %d\n", + ImGui::IsWindowHovered(), + ImGui::IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup)); + //ImGui::IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem)); + + // Testing IsItemHovered() function (because BulletText is an item itself and that would affect the output of IsItemHovered, we pass all lines in a single items to shorten the code) + ImGui::Button("ITEM"); + ImGui::BulletText( + "IsItemHovered() = %d\n" + "IsItemHovered(_AllowWhenBlockedByPopup) = %d\n" + "IsItemHovered(_AllowWhenBlockedByActiveItem) = %d\n" + "IsItemHovered(_AllowWhenOverlapped) = %d\n" + "IsItemhovered(_RectOnly) = %d\n", + ImGui::IsItemHovered(), + ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup), + ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem), + ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenOverlapped), + ImGui::IsItemHovered(ImGuiHoveredFlags_RectOnly)); + + ImGui::TreePop(); + } + if (ImGui::TreeNode("Dragging")) { ImGui::TextWrapped("You can use ImGui::GetMouseDragDelta(0) to query for the dragged amount on any widget."); From 695ea45fca41debe15c0ed2fe86ff0bc8961d67e Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 20 Oct 2017 17:59:48 +0200 Subject: [PATCH 457/921] IsWindowHovered(): Changed default behavior to now return false is a widget from another window is active + Added support for ImGuiHoveredFlags_AllowWhenBlockedByActiveItem. (relate to drag'n drop idoms: #143) --- imgui.cpp | 22 ++++++++++++++++++---- imgui_demo.cpp | 8 ++++---- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index efb234f0f..69b0dcd0b 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -5091,9 +5091,16 @@ const char* ImGui::GetStyleColorName(ImGuiCol idx) bool ImGui::IsWindowHovered(ImGuiHoveredFlags flags) { - IM_ASSERT((flags & (ImGuiHoveredFlags_AllowWhenOverlapped | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem)) == 0); // Flags not supported by this function + IM_ASSERT((flags & ImGuiHoveredFlags_AllowWhenOverlapped) == 0); // Flags not supported by this function ImGuiContext& g = *GImGui; - return g.HoveredWindow == g.CurrentWindow && IsWindowContentHoverable(g.HoveredRootWindow, flags); + if (g.HoveredWindow != g.CurrentWindow) + return false; + if (!IsWindowContentHoverable(g.HoveredRootWindow, flags)) + return false; + if (!(flags & ImGuiHoveredFlags_AllowWhenBlockedByActiveItem)) + if (g.ActiveId != 0 && g.ActiveIdWindow != g.CurrentWindow) + return false; + return true; } bool ImGui::IsWindowFocused() @@ -5116,9 +5123,16 @@ bool ImGui::IsRootWindowOrAnyChildFocused() bool ImGui::IsRootWindowOrAnyChildHovered(ImGuiHoveredFlags flags) { - IM_ASSERT((flags & (ImGuiHoveredFlags_AllowWhenOverlapped | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem)) == 0); // Flags not supported by this function + IM_ASSERT((flags & ImGuiHoveredFlags_AllowWhenOverlapped) == 0); // Flags not supported by this function ImGuiContext& g = *GImGui; - return g.HoveredRootWindow && (g.HoveredRootWindow == g.CurrentWindow->RootWindow) && IsWindowContentHoverable(g.HoveredRootWindow, flags); + if (!g.HoveredRootWindow || (g.HoveredRootWindow != g.CurrentWindow->RootWindow)) + return false; + if (!IsWindowContentHoverable(g.HoveredRootWindow, flags)) + return false; + if (!(flags & ImGuiHoveredFlags_AllowWhenBlockedByActiveItem)) + if (g.ActiveId != 0 && g.ActiveIdWindow != g.CurrentWindow) + return false; + return true; } float ImGui::GetWindowWidth() diff --git a/imgui_demo.cpp b/imgui_demo.cpp index d923dffeb..242decaed 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1768,11 +1768,11 @@ void ImGui::ShowTestWindow(bool* p_open) // Testing IsWindowHovered() function ImGui::BulletText( "IsWindowHovered() = %d\n" - "IsWindowHovered(_AllowWhenBlockedByPopup) = %d\n", - //"IsWindowHovered(_AllowWhenBlockedByActiveItem) = %d\n", + "IsWindowHovered(_AllowWhenBlockedByPopup) = %d\n" + "IsWindowHovered(_AllowWhenBlockedByActiveItem) = %d\n", ImGui::IsWindowHovered(), - ImGui::IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup)); - //ImGui::IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem)); + ImGui::IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup), + ImGui::IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem)); // Testing IsItemHovered() function (because BulletText is an item itself and that would affect the output of IsItemHovered, we pass all lines in a single items to shorten the code) ImGui::Button("ITEM"); From 3cc10d25a97a4eeba0dda8d02f3e0ed9c6e13c72 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 20 Oct 2017 17:59:59 +0200 Subject: [PATCH 458/921] BeginPopupContextItem(), BeginPopupContextWindow(): Using newly introduced IsItemHovered() flags to allow reopening another context menu (over same or not same item) with right-click. (#439) (+1 squashed commits) --- imgui.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 69b0dcd0b..385b7d220 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -216,6 +216,7 @@ Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. Also read releases logs https://github.com/ocornut/imgui/releases for more details. + - 2017/10/20 (1.52) - changed IsWindowHovered() default parameters behavior to return false if a popup window is blocking access to the window or an item is active in another window. You can use the newly introduced IsWindowHovered() flags to requests those specific behavior if you need them. - 2017/10/20 (1.52) - removed the IsItemRectHovered()/IsWindowRectHovered() names introduced in 1.51, the new flags available for IsItemHovered() and IsWindowHovered() are providing much more details/options, and those legacy entry points were confusing/misleading. - 2017/10/17 (1.52) - marked the old 5-parameters version of Begin() as obsolete (still available). Use SetNextWindowSize()+Begin() instead! - 2017/10/11 (1.52) - renamed AlignFirstTextHeightToWidgets() to AlignTextToFramePadding(). Kept inline redirection function (will obsolete). @@ -3758,8 +3759,9 @@ bool ImGui::BeginPopupContextItem(const char* str_id, int mouse_button) ImGuiWindow* window = GImGui->CurrentWindow; ImGuiID id = str_id ? window->GetID(str_id) : window->DC.LastItemId; // If user hasn't passed an ID, we can use the LastItemID. Using LastItemID as a Popup ID won't conflict! IM_ASSERT(id != 0); // However, you cannot pass a NULL str_id if the last item has no identifier (e.g. a Text() item) - if (IsItemHovered() && IsMouseClicked(mouse_button)) - OpenPopupEx(id, false); + if (IsMouseClicked(mouse_button)) + if (IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup)) + OpenPopupEx(id, true); return BeginPopupEx(id, ImGuiWindowFlags_ShowBorders | ImGuiWindowFlags_AlwaysAutoResize); } @@ -3768,9 +3770,10 @@ bool ImGui::BeginPopupContextWindow(const char* str_id, int mouse_button, bool a if (!str_id) str_id = "window_context"; ImGuiID id = GImGui->CurrentWindow->GetID(str_id); - if (IsWindowRectHovered() && IsMouseClicked(mouse_button)) - if (also_over_items || !IsAnyItemHovered()) - OpenPopupEx(id, true); + if (IsMouseClicked(mouse_button)) + if (IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup)) + if (also_over_items || !IsAnyItemHovered()) + OpenPopupEx(id, true); return BeginPopupEx(id, ImGuiWindowFlags_ShowBorders | ImGuiWindowFlags_AlwaysAutoResize); } From 43df7eb5ea1fe744e2bcb4aa24c3f2df28388321 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 20 Oct 2017 18:56:31 +0200 Subject: [PATCH 459/921] Added OpenPopupOnItemClick(); helper which mimic BeginPopupContextItem() but doesn't do the open. Made the color popups uses this standard function so they handle reopening a context menu. --- imgui.cpp | 51 +++++++++++++++++++++++++++++---------------------- imgui.h | 3 ++- 2 files changed, 31 insertions(+), 23 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 385b7d220..189fa6696 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3446,7 +3446,7 @@ bool ImGui::IsItemActive() bool ImGui::IsItemClicked(int mouse_button) { - return IsMouseClicked(mouse_button) && IsItemHovered(); + return IsMouseClicked(mouse_button) && IsItemHovered(ImGuiHoveredFlags_Default); } bool ImGui::IsAnyItemHovered() @@ -3746,22 +3746,29 @@ void ImGui::EndPopup() PopStyleVar(); } +bool ImGui::OpenPopupOnItemClick(const char* str_id, int mouse_button) +{ + ImGuiWindow* window = GImGui->CurrentWindow; + if (IsMouseClicked(mouse_button) && IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup)) + { + ImGuiID id = str_id ? window->GetID(str_id) : window->DC.LastItemId; // If user hasn't passed an ID, we can use the LastItemID. Using LastItemID as a Popup ID won't conflict! + IM_ASSERT(id != 0); // However, you cannot pass a NULL str_id if the last item has no identifier (e.g. a Text() item) + OpenPopupEx(id, true); + return true; + } + return false; +} + // This is a helper to handle the simplest case of associating one named popup to one given widget. -// 1. If you have many possible popups (for different "instances" of a same widget, or for wholly different widgets), you may be better off handling -// this yourself so you can store data relative to the widget that opened the popup instead of choosing different popup identifiers. -// 2. If you want right-clicking on the same item to reopen the popup at new location, use the same code replacing IsItemHovered() with IsItemRectHovered() -// and passing true to the OpenPopupEx(). -// This is because hovering an item in a window below the popup won't work. IsItemRectHovered() skips this test. -// The pattern of ignoring the fact that the item can be interacted with (because it is blocked by the active popup) may useful in some situation -// when e.g. large canvas where the content of menu driven by click position. +// You may want to handle this on user side if you have specific needs (e.g. tweaking IsItemHovered() parameters). +// You can pass a NULL str_id to use the identifier of the last item. bool ImGui::BeginPopupContextItem(const char* str_id, int mouse_button) { ImGuiWindow* window = GImGui->CurrentWindow; ImGuiID id = str_id ? window->GetID(str_id) : window->DC.LastItemId; // If user hasn't passed an ID, we can use the LastItemID. Using LastItemID as a Popup ID won't conflict! IM_ASSERT(id != 0); // However, you cannot pass a NULL str_id if the last item has no identifier (e.g. a Text() item) - if (IsMouseClicked(mouse_button)) - if (IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup)) - OpenPopupEx(id, true); + if (IsMouseClicked(mouse_button) && IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup)) + OpenPopupEx(id, true); return BeginPopupEx(id, ImGuiWindowFlags_ShowBorders | ImGuiWindowFlags_AlwaysAutoResize); } @@ -9575,8 +9582,8 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag value_changed |= value_changed_as_float |= DragFloat(ids[n], &f[n], 1.0f/255.0f, 0.0f, hdr ? 0.0f : 1.0f, fmt_table_float[fmt_idx][n]); else value_changed |= DragInt(ids[n], &i[n], 1.0f, 0, hdr ? 0 : 255, fmt_table_int[fmt_idx][n]); - if (!(flags & ImGuiColorEditFlags_NoOptions) && IsItemHovered() && IsMouseClicked(1)) - OpenPopup("context"); + if (!(flags & ImGuiColorEditFlags_NoOptions)) + OpenPopupOnItemClick("context"); } PopItemWidth(); PopItemWidth(); @@ -9602,8 +9609,8 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag else sscanf(p, "%02X%02X%02X", (unsigned int*)&i[0], (unsigned int*)&i[1], (unsigned int*)&i[2]); } - if (!(flags & ImGuiColorEditFlags_NoOptions) && IsItemHovered() && IsMouseClicked(1)) - OpenPopup("context"); + if (!(flags & ImGuiColorEditFlags_NoOptions)) + OpenPopupOnItemClick("context"); PopItemWidth(); } @@ -9624,9 +9631,9 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag SetNextWindowPos(window->DC.LastItemRect.GetBL() + ImVec2(-1,style.ItemSpacing.y)); } } - if (!(flags & ImGuiColorEditFlags_NoOptions) && IsItemHovered() && IsMouseClicked(1)) - OpenPopup("context"); - + if (!(flags & ImGuiColorEditFlags_NoOptions)) + OpenPopupOnItemClick("context"); + if (BeginPopup("picker")) { picker_active = true; @@ -9791,8 +9798,8 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl value_changed = value_changed_sv = true; } } - if (!(flags & ImGuiColorEditFlags_NoOptions) && IsItemHovered() && IsMouseClicked(1)) - OpenPopup("context"); + if (!(flags & ImGuiColorEditFlags_NoOptions)) + OpenPopupOnItemClick("context"); } else if (flags & ImGuiColorEditFlags_PickerHueBar) { @@ -9804,8 +9811,8 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl V = 1.0f - ImSaturate((io.MousePos.y - picker_pos.y) / (sv_picker_size-1)); value_changed = value_changed_sv = true; } - if (!(flags & ImGuiColorEditFlags_NoOptions) && IsItemHovered() && IsMouseClicked(1)) - OpenPopup("context"); + if (!(flags & ImGuiColorEditFlags_NoOptions)) + OpenPopupOnItemClick("context"); // Hue bar logic SetCursorScreenPos(ImVec2(bar0_pos_x, picker_pos.y)); diff --git a/imgui.h b/imgui.h index 3b72401d9..e281b4f1a 100644 --- a/imgui.h +++ b/imgui.h @@ -390,11 +390,12 @@ namespace ImGui // Popups IMGUI_API void OpenPopup(const char* str_id); // call to mark popup as open (don't call every frame!). popups are closed when user click outside, or if CloseCurrentPopup() is called within a BeginPopup()/EndPopup() block. By default, Selectable()/MenuItem() are calling CloseCurrentPopup(). Popup identifiers are relative to the current ID-stack (so OpenPopup and BeginPopup needs to be at the same level). + IMGUI_API bool OpenPopupOnItemClick(const char* str_id = NULL, int mouse_button = 1); // helper to open popup when clicked on last item. return true when just opened. IMGUI_API bool BeginPopup(const char* str_id); // return true if the popup is open, and you can start outputting to it. only call EndPopup() if BeginPopup() returned true! IMGUI_API bool BeginPopupModal(const char* name, bool* p_open = NULL, ImGuiWindowFlags extra_flags = 0); // modal dialog (block interactions behind the modal window, can't close the modal window by clicking outside) IMGUI_API bool BeginPopupContextItem(const char* str_id = NULL, int mouse_button = 1); // helper to open and begin popup when clicked on last item. if you can pass a NULL str_id only if the previous item had an id. If you want to use that on a non-interactive item such as Text() you need to pass in an explicit ID here. read comments in .cpp! IMGUI_API bool BeginPopupContextWindow(const char* str_id = NULL, int mouse_button = 1, bool also_over_items = true); // helper to open and begin popup when clicked on current window. - IMGUI_API bool BeginPopupContextVoid(const char* str_id = NULL, int mouse_button = 1); // helper to open and begin popup when clicked in void (no window). + IMGUI_API bool BeginPopupContextVoid(const char* str_id = NULL, int mouse_button = 1); // helper to open and begin popup when clicked in void (where there are no imgui windows). IMGUI_API void EndPopup(); IMGUI_API bool IsPopupOpen(const char* str_id); // return true if the popup is open IMGUI_API void CloseCurrentPopup(); // close the popup we have begin-ed into. clicking on a MenuItem or Selectable automatically close the current popup. From 59a89774d79ee5d39c38a0f0721702e2322e7bf5 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 20 Oct 2017 19:24:12 +0200 Subject: [PATCH 460/921] Popups: fixed CloseInactivePopups() so that right-clicking to close one level of popups in a popups stack won't close the whole stack. This is done by properly refocusing the lower level popup. Fixes 87ae40843c0b5c526edd9cdb62b072cd0bcc49ff (~#439) --- imgui.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 189fa6696..d40bacde5 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2802,9 +2802,7 @@ void ImGui::EndFrame() // With right mouse button we close popups without changing focus // (The left mouse button path calls FocusWindow which will lead NewFrame->CloseInactivePopups to trigger) if (g.IO.MouseClicked[1]) - { CloseInactivePopups(g.HoveredWindow); - } } } @@ -3605,8 +3603,8 @@ static void CloseInactivePopups(ImGuiWindow* ref_window) break; } } - if (n < g.OpenPopupStack.Size) // This test is not required but it allows to set a useful breakpoint on the line below - g.OpenPopupStack.resize(n); + if (n < g.OpenPopupStack.Size) // This test is not required but it allows to set a convenient breakpoint on the block below + ClosePopupToLevel(n); } static ImGuiWindow* GetFrontMostModalRootWindow() From aca23fd3f0eb1b6fb109840f5fc942c49312d096 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 20 Oct 2017 19:25:34 +0200 Subject: [PATCH 461/921] Popups: similarly to previous commit, we fix reopening a popup within a popup stack from truncating the whole stack. This is done by properly refocusing the lower level popup. (~#439) --- imgui.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/imgui.cpp b/imgui.cpp index d40bacde5..8849021f3 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3567,6 +3567,11 @@ void ImGui::OpenPopupEx(ImGuiID id, bool reopen_existing) { g.OpenPopupStack.resize(current_stack_size+1); g.OpenPopupStack[current_stack_size] = popup_ref; + + // When reopening a popup we first refocus its parent, otherwise if its parent is itself a popup it would get closed by CloseInactivePopups(). + // This is equivalent to what ClosePopupToLevel() does. + if (g.OpenPopupStack[current_stack_size].PopupId == id) + FocusWindow(window); } } From 6ab737a4bb288d553f4de3e3841e393ef96d32a0 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 20 Oct 2017 20:31:01 +0200 Subject: [PATCH 462/921] Popups: Fixed right-click to close popups not handling modal windows properly. (~#439) --- imgui.cpp | 27 ++++++++++++++++++++++----- imgui_demo.cpp | 2 ++ 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 8849021f3..b1593c260 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2802,7 +2802,23 @@ void ImGui::EndFrame() // With right mouse button we close popups without changing focus // (The left mouse button path calls FocusWindow which will lead NewFrame->CloseInactivePopups to trigger) if (g.IO.MouseClicked[1]) - CloseInactivePopups(g.HoveredWindow); + { + // Find the top-most window between HoveredWindow and the front most Modal Window. + // This is where we can trim the popup stack. + ImGuiWindow* modal = GetFrontMostModalRootWindow(); + bool hovered_window_above_modal = false; + if (modal == NULL) + hovered_window_above_modal = true; + for (int i = g.Windows.Size - 1; i >= 0 && hovered_window_above_modal == false; i--) + { + ImGuiWindow* window = g.Windows[i]; + if (window == modal) + break; + if (window == g.HoveredWindow) + hovered_window_above_modal = true; + } + CloseInactivePopups(hovered_window_above_modal ? g.HoveredWindow : modal); + } } } @@ -3588,7 +3604,7 @@ static void CloseInactivePopups(ImGuiWindow* ref_window) return; // When popups are stacked, clicking on a lower level popups puts focus back to it and close popups above it. - // Don't close our own child popup windows + // Don't close our own child popup windows. int n = 0; if (ref_window) { @@ -3601,6 +3617,7 @@ static void CloseInactivePopups(ImGuiWindow* ref_window) if (popup.Window->Flags & ImGuiWindowFlags_ChildWindow) continue; + // Trim the stack if popups are not direct descendant of the reference window (which is often the NavWindow) bool has_focus = false; for (int m = n; m < g.OpenPopupStack.Size && !has_focus; m++) has_focus = (g.OpenPopupStack[m].Window && g.OpenPopupStack[m].Window->RootWindow == ref_window->RootWindow); @@ -3616,9 +3633,9 @@ static ImGuiWindow* GetFrontMostModalRootWindow() { ImGuiContext& g = *GImGui; for (int n = g.OpenPopupStack.Size-1; n >= 0; n--) - if (ImGuiWindow* front_most_popup = g.OpenPopupStack.Data[n].Window) - if (front_most_popup->Flags & ImGuiWindowFlags_Modal) - return front_most_popup; + if (ImGuiWindow* popup = g.OpenPopupStack.Data[n].Window) + if (popup->Flags & ImGuiWindowFlags_Modal) + return popup; return NULL; } diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 242decaed..404dcbdbc 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1453,6 +1453,8 @@ void ImGui::ShowTestWindow(bool* p_open) ImGui::Text("Hello from Stacked The First\nUsing style.Colors[ImGuiCol_ModalWindowDarkening] for darkening."); static int item = 1; ImGui::Combo("Combo", &item, "aaaa\0bbbb\0cccc\0dddd\0eeee\0\0"); + static float color[4] = { 0.4f,0.7f,0.0f,0.5f }; + ImGui::ColorEdit4("color", color); // This is to test behavior of stacked regular popups over a modal if (ImGui::Button("Add another modal..")) ImGui::OpenPopup("Stacked 2"); From f7259e60eea334e274d797ca3d3c6536e85e7ca2 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 20 Oct 2017 21:17:51 +0200 Subject: [PATCH 463/921] Comments --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index b1593c260..15a4e5cd3 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -216,7 +216,7 @@ Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. Also read releases logs https://github.com/ocornut/imgui/releases for more details. - - 2017/10/20 (1.52) - changed IsWindowHovered() default parameters behavior to return false if a popup window is blocking access to the window or an item is active in another window. You can use the newly introduced IsWindowHovered() flags to requests those specific behavior if you need them. + - 2017/10/20 (1.52) - changed IsWindowHovered() default parameters behavior to return false an item is active in another window (e.g. click-dragging item from another window to this window). You can use the newly introduced IsWindowHovered() flags to requests that specific behavior if you need it. - 2017/10/20 (1.52) - removed the IsItemRectHovered()/IsWindowRectHovered() names introduced in 1.51, the new flags available for IsItemHovered() and IsWindowHovered() are providing much more details/options, and those legacy entry points were confusing/misleading. - 2017/10/17 (1.52) - marked the old 5-parameters version of Begin() as obsolete (still available). Use SetNextWindowSize()+Begin() instead! - 2017/10/11 (1.52) - renamed AlignFirstTextHeightToWidgets() to AlignTextToFramePadding(). Kept inline redirection function (will obsolete). From fce41d0b5569ceaf9e7901a013efc68980d57662 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 22 Oct 2017 10:21:49 +0200 Subject: [PATCH 464/921] Demo: Fixed Fonts "set as default button" not having collading id on collapsed nodes. --- imgui_demo.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 404dcbdbc..35ee618b9 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1951,6 +1951,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) for (int i = 0; i < atlas->Fonts.Size; i++) { ImFont* font = atlas->Fonts[i]; + ImGui::PushID(font); bool font_details_opened = ImGui::TreeNode(font, "Font %d: \'%s\', %.2f px, %d glyphs", i, font->ConfigData ? font->ConfigData[0].Name : "", font->FontSize, font->Glyphs.Size); ImGui::SameLine(); if (ImGui::SmallButton("Set as default")) ImGui::GetIO().FontDefault = font; if (font_details_opened) @@ -2011,6 +2012,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) } ImGui::TreePop(); } + ImGui::PopID(); } static float window_scale = 1.0f; ImGui::DragFloat("this window scale", &window_scale, 0.005f, 0.3f, 2.0f, "%.1f"); // scale only this window From 7f880674e5c3e594ac034215252b7d1455a1579f Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 22 Oct 2017 10:24:56 +0200 Subject: [PATCH 465/921] Font: Renamed ImFont::Clear() to ImFont::ClearOutputData() for consistency with what ImFontAtlas does. DisplayOffset is set by constructor but not reset by ClearOutputData. (#1349) --- imgui.h | 2 +- imgui_draw.cpp | 14 +++++--------- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/imgui.h b/imgui.h index e281b4f1a..c865d3578 100644 --- a/imgui.h +++ b/imgui.h @@ -1500,7 +1500,7 @@ struct ImFont // Methods IMGUI_API ImFont(); IMGUI_API ~ImFont(); - IMGUI_API void Clear(); + IMGUI_API void ClearOutputData(); IMGUI_API void BuildLookupTable(); IMGUI_API const ImFontGlyph*FindGlyph(ImWchar c) const; IMGUI_API void SetFallbackChar(ImWchar c); diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 302c338bb..c3a5f3d5c 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1618,12 +1618,8 @@ void ImFontAtlasBuildSetupFont(ImFontAtlas* atlas, ImFont* font, ImFontConfig* f { if (!font_config->MergeMode) { - ImVec2 display_offset = font->DisplayOffset; - - font->Clear(); - + font->ClearOutputData(); font->FontSize = font_config->SizePixels; - font->DisplayOffset = display_offset; font->ConfigData = font_config; font->ContainerAtlas = atlas; font->Ascent = ascent; @@ -1904,7 +1900,8 @@ ImFont::ImFont() { Scale = 1.0f; FallbackChar = (ImWchar)'?'; - Clear(); + DisplayOffset = ImVec2(0.0f, 1.0f); + ClearOutputData(); } ImFont::~ImFont() @@ -1917,13 +1914,12 @@ ImFont::~ImFont() if (g.Font == this) g.Font = NULL; */ - Clear(); + ClearOutputData(); } -void ImFont::Clear() +void ImFont::ClearOutputData() { FontSize = 0.0f; - DisplayOffset = ImVec2(0.0f, 1.0f); Glyphs.clear(); IndexAdvanceX.clear(); IndexLookup.clear(); From b177f2432dd9ab90f765adf39a6376e4ddea7bb9 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 22 Oct 2017 10:36:22 +0200 Subject: [PATCH 466/921] MenuItem(): Tweak to not draw over all horizontal space when in horizontal layout mode. (#1387) --- imgui.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 15a4e5cd3..c3e97846e 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9083,7 +9083,8 @@ bool ImGui::MenuItem(const char* label, const char* shortcut, bool selected, boo float w = window->MenuColumns.DeclColumns(label_size.x, shortcut_size.x, (float)(int)(g.FontSize * 1.20f)); // Feedback for next frame float extra_w = ImMax(0.0f, GetContentRegionAvail().x - w); - bool pressed = Selectable(label, false, ImGuiSelectableFlags_MenuItem | ImGuiSelectableFlags_DrawFillAvailWidth | (enabled ? 0 : ImGuiSelectableFlags_Disabled), ImVec2(w, 0.0f)); + ImGuiSelectableFlags flags = ImGuiSelectableFlags_MenuItem | (enabled ? 0 : ImGuiSelectableFlags_Disabled) | (window->DC.LayoutType == ImGuiLayoutType_Vertical ? ImGuiSelectableFlags_DrawFillAvailWidth : 0); + bool pressed = Selectable(label, false, flags, ImVec2(w, 0.0f)); if (shortcut_size.x > 0.0f) { PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]); From 1bc17516706652ae662d8837374473fd93f5ac6e Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 22 Oct 2017 10:54:53 +0200 Subject: [PATCH 467/921] MenuItem(): Tweaks to mimic exact spacing of BeginMenu() when inside a menu bar, which is a little misleading imho but may be useful. (#1387) --- imgui.cpp | 40 +++++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index c3e97846e..8ad739fa0 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9077,24 +9077,38 @@ bool ImGui::MenuItem(const char* label, const char* shortcut, bool selected, boo return false; ImGuiContext& g = *GImGui; + ImGuiStyle& style = g.Style; ImVec2 pos = window->DC.CursorPos; ImVec2 label_size = CalcTextSize(label, NULL, true); - ImVec2 shortcut_size = shortcut ? CalcTextSize(shortcut, NULL) : ImVec2(0.0f, 0.0f); - float w = window->MenuColumns.DeclColumns(label_size.x, shortcut_size.x, (float)(int)(g.FontSize * 1.20f)); // Feedback for next frame - float extra_w = ImMax(0.0f, GetContentRegionAvail().x - w); - ImGuiSelectableFlags flags = ImGuiSelectableFlags_MenuItem | (enabled ? 0 : ImGuiSelectableFlags_Disabled) | (window->DC.LayoutType == ImGuiLayoutType_Vertical ? ImGuiSelectableFlags_DrawFillAvailWidth : 0); - bool pressed = Selectable(label, false, flags, ImVec2(w, 0.0f)); - if (shortcut_size.x > 0.0f) + ImGuiSelectableFlags flags = ImGuiSelectableFlags_MenuItem | (enabled ? 0 : ImGuiSelectableFlags_Disabled); + bool pressed; + if (window->DC.LayoutType == ImGuiLayoutType_Horizontal) { - PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]); - RenderText(pos + ImVec2(window->MenuColumns.Pos[1] + extra_w, 0.0f), shortcut, NULL, false); - PopStyleColor(); + // Mimic the exact layout spacing of BeginMenu() to allow MenuItem() inside a menu bar, which is a little misleading but may be useful + // Note that in this situation we render neither the shortcut neither the selected tick mark + float w = label_size.x; + window->DC.CursorPos.x += (float)(int)(style.ItemSpacing.x * 0.5f); + PushStyleVar(ImGuiStyleVar_ItemSpacing, style.ItemSpacing * 2.0f); + pressed = Selectable(label, false, flags, ImVec2(w, 0.0f)); + PopStyleVar(); + window->DC.CursorPos.x += (float)(int)(style.ItemSpacing.x * (-1.0f + 0.5f)); // -1 spacing to compensate the spacing added when Selectable() did a SameLine(). It would also work to call SameLine() ourselves after the PopStyleVar(). + } + else + { + ImVec2 shortcut_size = shortcut ? CalcTextSize(shortcut, NULL) : ImVec2(0.0f, 0.0f); + float w = window->MenuColumns.DeclColumns(label_size.x, shortcut_size.x, (float)(int)(g.FontSize * 1.20f)); // Feedback for next frame + float extra_w = ImMax(0.0f, GetContentRegionAvail().x - w); + pressed = Selectable(label, false, flags | ImGuiSelectableFlags_DrawFillAvailWidth, ImVec2(w, 0.0f)); + if (shortcut_size.x > 0.0f) + { + PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]); + RenderText(pos + ImVec2(window->MenuColumns.Pos[1] + extra_w, 0.0f), shortcut, NULL, false); + PopStyleColor(); + } + if (selected) + RenderCheckMark(pos + ImVec2(window->MenuColumns.Pos[2] + extra_w + g.FontSize * (0.20f+0.200f), g.FontSize * 0.134f * 0.5f), GetColorU32(enabled ? ImGuiCol_Text : ImGuiCol_TextDisabled), g.FontSize * 0.866f); } - - if (selected) - RenderCheckMark(pos + ImVec2(window->MenuColumns.Pos[2] + extra_w + g.FontSize * (0.20f+0.200f), g.FontSize * 0.134f * 0.5f), GetColorU32(enabled ? ImGuiCol_Text : ImGuiCol_TextDisabled), g.FontSize * 0.866f); - return pressed; } From e03198bb0f636a4f997883b498125dee30f570db Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 23 Oct 2017 09:08:12 +0200 Subject: [PATCH 468/921] Fixed compilation for #1375 + coding style fixes. --- examples/directx9_example/imgui_impl_dx9.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/directx9_example/imgui_impl_dx9.cpp b/examples/directx9_example/imgui_impl_dx9.cpp index d1062560b..1d122adfc 100644 --- a/examples/directx9_example/imgui_impl_dx9.cpp +++ b/examples/directx9_example/imgui_impl_dx9.cpp @@ -171,13 +171,13 @@ void ImGui_ImplDX9_RenderDrawLists(ImDrawData* draw_data) d3d9_state_block->Release(); } -IMGUI_API LRESULT ImGui_ImplDX9_WndProcHandler(HWND, UINT msg, WPARAM wParam, LPARAM lParam) +IMGUI_API LRESULT ImGui_ImplDX9_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { ImGuiIO& io = ImGui::GetIO(); switch (msg) { case WM_LBUTTONDOWN: - SetCapture( hWnd ); + SetCapture(hwnd); io.MouseDown[0] = true; return true; case WM_LBUTTONUP: @@ -185,7 +185,7 @@ IMGUI_API LRESULT ImGui_ImplDX9_WndProcHandler(HWND, UINT msg, WPARAM wParam, LP io.MouseDown[0] = false; return true; case WM_RBUTTONDOWN: - SetCapture( hWnd ); + SetCapture(hwnd); io.MouseDown[1] = true; return true; case WM_RBUTTONUP: @@ -193,7 +193,7 @@ IMGUI_API LRESULT ImGui_ImplDX9_WndProcHandler(HWND, UINT msg, WPARAM wParam, LP io.MouseDown[1] = false; return true; case WM_MBUTTONDOWN: - SetCapture( hWnd ); + SetCapture(hwnd); io.MouseDown[2] = true; return true; case WM_MBUTTONUP: From 3e0765ee222a21bf801486f7a817d07569cada84 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 23 Oct 2017 09:43:13 +0200 Subject: [PATCH 469/921] Examples: DirectX9: Using SetCapture/ReleaseCapture to get correct behavior (#1375) --- examples/directx9_example/imgui_impl_dx9.cpp | 34 +++++++++++++------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/examples/directx9_example/imgui_impl_dx9.cpp b/examples/directx9_example/imgui_impl_dx9.cpp index 1d122adfc..0e94d3b81 100644 --- a/examples/directx9_example/imgui_impl_dx9.cpp +++ b/examples/directx9_example/imgui_impl_dx9.cpp @@ -171,34 +171,44 @@ void ImGui_ImplDX9_RenderDrawLists(ImDrawData* draw_data) d3d9_state_block->Release(); } +static bool IsAnyMouseButtonDown() +{ + ImGuiIO& io = ImGui::GetIO(); + for (int n = 0; n < ARRAYSIZE(io.MouseDown); n++) + if (io.MouseDown[n]) + return true; + return false; +} + +// We use Win32 SetCapture/ReleaseCapture() API to enable reading the mouse outside our Windows bounds. IMGUI_API LRESULT ImGui_ImplDX9_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { ImGuiIO& io = ImGui::GetIO(); switch (msg) { case WM_LBUTTONDOWN: - SetCapture(hwnd); + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); io.MouseDown[0] = true; return true; - case WM_LBUTTONUP: - ReleaseCapture(); - io.MouseDown[0] = false; - return true; case WM_RBUTTONDOWN: - SetCapture(hwnd); + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); io.MouseDown[1] = true; return true; - case WM_RBUTTONUP: - ReleaseCapture(); - io.MouseDown[1] = false; - return true; case WM_MBUTTONDOWN: - SetCapture(hwnd); + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); io.MouseDown[2] = true; return true; + case WM_LBUTTONUP: + io.MouseDown[0] = false; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return true; + case WM_RBUTTONUP: + io.MouseDown[1] = false; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + return true; case WM_MBUTTONUP: - ReleaseCapture(); io.MouseDown[2] = false; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); return true; case WM_MOUSEWHEEL: io.MouseWheel += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f; From a96f095deb83f001498157bf10eed3a44d3ee96a Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 23 Oct 2017 09:46:49 +0200 Subject: [PATCH 470/921] Examples: DirectX10, DirectX11: Using SetCapture/ReleaseCapture to get correct behavior (#1375) ps: DirectX 12 example (#302) may want to adopt that as well. --- .../directx10_example/imgui_impl_dx10.cpp | 29 ++++++++++++++----- .../directx11_example/imgui_impl_dx11.cpp | 29 ++++++++++++++----- 2 files changed, 44 insertions(+), 14 deletions(-) diff --git a/examples/directx10_example/imgui_impl_dx10.cpp b/examples/directx10_example/imgui_impl_dx10.cpp index f85edf9b5..e0afa6f65 100644 --- a/examples/directx10_example/imgui_impl_dx10.cpp +++ b/examples/directx10_example/imgui_impl_dx10.cpp @@ -225,28 +225,43 @@ void ImGui_ImplDX10_RenderDrawLists(ImDrawData* draw_data) ctx->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release(); } -IMGUI_API LRESULT ImGui_ImplDX10_WndProcHandler(HWND, UINT msg, WPARAM wParam, LPARAM lParam) +static bool IsAnyMouseButtonDown() +{ + ImGuiIO& io = ImGui::GetIO(); + for (int n = 0; n < ARRAYSIZE(io.MouseDown); n++) + if (io.MouseDown[n]) + return true; + return false; +} + +IMGUI_API LRESULT ImGui_ImplDX10_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { ImGuiIO& io = ImGui::GetIO(); switch (msg) { case WM_LBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); io.MouseDown[0] = true; return true; + case WM_RBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[1] = true; + return true; + case WM_MBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[2] = true; + return true; case WM_LBUTTONUP: io.MouseDown[0] = false; - return true; - case WM_RBUTTONDOWN: - io.MouseDown[1] = true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); return true; case WM_RBUTTONUP: io.MouseDown[1] = false; - return true; - case WM_MBUTTONDOWN: - io.MouseDown[2] = true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); return true; case WM_MBUTTONUP: io.MouseDown[2] = false; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); return true; case WM_MOUSEWHEEL: io.MouseWheel += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f; diff --git a/examples/directx11_example/imgui_impl_dx11.cpp b/examples/directx11_example/imgui_impl_dx11.cpp index 49a4aa481..82c43f7e1 100644 --- a/examples/directx11_example/imgui_impl_dx11.cpp +++ b/examples/directx11_example/imgui_impl_dx11.cpp @@ -232,28 +232,43 @@ void ImGui_ImplDX11_RenderDrawLists(ImDrawData* draw_data) ctx->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release(); } -IMGUI_API LRESULT ImGui_ImplDX11_WndProcHandler(HWND, UINT msg, WPARAM wParam, LPARAM lParam) +static bool IsAnyMouseButtonDown() +{ + ImGuiIO& io = ImGui::GetIO(); + for (int n = 0; n < ARRAYSIZE(io.MouseDown); n++) + if (io.MouseDown[n]) + return true; + return false; +} + +IMGUI_API LRESULT ImGui_ImplDX11_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { ImGuiIO& io = ImGui::GetIO(); switch (msg) { case WM_LBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); io.MouseDown[0] = true; return true; + case WM_RBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[1] = true; + return true; + case WM_MBUTTONDOWN: + if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); + io.MouseDown[2] = true; + return true; case WM_LBUTTONUP: io.MouseDown[0] = false; - return true; - case WM_RBUTTONDOWN: - io.MouseDown[1] = true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); return true; case WM_RBUTTONUP: io.MouseDown[1] = false; - return true; - case WM_MBUTTONDOWN: - io.MouseDown[2] = true; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); return true; case WM_MBUTTONUP: io.MouseDown[2] = false; + if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); return true; case WM_MOUSEWHEEL: io.MouseWheel += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f; From c14a66970b71df8f11086f602df6dd316f5f749f Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 23 Oct 2017 09:57:59 +0200 Subject: [PATCH 471/921] Examples: DirectX9/10/11: Renamed WndProc handler to use a generic Win32 name + returning 0 to all messages is more correct. --- .../directx10_example/imgui_impl_dx10.cpp | 24 +++++++++---------- examples/directx10_example/main.cpp | 4 ++-- .../directx11_example/imgui_impl_dx11.cpp | 24 +++++++++---------- examples/directx11_example/main.cpp | 4 ++-- examples/directx9_example/imgui_impl_dx9.cpp | 24 +++++++++---------- examples/directx9_example/main.cpp | 4 ++-- 6 files changed, 42 insertions(+), 42 deletions(-) diff --git a/examples/directx10_example/imgui_impl_dx10.cpp b/examples/directx10_example/imgui_impl_dx10.cpp index e0afa6f65..13dc99c95 100644 --- a/examples/directx10_example/imgui_impl_dx10.cpp +++ b/examples/directx10_example/imgui_impl_dx10.cpp @@ -234,7 +234,7 @@ static bool IsAnyMouseButtonDown() return false; } -IMGUI_API LRESULT ImGui_ImplDX10_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { ImGuiIO& io = ImGui::GetIO(); switch (msg) @@ -242,47 +242,47 @@ IMGUI_API LRESULT ImGui_ImplDX10_WndProcHandler(HWND hwnd, UINT msg, WPARAM wPar case WM_LBUTTONDOWN: if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); io.MouseDown[0] = true; - return true; + return 0; case WM_RBUTTONDOWN: if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); io.MouseDown[1] = true; - return true; + return 0; case WM_MBUTTONDOWN: if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); io.MouseDown[2] = true; - return true; + return 0; case WM_LBUTTONUP: io.MouseDown[0] = false; if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); - return true; + return 0; case WM_RBUTTONUP: io.MouseDown[1] = false; if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); - return true; + return 0; case WM_MBUTTONUP: io.MouseDown[2] = false; if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); - return true; + return 0; case WM_MOUSEWHEEL: io.MouseWheel += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f; - return true; + return 0; case WM_MOUSEMOVE: io.MousePos.x = (signed short)(lParam); io.MousePos.y = (signed short)(lParam >> 16); - return true; + return 0; case WM_KEYDOWN: if (wParam < 256) io.KeysDown[wParam] = 1; - return true; + return 0; case WM_KEYUP: if (wParam < 256) io.KeysDown[wParam] = 0; - return true; + return 0; case WM_CHAR: // You can also use ToAscii()+GetKeyboardState() to retrieve characters. if (wParam > 0 && wParam < 0x10000) io.AddInputCharacter((unsigned short)wParam); - return true; + return 0; } return 0; } diff --git a/examples/directx10_example/main.cpp b/examples/directx10_example/main.cpp index 4675a21da..ea690742d 100644 --- a/examples/directx10_example/main.cpp +++ b/examples/directx10_example/main.cpp @@ -74,10 +74,10 @@ void CleanupDeviceD3D() if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = NULL; } } -extern LRESULT ImGui_ImplDX10_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); +extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { - if (ImGui_ImplDX10_WndProcHandler(hWnd, msg, wParam, lParam)) + if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) return true; switch (msg) diff --git a/examples/directx11_example/imgui_impl_dx11.cpp b/examples/directx11_example/imgui_impl_dx11.cpp index 82c43f7e1..6d057e07c 100644 --- a/examples/directx11_example/imgui_impl_dx11.cpp +++ b/examples/directx11_example/imgui_impl_dx11.cpp @@ -241,7 +241,7 @@ static bool IsAnyMouseButtonDown() return false; } -IMGUI_API LRESULT ImGui_ImplDX11_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { ImGuiIO& io = ImGui::GetIO(); switch (msg) @@ -249,47 +249,47 @@ IMGUI_API LRESULT ImGui_ImplDX11_WndProcHandler(HWND hwnd, UINT msg, WPARAM wPar case WM_LBUTTONDOWN: if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); io.MouseDown[0] = true; - return true; + return 0; case WM_RBUTTONDOWN: if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); io.MouseDown[1] = true; - return true; + return 0; case WM_MBUTTONDOWN: if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); io.MouseDown[2] = true; - return true; + return 0; case WM_LBUTTONUP: io.MouseDown[0] = false; if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); - return true; + return 0; case WM_RBUTTONUP: io.MouseDown[1] = false; if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); - return true; + return 0; case WM_MBUTTONUP: io.MouseDown[2] = false; if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); - return true; + return 0; case WM_MOUSEWHEEL: io.MouseWheel += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f; - return true; + return 0; case WM_MOUSEMOVE: io.MousePos.x = (signed short)(lParam); io.MousePos.y = (signed short)(lParam >> 16); - return true; + return 0; case WM_KEYDOWN: if (wParam < 256) io.KeysDown[wParam] = 1; - return true; + return 0; case WM_KEYUP: if (wParam < 256) io.KeysDown[wParam] = 0; - return true; + return 0; case WM_CHAR: // You can also use ToAscii()+GetKeyboardState() to retrieve characters. if (wParam > 0 && wParam < 0x10000) io.AddInputCharacter((unsigned short)wParam); - return true; + return 0; } return 0; } diff --git a/examples/directx11_example/main.cpp b/examples/directx11_example/main.cpp index 04321610e..794503e38 100644 --- a/examples/directx11_example/main.cpp +++ b/examples/directx11_example/main.cpp @@ -77,10 +77,10 @@ void CleanupDeviceD3D() if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = NULL; } } -extern LRESULT ImGui_ImplDX11_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); +extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { - if (ImGui_ImplDX11_WndProcHandler(hWnd, msg, wParam, lParam)) + if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) return true; switch (msg) diff --git a/examples/directx9_example/imgui_impl_dx9.cpp b/examples/directx9_example/imgui_impl_dx9.cpp index 0e94d3b81..111ed8153 100644 --- a/examples/directx9_example/imgui_impl_dx9.cpp +++ b/examples/directx9_example/imgui_impl_dx9.cpp @@ -181,7 +181,7 @@ static bool IsAnyMouseButtonDown() } // We use Win32 SetCapture/ReleaseCapture() API to enable reading the mouse outside our Windows bounds. -IMGUI_API LRESULT ImGui_ImplDX9_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { ImGuiIO& io = ImGui::GetIO(); switch (msg) @@ -189,47 +189,47 @@ IMGUI_API LRESULT ImGui_ImplDX9_WndProcHandler(HWND hwnd, UINT msg, WPARAM wPara case WM_LBUTTONDOWN: if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); io.MouseDown[0] = true; - return true; + return 0; case WM_RBUTTONDOWN: if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); io.MouseDown[1] = true; - return true; + return 0; case WM_MBUTTONDOWN: if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); io.MouseDown[2] = true; - return true; + return 0; case WM_LBUTTONUP: io.MouseDown[0] = false; if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); - return true; + return 0; case WM_RBUTTONUP: io.MouseDown[1] = false; if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); - return true; + return 0; case WM_MBUTTONUP: io.MouseDown[2] = false; if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); - return true; + return 0; case WM_MOUSEWHEEL: io.MouseWheel += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f; - return true; + return 0; case WM_MOUSEMOVE: io.MousePos.x = (signed short)(lParam); io.MousePos.y = (signed short)(lParam >> 16); - return true; + return 0; case WM_KEYDOWN: if (wParam < 256) io.KeysDown[wParam] = 1; - return true; + return 0; case WM_KEYUP: if (wParam < 256) io.KeysDown[wParam] = 0; - return true; + return 0; case WM_CHAR: // You can also use ToAscii()+GetKeyboardState() to retrieve characters. if (wParam > 0 && wParam < 0x10000) io.AddInputCharacter((unsigned short)wParam); - return true; + return 0; } return 0; } diff --git a/examples/directx9_example/main.cpp b/examples/directx9_example/main.cpp index b8e5907c8..6a359c62b 100644 --- a/examples/directx9_example/main.cpp +++ b/examples/directx9_example/main.cpp @@ -12,10 +12,10 @@ static LPDIRECT3DDEVICE9 g_pd3dDevice = NULL; static D3DPRESENT_PARAMETERS g_d3dpp; -extern LRESULT ImGui_ImplDX9_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); +extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { - if (ImGui_ImplDX9_WndProcHandler(hWnd, msg, wParam, lParam)) + if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) return true; switch (msg) From d6a99567812e3a20cf828fc4976942df233302a7 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 23 Oct 2017 10:01:18 +0200 Subject: [PATCH 472/921] Examples: DirectX9/10/11: Added WM_SYSKEYDOWN / WM_SYSKEYUP handlers so e.g. VK_MENU can be read. --- examples/directx10_example/imgui_impl_dx10.cpp | 2 ++ examples/directx11_example/imgui_impl_dx11.cpp | 2 ++ examples/directx9_example/imgui_impl_dx9.cpp | 2 ++ 3 files changed, 6 insertions(+) diff --git a/examples/directx10_example/imgui_impl_dx10.cpp b/examples/directx10_example/imgui_impl_dx10.cpp index 13dc99c95..816e56211 100644 --- a/examples/directx10_example/imgui_impl_dx10.cpp +++ b/examples/directx10_example/imgui_impl_dx10.cpp @@ -271,10 +271,12 @@ IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wPa io.MousePos.y = (signed short)(lParam >> 16); return 0; case WM_KEYDOWN: + case WM_SYSKEYDOWN: if (wParam < 256) io.KeysDown[wParam] = 1; return 0; case WM_KEYUP: + case WM_SYSKEYUP: if (wParam < 256) io.KeysDown[wParam] = 0; return 0; diff --git a/examples/directx11_example/imgui_impl_dx11.cpp b/examples/directx11_example/imgui_impl_dx11.cpp index 6d057e07c..7b3a3ba83 100644 --- a/examples/directx11_example/imgui_impl_dx11.cpp +++ b/examples/directx11_example/imgui_impl_dx11.cpp @@ -278,10 +278,12 @@ IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wPa io.MousePos.y = (signed short)(lParam >> 16); return 0; case WM_KEYDOWN: + case WM_SYSKEYDOWN: if (wParam < 256) io.KeysDown[wParam] = 1; return 0; case WM_KEYUP: + case WM_SYSKEYUP: if (wParam < 256) io.KeysDown[wParam] = 0; return 0; diff --git a/examples/directx9_example/imgui_impl_dx9.cpp b/examples/directx9_example/imgui_impl_dx9.cpp index 111ed8153..fc05c9ce5 100644 --- a/examples/directx9_example/imgui_impl_dx9.cpp +++ b/examples/directx9_example/imgui_impl_dx9.cpp @@ -218,10 +218,12 @@ IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wPa io.MousePos.y = (signed short)(lParam >> 16); return 0; case WM_KEYDOWN: + case WM_SYSKEYDOWN: if (wParam < 256) io.KeysDown[wParam] = 1; return 0; case WM_KEYUP: + case WM_SYSKEYUP: if (wParam < 256) io.KeysDown[wParam] = 0; return 0; From 50f5be9266ce21391597695dc80b15a4724447cc Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 23 Oct 2017 10:04:38 +0200 Subject: [PATCH 473/921] Examples: GLFW+GL2/GL3: Minor tweaks, comments. --- examples/opengl2_example/imgui_impl_glfw.cpp | 9 +++++---- examples/opengl3_example/imgui_impl_glfw_gl3.cpp | 9 +++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/examples/opengl2_example/imgui_impl_glfw.cpp b/examples/opengl2_example/imgui_impl_glfw.cpp index 236a2d101..4aed20a6f 100644 --- a/examples/opengl2_example/imgui_impl_glfw.cpp +++ b/examples/opengl2_example/imgui_impl_glfw.cpp @@ -26,7 +26,7 @@ // Data static GLFWwindow* g_Window = NULL; static double g_Time = 0.0f; -static bool g_MousePressed[3] = { false, false, false }; +static bool g_MouseJustPressed[3] = { false, false, false }; static float g_MouseWheel = 0.0f; static GLuint g_FontTexture = 0; @@ -129,7 +129,7 @@ static void ImGui_ImplGlfwGL2_SetClipboardText(void* user_data, const char* text void ImGui_ImplGlfwGL2_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/) { if (action == GLFW_PRESS && button >= 0 && button < 3) - g_MousePressed[button] = true; + g_MouseJustPressed[button] = true; } void ImGui_ImplGlfwGL2_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset) @@ -287,8 +287,9 @@ void ImGui_ImplGlfwGL2_NewFrame() for (int i = 0; i < 3; i++) { - io.MouseDown[i] = g_MousePressed[i] || glfwGetMouseButton(g_Window, i) != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. - g_MousePressed[i] = false; + // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. + io.MouseDown[i] = g_MouseJustPressed[i] || glfwGetMouseButton(g_Window, i) != 0; + g_MouseJustPressed[i] = false; } io.MouseWheel = g_MouseWheel; diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp index ac711b91e..3611d6e6c 100644 --- a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp +++ b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp @@ -22,7 +22,7 @@ // Data static GLFWwindow* g_Window = NULL; static double g_Time = 0.0f; -static bool g_MousePressed[3] = { false, false, false }; +static bool g_MouseJustPressed[3] = { false, false, false }; static float g_MouseWheel = 0.0f; static GLuint g_FontTexture = 0; static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; @@ -150,7 +150,7 @@ static void ImGui_ImplGlfwGL3_SetClipboardText(void* user_data, const char* text void ImGui_ImplGlfwGL3_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/) { if (action == GLFW_PRESS && button >= 0 && button < 3) - g_MousePressed[button] = true; + g_MouseJustPressed[button] = true; } void ImGui_ImplGlfwGL3_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset) @@ -401,8 +401,9 @@ void ImGui_ImplGlfwGL3_NewFrame() for (int i = 0; i < 3; i++) { - io.MouseDown[i] = g_MousePressed[i] || glfwGetMouseButton(g_Window, i) != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. - g_MousePressed[i] = false; + // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. + io.MouseDown[i] = g_MouseJustPressed[i] || glfwGetMouseButton(g_Window, i) != 0; + g_MouseJustPressed[i] = false; } io.MouseWheel = g_MouseWheel; From e7922b3fa0df982c72e86750a419201b778e282d Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 23 Oct 2017 12:34:15 +0200 Subject: [PATCH 474/921] Factorized some code (+ declared as static function without namespace, a pattern with the Nav branch has started to use) --- imgui.cpp | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 8ad739fa0..239566c0d 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -659,6 +659,11 @@ static inline void DataTypeFormatString(ImGuiDataType data_type, void* data static void DataTypeApplyOp(ImGuiDataType data_type, int op, void* value1, const void* value2); static bool DataTypeApplyOpFromText(const char* buf, const char* initial_value_buf, ImGuiDataType data_type, void* data_ptr, const char* scalar_format); +namespace ImGui +{ +static void FocusPreviousWindow(); +} + //----------------------------------------------------------------------------- // Platform dependent default implementations //----------------------------------------------------------------------------- @@ -2434,12 +2439,7 @@ void ImGui::NewFrame() // Closing the focused window restore focus to the first active root window in descending z-order if (g.NavWindow && !g.NavWindow->WasActive) - for (int i = g.Windows.Size-1; i >= 0; i--) - if (g.Windows[i]->WasActive && !(g.Windows[i]->Flags & ImGuiWindowFlags_ChildWindow)) - { - FocusWindow(g.Windows[i]); - break; - } + FocusPreviousWindow(); // No window should be open at the beginning of the frame. // But in order to allow the user to call NewFrame() multiple times without calling Render(), we are doing an explicit clear. @@ -4833,6 +4833,17 @@ void ImGui::FocusWindow(ImGuiWindow* window) g.Windows.push_back(window); } +void ImGui::FocusPreviousWindow() +{ + ImGuiContext& g = *GImGui; + for (int i = g.Windows.Size - 1; i >= 0; i--) + if (g.Windows[i]->WasActive && !(g.Windows[i]->Flags & ImGuiWindowFlags_ChildWindow)) + { + FocusWindow(g.Windows[i]); + return; + } +} + void ImGui::PushItemWidth(float item_width) { ImGuiWindow* window = GetCurrentWindow(); From 97bf2131e20e647417fa9a8c988b0fa082c7f0f7 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 23 Oct 2017 14:37:47 +0200 Subject: [PATCH 475/921] Fixed calling SetNextTreeNodeOpen() on a collapsed window leaking to next frame. --- imgui.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/imgui.cpp b/imgui.cpp index 239566c0d..ab6b2906f 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -6472,6 +6472,8 @@ float ImGui::GetTreeNodeToLabelSpacing() void ImGui::SetNextTreeNodeOpen(bool is_open, ImGuiCond cond) { ImGuiContext& g = *GImGui; + if (g.CurrentWindow->SkipItems) + return; g.SetNextTreeNodeOpenVal = is_open; g.SetNextTreeNodeOpenCond = cond ? cond : ImGuiCond_Always; } From de72e9cc87e9f2da56145c3bd3c4681443c05184 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 19 Oct 2017 23:29:27 +0200 Subject: [PATCH 476/921] Internals: ImLerp() helper for ImVec4 --- imgui_internal.h | 1 + 1 file changed, 1 insertion(+) diff --git a/imgui_internal.h b/imgui_internal.h index 8f8dcc6c7..39efdb2bc 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -147,6 +147,7 @@ static inline int ImLerp(int a, int b, float t) static inline float ImLerp(float a, float b, float t) { return a + (b - a) * t; } static inline ImVec2 ImLerp(const ImVec2& a, const ImVec2& b, float t) { return ImVec2(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t); } static inline ImVec2 ImLerp(const ImVec2& a, const ImVec2& b, const ImVec2& t) { return ImVec2(a.x + (b.x - a.x) * t.x, a.y + (b.y - a.y) * t.y); } +static inline ImVec4 ImLerp(const ImVec4& a, const ImVec4& b, float t) { return ImVec4(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t, a.z + (b.z - a.z) * t, a.w + (b.w - a.w) * t); } static inline float ImLengthSqr(const ImVec2& lhs) { return lhs.x*lhs.x + lhs.y*lhs.y; } static inline float ImLengthSqr(const ImVec4& lhs) { return lhs.x*lhs.x + lhs.y*lhs.y + lhs.z*lhs.z + lhs.w*lhs.w; } static inline float ImInvLength(const ImVec2& lhs, float fail_value) { float d = lhs.x*lhs.x + lhs.y*lhs.y; if (d > 0.0f) return 1.0f / sqrtf(d); return fail_value; } From e9ff7162bca1fab3f110b84b5d55e9ad26a762f6 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 24 Oct 2017 10:43:41 +0200 Subject: [PATCH 477/921] ColorButton: Fixed rendering color button with a checkerboard if the transparency comes from the global style.Alpha and not from the actual source color. --- imgui.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index ab6b2906f..15b1f9d9e 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9433,7 +9433,7 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl float grid_step = ImMin(size.x, size.y) / 2.99f; float rounding = ImMin(g.Style.FrameRounding, grid_step * 0.5f); ImRect bb_inner = bb; - float off = -0.75f; // The border (using Col_FrameBg) tends to look off when color is near-opaque and rounding is enabled. This offset seemed like a good middleground to reduce those artefacts. + float off = -0.75f; // The border (using Col_FrameBg) tends to look off when color is near-opaque and rounding is enabled. This offset seemed like a good middle ground to reduce those artifacts. bb_inner.Expand(off); if ((flags & ImGuiColorEditFlags_AlphaPreviewHalf) && col.w < 1.0f) { @@ -9443,7 +9443,12 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl } else { - RenderColorRectWithAlphaCheckerboard(bb_inner.Min, bb_inner.Max, GetColorU32((flags & ImGuiColorEditFlags_AlphaPreview) ? col : col_without_alpha), grid_step, ImVec2(off, off), rounding); + // Because GetColorU32() multiplies by the global style Alpha and we don't want to display a checkerboard if the source code had no alpha + ImVec4 col_source = (flags & ImGuiColorEditFlags_AlphaPreview) ? col : col_without_alpha; + if (col_source.w < 1.0f) + RenderColorRectWithAlphaCheckerboard(bb_inner.Min, bb_inner.Max, GetColorU32(col_source), grid_step, ImVec2(off, off), rounding); + else + window->DrawList->AddRectFilled(bb_inner.Min, bb_inner.Max, GetColorU32(col_source), rounding, ~0); } if (window->Flags & ImGuiWindowFlags_ShowBorders) RenderFrameBorder(bb.Min, bb.Max, rounding); From 0260fdd1c6c7198d60fcbd02cce82e4deb8954f4 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 24 Oct 2017 12:10:37 +0200 Subject: [PATCH 478/921] ColorButton: As a small convenience, provide a text baseline. --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 15b1f9d9e..b8bf8d58a 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9419,7 +9419,7 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl if (size.y == 0.0f) size.y = default_size; const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size); - ItemSize(bb); + ItemSize(bb, (size.y >= default_size) ? g.Style.FramePadding.y : 0.0f); if (!ItemAdd(bb, id)) return false; From d2c65aa3e86b99e458cc562828041908b3b82679 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 24 Oct 2017 14:48:00 +0200 Subject: [PATCH 479/921] Examples: DirectX9/10/11: Tweak usage of SetCapture/ReleaseCapture. (#1375) ps: DirectX 12 example (#302) may want to adopt that as well. --- .../directx10_example/imgui_impl_dx10.cpp | 35 +++++++++--------- .../directx11_example/imgui_impl_dx11.cpp | 35 +++++++++--------- examples/directx9_example/imgui_impl_dx9.cpp | 36 ++++++++++--------- 3 files changed, 57 insertions(+), 49 deletions(-) diff --git a/examples/directx10_example/imgui_impl_dx10.cpp b/examples/directx10_example/imgui_impl_dx10.cpp index 816e56211..06171250b 100644 --- a/examples/directx10_example/imgui_impl_dx10.cpp +++ b/examples/directx10_example/imgui_impl_dx10.cpp @@ -234,35 +234,38 @@ static bool IsAnyMouseButtonDown() return false; } +// We use the Win32 capture API (GetCapture/SetCapture/ReleaseCapture) to be able to read mouse coordinations when dragging mouse outside of our window bounds. IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { ImGuiIO& io = ImGui::GetIO(); switch (msg) { case WM_LBUTTONDOWN: - if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); - io.MouseDown[0] = true; - return 0; case WM_RBUTTONDOWN: - if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); - io.MouseDown[1] = true; - return 0; case WM_MBUTTONDOWN: - if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); - io.MouseDown[2] = true; + { + int button = 0; + if (msg == WM_LBUTTONDOWN) button = 0; + if (msg == WM_RBUTTONDOWN) button = 1; + if (msg == WM_MBUTTONDOWN) button = 2; + if (!IsAnyMouseButtonDown() && GetCapture() == NULL) + SetCapture(hwnd); + io.MouseDown[button] = true; return 0; + } case WM_LBUTTONUP: - io.MouseDown[0] = false; - if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); - return 0; case WM_RBUTTONUP: - io.MouseDown[1] = false; - if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); - return 0; case WM_MBUTTONUP: - io.MouseDown[2] = false; - if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + { + int button = 0; + if (msg == WM_LBUTTONUP) button = 0; + if (msg == WM_RBUTTONUP) button = 1; + if (msg == WM_MBUTTONUP) button = 2; + io.MouseDown[button] = false; + if (!IsAnyMouseButtonDown() && GetCapture() == hwnd) + ReleaseCapture(); return 0; + } case WM_MOUSEWHEEL: io.MouseWheel += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f; return 0; diff --git a/examples/directx11_example/imgui_impl_dx11.cpp b/examples/directx11_example/imgui_impl_dx11.cpp index 7b3a3ba83..1f69bd727 100644 --- a/examples/directx11_example/imgui_impl_dx11.cpp +++ b/examples/directx11_example/imgui_impl_dx11.cpp @@ -241,35 +241,38 @@ static bool IsAnyMouseButtonDown() return false; } +// We use the Win32 capture API (GetCapture/SetCapture/ReleaseCapture) to be able to read mouse coordinations when dragging mouse outside of our window bounds. IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { ImGuiIO& io = ImGui::GetIO(); switch (msg) { case WM_LBUTTONDOWN: - if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); - io.MouseDown[0] = true; - return 0; case WM_RBUTTONDOWN: - if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); - io.MouseDown[1] = true; - return 0; case WM_MBUTTONDOWN: - if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); - io.MouseDown[2] = true; + { + int button = 0; + if (msg == WM_LBUTTONDOWN) button = 0; + if (msg == WM_RBUTTONDOWN) button = 1; + if (msg == WM_MBUTTONDOWN) button = 2; + if (!IsAnyMouseButtonDown() && GetCapture() == NULL) + SetCapture(hwnd); + io.MouseDown[button] = true; return 0; + } case WM_LBUTTONUP: - io.MouseDown[0] = false; - if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); - return 0; case WM_RBUTTONUP: - io.MouseDown[1] = false; - if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); - return 0; case WM_MBUTTONUP: - io.MouseDown[2] = false; - if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + { + int button = 0; + if (msg == WM_LBUTTONUP) button = 0; + if (msg == WM_RBUTTONUP) button = 1; + if (msg == WM_MBUTTONUP) button = 2; + io.MouseDown[button] = false; + if (!IsAnyMouseButtonDown() && GetCapture() == hwnd) + ReleaseCapture(); return 0; + } case WM_MOUSEWHEEL: io.MouseWheel += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f; return 0; diff --git a/examples/directx9_example/imgui_impl_dx9.cpp b/examples/directx9_example/imgui_impl_dx9.cpp index fc05c9ce5..02d2fd593 100644 --- a/examples/directx9_example/imgui_impl_dx9.cpp +++ b/examples/directx9_example/imgui_impl_dx9.cpp @@ -180,36 +180,38 @@ static bool IsAnyMouseButtonDown() return false; } -// We use Win32 SetCapture/ReleaseCapture() API to enable reading the mouse outside our Windows bounds. +// We use the Win32 capture API (GetCapture/SetCapture/ReleaseCapture) to be able to read mouse coordinations when dragging mouse outside of our window bounds. IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { ImGuiIO& io = ImGui::GetIO(); switch (msg) { case WM_LBUTTONDOWN: - if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); - io.MouseDown[0] = true; - return 0; case WM_RBUTTONDOWN: - if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); - io.MouseDown[1] = true; - return 0; case WM_MBUTTONDOWN: - if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd); - io.MouseDown[2] = true; + { + int button = 0; + if (msg == WM_LBUTTONDOWN) button = 0; + if (msg == WM_RBUTTONDOWN) button = 1; + if (msg == WM_MBUTTONDOWN) button = 2; + if (!IsAnyMouseButtonDown() && GetCapture() == NULL) + SetCapture(hwnd); + io.MouseDown[button] = true; return 0; + } case WM_LBUTTONUP: - io.MouseDown[0] = false; - if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); - return 0; case WM_RBUTTONUP: - io.MouseDown[1] = false; - if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); - return 0; case WM_MBUTTONUP: - io.MouseDown[2] = false; - if (!IsAnyMouseButtonDown()) ::ReleaseCapture(); + { + int button = 0; + if (msg == WM_LBUTTONUP) button = 0; + if (msg == WM_RBUTTONUP) button = 1; + if (msg == WM_MBUTTONUP) button = 2; + io.MouseDown[button] = false; + if (!IsAnyMouseButtonDown() && GetCapture() == hwnd) + ReleaseCapture(); return 0; + } case WM_MOUSEWHEEL: io.MouseWheel += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f; return 0; From 5b062c4c29a76c345cfedbba57fcd60bf11e0de5 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 24 Oct 2017 15:26:04 +0200 Subject: [PATCH 480/921] Fixed typos --- imgui.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index b8bf8d58a..eedd3d86f 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -216,8 +216,9 @@ Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. Also read releases logs https://github.com/ocornut/imgui/releases for more details. - - 2017/10/20 (1.52) - changed IsWindowHovered() default parameters behavior to return false an item is active in another window (e.g. click-dragging item from another window to this window). You can use the newly introduced IsWindowHovered() flags to requests that specific behavior if you need it. - - 2017/10/20 (1.52) - removed the IsItemRectHovered()/IsWindowRectHovered() names introduced in 1.51, the new flags available for IsItemHovered() and IsWindowHovered() are providing much more details/options, and those legacy entry points were confusing/misleading. + - 2017/10/20 (1.52) - changed IsWindowHovered() default parameters behavior to return false if an item is active in another window (e.g. click-dragging item from another window to this window). You can use the newly introduced IsWindowHovered() flags to requests this specific behavior if you need it. + - 2017/10/20 (1.52) - marked IsItemHoveredRect()/IsMouseHoveringWindow() as obsolete, in favor of using the newly introduced flags for IsItemHovered() and IsWindowHovered(). See https://github.com/ocornut/imgui/issues/1382 for details. + removed the IsItemRectHovered()/IsWindowRectHovered() names introduced in 1.51 since they were merely more consistent names for the two functions we are now obsoleting. - 2017/10/17 (1.52) - marked the old 5-parameters version of Begin() as obsolete (still available). Use SetNextWindowSize()+Begin() instead! - 2017/10/11 (1.52) - renamed AlignFirstTextHeightToWidgets() to AlignTextToFramePadding(). Kept inline redirection function (will obsolete). - 2017/09/25 (1.52) - removed SetNextWindowPosCenter() because SetNextWindowPos() now has the optional pivot information to do the same and more. Kept redirection function (will obsolete). From bc447bc0a4b398f371867ceaa65f26e5c094484f Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 24 Oct 2017 16:08:05 +0200 Subject: [PATCH 481/921] ImFontAtlas: Fixed memory leak if stbtt_InitFont() returned false. (#1391) --- imgui_draw.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index c3a5f3d5c..8137f4769 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1475,7 +1475,10 @@ bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas) const int font_offset = stbtt_GetFontOffsetForIndex((unsigned char*)cfg.FontData, cfg.FontNo); IM_ASSERT(font_offset >= 0); if (!stbtt_InitFont(&tmp.FontInfo, (unsigned char*)cfg.FontData, font_offset)) + { + ImGui::MemFree(tmp_array); return false; + } } // Allocate packing character data and flag packed characters buffer as non-packed (x0=y0=x1=y1=0) From 70cb427469de3da6e0d0db8b806c33b2899f08bf Mon Sep 17 00:00:00 2001 From: Patrick Doane Date: Tue, 24 Oct 2017 10:25:02 -0700 Subject: [PATCH 482/921] Add missing CloseClipboard call --- imgui.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/imgui.cpp b/imgui.cpp index eedd3d86f..629598540 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -10661,7 +10661,10 @@ static void SetClipboardTextFn_DefaultImpl(void*, const char* text) const int wbuf_length = ImTextCountCharsFromUtf8(text, NULL) + 1; HGLOBAL wbuf_handle = GlobalAlloc(GMEM_MOVEABLE, (SIZE_T)wbuf_length * sizeof(ImWchar)); if (wbuf_handle == NULL) + { + CloseClipboard(); return; + } ImWchar* wbuf_global = (ImWchar*)GlobalLock(wbuf_handle); ImTextStrFromUtf8(wbuf_global, wbuf_length, text, NULL); GlobalUnlock(wbuf_handle); From 7d2cd0e6ff96f8e802a06c79e5946a083d76025c Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 24 Oct 2017 20:19:32 +0200 Subject: [PATCH 483/921] Added IMGUI_DISABLE_FORMAT_STRING_FUNCTIONS support in imconfig.h (#1038) --- imconfig.h | 9 ++++++--- imgui.cpp | 2 ++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/imconfig.h b/imconfig.h index e557fa065..b175c9b26 100644 --- a/imconfig.h +++ b/imconfig.h @@ -13,6 +13,9 @@ //#define IMGUI_API __declspec( dllexport ) //#define IMGUI_API __declspec( dllimport ) +//---- Don't define obsolete functions names. Consider enabling from time to time or when updating to reduce like hood of using already obsolete function/names +//#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS + //---- Include imgui_user.h at the end of imgui.h //#define IMGUI_INCLUDE_IMGUI_USER_H @@ -24,13 +27,13 @@ //---- It is very strongly recommended to NOT disable the test windows. Please read the comment at the top of imgui_demo.cpp to learn why. //#define IMGUI_DISABLE_TEST_WINDOWS -//---- Don't define obsolete functions names. Consider enabling from time to time or when updating to reduce like hood of using already obsolete function/names -//#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS +//---- Don't implement ImFormatString(), ImFormatStringV() so you can reimplement them yourself. +//#define IMGUI_DISABLE_FORMAT_STRING_FUNCTIONS //---- Pack colors to BGRA instead of RGBA (remove need to post process vertex buffer in back ends) //#define IMGUI_USE_BGRA_PACKED_COLOR -//---- Implement STB libraries in a namespace to avoid conflicts +//---- Implement STB libraries in a namespace to avoid linkage conflicts //#define IMGUI_STB_NAMESPACE ImGuiStb //---- Define constructor and implicit cast operators to convert back<>forth from your math types and ImVec2/ImVec4. diff --git a/imgui.cpp b/imgui.cpp index 629598540..0b56b6354 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1011,6 +1011,7 @@ static const char* ImAtoi(const char* src, int* output) // MSVC version appears to return -1 on overflow, whereas glibc appears to return total count (which may be >= buf_size). // Ideally we would test for only one of those limits at runtime depending on the behavior the vsnprintf(), but trying to deduct it at compile time sounds like a pandora can of worm. +#ifndef IMGUI_DISABLE_FORMAT_STRING_FUNCTIONS int ImFormatString(char* buf, int buf_size, const char* fmt, ...) { IM_ASSERT(buf_size > 0); @@ -1033,6 +1034,7 @@ int ImFormatStringV(char* buf, int buf_size, const char* fmt, va_list args) buf[w] = 0; return w; } +#endif // #ifdef IMGUI_DISABLE_FORMAT_STRING_FUNCTIONS // Pass data_size==0 for zero-terminated strings // FIXME-OPT: Replace with e.g. FNV1a hash? CRC32 pretty much randomly access 1KB. Need to do proper measurements. From 8fd5620277f3d89605ff8e2c286d744194f89e25 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 24 Oct 2017 20:23:42 +0200 Subject: [PATCH 484/921] Renamed IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCS/IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCS to IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS/IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS for consistency. (ref #238, #520, #738) --- imconfig.h | 4 ++-- imgui.cpp | 7 ++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/imconfig.h b/imconfig.h index b175c9b26..85eff5fd4 100644 --- a/imconfig.h +++ b/imconfig.h @@ -20,8 +20,8 @@ //#define IMGUI_INCLUDE_IMGUI_USER_H //---- Don't implement default handlers for Windows (so as not to link with OpenClipboard() and others Win32 functions) -//#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCS -//#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCS +//#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS +//#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS //---- Don't implement test window functionality (ShowTestWindow()/ShowStyleEditor()/ShowUserGuide() methods will be empty) //---- It is very strongly recommended to NOT disable the test windows. Please read the comment at the top of imgui_demo.cpp to learn why. diff --git a/imgui.cpp b/imgui.cpp index 0b56b6354..fd1c44de8 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -216,6 +216,7 @@ Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. Also read releases logs https://github.com/ocornut/imgui/releases for more details. + - 2017/10/24 (1.52) - renamed IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCS/IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCS to IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS/IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS for consistency. - 2017/10/20 (1.52) - changed IsWindowHovered() default parameters behavior to return false if an item is active in another window (e.g. click-dragging item from another window to this window). You can use the newly introduced IsWindowHovered() flags to requests this specific behavior if you need it. - 2017/10/20 (1.52) - marked IsItemHoveredRect()/IsMouseHoveringWindow() as obsolete, in favor of using the newly introduced flags for IsItemHovered() and IsWindowHovered(). See https://github.com/ocornut/imgui/issues/1382 for details. removed the IsItemRectHovered()/IsWindowRectHovered() names introduced in 1.51 since they were merely more consistent names for the two functions we are now obsoleting. @@ -10620,14 +10621,14 @@ void ImGui::Value(const char* prefix, float v, const char* float_format) // PLATFORM DEPENDENT HELPERS //----------------------------------------------------------------------------- -#if defined(_WIN32) && !defined(_WINDOWS_) && (!defined(IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCS) || !defined(IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCS)) +#if defined(_WIN32) && !defined(_WINDOWS_) && (!defined(IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS) || !defined(IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS)) #undef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #include #endif // Win32 API clipboard implementation -#if defined(_WIN32) && !defined(IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCS) +#if defined(_WIN32) && !defined(IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS) #ifdef _MSC_VER #pragma comment(lib, "user32") @@ -10698,7 +10699,7 @@ static void SetClipboardTextFn_DefaultImpl(void*, const char* text) #endif // Win32 API IME support (for Asian languages, etc.) -#if defined(_WIN32) && !defined(__GNUC__) && !defined(IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCS) +#if defined(_WIN32) && !defined(__GNUC__) && !defined(IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS) #include #ifdef _MSC_VER From 1f3372b7f1fbf73a2b701fafbeb0af086d0f508f Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 24 Oct 2017 20:48:29 +0200 Subject: [PATCH 485/921] ImFormatString, ImFormatStringV(): clarifying specs so that passing a NULL buffer should return the desired length. (#1038) --- imgui.cpp | 13 ++++++++----- imgui_demo.cpp | 1 + 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index fd1c44de8..6d2ff61c9 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1010,16 +1010,18 @@ static const char* ImAtoi(const char* src, int* output) return src; } -// MSVC version appears to return -1 on overflow, whereas glibc appears to return total count (which may be >= buf_size). +// A) MSVC version appears to return -1 on overflow, whereas glibc appears to return total count (which may be >= buf_size). // Ideally we would test for only one of those limits at runtime depending on the behavior the vsnprintf(), but trying to deduct it at compile time sounds like a pandora can of worm. +// B) When buf==NULL vsnprintf() will return the output size. #ifndef IMGUI_DISABLE_FORMAT_STRING_FUNCTIONS int ImFormatString(char* buf, int buf_size, const char* fmt, ...) { - IM_ASSERT(buf_size > 0); va_list args; va_start(args, fmt); int w = vsnprintf(buf, buf_size, fmt, args); va_end(args); + if (buf == NULL) + return w; if (w == -1 || w >= buf_size) w = buf_size - 1; buf[w] = 0; @@ -1028,8 +1030,9 @@ int ImFormatString(char* buf, int buf_size, const char* fmt, ...) int ImFormatStringV(char* buf, int buf_size, const char* fmt, va_list args) { - IM_ASSERT(buf_size > 0); int w = vsnprintf(buf, buf_size, fmt, args); + if (buf == NULL) + return w; if (w == -1 || w >= buf_size) w = buf_size - 1; buf[w] = 0; @@ -1671,7 +1674,7 @@ void ImGuiTextBuffer::appendv(const char* fmt, va_list args) va_list args_copy; va_copy(args_copy, args); - int len = vsnprintf(NULL, 0, fmt, args); // FIXME-OPT: could do a first pass write attempt, likely successful on first pass. + int len = ImFormatStringV(NULL, 0, fmt, args); // FIXME-OPT: could do a first pass write attempt, likely successful on first pass. if (len <= 0) return; @@ -1684,7 +1687,7 @@ void ImGuiTextBuffer::appendv(const char* fmt, va_list args) } Buf.resize(needed_sz); - ImFormatStringV(&Buf[write_off] - 1, len+1, fmt, args_copy); + ImFormatStringV(&Buf[write_off - 1], len + 1, fmt, args_copy); } void ImGuiTextBuffer::append(const char* fmt, ...) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 35ee618b9..5fe78dbe5 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -2359,6 +2359,7 @@ struct ExampleAppConsole void AddLog(const char* fmt, ...) IM_FMTARGS(2) { + // FIXME-OPT char buf[1024]; va_list args; va_start(args, fmt); From efcd53a0c31c9f2ae5b2f1d21ab74a18ac1b97f3 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 24 Oct 2017 20:57:41 +0200 Subject: [PATCH 486/921] Removed direct dependency on sprintf() in imgui.cpp (#1038) (NB: imgui_demo stills uses it) --- imgui.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 6d2ff61c9..90a31c52b 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9502,16 +9502,16 @@ void ImGui::ColorEditOptionsPopup(const float* col, ImGuiColorEditFlags flags) { int cr = IM_F32_TO_INT8_SAT(col[0]), cg = IM_F32_TO_INT8_SAT(col[1]), cb = IM_F32_TO_INT8_SAT(col[2]), ca = (flags & ImGuiColorEditFlags_NoAlpha) ? 255 : IM_F32_TO_INT8_SAT(col[3]); char buf[64]; - sprintf(buf, "(%.3ff, %.3ff, %.3ff, %.3ff)", col[0], col[1], col[2], (flags & ImGuiColorEditFlags_NoAlpha) ? 1.0f : col[3]); + ImFormatString(buf, IM_ARRAYSIZE(buf), "(%.3ff, %.3ff, %.3ff, %.3ff)", col[0], col[1], col[2], (flags & ImGuiColorEditFlags_NoAlpha) ? 1.0f : col[3]); if (Selectable(buf)) SetClipboardText(buf); - sprintf(buf, "(%d,%d,%d,%d)", cr, cg, cb, ca); + ImFormatString(buf, IM_ARRAYSIZE(buf), "(%d,%d,%d,%d)", cr, cg, cb, ca); if (Selectable(buf)) SetClipboardText(buf); if (flags & ImGuiColorEditFlags_NoAlpha) - sprintf(buf, "0x%02X%02X%02X", cr, cg, cb); + ImFormatString(buf, IM_ARRAYSIZE(buf), "0x%02X%02X%02X", cr, cg, cb); else - sprintf(buf, "0x%02X%02X%02X%02X", cr, cg, cb, ca); + ImFormatString(buf, IM_ARRAYSIZE(buf), "0x%02X%02X%02X%02X", cr, cg, cb, ca); if (Selectable(buf)) SetClipboardText(buf); EndPopup(); @@ -10789,13 +10789,14 @@ void ImGui::ShowMetricsWindow(bool* p_open) while (clipper.Step()) for (int prim = clipper.DisplayStart, vtx_i = elem_offset + clipper.DisplayStart*3; prim < clipper.DisplayEnd; prim++) { - char buf[300], *buf_p = buf; + char buf[300]; + char *buf_p = buf, *buf_end = buf + IM_ARRAYSIZE(buf); ImVec2 triangles_pos[3]; for (int n = 0; n < 3; n++, vtx_i++) { ImDrawVert& v = draw_list->VtxBuffer[idx_buffer ? idx_buffer[vtx_i] : vtx_i]; triangles_pos[n] = v.pos; - buf_p += sprintf(buf_p, "%s %04d { pos = (%8.2f,%8.2f), uv = (%.6f,%.6f), col = %08X }\n", (n == 0) ? "vtx" : " ", vtx_i, v.pos.x, v.pos.y, v.uv.x, v.uv.y, v.col); + buf_p += ImFormatString(buf_p, (int)(buf_end - buf_p), "%s %04d { pos = (%8.2f,%8.2f), uv = (%.6f,%.6f), col = %08X }\n", (n == 0) ? "vtx" : " ", vtx_i, v.pos.x, v.pos.y, v.uv.x, v.uv.y, v.col); } ImGui::Selectable(buf, false); if (ImGui::IsItemHovered()) From 4faf99eff564d68bef9e43cb293c851fc489afc3 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 25 Oct 2017 09:28:54 +0200 Subject: [PATCH 487/921] Added most basic form of Disabled flag to disable interactions (but visuals aren't altered), in imgui_internals.h, undocumented/unsupported (#211, #1012) --- imgui.cpp | 6 +++++- imgui_internal.h | 7 ++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 90a31c52b..c77d4d7f4 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2051,6 +2051,8 @@ bool ImGui::IsItemHovered(ImGuiHoveredFlags flags) return false; if (!IsWindowContentHoverable(window, flags)) return false; + if (window->DC.ItemFlags & ImGuiItemFlags_Disabled) + return false; return true; } @@ -2070,6 +2072,8 @@ bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id) return false; if (!IsWindowContentHoverable(window, ImGuiHoveredFlags_Default)) return false; + if (window->DC.ItemFlags & ImGuiItemFlags_Disabled) + return false; SetHoveredID(id); return true; @@ -2090,7 +2094,7 @@ bool ImGui::FocusableItemRegister(ImGuiWindow* window, ImGuiID id, bool tab_stop { ImGuiContext& g = *GImGui; - const bool allow_keyboard_focus = (window->DC.ItemFlags & ImGuiItemFlags_AllowKeyboardFocus) != 0; + const bool allow_keyboard_focus = (window->DC.ItemFlags & (ImGuiItemFlags_AllowKeyboardFocus | ImGuiItemFlags_Disabled)) == ImGuiItemFlags_AllowKeyboardFocus; window->FocusIdxAllCounter++; if (allow_keyboard_focus) window->FocusIdxTabCounter++; diff --git a/imgui_internal.h b/imgui_internal.h index 39efdb2bc..24e484121 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -582,9 +582,10 @@ enum ImGuiItemFlags_ { ImGuiItemFlags_AllowKeyboardFocus = 1 << 0, // true ImGuiItemFlags_ButtonRepeat = 1 << 1, // false // Button() will return true multiple times based on io.KeyRepeatDelay and io.KeyRepeatRate settings. - //ImGuiItemFlags_Disabled = 1 << 2, // false // All widgets appears are disabled - //ImGuiItemFlags_AllowNavDefaultFocus = 1 << 3, // true - ImGuiItemFlags_SelectableDontClosePopup = 1 << 4, // false // MenuItem/Selectable() automatically closes current Popup window + ImGuiItemFlags_Disabled = 1 << 2, // false // FIXME-WIP: Disable interactions but doesn't affect visuals. Should be: grey out and disable interactions with widgets that affect data + view widgets (WIP) + //ImGuiItemFlags_NoNav = 1 << 3, // false + //ImGuiItemFlags_NoNavDefaultFocus = 1 << 4, // false + ImGuiItemFlags_SelectableDontClosePopup = 1 << 5, // false // MenuItem/Selectable() automatically closes current Popup window ImGuiItemFlags_Default_ = ImGuiItemFlags_AllowKeyboardFocus }; From daef33e268264211e244e3e3294ea7e00adf29e6 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 25 Oct 2017 11:01:41 +0200 Subject: [PATCH 488/921] Comments about mouse setup and clearing HoveredWindow when mouse down isn't owned by imgui (will affect some future hovered test and drag'n drop patterns) (#143, #1382, #1392) --- imgui.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index c77d4d7f4..2d27a79e0 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2382,7 +2382,7 @@ void ImGui::NewFrame() g.ModalWindowDarkeningRatio = 0.0f; } - // Are we using inputs? Tell user so they can capture/discard the inputs away from the rest of their application. + // Update the WantCaptureMouse/WantCAptureKeyboard flags, so user can capture/discard the inputs away from the rest of their application. // When clicking outside of a window we assume the click is owned by the application and won't request capture. We need to track click ownership. int mouse_earliest_button_down = -1; bool mouse_any_down = false; @@ -2392,7 +2392,7 @@ void ImGui::NewFrame() g.IO.MouseDownOwned[i] = (g.HoveredWindow != NULL) || (!g.OpenPopupStack.empty()); mouse_any_down |= g.IO.MouseDown[i]; if (g.IO.MouseDown[i]) - if (mouse_earliest_button_down == -1 || g.IO.MouseClickedTime[mouse_earliest_button_down] > g.IO.MouseClickedTime[i]) + if (mouse_earliest_button_down == -1 || g.IO.MouseClickedTime[i] < g.IO.MouseClickedTime[mouse_earliest_button_down]) mouse_earliest_button_down = i; } bool mouse_avail_to_imgui = (mouse_earliest_button_down == -1) || g.IO.MouseDownOwned[mouse_earliest_button_down]; @@ -2407,6 +2407,7 @@ void ImGui::NewFrame() g.OsImePosRequest = ImVec2(1.0f, 1.0f); // OS Input Method Editor showing on top-left of our window by default // If mouse was first clicked outside of ImGui bounds we also cancel out hovering. + // FIXME: For patterns of drag and drop between "application" and "imgui" we may need to rework/remove this test (first committed 311c0ca9 on 2015/02) if (!mouse_avail_to_imgui) g.HoveredWindow = g.HoveredRootWindow = NULL; From c5027d4fa1efea339710ef316c321146a9977830 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 25 Oct 2017 20:55:15 +0200 Subject: [PATCH 489/921] Examples: Extra clarification for the 100th person who insist on using the OpenGL2 code in spite of existing documentation leaning against it. (#1394) --- examples/README.txt | 30 +++++++++++-------- examples/opengl2_example/imgui_impl_glfw.cpp | 10 ++++--- .../sdl_opengl2_example/imgui_impl_sdl.cpp | 8 +++-- 3 files changed, 30 insertions(+), 18 deletions(-) diff --git a/examples/README.txt b/examples/README.txt index 2769c1bf4..35490b5b6 100644 --- a/examples/README.txt +++ b/examples/README.txt @@ -8,15 +8,16 @@ Third party languages and frameworks bindings: https://github.com/ocornut/imgui/ TL;DR; - Newcomers, read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup ImGui in your codebase. - - To LEARN how the library is setup, you may refer to 'opengl2_example' because is the simplest one. - The other examples requires more boilerplate and are harder to read. - However, USE 'opengl3_example' in your application if you are using any modern OpenGL3+ calls. - Mixing old fixed pipeline OpenGL2 and programmable pipeline OpenGL3+ isn't well supported by some drivers. - If you are not sure, in doubt, use 'opengl3_example'. - If you are using of the backend provided here, so you can copy the imgui_impl_xxx.cpp/h files to your project and use them unmodified. - - If you have your own engine, you probably want to start from one of the OpenGL example and adapt it to - your engine, but you can read the other examples as well. + - To LEARN how the library is setup, you may refer to 'opengl2_example' because is the simplest one to read. + However, do NOT USE the 'opengl2_example' if your code is using any modern GL3+ calls. + Mixing old fixed-pipeline OpenGL2 and modern OpenGL3+ is going to make everything more complicated. + Read comments below for details. If you are not sure, in doubt, use 'opengl3_example'. + - If you have your own engine, you probably want to read a few of the examples first then adapt it to + your engine. Please note that if your engine is based on OpenGL/DirectX you can perfectly use the + existing rendering backends, don't feel forced to rewrite them with your own engine API, or you can + do that later when you already got things to work. ImGui is highly portable and only requires a few things to run: - Providing mouse/keyboard inputs @@ -45,12 +46,12 @@ Also note that some setup or GPU drivers may be causing extra lag (possibly by e leaving you with no option but sadness/anger (Intel GPU drivers were reported as such). opengl2_example/ + *DO NOT USE THIS CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL* GLFW + OpenGL example (old, fixed graphic pipeline). - This is only provided as a reference to learn how ImGui integration works, because it is easier to read. - However, if your code is using GL3+ context, using this may confuse your driver. Please use the GL3 example below. - (You might be able to use this code in a GL3/GL4 context but make sure you disable the programmable - pipeline by calling "glUseProgram(0)" before ImGui::Render. It appears that many librairies and drivers - are having issues mixing GL2 calls and newer GL3/GL4 calls. So it isn't recommended that you use that.) + This is mostly provided as a reference to learn how ImGui integration works, because it is easier to read. + If your code is using GL3+ context or any semi modern OpenGL calls, using this is likely to make everything + more complicated, will require your code to reset every single OpenGL attributes to their initial state, + and might confuse your GPU driver. Prefer using opengl3_example. opengl3_example/ GLFW + OpenGL example (programmable pipeline, binding modern functions with GL3W). @@ -74,7 +75,12 @@ apple_example/ Synergy keyboard integration is rather hacky. sdl_opengl2_example/ + *DO NOT USE THIS CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL* SDL2 + OpenGL example (old fixed pipeline). + This is mostly provided as a reference to learn how ImGui integration works, because it is easier to read. + If your code is using GL3+ context or any semi modern OpenGL calls, using this is likely to make everything + more complicated, will require your code to reset every single OpenGL attributes to their initial state, + and might confuse your GPU driver. Prefer using sdl_opengl3_example. sdl_opengl3_example/ SDL2 + OpenGL3 example. diff --git a/examples/opengl2_example/imgui_impl_glfw.cpp b/examples/opengl2_example/imgui_impl_glfw.cpp index 4aed20a6f..643606db8 100644 --- a/examples/opengl2_example/imgui_impl_glfw.cpp +++ b/examples/opengl2_example/imgui_impl_glfw.cpp @@ -1,10 +1,12 @@ // ImGui GLFW binding with OpenGL // In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. -// If your context or own usage of OpenGL involve anything GL3/GL4, prefer using the code in opengl3_example. -// If you are not sure what that means, prefer using the code in opengl3_example. -// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). -// We cannot do that from GL2 code because the function doesn't exist. Mixing GL2 calls and GL3/GL4 calls is giving trouble to many librairies/drivers. +// *DO NOT USE THIS CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL* +// This is mostly provided as a reference to learn how ImGui integration works, because it is easier to read. +// If your code is using GL3+ context or any semi modern OpenGL calls, using this is likely to make everything +// more complicated, will require your code to reset every single OpenGL attributes to their initial state, +// and might confuse your GPU driver. Prefer using opengl3_example. +// The GL2 code is unable to reset attributes or even call e.g. "glUseProgram(0)" because they don't exist in that API. // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. // If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl.cpp b/examples/sdl_opengl2_example/imgui_impl_sdl.cpp index 78ce40357..8f870eb62 100644 --- a/examples/sdl_opengl2_example/imgui_impl_sdl.cpp +++ b/examples/sdl_opengl2_example/imgui_impl_sdl.cpp @@ -1,8 +1,12 @@ // ImGui SDL2 binding with OpenGL // In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. -// If your context or own usage of OpenGL involve anything GL3/GL4, prefer using the code in sdl_opengl3_example. -// If you are not sure what that means, prefer using the code in sdl_opengl3_example. +// *DO NOT USE THIS CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL* +// This is mostly provided as a reference to learn how ImGui integration works, because it is easier to read. +// If your code is using GL3+ context or any semi modern OpenGL calls, using this is likely to make everything +// more complicated, will require your code to reset every single OpenGL attributes to their initial state, +// and might confuse your GPU driver. Prefer using sdl_opengl3_example. +// The GL2 code is unable to reset attributes or even call e.g. "glUseProgram(0)" because they don't exist in that API. // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. // If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). From a6ff14d66e66c167fbcbc01c4aea1a8361e3dc4e Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 26 Oct 2017 16:12:53 +0200 Subject: [PATCH 490/921] Exposed IM_ARRAYSIZE() in imgui.h --- imgui.h | 6 ++++-- imgui_internal.h | 5 ++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/imgui.h b/imgui.h index c865d3578..2f58e066d 100644 --- a/imgui.h +++ b/imgui.h @@ -29,14 +29,16 @@ #define IM_ASSERT(_EXPR) assert(_EXPR) #endif +// Helpers // Some compilers support applying printf-style warnings to user functions. #if defined(__clang__) || defined(__GNUC__) -#define IM_FMTARGS(FMT) __attribute__((format(printf, FMT, FMT+1))) -#define IM_FMTLIST(FMT) __attribute__((format(printf, FMT, 0))) +#define IM_FMTARGS(FMT) __attribute__((format(printf, FMT, FMT+1))) +#define IM_FMTLIST(FMT) __attribute__((format(printf, FMT, 0))) #else #define IM_FMTARGS(FMT) #define IM_FMTLIST(FMT) #endif +#define IM_ARRAYSIZE(_ARR) ((int)(sizeof(_ARR)/sizeof(*_ARR))) #if defined(__clang__) #pragma clang diagnostic push diff --git a/imgui_internal.h b/imgui_internal.h index 24e484121..76a83beb9 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -79,9 +79,8 @@ extern IMGUI_API ImGuiContext* GImGui; // Current implicit ImGui context pointe // Helpers //----------------------------------------------------------------------------- -#define IM_ARRAYSIZE(_ARR) ((int)(sizeof(_ARR)/sizeof(*_ARR))) -#define IM_PI 3.14159265358979323846f -#define IM_OFFSETOF(_TYPE,_ELM) ((size_t)&(((_TYPE*)0)->_ELM)) +#define IM_PI 3.14159265358979323846f +#define IM_OFFSETOF(_TYPE,_ELM) ((size_t)&(((_TYPE*)0)->_ELM)) // Helpers: UTF-8 <> wchar IMGUI_API int ImTextStrToUtf8(char* buf, int buf_size, const ImWchar* in_text, const ImWchar* in_text_end); // return output UTF-8 bytes count From c432fcf2bbaded0d126360e332361173358c0a79 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 27 Oct 2017 12:01:52 +0200 Subject: [PATCH 491/921] Minor renaming. --- imgui.cpp | 34 +++++++++++++++++----------------- imgui_internal.h | 8 ++++---- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 2d27a79e0..65373204d 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2328,29 +2328,29 @@ void ImGui::NewFrame() g.IO.Framerate = 1.0f / (g.FramerateSecPerFrameAccum / (float)IM_ARRAYSIZE(g.FramerateSecPerFrame)); // Handle user moving window with mouse (at the beginning of the frame to avoid input lag or sheering). Only valid for root windows. - if (g.MovedWindowMoveId && g.MovedWindowMoveId == g.ActiveId) + if (g.MovingWindowMoveId && g.MovingWindowMoveId == g.ActiveId) { - KeepAliveID(g.MovedWindowMoveId); - IM_ASSERT(g.MovedWindow && g.MovedWindow->RootWindow); - IM_ASSERT(g.MovedWindow->MoveId == g.MovedWindowMoveId); + KeepAliveID(g.MovingWindowMoveId); + IM_ASSERT(g.MovingWindow && g.MovingWindow->RootWindow); + IM_ASSERT(g.MovingWindow->MoveId == g.MovingWindowMoveId); if (g.IO.MouseDown[0]) { - g.MovedWindow->RootWindow->PosFloat += g.IO.MouseDelta; + g.MovingWindow->RootWindow->PosFloat += g.IO.MouseDelta; if (g.IO.MouseDelta.x != 0.0f || g.IO.MouseDelta.y != 0.0f) - MarkIniSettingsDirty(g.MovedWindow->RootWindow); - FocusWindow(g.MovedWindow); + MarkIniSettingsDirty(g.MovingWindow->RootWindow); + FocusWindow(g.MovingWindow); } else { ClearActiveID(); - g.MovedWindow = NULL; - g.MovedWindowMoveId = 0; + g.MovingWindow = NULL; + g.MovingWindowMoveId = 0; } } else { - g.MovedWindow = NULL; - g.MovedWindowMoveId = 0; + g.MovingWindow = NULL; + g.MovingWindowMoveId = 0; } // Delay saving settings so we don't spam disk too much @@ -2362,11 +2362,11 @@ void ImGui::NewFrame() } // Find the window we are hovering. Child windows can extend beyond the limit of their parent so we need to derive HoveredRootWindow from HoveredWindow - g.HoveredWindow = g.MovedWindow ? g.MovedWindow : FindHoveredWindow(g.IO.MousePos, false); + g.HoveredWindow = g.MovingWindow ? g.MovingWindow : FindHoveredWindow(g.IO.MousePos, false); if (g.HoveredWindow && (g.HoveredWindow->Flags & ImGuiWindowFlags_ChildWindow)) g.HoveredRootWindow = g.HoveredWindow->RootWindow; else - g.HoveredRootWindow = g.MovedWindow ? g.MovedWindow->RootWindow : FindHoveredWindow(g.IO.MousePos, true); + g.HoveredRootWindow = g.MovingWindow ? g.MovingWindow->RootWindow : FindHoveredWindow(g.IO.MousePos, true); if (ImGuiWindow* modal_window = GetFrontMostModalRootWindow()) { @@ -2504,7 +2504,7 @@ void ImGui::Shutdown() g.HoveredWindow = NULL; g.HoveredRootWindow = NULL; g.ActiveIdWindow = NULL; - g.MovedWindow = NULL; + g.MovingWindow = NULL; for (int i = 0; i < g.Settings.Size; i++) ImGui::MemFree(g.Settings[i].Name); g.Settings.clear(); @@ -2799,9 +2799,9 @@ void ImGui::EndFrame() FocusWindow(g.HoveredWindow); if (!(g.HoveredWindow->Flags & ImGuiWindowFlags_NoMove) && !(g.HoveredRootWindow->Flags & ImGuiWindowFlags_NoMove)) { - g.MovedWindow = g.HoveredWindow; - g.MovedWindowMoveId = g.HoveredWindow->MoveId; - SetActiveID(g.MovedWindowMoveId, g.HoveredRootWindow); + g.MovingWindow = g.HoveredWindow; + g.MovingWindowMoveId = g.MovingWindow->MoveId; + SetActiveID(g.MovingWindowMoveId, g.HoveredRootWindow); } } else if (g.NavWindow != NULL && GetFrontMostModalRootWindow() == NULL) diff --git a/imgui_internal.h b/imgui_internal.h index 76a83beb9..f240b6084 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -435,8 +435,8 @@ struct ImGuiContext bool ActiveIdAllowOverlap; // Active widget allows another widget to steal active id (generally for overlapping widgets, but not always) ImVec2 ActiveIdClickOffset; // Clicked offset from upper-left corner, if applicable (currently only set by ButtonBehavior) ImGuiWindow* ActiveIdWindow; - ImGuiWindow* MovedWindow; // Track the child window we clicked on to move a window. - ImGuiID MovedWindowMoveId; // == MovedWindow->RootWindow->MoveId + ImGuiWindow* MovingWindow; // Track the child window we clicked on to move a window. + ImGuiID MovingWindowMoveId; // == MovingWindow->MoveId ImVector Settings; // .ini Settings float SettingsDirtyTimer; // Save .ini Settings on disk when time reaches zero ImVector ColorModifiers; // Stack for PushStyleColor()/PopStyleColor() @@ -527,8 +527,8 @@ struct ImGuiContext ActiveIdAllowOverlap = false; ActiveIdClickOffset = ImVec2(-1,-1); ActiveIdWindow = NULL; - MovedWindow = NULL; - MovedWindowMoveId = 0; + MovingWindow = NULL; + MovingWindowMoveId = 0; SettingsDirtyTimer = 0.0f; SetNextWindowPosVal = ImVec2(0.0f, 0.0f); From d42f6bb6ccdbfb77f6fe9bf0d195542c2ea1664a Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 27 Oct 2017 15:52:45 +0200 Subject: [PATCH 492/921] Merged a bit of code from Navigation branch to ease further merging (InnerRect is currently not required in the Master branch) --- imgui.cpp | 18 ++++++++++++------ imgui_internal.h | 1 + 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 65373204d..4699576e6 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4613,17 +4613,23 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) */ } - // Inner clipping rectangle + // Inner rectangle and inner clipping rectangle // We set this up after processing the resize grip so that our clip rectangle doesn't lag by a frame // Note that if our window is collapsed we will end up with a null clipping rectangle which is the correct behavior. const ImRect title_bar_rect = window->TitleBarRect(); const float border_size = window->BorderSize; - // Force round to ensure that e.g. (int)(max.x-min.x) in user's render code produce correct result. + window->InnerRect.Min.x = title_bar_rect.Min.x; + window->InnerRect.Min.y = title_bar_rect.Max.y + window->MenuBarHeight(); + window->InnerRect.Max.x = window->Pos.x + window->Size.x - window->ScrollbarSizes.x; + window->InnerRect.Max.y = window->Pos.y + window->Size.y - window->ScrollbarSizes.y; + //window->DrawList->AddRect(window->InnerRect.Min, window->InnerRect.Max, IM_COL32_WHITE); + + // Force round operator last to ensure that e.g. (int)(max.x-min.x) in user's render code produce correct result. ImRect clip_rect; - clip_rect.Min.x = ImFloor(0.5f + title_bar_rect.Min.x + ImMax(border_size, ImFloor(window->WindowPadding.x*0.5f))); - clip_rect.Min.y = ImFloor(0.5f + title_bar_rect.Max.y + window->MenuBarHeight() + border_size); - clip_rect.Max.x = ImFloor(0.5f + window->Pos.x + window->Size.x - window->ScrollbarSizes.x - ImMax(border_size, ImFloor(window->WindowPadding.x*0.5f))); - clip_rect.Max.y = ImFloor(0.5f + window->Pos.y + window->Size.y - window->ScrollbarSizes.y - border_size); + clip_rect.Min.x = ImFloor(0.5f + window->InnerRect.Min.x + ImMax(border_size, ImFloor(window->WindowPadding.x*0.5f))); + clip_rect.Min.y = ImFloor(0.5f + window->InnerRect.Min.y + border_size); + clip_rect.Max.x = ImFloor(0.5f + window->InnerRect.Max.x - ImMax(border_size, ImFloor(window->WindowPadding.x*0.5f))); + clip_rect.Max.y = ImFloor(0.5f + window->InnerRect.Max.y - border_size); PushClipRect(clip_rect.Min, clip_rect.Max, true); // Clear 'accessed' flag last thing diff --git a/imgui_internal.h b/imgui_internal.h index f240b6084..39fc77f5d 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -714,6 +714,7 @@ struct IMGUI_API ImGuiWindow ImVector IDStack; // ID stack. ID are hashes seeded with the value at the top of the stack ImRect ClipRect; // = DrawList->clip_rect_stack.back(). Scissoring / clipping rectangle. x1, y1, x2, y2. ImRect WindowRectClipped; // = WindowRect just after setup in Begin(). == window->Rect() for root window. + ImRect InnerRect; int LastFrameActive; float ItemWidthDefault; ImGuiSimpleColumns MenuColumns; // Simplified columns storage for menu items From 6243252d5a9649e40d1d28b091b26a6883c3a30e Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 27 Oct 2017 16:21:12 +0200 Subject: [PATCH 493/921] Internal: BeginTooltipEx() in imgui_internal.h --- imgui.cpp | 2 +- imgui_internal.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 4699576e6..a54da71ae 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3536,7 +3536,7 @@ static ImRect GetVisibleRect() } // Not exposed publicly as BeginTooltip() because bool parameters are evil. Let's see if other needs arise first. -static void BeginTooltipEx(ImGuiWindowFlags extra_flags, bool override_previous_tooltip) +void ImGui::BeginTooltipEx(ImGuiWindowFlags extra_flags, bool override_previous_tooltip) { ImGuiContext& g = *GImGui; char window_name[16]; diff --git a/imgui_internal.h b/imgui_internal.h index 39fc77f5d..131c158e7 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -802,6 +802,7 @@ namespace ImGui IMGUI_API void ClosePopup(ImGuiID id); IMGUI_API bool IsPopupOpen(ImGuiID id); IMGUI_API bool BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_flags); + IMGUI_API void BeginTooltipEx(ImGuiWindowFlags extra_flags, bool override_previous_tooltip = true); IMGUI_API int CalcTypematicPressedRepeatAmount(float t, float t_prev, float repeat_delay, float repeat_rate); From a6edd10ee6934ac3f35d49d18ba11a67ab664714 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 25 Oct 2017 22:02:06 +0200 Subject: [PATCH 494/921] NewFrame: Removed unnecessary call to FindHoveredWindow() and simplified code (went through this multiple times, hopefully haven't broken anything) --- imgui.cpp | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index a54da71ae..9910e6007 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -629,7 +629,7 @@ static void SetWindowScrollY(ImGuiWindow* window, float new_scroll_y static void SetWindowPos(ImGuiWindow* window, const ImVec2& pos, ImGuiCond cond); static void SetWindowSize(ImGuiWindow* window, const ImVec2& size, ImGuiCond cond); static void SetWindowCollapsed(ImGuiWindow* window, bool collapsed, ImGuiCond cond); -static ImGuiWindow* FindHoveredWindow(ImVec2 pos, bool excluding_childs); +static ImGuiWindow* FindHoveredWindow(ImVec2 pos); static ImGuiWindow* CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFlags flags); static void ClearSetNextWindowData(); static void CheckStacksSize(ImGuiWindow* window, bool write); @@ -2362,11 +2362,8 @@ void ImGui::NewFrame() } // Find the window we are hovering. Child windows can extend beyond the limit of their parent so we need to derive HoveredRootWindow from HoveredWindow - g.HoveredWindow = g.MovingWindow ? g.MovingWindow : FindHoveredWindow(g.IO.MousePos, false); - if (g.HoveredWindow && (g.HoveredWindow->Flags & ImGuiWindowFlags_ChildWindow)) - g.HoveredRootWindow = g.HoveredWindow->RootWindow; - else - g.HoveredRootWindow = g.MovingWindow ? g.MovingWindow->RootWindow : FindHoveredWindow(g.IO.MousePos, true); + g.HoveredWindow = g.MovingWindow ? g.MovingWindow : FindHoveredWindow(g.IO.MousePos); + g.HoveredRootWindow = g.HoveredWindow ? g.HoveredWindow->RootWindow : NULL; if (ImGuiWindow* modal_window = GetFrontMostModalRootWindow()) { @@ -3239,7 +3236,7 @@ void ImGui::CalcListClipping(int items_count, float items_height, int* out_items // Find window given position, search front-to-back // FIXME: Note that we have a lag here because WindowRectClipped is updated in Begin() so windows moved by user via SetWindowPos() and not SetNextWindowPos() will have that rectangle lagging by a frame at the time FindHoveredWindow() is called, aka before the next Begin(). Moving window thankfully isn't affected. -static ImGuiWindow* FindHoveredWindow(ImVec2 pos, bool excluding_childs) +static ImGuiWindow* FindHoveredWindow(ImVec2 pos) { ImGuiContext& g = *GImGui; for (int i = g.Windows.Size-1; i >= 0; i--) @@ -3249,10 +3246,8 @@ static ImGuiWindow* FindHoveredWindow(ImVec2 pos, bool excluding_childs) continue; if (window->Flags & ImGuiWindowFlags_NoInputs) continue; - if (excluding_childs && (window->Flags & ImGuiWindowFlags_ChildWindow) != 0) - continue; - // Using the clipped AABB so a child window will typically be clipped by its parent. + // Using the clipped AABB, a child window will typically be clipped by its parent (not always) ImRect bb(window->WindowRectClipped.Min - g.Style.TouchExtraPadding, window->WindowRectClipped.Max + g.Style.TouchExtraPadding); if (bb.Contains(pos)) return window; From 3656f2c76999cc9d65c7f33468e1b8ec9eb10379 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 25 Oct 2017 22:04:31 +0200 Subject: [PATCH 495/921] NewFrame: Allow MovedWindow setting the ImGuiWindowFlags_NoInputs after moving has started in order to be able to detect windows below it, which is useful for e.g. docking mechanisms. --- imgui.cpp | 7 +++++-- imgui.h | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 9910e6007..a55ef6aaf 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2361,8 +2361,11 @@ void ImGui::NewFrame() SaveIniSettingsToDisk(g.IO.IniFilename); } - // Find the window we are hovering. Child windows can extend beyond the limit of their parent so we need to derive HoveredRootWindow from HoveredWindow - g.HoveredWindow = g.MovingWindow ? g.MovingWindow : FindHoveredWindow(g.IO.MousePos); + // Find the window we are hovering + // - Child windows can extend beyond the limit of their parent so we need to derive HoveredRootWindow from HoveredWindow. + // - When moving a window we can skip the search, which also conveniently bypasses the fact that window->WindowRectClipped is lagging as this point. + // - We also support the moved window toggling the NoInputs flag after moving has started in order to be able to detect windows below it, which is useful for e.g. docking mechanisms. + g.HoveredWindow = (g.MovingWindow && !(g.MovingWindow->Flags & ImGuiWindowFlags_NoInputs)) ? g.MovingWindow : FindHoveredWindow(g.IO.MousePos); g.HoveredRootWindow = g.HoveredWindow ? g.HoveredWindow->RootWindow : NULL; if (ImGuiWindow* modal_window = GetFrontMostModalRootWindow()) diff --git a/imgui.h b/imgui.h index 2f58e066d..2a9018c73 100644 --- a/imgui.h +++ b/imgui.h @@ -502,7 +502,7 @@ enum ImGuiWindowFlags_ ImGuiWindowFlags_AlwaysAutoResize = 1 << 6, // Resize every window to its content every frame ImGuiWindowFlags_ShowBorders = 1 << 7, // Show borders around windows and items ImGuiWindowFlags_NoSavedSettings = 1 << 8, // Never load/save settings in .ini file - ImGuiWindowFlags_NoInputs = 1 << 9, // Disable catching mouse or keyboard inputs + ImGuiWindowFlags_NoInputs = 1 << 9, // Disable catching mouse or keyboard inputs, hovering test with pass through. ImGuiWindowFlags_MenuBar = 1 << 10, // Has a menu-bar ImGuiWindowFlags_HorizontalScrollbar = 1 << 11, // Allow horizontal scrollbar to appear (off by default). You may use SetNextWindowContentSize(ImVec2(width,0.0f)); prior to calling Begin() to specify width. Read code in imgui_demo in the "Horizontal Scrolling" section. ImGuiWindowFlags_NoFocusOnAppearing = 1 << 12, // Disable taking focus when transitioning from hidden to visible state From 3b83cd24f59bb997cc9b69f8cb8304df33de7f05 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 27 Oct 2017 13:16:37 +0200 Subject: [PATCH 496/921] Begin: Moved some code inside of the big if (first_begin_of_the_frame) scope --- imgui.cpp | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index a55ef6aaf..7204827c3 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4609,20 +4609,23 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) if (g.IO.KeyCtrl && IsKeyPressedMap(ImGuiKey_C)) ImGui::LogToClipboard(); */ + + // Inner rectangle + // We set this up after processing the resize grip so that our clip rectangle doesn't lag by a frame + // Note that if our window is collapsed we will end up with a null clipping rectangle which is the correct behavior. + window->InnerRect.Min.x = title_bar_rect.Min.x; + window->InnerRect.Min.y = title_bar_rect.Max.y + window->MenuBarHeight(); + window->InnerRect.Max.x = window->Pos.x + window->Size.x - window->ScrollbarSizes.x; + window->InnerRect.Max.y = window->Pos.y + window->Size.y - window->ScrollbarSizes.y; + //window->DrawList->AddRect(window->InnerRect.Min, window->InnerRect.Max, IM_COL32_WHITE); + + // Clear 'accessed' flag last thing + window->Accessed = false; } - // Inner rectangle and inner clipping rectangle - // We set this up after processing the resize grip so that our clip rectangle doesn't lag by a frame - // Note that if our window is collapsed we will end up with a null clipping rectangle which is the correct behavior. - const ImRect title_bar_rect = window->TitleBarRect(); - const float border_size = window->BorderSize; - window->InnerRect.Min.x = title_bar_rect.Min.x; - window->InnerRect.Min.y = title_bar_rect.Max.y + window->MenuBarHeight(); - window->InnerRect.Max.x = window->Pos.x + window->Size.x - window->ScrollbarSizes.x; - window->InnerRect.Max.y = window->Pos.y + window->Size.y - window->ScrollbarSizes.y; - //window->DrawList->AddRect(window->InnerRect.Min, window->InnerRect.Max, IM_COL32_WHITE); - + // Inner clipping rectangle // Force round operator last to ensure that e.g. (int)(max.x-min.x) in user's render code produce correct result. + const float border_size = window->BorderSize; ImRect clip_rect; clip_rect.Min.x = ImFloor(0.5f + window->InnerRect.Min.x + ImMax(border_size, ImFloor(window->WindowPadding.x*0.5f))); clip_rect.Min.y = ImFloor(0.5f + window->InnerRect.Min.y + border_size); @@ -4630,9 +4633,6 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) clip_rect.Max.y = ImFloor(0.5f + window->InnerRect.Max.y - border_size); PushClipRect(clip_rect.Min, clip_rect.Max, true); - // Clear 'accessed' flag last thing - if (first_begin_of_the_frame) - window->Accessed = false; window->BeginCount++; g.SetNextWindowSizeConstraint = false; From ccdb58b17ec97ef649886572fbe02af155d20c0a Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 27 Oct 2017 13:19:31 +0200 Subject: [PATCH 497/921] Internal: Added ImVec4 operators --- imgui_internal.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/imgui_internal.h b/imgui_internal.h index 131c158e7..8978ed79e 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -127,7 +127,9 @@ static inline ImVec2& operator+=(ImVec2& lhs, const ImVec2& rhs) static inline ImVec2& operator-=(ImVec2& lhs, const ImVec2& rhs) { lhs.x -= rhs.x; lhs.y -= rhs.y; return lhs; } static inline ImVec2& operator*=(ImVec2& lhs, const float rhs) { lhs.x *= rhs; lhs.y *= rhs; return lhs; } static inline ImVec2& operator/=(ImVec2& lhs, const float rhs) { lhs.x /= rhs; lhs.y /= rhs; return lhs; } +static inline ImVec4 operator+(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x+rhs.x, lhs.y+rhs.y, lhs.z+rhs.z, lhs.w+rhs.w); } static inline ImVec4 operator-(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x-rhs.x, lhs.y-rhs.y, lhs.z-rhs.z, lhs.w-rhs.w); } +static inline ImVec4 operator*(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x*rhs.x, lhs.y*rhs.y, lhs.z*rhs.z, lhs.w*rhs.w); } #endif static inline int ImMin(int lhs, int rhs) { return lhs < rhs ? lhs : rhs; } From 8dd7648db2b2f1813090a1706bea63d8a025c686 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 27 Oct 2017 15:31:44 +0200 Subject: [PATCH 498/921] Comments --- imgui.h | 1 + imgui_internal.h | 11 +++++------ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/imgui.h b/imgui.h index 2a9018c73..b79ef3fd8 100644 --- a/imgui.h +++ b/imgui.h @@ -571,6 +571,7 @@ enum ImGuiSelectableFlags_ ImGuiSelectableFlags_AllowDoubleClick = 1 << 2 // Generate press events on double clicks too }; +// Flags for ImGui::IsItemHovered(), ImGui::IsWindowHovered() enum ImGuiHoveredFlags_ { ImGuiHoveredFlags_Default = 0, // Return true if directly over the item/window, not obstructed by another window, not obstructed by an active popup or modal blocking inputs under them. diff --git a/imgui_internal.h b/imgui_internal.h index 8978ed79e..1e5d1da36 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -44,12 +44,11 @@ struct ImGuiMouseCursorData; struct ImGuiPopupRef; struct ImGuiWindow; -typedef int ImGuiLayoutType; // enum ImGuiLayoutType_ -typedef int ImGuiButtonFlags; // enum ImGuiButtonFlags_ -typedef int ImGuiTreeNodeFlags; // enum ImGuiTreeNodeFlags_ -typedef int ImGuiSliderFlags; // enum ImGuiSliderFlags_ -typedef int ImGuiSeparatorFlags; // enum ImGuiSeparatorFlags_ -typedef int ImGuiItemFlags; // enum ImGuiItemFlags_ +typedef int ImGuiLayoutType; // enum: horizontal or vertical // enum ImGuiLayoutType_ +typedef int ImGuiButtonFlags; // flags: for ButtonEx(), ButtonBehavior() // enum ImGuiButtonFlags_ +typedef int ImGuiItemFlags; // flags: for PushItemFlag() // enum ImGuiItemFlags_ +typedef int ImGuiSeparatorFlags; // flags: for Separator() - internal // enum ImGuiSeparatorFlags_ +typedef int ImGuiSliderFlags; // flags: for SliderBehavior() // enum ImGuiSliderFlags_ //------------------------------------------------------------------------- // STB libraries From 267ea506deb62feedf2f47f75faf144739468242 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 27 Oct 2017 16:45:56 +0200 Subject: [PATCH 499/921] Begin: Fix for unused "Debug" (fix for 3b83cd24f59bb997cc9b69f8cb8304df33de7f05 ) --- imgui.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 7204827c3..b44152191 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4618,9 +4618,6 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->InnerRect.Max.x = window->Pos.x + window->Size.x - window->ScrollbarSizes.x; window->InnerRect.Max.y = window->Pos.y + window->Size.y - window->ScrollbarSizes.y; //window->DrawList->AddRect(window->InnerRect.Min, window->InnerRect.Max, IM_COL32_WHITE); - - // Clear 'accessed' flag last thing - window->Accessed = false; } // Inner clipping rectangle @@ -4633,6 +4630,10 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) clip_rect.Max.y = ImFloor(0.5f + window->InnerRect.Max.y - border_size); PushClipRect(clip_rect.Min, clip_rect.Max, true); + // Clear 'accessed' flag last thing (After PushClipRect which will set the flag. We want the flag to stay false when the default "Debug" window is unused) + if (first_begin_of_the_frame) + window->Accessed = false; + window->BeginCount++; g.SetNextWindowSizeConstraint = false; From 9f200d10d569270995a8bb5893557196258fd997 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 27 Oct 2017 17:10:41 +0200 Subject: [PATCH 500/921] Version 1.52 --- imgui.cpp | 2 +- imgui.h | 4 ++-- imgui_demo.cpp | 2 +- imgui_draw.cpp | 2 +- imgui_internal.h | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index b44152191..b15c059fb 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.52 WIP +// dear imgui, v1.52 // (main code and documentation) // See ImGui::ShowTestWindow() in imgui_demo.cpp for demo code. diff --git a/imgui.h b/imgui.h index b79ef3fd8..3dafbe921 100644 --- a/imgui.h +++ b/imgui.h @@ -1,4 +1,4 @@ -// dear imgui, v1.52 WIP +// dear imgui, v1.52 // (headers) // See imgui.cpp file for documentation. @@ -16,7 +16,7 @@ #include // ptrdiff_t, NULL #include // memset, memmove, memcpy, strlen, strchr, strcpy, strcmp -#define IMGUI_VERSION "1.52 WIP" +#define IMGUI_VERSION "1.52" // Define attributes of all API symbols declarations, e.g. for DLL under Windows. #ifndef IMGUI_API diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 5fe78dbe5..ccbf17050 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.52 WIP +// dear imgui, v1.52 // (demo code) // Message to the person tempted to delete this file when integrating ImGui into their code base: diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 8137f4769..983cce141 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.52 WIP +// dear imgui, v1.52 // (drawing and font code) // Contains implementation for diff --git a/imgui_internal.h b/imgui_internal.h index 1e5d1da36..b5869775f 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1,4 +1,4 @@ -// dear imgui, v1.52 WIP +// dear imgui, v1.52 // (internals) // You may use this file to debug, understand or extend ImGui features but we don't provide any guarantee of forward compatibility! From b422f35872f9f03496919eb515e8d4c01736594c Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 27 Oct 2017 18:21:30 +0200 Subject: [PATCH 501/921] IO: Tracking extra mouse dragging data which is convenient for implementating various manual drag and drop patterns. --- imgui.cpp | 6 +++++- imgui.h | 3 ++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index b15c059fb..0c3594196 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2313,11 +2313,15 @@ void ImGui::NewFrame() g.IO.MouseClickedTime[i] = g.Time; } g.IO.MouseClickedPos[i] = g.IO.MousePos; + g.IO.MouseDragMaxDistanceAbs[i] = ImVec2(0.0f, 0.0f); g.IO.MouseDragMaxDistanceSqr[i] = 0.0f; } else if (g.IO.MouseDown[i]) { - g.IO.MouseDragMaxDistanceSqr[i] = ImMax(g.IO.MouseDragMaxDistanceSqr[i], ImLengthSqr(g.IO.MousePos - g.IO.MouseClickedPos[i])); + ImVec2 mouse_delta = g.IO.MousePos - g.IO.MouseClickedPos[i]; + g.IO.MouseDragMaxDistanceAbs[i].x = ImMax(g.IO.MouseDragMaxDistanceAbs[i].x, mouse_delta.x < 0.0f ? -mouse_delta.x : mouse_delta.x); + g.IO.MouseDragMaxDistanceAbs[i].y = ImMax(g.IO.MouseDragMaxDistanceAbs[i].y, mouse_delta.y < 0.0f ? -mouse_delta.y : mouse_delta.y); + g.IO.MouseDragMaxDistanceSqr[i] = ImMax(g.IO.MouseDragMaxDistanceSqr[i], ImLengthSqr(mouse_delta)); } } diff --git a/imgui.h b/imgui.h index 3dafbe921..f2c6d8500 100644 --- a/imgui.h +++ b/imgui.h @@ -877,7 +877,8 @@ struct ImGuiIO bool MouseDownOwned[5]; // Track if button was clicked inside a window. We don't request mouse capture from the application if click started outside ImGui bounds. float MouseDownDuration[5]; // Duration the mouse button has been down (0.0f == just clicked) float MouseDownDurationPrev[5]; // Previous time the mouse button has been down - float MouseDragMaxDistanceSqr[5]; // Squared maximum distance of how much mouse has traveled from the click point + ImVec2 MouseDragMaxDistanceAbs[5]; // Maximum distance, absolute, on each axis, of how much mouse has traveled from the clicking point + float MouseDragMaxDistanceSqr[5]; // Squared maximum distance of how much mouse has traveled from the clicking point float KeysDownDuration[512]; // Duration the keyboard key has been down (0.0f == just pressed) float KeysDownDurationPrev[512]; // Previous duration the key has been down From 77df1ba9e0024da82bcbc12521c6d923cc90e732 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 27 Oct 2017 19:54:56 +0200 Subject: [PATCH 502/921] Version 1.53 WIP --- imgui.cpp | 2 +- imgui.h | 4 ++-- imgui_demo.cpp | 2 +- imgui_draw.cpp | 2 +- imgui_internal.h | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 0c3594196..74d916054 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.52 +// dear imgui, v1.53 WIP // (main code and documentation) // See ImGui::ShowTestWindow() in imgui_demo.cpp for demo code. diff --git a/imgui.h b/imgui.h index f2c6d8500..ea16b76a5 100644 --- a/imgui.h +++ b/imgui.h @@ -1,4 +1,4 @@ -// dear imgui, v1.52 +// dear imgui, v1.53 WIP // (headers) // See imgui.cpp file for documentation. @@ -16,7 +16,7 @@ #include // ptrdiff_t, NULL #include // memset, memmove, memcpy, strlen, strchr, strcpy, strcmp -#define IMGUI_VERSION "1.52" +#define IMGUI_VERSION "1.53 WIP" // Define attributes of all API symbols declarations, e.g. for DLL under Windows. #ifndef IMGUI_API diff --git a/imgui_demo.cpp b/imgui_demo.cpp index ccbf17050..d2f4d9500 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.52 +// dear imgui, v1.53 WIP // (demo code) // Message to the person tempted to delete this file when integrating ImGui into their code base: diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 983cce141..a1a886cbc 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.52 +// dear imgui, v1.53 WIP // (drawing and font code) // Contains implementation for diff --git a/imgui_internal.h b/imgui_internal.h index b5869775f..1cb723ca7 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1,4 +1,4 @@ -// dear imgui, v1.52 +// dear imgui, v1.53 WIP // (internals) // You may use this file to debug, understand or extend ImGui features but we don't provide any guarantee of forward compatibility! From c503a50cff830b8aa1790875461c141604f0e62e Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 27 Oct 2017 20:01:30 +0200 Subject: [PATCH 503/921] Styles: Moved Classic colors code to imgui_draw.cpp. Sneakily added a StyleColorsDark() function. --- imgui.cpp | 50 ------------------------ imgui.h | 1 + imgui_draw.cpp | 104 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 105 insertions(+), 50 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 74d916054..b9f54ff04 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -726,56 +726,6 @@ ImGuiStyle::ImGuiStyle() ImGui::StyleColorsClassic(this); } -void ImGui::StyleColorsClassic(ImGuiStyle* dst) -{ - ImGuiStyle* style = dst ? dst : &ImGui::GetStyle(); - ImVec4* colors = style->Colors; - - colors[ImGuiCol_Text] = ImVec4(0.90f, 0.90f, 0.90f, 1.00f); - colors[ImGuiCol_TextDisabled] = ImVec4(0.60f, 0.60f, 0.60f, 1.00f); - colors[ImGuiCol_WindowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.70f); - colors[ImGuiCol_ChildWindowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); - colors[ImGuiCol_PopupBg] = ImVec4(0.05f, 0.05f, 0.10f, 0.90f); - colors[ImGuiCol_Border] = ImVec4(0.70f, 0.70f, 0.70f, 0.40f); - colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); - colors[ImGuiCol_FrameBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.30f); // Background of checkbox, radio button, plot, slider, text input - colors[ImGuiCol_FrameBgHovered] = ImVec4(0.90f, 0.80f, 0.80f, 0.40f); - colors[ImGuiCol_FrameBgActive] = ImVec4(0.90f, 0.65f, 0.65f, 0.45f); - colors[ImGuiCol_TitleBg] = ImVec4(0.27f, 0.27f, 0.54f, 0.83f); - colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.40f, 0.40f, 0.80f, 0.20f); - colors[ImGuiCol_TitleBgActive] = ImVec4(0.32f, 0.32f, 0.63f, 0.87f); - colors[ImGuiCol_MenuBarBg] = ImVec4(0.40f, 0.40f, 0.55f, 0.80f); - colors[ImGuiCol_ScrollbarBg] = ImVec4(0.20f, 0.25f, 0.30f, 0.60f); - colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.40f, 0.40f, 0.80f, 0.30f); - colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.40f, 0.40f, 0.80f, 0.40f); - colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.80f, 0.50f, 0.50f, 0.40f); - colors[ImGuiCol_ComboBg] = ImVec4(0.20f, 0.20f, 0.20f, 0.99f); - colors[ImGuiCol_CheckMark] = ImVec4(0.90f, 0.90f, 0.90f, 0.50f); - colors[ImGuiCol_SliderGrab] = ImVec4(1.00f, 1.00f, 1.00f, 0.30f); - colors[ImGuiCol_SliderGrabActive] = ImVec4(0.80f, 0.50f, 0.50f, 1.00f); - colors[ImGuiCol_Button] = ImVec4(0.67f, 0.40f, 0.40f, 0.60f); - colors[ImGuiCol_ButtonHovered] = ImVec4(0.67f, 0.40f, 0.40f, 1.00f); - colors[ImGuiCol_ButtonActive] = ImVec4(0.80f, 0.50f, 0.50f, 1.00f); - colors[ImGuiCol_Header] = ImVec4(0.40f, 0.40f, 0.90f, 0.45f); - colors[ImGuiCol_HeaderHovered] = ImVec4(0.45f, 0.45f, 0.90f, 0.80f); - colors[ImGuiCol_HeaderActive] = ImVec4(0.53f, 0.53f, 0.87f, 0.80f); - colors[ImGuiCol_Separator] = ImVec4(0.50f, 0.50f, 0.50f, 1.00f); - colors[ImGuiCol_SeparatorHovered] = ImVec4(0.60f, 0.60f, 0.70f, 1.00f); - colors[ImGuiCol_SeparatorActive] = ImVec4(0.70f, 0.70f, 0.90f, 1.00f); - colors[ImGuiCol_ResizeGrip] = ImVec4(1.00f, 1.00f, 1.00f, 0.30f); - colors[ImGuiCol_ResizeGripHovered] = ImVec4(1.00f, 1.00f, 1.00f, 0.60f); - colors[ImGuiCol_ResizeGripActive] = ImVec4(1.00f, 1.00f, 1.00f, 0.90f); - colors[ImGuiCol_CloseButton] = ImVec4(0.50f, 0.50f, 0.90f, 0.50f); - colors[ImGuiCol_CloseButtonHovered] = ImVec4(0.70f, 0.70f, 0.90f, 0.60f); - colors[ImGuiCol_CloseButtonActive] = ImVec4(0.70f, 0.70f, 0.70f, 1.00f); - colors[ImGuiCol_PlotLines] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f); - colors[ImGuiCol_PlotLinesHovered] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); - colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); - colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.60f, 0.00f, 1.00f); - colors[ImGuiCol_TextSelectedBg] = ImVec4(0.00f, 0.00f, 1.00f, 0.35f); - colors[ImGuiCol_ModalWindowDarkening] = ImVec4(0.20f, 0.20f, 0.20f, 0.35f); -} - // To scale your entire UI (e.g. if you want your app to use High DPI or generally be DPI aware) you may use this helper function. Scaling the fonts is done separately and is up to you. // Tips: if you need to change your scale multiple times, prefer calling this on a freshly initialized ImGuiStyle structure rather than scaling multiple times (because floating point multiplications are lossy). void ImGuiStyle::ScaleAllSizes(float scale_factor) diff --git a/imgui.h b/imgui.h index ea16b76a5..2ac954d28 100644 --- a/imgui.h +++ b/imgui.h @@ -416,6 +416,7 @@ namespace ImGui // Styles IMGUI_API void StyleColorsClassic(ImGuiStyle* dst = NULL); + IMGUI_API void StyleColorsDark(ImGuiStyle* dst = NULL); // Utilities IMGUI_API bool IsItemHovered(ImGuiHoveredFlags flags = 0); // is the last item hovered by mouse (and usable)? diff --git a/imgui_draw.cpp b/imgui_draw.cpp index a1a886cbc..8735e3fc1 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -2,6 +2,7 @@ // (drawing and font code) // Contains implementation for +// - Default styles // - ImDrawList // - ImDrawData // - ImFontAtlas @@ -116,6 +117,109 @@ namespace IMGUI_STB_NAMESPACE using namespace IMGUI_STB_NAMESPACE; #endif +//----------------------------------------------------------------------------- +// Style functions +//----------------------------------------------------------------------------- + +void ImGui::StyleColorsClassic(ImGuiStyle* dst) +{ + ImGuiStyle* style = dst ? dst : &ImGui::GetStyle(); + ImVec4* colors = style->Colors; + + colors[ImGuiCol_Text] = ImVec4(0.90f, 0.90f, 0.90f, 1.00f); + colors[ImGuiCol_TextDisabled] = ImVec4(0.60f, 0.60f, 0.60f, 1.00f); + colors[ImGuiCol_WindowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.70f); + colors[ImGuiCol_ChildWindowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); + colors[ImGuiCol_PopupBg] = ImVec4(0.05f, 0.05f, 0.10f, 0.90f); + colors[ImGuiCol_Border] = ImVec4(0.70f, 0.70f, 0.70f, 0.40f); + colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); + colors[ImGuiCol_FrameBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.30f); // Background of checkbox, radio button, plot, slider, text input + colors[ImGuiCol_FrameBgHovered] = ImVec4(0.90f, 0.80f, 0.80f, 0.40f); + colors[ImGuiCol_FrameBgActive] = ImVec4(0.90f, 0.65f, 0.65f, 0.45f); + colors[ImGuiCol_TitleBg] = ImVec4(0.27f, 0.27f, 0.54f, 0.83f); + colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.40f, 0.40f, 0.80f, 0.20f); + colors[ImGuiCol_TitleBgActive] = ImVec4(0.32f, 0.32f, 0.63f, 0.87f); + colors[ImGuiCol_MenuBarBg] = ImVec4(0.40f, 0.40f, 0.55f, 0.80f); + colors[ImGuiCol_ScrollbarBg] = ImVec4(0.20f, 0.25f, 0.30f, 0.60f); + colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.40f, 0.40f, 0.80f, 0.30f); + colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.40f, 0.40f, 0.80f, 0.40f); + colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.80f, 0.50f, 0.50f, 0.40f); + colors[ImGuiCol_ComboBg] = ImVec4(0.20f, 0.20f, 0.20f, 0.99f); + colors[ImGuiCol_CheckMark] = ImVec4(0.90f, 0.90f, 0.90f, 0.50f); + colors[ImGuiCol_SliderGrab] = ImVec4(1.00f, 1.00f, 1.00f, 0.30f); + colors[ImGuiCol_SliderGrabActive] = ImVec4(0.80f, 0.50f, 0.50f, 1.00f); + colors[ImGuiCol_Button] = ImVec4(0.67f, 0.40f, 0.40f, 0.60f); + colors[ImGuiCol_ButtonHovered] = ImVec4(0.67f, 0.40f, 0.40f, 1.00f); + colors[ImGuiCol_ButtonActive] = ImVec4(0.80f, 0.50f, 0.50f, 1.00f); + colors[ImGuiCol_Header] = ImVec4(0.40f, 0.40f, 0.90f, 0.45f); + colors[ImGuiCol_HeaderHovered] = ImVec4(0.45f, 0.45f, 0.90f, 0.80f); + colors[ImGuiCol_HeaderActive] = ImVec4(0.53f, 0.53f, 0.87f, 0.80f); + colors[ImGuiCol_Separator] = ImVec4(0.50f, 0.50f, 0.50f, 1.00f); + colors[ImGuiCol_SeparatorHovered] = ImVec4(0.60f, 0.60f, 0.70f, 1.00f); + colors[ImGuiCol_SeparatorActive] = ImVec4(0.70f, 0.70f, 0.90f, 1.00f); + colors[ImGuiCol_ResizeGrip] = ImVec4(1.00f, 1.00f, 1.00f, 0.30f); + colors[ImGuiCol_ResizeGripHovered] = ImVec4(1.00f, 1.00f, 1.00f, 0.60f); + colors[ImGuiCol_ResizeGripActive] = ImVec4(1.00f, 1.00f, 1.00f, 0.90f); + colors[ImGuiCol_CloseButton] = ImVec4(0.50f, 0.50f, 0.90f, 0.50f); + colors[ImGuiCol_CloseButtonHovered] = ImVec4(0.70f, 0.70f, 0.90f, 0.60f); + colors[ImGuiCol_CloseButtonActive] = ImVec4(0.70f, 0.70f, 0.70f, 1.00f); + colors[ImGuiCol_PlotLines] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f); + colors[ImGuiCol_PlotLinesHovered] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); + colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); + colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.60f, 0.00f, 1.00f); + colors[ImGuiCol_TextSelectedBg] = ImVec4(0.00f, 0.00f, 1.00f, 0.35f); + colors[ImGuiCol_ModalWindowDarkening] = ImVec4(0.20f, 0.20f, 0.20f, 0.35f); +} + +void ImGui::StyleColorsDark(ImGuiStyle* dst) +{ + ImGuiStyle* style = dst ? dst : &ImGui::GetStyle(); + ImVec4* colors = style->Colors; + + colors[ImGuiCol_Text] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f); + colors[ImGuiCol_TextDisabled] = ImVec4(0.40f, 0.40f, 0.40f, 1.00f); + colors[ImGuiCol_WindowBg] = ImVec4(0.06f, 0.06f, 0.06f, 0.94f); + colors[ImGuiCol_Border] = ImVec4(1.00f, 1.00f, 1.00f, 0.19f); + colors[ImGuiCol_ChildWindowBg] = ImVec4(1.00f, 1.00f, 1.00f, 0.00f); + colors[ImGuiCol_PopupBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.94f); + colors[ImGuiCol_FrameBg] = ImVec4(0.16f, 0.29f, 0.48f, 0.54f); + colors[ImGuiCol_FrameBgHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.40f); + colors[ImGuiCol_FrameBgActive] = ImVec4(0.26f, 0.59f, 0.98f, 0.67f); + colors[ImGuiCol_TitleBg] = ImVec4(0.04f, 0.04f, 0.04f, 1.00f); + colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.00f, 0.00f, 0.00f, 0.51f); + colors[ImGuiCol_TitleBgActive] = ImVec4(0.18f, 0.18f, 0.18f, 1.00f); + colors[ImGuiCol_MenuBarBg] = ImVec4(0.14f, 0.14f, 0.14f, 1.00f); + colors[ImGuiCol_ScrollbarBg] = ImVec4(0.02f, 0.02f, 0.02f, 0.53f); + colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.31f, 0.31f, 0.31f, 1.00f); + colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.41f, 0.41f, 0.41f, 1.00f); + colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.51f, 0.51f, 0.51f, 1.00f); + colors[ImGuiCol_ComboBg] = ImVec4(0.14f, 0.14f, 0.14f, 0.99f); + colors[ImGuiCol_CheckMark] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); + colors[ImGuiCol_SliderGrab] = ImVec4(0.24f, 0.52f, 0.88f, 1.00f); + colors[ImGuiCol_SliderGrabActive] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); + colors[ImGuiCol_Button] = ImVec4(0.26f, 0.59f, 0.98f, 0.40f); + colors[ImGuiCol_ButtonHovered] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); + colors[ImGuiCol_ButtonActive] = ImVec4(0.06f, 0.53f, 0.98f, 1.00f); + colors[ImGuiCol_Header] = ImVec4(0.26f, 0.59f, 0.98f, 0.31f); + colors[ImGuiCol_HeaderHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.80f); + colors[ImGuiCol_HeaderActive] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); + colors[ImGuiCol_Separator] = colors[ImGuiCol_Border];//ImVec4(0.61f, 0.61f, 0.61f, 1.00f); + colors[ImGuiCol_SeparatorHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.78f); + colors[ImGuiCol_SeparatorActive] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); + colors[ImGuiCol_ResizeGrip] = ImVec4(0.26f, 0.59f, 0.98f, 0.25f); + colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.67f); + colors[ImGuiCol_ResizeGripActive] = ImVec4(0.26f, 0.59f, 0.98f, 0.95f); + colors[ImGuiCol_CloseButton] = ImVec4(0.41f, 0.41f, 0.41f, 0.50f); + colors[ImGuiCol_CloseButtonHovered] = ImVec4(0.98f, 0.39f, 0.36f, 1.00f); + colors[ImGuiCol_CloseButtonActive] = ImVec4(0.98f, 0.39f, 0.36f, 1.00f); + colors[ImGuiCol_PlotLines] = ImVec4(0.61f, 0.61f, 0.61f, 1.00f); + colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.43f, 0.35f, 1.00f); + colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); + colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.60f, 0.00f, 1.00f); + colors[ImGuiCol_TextSelectedBg] = ImVec4(0.26f, 0.59f, 0.98f, 0.35f); + colors[ImGuiCol_ModalWindowDarkening] = ImVec4(0.80f, 0.80f, 0.80f, 0.35f); +} + //----------------------------------------------------------------------------- // ImDrawList //----------------------------------------------------------------------------- From f962ca0b0135aee66b5ce394507a0d473c6af603 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 27 Oct 2017 20:36:51 +0200 Subject: [PATCH 504/921] ColorTooltip: Resize ColorButton to align better with text, now that ColorButton provides a text baseline (0260fdd1c6c7198d60fcbd02cce82e4deb8954f4) --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index b9f54ff04..0c2e72a59 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9303,7 +9303,7 @@ void ImGui::ColorTooltip(const char* text, const float* col, ImGuiColorEditFlags Separator(); } - ImVec2 sz(g.FontSize * 3, g.FontSize * 3); + ImVec2 sz(g.FontSize * 3 + g.Style.FramePadding.y * 2, g.FontSize * 3 + g.Style.FramePadding.y * 2); ColorButton("##preview", ImVec4(col[0], col[1], col[2], col[3]), (flags & (ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf)) | ImGuiColorEditFlags_NoTooltip, sz); SameLine(); if (flags & ImGuiColorEditFlags_NoAlpha) From 3185a3a6975ba702e6f3d141375b50830a1b947b Mon Sep 17 00:00:00 2001 From: Adisorn Aeksatean Date: Sat, 28 Oct 2017 16:59:39 +0700 Subject: [PATCH 505/921] Add missing thai punctuations --- imgui_draw.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 8735e3fc1..c0eb09e75 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1955,6 +1955,7 @@ const ImWchar* ImFontAtlas::GetGlyphRangesThai() static const ImWchar ranges[] = { 0x0020, 0x00FF, // Basic Latin + 0x2000, 0x206F, // Punctuations 0x0E00, 0x0E7F, // Thai 0, }; From cb38caeda402e5b32c67b1c61ffe3e0b123b5651 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 28 Oct 2017 18:21:44 +0200 Subject: [PATCH 506/921] Examples: Added more comments near the fonts loading section, to catch common questions and errors (e.g. #1397, #1366, #1341, #1222, #1193, #1115, #951, etc.) --- examples/allegro5_example/main.cpp | 12 +++++++++--- examples/directx10_example/main.cpp | 12 +++++++++--- examples/directx11_example/main.cpp | 12 +++++++++--- examples/directx9_example/main.cpp | 12 +++++++++--- examples/marmalade_example/main.cpp | 12 +++++++++--- examples/opengl2_example/main.cpp | 12 +++++++++--- examples/opengl3_example/main.cpp | 12 +++++++++--- examples/sdl_opengl2_example/main.cpp | 12 +++++++++--- examples/sdl_opengl3_example/main.cpp | 12 +++++++++--- examples/vulkan_example/main.cpp | 12 +++++++++--- imgui.h | 6 +++--- 11 files changed, 93 insertions(+), 33 deletions(-) diff --git a/examples/allegro5_example/main.cpp b/examples/allegro5_example/main.cpp index cfff74ea4..1e274ff36 100644 --- a/examples/allegro5_example/main.cpp +++ b/examples/allegro5_example/main.cpp @@ -26,14 +26,20 @@ int main(int, char**) ImGui_ImplA5_Init(display); // Load Fonts - // (there is a default font, this is only if you want to change it. see extra_fonts/README.txt for more details) + // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. + // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. + // - If the file cannot be loaded, the function will return NULL. Please handle those errors in your application (e.g. use an assertion, or display an error and quit). + // - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call. + // - Read 'extra_fonts/README.txt' for more instructions and details. + // - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ ! //ImGuiIO& io = ImGui::GetIO(); //io.Fonts->AddFontDefault(); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Roboto-Medium.ttf", 16.0f); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Roboto-Medium.ttf", 16.0f); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); - //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + //IM_ASSERT(font != NULL); bool show_test_window = true; bool show_another_window = false; diff --git a/examples/directx10_example/main.cpp b/examples/directx10_example/main.cpp index ea690742d..0ed70bc38 100644 --- a/examples/directx10_example/main.cpp +++ b/examples/directx10_example/main.cpp @@ -126,14 +126,20 @@ int main(int, char**) ImGui_ImplDX10_Init(hwnd, g_pd3dDevice); // Load Fonts - // (there is a default font, this is only if you want to change it. see extra_fonts/README.txt for more details) + // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. + // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. + // - If the file cannot be loaded, the function will return NULL. Please handle those errors in your application (e.g. use an assertion, or display an error and quit). + // - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call. + // - Read 'extra_fonts/README.txt' for more instructions and details. + // - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ ! //ImGuiIO& io = ImGui::GetIO(); //io.Fonts->AddFontDefault(); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Roboto-Medium.ttf", 16.0f); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Roboto-Medium.ttf", 16.0f); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); - //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + //IM_ASSERT(font != NULL); bool show_test_window = true; bool show_another_window = false; diff --git a/examples/directx11_example/main.cpp b/examples/directx11_example/main.cpp index 794503e38..cd1b78828 100644 --- a/examples/directx11_example/main.cpp +++ b/examples/directx11_example/main.cpp @@ -129,14 +129,20 @@ int main(int, char**) ImGui_ImplDX11_Init(hwnd, g_pd3dDevice, g_pd3dDeviceContext); // Load Fonts - // (there is a default font, this is only if you want to change it. see extra_fonts/README.txt for more details) + // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. + // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. + // - If the file cannot be loaded, the function will return NULL. Please handle those errors in your application (e.g. use an assertion, or display an error and quit). + // - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call. + // - Read 'extra_fonts/README.txt' for more instructions and details. + // - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ ! //ImGuiIO& io = ImGui::GetIO(); //io.Fonts->AddFontDefault(); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Roboto-Medium.ttf", 16.0f); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Roboto-Medium.ttf", 16.0f); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); - //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + //IM_ASSERT(font != NULL); bool show_test_window = true; bool show_another_window = false; diff --git a/examples/directx9_example/main.cpp b/examples/directx9_example/main.cpp index 6a359c62b..bae6daeef 100644 --- a/examples/directx9_example/main.cpp +++ b/examples/directx9_example/main.cpp @@ -78,14 +78,20 @@ int main(int, char**) ImGui_ImplDX9_Init(hwnd, g_pd3dDevice); // Load Fonts - // (there is a default font, this is only if you want to change it. see extra_fonts/README.txt for more details) + // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. + // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. + // - If the file cannot be loaded, the function will return NULL. Please handle those errors in your application (e.g. use an assertion, or display an error and quit). + // - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call. + // - Read 'extra_fonts/README.txt' for more instructions and details. + // - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ ! //ImGuiIO& io = ImGui::GetIO(); //io.Fonts->AddFontDefault(); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Roboto-Medium.ttf", 16.0f); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Roboto-Medium.ttf", 16.0f); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); - //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + //IM_ASSERT(font != NULL); bool show_test_window = true; bool show_another_window = false; diff --git a/examples/marmalade_example/main.cpp b/examples/marmalade_example/main.cpp index eb0938ab7..f58c0c972 100644 --- a/examples/marmalade_example/main.cpp +++ b/examples/marmalade_example/main.cpp @@ -18,14 +18,20 @@ int main(int, char**) ImGui_Marmalade_Init(true); // Load Fonts - // (there is a default font, this is only if you want to change it. see extra_fonts/README.txt for more details) + // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. + // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. + // - If the file cannot be loaded, the function will return NULL. Please handle those errors in your application (e.g. use an assertion, or display an error and quit). + // - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call. + // - Read 'extra_fonts/README.txt' for more instructions and details. + // - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ ! //ImGuiIO& io = ImGui::GetIO(); //io.Fonts->AddFontDefault(); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Roboto-Medium.ttf", 16.0f); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Roboto-Medium.ttf", 16.0f); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); - //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + //IM_ASSERT(font != NULL); bool show_test_window = true; bool show_another_window = false; diff --git a/examples/opengl2_example/main.cpp b/examples/opengl2_example/main.cpp index bb688c687..232489cac 100644 --- a/examples/opengl2_example/main.cpp +++ b/examples/opengl2_example/main.cpp @@ -25,14 +25,20 @@ int main(int, char**) ImGui_ImplGlfwGL2_Init(window, true); // Load Fonts - // (there is a default font, this is only if you want to change it. see extra_fonts/README.txt for more details) + // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. + // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. + // - If the file cannot be loaded, the function will return NULL. Please handle those errors in your application (e.g. use an assertion, or display an error and quit). + // - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call. + // - Read 'extra_fonts/README.txt' for more instructions and details. + // - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ ! //ImGuiIO& io = ImGui::GetIO(); //io.Fonts->AddFontDefault(); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Roboto-Medium.ttf", 16.0f); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Roboto-Medium.ttf", 16.0f); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); - //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + //IM_ASSERT(font != NULL); bool show_test_window = true; bool show_another_window = false; diff --git a/examples/opengl3_example/main.cpp b/examples/opengl3_example/main.cpp index 6b20f8ce7..0a3289f91 100644 --- a/examples/opengl3_example/main.cpp +++ b/examples/opengl3_example/main.cpp @@ -33,14 +33,20 @@ int main(int, char**) ImGui_ImplGlfwGL3_Init(window, true); // Load Fonts - // (there is a default font, this is only if you want to change it. see extra_fonts/README.txt for more details) + // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. + // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. + // - If the file cannot be loaded, the function will return NULL. Please handle those errors in your application (e.g. use an assertion, or display an error and quit). + // - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call. + // - Read 'extra_fonts/README.txt' for more instructions and details. + // - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ ! //ImGuiIO& io = ImGui::GetIO(); //io.Fonts->AddFontDefault(); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Roboto-Medium.ttf", 16.0f); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Roboto-Medium.ttf", 16.0f); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); - //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + //IM_ASSERT(font != NULL); bool show_test_window = true; bool show_another_window = false; diff --git a/examples/sdl_opengl2_example/main.cpp b/examples/sdl_opengl2_example/main.cpp index 9d8a8622c..c1f17c8ca 100644 --- a/examples/sdl_opengl2_example/main.cpp +++ b/examples/sdl_opengl2_example/main.cpp @@ -31,14 +31,20 @@ int main(int, char**) ImGui_ImplSdlGL2_Init(window); // Load Fonts - // (there is a default font, this is only if you want to change it. see extra_fonts/README.txt for more details) + // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. + // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. + // - If the file cannot be loaded, the function will return NULL. Please handle those errors in your application (e.g. use an assertion, or display an error and quit). + // - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call. + // - Read 'extra_fonts/README.txt' for more instructions and details. + // - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ ! //ImGuiIO& io = ImGui::GetIO(); //io.Fonts->AddFontDefault(); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Roboto-Medium.ttf", 16.0f); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Roboto-Medium.ttf", 16.0f); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); - //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + //IM_ASSERT(font != NULL); bool show_test_window = true; bool show_another_window = false; diff --git a/examples/sdl_opengl3_example/main.cpp b/examples/sdl_opengl3_example/main.cpp index afd9fe58d..e07e6ca9b 100644 --- a/examples/sdl_opengl3_example/main.cpp +++ b/examples/sdl_opengl3_example/main.cpp @@ -34,14 +34,20 @@ int main(int, char**) ImGui_ImplSdlGL3_Init(window); // Load Fonts - // (there is a default font, this is only if you want to change it. see extra_fonts/README.txt for more details) + // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. + // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. + // - If the file cannot be loaded, the function will return NULL. Please handle those errors in your application (e.g. use an assertion, or display an error and quit). + // - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call. + // - Read 'extra_fonts/README.txt' for more instructions and details. + // - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ ! //ImGuiIO& io = ImGui::GetIO(); //io.Fonts->AddFontDefault(); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Roboto-Medium.ttf", 16.0f); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Roboto-Medium.ttf", 16.0f); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); - //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + //IM_ASSERT(font != NULL); bool show_test_window = true; bool show_another_window = false; diff --git a/examples/vulkan_example/main.cpp b/examples/vulkan_example/main.cpp index 379901749..2def96627 100644 --- a/examples/vulkan_example/main.cpp +++ b/examples/vulkan_example/main.cpp @@ -626,14 +626,20 @@ int main(int, char**) ImGui_ImplGlfwVulkan_Init(window, true, &init_data); // Load Fonts - // (there is a default font, this is only if you want to change it. see extra_fonts/README.txt for more details) + // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. + // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. + // - If the file cannot be loaded, the function will return NULL. Please handle those errors in your application (e.g. use an assertion, or display an error and quit). + // - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call. + // - Read 'extra_fonts/README.txt' for more instructions and details. + // - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ ! //ImGuiIO& io = ImGui::GetIO(); //io.Fonts->AddFontDefault(); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Roboto-Medium.ttf", 16.0f); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Roboto-Medium.ttf", 16.0f); //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); - //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + //IM_ASSERT(font != NULL); // Upload Fonts { diff --git a/imgui.h b/imgui.h index 2ac954d28..995b39801 100644 --- a/imgui.h +++ b/imgui.h @@ -1393,9 +1393,9 @@ struct ImFontAtlas IMGUI_API ImFont* AddFont(const ImFontConfig* font_cfg); IMGUI_API ImFont* AddFontDefault(const ImFontConfig* font_cfg = NULL); IMGUI_API ImFont* AddFontFromFileTTF(const char* filename, float size_pixels, const ImFontConfig* font_cfg = NULL, const ImWchar* glyph_ranges = NULL); - IMGUI_API ImFont* AddFontFromMemoryTTF(void* font_data, int font_size, float size_pixels, const ImFontConfig* font_cfg = NULL, const ImWchar* glyph_ranges = NULL); // Transfer ownership of 'ttf_data' to ImFontAtlas, will be deleted after Build() - IMGUI_API ImFont* AddFontFromMemoryCompressedTTF(const void* compressed_font_data, int compressed_font_size, float size_pixels, const ImFontConfig* font_cfg = NULL, const ImWchar* glyph_ranges = NULL); // 'compressed_font_data' still owned by caller. Compress with binary_to_compressed_c.cpp - IMGUI_API ImFont* AddFontFromMemoryCompressedBase85TTF(const char* compressed_font_data_base85, float size_pixels, const ImFontConfig* font_cfg = NULL, const ImWchar* glyph_ranges = NULL); // 'compressed_font_data_base85' still owned by caller. Compress with binary_to_compressed_c.cpp with -base85 paramaeter + IMGUI_API ImFont* AddFontFromMemoryTTF(void* font_data, int font_size, float size_pixels, const ImFontConfig* font_cfg = NULL, const ImWchar* glyph_ranges = NULL); // Note: Transfer ownership of 'ttf_data' to ImFontAtlas! Will be deleted after Build(). Set font_cfg->FontDataOwnedByAtlas to false to keep ownership. + IMGUI_API ImFont* AddFontFromMemoryCompressedTTF(const void* compressed_font_data, int compressed_font_size, float size_pixels, const ImFontConfig* font_cfg = NULL, const ImWchar* glyph_ranges = NULL); // 'compressed_font_data' still owned by caller. Compress with binary_to_compressed_c.cpp. + IMGUI_API ImFont* AddFontFromMemoryCompressedBase85TTF(const char* compressed_font_data_base85, float size_pixels, const ImFontConfig* font_cfg = NULL, const ImWchar* glyph_ranges = NULL); // 'compressed_font_data_base85' still owned by caller. Compress with binary_to_compressed_c.cpp with -base85 parameter. 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) From 36f00811b9c4b85d57441bc4b2017c0b861b62a4 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 28 Oct 2017 19:28:22 +0200 Subject: [PATCH 507/921] Examples: Comments to guide people unfamiliar with the librairies used. --- examples/opengl2_example/imgui_impl_glfw.cpp | 1 + examples/opengl2_example/imgui_impl_glfw.h | 6 +++--- examples/opengl2_example/main.cpp | 6 +++++- examples/opengl3_example/imgui_impl_glfw_gl3.cpp | 2 ++ examples/opengl3_example/imgui_impl_glfw_gl3.h | 2 ++ examples/opengl3_example/main.cpp | 4 +++- examples/sdl_opengl2_example/imgui_impl_sdl.cpp | 1 + examples/sdl_opengl2_example/imgui_impl_sdl.h | 1 + examples/sdl_opengl2_example/main.cpp | 1 + examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp | 2 ++ examples/sdl_opengl3_example/imgui_impl_sdl_gl3.h | 2 ++ examples/sdl_opengl3_example/main.cpp | 2 ++ 12 files changed, 25 insertions(+), 5 deletions(-) diff --git a/examples/opengl2_example/imgui_impl_glfw.cpp b/examples/opengl2_example/imgui_impl_glfw.cpp index 643606db8..f8bfddef5 100644 --- a/examples/opengl2_example/imgui_impl_glfw.cpp +++ b/examples/opengl2_example/imgui_impl_glfw.cpp @@ -1,5 +1,6 @@ // ImGui GLFW binding with OpenGL // In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// (GLFW is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan graphics context creation, etc.) // *DO NOT USE THIS CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL* // This is mostly provided as a reference to learn how ImGui integration works, because it is easier to read. diff --git a/examples/opengl2_example/imgui_impl_glfw.h b/examples/opengl2_example/imgui_impl_glfw.h index 470863af3..f17833ae1 100644 --- a/examples/opengl2_example/imgui_impl_glfw.h +++ b/examples/opengl2_example/imgui_impl_glfw.h @@ -1,9 +1,9 @@ // ImGui GLFW binding with OpenGL // In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// (GLFW is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan graphics context creation, etc.) -// If your context is GL3/GL3 then prefer using the code in opengl3_example. -// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). -// We cannot do that from GL2 code because the function doesn't exist. +// *DO NOT USE THIS CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL* +// See imgui_impl_glfw.cpp for details. // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. // If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). diff --git a/examples/opengl2_example/main.cpp b/examples/opengl2_example/main.cpp index 232489cac..d5643db30 100644 --- a/examples/opengl2_example/main.cpp +++ b/examples/opengl2_example/main.cpp @@ -1,5 +1,9 @@ -// ImGui - standalone example application for Glfw + OpenGL 2, using fixed pipeline +// ImGui - standalone example application for GLFW + OpenGL 2, using fixed pipeline // If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// (GLFW is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan graphics context creation, etc.) + +// *DO NOT USE THIS CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL* +// See imgui_impl_glfw.cpp for details. #include #include "imgui_impl_glfw.h" diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp index 3611d6e6c..bf143a11b 100644 --- a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp +++ b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp @@ -1,5 +1,7 @@ // ImGui GLFW binding with OpenGL3 + shaders // In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// (GLFW is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan graphics context creation, etc.) +// (GL3W is a helper library to access OpenGL functions since there is no standard header to access modern OpenGL functions easily. Alternatives are GLEW, Glad, etc.) // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. // If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.h b/examples/opengl3_example/imgui_impl_glfw_gl3.h index 83c69aa86..5f3043988 100644 --- a/examples/opengl3_example/imgui_impl_glfw_gl3.h +++ b/examples/opengl3_example/imgui_impl_glfw_gl3.h @@ -1,5 +1,7 @@ // ImGui GLFW binding with OpenGL3 + shaders // In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// (GLFW is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan graphics context creation, etc.) +// (GL3W is a helper library to access OpenGL functions since there is no standard header to access modern OpenGL functions easily. Alternatives are GLEW, Glad, etc.) // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. // If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). diff --git a/examples/opengl3_example/main.cpp b/examples/opengl3_example/main.cpp index 0a3289f91..5d778e893 100644 --- a/examples/opengl3_example/main.cpp +++ b/examples/opengl3_example/main.cpp @@ -1,5 +1,7 @@ -// ImGui - standalone example application for Glfw + OpenGL 3, using programmable pipeline +// ImGui - standalone example application for GLFW + OpenGL 3, using programmable pipeline // If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// (GLFW is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan graphics context creation, etc.) +// (GL3W is a helper library to access OpenGL functions since there is no standard header to access modern OpenGL functions easily. Alternatives are GLEW, Glad, etc.) #include #include "imgui_impl_glfw_gl3.h" diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl.cpp b/examples/sdl_opengl2_example/imgui_impl_sdl.cpp index 8f870eb62..261706ede 100644 --- a/examples/sdl_opengl2_example/imgui_impl_sdl.cpp +++ b/examples/sdl_opengl2_example/imgui_impl_sdl.cpp @@ -1,5 +1,6 @@ // ImGui SDL2 binding with OpenGL // In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// (SDL is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan graphics context creation, etc.) // *DO NOT USE THIS CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL* // This is mostly provided as a reference to learn how ImGui integration works, because it is easier to read. diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl.h b/examples/sdl_opengl2_example/imgui_impl_sdl.h index 65b2bd996..ea94f69a7 100644 --- a/examples/sdl_opengl2_example/imgui_impl_sdl.h +++ b/examples/sdl_opengl2_example/imgui_impl_sdl.h @@ -1,5 +1,6 @@ // ImGui SDL2 binding with OpenGL // In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// (SDL is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan graphics context creation, etc.) // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. // If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). diff --git a/examples/sdl_opengl2_example/main.cpp b/examples/sdl_opengl2_example/main.cpp index c1f17c8ca..6f60833e9 100644 --- a/examples/sdl_opengl2_example/main.cpp +++ b/examples/sdl_opengl2_example/main.cpp @@ -1,5 +1,6 @@ // ImGui - standalone example application for SDL2 + OpenGL // If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// (SDL is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan graphics context creation, etc.) #include #include "imgui_impl_sdl.h" diff --git a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp index 0301d31bc..b1604bd03 100644 --- a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp +++ b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp @@ -1,5 +1,7 @@ // ImGui SDL2 binding with OpenGL3 // In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// (SDL is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan graphics context creation, etc.) +// (GL3W is a helper library to access OpenGL functions since there is no standard header to access modern OpenGL functions easily. Alternatives are GLEW, Glad, etc.) // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. // If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). diff --git a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.h b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.h index 99abd4094..543818664 100644 --- a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.h +++ b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.h @@ -1,5 +1,7 @@ // ImGui SDL2 binding with OpenGL3 // In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// (SDL is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan graphics context creation, etc.) +// (GL3W is a helper library to access OpenGL functions since there is no standard header to access modern OpenGL functions easily. Alternatives are GLEW, Glad, etc.) // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. // If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). diff --git a/examples/sdl_opengl3_example/main.cpp b/examples/sdl_opengl3_example/main.cpp index e07e6ca9b..2494208b9 100644 --- a/examples/sdl_opengl3_example/main.cpp +++ b/examples/sdl_opengl3_example/main.cpp @@ -1,5 +1,7 @@ // ImGui - standalone example application for SDL2 + OpenGL // If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// (SDL is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan graphics context creation, etc.) +// (GL3W is a helper library to access OpenGL functions since there is no standard header to access modern OpenGL functions easily. Alternatives are GLEW, Glad, etc.) #include #include "imgui_impl_sdl_gl3.h" From f793562b4e52913b7e60ae39729fcfb8ab7c05e7 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 29 Oct 2017 11:23:38 +0100 Subject: [PATCH 508/921] TODO --- TODO.txt | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/TODO.txt b/TODO.txt index f1976f2fb..c305a4114 100644 --- a/TODO.txt +++ b/TODO.txt @@ -7,6 +7,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - doc/test: add a proper documentation+regression testing system (#435) - doc/test: checklist app to verify binding/integration of imgui (test inputs, rendering, callback, etc.). + - doc/tips: tips of the day: website? applet in imgui_club? - project: folder or separate repository with maintained helpers (e.g. imgui_memory_editor.h, imgui_stl.h, maybe imgui_dock would be there?) - window: calling SetNextWindowSize() every frame with <= 0 doesn't do anything, may be useful to allow (particularly when used for a single axis). (#690) @@ -20,7 +21,6 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - window: a collapsed window can be stuck behind the main menu bar? - window: when window is very small, prioritize resize button over close button. - window: detect extra End() call that pop the "Debug" window out and assert at End() call site instead of at end of frame. - - window/tooltip: allow to set the width of a tooltip to allow TextWrapped() etc. while keeping the height automatic. - window: increase minimum size of a window with menus or fix the menu rendering so that it doesn't look odd. - window: double-clicking on title bar to minimize isn't consistent, perhaps move to single-click on left-most collapse icon? - window: expose contents size. (#1045) @@ -86,6 +86,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - columns: optional sorting modifiers (up/down), sort list so sorting can be done multi-critera. notify user when sort order changed. - columns: option to alternate background colors on odd/even scanlines. - columns: allow columns to recurse. + - columns: allow a same columns set to be interrupted by e.g. CollapsingHeader and resume with columns in sync when moving them. - columns: separator function or parameter that works within the column (currently Separator() bypass all columns) (#125) - columns: flag to add horizontal separator above/below? - columns/layout: setup minimum line height (equivalent of automatically calling AlignFirstTextHeightToWidgets) @@ -152,7 +153,9 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - popups: add variant using global identifier similar to Begin/End (#402) - popups: border options. richer api like BeginChild() perhaps? (#197) - tooltip: tooltip that doesn't fit in entire screen seems to lose their "last preferred direction" and may teleport when moving mouse. - + - tooltip: allow to set the width of a tooltip to allow TextWrapped() etc. while keeping the height automatic. + - tooltip: allow tooltips with timers? or general timer policy? (instaneous vs timed) + - menus: calling BeginMenu() twice with a same name doesn't append as Begin() does for regular windows (#1207) - statusbar: add a per-window status bar helper similar to what menubar does. - shortcuts: local-style shortcut api, e.g. parse "&Save" @@ -205,7 +208,8 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - markup: simple markup language for color change? !- font: better CalcTextSizeA() API, at least for simple use cases. current one is horrible (perhaps have simple vs extended versions). - - font: enforce monospace through ImFontConfig (for icons?) + - font: better vertical centering (based e.g on height of lowercase 'x'?). currently Roboto-Medium size 16 px isn't currently centered. + - font: enforce monospace through ImFontConfig (for icons?) + create dual ImFont output from same input, reusing rasterized data but with different glyphs/AdvanceX - font: finish CustomRectRegister() to allow mapping unicode codepoint to custom texture data - font: PushFontSize API (#1018) - font/atlas: incremental updates From 53f9e28c77ab404e8cc7deeb0e2c5ec7fca999ea Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 29 Oct 2017 11:28:29 +0100 Subject: [PATCH 509/921] GetGlyphRangesThai(): removed extraneous codepoints (#1396) --- imgui_draw.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index c0eb09e75..56cb4b6ad 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1955,7 +1955,7 @@ const ImWchar* ImFontAtlas::GetGlyphRangesThai() static const ImWchar ranges[] = { 0x0020, 0x00FF, // Basic Latin - 0x2000, 0x206F, // Punctuations + 0x2010, 0x205E, // Punctuations 0x0E00, 0x0E7F, // Thai 0, }; From c5536e49efb61d786ea7f5a07031eeca34e00ec1 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 29 Oct 2017 21:15:02 +0100 Subject: [PATCH 510/921] Drag and drop API experiment --- imgui.cpp | 172 ++++++++++++++++++++++++++++++++++++++++++++++- imgui_internal.h | 53 +++++++++++++++ 2 files changed, 223 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 0c2e72a59..ad4a1895f 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2231,6 +2231,15 @@ void ImGui::NewFrame() if (g.ScalarAsInputTextId && g.ActiveId != g.ScalarAsInputTextId) g.ScalarAsInputTextId = 0; + // Elapse drag & drop payload + if (g.DragDropActive && g.DragDropPayload.DataFrameCount + 1 < g.FrameCount) + { + g.DragDropActive = false; + g.DragDropPayload.Clear(); + g.DragDropPayloadBufHeap.clear(); + memset(&g.DragDropPayloadBufLocal, 0, sizeof(g.DragDropPayloadBufLocal)); + } + // Update keyboard input state memcpy(g.IO.KeysDownDurationPrev, g.IO.KeysDownDuration, sizeof(g.IO.KeysDownDuration)); for (int i = 0; i < IM_ARRAYSIZE(g.IO.KeysDown); i++) @@ -5868,7 +5877,8 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool { if (hovered && (flags & ImGuiButtonFlags_PressedOnClickRelease)) if (!((flags & ImGuiButtonFlags_Repeat) && g.IO.MouseDownDurationPrev[0] >= g.IO.KeyRepeatDelay)) // Repeat mode trumps - pressed = true; + if (!g.DragDropActive) + pressed = true; ClearActiveID(); } } @@ -9426,7 +9436,7 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl else window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_FrameBg), rounding); // Color button are often in need of some sort of border - if (hovered && !(flags & ImGuiColorEditFlags_NoTooltip)) + if (!(flags & ImGuiColorEditFlags_NoTooltip) && hovered) ColorTooltip(desc_id, &col.x, flags & (ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf)); return pressed; @@ -10584,6 +10594,164 @@ void ImGui::Value(const char* prefix, float v, const char* float_format) } } +//----------------------------------------------------------------------------- +// DRAG AND DROP +//----------------------------------------------------------------------------- + +// Call when current ID is active. +// When this returns true you need to: a) call SetDragDropPayload() exactly once, b) you may render the payload visual/description, c) call EndDragDropSource() +bool ImGui::BeginDragDropSource(ImGuiDragDropFlags flags, int mouse_button) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + if (g.IO.MouseDown[mouse_button] == false) + return false; + if (g.ActiveId != window->DC.LastItemId) + return false; + + if (IsMouseDragging(mouse_button)) + { + if (!g.DragDropActive) + { + ImGuiPayload& payload = g.DragDropPayload; + payload.Clear(); + payload.SourceId = g.ActiveId; + payload.SourceParentId = window->IDStack.back(); + g.DragDropActive = true; + g.DragDropSourceFlags = flags; + g.DragDropMouseButton = mouse_button; + } + + if (!(flags & ImGuiDragDropFlags_SourceNoAutoTooltip)) + { + // FIXME-DRAG + //SetNextWindowPos(g.IO.MousePos - g.ActiveIdClickOffset - g.Style.WindowPadding); + //PushStyleVar(ImGuiStyleVar_Alpha, g.Style.Alpha * 0.60f); // This is better but e.g ColorButton with checkboard has issue with transparent colors :( + SetNextWindowPos(g.IO.MousePos); + PushStyleColor(ImGuiCol_PopupBg, GetStyleColorVec4(ImGuiCol_PopupBg) * ImVec4(1.0f, 1.0f, 1.0f, 0.6f)); + BeginTooltipEx(ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_ShowBorders); + } + return true; + } + return false; +} + +void ImGui::EndDragDropSource() +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(g.DragDropActive); + IM_ASSERT(g.DragDropPayload.DataFrameCount != -1); // Forgot to call SetDragDropSourcePayload(), at least once on the first frame of a successful BeginDragDropSource() + + if (!(g.DragDropSourceFlags & ImGuiDragDropFlags_SourceNoAutoTooltip)) + { + EndTooltip(); + PopStyleColor(); + //PopStyleVar(); + } +} + +// Use 'cond' to choose to submit paypload on drag start or every frame +bool ImGui::SetDragDropPayload(const char* type, const void* data, size_t data_size, ImGuiCond cond) +{ + ImGuiContext& g = *GImGui; + ImGuiPayload& payload = g.DragDropPayload; + if (cond == 0) + cond = ImGuiCond_Always; + + IM_ASSERT(type != NULL); + IM_ASSERT(strlen(type) < IM_ARRAYSIZE(payload.DataType)); // Payload type can be at most 8 characters longs + IM_ASSERT(data != NULL && data_size > 0); + IM_ASSERT(cond == ImGuiCond_Always || cond == ImGuiCond_Once); + IM_ASSERT(payload.SourceId != 0); // Not called between BeginDragDropSource() and EndDragDropSource() + + if (cond == ImGuiCond_Always || payload.DataFrameCount == -1) + { + // Copy payload + ImStrncpy(payload.DataType, type, IM_ARRAYSIZE(payload.DataType)); + g.DragDropPayloadBufHeap.resize(0); + if (data_size > sizeof(g.DragDropPayloadBufLocal)) + { + // Store in heap + g.DragDropPayloadBufHeap.resize((int)data_size); + payload.Data = g.DragDropPayloadBufHeap.Data; + memcpy((void*)payload.Data, data, data_size); + } + else if (data_size > 0) + { + // Store locally + memset(&g.DragDropPayloadBufLocal, 0, sizeof(g.DragDropPayloadBufLocal)); + payload.Data = g.DragDropPayloadBufLocal; + memcpy((void*)payload.Data, data, data_size); + } + else + { + payload.Data = NULL; + } + payload.DataSize = (int)data_size; + } + payload.DataFrameCount = g.FrameCount; + + return (payload.AcceptFrameCount == g.FrameCount) || (payload.AcceptFrameCount == g.FrameCount - 1); +} + +bool ImGui::BeginDragDropTarget() +{ + ImGuiContext& g = *GImGui; + if (!g.DragDropActive) + return false; + + ImGuiWindow* window = g.CurrentWindow; + //if (!window->DC.LastItemRectHoveredRect || (g.ActiveId == g.DragDropPayload.SourceId || g.ActiveIdPreviousFrame == g.DragDropPayload.SourceId)) + if (!window->DC.LastItemRectHoveredRect || (window->DC.LastItemId && window->DC.LastItemId == g.DragDropPayload.SourceId)) + return false; + if (window->RootWindow != g.HoveredWindow->RootWindow) + return false; + + return true; +} + +const ImGuiPayload* ImGui::AcceptDragDropPayload(const char* type, ImGuiDragDropFlags flags) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + ImGuiPayload& payload = g.DragDropPayload; + IM_ASSERT(g.DragDropActive); // Not called between BeginDragDropTarget() and EndDragDropTarget() ? + IM_ASSERT(window->DC.LastItemRectHoveredRect); // Not called between BeginDragDropTarget() and EndDragDropTarget() ? + IM_ASSERT(payload.DataFrameCount != -1); // Internal/usage error, please report! + if (type != NULL && !payload.IsDataType(type)) + return NULL; + + if (payload.AcceptId == 0) + payload.AcceptId = window->DC.LastItemId; + + bool was_accepted_previously = (payload.AcceptFrameCount == g.FrameCount - 1); + if (payload.AcceptFrameCount != g.FrameCount) + { + // Render drop visuals + if (!(flags & ImGuiDragDropFlags_AcceptNoDrawDefaultRect) && was_accepted_previously) + { + ImRect r = window->DC.LastItemRect; + r.Expand(4.0f); + window->DrawList->AddRectFilled(r.Min, r.Max, IM_COL32(255, 255, 0, 20), 0.0f); // FIXME-DRAG FIXME-STYLE + window->DrawList->AddRect(r.Min, r.Max, IM_COL32(255, 255, 0, 255), 0.0f, ~0, 2.0f); // FIXME-DRAG FIXME-STYLE + } + payload.AcceptFrameCount = g.FrameCount; + } + + payload.Delivery = was_accepted_previously && IsMouseReleased(g.DragDropMouseButton); + if (!payload.Delivery && !(flags & ImGuiDragDropFlags_AcceptBeforeDelivery)) + return NULL; + + return &payload; +} + +// We don't really use/need this now, but added it for the sake of consistency and because we might need it later. +void ImGui::EndDragDropTarget() +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(g.DragDropActive); +} + //----------------------------------------------------------------------------- // PLATFORM DEPENDENT HELPERS //----------------------------------------------------------------------------- diff --git a/imgui_internal.h b/imgui_internal.h index 1cb723ca7..5c82ea1d8 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -43,9 +43,11 @@ struct ImGuiIniData; struct ImGuiMouseCursorData; struct ImGuiPopupRef; struct ImGuiWindow; +struct ImGuiPayload; // User data payload for drag and drop operations typedef int ImGuiLayoutType; // enum: horizontal or vertical // enum ImGuiLayoutType_ typedef int ImGuiButtonFlags; // flags: for ButtonEx(), ButtonBehavior() // enum ImGuiButtonFlags_ +typedef int ImGuiDragDropFlags; // flags: for *DragDrop*() // enum ImGuiDragDropFlags_ typedef int ImGuiItemFlags; // flags: for PushItemFlag() // enum ImGuiItemFlags_ typedef int ImGuiSeparatorFlags; // flags: for Separator() - internal // enum ImGuiSeparatorFlags_ typedef int ImGuiSliderFlags; // flags: for SliderBehavior() // enum ImGuiSliderFlags_ @@ -215,6 +217,15 @@ enum ImGuiSeparatorFlags_ ImGuiSeparatorFlags_Vertical = 1 << 1 }; +// Flags for ImGui::BeginDragDropSource(), ImGui::AcceptDragDropPayload() +enum ImGuiDragDropFlags_ +{ + ImGuiDragDropFlags_SourceNoAutoTooltip = 1 << 0, + ImGuiDragDropFlags_AcceptBeforeDelivery = 1 << 1, // AcceptDragDropPayload() returns true even before the mouse button is released. You can then call IsDelivery() to test if the payload needs to be delivered. + ImGuiDragDropFlags_AcceptNoDrawDefaultRect = 1 << 2, // Do not draw the default highlight rectangle when hovering over target. + ImGuiDragDropFlags_AcceptPeekOnly = ImGuiDragDropFlags_AcceptBeforeDelivery | ImGuiDragDropFlags_AcceptNoDrawDefaultRect // For peeking ahead and inspecting the payload before delivery. +}; + // FIXME: this is in development, not exposed/functional as a generic feature yet. enum ImGuiLayoutType_ { @@ -404,6 +415,28 @@ struct ImGuiPopupRef ImGuiPopupRef(ImGuiID id, ImGuiWindow* parent_window, ImGuiID parent_menu_set, const ImVec2& mouse_pos) { PopupId = id; Window = NULL; ParentWindow = parent_window; ParentMenuSet = parent_menu_set; MousePosOnOpen = mouse_pos; } }; +// Data payload for Drag and Drop operations +struct ImGuiPayload +{ + // Members + const void* Data; // Data (copied and owned by dear imgui) + int DataSize; // Data size + + // [Internal] + ImGuiID SourceId; // Source item id + ImGuiID SourceParentId; // Source parent id (if available) + ImGuiID AcceptId; // Target item id (set at the time of accepting the payload) + int AcceptFrameCount; // Last time a target expressed a desire to accept the source + int DataFrameCount; // Data timestamp + char DataType[8 + 1]; // Data type tag (short user-supplied string) + bool Delivery; // Set when AcceptDragDropPayload() was called and the mouse button is released over the target item + + ImGuiPayload() { Clear(); } + void Clear() { SourceId = SourceParentId = AcceptId = 0; AcceptFrameCount = -1; Data = NULL; DataSize = 0; memset(DataType, 0, sizeof(DataType)); DataFrameCount = -1; Delivery = false; } + bool IsDataType(const char* type) const { return DataFrameCount != -1 && strcmp(type, DataType) == 0; } + bool IsDelivery() const { return Delivery; } +}; + // Main state for ImGui struct ImGuiContext { @@ -472,6 +505,14 @@ struct ImGuiContext ImGuiMouseCursor MouseCursor; ImGuiMouseCursorData MouseCursorData[ImGuiMouseCursor_Count_]; + // Drag and Drop + bool DragDropActive; + ImGuiDragDropFlags DragDropSourceFlags; + int DragDropMouseButton; + ImGuiPayload DragDropPayload; + ImVector DragDropPayloadBufHeap; // We don't expose the ImVector<> directly + unsigned char DragDropPayloadBufLocal[8]; + // Widget state ImGuiTextEditState InputTextState; ImFont InputTextPasswordFont; @@ -547,6 +588,10 @@ struct ImGuiContext SetNextTreeNodeOpenVal = false; SetNextTreeNodeOpenCond = 0; + DragDropActive = false; + DragDropSourceFlags = 0; + DragDropMouseButton = -1; + ScalarAsInputTextId = 0; ColorEditOptions = ImGuiColorEditFlags__OptionsDefault; DragCurrentValue = 0.0f; @@ -810,6 +855,14 @@ namespace ImGui IMGUI_API void Scrollbar(ImGuiLayoutType direction); IMGUI_API void VerticalSeparator(); // Vertical separator, for menu bars (use current line height). not exposed because it is misleading what it doesn't have an effect on regular layout. + // FIXME-WIP: New Drag and Drop API + IMGUI_API bool BeginDragDropSource(ImGuiDragDropFlags flags = 0, int mouse_button = 0); // Call when the current item is active. If this return true, you can call SetDragDropPayload() + EndDragDropSource() + IMGUI_API bool SetDragDropPayload(const char* type, const void* data, size_t data_size, ImGuiCond cond = 0); // Type is a user defined string of maximum 8 characters. Strings starting with '_' are reserved for dear imgui internal types. Data is copied and held by imgui. + IMGUI_API void EndDragDropSource(); + IMGUI_API bool BeginDragDropTarget(); // Call after submitting an item that may receive an item. If this returns true, you can call AcceptDragDropPayload() + EndDragDropTarget() + IMGUI_API const ImGuiPayload* AcceptDragDropPayload(const char* type, ImGuiDragDropFlags flags = 0); // Accept contents of a given type. If ImGuiDragDropFlags_AcceptBeforeDelivery is set you can peek into the payload before the mouse button is released. + IMGUI_API void EndDragDropTarget(); + // FIXME-WIP: New Columns API IMGUI_API void BeginColumns(const char* id, int count, ImGuiColumnsFlags flags = 0); // setup number of columns. use an identifier to distinguish multiple column sets. close with EndColumns(). IMGUI_API void EndColumns(); // close columns From b5f714e9f9d222f8e10ef641b2dabbcbf76fcfed Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 29 Oct 2017 21:31:49 +0100 Subject: [PATCH 511/921] Drag and Drop: made BeginDragDropSource() clear the IsItemHovered() by default, added a flag to keep it. --- imgui.cpp | 4 ++++ imgui_internal.h | 7 +++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index ad4a1895f..b11a28d73 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -10631,6 +10631,10 @@ bool ImGui::BeginDragDropSource(ImGuiDragDropFlags flags, int mouse_button) PushStyleColor(ImGuiCol_PopupBg, GetStyleColorVec4(ImGuiCol_PopupBg) * ImVec4(1.0f, 1.0f, 1.0f, 0.6f)); BeginTooltipEx(ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_ShowBorders); } + + if (!(flags & ImGuiDragDropFlags_SourceNoDisableHover)) + window->DC.LastItemRectHoveredRect = false; + return true; } return false; diff --git a/imgui_internal.h b/imgui_internal.h index 5c82ea1d8..d8dfca1cc 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -220,9 +220,12 @@ enum ImGuiSeparatorFlags_ // Flags for ImGui::BeginDragDropSource(), ImGui::AcceptDragDropPayload() enum ImGuiDragDropFlags_ { + // BeginDragDropSource() flags ImGuiDragDropFlags_SourceNoAutoTooltip = 1 << 0, - ImGuiDragDropFlags_AcceptBeforeDelivery = 1 << 1, // AcceptDragDropPayload() returns true even before the mouse button is released. You can then call IsDelivery() to test if the payload needs to be delivered. - ImGuiDragDropFlags_AcceptNoDrawDefaultRect = 1 << 2, // Do not draw the default highlight rectangle when hovering over target. + ImGuiDragDropFlags_SourceNoDisableHover = 1 << 1, // By default, when dragging we clear data so that IsItemHovered() will return true, to avoid subsequent user code submitting tooltips. + // BeginDragDropTarget() flags + ImGuiDragDropFlags_AcceptBeforeDelivery = 1 << 10, // AcceptDragDropPayload() returns true even before the mouse button is released. You can then call IsDelivery() to test if the payload needs to be delivered. + ImGuiDragDropFlags_AcceptNoDrawDefaultRect = 1 << 11, // Do not draw the default highlight rectangle when hovering over target. ImGuiDragDropFlags_AcceptPeekOnly = ImGuiDragDropFlags_AcceptBeforeDelivery | ImGuiDragDropFlags_AcceptNoDrawDefaultRect // For peeking ahead and inspecting the payload before delivery. }; From acf78da74288ba03875d387f502f8faf05ec6b76 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 29 Oct 2017 21:37:14 +0100 Subject: [PATCH 512/921] Drag and drop: moved to imgui.h --- imgui.h | 44 ++++++++++++++++++++++++++++++++++++++++++++ imgui_internal.h | 45 +-------------------------------------------- 2 files changed, 45 insertions(+), 44 deletions(-) diff --git a/imgui.h b/imgui.h index 995b39801..7f1baa9c8 100644 --- a/imgui.h +++ b/imgui.h @@ -64,6 +64,7 @@ struct ImGuiTextBuffer; // Text buffer for logging/accumulating text struct ImGuiTextEditCallbackData; // Shared state of ImGui::InputText() when using custom ImGuiTextEditCallback (rare/advanced use) struct ImGuiSizeConstraintCallbackData;// Structure used to constraint window size in custom ways when using custom ImGuiSizeConstraintCallback (rare/advanced use) struct ImGuiListClipper; // Helper to manually clip large list of items +struct ImGuiPayload; // User data payload for drag and drop operations struct ImGuiContext; // ImGui context (opaque) // Typedefs and Enumerations (declared as int for compatibility and to not pollute the top of this file) @@ -77,6 +78,7 @@ typedef int ImGuiKey; // enum: a key identifier (ImGui-side enum) typedef int ImGuiMouseCursor; // enum: a mouse cursor identifier // enum ImGuiMouseCursor_ typedef int ImGuiCond; // enum: a condition for Set*() // enum ImGuiCond_ typedef int ImGuiColorEditFlags; // flags: color edit flags for Color*() // enum ImGuiColorEditFlags_ +typedef int ImGuiDragDropFlags; // flags: for *DragDrop*() // enum ImGuiDragDropFlags_ typedef int ImGuiWindowFlags; // flags: window flags for Begin*() // enum ImGuiWindowFlags_ typedef int ImGuiColumnsFlags; // flags: for *Columns*() // enum ImGuiColumnsFlags_ typedef int ImGuiInputTextFlags; // flags: for InputText*() // enum ImGuiInputTextFlags_ @@ -410,6 +412,14 @@ namespace ImGui IMGUI_API void LogButtons(); // helper to display buttons for logging to tty/file/clipboard IMGUI_API void LogText(const char* fmt, ...) IM_FMTARGS(1); // pass text data straight to log (without being displayed) + // Drag and Drop + IMGUI_API bool BeginDragDropSource(ImGuiDragDropFlags flags = 0, int mouse_button = 0); // Call when the current item is active. If this return true, you can call SetDragDropPayload() + EndDragDropSource() + IMGUI_API bool SetDragDropPayload(const char* type, const void* data, size_t data_size, ImGuiCond cond = 0); // Type is a user defined string of maximum 8 characters. Strings starting with '_' are reserved for dear imgui internal types. Data is copied and held by imgui. + IMGUI_API void EndDragDropSource(); + IMGUI_API bool BeginDragDropTarget(); // Call after submitting an item that may receive an item. If this returns true, you can call AcceptDragDropPayload() + EndDragDropTarget() + IMGUI_API const ImGuiPayload* AcceptDragDropPayload(const char* type, ImGuiDragDropFlags flags = 0); // Accept contents of a given type. If ImGuiDragDropFlags_AcceptBeforeDelivery is set you can peek into the payload before the mouse button is released. + IMGUI_API void EndDragDropTarget(); + // Clipping IMGUI_API void PushClipRect(const ImVec2& clip_rect_min, const ImVec2& clip_rect_max, bool intersect_with_current_clip_rect); IMGUI_API void PopClipRect(); @@ -583,6 +593,18 @@ enum ImGuiHoveredFlags_ ImGuiHoveredFlags_RectOnly = ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem | ImGuiHoveredFlags_AllowWhenOverlapped }; +// Flags for ImGui::BeginDragDropSource(), ImGui::AcceptDragDropPayload() +enum ImGuiDragDropFlags_ +{ + // BeginDragDropSource() flags + ImGuiDragDropFlags_SourceNoAutoTooltip = 1 << 0, + ImGuiDragDropFlags_SourceNoDisableHover = 1 << 1, // By default, when dragging we clear data so that IsItemHovered() will return true, to avoid subsequent user code submitting tooltips. + // BeginDragDropTarget() flags + ImGuiDragDropFlags_AcceptBeforeDelivery = 1 << 10, // AcceptDragDropPayload() returns true even before the mouse button is released. You can then call IsDelivery() to test if the payload needs to be delivered. + ImGuiDragDropFlags_AcceptNoDrawDefaultRect = 1 << 11, // Do not draw the default highlight rectangle when hovering over target. + ImGuiDragDropFlags_AcceptPeekOnly = ImGuiDragDropFlags_AcceptBeforeDelivery | ImGuiDragDropFlags_AcceptNoDrawDefaultRect // For peeking ahead and inspecting the payload before delivery. +}; + // User fill ImGuiIO.KeyMap[] array with indices into the ImGuiIO.KeysDown[512] array enum ImGuiKey_ { @@ -1118,6 +1140,28 @@ struct ImGuiSizeConstraintCallbackData ImVec2 DesiredSize; // Read-write. Desired size, based on user's mouse position. Write to this field to restrain resizing. }; +// Data payload for Drag and Drop operations +struct ImGuiPayload +{ + // Members + const void* Data; // Data (copied and owned by dear imgui) + int DataSize; // Data size + + // [Internal] + ImGuiID SourceId; // Source item id + ImGuiID SourceParentId; // Source parent id (if available) + ImGuiID AcceptId; // Target item id (set at the time of accepting the payload) + int AcceptFrameCount; // Last time a target expressed a desire to accept the source + int DataFrameCount; // Data timestamp + char DataType[8 + 1]; // Data type tag (short user-supplied string) + bool Delivery; // Set when AcceptDragDropPayload() was called and the mouse button is released over the target item + + ImGuiPayload() { Clear(); } + void Clear() { SourceId = SourceParentId = AcceptId = 0; AcceptFrameCount = -1; Data = NULL; DataSize = 0; memset(DataType, 0, sizeof(DataType)); DataFrameCount = -1; Delivery = false; } + bool IsDataType(const char* type) const { return DataFrameCount != -1 && strcmp(type, DataType) == 0; } + bool IsDelivery() const { return Delivery; } +}; + // Helpers macros to generate 32-bits encoded colors #ifdef IMGUI_USE_BGRA_PACKED_COLOR #define IM_COL32_R_SHIFT 16 diff --git a/imgui_internal.h b/imgui_internal.h index d8dfca1cc..666b4491a 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -43,11 +43,9 @@ struct ImGuiIniData; struct ImGuiMouseCursorData; struct ImGuiPopupRef; struct ImGuiWindow; -struct ImGuiPayload; // User data payload for drag and drop operations typedef int ImGuiLayoutType; // enum: horizontal or vertical // enum ImGuiLayoutType_ typedef int ImGuiButtonFlags; // flags: for ButtonEx(), ButtonBehavior() // enum ImGuiButtonFlags_ -typedef int ImGuiDragDropFlags; // flags: for *DragDrop*() // enum ImGuiDragDropFlags_ typedef int ImGuiItemFlags; // flags: for PushItemFlag() // enum ImGuiItemFlags_ typedef int ImGuiSeparatorFlags; // flags: for Separator() - internal // enum ImGuiSeparatorFlags_ typedef int ImGuiSliderFlags; // flags: for SliderBehavior() // enum ImGuiSliderFlags_ @@ -217,18 +215,6 @@ enum ImGuiSeparatorFlags_ ImGuiSeparatorFlags_Vertical = 1 << 1 }; -// Flags for ImGui::BeginDragDropSource(), ImGui::AcceptDragDropPayload() -enum ImGuiDragDropFlags_ -{ - // BeginDragDropSource() flags - ImGuiDragDropFlags_SourceNoAutoTooltip = 1 << 0, - ImGuiDragDropFlags_SourceNoDisableHover = 1 << 1, // By default, when dragging we clear data so that IsItemHovered() will return true, to avoid subsequent user code submitting tooltips. - // BeginDragDropTarget() flags - ImGuiDragDropFlags_AcceptBeforeDelivery = 1 << 10, // AcceptDragDropPayload() returns true even before the mouse button is released. You can then call IsDelivery() to test if the payload needs to be delivered. - ImGuiDragDropFlags_AcceptNoDrawDefaultRect = 1 << 11, // Do not draw the default highlight rectangle when hovering over target. - ImGuiDragDropFlags_AcceptPeekOnly = ImGuiDragDropFlags_AcceptBeforeDelivery | ImGuiDragDropFlags_AcceptNoDrawDefaultRect // For peeking ahead and inspecting the payload before delivery. -}; - // FIXME: this is in development, not exposed/functional as a generic feature yet. enum ImGuiLayoutType_ { @@ -418,28 +404,6 @@ struct ImGuiPopupRef ImGuiPopupRef(ImGuiID id, ImGuiWindow* parent_window, ImGuiID parent_menu_set, const ImVec2& mouse_pos) { PopupId = id; Window = NULL; ParentWindow = parent_window; ParentMenuSet = parent_menu_set; MousePosOnOpen = mouse_pos; } }; -// Data payload for Drag and Drop operations -struct ImGuiPayload -{ - // Members - const void* Data; // Data (copied and owned by dear imgui) - int DataSize; // Data size - - // [Internal] - ImGuiID SourceId; // Source item id - ImGuiID SourceParentId; // Source parent id (if available) - ImGuiID AcceptId; // Target item id (set at the time of accepting the payload) - int AcceptFrameCount; // Last time a target expressed a desire to accept the source - int DataFrameCount; // Data timestamp - char DataType[8 + 1]; // Data type tag (short user-supplied string) - bool Delivery; // Set when AcceptDragDropPayload() was called and the mouse button is released over the target item - - ImGuiPayload() { Clear(); } - void Clear() { SourceId = SourceParentId = AcceptId = 0; AcceptFrameCount = -1; Data = NULL; DataSize = 0; memset(DataType, 0, sizeof(DataType)); DataFrameCount = -1; Delivery = false; } - bool IsDataType(const char* type) const { return DataFrameCount != -1 && strcmp(type, DataType) == 0; } - bool IsDelivery() const { return Delivery; } -}; - // Main state for ImGui struct ImGuiContext { @@ -594,6 +558,7 @@ struct ImGuiContext DragDropActive = false; DragDropSourceFlags = 0; DragDropMouseButton = -1; + memset(DragDropPayloadBufLocal, 0, sizeof(DragDropPayloadBufLocal)); ScalarAsInputTextId = 0; ColorEditOptions = ImGuiColorEditFlags__OptionsDefault; @@ -858,14 +823,6 @@ namespace ImGui IMGUI_API void Scrollbar(ImGuiLayoutType direction); IMGUI_API void VerticalSeparator(); // Vertical separator, for menu bars (use current line height). not exposed because it is misleading what it doesn't have an effect on regular layout. - // FIXME-WIP: New Drag and Drop API - IMGUI_API bool BeginDragDropSource(ImGuiDragDropFlags flags = 0, int mouse_button = 0); // Call when the current item is active. If this return true, you can call SetDragDropPayload() + EndDragDropSource() - IMGUI_API bool SetDragDropPayload(const char* type, const void* data, size_t data_size, ImGuiCond cond = 0); // Type is a user defined string of maximum 8 characters. Strings starting with '_' are reserved for dear imgui internal types. Data is copied and held by imgui. - IMGUI_API void EndDragDropSource(); - IMGUI_API bool BeginDragDropTarget(); // Call after submitting an item that may receive an item. If this returns true, you can call AcceptDragDropPayload() + EndDragDropTarget() - IMGUI_API const ImGuiPayload* AcceptDragDropPayload(const char* type, ImGuiDragDropFlags flags = 0); // Accept contents of a given type. If ImGuiDragDropFlags_AcceptBeforeDelivery is set you can peek into the payload before the mouse button is released. - IMGUI_API void EndDragDropTarget(); - // FIXME-WIP: New Columns API IMGUI_API void BeginColumns(const char* id, int count, ImGuiColumnsFlags flags = 0); // setup number of columns. use an identifier to distinguish multiple column sets. close with EndColumns(). IMGUI_API void EndColumns(); // close columns From 0e775807b4be21405817df60c53889ab0a1ce230 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 29 Oct 2017 23:10:44 +0100 Subject: [PATCH 513/921] Drag and Drop: Added a mechanism to allow widgets with no identifiers (such as Text/Image) to be used with BeginDragDropSource() given the explicit ImGuiDragDropFlags_SourceAllowNullID flag. --- imgui.cpp | 46 ++++++++++++++++++++++++++++++++++++++++++++-- imgui.h | 1 + imgui_internal.h | 1 + 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index b11a28d73..de89f4f69 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1860,6 +1860,16 @@ ImGuiID ImGuiWindow::GetIDNoKeepAlive(const char* str, const char* str_end) return ImHash(str, str_end ? (int)(str_end - str) : 0, seed); } +// This is particularly dodgy and used in extremely rare situation. +ImGuiID ImGuiWindow::GetIDFromRectangle(const ImRect& r_abs) +{ + ImGuiID seed = IDStack.back(); + const int r_rel[4] = { (int)(r_abs.Min.x - Pos.x), (int)(r_abs.Min.y - Pos.y), (int)(r_abs.Max.x - Pos.x), (int)(r_abs.Max.y - Pos.y) }; + ImGuiID id = ImHash(&r_rel, sizeof(r_rel), seed); + ImGui::KeepAliveID(id); + return id; +} + //----------------------------------------------------------------------------- // Internal API exposed in imgui_internal.h //----------------------------------------------------------------------------- @@ -10606,16 +10616,48 @@ bool ImGui::BeginDragDropSource(ImGuiDragDropFlags flags, int mouse_button) ImGuiWindow* window = g.CurrentWindow; if (g.IO.MouseDown[mouse_button] == false) return false; - if (g.ActiveId != window->DC.LastItemId) + + ImGuiID id = window->DC.LastItemId; + if (id == 0) + { + // If you want to use BeginDragDropSource() on an item with no unique identifier for interaction, such as Text() or Image(), you need to: + // A) Read the explanation below, B) Use the ImGuiDragDropFlags_SourceAllowNullID flag, C) Swallow your programmer pride. + if (!(flags & ImGuiDragDropFlags_SourceAllowNullID)) + { + IM_ASSERT(0); + return false; + } + + // Magic fallback (=somehow reprehensible) to handle items with no assigned ID, e.g. Text(), Image(). + // We build a throwaway ID based on current ID stack + relative AABB of items in window. + // THE IDENTIFIER WON'T SURVIVE ANY REPOSITIONING OF THE WIDGET, so if your widget moves your dragging operation will be canceled. + // If you want fail-proof dragging, + // We don't need to maintain/call ClearActiveID() as releasing the button will early out this function and trigger !ActiveIdIsAlive. + bool is_hovered = window->DC.LastItemRectHoveredRect; + if (!is_hovered && (g.ActiveId == 0 || g.ActiveIdWindow != window)) + return false; + id = window->DC.LastItemId = window->GetIDFromRectangle(window->DC.LastItemRect); + if (is_hovered) + SetHoveredID(id); + if (is_hovered && g.IO.MouseClicked[mouse_button]) + { + SetActiveID(id, window); + FocusWindow(window); + } + if (g.ActiveId == id) // Allow the underlying widget to display/return hovered during the mouse release frame, else we would get a flicker. + g.ActiveIdAllowOverlap = is_hovered; + } + if (g.ActiveId != id) return false; if (IsMouseDragging(mouse_button)) { if (!g.DragDropActive) { + IM_ASSERT(id != 0); ImGuiPayload& payload = g.DragDropPayload; payload.Clear(); - payload.SourceId = g.ActiveId; + payload.SourceId = id; payload.SourceParentId = window->IDStack.back(); g.DragDropActive = true; g.DragDropSourceFlags = flags; diff --git a/imgui.h b/imgui.h index 7f1baa9c8..25a9c5a6c 100644 --- a/imgui.h +++ b/imgui.h @@ -599,6 +599,7 @@ enum ImGuiDragDropFlags_ // BeginDragDropSource() flags ImGuiDragDropFlags_SourceNoAutoTooltip = 1 << 0, ImGuiDragDropFlags_SourceNoDisableHover = 1 << 1, // By default, when dragging we clear data so that IsItemHovered() will return true, to avoid subsequent user code submitting tooltips. + ImGuiDragDropFlags_SourceAllowNullID = 1 << 2, // Allow items such as Text(), Image() that have no unique identifier to be used as drag source, by manufacturing a temporary identifier based on their window-relative position. This is extremely unusual within the dear imgui ecosystem and so we made it explicit. // BeginDragDropTarget() flags ImGuiDragDropFlags_AcceptBeforeDelivery = 1 << 10, // AcceptDragDropPayload() returns true even before the mouse button is released. You can then call IsDelivery() to test if the payload needs to be delivered. ImGuiDragDropFlags_AcceptNoDrawDefaultRect = 1 << 11, // Do not draw the default highlight rectangle when hovering over target. diff --git a/imgui_internal.h b/imgui_internal.h index 666b4491a..dafb3aef8 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -754,6 +754,7 @@ public: ImGuiID GetID(const char* str, const char* str_end = NULL); ImGuiID GetID(const void* ptr); ImGuiID GetIDNoKeepAlive(const char* str, const char* str_end = NULL); + ImGuiID GetIDFromRectangle(const ImRect& r_abs); ImRect Rect() const { return ImRect(Pos.x, Pos.y, Pos.x+Size.x, Pos.y+Size.y); } float CalcFontSize() const { return GImGui->FontBaseSize * FontWindowScale; } From d46772b429df1a157b4c2d4ebc11509d3d726cac Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 29 Oct 2017 23:14:17 +0100 Subject: [PATCH 514/921] Comments --- imgui.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index de89f4f69..709ebdff1 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1860,7 +1860,7 @@ ImGuiID ImGuiWindow::GetIDNoKeepAlive(const char* str, const char* str_end) return ImHash(str, str_end ? (int)(str_end - str) : 0, seed); } -// This is particularly dodgy and used in extremely rare situation. +// This is only used in rare/specific situations to manufacture an ID out of nowhere. ImGuiID ImGuiWindow::GetIDFromRectangle(const ImRect& r_abs) { ImGuiID seed = IDStack.back(); @@ -10628,10 +10628,9 @@ bool ImGui::BeginDragDropSource(ImGuiDragDropFlags flags, int mouse_button) return false; } - // Magic fallback (=somehow reprehensible) to handle items with no assigned ID, e.g. Text(), Image(). + // Magic fallback (=somehow reprehensible) to handle items with no assigned ID, e.g. Text(), Image() // We build a throwaway ID based on current ID stack + relative AABB of items in window. // THE IDENTIFIER WON'T SURVIVE ANY REPOSITIONING OF THE WIDGET, so if your widget moves your dragging operation will be canceled. - // If you want fail-proof dragging, // We don't need to maintain/call ClearActiveID() as releasing the button will early out this function and trigger !ActiveIdIsAlive. bool is_hovered = window->DC.LastItemRectHoveredRect; if (!is_hovered && (g.ActiveId == 0 || g.ActiveIdWindow != window)) From b13d281356e1f6006bd78537b0a14e36b8b9faa3 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 29 Oct 2017 23:46:32 +0100 Subject: [PATCH 515/921] Maintaining ActiveIdTimer and HoveredIdTimer (the later is useful for drag and drop, both will be of course for creators of custom widgets) --- imgui.cpp | 11 +++++++++-- imgui_internal.h | 4 ++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 0c2e72a59..1c101e0f4 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1883,6 +1883,8 @@ void ImGui::SetActiveID(ImGuiID id, ImGuiWindow* window) { ImGuiContext& g = *GImGui; g.ActiveIdIsJustActivated = (g.ActiveId != id); + if (g.ActiveIdIsJustActivated) + g.ActiveIdTimer = 0.0f; g.ActiveId = id; g.ActiveIdAllowOverlap = false; g.ActiveIdIsAlive |= (id != 0); @@ -1899,6 +1901,7 @@ void ImGui::SetHoveredID(ImGuiID id) ImGuiContext& g = *GImGui; g.HoveredId = id; g.HoveredIdAllowOverlap = false; + g.HoveredIdTimer = (id != 0 && g.HoveredIdPreviousFrame == id) ? (g.HoveredIdTimer + g.IO.DeltaTime) : 0.0f; } void ImGui::KeepAliveID(ImGuiID id) @@ -2220,11 +2223,15 @@ void ImGui::NewFrame() g.RenderDrawData.CmdListsCount = g.RenderDrawData.TotalVtxCount = g.RenderDrawData.TotalIdxCount = 0; // Clear reference to active widget if the widget isn't alive anymore + if (!g.HoveredIdPreviousFrame) + g.HoveredIdTimer = 0.0f; g.HoveredIdPreviousFrame = g.HoveredId; g.HoveredId = 0; g.HoveredIdAllowOverlap = false; if (!g.ActiveIdIsAlive && g.ActiveIdPreviousFrame == g.ActiveId && g.ActiveId != 0) ClearActiveID(); + if (g.ActiveId) + g.ActiveIdTimer += g.IO.DeltaTime; g.ActiveIdPreviousFrame = g.ActiveId; g.ActiveIdIsAlive = false; g.ActiveIdIsJustActivated = false; @@ -10820,8 +10827,8 @@ void ImGui::ShowMetricsWindow(bool* p_open) { ImGui::Text("HoveredWindow: '%s'", g.HoveredWindow ? g.HoveredWindow->Name : "NULL"); ImGui::Text("HoveredRootWindow: '%s'", g.HoveredRootWindow ? g.HoveredRootWindow->Name : "NULL"); - ImGui::Text("HoveredId: 0x%08X/0x%08X", g.HoveredId, g.HoveredIdPreviousFrame); // Data is "in-flight" so depending on when the Metrics window is called we may see current frame information or not - ImGui::Text("ActiveId: 0x%08X/0x%08X", g.ActiveId, g.ActiveIdPreviousFrame); + ImGui::Text("HoveredId: 0x%08X/0x%08X (%.2f sec)", g.HoveredId, g.HoveredIdPreviousFrame, g.HoveredIdTimer); // Data is "in-flight" so depending on when the Metrics window is called we may see current frame information or not + ImGui::Text("ActiveId: 0x%08X/0x%08X (%.2f sec)", g.ActiveId, g.ActiveIdPreviousFrame, g.ActiveIdTimer); ImGui::Text("ActiveIdWindow: '%s'", g.ActiveIdWindow ? g.ActiveIdWindow->Name : "NULL"); ImGui::Text("NavWindow: '%s'", g.NavWindow ? g.NavWindow->Name : "NULL"); ImGui::TreePop(); diff --git a/imgui_internal.h b/imgui_internal.h index 1cb723ca7..ccfc3bf47 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -429,8 +429,10 @@ struct ImGuiContext ImGuiID HoveredId; // Hovered widget bool HoveredIdAllowOverlap; ImGuiID HoveredIdPreviousFrame; + float HoveredIdTimer; ImGuiID ActiveId; // Active widget ImGuiID ActiveIdPreviousFrame; + float ActiveIdTimer; bool ActiveIdIsAlive; // Active widget has been seen this frame bool ActiveIdIsJustActivated; // Set at the time of activation for one frame bool ActiveIdAllowOverlap; // Active widget allows another widget to steal active id (generally for overlapping widgets, but not always) @@ -521,8 +523,10 @@ struct ImGuiContext HoveredId = 0; HoveredIdAllowOverlap = false; HoveredIdPreviousFrame = 0; + HoveredIdTimer = 0.0f; ActiveId = 0; ActiveIdPreviousFrame = 0; + ActiveIdTimer = 0.0f; ActiveIdIsAlive = false; ActiveIdIsJustActivated = false; ActiveIdAllowOverlap = false; From a81061955568973e72ebea5d7a3f7035368bd50c Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 30 Oct 2017 00:03:04 +0100 Subject: [PATCH 516/921] Drag and Drop: Added support for drag and drop hold-long-to-open for CollapsingHeader() and TreeNode(). Open only! --- imgui.cpp | 13 +++++++++++++ imgui_internal.h | 3 ++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 8e7225fc8..383b012eb 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -5841,6 +5841,16 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool bool pressed = false; bool hovered = ItemHoverable(bb, id); + // Special mode for Drag and Drop where holding button pressed for a long time while dragging another item triggers the button + if ((flags & ImGuiButtonFlags_PressedOnDragDropHold) && g.DragDropActive && !hovered) + if (IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem)) + { + hovered = true; + SetHoveredID(id); + if (CalcTypematicPressedRepeatAmount(g.HoveredIdTimer + 0.0001f, g.HoveredIdTimer + 0.0001f - g.IO.DeltaTime, 0.01f, 0.70f)) // FIXME: Our formula for CalcTypematicPressedRepeatAmount() is fishy + pressed = true; + } + if ((flags & ImGuiButtonFlags_FlattenChilds) && g.HoveredRootWindow == window) g.HoveredWindow = backup_hovered_window; @@ -6271,6 +6281,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l // - OpenOnArrow .................... single-click on arrow to open // - OpenOnDoubleClick|OpenOnArrow .. single-click on arrow or double-click anywhere to open ImGuiButtonFlags button_flags = ImGuiButtonFlags_NoKeyModifiers | ((flags & ImGuiTreeNodeFlags_AllowOverlapMode) ? ImGuiButtonFlags_AllowOverlapMode : 0); + button_flags |= ImGuiButtonFlags_PressedOnDragDropHold; if (flags & ImGuiTreeNodeFlags_OpenOnDoubleClick) button_flags |= ImGuiButtonFlags_PressedOnDoubleClick | ((flags & ImGuiTreeNodeFlags_OpenOnArrow) ? ImGuiButtonFlags_PressedOnClickRelease : 0); bool hovered, held, pressed = ButtonBehavior(interact_bb, id, &hovered, &held, button_flags); @@ -6281,6 +6292,8 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l toggled |= IsMouseHoveringRect(interact_bb.Min, ImVec2(interact_bb.Min.x + text_offset_x, interact_bb.Max.y)); if (flags & ImGuiTreeNodeFlags_OpenOnDoubleClick) toggled |= g.IO.MouseDoubleClicked[0]; + if (g.DragDropActive && is_open) // We don't nodes to be highlighted when holding ever after the node has been opened, but don't close them! + toggled = false; if (toggled) { is_open = !is_open; diff --git a/imgui_internal.h b/imgui_internal.h index 6e69c6768..53af4b377 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -183,7 +183,8 @@ enum ImGuiButtonFlags_ ImGuiButtonFlags_AlignTextBaseLine = 1 << 8, // vertically align button to match text baseline (ButtonEx() only) ImGuiButtonFlags_NoKeyModifiers = 1 << 9, // disable interaction if a key modifier is held ImGuiButtonFlags_AllowOverlapMode = 1 << 10, // require previous frame HoveredId to either match id or be null before being usable - ImGuiButtonFlags_NoHoldingActiveID = 1 << 11 // don't set ActiveId while holding the mouse (ImGuiButtonFlags_PressedOnClick only) + ImGuiButtonFlags_NoHoldingActiveID = 1 << 11, // don't set ActiveId while holding the mouse (ImGuiButtonFlags_PressedOnClick only) + ImGuiButtonFlags_PressedOnDragDropHold = 1 << 12 // press when held into while we are drag and dropping another item }; enum ImGuiSliderFlags_ From 5956fff7e2959574e4273ca1b5cc540fd0dff0d5 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 30 Oct 2017 00:10:05 +0100 Subject: [PATCH 517/921] Drag and Drop: ImGuiButtonFlags_PressedOnDragDropHold focuses the target window. --- imgui.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/imgui.cpp b/imgui.cpp index 383b012eb..6603d3f97 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -5848,7 +5848,10 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool hovered = true; SetHoveredID(id); if (CalcTypematicPressedRepeatAmount(g.HoveredIdTimer + 0.0001f, g.HoveredIdTimer + 0.0001f - g.IO.DeltaTime, 0.01f, 0.70f)) // FIXME: Our formula for CalcTypematicPressedRepeatAmount() is fishy + { pressed = true; + FocusWindow(window); + } } if ((flags & ImGuiButtonFlags_FlattenChilds) && g.HoveredRootWindow == window) From 9e3f9fc2ddf0a170788f6b101c5027f82dd35cde Mon Sep 17 00:00:00 2001 From: Giuseppe Barbieri Date: Mon, 30 Oct 2017 09:35:42 +0100 Subject: [PATCH 518/921] Update imgui.cpp --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 1c101e0f4..40b5ea6c8 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1984,7 +1984,7 @@ bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id) } // This is roughly matching the behavior of internal-facing ItemHoverable() -// - we allow hovering to be true when ActiveId==window->MoveID, so that clicking on non-interactive items such as a Text() item still returns true with IsItemHovered()) +// - we allow hovering to be true when ActiveId==window->MoveID, so that clicking on non-interactive items such as a Text() item still returns true with IsItemHovered() // - this should work even for non-interactive items that have no ID, so we cannot use LastItemId bool ImGui::IsItemHovered(ImGuiHoveredFlags flags) { From 7f06d385a1c7305773a32a755982847c33f9ef8d Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 30 Oct 2017 09:50:54 +0100 Subject: [PATCH 519/921] Added assertions and comments for incorrect use/understanding of IsWindowFocused() etc. functions --- imgui.cpp | 6 +++++- imgui.h | 10 +++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 1c101e0f4..a5074aa3a 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -5125,25 +5125,29 @@ bool ImGui::IsWindowHovered(ImGuiHoveredFlags flags) bool ImGui::IsWindowFocused() { ImGuiContext& g = *GImGui; + IM_ASSERT(g.CurrentWindow); // Not inside a Begin()/End() return g.NavWindow == g.CurrentWindow; } bool ImGui::IsRootWindowFocused() { ImGuiContext& g = *GImGui; + IM_ASSERT(g.CurrentWindow); // Not inside a Begin()/End() return g.NavWindow == g.CurrentWindow->RootWindow; } bool ImGui::IsRootWindowOrAnyChildFocused() { ImGuiContext& g = *GImGui; + IM_ASSERT(g.CurrentWindow); // Not inside a Begin()/End() return g.NavWindow && g.NavWindow->RootWindow == g.CurrentWindow->RootWindow; } bool ImGui::IsRootWindowOrAnyChildHovered(ImGuiHoveredFlags flags) { - IM_ASSERT((flags & ImGuiHoveredFlags_AllowWhenOverlapped) == 0); // Flags not supported by this function ImGuiContext& g = *GImGui; + IM_ASSERT((flags & ImGuiHoveredFlags_AllowWhenOverlapped) == 0); // Flags not supported by this function + IM_ASSERT(g.CurrentWindow); // Not inside a Begin()/End() if (!g.HoveredRootWindow || (g.HoveredRootWindow != g.CurrentWindow->RootWindow)) return false; if (!IsWindowContentHoverable(g.HoveredRootWindow, flags)) diff --git a/imgui.h b/imgui.h index 995b39801..958ea9ab7 100644 --- a/imgui.h +++ b/imgui.h @@ -429,11 +429,11 @@ namespace ImGui IMGUI_API ImVec2 GetItemRectMax(); // " IMGUI_API ImVec2 GetItemRectSize(); // " IMGUI_API void SetItemAllowOverlap(); // allow last item to be overlapped by a subsequent item. sometimes useful with invisible buttons, selectables, etc. to catch unused area. - IMGUI_API bool IsWindowFocused(); // is current window focused - IMGUI_API bool IsWindowHovered(ImGuiHoveredFlags flags = 0); // is current window hovered (and typically: not blocked by a popup/modal) - IMGUI_API bool IsRootWindowFocused(); // is current root window focused (root = top-most parent of a child, otherwise self) - IMGUI_API bool IsRootWindowOrAnyChildFocused(); // is current root window or any of its child (including current window) focused - IMGUI_API bool IsRootWindowOrAnyChildHovered(ImGuiHoveredFlags flags = 0); // is current root window or any of its child (including current window) hovered and hoverable (not blocked by a popup) + IMGUI_API bool IsWindowFocused(); // is current Begin()-ed window focused? + IMGUI_API bool IsWindowHovered(ImGuiHoveredFlags flags = 0); // is current Begin()-ed window hovered (and typically: not blocked by a popup/modal)? + IMGUI_API bool IsRootWindowFocused(); // is current Begin()-ed root window focused (root = top-most parent of a child, otherwise self)? + IMGUI_API bool IsRootWindowOrAnyChildFocused(); // is current Begin()-ed root window or any of its child (including current window) focused? + IMGUI_API bool IsRootWindowOrAnyChildHovered(ImGuiHoveredFlags flags = 0); // is current Begin()-ed root window or any of its child (including current window) hovered and hoverable (not blocked by a popup)? IMGUI_API bool IsAnyWindowHovered(); // is mouse hovering any visible window IMGUI_API bool IsRectVisible(const ImVec2& size); // test if rectangle (of given size, starting from cursor position) is visible / not clipped. IMGUI_API bool IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max); // test if rectangle (in screen space) is visible / not clipped. to perform coarse clipping on user's side. From 6ab20ff9bf69684a2a8a7313e4f47caa3a33dc62 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 1 Nov 2017 12:33:38 +0100 Subject: [PATCH 520/921] Minor tweaks to the user guide. --- imgui.cpp | 28 +++++++++++++--------------- imgui_demo.cpp | 31 ++++++++++++++++--------------- 2 files changed, 29 insertions(+), 30 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 07ee5e8b6..9f5f781c3 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -59,23 +59,21 @@ END-USER GUIDE ============== - - Double-click title bar to collapse window - - Click upper right corner to close a window, available when 'bool* p_open' is passed to ImGui::Begin() - - Click and drag on lower right corner to resize window - - Click and drag on any empty space to move window - - Double-click/double-tap on lower right corner grip to auto-fit to content - - TAB/SHIFT+TAB to cycle through keyboard editable fields - - Use mouse wheel to scroll - - Use CTRL+mouse wheel to zoom window contents (if io.FontAllowScaling is true) - - CTRL+Click on a slider or drag box to input value as text + - Double-click on title bar to collapse window. + - Click upper right corner to close a window, available when 'bool* p_open' is passed to ImGui::Begin(). + - Click and drag on lower right corner to resize window (double-click to auto fit window to its contents). + - Click and drag on any empty space to move window. + - TAB/SHIFT+TAB to cycle through keyboard editable fields. + - CTRL+Click on a slider or drag box to input value as text. + - Use mouse wheel to scroll. - Text editor: - Hold SHIFT or use mouse to select text. - - CTRL+Left/Right to word jump - - CTRL+Shift+Left/Right to select words - - CTRL+A our Double-Click to select all - - CTRL+X,CTRL+C,CTRL+V to use OS clipboard - - CTRL+Z,CTRL+Y to undo/redo - - ESCAPE to revert text to its original value + - CTRL+Left/Right to word jump. + - CTRL+Shift+Left/Right to select words. + - CTRL+A our Double-Click to select all. + - CTRL+X,CTRL+C,CTRL+V to use OS clipboard/ + - CTRL+Z,CTRL+Y to undo/redo. + - ESCAPE to revert text to its original value. - You can apply arithmetic operators +,*,/ on numerical values. Use +- to subtract (because - would set a negative value!) - Controls are automatically adjusted for OSX to match standard OSX text editing operations. diff --git a/imgui_demo.cpp b/imgui_demo.cpp index d2f4d9500..508679185 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -101,23 +101,23 @@ static void ShowHelpMarker(const char* desc) void ImGui::ShowUserGuide() { ImGui::BulletText("Double-click on title bar to collapse window."); - ImGui::BulletText("Click and drag on lower right corner to resize window."); + ImGui::BulletText("Click and drag on lower right corner to resize window\n(double-click to auto fit window to its contents)."); ImGui::BulletText("Click and drag on any empty space to move window."); - ImGui::BulletText("Mouse Wheel to scroll."); + ImGui::BulletText("TAB/SHIFT+TAB to cycle through keyboard editable fields."); + ImGui::BulletText("CTRL+Click on a slider or drag box to input value as text."); if (ImGui::GetIO().FontAllowUserScaling) ImGui::BulletText("CTRL+Mouse Wheel to zoom window contents."); - ImGui::BulletText("TAB/SHIFT+TAB to cycle through keyboard editable fields."); - ImGui::BulletText("CTRL+Click on a slider or drag box to input text."); - ImGui::BulletText( - "While editing text:\n" - "- Hold SHIFT or use mouse to select text\n" - "- CTRL+Left/Right to word jump\n" - "- CTRL+A or double-click to select all\n" - "- CTRL+X,CTRL+C,CTRL+V clipboard\n" - "- CTRL+Z,CTRL+Y undo/redo\n" - "- ESCAPE to revert\n" - "- You can apply arithmetic operators +,*,/ on numerical values.\n" - " Use +- to subtract.\n"); + ImGui::BulletText("Mouse Wheel to scroll."); + ImGui::BulletText("While editing text:\n"); + ImGui::Indent(); + ImGui::BulletText("Hold SHIFT or use mouse to select text."); + ImGui::BulletText("CTRL+Left/Right to word jump."); + ImGui::BulletText("CTRL+A or double-click to select all."); + ImGui::BulletText("CTRL+X,CTRL+C,CTRL+V to use clipboard."); + ImGui::BulletText("CTRL+Z,CTRL+Y to undo/redo."); + ImGui::BulletText("ESCAPE to revert."); + ImGui::BulletText("You can apply arithmetic operators +,*,/ on numerical values.\nUse +- to subtract."); + ImGui::Unindent(); } // Demonstrate most ImGui features (big function!) @@ -230,7 +230,8 @@ void ImGui::ShowTestWindow(bool* p_open) ImGui::Spacing(); if (ImGui::CollapsingHeader("Help")) { - ImGui::TextWrapped("This window is being created by the ShowTestWindow() function. Please refer to the code for programming reference.\n\nUser Guide:"); + ImGui::TextWrapped("This window is being created by the ShowTestWindow() function. Please refer to the code in imgui_demo.cpp for reference.\n\n"); + ImGui::Text("USER GUIDE:"); ImGui::ShowUserGuide(); } From 59323b54da8071c058a219e57efd5143a891fd2e Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 1 Nov 2017 12:55:15 +0100 Subject: [PATCH 521/921] Demo: Comments (#1408) --- imgui.h | 2 +- imgui_demo.cpp | 20 +++++++++++++++----- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/imgui.h b/imgui.h index 958ea9ab7..5f568625b 100644 --- a/imgui.h +++ b/imgui.h @@ -129,7 +129,7 @@ namespace ImGui // Demo/Debug/Info IMGUI_API void ShowTestWindow(bool* p_open = NULL); // create demo/test window. demonstrate most ImGui features. call this to learn about the library! try to make it always available in your application! - IMGUI_API void ShowMetricsWindow(bool* p_open = NULL); // create metrics window. display ImGui internals: browse window list, draw commands, individual vertices, basic internal state, etc. + IMGUI_API void ShowMetricsWindow(bool* p_open = NULL); // create metrics window. display ImGui internals: draw commands (with individual draw calls and vertices), window list, basic internal state, etc. IMGUI_API void ShowStyleEditor(ImGuiStyle* ref = NULL); // add style editor block (not a window). you can pass in a reference ImGuiStyle structure to compare to, revert to and save to (else it uses the default style) IMGUI_API void ShowUserGuide(); // add basic help/info block (not a window): how to manipulate ImGui as a end-user (mouse/keyboard controls). diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 508679185..c27b886ca 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -543,17 +543,27 @@ void ImGui::ShowTestWindow(bool* p_open) { ImGui::TextWrapped("Below we are displaying the font texture (which is the only texture we have access to in this demo). Use the 'ImTextureID' type as storage to pass pointers or identifier to your own texture data. Hover the texture for a zoomed view!"); ImVec2 tex_screen_pos = ImGui::GetCursorScreenPos(); - float tex_w = (float)ImGui::GetIO().Fonts->TexWidth; - float tex_h = (float)ImGui::GetIO().Fonts->TexHeight; - ImTextureID tex_id = ImGui::GetIO().Fonts->TexID; + ImGuiIO& io = ImGui::GetIO(); + + // Here we are grabbing the font texture because that's the only one we have access to inside the demo code. + // Remember that ImTextureID is just storage for whatever you want it to be, it is essentially a value that will be passed to the render function inside the ImDrawCmd structure. + // If you use one of the default imgui_impl_XXXX.cpp renderer, they all have comments at the top of their file to specify what they expect to be stored in ImTextureID. + // (for example, the imgui_impl_dx11.cpp renderer expect a 'ID3D11ShaderResourceView*' pointer. The imgui_impl_glfw_gl3.cpp renderer expect a GLuint OpenGL texture identifier etc.) + // If you decided that ImTextureID = MyEngineTexture*, then you can pass your MyEngineTexture* pointers to ImGui::Image(), and gather width/height through your own functions, etc. + // Using ShowMetricsWindow() as a "debugger" to inspect the draw data that are being passed to your render will help you debug issues if you are confused about this. + // Consider using the lower-level ImDrawList::AddImage() API, via ImGui::GetWindowDrawList()->AddImage(). + ImTextureID tex_id = io.Fonts->TexID; + float tex_w = (float)io.Fonts->TexWidth; + float tex_h = (float)io.Fonts->TexHeight; + ImGui::Text("%.0fx%.0f", tex_w, tex_h); ImGui::Image(tex_id, ImVec2(tex_w, tex_h), ImVec2(0,0), ImVec2(1,1), ImColor(255,255,255,255), ImColor(255,255,255,128)); if (ImGui::IsItemHovered()) { ImGui::BeginTooltip(); float focus_sz = 32.0f; - float focus_x = ImGui::GetMousePos().x - tex_screen_pos.x - focus_sz * 0.5f; if (focus_x < 0.0f) focus_x = 0.0f; else if (focus_x > tex_w - focus_sz) focus_x = tex_w - focus_sz; - float focus_y = ImGui::GetMousePos().y - tex_screen_pos.y - focus_sz * 0.5f; if (focus_y < 0.0f) focus_y = 0.0f; else if (focus_y > tex_h - focus_sz) focus_y = tex_h - focus_sz; + float focus_x = io.MousePos.x - tex_screen_pos.x - focus_sz * 0.5f; if (focus_x < 0.0f) focus_x = 0.0f; else if (focus_x > tex_w - focus_sz) focus_x = tex_w - focus_sz; + float focus_y = io.MousePos.y - tex_screen_pos.y - focus_sz * 0.5f; if (focus_y < 0.0f) focus_y = 0.0f; else if (focus_y > tex_h - focus_sz) focus_y = tex_h - focus_sz; ImGui::Text("Min: (%.2f, %.2f)", focus_x, focus_y); ImGui::Text("Max: (%.2f, %.2f)", focus_x + focus_sz, focus_y + focus_sz); ImVec2 uv0 = ImVec2((focus_x) / tex_w, (focus_y) / tex_h); From fba704bf5d4a5eab392931ac3d46a45cff7a5eb3 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 1 Nov 2017 14:24:09 +0100 Subject: [PATCH 522/921] Examples: Added a bunch of comments/referencs related to io.WantCaptureMouse, io.WantCaptureKeyboard (#1262, #1237, #1219, #635, #1058, #1051, #912, #533, #703, #446, #459, #364, #213, #52, and more) --- examples/allegro5_example/imgui_impl_a5.cpp | 7 +++++-- examples/allegro5_example/main.cpp | 15 ++++++++++----- examples/directx10_example/imgui_impl_dx10.cpp | 9 +++++++-- examples/directx10_example/main.cpp | 12 ++++++++---- examples/directx11_example/imgui_impl_dx11.cpp | 9 +++++++-- examples/directx11_example/main.cpp | 12 ++++++++---- examples/directx9_example/imgui_impl_dx9.cpp | 9 +++++++-- examples/directx9_example/main.cpp | 12 ++++++++---- .../marmalade_example/imgui_impl_marmalade.cpp | 10 +++++----- examples/marmalade_example/main.cpp | 12 ++++++++---- examples/opengl2_example/imgui_impl_glfw.cpp | 4 ++-- examples/opengl2_example/main.cpp | 14 +++++++++----- examples/opengl3_example/imgui_impl_glfw_gl3.cpp | 4 ++-- examples/opengl3_example/main.cpp | 12 ++++++++---- examples/sdl_opengl2_example/imgui_impl_sdl.cpp | 6 +++++- examples/sdl_opengl2_example/main.cpp | 13 ++++++++++--- .../sdl_opengl3_example/imgui_impl_sdl_gl3.cpp | 6 +++++- examples/sdl_opengl3_example/main.cpp | 12 ++++++++---- .../vulkan_example/imgui_impl_glfw_vulkan.cpp | 4 ++-- examples/vulkan_example/main.cpp | 12 ++++++++---- imgui.h | 10 +++++----- 21 files changed, 137 insertions(+), 67 deletions(-) diff --git a/examples/allegro5_example/imgui_impl_a5.cpp b/examples/allegro5_example/imgui_impl_a5.cpp index 6f5b7b061..0d3859239 100644 --- a/examples/allegro5_example/imgui_impl_a5.cpp +++ b/examples/allegro5_example/imgui_impl_a5.cpp @@ -204,6 +204,10 @@ void ImGui_ImplA5_Shutdown() ImGui::Shutdown(); } +// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. +// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. +// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. +// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. bool ImGui_ImplA5_ProcessEvent(ALLEGRO_EVENT *ev) { ImGuiIO &io = ImGui::GetIO(); @@ -227,7 +231,6 @@ bool ImGui_ImplA5_ProcessEvent(ALLEGRO_EVENT *ev) return false; } - void ImGui_ImplA5_NewFrame() { if (!g_Texture) @@ -290,6 +293,6 @@ void ImGui_ImplA5_NewFrame() al_set_system_mouse_cursor(g_Display, cursor_id); } - // Start the frame + // Start the frame. This call will update the io.WantCaptureMouse, io.WantCaptureKeyboard flag that you can use to dispatch inputs (or not) to your application. ImGui::NewFrame(); } diff --git a/examples/allegro5_example/main.cpp b/examples/allegro5_example/main.cpp index 1e274ff36..4eb9a4aa9 100644 --- a/examples/allegro5_example/main.cpp +++ b/examples/allegro5_example/main.cpp @@ -49,11 +49,16 @@ int main(int, char**) bool running = true; while (running) { + // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. + // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. + // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. + // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. ALLEGRO_EVENT ev; while (al_get_next_event(queue, &ev)) { ImGui_ImplA5_ProcessEvent(&ev); - if (ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) running = false; + if (ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) + running = false; if (ev.type == ALLEGRO_EVENT_DISPLAY_RESIZE) { ImGui_ImplA5_InvalidateDeviceObjects(); @@ -63,8 +68,8 @@ int main(int, char**) } ImGui_ImplA5_NewFrame(); - // 1. Show a simple window - // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug" + // 1. Show a simple window. + // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug". { static float f; ImGui::Text("Hello, world!"); @@ -75,7 +80,7 @@ int main(int, char**) ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f/ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); } - // 2. Show another simple window, this time using an explicit Begin/End pair + // 2. Show another simple window. In most cases you will use an explicit Begin/End pair to name the window. if (show_another_window) { ImGui::Begin("Another Window", &show_another_window); @@ -83,7 +88,7 @@ int main(int, char**) ImGui::End(); } - // 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow() + // 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow(). if (show_test_window) { ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); diff --git a/examples/directx10_example/imgui_impl_dx10.cpp b/examples/directx10_example/imgui_impl_dx10.cpp index 06171250b..4670f0537 100644 --- a/examples/directx10_example/imgui_impl_dx10.cpp +++ b/examples/directx10_example/imgui_impl_dx10.cpp @@ -234,7 +234,12 @@ static bool IsAnyMouseButtonDown() return false; } -// We use the Win32 capture API (GetCapture/SetCapture/ReleaseCapture) to be able to read mouse coordinations when dragging mouse outside of our window bounds. +// Process Win32 mouse/keyboard inputs. +// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. +// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. +// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. +// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. +// PS: In this Win32 handler, we use the capture API (GetCapture/SetCapture/ReleaseCapture) to be able to read mouse coordinations when dragging mouse outside of our window bounds. IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { ImGuiIO& io = ImGui::GetIO(); @@ -604,6 +609,6 @@ void ImGui_ImplDX10_NewFrame() if (io.MouseDrawCursor) SetCursor(NULL); - // Start the frame + // Start the frame. This call will update the io.WantCaptureMouse, io.WantCaptureKeyboard flag that you can use to dispatch inputs (or not) to your application. ImGui::NewFrame(); } diff --git a/examples/directx10_example/main.cpp b/examples/directx10_example/main.cpp index 0ed70bc38..3ece69f90 100644 --- a/examples/directx10_example/main.cpp +++ b/examples/directx10_example/main.cpp @@ -150,6 +150,10 @@ int main(int, char**) ZeroMemory(&msg, sizeof(msg)); while (msg.message != WM_QUIT) { + // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. + // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. + // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. + // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. if (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE)) { TranslateMessage(&msg); @@ -158,8 +162,8 @@ int main(int, char**) } ImGui_ImplDX10_NewFrame(); - // 1. Show a simple window - // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug" + // 1. Show a simple window. + // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug". { static float f = 0.0f; ImGui::Text("Hello, world!"); @@ -170,7 +174,7 @@ int main(int, char**) ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); } - // 2. Show another simple window, this time using an explicit Begin/End pair + // 2. Show another simple window. In most cases you will use an explicit Begin/End pair to name the window. if (show_another_window) { ImGui::Begin("Another Window", &show_another_window); @@ -178,7 +182,7 @@ int main(int, char**) ImGui::End(); } - // 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow() + // 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow(). if (show_test_window) { ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); // Normally user code doesn't need/want to call it because positions are saved in .ini file anyway. Here we just want to make the demo initial state a bit more friendly! diff --git a/examples/directx11_example/imgui_impl_dx11.cpp b/examples/directx11_example/imgui_impl_dx11.cpp index 1f69bd727..df02577bb 100644 --- a/examples/directx11_example/imgui_impl_dx11.cpp +++ b/examples/directx11_example/imgui_impl_dx11.cpp @@ -241,7 +241,12 @@ static bool IsAnyMouseButtonDown() return false; } -// We use the Win32 capture API (GetCapture/SetCapture/ReleaseCapture) to be able to read mouse coordinations when dragging mouse outside of our window bounds. +// Process Win32 mouse/keyboard inputs. +// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. +// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. +// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. +// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. +// PS: In this Win32 handler, we use the capture API (GetCapture/SetCapture/ReleaseCapture) to be able to read mouse coordinations when dragging mouse outside of our window bounds. IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { ImGuiIO& io = ImGui::GetIO(); @@ -607,6 +612,6 @@ void ImGui_ImplDX11_NewFrame() if (io.MouseDrawCursor) SetCursor(NULL); - // Start the frame + // Start the frame. This call will update the io.WantCaptureMouse, io.WantCaptureKeyboard flag that you can use to dispatch inputs (or not) to your application. ImGui::NewFrame(); } diff --git a/examples/directx11_example/main.cpp b/examples/directx11_example/main.cpp index cd1b78828..9bd8637cf 100644 --- a/examples/directx11_example/main.cpp +++ b/examples/directx11_example/main.cpp @@ -153,6 +153,10 @@ int main(int, char**) ZeroMemory(&msg, sizeof(msg)); while (msg.message != WM_QUIT) { + // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. + // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. + // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. + // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. if (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE)) { TranslateMessage(&msg); @@ -161,8 +165,8 @@ int main(int, char**) } ImGui_ImplDX11_NewFrame(); - // 1. Show a simple window - // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug" + // 1. Show a simple window. + // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug". { static float f = 0.0f; ImGui::Text("Hello, world!"); @@ -173,7 +177,7 @@ int main(int, char**) ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); } - // 2. Show another simple window, this time using an explicit Begin/End pair + // 2. Show another simple window. In most cases you will use an explicit Begin/End pair to name the window. if (show_another_window) { ImGui::Begin("Another Window", &show_another_window); @@ -181,7 +185,7 @@ int main(int, char**) ImGui::End(); } - // 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow() + // 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow(). if (show_test_window) { ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); // Normally user code doesn't need/want to call it because positions are saved in .ini file anyway. Here we just want to make the demo initial state a bit more friendly! diff --git a/examples/directx9_example/imgui_impl_dx9.cpp b/examples/directx9_example/imgui_impl_dx9.cpp index 02d2fd593..24f53ba3a 100644 --- a/examples/directx9_example/imgui_impl_dx9.cpp +++ b/examples/directx9_example/imgui_impl_dx9.cpp @@ -180,7 +180,12 @@ static bool IsAnyMouseButtonDown() return false; } -// We use the Win32 capture API (GetCapture/SetCapture/ReleaseCapture) to be able to read mouse coordinations when dragging mouse outside of our window bounds. +// Process Win32 mouse/keyboard inputs. +// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. +// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. +// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. +// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. +// PS: In this Win32 handler, we use the capture API (GetCapture/SetCapture/ReleaseCapture) to be able to read mouse coordinations when dragging mouse outside of our window bounds. IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { ImGuiIO& io = ImGui::GetIO(); @@ -381,6 +386,6 @@ void ImGui_ImplDX9_NewFrame() if (io.MouseDrawCursor) SetCursor(NULL); - // Start the frame + // Start the frame. This call will update the io.WantCaptureMouse, io.WantCaptureKeyboard flag that you can use to dispatch inputs (or not) to your application. ImGui::NewFrame(); } diff --git a/examples/directx9_example/main.cpp b/examples/directx9_example/main.cpp index bae6daeef..5a5c0d192 100644 --- a/examples/directx9_example/main.cpp +++ b/examples/directx9_example/main.cpp @@ -104,6 +104,10 @@ int main(int, char**) UpdateWindow(hwnd); while (msg.message != WM_QUIT) { + // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. + // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. + // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. + // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. if (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE)) { TranslateMessage(&msg); @@ -112,8 +116,8 @@ int main(int, char**) } ImGui_ImplDX9_NewFrame(); - // 1. Show a simple window - // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug" + // 1. Show a simple window. + // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug". { static float f = 0.0f; ImGui::Text("Hello, world!"); @@ -124,7 +128,7 @@ int main(int, char**) ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); } - // 2. Show another simple window, this time using an explicit Begin/End pair + // 2. Show another simple window. In most cases you will use an explicit Begin/End pair to name the window. if (show_another_window) { ImGui::Begin("Another Window", &show_another_window); @@ -132,7 +136,7 @@ int main(int, char**) ImGui::End(); } - // 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow() + // 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow(). if (show_test_window) { ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); diff --git a/examples/marmalade_example/imgui_impl_marmalade.cpp b/examples/marmalade_example/imgui_impl_marmalade.cpp index ae7f10c0d..6ecffa736 100644 --- a/examples/marmalade_example/imgui_impl_marmalade.cpp +++ b/examples/marmalade_example/imgui_impl_marmalade.cpp @@ -27,7 +27,7 @@ static char* g_ClipboardText = NULL; static bool g_osdKeyboardEnabled = false; // use this setting to scale the interface - e.g. on device you could use 2 or 3 scale factor -static ImVec2 g_scale = ImVec2(1.0f,1.0f); +static ImVec2 g_RenderScale = ImVec2(1.0f,1.0f); // This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) void ImGui_Marmalade_RenderDrawLists(ImDrawData* draw_data) @@ -48,9 +48,9 @@ void ImGui_Marmalade_RenderDrawLists(ImDrawData* draw_data) for( int i=0; i < nVert; i++ ) { - // TODO: optimize multiplication on gpu using vertex shader - pVertStream[i].x = cmd_list->VtxBuffer[i].pos.x * g_scale.x; - pVertStream[i].y = cmd_list->VtxBuffer[i].pos.y * g_scale.y; + // TODO: optimize multiplication on gpu using vertex shader/projection matrix. + pVertStream[i].x = cmd_list->VtxBuffer[i].pos.x * g_RenderScale.x; + pVertStream[i].y = cmd_list->VtxBuffer[i].pos.y * g_RenderScale.y; pUVStream[i].x = cmd_list->VtxBuffer[i].uv.x; pUVStream[i].y = cmd_list->VtxBuffer[i].uv.y; pColStream[i] = cmd_list->VtxBuffer[i].col; @@ -287,7 +287,7 @@ void ImGui_Marmalade_NewFrame() // TODO: Hide OS mouse cursor if ImGui is drawing it // s3ePointerSetInt(S3E_POINTER_HIDE_CURSOR,(io.MouseDrawCursor ? 0 : 1)); - // Start the frame + // Start the frame. This call will update the io.WantCaptureMouse, io.WantCaptureKeyboard flag that you can use to dispatch inputs (or not) to your application. ImGui::NewFrame(); // Show/hide OSD keyboard diff --git a/examples/marmalade_example/main.cpp b/examples/marmalade_example/main.cpp index f58c0c972..f87b3bc51 100644 --- a/examples/marmalade_example/main.cpp +++ b/examples/marmalade_example/main.cpp @@ -43,12 +43,16 @@ int main(int, char**) if (s3eDeviceCheckQuitRequest()) break; + // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. + // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. + // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. + // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. s3eKeyboardUpdate(); s3ePointerUpdate(); ImGui_Marmalade_NewFrame(); - // 1. Show a simple window - // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug" + // 1. Show a simple window. + // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug". { static float f = 0.0f; ImGui::Text("Hello, world!"); @@ -59,7 +63,7 @@ int main(int, char**) ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); } - // 2. Show another simple window, this time using an explicit Begin/End pair + // 2. Show another simple window. In most cases you will use an explicit Begin/End pair to name the window. if (show_another_window) { ImGui::Begin("Another Window", &show_another_window); @@ -67,7 +71,7 @@ int main(int, char**) ImGui::End(); } - // 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow() + // 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow(). if (show_test_window) { ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); diff --git a/examples/opengl2_example/imgui_impl_glfw.cpp b/examples/opengl2_example/imgui_impl_glfw.cpp index f8bfddef5..52962c19e 100644 --- a/examples/opengl2_example/imgui_impl_glfw.cpp +++ b/examples/opengl2_example/imgui_impl_glfw.cpp @@ -137,7 +137,7 @@ void ImGui_ImplGlfwGL2_MouseButtonCallback(GLFWwindow*, int button, int action, void ImGui_ImplGlfwGL2_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset) { - g_MouseWheel += (float)yoffset; // Use fractional mouse wheel, 1.0 unit 5 lines. + g_MouseWheel += (float)yoffset; // Use fractional mouse wheel. } void ImGui_ImplGlfwGL2_KeyCallback(GLFWwindow*, int key, int, int action, int mods) @@ -301,6 +301,6 @@ void ImGui_ImplGlfwGL2_NewFrame() // Hide OS mouse cursor if ImGui is drawing it glfwSetInputMode(g_Window, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL); - // Start the frame + // Start the frame. This call will update the io.WantCaptureMouse, io.WantCaptureKeyboard flag that you can use to dispatch inputs (or not) to your application. ImGui::NewFrame(); } diff --git a/examples/opengl2_example/main.cpp b/examples/opengl2_example/main.cpp index d5643db30..1f3336d21 100644 --- a/examples/opengl2_example/main.cpp +++ b/examples/opengl2_example/main.cpp @@ -51,11 +51,15 @@ int main(int, char**) // Main loop while (!glfwWindowShouldClose(window)) { + // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. + // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. + // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. + // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. glfwPollEvents(); ImGui_ImplGlfwGL2_NewFrame(); - // 1. Show a simple window - // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug" + // 1. Show a simple window. + // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug". { static float f = 0.0f; ImGui::Text("Hello, world!"); @@ -66,7 +70,7 @@ int main(int, char**) ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); } - // 2. Show another simple window, this time using an explicit Begin/End pair + // 2. Show another simple window. In most cases you will use an explicit Begin/End pair to name the window. if (show_another_window) { ImGui::Begin("Another Window", &show_another_window); @@ -74,7 +78,7 @@ int main(int, char**) ImGui::End(); } - // 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow() + // 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow(). if (show_test_window) { ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); @@ -87,7 +91,7 @@ int main(int, char**) glViewport(0, 0, display_w, display_h); glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); glClear(GL_COLOR_BUFFER_BIT); - //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context where shaders may be bound + //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context where shaders may be bound, but prefer using the GL3+ code. ImGui::Render(); glfwSwapBuffers(window); } diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp index bf143a11b..7d924fcf1 100644 --- a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp +++ b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp @@ -157,7 +157,7 @@ void ImGui_ImplGlfwGL3_MouseButtonCallback(GLFWwindow*, int button, int action, void ImGui_ImplGlfwGL3_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset) { - g_MouseWheel += (float)yoffset; // Use fractional mouse wheel, 1.0 unit 5 lines. + g_MouseWheel += (float)yoffset; // Use fractional mouse wheel. } void ImGui_ImplGlfwGL3_KeyCallback(GLFWwindow*, int key, int, int action, int mods) @@ -414,6 +414,6 @@ void ImGui_ImplGlfwGL3_NewFrame() // Hide OS mouse cursor if ImGui is drawing it glfwSetInputMode(g_Window, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL); - // Start the frame + // Start the frame. This call will update the io.WantCaptureMouse, io.WantCaptureKeyboard flag that you can use to dispatch inputs (or not) to your application. ImGui::NewFrame(); } diff --git a/examples/opengl3_example/main.cpp b/examples/opengl3_example/main.cpp index 5d778e893..062843d6b 100644 --- a/examples/opengl3_example/main.cpp +++ b/examples/opengl3_example/main.cpp @@ -57,11 +57,15 @@ int main(int, char**) // Main loop while (!glfwWindowShouldClose(window)) { + // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. + // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. + // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. + // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. glfwPollEvents(); ImGui_ImplGlfwGL3_NewFrame(); - // 1. Show a simple window - // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug" + // 1. Show a simple window. + // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug". { static float f = 0.0f; ImGui::Text("Hello, world!"); @@ -72,7 +76,7 @@ int main(int, char**) ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); } - // 2. Show another simple window, this time using an explicit Begin/End pair + // 2. Show another simple window. In most cases you will use an explicit Begin/End pair to name the window. if (show_another_window) { ImGui::Begin("Another Window", &show_another_window); @@ -80,7 +84,7 @@ int main(int, char**) ImGui::End(); } - // 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow() + // 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow(). if (show_test_window) { ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl.cpp b/examples/sdl_opengl2_example/imgui_impl_sdl.cpp index 261706ede..2982f8dee 100644 --- a/examples/sdl_opengl2_example/imgui_impl_sdl.cpp +++ b/examples/sdl_opengl2_example/imgui_impl_sdl.cpp @@ -122,6 +122,10 @@ static void ImGui_ImplSdl_SetClipboardText(void*, const char* text) SDL_SetClipboardText(text); } +// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. +// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. +// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. +// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. bool ImGui_ImplSdlGL2_ProcessEvent(SDL_Event* event) { ImGuiIO& io = ImGui::GetIO(); @@ -286,6 +290,6 @@ void ImGui_ImplSdlGL2_NewFrame(SDL_Window *window) // Hide OS mouse cursor if ImGui is drawing it SDL_ShowCursor(io.MouseDrawCursor ? 0 : 1); - // Start the frame + // Start the frame. This call will update the io.WantCaptureMouse, io.WantCaptureKeyboard flag that you can use to dispatch inputs (or not) to your application. ImGui::NewFrame(); } diff --git a/examples/sdl_opengl2_example/main.cpp b/examples/sdl_opengl2_example/main.cpp index 6f60833e9..cfa43e8e8 100644 --- a/examples/sdl_opengl2_example/main.cpp +++ b/examples/sdl_opengl2_example/main.cpp @@ -2,6 +2,9 @@ // If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. // (SDL is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan graphics context creation, etc.) +// *DO NOT USE THIS CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL* +// See imgui_impl_sdl.cpp for details. + #include #include "imgui_impl_sdl.h" #include @@ -55,6 +58,10 @@ int main(int, char**) bool done = false; while (!done) { + // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. + // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. + // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. + // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. SDL_Event event; while (SDL_PollEvent(&event)) { @@ -65,7 +72,7 @@ int main(int, char**) ImGui_ImplSdlGL2_NewFrame(window); // 1. Show a simple window - // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug" + // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug". { static float f = 0.0f; ImGui::Text("Hello, world!"); @@ -76,7 +83,7 @@ int main(int, char**) ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); } - // 2. Show another simple window, this time using an explicit Begin/End pair + // 2. Show another simple window. In most cases you will use an explicit Begin/End pair to name the window. if (show_another_window) { ImGui::Begin("Another Window", &show_another_window); @@ -84,7 +91,7 @@ int main(int, char**) ImGui::End(); } - // 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow() + // 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow(). if (show_test_window) { ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); diff --git a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp index b1604bd03..68e27a68c 100644 --- a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp +++ b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp @@ -143,6 +143,10 @@ static void ImGui_ImplSdlGL3_SetClipboardText(void*, const char* text) SDL_SetClipboardText(text); } +// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. +// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. +// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. +// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. bool ImGui_ImplSdlGL3_ProcessEvent(SDL_Event* event) { ImGuiIO& io = ImGui::GetIO(); @@ -398,6 +402,6 @@ void ImGui_ImplSdlGL3_NewFrame(SDL_Window* window) // Hide OS mouse cursor if ImGui is drawing it SDL_ShowCursor(io.MouseDrawCursor ? 0 : 1); - // Start the frame + // Start the frame. This call will update the io.WantCaptureMouse, io.WantCaptureKeyboard flag that you can use to dispatch inputs (or not) to your application. ImGui::NewFrame(); } diff --git a/examples/sdl_opengl3_example/main.cpp b/examples/sdl_opengl3_example/main.cpp index 2494208b9..e51b32089 100644 --- a/examples/sdl_opengl3_example/main.cpp +++ b/examples/sdl_opengl3_example/main.cpp @@ -59,6 +59,10 @@ int main(int, char**) bool done = false; while (!done) { + // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. + // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. + // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. + // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. SDL_Event event; while (SDL_PollEvent(&event)) { @@ -68,8 +72,8 @@ int main(int, char**) } ImGui_ImplSdlGL3_NewFrame(window); - // 1. Show a simple window - // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug" + // 1. Show a simple window. + // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug". { static float f = 0.0f; ImGui::Text("Hello, world!"); @@ -80,7 +84,7 @@ int main(int, char**) ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); } - // 2. Show another simple window, this time using an explicit Begin/End pair + // 2. Show another simple window. In most cases you will use an explicit Begin/End pair to name the window. if (show_another_window) { ImGui::Begin("Another Window", &show_another_window); @@ -88,7 +92,7 @@ int main(int, char**) ImGui::End(); } - // 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow() + // 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow(). if (show_test_window) { ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); diff --git a/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp b/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp index 90f783278..1d12e3f77 100644 --- a/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp +++ b/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp @@ -332,7 +332,7 @@ void ImGui_ImplGlfwVulkan_MouseButtonCallback(GLFWwindow*, int button, int actio void ImGui_ImplGlfwVulkan_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset) { - g_MouseWheel += (float)yoffset; // Use fractional mouse wheel, 1.0 unit 5 lines. + g_MouseWheel += (float)yoffset; // Use fractional mouse wheel. } void ImGui_ImplGlfwVulkan_KeyCallback(GLFWwindow*, int key, int, int action, int mods) @@ -830,7 +830,7 @@ void ImGui_ImplGlfwVulkan_NewFrame() // Hide OS mouse cursor if ImGui is drawing it glfwSetInputMode(g_Window, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL); - // Start the frame + // Start the frame. This call will update the io.WantCaptureMouse, io.WantCaptureKeyboard flag that you can use to dispatch inputs (or not) to your application. ImGui::NewFrame(); } diff --git a/examples/vulkan_example/main.cpp b/examples/vulkan_example/main.cpp index 2def96627..9d54976a3 100644 --- a/examples/vulkan_example/main.cpp +++ b/examples/vulkan_example/main.cpp @@ -686,11 +686,15 @@ int main(int, char**) // Main loop while (!glfwWindowShouldClose(window)) { + // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. + // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. + // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. + // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. glfwPollEvents(); ImGui_ImplGlfwVulkan_NewFrame(); - // 1. Show a simple window - // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug" + // 1. Show a simple window. + // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug". { static float f = 0.0f; ImGui::Text("Hello, world!"); @@ -701,7 +705,7 @@ int main(int, char**) ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); } - // 2. Show another simple window, this time using an explicit Begin/End pair + // 2. Show another simple window. In most cases you will use an explicit Begin/End pair to name the window. if (show_another_window) { ImGui::Begin("Another Window", &show_another_window); @@ -709,7 +713,7 @@ int main(int, char**) ImGui::End(); } - // 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow() + // 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow(). if (show_test_window) { ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); diff --git a/imgui.h b/imgui.h index 5f568625b..383aa2073 100644 --- a/imgui.h +++ b/imgui.h @@ -854,16 +854,16 @@ struct ImGuiIO // Output - Retrieve after calling NewFrame() //------------------------------------------------------------------ - bool WantCaptureMouse; // Mouse is hovering a window or widget is active (= ImGui will use your mouse input). Use to hide mouse from the rest of your application - bool WantCaptureKeyboard; // Widget is active (= ImGui will use your keyboard input). Use to hide keyboard from the rest of your application - bool WantTextInput; // Some text input widget is active, which will read input characters from the InputCharacters array. Use to activate on screen keyboard if your system needs one - bool WantMoveMouse; // [BETA-NAV] MousePos has been altered. back-end should reposition mouse on next frame. used only if 'NavMovesMouse=true'. + bool WantCaptureMouse; // When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. This is set by ImGui when it wants to use your mouse (e.g. unclicked mouse is hovering a window, or a widget is active). + bool WantCaptureKeyboard; // When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. This is set by ImGui when it wants to use your keyboard inputs. + bool WantTextInput; // Mobile/console: when io.WantTextInput is true, you may display an on-screen keyboard. This is set by ImGui when it wants textual keyboard input to happen (e.g. when a InputText widget is active). + bool WantMoveMouse; // [BETA-NAV] MousePos has been altered, back-end should reposition mouse on next frame. Set only when 'NavMovesMouse=true'. float Framerate; // Application framerate estimation, in frame per second. Solely for convenience. Rolling average estimation based on IO.DeltaTime over 120 frames int MetricsAllocs; // Number of active memory allocations int MetricsRenderVertices; // Vertices output during last call to Render() int MetricsRenderIndices; // Indices output during last call to Render() = number of triangles * 3 int MetricsActiveWindows; // Number of visible root windows (exclude child windows) - ImVec2 MouseDelta; // Mouse delta. Note that this is zero if either current or previous position are negative, so a disappearing/reappearing mouse won't have a huge delta for one frame. + ImVec2 MouseDelta; // Mouse delta. Note that this is zero if either current or previous position are invalid (-FLT_MAX,-FLT_MAX), so a disappearing/reappearing mouse won't have a huge delta. //------------------------------------------------------------------ // [Internal] ImGui will maintain those fields. Forward compatibility not guaranteed! From db190c16f6a970fdaa918ae6be97bb4b246b20b7 Mon Sep 17 00:00:00 2001 From: Giuseppe Barbieri Date: Wed, 1 Nov 2017 16:48:56 +0100 Subject: [PATCH 523/921] Update imgui_draw.cpp --- imgui_draw.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 56cb4b6ad..bc6588d98 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -137,8 +137,8 @@ void ImGui::StyleColorsClassic(ImGuiStyle* dst) colors[ImGuiCol_FrameBgHovered] = ImVec4(0.90f, 0.80f, 0.80f, 0.40f); colors[ImGuiCol_FrameBgActive] = ImVec4(0.90f, 0.65f, 0.65f, 0.45f); colors[ImGuiCol_TitleBg] = ImVec4(0.27f, 0.27f, 0.54f, 0.83f); - colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.40f, 0.40f, 0.80f, 0.20f); colors[ImGuiCol_TitleBgActive] = ImVec4(0.32f, 0.32f, 0.63f, 0.87f); + colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.40f, 0.40f, 0.80f, 0.20f); colors[ImGuiCol_MenuBarBg] = ImVec4(0.40f, 0.40f, 0.55f, 0.80f); colors[ImGuiCol_ScrollbarBg] = ImVec4(0.20f, 0.25f, 0.30f, 0.60f); colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.40f, 0.40f, 0.80f, 0.30f); From 66f42324ad6203560de5631753644ce4d8e81bc8 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 1 Nov 2017 17:24:17 +0100 Subject: [PATCH 524/921] Drag and Drop: Added ImGuiDragDropFlags_SourceNoHoldToOpenOthers flag. --- imgui.cpp | 2 +- imgui.h | 15 ++++++++------- imgui_internal.h | 2 +- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 6603d3f97..192238658 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -5842,7 +5842,7 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool bool hovered = ItemHoverable(bb, id); // Special mode for Drag and Drop where holding button pressed for a long time while dragging another item triggers the button - if ((flags & ImGuiButtonFlags_PressedOnDragDropHold) && g.DragDropActive && !hovered) + if ((flags & ImGuiButtonFlags_PressedOnDragDropHold) && g.DragDropActive && !(g.DragDropSourceFlags & ImGuiDragDropFlags_SourceNoHoldToOpenOthers)) if (IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem)) { hovered = true; diff --git a/imgui.h b/imgui.h index 25a9c5a6c..12ea6e2a1 100644 --- a/imgui.h +++ b/imgui.h @@ -597,13 +597,14 @@ enum ImGuiHoveredFlags_ enum ImGuiDragDropFlags_ { // BeginDragDropSource() flags - ImGuiDragDropFlags_SourceNoAutoTooltip = 1 << 0, - ImGuiDragDropFlags_SourceNoDisableHover = 1 << 1, // By default, when dragging we clear data so that IsItemHovered() will return true, to avoid subsequent user code submitting tooltips. - ImGuiDragDropFlags_SourceAllowNullID = 1 << 2, // Allow items such as Text(), Image() that have no unique identifier to be used as drag source, by manufacturing a temporary identifier based on their window-relative position. This is extremely unusual within the dear imgui ecosystem and so we made it explicit. - // BeginDragDropTarget() flags - ImGuiDragDropFlags_AcceptBeforeDelivery = 1 << 10, // AcceptDragDropPayload() returns true even before the mouse button is released. You can then call IsDelivery() to test if the payload needs to be delivered. - ImGuiDragDropFlags_AcceptNoDrawDefaultRect = 1 << 11, // Do not draw the default highlight rectangle when hovering over target. - ImGuiDragDropFlags_AcceptPeekOnly = ImGuiDragDropFlags_AcceptBeforeDelivery | ImGuiDragDropFlags_AcceptNoDrawDefaultRect // For peeking ahead and inspecting the payload before delivery. + ImGuiDragDropFlags_SourceNoAutoTooltip = 1 << 0, // By default, a successful call to BeginDragDropSource opens a tooltip so you can display a preview or description of the dragged contents. This flag disable this behavior. + ImGuiDragDropFlags_SourceNoDisableHover = 1 << 1, // By default, when dragging we clear data so that IsItemHovered() will return true, to avoid subsequent user code submitting tooltips. This flag disable this behavior so you can still call IsItemHovered() on the source item. + ImGuiDragDropFlags_SourceNoHoldToOpenOthers = 1 << 2, // Disable the behavior that allows to open tree nodes and collapsing header by holding over them while dragging a source item. + ImGuiDragDropFlags_SourceAllowNullID = 1 << 3, // Allow items such as Text(), Image() that have no unique identifier to be used as drag source, by manufacturing a temporary identifier based on their window-relative position. This is extremely unusual within the dear imgui ecosystem and so we made it explicit. + // AcceptDragDropPayload() flags + ImGuiDragDropFlags_AcceptBeforeDelivery = 1 << 10, // AcceptDragDropPayload() will returns true even before the mouse button is released. You can then call IsDelivery() to test if the payload needs to be delivered. + ImGuiDragDropFlags_AcceptNoDrawDefaultRect = 1 << 11, // Do not draw the default highlight rectangle when hovering over target. + ImGuiDragDropFlags_AcceptPeekOnly = ImGuiDragDropFlags_AcceptBeforeDelivery | ImGuiDragDropFlags_AcceptNoDrawDefaultRect // For peeking ahead and inspecting the payload before delivery. }; // User fill ImGuiIO.KeyMap[] array with indices into the ImGuiIO.KeysDown[512] array diff --git a/imgui_internal.h b/imgui_internal.h index 53af4b377..5e80c6eef 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -184,7 +184,7 @@ enum ImGuiButtonFlags_ ImGuiButtonFlags_NoKeyModifiers = 1 << 9, // disable interaction if a key modifier is held ImGuiButtonFlags_AllowOverlapMode = 1 << 10, // require previous frame HoveredId to either match id or be null before being usable ImGuiButtonFlags_NoHoldingActiveID = 1 << 11, // don't set ActiveId while holding the mouse (ImGuiButtonFlags_PressedOnClick only) - ImGuiButtonFlags_PressedOnDragDropHold = 1 << 12 // press when held into while we are drag and dropping another item + ImGuiButtonFlags_PressedOnDragDropHold = 1 << 12 // press when held into while we are drag and dropping another item (used by e.g. tree nodes, collapsing headers) }; enum ImGuiSliderFlags_ From 6fb43f2011ba5ea6446fb0e659160190e2a712c3 Mon Sep 17 00:00:00 2001 From: Giuseppe Barbieri Date: Wed, 1 Nov 2017 17:56:03 +0100 Subject: [PATCH 525/921] Update imgui.h --- imgui.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.h b/imgui.h index 383aa2073..abdf96e78 100644 --- a/imgui.h +++ b/imgui.h @@ -1356,7 +1356,7 @@ struct ImFontConfig float SizePixels; // // Size in pixels for rasterizer. int OversampleH, OversampleV; // 3, 1 // Rasterize at higher quality for sub-pixel positioning. We don't use sub-pixel positions on the Y axis. bool PixelSnapH; // false // Align every glyph to pixel boundary. Useful e.g. if you are merging a non-pixel aligned font with the default font. If enabled, you can set OversampleH/V to 1. - ImVec2 GlyphExtraSpacing; // 1, 0 // Extra spacing (in pixels) between glyphs. Only X axis is supported for now. + ImVec2 GlyphExtraSpacing; // 0, 0 // Extra spacing (in pixels) between glyphs. Only X axis is supported for now. ImVec2 GlyphOffset; // 0, 0 // Offset all glyphs from this font input. const ImWchar* GlyphRanges; // NULL // Pointer to a user-provided list of Unicode range (2 value per range, values are inclusive, zero-terminated list). THE ARRAY DATA NEEDS TO PERSIST AS LONG AS THE FONT IS ALIVE. bool MergeMode; // false // Merge into previous ImFont, so you can combine multiple inputs font into one ImFont (e.g. ASCII font + icons + Japanese glyphs). You may want to use GlyphOffset.y when merge font of different heights. From 2a3a25e792e22e8ef5c2c1e5c649c34b5fe99011 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 2 Nov 2017 10:41:21 +0100 Subject: [PATCH 526/921] Reordered fields in other Style functions (#1409) --- imgui_draw.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index bc6588d98..cea664521 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -186,8 +186,8 @@ void ImGui::StyleColorsDark(ImGuiStyle* dst) colors[ImGuiCol_FrameBgHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.40f); colors[ImGuiCol_FrameBgActive] = ImVec4(0.26f, 0.59f, 0.98f, 0.67f); colors[ImGuiCol_TitleBg] = ImVec4(0.04f, 0.04f, 0.04f, 1.00f); - colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.00f, 0.00f, 0.00f, 0.51f); colors[ImGuiCol_TitleBgActive] = ImVec4(0.18f, 0.18f, 0.18f, 1.00f); + colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.00f, 0.00f, 0.00f, 0.51f); colors[ImGuiCol_MenuBarBg] = ImVec4(0.14f, 0.14f, 0.14f, 1.00f); colors[ImGuiCol_ScrollbarBg] = ImVec4(0.02f, 0.02f, 0.02f, 0.53f); colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.31f, 0.31f, 0.31f, 1.00f); From 803ac3a5c641d69a879fe290cb5d401677126e2d Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 2 Nov 2017 16:23:03 +0100 Subject: [PATCH 527/921] IsWindowHovered() Fix behavior when an item is active to use the same logic as IsItemHovered() (#1382, #1404) --- imgui.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 9f5f781c3..6ef4db0c6 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -5115,7 +5115,7 @@ bool ImGui::IsWindowHovered(ImGuiHoveredFlags flags) if (!IsWindowContentHoverable(g.HoveredRootWindow, flags)) return false; if (!(flags & ImGuiHoveredFlags_AllowWhenBlockedByActiveItem)) - if (g.ActiveId != 0 && g.ActiveIdWindow != g.CurrentWindow) + if (g.ActiveId != 0 && !g.ActiveIdAllowOverlap) return false; return true; } @@ -5151,7 +5151,7 @@ bool ImGui::IsRootWindowOrAnyChildHovered(ImGuiHoveredFlags flags) if (!IsWindowContentHoverable(g.HoveredRootWindow, flags)) return false; if (!(flags & ImGuiHoveredFlags_AllowWhenBlockedByActiveItem)) - if (g.ActiveId != 0 && g.ActiveIdWindow != g.CurrentWindow) + if (g.ActiveId != 0 && !g.ActiveIdAllowOverlap) return false; return true; } From ff4d4ca65191f4607e9e732811146ee1f3819cf1 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 2 Nov 2017 16:44:24 +0100 Subject: [PATCH 528/921] IsWindowHovered(): Added ImGuiHoveredFlags_FlattenChilds flag. Made IsRootWindowOrAnyChildHovered() obsolete in favor of IsWindowHovered( ImGuiHoveredFlags_FlattenChilds) (#1382, #1404) --- imgui.cpp | 30 +++++++++++++----------------- imgui.h | 3 ++- imgui_demo.cpp | 8 +++++--- 3 files changed, 20 insertions(+), 21 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 6ef4db0c6..1cccefcb9 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -214,6 +214,7 @@ Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. Also read releases logs https://github.com/ocornut/imgui/releases for more details. + - 2017/11/02 (1.53) - marked IsRootWindowOrAnyChildHovered() as obsolete is favor of using IsWindowHovered(ImGuiHoveredFlags_FlattenChilds); - 2017/10/24 (1.52) - renamed IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCS/IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCS to IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS/IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS for consistency. - 2017/10/20 (1.52) - changed IsWindowHovered() default parameters behavior to return false if an item is active in another window (e.g. click-dragging item from another window to this window). You can use the newly introduced IsWindowHovered() flags to requests this specific behavior if you need it. - 2017/10/20 (1.52) - marked IsItemHoveredRect()/IsMouseHoveringWindow() as obsolete, in favor of using the newly introduced flags for IsItemHovered() and IsWindowHovered(). See https://github.com/ocornut/imgui/issues/1382 for details. @@ -1991,6 +1992,8 @@ bool ImGui::IsItemHovered(ImGuiHoveredFlags flags) ImGuiWindow* window = g.CurrentWindow; if (!window->DC.LastItemRectHoveredRect) return false; + IM_ASSERT((flags & ImGuiHoveredFlags_FlattenChilds) == 0); // Flags not supported by this function + // [2017/10/16] Reverted commit 344d48be3 and testing RootWindow instead. I believe it is correct to NOT test for RootWindow but this leaves us unable to use IsItemHovered() after EndChild() itself. // Until a solution is found I believe reverting to the test from 2017/09/27 is safe since this was the test that has been running for a long while. //if (g.HoveredWindow != window) @@ -5110,8 +5113,16 @@ bool ImGui::IsWindowHovered(ImGuiHoveredFlags flags) { IM_ASSERT((flags & ImGuiHoveredFlags_AllowWhenOverlapped) == 0); // Flags not supported by this function ImGuiContext& g = *GImGui; - if (g.HoveredWindow != g.CurrentWindow) - return false; + if (flags & ImGuiHoveredFlags_FlattenChilds) + { + if (g.HoveredRootWindow != g.CurrentWindow->RootWindow) + return false; + } + else + { + if (g.HoveredWindow != g.CurrentWindow) + return false; + } if (!IsWindowContentHoverable(g.HoveredRootWindow, flags)) return false; if (!(flags & ImGuiHoveredFlags_AllowWhenBlockedByActiveItem)) @@ -5141,21 +5152,6 @@ bool ImGui::IsRootWindowOrAnyChildFocused() return g.NavWindow && g.NavWindow->RootWindow == g.CurrentWindow->RootWindow; } -bool ImGui::IsRootWindowOrAnyChildHovered(ImGuiHoveredFlags flags) -{ - ImGuiContext& g = *GImGui; - IM_ASSERT((flags & ImGuiHoveredFlags_AllowWhenOverlapped) == 0); // Flags not supported by this function - IM_ASSERT(g.CurrentWindow); // Not inside a Begin()/End() - if (!g.HoveredRootWindow || (g.HoveredRootWindow != g.CurrentWindow->RootWindow)) - return false; - if (!IsWindowContentHoverable(g.HoveredRootWindow, flags)) - return false; - if (!(flags & ImGuiHoveredFlags_AllowWhenBlockedByActiveItem)) - if (g.ActiveId != 0 && !g.ActiveIdAllowOverlap) - return false; - return true; -} - float ImGui::GetWindowWidth() { ImGuiWindow* window = GImGui->CurrentWindow; diff --git a/imgui.h b/imgui.h index abdf96e78..9a1a159a3 100644 --- a/imgui.h +++ b/imgui.h @@ -433,7 +433,6 @@ namespace ImGui IMGUI_API bool IsWindowHovered(ImGuiHoveredFlags flags = 0); // is current Begin()-ed window hovered (and typically: not blocked by a popup/modal)? IMGUI_API bool IsRootWindowFocused(); // is current Begin()-ed root window focused (root = top-most parent of a child, otherwise self)? IMGUI_API bool IsRootWindowOrAnyChildFocused(); // is current Begin()-ed root window or any of its child (including current window) focused? - IMGUI_API bool IsRootWindowOrAnyChildHovered(ImGuiHoveredFlags flags = 0); // is current Begin()-ed root window or any of its child (including current window) hovered and hoverable (not blocked by a popup)? IMGUI_API bool IsAnyWindowHovered(); // is mouse hovering any visible window IMGUI_API bool IsRectVisible(const ImVec2& size); // test if rectangle (of given size, starting from cursor position) is visible / not clipped. IMGUI_API bool IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max); // test if rectangle (in screen space) is visible / not clipped. to perform coarse clipping on user's side. @@ -580,6 +579,7 @@ enum ImGuiHoveredFlags_ //ImGuiHoveredFlags_AllowWhenBlockedByModal = 1 << 1, // Return true even if a modal popup window is normally blocking access to this item/window. FIXME-TODO: Unavailable yet. ImGuiHoveredFlags_AllowWhenBlockedByActiveItem = 1 << 2, // Return true even if an active item is blocking access to this item/window ImGuiHoveredFlags_AllowWhenOverlapped = 1 << 3, // Return true even if the position is overlapped by another window + ImGuiHoveredFlags_FlattenChilds = 1 << 4, // Treat all child windows as the same window (for IsWindowHovered()) ImGuiHoveredFlags_RectOnly = ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem | ImGuiHoveredFlags_AllowWhenOverlapped }; @@ -893,6 +893,7 @@ struct ImGuiIO #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS namespace ImGui { + static inline bool IsRootWindowOrAnyChildHovered(ImGuiHoveredFlags flags = 0) { return IsItemHovered(flags | ImGuiHoveredFlags_FlattenChilds); } // OBSOLETE 1.53+ use flags directly bool Begin(const char* name, bool* p_open, const ImVec2& size_on_first_use, float bg_alpha_override = -1.0f, ImGuiWindowFlags flags = 0); // OBSOLETE 1.52+. use SetNextWindowSize() instead if you want to set a window size. static inline void AlignFirstTextHeightToWidgets() { AlignTextToFramePadding(); } // OBSOLETE 1.52+ static inline void SetNextWindowPosCenter(ImGuiCond cond = 0) { SetNextWindowPos(ImVec2(GetIO().DisplaySize.x * 0.5f, GetIO().DisplaySize.y * 0.5f), cond, ImVec2(0.5f, 0.5f)); } // OBSOLETE 1.52+ diff --git a/imgui_demo.cpp b/imgui_demo.cpp index c27b886ca..0d6a44232 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1778,14 +1778,16 @@ void ImGui::ShowTestWindow(bool* p_open) if (ImGui::TreeNode("Hovering")) { - // Testing IsWindowHovered() function + // Testing IsWindowHovered() function with its various flags (note that the flags can be combined) ImGui::BulletText( "IsWindowHovered() = %d\n" "IsWindowHovered(_AllowWhenBlockedByPopup) = %d\n" - "IsWindowHovered(_AllowWhenBlockedByActiveItem) = %d\n", + "IsWindowHovered(_AllowWhenBlockedByActiveItem) = %d\n" + "IsWindowHovered(_FlattenChilds) = %d\n", ImGui::IsWindowHovered(), ImGui::IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup), - ImGui::IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem)); + ImGui::IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem), + ImGui::IsWindowHovered(ImGuiHoveredFlags_FlattenChilds)); // Testing IsItemHovered() function (because BulletText is an item itself and that would affect the output of IsItemHovered, we pass all lines in a single items to shorten the code) ImGui::Button("ITEM"); From 982ce50b37492c79ddabb6e6b456b27964453940 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 2 Nov 2017 16:44:32 +0100 Subject: [PATCH 529/921] IsWindowHovered() returns true when moving window (#1382, #1404) --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 1cccefcb9..daa658d74 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -5126,7 +5126,7 @@ bool ImGui::IsWindowHovered(ImGuiHoveredFlags flags) if (!IsWindowContentHoverable(g.HoveredRootWindow, flags)) return false; if (!(flags & ImGuiHoveredFlags_AllowWhenBlockedByActiveItem)) - if (g.ActiveId != 0 && !g.ActiveIdAllowOverlap) + if (g.ActiveId != 0 && !g.ActiveIdAllowOverlap && g.ActiveId != g.HoveredWindow->MoveId) return false; return true; } From 553bdeedf78126b9b91289a64dce6efe2e8b741e Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 2 Nov 2017 18:30:46 +0100 Subject: [PATCH 530/921] Drag and Drop: Made it legal to not call SetDragDropPayload() between BeginDragDropSource() and EndDragDropSource(). (#143) --- imgui.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index e3481db80..73456b358 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -10706,7 +10706,6 @@ void ImGui::EndDragDropSource() { ImGuiContext& g = *GImGui; IM_ASSERT(g.DragDropActive); - IM_ASSERT(g.DragDropPayload.DataFrameCount != -1); // Forgot to call SetDragDropSourcePayload(), at least once on the first frame of a successful BeginDragDropSource() if (!(g.DragDropSourceFlags & ImGuiDragDropFlags_SourceNoAutoTooltip)) { @@ -10714,9 +10713,16 @@ void ImGui::EndDragDropSource() PopStyleColor(); //PopStyleVar(); } + + // Discard the drag if have not called SetDragDropPayload() + if (g.DragDropPayload.DataFrameCount == -1) + { + g.DragDropActive = false; + g.DragDropPayload.Clear(); + } } -// Use 'cond' to choose to submit paypload on drag start or every frame +// Use 'cond' to choose to submit payload on drag start or every frame bool ImGui::SetDragDropPayload(const char* type, const void* data, size_t data_size, ImGuiCond cond) { ImGuiContext& g = *GImGui; @@ -10783,7 +10789,7 @@ const ImGuiPayload* ImGui::AcceptDragDropPayload(const char* type, ImGuiDragDrop ImGuiPayload& payload = g.DragDropPayload; IM_ASSERT(g.DragDropActive); // Not called between BeginDragDropTarget() and EndDragDropTarget() ? IM_ASSERT(window->DC.LastItemRectHoveredRect); // Not called between BeginDragDropTarget() and EndDragDropTarget() ? - IM_ASSERT(payload.DataFrameCount != -1); // Internal/usage error, please report! + IM_ASSERT(payload.DataFrameCount != -1); // Forgot to call EndDragDropTarget() ? if (type != NULL && !payload.IsDataType(type)) return NULL; From 16a5da9521f966ad90eef15aec012e0a07dd903f Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 3 Nov 2017 20:17:13 +0100 Subject: [PATCH 531/921] RenderTriangle() minor tweak to align Left/Right and Up/Down arrow extents visually --- imgui.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index daa658d74..237154fe3 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3105,6 +3105,7 @@ void ImGui::RenderTriangle(ImVec2 p_min, ImGuiDir dir, float scale) case ImGuiDir_Left: r = -r; // ...fall through, no break! case ImGuiDir_Right: + center.x -= r * 0.25f; a = ImVec2(1,0) * r; b = ImVec2(-0.500f,+0.866f) * r; c = ImVec2(-0.500f,-0.866f) * r; @@ -9096,7 +9097,7 @@ bool ImGui::MenuItem(const char* label, const char* shortcut, bool selected, boo PopStyleColor(); } if (selected) - RenderCheckMark(pos + ImVec2(window->MenuColumns.Pos[2] + extra_w + g.FontSize * (0.20f+0.200f), g.FontSize * 0.134f * 0.5f), GetColorU32(enabled ? ImGuiCol_Text : ImGuiCol_TextDisabled), g.FontSize * 0.866f); + RenderCheckMark(pos + ImVec2(window->MenuColumns.Pos[2] + extra_w + g.FontSize * 0.40f, g.FontSize * 0.134f * 0.5f), GetColorU32(enabled ? ImGuiCol_Text : ImGuiCol_TextDisabled), g.FontSize * 0.866f); } return pressed; } @@ -9215,7 +9216,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled) float extra_w = ImMax(0.0f, GetContentRegionAvail().x - w); pressed = Selectable(label, menu_is_open, ImGuiSelectableFlags_Menu | ImGuiSelectableFlags_DontClosePopups | ImGuiSelectableFlags_DrawFillAvailWidth | (!enabled ? ImGuiSelectableFlags_Disabled : 0), ImVec2(w, 0.0f)); if (!enabled) PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]); - RenderTriangle(pos + ImVec2(window->MenuColumns.Pos[2] + extra_w + g.FontSize * 0.20f, 0.0f), ImGuiDir_Right); + RenderTriangle(pos + ImVec2(window->MenuColumns.Pos[2] + extra_w + g.FontSize * 0.30f, 0.0f), ImGuiDir_Right); if (!enabled) PopStyleColor(); } From 8b725c94cbab321d7bc1b4ee7d1efbf131c4f41d Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 6 Nov 2017 19:39:23 +0100 Subject: [PATCH 532/921] Drag and Drop: Rework internal to allow overlapping targets (#143) --- imgui.cpp | 32 +++++++++++++++----------------- imgui.h | 7 ++++--- 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 73456b358..8c52e4695 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2250,6 +2250,8 @@ void ImGui::NewFrame() g.ScalarAsInputTextId = 0; // Elapse drag & drop payload + g.DragDropPayload.AcceptIdPrev = g.DragDropPayload.AcceptIdCurr; + g.DragDropPayload.AcceptIdCurr = 0; if (g.DragDropActive && g.DragDropPayload.DataFrameCount + 1 < g.FrameCount) { g.DragDropActive = false; @@ -10773,7 +10775,6 @@ bool ImGui::BeginDragDropTarget() return false; ImGuiWindow* window = g.CurrentWindow; - //if (!window->DC.LastItemRectHoveredRect || (g.ActiveId == g.DragDropPayload.SourceId || g.ActiveIdPreviousFrame == g.DragDropPayload.SourceId)) if (!window->DC.LastItemRectHoveredRect || (window->DC.LastItemId && window->DC.LastItemId == g.DragDropPayload.SourceId)) return false; if (window->RootWindow != g.HoveredWindow->RootWindow) @@ -10793,23 +10794,20 @@ const ImGuiPayload* ImGui::AcceptDragDropPayload(const char* type, ImGuiDragDrop if (type != NULL && !payload.IsDataType(type)) return NULL; - if (payload.AcceptId == 0) - payload.AcceptId = window->DC.LastItemId; - - bool was_accepted_previously = (payload.AcceptFrameCount == g.FrameCount - 1); - if (payload.AcceptFrameCount != g.FrameCount) - { - // Render drop visuals - if (!(flags & ImGuiDragDropFlags_AcceptNoDrawDefaultRect) && was_accepted_previously) - { - ImRect r = window->DC.LastItemRect; - r.Expand(4.0f); - window->DrawList->AddRectFilled(r.Min, r.Max, IM_COL32(255, 255, 0, 20), 0.0f); // FIXME-DRAG FIXME-STYLE - window->DrawList->AddRect(r.Min, r.Max, IM_COL32(255, 255, 0, 255), 0.0f, ~0, 2.0f); // FIXME-DRAG FIXME-STYLE - } - payload.AcceptFrameCount = g.FrameCount; - } + // NB: We currently accept NULL id however, overlapping targets required unique ID to function + const bool was_accepted_previously = (payload.AcceptIdPrev == window->DC.LastItemId); + //if (window->DC.LastItemId) + payload.AcceptIdCurr = window->DC.LastItemId; + // Render drop visuals + if (!(flags & ImGuiDragDropFlags_AcceptNoDrawDefaultRect) && was_accepted_previously) + { + ImRect r = window->DC.LastItemRect; + r.Expand(4.0f); + window->DrawList->AddRectFilled(r.Min, r.Max, IM_COL32(255, 255, 0, 20), 0.0f); // FIXME-DRAG FIXME-STYLE + window->DrawList->AddRect(r.Min, r.Max, IM_COL32(255, 255, 0, 255), 0.0f, ~0, 2.0f); // FIXME-DRAG FIXME-STYLE + } + payload.AcceptFrameCount = g.FrameCount; payload.Delivery = was_accepted_previously && IsMouseReleased(g.DragDropMouseButton); if (!payload.Delivery && !(flags & ImGuiDragDropFlags_AcceptBeforeDelivery)) return NULL; diff --git a/imgui.h b/imgui.h index 6191f0991..849d78648 100644 --- a/imgui.h +++ b/imgui.h @@ -587,7 +587,7 @@ enum ImGuiHoveredFlags_ ImGuiHoveredFlags_Default = 0, // Return true if directly over the item/window, not obstructed by another window, not obstructed by an active popup or modal blocking inputs under them. ImGuiHoveredFlags_AllowWhenBlockedByPopup = 1 << 0, // Return true even if a popup window is normally blocking access to this item/window //ImGuiHoveredFlags_AllowWhenBlockedByModal = 1 << 1, // Return true even if a modal popup window is normally blocking access to this item/window. FIXME-TODO: Unavailable yet. - ImGuiHoveredFlags_AllowWhenBlockedByActiveItem = 1 << 2, // Return true even if an active item is blocking access to this item/window + ImGuiHoveredFlags_AllowWhenBlockedByActiveItem = 1 << 2, // Return true even if an active item is blocking access to this item/window. Useful for Drag and Drop patterns. ImGuiHoveredFlags_AllowWhenOverlapped = 1 << 3, // Return true even if the position is overlapped by another window ImGuiHoveredFlags_FlattenChilds = 1 << 4, // Treat all child windows as the same window (for IsWindowHovered()) ImGuiHoveredFlags_RectOnly = ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem | ImGuiHoveredFlags_AllowWhenOverlapped @@ -1153,14 +1153,15 @@ struct ImGuiPayload // [Internal] ImGuiID SourceId; // Source item id ImGuiID SourceParentId; // Source parent id (if available) - ImGuiID AcceptId; // Target item id (set at the time of accepting the payload) + ImGuiID AcceptIdCurr; // Target item id (set at the time of accepting the payload) + ImGuiID AcceptIdPrev; // Target item id from previous frame (we need to store this to allow for overlapping drag and drop targets) int AcceptFrameCount; // Last time a target expressed a desire to accept the source int DataFrameCount; // Data timestamp char DataType[8 + 1]; // Data type tag (short user-supplied string) bool Delivery; // Set when AcceptDragDropPayload() was called and the mouse button is released over the target item ImGuiPayload() { Clear(); } - void Clear() { SourceId = SourceParentId = AcceptId = 0; AcceptFrameCount = -1; Data = NULL; DataSize = 0; memset(DataType, 0, sizeof(DataType)); DataFrameCount = -1; Delivery = false; } + void Clear() { SourceId = SourceParentId = AcceptIdCurr = AcceptIdPrev = 0; AcceptFrameCount = -1; Data = NULL; DataSize = 0; memset(DataType, 0, sizeof(DataType)); DataFrameCount = -1; Delivery = false; } bool IsDataType(const char* type) const { return DataFrameCount != -1 && strcmp(type, DataType) == 0; } bool IsDelivery() const { return Delivery; } }; From de1e7dc088952f484cd905e815449519641d0e81 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 6 Nov 2017 20:02:56 +0100 Subject: [PATCH 533/921] Drag and Drop: Moved internal fields out of public sight. (#143) --- imgui.cpp | 33 +++++++++++++++++++-------------- imgui.h | 5 +---- imgui_internal.h | 5 +++++ 3 files changed, 25 insertions(+), 18 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 8c52e4695..999b373f3 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -662,6 +662,7 @@ static bool DataTypeApplyOpFromText(const char* buf, const char* ini namespace ImGui { +static void ClearDragDrop(); static void FocusPreviousWindow(); } @@ -2250,15 +2251,14 @@ void ImGui::NewFrame() g.ScalarAsInputTextId = 0; // Elapse drag & drop payload - g.DragDropPayload.AcceptIdPrev = g.DragDropPayload.AcceptIdCurr; - g.DragDropPayload.AcceptIdCurr = 0; if (g.DragDropActive && g.DragDropPayload.DataFrameCount + 1 < g.FrameCount) { - g.DragDropActive = false; - g.DragDropPayload.Clear(); + ClearDragDrop(); g.DragDropPayloadBufHeap.clear(); memset(&g.DragDropPayloadBufLocal, 0, sizeof(g.DragDropPayloadBufLocal)); } + g.DragDropAcceptIdPrev = g.DragDropAcceptIdCurr; + g.DragDropAcceptIdCurr = 0; // Update keyboard input state memcpy(g.IO.KeysDownDurationPrev, g.IO.KeysDownDuration, sizeof(g.IO.KeysDownDuration)); @@ -10631,6 +10631,15 @@ void ImGui::Value(const char* prefix, float v, const char* float_format) // DRAG AND DROP //----------------------------------------------------------------------------- +static void ImGui::ClearDragDrop() +{ + ImGuiContext& g = *GImGui; + g.DragDropActive = false; + g.DragDropPayload.Clear(); + g.DragDropAcceptIdCurr = g.DragDropAcceptIdPrev = 0; + g.DragDropAcceptFrameCount = -1; +} + // Call when current ID is active. // When this returns true you need to: a) call SetDragDropPayload() exactly once, b) you may render the payload visual/description, c) call EndDragDropSource() bool ImGui::BeginDragDropSource(ImGuiDragDropFlags flags, int mouse_button) @@ -10677,8 +10686,8 @@ bool ImGui::BeginDragDropSource(ImGuiDragDropFlags flags, int mouse_button) if (!g.DragDropActive) { IM_ASSERT(id != 0); + ClearDragDrop(); ImGuiPayload& payload = g.DragDropPayload; - payload.Clear(); payload.SourceId = id; payload.SourceParentId = window->IDStack.back(); g.DragDropActive = true; @@ -10718,10 +10727,7 @@ void ImGui::EndDragDropSource() // Discard the drag if have not called SetDragDropPayload() if (g.DragDropPayload.DataFrameCount == -1) - { - g.DragDropActive = false; - g.DragDropPayload.Clear(); - } + ClearDragDrop(); } // Use 'cond' to choose to submit payload on drag start or every frame @@ -10765,7 +10771,7 @@ bool ImGui::SetDragDropPayload(const char* type, const void* data, size_t data_s } payload.DataFrameCount = g.FrameCount; - return (payload.AcceptFrameCount == g.FrameCount) || (payload.AcceptFrameCount == g.FrameCount - 1); + return (g.DragDropAcceptFrameCount == g.FrameCount) || (g.DragDropAcceptFrameCount == g.FrameCount - 1); } bool ImGui::BeginDragDropTarget() @@ -10795,9 +10801,8 @@ const ImGuiPayload* ImGui::AcceptDragDropPayload(const char* type, ImGuiDragDrop return NULL; // NB: We currently accept NULL id however, overlapping targets required unique ID to function - const bool was_accepted_previously = (payload.AcceptIdPrev == window->DC.LastItemId); - //if (window->DC.LastItemId) - payload.AcceptIdCurr = window->DC.LastItemId; + const bool was_accepted_previously = (g.DragDropAcceptIdPrev == window->DC.LastItemId); + g.DragDropAcceptIdCurr = window->DC.LastItemId; // Render drop visuals if (!(flags & ImGuiDragDropFlags_AcceptNoDrawDefaultRect) && was_accepted_previously) @@ -10807,7 +10812,7 @@ const ImGuiPayload* ImGui::AcceptDragDropPayload(const char* type, ImGuiDragDrop window->DrawList->AddRectFilled(r.Min, r.Max, IM_COL32(255, 255, 0, 20), 0.0f); // FIXME-DRAG FIXME-STYLE window->DrawList->AddRect(r.Min, r.Max, IM_COL32(255, 255, 0, 255), 0.0f, ~0, 2.0f); // FIXME-DRAG FIXME-STYLE } - payload.AcceptFrameCount = g.FrameCount; + g.DragDropAcceptFrameCount = g.FrameCount; payload.Delivery = was_accepted_previously && IsMouseReleased(g.DragDropMouseButton); if (!payload.Delivery && !(flags & ImGuiDragDropFlags_AcceptBeforeDelivery)) return NULL; diff --git a/imgui.h b/imgui.h index 849d78648..1624e3173 100644 --- a/imgui.h +++ b/imgui.h @@ -1153,15 +1153,12 @@ struct ImGuiPayload // [Internal] ImGuiID SourceId; // Source item id ImGuiID SourceParentId; // Source parent id (if available) - ImGuiID AcceptIdCurr; // Target item id (set at the time of accepting the payload) - ImGuiID AcceptIdPrev; // Target item id from previous frame (we need to store this to allow for overlapping drag and drop targets) - int AcceptFrameCount; // Last time a target expressed a desire to accept the source int DataFrameCount; // Data timestamp char DataType[8 + 1]; // Data type tag (short user-supplied string) bool Delivery; // Set when AcceptDragDropPayload() was called and the mouse button is released over the target item ImGuiPayload() { Clear(); } - void Clear() { SourceId = SourceParentId = AcceptIdCurr = AcceptIdPrev = 0; AcceptFrameCount = -1; Data = NULL; DataSize = 0; memset(DataType, 0, sizeof(DataType)); DataFrameCount = -1; Delivery = false; } + void Clear() { SourceId = SourceParentId = 0; Data = NULL; DataSize = 0; memset(DataType, 0, sizeof(DataType)); DataFrameCount = -1; Delivery = false; } bool IsDataType(const char* type) const { return DataFrameCount != -1 && strcmp(type, DataType) == 0; } bool IsDelivery() const { return Delivery; } }; diff --git a/imgui_internal.h b/imgui_internal.h index 5e80c6eef..5c3b24c8a 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -480,6 +480,9 @@ struct ImGuiContext ImGuiDragDropFlags DragDropSourceFlags; int DragDropMouseButton; ImGuiPayload DragDropPayload; + ImGuiID DragDropAcceptIdCurr; // Target item id (set at the time of accepting the payload) + ImGuiID DragDropAcceptIdPrev; // Target item id from previous frame (we need to store this to allow for overlapping drag and drop targets) + int DragDropAcceptFrameCount; // Last time a target expressed a desire to accept the source ImVector DragDropPayloadBufHeap; // We don't expose the ImVector<> directly unsigned char DragDropPayloadBufLocal[8]; @@ -563,6 +566,8 @@ struct ImGuiContext DragDropActive = false; DragDropSourceFlags = 0; DragDropMouseButton = -1; + DragDropAcceptIdPrev = DragDropAcceptIdCurr = 0; + DragDropAcceptFrameCount = -1; memset(DragDropPayloadBufLocal, 0, sizeof(DragDropPayloadBufLocal)); ScalarAsInputTextId = 0; From f0b4097c54d435d6ba9997ecad7aa434c19f5406 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 6 Nov 2017 23:55:40 +0100 Subject: [PATCH 534/921] Begin: Simplified code and fixed a bug where appending into a window a second time (from a remote window) would incorrectly overwrite RootWindow with the current window in the stack. Our docking code uses this pattern. --- imgui.cpp | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 237154fe3..9c9e7b12e 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4181,21 +4181,17 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) g.SetNextWindowFocus = false; } - // Update known root window (if we are a child window, otherwise window == window->RootWindow) - int root_idx, root_non_popup_idx; - for (root_idx = g.CurrentWindowStack.Size - 1; root_idx > 0; root_idx--) - if (!(g.CurrentWindowStack[root_idx]->Flags & ImGuiWindowFlags_ChildWindow)) - break; - for (root_non_popup_idx = root_idx; root_non_popup_idx > 0; root_non_popup_idx--) - if (!(g.CurrentWindowStack[root_non_popup_idx]->Flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_Popup)) || (g.CurrentWindowStack[root_non_popup_idx]->Flags & ImGuiWindowFlags_Modal)) - break; - window->ParentWindow = parent_window; - window->RootWindow = g.CurrentWindowStack[root_idx]; - window->RootNonPopupWindow = g.CurrentWindowStack[root_non_popup_idx]; // Used to display TitleBgActive color and for selecting which window to use for NavWindowing - // When reusing window again multiple times a frame, just append content (don't need to setup again) if (first_begin_of_the_frame) { + // Initialize + window->ParentWindow = parent_window; + window->RootWindow = !(flags & ImGuiWindowFlags_ChildWindow) ? window : parent_window->RootWindow; + window->RootNonPopupWindow = !(flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_Popup)) || (flags & ImGuiWindowFlags_Modal) ? window : parent_window->RootNonPopupWindow; // Used to display TitleBgActive color and for selecting which window to use for NavWindowing + //window->RootNavWindow = window; + //while (window->RootNavWindow->Flags & ImGuiWindowFlags_NavFlattened) + // window->RootNavWindow = window->RootNavWindow->ParentWindow; + window->Active = true; window->OrderWithinParent = 0; window->BeginCount = 0; From 2c7ba21417dbc82e277e223e556e5a29a0674798 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 7 Nov 2017 11:37:38 +0100 Subject: [PATCH 535/921] Fixed auto-resize allocating too much space for scrollbar when SizeContents is bigger than maximum window size (fixes c0547d358d746699f8d46a4996e49fdac8c55748) (#1417) --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 9c9e7b12e..d762910ad 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4039,7 +4039,7 @@ static ImVec2 CalcSizeAutoFit(ImGuiWindow* window) if (size_auto_fit_after_constraint.x < window->SizeContents.x && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar)) size_auto_fit.y += style.ScrollbarSize; if (size_auto_fit_after_constraint.y < window->SizeContents.y && !(flags & ImGuiWindowFlags_NoScrollbar)) - size_auto_fit.x += style.ScrollbarSize * 2.0f; + size_auto_fit.x += style.ScrollbarSize; size_auto_fit.y = ImMax(size_auto_fit.y - style.ItemSpacing.y, 0.0f); } return size_auto_fit; From 8e6adc78afe090fe012ec50625aad82666303f86 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 7 Nov 2017 11:38:14 +0100 Subject: [PATCH 536/921] Examples: Constrained Resize: Added more test cases (for #1417) --- imgui_demo.cpp | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 0d6a44232..7f45c50ea 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -2145,31 +2145,40 @@ static void ShowExampleAppConstrainedResize(bool* p_open) static void Step(ImGuiSizeConstraintCallbackData* data) { float step = (float)(int)(intptr_t)data->UserData; data->DesiredSize = ImVec2((int)(data->DesiredSize.x / step + 0.5f) * step, (int)(data->DesiredSize.y / step + 0.5f) * step); } }; + static bool auto_resize = false; static int type = 0; + static int display_lines = 10; if (type == 0) ImGui::SetNextWindowSizeConstraints(ImVec2(-1, 0), ImVec2(-1, FLT_MAX)); // Vertical only if (type == 1) ImGui::SetNextWindowSizeConstraints(ImVec2(0, -1), ImVec2(FLT_MAX, -1)); // Horizontal only if (type == 2) ImGui::SetNextWindowSizeConstraints(ImVec2(100, 100), ImVec2(FLT_MAX, FLT_MAX)); // Width > 100, Height > 100 - if (type == 3) ImGui::SetNextWindowSizeConstraints(ImVec2(300, 0), ImVec2(400, FLT_MAX)); // Width 300-400 - if (type == 4) ImGui::SetNextWindowSizeConstraints(ImVec2(0, 0), ImVec2(FLT_MAX, FLT_MAX), CustomConstraints::Square); // Always Square - if (type == 5) ImGui::SetNextWindowSizeConstraints(ImVec2(0, 0), ImVec2(FLT_MAX, FLT_MAX), CustomConstraints::Step, (void*)100);// Fixed Step + if (type == 3) ImGui::SetNextWindowSizeConstraints(ImVec2(400, -1), ImVec2(500, -1)); // Width 400-500 + if (type == 4) ImGui::SetNextWindowSizeConstraints(ImVec2(-1, 400), ImVec2(-1, 500)); // Height 400-500 + if (type == 5) ImGui::SetNextWindowSizeConstraints(ImVec2(0, 0), ImVec2(FLT_MAX, FLT_MAX), CustomConstraints::Square); // Always Square + if (type == 6) ImGui::SetNextWindowSizeConstraints(ImVec2(0, 0), ImVec2(FLT_MAX, FLT_MAX), CustomConstraints::Step, (void*)100);// Fixed Step - if (ImGui::Begin("Example: Constrained Resize", p_open)) + ImGuiWindowFlags flags = auto_resize ? ImGuiWindowFlags_AlwaysAutoResize : 0; + if (ImGui::Begin("Example: Constrained Resize", p_open, flags)) { const char* desc[] = { "Resize vertical only", "Resize horizontal only", "Width > 100, Height > 100", - "Width 300-400", + "Width 400-500", + "Height 400-500", "Custom: Always Square", "Custom: Fixed Steps (100)", }; - ImGui::Combo("Constraint", &type, desc, IM_ARRAYSIZE(desc)); - if (ImGui::Button("200x200")) { ImGui::SetWindowSize(ImVec2(200,200)); } ImGui::SameLine(); - if (ImGui::Button("500x500")) { ImGui::SetWindowSize(ImVec2(500,500)); } ImGui::SameLine(); - if (ImGui::Button("800x200")) { ImGui::SetWindowSize(ImVec2(800,200)); } - for (int i = 0; i < 10; i++) - ImGui::Text("Hello, sailor! Making this line long enough for the example."); + if (ImGui::Button("200x200")) { ImGui::SetWindowSize(ImVec2(200, 200)); } ImGui::SameLine(); + if (ImGui::Button("500x500")) { ImGui::SetWindowSize(ImVec2(500, 500)); } ImGui::SameLine(); + if (ImGui::Button("800x200")) { ImGui::SetWindowSize(ImVec2(800, 200)); } + ImGui::PushItemWidth(200); + ImGui::Combo("Constraint", &type, desc, IM_ARRAYSIZE(desc)); + ImGui::DragInt("Lines", &display_lines, 0.2f, 1, 100); + ImGui::PopItemWidth(); + ImGui::Checkbox("Auto-resize", &auto_resize); + for (int i = 0; i < display_lines; i++) + ImGui::Text("%*sHello, sailor! Making this line long enough for the example.", i * 4, ""); } ImGui::End(); } From 571b08f31528cf13fe6c8885a8dc13c174aeced3 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 7 Nov 2017 13:59:55 +0100 Subject: [PATCH 537/921] Internal: FindWindowByName() faster and doesn't touch every windows --- imgui.cpp | 10 +++------- imgui_internal.h | 1 + 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index d762910ad..ce03aafb0 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3920,13 +3920,9 @@ static ImVec2 FindBestPopupWindowPos(const ImVec2& base_pos, const ImVec2& size, ImGuiWindow* ImGui::FindWindowByName(const char* name) { - // FIXME-OPT: Store sorted hashes -> pointers so we can do a bissection in a contiguous block ImGuiContext& g = *GImGui; ImGuiID id = ImHash(name, 0); - for (int i = 0; i < g.Windows.Size; i++) - if (g.Windows[i]->ID == id) - return g.Windows[i]; - return NULL; + return (ImGuiWindow*)g.WindowsById.GetVoidPtr(id); } static ImGuiWindow* CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFlags flags) @@ -3937,6 +3933,7 @@ static ImGuiWindow* CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFl ImGuiWindow* window = (ImGuiWindow*)ImGui::MemAlloc(sizeof(ImGuiWindow)); IM_PLACEMENT_NEW(window) ImGuiWindow(name); window->Flags = flags; + g.WindowsById.SetVoidPtr(window->ID, window); if (flags & ImGuiWindowFlags_NoSavedSettings) { @@ -5280,8 +5277,7 @@ bool ImGui::IsWindowAppearing() void ImGui::SetWindowCollapsed(const char* name, bool collapsed, ImGuiCond cond) { - ImGuiWindow* window = FindWindowByName(name); - if (window) + if (ImGuiWindow* window = FindWindowByName(name)) SetWindowCollapsed(window, collapsed, cond); } diff --git a/imgui_internal.h b/imgui_internal.h index ccfc3bf47..9781f8225 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -422,6 +422,7 @@ struct ImGuiContext ImVector Windows; ImVector WindowsSortBuffer; ImVector CurrentWindowStack; + ImGuiStorage WindowsById; ImGuiWindow* CurrentWindow; // Being drawn into ImGuiWindow* NavWindow; // Nav/focused window for navigation ImGuiWindow* HoveredWindow; // Will catch mouse inputs From 1870738880246c18c150d19dbac8a35426688997 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 7 Nov 2017 14:05:48 +0100 Subject: [PATCH 538/921] LowerBound() minor tweaks --- imgui.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index ce03aafb0..69ee04d9b 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1385,10 +1385,10 @@ static ImVector::iterator LowerBound(ImVector::iterator first = data.begin(); ImVector::iterator last = data.end(); - int count = (int)(last - first); + size_t count = (size_t)(last - first); while (count > 0) { - int count2 = count / 2; + size_t count2 = count >> 1; ImVector::iterator mid = first + count2; if (mid->key < key) { From aae52522c3d6ebd35dedb0f62e8e23cdc5768c1d Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 7 Nov 2017 13:11:45 +0100 Subject: [PATCH 539/921] Internals: Remove requirement to define IMGUI_DEFINE_PLACEMENT_NEW (#1103) --- imgui_internal.h | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/imgui_internal.h b/imgui_internal.h index 9781f8225..a5d877229 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -2,10 +2,9 @@ // (internals) // You may use this file to debug, understand or extend ImGui features but we don't provide any guarantee of forward compatibility! -// Implement maths operators for ImVec2 (disabled by default to not collide with using IM_VEC2_CLASS_EXTRA along with your own math types+operators) +// Set: // #define IMGUI_DEFINE_MATH_OPERATORS -// Define IM_PLACEMENT_NEW() macro helper. -// #define IMGUI_DEFINE_PLACEMENT_NEW +// To implement maths operators for ImVec2 (disabled by default to not collide with using IM_VEC2_CLASS_EXTRA along with your own math types+operators) #pragma once @@ -159,12 +158,10 @@ static inline float ImLinearSweep(float current, float target, float speed) // We call C++ constructor on own allocated memory via the placement "new(ptr) Type()" syntax. // Defining a custom placement new() with a dummy parameter allows us to bypass including which on some platforms complains when user has disabled exceptions. -#ifdef IMGUI_DEFINE_PLACEMENT_NEW struct ImPlacementNewDummy {}; inline void* operator new(size_t, ImPlacementNewDummy, void* ptr) { return ptr; } inline void operator delete(void*, ImPlacementNewDummy, void*) {} #define IM_PLACEMENT_NEW(_PTR) new(ImPlacementNewDummy(), _PTR) -#endif //----------------------------------------------------------------------------- // Types From 41862b8c0e9f651a253de45c2b7e982c19c9ea9d Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 7 Nov 2017 16:41:58 +0100 Subject: [PATCH 540/921] ButtonBehavior: Fixed ImGuiButtonFlags_NoHoldingActiveID from incorrectly setting ActiveIdClickOffset, which probably have no known effect, but it is more correct this way. (#1418) --- imgui.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 69ee04d9b..ba212d73a 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -5835,11 +5835,15 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool { pressed = true; if (flags & ImGuiButtonFlags_NoHoldingActiveID) + { ClearActiveID(); + } else + { SetActiveID(id, window); // Hold on ID + g.ActiveIdClickOffset = g.IO.MousePos - bb.Min; + } FocusWindow(window); - g.ActiveIdClickOffset = g.IO.MousePos - bb.Min; } if ((flags & ImGuiButtonFlags_PressedOnRelease) && g.IO.MouseReleased[0]) { From 2ab27be3de2cb794f3be360f5031371460420527 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 7 Nov 2017 22:23:02 +0100 Subject: [PATCH 541/921] Child window with MenuBar use regular WindowPadding.y so layout look consistent in child or in a regular window. --- imgui.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index ba212d73a..d9ccc4337 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4251,7 +4251,9 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) } // Lock window padding so that altering the ShowBorders flag for children doesn't have side-effects. - window->WindowPadding = ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & (ImGuiWindowFlags_AlwaysUseWindowPadding | ImGuiWindowFlags_ShowBorders | ImGuiWindowFlags_ComboBox | ImGuiWindowFlags_Popup))) ? ImVec2(0,0) : style.WindowPadding; + window->WindowPadding = style.WindowPadding; + if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & (ImGuiWindowFlags_AlwaysUseWindowPadding | ImGuiWindowFlags_ShowBorders | ImGuiWindowFlags_ComboBox | ImGuiWindowFlags_Popup))) + window->WindowPadding = ImVec2(0.0f, (flags & ImGuiWindowFlags_MenuBar) ? style.WindowPadding.y : 0.0f); // Calculate auto-fit size, handle automatic resize const ImVec2 size_auto_fit = CalcSizeAutoFit(window); From b6504b8eee930cca4a98d36603273c407a69c135 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 8 Nov 2017 15:47:52 +0100 Subject: [PATCH 542/921] Drag and drop: Handle overlapping drag target priorities given their surface, which appears to make most sense for drag and drop operations. --- imgui.cpp | 14 ++++++++++++-- imgui_internal.h | 1 + 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 999b373f3..a5e9d37ac 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2259,6 +2259,7 @@ void ImGui::NewFrame() } g.DragDropAcceptIdPrev = g.DragDropAcceptIdCurr; g.DragDropAcceptIdCurr = 0; + g.DragDropAcceptIdCurrRectSurface = FLT_MAX; // Update keyboard input state memcpy(g.IO.KeysDownDurationPrev, g.IO.KeysDownDuration, sizeof(g.IO.KeysDownDuration)); @@ -10637,6 +10638,7 @@ static void ImGui::ClearDragDrop() g.DragDropActive = false; g.DragDropPayload.Clear(); g.DragDropAcceptIdCurr = g.DragDropAcceptIdPrev = 0; + g.DragDropAcceptIdCurrRectSurface = FLT_MAX; g.DragDropAcceptFrameCount = -1; } @@ -10800,14 +10802,22 @@ const ImGuiPayload* ImGui::AcceptDragDropPayload(const char* type, ImGuiDragDrop if (type != NULL && !payload.IsDataType(type)) return NULL; - // NB: We currently accept NULL id however, overlapping targets required unique ID to function + // NB: We currently accept NULL id as target. However, overlapping targets requires a unique ID to function! const bool was_accepted_previously = (g.DragDropAcceptIdPrev == window->DC.LastItemId); g.DragDropAcceptIdCurr = window->DC.LastItemId; + // Accept smallest drag target bounding box, this allows us to nest drag targets conveniently without ordering constraints. + ImRect r = window->DC.LastItemRect; + float r_surface = r.GetWidth() * r.GetHeight(); + if (r_surface < g.DragDropAcceptIdCurrRectSurface) + { + g.DragDropAcceptIdCurr = window->DC.LastItemId; + g.DragDropAcceptIdCurrRectSurface = r_surface; + } + // Render drop visuals if (!(flags & ImGuiDragDropFlags_AcceptNoDrawDefaultRect) && was_accepted_previously) { - ImRect r = window->DC.LastItemRect; r.Expand(4.0f); window->DrawList->AddRectFilled(r.Min, r.Max, IM_COL32(255, 255, 0, 20), 0.0f); // FIXME-DRAG FIXME-STYLE window->DrawList->AddRect(r.Min, r.Max, IM_COL32(255, 255, 0, 255), 0.0f, ~0, 2.0f); // FIXME-DRAG FIXME-STYLE diff --git a/imgui_internal.h b/imgui_internal.h index 5c3b24c8a..c93faf7f6 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -480,6 +480,7 @@ struct ImGuiContext ImGuiDragDropFlags DragDropSourceFlags; int DragDropMouseButton; ImGuiPayload DragDropPayload; + float DragDropAcceptIdCurrRectSurface; ImGuiID DragDropAcceptIdCurr; // Target item id (set at the time of accepting the payload) ImGuiID DragDropAcceptIdPrev; // Target item id from previous frame (we need to store this to allow for overlapping drag and drop targets) int DragDropAcceptFrameCount; // Last time a target expressed a desire to accept the source From 9ac8820ee2ad3b569b592519a50b6dad4607eb04 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 8 Nov 2017 22:32:22 +0100 Subject: [PATCH 543/921] Fixed non-pixel aligned bounding box of window resize grip, / which triumphally led to any re-arrangement of operations inside the resize grip code outputting non-exact size_target values which led to unstable window position because clamping code uses size in a subtraction, etc etc. Lovely how a whole system can be made to act weird with a single bad input. --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index d9ccc4337..0ded20c05 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4386,7 +4386,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // Manual resize // Using the FlattenChilds button flag, we make the resize button accessible even if we are hovering over a child window const ImVec2 br = window->Rect().GetBR(); - const ImRect resize_rect(br - ImVec2(resize_corner_size * 0.75f, resize_corner_size * 0.75f), br); + const ImRect resize_rect(br - ImFloor(ImVec2(resize_corner_size * 0.75f, resize_corner_size * 0.75f)), br); const ImGuiID resize_id = window->GetID("#RESIZE"); bool hovered, held; ButtonBehavior(resize_rect, resize_id, &hovered, &held, ImGuiButtonFlags_FlattenChilds); From a4cc3d4637f7aa3aac7c730c6d21370c8737a76f Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 8 Nov 2017 22:36:31 +0100 Subject: [PATCH 544/921] Minor tweaks/comments. Note that the reordering the one subtraction caused subtle havoc before the patch in 9ac8820ee2ad3b569b592519a50b6dad4607eb04. --- imgui.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 0ded20c05..d64ac6d3d 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4404,7 +4404,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) else if (held) { // We don't use an incremental MouseDelta but rather compute an absolute target size based on mouse position - size_target = (g.IO.MousePos - g.ActiveIdClickOffset + resize_rect.GetSize()) - window->Pos; + size_target = (g.IO.MousePos - g.ActiveIdClickOffset - window->Pos) + resize_rect.GetSize(); } if (size_target.x != FLT_MAX && size_target.y != FLT_MAX) @@ -10456,8 +10456,8 @@ void ImGui::EndColumns() { float x = window->Pos.x + GetColumnOffset(i); const ImGuiID column_id = window->DC.ColumnsSetId + ImGuiID(i); - const float column_w = 4.0f; // Width for interaction - const ImRect column_rect(ImVec2(x - column_w, y1), ImVec2(x + column_w, y2)); + const float column_hw = 4.0f; // Half-width for interaction + const ImRect column_rect(ImVec2(x - column_hw, y1), ImVec2(x + column_hw, y2)); if (IsClippedEx(column_rect, column_id, false)) continue; @@ -10468,7 +10468,7 @@ void ImGui::EndColumns() if (hovered || held) g.MouseCursor = ImGuiMouseCursor_ResizeEW; if (held && g.ActiveIdIsJustActivated) - g.ActiveIdClickOffset.x -= column_w; // Store from center of column line (we used a 8 wide rect for columns clicking). This is used by GetDraggedColumnOffset(). + g.ActiveIdClickOffset.x -= column_hw; // Store from center of column line (we used a 8 wide rect for columns clicking). This is used by GetDraggedColumnOffset(). if (held) dragging_column = i; } From 2df8fa95dfe3463ece78c56b02dc815c3e71331a Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 8 Nov 2017 23:17:08 +0100 Subject: [PATCH 545/921] Fixed vertical scrollbar flickering/appearing, typically when manually resizing and using a pattern of filling available height (e.g. full sized BeginChild). THIS IS A GREAT FIX, this glitch was nasty and annoying (and yet somehow nobody reported it?). Hopefully haven't broken anything else... --- imgui.cpp | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index d64ac6d3d..35e30968b 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4232,10 +4232,21 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // SIZE - // Save contents size from last frame for auto-fitting (unless explicitly specified) + // Update contents size from last frame for auto-fitting (unless explicitly specified) window->SizeContents.x = (float)(int)((window->SizeContentsExplicit.x != 0.0f) ? window->SizeContentsExplicit.x : ((window_is_new ? 0.0f : window->DC.CursorMaxPos.x - window->Pos.x) + window->Scroll.x)); window->SizeContents.y = (float)(int)((window->SizeContentsExplicit.y != 0.0f) ? window->SizeContentsExplicit.y : ((window_is_new ? 0.0f : window->DC.CursorMaxPos.y - window->Pos.y) + window->Scroll.y)); + // Update scrollbar status based on the Size that was effective during last frame (and not the upcoming Size which we are updating below), so that user code consuming exactly the available size won't trigger scrollbars when e.g. manually resizing. + if (!window->Collapsed) + { + window->ScrollbarY = (flags & ImGuiWindowFlags_AlwaysVerticalScrollbar) || ((window->SizeContents.y > window->Size.y + style.ItemSpacing.y) && !(flags & ImGuiWindowFlags_NoScrollbar)); + window->ScrollbarX = (flags & ImGuiWindowFlags_AlwaysHorizontalScrollbar) || ((window->SizeContents.x > window->Size.x - (window->ScrollbarY ? style.ScrollbarSize : 0.0f) - window->WindowPadding.x) && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar)); + if (window->ScrollbarX && !window->ScrollbarY) + window->ScrollbarY = (window->SizeContents.y > window->Size.y + style.ItemSpacing.y - style.ScrollbarSize) && !(flags & ImGuiWindowFlags_NoScrollbar); + window->ScrollbarSizes = ImVec2(window->ScrollbarY ? style.ScrollbarSize : 0.0f, window->ScrollbarX ? style.ScrollbarSize : 0.0f); + window->BorderSize = (flags & ImGuiWindowFlags_ShowBorders) ? 1.0f : 0.0f; + } + // Hide popup/tooltip window when first appearing while we measure size (because we recycle them) if (window->HiddenFrames > 0) window->HiddenFrames--; @@ -4416,14 +4427,6 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) title_bar_rect = window->TitleBarRect(); } - // Scrollbars - window->ScrollbarY = (flags & ImGuiWindowFlags_AlwaysVerticalScrollbar) || ((window->SizeContents.y > window->Size.y + style.ItemSpacing.y) && !(flags & ImGuiWindowFlags_NoScrollbar)); - window->ScrollbarX = (flags & ImGuiWindowFlags_AlwaysHorizontalScrollbar) || ((window->SizeContents.x > window->Size.x - (window->ScrollbarY ? style.ScrollbarSize : 0.0f) - window->WindowPadding.x) && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar)); - if (window->ScrollbarX && !window->ScrollbarY) - window->ScrollbarY = (window->SizeContents.y > window->Size.y + style.ItemSpacing.y - style.ScrollbarSize) && !(flags & ImGuiWindowFlags_NoScrollbar); - window->ScrollbarSizes = ImVec2(window->ScrollbarY ? style.ScrollbarSize : 0.0f, window->ScrollbarX ? style.ScrollbarSize : 0.0f); - window->BorderSize = (flags & ImGuiWindowFlags_ShowBorders) ? 1.0f : 0.0f; - // Window background, Default Alpha ImU32 bg_col = GetColorU32(GetWindowBgColorIdxFromFlags(flags)); window->DrawList->AddRectFilled(window->Pos+ImVec2(0,window->TitleBarHeight()), window->Pos+window->Size, bg_col, window_rounding, (flags & ImGuiWindowFlags_NoTitleBar) ? ImGuiCorner_All : ImGuiCorner_BotLeft|ImGuiCorner_BotRight); From b1653cd361aa2acd632877829c6d55a859e39d20 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 9 Nov 2017 20:09:09 +0100 Subject: [PATCH 546/921] Drag and Drop: Allow NULL payload (since type only can be useful). (#143) --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index a5e9d37ac..2ead2edf2 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -10742,7 +10742,7 @@ bool ImGui::SetDragDropPayload(const char* type, const void* data, size_t data_s IM_ASSERT(type != NULL); IM_ASSERT(strlen(type) < IM_ARRAYSIZE(payload.DataType)); // Payload type can be at most 8 characters longs - IM_ASSERT(data != NULL && data_size > 0); + IM_ASSERT((data != NULL && data_size > 0) || (data == NULL && data_size == 0)); IM_ASSERT(cond == ImGuiCond_Always || cond == ImGuiCond_Once); IM_ASSERT(payload.SourceId != 0); // Not called between BeginDragDropSource() and EndDragDropSource() From 4b94738c7e64a7a912a72b373063b42a407ec1bd Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 9 Nov 2017 20:17:10 +0100 Subject: [PATCH 547/921] Drag and Drop: Drop target rectangle goes out of clipping range (#143) --- imgui.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 2ead2edf2..cdb025421 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -10818,9 +10818,13 @@ const ImGuiPayload* ImGui::AcceptDragDropPayload(const char* type, ImGuiDragDrop // Render drop visuals if (!(flags & ImGuiDragDropFlags_AcceptNoDrawDefaultRect) && was_accepted_previously) { - r.Expand(4.0f); - window->DrawList->AddRectFilled(r.Min, r.Max, IM_COL32(255, 255, 0, 20), 0.0f); // FIXME-DRAG FIXME-STYLE - window->DrawList->AddRect(r.Min, r.Max, IM_COL32(255, 255, 0, 255), 0.0f, ~0, 2.0f); // FIXME-DRAG FIXME-STYLE + // FIXME-DRAG FIXME-STYLE: Settle on a proper default visuals for drop target, w/ ImGuiCol enum value probably. + r.Expand(5.0f); + bool push_clip_rect = !window->ClipRect.Contains(r); + if (push_clip_rect) window->DrawList->PushClipRectFullScreen(); + window->DrawList->AddRectFilled(r.Min, r.Max, IM_COL32(255, 255, 0, 20), 0.0f); + window->DrawList->AddRect(r.Min + ImVec2(1.5f,1.5f), r.Max - ImVec2(1.5f,1.5f), IM_COL32(255, 255, 0, 255), 0.0f, ~0, 2.0f); + if (push_clip_rect) window->DrawList->PopClipRect(); } g.DragDropAcceptFrameCount = g.FrameCount; payload.Delivery = was_accepted_previously && IsMouseReleased(g.DragDropMouseButton); From 8451855a3075b14b653a561c37a7ba3eb80431a9 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 9 Nov 2017 20:08:29 +0100 Subject: [PATCH 548/921] ButtonBehavior: Fixed ImGuiButtonFlags_AllowOverlapMode to avoid temporarily activating widgets on click before they have been correctly double-hovered. (#319, #600) --- imgui.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 35e30968b..17f42f2a0 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -5821,6 +5821,10 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool if ((flags & ImGuiButtonFlags_FlattenChilds) && g.HoveredRootWindow == window) g.HoveredWindow = backup_hovered_window; + // AllowOverlap mode (rarely used) requires previous frame HoveredId to be null or to match. This allows using patterns where a later submitted widget overlaps a previous one. + if (hovered && (flags & ImGuiButtonFlags_AllowOverlapMode) && (g.HoveredIdPreviousFrame != id && g.HoveredIdPreviousFrame != 0)) + hovered = false; + if (hovered) { if (!(flags & ImGuiButtonFlags_NoKeyModifiers) || (!g.IO.KeyCtrl && !g.IO.KeyShift && !g.IO.KeyAlt)) @@ -5880,10 +5884,6 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool } } - // AllowOverlap mode (rarely used) requires previous frame HoveredId to be null or to match. This allows using patterns where a later submitted widget overlaps a previous one. - if (hovered && (flags & ImGuiButtonFlags_AllowOverlapMode) && (g.HoveredIdPreviousFrame != id && g.HoveredIdPreviousFrame != 0)) - hovered = pressed = held = false; - if (out_hovered) *out_hovered = hovered; if (out_held) *out_held = held; From ba09de3a392fa3a0395aa3aa1101f1b90121cc0d Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 10 Nov 2017 11:37:27 +0100 Subject: [PATCH 549/921] Begin: Fixed appending into a child window with a second Begin() from a different window stack querying the wrong window for the window->Collapsed test. --- imgui.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 17f42f2a0..dc501d46b 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4106,12 +4106,14 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) else flags = window->Flags; + // Parent window is latched only on the first call to Begin() of the frame, so further append-calls can be done from a different window stack + ImGuiWindow* parent_window = first_begin_of_the_frame ? (!g.CurrentWindowStack.empty() ? g.CurrentWindowStack.back() : NULL) : window->ParentWindow; + IM_ASSERT(parent_window != NULL || !(flags & ImGuiWindowFlags_ChildWindow)); + // Add to stack - ImGuiWindow* parent_window = !g.CurrentWindowStack.empty() ? g.CurrentWindowStack.back() : NULL; g.CurrentWindowStack.push_back(window); SetCurrentWindow(window); CheckStacksSize(window, true); - IM_ASSERT(parent_window != NULL || !(flags & ImGuiWindowFlags_ChildWindow)); bool window_just_activated_by_user = (window->LastFrameActive < current_frame - 1); // Not using !WasActive because the implicit "Debug" window would always toggle off->on if (flags & ImGuiWindowFlags_Popup) From 9daac64ff810d5237e1256c9192a66b8aac06cef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Branimir=20Karad=C5=BEi=C4=87?= Date: Fri, 10 Nov 2017 22:59:06 -0800 Subject: [PATCH 550/921] Clean g.WindowsById storage on shutdown. --- imgui.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/imgui.cpp b/imgui.cpp index dc501d46b..2a5195fe9 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2462,6 +2462,7 @@ void ImGui::Shutdown() g.WindowsSortBuffer.clear(); g.CurrentWindow = NULL; g.CurrentWindowStack.clear(); + g.WindowsById.Clear(); g.NavWindow = NULL; g.HoveredWindow = NULL; g.HoveredRootWindow = NULL; From 161670418b00aef7207027cac208dc12eb45ff28 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 11 Nov 2017 16:20:34 +0100 Subject: [PATCH 551/921] Update documentation for extra fonts --- extra_fonts/README.txt | 51 ++++++++++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 19 deletions(-) diff --git a/extra_fonts/README.txt b/extra_fonts/README.txt index 77fdaa6c0..a41360831 100644 --- a/extra_fonts/README.txt +++ b/extra_fonts/README.txt @@ -1,6 +1,8 @@ - The code in imgui.cpp embeds a copy of 'ProggyClean.ttf' that you can use without any external files. - The files in this folder are only provided as a convenience, you can use any .TTF/.OTF. + The code in imgui.cpp embeds a copy of 'ProggyClean.ttf' (by Tristan Grimmer) that is used by default. + We embed the font in source code so you can use Dear ImGui without any file system access. + You may also load external .TTF/.OTF files. + The files in this folder are suggested fonts, provided as a convenience. (Note: .OTF support in stb_truetype.h currently doesn't appear to load every font) Fonts are rasterized in a single texture at the time of calling either of io.Fonts.GetTexDataAsAlpha8()/GetTexDataAsRGBA32()/Build(). @@ -12,6 +14,7 @@ Using an icon font (such as FontAwesome: http://fontawesome.io) is an easy and practical way to use icons in your ImGui application. A common pattern is to merge the icon font within your main font, so you can refer to the icons directly from your strings without having to change fonts back and forth. To refer to the icon from your C++ code, you can use headers files created by Juliette Foucaut, at https://github.com/juliettef/IconFontCppHeaders + See Links below for other icons fonts and related tools. // Merge icons into default tool font #include "IconsFontAwesome.h" @@ -40,7 +43,7 @@ ImGuiIO& io = ImGui::GetIO(); io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels); - Detailed options: + Advanced options: ImFontConfig config; config.OversampleH = 3; @@ -106,17 +109,23 @@ REMAPPING CODEPOINTS --------------------------------- - All your strings needs to use UTF-8 encoding. Specifying literal in your source code using a local code page (such as CP-923 for Japanese CP-1251 for Cyrillic) will NOT work! + All your strings needs to use UTF-8 encoding. Specifying literal in your source code using a local code page (such as CP-923 for Japanese, or CP-1251 for Cyrillic) will NOT work! In C++11 you can encode a string literal in UTF-8 by using the u8"hello" syntax. Otherwise you can convert yourself to UTF-8 or load text data from file already saved as UTF-8. - You can also try to remap your local codepage characters to their Unicode codepoint using font->AddRemapChar(), but international users may have problems reading/editing your source code. + e.g. + u8"hello" + u8"こんにちは" + You may also try to remap your local codepage characters to their Unicode codepoint using font->AddRemapChar(), but international users may have problems reading/editing your source code. --------------------------------- EMBEDDING FONT IN SOURCE CODE --------------------------------- - Compile and use 'binary_to_compressed_c.cpp' to create a compressed C style array. + Compile and use 'binary_to_compressed_c.cpp' to create a compressed C style array that you can embed in source code. See the documentation in binary_to_compressed_c.cpp for instruction on how to use the tool. + You may find a precompiled version binary_to_compressed_c.exe for Windows instead of demo binaries package (see README). + The tool optionally used Base85 encoding to reduce the size of _source code_ but the read-only arrays will be about 20% bigger. + Then load the font with: ImFont* font = io.Fonts->AddFontFromMemoryCompressedTTF(compressed_data, compressed_data_size, size_pixels, ...); @@ -164,36 +173,40 @@ --------------------------------- - LINKS + LINKS & OTHER FONTS --------------------------------- - Icon fonts + (Icons) Icon fonts https://fortawesome.github.io/Font-Awesome/ https://github.com/SamBrishes/kenney-icon-font https://design.google.com/icons/ + You can use https://github.com/juliettef/IconFontCppHeaders for C/C++ header files with name #define to access icon codepoint in source code. - IcoMoon - Custom Icon font builder + (Icons) IcoMoon - Custom Icon font builder https://icomoon.io/app - Typefaces for source code beautification - https://github.com/chrissimpkins/codeface + (Regular) Open Sans Fonts + https://fonts.google.com/specimen/Open+Sans + + (Regular) Google Noto Fonts (worldwide languages) + https://www.google.com/get/noto/ - Programmation fonts + (Monospace) Typefaces for source code beautification + https://github.com/chrissimpkins/codeface + + (Monospace) Programmation fonts http://s9w.github.io/font_compare/ - Proggy Programming Fonts + (Monospace) Proggy Programming Fonts http://upperbounds.net - Inconsolata + (Monospace) Inconsolata http://www.levien.com/type/myfonts/inconsolata.html - Google Noto Fonts (worldwide languages) - https://www.google.com/get/noto/ - - Adobe Source Code Pro: Monospaced font family for user interface and coding environments + (Monospace) Adobe Source Code Pro: Monospaced font family for user interface and coding environments https://github.com/adobe-fonts/source-code-pro - Monospace/Fixed Width Programmer's Fonts + (Monospace) Monospace/Fixed Width Programmer's Fonts http://www.lowing.org/fonts/ (Japanese) M+ fonts by Coji Morishita are free and include most useful Kanjis you would need. From 631bd8a9f8492778ddd10f4ed23f036c377f71fd Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 11 Nov 2017 18:12:33 +0100 Subject: [PATCH 552/921] Added bindings --- README.md | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 306a8e542..f5da3b358 100644 --- a/README.md +++ b/README.md @@ -55,15 +55,17 @@ Integrating Dear ImGui within your custom engine is a matter of wiring mouse/key _NB: those third-party bindings may be more or less maintained, more or less close to the spirit of original API and therefore I cannot give much guarantee about them. People who create language bindings sometimes haven't used the C++ API themselves (for the good reason that they aren't C++ users). Dear ImGui was designed with C++ in mind and some of the subtleties may be lost in translation with other languages. If your language supports it, I would suggest replicating the function overloading and default parameters used in the original, else the API may be harder to use. In doubt, please check the original C++ version first!_ Languages: -- C (cimgui): thin c-api wrapper for ImGui https://github.com/Extrawurst/cimgui -- C#/.Net (ImGui.NET): An ImGui wrapper for .NET Core https://github.com/mellinoe/ImGui.NET -- D (DerelictImgui): Dynamic bindings for the D programming language: https://github.com/Extrawurst/DerelictImgui +- C (cimgui): https://github.com/Extrawurst/cimgui +- C#/.Net (ImGui.NET): https://github.com/mellinoe/ImGui.NET +- ChaiScript: https://github.com/JuJuBoSc/imgui-chaiscript +- D (DerelictImgui): https://github.com/Extrawurst/DerelictImgui - Go (go-imgui): https://github.com/Armored-Dragon/go-imgui - Lua: https://github.com/patrickriordan/imgui_lua_bindings -- Pascal (imgui-pas) https://github.com/dpethes/imgui-pas -- Python (CyImGui): Python bindings for dear imgui using Cython: https://github.com/chromy/cyimgui -- Python (pyimgui): Another Python bindings for dear imgui: https://github.com/swistakm/pyimgui -- Rust (imgui-rs): Rust bindings for dear imgui https://github.com/Gekkio/imgui-rs +- Odin: https://github.com/ThisDrunkDane/odin-dear_imgui +- Pascal (imgui-pas): https://github.com/dpethes/imgui-pas +- Python (CyImGui): https://github.com/chromy/cyimgui +- Python (pyimgui): https://github.com/swistakm/pyimgui +- Rust (imgui-rs): https://github.com/Gekkio/imgui-rs Frameworks: - Main ImGui repository include examples for DirectX9, DirectX10, DirectX11, OpenGL2/3, Vulkan, Allegro 5, SDL+GL2/3, iOS and Marmalade: https://github.com/ocornut/imgui/tree/master/examples @@ -78,6 +80,7 @@ Frameworks: - Irrlicht (IrrIMGUI): https://github.com/ZahlGraf/IrrIMGUI - Ogre: https://bitbucket.org/LMCrashy/ogreimgui/src - openFrameworks (ofxImGui): https://github.com/jvcleave/ofxImGui +- OpenSceneGraph/OSG: https://gist.github.com/fulezi/d2442ca7626bf270226014501357042c - LÖVE: https://github.com/slages/love-imgui - NanoRT (software raytraced) https://github.com/syoyo/imgui/tree/nanort/examples/raytrace_example - Qt3d https://github.com/alpqr/imgui-qt3d From a1c736fa6aec984c5b2b6421b196a82a38e20851 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 11 Nov 2017 18:22:00 +0100 Subject: [PATCH 553/921] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index f5da3b358..d44ec5769 100644 --- a/README.md +++ b/README.md @@ -129,6 +129,8 @@ The Immediate Mode GUI paradigm may at first appear unusual to some users. This - [Nicolas Guillemot's CppCon'16 flashtalk about Dear ImGui](https://www.youtube.com/watch?v=LSRJ1jZq90k). - [Thierry Excoffier's Zero Memory Widget](http://perso.univ-lyon1.fr/thierry.excoffier/ZMW/). +See the [Software using dear imgui page](https://github.com/ocornut/imgui/wiki/Software-using-dear-imgui) for an incomplete list of software which are publicly known to use dear migui. + See the [Links page](https://github.com/ocornut/imgui/wiki/Links) for third-party bindings to different languages and frameworks. Frequently Asked Question (FAQ) From 669498ff26040636a27ea44a7129a223c9701601 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 12 Nov 2017 16:03:09 +0100 Subject: [PATCH 554/921] Added io.OptNoCursorBlink option to disable cursor blinking. (#1427). Renamed io.OSXBehaviors to io.OptMacOSXBehaviors. Should affect users as the compile-time default is usually enough. (#473, #650) --- imgui.cpp | 27 +++++++++++++++------------ imgui.h | 3 ++- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 2a5195fe9..1f9100c02 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -774,7 +774,15 @@ ImGuiIO::ImGuiIO() DisplayFramebufferScale = ImVec2(1.0f, 1.0f); DisplayVisibleMin = DisplayVisibleMax = ImVec2(0.0f, 0.0f); - // User functions + // Advanced/subtle behaviors +#ifdef __APPLE__ + OptMacOSXBehaviors = true; // Set Mac OS X style defaults based on __APPLE__ compile time flag +#else + OptMacOSXBehaviors = false; +#endif + OptNoCursorBlink = false; + + // Settings (User Functions) RenderDrawListsFn = NULL; MemAllocFn = malloc; MemFreeFn = free; @@ -790,11 +798,6 @@ ImGuiIO::ImGuiIO() MouseDragThreshold = 6.0f; for (int i = 0; i < IM_ARRAYSIZE(MouseDownDuration); i++) MouseDownDuration[i] = MouseDownDurationPrev[i] = -1.0f; for (int i = 0; i < IM_ARRAYSIZE(KeysDownDuration); i++) KeysDownDuration[i] = KeysDownDurationPrev[i] = -1.0f; - - // Set OS X style defaults based on __APPLE__ compile time flag -#ifdef __APPLE__ - OSXBehaviors = true; -#endif } // Pass in translated ASCII characters for text input. @@ -8099,7 +8102,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 const float mouse_x = (io.MousePos.x - frame_bb.Min.x - style.FramePadding.x) + edit_state.ScrollX; const float mouse_y = (is_multiline ? (io.MousePos.y - draw_window->DC.CursorPos.y - style.FramePadding.y) : (g.FontSize*0.5f)); - const bool osx_double_click_selects_words = io.OSXBehaviors; // OS X style: Double click selects by word instead of selecting whole text + const bool osx_double_click_selects_words = io.OptMacOSXBehaviors; // OS X style: Double click selects by word instead of selecting whole text if (select_all || (hovered && !osx_double_click_selects_words && io.MouseDoubleClicked[0])) { edit_state.SelectAll(); @@ -8151,9 +8154,9 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 { // Handle key-presses const int k_mask = (io.KeyShift ? STB_TEXTEDIT_K_SHIFT : 0); - const bool is_shortcut_key_only = (io.OSXBehaviors ? (io.KeySuper && !io.KeyCtrl) : (io.KeyCtrl && !io.KeySuper)) && !io.KeyAlt && !io.KeyShift; // OS X style: Shortcuts using Cmd/Super instead of Ctrl - const bool is_wordmove_key_down = io.OSXBehaviors ? io.KeyAlt : io.KeyCtrl; // OS X style: Text editing cursor movement using Alt instead of Ctrl - const bool is_startend_key_down = io.OSXBehaviors && io.KeySuper && !io.KeyCtrl && !io.KeyAlt; // OS X style: Line/Text Start and End using Cmd+Arrows instead of Home/End + const bool is_shortcut_key_only = (io.OptMacOSXBehaviors ? (io.KeySuper && !io.KeyCtrl) : (io.KeyCtrl && !io.KeySuper)) && !io.KeyAlt && !io.KeyShift; // OS X style: Shortcuts using Cmd/Super instead of Ctrl + const bool is_wordmove_key_down = io.OptMacOSXBehaviors ? io.KeyAlt : io.KeyCtrl; // OS X style: Text editing cursor movement using Alt instead of Ctrl + const bool is_startend_key_down = io.OptMacOSXBehaviors && io.KeySuper && !io.KeyCtrl && !io.KeyAlt; // OS X style: Line/Text Start and End using Cmd+Arrows instead of Home/End if (IsKeyPressedMap(ImGuiKey_LeftArrow)) { edit_state.OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_LINESTART : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDLEFT : STB_TEXTEDIT_K_LEFT) | k_mask); } else if (IsKeyPressedMap(ImGuiKey_RightArrow)) { edit_state.OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_LINEEND : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDRIGHT : STB_TEXTEDIT_K_RIGHT) | k_mask); } @@ -8167,7 +8170,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 if (!edit_state.HasSelection()) { if (is_wordmove_key_down) edit_state.OnKeyPressed(STB_TEXTEDIT_K_WORDLEFT|STB_TEXTEDIT_K_SHIFT); - else if (io.OSXBehaviors && io.KeySuper && !io.KeyAlt && !io.KeyCtrl) edit_state.OnKeyPressed(STB_TEXTEDIT_K_LINESTART|STB_TEXTEDIT_K_SHIFT); + else if (io.OptMacOSXBehaviors && io.KeySuper && !io.KeyAlt && !io.KeyCtrl) edit_state.OnKeyPressed(STB_TEXTEDIT_K_LINESTART|STB_TEXTEDIT_K_SHIFT); } edit_state.OnKeyPressed(STB_TEXTEDIT_K_BACKSPACE | k_mask); } @@ -8491,7 +8494,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 draw_window->DrawList->AddText(g.Font, g.FontSize, render_pos - render_scroll, GetColorU32(ImGuiCol_Text), buf_display, buf_display + edit_state.CurLenA, 0.0f, is_multiline ? NULL : &clip_rect); // Draw blinking cursor - bool cursor_is_visible = (g.InputTextState.CursorAnim <= 0.0f) || fmodf(g.InputTextState.CursorAnim, 1.20f) <= 0.80f; + bool cursor_is_visible = (g.IO.OptNoCursorBlink) || (g.InputTextState.CursorAnim <= 0.0f) || fmodf(g.InputTextState.CursorAnim, 1.20f) <= 0.80f; ImVec2 cursor_screen_pos = render_pos + cursor_offset - render_scroll; ImRect cursor_screen_rect(cursor_screen_pos.x, cursor_screen_pos.y-g.FontSize+0.5f, cursor_screen_pos.x+1.0f, cursor_screen_pos.y-1.5f); if (cursor_is_visible && cursor_screen_rect.Overlaps(clip_rect)) diff --git a/imgui.h b/imgui.h index 9a1a159a3..68d53dced 100644 --- a/imgui.h +++ b/imgui.h @@ -803,7 +803,8 @@ struct ImGuiIO ImVec2 DisplayVisibleMax; // (0.0f,0.0f) // If the values are the same, we defaults to Min=(0.0f) and Max=DisplaySize // Advanced/subtle behaviors - bool OSXBehaviors; // = defined(__APPLE__) // OS X style: Text editing cursor movement using Alt instead of Ctrl, Shortcuts using Cmd/Super instead of Ctrl, Line/Text Start and End using Cmd+Arrows instead of Home/End, Double click selects by word instead of selecting whole text, Multi-selection in lists uses Cmd/Super instead of Ctrl + bool OptMacOSXBehaviors; // = defined(__APPLE__) // OS X style: Text editing cursor movement using Alt instead of Ctrl, Shortcuts using Cmd/Super instead of Ctrl, Line/Text Start and End using Cmd+Arrows instead of Home/End, Double click selects by word instead of selecting whole text, Multi-selection in lists uses Cmd/Super instead of Ctrl + bool OptNoCursorBlink; // = false // Disable blinking cursor //------------------------------------------------------------------ // Settings (User Functions) From 30bf40195bc0d3e4668ddb39db25344a622593e4 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 12 Nov 2017 16:06:44 +0100 Subject: [PATCH 555/921] io.OptNoCursorBlink -> io.OptCursorBlink (#1427) --- imgui.cpp | 4 ++-- imgui.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 1f9100c02..5f5a80a79 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -780,7 +780,7 @@ ImGuiIO::ImGuiIO() #else OptMacOSXBehaviors = false; #endif - OptNoCursorBlink = false; + OptCursorBlink = true; // Settings (User Functions) RenderDrawListsFn = NULL; @@ -8494,7 +8494,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 draw_window->DrawList->AddText(g.Font, g.FontSize, render_pos - render_scroll, GetColorU32(ImGuiCol_Text), buf_display, buf_display + edit_state.CurLenA, 0.0f, is_multiline ? NULL : &clip_rect); // Draw blinking cursor - bool cursor_is_visible = (g.IO.OptNoCursorBlink) || (g.InputTextState.CursorAnim <= 0.0f) || fmodf(g.InputTextState.CursorAnim, 1.20f) <= 0.80f; + bool cursor_is_visible = (!g.IO.OptCursorBlink) || (g.InputTextState.CursorAnim <= 0.0f) || fmodf(g.InputTextState.CursorAnim, 1.20f) <= 0.80f; ImVec2 cursor_screen_pos = render_pos + cursor_offset - render_scroll; ImRect cursor_screen_rect(cursor_screen_pos.x, cursor_screen_pos.y-g.FontSize+0.5f, cursor_screen_pos.x+1.0f, cursor_screen_pos.y-1.5f); if (cursor_is_visible && cursor_screen_rect.Overlaps(clip_rect)) diff --git a/imgui.h b/imgui.h index 68d53dced..162ded07c 100644 --- a/imgui.h +++ b/imgui.h @@ -804,7 +804,7 @@ struct ImGuiIO // Advanced/subtle behaviors bool OptMacOSXBehaviors; // = defined(__APPLE__) // OS X style: Text editing cursor movement using Alt instead of Ctrl, Shortcuts using Cmd/Super instead of Ctrl, Line/Text Start and End using Cmd+Arrows instead of Home/End, Double click selects by word instead of selecting whole text, Multi-selection in lists uses Cmd/Super instead of Ctrl - bool OptNoCursorBlink; // = false // Disable blinking cursor + bool OptCursorBlink; // = true // Enable blinking cursor, for users who consider it annoying. //------------------------------------------------------------------ // Settings (User Functions) From 4d00dd8326b288aa0ff87ad6de4975d0578cfd56 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 13 Nov 2017 15:15:48 +0100 Subject: [PATCH 556/921] Fixed scrollbar flickering on/off when uncollapsing a window (fixes 2df8fa95dfe3463ece78c56b02dc815c3e71331a) --- imgui.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 5f5a80a79..a98806171 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4245,10 +4245,10 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // Update scrollbar status based on the Size that was effective during last frame (and not the upcoming Size which we are updating below), so that user code consuming exactly the available size won't trigger scrollbars when e.g. manually resizing. if (!window->Collapsed) { - window->ScrollbarY = (flags & ImGuiWindowFlags_AlwaysVerticalScrollbar) || ((window->SizeContents.y > window->Size.y + style.ItemSpacing.y) && !(flags & ImGuiWindowFlags_NoScrollbar)); - window->ScrollbarX = (flags & ImGuiWindowFlags_AlwaysHorizontalScrollbar) || ((window->SizeContents.x > window->Size.x - (window->ScrollbarY ? style.ScrollbarSize : 0.0f) - window->WindowPadding.x) && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar)); + window->ScrollbarY = (flags & ImGuiWindowFlags_AlwaysVerticalScrollbar) || ((window->SizeContents.y > window->SizeFull.y + style.ItemSpacing.y) && !(flags & ImGuiWindowFlags_NoScrollbar)); + window->ScrollbarX = (flags & ImGuiWindowFlags_AlwaysHorizontalScrollbar) || ((window->SizeContents.x > window->SizeFull.x - (window->ScrollbarY ? style.ScrollbarSize : 0.0f) - window->WindowPadding.x) && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar)); if (window->ScrollbarX && !window->ScrollbarY) - window->ScrollbarY = (window->SizeContents.y > window->Size.y + style.ItemSpacing.y - style.ScrollbarSize) && !(flags & ImGuiWindowFlags_NoScrollbar); + window->ScrollbarY = (window->SizeContents.y > window->SizeFull.y + style.ItemSpacing.y - style.ScrollbarSize) && !(flags & ImGuiWindowFlags_NoScrollbar); window->ScrollbarSizes = ImVec2(window->ScrollbarY ? style.ScrollbarSize : 0.0f, window->ScrollbarX ? style.ScrollbarSize : 0.0f); window->BorderSize = (flags & ImGuiWindowFlags_ShowBorders) ? 1.0f : 0.0f; } From 7908cce25f01c2e2dffe01732a7efc8a01055140 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 10 Nov 2017 13:13:28 +0100 Subject: [PATCH 557/921] Drag and Drop: Added internal BeginDragDropTargetCustom() convenient to avoid submitting dummy ItemAdd. (#143) --- imgui.cpp | 39 ++++++++++++++++++++++++++++++--------- imgui_internal.h | 5 +++++ 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index cdb025421..b43295e8f 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -10776,6 +10776,27 @@ bool ImGui::SetDragDropPayload(const char* type, const void* data, size_t data_s return (g.DragDropAcceptFrameCount == g.FrameCount) || (g.DragDropAcceptFrameCount == g.FrameCount - 1); } +bool ImGui::BeginDragDropTargetCustom(const ImRect& bb, ImGuiID id) +{ + ImGuiContext& g = *GImGui; + if (!g.DragDropActive) + return false; + + ImGuiWindow* window = g.CurrentWindow; + if (g.HoveredWindow == NULL || window->RootWindow != g.HoveredWindow->RootWindow) + return false; + if (!IsMouseHoveringRect(bb.Min, bb.Max) || (id && id == g.DragDropPayload.SourceId)) + return false; + + g.DragDropTargetRect = bb; + g.DragDropTargetId = id; + return true; +} + +// We don't use BeginDragDropTargetCustom() and duplicate its code because: +// 1) LastItemRectHoveredRect which handles items that pushes a temporarily clip rectangle in their code. Calling BeginDragDropTargetCustom(LastItemRect) would not handle it. +// 2) and it's faster. as this code may be very frequently called, we want to early out as fast as we can. +// Also note how the HoveredWindow test is positioned differently in both functions (in both functions we optimize for the cheapest early out case) bool ImGui::BeginDragDropTarget() { ImGuiContext& g = *GImGui; @@ -10785,9 +10806,11 @@ bool ImGui::BeginDragDropTarget() ImGuiWindow* window = g.CurrentWindow; if (!window->DC.LastItemRectHoveredRect || (window->DC.LastItemId && window->DC.LastItemId == g.DragDropPayload.SourceId)) return false; - if (window->RootWindow != g.HoveredWindow->RootWindow) + if (g.HoveredWindow == NULL || window->RootWindow != g.HoveredWindow->RootWindow) return false; + g.DragDropTargetRect = window->DC.LastItemRect; + g.DragDropTargetId = window->DC.LastItemId; return true; } @@ -10797,25 +10820,22 @@ const ImGuiPayload* ImGui::AcceptDragDropPayload(const char* type, ImGuiDragDrop ImGuiWindow* window = g.CurrentWindow; ImGuiPayload& payload = g.DragDropPayload; IM_ASSERT(g.DragDropActive); // Not called between BeginDragDropTarget() and EndDragDropTarget() ? - IM_ASSERT(window->DC.LastItemRectHoveredRect); // Not called between BeginDragDropTarget() and EndDragDropTarget() ? IM_ASSERT(payload.DataFrameCount != -1); // Forgot to call EndDragDropTarget() ? if (type != NULL && !payload.IsDataType(type)) return NULL; - // NB: We currently accept NULL id as target. However, overlapping targets requires a unique ID to function! - const bool was_accepted_previously = (g.DragDropAcceptIdPrev == window->DC.LastItemId); - g.DragDropAcceptIdCurr = window->DC.LastItemId; - // Accept smallest drag target bounding box, this allows us to nest drag targets conveniently without ordering constraints. - ImRect r = window->DC.LastItemRect; + // NB: We currently accept NULL id as target. However, overlapping targets requires a unique ID to function! + const bool was_accepted_previously = (g.DragDropAcceptIdPrev == g.DragDropTargetId); + ImRect r = g.DragDropTargetRect; float r_surface = r.GetWidth() * r.GetHeight(); if (r_surface < g.DragDropAcceptIdCurrRectSurface) { - g.DragDropAcceptIdCurr = window->DC.LastItemId; + g.DragDropAcceptIdCurr = g.DragDropTargetId; g.DragDropAcceptIdCurrRectSurface = r_surface; } - // Render drop visuals + // Render default drop visuals if (!(flags & ImGuiDragDropFlags_AcceptNoDrawDefaultRect) && was_accepted_previously) { // FIXME-DRAG FIXME-STYLE: Settle on a proper default visuals for drop target, w/ ImGuiCol enum value probably. @@ -10826,6 +10846,7 @@ const ImGuiPayload* ImGui::AcceptDragDropPayload(const char* type, ImGuiDragDrop window->DrawList->AddRect(r.Min + ImVec2(1.5f,1.5f), r.Max - ImVec2(1.5f,1.5f), IM_COL32(255, 255, 0, 255), 0.0f, ~0, 2.0f); if (push_clip_rect) window->DrawList->PopClipRect(); } + g.DragDropAcceptFrameCount = g.FrameCount; payload.Delivery = was_accepted_previously && IsMouseReleased(g.DragDropMouseButton); if (!payload.Delivery && !(flags & ImGuiDragDropFlags_AcceptBeforeDelivery)) diff --git a/imgui_internal.h b/imgui_internal.h index c93faf7f6..849ab612d 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -480,6 +480,8 @@ struct ImGuiContext ImGuiDragDropFlags DragDropSourceFlags; int DragDropMouseButton; ImGuiPayload DragDropPayload; + ImRect DragDropTargetRect; + ImGuiID DragDropTargetId; float DragDropAcceptIdCurrRectSurface; ImGuiID DragDropAcceptIdCurr; // Target item id (set at the time of accepting the payload) ImGuiID DragDropAcceptIdPrev; // Target item id from previous frame (we need to store this to allow for overlapping drag and drop targets) @@ -567,6 +569,7 @@ struct ImGuiContext DragDropActive = false; DragDropSourceFlags = 0; DragDropMouseButton = -1; + DragDropTargetId = 0; DragDropAcceptIdPrev = DragDropAcceptIdCurr = 0; DragDropAcceptFrameCount = -1; memset(DragDropPayloadBufLocal, 0, sizeof(DragDropPayloadBufLocal)); @@ -835,6 +838,8 @@ namespace ImGui IMGUI_API void Scrollbar(ImGuiLayoutType direction); IMGUI_API void VerticalSeparator(); // Vertical separator, for menu bars (use current line height). not exposed because it is misleading what it doesn't have an effect on regular layout. + IMGUI_API bool BeginDragDropTargetCustom(const ImRect& bb, ImGuiID id); + // FIXME-WIP: New Columns API IMGUI_API void BeginColumns(const char* id, int count, ImGuiColumnsFlags flags = 0); // setup number of columns. use an identifier to distinguish multiple column sets. close with EndColumns(). IMGUI_API void EndColumns(); // close columns From 3e06450d276eefcd7bb368badab67e766d5a5751 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 11 Nov 2017 16:58:43 +0100 Subject: [PATCH 558/921] Internals: Added ArrowButton() helper. --- imgui.cpp | 26 ++++++++++++++++++++++++++ imgui_internal.h | 1 + 2 files changed, 27 insertions(+) diff --git a/imgui.cpp b/imgui.cpp index a98806171..55806a38c 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -5995,6 +5995,32 @@ bool ImGui::CloseButton(ImGuiID id, const ImVec2& pos, float radius) return pressed; } +// [Internal] +bool ImGui::ArrowButton(ImGuiID id, ImGuiDir dir, ImVec2 padding, ImGuiButtonFlags flags) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + if (window->SkipItems) + return false; + + const ImGuiStyle& style = g.Style; + + const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(g.FontSize + padding.x * 2.0f, g.FontSize + padding.y * 2.0f)); + ItemSize(bb, style.FramePadding.y); + if (!ItemAdd(bb, id)) + return false; + + bool hovered, held; + bool pressed = ButtonBehavior(bb, id, &hovered, &held, flags); + + const ImU32 col = GetColorU32((hovered && held) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button); + RenderNavHighlight(bb, id); + RenderFrame(bb.Min, bb.Max, col, true, style.FrameRounding); + RenderTriangle(bb.Min + padding, dir, 1.0f); + + return pressed; +} + void ImGui::Image(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, const ImVec4& tint_col, const ImVec4& border_col) { ImGuiWindow* window = GetCurrentWindow(); diff --git a/imgui_internal.h b/imgui_internal.h index a5d877229..85eced9d3 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -838,6 +838,7 @@ namespace ImGui IMGUI_API bool ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool* out_held, ImGuiButtonFlags flags = 0); IMGUI_API bool ButtonEx(const char* label, const ImVec2& size_arg = ImVec2(0,0), ImGuiButtonFlags flags = 0); IMGUI_API bool CloseButton(ImGuiID id, const ImVec2& pos, float radius); + IMGUI_API bool ArrowButton(ImGuiID id, ImGuiDir dir, ImVec2 padding, ImGuiButtonFlags flags = 0); IMGUI_API bool SliderBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v_min, float v_max, float power, int decimal_precision, ImGuiSliderFlags flags = 0); IMGUI_API bool SliderFloatN(const char* label, float* v, int components, float v_min, float v_max, const char* display_format, float power); From 852ece3a0e29a27771148c95fda51ba5e4e65e0c Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 13 Nov 2017 16:04:03 +0100 Subject: [PATCH 559/921] Fixed build (3e06450d276eefcd7bb368badab67e766d5a5751 not meant for master branch, but ok) --- imgui.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/imgui.cpp b/imgui.cpp index 55806a38c..b085efe1c 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -6014,7 +6014,9 @@ bool ImGui::ArrowButton(ImGuiID id, ImGuiDir dir, ImVec2 padding, ImGuiButtonFla bool pressed = ButtonBehavior(bb, id, &hovered, &held, flags); const ImU32 col = GetColorU32((hovered && held) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button); +#ifdef IMGUI_HAS_NAV RenderNavHighlight(bb, id); +#endif RenderFrame(bb.Min, bb.Max, col, true, style.FrameRounding); RenderTriangle(bb.Min + padding, dir, 1.0f); From ffad688fc8d5b957716cb873c1bfbd5c12839bbf Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 14 Nov 2017 22:11:43 +0100 Subject: [PATCH 560/921] Drag and Drop: Added payload->IsPreview() to user can render their custom preview while handling overlapping drop targets. (#143) --- imgui.cpp | 3 ++- imgui.h | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index b43295e8f..3eecc73ab 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -10836,7 +10836,8 @@ const ImGuiPayload* ImGui::AcceptDragDropPayload(const char* type, ImGuiDragDrop } // Render default drop visuals - if (!(flags & ImGuiDragDropFlags_AcceptNoDrawDefaultRect) && was_accepted_previously) + payload.Preview = was_accepted_previously; + if (!(flags & ImGuiDragDropFlags_AcceptNoDrawDefaultRect) && payload.Preview) { // FIXME-DRAG FIXME-STYLE: Settle on a proper default visuals for drop target, w/ ImGuiCol enum value probably. r.Expand(5.0f); diff --git a/imgui.h b/imgui.h index 1624e3173..7959d0e76 100644 --- a/imgui.h +++ b/imgui.h @@ -1155,11 +1155,13 @@ struct ImGuiPayload ImGuiID SourceParentId; // Source parent id (if available) int DataFrameCount; // Data timestamp char DataType[8 + 1]; // Data type tag (short user-supplied string) - bool Delivery; // Set when AcceptDragDropPayload() was called and the mouse button is released over the target item + bool Preview; // Set when AcceptDragDropPayload() was called and mouse has been hovering the target item (nb: handle overlapping drag targets) + bool Delivery; // Set when AcceptDragDropPayload() was called and mouse button is released over the target item. ImGuiPayload() { Clear(); } - void Clear() { SourceId = SourceParentId = 0; Data = NULL; DataSize = 0; memset(DataType, 0, sizeof(DataType)); DataFrameCount = -1; Delivery = false; } + void Clear() { SourceId = SourceParentId = 0; Data = NULL; DataSize = 0; memset(DataType, 0, sizeof(DataType)); DataFrameCount = -1; Preview = Delivery = false; } bool IsDataType(const char* type) const { return DataFrameCount != -1 && strcmp(type, DataType) == 0; } + bool IsPreview() const { return Preview; } bool IsDelivery() const { return Delivery; } }; From 0858c3d7cbc208223563f52202cb0cccb970622b Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 14 Nov 2017 22:21:38 +0100 Subject: [PATCH 561/921] Demo: Custom Rendering: Fixed clipping rectangle extruding out of parent window. --- imgui_demo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 7f45c50ea..f6918f578 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -2327,7 +2327,7 @@ static void ShowExampleAppCustomRendering(bool* p_open) points.pop_back(); } } - draw_list->PushClipRect(canvas_pos, ImVec2(canvas_pos.x+canvas_size.x, canvas_pos.y+canvas_size.y)); // clip lines within the canvas (if we resize it, etc.) + draw_list->PushClipRect(canvas_pos, ImVec2(canvas_pos.x+canvas_size.x, canvas_pos.y+canvas_size.y), true); // clip lines within the canvas (if we resize it, etc.) for (int i = 0; i < points.Size - 1; i += 2) draw_list->AddLine(ImVec2(canvas_pos.x + points[i].x, canvas_pos.y + points[i].y), ImVec2(canvas_pos.x + points[i+1].x, canvas_pos.y + points[i+1].y), IM_COL32(255,255,0,255), 2.0f); draw_list->PopClipRect(); From 6001d9c7a46f70bb029aa779c42fafd3c2b22652 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 14 Nov 2017 22:40:57 +0100 Subject: [PATCH 562/921] Columns: Clipping columns borders on Y axis on CPU because some GPU drivers appears to be unhappy with triangle spanning large regions (not sure why tbh). (#125) Demo: Columns: Adding a billion of extra lines and using clipper. --- imgui.cpp | 3 ++- imgui_demo.cpp | 19 ++++++++++++------- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index b085efe1c..b828d0e90 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -10511,9 +10511,10 @@ void ImGui::EndColumns() } // Draw column + // We clip the Y boundaries CPU side because very long triangles are mishandled by some GPU drivers. const ImU32 col = GetColorU32(held ? ImGuiCol_SeparatorActive : hovered ? ImGuiCol_SeparatorHovered : ImGuiCol_Separator); const float xi = (float)(int)x; - window->DrawList->AddLine(ImVec2(xi, y1 + 1.0f), ImVec2(xi, y2), col); + window->DrawList->AddLine(ImVec2(xi, ImMax(y1 + 1.0f, window->ClipRect.Min.y)), ImVec2(xi, ImMin(y2, window->ClipRect.Max.y)), col); } // Apply dragging after drawing the column lines, so our rendered lines are in sync with how items were displayed during the frame. diff --git a/imgui_demo.cpp b/imgui_demo.cpp index f6918f578..d9ccad31d 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1652,14 +1652,19 @@ void ImGui::ShowTestWindow(bool* p_open) if (ImGui::TreeNode("Horizontal Scrolling")) { ImGui::SetNextWindowContentWidth(1500); - ImGui::BeginChild("##scrollingregion", ImVec2(0, 120), false, ImGuiWindowFlags_HorizontalScrollbar); + ImGui::BeginChild("##ScrollingRegion", ImVec2(0, ImGui::GetFontSize() * 20), false, ImGuiWindowFlags_HorizontalScrollbar); ImGui::Columns(10); - for (int i = 0; i < 20; i++) - for (int j = 0; j < 10; j++) - { - ImGui::Text("Line %d Column %d...", i, j); - ImGui::NextColumn(); - } + int ITEMS_COUNT = 2000; + ImGuiListClipper clipper(ITEMS_COUNT); // Also demonstrate using the clipper for large list + while (clipper.Step()) + { + for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) + for (int j = 0; j < 10; j++) + { + ImGui::Text("Line %d Column %d...", i, j); + ImGui::NextColumn(); + } + } ImGui::Columns(1); ImGui::EndChild(); ImGui::TreePop(); From 64e79035d5133cf15de41aab0ec9a43bcd4ad08a Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 14 Nov 2017 23:17:28 +0100 Subject: [PATCH 563/921] Scrollbar flicker fix for menus/popups (fixes 4d00dd8326b288aa0ff87ad6de4975d0578cfd56 and 2df8fa95dfe3463ece78c56b02dc815c3e71331a). Hopefully right this time. --- imgui.cpp | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index b828d0e90..f08085859 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4242,17 +4242,6 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->SizeContents.x = (float)(int)((window->SizeContentsExplicit.x != 0.0f) ? window->SizeContentsExplicit.x : ((window_is_new ? 0.0f : window->DC.CursorMaxPos.x - window->Pos.x) + window->Scroll.x)); window->SizeContents.y = (float)(int)((window->SizeContentsExplicit.y != 0.0f) ? window->SizeContentsExplicit.y : ((window_is_new ? 0.0f : window->DC.CursorMaxPos.y - window->Pos.y) + window->Scroll.y)); - // Update scrollbar status based on the Size that was effective during last frame (and not the upcoming Size which we are updating below), so that user code consuming exactly the available size won't trigger scrollbars when e.g. manually resizing. - if (!window->Collapsed) - { - window->ScrollbarY = (flags & ImGuiWindowFlags_AlwaysVerticalScrollbar) || ((window->SizeContents.y > window->SizeFull.y + style.ItemSpacing.y) && !(flags & ImGuiWindowFlags_NoScrollbar)); - window->ScrollbarX = (flags & ImGuiWindowFlags_AlwaysHorizontalScrollbar) || ((window->SizeContents.x > window->SizeFull.x - (window->ScrollbarY ? style.ScrollbarSize : 0.0f) - window->WindowPadding.x) && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar)); - if (window->ScrollbarX && !window->ScrollbarY) - window->ScrollbarY = (window->SizeContents.y > window->SizeFull.y + style.ItemSpacing.y - style.ScrollbarSize) && !(flags & ImGuiWindowFlags_NoScrollbar); - window->ScrollbarSizes = ImVec2(window->ScrollbarY ? style.ScrollbarSize : 0.0f, window->ScrollbarX ? style.ScrollbarSize : 0.0f); - window->BorderSize = (flags & ImGuiWindowFlags_ShowBorders) ? 1.0f : 0.0f; - } - // Hide popup/tooltip window when first appearing while we measure size (because we recycle them) if (window->HiddenFrames > 0) window->HiddenFrames--; @@ -4303,7 +4292,22 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // Apply minimum/maximum window size constraints and final size window->SizeFull = CalcSizeFullWithConstraint(window, window->SizeFull); window->Size = window->Collapsed ? window->TitleBarRect().GetSize() : window->SizeFull; - + if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Popup)) + window->Size = window->SizeFull; + + // SCROLLBAR STATUS + + // Update scrollbar status (based on the Size that was effective during last frame or the auto-resized Size). We need to do this before manual resize (below) is effective. + if (!window->Collapsed) + { + window->ScrollbarY = (flags & ImGuiWindowFlags_AlwaysVerticalScrollbar) || ((window->SizeContents.y > window->SizeFull.y + style.ItemSpacing.y) && !(flags & ImGuiWindowFlags_NoScrollbar)); + window->ScrollbarX = (flags & ImGuiWindowFlags_AlwaysHorizontalScrollbar) || ((window->SizeContents.x > window->SizeFull.x - (window->ScrollbarY ? style.ScrollbarSize : 0.0f) - window->WindowPadding.x) && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar)); + if (window->ScrollbarX && !window->ScrollbarY) + window->ScrollbarY = (window->SizeContents.y > window->SizeFull.y + style.ItemSpacing.y - style.ScrollbarSize) && !(flags & ImGuiWindowFlags_NoScrollbar); + window->ScrollbarSizes = ImVec2(window->ScrollbarY ? style.ScrollbarSize : 0.0f, window->ScrollbarX ? style.ScrollbarSize : 0.0f); + window->BorderSize = (flags & ImGuiWindowFlags_ShowBorders) ? 1.0f : 0.0f; + } + // POSITION // Position child window @@ -4316,7 +4320,6 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) { IM_ASSERT(window_size_set_by_api); // Submitted by BeginChild() window->Pos = window->PosFloat = parent_window->DC.CursorPos; - window->Size = window->SizeFull; } const bool window_pos_with_pivot = (window->SetWindowPosVal.x != FLT_MAX && window->HiddenFrames == 0); @@ -4485,6 +4488,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->ContentsRegionRect.Max.y = -window->Scroll.y - window->WindowPadding.y + (window->SizeContentsExplicit.y != 0.0f ? window->SizeContentsExplicit.y : (window->Size.y - window->ScrollbarSizes.y)); // Setup drawing context + // (NB: That term "drawing context / DC" lost its meaning a long time ago. Initially was meant to hold transient data only. Nowadays difference between window-> and window->DC-> is dubious.) window->DC.IndentX = 0.0f + window->WindowPadding.x - window->Scroll.x; window->DC.GroupOffsetX = 0.0f; window->DC.ColumnsOffsetX = 0.0f; From 27fd1b913b7cbf1eafdffe6a6539a21776171cdf Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 15 Nov 2017 14:35:45 +0100 Subject: [PATCH 564/921] Made it guaranteed by API that after calling Begin() the last Item represent the title bar. (#823) --- imgui.cpp | 5 +++++ imgui_demo.cpp | 11 ++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index f08085859..eef43a4fd 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4589,6 +4589,11 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->InnerRect.Max.x = window->Pos.x + window->Size.x - window->ScrollbarSizes.x; window->InnerRect.Max.y = window->Pos.y + window->Size.y - window->ScrollbarSizes.y; //window->DrawList->AddRect(window->InnerRect.Min, window->InnerRect.Max, IM_COL32_WHITE); + + // After Begin() we fill the last item / hovered data using the title bar data. Make that a standard behavior (to allow usage of context menus on title bar only, etc.). + window->DC.LastItemId = window->MoveId; + window->DC.LastItemRect = title_bar_rect; + window->DC.LastItemRectHoveredRect = IsMouseHoveringRect(title_bar_rect.Min, title_bar_rect.Max, false); } // Inner clipping rectangle diff --git a/imgui_demo.cpp b/imgui_demo.cpp index d9ccad31d..c627f5bdc 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -2406,6 +2406,15 @@ struct ExampleAppConsole return; } + // As a specific feature guaranteed by the library, after calling Begin() the last Item represent the title bar. So e.g. IsItemHovered() will return true when hovering the title bar. + // Here we create a context menu only available from the title bar. + if (ImGui::BeginPopupContextItem()) + { + if (ImGui::MenuItem("Close")) + *p_open = false; + ImGui::EndPopup(); + } + ImGui::TextWrapped("This example implements a console with basic coloring, completion and history. A more elaborate implementation may want to store entries along with extra data such as timestamp, emitter, etc."); ImGui::TextWrapped("Enter 'HELP' for help, press TAB to use text completion."); @@ -2850,7 +2859,7 @@ static void ShowExampleAppLongText(bool* p_open) static ImGuiTextBuffer log; static int lines = 0; ImGui::Text("Printing unusually long amount of text."); - ImGui::Combo("Test type", &test_type, "Single call to TextUnformatted()\0Multiple calls to Text(), clipped manually\0Multiple calls to Text(), not clipped\0"); + ImGui::Combo("Test type", &test_type, "Single call to TextUnformatted()\0Multiple calls to Text(), clipped manually\0Multiple calls to Text(), not clipped (slow)\0"); ImGui::Text("Buffer contents: %d lines, %d bytes", lines, log.size()); if (ImGui::Button("Clear")) { log.clear(); lines = 0; } ImGui::SameLine(); From 5027311e7fc8f7e1d5d00ed68449d2010d351628 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 15 Nov 2017 17:59:12 +0100 Subject: [PATCH 565/921] Drag and drop: Standardizing payload types as defines. (#143) --- imgui_internal.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/imgui_internal.h b/imgui_internal.h index 1980e45bd..45bbedeb7 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -167,6 +167,10 @@ inline void operator delete(void*, ImPlacementNewDummy, void*) {} // Types //----------------------------------------------------------------------------- +// Drag and Drop payload types. String starting with '_' are managed by Dear ImGui. +#define IMGUI_PAYLOAD_TYPE_COLOR_4F "_COL4F" // float[4] // Standard type for colors. User code may use this type. Build a float[4] out of a float[3] if you don't have alpha. +#define IMGUI_PAYLOAD_TYPE_DOCKABLE "_IMDOCK" // ImGuiWindow* // [Internal] Docking/tabs + enum ImGuiButtonFlags_ { ImGuiButtonFlags_Repeat = 1 << 0, // hold to repeat @@ -239,7 +243,8 @@ enum ImGuiDir ImGuiDir_Left = 0, ImGuiDir_Right = 1, ImGuiDir_Up = 2, - ImGuiDir_Down = 3 + ImGuiDir_Down = 3, + ImGuiDir_Count_ }; enum ImGuiCorner From 5ea6e80da155e45d7e94b917966adb85fe992e3c Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 15 Nov 2017 22:20:40 +0100 Subject: [PATCH 566/921] Make it possible to use SetNextWindowPos() on a child window. Useful internally. --- imgui.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index eef43a4fd..f52505bfe 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4293,7 +4293,10 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->SizeFull = CalcSizeFullWithConstraint(window, window->SizeFull); window->Size = window->Collapsed ? window->TitleBarRect().GetSize() : window->SizeFull; if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Popup)) + { + IM_ASSERT(window_size_set_by_api); // Submitted by BeginChild() window->Size = window->SizeFull; + } // SCROLLBAR STATUS @@ -4316,11 +4319,8 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->OrderWithinParent = parent_window->DC.ChildWindows.Size; parent_window->DC.ChildWindows.push_back(window); } - if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Popup)) - { - IM_ASSERT(window_size_set_by_api); // Submitted by BeginChild() + if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Popup) && !window_pos_set_by_api) window->Pos = window->PosFloat = parent_window->DC.CursorPos; - } const bool window_pos_with_pivot = (window->SetWindowPosVal.x != FLT_MAX && window->HiddenFrames == 0); if (window_pos_with_pivot) From f5bdf443c9436c3585537bd6637a4bbbaa6be26f Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 15 Nov 2017 22:37:43 +0100 Subject: [PATCH 567/921] Minor comments, tweaks --- imgui.cpp | 9 ++------- imgui.h | 4 ++-- imgui_draw.cpp | 37 +++++++++++++++++++------------------ 3 files changed, 23 insertions(+), 27 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index f52505bfe..1a5ac52c3 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1375,13 +1375,8 @@ void* ImFileLoadToMemory(const char* filename, const char* file_open_mode, int* //----------------------------------------------------------------------------- // ImGuiStorage -//----------------------------------------------------------------------------- - // Helper: Key->value storage -void ImGuiStorage::Clear() -{ - Data.clear(); -} +//----------------------------------------------------------------------------- // std::lower_bound but without the bullshit static ImVector::iterator LowerBound(ImVector& data, ImGuiID key) @@ -1651,7 +1646,7 @@ void ImGuiTextBuffer::append(const char* fmt, ...) } //----------------------------------------------------------------------------- -// ImGuiSimpleColumns +// ImGuiSimpleColumns (internal use only) //----------------------------------------------------------------------------- ImGuiSimpleColumns::ImGuiSimpleColumns() diff --git a/imgui.h b/imgui.h index 162ded07c..42098322d 100644 --- a/imgui.h +++ b/imgui.h @@ -1050,7 +1050,7 @@ struct ImGuiStorage { ImGuiID key; union { int val_i; float val_f; void* val_p; }; - Pair(ImGuiID _key, int _val_i) { key = _key; val_i = _val_i; } + Pair(ImGuiID _key, int _val_i) { key = _key; val_i = _val_i; } Pair(ImGuiID _key, float _val_f) { key = _key; val_f = _val_f; } Pair(ImGuiID _key, void* _val_p) { key = _key; val_p = _val_p; } }; @@ -1059,7 +1059,7 @@ struct ImGuiStorage // - Get***() functions find pair, never add/allocate. Pairs are sorted so a query is O(log N) // - Set***() functions find pair, insertion on demand if missing. // - Sorted insertion is costly, paid once. A typical frame shouldn't need to insert any new pair. - IMGUI_API void Clear(); + void Clear() { Data.clear(); } IMGUI_API int GetInt(ImGuiID key, int default_val = 0) const; IMGUI_API void SetInt(ImGuiID key, int val); IMGUI_API bool GetBool(ImGuiID key, bool default_val = false) const; diff --git a/imgui_draw.cpp b/imgui_draw.cpp index cea664521..1b173e859 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -264,7 +264,7 @@ void ImDrawList::ClearFreeMemory() _Channels.clear(); } -// Use macros because C++ is a terrible language, we want guaranteed inline, no code in header, and no overhead in Debug mode +// Using macros because C++ is a terrible language, we want guaranteed inline, no code in header, and no overhead in Debug builds #define GetCurrentClipRect() (_ClipRectStack.Size ? _ClipRectStack.Data[_ClipRectStack.Size-1] : GNullClipRect) #define GetCurrentTextureId() (_TextureIdStack.Size ? _TextureIdStack.Data[_TextureIdStack.Size-1] : NULL) @@ -388,7 +388,7 @@ void ImDrawList::ChannelsSplit(int channels_count) _Channels.resize(channels_count); _ChannelsCount = channels_count; - // _Channels[] (24 bytes each) hold storage that we'll swap with this->_CmdBuffer/_IdxBuffer + // _Channels[] (24/32 bytes each) hold storage that we'll swap with this->_CmdBuffer/_IdxBuffer // The content of _Channels[0] at this point doesn't matter. We clear it to make state tidy in a debugger but we don't strictly need to. // When we switch to the next channel, we'll copy _CmdBuffer/_IdxBuffer into _Channels[0] and then _Channels[1] into _CmdBuffer/_IdxBuffer memset(&_Channels[0], 0, sizeof(ImDrawChannel)); @@ -1208,7 +1208,7 @@ ImFontConfig::ImFontConfig() const int FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF = 90; const int FONT_ATLAS_DEFAULT_TEX_DATA_H = 27; const unsigned int FONT_ATLAS_DEFAULT_TEX_DATA_ID = 0x80000000; -const char FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS[FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF * FONT_ATLAS_DEFAULT_TEX_DATA_H + 1] = +static const char FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS[FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF * FONT_ATLAS_DEFAULT_TEX_DATA_H + 1] = { "..- -XXXXXXX- X - X -XXXXXXX - XXXXXXX" "..- -X.....X- X.X - X.X -X.....X - X.....X" @@ -1239,6 +1239,19 @@ const char FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS[FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF " - XX XX - " }; +static const ImVec2 FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[ImGuiMouseCursor_Count_][3] = +{ + // Pos ........ Size ......... Offset ...... + { ImVec2(0,3), ImVec2(12,19), ImVec2( 0, 0) }, // ImGuiMouseCursor_Arrow + { ImVec2(13,0), ImVec2(7,16), ImVec2( 4, 8) }, // ImGuiMouseCursor_TextInput + { ImVec2(31,0), ImVec2(23,23), ImVec2(11,11) }, // ImGuiMouseCursor_Move + { ImVec2(21,0), ImVec2( 9,23), ImVec2( 5,11) }, // ImGuiMouseCursor_ResizeNS + { ImVec2(55,18),ImVec2(23, 9), ImVec2(11, 5) }, // ImGuiMouseCursor_ResizeEW + { ImVec2(73,0), ImVec2(17,17), ImVec2( 9, 9) }, // ImGuiMouseCursor_ResizeNESW + { ImVec2(55,0), ImVec2(17,17), ImVec2( 9, 9) }, // ImGuiMouseCursor_ResizeNWSE +}; + + ImFontAtlas::ImFontAtlas() { TexID = NULL; @@ -1784,26 +1797,14 @@ static void ImFontAtlasBuildRenderDefaultTexData(ImFontAtlas* atlas) atlas->TexUvWhitePixel = ImVec2((r.X + 0.5f) * tex_uv_scale.x, (r.Y + 0.5f) * tex_uv_scale.y); // Setup mouse cursors - const ImVec2 cursor_datas[ImGuiMouseCursor_Count_][3] = - { - // Pos ........ Size ......... Offset ...... - { ImVec2(0,3), ImVec2(12,19), ImVec2( 0, 0) }, // ImGuiMouseCursor_Arrow - { ImVec2(13,0), ImVec2(7,16), ImVec2( 4, 8) }, // ImGuiMouseCursor_TextInput - { ImVec2(31,0), ImVec2(23,23), ImVec2(11,11) }, // ImGuiMouseCursor_Move - { ImVec2(21,0), ImVec2( 9,23), ImVec2( 5,11) }, // ImGuiMouseCursor_ResizeNS - { ImVec2(55,18),ImVec2(23, 9), ImVec2(11, 5) }, // ImGuiMouseCursor_ResizeEW - { ImVec2(73,0), ImVec2(17,17), ImVec2( 9, 9) }, // ImGuiMouseCursor_ResizeNESW - { ImVec2(55,0), ImVec2(17,17), ImVec2( 9, 9) }, // ImGuiMouseCursor_ResizeNWSE - }; - for (int type = 0; type < ImGuiMouseCursor_Count_; type++) { ImGuiMouseCursorData& cursor_data = GImGui->MouseCursorData[type]; - ImVec2 pos = cursor_datas[type][0] + ImVec2((float)r.X, (float)r.Y); - const ImVec2 size = cursor_datas[type][1]; + ImVec2 pos = FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[type][0] + ImVec2((float)r.X, (float)r.Y); + const ImVec2 size = FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[type][1]; cursor_data.Type = type; cursor_data.Size = size; - cursor_data.HotOffset = cursor_datas[type][2]; + cursor_data.HotOffset = FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[type][2]; cursor_data.TexUvMin[0] = (pos) * tex_uv_scale; cursor_data.TexUvMax[0] = (pos + size) * tex_uv_scale; pos.x += FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF + 1; From 9b82d9fbef1f8897503c035fe73753ab5557be67 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 15 Nov 2017 23:11:36 +0100 Subject: [PATCH 568/921] Scrollbar: Minor graphical fix for when scrollbar don't have enough visible space to display the full grab. --- imgui.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 1a5ac52c3..5b907ac90 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4782,10 +4782,12 @@ void ImGui::Scrollbar(ImGuiLayoutType direction) // Render const ImU32 grab_col = GetColorU32(held ? ImGuiCol_ScrollbarGrabActive : hovered ? ImGuiCol_ScrollbarGrabHovered : ImGuiCol_ScrollbarGrab); + ImRect grab_rect; if (horizontal) - window->DrawList->AddRectFilled(ImVec2(ImLerp(bb.Min.x, bb.Max.x, grab_v_norm), bb.Min.y), ImVec2(ImLerp(bb.Min.x, bb.Max.x, grab_v_norm) + grab_h_pixels, bb.Max.y), grab_col, style.ScrollbarRounding); + grab_rect = ImRect(ImLerp(bb.Min.x, bb.Max.x, grab_v_norm), bb.Min.y, ImMin(ImLerp(bb.Min.x, bb.Max.x, grab_v_norm) + grab_h_pixels, window_rect.Max.x), bb.Max.y); else - window->DrawList->AddRectFilled(ImVec2(bb.Min.x, ImLerp(bb.Min.y, bb.Max.y, grab_v_norm)), ImVec2(bb.Max.x, ImLerp(bb.Min.y, bb.Max.y, grab_v_norm) + grab_h_pixels), grab_col, style.ScrollbarRounding); + grab_rect = ImRect(bb.Min.x, ImLerp(bb.Min.y, bb.Max.y, grab_v_norm), bb.Max.x, ImMin(ImLerp(bb.Min.y, bb.Max.y, grab_v_norm) + grab_h_pixels, window_rect.Max.y)); + window->DrawList->AddRectFilled(grab_rect.Min, grab_rect.Max, grab_col, style.ScrollbarRounding); } // Moving window to front of display (which happens to be back of our sorted list) From f36037b3845d45c445e75688b66bc4c85032dee6 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 15 Nov 2017 23:38:17 +0100 Subject: [PATCH 569/921] Menu: Fixed minor rendering issues on the right size with rounded window when resizing a window small. --- imgui.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/imgui.cpp b/imgui.cpp index 5b907ac90..19eeda3a4 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9187,10 +9187,12 @@ bool ImGui::BeginMenuBar() if (!(window->Flags & ImGuiWindowFlags_MenuBar)) return false; + ImGuiContext& g = *GImGui; IM_ASSERT(!window->DC.MenuBarAppending); BeginGroup(); // Save position PushID("##menubar"); ImRect rect = window->MenuBarRect(); + rect.Max.x = ImMax(rect.Min.x, rect.Max.x - g.Style.WindowRounding); PushClipRect(ImVec2(ImFloor(rect.Min.x+0.5f), ImFloor(rect.Min.y + window->BorderSize + 0.5f)), ImVec2(ImFloor(rect.Max.x+0.5f), ImFloor(rect.Max.y+0.5f)), false); window->DC.CursorPos = ImVec2(rect.Min.x + window->DC.MenuBarOffsetX, rect.Min.y);// + g.Style.FramePadding.y); window->DC.LayoutType = ImGuiLayoutType_Horizontal; @@ -9241,6 +9243,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled) { // Menu inside an horizontal menu bar // Selectable extend their highlight by half ItemSpacing in each direction. + // For ChildMenu, the popup position will be overwritten by the call to FindBestPopupWindowPos() in Begin() popup_pos = ImVec2(pos.x - window->WindowPadding.x, pos.y - style.FramePadding.y + window->MenuBarHeight()); window->DC.CursorPos.x += (float)(int)(style.ItemSpacing.x * 0.5f); PushStyleVar(ImGuiStyleVar_ItemSpacing, style.ItemSpacing * 2.0f); From e9a7e73bbaacec886f9b39130428b81b7f95bf16 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 15 Nov 2017 23:42:18 +0100 Subject: [PATCH 570/921] Windows with MenuBar have a larger minimum height to avoid artefacts (I fixed most of the vertical/horizontal artefacts, but the ones in rounded corners were too hard to fix). --- imgui.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/imgui.cpp b/imgui.cpp index 19eeda3a4..088012bbc 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4012,7 +4012,10 @@ static ImVec2 CalcSizeFullWithConstraint(ImGuiWindow* window, ImVec2 new_size) } } if (!(window->Flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_AlwaysAutoResize))) + { new_size = ImMax(new_size, g.Style.WindowMinSize); + new_size.y = ImMax(new_size.y, window->TitleBarHeight() + window->MenuBarHeight() + ImMax(0.0f, g.Style.WindowRounding - 1.0f)); // Reduce artifacts with very small windows + } return new_size; } From 7c4be0a000abfc6645f56f654794473d5d358940 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 16 Nov 2017 13:11:16 +0100 Subject: [PATCH 571/921] Internals: Added BringWindowToFront(), BringWindowToBack() helpers. --- imgui.cpp | 43 ++++++++++++++++++++++++++++++++----------- imgui_internal.h | 2 ++ 2 files changed, 34 insertions(+), 11 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 088012bbc..6d5b6bc9a 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4793,7 +4793,35 @@ void ImGui::Scrollbar(ImGuiLayoutType direction) window->DrawList->AddRectFilled(grab_rect.Min, grab_rect.Max, grab_col, style.ScrollbarRounding); } -// Moving window to front of display (which happens to be back of our sorted list) +void ImGui::BringWindowToFront(ImGuiWindow* window) +{ + ImGuiContext& g = *GImGui; + if (g.Windows.back() == window) + return; + for (int i = 0; i < g.Windows.Size; i++) + if (g.Windows[i] == window) + { + g.Windows.erase(g.Windows.begin() + i); + g.Windows.push_back(window); + break; + } +} + +void ImGui::BringWindowToBack(ImGuiWindow* window) +{ + ImGuiContext& g = *GImGui; + if (g.Windows[0] == window) + return; + for (int i = 0; i < g.Windows.Size; i++) + if (g.Windows[i] == window) + { + memmove(&g.Windows[1], &g.Windows[0], (size_t)i * sizeof(ImGuiWindow*)); + g.Windows[0] = window; + break; + } +} + +// Moving window to front of display and set focus (which happens to be back of our sorted list) void ImGui::FocusWindow(ImGuiWindow* window) { ImGuiContext& g = *GImGui; @@ -4805,7 +4833,7 @@ void ImGui::FocusWindow(ImGuiWindow* window) if (!window) return; - // And move its root window to the top of the pile + // Move the root window to the top of the pile if (window->RootWindow) window = window->RootWindow; @@ -4815,15 +4843,8 @@ void ImGui::FocusWindow(ImGuiWindow* window) ClearActiveID(); // Bring to front - if ((window->Flags & ImGuiWindowFlags_NoBringToFrontOnFocus) || g.Windows.back() == window) - return; - for (int i = 0; i < g.Windows.Size; i++) - if (g.Windows[i] == window) - { - g.Windows.erase(g.Windows.begin() + i); - break; - } - g.Windows.push_back(window); + if (!(window->Flags & ImGuiWindowFlags_NoBringToFrontOnFocus)) + BringWindowToFront(window); } void ImGui::FocusPreviousWindow() diff --git a/imgui_internal.h b/imgui_internal.h index 85eced9d3..be8d84d8a 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -779,6 +779,8 @@ namespace ImGui IMGUI_API ImGuiWindow* GetParentWindow(); IMGUI_API ImGuiWindow* FindWindowByName(const char* name); IMGUI_API void FocusWindow(ImGuiWindow* window); + IMGUI_API void BringWindowToFront(ImGuiWindow* window); + IMGUI_API void BringWindowToBack(ImGuiWindow* window); IMGUI_API void Initialize(); IMGUI_API void EndFrame(); // Ends the ImGui frame. Automatically called by Render()! you most likely don't need to ever call that yourself directly. If you don't need to render you can call EndFrame() but you'll have wasted CPU already. If you don't need to render, don't create any windows instead! From 4ad414c8d45493f6282997c7930d1b7737ff9a63 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 13 Nov 2017 23:25:13 +0100 Subject: [PATCH 572/921] Internals: Window: Store whether the windows has a close button (we need that info for window/tabs dropping preview calculation) --- imgui.cpp | 2 ++ imgui_internal.h | 1 + 2 files changed, 3 insertions(+) diff --git a/imgui.cpp b/imgui.cpp index 6d5b6bc9a..9154c7bf1 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1800,6 +1800,7 @@ ImGuiWindow::ImGuiWindow(const char* name) Collapsed = false; SkipItems = false; Appearing = false; + CloseButton = false; BeginCount = 0; PopupId = 0; AutoFitFramesX = AutoFitFramesY = -1; @@ -4130,6 +4131,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) const bool window_just_appearing_after_hidden_for_resize = (window->HiddenFrames == 1); window->Appearing = (window_just_activated_by_user || window_just_appearing_after_hidden_for_resize); + window->CloseButton = (p_open != NULL); // Process SetNextWindow***() calls bool window_pos_set_by_api = false, window_size_set_by_api = false; diff --git a/imgui_internal.h b/imgui_internal.h index be8d84d8a..6a081dfb6 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -700,6 +700,7 @@ struct IMGUI_API ImGuiWindow bool Collapsed; // Set when collapsing window to become only title-bar bool SkipItems; // Set when items can safely be all clipped (e.g. window not visible or collapsed) bool Appearing; // Set during the frame where the window is appearing (or re-appearing) + bool CloseButton; // Set when the window has a close button (p_open != NULL) int BeginCount; // Number of Begin() during the current frame (generally 0 or 1, 1+ if appending via multiple Begin/End pairs) ImGuiID PopupId; // ID in the popup stack when this window is used as a popup/menu (because we use generic Name/ID for recycling) int AutoFitFramesX, AutoFitFramesY; From 29d962069d3b90478244a398bb1754195f5b0ece Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 13 Nov 2017 22:15:50 +0100 Subject: [PATCH 573/921] Internals: Updating condition/allow flags with a function. --- imgui.cpp | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 9154c7bf1..832904baf 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3918,6 +3918,13 @@ static ImVec2 FindBestPopupWindowPos(const ImVec2& base_pos, const ImVec2& size, return pos; } +static void SetWindowConditionAllowFlags(ImGuiWindow* window, ImGuiCond flags, bool enabled) +{ + window->SetWindowPosAllowFlags = enabled ? (window->SetWindowPosAllowFlags | flags) : (window->SetWindowPosAllowFlags & ~flags); + window->SetWindowSizeAllowFlags = enabled ? (window->SetWindowSizeAllowFlags | flags) : (window->SetWindowSizeAllowFlags & ~flags); + window->SetWindowCollapsedAllowFlags = enabled ? (window->SetWindowCollapsedAllowFlags | flags) : (window->SetWindowCollapsedAllowFlags & ~flags); +} + ImGuiWindow* ImGui::FindWindowByName(const char* name) { ImGuiContext& g = *GImGui; @@ -3949,15 +3956,9 @@ static ImGuiWindow* CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFl ImGuiIniData* settings = FindWindowSettings(name); if (!settings) - { settings = AddWindowSettings(name); - } else - { - window->SetWindowPosAllowFlags &= ~ImGuiCond_FirstUseEver; - window->SetWindowSizeAllowFlags &= ~ImGuiCond_FirstUseEver; - window->SetWindowCollapsedAllowFlags &= ~ImGuiCond_FirstUseEver; - } + SetWindowConditionAllowFlags(window, ImGuiCond_FirstUseEver, false); if (settings->Pos.x != FLT_MAX) { @@ -4134,11 +4135,11 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->CloseButton = (p_open != NULL); // Process SetNextWindow***() calls + if (window->Appearing) + SetWindowConditionAllowFlags(window, ImGuiCond_Appearing, true); bool window_pos_set_by_api = false, window_size_set_by_api = false; if (g.SetNextWindowPosCond) { - if (window->Appearing) - window->SetWindowPosAllowFlags |= ImGuiCond_Appearing; window_pos_set_by_api = (window->SetWindowPosAllowFlags & g.SetNextWindowPosCond) != 0; if (window_pos_set_by_api && ImLengthSqr(g.SetNextWindowPosPivot) > 0.00001f) { @@ -4156,8 +4157,6 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) } if (g.SetNextWindowSizeCond) { - if (window->Appearing) - window->SetWindowSizeAllowFlags |= ImGuiCond_Appearing; window_size_set_by_api = (window->SetWindowSizeAllowFlags & g.SetNextWindowSizeCond) != 0; SetWindowSize(window, g.SetNextWindowSizeVal, g.SetNextWindowSizeCond); g.SetNextWindowSizeCond = 0; @@ -4173,8 +4172,6 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) } if (g.SetNextWindowCollapsedCond) { - if (window->Appearing) - window->SetWindowCollapsedAllowFlags |= ImGuiCond_Appearing; SetWindowCollapsed(window, g.SetNextWindowCollapsedVal, g.SetNextWindowCollapsedCond); g.SetNextWindowCollapsedCond = 0; } @@ -4183,6 +4180,8 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) SetWindowFocus(); g.SetNextWindowFocus = false; } + if (window->Appearing) + SetWindowConditionAllowFlags(window, ImGuiCond_Appearing, false); // When reusing window again multiple times a frame, just append content (don't need to setup again) if (first_begin_of_the_frame) From 834fa52c8ed2af4cf9c34dc9d88279d425632294 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 16 Nov 2017 17:34:34 +0100 Subject: [PATCH 574/921] Columns: Added ImGuiColumnsFlags_GrowParentContentsSize to internal API to restore old content sizes behavior. (#1444, #125) --- imgui.cpp | 3 ++- imgui_internal.h | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 832904baf..9c50555f7 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -10515,7 +10515,8 @@ void ImGui::EndColumns() window->DC.ColumnsCellMaxY = ImMax(window->DC.ColumnsCellMaxY, window->DC.CursorPos.y); window->DC.CursorPos.y = window->DC.ColumnsCellMaxY; - window->DC.CursorMaxPos.x = ImMax(window->DC.ColumnsStartMaxPosX, window->DC.ColumnsMaxX); // Columns don't grow parent + if (!(window->DC.ColumnsFlags & ImGuiColumnsFlags_GrowParentContentsSize)) + window->DC.CursorMaxPos.x = ImMax(window->DC.ColumnsStartMaxPosX, window->DC.ColumnsMaxX); // Restore cursor max pos, as columns don't grow parent // Draw columns borders and handle resize if (!(window->DC.ColumnsFlags & ImGuiColumnsFlags_NoBorder) && !window->SkipItems) diff --git a/imgui_internal.h b/imgui_internal.h index 6a081dfb6..c7600655e 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -194,7 +194,8 @@ enum ImGuiColumnsFlags_ ImGuiColumnsFlags_NoBorder = 1 << 0, // Disable column dividers ImGuiColumnsFlags_NoResize = 1 << 1, // Disable resizing columns when clicking on the dividers ImGuiColumnsFlags_NoPreserveWidths = 1 << 2, // Disable column width preservation when adjusting columns - ImGuiColumnsFlags_NoForceWithinWindow = 1 << 3 // Disable forcing columns to fit within window + ImGuiColumnsFlags_NoForceWithinWindow = 1 << 3, // Disable forcing columns to fit within window + ImGuiColumnsFlags_GrowParentContentsSize= 1 << 4, // (WIP) Restore pre-1.51 behavior of extending the parent window contents size but _without affecting the columns width at all_. Will eventually remove. }; enum ImGuiSelectableFlagsPrivate_ From f5871c0b92c88a1c1bbb8eaeff29cf29ba7ffeac Mon Sep 17 00:00:00 2001 From: Francisco Demartino Date: Thu, 16 Nov 2017 21:45:21 -0300 Subject: [PATCH 575/921] fix uninitialized atlas packing context --- imgui_draw.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 1b173e859..11847dce0 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1566,7 +1566,7 @@ bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas) // Start packing const int max_tex_height = 1024*32; - stbtt_pack_context spc; + stbtt_pack_context spc = {}; stbtt_PackBegin(&spc, NULL, atlas->TexWidth, max_tex_height, 0, atlas->TexGlyphPadding, NULL); stbtt_PackSetOversampling(&spc, 1, 1); From da2be7bbdce1b0260330a8ee46df462101baf202 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 17 Nov 2017 21:29:37 +0100 Subject: [PATCH 576/921] Style: ScaleAllSizes() helper rounds down every values so they are aligned on integers. --- imgui.cpp | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 9c50555f7..0eb5f81a3 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -726,26 +726,26 @@ ImGuiStyle::ImGuiStyle() } // To scale your entire UI (e.g. if you want your app to use High DPI or generally be DPI aware) you may use this helper function. Scaling the fonts is done separately and is up to you. -// Tips: if you need to change your scale multiple times, prefer calling this on a freshly initialized ImGuiStyle structure rather than scaling multiple times (because floating point multiplications are lossy). +// Important: This operation is lossy because we round all sizes to integer. If you need to change your scale multiples, call this over a freshly initialized ImGuiStyle structure rather than scaling multiple times. void ImGuiStyle::ScaleAllSizes(float scale_factor) { - WindowPadding *= scale_factor; - WindowMinSize *= scale_factor; - WindowRounding *= scale_factor; - ChildWindowRounding *= scale_factor; - FramePadding *= scale_factor; - FrameRounding *= scale_factor; - ItemSpacing *= scale_factor; - ItemInnerSpacing *= scale_factor; - TouchExtraPadding *= scale_factor; - IndentSpacing *= scale_factor; - ColumnsMinSpacing *= scale_factor; - ScrollbarSize *= scale_factor; - ScrollbarRounding *= scale_factor; - GrabMinSize *= scale_factor; - GrabRounding *= scale_factor; - DisplayWindowPadding *= scale_factor; - DisplaySafeAreaPadding *= scale_factor; + WindowPadding = ImFloor(WindowPadding * scale_factor); + WindowMinSize = ImFloor(WindowMinSize * scale_factor); + WindowRounding = ImFloor(WindowRounding * scale_factor); + ChildWindowRounding = ImFloor(ChildWindowRounding * scale_factor); + FramePadding = ImFloor(FramePadding * scale_factor); + FrameRounding = ImFloor(FrameRounding * scale_factor); + ItemSpacing = ImFloor(ItemSpacing * scale_factor); + ItemInnerSpacing = ImFloor(ItemInnerSpacing * scale_factor); + TouchExtraPadding = ImFloor(TouchExtraPadding * scale_factor); + IndentSpacing = ImFloor(IndentSpacing * scale_factor); + ColumnsMinSpacing = ImFloor(ColumnsMinSpacing * scale_factor); + ScrollbarSize = ImFloor(ScrollbarSize * scale_factor); + ScrollbarRounding = ImFloor(ScrollbarRounding * scale_factor); + GrabMinSize = ImFloor(GrabMinSize * scale_factor); + GrabRounding = ImFloor(GrabRounding * scale_factor); + DisplayWindowPadding = ImFloor(DisplayWindowPadding * scale_factor); + DisplaySafeAreaPadding = ImFloor(DisplaySafeAreaPadding * scale_factor); } ImGuiIO::ImGuiIO() From 979fe30a6f4307fdc83b08a7e845370a766c761c Mon Sep 17 00:00:00 2001 From: Codecat Date: Sat, 18 Nov 2017 13:56:59 +0100 Subject: [PATCH 577/921] Fix wrong comment in dx implementation headers --- examples/directx10_example/imgui_impl_dx10.h | 2 +- examples/directx11_example/imgui_impl_dx11.h | 2 +- examples/directx9_example/imgui_impl_dx9.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/directx10_example/imgui_impl_dx10.h b/examples/directx10_example/imgui_impl_dx10.h index 7877e775a..38a03a27e 100644 --- a/examples/directx10_example/imgui_impl_dx10.h +++ b/examples/directx10_example/imgui_impl_dx10.h @@ -20,5 +20,5 @@ IMGUI_API bool ImGui_ImplDX10_CreateDeviceObjects(); // You may or not need this for your implementation, but it can serve as reference for handling inputs. // Commented out to avoid dragging dependencies on types. You can copy the extern declaration in your code. /* -IMGUI_API LRESULT ImGui_ImplDX10_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); +IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); */ diff --git a/examples/directx11_example/imgui_impl_dx11.h b/examples/directx11_example/imgui_impl_dx11.h index 7d6f710fd..36066746d 100644 --- a/examples/directx11_example/imgui_impl_dx11.h +++ b/examples/directx11_example/imgui_impl_dx11.h @@ -21,5 +21,5 @@ IMGUI_API bool ImGui_ImplDX11_CreateDeviceObjects(); // You may or not need this for your implementation, but it can serve as reference for handling inputs. // Commented out to avoid dragging dependencies on types. You can copy the extern declaration in your code. /* -IMGUI_API LRESULT ImGui_ImplDX11_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); +IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); */ diff --git a/examples/directx9_example/imgui_impl_dx9.h b/examples/directx9_example/imgui_impl_dx9.h index 090ca9987..acaed5318 100644 --- a/examples/directx9_example/imgui_impl_dx9.h +++ b/examples/directx9_example/imgui_impl_dx9.h @@ -20,5 +20,5 @@ IMGUI_API bool ImGui_ImplDX9_CreateDeviceObjects(); // You may or not need this for your implementation, but it can serve as reference for handling inputs. // Commented out to avoid dragging dependencies on types. You can copy the extern declaration in your code. /* -IMGUI_API LRESULT ImGui_ImplDX9_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); +IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); */ From bd4bc929ce133a60799892cb4272ace9fa598976 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 18 Nov 2017 18:28:21 +0100 Subject: [PATCH 578/921] Style: renamed style.ChildWindowRounding to style.ChildRounding, ImGuiStyleVar_ChildWindowRounding to ImGuiStyleVar_ChildRounding. --- imgui.cpp | 13 +++++++------ imgui.h | 9 +++++++-- imgui_demo.cpp | 4 ++-- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 0eb5f81a3..c8a72445e 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -214,6 +214,7 @@ Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. Also read releases logs https://github.com/ocornut/imgui/releases for more details. + - 2017/11/18 (1.53) - renamed style.ChildWindowRounding to style.ChildRounding, ImGuiStyleVar_ChildWindowRounding to ImGuiStyleVar_ChildRounding - 2017/11/02 (1.53) - marked IsRootWindowOrAnyChildHovered() as obsolete is favor of using IsWindowHovered(ImGuiHoveredFlags_FlattenChilds); - 2017/10/24 (1.52) - renamed IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCS/IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCS to IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS/IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS for consistency. - 2017/10/20 (1.52) - changed IsWindowHovered() default parameters behavior to return false if an item is active in another window (e.g. click-dragging item from another window to this window). You can use the newly introduced IsWindowHovered() flags to requests this specific behavior if you need it. @@ -703,7 +704,7 @@ ImGuiStyle::ImGuiStyle() WindowMinSize = ImVec2(32,32); // Minimum window size WindowRounding = 9.0f; // Radius of window corners rounding. Set to 0.0f to have rectangular windows WindowTitleAlign = ImVec2(0.0f,0.5f);// Alignment for title bar text - ChildWindowRounding = 0.0f; // Radius of child window corners rounding. Set to 0.0f to have rectangular child windows + ChildRounding = 0.0f; // Radius of child window corners rounding. Set to 0.0f to have rectangular child 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). ItemSpacing = ImVec2(8,4); // Horizontal and vertical spacing between widgets/lines @@ -732,7 +733,7 @@ void ImGuiStyle::ScaleAllSizes(float scale_factor) WindowPadding = ImFloor(WindowPadding * scale_factor); WindowMinSize = ImFloor(WindowMinSize * scale_factor); WindowRounding = ImFloor(WindowRounding * scale_factor); - ChildWindowRounding = ImFloor(ChildWindowRounding * scale_factor); + ChildRounding = ImFloor(ChildRounding * scale_factor); FramePadding = ImFloor(FramePadding * scale_factor); FrameRounding = ImFloor(FrameRounding * scale_factor); ItemSpacing = ImFloor(ItemSpacing * scale_factor); @@ -3863,7 +3864,7 @@ bool ImGui::BeginChildFrame(ImGuiID id, const ImVec2& size, ImGuiWindowFlags ext ImGuiContext& g = *GImGui; const ImGuiStyle& style = g.Style; PushStyleColor(ImGuiCol_ChildWindowBg, style.Colors[ImGuiCol_FrameBg]); - PushStyleVar(ImGuiStyleVar_ChildWindowRounding, style.FrameRounding); + PushStyleVar(ImGuiStyleVar_ChildRounding, style.FrameRounding); PushStyleVar(ImGuiStyleVar_WindowPadding, style.FramePadding); return BeginChild(id, size, (g.CurrentWindow->Flags & ImGuiWindowFlags_ShowBorders) ? true : false, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysUseWindowPadding | extra_flags); } @@ -4390,7 +4391,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // Draw window + handle manual resize ImRect title_bar_rect = window->TitleBarRect(); - const float window_rounding = (flags & ImGuiWindowFlags_ChildWindow) ? style.ChildWindowRounding : style.WindowRounding; + const float window_rounding = (flags & ImGuiWindowFlags_ChildWindow) ? style.ChildRounding : style.WindowRounding; if (window->Collapsed) { // Title bar only @@ -4710,7 +4711,7 @@ void ImGui::Scrollbar(ImGuiLayoutType direction) if (bb.GetWidth() <= 0.0f || bb.GetHeight() <= 0.0f) return; - float window_rounding = (window->Flags & ImGuiWindowFlags_ChildWindow) ? style.ChildWindowRounding : style.WindowRounding; + float window_rounding = (window->Flags & ImGuiWindowFlags_ChildWindow) ? style.ChildRounding : style.WindowRounding; int window_rounding_corners; if (horizontal) window_rounding_corners = ImGuiCorner_BotLeft | (other_scrollbar ? 0 : ImGuiCorner_BotRight); @@ -5033,7 +5034,7 @@ static const ImGuiStyleVarInfo GStyleVarInfo[ImGuiStyleVar_Count_] = { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowPadding) }, // ImGuiStyleVar_WindowPadding { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowRounding) }, // ImGuiStyleVar_WindowRounding { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowMinSize) }, // ImGuiStyleVar_WindowMinSize - { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, ChildWindowRounding) }, // ImGuiStyleVar_ChildWindowRounding + { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, ChildRounding) }, // ImGuiStyleVar_ChildRounding { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, FramePadding) }, // ImGuiStyleVar_FramePadding { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, FrameRounding) }, // ImGuiStyleVar_FrameRounding { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, ItemSpacing) }, // ImGuiStyleVar_ItemSpacing diff --git a/imgui.h b/imgui.h index 42098322d..5ae5a0aec 100644 --- a/imgui.h +++ b/imgui.h @@ -672,7 +672,7 @@ enum ImGuiStyleVar_ ImGuiStyleVar_WindowPadding, // ImVec2 WindowPadding ImGuiStyleVar_WindowRounding, // float WindowRounding ImGuiStyleVar_WindowMinSize, // ImVec2 WindowMinSize - ImGuiStyleVar_ChildWindowRounding, // float ChildWindowRounding + ImGuiStyleVar_ChildRounding, // float ChildRounding ImGuiStyleVar_FramePadding, // ImVec2 FramePadding ImGuiStyleVar_FrameRounding, // float FrameRounding ImGuiStyleVar_ItemSpacing, // ImVec2 ItemSpacing @@ -681,6 +681,11 @@ enum ImGuiStyleVar_ ImGuiStyleVar_GrabMinSize, // float GrabMinSize ImGuiStyleVar_ButtonTextAlign, // ImVec2 ButtonTextAlign ImGuiStyleVar_Count_ + + // Obsolete names (will be removed) +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS + , ImGuiStyleVar_ChildWindowRounding = ImGuiStyleVar_ChildRounding +#endif }; // Enumeration for ColorEdit3() / ColorEdit4() / ColorPicker3() / ColorPicker4() / ColorButton() @@ -749,7 +754,7 @@ struct ImGuiStyle ImVec2 WindowMinSize; // Minimum window size float WindowRounding; // Radius of window corners rounding. Set to 0.0f to have rectangular windows ImVec2 WindowTitleAlign; // Alignment for title bar text. Defaults to (0.0f,0.5f) for left-aligned,vertically centered. - float ChildWindowRounding; // Radius of child window corners rounding. Set to 0.0f to have rectangular windows + float ChildRounding; // 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). ImVec2 ItemSpacing; // Horizontal and vertical spacing between widgets/lines diff --git a/imgui_demo.cpp b/imgui_demo.cpp index c627f5bdc..0e9979599 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1000,7 +1000,7 @@ void ImGui::ShowTestWindow(bool* p_open) ImGui::SameLine(); - ImGui::PushStyleVar(ImGuiStyleVar_ChildWindowRounding, 5.0f); + ImGui::PushStyleVar(ImGuiStyleVar_ChildRounding, 5.0f); ImGui::BeginChild("Sub2", ImVec2(0,300), true); ImGui::Text("With border"); ImGui::Columns(2); @@ -1883,7 +1883,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) { ImGui::SliderFloat2("WindowPadding", (float*)&style.WindowPadding, 0.0f, 20.0f, "%.0f"); ImGui::SliderFloat("WindowRounding", &style.WindowRounding, 0.0f, 16.0f, "%.0f"); - ImGui::SliderFloat("ChildWindowRounding", &style.ChildWindowRounding, 0.0f, 16.0f, "%.0f"); + ImGui::SliderFloat("ChildRounding", &style.ChildRounding, 0.0f, 16.0f, "%.0f"); ImGui::SliderFloat2("FramePadding", (float*)&style.FramePadding, 0.0f, 20.0f, "%.0f"); ImGui::SliderFloat("FrameRounding", &style.FrameRounding, 0.0f, 16.0f, "%.0f"); ImGui::SliderFloat2("ItemSpacing", (float*)&style.ItemSpacing, 0.0f, 20.0f, "%.0f"); From 29e0078b6637e43b559048c33f8f7309d41f473e Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 18 Nov 2017 19:02:02 +0100 Subject: [PATCH 579/921] Internals: Window minor internal renaming + added WindowRounding latch. --- imgui.cpp | 25 +++++++++++++------------ imgui_internal.h | 5 +++-- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index c8a72445e..275516c7a 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1789,13 +1789,14 @@ ImGuiWindow::ImGuiWindow(const char* name) Size = SizeFull = ImVec2(0.0f, 0.0f); SizeContents = SizeContentsExplicit = ImVec2(0.0f, 0.0f); WindowPadding = ImVec2(0.0f, 0.0f); + WindowRounding = 0.0f; + WindowBorderSize = 0.0f; MoveId = GetID("#MOVE"); Scroll = ImVec2(0.0f, 0.0f); ScrollTarget = ImVec2(FLT_MAX, FLT_MAX); ScrollTargetCenterRatio = ImVec2(0.5f, 0.5f); ScrollbarX = ScrollbarY = false; ScrollbarSizes = ImVec2(0.0f, 0.0f); - BorderSize = 0.0f; Active = WasActive = false; Accessed = false; Collapsed = false; @@ -4260,6 +4261,9 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->WindowPadding = style.WindowPadding; if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & (ImGuiWindowFlags_AlwaysUseWindowPadding | ImGuiWindowFlags_ShowBorders | ImGuiWindowFlags_ComboBox | ImGuiWindowFlags_Popup))) window->WindowPadding = ImVec2(0.0f, (flags & ImGuiWindowFlags_MenuBar) ? style.WindowPadding.y : 0.0f); + window->WindowRounding = (flags & ImGuiWindowFlags_ChildWindow) ? style.ChildRounding : style.WindowRounding; + window->WindowBorderSize = (flags & ImGuiWindowFlags_ShowBorders) ? 1.0f : 0.0f; + const float window_rounding = window->WindowRounding; // Calculate auto-fit size, handle automatic resize const ImVec2 size_auto_fit = CalcSizeAutoFit(window); @@ -4308,7 +4312,6 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) if (window->ScrollbarX && !window->ScrollbarY) window->ScrollbarY = (window->SizeContents.y > window->SizeFull.y + style.ItemSpacing.y - style.ScrollbarSize) && !(flags & ImGuiWindowFlags_NoScrollbar); window->ScrollbarSizes = ImVec2(window->ScrollbarY ? style.ScrollbarSize : 0.0f, window->ScrollbarX ? style.ScrollbarSize : 0.0f); - window->BorderSize = (flags & ImGuiWindowFlags_ShowBorders) ? 1.0f : 0.0f; } // POSITION @@ -4391,7 +4394,6 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // Draw window + handle manual resize ImRect title_bar_rect = window->TitleBarRect(); - const float window_rounding = (flags & ImGuiWindowFlags_ChildWindow) ? style.ChildRounding : style.WindowRounding; if (window->Collapsed) { // Title bar only @@ -4465,9 +4467,9 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) if (!(flags & ImGuiWindowFlags_NoResize)) { const ImVec2 br = window->Rect().GetBR(); - window->DrawList->PathLineTo(br + ImVec2(-resize_corner_size, -window->BorderSize)); - window->DrawList->PathLineTo(br + ImVec2(-window->BorderSize, -resize_corner_size)); - window->DrawList->PathArcToFast(ImVec2(br.x - window_rounding - window->BorderSize, br.y - window_rounding - window->BorderSize), window_rounding, 0, 3); + window->DrawList->PathLineTo(br + ImVec2(-resize_corner_size, -window->WindowBorderSize)); + window->DrawList->PathLineTo(br + ImVec2(-window->WindowBorderSize, -resize_corner_size)); + window->DrawList->PathArcToFast(ImVec2(br.x - window_rounding - window->WindowBorderSize, br.y - window_rounding - window->WindowBorderSize), window_rounding, 0, 3); window->DrawList->PathFillConvex(resize_col); } @@ -4598,7 +4600,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // Inner clipping rectangle // Force round operator last to ensure that e.g. (int)(max.x-min.x) in user's render code produce correct result. - const float border_size = window->BorderSize; + const float border_size = window->WindowBorderSize; ImRect clip_rect; clip_rect.Min.x = ImFloor(0.5f + window->InnerRect.Min.x + ImMax(border_size, ImFloor(window->WindowPadding.x*0.5f))); clip_rect.Min.y = ImFloor(0.5f + window->InnerRect.Min.y + border_size); @@ -4702,7 +4704,7 @@ void ImGui::Scrollbar(ImGuiLayoutType direction) bool other_scrollbar = (horizontal ? window->ScrollbarY : window->ScrollbarX); float other_scrollbar_size_w = other_scrollbar ? style.ScrollbarSize : 0.0f; const ImRect window_rect = window->Rect(); - const float border_size = window->BorderSize; + const float border_size = window->WindowBorderSize; ImRect bb = horizontal ? ImRect(window->Pos.x + border_size, window_rect.Max.y - style.ScrollbarSize, window_rect.Max.x - other_scrollbar_size_w - border_size, window_rect.Max.y - border_size) : ImRect(window_rect.Max.x - style.ScrollbarSize, window->Pos.y + border_size, window_rect.Max.x - border_size, window_rect.Max.y - other_scrollbar_size_w - border_size); @@ -4711,13 +4713,12 @@ void ImGui::Scrollbar(ImGuiLayoutType direction) if (bb.GetWidth() <= 0.0f || bb.GetHeight() <= 0.0f) return; - float window_rounding = (window->Flags & ImGuiWindowFlags_ChildWindow) ? style.ChildRounding : style.WindowRounding; int window_rounding_corners; if (horizontal) window_rounding_corners = ImGuiCorner_BotLeft | (other_scrollbar ? 0 : ImGuiCorner_BotRight); else window_rounding_corners = (((window->Flags & ImGuiWindowFlags_NoTitleBar) && !(window->Flags & ImGuiWindowFlags_MenuBar)) ? ImGuiCorner_TopRight : 0) | (other_scrollbar ? 0 : ImGuiCorner_BotRight); - window->DrawList->AddRectFilled(bb.Min, bb.Max, GetColorU32(ImGuiCol_ScrollbarBg), window_rounding, window_rounding_corners); + window->DrawList->AddRectFilled(bb.Min, bb.Max, GetColorU32(ImGuiCol_ScrollbarBg), window->WindowRounding, window_rounding_corners); bb.Expand(ImVec2(-ImClamp((float)(int)((bb.Max.x - bb.Min.x - 2.0f) * 0.5f), 0.0f, 3.0f), -ImClamp((float)(int)((bb.Max.y - bb.Min.y - 2.0f) * 0.5f), 0.0f, 3.0f))); // V denote the main, longer axis of the scrollbar (= height for a vertical scrollbar) @@ -7610,7 +7611,7 @@ void ImGui::ProgressBar(float fraction, const ImVec2& size_arg, const char* over // Render fraction = ImSaturate(fraction); RenderFrame(bb.Min, bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding); - bb.Expand(ImVec2(-window->BorderSize, -window->BorderSize)); + bb.Expand(ImVec2(-window->WindowBorderSize, -window->WindowBorderSize)); const ImVec2 fill_br = ImVec2(ImLerp(bb.Min.x, bb.Max.x, fraction), bb.Max.y); RenderRectFilledRangeH(window->DrawList, bb, GetColorU32(ImGuiCol_PlotHistogram), 0.0f, fraction, style.FrameRounding); @@ -9219,7 +9220,7 @@ bool ImGui::BeginMenuBar() PushID("##menubar"); ImRect rect = window->MenuBarRect(); rect.Max.x = ImMax(rect.Min.x, rect.Max.x - g.Style.WindowRounding); - PushClipRect(ImVec2(ImFloor(rect.Min.x+0.5f), ImFloor(rect.Min.y + window->BorderSize + 0.5f)), ImVec2(ImFloor(rect.Max.x+0.5f), ImFloor(rect.Max.y+0.5f)), false); + PushClipRect(ImVec2(ImFloor(rect.Min.x+0.5f), ImFloor(rect.Min.y + window->WindowBorderSize + 0.5f)), ImVec2(ImFloor(rect.Max.x+0.5f), ImFloor(rect.Max.y+0.5f)), false); window->DC.CursorPos = ImVec2(rect.Min.x + window->DC.MenuBarOffsetX, rect.Min.y);// + g.Style.FramePadding.y); window->DC.LayoutType = ImGuiLayoutType_Horizontal; window->DC.MenuBarAppending = true; diff --git a/imgui_internal.h b/imgui_internal.h index c7600655e..0d21c633a 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -687,14 +687,15 @@ struct IMGUI_API ImGuiWindow ImVec2 SizeContents; // Size of contents (== extents reach of the drawing cursor) from previous frame ImVec2 SizeContentsExplicit; // Size of contents explicitly set by the user via SetNextWindowContentSize() ImRect ContentsRegionRect; // Maximum visible content position in window coordinates. ~~ (SizeContentsExplicit ? SizeContentsExplicit : Size - ScrollbarSizes) - CursorStartPos, per axis - ImVec2 WindowPadding; // Window padding at the time of begin. We need to lock it, in particular manipulation of the ShowBorder would have an effect + ImVec2 WindowPadding; // Window padding at the time of begin. + float WindowRounding; // Window rounding at the time of begin. + float WindowBorderSize; // Window border size at the time of begin. ImGuiID MoveId; // == window->GetID("#MOVE") ImVec2 Scroll; ImVec2 ScrollTarget; // target scroll position. stored as cursor position with scrolling canceled out, so the highest point is always 0.0f. (FLT_MAX for no change) ImVec2 ScrollTargetCenterRatio; // 0.0f = scroll so that target position is at top, 0.5f = scroll so that target position is centered bool ScrollbarX, ScrollbarY; ImVec2 ScrollbarSizes; - float BorderSize; bool Active; // Set to true on Begin() bool WasActive; bool Accessed; // Set to true when any widget access the current window From 331eac511e7234db069660810cfe6ed2cdb8d609 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 18 Nov 2017 19:08:52 +0100 Subject: [PATCH 580/921] Style: Dark: Tweaks + setting BorderShadow correctly. --- imgui_draw.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 1b173e859..776365b50 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -177,11 +177,12 @@ void ImGui::StyleColorsDark(ImGuiStyle* dst) ImVec4* colors = style->Colors; colors[ImGuiCol_Text] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f); - colors[ImGuiCol_TextDisabled] = ImVec4(0.40f, 0.40f, 0.40f, 1.00f); + colors[ImGuiCol_TextDisabled] = ImVec4(0.50f, 0.50f, 0.50f, 1.00f); colors[ImGuiCol_WindowBg] = ImVec4(0.06f, 0.06f, 0.06f, 0.94f); - colors[ImGuiCol_Border] = ImVec4(1.00f, 1.00f, 1.00f, 0.19f); colors[ImGuiCol_ChildWindowBg] = ImVec4(1.00f, 1.00f, 1.00f, 0.00f); colors[ImGuiCol_PopupBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.94f); + colors[ImGuiCol_Border] = ImVec4(1.00f, 1.00f, 1.00f, 0.19f); + colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); colors[ImGuiCol_FrameBg] = ImVec4(0.16f, 0.29f, 0.48f, 0.54f); colors[ImGuiCol_FrameBgHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.40f); colors[ImGuiCol_FrameBgActive] = ImVec4(0.26f, 0.59f, 0.98f, 0.67f); From c1b5eab8685e9898e81819ea372be5886002b4d5 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 18 Nov 2017 19:10:01 +0100 Subject: [PATCH 581/921] Style Editor: Sneakily adding a combo box to change colors (#707) --- imgui_demo.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 0e9979599..c138d2362 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1852,6 +1852,16 @@ void ImGui::ShowTestWindow(bool* p_open) void ImGui::ShowStyleEditor(ImGuiStyle* ref) { ImGuiStyle& style = ImGui::GetStyle(); + ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.55f); + + // Style selector + static int style_idx = 0; + if (ImGui::Combo("Colors##Selector", &style_idx, "Classic\0Dark\0")) + switch (style_idx) + { + case 0: ImGui::StyleColorsClassic(); break; + case 1: ImGui::StyleColorsDark(); break; + } // You can pass in a reference ImGuiStyle structure to compare to, revert to and save to (else it compares to the default style) const ImGuiStyle default_style; // Default style @@ -1865,8 +1875,6 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) *ref = style; } - ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.55f); - if (ImGui::TreeNode("Rendering")) { ImGui::Checkbox("Anti-aliased lines", &style.AntiAliasedLines); ImGui::SameLine(); ShowHelpMarker("When disabling anti-aliasing lines, you'll probably want to disable borders in your style as well."); From 1c41603b31d059b7ac27689de68c8d746e405126 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 18 Nov 2017 21:59:50 +0100 Subject: [PATCH 582/921] Style Editor: Using local storage so Save/Revert button made some more sense without code passing its storage. Tweaked layout, added horizontal scroll bar, Fixed Save/Revert button to be always accessible. (fix #1211) --- imgui_demo.cpp | 59 +++++++++++++++++++++++++++++++------------------- 1 file changed, 37 insertions(+), 22 deletions(-) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index c138d2362..f06464c65 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1851,30 +1851,41 @@ void ImGui::ShowTestWindow(bool* p_open) void ImGui::ShowStyleEditor(ImGuiStyle* ref) { + // You can pass in a reference ImGuiStyle structure to compare to, revert to and save to (else it compares to an internally stored reference) ImGuiStyle& style = ImGui::GetStyle(); - ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.55f); + static ImGuiStyle ref_saved_style; - // Style selector + // Default to using internal storage as reference + static bool init = true; + if (init && ref == NULL) + ref_saved_style = style; + init = false; + if (ref == NULL) + ref = &ref_saved_style; + + ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.50f); + + // Default Styles Selector static int style_idx = 0; if (ImGui::Combo("Colors##Selector", &style_idx, "Classic\0Dark\0")) + { switch (style_idx) { case 0: ImGui::StyleColorsClassic(); break; case 1: ImGui::StyleColorsDark(); break; } - - // You can pass in a reference ImGuiStyle structure to compare to, revert to and save to (else it compares to the default style) - const ImGuiStyle default_style; // Default style - if (ImGui::Button("Revert Style")) - style = ref ? *ref : default_style; - - if (ref) - { - ImGui::SameLine(); - if (ImGui::Button("Save Style")) - *ref = style; + ref_saved_style = style; } + // Save/Revert button + if (ImGui::Button("Save Ref")) + *ref = ref_saved_style = style; + ImGui::SameLine(); + if (ImGui::Button("Revert Ref")) + style = *ref; + ImGui::SameLine(); + ShowHelpMarker("Save/Revert in local non-persistent storage. Default Colors definition are not affected. Use \"Export Colors\" below to save them somewhere."); + if (ImGui::TreeNode("Rendering")) { ImGui::Checkbox("Anti-aliased lines", &style.AntiAliasedLines); ImGui::SameLine(); ShowHelpMarker("When disabling anti-aliasing lines, you'll probably want to disable borders in your style as well."); @@ -1911,8 +1922,8 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) if (ImGui::TreeNode("Colors")) { static int output_dest = 0; - static bool output_only_modified = false; - if (ImGui::Button("Copy Colors")) + static bool output_only_modified = true; + if (ImGui::Button("Export Unsaved")) { if (output_dest == 0) ImGui::LogToClipboard(); @@ -1923,13 +1934,13 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) { const ImVec4& col = style.Colors[i]; const char* name = ImGui::GetStyleColorName(i); - if (!output_only_modified || memcmp(&col, (ref ? &ref->Colors[i] : &default_style.Colors[i]), sizeof(ImVec4)) != 0) + if (!output_only_modified || memcmp(&col, &ref->Colors[i], sizeof(ImVec4)) != 0) ImGui::LogText("colors[ImGuiCol_%s]%*s= ImVec4(%.2ff, %.2ff, %.2ff, %.2ff);" IM_NEWLINE, name, 23-(int)strlen(name), "", col.x, col.y, col.z, col.w); } ImGui::LogFinish(); } ImGui::SameLine(); ImGui::PushItemWidth(120); ImGui::Combo("##output_type", &output_dest, "To Clipboard\0To TTY\0"); ImGui::PopItemWidth(); - ImGui::SameLine(); ImGui::Checkbox("Only Modified Fields", &output_only_modified); + ImGui::SameLine(); ImGui::Checkbox("Only Modified Colors", &output_only_modified); ImGui::Text("Tip: Left-click on colored square to open color picker,\nRight-click to open edit options menu."); @@ -1941,7 +1952,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) ImGui::RadioButton("Alpha", &alpha_flags, ImGuiColorEditFlags_AlphaPreview); ImGui::SameLine(); ImGui::RadioButton("Both", &alpha_flags, ImGuiColorEditFlags_AlphaPreviewHalf); - ImGui::BeginChild("#colors", ImVec2(0, 300), true, ImGuiWindowFlags_AlwaysVerticalScrollbar); + ImGui::BeginChild("#colors", ImVec2(0, 300), true, ImGuiWindowFlags_AlwaysVerticalScrollbar | ImGuiWindowFlags_AlwaysHorizontalScrollbar); ImGui::PushItemWidth(-160); for (int i = 0; i < ImGuiCol_COUNT; i++) { @@ -1949,12 +1960,16 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) if (!filter.PassFilter(name)) continue; ImGui::PushID(i); - ImGui::ColorEdit4(name, (float*)&style.Colors[i], ImGuiColorEditFlags_AlphaBar | alpha_flags); - if (memcmp(&style.Colors[i], (ref ? &ref->Colors[i] : &default_style.Colors[i]), sizeof(ImVec4)) != 0) + ImGui::ColorEdit4("##color", (float*)&style.Colors[i], ImGuiColorEditFlags_AlphaBar | alpha_flags); + if (memcmp(&style.Colors[i], &ref->Colors[i], sizeof(ImVec4)) != 0) { - ImGui::SameLine(); if (ImGui::Button("Revert")) style.Colors[i] = ref ? ref->Colors[i] : default_style.Colors[i]; - if (ref) { ImGui::SameLine(); if (ImGui::Button("Save")) ref->Colors[i] = style.Colors[i]; } + // Tips: in a real user application, you may want to merge and use an icon font into the main font, so instead of "Save"/"Revert" you'd use icons. + // Read the FAQ and extra_fonts/README.txt about using icon fonts. It's really easy and super convenient! + ImGui::SameLine(0.0f, style.ItemInnerSpacing.x); if (ImGui::Button("Save")) ref->Colors[i] = style.Colors[i]; + ImGui::SameLine(0.0f, style.ItemInnerSpacing.x); if (ImGui::Button("Revert")) style.Colors[i] = ref->Colors[i]; } + ImGui::SameLine(0.0f, style.ItemInnerSpacing.x); + ImGui::TextUnformatted(name); ImGui::PopID(); } ImGui::PopItemWidth(); From 58345b11e1a999ad3fb562a24aade7c6944e5a02 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 18 Nov 2017 23:16:40 +0100 Subject: [PATCH 583/921] Style: Removed ImGuiCol_ComboBg in favor of combo boxes using ImGuiCol_PopupBg for consistency. (#707) --- imgui.cpp | 6 ++---- imgui.h | 1 - imgui_draw.cpp | 2 -- 3 files changed, 2 insertions(+), 7 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 275516c7a..07cda4ddf 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -214,7 +214,8 @@ Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. Also read releases logs https://github.com/ocornut/imgui/releases for more details. - - 2017/11/18 (1.53) - renamed style.ChildWindowRounding to style.ChildRounding, ImGuiStyleVar_ChildWindowRounding to ImGuiStyleVar_ChildRounding + - 2017/11/18 (1.53) - Style: removed ImGuiCol_ComboBg in favor of combo boxes using ImGuiCol_PopupBg for consistency. + - 2017/11/18 (1.53) - Style: renamed style.ChildWindowRounding to style.ChildRounding, ImGuiStyleVar_ChildWindowRounding to ImGuiStyleVar_ChildRounding. - 2017/11/02 (1.53) - marked IsRootWindowOrAnyChildHovered() as obsolete is favor of using IsWindowHovered(ImGuiHoveredFlags_FlattenChilds); - 2017/10/24 (1.52) - renamed IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCS/IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCS to IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS/IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS for consistency. - 2017/10/20 (1.52) - changed IsWindowHovered() default parameters behavior to return false if an item is active in another window (e.g. click-dragging item from another window to this window). You can use the newly introduced IsWindowHovered() flags to requests this specific behavior if you need it. @@ -4068,8 +4069,6 @@ static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window) static ImGuiCol GetWindowBgColorIdxFromFlags(ImGuiWindowFlags flags) { - if (flags & ImGuiWindowFlags_ComboBox) - return ImGuiCol_ComboBg; if (flags & (ImGuiWindowFlags_Tooltip | ImGuiWindowFlags_Popup)) return ImGuiCol_PopupBg; if (flags & ImGuiWindowFlags_ChildWindow) @@ -5117,7 +5116,6 @@ const char* ImGui::GetStyleColorName(ImGuiCol idx) case ImGuiCol_ScrollbarGrab: return "ScrollbarGrab"; case ImGuiCol_ScrollbarGrabHovered: return "ScrollbarGrabHovered"; case ImGuiCol_ScrollbarGrabActive: return "ScrollbarGrabActive"; - case ImGuiCol_ComboBg: return "ComboBg"; case ImGuiCol_CheckMark: return "CheckMark"; case ImGuiCol_SliderGrab: return "SliderGrab"; case ImGuiCol_SliderGrabActive: return "SliderGrabActive"; diff --git a/imgui.h b/imgui.h index 5ae5a0aec..d25beea73 100644 --- a/imgui.h +++ b/imgui.h @@ -629,7 +629,6 @@ enum ImGuiCol_ ImGuiCol_ScrollbarGrab, ImGuiCol_ScrollbarGrabHovered, ImGuiCol_ScrollbarGrabActive, - ImGuiCol_ComboBg, ImGuiCol_CheckMark, ImGuiCol_SliderGrab, ImGuiCol_SliderGrabActive, diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 776365b50..26ef65423 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -144,7 +144,6 @@ void ImGui::StyleColorsClassic(ImGuiStyle* dst) colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.40f, 0.40f, 0.80f, 0.30f); colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.40f, 0.40f, 0.80f, 0.40f); colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.80f, 0.50f, 0.50f, 0.40f); - colors[ImGuiCol_ComboBg] = ImVec4(0.20f, 0.20f, 0.20f, 0.99f); colors[ImGuiCol_CheckMark] = ImVec4(0.90f, 0.90f, 0.90f, 0.50f); colors[ImGuiCol_SliderGrab] = ImVec4(1.00f, 1.00f, 1.00f, 0.30f); colors[ImGuiCol_SliderGrabActive] = ImVec4(0.80f, 0.50f, 0.50f, 1.00f); @@ -194,7 +193,6 @@ void ImGui::StyleColorsDark(ImGuiStyle* dst) colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.31f, 0.31f, 0.31f, 1.00f); colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.41f, 0.41f, 0.41f, 1.00f); colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.51f, 0.51f, 0.51f, 1.00f); - colors[ImGuiCol_ComboBg] = ImVec4(0.14f, 0.14f, 0.14f, 0.99f); colors[ImGuiCol_CheckMark] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); colors[ImGuiCol_SliderGrab] = ImVec4(0.24f, 0.52f, 0.88f, 1.00f); colors[ImGuiCol_SliderGrabActive] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); From e7e81b265d183245b5c8668fddf94ec0a5573e5a Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 18 Nov 2017 23:36:37 +0100 Subject: [PATCH 584/921] Demo: Tweaks. --- imgui_demo.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index f06464c65..b5a476f1b 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -2135,8 +2135,15 @@ static void ShowExampleMenuFile() } if (ImGui::BeginMenu("Colors")) { + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0,0)); for (int i = 0; i < ImGuiCol_COUNT; i++) - ImGui::MenuItem(ImGui::GetStyleColorName((ImGuiCol)i)); + { + const char* name = ImGui::GetStyleColorName((ImGuiCol)i); + ImGui::ColorButton(name, ImGui::GetStyleColorVec4((ImGuiCol)i)); + ImGui::SameLine(); + ImGui::MenuItem(name); + } + ImGui::PopStyleVar(); ImGui::EndMenu(); } if (ImGui::BeginMenu("Disabled", false)) // Disabled From 0a61b7195c4523f96bc7bfda670e6896711e8589 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 18 Nov 2017 23:53:11 +0100 Subject: [PATCH 585/921] Style: Added a default StyleColorsLight(). (#707) --- imgui.h | 1 + imgui_demo.cpp | 3 ++- imgui_draw.cpp | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 1 deletion(-) diff --git a/imgui.h b/imgui.h index d25beea73..8271ef4fb 100644 --- a/imgui.h +++ b/imgui.h @@ -417,6 +417,7 @@ namespace ImGui // Styles IMGUI_API void StyleColorsClassic(ImGuiStyle* dst = NULL); IMGUI_API void StyleColorsDark(ImGuiStyle* dst = NULL); + IMGUI_API void StyleColorsLight(ImGuiStyle* dst = NULL); // Utilities IMGUI_API bool IsItemHovered(ImGuiHoveredFlags flags = 0); // is the last item hovered by mouse (and usable)? diff --git a/imgui_demo.cpp b/imgui_demo.cpp index b5a476f1b..43b07577e 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1867,12 +1867,13 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) // Default Styles Selector static int style_idx = 0; - if (ImGui::Combo("Colors##Selector", &style_idx, "Classic\0Dark\0")) + if (ImGui::Combo("Colors##Selector", &style_idx, "Classic\0Dark\0Light\0")) { switch (style_idx) { case 0: ImGui::StyleColorsClassic(); break; case 1: ImGui::StyleColorsDark(); break; + case 2: ImGui::StyleColorsLight(); break; } ref_saved_style = style; } diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 26ef65423..c9ae392c9 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -219,6 +219,58 @@ void ImGui::StyleColorsDark(ImGuiStyle* dst) colors[ImGuiCol_ModalWindowDarkening] = ImVec4(0.80f, 0.80f, 0.80f, 0.35f); } +void ImGui::StyleColorsLight(ImGuiStyle* dst) +{ + ImGuiStyle* style = dst ? dst : &ImGui::GetStyle(); + ImVec4* colors = style->Colors; + + colors[ImGuiCol_Text] = ImVec4(0.00f, 0.00f, 0.00f, 1.00f); + colors[ImGuiCol_TextDisabled] = ImVec4(0.60f, 0.60f, 0.60f, 1.00f); + //colors[ImGuiCol_TextHovered] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f); + //colors[ImGuiCol_TextActive] = ImVec4(1.00f, 1.00f, 0.00f, 1.00f); + colors[ImGuiCol_WindowBg] = ImVec4(0.94f, 0.94f, 0.94f, 1.00f); + colors[ImGuiCol_ChildWindowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); + colors[ImGuiCol_PopupBg] = ImVec4(1.00f, 1.00f, 1.00f, 0.94f); + colors[ImGuiCol_Border] = ImVec4(0.00f, 0.00f, 0.00f, 0.30f); + colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); + colors[ImGuiCol_FrameBg] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f); + colors[ImGuiCol_FrameBgHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.40f); + colors[ImGuiCol_FrameBgActive] = ImVec4(0.26f, 0.59f, 0.98f, 0.67f); + colors[ImGuiCol_TitleBg] = ImVec4(0.96f, 0.96f, 0.96f, 1.00f); + colors[ImGuiCol_TitleBgCollapsed] = ImVec4(1.00f, 1.00f, 1.00f, 0.51f); + colors[ImGuiCol_TitleBgActive] = ImVec4(0.82f, 0.82f, 0.82f, 1.00f); + colors[ImGuiCol_MenuBarBg] = ImVec4(0.86f, 0.86f, 0.86f, 1.00f); + colors[ImGuiCol_ScrollbarBg] = ImVec4(0.98f, 0.98f, 0.98f, 0.53f); + colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.69f, 0.69f, 0.69f, 0.80f); + colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.49f, 0.49f, 0.49f, 0.80f); + colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.49f, 0.49f, 0.49f, 1.00f); + colors[ImGuiCol_CheckMark] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); + colors[ImGuiCol_SliderGrab] = ImVec4(0.26f, 0.59f, 0.98f, 0.78f); + colors[ImGuiCol_SliderGrabActive] = ImVec4(0.46f, 0.54f, 0.80f, 0.60f); + colors[ImGuiCol_Button] = ImVec4(0.26f, 0.59f, 0.98f, 0.40f); + colors[ImGuiCol_ButtonHovered] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); + colors[ImGuiCol_ButtonActive] = ImVec4(0.06f, 0.53f, 0.98f, 1.00f); + colors[ImGuiCol_Header] = ImVec4(0.26f, 0.59f, 0.98f, 0.31f); + colors[ImGuiCol_HeaderHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.80f); + colors[ImGuiCol_HeaderActive] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); + colors[ImGuiCol_Separator] = ImVec4(0.39f, 0.39f, 0.39f, 1.00f); + colors[ImGuiCol_SeparatorHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.78f); + colors[ImGuiCol_SeparatorActive] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); + colors[ImGuiCol_ResizeGrip] = ImVec4(0.80f, 0.80f, 0.80f, 0.56f); + colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.67f); + colors[ImGuiCol_ResizeGripActive] = ImVec4(0.26f, 0.59f, 0.98f, 0.95f); + colors[ImGuiCol_CloseButton] = ImVec4(0.59f, 0.59f, 0.59f, 0.50f); + colors[ImGuiCol_CloseButtonHovered] = ImVec4(0.98f, 0.39f, 0.36f, 1.00f); + colors[ImGuiCol_CloseButtonActive] = ImVec4(0.98f, 0.39f, 0.36f, 1.00f); + colors[ImGuiCol_PlotLines] = ImVec4(0.39f, 0.39f, 0.39f, 1.00f); + colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.43f, 0.35f, 1.00f); + colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); + colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.45f, 0.00f, 1.00f); + colors[ImGuiCol_TextSelectedBg] = ImVec4(0.26f, 0.59f, 0.98f, 0.35f); + colors[ImGuiCol_ModalWindowDarkening] = ImVec4(0.20f, 0.20f, 0.20f, 0.35f); +} + + //----------------------------------------------------------------------------- // ImDrawList //----------------------------------------------------------------------------- From 0e4f1df1a4d600059d9e4ba1821630b227992030 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 18 Nov 2017 23:56:15 +0100 Subject: [PATCH 586/921] Style: Made changes to Classic style (!!!). Tweaked Dark style. (#707) --- imgui_draw.cpp | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index c9ae392c9..3a934eabc 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -130,12 +130,12 @@ void ImGui::StyleColorsClassic(ImGuiStyle* dst) colors[ImGuiCol_TextDisabled] = ImVec4(0.60f, 0.60f, 0.60f, 1.00f); colors[ImGuiCol_WindowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.70f); colors[ImGuiCol_ChildWindowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); - colors[ImGuiCol_PopupBg] = ImVec4(0.05f, 0.05f, 0.10f, 0.90f); - colors[ImGuiCol_Border] = ImVec4(0.70f, 0.70f, 0.70f, 0.40f); + colors[ImGuiCol_PopupBg] = ImVec4(0.11f, 0.11f, 0.14f, 0.92f); + colors[ImGuiCol_Border] = ImVec4(0.70f, 0.70f, 0.70f, 0.27f); colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); - colors[ImGuiCol_FrameBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.30f); // Background of checkbox, radio button, plot, slider, text input - colors[ImGuiCol_FrameBgHovered] = ImVec4(0.90f, 0.80f, 0.80f, 0.40f); - colors[ImGuiCol_FrameBgActive] = ImVec4(0.90f, 0.65f, 0.65f, 0.45f); + colors[ImGuiCol_FrameBg] = ImVec4(0.43f, 0.43f, 0.43f, 0.39f); + colors[ImGuiCol_FrameBgHovered] = ImVec4(0.47f, 0.47f, 0.69f, 0.40f); + colors[ImGuiCol_FrameBgActive] = ImVec4(0.42f, 0.41f, 0.64f, 0.69f); colors[ImGuiCol_TitleBg] = ImVec4(0.27f, 0.27f, 0.54f, 0.83f); colors[ImGuiCol_TitleBgActive] = ImVec4(0.32f, 0.32f, 0.63f, 0.87f); colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.40f, 0.40f, 0.80f, 0.20f); @@ -143,22 +143,22 @@ void ImGui::StyleColorsClassic(ImGuiStyle* dst) colors[ImGuiCol_ScrollbarBg] = ImVec4(0.20f, 0.25f, 0.30f, 0.60f); colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.40f, 0.40f, 0.80f, 0.30f); colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.40f, 0.40f, 0.80f, 0.40f); - colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.80f, 0.50f, 0.50f, 0.40f); + colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.41f, 0.39f, 0.80f, 0.60f); colors[ImGuiCol_CheckMark] = ImVec4(0.90f, 0.90f, 0.90f, 0.50f); colors[ImGuiCol_SliderGrab] = ImVec4(1.00f, 1.00f, 1.00f, 0.30f); - colors[ImGuiCol_SliderGrabActive] = ImVec4(0.80f, 0.50f, 0.50f, 1.00f); - colors[ImGuiCol_Button] = ImVec4(0.67f, 0.40f, 0.40f, 0.60f); - colors[ImGuiCol_ButtonHovered] = ImVec4(0.67f, 0.40f, 0.40f, 1.00f); - colors[ImGuiCol_ButtonActive] = ImVec4(0.80f, 0.50f, 0.50f, 1.00f); + colors[ImGuiCol_SliderGrabActive] = ImVec4(0.41f, 0.39f, 0.80f, 0.60f); + colors[ImGuiCol_Button] = ImVec4(0.35f, 0.40f, 0.61f, 0.62f); + colors[ImGuiCol_ButtonHovered] = ImVec4(0.40f, 0.48f, 0.71f, 0.79f); + colors[ImGuiCol_ButtonActive] = ImVec4(0.46f, 0.54f, 0.80f, 1.00f); colors[ImGuiCol_Header] = ImVec4(0.40f, 0.40f, 0.90f, 0.45f); colors[ImGuiCol_HeaderHovered] = ImVec4(0.45f, 0.45f, 0.90f, 0.80f); colors[ImGuiCol_HeaderActive] = ImVec4(0.53f, 0.53f, 0.87f, 0.80f); colors[ImGuiCol_Separator] = ImVec4(0.50f, 0.50f, 0.50f, 1.00f); colors[ImGuiCol_SeparatorHovered] = ImVec4(0.60f, 0.60f, 0.70f, 1.00f); colors[ImGuiCol_SeparatorActive] = ImVec4(0.70f, 0.70f, 0.90f, 1.00f); - colors[ImGuiCol_ResizeGrip] = ImVec4(1.00f, 1.00f, 1.00f, 0.30f); - colors[ImGuiCol_ResizeGripHovered] = ImVec4(1.00f, 1.00f, 1.00f, 0.60f); - colors[ImGuiCol_ResizeGripActive] = ImVec4(1.00f, 1.00f, 1.00f, 0.90f); + colors[ImGuiCol_ResizeGrip] = ImVec4(1.00f, 1.00f, 1.00f, 0.16f); + colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.78f, 0.82f, 1.00f, 0.60f); + colors[ImGuiCol_ResizeGripActive] = ImVec4(0.78f, 0.82f, 1.00f, 0.90f); colors[ImGuiCol_CloseButton] = ImVec4(0.50f, 0.50f, 0.90f, 0.50f); colors[ImGuiCol_CloseButtonHovered] = ImVec4(0.70f, 0.70f, 0.90f, 0.60f); colors[ImGuiCol_CloseButtonActive] = ImVec4(0.70f, 0.70f, 0.70f, 1.00f); @@ -179,14 +179,14 @@ void ImGui::StyleColorsDark(ImGuiStyle* dst) colors[ImGuiCol_TextDisabled] = ImVec4(0.50f, 0.50f, 0.50f, 1.00f); colors[ImGuiCol_WindowBg] = ImVec4(0.06f, 0.06f, 0.06f, 0.94f); colors[ImGuiCol_ChildWindowBg] = ImVec4(1.00f, 1.00f, 1.00f, 0.00f); - colors[ImGuiCol_PopupBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.94f); - colors[ImGuiCol_Border] = ImVec4(1.00f, 1.00f, 1.00f, 0.19f); + colors[ImGuiCol_PopupBg] = ImVec4(0.08f, 0.08f, 0.08f, 0.94f); + colors[ImGuiCol_Border] = ImVec4(0.86f, 0.86f, 1.00f, 0.20f); colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); colors[ImGuiCol_FrameBg] = ImVec4(0.16f, 0.29f, 0.48f, 0.54f); colors[ImGuiCol_FrameBgHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.40f); colors[ImGuiCol_FrameBgActive] = ImVec4(0.26f, 0.59f, 0.98f, 0.67f); colors[ImGuiCol_TitleBg] = ImVec4(0.04f, 0.04f, 0.04f, 1.00f); - colors[ImGuiCol_TitleBgActive] = ImVec4(0.18f, 0.18f, 0.18f, 1.00f); + colors[ImGuiCol_TitleBgActive] = ImVec4(0.16f, 0.29f, 0.48f, 1.00f); colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.00f, 0.00f, 0.00f, 0.51f); colors[ImGuiCol_MenuBarBg] = ImVec4(0.14f, 0.14f, 0.14f, 1.00f); colors[ImGuiCol_ScrollbarBg] = ImVec4(0.02f, 0.02f, 0.02f, 0.53f); From 6f7b1bf2e165ddb75ad325433386f2e1c904bd20 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 19 Nov 2017 00:07:38 +0100 Subject: [PATCH 587/921] Internals: Renamed ImGuiWindow::Accessed to WriteAccessed. --- imgui.cpp | 10 +++++----- imgui_internal.h | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 07cda4ddf..6fe790131 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1799,7 +1799,7 @@ ImGuiWindow::ImGuiWindow(const char* name) ScrollbarX = ScrollbarY = false; ScrollbarSizes = ImVec2(0.0f, 0.0f); Active = WasActive = false; - Accessed = false; + WriteAccessed = false; Collapsed = false; SkipItems = false; Appearing = false; @@ -2410,7 +2410,7 @@ void ImGui::NewFrame() ImGuiWindow* window = g.Windows[i]; window->WasActive = window->Active; window->Active = false; - window->Accessed = false; + window->WriteAccessed = false; } // Closing the focused window restore focus to the first active root window in descending z-order @@ -2748,7 +2748,7 @@ void ImGui::EndFrame() // Hide implicit "Debug" window if it hasn't been used IM_ASSERT(g.CurrentWindowStack.Size == 1); // Mismatched Begin()/End() calls - if (g.CurrentWindow && !g.CurrentWindow->Accessed) + if (g.CurrentWindow && !g.CurrentWindow->WriteAccessed) g.CurrentWindow->Active = false; ImGui::End(); @@ -4609,7 +4609,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // Clear 'accessed' flag last thing (After PushClipRect which will set the flag. We want the flag to stay false when the default "Debug" window is unused) if (first_begin_of_the_frame) - window->Accessed = false; + window->WriteAccessed = false; window->BeginCount++; g.SetNextWindowSizeConstraint = false; @@ -10867,7 +10867,7 @@ void ImGui::ShowMetricsWindow(bool* p_open) if (ImGui::IsItemHovered()) GImGui->OverlayDrawList.AddRect(window->Pos, window->Pos + window->Size, IM_COL32(255,255,0,255)); ImGui::BulletText("Scroll: (%.2f,%.2f)", window->Scroll.x, window->Scroll.y); - ImGui::BulletText("Active: %d, Accessed: %d", window->Active, window->Accessed); + ImGui::BulletText("Active: %d, WriteAccessed: %d", window->Active, window->WriteAccessed); if (window->RootWindow != window) NodeWindow(window->RootWindow, "RootWindow"); if (window->DC.ChildWindows.Size > 0) NodeWindows(window->DC.ChildWindows, "ChildWindows"); ImGui::BulletText("Storage: %d bytes", window->StateStorage.Data.Size * (int)sizeof(ImGuiStorage::Pair)); diff --git a/imgui_internal.h b/imgui_internal.h index 0d21c633a..ea2b397d6 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -698,7 +698,7 @@ struct IMGUI_API ImGuiWindow ImVec2 ScrollbarSizes; bool Active; // Set to true on Begin() bool WasActive; - bool Accessed; // Set to true when any widget access the current window + bool WriteAccessed; // Set to true when any widget access the current window bool Collapsed; // Set when collapsing window to become only title-bar bool SkipItems; // Set when items can safely be all clipped (e.g. window not visible or collapsed) bool Appearing; // Set during the frame where the window is appearing (or re-appearing) @@ -778,7 +778,7 @@ namespace ImGui // - ImGui::NewFrame() has never been called, which is illegal. // - You are calling ImGui functions after ImGui::Render() and before the next ImGui::NewFrame(), which is also illegal. inline ImGuiWindow* GetCurrentWindowRead() { ImGuiContext& g = *GImGui; return g.CurrentWindow; } - inline ImGuiWindow* GetCurrentWindow() { ImGuiContext& g = *GImGui; g.CurrentWindow->Accessed = true; return g.CurrentWindow; } + inline ImGuiWindow* GetCurrentWindow() { ImGuiContext& g = *GImGui; g.CurrentWindow->WriteAccessed = true; return g.CurrentWindow; } IMGUI_API ImGuiWindow* GetParentWindow(); IMGUI_API ImGuiWindow* FindWindowByName(const char* name); IMGUI_API void FocusWindow(ImGuiWindow* window); From 067605052df780a91b0356f28dd918e0d21d6dcf Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 19 Nov 2017 00:11:18 +0100 Subject: [PATCH 588/921] Fix IsItemHovered() returning true for non-title bar hidden items that are clipped due to window collapsing logic. Fix 27fd1b913b7cbf1eafdffe6a6539a21776171cdf. (#823) --- imgui.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/imgui.cpp b/imgui.cpp index 6fe790131..3c9bf7dd3 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2009,6 +2009,9 @@ bool ImGui::IsItemHovered(ImGuiHoveredFlags flags) return false; if (window->DC.ItemFlags & ImGuiItemFlags_Disabled) return false; + // Special handling for the 1st item after Begin() which represent the title bar. When the window is collapsed (SkipItems==true) that last item will never be overwritten. + if (window->DC.LastItemId == window->MoveId && window->WriteAccessed) + return false; return true; } From d7af1a218e163947ccd2992e5b59b5f551c32020 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 19 Nov 2017 00:28:10 +0100 Subject: [PATCH 589/921] Style: Added PopupRounding setting. (#1112) --- imgui.cpp | 5 ++++- imgui.h | 2 ++ imgui_demo.cpp | 1 + 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 3c9bf7dd3..3881d99d7 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -706,6 +706,7 @@ ImGuiStyle::ImGuiStyle() WindowRounding = 9.0f; // Radius of window corners rounding. Set to 0.0f to have rectangular windows WindowTitleAlign = ImVec2(0.0f,0.5f);// Alignment for title bar text ChildRounding = 0.0f; // Radius of child window corners rounding. Set to 0.0f to have rectangular child windows + PopupRounding = 0.0f; // Radius of popup window corners rounding. Set to 0.0f to have rectangular child 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). ItemSpacing = ImVec2(8,4); // Horizontal and vertical spacing between widgets/lines @@ -735,6 +736,7 @@ void ImGuiStyle::ScaleAllSizes(float scale_factor) WindowMinSize = ImFloor(WindowMinSize * scale_factor); WindowRounding = ImFloor(WindowRounding * scale_factor); ChildRounding = ImFloor(ChildRounding * scale_factor); + PopupRounding = ImFloor(PopupRounding * scale_factor); FramePadding = ImFloor(FramePadding * scale_factor); FrameRounding = ImFloor(FrameRounding * scale_factor); ItemSpacing = ImFloor(ItemSpacing * scale_factor); @@ -4263,8 +4265,8 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->WindowPadding = style.WindowPadding; if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & (ImGuiWindowFlags_AlwaysUseWindowPadding | ImGuiWindowFlags_ShowBorders | ImGuiWindowFlags_ComboBox | ImGuiWindowFlags_Popup))) window->WindowPadding = ImVec2(0.0f, (flags & ImGuiWindowFlags_MenuBar) ? style.WindowPadding.y : 0.0f); - window->WindowRounding = (flags & ImGuiWindowFlags_ChildWindow) ? style.ChildRounding : style.WindowRounding; window->WindowBorderSize = (flags & ImGuiWindowFlags_ShowBorders) ? 1.0f : 0.0f; + window->WindowRounding = (flags & ImGuiWindowFlags_ChildWindow) ? style.ChildRounding : ((flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiWindowFlags_Modal)) ? style.PopupRounding : style.WindowRounding; const float window_rounding = window->WindowRounding; // Calculate auto-fit size, handle automatic resize @@ -5038,6 +5040,7 @@ static const ImGuiStyleVarInfo GStyleVarInfo[ImGuiStyleVar_Count_] = { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowRounding) }, // ImGuiStyleVar_WindowRounding { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowMinSize) }, // ImGuiStyleVar_WindowMinSize { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, ChildRounding) }, // ImGuiStyleVar_ChildRounding + { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, PopupRounding) }, // ImGuiStyleVar_PopupRounding { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, FramePadding) }, // ImGuiStyleVar_FramePadding { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, FrameRounding) }, // ImGuiStyleVar_FrameRounding { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, ItemSpacing) }, // ImGuiStyleVar_ItemSpacing diff --git a/imgui.h b/imgui.h index 8271ef4fb..e623901e1 100644 --- a/imgui.h +++ b/imgui.h @@ -673,6 +673,7 @@ enum ImGuiStyleVar_ ImGuiStyleVar_WindowRounding, // float WindowRounding ImGuiStyleVar_WindowMinSize, // ImVec2 WindowMinSize ImGuiStyleVar_ChildRounding, // float ChildRounding + ImGuiStyleVar_PopupRounding, // float PopupRounding ImGuiStyleVar_FramePadding, // ImVec2 FramePadding ImGuiStyleVar_FrameRounding, // float FrameRounding ImGuiStyleVar_ItemSpacing, // ImVec2 ItemSpacing @@ -755,6 +756,7 @@ struct ImGuiStyle float WindowRounding; // Radius of window corners rounding. Set to 0.0f to have rectangular windows ImVec2 WindowTitleAlign; // Alignment for title bar text. Defaults to (0.0f,0.5f) for left-aligned,vertically centered. float ChildRounding; // Radius of child window corners rounding. Set to 0.0f to have rectangular windows. + float PopupRounding; // Radius of popup window corners rounding. 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). ImVec2 ItemSpacing; // Horizontal and vertical spacing between widgets/lines diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 43b07577e..9ac07b764 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1904,6 +1904,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) ImGui::SliderFloat2("WindowPadding", (float*)&style.WindowPadding, 0.0f, 20.0f, "%.0f"); ImGui::SliderFloat("WindowRounding", &style.WindowRounding, 0.0f, 16.0f, "%.0f"); ImGui::SliderFloat("ChildRounding", &style.ChildRounding, 0.0f, 16.0f, "%.0f"); + ImGui::SliderFloat("PopupRounding", &style.PopupRounding, 0.0f, 16.0f, "%.0f"); ImGui::SliderFloat2("FramePadding", (float*)&style.FramePadding, 0.0f, 20.0f, "%.0f"); ImGui::SliderFloat("FrameRounding", &style.FrameRounding, 0.0f, 16.0f, "%.0f"); ImGui::SliderFloat2("ItemSpacing", (float*)&style.ItemSpacing, 0.0f, 20.0f, "%.0f"); From 8a7f03cbf9a64fc6c9bc6d6f90384a9e4a453999 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 19 Nov 2017 00:29:59 +0100 Subject: [PATCH 590/921] Combo: Offset popup position by border size so that a double border isn't so visible. (#707) --- imgui.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 3881d99d7..1510f1d0a 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -8880,12 +8880,12 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImVec2 popu // Position our combo ABOVE because there's more space to fit! (FIXME: Handle in Begin() or use a shared helper. We have similar code in Begin() for popup placement) popup_y1 = ImClamp(frame_bb.Min.y - popup_size.y, style.DisplaySafeAreaPadding.y, frame_bb.Min.y); popup_y2 = frame_bb.Min.y; - SetNextWindowPos(ImVec2(frame_bb.Min.x, frame_bb.Min.y), ImGuiCond_Always, ImVec2(0.0f, 1.0f)); + SetNextWindowPos(ImVec2(frame_bb.Min.x, frame_bb.Min.y + window->WindowBorderSize), ImGuiCond_Always, ImVec2(0.0f, 1.0f)); } else { // Position our combo below - SetNextWindowPos(ImVec2(frame_bb.Min.x, frame_bb.Max.y), ImGuiCond_Always, ImVec2(0.0f, 0.0f)); + SetNextWindowPos(ImVec2(frame_bb.Min.x, frame_bb.Max.y - window->WindowBorderSize), ImGuiCond_Always, ImVec2(0.0f, 0.0f)); } SetNextWindowSize(ImVec2(popup_size.x, popup_y2 - popup_y1), ImGuiCond_Appearing); PushStyleVar(ImGuiStyleVar_WindowPadding, style.FramePadding); From 4daf377c9bc0bfaea44d176689c5b66818905867 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 19 Nov 2017 00:32:47 +0100 Subject: [PATCH 591/921] Added comment about TextUnformatted(). (#1450) --- imgui.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.h b/imgui.h index e623901e1..8dfc3753c 100644 --- a/imgui.h +++ b/imgui.h @@ -258,7 +258,7 @@ namespace ImGui IMGUI_API ImGuiID GetID(const void* ptr_id); // Widgets: Text - IMGUI_API void TextUnformatted(const char* text, const char* text_end = NULL); // doesn't require null terminated string if 'text_end' is specified. no copy done, no limits, recommended for long chunks of text + IMGUI_API void TextUnformatted(const char* text, const char* text_end = NULL); // raw text without formatting. Roughly equivalent to Text("%s", text) but: A) doesn't require null terminated string if 'text_end' is specified, B) it's faster, no memory copy is done, no buffer size limits, recommended for long chunks of text. IMGUI_API void Text(const char* fmt, ...) IM_FMTARGS(1); // simple formatted text IMGUI_API void TextV(const char* fmt, va_list args) IM_FMTLIST(1); IMGUI_API void TextColored(const ImVec4& col, const char* fmt, ...) IM_FMTARGS(2); // shortcut for PushStyleColor(ImGuiCol_Text, col); Text(fmt, ...); PopStyleColor(); From 4cdd998be8bdbdc71cdd911c9cc95cb31b058a04 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 19 Nov 2017 00:49:23 +0100 Subject: [PATCH 592/921] Demo: Fix warning "format not a string literal and no format arguments" for over-zealous compilers settings. (#1450, #1451) --- imgui_demo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 9ac07b764..d6475d01c 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1341,7 +1341,7 @@ void ImGui::ShowTestWindow(bool* p_open) if (ImGui::Button("Select..")) ImGui::OpenPopup("select"); ImGui::SameLine(); - ImGui::Text(selected_fish == -1 ? "" : names[selected_fish]); + ImGui::TextUnformatted(selected_fish == -1 ? "" : names[selected_fish]); if (ImGui::BeginPopup("select")) { ImGui::Text("Aquarium"); From 538a704143924c509d2397e9b99b619a641cca3e Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 19 Nov 2017 12:00:07 +0100 Subject: [PATCH 593/921] NewFrame(): using literal strings in the most-frequently firing IM_ASSERT expression to increase the odd of programmers seeing them (especially those who don't use a debugger). --- imgui.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 1510f1d0a..f61823894 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2204,12 +2204,13 @@ void ImGui::NewFrame() ImGuiContext& g = *GImGui; // Check user data - IM_ASSERT(g.IO.DeltaTime >= 0.0f); // Need a positive DeltaTime (zero is tolerated but will cause some timing issues) - IM_ASSERT(g.IO.DisplaySize.x >= 0.0f && g.IO.DisplaySize.y >= 0.0f); - IM_ASSERT(g.IO.Fonts->Fonts.Size > 0); // Font Atlas not created. Did you call io.Fonts->GetTexDataAsRGBA32 / GetTexDataAsAlpha8 ? - IM_ASSERT(g.IO.Fonts->Fonts[0]->IsLoaded()); // Font Atlas not created. Did you call io.Fonts->GetTexDataAsRGBA32 / GetTexDataAsAlpha8 ? - IM_ASSERT(g.Style.CurveTessellationTol > 0.0f); // Invalid style setting - IM_ASSERT(g.Style.Alpha >= 0.0f && g.Style.Alpha <= 1.0f); // Invalid style setting. Alpha cannot be negative (allows us to avoid a few clamps in color computations) + // (We pass an error message in the assert expression as a trick to get it visible to programmers who are not using a debugger, as most assert handlers display their argument) + IM_ASSERT(g.IO.DeltaTime >= 0.0f && "Need a positive DeltaTime (zero is tolerated but will cause some timing issues)"); + IM_ASSERT(g.IO.DisplaySize.x >= 0.0f && g.IO.DisplaySize.y >= 0.0f && "Invalid DisplaySize value"); + IM_ASSERT(g.IO.Fonts->Fonts.Size > 0 && "Font Atlas not created. Did you call io.Fonts->GetTexDataAsRGBA32 / GetTexDataAsAlpha8 ?"); + IM_ASSERT(g.IO.Fonts->Fonts[0]->IsLoaded() && "Font Atlas not created. Did you call io.Fonts->GetTexDataAsRGBA32 / GetTexDataAsAlpha8 ?"); + IM_ASSERT(g.Style.CurveTessellationTol > 0.0f && "Invalid style setting"); + IM_ASSERT(g.Style.Alpha >= 0.0f && g.Style.Alpha <= 1.0f && "Invalid style setting. Alpha cannot be negative (allows us to avoid a few clamps in color computations)"); // Initialize on first frame if (!g.Initialized) From 9a44d447cd29096c74e38bec917015c0ee1ffaea Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 19 Nov 2017 12:04:54 +0100 Subject: [PATCH 594/921] NewFrame() now asserts if neither Render or EndFrame have been called. Exposed EndFrame(). Made it legal to call EndFrame() more than one. (#1423 etc.) --- imgui.cpp | 4 +++- imgui.h | 5 +++-- imgui_internal.h | 1 - 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index f61823894..42a8465b1 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2211,6 +2211,7 @@ void ImGui::NewFrame() IM_ASSERT(g.IO.Fonts->Fonts[0]->IsLoaded() && "Font Atlas not created. Did you call io.Fonts->GetTexDataAsRGBA32 / GetTexDataAsAlpha8 ?"); IM_ASSERT(g.Style.CurveTessellationTol > 0.0f && "Invalid style setting"); IM_ASSERT(g.Style.Alpha >= 0.0f && g.Style.Alpha <= 1.0f && "Invalid style setting. Alpha cannot be negative (allows us to avoid a few clamps in color computations)"); + IM_ASSERT((g.FrameCount == 0 || g.FrameCountEnded == g.FrameCount) && "Forgot to call Render() or EndFrame() at the end of the previous frame?"); // Initialize on first frame if (!g.Initialized) @@ -2743,7 +2744,8 @@ void ImGui::EndFrame() { ImGuiContext& g = *GImGui; IM_ASSERT(g.Initialized); // Forgot to call ImGui::NewFrame() - IM_ASSERT(g.FrameCountEnded != g.FrameCount); // ImGui::EndFrame() called multiple times, or forgot to call ImGui::NewFrame() again + if (g.FrameCountEnded == g.FrameCount) // Don't process EndFrame() multiple times. + return; // Notify OS when our Input Method Editor cursor has moved (e.g. CJK inputs using Microsoft IME) if (g.IO.ImeSetInputScreenPosFn && ImLengthSqr(g.OsImePosRequest - g.OsImePosSet) > 0.0001f) diff --git a/imgui.h b/imgui.h index 8dfc3753c..d7d62fe63 100644 --- a/imgui.h +++ b/imgui.h @@ -123,8 +123,9 @@ namespace ImGui IMGUI_API ImGuiIO& GetIO(); IMGUI_API ImGuiStyle& GetStyle(); IMGUI_API ImDrawData* GetDrawData(); // same value as passed to your io.RenderDrawListsFn() function. valid after Render() and until the next call to NewFrame() - IMGUI_API void NewFrame(); // start a new ImGui frame, you can submit any command from this point until NewFrame()/Render(). - IMGUI_API void Render(); // ends the ImGui frame, finalize rendering data, then call your io.RenderDrawListsFn() function if set. + IMGUI_API void NewFrame(); // start a new ImGui frame, you can submit any command from this point until Render()/EndFrame(). + IMGUI_API void Render(); // ends the ImGui frame, finalize the draw data, then call your io.RenderDrawListsFn() function if set. + IMGUI_API void EndFrame(); // ends the ImGui frame. automatically called by Render(), so most likely don't need to ever call that yourself directly. If you don't need to render you may call EndFrame() but you'll have wasted CPU already. If you don't need to render, better to not create any imgui windows instead! IMGUI_API void Shutdown(); // Demo/Debug/Info diff --git a/imgui_internal.h b/imgui_internal.h index ea2b397d6..6a5c24aa6 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -786,7 +786,6 @@ namespace ImGui IMGUI_API void BringWindowToBack(ImGuiWindow* window); IMGUI_API void Initialize(); - IMGUI_API void EndFrame(); // Ends the ImGui frame. Automatically called by Render()! you most likely don't need to ever call that yourself directly. If you don't need to render you can call EndFrame() but you'll have wasted CPU already. If you don't need to render, don't create any windows instead! IMGUI_API void SetActiveID(ImGuiID id, ImGuiWindow* window); IMGUI_API void ClearActiveID(); From e605f217974de0487f5b16e968ada00620b7066d Mon Sep 17 00:00:00 2001 From: Jason Wilkins Date: Wed, 8 Mar 2017 02:07:27 -0600 Subject: [PATCH 595/921] TreePush with zero arguments was ambiguous. Resolved by making it call TreePush(const void*) --- imgui.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.h b/imgui.h index d7d62fe63..cc4e4a9af 100644 --- a/imgui.h +++ b/imgui.h @@ -351,7 +351,7 @@ namespace ImGui IMGUI_API bool TreeNodeEx(const void* ptr_id, ImGuiTreeNodeFlags flags, const char* fmt, ...) IM_FMTARGS(3); IMGUI_API bool TreeNodeExV(const char* str_id, ImGuiTreeNodeFlags flags, const char* fmt, va_list args) IM_FMTLIST(3); IMGUI_API bool TreeNodeExV(const void* ptr_id, ImGuiTreeNodeFlags flags, const char* fmt, va_list args) IM_FMTLIST(3); - IMGUI_API void TreePush(const char* str_id = NULL); // ~ Indent()+PushId(). Already called by TreeNode() when returning true, but you can call Push/Pop yourself for layout purpose + IMGUI_API void TreePush(const char* str_id); // ~ Indent()+PushId(). Already called by TreeNode() when returning true, but you can call Push/Pop yourself for layout purpose IMGUI_API void TreePush(const void* ptr_id = NULL); // " IMGUI_API void TreePop(); // ~ Unindent()+PopId() IMGUI_API void TreeAdvanceToLabelPos(); // advance cursor x position by GetTreeNodeToLabelSpacing() From 9886b09a0a0058c4ca0070349b5f7fa6b9e9ab43 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 19 Nov 2017 12:39:30 +0100 Subject: [PATCH 596/921] Minor tweak, removed extraneous empty destructor. --- imgui.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/imgui.h b/imgui.h index cc4e4a9af..f8d034cc1 100644 --- a/imgui.h +++ b/imgui.h @@ -1019,12 +1019,11 @@ struct ImGuiTextFilter int CountGrep; IMGUI_API ImGuiTextFilter(const char* default_filter = ""); - ~ImGuiTextFilter() {} - void Clear() { InputBuf[0] = 0; Build(); } IMGUI_API bool Draw(const char* label = "Filter (inc,-exc)", float width = 0.0f); // Helper calling InputText+Build IMGUI_API bool PassFilter(const char* text, const char* text_end = NULL) const; - bool IsActive() const { return !Filters.empty(); } IMGUI_API void Build(); + void Clear() { InputBuf[0] = 0; Build(); } + bool IsActive() const { return !Filters.empty(); } }; // Helper: Text buffer for logging/accumulating text @@ -1115,7 +1114,7 @@ struct ImGuiTextEditCallbackData // NB: Helper functions for text manipulation. Calling those function loses selection. IMGUI_API void DeleteChars(int pos, int bytes_count); IMGUI_API void InsertChars(int pos, const char* text, const char* text_end = NULL); - bool HasSelection() const { return SelectionStart != SelectionEnd; } + bool HasSelection() const { return SelectionStart != SelectionEnd; } }; // Resizing callback data to apply custom constraint. As enabled by SetNextWindowSizeConstraints(). Callback is called during the next Begin(). From 022f8c2342610d92c9477c0ed18ec3c6bb861cd3 Mon Sep 17 00:00:00 2001 From: Jason Wilkins Date: Thu, 16 Mar 2017 21:55:16 -0500 Subject: [PATCH 597/921] fixed incomplete replacement of unsigned short with ImWchar in interface of ImFont::FindGlyph --- imgui_draw.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 958cdbe84..6147103cf 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -2183,7 +2183,7 @@ void ImFont::AddRemapChar(ImWchar dst, ImWchar src, bool overwrite_dst) IndexAdvanceX[dst] = (src < index_size) ? IndexAdvanceX.Data[src] : 1.0f; } -const ImFontGlyph* ImFont::FindGlyph(unsigned short c) const +const ImFontGlyph* ImFont::FindGlyph(ImWchar c) const { if (c < IndexLookup.Size) { From 39137ccc3e78a55e7095acfd43f41b1da7d6fc32 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 19 Nov 2017 13:52:40 +0100 Subject: [PATCH 598/921] Style: renamed ImGuiCol_ChildWindowBg to ImGuiCol_ChildBg. (#707) --- imgui.cpp | 7 ++++--- imgui.h | 4 ++-- imgui_draw.cpp | 6 +++--- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 42a8465b1..a27e0fe7c 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -215,6 +215,7 @@ Also read releases logs https://github.com/ocornut/imgui/releases for more details. - 2017/11/18 (1.53) - Style: removed ImGuiCol_ComboBg in favor of combo boxes using ImGuiCol_PopupBg for consistency. + - 2017/11/18 (1.53) - Style: renamed ImGuiCol_ChildWindowBg to ImGuiCol_ChildBg. - 2017/11/18 (1.53) - Style: renamed style.ChildWindowRounding to style.ChildRounding, ImGuiStyleVar_ChildWindowRounding to ImGuiStyleVar_ChildRounding. - 2017/11/02 (1.53) - marked IsRootWindowOrAnyChildHovered() as obsolete is favor of using IsWindowHovered(ImGuiHoveredFlags_FlattenChilds); - 2017/10/24 (1.52) - renamed IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCS/IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCS to IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS/IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS for consistency. @@ -3873,7 +3874,7 @@ bool ImGui::BeginChildFrame(ImGuiID id, const ImVec2& size, ImGuiWindowFlags ext { ImGuiContext& g = *GImGui; const ImGuiStyle& style = g.Style; - PushStyleColor(ImGuiCol_ChildWindowBg, style.Colors[ImGuiCol_FrameBg]); + PushStyleColor(ImGuiCol_ChildBg, style.Colors[ImGuiCol_FrameBg]); PushStyleVar(ImGuiStyleVar_ChildRounding, style.FrameRounding); PushStyleVar(ImGuiStyleVar_WindowPadding, style.FramePadding); return BeginChild(id, size, (g.CurrentWindow->Flags & ImGuiWindowFlags_ShowBorders) ? true : false, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysUseWindowPadding | extra_flags); @@ -4080,7 +4081,7 @@ static ImGuiCol GetWindowBgColorIdxFromFlags(ImGuiWindowFlags flags) if (flags & (ImGuiWindowFlags_Tooltip | ImGuiWindowFlags_Popup)) return ImGuiCol_PopupBg; if (flags & ImGuiWindowFlags_ChildWindow) - return ImGuiCol_ChildWindowBg; + return ImGuiCol_ChildBg; return ImGuiCol_WindowBg; } @@ -5110,7 +5111,7 @@ const char* ImGui::GetStyleColorName(ImGuiCol idx) case ImGuiCol_Text: return "Text"; case ImGuiCol_TextDisabled: return "TextDisabled"; case ImGuiCol_WindowBg: return "WindowBg"; - case ImGuiCol_ChildWindowBg: return "ChildWindowBg"; + case ImGuiCol_ChildBg: return "ChildBg"; case ImGuiCol_PopupBg: return "PopupBg"; case ImGuiCol_Border: return "Border"; case ImGuiCol_BorderShadow: return "BorderShadow"; diff --git a/imgui.h b/imgui.h index f8d034cc1..c22092618 100644 --- a/imgui.h +++ b/imgui.h @@ -616,7 +616,7 @@ enum ImGuiCol_ ImGuiCol_Text, ImGuiCol_TextDisabled, ImGuiCol_WindowBg, // Background of normal windows - ImGuiCol_ChildWindowBg, // Background of child windows + ImGuiCol_ChildBg, // Background of child windows ImGuiCol_PopupBg, // Background of popups, menus, tooltips windows ImGuiCol_Border, ImGuiCol_BorderShadow, @@ -659,7 +659,7 @@ enum ImGuiCol_ // Obsolete names (will be removed) #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS - , ImGuiCol_Column = ImGuiCol_Separator, ImGuiCol_ColumnHovered = ImGuiCol_SeparatorHovered, ImGuiCol_ColumnActive = ImGuiCol_SeparatorActive + , ImGuiCol_ChildWindowBg = ImGuiCol_ChildBg, ImGuiCol_Column = ImGuiCol_Separator, ImGuiCol_ColumnHovered = ImGuiCol_SeparatorHovered, ImGuiCol_ColumnActive = ImGuiCol_SeparatorActive #endif }; diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 6147103cf..e2caf192f 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -129,7 +129,7 @@ void ImGui::StyleColorsClassic(ImGuiStyle* dst) colors[ImGuiCol_Text] = ImVec4(0.90f, 0.90f, 0.90f, 1.00f); colors[ImGuiCol_TextDisabled] = ImVec4(0.60f, 0.60f, 0.60f, 1.00f); colors[ImGuiCol_WindowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.70f); - colors[ImGuiCol_ChildWindowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); + colors[ImGuiCol_ChildBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); colors[ImGuiCol_PopupBg] = ImVec4(0.11f, 0.11f, 0.14f, 0.92f); colors[ImGuiCol_Border] = ImVec4(0.70f, 0.70f, 0.70f, 0.27f); colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); @@ -178,7 +178,7 @@ void ImGui::StyleColorsDark(ImGuiStyle* dst) colors[ImGuiCol_Text] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f); colors[ImGuiCol_TextDisabled] = ImVec4(0.50f, 0.50f, 0.50f, 1.00f); colors[ImGuiCol_WindowBg] = ImVec4(0.06f, 0.06f, 0.06f, 0.94f); - colors[ImGuiCol_ChildWindowBg] = ImVec4(1.00f, 1.00f, 1.00f, 0.00f); + colors[ImGuiCol_ChildBg] = ImVec4(1.00f, 1.00f, 1.00f, 0.00f); colors[ImGuiCol_PopupBg] = ImVec4(0.08f, 0.08f, 0.08f, 0.94f); colors[ImGuiCol_Border] = ImVec4(0.86f, 0.86f, 1.00f, 0.20f); colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); @@ -229,7 +229,7 @@ void ImGui::StyleColorsLight(ImGuiStyle* dst) //colors[ImGuiCol_TextHovered] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f); //colors[ImGuiCol_TextActive] = ImVec4(1.00f, 1.00f, 0.00f, 1.00f); colors[ImGuiCol_WindowBg] = ImVec4(0.94f, 0.94f, 0.94f, 1.00f); - colors[ImGuiCol_ChildWindowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); + colors[ImGuiCol_ChildBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); colors[ImGuiCol_PopupBg] = ImVec4(1.00f, 1.00f, 1.00f, 0.94f); colors[ImGuiCol_Border] = ImVec4(0.00f, 0.00f, 0.00f, 0.30f); colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); From f7fe8248054a255936f1d8ac2a8a00ebf190cd90 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 19 Nov 2017 13:55:38 +0100 Subject: [PATCH 599/921] Style: Tweaked border settings to homogenize a little how they look over different backgrounds. (#707) --- imgui_draw.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index e2caf192f..8718e9783 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -131,7 +131,7 @@ void ImGui::StyleColorsClassic(ImGuiStyle* dst) colors[ImGuiCol_WindowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.70f); colors[ImGuiCol_ChildBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); colors[ImGuiCol_PopupBg] = ImVec4(0.11f, 0.11f, 0.14f, 0.92f); - colors[ImGuiCol_Border] = ImVec4(0.70f, 0.70f, 0.70f, 0.27f); + colors[ImGuiCol_Border] = ImVec4(0.50f, 0.50f, 0.50f, 0.50f); colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); colors[ImGuiCol_FrameBg] = ImVec4(0.43f, 0.43f, 0.43f, 0.39f); colors[ImGuiCol_FrameBgHovered] = ImVec4(0.47f, 0.47f, 0.69f, 0.40f); @@ -180,7 +180,7 @@ void ImGui::StyleColorsDark(ImGuiStyle* dst) colors[ImGuiCol_WindowBg] = ImVec4(0.06f, 0.06f, 0.06f, 0.94f); colors[ImGuiCol_ChildBg] = ImVec4(1.00f, 1.00f, 1.00f, 0.00f); colors[ImGuiCol_PopupBg] = ImVec4(0.08f, 0.08f, 0.08f, 0.94f); - colors[ImGuiCol_Border] = ImVec4(0.86f, 0.86f, 1.00f, 0.20f); + colors[ImGuiCol_Border] = ImVec4(0.43f, 0.43f, 0.50f, 0.50f); colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); colors[ImGuiCol_FrameBg] = ImVec4(0.16f, 0.29f, 0.48f, 0.54f); colors[ImGuiCol_FrameBgHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.40f); From c433bc971f679fbed8ce43d633bd365868395b02 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 19 Nov 2017 14:58:10 +0100 Subject: [PATCH 600/921] Reorder fields for consistency. --- imgui.cpp | 4 ++-- imgui.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index a27e0fe7c..5a725c981 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -703,8 +703,8 @@ ImGuiStyle::ImGuiStyle() { Alpha = 1.0f; // Global alpha applies to everything in ImGui 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 + WindowMinSize = ImVec2(32,32); // Minimum window size WindowTitleAlign = ImVec2(0.0f,0.5f);// Alignment for title bar text ChildRounding = 0.0f; // Radius of child window corners rounding. Set to 0.0f to have rectangular child windows PopupRounding = 0.0f; // Radius of popup window corners rounding. Set to 0.0f to have rectangular child windows @@ -734,8 +734,8 @@ ImGuiStyle::ImGuiStyle() void ImGuiStyle::ScaleAllSizes(float scale_factor) { WindowPadding = ImFloor(WindowPadding * scale_factor); - WindowMinSize = ImFloor(WindowMinSize * scale_factor); WindowRounding = ImFloor(WindowRounding * scale_factor); + WindowMinSize = ImFloor(WindowMinSize * scale_factor); ChildRounding = ImFloor(ChildRounding * scale_factor); PopupRounding = ImFloor(PopupRounding * scale_factor); FramePadding = ImFloor(FramePadding * scale_factor); diff --git a/imgui.h b/imgui.h index c22092618..5515940a1 100644 --- a/imgui.h +++ b/imgui.h @@ -753,8 +753,8 @@ struct ImGuiStyle { float Alpha; // Global alpha applies to everything in ImGui 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 + ImVec2 WindowMinSize; // Minimum window size ImVec2 WindowTitleAlign; // Alignment for title bar text. Defaults to (0.0f,0.5f) for left-aligned,vertically centered. float ChildRounding; // Radius of child window corners rounding. Set to 0.0f to have rectangular windows. float PopupRounding; // Radius of popup window corners rounding. From abbf836fd09fa26449f97e130f3838b07d59733d Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 19 Nov 2017 15:56:51 +0100 Subject: [PATCH 601/921] Style, Begin: removed ImGuiWindowFlags_ShowBorders window flag. Borders are now fully set up in the ImGuiStyle structure (see e.g. style.FrameBorderSize, style.WindowBorderSize). Use ImGui::ShowStyleEditor() to look them up. (#707, fix #819, #1031, ref #1019, ref #447) --- imgui.cpp | 106 +++++++++++++++++++++++++++---------------------- imgui.h | 10 ++++- imgui_demo.cpp | 49 ++++++++++++++--------- 3 files changed, 98 insertions(+), 67 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 5a725c981..ca13fcdb4 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -214,6 +214,8 @@ Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. Also read releases logs https://github.com/ocornut/imgui/releases for more details. + - 2017/11/18 (1.53) - Style, Begin: removed ImGuiWindowFlags_ShowBorders window flag. Borders are now fully set up in the ImGuiStyle structure (see e.g. style.FrameBorderSize, style.WindowBorderSize). Use ImGui::ShowStyleEditor() to look them up. + Please note that the style system will keep evolving (hopefully stabilizing in Q1 2018), and so custom styles will probably subtly break over time. It is recommended you use the StyleColorsClassic(), StyleColorsDark(), StyleColorsLight() functions. - 2017/11/18 (1.53) - Style: removed ImGuiCol_ComboBg in favor of combo boxes using ImGuiCol_PopupBg for consistency. - 2017/11/18 (1.53) - Style: renamed ImGuiCol_ChildWindowBg to ImGuiCol_ChildBg. - 2017/11/18 (1.53) - Style: renamed style.ChildWindowRounding to style.ChildRounding, ImGuiStyleVar_ChildWindowRounding to ImGuiStyleVar_ChildRounding. @@ -704,12 +706,16 @@ ImGuiStyle::ImGuiStyle() Alpha = 1.0f; // Global alpha applies to everything in ImGui WindowPadding = ImVec2(8,8); // Padding within a window WindowRounding = 9.0f; // Radius of window corners rounding. Set to 0.0f to have rectangular windows + WindowBorderSize = 0.0f; // Thickness of border around windows. Generally set to 0.0f or 1.0f. Other values not well tested. WindowMinSize = ImVec2(32,32); // Minimum window size WindowTitleAlign = ImVec2(0.0f,0.5f);// Alignment for title bar text ChildRounding = 0.0f; // Radius of child window corners rounding. Set to 0.0f to have rectangular child windows + ChildBorderSize = 1.0f; // Thickness of border around child windows. Generally set to 0.0f or 1.0f. Other values not well tested. PopupRounding = 0.0f; // Radius of popup window corners rounding. Set to 0.0f to have rectangular child windows + PopupBorderSize = 1.0f; // Thickness of border around popup or tooltip windows. Generally set to 0.0f or 1.0f. Other values not well tested. 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). + FrameBorderSize = 0.0f; // Thickness of border around frames. Generally set to 0.0f or 1.0f. Other values not well tested. ItemSpacing = ImVec2(8,4); // Horizontal and vertical spacing between widgets/lines ItemInnerSpacing = ImVec2(4,4); // Horizontal and vertical spacing between within elements of a composed widget (e.g. a slider and its label) TouchExtraPadding = ImVec2(0,0); // Expand reactive bounding box for touch-based system where touch position is not accurate enough. Unfortunately we don't sort widgets so priority on overlap will always be given to the first widget. So don't grow this too much! @@ -3075,10 +3081,11 @@ void ImGui::RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool border, ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; window->DrawList->AddRectFilled(p_min, p_max, fill_col, rounding); - if (border && (window->Flags & ImGuiWindowFlags_ShowBorders)) + const float border_size = g.Style.FrameBorderSize; + if (border && border_size > 0.0f) { - window->DrawList->AddRect(p_min+ImVec2(1,1), p_max+ImVec2(1,1), GetColorU32(ImGuiCol_BorderShadow), rounding); - window->DrawList->AddRect(p_min, p_max, GetColorU32(ImGuiCol_Border), rounding); + window->DrawList->AddRect(p_min+ImVec2(1,1), p_max+ImVec2(1,1), GetColorU32(ImGuiCol_BorderShadow), rounding, ~0, border_size); + window->DrawList->AddRect(p_min, p_max, GetColorU32(ImGuiCol_Border), rounding, ~0, border_size); } } @@ -3086,10 +3093,11 @@ void ImGui::RenderFrameBorder(ImVec2 p_min, ImVec2 p_max, float rounding) { ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; - if (window->Flags & ImGuiWindowFlags_ShowBorders) + const float border_size = g.Style.FrameBorderSize; + if (border_size > 0.0f) { - window->DrawList->AddRect(p_min+ImVec2(1,1), p_max+ImVec2(1,1), GetColorU32(ImGuiCol_BorderShadow), rounding); - window->DrawList->AddRect(p_min, p_max, GetColorU32(ImGuiCol_Border), rounding); + window->DrawList->AddRect(p_min+ImVec2(1,1), p_max+ImVec2(1,1), GetColorU32(ImGuiCol_BorderShadow), rounding, ~0, border_size); + window->DrawList->AddRect(p_min, p_max, GetColorU32(ImGuiCol_Border), rounding, ~0, border_size); } } @@ -3665,14 +3673,12 @@ static inline void ClearSetNextWindowData() bool ImGui::BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_flags) { ImGuiContext& g = *GImGui; - ImGuiWindow* window = g.CurrentWindow; if (!IsPopupOpen(id)) { ClearSetNextWindowData(); // We behave like Begin() and need to consume those values return false; } - PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); ImGuiWindowFlags flags = extra_flags|ImGuiWindowFlags_Popup|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings; char name[20]; @@ -3682,9 +3688,7 @@ bool ImGui::BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_flags) ImFormatString(name, IM_ARRAYSIZE(name), "##popup_%08x", id); // Not recycling, so we can close/open during the same frame bool is_open = Begin(name, NULL, flags); - if (!(window->Flags & ImGuiWindowFlags_ShowBorders)) - g.CurrentWindow->Flags &= ~ImGuiWindowFlags_ShowBorders; - if (!is_open) // NB: is_open can be 'false' when the popup is completely clipped (e.g. zero size display) + if (!is_open) // NB: Begin can return false when the popup is completely clipped (e.g. zero size display) EndPopup(); return is_open; @@ -3698,7 +3702,7 @@ bool ImGui::BeginPopup(const char* str_id) ClearSetNextWindowData(); // We behave like Begin() and need to consume those values return false; } - return BeginPopupEx(g.CurrentWindow->GetID(str_id), ImGuiWindowFlags_ShowBorders | ImGuiWindowFlags_AlwaysAutoResize); + return BeginPopupEx(g.CurrentWindow->GetID(str_id), ImGuiWindowFlags_AlwaysAutoResize); } bool ImGui::IsPopupOpen(ImGuiID id) @@ -3747,8 +3751,6 @@ void ImGui::EndPopup() IM_ASSERT(window->Flags & ImGuiWindowFlags_Popup); // Mismatched BeginPopup()/EndPopup() calls IM_ASSERT(GImGui->CurrentPopupStack.Size > 0); End(); - if (!(window->Flags & ImGuiWindowFlags_Modal)) - PopStyleVar(); } bool ImGui::OpenPopupOnItemClick(const char* str_id, int mouse_button) @@ -3774,7 +3776,7 @@ bool ImGui::BeginPopupContextItem(const char* str_id, int mouse_button) IM_ASSERT(id != 0); // However, you cannot pass a NULL str_id if the last item has no identifier (e.g. a Text() item) if (IsMouseClicked(mouse_button) && IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup)) OpenPopupEx(id, true); - return BeginPopupEx(id, ImGuiWindowFlags_ShowBorders | ImGuiWindowFlags_AlwaysAutoResize); + return BeginPopupEx(id, ImGuiWindowFlags_AlwaysAutoResize); } bool ImGui::BeginPopupContextWindow(const char* str_id, int mouse_button, bool also_over_items) @@ -3786,7 +3788,7 @@ bool ImGui::BeginPopupContextWindow(const char* str_id, int mouse_button, bool a if (IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup)) if (also_over_items || !IsAnyItemHovered()) OpenPopupEx(id, true); - return BeginPopupEx(id, ImGuiWindowFlags_ShowBorders | ImGuiWindowFlags_AlwaysAutoResize); + return BeginPopupEx(id, ImGuiWindowFlags_AlwaysAutoResize); } bool ImGui::BeginPopupContextVoid(const char* str_id, int mouse_button) @@ -3796,11 +3798,12 @@ bool ImGui::BeginPopupContextVoid(const char* str_id, int mouse_button) ImGuiID id = GImGui->CurrentWindow->GetID(str_id); if (!IsAnyWindowHovered() && IsMouseClicked(mouse_button)) OpenPopupEx(id, true); - return BeginPopupEx(id, ImGuiWindowFlags_ShowBorders | ImGuiWindowFlags_AlwaysAutoResize); + return BeginPopupEx(id, ImGuiWindowFlags_AlwaysAutoResize); } static bool BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, bool border, ImGuiWindowFlags extra_flags) { + ImGuiContext& g = *GImGui; ImGuiWindow* parent_window = ImGui::GetCurrentWindow(); ImGuiWindowFlags flags = ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_ChildWindow; flags |= (parent_window->Flags & ImGuiWindowFlags_NoMove); // Inherit the NoMove flag @@ -3812,8 +3815,10 @@ static bool BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, b size.x = ImMax(content_avail.x, 4.0f) - fabsf(size.x); // Arbitrary minimum zero-ish child size of 4.0f (0.0f causing too much issues) if (size.y <= 0.0f) size.y = ImMax(content_avail.y, 4.0f) - fabsf(size.y); - if (border) - flags |= ImGuiWindowFlags_ShowBorders; + + const float backup_border_size = g.Style.ChildBorderSize; + if (!border) + g.Style.ChildBorderSize = 0.0f; flags |= extra_flags; char title[256]; @@ -3826,8 +3831,7 @@ static bool BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, b bool ret = ImGui::Begin(title, NULL, flags); ImGuiWindow* child_window = ImGui::GetCurrentWindow(); child_window->AutoFitChildAxises = auto_fit_axises; - if (!(parent_window->Flags & ImGuiWindowFlags_ShowBorders)) - child_window->Flags &= ~ImGuiWindowFlags_ShowBorders; + g.Style.ChildBorderSize = backup_border_size; return ret; } @@ -3876,14 +3880,15 @@ bool ImGui::BeginChildFrame(ImGuiID id, const ImVec2& size, ImGuiWindowFlags ext const ImGuiStyle& style = g.Style; PushStyleColor(ImGuiCol_ChildBg, style.Colors[ImGuiCol_FrameBg]); PushStyleVar(ImGuiStyleVar_ChildRounding, style.FrameRounding); + PushStyleVar(ImGuiStyleVar_ChildBorderSize, style.FrameBorderSize); PushStyleVar(ImGuiStyleVar_WindowPadding, style.FramePadding); - return BeginChild(id, size, (g.CurrentWindow->Flags & ImGuiWindowFlags_ShowBorders) ? true : false, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysUseWindowPadding | extra_flags); + return BeginChild(id, size, true, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysUseWindowPadding | extra_flags); } void ImGui::EndChildFrame() { EndChild(); - PopStyleVar(2); + PopStyleVar(3); PopStyleColor(); } @@ -4265,13 +4270,15 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) } } - // Lock window padding so that altering the ShowBorders flag for children doesn't have side-effects. + // Lock window padding so that altering the border sizes for children doesn't have side-effects. window->WindowPadding = style.WindowPadding; - if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & (ImGuiWindowFlags_AlwaysUseWindowPadding | ImGuiWindowFlags_ShowBorders | ImGuiWindowFlags_ComboBox | ImGuiWindowFlags_Popup))) + if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & (ImGuiWindowFlags_AlwaysUseWindowPadding | ImGuiWindowFlags_ComboBox | ImGuiWindowFlags_Popup)) && style.WindowBorderSize == 0.0f) window->WindowPadding = ImVec2(0.0f, (flags & ImGuiWindowFlags_MenuBar) ? style.WindowPadding.y : 0.0f); - window->WindowBorderSize = (flags & ImGuiWindowFlags_ShowBorders) ? 1.0f : 0.0f; window->WindowRounding = (flags & ImGuiWindowFlags_ChildWindow) ? style.ChildRounding : ((flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiWindowFlags_Modal)) ? style.PopupRounding : style.WindowRounding; + window->WindowBorderSize = (flags & ImGuiWindowFlags_ChildWindow) ? style.ChildBorderSize : ((flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiWindowFlags_Modal)) ? style.PopupBorderSize : style.WindowBorderSize; + const ImVec2 window_padding = window->WindowPadding; const float window_rounding = window->WindowRounding; + const float window_border_size = window->WindowBorderSize; // Calculate auto-fit size, handle automatic resize const ImVec2 size_auto_fit = CalcSizeAutoFit(window); @@ -4405,7 +4412,10 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) if (window->Collapsed) { // Title bar only + float backup_border_size = style.FrameBorderSize; + g.Style.FrameBorderSize = window->WindowBorderSize; RenderFrame(title_bar_rect.Min, title_bar_rect.Max, GetColorU32(ImGuiCol_TitleBgCollapsed), true, window_rounding); + g.Style.FrameBorderSize = backup_border_size; } else { @@ -4459,9 +4469,9 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) if (flags & ImGuiWindowFlags_MenuBar) { ImRect menu_bar_rect = window->MenuBarRect(); - if (flags & ImGuiWindowFlags_ShowBorders) - window->DrawList->AddLine(menu_bar_rect.GetBL(), menu_bar_rect.GetBR(), GetColorU32(ImGuiCol_Border)); window->DrawList->AddRectFilled(menu_bar_rect.GetTL(), menu_bar_rect.GetBR(), GetColorU32(ImGuiCol_MenuBarBg), (flags & ImGuiWindowFlags_NoTitleBar) ? window_rounding : 0.0f, ImGuiCorner_TopLeft|ImGuiCorner_TopRight); + if (style.FrameBorderSize > 0.0f) + window->DrawList->AddLine(menu_bar_rect.GetBL(), menu_bar_rect.GetBR(), GetColorU32(ImGuiCol_Border), style.FrameBorderSize); } // Scrollbars @@ -4475,20 +4485,17 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) if (!(flags & ImGuiWindowFlags_NoResize)) { const ImVec2 br = window->Rect().GetBR(); - window->DrawList->PathLineTo(br + ImVec2(-resize_corner_size, -window->WindowBorderSize)); - window->DrawList->PathLineTo(br + ImVec2(-window->WindowBorderSize, -resize_corner_size)); - window->DrawList->PathArcToFast(ImVec2(br.x - window_rounding - window->WindowBorderSize, br.y - window_rounding - window->WindowBorderSize), window_rounding, 0, 3); + window->DrawList->PathLineTo(br + ImVec2(-resize_corner_size, -window_border_size)); + window->DrawList->PathLineTo(br + ImVec2(-window_border_size, -resize_corner_size)); + window->DrawList->PathArcToFast(ImVec2(br.x - window_rounding - window_border_size, br.y - window_rounding - window_border_size), window_rounding, 0, 3); window->DrawList->PathFillConvex(resize_col); } // Borders - if (flags & ImGuiWindowFlags_ShowBorders) - { - window->DrawList->AddRect(window->Pos+ImVec2(1,1), window->Pos+window->Size+ImVec2(1,1), GetColorU32(ImGuiCol_BorderShadow), window_rounding); - window->DrawList->AddRect(window->Pos, window->Pos+window->Size, GetColorU32(ImGuiCol_Border), window_rounding); - if (!(flags & ImGuiWindowFlags_NoTitleBar)) - window->DrawList->AddLine(title_bar_rect.GetBL()+ImVec2(1,0), title_bar_rect.GetBR()-ImVec2(1,0), GetColorU32(ImGuiCol_Border)); - } + if (window_border_size > 0.0f) + window->DrawList->AddRect(window->Pos, window->Pos+window->Size, GetColorU32(ImGuiCol_Border), window_rounding, ~0, window_border_size); + if (style.FrameBorderSize > 0 && !(flags & ImGuiWindowFlags_NoTitleBar)) + window->DrawList->AddLine(title_bar_rect.GetBL()+ImVec2(1,-1), title_bar_rect.GetBR()+ImVec2(-1,-1), GetColorU32(ImGuiCol_Border), style.FrameBorderSize); } // Update ContentsRegionMax. All the variable it depends on are set above in this function. @@ -5042,11 +5049,15 @@ static const ImGuiStyleVarInfo GStyleVarInfo[ImGuiStyleVar_Count_] = { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, Alpha) }, // ImGuiStyleVar_Alpha { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowPadding) }, // ImGuiStyleVar_WindowPadding { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowRounding) }, // ImGuiStyleVar_WindowRounding + { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowBorderSize) }, // ImGuiStyleVar_WindowBorderSize { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowMinSize) }, // ImGuiStyleVar_WindowMinSize { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, ChildRounding) }, // ImGuiStyleVar_ChildRounding + { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, ChildBorderSize) }, // ImGuiStyleVar_ChildBorderSize { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, PopupRounding) }, // ImGuiStyleVar_PopupRounding + { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, PopupBorderSize) }, // ImGuiStyleVar_PopupBorderSize { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, FramePadding) }, // ImGuiStyleVar_FramePadding { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, FrameRounding) }, // ImGuiStyleVar_FrameRounding + { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, FrameBorderSize) }, // ImGuiStyleVar_FrameBorderSize { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, ItemSpacing) }, // ImGuiStyleVar_ItemSpacing { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, ItemInnerSpacing) }, // ImGuiStyleVar_ItemInnerSpacing { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, IndentSpacing) }, // ImGuiStyleVar_IndentSpacing @@ -7619,7 +7630,7 @@ void ImGui::ProgressBar(float fraction, const ImVec2& size_arg, const char* over // Render fraction = ImSaturate(fraction); RenderFrame(bb.Min, bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding); - bb.Expand(ImVec2(-window->WindowBorderSize, -window->WindowBorderSize)); + bb.Expand(ImVec2(-style.FrameBorderSize, -style.FrameBorderSize)); const ImVec2 fill_br = ImVec2(ImLerp(bb.Min.x, bb.Max.x, fraction), bb.Max.y); RenderRectFilledRangeH(window->DrawList, bb, GetColorU32(ImGuiCol_PlotHistogram), 0.0f, fraction, style.FrameRounding); @@ -7742,10 +7753,10 @@ bool ImGui::RadioButton(const char* label, bool active) window->DrawList->AddCircleFilled(center, radius-pad, GetColorU32(ImGuiCol_CheckMark), 16); } - if (window->Flags & ImGuiWindowFlags_ShowBorders) + if (style.FrameBorderSize > 0.0f) { - window->DrawList->AddCircle(center+ImVec2(1,1), radius, GetColorU32(ImGuiCol_BorderShadow), 16); - window->DrawList->AddCircle(center, radius, GetColorU32(ImGuiCol_Border), 16); + window->DrawList->AddCircle(center+ImVec2(1,1), radius, GetColorU32(ImGuiCol_BorderShadow), 16, style.FrameBorderSize); + window->DrawList->AddCircle(center, radius, GetColorU32(ImGuiCol_Border), 16, style.FrameBorderSize); } if (g.LogEnabled) @@ -8884,18 +8895,17 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImVec2 popu // Position our combo ABOVE because there's more space to fit! (FIXME: Handle in Begin() or use a shared helper. We have similar code in Begin() for popup placement) popup_y1 = ImClamp(frame_bb.Min.y - popup_size.y, style.DisplaySafeAreaPadding.y, frame_bb.Min.y); popup_y2 = frame_bb.Min.y; - SetNextWindowPos(ImVec2(frame_bb.Min.x, frame_bb.Min.y + window->WindowBorderSize), ImGuiCond_Always, ImVec2(0.0f, 1.0f)); + SetNextWindowPos(ImVec2(frame_bb.Min.x, frame_bb.Min.y + style.FrameBorderSize), ImGuiCond_Always, ImVec2(0.0f, 1.0f)); } else { // Position our combo below - SetNextWindowPos(ImVec2(frame_bb.Min.x, frame_bb.Max.y - window->WindowBorderSize), ImGuiCond_Always, ImVec2(0.0f, 0.0f)); + SetNextWindowPos(ImVec2(frame_bb.Min.x, frame_bb.Max.y - style.FrameBorderSize), ImGuiCond_Always, ImVec2(0.0f, 0.0f)); } SetNextWindowSize(ImVec2(popup_size.x, popup_y2 - popup_y1), ImGuiCond_Appearing); PushStyleVar(ImGuiStyleVar_WindowPadding, style.FramePadding); - const ImGuiWindowFlags flags = ImGuiWindowFlags_ComboBox | ((window->Flags & ImGuiWindowFlags_ShowBorders) ? ImGuiWindowFlags_ShowBorders : 0); - if (!BeginPopupEx(id, flags)) + if (!BeginPopupEx(id, ImGuiWindowFlags_ComboBox)) { IM_ASSERT(0); // This should never happen as we tested for IsPopupOpen() above return false; @@ -9361,7 +9371,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled) if (menu_is_open) { SetNextWindowPos(popup_pos, ImGuiCond_Always); - ImGuiWindowFlags flags = ImGuiWindowFlags_ShowBorders | ImGuiWindowFlags_AlwaysAutoResize | ((window->Flags & (ImGuiWindowFlags_Popup|ImGuiWindowFlags_ChildMenu)) ? ImGuiWindowFlags_ChildMenu|ImGuiWindowFlags_ChildWindow : ImGuiWindowFlags_ChildMenu); + ImGuiWindowFlags flags = ImGuiWindowFlags_AlwaysAutoResize | ((window->Flags & (ImGuiWindowFlags_Popup|ImGuiWindowFlags_ChildMenu)) ? ImGuiWindowFlags_ChildMenu|ImGuiWindowFlags_ChildWindow : ImGuiWindowFlags_ChildMenu); menu_is_open = BeginPopupEx(id, flags); // menu_is_open can be 'false' when the popup is completely clipped (e.g. zero size display) } @@ -9506,7 +9516,7 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl else window->DrawList->AddRectFilled(bb_inner.Min, bb_inner.Max, GetColorU32(col_source), rounding, ~0); } - if (window->Flags & ImGuiWindowFlags_ShowBorders) + if (g.Style.FrameBorderSize > 0.0f) RenderFrameBorder(bb.Min, bb.Max, rounding); else window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_FrameBg), rounding); // Color button are often in need of some sort of border diff --git a/imgui.h b/imgui.h index 5515940a1..98e016bf9 100644 --- a/imgui.h +++ b/imgui.h @@ -502,7 +502,7 @@ enum ImGuiWindowFlags_ ImGuiWindowFlags_NoScrollWithMouse = 1 << 4, // Disable user vertically scrolling with mouse wheel ImGuiWindowFlags_NoCollapse = 1 << 5, // Disable user collapsing window by double-clicking on it ImGuiWindowFlags_AlwaysAutoResize = 1 << 6, // Resize every window to its content every frame - ImGuiWindowFlags_ShowBorders = 1 << 7, // Show borders around windows and items + //ImGuiWindowFlags_ShowBorders = 1 << 7, // Show borders around windows and items (OBSOLETE! Use e.g. style.FrameBorderSize=1.0f to enable borders). ImGuiWindowFlags_NoSavedSettings = 1 << 8, // Never load/save settings in .ini file ImGuiWindowFlags_NoInputs = 1 << 9, // Disable catching mouse or keyboard inputs, hovering test with pass through. ImGuiWindowFlags_MenuBar = 1 << 10, // Has a menu-bar @@ -672,11 +672,15 @@ enum ImGuiStyleVar_ ImGuiStyleVar_Alpha, // float Alpha ImGuiStyleVar_WindowPadding, // ImVec2 WindowPadding ImGuiStyleVar_WindowRounding, // float WindowRounding + ImGuiStyleVar_WindowBorderSize, // float WindowBorderSize ImGuiStyleVar_WindowMinSize, // ImVec2 WindowMinSize ImGuiStyleVar_ChildRounding, // float ChildRounding + ImGuiStyleVar_ChildBorderSize, // float ChildBorderSize ImGuiStyleVar_PopupRounding, // float PopupRounding + ImGuiStyleVar_PopupBorderSize, // float PopupBorderSize ImGuiStyleVar_FramePadding, // ImVec2 FramePadding ImGuiStyleVar_FrameRounding, // float FrameRounding + ImGuiStyleVar_FrameBorderSize, // float FrameBorderSize ImGuiStyleVar_ItemSpacing, // ImVec2 ItemSpacing ImGuiStyleVar_ItemInnerSpacing, // ImVec2 ItemInnerSpacing ImGuiStyleVar_IndentSpacing, // float IndentSpacing @@ -754,12 +758,16 @@ struct ImGuiStyle float Alpha; // Global alpha applies to everything in ImGui ImVec2 WindowPadding; // Padding within a window float WindowRounding; // Radius of window corners rounding. Set to 0.0f to have rectangular windows + float WindowBorderSize; // Thickness of border around windows. Generally set to 0.0f or 1.0f. (Other values are not well tested and more CPU/GPU costly) ImVec2 WindowMinSize; // Minimum window size ImVec2 WindowTitleAlign; // Alignment for title bar text. Defaults to (0.0f,0.5f) for left-aligned,vertically centered. float ChildRounding; // Radius of child window corners rounding. Set to 0.0f to have rectangular windows. + float ChildBorderSize; // Thickness of border around child windows. Generally set to 0.0f or 1.0f. (Other values are not well tested and more CPU/GPU costly) float PopupRounding; // Radius of popup window corners rounding. + float PopupBorderSize; // Thickness of border around popup windows. Generally set to 0.0f or 1.0f. (Other values are not well tested and more CPU/GPU costly) 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). + float FrameBorderSize; // Thickness of border around frames. Generally set to 0.0f or 1.0f. (Other values are not well tested and more CPU/GPU costly) ImVec2 ItemSpacing; // Horizontal and vertical spacing between widgets/lines ImVec2 ItemInnerSpacing; // Horizontal and vertical spacing between within elements of a composed widget (e.g. a slider and its label) ImVec2 TouchExtraPadding; // Expand reactive bounding box for touch-based system where touch position is not accurate enough. Unfortunately we don't sort widgets so priority on overlap will always be given to the first widget. So don't grow this too much! diff --git a/imgui_demo.cpp b/imgui_demo.cpp index d6475d01c..7ee7de827 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -165,22 +165,20 @@ void ImGui::ShowTestWindow(bool* p_open) } static bool no_titlebar = false; - static bool no_border = true; - static bool no_resize = false; - static bool no_move = false; static bool no_scrollbar = false; - static bool no_collapse = false; static bool no_menu = false; + static bool no_move = false; + static bool no_resize = false; + static bool no_collapse = false; // Demonstrate the various window flags. Typically you would just use the default. ImGuiWindowFlags window_flags = 0; if (no_titlebar) window_flags |= ImGuiWindowFlags_NoTitleBar; - if (!no_border) window_flags |= ImGuiWindowFlags_ShowBorders; - if (no_resize) window_flags |= ImGuiWindowFlags_NoResize; - if (no_move) window_flags |= ImGuiWindowFlags_NoMove; if (no_scrollbar) window_flags |= ImGuiWindowFlags_NoScrollbar; - if (no_collapse) window_flags |= ImGuiWindowFlags_NoCollapse; if (!no_menu) window_flags |= ImGuiWindowFlags_MenuBar; + if (no_move) window_flags |= ImGuiWindowFlags_NoMove; + if (no_resize) window_flags |= ImGuiWindowFlags_NoResize; + if (no_collapse) window_flags |= ImGuiWindowFlags_NoCollapse; ImGui::SetNextWindowSize(ImVec2(550,680), ImGuiCond_FirstUseEver); if (!ImGui::Begin("ImGui Demo", p_open, window_flags)) { @@ -238,12 +236,11 @@ void ImGui::ShowTestWindow(bool* p_open) if (ImGui::CollapsingHeader("Window options")) { ImGui::Checkbox("No titlebar", &no_titlebar); ImGui::SameLine(150); - ImGui::Checkbox("No border", &no_border); ImGui::SameLine(300); - ImGui::Checkbox("No resize", &no_resize); - ImGui::Checkbox("No move", &no_move); ImGui::SameLine(150); ImGui::Checkbox("No scrollbar", &no_scrollbar); ImGui::SameLine(300); - ImGui::Checkbox("No collapse", &no_collapse); ImGui::Checkbox("No menu", &no_menu); + ImGui::Checkbox("No move", &no_move); ImGui::SameLine(150); + ImGui::Checkbox("No resize", &no_resize); ImGui::SameLine(300); + ImGui::Checkbox("No collapse", &no_collapse); if (ImGui::TreeNode("Style")) { @@ -685,7 +682,6 @@ void ImGui::ShowTestWindow(bool* p_open) ImGui::TreePop(); } - if (ImGui::TreeNode("Plots widgets")) { static bool animate = true; @@ -1878,6 +1874,17 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) ref_saved_style = style; } + // Simplified Settings + if (ImGui::SliderFloat("FrameRounding", &style.FrameRounding, 0.0f, 12.0f, "%.0f")) + style.GrabRounding = style.FrameRounding; // Make GrabRounding always the same value as FrameRounding + bool window_border = (style.WindowBorderSize > 0.0f); + if (ImGui::Checkbox("WindowBorder", &window_border)) + style.WindowBorderSize = window_border ? 1.0f : 0.0f; + ImGui::SameLine(); + bool frame_border = (style.FrameBorderSize > 0.0f); + if (ImGui::Checkbox("FrameBorder", &frame_border)) + style.FrameBorderSize = frame_border ? 1.0f : 0.0f; + // Save/Revert button if (ImGui::Button("Save Ref")) *ref = ref_saved_style = style; @@ -1902,19 +1909,25 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) if (ImGui::TreeNode("Settings")) { ImGui::SliderFloat2("WindowPadding", (float*)&style.WindowPadding, 0.0f, 20.0f, "%.0f"); - ImGui::SliderFloat("WindowRounding", &style.WindowRounding, 0.0f, 16.0f, "%.0f"); - ImGui::SliderFloat("ChildRounding", &style.ChildRounding, 0.0f, 16.0f, "%.0f"); ImGui::SliderFloat("PopupRounding", &style.PopupRounding, 0.0f, 16.0f, "%.0f"); ImGui::SliderFloat2("FramePadding", (float*)&style.FramePadding, 0.0f, 20.0f, "%.0f"); - ImGui::SliderFloat("FrameRounding", &style.FrameRounding, 0.0f, 16.0f, "%.0f"); ImGui::SliderFloat2("ItemSpacing", (float*)&style.ItemSpacing, 0.0f, 20.0f, "%.0f"); ImGui::SliderFloat2("ItemInnerSpacing", (float*)&style.ItemInnerSpacing, 0.0f, 20.0f, "%.0f"); ImGui::SliderFloat2("TouchExtraPadding", (float*)&style.TouchExtraPadding, 0.0f, 10.0f, "%.0f"); ImGui::SliderFloat("IndentSpacing", &style.IndentSpacing, 0.0f, 30.0f, "%.0f"); ImGui::SliderFloat("ScrollbarSize", &style.ScrollbarSize, 1.0f, 20.0f, "%.0f"); - ImGui::SliderFloat("ScrollbarRounding", &style.ScrollbarRounding, 0.0f, 16.0f, "%.0f"); ImGui::SliderFloat("GrabMinSize", &style.GrabMinSize, 1.0f, 20.0f, "%.0f"); - ImGui::SliderFloat("GrabRounding", &style.GrabRounding, 0.0f, 16.0f, "%.0f"); + ImGui::Text("BorderSize"); + ImGui::SliderFloat("WindowBorderSize", &style.WindowBorderSize, 0.0f, 1.0f, "%.0f"); + ImGui::SliderFloat("ChildBorderSize", &style.ChildBorderSize, 0.0f, 1.0f, "%.0f"); + ImGui::SliderFloat("PopupBorderSize", &style.PopupBorderSize, 0.0f, 1.0f, "%.0f"); + ImGui::SliderFloat("FrameBorderSize", &style.FrameBorderSize, 0.0f, 1.0f, "%.0f"); + ImGui::Text("Rounding"); + ImGui::SliderFloat("WindowRounding", &style.WindowRounding, 0.0f, 14.0f, "%.0f"); + ImGui::SliderFloat("ChildRounding", &style.ChildRounding, 0.0f, 16.0f, "%.0f"); + ImGui::SliderFloat("FrameRounding", &style.FrameRounding, 0.0f, 12.0f, "%.0f"); + ImGui::SliderFloat("ScrollbarRounding", &style.ScrollbarRounding, 0.0f, 12.0f, "%.0f"); + ImGui::SliderFloat("GrabRounding", &style.GrabRounding, 0.0f, 12.0f, "%.0f"); ImGui::Text("Alignment"); ImGui::SliderFloat2("WindowTitleAlign", (float*)&style.WindowTitleAlign, 0.0f, 1.0f, "%.2f"); ImGui::SliderFloat2("ButtonTextAlign", (float*)&style.ButtonTextAlign, 0.0f, 1.0f, "%.2f"); ImGui::SameLine(); ShowHelpMarker("Alignment applies when a button is larger than its text content."); From 28a31997b76c59dba9d6d2ba03c5c1cf7b3a6ce6 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 19 Nov 2017 16:03:42 +0100 Subject: [PATCH 602/921] Style Editor: Simplified settings also show PopupBorderSize as a checkbox. (#707, #1019) --- imgui_demo.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 7ee7de827..7bf92e348 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1877,13 +1877,11 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) // Simplified Settings if (ImGui::SliderFloat("FrameRounding", &style.FrameRounding, 0.0f, 12.0f, "%.0f")) style.GrabRounding = style.FrameRounding; // Make GrabRounding always the same value as FrameRounding - bool window_border = (style.WindowBorderSize > 0.0f); - if (ImGui::Checkbox("WindowBorder", &window_border)) - style.WindowBorderSize = window_border ? 1.0f : 0.0f; + { bool window_border = (style.WindowBorderSize > 0.0f); if (ImGui::Checkbox("WindowBorder", &window_border)) style.WindowBorderSize = window_border ? 1.0f : 0.0f; } ImGui::SameLine(); - bool frame_border = (style.FrameBorderSize > 0.0f); - if (ImGui::Checkbox("FrameBorder", &frame_border)) - style.FrameBorderSize = frame_border ? 1.0f : 0.0f; + { bool frame_border = (style.FrameBorderSize > 0.0f); if (ImGui::Checkbox("FrameBorder", &frame_border)) style.FrameBorderSize = frame_border ? 1.0f : 0.0f; } + ImGui::SameLine(); + { bool popup_border = (style.PopupBorderSize > 0.0f); if (ImGui::Checkbox("PopupBorder", &popup_border)) style.PopupBorderSize = popup_border ? 1.0f : 0.0f; } // Save/Revert button if (ImGui::Button("Save Ref")) From dc2768503f91b5d11e6cbb76fde873a53e3ccf7f Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 19 Nov 2017 16:24:17 +0100 Subject: [PATCH 603/921] Fix for drag and drop branch. --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 2510fb70d..978277d64 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -10796,7 +10796,7 @@ bool ImGui::BeginDragDropSource(ImGuiDragDropFlags flags, int mouse_button) //PushStyleVar(ImGuiStyleVar_Alpha, g.Style.Alpha * 0.60f); // This is better but e.g ColorButton with checkboard has issue with transparent colors :( SetNextWindowPos(g.IO.MousePos); PushStyleColor(ImGuiCol_PopupBg, GetStyleColorVec4(ImGuiCol_PopupBg) * ImVec4(1.0f, 1.0f, 1.0f, 0.6f)); - BeginTooltipEx(ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_ShowBorders); + BeginTooltipEx(ImGuiWindowFlags_NoInputs); } if (!(flags & ImGuiDragDropFlags_SourceNoDisableHover)) From 8b2d449b165f2214a088f8d0cd8a20b684e99787 Mon Sep 17 00:00:00 2001 From: thedmd Date: Sun, 19 Nov 2017 21:00:38 +0100 Subject: [PATCH 604/921] Add ShadeVertsLinearUV() --- imgui_draw.cpp | 24 ++++++++++++++++++++++++ imgui_internal.h | 2 ++ 2 files changed, 26 insertions(+) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 8718e9783..5d8cc5d91 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1226,6 +1226,30 @@ void ImGui::ShadeVertsLinearAlphaGradientForLeftToRightText(ImDrawVert* vert_sta } } +// Distribute UV over (a, b) rectangle +void ImGui::ShadeVertsLinearUV(ImDrawVert* vert_start, ImDrawVert* vert_end, const ImVec2& a, const ImVec2& b, const ImVec2& uv_a, const ImVec2& uv_b, bool clamp) +{ + const ImVec2 size = b - a; + const ImVec2 uv_size = uv_b - uv_a; + const ImVec2 scale = ImVec2( + size.x ? (uv_size.x / size.x) : 0.0f, + size.y ? (uv_size.y / size.y) : 0.0f); + + if (clamp) + { + const ImVec2 min = ImMin(uv_a, uv_b); + const ImVec2 max = ImMax(uv_a, uv_b); + + for (ImDrawVert* vertex = vert_start; vertex < vert_end; ++vertex) + vertex->uv = ImClamp(uv_a + ImMul(ImVec2(vertex->pos.x, vertex->pos.y) - a, scale), min, max); + } + else + { + for (ImDrawVert* vertex = vert_start; vertex < vert_end; ++vertex) + vertex->uv = uv_a + ImMul(ImVec2(vertex->pos.x, vertex->pos.y) - a, scale); + } +} + //----------------------------------------------------------------------------- // ImFontConfig //----------------------------------------------------------------------------- diff --git a/imgui_internal.h b/imgui_internal.h index 6a5c24aa6..f9c9a7d43 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -155,6 +155,7 @@ static inline ImVec2 ImFloor(const ImVec2& v) static inline float ImDot(const ImVec2& a, const ImVec2& b) { return a.x * b.x + a.y * b.y; } static inline ImVec2 ImRotate(const ImVec2& v, float cos_a, float sin_a) { return ImVec2(v.x * cos_a - v.y * sin_a, v.x * sin_a + v.y * cos_a); } static inline float ImLinearSweep(float current, float target, float speed) { if (current < target) return ImMin(current + speed, target); if (current > target) return ImMax(current - speed, target); return current; } +static inline ImVec2 ImMul(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x * rhs.x, lhs.y * rhs.y); } // We call C++ constructor on own allocated memory via the placement "new(ptr) Type()" syntax. // Defining a custom placement new() with a dummy parameter allows us to bypass including which on some platforms complains when user has disabled exceptions. @@ -873,6 +874,7 @@ namespace ImGui // Shade functions IMGUI_API void ShadeVertsLinearColorGradientKeepAlpha(ImDrawVert* vert_start, ImDrawVert* vert_end, ImVec2 gradient_p0, ImVec2 gradient_p1, ImU32 col0, ImU32 col1); IMGUI_API void ShadeVertsLinearAlphaGradientForLeftToRightText(ImDrawVert* vert_start, ImDrawVert* vert_end, float gradient_p0_x, float gradient_p1_x); + IMGUI_API void ShadeVertsLinearUV(ImDrawVert* vert_start, ImDrawVert* vert_end, const ImVec2& a, const ImVec2& b, const ImVec2& uv_a, const ImVec2& uv_b, bool clamp); } // namespace ImGui From 79f07f6ff040f6bfbf6b86320bf417f1d495966b Mon Sep 17 00:00:00 2001 From: thedmd Date: Sun, 19 Nov 2017 21:48:13 +0100 Subject: [PATCH 605/921] Add AddImageRounded() to ImDrawList --- imgui.h | 2 ++ imgui_draw.cpp | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/imgui.h b/imgui.h index 98e016bf9..b1bba790f 100644 --- a/imgui.h +++ b/imgui.h @@ -1308,6 +1308,7 @@ struct ImDrawList IMGUI_API void AddText(const ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL, float wrap_width = 0.0f, const ImVec4* cpu_fine_clip_rect = NULL); IMGUI_API void AddImage(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& uv_a = ImVec2(0,0), const ImVec2& uv_b = ImVec2(1,1), ImU32 col = 0xFFFFFFFF); IMGUI_API void AddImageQuad(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, const ImVec2& uv_a = ImVec2(0,0), const ImVec2& uv_b = ImVec2(1,0), const ImVec2& uv_c = ImVec2(1,1), const ImVec2& uv_d = ImVec2(0,1), ImU32 col = 0xFFFFFFFF); + IMGUI_API void AddImageRounded(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, float rounding, const ImVec2& uv_a = ImVec2(0,0), const ImVec2& uv_b = ImVec2(1,1), ImU32 col = 0xFFFFFFFF, int rounding_corners = ~0); IMGUI_API void AddPolyline(const ImVec2* points, const int num_points, ImU32 col, bool closed, float thickness, bool anti_aliased); IMGUI_API void AddConvexPolyFilled(const ImVec2* points, const int num_points, ImU32 col, bool anti_aliased); IMGUI_API void AddBezierCurve(const ImVec2& pos0, const ImVec2& cp0, const ImVec2& cp1, const ImVec2& pos1, ImU32 col, float thickness, int num_segments = 0); @@ -1347,6 +1348,7 @@ struct ImDrawList inline void PrimVtx(const ImVec2& pos, const ImVec2& uv, ImU32 col) { PrimWriteIdx((ImDrawIdx)_VtxCurrentIdx); PrimWriteVtx(pos, uv, col); } IMGUI_API void UpdateClipRect(); IMGUI_API void UpdateTextureID(); + IMGUI_API void PrimDistributeUV(ImDrawVert* start, ImDrawVert* end, const ImVec2& a, const ImVec2& b, const ImVec2& uv_a, const ImVec2& uv_b, bool clamp); }; // All draw data to render an ImGui frame diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 5d8cc5d91..e3098f770 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1152,6 +1152,41 @@ void ImDrawList::AddImageQuad(ImTextureID user_texture_id, const ImVec2& a, cons PopTextureID(); } +void ImDrawList::AddImageRounded(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, float rounding, const ImVec2& uv_a, const ImVec2& uv_b, ImU32 col, int rounding_corners) +{ + if ((col & IM_COL32_A_MASK) == 0) + return; + + if (rounding <= 0.0f) + { + AddImage(user_texture_id, a, b, uv_a, uv_b, col); + return; + } + + // FIXME-OPT: This is wasting draw calls. + const bool push_texture_id = _TextureIdStack.empty() || user_texture_id != _TextureIdStack.back(); + if (push_texture_id) + PushTextureID(user_texture_id); + + if (rounding > 0.0f && rounding_corners != 0) + { + size_t startIndex = VtxBuffer.size(); + PathRect(a, b, rounding, rounding_corners); + PathFillConvex(col); + size_t endIndex = VtxBuffer.size(); + + ImGui::ShadeVertsLinearUV(VtxBuffer.Data + startIndex, VtxBuffer.Data + endIndex, a, b, uv_a, uv_b, true); + } + else + { + PrimReserve(6, 4); + PrimRectUV(a, b, uv_a, uv_b, col); + } + + if (push_texture_id) + PopTextureID(); +} + //----------------------------------------------------------------------------- // ImDrawData //----------------------------------------------------------------------------- From e996286c38ff580f0c80c3b22775c785660fa3b6 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 20 Nov 2017 12:40:38 +0100 Subject: [PATCH 606/921] Todo list update --- TODO.txt | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/TODO.txt b/TODO.txt index c305a4114..1271d346f 100644 --- a/TODO.txt +++ b/TODO.txt @@ -24,7 +24,9 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - window: increase minimum size of a window with menus or fix the menu rendering so that it doesn't look odd. - window: double-clicking on title bar to minimize isn't consistent, perhaps move to single-click on left-most collapse icon? - window: expose contents size. (#1045) + - window: resize from borders and/or all corners. (#822) - window: GetWindowSize() returns (0,0) when not calculated? (#1045) + - window: refactor IsWindowFocused(), merge all three existing variants, add flags, similar to #1382. - window: freeze window flag: if not focused/hovered, return false, render with previous ImDrawList. and/or reduce refresh rate. !- scrolling: allow immediately effective change of scroll after Begin() if we haven't appended items yet. - scrolling/clipping: separator on the initial position of a window is not visible (cursorpos.y <= clippos.y). (2017-08-20: can't repro) @@ -35,7 +37,8 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - drawlist: maintaining bounding box per command would allow to merge draw command when clipping isn't relied on (typical non-scrolling window or non-overflowing column would merge with previous command). - drawlist: avoid passing null (-9999,+9999) rectangle to end-user, instead perhaps pass rectangle based on io.DisplaySize? - drawlist: primtiives/helpers to manipulate vertices post submission, so e.g. a quad/rect can be resized to fit later submitted content, _without_ using the ChannelSplit api - + - drawlist: non-AA strokes have gaps between points (#593, #288), especially RenderCheckmark(). + - main: considering adding an Init() function? some constructs are awkward in the implementation because of the lack of them. - main: find a way to preserve relative orders of multiple reappearing windows (so an app toggling between "modes" e.g. fullscreen vs all tools) won't lose relative ordering. - 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 @@ -163,9 +166,11 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - shortcuts: programmatically access shortcuts "Focus("&Save")) - menus: menubars: main menu-bar could affect clamping of windows position (~ akin to modifying DisplayMin) + - text: selectable text (for copy) as a generic feature (ItemFlags?) - text: proper alignment options in imgui_internal.h - text wrapped: figure out better way to use TextWrapped() in an always auto-resize context (tooltip, etc.) (#249) - text: it's currently impossible to have a window title with "##". perhaps an official workaround would be nice. \ style inhibitor? non-visible ascii code to insert between #? + - text link/url button: underlined. should api expose an ID or use text contents as ID? which colors enum to use? - tree node / optimization: avoid formatting when clipped. - tree node: tree-node/header right-most side doesn't take account of horizontal scrolling. @@ -207,6 +212,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - pie menus patterns (#434) - markup: simple markup language for color change? + - font: free the Alpha buffer if user only requested RGBA. !- font: better CalcTextSizeA() API, at least for simple use cases. current one is horrible (perhaps have simple vs extended versions). - font: better vertical centering (based e.g on height of lowercase 'x'?). currently Roboto-Medium size 16 px isn't currently centered. - font: enforce monospace through ImFontConfig (for icons?) + create dual ImFont output from same input, reusing rasterized data but with different glyphs/AdvanceX @@ -228,6 +234,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - nav: integrate navigation branch into master. (#787) - nav: integrate/design keyboard controls. - nav: once tab should go through most/all widgets (in submission order?) + - nav: currently cannot access menubar of a child window with Alt/menu key. - nav: esc/enter default behavior for popups, e.g. be able to mark an "ok" or "cancel" button that would get triggered by those keys. - focus: preserve ActiveId/focus stack state, e.g. when opening a menu and close it, previously selected InputText() focus gets restored (#622) - focus: SetKeyboardFocusHere() on with >= 0 offset could be done on same frame (else latch and modulate on beginning of next frame) @@ -236,7 +243,8 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - inputs: allow to pass explicit double-clicks if that's the only thing the user's backend can get them. (e.g. for windows by the CS_DBLCLKS style). - inputs: support track pad style scrolling & slider edit. - - misc: make the ImGuiCond values linear (non-power-of-two). internal storage for ImGuiWindow can use integers to combine into flags. + - misc: idle refresh: expose cursor blink animation timer for backend to be able to lower framerate. + - misc: make the ImGuiCond values linear (non-power-of-two). internal storage for ImGuiWindow can use integers to combine into flags (Why?) - misc: provide a way to compile out the entire implementation while providing a dummy API (e.g. #define IMGUI_DUMMY_IMPL) - misc: provide HoveredTime and ActivatedTime to ease the creation of animations. - misc: fix for compilation settings where stdcall isn't the default (e.g. vectorcall) (#1230) From 8c0f2e49466ad9d5e78e25aa05a61023a1fa2da4 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 20 Nov 2017 13:05:50 +0100 Subject: [PATCH 607/921] Added comment to help people dealing with 58345b11e1a999ad3fb562a24aade7c6944e5a02 breakage (#707) --- imgui.h | 1 + 1 file changed, 1 insertion(+) diff --git a/imgui.h b/imgui.h index 98e016bf9..de09567b7 100644 --- a/imgui.h +++ b/imgui.h @@ -659,6 +659,7 @@ enum ImGuiCol_ // Obsolete names (will be removed) #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS + //, ImGuiCol_ComboBg = ImGuiCol_PopupBg // ComboBg has been merged with PopupBg, so a redirect isn't accurate. , ImGuiCol_ChildWindowBg = ImGuiCol_ChildBg, ImGuiCol_Column = ImGuiCol_Separator, ImGuiCol_ColumnHovered = ImGuiCol_SeparatorHovered, ImGuiCol_ColumnActive = ImGuiCol_SeparatorActive #endif }; From 7f447c8270e2baaa9dc08f98a3b4ecba42de28e8 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 20 Nov 2017 13:16:57 +0100 Subject: [PATCH 608/921] Color picker: Tweak vertex shading code, since we aren't shading between PrimReserve and PrimVert the code can be expressed more naturally. (#346) --- imgui.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index ca13fcdb4..234d77a98 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -10040,14 +10040,15 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl { const float a0 = (n) /6.0f * 2.0f * IM_PI - aeps; const float a1 = (n+1.0f)/6.0f * 2.0f * IM_PI + aeps; - int vert_start_idx = draw_list->_VtxCurrentIdx; + const int vert_start_idx = draw_list->VtxBuffer.Size; draw_list->PathArcTo(wheel_center, (wheel_r_inner + wheel_r_outer)*0.5f, a0, a1, segment_per_arc); draw_list->PathStroke(IM_COL32_WHITE, false, wheel_thickness); + const int vert_end_idx = draw_list->VtxBuffer.Size; // Paint colors over existing vertices ImVec2 gradient_p0(wheel_center.x + cosf(a0) * wheel_r_inner, wheel_center.y + sinf(a0) * wheel_r_inner); ImVec2 gradient_p1(wheel_center.x + cosf(a1) * wheel_r_inner, wheel_center.y + sinf(a1) * wheel_r_inner); - ShadeVertsLinearColorGradientKeepAlpha(draw_list->_VtxWritePtr - (draw_list->_VtxCurrentIdx - vert_start_idx), draw_list->_VtxWritePtr, gradient_p0, gradient_p1, hue_colors[n], hue_colors[n+1]); + ShadeVertsLinearColorGradientKeepAlpha(draw_list->VtxBuffer.Data + vert_start_idx, draw_list->VtxBuffer.Data + vert_end_idx, gradient_p0, gradient_p1, hue_colors[n], hue_colors[n+1]); } // Render Cursor + preview on Hue Wheel From 3c5e64db782940588e5d7b61e05552126e85775b Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 20 Nov 2017 13:30:25 +0100 Subject: [PATCH 609/921] Demo: Tweaked Image() code. --- imgui_demo.cpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 7bf92e348..a1e8b0836 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -539,7 +539,6 @@ void ImGui::ShowTestWindow(bool* p_open) if (ImGui::TreeNode("Images")) { ImGui::TextWrapped("Below we are displaying the font texture (which is the only texture we have access to in this demo). Use the 'ImTextureID' type as storage to pass pointers or identifier to your own texture data. Hover the texture for a zoomed view!"); - ImVec2 tex_screen_pos = ImGui::GetCursorScreenPos(); ImGuiIO& io = ImGui::GetIO(); // Here we are grabbing the font texture because that's the only one we have access to inside the demo code. @@ -549,23 +548,24 @@ void ImGui::ShowTestWindow(bool* p_open) // If you decided that ImTextureID = MyEngineTexture*, then you can pass your MyEngineTexture* pointers to ImGui::Image(), and gather width/height through your own functions, etc. // Using ShowMetricsWindow() as a "debugger" to inspect the draw data that are being passed to your render will help you debug issues if you are confused about this. // Consider using the lower-level ImDrawList::AddImage() API, via ImGui::GetWindowDrawList()->AddImage(). - ImTextureID tex_id = io.Fonts->TexID; - float tex_w = (float)io.Fonts->TexWidth; - float tex_h = (float)io.Fonts->TexHeight; + ImTextureID my_tex_id = io.Fonts->TexID; + float my_tex_w = (float)io.Fonts->TexWidth; + float my_tex_h = (float)io.Fonts->TexHeight; - ImGui::Text("%.0fx%.0f", tex_w, tex_h); - ImGui::Image(tex_id, ImVec2(tex_w, tex_h), ImVec2(0,0), ImVec2(1,1), ImColor(255,255,255,255), ImColor(255,255,255,128)); + ImGui::Text("%.0fx%.0f", my_tex_w, my_tex_h); + ImVec2 pos = ImGui::GetCursorScreenPos(); + ImGui::Image(my_tex_id, ImVec2(my_tex_w, my_tex_h), ImVec2(0,0), ImVec2(1,1), ImColor(255,255,255,255), ImColor(255,255,255,128)); if (ImGui::IsItemHovered()) { ImGui::BeginTooltip(); float focus_sz = 32.0f; - float focus_x = io.MousePos.x - tex_screen_pos.x - focus_sz * 0.5f; if (focus_x < 0.0f) focus_x = 0.0f; else if (focus_x > tex_w - focus_sz) focus_x = tex_w - focus_sz; - float focus_y = io.MousePos.y - tex_screen_pos.y - focus_sz * 0.5f; if (focus_y < 0.0f) focus_y = 0.0f; else if (focus_y > tex_h - focus_sz) focus_y = tex_h - focus_sz; + float focus_x = io.MousePos.x - pos.x - focus_sz * 0.5f; if (focus_x < 0.0f) focus_x = 0.0f; else if (focus_x > my_tex_w - focus_sz) focus_x = my_tex_w - focus_sz; + float focus_y = io.MousePos.y - pos.y - focus_sz * 0.5f; if (focus_y < 0.0f) focus_y = 0.0f; else if (focus_y > my_tex_h - focus_sz) focus_y = my_tex_h - focus_sz; ImGui::Text("Min: (%.2f, %.2f)", focus_x, focus_y); ImGui::Text("Max: (%.2f, %.2f)", focus_x + focus_sz, focus_y + focus_sz); - ImVec2 uv0 = ImVec2((focus_x) / tex_w, (focus_y) / tex_h); - ImVec2 uv1 = ImVec2((focus_x + focus_sz) / tex_w, (focus_y + focus_sz) / tex_h); - ImGui::Image(tex_id, ImVec2(128,128), uv0, uv1, ImColor(255,255,255,255), ImColor(255,255,255,128)); + ImVec2 uv0 = ImVec2((focus_x) / my_tex_w, (focus_y) / my_tex_h); + ImVec2 uv1 = ImVec2((focus_x + focus_sz) / my_tex_w, (focus_y + focus_sz) / my_tex_h); + ImGui::Image(my_tex_id, ImVec2(128,128), uv0, uv1, ImColor(255,255,255,255), ImColor(255,255,255,128)); ImGui::EndTooltip(); } ImGui::TextWrapped("And now some textured buttons.."); @@ -574,7 +574,7 @@ void ImGui::ShowTestWindow(bool* p_open) { ImGui::PushID(i); int frame_padding = -1 + i; // -1 = uses default padding - if (ImGui::ImageButton(tex_id, ImVec2(32,32), ImVec2(0,0), ImVec2(32.0f/tex_w,32/tex_h), frame_padding, ImColor(0,0,0,255))) + if (ImGui::ImageButton(my_tex_id, ImVec2(32,32), ImVec2(0,0), ImVec2(32.0f/my_tex_w,32/my_tex_h), frame_padding, ImColor(0,0,0,255))) pressed_count += 1; ImGui::PopID(); ImGui::SameLine(); From 31683cfe343ceed744f02e76522a783862abb499 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 20 Nov 2017 13:31:40 +0100 Subject: [PATCH 610/921] ImDrawList::AddImageRounded: removed PrimDistributeUV declaration, fixed coding style, restored argument order from original PR. (#845) --- imgui.h | 3 +-- imgui_draw.cpp | 25 +++++++------------------ 2 files changed, 8 insertions(+), 20 deletions(-) diff --git a/imgui.h b/imgui.h index d182660af..3f760be12 100644 --- a/imgui.h +++ b/imgui.h @@ -1309,7 +1309,7 @@ struct ImDrawList IMGUI_API void AddText(const ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL, float wrap_width = 0.0f, const ImVec4* cpu_fine_clip_rect = NULL); IMGUI_API void AddImage(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& uv_a = ImVec2(0,0), const ImVec2& uv_b = ImVec2(1,1), ImU32 col = 0xFFFFFFFF); IMGUI_API void AddImageQuad(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, const ImVec2& uv_a = ImVec2(0,0), const ImVec2& uv_b = ImVec2(1,0), const ImVec2& uv_c = ImVec2(1,1), const ImVec2& uv_d = ImVec2(0,1), ImU32 col = 0xFFFFFFFF); - IMGUI_API void AddImageRounded(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, float rounding, const ImVec2& uv_a = ImVec2(0,0), const ImVec2& uv_b = ImVec2(1,1), ImU32 col = 0xFFFFFFFF, int rounding_corners = ~0); + IMGUI_API void AddImageRounded(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& uv_a, const ImVec2& uv_b, ImU32 col, float rounding, int rounding_corners = ~0); IMGUI_API void AddPolyline(const ImVec2* points, const int num_points, ImU32 col, bool closed, float thickness, bool anti_aliased); IMGUI_API void AddConvexPolyFilled(const ImVec2* points, const int num_points, ImU32 col, bool anti_aliased); IMGUI_API void AddBezierCurve(const ImVec2& pos0, const ImVec2& cp0, const ImVec2& cp1, const ImVec2& pos1, ImU32 col, float thickness, int num_segments = 0); @@ -1349,7 +1349,6 @@ struct ImDrawList inline void PrimVtx(const ImVec2& pos, const ImVec2& uv, ImU32 col) { PrimWriteIdx((ImDrawIdx)_VtxCurrentIdx); PrimWriteVtx(pos, uv, col); } IMGUI_API void UpdateClipRect(); IMGUI_API void UpdateTextureID(); - IMGUI_API void PrimDistributeUV(ImDrawVert* start, ImDrawVert* end, const ImVec2& a, const ImVec2& b, const ImVec2& uv_a, const ImVec2& uv_b, bool clamp); }; // All draw data to render an ImGui frame diff --git a/imgui_draw.cpp b/imgui_draw.cpp index e3098f770..5dd9581e2 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1124,7 +1124,6 @@ void ImDrawList::AddImage(ImTextureID user_texture_id, const ImVec2& a, const Im if ((col & IM_COL32_A_MASK) == 0) return; - // FIXME-OPT: This is wasting draw calls. const bool push_texture_id = _TextureIdStack.empty() || user_texture_id != _TextureIdStack.back(); if (push_texture_id) PushTextureID(user_texture_id); @@ -1152,36 +1151,26 @@ void ImDrawList::AddImageQuad(ImTextureID user_texture_id, const ImVec2& a, cons PopTextureID(); } -void ImDrawList::AddImageRounded(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, float rounding, const ImVec2& uv_a, const ImVec2& uv_b, ImU32 col, int rounding_corners) +void ImDrawList::AddImageRounded(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& uv_a, const ImVec2& uv_b, ImU32 col, float rounding, int rounding_corners) { if ((col & IM_COL32_A_MASK) == 0) return; - if (rounding <= 0.0f) + if (rounding <= 0.0f || (rounding_corners & ImGuiCorner_All) == 0) { AddImage(user_texture_id, a, b, uv_a, uv_b, col); return; } - // FIXME-OPT: This is wasting draw calls. const bool push_texture_id = _TextureIdStack.empty() || user_texture_id != _TextureIdStack.back(); if (push_texture_id) PushTextureID(user_texture_id); - if (rounding > 0.0f && rounding_corners != 0) - { - size_t startIndex = VtxBuffer.size(); - PathRect(a, b, rounding, rounding_corners); - PathFillConvex(col); - size_t endIndex = VtxBuffer.size(); - - ImGui::ShadeVertsLinearUV(VtxBuffer.Data + startIndex, VtxBuffer.Data + endIndex, a, b, uv_a, uv_b, true); - } - else - { - PrimReserve(6, 4); - PrimRectUV(a, b, uv_a, uv_b, col); - } + int vert_start_idx = VtxBuffer.Size; + PathRect(a, b, rounding, rounding_corners); + PathFillConvex(col); + int vert_end_idx = VtxBuffer.Size; + ImGui::ShadeVertsLinearUV(VtxBuffer.Data + vert_start_idx, VtxBuffer.Data + vert_end_idx, a, b, uv_a, uv_b, true); if (push_texture_id) PopTextureID(); From 3f5b2a3fe353ff29b1b15334964aaec4e7dff576 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 20 Nov 2017 13:53:16 +0100 Subject: [PATCH 611/921] Exposed ImDrawCornerFlags, replaced occurences of ~0 with an explicit ImDrawCornerFlags_All. Inversed BotLeft (prev 1<<3, now 1<<2) and BotRight (prev 1<<2, now 1<<3). --- imgui.cpp | 30 +++++++++++++++--------------- imgui.h | 22 ++++++++++++++++++---- imgui_demo.cpp | 6 ++++-- imgui_draw.cpp | 19 +++++++------------ imgui_internal.h | 9 --------- 5 files changed, 44 insertions(+), 42 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 234d77a98..0754dc1db 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3084,8 +3084,8 @@ void ImGui::RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool border, const float border_size = g.Style.FrameBorderSize; if (border && border_size > 0.0f) { - window->DrawList->AddRect(p_min+ImVec2(1,1), p_max+ImVec2(1,1), GetColorU32(ImGuiCol_BorderShadow), rounding, ~0, border_size); - window->DrawList->AddRect(p_min, p_max, GetColorU32(ImGuiCol_Border), rounding, ~0, border_size); + window->DrawList->AddRect(p_min+ImVec2(1,1), p_max+ImVec2(1,1), GetColorU32(ImGuiCol_BorderShadow), rounding, ImDrawCornerFlags_All, border_size); + window->DrawList->AddRect(p_min, p_max, GetColorU32(ImGuiCol_Border), rounding, ImDrawCornerFlags_All, border_size); } } @@ -3096,8 +3096,8 @@ void ImGui::RenderFrameBorder(ImVec2 p_min, ImVec2 p_max, float rounding) const float border_size = g.Style.FrameBorderSize; if (border_size > 0.0f) { - window->DrawList->AddRect(p_min+ImVec2(1,1), p_max+ImVec2(1,1), GetColorU32(ImGuiCol_BorderShadow), rounding, ~0, border_size); - window->DrawList->AddRect(p_min, p_max, GetColorU32(ImGuiCol_Border), rounding, ~0, border_size); + window->DrawList->AddRect(p_min+ImVec2(1,1), p_max+ImVec2(1,1), GetColorU32(ImGuiCol_BorderShadow), rounding, ImDrawCornerFlags_All, border_size); + window->DrawList->AddRect(p_min, p_max, GetColorU32(ImGuiCol_Border), rounding, ImDrawCornerFlags_All, border_size); } } @@ -4458,18 +4458,18 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // Window background, Default Alpha ImU32 bg_col = GetColorU32(GetWindowBgColorIdxFromFlags(flags)); - window->DrawList->AddRectFilled(window->Pos+ImVec2(0,window->TitleBarHeight()), window->Pos+window->Size, bg_col, window_rounding, (flags & ImGuiWindowFlags_NoTitleBar) ? ImGuiCorner_All : ImGuiCorner_BotLeft|ImGuiCorner_BotRight); + window->DrawList->AddRectFilled(window->Pos+ImVec2(0,window->TitleBarHeight()), window->Pos+window->Size, bg_col, window_rounding, (flags & ImGuiWindowFlags_NoTitleBar) ? ImDrawCornerFlags_All : ImDrawCornerFlags_Bot); // Title bar const bool is_focused = g.NavWindow && window->RootNonPopupWindow == g.NavWindow->RootNonPopupWindow; if (!(flags & ImGuiWindowFlags_NoTitleBar)) - window->DrawList->AddRectFilled(title_bar_rect.GetTL(), title_bar_rect.GetBR(), GetColorU32(is_focused ? ImGuiCol_TitleBgActive : ImGuiCol_TitleBg), window_rounding, ImGuiCorner_TopLeft|ImGuiCorner_TopRight); + window->DrawList->AddRectFilled(title_bar_rect.GetTL(), title_bar_rect.GetBR(), GetColorU32(is_focused ? ImGuiCol_TitleBgActive : ImGuiCol_TitleBg), window_rounding, ImDrawCornerFlags_Top); // Menu bar if (flags & ImGuiWindowFlags_MenuBar) { ImRect menu_bar_rect = window->MenuBarRect(); - window->DrawList->AddRectFilled(menu_bar_rect.GetTL(), menu_bar_rect.GetBR(), GetColorU32(ImGuiCol_MenuBarBg), (flags & ImGuiWindowFlags_NoTitleBar) ? window_rounding : 0.0f, ImGuiCorner_TopLeft|ImGuiCorner_TopRight); + window->DrawList->AddRectFilled(menu_bar_rect.GetTL(), menu_bar_rect.GetBR(), GetColorU32(ImGuiCol_MenuBarBg), (flags & ImGuiWindowFlags_NoTitleBar) ? window_rounding : 0.0f, ImDrawCornerFlags_Top); if (style.FrameBorderSize > 0.0f) window->DrawList->AddLine(menu_bar_rect.GetBL(), menu_bar_rect.GetBR(), GetColorU32(ImGuiCol_Border), style.FrameBorderSize); } @@ -4493,7 +4493,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // Borders if (window_border_size > 0.0f) - window->DrawList->AddRect(window->Pos, window->Pos+window->Size, GetColorU32(ImGuiCol_Border), window_rounding, ~0, window_border_size); + window->DrawList->AddRect(window->Pos, window->Pos+window->Size, GetColorU32(ImGuiCol_Border), window_rounding, ImDrawCornerFlags_All, window_border_size); if (style.FrameBorderSize > 0 && !(flags & ImGuiWindowFlags_NoTitleBar)) window->DrawList->AddLine(title_bar_rect.GetBL()+ImVec2(1,-1), title_bar_rect.GetBR()+ImVec2(-1,-1), GetColorU32(ImGuiCol_Border), style.FrameBorderSize); } @@ -4730,9 +4730,9 @@ void ImGui::Scrollbar(ImGuiLayoutType direction) int window_rounding_corners; if (horizontal) - window_rounding_corners = ImGuiCorner_BotLeft | (other_scrollbar ? 0 : ImGuiCorner_BotRight); + window_rounding_corners = ImDrawCornerFlags_BotLeft | (other_scrollbar ? 0 : ImDrawCornerFlags_BotRight); else - window_rounding_corners = (((window->Flags & ImGuiWindowFlags_NoTitleBar) && !(window->Flags & ImGuiWindowFlags_MenuBar)) ? ImGuiCorner_TopRight : 0) | (other_scrollbar ? 0 : ImGuiCorner_BotRight); + window_rounding_corners = (((window->Flags & ImGuiWindowFlags_NoTitleBar) && !(window->Flags & ImGuiWindowFlags_MenuBar)) ? ImDrawCornerFlags_TopRight : 0) | (other_scrollbar ? 0 : ImDrawCornerFlags_BotRight); window->DrawList->AddRectFilled(bb.Min, bb.Max, GetColorU32(ImGuiCol_ScrollbarBg), window->WindowRounding, window_rounding_corners); bb.Expand(ImVec2(-ImClamp((float)(int)((bb.Max.x - bb.Min.x - 2.0f) * 0.5f), 0.0f, 3.0f), -ImClamp((float)(int)((bb.Max.y - bb.Min.y - 2.0f) * 0.5f), 0.0f, 3.0f))); @@ -9440,8 +9440,8 @@ void ImGui::RenderColorRectWithAlphaCheckerboard(ImVec2 p_min, ImVec2 p_max, ImU if (x2 <= x1) continue; int rounding_corners_flags_cell = 0; - if (y1 <= p_min.y) { if (x1 <= p_min.x) rounding_corners_flags_cell |= ImGuiCorner_TopLeft; if (x2 >= p_max.x) rounding_corners_flags_cell |= ImGuiCorner_TopRight; } - if (y2 >= p_max.y) { if (x1 <= p_min.x) rounding_corners_flags_cell |= ImGuiCorner_BotLeft; if (x2 >= p_max.x) rounding_corners_flags_cell |= ImGuiCorner_BotRight; } + if (y1 <= p_min.y) { if (x1 <= p_min.x) rounding_corners_flags_cell |= ImDrawCornerFlags_TopLeft; if (x2 >= p_max.x) rounding_corners_flags_cell |= ImDrawCornerFlags_TopRight; } + if (y2 >= p_max.y) { if (x1 <= p_min.x) rounding_corners_flags_cell |= ImDrawCornerFlags_BotLeft; if (x2 >= p_max.x) rounding_corners_flags_cell |= ImDrawCornerFlags_BotRight; } rounding_corners_flags_cell &= rounding_corners_flags; window->DrawList->AddRectFilled(ImVec2(x1,y1), ImVec2(x2,y2), col_bg2, rounding_corners_flags_cell ? rounding : 0.0f, rounding_corners_flags_cell); } @@ -9504,8 +9504,8 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl if ((flags & ImGuiColorEditFlags_AlphaPreviewHalf) && col.w < 1.0f) { float mid_x = (float)(int)((bb_inner.Min.x + bb_inner.Max.x) * 0.5f + 0.5f); - RenderColorRectWithAlphaCheckerboard(ImVec2(bb_inner.Min.x + grid_step, bb_inner.Min.y), bb_inner.Max, GetColorU32(col), grid_step, ImVec2(-grid_step + off, off), rounding, ImGuiCorner_TopRight|ImGuiCorner_BotRight); - window->DrawList->AddRectFilled(bb_inner.Min, ImVec2(mid_x, bb_inner.Max.y), GetColorU32(col_without_alpha), rounding, ImGuiCorner_TopLeft|ImGuiCorner_BotLeft); + RenderColorRectWithAlphaCheckerboard(ImVec2(bb_inner.Min.x + grid_step, bb_inner.Min.y), bb_inner.Max, GetColorU32(col), grid_step, ImVec2(-grid_step + off, off), rounding, ImDrawCornerFlags_TopRight| ImDrawCornerFlags_BotRight); + window->DrawList->AddRectFilled(bb_inner.Min, ImVec2(mid_x, bb_inner.Max.y), GetColorU32(col_without_alpha), rounding, ImDrawCornerFlags_TopLeft|ImDrawCornerFlags_BotLeft); } else { @@ -9514,7 +9514,7 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl if (col_source.w < 1.0f) RenderColorRectWithAlphaCheckerboard(bb_inner.Min, bb_inner.Max, GetColorU32(col_source), grid_step, ImVec2(off, off), rounding); else - window->DrawList->AddRectFilled(bb_inner.Min, bb_inner.Max, GetColorU32(col_source), rounding, ~0); + window->DrawList->AddRectFilled(bb_inner.Min, bb_inner.Max, GetColorU32(col_source), rounding, ImDrawCornerFlags_All); } if (g.Style.FrameBorderSize > 0.0f) RenderFrameBorder(bb.Min, bb.Max, rounding); diff --git a/imgui.h b/imgui.h index 3f760be12..319e76b01 100644 --- a/imgui.h +++ b/imgui.h @@ -76,6 +76,7 @@ typedef int ImGuiStyleVar; // enum: a variable identifier for styling typedef int ImGuiKey; // enum: a key identifier (ImGui-side enum) // enum ImGuiKey_ typedef int ImGuiMouseCursor; // enum: a mouse cursor identifier // enum ImGuiMouseCursor_ typedef int ImGuiCond; // enum: a condition for Set*() // enum ImGuiCond_ +typedef int ImDrawCornerFlags; // flags: corner flags for AddRect*() etc. // enum ImDrawCornerFlags_ typedef int ImGuiColorEditFlags; // flags: color edit flags for Color*() // enum ImGuiColorEditFlags_ typedef int ImGuiWindowFlags; // flags: window flags for Begin*() // enum ImGuiWindowFlags_ typedef int ImGuiColumnsFlags; // flags: for *Columns*() // enum ImGuiColumnsFlags_ @@ -1258,6 +1259,19 @@ struct ImDrawChannel ImVector IdxBuffer; }; +enum ImDrawCornerFlags_ +{ + ImDrawCornerFlags_TopLeft = 1 << 0, // 0x1 + ImDrawCornerFlags_TopRight = 1 << 1, // 0x2 + ImDrawCornerFlags_BotLeft = 1 << 2, // 0x4 + ImDrawCornerFlags_BotRight = 1 << 3, // 0x8 + ImDrawCornerFlags_Top = ImDrawCornerFlags_TopLeft | ImDrawCornerFlags_TopRight, // 0x3 + ImDrawCornerFlags_Bot = ImDrawCornerFlags_BotLeft | ImDrawCornerFlags_BotRight, // 0xC + ImDrawCornerFlags_Left = ImDrawCornerFlags_TopLeft | ImDrawCornerFlags_BotLeft, // 0x5 + ImDrawCornerFlags_Right = ImDrawCornerFlags_TopRight | ImDrawCornerFlags_BotRight, // 0xA + ImDrawCornerFlags_All = 0xF // In your function calls you may use ~0 (= all bits sets) instead of ImDrawCornerFlags_All, as a convenience +}; + // Draw command list // This is the low-level list of polygons that ImGui functions are filling. At the end of the frame, all command lists are passed to your ImGuiIO::RenderDrawListFn function for rendering. // At the moment, each ImGui window contains its own ImDrawList but they could potentially be merged in the future. @@ -1296,8 +1310,8 @@ struct ImDrawList // Primitives IMGUI_API void AddLine(const ImVec2& a, const ImVec2& b, ImU32 col, float thickness = 1.0f); - IMGUI_API void AddRect(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding = 0.0f, int rounding_corners_flags = ~0, float thickness = 1.0f); // a: upper-left, b: lower-right, rounding_corners_flags: 4-bits corresponding to which corner to round - IMGUI_API void AddRectFilled(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding = 0.0f, int rounding_corners_flags = ~0); // a: upper-left, b: lower-right + IMGUI_API void AddRect(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding = 0.0f, int rounding_corners_flags = ImDrawCornerFlags_All, float thickness = 1.0f); // a: upper-left, b: lower-right, rounding_corners_flags: 4-bits corresponding to which corner to round + IMGUI_API void AddRectFilled(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding = 0.0f, int rounding_corners_flags = ImDrawCornerFlags_All); // a: upper-left, b: lower-right IMGUI_API void AddRectFilledMultiColor(const ImVec2& a, const ImVec2& b, ImU32 col_upr_left, ImU32 col_upr_right, ImU32 col_bot_right, ImU32 col_bot_left); IMGUI_API void AddQuad(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, ImU32 col, float thickness = 1.0f); IMGUI_API void AddQuadFilled(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, ImU32 col); @@ -1309,7 +1323,7 @@ struct ImDrawList IMGUI_API void AddText(const ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL, float wrap_width = 0.0f, const ImVec4* cpu_fine_clip_rect = NULL); IMGUI_API void AddImage(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& uv_a = ImVec2(0,0), const ImVec2& uv_b = ImVec2(1,1), ImU32 col = 0xFFFFFFFF); IMGUI_API void AddImageQuad(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, const ImVec2& uv_a = ImVec2(0,0), const ImVec2& uv_b = ImVec2(1,0), const ImVec2& uv_c = ImVec2(1,1), const ImVec2& uv_d = ImVec2(0,1), ImU32 col = 0xFFFFFFFF); - IMGUI_API void AddImageRounded(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& uv_a, const ImVec2& uv_b, ImU32 col, float rounding, int rounding_corners = ~0); + IMGUI_API void AddImageRounded(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& uv_a, const ImVec2& uv_b, ImU32 col, float rounding, int rounding_corners = ImDrawCornerFlags_All); IMGUI_API void AddPolyline(const ImVec2* points, const int num_points, ImU32 col, bool closed, float thickness, bool anti_aliased); IMGUI_API void AddConvexPolyFilled(const ImVec2* points, const int num_points, ImU32 col, bool anti_aliased); IMGUI_API void AddBezierCurve(const ImVec2& pos0, const ImVec2& cp0, const ImVec2& cp1, const ImVec2& pos1, ImU32 col, float thickness, int num_segments = 0); @@ -1323,7 +1337,7 @@ struct ImDrawList IMGUI_API void PathArcTo(const ImVec2& centre, float radius, float a_min, float a_max, int num_segments = 10); IMGUI_API void PathArcToFast(const ImVec2& centre, float radius, int a_min_of_12, int a_max_of_12); // Use precomputed angles for a 12 steps circle IMGUI_API void PathBezierCurveTo(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, int num_segments = 0); - IMGUI_API void PathRect(const ImVec2& rect_min, const ImVec2& rect_max, float rounding = 0.0f, int rounding_corners_flags = ~0); // rounding_corners_flags: 4-bits corresponding to which corner to round + IMGUI_API void PathRect(const ImVec2& rect_min, const ImVec2& rect_max, float rounding = 0.0f, int rounding_corners_flags = ImDrawCornerFlags_All); // Channels // - Use to simulate layers. By switching channels to can render out-of-order (e.g. submit foreground primitives before background primitives) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index a1e8b0836..b1fefba49 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -2315,8 +2315,9 @@ static void ShowExampleAppCustomRendering(bool* p_open) { float thickness = (n == 0) ? 1.0f : 4.0f; draw_list->AddCircle(ImVec2(x+sz*0.5f, y+sz*0.5f), sz*0.5f, col32, 20, thickness); x += sz+spacing; - draw_list->AddRect(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, 0.0f, ~0, thickness); x += sz+spacing; - draw_list->AddRect(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, 10.0f, ~0, thickness); x += sz+spacing; + draw_list->AddRect(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, 0.0f, ImDrawCornerFlags_All, thickness); x += sz+spacing; + draw_list->AddRect(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, 10.0f, ImDrawCornerFlags_All, thickness); x += sz+spacing; + draw_list->AddRect(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, 10.0f, ImDrawCornerFlags_TopLeft|ImDrawCornerFlags_BotRight, thickness); x += sz+spacing; draw_list->AddTriangle(ImVec2(x+sz*0.5f, y), ImVec2(x+sz,y+sz-0.5f), ImVec2(x,y+sz-0.5f), col32, thickness); x += sz+spacing; draw_list->AddLine(ImVec2(x, y), ImVec2(x+sz, y ), col32, thickness); x += sz+spacing; draw_list->AddLine(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, thickness); x += sz+spacing; @@ -2328,6 +2329,7 @@ static void ShowExampleAppCustomRendering(bool* p_open) draw_list->AddCircleFilled(ImVec2(x+sz*0.5f, y+sz*0.5f), sz*0.5f, col32, 32); x += sz+spacing; draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x+sz, y+sz), col32); x += sz+spacing; draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, 10.0f); x += sz+spacing; + draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, 10.0f, ImDrawCornerFlags_TopLeft|ImDrawCornerFlags_BotRight); x += sz+spacing; draw_list->AddTriangleFilled(ImVec2(x+sz*0.5f, y), ImVec2(x+sz,y+sz-0.5f), ImVec2(x,y+sz-0.5f), col32); x += sz+spacing; draw_list->AddRectFilledMultiColor(ImVec2(x, y), ImVec2(x+sz, y+sz), ImColor(0,0,0), ImColor(255,0,0), ImColor(255,255,0), ImColor(0,255,0)); ImGui::Dummy(ImVec2((sz+spacing)*8, (sz+spacing)*3)); diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 5dd9581e2..28d25e2d7 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -931,13 +931,8 @@ void ImDrawList::PathBezierCurveTo(const ImVec2& p2, const ImVec2& p3, const ImV void ImDrawList::PathRect(const ImVec2& a, const ImVec2& b, float rounding, int rounding_corners) { - const int corners_top = ImGuiCorner_TopLeft | ImGuiCorner_TopRight; - const int corners_bottom = ImGuiCorner_BotLeft | ImGuiCorner_BotRight; - const int corners_left = ImGuiCorner_TopLeft | ImGuiCorner_BotLeft; - const int corners_right = ImGuiCorner_TopRight | ImGuiCorner_BotRight; - - rounding = ImMin(rounding, fabsf(b.x - a.x) * ( ((rounding_corners & corners_top) == corners_top) || ((rounding_corners & corners_bottom) == corners_bottom) ? 0.5f : 1.0f ) - 1.0f); - rounding = ImMin(rounding, fabsf(b.y - a.y) * ( ((rounding_corners & corners_left) == corners_left) || ((rounding_corners & corners_right) == corners_right) ? 0.5f : 1.0f ) - 1.0f); + rounding = ImMin(rounding, fabsf(b.x - a.x) * ( ((rounding_corners & ImDrawCornerFlags_Top) == ImDrawCornerFlags_Top) || ((rounding_corners & ImDrawCornerFlags_Bot) == ImDrawCornerFlags_Bot) ? 0.5f : 1.0f ) - 1.0f); + rounding = ImMin(rounding, fabsf(b.y - a.y) * ( ((rounding_corners & ImDrawCornerFlags_Left) == ImDrawCornerFlags_Left) || ((rounding_corners & ImDrawCornerFlags_Right) == ImDrawCornerFlags_Right) ? 0.5f : 1.0f ) - 1.0f); if (rounding <= 0.0f || rounding_corners == 0) { @@ -948,10 +943,10 @@ void ImDrawList::PathRect(const ImVec2& a, const ImVec2& b, float rounding, int } else { - const float rounding_tl = (rounding_corners & ImGuiCorner_TopLeft) ? rounding : 0.0f; - const float rounding_tr = (rounding_corners & ImGuiCorner_TopRight) ? rounding : 0.0f; - const float rounding_br = (rounding_corners & ImGuiCorner_BotRight) ? rounding : 0.0f; - const float rounding_bl = (rounding_corners & ImGuiCorner_BotLeft) ? rounding : 0.0f; + const float rounding_tl = (rounding_corners & ImDrawCornerFlags_TopLeft) ? rounding : 0.0f; + const float rounding_tr = (rounding_corners & ImDrawCornerFlags_TopRight) ? rounding : 0.0f; + const float rounding_br = (rounding_corners & ImDrawCornerFlags_BotRight) ? rounding : 0.0f; + const float rounding_bl = (rounding_corners & ImDrawCornerFlags_BotLeft) ? rounding : 0.0f; PathArcToFast(ImVec2(a.x + rounding_tl, a.y + rounding_tl), rounding_tl, 6, 9); PathArcToFast(ImVec2(b.x - rounding_tr, a.y + rounding_tr), rounding_tr, 9, 12); PathArcToFast(ImVec2(b.x - rounding_br, b.y - rounding_br), rounding_br, 0, 3); @@ -1156,7 +1151,7 @@ void ImDrawList::AddImageRounded(ImTextureID user_texture_id, const ImVec2& a, c if ((col & IM_COL32_A_MASK) == 0) return; - if (rounding <= 0.0f || (rounding_corners & ImGuiCorner_All) == 0) + if (rounding <= 0.0f || (rounding_corners & ImDrawCornerFlags_All) == 0) { AddImage(user_texture_id, a, b, uv_a, uv_b, col); return; diff --git a/imgui_internal.h b/imgui_internal.h index f9c9a7d43..cf62d9150 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -243,15 +243,6 @@ enum ImGuiDir ImGuiDir_Down = 3 }; -enum ImGuiCorner -{ - ImGuiCorner_TopLeft = 1 << 0, // 1 - ImGuiCorner_TopRight = 1 << 1, // 2 - ImGuiCorner_BotRight = 1 << 2, // 4 - ImGuiCorner_BotLeft = 1 << 3, // 8 - ImGuiCorner_All = 0x0F -}; - // 2D axis aligned bounding-box // NB: we can't rely on ImVec2 math operators being available here struct IMGUI_API ImRect From 195abc3d178525d7d85f0629a6de2e7610692eca Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 20 Nov 2017 15:19:38 +0100 Subject: [PATCH 612/921] Begin: Fix border size latch when rounding uses Child or Popup value. (#707) --- imgui.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 0754dc1db..1c1853020 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4270,15 +4270,15 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) } } - // Lock window padding so that altering the border sizes for children doesn't have side-effects. - window->WindowPadding = style.WindowPadding; - if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & (ImGuiWindowFlags_AlwaysUseWindowPadding | ImGuiWindowFlags_ComboBox | ImGuiWindowFlags_Popup)) && style.WindowBorderSize == 0.0f) - window->WindowPadding = ImVec2(0.0f, (flags & ImGuiWindowFlags_MenuBar) ? style.WindowPadding.y : 0.0f); + // Lock window rounding, border size and rounding so that altering the border sizes for children doesn't have side-effects. window->WindowRounding = (flags & ImGuiWindowFlags_ChildWindow) ? style.ChildRounding : ((flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiWindowFlags_Modal)) ? style.PopupRounding : style.WindowRounding; window->WindowBorderSize = (flags & ImGuiWindowFlags_ChildWindow) ? style.ChildBorderSize : ((flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiWindowFlags_Modal)) ? style.PopupBorderSize : style.WindowBorderSize; - const ImVec2 window_padding = window->WindowPadding; + window->WindowPadding = style.WindowPadding; + if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & (ImGuiWindowFlags_AlwaysUseWindowPadding | ImGuiWindowFlags_ComboBox | ImGuiWindowFlags_Popup)) && window->WindowBorderSize == 0.0f) + window->WindowPadding = ImVec2(0.0f, (flags & ImGuiWindowFlags_MenuBar) ? style.WindowPadding.y : 0.0f); const float window_rounding = window->WindowRounding; const float window_border_size = window->WindowBorderSize; + const ImVec2 window_padding = window->WindowPadding; // Calculate auto-fit size, handle automatic resize const ImVec2 size_auto_fit = CalcSizeAutoFit(window); From 302757447aa6f0eed177e6cb33de887242a6355e Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 20 Nov 2017 19:39:27 +0100 Subject: [PATCH 613/921] Internals: Added SplitterBehavior(). (#319) --- imgui.cpp | 49 ++++++++++++++++++++++++++++++++++++++++++++++++ imgui_internal.h | 8 ++++++++ 2 files changed, 57 insertions(+) diff --git a/imgui.cpp b/imgui.cpp index 1c1853020..c074864c3 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -10184,6 +10184,55 @@ void ImGui::VerticalSeparator() LogText(" |"); } +bool ImGui::SplitterBehavior(ImGuiID id, const ImRect& bb, ImGuiAxis axis, float* size1, float* size2, float min_size1, float min_size2, float hover_extend) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + + const ImGuiItemFlags item_flags_backup = window->DC.ItemFlags; +#ifdef IMGUI_HAS_NAV + window->DC.ItemFlags |= ImGuiItemFlags_NoNav | ImGuiItemFlags_NoNavDefaultFocus; +#endif + bool add = ItemAdd(bb, id); + window->DC.ItemFlags = item_flags_backup; + if (!add) + return false; + + bool hovered, held; + ImRect bb_interact = bb; + bb_interact.Expand(axis == ImGuiAxis_Y ? ImVec2(0.0f, hover_extend) : ImVec2(hover_extend, 0.0f)); + ButtonBehavior(bb_interact, id, &hovered, &held, ImGuiButtonFlags_FlattenChilds | ImGuiButtonFlags_AllowOverlapMode); + if (g.ActiveId != id) + SetItemAllowOverlap(); + + if (held || (g.HoveredId == id && g.HoveredIdPreviousFrame == id)) + SetMouseCursor(axis == ImGuiAxis_Y ? ImGuiMouseCursor_ResizeNS : ImGuiMouseCursor_ResizeEW); + + ImRect bb_render = bb; + if (held) + { + ImVec2 mouse_delta_2d = g.IO.MousePos - g.ActiveIdClickOffset - bb_interact.Min; + float mouse_delta = (axis == ImGuiAxis_Y) ? mouse_delta_2d.y : mouse_delta_2d.x; + + // Minimum pane size + if (mouse_delta < min_size1 - *size1) + mouse_delta = min_size1 - *size1; + if (mouse_delta > *size2 - min_size2) + mouse_delta = *size2 - min_size2; + + // Apply resize + *size1 += mouse_delta; + *size2 -= mouse_delta; + bb_render.Translate((axis == ImGuiAxis_X) ? ImVec2(mouse_delta, 0.0f) : ImVec2(0.0f, mouse_delta)); + } + + // Render + const ImU32 col = GetColorU32(held ? ImGuiCol_SeparatorActive : hovered ? ImGuiCol_SeparatorHovered : ImGuiCol_Separator); + RenderFrame(bb_render.Min, bb_render.Max, col, true, g.Style.FrameRounding); + + return held; +} + void ImGui::Spacing() { ImGuiWindow* window = GetCurrentWindow(); diff --git a/imgui_internal.h b/imgui_internal.h index cf62d9150..e54936a5b 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -221,6 +221,13 @@ enum ImGuiLayoutType_ ImGuiLayoutType_Horizontal }; +enum ImGuiAxis +{ + ImGuiAxis_None = -1, + ImGuiAxis_X = 0, + ImGuiAxis_Y = 1, +}; + enum ImGuiPlotType { ImGuiPlotType_Lines, @@ -807,6 +814,7 @@ namespace ImGui IMGUI_API void Scrollbar(ImGuiLayoutType direction); IMGUI_API void VerticalSeparator(); // Vertical separator, for menu bars (use current line height). not exposed because it is misleading what it doesn't have an effect on regular layout. + IMGUI_API bool SplitterBehavior(ImGuiID id, const ImRect& bb, ImGuiAxis axis, float* size1, float* size2, float min_size1, float min_size2, float hover_extend = 0.0f); // FIXME-WIP: New Columns API IMGUI_API void BeginColumns(const char* id, int count, ImGuiColumnsFlags flags = 0); // setup number of columns. use an identifier to distinguish multiple column sets. close with EndColumns(). From 176d8fbe747d63ecf282480e258ad9a174816404 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 22 Nov 2017 11:02:42 +0100 Subject: [PATCH 614/921] Fixed unreferenced variable warnings. --- imgui.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index c074864c3..023662932 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3747,9 +3747,9 @@ bool ImGui::BeginPopupModal(const char* name, bool* p_open, ImGuiWindowFlags ext void ImGui::EndPopup() { - ImGuiWindow* window = GetCurrentWindow(); - IM_ASSERT(window->Flags & ImGuiWindowFlags_Popup); // Mismatched BeginPopup()/EndPopup() calls - IM_ASSERT(GImGui->CurrentPopupStack.Size > 0); + ImGuiContext& g = *GImGui; (void)g; + IM_ASSERT(g.CurrentWindow->Flags & ImGuiWindowFlags_Popup); // Mismatched BeginPopup()/EndPopup() calls + IM_ASSERT(g.CurrentPopupStack.Size > 0); End(); } @@ -4278,7 +4278,6 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->WindowPadding = ImVec2(0.0f, (flags & ImGuiWindowFlags_MenuBar) ? style.WindowPadding.y : 0.0f); const float window_rounding = window->WindowRounding; const float window_border_size = window->WindowBorderSize; - const ImVec2 window_padding = window->WindowPadding; // Calculate auto-fit size, handle automatic resize const ImVec2 size_auto_fit = CalcSizeAutoFit(window); From 21b456e5678c196c0fe242dc0e82cc22be5d1307 Mon Sep 17 00:00:00 2001 From: Giuseppe Barbieri Date: Wed, 22 Nov 2017 11:19:52 +0100 Subject: [PATCH 615/921] Update imgui.cpp --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 023662932..1d2a5a773 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9717,7 +9717,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag PushItemWidth(w_items_all); if (InputText("##Text", buf, IM_ARRAYSIZE(buf), ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsUppercase)) { - value_changed |= true; + value_changed = true; char* p = buf; while (*p == '#' || ImCharIsSpace(*p)) p++; From aafa6cece5b7eea039db5c56cb11032d9441be8b Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 22 Nov 2017 11:26:16 +0100 Subject: [PATCH 616/921] Tweak expression to be less weird (how did that ever happen?) --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 1d2a5a773..2323dce02 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9697,7 +9697,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag if (n + 1 == components) PushItemWidth(w_item_last); if (flags & ImGuiColorEditFlags_Float) - value_changed |= value_changed_as_float |= DragFloat(ids[n], &f[n], 1.0f/255.0f, 0.0f, hdr ? 0.0f : 1.0f, fmt_table_float[fmt_idx][n]); + value_changed = value_changed_as_float = value_changed | DragFloat(ids[n], &f[n], 1.0f/255.0f, 0.0f, hdr ? 0.0f : 1.0f, fmt_table_float[fmt_idx][n]); else value_changed |= DragInt(ids[n], &i[n], 1.0f, 0, hdr ? 0 : 255, fmt_table_int[fmt_idx][n]); if (!(flags & ImGuiColorEditFlags_NoOptions)) From 1b2ec35b8ded8399cc3d47642121e090ef353f65 Mon Sep 17 00:00:00 2001 From: Giuseppe Barbieri Date: Wed, 22 Nov 2017 12:58:11 +0100 Subject: [PATCH 617/921] Update imgui_draw.cpp --- imgui_draw.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 28d25e2d7..481014443 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -237,8 +237,8 @@ void ImGui::StyleColorsLight(ImGuiStyle* dst) colors[ImGuiCol_FrameBgHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.40f); colors[ImGuiCol_FrameBgActive] = ImVec4(0.26f, 0.59f, 0.98f, 0.67f); colors[ImGuiCol_TitleBg] = ImVec4(0.96f, 0.96f, 0.96f, 1.00f); - colors[ImGuiCol_TitleBgCollapsed] = ImVec4(1.00f, 1.00f, 1.00f, 0.51f); colors[ImGuiCol_TitleBgActive] = ImVec4(0.82f, 0.82f, 0.82f, 1.00f); + colors[ImGuiCol_TitleBgCollapsed] = ImVec4(1.00f, 1.00f, 1.00f, 0.51f); colors[ImGuiCol_MenuBarBg] = ImVec4(0.86f, 0.86f, 0.86f, 1.00f); colors[ImGuiCol_ScrollbarBg] = ImVec4(0.98f, 0.98f, 0.98f, 0.53f); colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.69f, 0.69f, 0.69f, 0.80f); From 7763ab3fcc1f728f35919aae2225c05b084f16c4 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 22 Nov 2017 12:26:50 +0100 Subject: [PATCH 618/921] Menu bar: better software clipping to handle small windows, in particular child window don't have the minimum constraint added in e9a7e73bbaacec886f9b39130428b81b7f95bf16 so we need to render clipped menus better. --- imgui.cpp | 23 ++++++++++++++--------- imgui_internal.h | 1 + 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 2323dce02..c1361f735 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4460,16 +4460,17 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->DrawList->AddRectFilled(window->Pos+ImVec2(0,window->TitleBarHeight()), window->Pos+window->Size, bg_col, window_rounding, (flags & ImGuiWindowFlags_NoTitleBar) ? ImDrawCornerFlags_All : ImDrawCornerFlags_Bot); // Title bar - const bool is_focused = g.NavWindow && window->RootNonPopupWindow == g.NavWindow->RootNonPopupWindow; + const bool window_is_focused = g.NavWindow && window->RootNonPopupWindow == g.NavWindow->RootNonPopupWindow; if (!(flags & ImGuiWindowFlags_NoTitleBar)) - window->DrawList->AddRectFilled(title_bar_rect.GetTL(), title_bar_rect.GetBR(), GetColorU32(is_focused ? ImGuiCol_TitleBgActive : ImGuiCol_TitleBg), window_rounding, ImDrawCornerFlags_Top); + window->DrawList->AddRectFilled(title_bar_rect.Min, title_bar_rect.Max, GetColorU32(window_is_focused ? ImGuiCol_TitleBgActive : ImGuiCol_TitleBg), window_rounding, ImDrawCornerFlags_Top); // Menu bar if (flags & ImGuiWindowFlags_MenuBar) { ImRect menu_bar_rect = window->MenuBarRect(); - window->DrawList->AddRectFilled(menu_bar_rect.GetTL(), menu_bar_rect.GetBR(), GetColorU32(ImGuiCol_MenuBarBg), (flags & ImGuiWindowFlags_NoTitleBar) ? window_rounding : 0.0f, ImDrawCornerFlags_Top); - if (style.FrameBorderSize > 0.0f) + menu_bar_rect.ClipWith(window->Rect()); // Soft clipping, in particular child window don't have minimum size covering the menu bar so this is useful for them. + window->DrawList->AddRectFilled(menu_bar_rect.Min, menu_bar_rect.Max, GetColorU32(ImGuiCol_MenuBarBg), (flags & ImGuiWindowFlags_NoTitleBar) ? window_rounding : 0.0f, ImDrawCornerFlags_Top); + if (style.FrameBorderSize > 0.0f && menu_bar_rect.Max.y < window->Pos.y + window->Size.y) window->DrawList->AddLine(menu_bar_rect.GetBL(), menu_bar_rect.GetBR(), GetColorU32(ImGuiCol_Border), style.FrameBorderSize); } @@ -9231,14 +9232,18 @@ bool ImGui::BeginMenuBar() if (!(window->Flags & ImGuiWindowFlags_MenuBar)) return false; - ImGuiContext& g = *GImGui; IM_ASSERT(!window->DC.MenuBarAppending); BeginGroup(); // Save position PushID("##menubar"); - ImRect rect = window->MenuBarRect(); - rect.Max.x = ImMax(rect.Min.x, rect.Max.x - g.Style.WindowRounding); - PushClipRect(ImVec2(ImFloor(rect.Min.x+0.5f), ImFloor(rect.Min.y + window->WindowBorderSize + 0.5f)), ImVec2(ImFloor(rect.Max.x+0.5f), ImFloor(rect.Max.y+0.5f)), false); - window->DC.CursorPos = ImVec2(rect.Min.x + window->DC.MenuBarOffsetX, rect.Min.y);// + g.Style.FramePadding.y); + + // We don't clip with regular window clipping rectangle as it is already set to the area below. However we clip with window full rect. + // We remove 1 worth of rounding to Max.x to that text in long menus don't tend to display over the lower-right rounded area, which looks particularly glitchy. + ImRect bar_rect = window->MenuBarRect(); + ImRect clip_rect(ImFloor(bar_rect.Min.x + 0.5f), ImFloor(bar_rect.Min.y + window->WindowBorderSize + 0.5f), ImFloor(ImMax(bar_rect.Min.x, bar_rect.Max.x - window->WindowRounding) + 0.5f), ImFloor(bar_rect.Max.y + 0.5f)); + clip_rect.ClipWith(window->Rect()); + PushClipRect(clip_rect.Min, clip_rect.Max, false); + + window->DC.CursorPos = ImVec2(bar_rect.Min.x + window->DC.MenuBarOffsetX, bar_rect.Min.y);// + g.Style.FramePadding.y); window->DC.LayoutType = ImGuiLayoutType_Horizontal; window->DC.MenuBarAppending = true; AlignTextToFramePadding(); diff --git a/imgui_internal.h b/imgui_internal.h index e54936a5b..f155abf74 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -746,6 +746,7 @@ public: ImGuiID GetID(const void* ptr); ImGuiID GetIDNoKeepAlive(const char* str, const char* str_end = NULL); + // We don't use g.FontSize because the window may be != g.CurrentWidow. ImRect Rect() const { return ImRect(Pos.x, Pos.y, Pos.x+Size.x, Pos.y+Size.y); } float CalcFontSize() const { return GImGui->FontBaseSize * FontWindowScale; } float TitleBarHeight() const { return (Flags & ImGuiWindowFlags_NoTitleBar) ? 0.0f : CalcFontSize() + GImGui->Style.FramePadding.y * 2.0f; } From 6bd3b45b34476b77e95874db1934b95e910db189 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 24 Nov 2017 09:23:17 +0100 Subject: [PATCH 619/921] Sisyphus says: tweaked comments about not using old-style OpenGL examples (#1459, #1394 etc.) --- examples/README.txt | 13 +++++++------ examples/opengl2_example/imgui_impl_glfw.cpp | 13 +++++++------ examples/opengl2_example/imgui_impl_glfw.h | 5 +++-- examples/opengl2_example/main.cpp | 5 +++-- imgui.cpp | 3 +-- 5 files changed, 21 insertions(+), 18 deletions(-) diff --git a/examples/README.txt b/examples/README.txt index 35490b5b6..8ec8e7528 100644 --- a/examples/README.txt +++ b/examples/README.txt @@ -46,12 +46,13 @@ Also note that some setup or GPU drivers may be causing extra lag (possibly by e leaving you with no option but sadness/anger (Intel GPU drivers were reported as such). opengl2_example/ - *DO NOT USE THIS CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL* - GLFW + OpenGL example (old, fixed graphic pipeline). - This is mostly provided as a reference to learn how ImGui integration works, because it is easier to read. - If your code is using GL3+ context or any semi modern OpenGL calls, using this is likely to make everything - more complicated, will require your code to reset every single OpenGL attributes to their initial state, - and might confuse your GPU driver. Prefer using opengl3_example. + **DO NOT USE THIS CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL (SHADERS, VBO, VAO, etc.)** + **Prefer using the code in the opengl3_example/ folder** + GLFW + OpenGL example (legacy fixed graphic pipeline). + This code is mostly provided as a reference to learn how ImGui integration works, because it is shorter to read. + If your code is using GL3+ context or any semi modern OpenGL calls, using this is likely to make everything more + complicated, will require your code to reset every single OpenGL attributes to their initial state, and might + confuse your GPU driver. opengl3_example/ GLFW + OpenGL example (programmable pipeline, binding modern functions with GL3W). diff --git a/examples/opengl2_example/imgui_impl_glfw.cpp b/examples/opengl2_example/imgui_impl_glfw.cpp index 52962c19e..b6bb56a31 100644 --- a/examples/opengl2_example/imgui_impl_glfw.cpp +++ b/examples/opengl2_example/imgui_impl_glfw.cpp @@ -1,12 +1,13 @@ -// ImGui GLFW binding with OpenGL +// ImGui GLFW binding with OpenGL (legacy fixed pipeline) // In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. // (GLFW is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan graphics context creation, etc.) -// *DO NOT USE THIS CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL* -// This is mostly provided as a reference to learn how ImGui integration works, because it is easier to read. -// If your code is using GL3+ context or any semi modern OpenGL calls, using this is likely to make everything -// more complicated, will require your code to reset every single OpenGL attributes to their initial state, -// and might confuse your GPU driver. Prefer using opengl3_example. +// **DO NOT USE THIS CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL (SHADERS, VBO, VAO, etc.)** +// **Prefer using the code in the opengl3_example/ folder** +// This code is mostly provided as a reference to learn how ImGui integration works, because it is shorter to read. +// If your code is using GL3+ context or any semi modern OpenGL calls, using this is likely to make everything more +// complicated, will require your code to reset every single OpenGL attributes to their initial state, and might +// confuse your GPU driver. // The GL2 code is unable to reset attributes or even call e.g. "glUseProgram(0)" because they don't exist in that API. // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. diff --git a/examples/opengl2_example/imgui_impl_glfw.h b/examples/opengl2_example/imgui_impl_glfw.h index f17833ae1..22f910eaa 100644 --- a/examples/opengl2_example/imgui_impl_glfw.h +++ b/examples/opengl2_example/imgui_impl_glfw.h @@ -1,8 +1,9 @@ -// ImGui GLFW binding with OpenGL +// ImGui GLFW binding with OpenGL (legacy fixed pipeline) // In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. // (GLFW is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan graphics context creation, etc.) -// *DO NOT USE THIS CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL* +// **DO NOT USE THIS CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL (SHADERS, VBO, VAO, etc.)** +// **Prefer using the code in the opengl3_example/ folder** // See imgui_impl_glfw.cpp for details. // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. diff --git a/examples/opengl2_example/main.cpp b/examples/opengl2_example/main.cpp index 1f3336d21..ed8f1a7b6 100644 --- a/examples/opengl2_example/main.cpp +++ b/examples/opengl2_example/main.cpp @@ -1,8 +1,9 @@ -// ImGui - standalone example application for GLFW + OpenGL 2, using fixed pipeline +// ImGui - standalone example application for GLFW + OpenGL2, using legacy fixed pipeline // If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. // (GLFW is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan graphics context creation, etc.) -// *DO NOT USE THIS CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL* +// **DO NOT USE THIS CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL (SHADERS, VBO, VAO, etc.)** +// **Prefer using the code in the opengl3_example/ folder** // See imgui_impl_glfw.cpp for details. #include diff --git a/imgui.cpp b/imgui.cpp index c1361f735..0c209b67b 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -103,8 +103,7 @@ - Add the Dear ImGui source files to your projects, using your preferred build system. It is recommended you build the .cpp files as part of your project and not as a library. - You can later customize the imconfig.h file to tweak some compilation time behavior, such as integrating imgui types with your own maths types. - - See examples/ folder for standalone sample applications. To understand the integration process, you can read examples/opengl2_example/ because - it is short, then switch to the one more appropriate to your use case. + - See examples/ folder for standalone sample applications. - You may be able to grab and copy a ready made imgui_impl_*** file from the examples/. - When using Dear ImGui, your programming IDE is your friend: follow the declaration of variables, functions and types to find comments about them. From ef5dd30625913d8aef7083d4bc2f711131f7a86c Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 24 Nov 2017 09:27:45 +0100 Subject: [PATCH 620/921] Sisyphus says: tweaked comments about not using old-style OpenGL examples (#1459, #1394 etc.) --- examples/README.txt | 19 +++++++++++-------- examples/opengl2_example/imgui_impl_glfw.cpp | 2 +- examples/opengl2_example/imgui_impl_glfw.h | 2 +- .../sdl_opengl2_example/imgui_impl_sdl.cpp | 13 +++++++------ examples/sdl_opengl2_example/imgui_impl_sdl.h | 6 +++++- examples/sdl_opengl2_example/main.cpp | 3 ++- 6 files changed, 27 insertions(+), 18 deletions(-) diff --git a/examples/README.txt b/examples/README.txt index 8ec8e7528..1f00756f1 100644 --- a/examples/README.txt +++ b/examples/README.txt @@ -48,7 +48,7 @@ leaving you with no option but sadness/anger (Intel GPU drivers were reported as opengl2_example/ **DO NOT USE THIS CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL (SHADERS, VBO, VAO, etc.)** **Prefer using the code in the opengl3_example/ folder** - GLFW + OpenGL example (legacy fixed graphic pipeline). + GLFW + OpenGL example (legacy, fixed pipeline). This code is mostly provided as a reference to learn how ImGui integration works, because it is shorter to read. If your code is using GL3+ context or any semi modern OpenGL calls, using this is likely to make everything more complicated, will require your code to reset every single OpenGL attributes to their initial state, and might @@ -57,7 +57,7 @@ opengl2_example/ opengl3_example/ GLFW + OpenGL example (programmable pipeline, binding modern functions with GL3W). This uses more modern OpenGL calls and custom shaders. - Prefer using that if you are using modern OpenGL3/4 in your application. + Prefer using that if you are using modern OpenGL in your application (anything with shaders, vbo, vao, etc.). directx9_example/ DirectX9 example, Windows only. @@ -76,15 +76,18 @@ apple_example/ Synergy keyboard integration is rather hacky. sdl_opengl2_example/ - *DO NOT USE THIS CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL* - SDL2 + OpenGL example (old fixed pipeline). - This is mostly provided as a reference to learn how ImGui integration works, because it is easier to read. - If your code is using GL3+ context or any semi modern OpenGL calls, using this is likely to make everything - more complicated, will require your code to reset every single OpenGL attributes to their initial state, - and might confuse your GPU driver. Prefer using sdl_opengl3_example. + **DO NOT USE THIS CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL (SHADERS, VBO, VAO, etc.)** + **Prefer using the code in the sdl_opengl3_example/ folder** + SDL2 + OpenGL example (legacy, fixed pipeline). + This code is mostly provided as a reference to learn how ImGui integration works, because it is shorter to read. + If your code is using GL3+ context or any semi modern OpenGL calls, using this is likely to make everything more + complicated, will require your code to reset every single OpenGL attributes to their initial state, and might + confuse your GPU driver. sdl_opengl3_example/ SDL2 + OpenGL3 example. + This uses more modern OpenGL calls and custom shaders. + Prefer using that if you are using modern OpenGL in your application (anything with shaders, vbo, vao, etc.). allegro5_example/ Allegro 5 example. diff --git a/examples/opengl2_example/imgui_impl_glfw.cpp b/examples/opengl2_example/imgui_impl_glfw.cpp index b6bb56a31..364d92889 100644 --- a/examples/opengl2_example/imgui_impl_glfw.cpp +++ b/examples/opengl2_example/imgui_impl_glfw.cpp @@ -1,4 +1,4 @@ -// ImGui GLFW binding with OpenGL (legacy fixed pipeline) +// ImGui GLFW binding with OpenGL (legacy, fixed pipeline) // In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. // (GLFW is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan graphics context creation, etc.) diff --git a/examples/opengl2_example/imgui_impl_glfw.h b/examples/opengl2_example/imgui_impl_glfw.h index 22f910eaa..d04a84fa8 100644 --- a/examples/opengl2_example/imgui_impl_glfw.h +++ b/examples/opengl2_example/imgui_impl_glfw.h @@ -1,4 +1,4 @@ -// ImGui GLFW binding with OpenGL (legacy fixed pipeline) +// ImGui GLFW binding with OpenGL (legacy, fixed pipeline) // In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. // (GLFW is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan graphics context creation, etc.) diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl.cpp b/examples/sdl_opengl2_example/imgui_impl_sdl.cpp index 2982f8dee..66f3ed5a8 100644 --- a/examples/sdl_opengl2_example/imgui_impl_sdl.cpp +++ b/examples/sdl_opengl2_example/imgui_impl_sdl.cpp @@ -1,12 +1,13 @@ -// ImGui SDL2 binding with OpenGL +// ImGui SDL2 binding with OpenGL (legacy, fixed pipeline) // In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. // (SDL is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan graphics context creation, etc.) -// *DO NOT USE THIS CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL* -// This is mostly provided as a reference to learn how ImGui integration works, because it is easier to read. -// If your code is using GL3+ context or any semi modern OpenGL calls, using this is likely to make everything -// more complicated, will require your code to reset every single OpenGL attributes to their initial state, -// and might confuse your GPU driver. Prefer using sdl_opengl3_example. +// **DO NOT USE THIS CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL (SHADERS, VBO, VAO, etc.)** +// **Prefer using the code in the sdl_opengl3_example/ folder** +// This code is mostly provided as a reference to learn how ImGui integration works, because it is shorter to read. +// If your code is using GL3+ context or any semi modern OpenGL calls, using this is likely to make everything more +// complicated, will require your code to reset every single OpenGL attributes to their initial state, and might +// confuse your GPU driver. // The GL2 code is unable to reset attributes or even call e.g. "glUseProgram(0)" because they don't exist in that API. // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl.h b/examples/sdl_opengl2_example/imgui_impl_sdl.h index ea94f69a7..32d7bc0e9 100644 --- a/examples/sdl_opengl2_example/imgui_impl_sdl.h +++ b/examples/sdl_opengl2_example/imgui_impl_sdl.h @@ -1,7 +1,11 @@ -// ImGui SDL2 binding with OpenGL +// ImGui SDL2 binding with OpenGL (legacy, fixed pipeline) // In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. // (SDL is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan graphics context creation, etc.) +// **DO NOT USE THIS CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL (SHADERS, VBO, VAO, etc.)** +// **Prefer using the code in the sdl_opengl3_example/ folder** +// See imgui_impl_sdl.cpp for details. + // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. // If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). // If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. diff --git a/examples/sdl_opengl2_example/main.cpp b/examples/sdl_opengl2_example/main.cpp index cfa43e8e8..77241a5ba 100644 --- a/examples/sdl_opengl2_example/main.cpp +++ b/examples/sdl_opengl2_example/main.cpp @@ -2,7 +2,8 @@ // If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. // (SDL is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan graphics context creation, etc.) -// *DO NOT USE THIS CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL* +// **DO NOT USE THIS CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL (SHADERS, VBO, VAO, etc.)** +// **Prefer using the code in the sdl_opengl3_example/ folder** // See imgui_impl_sdl.cpp for details. #include From d9c5d72962b4f88491cf570aaaa2b0ce8e2b6fb9 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 24 Nov 2017 11:26:42 +0100 Subject: [PATCH 621/921] ImGuiStorage: Added BuildSortByKey() helper to rebuild storage from stratch. --- imgui.cpp | 17 +++++++++++++++++ imgui.h | 3 +++ 2 files changed, 20 insertions(+) diff --git a/imgui.cpp b/imgui.cpp index 0c209b67b..211bd299d 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1411,6 +1411,23 @@ static ImVector::iterator LowerBound(ImVectorkey > ((const Pair*)rhs)->key) return +1; + if (((const Pair*)lhs)->key < ((const Pair*)rhs)->key) return -1; + return 0; + } + }; + if (Data.Size > 1) + qsort(Data.Data, (size_t)Data.Size, sizeof(Pair), StaticFunc::PairCompareByID); +} + int ImGuiStorage::GetInt(ImGuiID key, int default_val) const { ImVector::iterator it = LowerBound(const_cast&>(Data), key); diff --git a/imgui.h b/imgui.h index 319e76b01..4599d705f 100644 --- a/imgui.h +++ b/imgui.h @@ -1097,6 +1097,9 @@ struct ImGuiStorage // Use on your own storage if you know only integer are being stored (open/close all tree nodes) IMGUI_API void SetAllInt(int val); + + // For quicker full rebuild of a storage (instead of an incremental one), you may add all your contents and then sort once. + IMGUI_API void BuildSortByKey(); }; // Shared state of InputText(), passed to callback when a ImGuiInputTextFlags_Callback* flag is used and the corresponding callback is triggered. From 0f955b818d729805300f9e0aed936fa794d71b5b Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 26 Nov 2017 11:44:52 +0100 Subject: [PATCH 622/921] Fixed DroidSans font link (#1460) --- extra_fonts/README.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extra_fonts/README.txt b/extra_fonts/README.txt index a41360831..5d41a6bb8 100644 --- a/extra_fonts/README.txt +++ b/extra_fonts/README.txt @@ -153,7 +153,7 @@ DroidSans.ttf Copyright (c) Steve Matteson Apache License, version 2.0 - http://www.google.com/fonts/specimen/Droid+Sans + https://www.fontsquirrel.com/fonts/droid-sans ProggyClean.ttf Copyright (c) 2004, 2005 Tristan Grimmer From 532f564fd325421d11991c21a5e8bdfbb2b1bc26 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 27 Nov 2017 16:55:06 +0100 Subject: [PATCH 623/921] ImGuiTextBuffer: Renamed append() helper to appendf(), appendv() to appendfv(). Added reserve(). --- imgui.cpp | 9 +++++---- imgui.h | 5 +++-- imgui_demo.cpp | 4 ++-- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 211bd299d..505fa0a8d 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -213,6 +213,7 @@ Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. Also read releases logs https://github.com/ocornut/imgui/releases for more details. + - 2017/11/27 (1.53) - renamed ImGuiTextBuffer::append() helper to appendf(), appendv() to appendfv(). If you copied the 'Log' demo in your code, it uses appendv() so that needs to be renamed. - 2017/11/18 (1.53) - Style, Begin: removed ImGuiWindowFlags_ShowBorders window flag. Borders are now fully set up in the ImGuiStyle structure (see e.g. style.FrameBorderSize, style.WindowBorderSize). Use ImGui::ShowStyleEditor() to look them up. Please note that the style system will keep evolving (hopefully stabilizing in Q1 2018), and so custom styles will probably subtly break over time. It is recommended you use the StyleColorsClassic(), StyleColorsDark(), StyleColorsLight() functions. - 2017/11/18 (1.53) - Style: removed ImGuiCol_ComboBg in favor of combo boxes using ImGuiCol_PopupBg for consistency. @@ -1643,7 +1644,7 @@ bool ImGuiTextFilter::PassFilter(const char* text, const char* text_end) const #endif // Helper: Text buffer for logging/accumulating text -void ImGuiTextBuffer::appendv(const char* fmt, va_list args) +void ImGuiTextBuffer::appendfv(const char* fmt, va_list args) { va_list args_copy; va_copy(args_copy, args); @@ -1664,11 +1665,11 @@ void ImGuiTextBuffer::appendv(const char* fmt, va_list args) ImFormatStringV(&Buf[write_off - 1], len + 1, fmt, args_copy); } -void ImGuiTextBuffer::append(const char* fmt, ...) +void ImGuiTextBuffer::appendf(const char* fmt, ...) { va_list args; va_start(args, fmt); - appendv(fmt, args); + appendfv(fmt, args); va_end(args); } @@ -2947,7 +2948,7 @@ void ImGui::LogText(const char* fmt, ...) } else { - g.LogClipboard->appendv(fmt, args); + g.LogClipboard->appendfv(fmt, args); } va_end(args); } diff --git a/imgui.h b/imgui.h index 4599d705f..309730f2f 100644 --- a/imgui.h +++ b/imgui.h @@ -1048,9 +1048,10 @@ struct ImGuiTextBuffer int size() const { return Buf.Size - 1; } bool empty() { return Buf.Size <= 1; } void clear() { Buf.clear(); Buf.push_back(0); } + void reserve(int capacity) { Buf.reserve(capacity); } const char* c_str() const { return Buf.Data; } - IMGUI_API void append(const char* fmt, ...) IM_FMTARGS(2); - IMGUI_API void appendv(const char* fmt, va_list args) IM_FMTLIST(2); + IMGUI_API void appendf(const char* fmt, ...) IM_FMTARGS(2); + IMGUI_API void appendfv(const char* fmt, va_list args) IM_FMTLIST(2); }; // Helper: Simple Key->value storage diff --git a/imgui_demo.cpp b/imgui_demo.cpp index b1fefba49..30a4ce464 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -2707,7 +2707,7 @@ struct ExampleAppLog int old_size = Buf.size(); va_list args; va_start(args, fmt); - Buf.appendv(fmt, args); + Buf.appendfv(fmt, args); va_end(args); for (int new_size = Buf.size(); old_size < new_size; old_size++) if (Buf[old_size] == '\n') @@ -2911,7 +2911,7 @@ static void ShowExampleAppLongText(bool* p_open) if (ImGui::Button("Add 1000 lines")) { for (int i = 0; i < 1000; i++) - log.append("%i The quick brown fox jumps over the lazy dog\n", lines+i); + log.appendf("%i The quick brown fox jumps over the lazy dog\n", lines+i); lines += 1000; } ImGui::BeginChild("Log"); From ade09b9e3c7bbc3e46256fea10b64ce992eec331 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 27 Nov 2017 19:01:40 +0100 Subject: [PATCH 624/921] Settings: Basic internal refactor to have functions for saving from/to memory (not exposed) --- imgui.cpp | 52 ++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 36 insertions(+), 16 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 505fa0a8d..fcf3e8c39 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -646,7 +646,9 @@ static void AddWindowToSortedBuffer(ImVector& out_sort static ImGuiIniData* FindWindowSettings(const char* name); static ImGuiIniData* AddWindowSettings(const char* name); static void LoadIniSettingsFromDisk(const char* ini_filename); +static void LoadIniSettingsFromMemory(const char* buf, const char* buf_end = NULL); static void SaveIniSettingsToDisk(const char* ini_filename); +static void SaveIniSettingsToMemory(ImVector& out_buf); static void MarkIniSettingsDirty(ImGuiWindow* window); static ImRect GetVisibleRect(); @@ -2562,18 +2564,23 @@ static ImGuiIniData* AddWindowSettings(const char* name) // FIXME: Write something less rubbish static void LoadIniSettingsFromDisk(const char* ini_filename) { - ImGuiContext& g = *GImGui; if (!ini_filename) return; - int file_size; char* file_data = (char*)ImFileLoadToMemory(ini_filename, "rb", &file_size, 1); if (!file_data) return; + LoadIniSettingsFromMemory(file_data, file_data + file_size); + ImGui::MemFree(file_data); +} +static void LoadIniSettingsFromMemory(const char* buf, const char* buf_end) +{ + ImGuiContext& g = *GImGui; + if (!buf_end) + buf_end = buf + strlen(buf); ImGuiIniData* settings = NULL; - const char* buf_end = file_data + file_size; - for (const char* line_start = file_data; line_start < buf_end; ) + for (const char* line_start = buf; line_start < buf_end; ) { const char* line_end = line_start; while (line_end < buf_end && *line_end != '\n' && *line_end != '\r') @@ -2601,8 +2608,6 @@ static void LoadIniSettingsFromDisk(const char* ini_filename) line_start = line_end+1; } - - ImGui::MemFree(file_data); } static void SaveIniSettingsToDisk(const char* ini_filename) @@ -2612,6 +2617,22 @@ static void SaveIniSettingsToDisk(const char* ini_filename) if (!ini_filename) return; + ImVector buf; + SaveIniSettingsToMemory(buf); + + // Write .ini file + FILE* f = ImFileOpen(ini_filename, "wt"); + if (!f) + return; + fwrite(buf.Data, sizeof(char), (size_t)buf.Size, f); + fclose(f); +} + +static void SaveIniSettingsToMemory(ImVector& out_buf) +{ + ImGuiContext& g = *GImGui; + g.SettingsDirtyTimer = 0.0f; + // Gather data from windows that were active during this session for (int i = 0; i != g.Windows.Size; i++) { @@ -2626,11 +2647,10 @@ static void SaveIniSettingsToDisk(const char* ini_filename) settings->Collapsed = window->Collapsed; } - // Write .ini file + // Write a buffer // If a window wasn't opened in this session we preserve its settings - FILE* f = ImFileOpen(ini_filename, "wt"); - if (!f) - return; + ImGuiTextBuffer buf; + buf.reserve(g.Settings.Size * 64); // ballpark reserve for (int i = 0; i != g.Settings.Size; i++) { const ImGuiIniData* settings = &g.Settings[i]; @@ -2639,14 +2659,14 @@ static void SaveIniSettingsToDisk(const char* ini_filename) const char* name = settings->Name; if (const char* p = strstr(name, "###")) // Skip to the "###" marker if any. We don't skip past to match the behavior of GetID() name = p; - fprintf(f, "[%s]\n", name); - fprintf(f, "Pos=%d,%d\n", (int)settings->Pos.x, (int)settings->Pos.y); - fprintf(f, "Size=%d,%d\n", (int)settings->Size.x, (int)settings->Size.y); - fprintf(f, "Collapsed=%d\n", settings->Collapsed); - fprintf(f, "\n"); + buf.appendf("[%s]\n", name); + buf.appendf("Pos=%d,%d\n", (int)settings->Pos.x, (int)settings->Pos.y); + buf.appendf("Size=%d,%d\n", (int)settings->Size.x, (int)settings->Size.y); + buf.appendf("Collapsed=%d\n", settings->Collapsed); + buf.appendf("\n"); } - fclose(f); + out_buf.swap(buf.Buf); } static void MarkIniSettingsDirty(ImGuiWindow* window) From 77a310736dfbd79c9d0cf8f52835ed5f4d859441 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emmanuel=20Beno=C3=AEt?= Date: Mon, 27 Nov 2017 20:36:23 +0100 Subject: [PATCH 625/921] Horizontal mouse wheel support This patch adds support for the horizontal mouse wheel in ImGui. It affects windows that can be scrolled, as long as the Ctrl key is not being pressed. The scrolling speed has been set empirically so that it matches the scrolling speed on the Firefox browser when the horizontal wheel is used. Internally, it adds a MouseHorizWheel to ImGuiIO, which is then used in NewFrame to scroll the current window. The SDL/GL2, SDL/GL3, GLFW/GL2 and GLFW/GL3 examples has been modified to use it. --- examples/opengl2_example/imgui_impl_glfw.cpp | 9 ++++++--- .../opengl3_example/imgui_impl_glfw_gl3.cpp | 9 ++++++--- .../sdl_opengl2_example/imgui_impl_sdl.cpp | 8 +++++++- .../sdl_opengl3_example/imgui_impl_sdl_gl3.cpp | 8 +++++++- imgui.cpp | 18 ++++++++++++++++++ imgui.h | 1 + 6 files changed, 45 insertions(+), 8 deletions(-) diff --git a/examples/opengl2_example/imgui_impl_glfw.cpp b/examples/opengl2_example/imgui_impl_glfw.cpp index 364d92889..8aa6395ac 100644 --- a/examples/opengl2_example/imgui_impl_glfw.cpp +++ b/examples/opengl2_example/imgui_impl_glfw.cpp @@ -31,6 +31,7 @@ static GLFWwindow* g_Window = NULL; static double g_Time = 0.0f; static bool g_MouseJustPressed[3] = { false, false, false }; +static float g_MouseHorizWheel = 0.0f; static float g_MouseWheel = 0.0f; static GLuint g_FontTexture = 0; @@ -136,9 +137,10 @@ void ImGui_ImplGlfwGL2_MouseButtonCallback(GLFWwindow*, int button, int action, g_MouseJustPressed[button] = true; } -void ImGui_ImplGlfwGL2_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset) +void ImGui_ImplGlfwGL2_ScrollCallback(GLFWwindow*, double xoffset, double yoffset) { - g_MouseWheel += (float)yoffset; // Use fractional mouse wheel. + g_MouseHorizWheel += (float)xoffset; // Use fractional mouse wheel. + g_MouseWheel += (float)yoffset; } void ImGui_ImplGlfwGL2_KeyCallback(GLFWwindow*, int key, int, int action, int mods) @@ -296,8 +298,9 @@ void ImGui_ImplGlfwGL2_NewFrame() g_MouseJustPressed[i] = false; } + io.MouseHorizWheel = g_MouseHorizWheel; io.MouseWheel = g_MouseWheel; - g_MouseWheel = 0.0f; + g_MouseHorizWheel = g_MouseWheel = 0.0f; // Hide OS mouse cursor if ImGui is drawing it glfwSetInputMode(g_Window, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL); diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp index 7d924fcf1..01accf0c2 100644 --- a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp +++ b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp @@ -25,6 +25,7 @@ static GLFWwindow* g_Window = NULL; static double g_Time = 0.0f; static bool g_MouseJustPressed[3] = { false, false, false }; +static float g_MouseHorizWheel = 0.0f; static float g_MouseWheel = 0.0f; static GLuint g_FontTexture = 0; static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; @@ -155,9 +156,10 @@ void ImGui_ImplGlfwGL3_MouseButtonCallback(GLFWwindow*, int button, int action, g_MouseJustPressed[button] = true; } -void ImGui_ImplGlfwGL3_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset) +void ImGui_ImplGlfwGL3_ScrollCallback(GLFWwindow*, double xoffset, double yoffset) { - g_MouseWheel += (float)yoffset; // Use fractional mouse wheel. + g_MouseHorizWheel += (float)xoffset; // Use fractional mouse wheel. + g_MouseWheel += (float)yoffset; } void ImGui_ImplGlfwGL3_KeyCallback(GLFWwindow*, int key, int, int action, int mods) @@ -408,8 +410,9 @@ void ImGui_ImplGlfwGL3_NewFrame() g_MouseJustPressed[i] = false; } + io.MouseHorizWheel = g_MouseHorizWheel; io.MouseWheel = g_MouseWheel; - g_MouseWheel = 0.0f; + g_MouseHorizWheel = g_MouseWheel = 0.0f; // Hide OS mouse cursor if ImGui is drawing it glfwSetInputMode(g_Window, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL); diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl.cpp b/examples/sdl_opengl2_example/imgui_impl_sdl.cpp index 66f3ed5a8..b0a2553dc 100644 --- a/examples/sdl_opengl2_example/imgui_impl_sdl.cpp +++ b/examples/sdl_opengl2_example/imgui_impl_sdl.cpp @@ -24,6 +24,7 @@ // Data static double g_Time = 0.0f; static bool g_MousePressed[3] = { false, false, false }; +static float g_MouseHorizWheel = 0.0f; static float g_MouseWheel = 0.0f; static GLuint g_FontTexture = 0; @@ -134,6 +135,10 @@ bool ImGui_ImplSdlGL2_ProcessEvent(SDL_Event* event) { case SDL_MOUSEWHEEL: { + if (event->wheel.x > 0) + g_MouseHorizWheel = 1; + if (event->wheel.x < 0) + g_MouseHorizWheel = -1; if (event->wheel.y > 0) g_MouseWheel = 1; if (event->wheel.y < 0) @@ -285,8 +290,9 @@ void ImGui_ImplSdlGL2_NewFrame(SDL_Window *window) io.MouseDown[2] = g_MousePressed[2] || (mouseMask & SDL_BUTTON(SDL_BUTTON_MIDDLE)) != 0; g_MousePressed[0] = g_MousePressed[1] = g_MousePressed[2] = false; + io.MouseHorizWheel = g_MouseHorizWheel; io.MouseWheel = g_MouseWheel; - g_MouseWheel = 0.0f; + g_MouseWheel = g_MouseHorizWheel = 0.0f; // Hide OS mouse cursor if ImGui is drawing it SDL_ShowCursor(io.MouseDrawCursor ? 0 : 1); diff --git a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp index 68e27a68c..933669cf4 100644 --- a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp +++ b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp @@ -19,6 +19,7 @@ // Data static double g_Time = 0.0f; static bool g_MousePressed[3] = { false, false, false }; +static float g_MouseHorizWheel = 0.0f; static float g_MouseWheel = 0.0f; static GLuint g_FontTexture = 0; static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; @@ -154,6 +155,10 @@ bool ImGui_ImplSdlGL3_ProcessEvent(SDL_Event* event) { case SDL_MOUSEWHEEL: { + if (event->wheel.x > 0) + g_MouseHorizWheel = 1; + if (event->wheel.x < 0) + g_MouseHorizWheel = -1; if (event->wheel.y > 0) g_MouseWheel = 1; if (event->wheel.y < 0) @@ -396,8 +401,9 @@ void ImGui_ImplSdlGL3_NewFrame(SDL_Window* window) io.MouseDown[2] = g_MousePressed[2] || (mouseMask & SDL_BUTTON(SDL_BUTTON_MIDDLE)) != 0; g_MousePressed[0] = g_MousePressed[1] = g_MousePressed[2] = false; + io.MouseHorizWheel = g_MouseHorizWheel; io.MouseWheel = g_MouseWheel; - g_MouseWheel = 0.0f; + g_MouseHorizWheel = g_MouseWheel = 0.0f; // Hide OS mouse cursor if ImGui is drawing it SDL_ShowCursor(io.MouseDrawCursor ? 0 : 1); diff --git a/imgui.cpp b/imgui.cpp index 211bd299d..f13cfb4d6 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -628,6 +628,7 @@ static bool IsKeyPressedMap(ImGuiKey key, bool repeat = true); static ImFont* GetDefaultFont(); static void SetCurrentFont(ImFont* font); static void SetCurrentWindow(ImGuiWindow* window); +static void SetWindowScrollX(ImGuiWindow* window, float new_scroll_x); static void SetWindowScrollY(ImGuiWindow* window, float new_scroll_y); static void SetWindowPos(ImGuiWindow* window, const ImVec2& pos, ImGuiCond cond); static void SetWindowSize(ImGuiWindow* window, const ImVec2& size, ImGuiCond cond); @@ -2430,6 +2431,16 @@ void ImGui::NewFrame() } } + // Horizontal wheel scrolling; for consistency, only allowed if Ctrl is not pressed. + if (g.HoveredWindow && g.IO.MouseHorizWheel != 0.0f && !g.HoveredWindow->Collapsed) + { + ImGuiWindow* window = g.HoveredWindow; + if (!g.IO.KeyCtrl && !(window->Flags & ImGuiWindowFlags_NoScrollWithMouse)) + { + SetWindowScrollX(window, window->Scroll.x - g.IO.MouseHorizWheel * 10.f); + } + } + // Pressing TAB activate widget focus if (g.ActiveId == 0 && g.NavWindow != NULL && g.NavWindow->Active && IsKeyPressedMap(ImGuiKey_Tab, false)) g.NavWindow->FocusIdxTabRequestNext = 0; @@ -5244,6 +5255,13 @@ ImVec2 ImGui::GetWindowPos() return window->Pos; } +static void SetWindowScrollX(ImGuiWindow* window, float new_scroll_x) +{ + window->DC.CursorMaxPos.x += window->Scroll.x; // SizeContents is generally computed based on CursorMaxPos which is affected by scroll position, so we need to apply our change to it. + window->Scroll.x = new_scroll_x; + window->DC.CursorMaxPos.x -= window->Scroll.x; +} + static void SetWindowScrollY(ImGuiWindow* window, float new_scroll_y) { window->DC.CursorMaxPos.y += window->Scroll.y; // SizeContents is generally computed based on CursorMaxPos which is affected by scroll position, so we need to apply our change to it. diff --git a/imgui.h b/imgui.h index 4599d705f..d45b5e865 100644 --- a/imgui.h +++ b/imgui.h @@ -856,6 +856,7 @@ struct ImGuiIO ImVec2 MousePos; // Mouse position, in pixels. Set to ImVec2(-FLT_MAX,-FLT_MAX) if mouse is unavailable (on another screen, etc.) bool MouseDown[5]; // Mouse buttons: left, right, middle + extras. ImGui itself mostly only uses left button (BeginPopupContext** are using right button). Others buttons allows us to track if the mouse is being used by your application + available to user as a convenience via IsMouse** API. float MouseWheel; // Mouse wheel: 1 unit scrolls about 5 lines text. + float MouseHorizWheel; // Horizontal mouse wheel bool MouseDrawCursor; // Request ImGui to draw a mouse cursor for you (if you are on a platform without a mouse cursor). bool KeyCtrl; // Keyboard modifier pressed: Control bool KeyShift; // Keyboard modifier pressed: Shift From d552cabd15017f61a291787935985b97d2e0380c Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 27 Nov 2017 23:00:27 +0100 Subject: [PATCH 626/921] Settings: Internal renaming of structure and fields names. --- imgui.cpp | 50 +++++++++++++++++++++++++----------------------- imgui_internal.h | 6 +++--- 2 files changed, 29 insertions(+), 27 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index fcf3e8c39..8b6189881 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -643,8 +643,9 @@ static void AddDrawListToRenderList(ImVector& out_rende static void AddWindowToRenderList(ImVector& out_render_list, ImGuiWindow* window); static void AddWindowToSortedBuffer(ImVector& out_sorted_windows, ImGuiWindow* window); -static ImGuiIniData* FindWindowSettings(const char* name); -static ImGuiIniData* AddWindowSettings(const char* name); +static ImGuiSettingsWindow* FindWindowSettings(const char* name); +static ImGuiSettingsWindow* AddWindowSettings(const char* name); + static void LoadIniSettingsFromDisk(const char* ini_filename); static void LoadIniSettingsFromMemory(const char* buf, const char* buf_end = NULL); static void SaveIniSettingsToDisk(const char* ini_filename); @@ -2468,7 +2469,7 @@ void ImGui::Initialize() g.LogClipboard = (ImGuiTextBuffer*)ImGui::MemAlloc(sizeof(ImGuiTextBuffer)); IM_PLACEMENT_NEW(g.LogClipboard) ImGuiTextBuffer(); - IM_ASSERT(g.Settings.empty()); + IM_ASSERT(g.SettingsWindows.empty()); LoadIniSettingsFromDisk(g.IO.IniFilename); g.Initialized = true; } @@ -2503,9 +2504,9 @@ void ImGui::Shutdown() g.HoveredRootWindow = NULL; g.ActiveIdWindow = NULL; g.MovingWindow = NULL; - for (int i = 0; i < g.Settings.Size; i++) - ImGui::MemFree(g.Settings[i].Name); - g.Settings.clear(); + for (int i = 0; i < g.SettingsWindows.Size; i++) + ImGui::MemFree(g.SettingsWindows[i].Name); + g.SettingsWindows.clear(); g.ColorModifiers.clear(); g.StyleModifiers.clear(); g.FontStack.clear(); @@ -2535,29 +2536,30 @@ void ImGui::Shutdown() g.Initialized = false; } -static ImGuiIniData* FindWindowSettings(const char* name) +static ImGuiSettingsWindow* FindWindowSettings(const char* name) { ImGuiContext& g = *GImGui; ImGuiID id = ImHash(name, 0); - for (int i = 0; i != g.Settings.Size; i++) + for (int i = 0; i != g.SettingsWindows.Size; i++) { - ImGuiIniData* ini = &g.Settings[i]; + ImGuiSettingsWindow* ini = &g.SettingsWindows[i]; if (ini->Id == id) return ini; } return NULL; } -static ImGuiIniData* AddWindowSettings(const char* name) +static ImGuiSettingsWindow* AddWindowSettings(const char* name) { - GImGui->Settings.resize(GImGui->Settings.Size + 1); - ImGuiIniData* ini = &GImGui->Settings.back(); - ini->Name = ImStrdup(name); - ini->Id = ImHash(name, 0); - ini->Collapsed = false; - ini->Pos = ImVec2(FLT_MAX,FLT_MAX); - ini->Size = ImVec2(0,0); - return ini; + ImGuiContext& g = *GImGui; + g.SettingsWindows.resize(g.SettingsWindows.Size + 1); + ImGuiSettingsWindow* settings = &g.SettingsWindows.back(); + settings->Name = ImStrdup(name); + settings->Id = ImHash(name, 0); + settings->Collapsed = false; + settings->Pos = ImVec2(FLT_MAX,FLT_MAX); + settings->Size = ImVec2(0,0); + return settings; } // Zero-tolerance, poor-man .ini parsing @@ -2579,7 +2581,7 @@ static void LoadIniSettingsFromMemory(const char* buf, const char* buf_end) ImGuiContext& g = *GImGui; if (!buf_end) buf_end = buf + strlen(buf); - ImGuiIniData* settings = NULL; + ImGuiSettingsWindow* settings = NULL; for (const char* line_start = buf; line_start < buf_end; ) { const char* line_end = line_start; @@ -2639,7 +2641,7 @@ static void SaveIniSettingsToMemory(ImVector& out_buf) ImGuiWindow* window = g.Windows[i]; if (window->Flags & ImGuiWindowFlags_NoSavedSettings) continue; - ImGuiIniData* settings = FindWindowSettings(window->Name); + ImGuiSettingsWindow* settings = FindWindowSettings(window->Name); if (!settings) // This will only return NULL in the rare instance where the window was first created with ImGuiWindowFlags_NoSavedSettings then had the flag disabled later on. We don't bind settings in this case (bug #1000). continue; settings->Pos = window->Pos; @@ -2650,10 +2652,10 @@ static void SaveIniSettingsToMemory(ImVector& out_buf) // Write a buffer // If a window wasn't opened in this session we preserve its settings ImGuiTextBuffer buf; - buf.reserve(g.Settings.Size * 64); // ballpark reserve - for (int i = 0; i != g.Settings.Size; i++) + buf.reserve(g.SettingsWindows.Size * 64); // ballpark reserve + for (int i = 0; i != g.SettingsWindows.Size; i++) { - const ImGuiIniData* settings = &g.Settings[i]; + const ImGuiSettingsWindow* settings = &g.SettingsWindows[i]; if (settings->Pos.x == FLT_MAX) continue; const char* name = settings->Name; @@ -4008,7 +4010,7 @@ static ImGuiWindow* CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFl window->PosFloat = ImVec2(60, 60); window->Pos = ImVec2((float)(int)window->PosFloat.x, (float)(int)window->PosFloat.y); - ImGuiIniData* settings = FindWindowSettings(name); + ImGuiSettingsWindow* settings = FindWindowSettings(name); if (!settings) settings = AddWindowSettings(name); else diff --git a/imgui_internal.h b/imgui_internal.h index f155abf74..ed2279294 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -38,7 +38,7 @@ struct ImGuiGroupData; struct ImGuiSimpleColumns; struct ImGuiDrawContext; struct ImGuiTextEditState; -struct ImGuiIniData; +struct ImGuiSettingsWindow; struct ImGuiMouseCursorData; struct ImGuiPopupRef; struct ImGuiWindow; @@ -370,7 +370,7 @@ struct IMGUI_API ImGuiTextEditState }; // Data saved in imgui.ini file -struct ImGuiIniData +struct ImGuiSettingsWindow { char* Name; ImGuiID Id; @@ -438,7 +438,7 @@ struct ImGuiContext ImGuiWindow* ActiveIdWindow; ImGuiWindow* MovingWindow; // Track the child window we clicked on to move a window. ImGuiID MovingWindowMoveId; // == MovingWindow->MoveId - ImVector Settings; // .ini Settings + ImVector SettingsWindows; // .ini Settings float SettingsDirtyTimer; // Save .ini Settings on disk when time reaches zero ImVector ColorModifiers; // Stack for PushStyleColor()/PopStyleColor() ImVector StyleModifiers; // Stack for PushStyleVar()/PopStyleVar() From 7e2d0d734c477e033fd57a875705dc5ad8571687 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 27 Nov 2017 23:55:42 +0100 Subject: [PATCH 627/921] Settings: basic refactor so that additional data structures can be loaded/saved. Parser/saver is still the minimum viable poor-man parsing. --- imgui.cpp | 182 ++++++++++++++++++++++++++++++----------------- imgui_internal.h | 20 +++++- 2 files changed, 135 insertions(+), 67 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 8b6189881..41b3b6216 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -647,7 +647,7 @@ static ImGuiSettingsWindow* FindWindowSettings(const char* name); static ImGuiSettingsWindow* AddWindowSettings(const char* name); static void LoadIniSettingsFromDisk(const char* ini_filename); -static void LoadIniSettingsFromMemory(const char* buf, const char* buf_end = NULL); +static void LoadIniSettingsFromMemory(const char* buf); static void SaveIniSettingsToDisk(const char* ini_filename); static void SaveIniSettingsToMemory(ImVector& out_buf); static void MarkIniSettingsDirty(ImGuiWindow* window); @@ -924,8 +924,16 @@ void ImStrncpy(char* dst, const char* src, int count) char* ImStrdup(const char *str) { size_t len = strlen(str) + 1; - void* buff = ImGui::MemAlloc(len); - return (char*)memcpy(buff, (const void*)str, len); + void* buf = ImGui::MemAlloc(len); + return (char*)memcpy(buf, (const void*)str, len); +} + +char* ImStrchrRange(const char* str, const char* str_end, char c) +{ + for ( ; str < str_end; str++) + if (*str == c) + return (char*)str; + return NULL; } int ImStrlenW(const ImWchar* str) @@ -2463,12 +2471,75 @@ void ImGui::NewFrame() ImGui::Begin("Debug##Default"); } +static void* SettingsHandlerWindow_ReadOpenEntry(ImGuiContext&, const char* name) +{ + ImGuiSettingsWindow* settings = FindWindowSettings(name); + if (!settings) + settings = AddWindowSettings(name); + return (void*)settings; +} + +static void SettingsHandlerWindow_ReadLine(ImGuiContext&, void* entry, const char* line) +{ + ImGuiSettingsWindow* settings = (ImGuiSettingsWindow*)entry; + float x, y; + int i; + if (sscanf(line, "Pos=%f,%f", &x, &y) == 2) settings->Pos = ImVec2(x, y); + else if (sscanf(line, "Size=%f,%f", &x, &y) == 2) settings->Size = ImMax(ImVec2(x, y), GImGui->Style.WindowMinSize); + else if (sscanf(line, "Collapsed=%d", &i) == 1) settings->Collapsed = (i != 0); +} + +static void SettingsHandlerWindow_WriteAll(ImGuiContext& g, ImGuiTextBuffer* buf) +{ + // Gather data from windows that were active during this session + for (int i = 0; i != g.Windows.Size; i++) + { + ImGuiWindow* window = g.Windows[i]; + if (window->Flags & ImGuiWindowFlags_NoSavedSettings) + continue; + ImGuiSettingsWindow* settings = FindWindowSettings(window->Name); + if (!settings) // This will only return NULL in the rare instance where the window was first created with ImGuiWindowFlags_NoSavedSettings then had the flag disabled later on. We don't bind settings in this case (bug #1000). + continue; + settings->Pos = window->Pos; + settings->Size = window->SizeFull; + settings->Collapsed = window->Collapsed; + } + + // Write a buffer + // If a window wasn't opened in this session we preserve its settings + buf->reserve(buf->size() + g.SettingsWindows.Size * 96); // ballpark reserve + for (int i = 0; i != g.SettingsWindows.Size; i++) + { + const ImGuiSettingsWindow* settings = &g.SettingsWindows[i]; + if (settings->Pos.x == FLT_MAX) + continue; + const char* name = settings->Name; + if (const char* p = strstr(name, "###")) // Skip to the "###" marker if any. We don't skip past to match the behavior of GetID() + name = p; + buf->appendf("[Window][%s]\n", name); + buf->appendf("Pos=%d,%d\n", (int)settings->Pos.x, (int)settings->Pos.y); + buf->appendf("Size=%d,%d\n", (int)settings->Size.x, (int)settings->Size.y); + buf->appendf("Collapsed=%d\n", settings->Collapsed); + buf->appendf("\n"); + } +} + void ImGui::Initialize() { ImGuiContext& g = *GImGui; g.LogClipboard = (ImGuiTextBuffer*)ImGui::MemAlloc(sizeof(ImGuiTextBuffer)); IM_PLACEMENT_NEW(g.LogClipboard) ImGuiTextBuffer(); + // Add .ini handle for ImGuiWindow type + ImGuiSettingsHandler ini_handler; + ini_handler.TypeName = "Window"; + ini_handler.TypeHash = ImHash("Window", 0, 0); + ini_handler.ReadOpenEntryFn = SettingsHandlerWindow_ReadOpenEntry; + ini_handler.ReadLineFn = SettingsHandlerWindow_ReadLine; + ini_handler.WriteAllFn = SettingsHandlerWindow_WriteAll; + g.SettingsHandlers.push_back(ini_handler); + + // Load .ini file IM_ASSERT(g.SettingsWindows.empty()); LoadIniSettingsFromDisk(g.IO.IniFilename); g.Initialized = true; @@ -2506,7 +2577,6 @@ void ImGui::Shutdown() g.MovingWindow = NULL; for (int i = 0; i < g.SettingsWindows.Size; i++) ImGui::MemFree(g.SettingsWindows[i].Name); - g.SettingsWindows.clear(); g.ColorModifiers.clear(); g.StyleModifiers.clear(); g.FontStack.clear(); @@ -2522,6 +2592,9 @@ void ImGui::Shutdown() g.InputTextState.InitialText.clear(); g.InputTextState.TempTextBuffer.clear(); + g.SettingsWindows.clear(); + g.SettingsHandlers.clear(); + if (g.LogFile && g.LogFile != stdout) { fclose(g.LogFile); @@ -2562,54 +2635,64 @@ static ImGuiSettingsWindow* AddWindowSettings(const char* name) return settings; } -// Zero-tolerance, poor-man .ini parsing -// FIXME: Write something less rubbish static void LoadIniSettingsFromDisk(const char* ini_filename) { if (!ini_filename) return; - int file_size; - char* file_data = (char*)ImFileLoadToMemory(ini_filename, "rb", &file_size, 1); + char* file_data = (char*)ImFileLoadToMemory(ini_filename, "rb", NULL, +1); if (!file_data) return; - LoadIniSettingsFromMemory(file_data, file_data + file_size); + LoadIniSettingsFromMemory(file_data); ImGui::MemFree(file_data); } -static void LoadIniSettingsFromMemory(const char* buf, const char* buf_end) +// Zero-tolerance, no error reporting, cheap .ini parsing +static void LoadIniSettingsFromMemory(const char* buf_readonly) { + // For convenience and to make the code simpler, we'll write zero terminators inside the buffer. So let's create a writable copy. + char* buf = ImStrdup(buf_readonly); + char* buf_end = buf + strlen(buf); + ImGuiContext& g = *GImGui; - if (!buf_end) - buf_end = buf + strlen(buf); - ImGuiSettingsWindow* settings = NULL; - for (const char* line_start = buf; line_start < buf_end; ) + void* entry_data = NULL; + const ImGuiSettingsHandler* entry_handler = NULL; + + char* line_end = NULL; + for (char* line = buf; line < buf_end; line = line_end + 1) { - const char* line_end = line_start; + // Skip new lines markers, then find end of the line + while (*line == '\n' || *line == '\r') + line++; + line_end = line; while (line_end < buf_end && *line_end != '\n' && *line_end != '\r') line_end++; + line_end[0] = 0; - if (line_start[0] == '[' && line_end > line_start && line_end[-1] == ']') + if (line[0] == '[' && line_end > line && line_end[-1] == ']') { - char name[64]; - ImFormatString(name, IM_ARRAYSIZE(name), "%.*s", (int)(line_end-line_start-2), line_start+1); - settings = FindWindowSettings(name); - if (!settings) - settings = AddWindowSettings(name); + // Parse "[Type][Name]". Note that 'Name' can itself contains [] characters, which is acceptable with the current format and parsing code. + char* name_end = line_end - 1; + *name_end = 0; + char* type_start = line + 1; + char* type_end = ImStrchrRange(type_start, name_end, ']'); + char* name_start = type_end ? ImStrchrRange(type_end + 1, name_end, '[') : NULL; + if (type_start && type_end && name_start++ && name_end) + { + const ImGuiID type_hash = ImHash(type_start, type_end - type_start, 0); + entry_handler = NULL; + for (int handler_n = 0; handler_n < g.SettingsHandlers.Size && entry_handler == NULL; handler_n++) + if (g.SettingsHandlers[handler_n].TypeHash == type_hash) + entry_handler = &g.SettingsHandlers[handler_n]; + entry_data = entry_handler ? entry_handler->ReadOpenEntryFn(g, name_start) : NULL; + } } - else if (settings) + else if (entry_handler != NULL && entry_data != NULL) { - float x, y; - int i; - if (sscanf(line_start, "Pos=%f,%f", &x, &y) == 2) - settings->Pos = ImVec2(x, y); - else if (sscanf(line_start, "Size=%f,%f", &x, &y) == 2) - settings->Size = ImMax(ImVec2(x, y), g.Style.WindowMinSize); - else if (sscanf(line_start, "Collapsed=%d", &i) == 1) - settings->Collapsed = (i != 0); + // Let type handler parse the line + entry_handler->ReadLineFn(g, entry_data, line); } - - line_start = line_end+1; } + ImGui::MemFree(buf); } static void SaveIniSettingsToDisk(const char* ini_filename) @@ -2622,7 +2705,6 @@ static void SaveIniSettingsToDisk(const char* ini_filename) ImVector buf; SaveIniSettingsToMemory(buf); - // Write .ini file FILE* f = ImFileOpen(ini_filename, "wt"); if (!f) return; @@ -2635,39 +2717,11 @@ static void SaveIniSettingsToMemory(ImVector& out_buf) ImGuiContext& g = *GImGui; g.SettingsDirtyTimer = 0.0f; - // Gather data from windows that were active during this session - for (int i = 0; i != g.Windows.Size; i++) - { - ImGuiWindow* window = g.Windows[i]; - if (window->Flags & ImGuiWindowFlags_NoSavedSettings) - continue; - ImGuiSettingsWindow* settings = FindWindowSettings(window->Name); - if (!settings) // This will only return NULL in the rare instance where the window was first created with ImGuiWindowFlags_NoSavedSettings then had the flag disabled later on. We don't bind settings in this case (bug #1000). - continue; - settings->Pos = window->Pos; - settings->Size = window->SizeFull; - settings->Collapsed = window->Collapsed; - } - - // Write a buffer - // If a window wasn't opened in this session we preserve its settings ImGuiTextBuffer buf; - buf.reserve(g.SettingsWindows.Size * 64); // ballpark reserve - for (int i = 0; i != g.SettingsWindows.Size; i++) - { - const ImGuiSettingsWindow* settings = &g.SettingsWindows[i]; - if (settings->Pos.x == FLT_MAX) - continue; - const char* name = settings->Name; - if (const char* p = strstr(name, "###")) // Skip to the "###" marker if any. We don't skip past to match the behavior of GetID() - name = p; - buf.appendf("[%s]\n", name); - buf.appendf("Pos=%d,%d\n", (int)settings->Pos.x, (int)settings->Pos.y); - buf.appendf("Size=%d,%d\n", (int)settings->Size.x, (int)settings->Size.y); - buf.appendf("Collapsed=%d\n", settings->Collapsed); - buf.appendf("\n"); - } + for (int handler_n = 0; handler_n < g.SettingsHandlers.Size; handler_n++) + g.SettingsHandlers[handler_n].WriteAllFn(g, &buf); + buf.Buf.pop_back(); // Remove extra zero-terminator used by ImGuiTextBuffer out_buf.swap(buf.Buf); } diff --git a/imgui_internal.h b/imgui_internal.h index ed2279294..e5ecb8b05 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -106,6 +106,7 @@ IMGUI_API int ImStricmp(const char* str1, const char* str2); IMGUI_API int ImStrnicmp(const char* str1, const char* str2, int count); IMGUI_API void ImStrncpy(char* dst, const char* src, int count); IMGUI_API char* ImStrdup(const char* str); +IMGUI_API char* ImStrchrRange(const char* str_begin, const char* str_end, char c); IMGUI_API int ImStrlenW(const ImWchar* str); IMGUI_API const ImWchar*ImStrbolW(const ImWchar* buf_mid_line, const ImWchar* buf_begin); // Find beginning-of-line IMGUI_API const char* ImStristr(const char* haystack, const char* haystack_end, const char* needle, const char* needle_end); @@ -379,6 +380,15 @@ struct ImGuiSettingsWindow bool Collapsed; }; +struct ImGuiSettingsHandler +{ + const char* TypeName; // Short description stored in .ini file. Disallowed characters: '[' ']' + ImGuiID TypeHash; // == ImHash(TypeName, 0, 0) + void* (*ReadOpenEntryFn)(ImGuiContext& ctx, const char* name); + void (*ReadLineFn)(ImGuiContext& ctx, void* entry, const char* line); + void (*WriteAllFn)(ImGuiContext& ctx, ImGuiTextBuffer* out_buf); +}; + // Mouse cursor data (used when io.MouseDrawCursor is set) struct ImGuiMouseCursorData { @@ -438,8 +448,6 @@ struct ImGuiContext ImGuiWindow* ActiveIdWindow; ImGuiWindow* MovingWindow; // Track the child window we clicked on to move a window. ImGuiID MovingWindowMoveId; // == MovingWindow->MoveId - ImVector SettingsWindows; // .ini Settings - float SettingsDirtyTimer; // Save .ini Settings on disk when time reaches zero ImVector ColorModifiers; // Stack for PushStyleColor()/PopStyleColor() ImVector StyleModifiers; // Stack for PushStyleVar()/PopStyleVar() ImVector FontStack; // Stack for PushFont()/PopFont() @@ -488,6 +496,11 @@ struct ImGuiContext ImVector PrivateClipboard; // If no custom clipboard handler is defined ImVec2 OsImePosRequest, OsImePosSet; // Cursor position request & last passed to the OS Input Method Editor + // Settings + float SettingsDirtyTimer; // Save .ini Settings on disk when time reaches zero + ImVector SettingsWindows; // .ini settings for ImGuiWindow + ImVector SettingsHandlers; // List of .ini settings handlers + // Logging bool LogEnabled; FILE* LogFile; // If != NULL log to stdout/ file @@ -532,7 +545,6 @@ struct ImGuiContext ActiveIdWindow = NULL; MovingWindow = NULL; MovingWindowMoveId = 0; - SettingsDirtyTimer = 0.0f; SetNextWindowPosVal = ImVec2(0.0f, 0.0f); SetNextWindowSizeVal = ImVec2(0.0f, 0.0f); @@ -565,6 +577,8 @@ struct ImGuiContext MouseCursor = ImGuiMouseCursor_Arrow; memset(MouseCursorData, 0, sizeof(MouseCursorData)); + SettingsDirtyTimer = 0.0f; + LogEnabled = false; LogFile = NULL; LogClipboard = NULL; From e000ee01169f735b0ddc91553b42ff3a857e9b9b Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 28 Nov 2017 10:48:01 +0100 Subject: [PATCH 628/921] Examples: DirectX9: Handle loss of D3D9 device (D3DERR_DEVICELOST). (#1464) --- examples/directx9_example/main.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/examples/directx9_example/main.cpp b/examples/directx9_example/main.cpp index 5a5c0d192..30c820ef3 100644 --- a/examples/directx9_example/main.cpp +++ b/examples/directx9_example/main.cpp @@ -154,7 +154,15 @@ int main(int, char**) ImGui::Render(); g_pd3dDevice->EndScene(); } - g_pd3dDevice->Present(NULL, NULL, NULL, NULL); + HRESULT result = g_pd3dDevice->Present(NULL, NULL, NULL, NULL); + + // Handle loss of D3D9 device + if (result == D3DERR_DEVICELOST && g_pd3dDevice->TestCooperativeLevel() == D3DERR_DEVICENOTRESET) + { + ImGui_ImplDX9_InvalidateDeviceObjects(); + g_pd3dDevice->Reset(&g_d3dpp); + ImGui_ImplDX9_CreateDeviceObjects(); + } } ImGui_ImplDX9_Shutdown(); From f3ec608c19462e4829ca2bf5833511290ea770b0 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 28 Nov 2017 00:32:25 +0100 Subject: [PATCH 629/921] Settings: Initializing ImGuiSettingsWindow so external users don't end up with uncleared data. Exposed MarkIniSettingsDirty() in imgui_internal.h --- imgui.cpp | 7 +++++++ imgui_internal.h | 4 ++++ 2 files changed, 11 insertions(+) diff --git a/imgui.cpp b/imgui.cpp index 41b3b6216..72dda9327 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2725,6 +2725,13 @@ static void SaveIniSettingsToMemory(ImVector& out_buf) out_buf.swap(buf.Buf); } +void ImGui::MarkIniSettingsDirty() +{ + ImGuiContext& g = *GImGui; + if (g.SettingsDirtyTimer <= 0.0f) + g.SettingsDirtyTimer = g.IO.IniSavingRate; +} + static void MarkIniSettingsDirty(ImGuiWindow* window) { ImGuiContext& g = *GImGui; diff --git a/imgui_internal.h b/imgui_internal.h index e5ecb8b05..249dff851 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -378,6 +378,8 @@ struct ImGuiSettingsWindow ImVec2 Pos; ImVec2 Size; bool Collapsed; + + ImGuiSettingsWindow() { Name = NULL; Id = 0; Pos = Size = ImVec2(0,0); Collapsed = false; } }; struct ImGuiSettingsHandler @@ -801,6 +803,8 @@ namespace ImGui IMGUI_API void Initialize(); + IMGUI_API void MarkIniSettingsDirty(); + IMGUI_API void SetActiveID(ImGuiID id, ImGuiWindow* window); IMGUI_API void ClearActiveID(); IMGUI_API void SetHoveredID(ImGuiID id); From 4c4f1b0224adcfbd35e6d83577ba12f95067f5ab Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 28 Nov 2017 00:33:03 +0100 Subject: [PATCH 630/921] ImVector: Added ImVector::push_front helper. --- imgui.h | 1 + 1 file changed, 1 insertion(+) diff --git a/imgui.h b/imgui.h index 309730f2f..f09209103 100644 --- a/imgui.h +++ b/imgui.h @@ -983,6 +983,7 @@ public: inline void push_back(const value_type& v) { if (Size == Capacity) reserve(_grow_capacity(Size+1)); Data[Size++] = v; } inline void pop_back() { IM_ASSERT(Size > 0); Size--; } + inline void push_front(const value_type& v) { if (Size == 0) push_back(v); else insert(Data, v); } inline iterator erase(const_iterator it) { IM_ASSERT(it >= Data && it < Data+Size); const ptrdiff_t off = it - Data; memmove(Data + off, Data + off + 1, ((size_t)Size - (size_t)off - 1) * sizeof(value_type)); Size--; return Data + off; } inline iterator insert(const_iterator it, const value_type& v) { IM_ASSERT(it >= Data && it <= Data+Size); const ptrdiff_t off = it - Data; if (Size == Capacity) reserve(Capacity ? Capacity * 2 : 4); if (off < (int)Size) memmove(Data + off + 1, Data + off, ((size_t)Size - (size_t)off) * sizeof(value_type)); Data[off] = v; Size++; return Data + off; } From e5ebe42207225d5f6e2165f90bbae79b283994c0 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 28 Nov 2017 00:33:12 +0100 Subject: [PATCH 631/921] Settings: Make ImGuiWindow settings always first in the list. --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 72dda9327..0ecbedb61 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2537,7 +2537,7 @@ void ImGui::Initialize() ini_handler.ReadOpenEntryFn = SettingsHandlerWindow_ReadOpenEntry; ini_handler.ReadLineFn = SettingsHandlerWindow_ReadLine; ini_handler.WriteAllFn = SettingsHandlerWindow_WriteAll; - g.SettingsHandlers.push_back(ini_handler); + g.SettingsHandlers.push_front(ini_handler); // Load .ini file IM_ASSERT(g.SettingsWindows.empty()); From c8b5b569dacd25abc45cda1bf70bff53b15ac945 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 28 Nov 2017 11:26:14 +0100 Subject: [PATCH 632/921] Examples: DirectX9: Call EndFrame(), fix for assert added in 9a44d447cd29096c74e38bec917015c0ee1ffaea --- examples/directx9_example/main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/directx9_example/main.cpp b/examples/directx9_example/main.cpp index 30c820ef3..af53ddb30 100644 --- a/examples/directx9_example/main.cpp +++ b/examples/directx9_example/main.cpp @@ -144,6 +144,7 @@ int main(int, char**) } // Rendering + ImGui::EndFrame(); g_pd3dDevice->SetRenderState(D3DRS_ZENABLE, false); g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, false); g_pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, false); From 1a8a7c9d170a49e9c3170df59674eab74810bab6 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 28 Nov 2017 16:23:46 +0100 Subject: [PATCH 633/921] Settings: Import old style .ini file --- imgui.cpp | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 0ecbedb61..60b1d1c5f 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2676,15 +2676,22 @@ static void LoadIniSettingsFromMemory(const char* buf_readonly) char* type_start = line + 1; char* type_end = ImStrchrRange(type_start, name_end, ']'); char* name_start = type_end ? ImStrchrRange(type_end + 1, name_end, '[') : NULL; - if (type_start && type_end && name_start++ && name_end) + if (!type_end || !name_start) { - const ImGuiID type_hash = ImHash(type_start, type_end - type_start, 0); - entry_handler = NULL; - for (int handler_n = 0; handler_n < g.SettingsHandlers.Size && entry_handler == NULL; handler_n++) - if (g.SettingsHandlers[handler_n].TypeHash == type_hash) - entry_handler = &g.SettingsHandlers[handler_n]; - entry_data = entry_handler ? entry_handler->ReadOpenEntryFn(g, name_start) : NULL; + name_start = type_start; // Import legacy entries that have no type + type_start = "Window"; } + else + { + *type_end = 0; // Overwrite first ']' + name_start++; // Skip second '[' + } + const ImGuiID type_hash = ImHash(type_start, 0, 0); + entry_handler = NULL; + for (int handler_n = 0; handler_n < g.SettingsHandlers.Size && entry_handler == NULL; handler_n++) + if (g.SettingsHandlers[handler_n].TypeHash == type_hash) + entry_handler = &g.SettingsHandlers[handler_n]; + entry_data = entry_handler ? entry_handler->ReadOpenEntryFn(g, name_start) : NULL; } else if (entry_handler != NULL && entry_data != NULL) { From 4a43632163b49744455e04ca9654e045708dccab Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 28 Nov 2017 17:27:54 +0100 Subject: [PATCH 634/921] Build fix --- imgui.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 60b1d1c5f..91de2d970 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2671,11 +2671,11 @@ static void LoadIniSettingsFromMemory(const char* buf_readonly) if (line[0] == '[' && line_end > line && line_end[-1] == ']') { // Parse "[Type][Name]". Note that 'Name' can itself contains [] characters, which is acceptable with the current format and parsing code. - char* name_end = line_end - 1; - *name_end = 0; - char* type_start = line + 1; + line_end[-1] = 0; + const char* name_end = line_end - 1; + const char* type_start = line + 1; char* type_end = ImStrchrRange(type_start, name_end, ']'); - char* name_start = type_end ? ImStrchrRange(type_end + 1, name_end, '[') : NULL; + const char* name_start = type_end ? ImStrchrRange(type_end + 1, name_end, '[') : NULL; if (!type_end || !name_start) { name_start = type_start; // Import legacy entries that have no type From 963259d128c9d8b1f0b9dcdbc07d32cb64c0a1f5 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 28 Nov 2017 19:20:50 +0100 Subject: [PATCH 635/921] Settings: Internals: Renamed ImGuiSettingsWindow to ImGuiWindowSettings. --- imgui.cpp | 22 +++++++++++----------- imgui_internal.h | 8 ++++---- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 91de2d970..f77a5b2e9 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -643,8 +643,8 @@ static void AddDrawListToRenderList(ImVector& out_rende static void AddWindowToRenderList(ImVector& out_render_list, ImGuiWindow* window); static void AddWindowToSortedBuffer(ImVector& out_sorted_windows, ImGuiWindow* window); -static ImGuiSettingsWindow* FindWindowSettings(const char* name); -static ImGuiSettingsWindow* AddWindowSettings(const char* name); +static ImGuiWindowSettings* FindWindowSettings(const char* name); +static ImGuiWindowSettings* AddWindowSettings(const char* name); static void LoadIniSettingsFromDisk(const char* ini_filename); static void LoadIniSettingsFromMemory(const char* buf); @@ -2473,7 +2473,7 @@ void ImGui::NewFrame() static void* SettingsHandlerWindow_ReadOpenEntry(ImGuiContext&, const char* name) { - ImGuiSettingsWindow* settings = FindWindowSettings(name); + ImGuiWindowSettings* settings = FindWindowSettings(name); if (!settings) settings = AddWindowSettings(name); return (void*)settings; @@ -2481,7 +2481,7 @@ static void* SettingsHandlerWindow_ReadOpenEntry(ImGuiContext&, const char* name static void SettingsHandlerWindow_ReadLine(ImGuiContext&, void* entry, const char* line) { - ImGuiSettingsWindow* settings = (ImGuiSettingsWindow*)entry; + ImGuiWindowSettings* settings = (ImGuiWindowSettings*)entry; float x, y; int i; if (sscanf(line, "Pos=%f,%f", &x, &y) == 2) settings->Pos = ImVec2(x, y); @@ -2497,7 +2497,7 @@ static void SettingsHandlerWindow_WriteAll(ImGuiContext& g, ImGuiTextBuffer* buf ImGuiWindow* window = g.Windows[i]; if (window->Flags & ImGuiWindowFlags_NoSavedSettings) continue; - ImGuiSettingsWindow* settings = FindWindowSettings(window->Name); + ImGuiWindowSettings* settings = FindWindowSettings(window->Name); if (!settings) // This will only return NULL in the rare instance where the window was first created with ImGuiWindowFlags_NoSavedSettings then had the flag disabled later on. We don't bind settings in this case (bug #1000). continue; settings->Pos = window->Pos; @@ -2510,7 +2510,7 @@ static void SettingsHandlerWindow_WriteAll(ImGuiContext& g, ImGuiTextBuffer* buf buf->reserve(buf->size() + g.SettingsWindows.Size * 96); // ballpark reserve for (int i = 0; i != g.SettingsWindows.Size; i++) { - const ImGuiSettingsWindow* settings = &g.SettingsWindows[i]; + const ImGuiWindowSettings* settings = &g.SettingsWindows[i]; if (settings->Pos.x == FLT_MAX) continue; const char* name = settings->Name; @@ -2609,24 +2609,24 @@ void ImGui::Shutdown() g.Initialized = false; } -static ImGuiSettingsWindow* FindWindowSettings(const char* name) +static ImGuiWindowSettings* FindWindowSettings(const char* name) { ImGuiContext& g = *GImGui; ImGuiID id = ImHash(name, 0); for (int i = 0; i != g.SettingsWindows.Size; i++) { - ImGuiSettingsWindow* ini = &g.SettingsWindows[i]; + ImGuiWindowSettings* ini = &g.SettingsWindows[i]; if (ini->Id == id) return ini; } return NULL; } -static ImGuiSettingsWindow* AddWindowSettings(const char* name) +static ImGuiWindowSettings* AddWindowSettings(const char* name) { ImGuiContext& g = *GImGui; g.SettingsWindows.resize(g.SettingsWindows.Size + 1); - ImGuiSettingsWindow* settings = &g.SettingsWindows.back(); + ImGuiWindowSettings* settings = &g.SettingsWindows.back(); settings->Name = ImStrdup(name); settings->Id = ImHash(name, 0); settings->Collapsed = false; @@ -4078,7 +4078,7 @@ static ImGuiWindow* CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFl window->PosFloat = ImVec2(60, 60); window->Pos = ImVec2((float)(int)window->PosFloat.x, (float)(int)window->PosFloat.y); - ImGuiSettingsWindow* settings = FindWindowSettings(name); + ImGuiWindowSettings* settings = FindWindowSettings(name); if (!settings) settings = AddWindowSettings(name); else diff --git a/imgui_internal.h b/imgui_internal.h index 249dff851..84ad3e00b 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -38,10 +38,10 @@ struct ImGuiGroupData; struct ImGuiSimpleColumns; struct ImGuiDrawContext; struct ImGuiTextEditState; -struct ImGuiSettingsWindow; struct ImGuiMouseCursorData; struct ImGuiPopupRef; struct ImGuiWindow; +struct ImGuiWindowSettings; typedef int ImGuiLayoutType; // enum: horizontal or vertical // enum ImGuiLayoutType_ typedef int ImGuiButtonFlags; // flags: for ButtonEx(), ButtonBehavior() // enum ImGuiButtonFlags_ @@ -371,7 +371,7 @@ struct IMGUI_API ImGuiTextEditState }; // Data saved in imgui.ini file -struct ImGuiSettingsWindow +struct ImGuiWindowSettings { char* Name; ImGuiID Id; @@ -379,7 +379,7 @@ struct ImGuiSettingsWindow ImVec2 Size; bool Collapsed; - ImGuiSettingsWindow() { Name = NULL; Id = 0; Pos = Size = ImVec2(0,0); Collapsed = false; } + ImGuiWindowSettings() { Name = NULL; Id = 0; Pos = Size = ImVec2(0,0); Collapsed = false; } }; struct ImGuiSettingsHandler @@ -500,7 +500,7 @@ struct ImGuiContext // Settings float SettingsDirtyTimer; // Save .ini Settings on disk when time reaches zero - ImVector SettingsWindows; // .ini settings for ImGuiWindow + ImVector SettingsWindows; // .ini settings for ImGuiWindow ImVector SettingsHandlers; // List of .ini settings handlers // Logging From 35eb5c5c998d1f55f2f3c23365f9228fd188d82a Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 28 Nov 2017 19:25:16 +0100 Subject: [PATCH 636/921] Settings: Internals: Exposed FindWindowSettings(). Simplified some code. --- imgui.cpp | 21 +++++++-------------- imgui_internal.h | 3 ++- 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index f77a5b2e9..a7773291c 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -643,7 +643,6 @@ static void AddDrawListToRenderList(ImVector& out_rende static void AddWindowToRenderList(ImVector& out_render_list, ImGuiWindow* window); static void AddWindowToSortedBuffer(ImVector& out_sorted_windows, ImGuiWindow* window); -static ImGuiWindowSettings* FindWindowSettings(const char* name); static ImGuiWindowSettings* AddWindowSettings(const char* name); static void LoadIniSettingsFromDisk(const char* ini_filename); @@ -2473,7 +2472,7 @@ void ImGui::NewFrame() static void* SettingsHandlerWindow_ReadOpenEntry(ImGuiContext&, const char* name) { - ImGuiWindowSettings* settings = FindWindowSettings(name); + ImGuiWindowSettings* settings = ImGui::FindWindowSettings(ImHash(name, 0)); if (!settings) settings = AddWindowSettings(name); return (void*)settings; @@ -2497,7 +2496,7 @@ static void SettingsHandlerWindow_WriteAll(ImGuiContext& g, ImGuiTextBuffer* buf ImGuiWindow* window = g.Windows[i]; if (window->Flags & ImGuiWindowFlags_NoSavedSettings) continue; - ImGuiWindowSettings* settings = FindWindowSettings(window->Name); + ImGuiWindowSettings* settings = ImGui::FindWindowSettings(window->ID); if (!settings) // This will only return NULL in the rare instance where the window was first created with ImGuiWindowFlags_NoSavedSettings then had the flag disabled later on. We don't bind settings in this case (bug #1000). continue; settings->Pos = window->Pos; @@ -2609,29 +2608,23 @@ void ImGui::Shutdown() g.Initialized = false; } -static ImGuiWindowSettings* FindWindowSettings(const char* name) +ImGuiWindowSettings* ImGui::FindWindowSettings(ImGuiID id) { ImGuiContext& g = *GImGui; - ImGuiID id = ImHash(name, 0); for (int i = 0; i != g.SettingsWindows.Size; i++) - { - ImGuiWindowSettings* ini = &g.SettingsWindows[i]; - if (ini->Id == id) - return ini; - } + if (g.SettingsWindows[i].Id == id) + return &g.SettingsWindows[i]; return NULL; } static ImGuiWindowSettings* AddWindowSettings(const char* name) { ImGuiContext& g = *GImGui; - g.SettingsWindows.resize(g.SettingsWindows.Size + 1); + g.SettingsWindows.push_back(ImGuiWindowSettings()); ImGuiWindowSettings* settings = &g.SettingsWindows.back(); settings->Name = ImStrdup(name); settings->Id = ImHash(name, 0); - settings->Collapsed = false; settings->Pos = ImVec2(FLT_MAX,FLT_MAX); - settings->Size = ImVec2(0,0); return settings; } @@ -4078,7 +4071,7 @@ static ImGuiWindow* CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFl window->PosFloat = ImVec2(60, 60); window->Pos = ImVec2((float)(int)window->PosFloat.x, (float)(int)window->PosFloat.y); - ImGuiWindowSettings* settings = FindWindowSettings(name); + ImGuiWindowSettings* settings = ImGui::FindWindowSettings(window->ID); if (!settings) settings = AddWindowSettings(name); else diff --git a/imgui_internal.h b/imgui_internal.h index 84ad3e00b..23e99f163 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -803,7 +803,8 @@ namespace ImGui IMGUI_API void Initialize(); - IMGUI_API void MarkIniSettingsDirty(); + IMGUI_API void MarkIniSettingsDirty(); + IMGUI_API ImGuiWindowSettings* FindWindowSettings(ImGuiID id); IMGUI_API void SetActiveID(ImGuiID id, ImGuiWindow* window); IMGUI_API void ClearActiveID(); From 7ae71e4984bf5aed6ca17f933ff1a1e0c8428d35 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 28 Nov 2017 20:03:10 +0100 Subject: [PATCH 637/921] Settings: Internals: Added FindSettingsHandler() --- imgui.cpp | 14 ++++++++++---- imgui_internal.h | 5 +++-- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index a7773291c..970487520 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2639,6 +2639,15 @@ static void LoadIniSettingsFromDisk(const char* ini_filename) ImGui::MemFree(file_data); } +ImGuiSettingsHandler* ImGui::FindSettingsHandler(ImGuiID type_hash) +{ + ImGuiContext& g = *GImGui; + for (int handler_n = 0; handler_n < g.SettingsHandlers.Size; handler_n++) + if (g.SettingsHandlers[handler_n].TypeHash == type_hash) + return &g.SettingsHandlers[handler_n]; + return NULL; +} + // Zero-tolerance, no error reporting, cheap .ini parsing static void LoadIniSettingsFromMemory(const char* buf_readonly) { @@ -2680,10 +2689,7 @@ static void LoadIniSettingsFromMemory(const char* buf_readonly) name_start++; // Skip second '[' } const ImGuiID type_hash = ImHash(type_start, 0, 0); - entry_handler = NULL; - for (int handler_n = 0; handler_n < g.SettingsHandlers.Size && entry_handler == NULL; handler_n++) - if (g.SettingsHandlers[handler_n].TypeHash == type_hash) - entry_handler = &g.SettingsHandlers[handler_n]; + entry_handler = ImGui::FindSettingsHandler(type_hash); entry_data = entry_handler ? entry_handler->ReadOpenEntryFn(g, name_start) : NULL; } else if (entry_handler != NULL && entry_data != NULL) diff --git a/imgui_internal.h b/imgui_internal.h index 23e99f163..1528bdd92 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -803,8 +803,9 @@ namespace ImGui IMGUI_API void Initialize(); - IMGUI_API void MarkIniSettingsDirty(); - IMGUI_API ImGuiWindowSettings* FindWindowSettings(ImGuiID id); + IMGUI_API void MarkIniSettingsDirty(); + IMGUI_API ImGuiSettingsHandler* FindSettingsHandler(ImGuiID type_id); + IMGUI_API ImGuiWindowSettings* FindWindowSettings(ImGuiID id); IMGUI_API void SetActiveID(ImGuiID id, ImGuiWindow* window); IMGUI_API void ClearActiveID(); From 2e1013a0c62f949a16082cfc9a2a2750fc38d506 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 28 Nov 2017 21:04:13 +0100 Subject: [PATCH 638/921] Settings: Internals: Simplifying code a bit. Creating Settings structure during first save. Windows where ImGuiWindowFlags_NoSavedSettings was late toggled will save settings correctly. (#1000) --- imgui.cpp | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 970487520..1f2376469 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2497,8 +2497,8 @@ static void SettingsHandlerWindow_WriteAll(ImGuiContext& g, ImGuiTextBuffer* buf if (window->Flags & ImGuiWindowFlags_NoSavedSettings) continue; ImGuiWindowSettings* settings = ImGui::FindWindowSettings(window->ID); - if (!settings) // This will only return NULL in the rare instance where the window was first created with ImGuiWindowFlags_NoSavedSettings then had the flag disabled later on. We don't bind settings in this case (bug #1000). - continue; + if (!settings) + settings = AddWindowSettings(window->Name); settings->Pos = window->Pos; settings->Size = window->SizeFull; settings->Collapsed = window->Collapsed; @@ -2624,7 +2624,6 @@ static ImGuiWindowSettings* AddWindowSettings(const char* name) ImGuiWindowSettings* settings = &g.SettingsWindows.back(); settings->Name = ImStrdup(name); settings->Id = ImHash(name, 0); - settings->Pos = ImVec2(FLT_MAX,FLT_MAX); return settings; } @@ -4077,21 +4076,15 @@ static ImGuiWindow* CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFl window->PosFloat = ImVec2(60, 60); window->Pos = ImVec2((float)(int)window->PosFloat.x, (float)(int)window->PosFloat.y); - ImGuiWindowSettings* settings = ImGui::FindWindowSettings(window->ID); - if (!settings) - settings = AddWindowSettings(name); - else - SetWindowConditionAllowFlags(window, ImGuiCond_FirstUseEver, false); - - if (settings->Pos.x != FLT_MAX) + if (ImGuiWindowSettings* settings = ImGui::FindWindowSettings(window->ID)) { + SetWindowConditionAllowFlags(window, ImGuiCond_FirstUseEver, false); window->PosFloat = settings->Pos; window->Pos = ImVec2((float)(int)window->PosFloat.x, (float)(int)window->PosFloat.y); window->Collapsed = settings->Collapsed; + if (ImLengthSqr(settings->Size) > 0.00001f) + size = settings->Size; } - - if (ImLengthSqr(settings->Size) > 0.00001f) - size = settings->Size; window->Size = window->SizeFull = size; } From 52e475230f7abcfb79a2a90f4954da1976223615 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 28 Nov 2017 22:51:07 +0100 Subject: [PATCH 639/921] Settings: Internals: Renaming. --- imgui.cpp | 6 +++--- imgui_internal.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 1f2376469..e86687794 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2470,7 +2470,7 @@ void ImGui::NewFrame() ImGui::Begin("Debug##Default"); } -static void* SettingsHandlerWindow_ReadOpenEntry(ImGuiContext&, const char* name) +static void* SettingsHandlerWindow_ReadOpen(ImGuiContext&, const char* name) { ImGuiWindowSettings* settings = ImGui::FindWindowSettings(ImHash(name, 0)); if (!settings) @@ -2533,7 +2533,7 @@ void ImGui::Initialize() ImGuiSettingsHandler ini_handler; ini_handler.TypeName = "Window"; ini_handler.TypeHash = ImHash("Window", 0, 0); - ini_handler.ReadOpenEntryFn = SettingsHandlerWindow_ReadOpenEntry; + ini_handler.ReadOpenFn = SettingsHandlerWindow_ReadOpen; ini_handler.ReadLineFn = SettingsHandlerWindow_ReadLine; ini_handler.WriteAllFn = SettingsHandlerWindow_WriteAll; g.SettingsHandlers.push_front(ini_handler); @@ -2689,7 +2689,7 @@ static void LoadIniSettingsFromMemory(const char* buf_readonly) } const ImGuiID type_hash = ImHash(type_start, 0, 0); entry_handler = ImGui::FindSettingsHandler(type_hash); - entry_data = entry_handler ? entry_handler->ReadOpenEntryFn(g, name_start) : NULL; + entry_data = entry_handler ? entry_handler->ReadOpenFn(g, name_start) : NULL; } else if (entry_handler != NULL && entry_data != NULL) { diff --git a/imgui_internal.h b/imgui_internal.h index 1528bdd92..80d18ac5f 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -386,7 +386,7 @@ struct ImGuiSettingsHandler { const char* TypeName; // Short description stored in .ini file. Disallowed characters: '[' ']' ImGuiID TypeHash; // == ImHash(TypeName, 0, 0) - void* (*ReadOpenEntryFn)(ImGuiContext& ctx, const char* name); + void* (*ReadOpenFn)(ImGuiContext& ctx, const char* name); void (*ReadLineFn)(ImGuiContext& ctx, void* entry, const char* line); void (*WriteAllFn)(ImGuiContext& ctx, ImGuiTextBuffer* out_buf); }; From 25c159fac8c36411395871b7c41c2cd4cdd562fa Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 29 Nov 2017 21:10:59 +0100 Subject: [PATCH 640/921] Internals: Removed unnecessary duplicate scrolling code + added extra infos to Metrics window. --- imgui.cpp | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index e86687794..84bde0c45 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4162,6 +4162,16 @@ static ImVec2 CalcSizeAutoFit(ImGuiWindow* window) return size_auto_fit; } +static float GetScrollMaxX(ImGuiWindow* window) +{ + return ImMax(0.0f, window->SizeContents.x - (window->SizeFull.x - window->ScrollbarSizes.x)); +} + +static float GetScrollMaxY(ImGuiWindow* window) +{ + return ImMax(0.0f, window->SizeContents.y - (window->SizeFull.y - window->ScrollbarSizes.y)); +} + static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window) { ImVec2 scroll = window->Scroll; @@ -4174,8 +4184,8 @@ static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window) scroll = ImMax(scroll, ImVec2(0.0f, 0.0f)); if (!window->Collapsed && !window->SkipItems) { - scroll.x = ImMin(scroll.x, ImMax(0.0f, window->SizeContents.x - (window->SizeFull.x - window->ScrollbarSizes.x))); // == GetScrollMaxX for that window - scroll.y = ImMin(scroll.y, ImMax(0.0f, window->SizeContents.y - (window->SizeFull.y - window->ScrollbarSizes.y))); // == GetScrollMaxY for that window + scroll.x = ImMin(scroll.x, GetScrollMaxX(window)); + scroll.y = ImMin(scroll.y, GetScrollMaxY(window)); } return scroll; } @@ -5671,14 +5681,12 @@ float ImGui::GetScrollY() float ImGui::GetScrollMaxX() { - ImGuiWindow* window = GetCurrentWindowRead(); - return ImMax(0.0f, window->SizeContents.x - (window->SizeFull.x - window->ScrollbarSizes.x)); + return GetScrollMaxX(GImGui->CurrentWindow); } float ImGui::GetScrollMaxY() { - ImGuiWindow* window = GetCurrentWindowRead(); - return ImMax(0.0f, window->SizeContents.y - (window->SizeFull.y - window->ScrollbarSizes.y)); + return GetScrollMaxY(GImGui->CurrentWindow); } void ImGui::SetScrollX(float scroll_x) @@ -11039,7 +11047,7 @@ void ImGui::ShowMetricsWindow(bool* p_open) ImGui::BulletText("Pos: (%.1f,%.1f), Size: (%.1f,%.1f), SizeContents (%.1f,%.1f)", window->Pos.x, window->Pos.y, window->Size.x, window->Size.y, window->SizeContents.x, window->SizeContents.y); if (ImGui::IsItemHovered()) GImGui->OverlayDrawList.AddRect(window->Pos, window->Pos + window->Size, IM_COL32(255,255,0,255)); - ImGui::BulletText("Scroll: (%.2f,%.2f)", window->Scroll.x, window->Scroll.y); + ImGui::BulletText("Scroll: (%.2f/%.2f,%.2f/%.2f)", window->Scroll.x, GetScrollMaxX(window), window->Scroll.y, GetScrollMaxY(window)); ImGui::BulletText("Active: %d, WriteAccessed: %d", window->Active, window->WriteAccessed); if (window->RootWindow != window) NodeWindow(window->RootWindow, "RootWindow"); if (window->DC.ChildWindows.Size > 0) NodeWindows(window->DC.ChildWindows, "ChildWindows"); From a20fe279c5b022a2df2510081b1f32605d9f4dce Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 29 Nov 2017 23:33:31 +0100 Subject: [PATCH 641/921] Demo: Layout: Removed unnecessary BeginChild/EndChild calls --- imgui_demo.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 30a4ce464..a25226212 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -2807,11 +2807,9 @@ static void ShowExampleAppLayout(bool* p_open) ImGui::Separator(); ImGui::TextWrapped("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. "); ImGui::EndChild(); - ImGui::BeginChild("buttons"); if (ImGui::Button("Revert")) {} ImGui::SameLine(); if (ImGui::Button("Save")) {} - ImGui::EndChild(); ImGui::EndGroup(); } ImGui::End(); From c36e586cce1279b419ab4b443ca6ce63b03ce7cc Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 29 Nov 2017 23:39:23 +0100 Subject: [PATCH 642/921] Style, Scrolling: Fixed padding and scrolling asymetry where lower/right sides of a window wouldn't use WindowPadding properly + causing minor scrolling glitches. --- imgui.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 84bde0c45..08f4ec250 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1983,7 +1983,7 @@ void ImGui::ItemSize(const ImVec2& size, float text_offset_y) window->DC.CursorPosPrevLine = ImVec2(window->DC.CursorPos.x + size.x, window->DC.CursorPos.y); window->DC.CursorPos = ImVec2((float)(int)(window->Pos.x + window->DC.IndentX + window->DC.ColumnsOffsetX), (float)(int)(window->DC.CursorPos.y + line_height + g.Style.ItemSpacing.y)); window->DC.CursorMaxPos.x = ImMax(window->DC.CursorMaxPos.x, window->DC.CursorPosPrevLine.x); - window->DC.CursorMaxPos.y = ImMax(window->DC.CursorMaxPos.y, window->DC.CursorPos.y); + window->DC.CursorMaxPos.y = ImMax(window->DC.CursorMaxPos.y, window->DC.CursorPos.y - g.Style.ItemSpacing.y); //if (g.IO.KeyAlt) window->DrawList->AddCircle(window->DC.CursorMaxPos, 3.0f, IM_COL32(255,0,0,255), 4); // [DEBUG] window->DC.PrevLineHeight = line_height; @@ -4146,18 +4146,17 @@ static ImVec2 CalcSizeAutoFit(ImGuiWindow* window) if ((flags & ImGuiWindowFlags_Tooltip) != 0) { // Tooltip always resize. We keep the spacing symmetric on both axises for aesthetic purpose. - size_auto_fit = window->SizeContents + window->WindowPadding - ImVec2(0.0f, style.ItemSpacing.y); + size_auto_fit = window->SizeContents; } else { // Handling case of auto fit window not fitting on the screen (on either axis): we are growing the size on the other axis to compensate for expected scrollbar. FIXME: Might turn bigger than DisplaySize-WindowPadding. - size_auto_fit = ImClamp(window->SizeContents + window->WindowPadding, style.WindowMinSize, ImMax(style.WindowMinSize, g.IO.DisplaySize - g.Style.DisplaySafeAreaPadding)); + size_auto_fit = ImClamp(window->SizeContents, style.WindowMinSize, ImMax(style.WindowMinSize, g.IO.DisplaySize - g.Style.DisplaySafeAreaPadding)); ImVec2 size_auto_fit_after_constraint = CalcSizeFullWithConstraint(window, size_auto_fit); if (size_auto_fit_after_constraint.x < window->SizeContents.x && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar)) size_auto_fit.y += style.ScrollbarSize; if (size_auto_fit_after_constraint.y < window->SizeContents.y && !(flags & ImGuiWindowFlags_NoScrollbar)) size_auto_fit.x += style.ScrollbarSize; - size_auto_fit.y = ImMax(size_auto_fit.y - style.ItemSpacing.y, 0.0f); } return size_auto_fit; } @@ -4364,6 +4363,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // Update contents size from last frame for auto-fitting (unless explicitly specified) window->SizeContents.x = (float)(int)((window->SizeContentsExplicit.x != 0.0f) ? window->SizeContentsExplicit.x : ((window_is_new ? 0.0f : window->DC.CursorMaxPos.x - window->Pos.x) + window->Scroll.x)); window->SizeContents.y = (float)(int)((window->SizeContentsExplicit.y != 0.0f) ? window->SizeContentsExplicit.y : ((window_is_new ? 0.0f : window->DC.CursorMaxPos.y - window->Pos.y) + window->Scroll.y)); + window->SizeContents += window->WindowPadding; // Hide popup/tooltip window when first appearing while we measure size (because we recycle them) if (window->HiddenFrames > 0) @@ -4430,10 +4430,10 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // Update scrollbar status (based on the Size that was effective during last frame or the auto-resized Size). We need to do this before manual resize (below) is effective. if (!window->Collapsed) { - window->ScrollbarY = (flags & ImGuiWindowFlags_AlwaysVerticalScrollbar) || ((window->SizeContents.y > window->SizeFull.y + style.ItemSpacing.y) && !(flags & ImGuiWindowFlags_NoScrollbar)); + window->ScrollbarY = (flags & ImGuiWindowFlags_AlwaysVerticalScrollbar) || ((window->SizeContents.y > window->SizeFull.y) && !(flags & ImGuiWindowFlags_NoScrollbar)); window->ScrollbarX = (flags & ImGuiWindowFlags_AlwaysHorizontalScrollbar) || ((window->SizeContents.x > window->SizeFull.x - (window->ScrollbarY ? style.ScrollbarSize : 0.0f) - window->WindowPadding.x) && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar)); if (window->ScrollbarX && !window->ScrollbarY) - window->ScrollbarY = (window->SizeContents.y > window->SizeFull.y + style.ItemSpacing.y - style.ScrollbarSize) && !(flags & ImGuiWindowFlags_NoScrollbar); + window->ScrollbarY = (window->SizeContents.y > window->SizeFull.y + style.ScrollbarSize) && !(flags & ImGuiWindowFlags_NoScrollbar); window->ScrollbarSizes = ImVec2(window->ScrollbarY ? style.ScrollbarSize : 0.0f, window->ScrollbarX ? style.ScrollbarSize : 0.0f); } @@ -10409,7 +10409,6 @@ void ImGui::EndGroup() ImGuiGroupData& group_data = window->DC.GroupStack.back(); ImRect group_bb(group_data.BackupCursorPos, window->DC.CursorMaxPos); - group_bb.Max.y -= g.Style.ItemSpacing.y; // Cancel out last vertical spacing because we are adding one ourselves. group_bb.Max = ImMax(group_bb.Min, group_bb.Max); window->DC.CursorPos = group_data.BackupCursorPos; From b513fdce481a950cc27b90b8284eb5765922ee7b Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 29 Nov 2017 23:47:15 +0100 Subject: [PATCH 643/921] Scrolling: SetScrollFromPosY() tweak to match change in a0d53fee81084a547bf21f46e736ea89f79fffb5 with similar desirable jump/discontinuity at each limit to skip the (ItemSpacing>WindowPadding) difference (followup to 0e5b64ecd2e291eac3475e10ab8aa1fa773a3a03, #150) --- imgui.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 08f4ec250..20b0b2e8a 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -5709,9 +5709,13 @@ void ImGui::SetScrollFromPosY(float pos_y, float center_y_ratio) ImGuiWindow* window = GetCurrentWindow(); IM_ASSERT(center_y_ratio >= 0.0f && center_y_ratio <= 1.0f); window->ScrollTarget.y = (float)(int)(pos_y + window->Scroll.y); - if (center_y_ratio <= 0.0f && window->ScrollTarget.y <= window->WindowPadding.y) // Minor hack to make "scroll to top" take account of WindowPadding, else it would scroll to (WindowPadding.y - ItemSpacing.y) - window->ScrollTarget.y = 0.0f; window->ScrollTargetCenterRatio.y = center_y_ratio; + + // Minor hack to to make scrolling to top/bottom of window take account of WindowPadding, it looks more right to the user this way + if (center_y_ratio <= 0.0f && window->ScrollTarget.y <= window->WindowPadding.y) + window->ScrollTarget.y = 0.0f; + else if (center_y_ratio >= 1.0f && window->ScrollTarget.y >= window->SizeContents.y - window->WindowPadding.y + GImGui->Style.ItemSpacing.y) + window->ScrollTarget.y = window->SizeContents.y; } // center_y_ratio: 0.0f top of last item, 0.5f vertical center of last item, 1.0f bottom of last item. From 0d53c8d4809bdfcacb0ad52d695fa257007ad4ad Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 29 Nov 2017 23:47:59 +0100 Subject: [PATCH 644/921] Demo: Console: Fixed incorrect positioning which was hidden by a minor scroll issue (this would affect people who copied the console code as is) --- imgui_demo.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index a25226212..6b0fed769 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -2480,7 +2480,7 @@ struct ExampleAppConsole ImGui::PopStyleVar(); ImGui::Separator(); - ImGui::BeginChild("ScrollingRegion", ImVec2(0,-ImGui::GetItemsLineHeightWithSpacing()), false, ImGuiWindowFlags_HorizontalScrollbar); + ImGui::BeginChild("ScrollingRegion", ImVec2(0, -ImGui::GetStyle().ItemSpacing.y - ImGui::GetItemsLineHeightWithSpacing()), false, ImGuiWindowFlags_HorizontalScrollbar); // Leave room for 1 separator + 1 InputText if (ImGui::BeginPopupContextWindow()) { if (ImGui::Selectable("Clear")) ClearLog(); @@ -2807,9 +2807,9 @@ static void ShowExampleAppLayout(bool* p_open) ImGui::Separator(); ImGui::TextWrapped("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. "); ImGui::EndChild(); - if (ImGui::Button("Revert")) {} - ImGui::SameLine(); - if (ImGui::Button("Save")) {} + if (ImGui::Button("Revert")) {} + ImGui::SameLine(); + if (ImGui::Button("Save")) {} ImGui::EndGroup(); } ImGui::End(); From 6ea744d8f42cd8b5bd89562126712ddd79700721 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 30 Nov 2017 16:54:39 +0100 Subject: [PATCH 645/921] Drag and Drop: Added DragSource from color square. Added DragTarget on ColorEdit4 widget. (#143) --- imgui.cpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/imgui.cpp b/imgui.cpp index a21cba8bc..280a2438a 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9671,6 +9671,16 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl else window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_FrameBg), rounding); // Color button are often in need of some sort of border + if (g.ActiveId == id && BeginDragDropSource()) // NB: The ActiveId test is merely an optional micro-optimization + { + SetDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_4F, &col, sizeof(col), ImGuiCond_Once); + ColorButton(desc_id, col, flags); + SameLine(); + TextUnformatted("Color"); + EndDragDropSource(); + hovered = false; + } + if (!(flags & ImGuiColorEditFlags_NoTooltip) && hovered) ColorTooltip(desc_id, &col.x, flags & (ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf)); @@ -9947,6 +9957,17 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag PopID(); EndGroup(); + if (window->DC.LastItemRectHoveredRect && BeginDragDropTarget()) // NB: The LastItemRectHoveredRect test is merely an optional micro-optimization + { + if (const ImGuiPayload* payload = AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_4F)) + { + IM_ASSERT(payload->DataSize == sizeof(ImVec4)); + memcpy((float*)col, payload->Data, sizeof(ImVec4)); + value_changed = true; + } + EndDragDropTarget(); + } + return value_changed; } From aea3fe41b9a3dea659b92f50215be2b6b104bb68 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 30 Nov 2017 23:07:48 +0100 Subject: [PATCH 646/921] Style: Tweaks Dark and Light styles. (#707) --- imgui_draw.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 481014443..2c937e597 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -203,8 +203,8 @@ void ImGui::StyleColorsDark(ImGuiStyle* dst) colors[ImGuiCol_HeaderHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.80f); colors[ImGuiCol_HeaderActive] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); colors[ImGuiCol_Separator] = colors[ImGuiCol_Border];//ImVec4(0.61f, 0.61f, 0.61f, 1.00f); - colors[ImGuiCol_SeparatorHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.78f); - colors[ImGuiCol_SeparatorActive] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); + colors[ImGuiCol_SeparatorHovered] = ImVec4(0.10f, 0.40f, 0.75f, 0.78f); + colors[ImGuiCol_SeparatorActive] = ImVec4(0.10f, 0.40f, 0.75f, 1.00f); colors[ImGuiCol_ResizeGrip] = ImVec4(0.26f, 0.59f, 0.98f, 0.25f); colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.67f); colors[ImGuiCol_ResizeGripActive] = ImVec4(0.26f, 0.59f, 0.98f, 0.95f); @@ -230,7 +230,7 @@ void ImGui::StyleColorsLight(ImGuiStyle* dst) //colors[ImGuiCol_TextActive] = ImVec4(1.00f, 1.00f, 0.00f, 1.00f); colors[ImGuiCol_WindowBg] = ImVec4(0.94f, 0.94f, 0.94f, 1.00f); colors[ImGuiCol_ChildBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); - colors[ImGuiCol_PopupBg] = ImVec4(1.00f, 1.00f, 1.00f, 0.94f); + colors[ImGuiCol_PopupBg] = ImVec4(1.00f, 1.00f, 1.00f, 0.98f); colors[ImGuiCol_Border] = ImVec4(0.00f, 0.00f, 0.00f, 0.30f); colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); colors[ImGuiCol_FrameBg] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f); @@ -254,8 +254,8 @@ void ImGui::StyleColorsLight(ImGuiStyle* dst) colors[ImGuiCol_HeaderHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.80f); colors[ImGuiCol_HeaderActive] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); colors[ImGuiCol_Separator] = ImVec4(0.39f, 0.39f, 0.39f, 1.00f); - colors[ImGuiCol_SeparatorHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.78f); - colors[ImGuiCol_SeparatorActive] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); + colors[ImGuiCol_SeparatorHovered] = ImVec4(0.14f, 0.44f, 0.80f, 0.78f); + colors[ImGuiCol_SeparatorActive] = ImVec4(0.14f, 0.44f, 0.80f, 1.00f); colors[ImGuiCol_ResizeGrip] = ImVec4(0.80f, 0.80f, 0.80f, 0.56f); colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.67f); colors[ImGuiCol_ResizeGripActive] = ImVec4(0.26f, 0.59f, 0.98f, 0.95f); From c860a0a85cc6f5264dc1774568ea965df0ff027e Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 1 Dec 2017 17:38:25 +0100 Subject: [PATCH 647/921] Internals: ImRect: Added IsFinite() helper. --- imgui_internal.h | 1 + 1 file changed, 1 insertion(+) diff --git a/imgui_internal.h b/imgui_internal.h index 80d18ac5f..b3371f5c1 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -281,6 +281,7 @@ struct IMGUI_API ImRect void Translate(const ImVec2& v) { Min.x += v.x; Min.y += v.y; Max.x += v.x; Max.y += v.y; } void ClipWith(const ImRect& clip) { if (Min.x < clip.Min.x) Min.x = clip.Min.x; if (Min.y < clip.Min.y) Min.y = clip.Min.y; if (Max.x > clip.Max.x) Max.x = clip.Max.x; if (Max.y > clip.Max.y) Max.y = clip.Max.y; } void Floor() { Min.x = (float)(int)Min.x; Min.y = (float)(int)Min.y; Max.x = (float)(int)Max.x; Max.y = (float)(int)Max.y; } + bool IsFinite() const { return Min.x != FLT_MAX; } ImVec2 GetClosestPoint(ImVec2 p, bool on_edge) const { if (!on_edge && Contains(p)) From be6384eb2a85aaaba0b152a464b6d2d949eddee3 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 30 Nov 2017 19:06:09 +0100 Subject: [PATCH 648/921] Style: Tweaked default WindowRounding value from 9 to 7 (#707) --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 20b0b2e8a..f31b99d8b 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -707,7 +707,7 @@ ImGuiStyle::ImGuiStyle() { Alpha = 1.0f; // Global alpha applies to everything in ImGui WindowPadding = ImVec2(8,8); // Padding within a window - WindowRounding = 9.0f; // Radius of window corners rounding. Set to 0.0f to have rectangular windows + WindowRounding = 7.0f; // Radius of window corners rounding. Set to 0.0f to have rectangular windows WindowBorderSize = 0.0f; // Thickness of border around windows. Generally set to 0.0f or 1.0f. Other values not well tested. WindowMinSize = ImVec2(32,32); // Minimum window size WindowTitleAlign = ImVec2(0.0f,0.5f);// Alignment for title bar text From 5f7cd7fb1c0793e5581e9914a39c53f327262a64 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 30 Nov 2017 18:02:42 +0100 Subject: [PATCH 649/921] Internals: Splitter Behavior doesn't show a border. (#319) --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index f31b99d8b..de781c5f8 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -10343,7 +10343,7 @@ bool ImGui::SplitterBehavior(ImGuiID id, const ImRect& bb, ImGuiAxis axis, float // Render const ImU32 col = GetColorU32(held ? ImGuiCol_SeparatorActive : hovered ? ImGuiCol_SeparatorHovered : ImGuiCol_Separator); - RenderFrame(bb_render.Min, bb_render.Max, col, true, g.Style.FrameRounding); + window->DrawList->AddRectFilled(bb_render.Min, bb_render.Max, col, g.Style.FrameRounding); return held; } From 77d1a4b6369943064a8faf9025ef211c0473ab4c Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 5 Dec 2017 16:12:45 +0100 Subject: [PATCH 650/921] Fixed a one frame glitch, when window claiming focus themselves on appear, the title bar wouldn't use the focused color on that frame. --- imgui.cpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index de781c5f8..e6a91bc67 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4515,6 +4515,12 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) if ((flags & ImGuiWindowFlags_Modal) != 0 && window == GetFrontMostModalRootWindow()) window->DrawList->AddRectFilled(fullscreen_rect.Min, fullscreen_rect.Max, GetColorU32(ImGuiCol_ModalWindowDarkening, g.ModalWindowDarkeningRatio)); + // Apply focus, new windows appears in front + bool want_focus = false; + if (window_just_activated_by_user && !(flags & ImGuiWindowFlags_NoFocusOnAppearing)) + if (!(flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_Tooltip)) || (flags & ImGuiWindowFlags_Popup)) + want_focus = true; + // Draw window + handle manual resize ImRect title_bar_rect = window->TitleBarRect(); if (window->Collapsed) @@ -4569,7 +4575,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->DrawList->AddRectFilled(window->Pos+ImVec2(0,window->TitleBarHeight()), window->Pos+window->Size, bg_col, window_rounding, (flags & ImGuiWindowFlags_NoTitleBar) ? ImDrawCornerFlags_All : ImDrawCornerFlags_Bot); // Title bar - const bool window_is_focused = g.NavWindow && window->RootNonPopupWindow == g.NavWindow->RootNonPopupWindow; + const bool window_is_focused = want_focus || (g.NavWindow && window->RootNonPopupWindow == g.NavWindow->RootNonPopupWindow); if (!(flags & ImGuiWindowFlags_NoTitleBar)) window->DrawList->AddRectFilled(title_bar_rect.Min, title_bar_rect.Max, GetColorU32(window_is_focused ? ImGuiCol_TitleBgActive : ImGuiCol_TitleBg), window_rounding, ImDrawCornerFlags_Top); @@ -4656,10 +4662,9 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) if (window->AutoFitFramesY > 0) window->AutoFitFramesY--; - // New windows appears in front (we need to do that AFTER setting DC.CursorStartPos so our initial navigation reference rectangle can start around there) - if (window_just_activated_by_user && !(flags & ImGuiWindowFlags_NoFocusOnAppearing)) - if (!(flags & (ImGuiWindowFlags_ChildWindow|ImGuiWindowFlags_Tooltip)) || (flags & ImGuiWindowFlags_Popup)) - FocusWindow(window); + // Apply focus (we need to call FocusWindow() AFTER setting DC.CursorStartPos so our initial navigation reference rectangle can start around there) + if (want_focus) + FocusWindow(window); // Title bar if (!(flags & ImGuiWindowFlags_NoTitleBar)) From fe2cf231a8cf3b91c04d8c4ec2b684eca63424a8 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 6 Dec 2017 11:18:17 +0100 Subject: [PATCH 651/921] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index d44ec5769..29fcab16e 100644 --- a/README.md +++ b/README.md @@ -77,6 +77,7 @@ Frameworks: - Cinder: https://github.com/simongeilfus/Cinder-ImGui - cocos2d-x: https://github.com/c0i/imguix https://github.com/ocornut/imgui/issues/551 - Flexium/SFML (FlexGUI): https://github.com/DXsmiley/FlexGUI +- GML/GameMakerStudio2 (ImGuiGML): https://marketplace.yoyogames.com/assets/6221/imguigml - Irrlicht (IrrIMGUI): https://github.com/ZahlGraf/IrrIMGUI - Ogre: https://bitbucket.org/LMCrashy/ogreimgui/src - openFrameworks (ofxImGui): https://github.com/jvcleave/ofxImGui From 90ae1c59c4fc9d13210fbf6dbc6ad9508f7b06fa Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 5 Dec 2017 20:36:35 +0100 Subject: [PATCH 652/921] Added ImGuiWindowFlags_ResizeFromAnySide flag and code to resize from any of the 4 corners (only 2 corners enabled). (#822) --- imgui.cpp | 115 +++++++++++++++++++++++++++++++++++++++--------------- imgui.h | 2 + 2 files changed, 86 insertions(+), 31 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index e6a91bc67..1eaf0efac 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4198,6 +4198,37 @@ static ImGuiCol GetWindowBgColorIdxFromFlags(ImGuiWindowFlags flags) return ImGuiCol_WindowBg; } +static void CalcResizePosSizeFromAnyCorner(ImGuiWindow* window, const ImVec2& corner_target, const ImVec2& corner_norm, ImVec2* out_pos, ImVec2* out_size) +{ + ImVec2 pos_min = ImLerp(corner_target, window->Pos, corner_norm); // Expected window upper-left + ImVec2 pos_max = ImLerp(window->Pos + window->Size, corner_target, corner_norm); // Expected window lower-right + ImVec2 size_expected = pos_max - pos_min; + ImVec2 size_constrained = CalcSizeFullWithConstraint(window, size_expected); + *out_pos = pos_min; + if (corner_norm.x == 0.0f) + out_pos->x -= (size_constrained.x - size_expected.x); + if (corner_norm.y == 0.0f) + out_pos->y -= (size_constrained.y - size_expected.y); + *out_size = size_constrained; +} + +struct ImGuiResizeGripDef +{ + const char* StrId; + ImVec2 CornerNorm; + ImVec2 InnerDir; + int AngleMin12, AngleMax12; + ImGuiMouseCursor MouseCursor; +}; + +const ImGuiResizeGripDef resize_grip_def[4] = +{ + { "#RESIZE0", ImVec2(1,1), ImVec2(-1,-1), 0, 3, ImGuiMouseCursor_ResizeNWSE }, // Lower right + { "#RESIZE1", ImVec2(0,1), ImVec2(+1,-1), 3, 6, ImGuiMouseCursor_ResizeNESW }, // Lower left + { "#RESIZE2", ImVec2(0,0), ImVec2(+1,+1), 6, 9, ImGuiMouseCursor_ResizeNWSE }, // Upper left + { "#RESIZE3", ImVec2(1,0), ImVec2(-1,+1), 9,12, ImGuiMouseCursor_ResizeNESW }, // Upper right +}; + // Push a new ImGui window to add widgets to. // - A default window called "Debug" is automatically stacked at the beginning of every frame so you can use widgets without explicitly calling a Begin/End pair. // - Begin/End can be called multiple times during the frame with the same window name to append content. @@ -4533,39 +4564,58 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) } else { - ImU32 resize_col = 0; - const float resize_corner_size = ImMax(g.FontSize * 1.35f, window_rounding + 1.0f + g.FontSize * 0.2f); + // Handle resize for: Resize Grips, Gamepad + ImU32 resize_grip_col[4] = { 0 }; + const int resize_grip_count = (flags & ImGuiWindowFlags_ResizeFromAnySide) ? 2 : 1; // 4 + const float resize_corner_size = (float)(int)ImMax(g.FontSize * 1.35f, window_rounding + 1.0f + g.FontSize * 0.2f); if (!(flags & ImGuiWindowFlags_AlwaysAutoResize) && window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0 && !(flags & ImGuiWindowFlags_NoResize)) { - // Manual resize - // Using the FlattenChilds button flag, we make the resize button accessible even if we are hovering over a child window - const ImVec2 br = window->Rect().GetBR(); - const ImRect resize_rect(br - ImFloor(ImVec2(resize_corner_size * 0.75f, resize_corner_size * 0.75f)), br); - const ImGuiID resize_id = window->GetID("#RESIZE"); - bool hovered, held; - ButtonBehavior(resize_rect, resize_id, &hovered, &held, ImGuiButtonFlags_FlattenChilds); - resize_col = GetColorU32(held ? ImGuiCol_ResizeGripActive : hovered ? ImGuiCol_ResizeGripHovered : ImGuiCol_ResizeGrip); - if (hovered || held) - g.MouseCursor = ImGuiMouseCursor_ResizeNWSE; + ImVec2 pos_target(FLT_MAX, FLT_MAX); + ImVec2 size_target(FLT_MAX, FLT_MAX); - ImVec2 size_target(FLT_MAX,FLT_MAX); - if (g.HoveredWindow == window && held && g.IO.MouseDoubleClicked[0]) + // Manual resize grips + for (int resize_grip_n = 0; resize_grip_n < resize_grip_count; resize_grip_n++) { - // Manual auto-fit when double-clicking - size_target = size_auto_fit; - ClearActiveID(); - } - else if (held) - { - // We don't use an incremental MouseDelta but rather compute an absolute target size based on mouse position - size_target = (g.IO.MousePos - g.ActiveIdClickOffset - window->Pos) + resize_rect.GetSize(); + const ImGuiResizeGripDef& grip = resize_grip_def[resize_grip_n]; + const ImVec2 corner = ImLerp(window->Pos, window->Pos + window->Size, grip.CornerNorm); + + // Using the FlattenChilds button flag we make the resize button accessible even if we are hovering over a child window + ImRect resize_rect; + resize_rect.Add(corner); + resize_rect.Add(corner + grip.InnerDir * (float)(int)(resize_corner_size * 0.75f)); + bool hovered, held; + ButtonBehavior(resize_rect, window->GetID(grip.StrId), &hovered, &held, ImGuiButtonFlags_FlattenChilds); + if (hovered || held) + g.MouseCursor = grip.MouseCursor; + + if (g.HoveredWindow == window && held && g.IO.MouseDoubleClicked[0]) + { + // Manual auto-fit when double-clicking + size_target = CalcSizeFullWithConstraint(window, size_auto_fit); + ClearActiveID(); + } + else if (held) + { + // Resize from any of the four corners + // We don't use an incremental MouseDelta but rather compute an absolute target size based on mouse position + ImVec2 corner_target = g.IO.MousePos - g.ActiveIdClickOffset + resize_rect.GetSize() * grip.CornerNorm; // Corner of the window corresponding to our corner grip + CalcResizePosSizeFromAnyCorner(window, corner_target, grip.CornerNorm, &pos_target, &size_target); + } + resize_grip_col[resize_grip_n] = GetColorU32(held ? ImGuiCol_ResizeGripActive : hovered ? ImGuiCol_ResizeGripHovered : ImGuiCol_ResizeGrip); } - if (size_target.x != FLT_MAX && size_target.y != FLT_MAX) + // Apply back modified position/size to window + if (size_target.x != FLT_MAX) { - window->SizeFull = CalcSizeFullWithConstraint(window, size_target); + window->SizeFull = size_target; MarkIniSettingsDirty(window); } + if (pos_target.x != FLT_MAX) + { + window->Pos = window->PosFloat = ImVec2((float)(int)pos_target.x, (float)(int)pos_target.y); + MarkIniSettingsDirty(window); + } + window->Size = window->SizeFull; title_bar_rect = window->TitleBarRect(); } @@ -4595,15 +4645,18 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) if (window->ScrollbarY) Scrollbar(ImGuiLayoutType_Vertical); - // Render resize grip - // (after the input handling so we don't have a frame of latency) + // Render resize grips (after their input handling so we don't have a frame of latency) if (!(flags & ImGuiWindowFlags_NoResize)) { - const ImVec2 br = window->Rect().GetBR(); - window->DrawList->PathLineTo(br + ImVec2(-resize_corner_size, -window_border_size)); - window->DrawList->PathLineTo(br + ImVec2(-window_border_size, -resize_corner_size)); - window->DrawList->PathArcToFast(ImVec2(br.x - window_rounding - window_border_size, br.y - window_rounding - window_border_size), window_rounding, 0, 3); - window->DrawList->PathFillConvex(resize_col); + for (int resize_grip_n = 0; resize_grip_n < resize_grip_count; resize_grip_n++) + { + const ImGuiResizeGripDef& grip = resize_grip_def[resize_grip_n]; + const ImVec2 corner = ImLerp(window->Pos, window->Pos + window->Size, grip.CornerNorm); + window->DrawList->PathLineTo(corner + grip.InnerDir * ((resize_grip_n & 1) ? ImVec2(window_border_size, resize_corner_size) : ImVec2(resize_corner_size, window_border_size))); + window->DrawList->PathLineTo(corner + grip.InnerDir * ((resize_grip_n & 1) ? ImVec2(resize_corner_size, window_border_size) : ImVec2(window_border_size, resize_corner_size))); + window->DrawList->PathArcToFast(ImVec2(corner.x + grip.InnerDir.x * (window_rounding + window_border_size), corner.y + grip.InnerDir.y * (window_rounding + window_border_size)), window_rounding, grip.AngleMin12, grip.AngleMax12); + window->DrawList->PathFillConvex(resize_grip_col[resize_grip_n]); + } } // Borders diff --git a/imgui.h b/imgui.h index f09209103..ec5692e1a 100644 --- a/imgui.h +++ b/imgui.h @@ -513,6 +513,8 @@ enum ImGuiWindowFlags_ ImGuiWindowFlags_AlwaysVerticalScrollbar= 1 << 14, // Always show vertical scrollbar (even if ContentSize.y < Size.y) ImGuiWindowFlags_AlwaysHorizontalScrollbar=1<< 15, // Always show horizontal scrollbar (even if ContentSize.x < Size.x) ImGuiWindowFlags_AlwaysUseWindowPadding = 1 << 16, // Ensure child windows without border uses style.WindowPadding (ignored by default for non-bordered child windows, because more convenient) + ImGuiWindowFlags_ResizeFromAnySide = 1 << 17, + // [Internal] ImGuiWindowFlags_ChildWindow = 1 << 22, // Don't use! For internal use by BeginChild() ImGuiWindowFlags_ComboBox = 1 << 23, // Don't use! For internal use by ComboBox() From e103fe8c1f0951c1045f9ffe3ae24273cd44ab28 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 5 Dec 2017 22:05:24 +0100 Subject: [PATCH 653/921] Tweak four-corners resize grip code. Added ImRect::FixInverted() helper. (#822) --- imgui.cpp | 39 ++++++++++++++++++++------------------- imgui_internal.h | 1 + 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 1eaf0efac..5d95827b1 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4214,19 +4214,17 @@ static void CalcResizePosSizeFromAnyCorner(ImGuiWindow* window, const ImVec2& co struct ImGuiResizeGripDef { - const char* StrId; - ImVec2 CornerNorm; + ImVec2 CornerPos; ImVec2 InnerDir; int AngleMin12, AngleMax12; - ImGuiMouseCursor MouseCursor; }; const ImGuiResizeGripDef resize_grip_def[4] = { - { "#RESIZE0", ImVec2(1,1), ImVec2(-1,-1), 0, 3, ImGuiMouseCursor_ResizeNWSE }, // Lower right - { "#RESIZE1", ImVec2(0,1), ImVec2(+1,-1), 3, 6, ImGuiMouseCursor_ResizeNESW }, // Lower left - { "#RESIZE2", ImVec2(0,0), ImVec2(+1,+1), 6, 9, ImGuiMouseCursor_ResizeNWSE }, // Upper left - { "#RESIZE3", ImVec2(1,0), ImVec2(-1,+1), 9,12, ImGuiMouseCursor_ResizeNESW }, // Upper right + { ImVec2(1,1), ImVec2(-1,-1), 0, 3 }, // Lower right + { ImVec2(0,1), ImVec2(+1,-1), 3, 6 }, // Lower left + { ImVec2(0,0), ImVec2(+1,+1), 6, 9 }, // Upper left + { ImVec2(1,0), ImVec2(-1,+1), 9,12 }, // Upper right }; // Push a new ImGui window to add widgets to. @@ -4567,26 +4565,28 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // Handle resize for: Resize Grips, Gamepad ImU32 resize_grip_col[4] = { 0 }; const int resize_grip_count = (flags & ImGuiWindowFlags_ResizeFromAnySide) ? 2 : 1; // 4 - const float resize_corner_size = (float)(int)ImMax(g.FontSize * 1.35f, window_rounding + 1.0f + g.FontSize * 0.2f); + + const float grip_draw_size = (float)(int)ImMax(g.FontSize * 1.35f, window_rounding + 1.0f + g.FontSize * 0.2f); + const float grip_hover_size = (float)(int)(grip_draw_size * 0.75f); if (!(flags & ImGuiWindowFlags_AlwaysAutoResize) && window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0 && !(flags & ImGuiWindowFlags_NoResize)) { ImVec2 pos_target(FLT_MAX, FLT_MAX); ImVec2 size_target(FLT_MAX, FLT_MAX); // Manual resize grips + PushID("#RESIZE"); for (int resize_grip_n = 0; resize_grip_n < resize_grip_count; resize_grip_n++) { const ImGuiResizeGripDef& grip = resize_grip_def[resize_grip_n]; - const ImVec2 corner = ImLerp(window->Pos, window->Pos + window->Size, grip.CornerNorm); + const ImVec2 corner = ImLerp(window->Pos, window->Pos + window->Size, grip.CornerPos); // Using the FlattenChilds button flag we make the resize button accessible even if we are hovering over a child window - ImRect resize_rect; - resize_rect.Add(corner); - resize_rect.Add(corner + grip.InnerDir * (float)(int)(resize_corner_size * 0.75f)); + ImRect resize_rect(corner, corner + grip.InnerDir * grip_hover_size); + resize_rect.FixInverted(); bool hovered, held; - ButtonBehavior(resize_rect, window->GetID(grip.StrId), &hovered, &held, ImGuiButtonFlags_FlattenChilds); + ButtonBehavior(resize_rect, window->GetID((void*)resize_grip_n), &hovered, &held, ImGuiButtonFlags_FlattenChilds); if (hovered || held) - g.MouseCursor = grip.MouseCursor; + g.MouseCursor = (resize_grip_n & 1) ? ImGuiMouseCursor_ResizeNESW : ImGuiMouseCursor_ResizeNWSE; if (g.HoveredWindow == window && held && g.IO.MouseDoubleClicked[0]) { @@ -4598,11 +4598,12 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) { // Resize from any of the four corners // We don't use an incremental MouseDelta but rather compute an absolute target size based on mouse position - ImVec2 corner_target = g.IO.MousePos - g.ActiveIdClickOffset + resize_rect.GetSize() * grip.CornerNorm; // Corner of the window corresponding to our corner grip - CalcResizePosSizeFromAnyCorner(window, corner_target, grip.CornerNorm, &pos_target, &size_target); + ImVec2 corner_target = g.IO.MousePos - g.ActiveIdClickOffset + resize_rect.GetSize() * grip.CornerPos; // Corner of the window corresponding to our corner grip + CalcResizePosSizeFromAnyCorner(window, corner_target, grip.CornerPos, &pos_target, &size_target); } resize_grip_col[resize_grip_n] = GetColorU32(held ? ImGuiCol_ResizeGripActive : hovered ? ImGuiCol_ResizeGripHovered : ImGuiCol_ResizeGrip); } + PopID(); // Apply back modified position/size to window if (size_target.x != FLT_MAX) @@ -4651,9 +4652,9 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) for (int resize_grip_n = 0; resize_grip_n < resize_grip_count; resize_grip_n++) { const ImGuiResizeGripDef& grip = resize_grip_def[resize_grip_n]; - const ImVec2 corner = ImLerp(window->Pos, window->Pos + window->Size, grip.CornerNorm); - window->DrawList->PathLineTo(corner + grip.InnerDir * ((resize_grip_n & 1) ? ImVec2(window_border_size, resize_corner_size) : ImVec2(resize_corner_size, window_border_size))); - window->DrawList->PathLineTo(corner + grip.InnerDir * ((resize_grip_n & 1) ? ImVec2(resize_corner_size, window_border_size) : ImVec2(window_border_size, resize_corner_size))); + const ImVec2 corner = ImLerp(window->Pos, window->Pos + window->Size, grip.CornerPos); + window->DrawList->PathLineTo(corner + grip.InnerDir * ((resize_grip_n & 1) ? ImVec2(window_border_size, grip_draw_size) : ImVec2(grip_draw_size, window_border_size))); + window->DrawList->PathLineTo(corner + grip.InnerDir * ((resize_grip_n & 1) ? ImVec2(grip_draw_size, window_border_size) : ImVec2(window_border_size, grip_draw_size))); window->DrawList->PathArcToFast(ImVec2(corner.x + grip.InnerDir.x * (window_rounding + window_border_size), corner.y + grip.InnerDir.y * (window_rounding + window_border_size)), window_rounding, grip.AngleMin12, grip.AngleMax12); window->DrawList->PathFillConvex(resize_grip_col[resize_grip_n]); } diff --git a/imgui_internal.h b/imgui_internal.h index b3371f5c1..23992c438 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -281,6 +281,7 @@ struct IMGUI_API ImRect void Translate(const ImVec2& v) { Min.x += v.x; Min.y += v.y; Max.x += v.x; Max.y += v.y; } void ClipWith(const ImRect& clip) { if (Min.x < clip.Min.x) Min.x = clip.Min.x; if (Min.y < clip.Min.y) Min.y = clip.Min.y; if (Max.x > clip.Max.x) Max.x = clip.Max.x; if (Max.y > clip.Max.y) Max.y = clip.Max.y; } void Floor() { Min.x = (float)(int)Min.x; Min.y = (float)(int)Min.y; Max.x = (float)(int)Max.x; Max.y = (float)(int)Max.y; } + void FixInverted() { if (Min.x > Max.x) ImSwap(Min.x, Max.x); if (Min.y > Max.y) ImSwap(Min.y, Max.y); } bool IsFinite() const { return Min.x != FLT_MAX; } ImVec2 GetClosestPoint(ImVec2 p, bool on_edge) const { From 531e559e49a3cdf988de6ea2dac904536da9c6a0 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 5 Dec 2017 22:38:02 +0100 Subject: [PATCH 654/921] Windows can be resized from their borders when ImGuiWindowFlags_ResizeFromAnySide is set. (#822) The interaction is currently unsatisfying because we can only reach a window from its inner rectangle (because of HoveredWindow filtering). --- imgui.cpp | 45 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 5d95827b1..c02e29203 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4227,6 +4227,18 @@ const ImGuiResizeGripDef resize_grip_def[4] = { ImVec2(1,0), ImVec2(-1,+1), 9,12 }, // Upper right }; +static ImRect GetBorderRect(ImGuiWindow* window, int border_n, float perp_padding, float thickness) +{ + ImRect rect = window->Rect(); + if (thickness == 0.0f) rect.Max -= ImVec2(1,1); + if (border_n == 0) return ImRect(rect.Min.x + perp_padding, rect.Min.y, rect.Max.x - perp_padding, rect.Min.y + thickness); + if (border_n == 1) return ImRect(rect.Max.x - thickness, rect.Min.y + perp_padding, rect.Max.x, rect.Max.y - perp_padding); + if (border_n == 2) return ImRect(rect.Min.x + perp_padding, rect.Max.y - thickness, rect.Max.x - perp_padding, rect.Max.y); + if (border_n == 3) return ImRect(rect.Min.x, rect.Min.y + perp_padding, rect.Min.x + thickness, rect.Max.y - perp_padding); + IM_ASSERT(0); + return ImRect(); +} + // Push a new ImGui window to add widgets to. // - A default window called "Debug" is automatically stacked at the beginning of every frame so you can use widgets without explicitly calling a Begin/End pair. // - Begin/End can be called multiple times during the frame with the same window name to append content. @@ -4562,9 +4574,11 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) } else { - // Handle resize for: Resize Grips, Gamepad + // Handle resize for: Resize Grips, Borders, Gamepad + int border_hovered = -1, border_held = -1; ImU32 resize_grip_col[4] = { 0 }; const int resize_grip_count = (flags & ImGuiWindowFlags_ResizeFromAnySide) ? 2 : 1; // 4 + const int resize_border_count = (flags & ImGuiWindowFlags_ResizeFromAnySide) ? 4 : 0; const float grip_draw_size = (float)(int)ImMax(g.FontSize * 1.35f, window_rounding + 1.0f + g.FontSize * 0.2f); const float grip_hover_size = (float)(int)(grip_draw_size * 0.75f); @@ -4603,6 +4617,30 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) } resize_grip_col[resize_grip_n] = GetColorU32(held ? ImGuiCol_ResizeGripActive : hovered ? ImGuiCol_ResizeGripHovered : ImGuiCol_ResizeGrip); } + for (int border_n = 0; border_n < resize_border_count; border_n++) + { + const float BORDER_SIZE = 5.0f; // FIXME: Only works _inside_ window because of HoveredWindow check. + const float BORDER_APPEAR_TIMER = 0.05f; // Reduce visual noise + bool hovered, held; + ImRect border_rect = GetBorderRect(window, border_n, grip_hover_size, BORDER_SIZE); + ButtonBehavior(border_rect, window->GetID((void*)(border_n+4)), &hovered, &held, ImGuiButtonFlags_FlattenChilds); + if ((hovered && g.HoveredIdTimer > BORDER_APPEAR_TIMER) || (held && g.ActiveIdTimer > BORDER_APPEAR_TIMER)) + { + g.MouseCursor = (border_n & 1) ? ImGuiMouseCursor_ResizeEW : ImGuiMouseCursor_ResizeNS; + if (hovered) border_hovered = border_n; + if (held) border_held = border_n; + } + if (held) + { + ImVec2 border_target = window->Pos; + ImVec2 border_posn; + if (border_n == 0) { border_posn = ImVec2(0, 0); border_target.y = (g.IO.MousePos.y - g.ActiveIdClickOffset.y); } + if (border_n == 1) { border_posn = ImVec2(1, 0); border_target.x = (g.IO.MousePos.x - g.ActiveIdClickOffset.x + BORDER_SIZE); } + if (border_n == 2) { border_posn = ImVec2(0, 1); border_target.y = (g.IO.MousePos.y - g.ActiveIdClickOffset.y + BORDER_SIZE); } + if (border_n == 3) { border_posn = ImVec2(0, 0); border_target.x = (g.IO.MousePos.x - g.ActiveIdClickOffset.x); } + CalcResizePosSizeFromAnyCorner(window, border_target, border_posn, &pos_target, &size_target); + } + } PopID(); // Apply back modified position/size to window @@ -4663,6 +4701,11 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // Borders if (window_border_size > 0.0f) window->DrawList->AddRect(window->Pos, window->Pos+window->Size, GetColorU32(ImGuiCol_Border), window_rounding, ImDrawCornerFlags_All, window_border_size); + if (border_held != -1 || border_hovered != -1) + { + ImRect border = GetBorderRect(window, border_held != -1 ? border_held : border_hovered, grip_draw_size, 0.0f); + window->DrawList->AddLine(border.Min, border.Max, GetColorU32(border_held != -1 ? ImGuiCol_SeparatorActive : ImGuiCol_SeparatorHovered), ImMax(1.0f, window_border_size)); + } if (style.FrameBorderSize > 0 && !(flags & ImGuiWindowFlags_NoTitleBar)) window->DrawList->AddLine(title_bar_rect.GetBL()+ImVec2(1,-1), title_bar_rect.GetBR()+ImVec2(-1,-1), GetColorU32(ImGuiCol_Border), style.FrameBorderSize); } From 3b7e4eaf384e7f5a299e5e411bc5289217545ce5 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 5 Dec 2017 22:53:58 +0100 Subject: [PATCH 655/921] Comments about ImGuiWindowFlags_ResizeFromAnySide. Removed hovering color. May need its own color. (#822) --- imgui.cpp | 11 +++++------ imgui.h | 2 +- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index c02e29203..5c5a7f7b0 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4575,7 +4575,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) else { // Handle resize for: Resize Grips, Borders, Gamepad - int border_hovered = -1, border_held = -1; + int border_held = -1; ImU32 resize_grip_col[4] = { 0 }; const int resize_grip_count = (flags & ImGuiWindowFlags_ResizeFromAnySide) ? 2 : 1; // 4 const int resize_border_count = (flags & ImGuiWindowFlags_ResizeFromAnySide) ? 4 : 0; @@ -4624,10 +4624,9 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) bool hovered, held; ImRect border_rect = GetBorderRect(window, border_n, grip_hover_size, BORDER_SIZE); ButtonBehavior(border_rect, window->GetID((void*)(border_n+4)), &hovered, &held, ImGuiButtonFlags_FlattenChilds); - if ((hovered && g.HoveredIdTimer > BORDER_APPEAR_TIMER) || (held && g.ActiveIdTimer > BORDER_APPEAR_TIMER)) + if ((hovered && g.HoveredIdTimer > BORDER_APPEAR_TIMER) || held) { g.MouseCursor = (border_n & 1) ? ImGuiMouseCursor_ResizeEW : ImGuiMouseCursor_ResizeNS; - if (hovered) border_hovered = border_n; if (held) border_held = border_n; } if (held) @@ -4701,10 +4700,10 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // Borders if (window_border_size > 0.0f) window->DrawList->AddRect(window->Pos, window->Pos+window->Size, GetColorU32(ImGuiCol_Border), window_rounding, ImDrawCornerFlags_All, window_border_size); - if (border_held != -1 || border_hovered != -1) + if (border_held != -1) { - ImRect border = GetBorderRect(window, border_held != -1 ? border_held : border_hovered, grip_draw_size, 0.0f); - window->DrawList->AddLine(border.Min, border.Max, GetColorU32(border_held != -1 ? ImGuiCol_SeparatorActive : ImGuiCol_SeparatorHovered), ImMax(1.0f, window_border_size)); + ImRect border = GetBorderRect(window, border_held, grip_draw_size, 0.0f); + window->DrawList->AddLine(border.Min, border.Max, GetColorU32(ImGuiCol_SeparatorActive), ImMax(1.0f, window_border_size)); } if (style.FrameBorderSize > 0 && !(flags & ImGuiWindowFlags_NoTitleBar)) window->DrawList->AddLine(title_bar_rect.GetBL()+ImVec2(1,-1), title_bar_rect.GetBR()+ImVec2(-1,-1), GetColorU32(ImGuiCol_Border), style.FrameBorderSize); diff --git a/imgui.h b/imgui.h index ec5692e1a..71fe24c2d 100644 --- a/imgui.h +++ b/imgui.h @@ -513,7 +513,7 @@ enum ImGuiWindowFlags_ ImGuiWindowFlags_AlwaysVerticalScrollbar= 1 << 14, // Always show vertical scrollbar (even if ContentSize.y < Size.y) ImGuiWindowFlags_AlwaysHorizontalScrollbar=1<< 15, // Always show horizontal scrollbar (even if ContentSize.x < Size.x) ImGuiWindowFlags_AlwaysUseWindowPadding = 1 << 16, // Ensure child windows without border uses style.WindowPadding (ignored by default for non-bordered child windows, because more convenient) - ImGuiWindowFlags_ResizeFromAnySide = 1 << 17, + ImGuiWindowFlags_ResizeFromAnySide = 1 << 17, // (WIP) Enable resize from any corners and borders. Your back-end needs to honor the different values of io.MouseCursor set by imgui. // [Internal] ImGuiWindowFlags_ChildWindow = 1 << 22, // Don't use! For internal use by BeginChild() From ecacaf7f2d678c17acd8503c38f084be2fd7cfd8 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 5 Dec 2017 23:03:08 +0100 Subject: [PATCH 656/921] Lower-right resize grip only appears when hovered. (#822) --- imgui.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 5c5a7f7b0..c7265bbc6 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4602,7 +4602,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) if (hovered || held) g.MouseCursor = (resize_grip_n & 1) ? ImGuiMouseCursor_ResizeNESW : ImGuiMouseCursor_ResizeNWSE; - if (g.HoveredWindow == window && held && g.IO.MouseDoubleClicked[0]) + if (g.HoveredWindow == window && held && g.IO.MouseDoubleClicked[0] && resize_grip_n == 0) { // Manual auto-fit when double-clicking size_target = CalcSizeFullWithConstraint(window, size_auto_fit); @@ -4615,7 +4615,8 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) ImVec2 corner_target = g.IO.MousePos - g.ActiveIdClickOffset + resize_rect.GetSize() * grip.CornerPos; // Corner of the window corresponding to our corner grip CalcResizePosSizeFromAnyCorner(window, corner_target, grip.CornerPos, &pos_target, &size_target); } - resize_grip_col[resize_grip_n] = GetColorU32(held ? ImGuiCol_ResizeGripActive : hovered ? ImGuiCol_ResizeGripHovered : ImGuiCol_ResizeGrip); + if (resize_grip_n == 0 || held || hovered) + resize_grip_col[resize_grip_n] = GetColorU32(held ? ImGuiCol_ResizeGripActive : hovered ? ImGuiCol_ResizeGripHovered : ImGuiCol_ResizeGrip); } for (int border_n = 0; border_n < resize_border_count; border_n++) { From beda5fc5a0252b80ee16293afb80701807a33150 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 6 Dec 2017 15:13:23 +0100 Subject: [PATCH 657/921] Fixed scrollbar enable/disable calculation when size is modified programmatically. This is the generalization of the fix in 2df8fa95dfe3463ece78c56b02dc815c3e71331a. --- imgui.cpp | 21 ++++++++++----------- imgui_internal.h | 1 + 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index c7265bbc6..0f9f663f3 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4064,12 +4064,8 @@ static ImGuiWindow* CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFl window->Flags = flags; g.WindowsById.SetVoidPtr(window->ID, window); - if (flags & ImGuiWindowFlags_NoSavedSettings) - { - // User can disable loading and saving of settings. Tooltip and child windows also don't store settings. - window->Size = window->SizeFull = size; - } - else + // User can disable loading and saving of settings. Tooltip and child windows also don't store settings. + if (!(flags & ImGuiWindowFlags_NoSavedSettings)) { // Retrieve settings from .ini file // Use SetWindowPos() or SetNextWindowPos() with the appropriate condition flag to change the initial position of a window. @@ -4085,8 +4081,8 @@ static ImGuiWindow* CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFl if (ImLengthSqr(settings->Size) > 0.00001f) size = settings->Size; } - window->Size = window->SizeFull = size; } + window->Size = window->SizeFull = window->SizeFullAtLastBegin = size; if ((flags & ImGuiWindowFlags_AlwaysAutoResize) != 0) { @@ -4468,13 +4464,13 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // SCROLLBAR STATUS - // Update scrollbar status (based on the Size that was effective during last frame or the auto-resized Size). We need to do this before manual resize (below) is effective. + // Update scrollbar status (based on the Size that was effective during last frame or the auto-resized Size). if (!window->Collapsed) { - window->ScrollbarY = (flags & ImGuiWindowFlags_AlwaysVerticalScrollbar) || ((window->SizeContents.y > window->SizeFull.y) && !(flags & ImGuiWindowFlags_NoScrollbar)); - window->ScrollbarX = (flags & ImGuiWindowFlags_AlwaysHorizontalScrollbar) || ((window->SizeContents.x > window->SizeFull.x - (window->ScrollbarY ? style.ScrollbarSize : 0.0f) - window->WindowPadding.x) && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar)); + window->ScrollbarY = (flags & ImGuiWindowFlags_AlwaysVerticalScrollbar) || ((window->SizeContents.y > window->SizeFullAtLastBegin.y) && !(flags & ImGuiWindowFlags_NoScrollbar)); + window->ScrollbarX = (flags & ImGuiWindowFlags_AlwaysHorizontalScrollbar) || ((window->SizeContents.x > window->SizeFullAtLastBegin.x - (window->ScrollbarY ? style.ScrollbarSize : 0.0f) - window->WindowPadding.x) && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar)); if (window->ScrollbarX && !window->ScrollbarY) - window->ScrollbarY = (window->SizeContents.y > window->SizeFull.y + style.ScrollbarSize) && !(flags & ImGuiWindowFlags_NoScrollbar); + window->ScrollbarY = (window->SizeContents.y > window->SizeFullAtLastBegin.y + style.ScrollbarSize) && !(flags & ImGuiWindowFlags_NoScrollbar); window->ScrollbarSizes = ImVec2(window->ScrollbarY ? style.ScrollbarSize : 0.0f, window->ScrollbarX ? style.ScrollbarSize : 0.0f); } @@ -4710,6 +4706,9 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->DrawList->AddLine(title_bar_rect.GetBL()+ImVec2(1,-1), title_bar_rect.GetBR()+ImVec2(-1,-1), GetColorU32(ImGuiCol_Border), style.FrameBorderSize); } + // Store a backup of SizeFull which we will use next frame to decide if we need scrollbars. + window->SizeFullAtLastBegin = window->SizeFull; + // Update ContentsRegionMax. All the variable it depends on are set above in this function. window->ContentsRegionRect.Min.x = -window->Scroll.x + window->WindowPadding.x; window->ContentsRegionRect.Min.y = -window->Scroll.y + window->WindowPadding.y + window->TitleBarHeight() + window->MenuBarHeight(); diff --git a/imgui_internal.h b/imgui_internal.h index 23992c438..1483a5e72 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -701,6 +701,7 @@ struct IMGUI_API ImGuiWindow ImVec2 Pos; // Position rounded-up to nearest pixel ImVec2 Size; // Current size (==SizeFull or collapsed title bar size) ImVec2 SizeFull; // Size when non collapsed + ImVec2 SizeFullAtLastBegin; // Copy of SizeFull at the end of Begin. This is the reference value we'll use on the next frame to decide if we need scrollbars. ImVec2 SizeContents; // Size of contents (== extents reach of the drawing cursor) from previous frame ImVec2 SizeContentsExplicit; // Size of contents explicitly set by the user via SetNextWindowContentSize() ImRect ContentsRegionRect; // Maximum visible content position in window coordinates. ~~ (SizeContentsExplicit ? SizeContentsExplicit : Size - ScrollbarSizes) - CursorStartPos, per axis From 8f41508c5269479881eadbba96a821d1eb44cd54 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 6 Dec 2017 17:42:28 +0100 Subject: [PATCH 658/921] Begin: Move the code that update the Appearing flag above the BeginDocked() branch. --- imgui.cpp | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 0f9f663f3..b6c707642 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4270,6 +4270,20 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) else flags = window->Flags; + // Update the Appearing flag + bool window_just_activated_by_user = (window->LastFrameActive < current_frame - 1); // Not using !WasActive because the implicit "Debug" window would always toggle off->on + const bool window_just_appearing_after_hidden_for_resize = (window->HiddenFrames == 1); + if (flags & ImGuiWindowFlags_Popup) + { + ImGuiPopupRef& popup_ref = g.OpenPopupStack[g.CurrentPopupStack.Size]; + window_just_activated_by_user |= (window->PopupId != popup_ref.PopupId); // We recycle popups so treat window as activated if popup id changed + window_just_activated_by_user |= (window != popup_ref.Window); + } + window->Appearing = (window_just_activated_by_user || window_just_appearing_after_hidden_for_resize); + window->CloseButton = (p_open != NULL); + if (window->Appearing) + SetWindowConditionAllowFlags(window, ImGuiCond_Appearing, true); + // Parent window is latched only on the first call to Begin() of the frame, so further append-calls can be done from a different window stack ImGuiWindow* parent_window = first_begin_of_the_frame ? (!g.CurrentWindowStack.empty() ? g.CurrentWindowStack.back() : NULL) : window->ParentWindow; IM_ASSERT(parent_window != NULL || !(flags & ImGuiWindowFlags_ChildWindow)); @@ -4278,25 +4292,15 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) g.CurrentWindowStack.push_back(window); SetCurrentWindow(window); CheckStacksSize(window, true); - - bool window_just_activated_by_user = (window->LastFrameActive < current_frame - 1); // Not using !WasActive because the implicit "Debug" window would always toggle off->on if (flags & ImGuiWindowFlags_Popup) { ImGuiPopupRef& popup_ref = g.OpenPopupStack[g.CurrentPopupStack.Size]; - window_just_activated_by_user |= (window->PopupId != popup_ref.PopupId); // We recycle popups so treat window as activated if popup id changed - window_just_activated_by_user |= (window != popup_ref.Window); popup_ref.Window = window; g.CurrentPopupStack.push_back(popup_ref); window->PopupId = popup_ref.PopupId; } - const bool window_just_appearing_after_hidden_for_resize = (window->HiddenFrames == 1); - window->Appearing = (window_just_activated_by_user || window_just_appearing_after_hidden_for_resize); - window->CloseButton = (p_open != NULL); - // Process SetNextWindow***() calls - if (window->Appearing) - SetWindowConditionAllowFlags(window, ImGuiCond_Appearing, true); bool window_pos_set_by_api = false, window_size_set_by_api = false; if (g.SetNextWindowPosCond) { From 20c7aab60c5beec1d1a5f353ab4385988d6e9abd Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 7 Dec 2017 12:49:52 +0100 Subject: [PATCH 659/921] Exposed GetOverlayDrawList(). (~#545, ~#530) --- imgui.cpp | 5 +++++ imgui.h | 1 + 2 files changed, 6 insertions(+) diff --git a/imgui.cpp b/imgui.cpp index b6c707642..20a1b7a16 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2233,6 +2233,11 @@ int ImGui::GetFrameCount() return GImGui->FrameCount; } +ImDrawList* ImGui::GetOverlayDrawList() +{ + return &GImGui->OverlayDrawList; +} + void ImGui::NewFrame() { ImGuiContext& g = *GImGui; diff --git a/imgui.h b/imgui.h index 71fe24c2d..8929dea76 100644 --- a/imgui.h +++ b/imgui.h @@ -441,6 +441,7 @@ namespace ImGui IMGUI_API bool IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max); // test if rectangle (in screen space) is visible / not clipped. to perform coarse clipping on user's side. IMGUI_API float GetTime(); IMGUI_API int GetFrameCount(); + IMGUI_API ImDrawList* GetOverlayDrawList(); // this draw list will be the last rendered one, useful to quickly draw overlays shapes/text IMGUI_API const char* GetStyleColorName(ImGuiCol idx); IMGUI_API ImVec2 CalcItemRectClosestPoint(const ImVec2& pos, bool on_edge = false, float outward = +0.0f); // utility to find the closest point the last item bounding rectangle edge. useful to visually link items IMGUI_API ImVec2 CalcTextSize(const char* text, const char* text_end = NULL, bool hide_text_after_double_hash = false, float wrap_width = -1.0f); From 94bf12f14b69393fa8f471fc90dcdd370fb91566 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 6 Dec 2017 22:20:08 +0100 Subject: [PATCH 660/921] Demo: Display better mouse cursor info for debugging backends. --- imgui.h | 2 +- imgui_demo.cpp | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/imgui.h b/imgui.h index 8929dea76..f8153c85a 100644 --- a/imgui.h +++ b/imgui.h @@ -738,7 +738,7 @@ enum ImGuiMouseCursor_ ImGuiMouseCursor_Move, // Unused ImGuiMouseCursor_ResizeNS, // Unused ImGuiMouseCursor_ResizeEW, // When hovering over a column - ImGuiMouseCursor_ResizeNESW, // Unused + ImGuiMouseCursor_ResizeNESW, // When hovering over the bottom-left corner of a window ImGuiMouseCursor_ResizeNWSE, // When hovering over the bottom-right corner of a window ImGuiMouseCursor_Count_ }; diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 6b0fed769..db3a163df 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1828,12 +1828,16 @@ void ImGui::ShowTestWindow(bool* p_open) if (ImGui::TreeNode("Mouse cursors")) { + const char* mouse_cursors_names[] = { "Arrow", "TextInput", "Move", "ResizeNS", "ResizeEW", "ResizeNESW", "ResizeNWSE" }; + IM_ASSERT(IM_ARRAYSIZE(mouse_cursors_names) == ImGuiMouseCursor_Count_); + + ImGui::Text("Current mouse cursor = %d: %s", ImGui::GetMouseCursor(), mouse_cursors_names[ImGui::GetMouseCursor()]); ImGui::Text("Hover to see mouse cursors:"); ImGui::SameLine(); ShowHelpMarker("Your application can render a different mouse cursor based on what ImGui::GetMouseCursor() returns. If software cursor rendering (io.MouseDrawCursor) is set ImGui will draw the right cursor for you, otherwise your backend needs to handle it."); for (int i = 0; i < ImGuiMouseCursor_Count_; i++) { char label[32]; - sprintf(label, "Mouse cursor %d", i); + sprintf(label, "Mouse cursor %d: %s", i, mouse_cursors_names[i]); ImGui::Bullet(); ImGui::Selectable(label, false); if (ImGui::IsItemHovered()) ImGui::SetMouseCursor(i); From abe5ad3c7a9fc2546642af7218285a95f59c4629 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 6 Dec 2017 23:38:33 +0100 Subject: [PATCH 661/921] Demo: Added display for IsMouseDragging() function. --- imgui_demo.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index db3a163df..95608aff8 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1810,6 +1810,8 @@ void ImGui::ShowTestWindow(bool* p_open) if (ImGui::TreeNode("Dragging")) { ImGui::TextWrapped("You can use ImGui::GetMouseDragDelta(0) to query for the dragged amount on any widget."); + for (int button = 0; button < 3; button++) + ImGui::Text("IsMouseDragging(%d) = %d", button, ImGui::IsMouseDragging(button)); ImGui::Button("Drag Me"); if (ImGui::IsItemActive()) { From 8959c64b335a73528fa939a16e197a40c2eeca82 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 7 Dec 2017 13:26:56 +0100 Subject: [PATCH 662/921] Internals: Cleanup FindBestPopupWindowPos() to be more digestible, since we are bounds to rework the logic there. No functional changes intended --- imgui.cpp | 37 ++++++++++++++++++++++++------------- imgui_internal.h | 5 +++-- 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 20a1b7a16..4d986dce5 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -656,7 +656,7 @@ static ImRect GetVisibleRect(); static void CloseInactivePopups(ImGuiWindow* ref_window); static void ClosePopupToLevel(int remaining); static ImGuiWindow* GetFrontMostModalRootWindow(); -static ImVec2 FindBestPopupWindowPos(const ImVec2& base_pos, const ImVec2& size, int* last_dir, const ImRect& rect_to_avoid); +static ImVec2 FindBestPopupWindowPos(const ImVec2& base_pos, const ImVec2& size, ImGuiDir* last_dir, const ImRect& rect_to_avoid); static bool InputTextFilterCharacter(unsigned int* p_char, ImGuiInputTextFlags flags, ImGuiTextEditCallback callback, void* user_data); static int InputTextCalcTextLenAndLineCount(const char* text_begin, const char** out_text_end); @@ -1845,7 +1845,7 @@ ImGuiWindow::ImGuiWindow(const char* name) AutoFitFramesX = AutoFitFramesY = -1; AutoFitOnlyGrows = false; AutoFitChildAxises = 0x00; - AutoPosLastDirection = -1; + AutoPosLastDirection = ImGuiDir_None; HiddenFrames = 0; SetWindowPosAllowFlags = SetWindowSizeAllowFlags = SetWindowCollapsedAllowFlags = ImGuiCond_Always | ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing; SetWindowPosVal = SetWindowPosPivot = ImVec2(FLT_MAX, FLT_MAX); @@ -4017,28 +4017,39 @@ static void CheckStacksSize(ImGuiWindow* window, bool write) IM_ASSERT(p_backup == window->DC.StackSizesBackup + IM_ARRAYSIZE(window->DC.StackSizesBackup)); } -static ImVec2 FindBestPopupWindowPos(const ImVec2& base_pos, const ImVec2& size, int* last_dir, const ImRect& r_inner) +static ImVec2 FindBestPopupWindowPos(const ImVec2& base_pos, const ImVec2& size, ImGuiDir* last_dir, const ImRect& r_avoid) { const ImGuiStyle& style = GImGui->Style; - // Clamp into visible area while not overlapping the cursor. Safety padding is optional if our popup size won't fit without it. + // r_avoid = the rectangle to avoid (e.g. for tooltip it is a rectangle around the mouse cursor which we want to avoid. for popups it's a small point around the cursor.) + // r_outer = the visible area rectangle, minus safe area padding. If our popup size won't fit because of safe area padding we ignore it. ImVec2 safe_padding = style.DisplaySafeAreaPadding; ImRect r_outer(GetVisibleRect()); r_outer.Expand(ImVec2((size.x - r_outer.GetWidth() > safe_padding.x*2) ? -safe_padding.x : 0.0f, (size.y - r_outer.GetHeight() > safe_padding.y*2) ? -safe_padding.y : 0.0f)); ImVec2 base_pos_clamped = ImClamp(base_pos, r_outer.Min, r_outer.Max - size); + //GImGui->OverlayDrawList.AddRect(r_avoid.Min, r_avoid.Max, IM_COL32(255,0,0,255)); + //GImGui->OverlayDrawList.AddRect(r_outer.Min, r_outer.Max, IM_COL32(0,255,0,255)); - for (int n = (*last_dir != -1) ? -1 : 0; n < 4; n++) // Last, Right, down, up, left. (Favor last used direction). + const ImGuiDir dir_prefered_order[ImGuiDir_Count_] = { ImGuiDir_Right, ImGuiDir_Down, ImGuiDir_Up, ImGuiDir_Left }; + for (int n = (*last_dir != ImGuiDir_None) ? -1 : 0; n < ImGuiDir_Count_; n++) { - const int dir = (n == -1) ? *last_dir : n; - ImRect rect(dir == 0 ? r_inner.Max.x : r_outer.Min.x, dir == 1 ? r_inner.Max.y : r_outer.Min.y, dir == 3 ? r_inner.Min.x : r_outer.Max.x, dir == 2 ? r_inner.Min.y : r_outer.Max.y); - if (rect.GetWidth() < size.x || rect.GetHeight() < size.y) + const ImGuiDir dir = (n == -1) ? *last_dir : dir_prefered_order[n]; + float avail_w = (dir == ImGuiDir_Left ? r_avoid.Min.x : r_outer.Max.x) - (dir == ImGuiDir_Right ? r_avoid.Max.x : r_outer.Min.x); + if (avail_w < size.x) continue; + float avail_h = (dir == ImGuiDir_Down ? r_avoid.Min.y : r_outer.Max.y) - (dir == ImGuiDir_Down ? r_avoid.Max.y : r_outer.Min.y); + if (avail_h < size.y) + continue; + + ImVec2 pos; + pos.x = (dir == ImGuiDir_Left) ? r_avoid.Min.x - size.x : (dir == ImGuiDir_Right) ? r_avoid.Max.x : base_pos_clamped.x; + pos.y = (dir == ImGuiDir_Up) ? r_avoid.Min.y - size.y : (dir == ImGuiDir_Down) ? r_avoid.Max.y : base_pos_clamped.y; *last_dir = dir; - return ImVec2(dir == 0 ? r_inner.Max.x : dir == 3 ? r_inner.Min.x - size.x : base_pos_clamped.x, dir == 1 ? r_inner.Max.y : dir == 2 ? r_inner.Min.y - size.y : base_pos_clamped.y); + return pos; } // Fallback, try to keep within display - *last_dir = -1; + *last_dir = ImGuiDir_None; ImVec2 pos = base_pos; pos.x = ImMax(ImMin(pos.x + size.x, r_outer.Max.x) - size.x, r_outer.Min.x); pos.y = ImMax(ImMin(pos.y + size.y, r_outer.Max.y) - size.y, r_outer.Min.y); @@ -4382,7 +4393,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) if (window_just_activated_by_user) { // Popup first latch mouse position, will position itself when it appears next frame - window->AutoPosLastDirection = -1; + window->AutoPosLastDirection = ImGuiDir_None; if ((flags & ImGuiWindowFlags_Popup) != 0 && !window_pos_set_by_api) window->PosFloat = g.IO.MousePos; } @@ -4523,9 +4534,9 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) if ((flags & ImGuiWindowFlags_Tooltip) != 0 && !window_pos_set_by_api) { ImVec2 ref_pos = g.IO.MousePos; - ImRect rect_to_avoid(ref_pos.x - 16, ref_pos.y - 8, ref_pos.x + 24, ref_pos.y + 24); // FIXME: Completely hard-coded. Perhaps center on cursor hit-point instead? + ImRect rect_to_avoid(ref_pos.x - 16, ref_pos.y - 8, ref_pos.x + 24, ref_pos.y + 24); // FIXME: Completely hard-coded. Store boxes in mouse cursor data? Scale? Center on cursor hit-point? window->PosFloat = FindBestPopupWindowPos(ref_pos, window->Size, &window->AutoPosLastDirection, rect_to_avoid); - if (window->AutoPosLastDirection == -1) + if (window->AutoPosLastDirection == ImGuiDir_None) window->PosFloat = ref_pos + ImVec2(2,2); // If there's not enough room, for tooltip we prefer avoiding the cursor at all cost even if it means that part of the tooltip won't be visible. } diff --git a/imgui_internal.h b/imgui_internal.h index 1483a5e72..3a2c6270d 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -248,7 +248,8 @@ enum ImGuiDir ImGuiDir_Left = 0, ImGuiDir_Right = 1, ImGuiDir_Up = 2, - ImGuiDir_Down = 3 + ImGuiDir_Down = 3, + ImGuiDir_Count_ }; // 2D axis aligned bounding-box @@ -726,7 +727,7 @@ struct IMGUI_API ImGuiWindow int AutoFitFramesX, AutoFitFramesY; bool AutoFitOnlyGrows; int AutoFitChildAxises; - int AutoPosLastDirection; + ImGuiDir AutoPosLastDirection; int HiddenFrames; ImGuiCond SetWindowPosAllowFlags; // store condition flags for next SetWindowPos() call. ImGuiCond SetWindowSizeAllowFlags; // store condition flags for next SetWindowSize() call. From 3c9f9a455e7d3e81cd42421dab837597d8e52911 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 7 Dec 2017 16:36:07 +0100 Subject: [PATCH 663/921] Internals: Cleanup FindBestPopupWindowPos() to be more digestible, since we are bounds to rework the logic there. No functional changes intended. FIXED TYPO. --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 4d986dce5..360f0f513 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4037,7 +4037,7 @@ static ImVec2 FindBestPopupWindowPos(const ImVec2& base_pos, const ImVec2& size, float avail_w = (dir == ImGuiDir_Left ? r_avoid.Min.x : r_outer.Max.x) - (dir == ImGuiDir_Right ? r_avoid.Max.x : r_outer.Min.x); if (avail_w < size.x) continue; - float avail_h = (dir == ImGuiDir_Down ? r_avoid.Min.y : r_outer.Max.y) - (dir == ImGuiDir_Down ? r_avoid.Max.y : r_outer.Min.y); + float avail_h = (dir == ImGuiDir_Up ? r_avoid.Min.y : r_outer.Max.y) - (dir == ImGuiDir_Down ? r_avoid.Max.y : r_outer.Min.y); if (avail_h < size.y) continue; From cc2c0238808eb626bf613e1a920bd9b9e5f83299 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 7 Dec 2017 17:04:39 +0100 Subject: [PATCH 664/921] Fixed scrollbar issue, followup to beda5fc5a0252b80ee16293afb80701807a33150 and 2df8fa95dfe3463ece78c56b02dc815c3e71331a. --- imgui.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 360f0f513..2ab52c7d9 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4447,28 +4447,29 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // Calculate auto-fit size, handle automatic resize const ImVec2 size_auto_fit = CalcSizeAutoFit(window); + ImVec2 size_for_scrollbars_visibility = window->SizeFullAtLastBegin; if (window->Collapsed) { // We still process initial auto-fit on collapsed windows to get a window width, // But otherwise we don't honor ImGuiWindowFlags_AlwaysAutoResize when collapsed. if (window->AutoFitFramesX > 0) - window->SizeFull.x = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.x, size_auto_fit.x) : size_auto_fit.x; + window->SizeFull.x = size_for_scrollbars_visibility.x = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.x, size_auto_fit.x) : size_auto_fit.x; if (window->AutoFitFramesY > 0) - window->SizeFull.y = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.y, size_auto_fit.y) : size_auto_fit.y; + window->SizeFull.y = size_for_scrollbars_visibility.y = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.y, size_auto_fit.y) : size_auto_fit.y; } else if (!window_size_set_by_api) { if (flags & ImGuiWindowFlags_AlwaysAutoResize) { - window->SizeFull = size_auto_fit; + window->SizeFull = size_for_scrollbars_visibility = size_auto_fit; } else if (window->AutoFitFramesX > 0 || window->AutoFitFramesY > 0) { // Auto-fit only grows during the first few frames if (window->AutoFitFramesX > 0) - window->SizeFull.x = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.x, size_auto_fit.x) : size_auto_fit.x; + window->SizeFull.x = size_for_scrollbars_visibility.x = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.x, size_auto_fit.x) : size_auto_fit.x; if (window->AutoFitFramesY > 0) - window->SizeFull.y = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.y, size_auto_fit.y) : size_auto_fit.y; + window->SizeFull.y = size_for_scrollbars_visibility.y = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.y, size_auto_fit.y) : size_auto_fit.y; MarkIniSettingsDirty(window); } } @@ -4487,10 +4488,10 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // Update scrollbar status (based on the Size that was effective during last frame or the auto-resized Size). if (!window->Collapsed) { - window->ScrollbarY = (flags & ImGuiWindowFlags_AlwaysVerticalScrollbar) || ((window->SizeContents.y > window->SizeFullAtLastBegin.y) && !(flags & ImGuiWindowFlags_NoScrollbar)); - window->ScrollbarX = (flags & ImGuiWindowFlags_AlwaysHorizontalScrollbar) || ((window->SizeContents.x > window->SizeFullAtLastBegin.x - (window->ScrollbarY ? style.ScrollbarSize : 0.0f) - window->WindowPadding.x) && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar)); + window->ScrollbarY = (flags & ImGuiWindowFlags_AlwaysVerticalScrollbar) || ((window->SizeContents.y > size_for_scrollbars_visibility.y) && !(flags & ImGuiWindowFlags_NoScrollbar)); + window->ScrollbarX = (flags & ImGuiWindowFlags_AlwaysHorizontalScrollbar) || ((window->SizeContents.x > size_for_scrollbars_visibility.x - (window->ScrollbarY ? style.ScrollbarSize : 0.0f) - window->WindowPadding.x) && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar)); if (window->ScrollbarX && !window->ScrollbarY) - window->ScrollbarY = (window->SizeContents.y > window->SizeFullAtLastBegin.y + style.ScrollbarSize) && !(flags & ImGuiWindowFlags_NoScrollbar); + window->ScrollbarY = (window->SizeContents.y > size_for_scrollbars_visibility.y + style.ScrollbarSize) && !(flags & ImGuiWindowFlags_NoScrollbar); window->ScrollbarSizes = ImVec2(window->ScrollbarY ? style.ScrollbarSize : 0.0f, window->ScrollbarX ? style.ScrollbarSize : 0.0f); } From 92f7bd3605dae216ee7aecf7f91c0d43b41ac358 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 7 Dec 2017 21:06:15 +0100 Subject: [PATCH 665/921] Fixed 64-bit warnings. --- imgui.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 2ab52c7d9..32e5563ee 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4615,7 +4615,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) ImRect resize_rect(corner, corner + grip.InnerDir * grip_hover_size); resize_rect.FixInverted(); bool hovered, held; - ButtonBehavior(resize_rect, window->GetID((void*)resize_grip_n), &hovered, &held, ImGuiButtonFlags_FlattenChilds); + ButtonBehavior(resize_rect, window->GetID((void*)(intptr_t)resize_grip_n), &hovered, &held, ImGuiButtonFlags_FlattenChilds); if (hovered || held) g.MouseCursor = (resize_grip_n & 1) ? ImGuiMouseCursor_ResizeNESW : ImGuiMouseCursor_ResizeNWSE; @@ -4641,7 +4641,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) const float BORDER_APPEAR_TIMER = 0.05f; // Reduce visual noise bool hovered, held; ImRect border_rect = GetBorderRect(window, border_n, grip_hover_size, BORDER_SIZE); - ButtonBehavior(border_rect, window->GetID((void*)(border_n+4)), &hovered, &held, ImGuiButtonFlags_FlattenChilds); + ButtonBehavior(border_rect, window->GetID((void*)(intptr_t)(border_n+4)), &hovered, &held, ImGuiButtonFlags_FlattenChilds); if ((hovered && g.HoveredIdTimer > BORDER_APPEAR_TIMER) || held) { g.MouseCursor = (border_n & 1) ? ImGuiMouseCursor_ResizeEW : ImGuiMouseCursor_ResizeNS; From e045eddd776e30b997d7a493b444e51f1821ec1e Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 7 Dec 2017 17:11:51 +0100 Subject: [PATCH 666/921] Minor tweaks. Using ImGuiAxis defines. --- imgui.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 32e5563ee..913a26eb1 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3633,7 +3633,7 @@ void ImGui::BeginTooltipEx(ImGuiWindowFlags extra_flags, bool override_previous_ char window_name[16]; ImFormatString(window_name, IM_ARRAYSIZE(window_name), "##Tooltip%02d", g.TooltipOverrideCount); if (override_previous_tooltip) - if (ImGuiWindow* window = ImGui::FindWindowByName(window_name)) + if (ImGuiWindow* window = FindWindowByName(window_name)) if (window->Active) { // Hide previous tooltips. We can't easily "reset" the content of a window so we create a new one. @@ -3641,7 +3641,7 @@ void ImGui::BeginTooltipEx(ImGuiWindowFlags extra_flags, bool override_previous_ ImFormatString(window_name, IM_ARRAYSIZE(window_name), "##Tooltip%02d", ++g.TooltipOverrideCount); } ImGuiWindowFlags flags = ImGuiWindowFlags_Tooltip|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_AlwaysAutoResize; - ImGui::Begin(window_name, NULL, flags | extra_flags); + Begin(window_name, NULL, flags | extra_flags); } void ImGui::SetTooltipV(const char* fmt, va_list args) @@ -3920,7 +3920,7 @@ static bool BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, b const ImVec2 content_avail = ImGui::GetContentRegionAvail(); ImVec2 size = ImFloor(size_arg); - const int auto_fit_axises = ((size.x == 0.0f) ? 0x01 : 0x00) | ((size.y == 0.0f) ? 0x02 : 0x00); + const int auto_fit_axises = ((size.x == 0.0f) ? (1 << ImGuiAxis_X) : 0x00) | ((size.y == 0.0f) ? (1 << ImGuiAxis_Y) : 0x00); if (size.x <= 0.0f) size.x = ImMax(content_avail.x, 4.0f) - fabsf(size.x); // Arbitrary minimum zero-ish child size of 4.0f (0.0f causing too much issues) if (size.y <= 0.0f) @@ -3970,9 +3970,9 @@ void ImGui::EndChild() { // When using auto-filling child window, we don't provide full width/height to ItemSize so that it doesn't feed back into automatic size-fitting. ImVec2 sz = GetWindowSize(); - if (window->AutoFitChildAxises & 0x01) // Arbitrary minimum zero-ish child size of 4.0f causes less trouble than a 0.0f + if (window->AutoFitChildAxises & (1 << ImGuiAxis_X)) // Arbitrary minimum zero-ish child size of 4.0f causes less trouble than a 0.0f sz.x = ImMax(4.0f, sz.x); - if (window->AutoFitChildAxises & 0x02) + if (window->AutoFitChildAxises & (1 << ImGuiAxis_Y)) sz.y = ImMax(4.0f, sz.y); ImGui::End(); From 8dcc1a8a209b9151e7a4003d01e02cf54ee9eb6d Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 7 Dec 2017 18:07:42 +0100 Subject: [PATCH 667/921] Begin: Sizing fixes regarding uses SetNextWindowSize() on individual axises. --- imgui.cpp | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 913a26eb1..e112136b5 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4317,7 +4317,8 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) } // Process SetNextWindow***() calls - bool window_pos_set_by_api = false, window_size_set_by_api = false; + bool window_pos_set_by_api = false; + bool window_size_x_set_by_api = false, window_size_y_set_by_api = false; if (g.SetNextWindowPosCond) { window_pos_set_by_api = (window->SetWindowPosAllowFlags & g.SetNextWindowPosCond) != 0; @@ -4337,7 +4338,8 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) } if (g.SetNextWindowSizeCond) { - window_size_set_by_api = (window->SetWindowSizeAllowFlags & g.SetNextWindowSizeCond) != 0; + window_size_x_set_by_api = (window->SetWindowSizeAllowFlags & g.SetNextWindowSizeCond) != 0 && (g.SetNextWindowSizeVal.x > 0.0f); + window_size_y_set_by_api = (window->SetWindowSizeAllowFlags & g.SetNextWindowSizeCond) != 0 && (g.SetNextWindowSizeVal.y > 0.0f); SetWindowSize(window, g.SetNextWindowSizeVal, g.SetNextWindowSizeCond); g.SetNextWindowSizeCond = 0; } @@ -4422,7 +4424,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->SizeContents.y = (float)(int)((window->SizeContentsExplicit.y != 0.0f) ? window->SizeContentsExplicit.y : ((window_is_new ? 0.0f : window->DC.CursorMaxPos.y - window->Pos.y) + window->Scroll.y)); window->SizeContents += window->WindowPadding; - // Hide popup/tooltip window when first appearing while we measure size (because we recycle them) + // Hide popup/tooltip window when re-opening while we measure size (because we recycle the windows) if (window->HiddenFrames > 0) window->HiddenFrames--; if ((flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_Tooltip)) != 0 && window_just_activated_by_user) @@ -4430,8 +4432,10 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->HiddenFrames = 1; if (flags & ImGuiWindowFlags_AlwaysAutoResize) { - if (!window_size_set_by_api) - window->Size = window->SizeFull = ImVec2(0.f, 0.f); + if (!window_size_x_set_by_api) + window->Size.x = window->SizeFull.x = 0.f; + if (!window_size_y_set_by_api) + window->Size.y = window->SizeFull.y = 0.f; window->SizeContents = ImVec2(0.f, 0.f); } } @@ -4457,18 +4461,22 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) if (window->AutoFitFramesY > 0) window->SizeFull.y = size_for_scrollbars_visibility.y = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.y, size_auto_fit.y) : size_auto_fit.y; } - else if (!window_size_set_by_api) + else { + // Using SetNextWindowSize() overrides ImGuiWindowFlags_AlwaysAutoResize, so it can be used on tooltips/popups, etc. if (flags & ImGuiWindowFlags_AlwaysAutoResize) { - window->SizeFull = size_for_scrollbars_visibility = size_auto_fit; + if (!window_size_x_set_by_api) + window->SizeFull.x = size_for_scrollbars_visibility.x = size_auto_fit.x; + if (!window_size_y_set_by_api) + window->SizeFull.y = size_for_scrollbars_visibility.y = size_auto_fit.y; } else if (window->AutoFitFramesX > 0 || window->AutoFitFramesY > 0) { // Auto-fit only grows during the first few frames - if (window->AutoFitFramesX > 0) + if (!window_size_x_set_by_api && window->AutoFitFramesX > 0) window->SizeFull.x = size_for_scrollbars_visibility.x = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.x, size_auto_fit.x) : size_auto_fit.x; - if (window->AutoFitFramesY > 0) + if (!window_size_y_set_by_api && window->AutoFitFramesY > 0) window->SizeFull.y = size_for_scrollbars_visibility.y = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.y, size_auto_fit.y) : size_auto_fit.y; MarkIniSettingsDirty(window); } @@ -4479,7 +4487,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->Size = window->Collapsed ? window->TitleBarRect().GetSize() : window->SizeFull; if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Popup)) { - IM_ASSERT(window_size_set_by_api); // Submitted by BeginChild() + IM_ASSERT(window_size_x_set_by_api && window_size_x_set_by_api); // Submitted by BeginChild() window->Size = window->SizeFull; } From 7f2b9ea4c0fcbb2f9c2d14150441a4187c0c1c71 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 7 Dec 2017 18:10:37 +0100 Subject: [PATCH 668/921] Begin: Minor refactor following fcf652f8ee7267055e331bf7a0133ed477816f27. Merging the if (Collapsed) block with the main one. --- imgui.cpp | 40 +++++++++++++++------------------------- 1 file changed, 15 insertions(+), 25 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index e112136b5..fa352ba5f 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4452,34 +4452,24 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // Calculate auto-fit size, handle automatic resize const ImVec2 size_auto_fit = CalcSizeAutoFit(window); ImVec2 size_for_scrollbars_visibility = window->SizeFullAtLastBegin; - if (window->Collapsed) - { - // We still process initial auto-fit on collapsed windows to get a window width, - // But otherwise we don't honor ImGuiWindowFlags_AlwaysAutoResize when collapsed. - if (window->AutoFitFramesX > 0) - window->SizeFull.x = size_for_scrollbars_visibility.x = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.x, size_auto_fit.x) : size_auto_fit.x; - if (window->AutoFitFramesY > 0) - window->SizeFull.y = size_for_scrollbars_visibility.y = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.y, size_auto_fit.y) : size_auto_fit.y; - } - else + if (flags & ImGuiWindowFlags_AlwaysAutoResize && !window->Collapsed) { // Using SetNextWindowSize() overrides ImGuiWindowFlags_AlwaysAutoResize, so it can be used on tooltips/popups, etc. - if (flags & ImGuiWindowFlags_AlwaysAutoResize) - { - if (!window_size_x_set_by_api) - window->SizeFull.x = size_for_scrollbars_visibility.x = size_auto_fit.x; - if (!window_size_y_set_by_api) - window->SizeFull.y = size_for_scrollbars_visibility.y = size_auto_fit.y; - } - else if (window->AutoFitFramesX > 0 || window->AutoFitFramesY > 0) - { - // Auto-fit only grows during the first few frames - if (!window_size_x_set_by_api && window->AutoFitFramesX > 0) - window->SizeFull.x = size_for_scrollbars_visibility.x = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.x, size_auto_fit.x) : size_auto_fit.x; - if (!window_size_y_set_by_api && window->AutoFitFramesY > 0) - window->SizeFull.y = size_for_scrollbars_visibility.y = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.y, size_auto_fit.y) : size_auto_fit.y; + if (!window_size_x_set_by_api) + window->SizeFull.x = size_for_scrollbars_visibility.x = size_auto_fit.x; + if (!window_size_y_set_by_api) + window->SizeFull.y = size_for_scrollbars_visibility.y = size_auto_fit.y; + } + else if (window->AutoFitFramesX > 0 || window->AutoFitFramesY > 0) + { + // Auto-fit only grows during the first few frames + // We still process initial auto-fit on collapsed windows to get a window width, but otherwise don't honor ImGuiWindowFlags_AlwaysAutoResize ImGuiWindowFlags_AlwaysAutoResize. + if (!window_size_x_set_by_api && window->AutoFitFramesX > 0) + window->SizeFull.x = size_for_scrollbars_visibility.x = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.x, size_auto_fit.x) : size_auto_fit.x; + if (!window_size_y_set_by_api && window->AutoFitFramesY > 0) + window->SizeFull.y = size_for_scrollbars_visibility.y = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.y, size_auto_fit.y) : size_auto_fit.y; + if (!window->Collapsed) MarkIniSettingsDirty(window); - } } // Apply minimum/maximum window size constraints and final size From 97edd42fc040c68cc8985b93b99408e2783b27a0 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 7 Dec 2017 18:51:48 +0100 Subject: [PATCH 669/921] Indent(), Unindent(): Allow passing negative values. --- imgui.cpp | 4 ++-- imgui.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index fa352ba5f..3ff7d5abe 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -10892,7 +10892,7 @@ void ImGui::Indent(float indent_w) { ImGuiContext& g = *GImGui; ImGuiWindow* window = GetCurrentWindow(); - window->DC.IndentX += (indent_w > 0.0f) ? indent_w : g.Style.IndentSpacing; + window->DC.IndentX += (indent_w != 0.0f) ? indent_w : g.Style.IndentSpacing; window->DC.CursorPos.x = window->Pos.x + window->DC.IndentX + window->DC.ColumnsOffsetX; } @@ -10900,7 +10900,7 @@ void ImGui::Unindent(float indent_w) { ImGuiContext& g = *GImGui; ImGuiWindow* window = GetCurrentWindow(); - window->DC.IndentX -= (indent_w > 0.0f) ? indent_w : g.Style.IndentSpacing; + window->DC.IndentX -= (indent_w != 0.0f) ? indent_w : g.Style.IndentSpacing; window->DC.CursorPos.x = window->Pos.x + window->DC.IndentX + window->DC.ColumnsOffsetX; } diff --git a/imgui.h b/imgui.h index f8153c85a..ae31f051c 100644 --- a/imgui.h +++ b/imgui.h @@ -218,8 +218,8 @@ namespace ImGui IMGUI_API void NewLine(); // undo a SameLine() IMGUI_API void Spacing(); // add vertical spacing IMGUI_API void Dummy(const ImVec2& size); // add a dummy item of given size - IMGUI_API void Indent(float indent_w = 0.0f); // move content position toward the right, by style.IndentSpacing or indent_w if >0 - IMGUI_API void Unindent(float indent_w = 0.0f); // move content position back to the left, by style.IndentSpacing or indent_w if >0 + IMGUI_API void Indent(float indent_w = 0.0f); // move content position toward the right, by style.IndentSpacing or indent_w if != 0 + IMGUI_API void Unindent(float indent_w = 0.0f); // move content position back to the left, by style.IndentSpacing or indent_w if != 0 IMGUI_API void BeginGroup(); // lock horizontal starting position + capture group bounding box into one "item" (so you can use IsItemHovered() or layout primitives such as SameLine() on whole group, etc.) IMGUI_API void EndGroup(); IMGUI_API ImVec2 GetCursorPos(); // cursor position is relative to window position From 45466a8cf99c16a7b9493da0b835a5e09e97a850 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 7 Dec 2017 20:14:24 +0100 Subject: [PATCH 670/921] Internals: BeginCombo() added dummy ImGuiComboFlags. --- imgui.cpp | 5 +++-- imgui_internal.h | 7 ++++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 3ff7d5abe..33e03ac54 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9071,8 +9071,9 @@ bool ImGui::Combo(const char* label, int* current_item, const char* items_separa return value_changed; } -bool ImGui::BeginCombo(const char* label, const char* preview_value, ImVec2 popup_size) +bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboFlags flags, ImVec2 popup_size) { + (void)flags; // Unused ImGuiWindow* window = GetCurrentWindow(); if (window->SkipItems) return false; @@ -9167,7 +9168,7 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi height_in_items = 7; float popup_height = (g.FontSize + style.ItemSpacing.y) * ImMin(items_count, height_in_items) + (style.FramePadding.y * 3); - if (!BeginCombo(label, preview_text, ImVec2(0.0f, popup_height))) + if (!BeginCombo(label, preview_text, 0, ImVec2(0.0f, popup_height))) return false; // Display items diff --git a/imgui_internal.h b/imgui_internal.h index 3a2c6270d..d796c066f 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -48,6 +48,7 @@ typedef int ImGuiButtonFlags; // flags: for ButtonEx(), ButtonBehavior() typedef int ImGuiItemFlags; // flags: for PushItemFlag() // enum ImGuiItemFlags_ typedef int ImGuiSeparatorFlags; // flags: for Separator() - internal // enum ImGuiSeparatorFlags_ typedef int ImGuiSliderFlags; // flags: for SliderBehavior() // enum ImGuiSliderFlags_ +typedef int ImGuiComboFlags; // flags: for BeginCombo() // enum ImGuiComboFlags_ //------------------------------------------------------------------------- // STB libraries @@ -209,6 +210,10 @@ enum ImGuiSelectableFlagsPrivate_ ImGuiSelectableFlags_DrawFillAvailWidth = 1 << 6 }; +enum ImGuiComboFlags_ +{ +}; + enum ImGuiSeparatorFlags_ { ImGuiSeparatorFlags_Horizontal = 1 << 0, // Axis default to current layout type, so generally Horizontal unless e.g. in a menu bar @@ -847,7 +852,7 @@ namespace ImGui IMGUI_API void PushColumnClipRect(int column_index = -1); // FIXME-WIP: New Combo API - IMGUI_API bool BeginCombo(const char* label, const char* preview_value, ImVec2 popup_size = ImVec2(0.0f,0.0f)); + IMGUI_API bool BeginCombo(const char* label, const char* preview_value, ImGuiComboFlags flags = 0, ImVec2 popup_size = ImVec2(0.0f,0.0f)); IMGUI_API void EndCombo(); // NB: All position are in absolute pixels coordinates (never using window coordinates internally) From f658edc72a2029b9a0524cc0eae2550b8a826cc5 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 7 Dec 2017 20:47:00 +0100 Subject: [PATCH 671/921] Begin: Remove unnecessary usage of window_is_new flag, as both fields are zero on window creation. --- imgui.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 33e03ac54..cfdb6b004 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4270,13 +4270,11 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) flags |= ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize; // Find or create - bool window_is_new = false; ImGuiWindow* window = FindWindowByName(name); if (!window) { ImVec2 size_on_first_use = (g.SetNextWindowSizeCond != 0) ? g.SetNextWindowSizeVal : ImVec2(0.0f, 0.0f); // Any condition flag will do since we are creating a new window here. window = CreateNewWindow(name, size_on_first_use, flags); - window_is_new = true; } const int current_frame = g.FrameCount; @@ -4420,8 +4418,8 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // SIZE // Update contents size from last frame for auto-fitting (unless explicitly specified) - window->SizeContents.x = (float)(int)((window->SizeContentsExplicit.x != 0.0f) ? window->SizeContentsExplicit.x : ((window_is_new ? 0.0f : window->DC.CursorMaxPos.x - window->Pos.x) + window->Scroll.x)); - window->SizeContents.y = (float)(int)((window->SizeContentsExplicit.y != 0.0f) ? window->SizeContentsExplicit.y : ((window_is_new ? 0.0f : window->DC.CursorMaxPos.y - window->Pos.y) + window->Scroll.y)); + window->SizeContents.x = (float)(int)((window->SizeContentsExplicit.x != 0.0f) ? window->SizeContentsExplicit.x : (window->DC.CursorMaxPos.x - window->Pos.x + window->Scroll.x)); + window->SizeContents.y = (float)(int)((window->SizeContentsExplicit.y != 0.0f) ? window->SizeContentsExplicit.y : (window->DC.CursorMaxPos.y - window->Pos.y + window->Scroll.y)); window->SizeContents += window->WindowPadding; // Hide popup/tooltip window when re-opening while we measure size (because we recycle the windows) From ca0bb000ad5c400e13509e1d3a6a6e4fe8e23e53 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 7 Dec 2017 20:47:57 +0100 Subject: [PATCH 672/921] Begin: Factored out a bit of code to CalcSizeContents() --- imgui.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index cfdb6b004..367aa754e 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4149,6 +4149,14 @@ static ImVec2 CalcSizeFullWithConstraint(ImGuiWindow* window, ImVec2 new_size) return new_size; } +static ImVec2 CalcSizeContents(ImGuiWindow* window) +{ + ImVec2 sz; + sz.x = (float)(int)((window->SizeContentsExplicit.x != 0.0f) ? window->SizeContentsExplicit.x : (window->DC.CursorMaxPos.x - window->Pos.x + window->Scroll.x)); + sz.y = (float)(int)((window->SizeContentsExplicit.y != 0.0f) ? window->SizeContentsExplicit.y : (window->DC.CursorMaxPos.y - window->Pos.y + window->Scroll.y)); + return sz + window->WindowPadding; +} + static ImVec2 CalcSizeAutoFit(ImGuiWindow* window) { ImGuiContext& g = *GImGui; @@ -4418,9 +4426,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // SIZE // Update contents size from last frame for auto-fitting (unless explicitly specified) - window->SizeContents.x = (float)(int)((window->SizeContentsExplicit.x != 0.0f) ? window->SizeContentsExplicit.x : (window->DC.CursorMaxPos.x - window->Pos.x + window->Scroll.x)); - window->SizeContents.y = (float)(int)((window->SizeContentsExplicit.y != 0.0f) ? window->SizeContentsExplicit.y : (window->DC.CursorMaxPos.y - window->Pos.y + window->Scroll.y)); - window->SizeContents += window->WindowPadding; + window->SizeContents = CalcSizeContents(window); // Hide popup/tooltip window when re-opening while we measure size (because we recycle the windows) if (window->HiddenFrames > 0) From e118239f6909527f5fb1fa7ef83c2c5ba1e8f132 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 8 Dec 2017 09:34:05 +0100 Subject: [PATCH 673/921] IsItemHovered() comments (#1382) --- imgui.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 367aa754e..2e1df2fed 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2026,26 +2026,35 @@ bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id) bool ImGui::IsItemHovered(ImGuiHoveredFlags flags) { ImGuiContext& g = *GImGui; - ImGuiWindow* window = g.CurrentWindow; + + // Test for bounding box overlap, as updated as ItemAdd() if (!window->DC.LastItemRectHoveredRect) return false; IM_ASSERT((flags & ImGuiHoveredFlags_FlattenChilds) == 0); // Flags not supported by this function + // Test if we are hovering the right window (our window could be behind another window) // [2017/10/16] Reverted commit 344d48be3 and testing RootWindow instead. I believe it is correct to NOT test for RootWindow but this leaves us unable to use IsItemHovered() after EndChild() itself. // Until a solution is found I believe reverting to the test from 2017/09/27 is safe since this was the test that has been running for a long while. //if (g.HoveredWindow != window) // return false; if (g.HoveredRootWindow != window->RootWindow && !(flags & ImGuiHoveredFlags_AllowWhenOverlapped)) return false; + + // Test if another item is active (e.g. being dragged) if (!(flags & ImGuiHoveredFlags_AllowWhenBlockedByActiveItem)) if (g.ActiveId != 0 && g.ActiveId != window->DC.LastItemId && !g.ActiveIdAllowOverlap && g.ActiveId != window->MoveId) return false; + + // Test if interactions on this window are blocked by an active popup or modal if (!IsWindowContentHoverable(window, flags)) return false; + + // Test if the item is disabled if (window->DC.ItemFlags & ImGuiItemFlags_Disabled) return false; - // Special handling for the 1st item after Begin() which represent the title bar. When the window is collapsed (SkipItems==true) that last item will never be overwritten. + + // Special handling for the 1st item after Begin() which represent the title bar. When the window is collapsed (SkipItems==true) that last item will never be overwritten so we need to detect tht case. if (window->DC.LastItemId == window->MoveId && window->WriteAccessed) return false; return true; From 7bf85db6c451163133a1197457a7a1dd7ff6fbdb Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 8 Dec 2017 12:48:53 +0100 Subject: [PATCH 674/921] Drag and drop: Added COL3F payload for color without alpha overwrite. Exposed standard color payload types in imgui.h (#143) --- imgui.cpp | 13 ++++++++++--- imgui.h | 4 ++++ imgui_internal.h | 3 +-- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 950addd73..c64a83393 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9677,7 +9677,10 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl if (g.ActiveId == id && BeginDragDropSource()) // NB: The ActiveId test is merely an optional micro-optimization { - SetDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_4F, &col, sizeof(col), ImGuiCond_Once); + if (flags & ImGuiColorEditFlags_NoAlpha) + SetDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_3F, &col, sizeof(float) * 3, ImGuiCond_Once); + else + SetDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_4F, &col, sizeof(float) * 4, ImGuiCond_Once); ColorButton(desc_id, col, flags); SameLine(); TextUnformatted("Color"); @@ -9963,10 +9966,14 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag if (window->DC.LastItemRectHoveredRect && BeginDragDropTarget()) // NB: The LastItemRectHoveredRect test is merely an optional micro-optimization { + if (const ImGuiPayload* payload = AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_3F)) + { + memcpy((float*)col, payload->Data, sizeof(float) * 3); + value_changed = true; + } if (const ImGuiPayload* payload = AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_4F)) { - IM_ASSERT(payload->DataSize == sizeof(ImVec4)); - memcpy((float*)col, payload->Data, sizeof(ImVec4)); + memcpy((float*)col, payload->Data, sizeof(float) * components); value_changed = true; } EndDragDropTarget(); diff --git a/imgui.h b/imgui.h index 0bc003109..294f66951 100644 --- a/imgui.h +++ b/imgui.h @@ -610,6 +610,10 @@ enum ImGuiDragDropFlags_ ImGuiDragDropFlags_AcceptPeekOnly = ImGuiDragDropFlags_AcceptBeforeDelivery | ImGuiDragDropFlags_AcceptNoDrawDefaultRect // For peeking ahead and inspecting the payload before delivery. }; +// Standard Drag and Drop payload types. Types starting with '_' are defined by Dear ImGui. +#define IMGUI_PAYLOAD_TYPE_COLOR_3F "_COL3F" // float[3] // Standard type for colors, without alpha. User code may use this type. +#define IMGUI_PAYLOAD_TYPE_COLOR_4F "_COL4F" // float[4] // Standard type for colors. User code may use this type. + // User fill ImGuiIO.KeyMap[] array with indices into the ImGuiIO.KeysDown[512] array enum ImGuiKey_ { diff --git a/imgui_internal.h b/imgui_internal.h index 92d98876b..1bf610843 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -169,8 +169,7 @@ inline void operator delete(void*, ImPlacementNewDummy, void*) {} // Types //----------------------------------------------------------------------------- -// Drag and Drop payload types. String starting with '_' are managed by Dear ImGui. -#define IMGUI_PAYLOAD_TYPE_COLOR_4F "_COL4F" // float[4] // Standard type for colors. User code may use this type. Build a float[4] out of a float[3] if you don't have alpha. +// Internal Drag and Drop payload types. String starting with '_' are reserved for Dear ImGui. #define IMGUI_PAYLOAD_TYPE_DOCKABLE "_IMDOCK" // ImGuiWindow* // [Internal] Docking/tabs enum ImGuiButtonFlags_ From a4863e8084e4b80a38e2b76a9dd724c971ee5e7d Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 8 Dec 2017 12:49:35 +0100 Subject: [PATCH 675/921] Demo: Picker with palette demo supports drag and drop. (#143, #346) --- imgui_demo.cpp | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 6b0fed769..c74df6009 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -775,12 +775,19 @@ void ImGui::ShowTestWindow(bool* p_open) ImGui::ColorEdit4("MyColor##3", (float*)&color, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel | misc_flags); ImGui::Text("Color button with Custom Picker Popup:"); + + // Generate a dummy palette static bool saved_palette_inited = false; static ImVec4 saved_palette[32]; - static ImVec4 backup_color; if (!saved_palette_inited) for (int n = 0; n < IM_ARRAYSIZE(saved_palette); n++) + { ImGui::ColorConvertHSVtoRGB(n / 31.0f, 0.8f, 0.8f, saved_palette[n].x, saved_palette[n].y, saved_palette[n].z); + saved_palette[n].w = 1.0f; // Alpha + } + saved_palette_inited = true; + + static ImVec4 backup_color; bool open_popup = ImGui::ColorButton("MyColor##3b", color, misc_flags); ImGui::SameLine(); open_popup |= ImGui::Button("Palette"); @@ -809,8 +816,18 @@ void ImGui::ShowTestWindow(bool* p_open) ImGui::PushID(n); if ((n % 8) != 0) ImGui::SameLine(0.0f, ImGui::GetStyle().ItemSpacing.y); - if (ImGui::ColorButton("##palette", saved_palette[n], ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_NoTooltip, ImVec2(20,20))) + if (ImGui::ColorButton("##palette", saved_palette[n], ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_NoTooltip, ImVec2(20,20))) color = ImVec4(saved_palette[n].x, saved_palette[n].y, saved_palette[n].z, color.w); // Preserve alpha! + + if (ImGui::BeginDragDropTarget()) + { + if (const ImGuiPayload* payload = AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_3F)) + memcpy((float*)&saved_palette[n], payload->Data, sizeof(float) * 3); + if (const ImGuiPayload* payload = AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_4F)) + memcpy((float*)&saved_palette[n], payload->Data, sizeof(float) * 4); + EndDragDropTarget(); + } + ImGui::PopID(); } ImGui::EndGroup(); From 9872297a84bcbca7f5bb872b71a0f38cb599edd6 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 7 Dec 2017 22:22:53 +0100 Subject: [PATCH 676/921] Internals: Renamed FindBestPopupWindowPos() to FindBestWindowPosForPopup() --- imgui.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 2e1df2fed..8da6ff20d 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -656,7 +656,7 @@ static ImRect GetVisibleRect(); static void CloseInactivePopups(ImGuiWindow* ref_window); static void ClosePopupToLevel(int remaining); static ImGuiWindow* GetFrontMostModalRootWindow(); -static ImVec2 FindBestPopupWindowPos(const ImVec2& base_pos, const ImVec2& size, ImGuiDir* last_dir, const ImRect& rect_to_avoid); +static ImVec2 FindBestWindowPosForPopup(const ImVec2& base_pos, const ImVec2& size, ImGuiDir* last_dir, const ImRect& rect_to_avoid); static bool InputTextFilterCharacter(unsigned int* p_char, ImGuiInputTextFlags flags, ImGuiTextEditCallback callback, void* user_data); static int InputTextCalcTextLenAndLineCount(const char* text_begin, const char** out_text_end); @@ -4026,7 +4026,7 @@ static void CheckStacksSize(ImGuiWindow* window, bool write) IM_ASSERT(p_backup == window->DC.StackSizesBackup + IM_ARRAYSIZE(window->DC.StackSizesBackup)); } -static ImVec2 FindBestPopupWindowPos(const ImVec2& base_pos, const ImVec2& size, ImGuiDir* last_dir, const ImRect& r_avoid) +static ImVec2 FindBestWindowPosForPopup(const ImVec2& base_pos, const ImVec2& size, ImGuiDir* last_dir, const ImRect& r_avoid) { const ImGuiStyle& style = GImGui->Style; @@ -4150,6 +4150,8 @@ static ImVec2 CalcSizeFullWithConstraint(ImGuiWindow* window, ImVec2 new_size) new_size = data.DesiredSize; } } + + // Minimum size if (!(window->Flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_AlwaysAutoResize))) { new_size = ImMax(new_size, g.Style.WindowMinSize); @@ -4534,12 +4536,12 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) rect_to_avoid = ImRect(-FLT_MAX, parent_window->Pos.y + parent_window->TitleBarHeight(), FLT_MAX, parent_window->Pos.y + parent_window->TitleBarHeight() + parent_window->MenuBarHeight()); else rect_to_avoid = ImRect(parent_window->Pos.x + horizontal_overlap, -FLT_MAX, parent_window->Pos.x + parent_window->Size.x - horizontal_overlap - parent_window->ScrollbarSizes.x, FLT_MAX); - window->PosFloat = FindBestPopupWindowPos(window->PosFloat, window->Size, &window->AutoPosLastDirection, rect_to_avoid); + window->PosFloat = FindBestWindowPosForPopup(window->PosFloat, window->Size, &window->AutoPosLastDirection, rect_to_avoid); } else if ((flags & ImGuiWindowFlags_Popup) != 0 && !window_pos_set_by_api && window_just_appearing_after_hidden_for_resize) { ImRect rect_to_avoid(window->PosFloat.x - 1, window->PosFloat.y - 1, window->PosFloat.x + 1, window->PosFloat.y + 1); - window->PosFloat = FindBestPopupWindowPos(window->PosFloat, window->Size, &window->AutoPosLastDirection, rect_to_avoid); + window->PosFloat = FindBestWindowPosForPopup(window->PosFloat, window->Size, &window->AutoPosLastDirection, rect_to_avoid); } // Position tooltip (always follows mouse) @@ -4547,7 +4549,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) { ImVec2 ref_pos = g.IO.MousePos; ImRect rect_to_avoid(ref_pos.x - 16, ref_pos.y - 8, ref_pos.x + 24, ref_pos.y + 24); // FIXME: Completely hard-coded. Store boxes in mouse cursor data? Scale? Center on cursor hit-point? - window->PosFloat = FindBestPopupWindowPos(ref_pos, window->Size, &window->AutoPosLastDirection, rect_to_avoid); + window->PosFloat = FindBestWindowPosForPopup(ref_pos, window->Size, &window->AutoPosLastDirection, rect_to_avoid); if (window->AutoPosLastDirection == ImGuiDir_None) window->PosFloat = ref_pos + ImVec2(2,2); // If there's not enough room, for tooltip we prefer avoiding the cursor at all cost even if it means that part of the tooltip won't be visible. } From 541dfd790168e235d70b81136fd61b794168cc31 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 7 Dec 2017 22:23:27 +0100 Subject: [PATCH 677/921] Combo: Comments + fixed missing lower window padding. --- imgui.cpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 8da6ff20d..cee33f500 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9135,11 +9135,12 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboF if (popup_size.x == 0.0f) popup_size.x = w; + // FIXME: Start using shared helpers or handle in Begin(). We have similar code in Begin() calling FindBestWindowPosForPopup() float popup_y1 = frame_bb.Max.y; float popup_y2 = ImClamp(popup_y1 + popup_size.y, popup_y1, g.IO.DisplaySize.y - style.DisplaySafeAreaPadding.y); if ((popup_y2 - popup_y1) < ImMin(popup_size.y, frame_bb.Min.y - style.DisplaySafeAreaPadding.y)) { - // Position our combo ABOVE because there's more space to fit! (FIXME: Handle in Begin() or use a shared helper. We have similar code in Begin() for popup placement) + // Position our combo ABOVE because there's more space to fit! popup_y1 = ImClamp(frame_bb.Min.y - popup_size.y, style.DisplaySafeAreaPadding.y, frame_bb.Min.y); popup_y2 = frame_bb.Min.y; SetNextWindowPos(ImVec2(frame_bb.Min.x, frame_bb.Min.y + style.FrameBorderSize), ImGuiCond_Always, ImVec2(0.0f, 1.0f)); @@ -9150,22 +9151,26 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboF SetNextWindowPos(ImVec2(frame_bb.Min.x, frame_bb.Max.y - style.FrameBorderSize), ImGuiCond_Always, ImVec2(0.0f, 0.0f)); } SetNextWindowSize(ImVec2(popup_size.x, popup_y2 - popup_y1), ImGuiCond_Appearing); - PushStyleVar(ImGuiStyleVar_WindowPadding, style.FramePadding); if (!BeginPopupEx(id, ImGuiWindowFlags_ComboBox)) { IM_ASSERT(0); // This should never happen as we tested for IsPopupOpen() above return false; } - Spacing(); + + // Horizontally align ourselves with the framed text + if (style.FramePadding.x != style.WindowPadding.x) + Indent(style.FramePadding.x - style.WindowPadding.x); return true; } void ImGui::EndCombo() { + const ImGuiStyle& style = GImGui->Style; + if (style.FramePadding.x != style.WindowPadding.x) + Unindent(style.FramePadding.x - style.WindowPadding.x); EndPopup(); - PopStyleVar(); } // Combo box function. @@ -9181,7 +9186,7 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi // Size default to hold ~7 items if (height_in_items < 0) height_in_items = 7; - float popup_height = (g.FontSize + style.ItemSpacing.y) * ImMin(items_count, height_in_items) + (style.FramePadding.y * 3); + float popup_height = (g.FontSize + style.ItemSpacing.y) * ImMin(items_count, height_in_items) - style.ItemSpacing.y + (style.WindowPadding.y * 2); if (!BeginCombo(label, preview_text, 0, ImVec2(0.0f, popup_height))) return false; From 74f42baf3ebb89b9be08593bb27123e0a80328a3 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 8 Dec 2017 11:48:18 +0100 Subject: [PATCH 678/921] Fixed scrollbar issue, source size when explicit was read before applying custom size constraints (followup to cc2c0238808eb626bf613e1a920bd9b9e5f83299 etc.) --- imgui.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index cee33f500..318d3373a 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4466,23 +4466,23 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // Calculate auto-fit size, handle automatic resize const ImVec2 size_auto_fit = CalcSizeAutoFit(window); - ImVec2 size_for_scrollbars_visibility = window->SizeFullAtLastBegin; + ImVec2 size_full_modified(FLT_MAX, FLT_MAX); if (flags & ImGuiWindowFlags_AlwaysAutoResize && !window->Collapsed) { // Using SetNextWindowSize() overrides ImGuiWindowFlags_AlwaysAutoResize, so it can be used on tooltips/popups, etc. if (!window_size_x_set_by_api) - window->SizeFull.x = size_for_scrollbars_visibility.x = size_auto_fit.x; + window->SizeFull.x = size_full_modified.x = size_auto_fit.x; if (!window_size_y_set_by_api) - window->SizeFull.y = size_for_scrollbars_visibility.y = size_auto_fit.y; + window->SizeFull.y = size_full_modified.y = size_auto_fit.y; } else if (window->AutoFitFramesX > 0 || window->AutoFitFramesY > 0) { // Auto-fit only grows during the first few frames // We still process initial auto-fit on collapsed windows to get a window width, but otherwise don't honor ImGuiWindowFlags_AlwaysAutoResize ImGuiWindowFlags_AlwaysAutoResize. if (!window_size_x_set_by_api && window->AutoFitFramesX > 0) - window->SizeFull.x = size_for_scrollbars_visibility.x = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.x, size_auto_fit.x) : size_auto_fit.x; + window->SizeFull.x = size_full_modified.x = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.x, size_auto_fit.x) : size_auto_fit.x; if (!window_size_y_set_by_api && window->AutoFitFramesY > 0) - window->SizeFull.y = size_for_scrollbars_visibility.y = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.y, size_auto_fit.y) : size_auto_fit.y; + window->SizeFull.y = size_full_modified.y = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.y, size_auto_fit.y) : size_auto_fit.y; if (!window->Collapsed) MarkIniSettingsDirty(window); } @@ -4501,10 +4501,13 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // Update scrollbar status (based on the Size that was effective during last frame or the auto-resized Size). if (!window->Collapsed) { - window->ScrollbarY = (flags & ImGuiWindowFlags_AlwaysVerticalScrollbar) || ((window->SizeContents.y > size_for_scrollbars_visibility.y) && !(flags & ImGuiWindowFlags_NoScrollbar)); - window->ScrollbarX = (flags & ImGuiWindowFlags_AlwaysHorizontalScrollbar) || ((window->SizeContents.x > size_for_scrollbars_visibility.x - (window->ScrollbarY ? style.ScrollbarSize : 0.0f) - window->WindowPadding.x) && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar)); + // When reading the current size we need to read it after size constraints have been applied + float size_x_for_scrollbars = size_full_modified.x != FLT_MAX ? window->SizeFull.x : window->SizeFullAtLastBegin.x; + float size_y_for_scrollbars = size_full_modified.y != FLT_MAX ? window->SizeFull.y : window->SizeFullAtLastBegin.y; + window->ScrollbarY = (flags & ImGuiWindowFlags_AlwaysVerticalScrollbar) || ((window->SizeContents.y > size_y_for_scrollbars) && !(flags & ImGuiWindowFlags_NoScrollbar)); + window->ScrollbarX = (flags & ImGuiWindowFlags_AlwaysHorizontalScrollbar) || ((window->SizeContents.x > size_x_for_scrollbars - (window->ScrollbarY ? style.ScrollbarSize : 0.0f) - window->WindowPadding.x) && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar)); if (window->ScrollbarX && !window->ScrollbarY) - window->ScrollbarY = (window->SizeContents.y > size_for_scrollbars_visibility.y + style.ScrollbarSize) && !(flags & ImGuiWindowFlags_NoScrollbar); + window->ScrollbarY = (window->SizeContents.y > size_y_for_scrollbars + style.ScrollbarSize) && !(flags & ImGuiWindowFlags_NoScrollbar); window->ScrollbarSizes = ImVec2(window->ScrollbarY ? style.ScrollbarSize : 0.0f, window->ScrollbarX ? style.ScrollbarSize : 0.0f); } From d9d231dc6b42f994640bcc9357131ab4fe5e52d2 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 8 Dec 2017 12:30:58 +0100 Subject: [PATCH 679/921] Internals: Renamed CalcSizeFullWithConstraint() to CalcSizeAfterConstraint() which is more appropriate + added explicit parameter to CalcSizeAutoFit() so it can be used externally. --- imgui.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 318d3373a..b43e6c3ad 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4130,7 +4130,7 @@ static ImGuiWindow* CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFl return window; } -static ImVec2 CalcSizeFullWithConstraint(ImGuiWindow* window, ImVec2 new_size) +static ImVec2 CalcSizeAfterConstraint(ImGuiWindow* window, ImVec2 new_size) { ImGuiContext& g = *GImGui; if (g.SetNextWindowSizeConstraint) @@ -4168,7 +4168,7 @@ static ImVec2 CalcSizeContents(ImGuiWindow* window) return sz + window->WindowPadding; } -static ImVec2 CalcSizeAutoFit(ImGuiWindow* window) +static ImVec2 CalcSizeAutoFit(ImGuiWindow* window, const ImVec2& size_contents) { ImGuiContext& g = *GImGui; ImGuiStyle& style = g.Style; @@ -4177,16 +4177,16 @@ static ImVec2 CalcSizeAutoFit(ImGuiWindow* window) if ((flags & ImGuiWindowFlags_Tooltip) != 0) { // Tooltip always resize. We keep the spacing symmetric on both axises for aesthetic purpose. - size_auto_fit = window->SizeContents; + size_auto_fit = size_contents; } else { // Handling case of auto fit window not fitting on the screen (on either axis): we are growing the size on the other axis to compensate for expected scrollbar. FIXME: Might turn bigger than DisplaySize-WindowPadding. - size_auto_fit = ImClamp(window->SizeContents, style.WindowMinSize, ImMax(style.WindowMinSize, g.IO.DisplaySize - g.Style.DisplaySafeAreaPadding)); - ImVec2 size_auto_fit_after_constraint = CalcSizeFullWithConstraint(window, size_auto_fit); - if (size_auto_fit_after_constraint.x < window->SizeContents.x && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar)) + size_auto_fit = ImClamp(size_contents, style.WindowMinSize, ImMax(style.WindowMinSize, g.IO.DisplaySize - g.Style.DisplaySafeAreaPadding)); + ImVec2 size_auto_fit_after_constraint = CalcSizeAfterConstraint(window, size_auto_fit); + if (size_auto_fit_after_constraint.x < size_contents.x && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar)) size_auto_fit.y += style.ScrollbarSize; - if (size_auto_fit_after_constraint.y < window->SizeContents.y && !(flags & ImGuiWindowFlags_NoScrollbar)) + if (size_auto_fit_after_constraint.y < size_contents.y && !(flags & ImGuiWindowFlags_NoScrollbar)) size_auto_fit.x += style.ScrollbarSize; } return size_auto_fit; @@ -4234,7 +4234,7 @@ static void CalcResizePosSizeFromAnyCorner(ImGuiWindow* window, const ImVec2& co ImVec2 pos_min = ImLerp(corner_target, window->Pos, corner_norm); // Expected window upper-left ImVec2 pos_max = ImLerp(window->Pos + window->Size, corner_target, corner_norm); // Expected window lower-right ImVec2 size_expected = pos_max - pos_min; - ImVec2 size_constrained = CalcSizeFullWithConstraint(window, size_expected); + ImVec2 size_constrained = CalcSizeAfterConstraint(window, size_expected); *out_pos = pos_min; if (corner_norm.x == 0.0f) out_pos->x -= (size_constrained.x - size_expected.x); @@ -4465,7 +4465,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) const float window_border_size = window->WindowBorderSize; // Calculate auto-fit size, handle automatic resize - const ImVec2 size_auto_fit = CalcSizeAutoFit(window); + const ImVec2 size_auto_fit = CalcSizeAutoFit(window, window->SizeContents); ImVec2 size_full_modified(FLT_MAX, FLT_MAX); if (flags & ImGuiWindowFlags_AlwaysAutoResize && !window->Collapsed) { @@ -4488,7 +4488,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) } // Apply minimum/maximum window size constraints and final size - window->SizeFull = CalcSizeFullWithConstraint(window, window->SizeFull); + window->SizeFull = CalcSizeAfterConstraint(window, window->SizeFull); window->Size = window->Collapsed ? window->TitleBarRect().GetSize() : window->SizeFull; if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Popup)) { @@ -4638,7 +4638,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) if (g.HoveredWindow == window && held && g.IO.MouseDoubleClicked[0] && resize_grip_n == 0) { // Manual auto-fit when double-clicking - size_target = CalcSizeFullWithConstraint(window, size_auto_fit); + size_target = CalcSizeAfterConstraint(window, size_auto_fit); ClearActiveID(); } else if (held) From a5e93921404fcf2c94e2e245f0ff8569eef3baae Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 8 Dec 2017 14:44:58 +0100 Subject: [PATCH 680/921] Combo: Added flags to BeginCombo() new api, removed explicit height, default to 8 instead of 7 items, allow popup height constraints via SetNextWindowSizeConstraints(), width expand if contents doesn't fit, popup reposition policy if it doesn't fit. --- imgui.cpp | 112 +++++++++++++++++++++++++++++++++-------------- imgui_internal.h | 10 ++++- 2 files changed, 87 insertions(+), 35 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index b43e6c3ad..d921ad2d0 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4026,7 +4026,7 @@ static void CheckStacksSize(ImGuiWindow* window, bool write) IM_ASSERT(p_backup == window->DC.StackSizesBackup + IM_ARRAYSIZE(window->DC.StackSizesBackup)); } -static ImVec2 FindBestWindowPosForPopup(const ImVec2& base_pos, const ImVec2& size, ImGuiDir* last_dir, const ImRect& r_avoid) +static ImVec2 FindBestWindowPosForPopup(const ImVec2& base_pos, const ImVec2& size, ImGuiDir* last_dir, const ImRect& r_avoid, ImGuiWindowFlags flags) { const ImGuiStyle& style = GImGui->Style; @@ -4039,17 +4039,38 @@ static ImVec2 FindBestWindowPosForPopup(const ImVec2& base_pos, const ImVec2& si //GImGui->OverlayDrawList.AddRect(r_avoid.Min, r_avoid.Max, IM_COL32(255,0,0,255)); //GImGui->OverlayDrawList.AddRect(r_outer.Min, r_outer.Max, IM_COL32(0,255,0,255)); + // Combo Box policy (we want a connecting edge) + if (flags & ImGuiWindowFlags_ComboBox) + { + const ImGuiDir dir_prefered_order[ImGuiDir_Count_] = { ImGuiDir_Down, ImGuiDir_Right, ImGuiDir_Left, ImGuiDir_Up }; + for (int n = (*last_dir != ImGuiDir_None) ? -1 : 0; n < ImGuiDir_Count_; n++) + { + const ImGuiDir dir = (n == -1) ? *last_dir : dir_prefered_order[n]; + if (n != -1 && dir == *last_dir) // Already tried this direction? + continue; + ImVec2 pos; + if (dir == ImGuiDir_Down) pos = ImVec2(r_avoid.Min.x, r_avoid.Max.y); // Below, Toward Right (default) + if (dir == ImGuiDir_Right) pos = ImVec2(r_avoid.Min.x, r_avoid.Min.y - size.y); // Above, Toward Right + if (dir == ImGuiDir_Left) pos = ImVec2(r_avoid.Max.x - size.x, r_avoid.Max.y); // Below, Toward Left + if (dir == ImGuiDir_Up) pos = ImVec2(r_avoid.Max.x - size.x, r_avoid.Min.y - size.y); // Above, Toward Left + if (!r_outer.Contains(ImRect(pos, pos + size))) + continue; + *last_dir = dir; + return pos; + } + } + + // Default popup policy const ImGuiDir dir_prefered_order[ImGuiDir_Count_] = { ImGuiDir_Right, ImGuiDir_Down, ImGuiDir_Up, ImGuiDir_Left }; for (int n = (*last_dir != ImGuiDir_None) ? -1 : 0; n < ImGuiDir_Count_; n++) { const ImGuiDir dir = (n == -1) ? *last_dir : dir_prefered_order[n]; + if (n != -1 && dir == *last_dir) // Already tried this direction? + continue; float avail_w = (dir == ImGuiDir_Left ? r_avoid.Min.x : r_outer.Max.x) - (dir == ImGuiDir_Right ? r_avoid.Max.x : r_outer.Min.x); - if (avail_w < size.x) - continue; float avail_h = (dir == ImGuiDir_Up ? r_avoid.Min.y : r_outer.Max.y) - (dir == ImGuiDir_Down ? r_avoid.Max.y : r_outer.Min.y); - if (avail_h < size.y) + if (avail_w < size.x || avail_h < size.y) continue; - ImVec2 pos; pos.x = (dir == ImGuiDir_Left) ? r_avoid.Min.x - size.x : (dir == ImGuiDir_Right) ? r_avoid.Max.x : base_pos_clamped.x; pos.y = (dir == ImGuiDir_Up) ? r_avoid.Min.y - size.y : (dir == ImGuiDir_Down) ? r_avoid.Max.y : base_pos_clamped.y; @@ -4539,12 +4560,12 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) rect_to_avoid = ImRect(-FLT_MAX, parent_window->Pos.y + parent_window->TitleBarHeight(), FLT_MAX, parent_window->Pos.y + parent_window->TitleBarHeight() + parent_window->MenuBarHeight()); else rect_to_avoid = ImRect(parent_window->Pos.x + horizontal_overlap, -FLT_MAX, parent_window->Pos.x + parent_window->Size.x - horizontal_overlap - parent_window->ScrollbarSizes.x, FLT_MAX); - window->PosFloat = FindBestWindowPosForPopup(window->PosFloat, window->Size, &window->AutoPosLastDirection, rect_to_avoid); + window->PosFloat = FindBestWindowPosForPopup(window->PosFloat, window->Size, &window->AutoPosLastDirection, rect_to_avoid, flags); } else if ((flags & ImGuiWindowFlags_Popup) != 0 && !window_pos_set_by_api && window_just_appearing_after_hidden_for_resize) { ImRect rect_to_avoid(window->PosFloat.x - 1, window->PosFloat.y - 1, window->PosFloat.x + 1, window->PosFloat.y + 1); - window->PosFloat = FindBestWindowPosForPopup(window->PosFloat, window->Size, &window->AutoPosLastDirection, rect_to_avoid); + window->PosFloat = FindBestWindowPosForPopup(window->PosFloat, window->Size, &window->AutoPosLastDirection, rect_to_avoid, flags); } // Position tooltip (always follows mouse) @@ -4552,7 +4573,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) { ImVec2 ref_pos = g.IO.MousePos; ImRect rect_to_avoid(ref_pos.x - 16, ref_pos.y - 8, ref_pos.x + 24, ref_pos.y + 24); // FIXME: Completely hard-coded. Store boxes in mouse cursor data? Scale? Center on cursor hit-point? - window->PosFloat = FindBestWindowPosForPopup(ref_pos, window->Size, &window->AutoPosLastDirection, rect_to_avoid); + window->PosFloat = FindBestWindowPosForPopup(ref_pos, window->Size, &window->AutoPosLastDirection, rect_to_avoid, flags); if (window->AutoPosLastDirection == ImGuiDir_None) window->PosFloat = ref_pos + ImVec2(2,2); // If there's not enough room, for tooltip we prefer avoiding the cursor at all cost even if it means that part of the tooltip won't be visible. } @@ -9089,14 +9110,25 @@ bool ImGui::Combo(const char* label, int* current_item, const char* items_separa return value_changed; } -bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboFlags flags, ImVec2 popup_size) +static float CalcMaxPopupHeightFromItemCount(int items_count) { - (void)flags; // Unused + ImGuiContext& g = *GImGui; + if (items_count <= 0) + return FLT_MAX; + return (g.FontSize + g.Style.ItemSpacing.y) * items_count - g.Style.ItemSpacing.y + (g.Style.WindowPadding.y * 2); +} + +bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboFlags flags) +{ + // Always consume the SetNextWindowSizeConstraint() call in our early return paths + ImGuiContext& g = *GImGui; + bool backup_has_next_window_size_constraint = g.SetNextWindowSizeConstraint; + g.SetNextWindowSizeConstraint = false; + ImGuiWindow* window = GetCurrentWindow(); if (window->SkipItems) return false; - ImGuiContext& g = *GImGui; const ImGuiStyle& style = g.Style; const ImGuiID id = window->GetID(label); const float w = CalcItemWidth(); @@ -9135,28 +9167,41 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboF if (!popup_open) return false; - if (popup_size.x == 0.0f) - popup_size.x = w; - - // FIXME: Start using shared helpers or handle in Begin(). We have similar code in Begin() calling FindBestWindowPosForPopup() - float popup_y1 = frame_bb.Max.y; - float popup_y2 = ImClamp(popup_y1 + popup_size.y, popup_y1, g.IO.DisplaySize.y - style.DisplaySafeAreaPadding.y); - if ((popup_y2 - popup_y1) < ImMin(popup_size.y, frame_bb.Min.y - style.DisplaySafeAreaPadding.y)) + if (backup_has_next_window_size_constraint) { - // Position our combo ABOVE because there's more space to fit! - popup_y1 = ImClamp(frame_bb.Min.y - popup_size.y, style.DisplaySafeAreaPadding.y, frame_bb.Min.y); - popup_y2 = frame_bb.Min.y; - SetNextWindowPos(ImVec2(frame_bb.Min.x, frame_bb.Min.y + style.FrameBorderSize), ImGuiCond_Always, ImVec2(0.0f, 1.0f)); + g.SetNextWindowSizeConstraint = true; + g.SetNextWindowSizeConstraintRect.Min.x = ImMax(g.SetNextWindowSizeConstraintRect.Min.x, w); } else { - // Position our combo below - SetNextWindowPos(ImVec2(frame_bb.Min.x, frame_bb.Max.y - style.FrameBorderSize), ImGuiCond_Always, ImVec2(0.0f, 0.0f)); + if ((flags & ImGuiComboFlags_HeightMask_) == 0) + flags |= ImGuiComboFlags_HeightRegular; + IM_ASSERT(ImIsPowerOfTwo(flags & ImGuiComboFlags_HeightMask_)); // Only one + int popup_max_height_in_items = -1; + if (flags & ImGuiComboFlags_HeightRegular) popup_max_height_in_items = 8; + else if (flags & ImGuiComboFlags_HeightSmall) popup_max_height_in_items = 4; + else if (flags & ImGuiComboFlags_HeightLarge) popup_max_height_in_items = 20; + SetNextWindowSizeConstraints(ImVec2(w, 0.0f), ImVec2(FLT_MAX, CalcMaxPopupHeightFromItemCount(popup_max_height_in_items))); } - SetNextWindowSize(ImVec2(popup_size.x, popup_y2 - popup_y1), ImGuiCond_Appearing); - if (!BeginPopupEx(id, ImGuiWindowFlags_ComboBox)) + char name[20]; + ImFormatString(name, IM_ARRAYSIZE(name), "##combo_%08X", id); + + // Peak into expected window size so we can position it + if (ImGuiWindow* popup_window = FindWindowByName(name)) { + ImVec2 size_contents = CalcSizeContents(popup_window); + ImVec2 size_expected = CalcSizeAfterConstraint(popup_window, CalcSizeAutoFit(popup_window, size_contents)); + if (flags & ImGuiComboFlags_PopupAlignLeft) + popup_window->AutoPosLastDirection = ImGuiDir_Left; + ImVec2 pos = FindBestWindowPosForPopup(frame_bb.GetBL(), size_expected, &popup_window->AutoPosLastDirection, frame_bb, ImGuiWindowFlags_ComboBox); + SetNextWindowPos(pos); + } + + ImGuiWindowFlags window_flags = ImGuiWindowFlags_ComboBox | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_Popup | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoSavedSettings; + if (!Begin(name, NULL, window_flags)) + { + EndPopup(); IM_ASSERT(0); // This should never happen as we tested for IsPopupOpen() above return false; } @@ -9177,21 +9222,20 @@ void ImGui::EndCombo() } // Combo box function. -bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(void*, int, const char**), void* data, int items_count, int height_in_items) +bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(void*, int, const char**), void* data, int items_count, int popup_max_height_in_items) { ImGuiContext& g = *GImGui; - const ImGuiStyle& style = g.Style; const char* preview_text = NULL; if (*current_item >= 0 && *current_item < items_count) items_getter(data, *current_item, &preview_text); - // Size default to hold ~7 items - if (height_in_items < 0) - height_in_items = 7; - float popup_height = (g.FontSize + style.ItemSpacing.y) * ImMin(items_count, height_in_items) - style.ItemSpacing.y + (style.WindowPadding.y * 2); - - if (!BeginCombo(label, preview_text, 0, ImVec2(0.0f, popup_height))) + if (popup_max_height_in_items != -1 && !g.SetNextWindowSizeConstraint) + { + float popup_max_height = CalcMaxPopupHeightFromItemCount(popup_max_height_in_items); + SetNextWindowSizeConstraints(ImVec2(0,0), ImVec2(FLT_MAX, popup_max_height)); + } + if (!BeginCombo(label, preview_text, 0)) return false; // Display items diff --git a/imgui_internal.h b/imgui_internal.h index d796c066f..3774a8b83 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -212,6 +212,14 @@ enum ImGuiSelectableFlagsPrivate_ enum ImGuiComboFlags_ { + ImGuiComboFlags_PopupAlignLeft = 1 << 0, // Align the popup toward the left by default + + // If you want your combo popup to be a specific size you can use SetNextWindowSizeConstraints() prior to calling BeginCombo() + ImGuiComboFlags_HeightSmall = 1 << 1, // Max ~4 items visible + ImGuiComboFlags_HeightRegular = 1 << 2, // Max ~8 items visible (default) + ImGuiComboFlags_HeightLarge = 1 << 3, // Max ~20 items visible + ImGuiComboFlags_HeightLargest = 1 << 4, // As many fitting items as possible + ImGuiComboFlags_HeightMask_ = ImGuiComboFlags_HeightSmall | ImGuiComboFlags_HeightRegular | ImGuiComboFlags_HeightLarge | ImGuiComboFlags_HeightLargest }; enum ImGuiSeparatorFlags_ @@ -852,7 +860,7 @@ namespace ImGui IMGUI_API void PushColumnClipRect(int column_index = -1); // FIXME-WIP: New Combo API - IMGUI_API bool BeginCombo(const char* label, const char* preview_value, ImGuiComboFlags flags = 0, ImVec2 popup_size = ImVec2(0.0f,0.0f)); + IMGUI_API bool BeginCombo(const char* label, const char* preview_value, ImGuiComboFlags flags = 0); IMGUI_API void EndCombo(); // NB: All position are in absolute pixels coordinates (never using window coordinates internally) From e998c7d3e3270d60459424d65bed705f22fb2447 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 8 Dec 2017 14:45:43 +0100 Subject: [PATCH 681/921] Combo: Moved functions (untouched). --- imgui.cpp | 98 +++++++++++++++++++++++++++---------------------------- 1 file changed, 49 insertions(+), 49 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index d921ad2d0..793d3738f 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9061,55 +9061,6 @@ bool ImGui::InputInt4(const char* label, int v[4], ImGuiInputTextFlags extra_fla return InputIntN(label, v, 4, extra_flags); } -static bool Items_ArrayGetter(void* data, int idx, const char** out_text) -{ - const char* const* items = (const char* const*)data; - if (out_text) - *out_text = items[idx]; - return true; -} - -static bool Items_SingleStringGetter(void* data, int idx, const char** out_text) -{ - // FIXME-OPT: we could pre-compute the indices to fasten this. But only 1 active combo means the waste is limited. - const char* items_separated_by_zeros = (const char*)data; - int items_count = 0; - const char* p = items_separated_by_zeros; - while (*p) - { - if (idx == items_count) - break; - p += strlen(p) + 1; - items_count++; - } - if (!*p) - return false; - if (out_text) - *out_text = p; - return true; -} - -// Combo box helper allowing to pass an array of strings. -bool ImGui::Combo(const char* label, int* current_item, const char* const* items, int items_count, int height_in_items) -{ - const bool value_changed = Combo(label, current_item, Items_ArrayGetter, (void*)items, items_count, height_in_items); - return value_changed; -} - -// Combo box helper allowing to pass all items in a single string. -bool ImGui::Combo(const char* label, int* current_item, const char* items_separated_by_zeros, int height_in_items) -{ - int items_count = 0; - const char* p = items_separated_by_zeros; // FIXME-OPT: Avoid computing this, or at least only when combo is open - while (*p) - { - p += strlen(p) + 1; - items_count++; - } - bool value_changed = Combo(label, current_item, Items_SingleStringGetter, (void*)items_separated_by_zeros, items_count, height_in_items); - return value_changed; -} - static float CalcMaxPopupHeightFromItemCount(int items_count) { ImGuiContext& g = *GImGui; @@ -9262,6 +9213,55 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi return value_changed; } +static bool Items_ArrayGetter(void* data, int idx, const char** out_text) +{ + const char* const* items = (const char* const*)data; + if (out_text) + *out_text = items[idx]; + return true; +} + +static bool Items_SingleStringGetter(void* data, int idx, const char** out_text) +{ + // FIXME-OPT: we could pre-compute the indices to fasten this. But only 1 active combo means the waste is limited. + const char* items_separated_by_zeros = (const char*)data; + int items_count = 0; + const char* p = items_separated_by_zeros; + while (*p) + { + if (idx == items_count) + break; + p += strlen(p) + 1; + items_count++; + } + if (!*p) + return false; + if (out_text) + *out_text = p; + return true; +} + +// Combo box helper allowing to pass an array of strings. +bool ImGui::Combo(const char* label, int* current_item, const char* const* items, int items_count, int height_in_items) +{ + const bool value_changed = Combo(label, current_item, Items_ArrayGetter, (void*)items, items_count, height_in_items); + return value_changed; +} + +// Combo box helper allowing to pass all items in a single string. +bool ImGui::Combo(const char* label, int* current_item, const char* items_separated_by_zeros, int height_in_items) +{ + int items_count = 0; + const char* p = items_separated_by_zeros; // FIXME-OPT: Avoid computing this, or at least only when combo is open + while (*p) + { + p += strlen(p) + 1; + items_count++; + } + bool value_changed = Combo(label, current_item, Items_SingleStringGetter, (void*)items_separated_by_zeros, items_count, height_in_items); + return value_changed; +} + // Tip: pass an empty label (e.g. "##dummy") then you can use the space to draw other text or image. // But you need to make sure the ID is unique, e.g. enclose calls in PushID/PopID. bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags flags, const ImVec2& size_arg) From befc58771c0c2b95df6b84b667b2ccd7fc11b768 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 8 Dec 2017 14:48:25 +0100 Subject: [PATCH 682/921] Combo: Recycling windows by using a stack number instead of a unique id, wasitng less windows. --- imgui.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 793d3738f..bf4abb016 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9135,8 +9135,8 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboF SetNextWindowSizeConstraints(ImVec2(w, 0.0f), ImVec2(FLT_MAX, CalcMaxPopupHeightFromItemCount(popup_max_height_in_items))); } - char name[20]; - ImFormatString(name, IM_ARRAYSIZE(name), "##combo_%08X", id); + char name[16]; + ImFormatString(name, IM_ARRAYSIZE(name), "##combo_%d", g.CurrentPopupStack.Size); // Recycle windows based on depth // Peak into expected window size so we can position it if (ImGuiWindow* popup_window = FindWindowByName(name)) From 7ac5f11b292a6627a454c95dee0e9e2a1430ee90 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 8 Dec 2017 14:52:33 +0100 Subject: [PATCH 683/921] Standardizing the casing/format of internal window names + Misc comments. --- imgui.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index bf4abb016..dde89902f 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3640,14 +3640,14 @@ void ImGui::BeginTooltipEx(ImGuiWindowFlags extra_flags, bool override_previous_ { ImGuiContext& g = *GImGui; char window_name[16]; - ImFormatString(window_name, IM_ARRAYSIZE(window_name), "##Tooltip%02d", g.TooltipOverrideCount); + ImFormatString(window_name, IM_ARRAYSIZE(window_name), "##Tooltip_%02d", g.TooltipOverrideCount); if (override_previous_tooltip) if (ImGuiWindow* window = FindWindowByName(window_name)) if (window->Active) { // Hide previous tooltips. We can't easily "reset" the content of a window so we create a new one. window->HiddenFrames = 1; - ImFormatString(window_name, IM_ARRAYSIZE(window_name), "##Tooltip%02d", ++g.TooltipOverrideCount); + ImFormatString(window_name, IM_ARRAYSIZE(window_name), "##Tooltip_%02d", ++g.TooltipOverrideCount); } ImGuiWindowFlags flags = ImGuiWindowFlags_Tooltip|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_AlwaysAutoResize; Begin(window_name, NULL, flags | extra_flags); @@ -3688,7 +3688,7 @@ void ImGui::OpenPopupEx(ImGuiID id, bool reopen_existing) ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; int current_stack_size = g.CurrentPopupStack.Size; - ImGuiPopupRef popup_ref = ImGuiPopupRef(id, window, window->GetID("##menus"), g.IO.MousePos); // Tagged as new ref because constructor sets Window to NULL (we are passing the ParentWindow info here) + ImGuiPopupRef popup_ref = ImGuiPopupRef(id, window, window->GetID("##Menus"), g.IO.MousePos); // Tagged as new ref because constructor sets Window to NULL (we are passing the ParentWindow info here) if (g.OpenPopupStack.Size < current_stack_size + 1) g.OpenPopupStack.push_back(popup_ref); else if (reopen_existing || g.OpenPopupStack[current_stack_size].PopupId != id) @@ -3802,9 +3802,9 @@ bool ImGui::BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_flags) char name[20]; if (flags & ImGuiWindowFlags_ChildMenu) - ImFormatString(name, IM_ARRAYSIZE(name), "##menu_%d", g.CurrentPopupStack.Size); // Recycle windows based on depth + ImFormatString(name, IM_ARRAYSIZE(name), "##Menu_%02d", g.CurrentPopupStack.Size); // Recycle windows based on depth else - ImFormatString(name, IM_ARRAYSIZE(name), "##popup_%08x", id); // Not recycling, so we can close/open during the same frame + ImFormatString(name, IM_ARRAYSIZE(name), "##Popup_%08x", id); // Not recycling, so we can close/open during the same frame bool is_open = Begin(name, NULL, flags); if (!is_open) // NB: Begin can return false when the popup is completely clipped (e.g. zero size display) @@ -4202,7 +4202,7 @@ static ImVec2 CalcSizeAutoFit(ImGuiWindow* window, const ImVec2& size_contents) } else { - // Handling case of auto fit window not fitting on the screen (on either axis): we are growing the size on the other axis to compensate for expected scrollbar. FIXME: Might turn bigger than DisplaySize-WindowPadding. + // When the window cannot fit all contents (either because of constraints, either because screen is too small): we are growing the size on the other axis to compensate for expected scrollbar. FIXME: Might turn bigger than DisplaySize-WindowPadding. size_auto_fit = ImClamp(size_contents, style.WindowMinSize, ImMax(style.WindowMinSize, g.IO.DisplaySize - g.Style.DisplaySafeAreaPadding)); ImVec2 size_auto_fit_after_constraint = CalcSizeAfterConstraint(window, size_auto_fit); if (size_auto_fit_after_constraint.x < size_contents.x && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar)) @@ -4499,7 +4499,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) else if (window->AutoFitFramesX > 0 || window->AutoFitFramesY > 0) { // Auto-fit only grows during the first few frames - // We still process initial auto-fit on collapsed windows to get a window width, but otherwise don't honor ImGuiWindowFlags_AlwaysAutoResize ImGuiWindowFlags_AlwaysAutoResize. + // We still process initial auto-fit on collapsed windows to get a window width, but otherwise don't honor ImGuiWindowFlags_AlwaysAutoResize when collapsed. if (!window_size_x_set_by_api && window->AutoFitFramesX > 0) window->SizeFull.x = size_full_modified.x = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.x, size_auto_fit.x) : size_auto_fit.x; if (!window_size_y_set_by_api && window->AutoFitFramesY > 0) @@ -9136,7 +9136,7 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboF } char name[16]; - ImFormatString(name, IM_ARRAYSIZE(name), "##combo_%d", g.CurrentPopupStack.Size); // Recycle windows based on depth + ImFormatString(name, IM_ARRAYSIZE(name), "##Combo_%02d", g.CurrentPopupStack.Size); // Recycle windows based on depth // Peak into expected window size so we can position it if (ImGuiWindow* popup_window = FindWindowByName(name)) @@ -9580,7 +9580,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled) bool pressed; bool menu_is_open = IsPopupOpen(id); - bool menuset_is_open = !(window->Flags & ImGuiWindowFlags_Popup) && (g.OpenPopupStack.Size > g.CurrentPopupStack.Size && g.OpenPopupStack[g.CurrentPopupStack.Size].ParentMenuSet == window->GetID("##menus")); + bool menuset_is_open = !(window->Flags & ImGuiWindowFlags_Popup) && (g.OpenPopupStack.Size > g.CurrentPopupStack.Size && g.OpenPopupStack[g.CurrentPopupStack.Size].ParentMenuSet == window->GetID("##Menus")); ImGuiWindow* backed_nav_window = g.NavWindow; if (menuset_is_open) g.NavWindow = window; // Odd hack to allow hovering across menus of a same menu-set (otherwise we wouldn't be able to hover parent) From a263dce2f29f07074b031159259cd1e4b432ad49 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 8 Dec 2017 17:16:33 +0100 Subject: [PATCH 684/921] Combo: Cleanup. Removed unrequired uses of the _ComboBox flag (the test in EndChild() is from commit no 1!). We could remove ImGuiWindowFlags_ComboBox soonish. --- imgui.cpp | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index dde89902f..c01c9492b 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2768,8 +2768,6 @@ static int ChildWindowComparer(const void* lhs, const void* rhs) return d; if (int d = (a->Flags & ImGuiWindowFlags_Tooltip) - (b->Flags & ImGuiWindowFlags_Tooltip)) return d; - if (int d = (a->Flags & ImGuiWindowFlags_ComboBox) - (b->Flags & ImGuiWindowFlags_ComboBox)) - return d; return (a->OrderWithinParent - b->OrderWithinParent); } @@ -3971,7 +3969,7 @@ void ImGui::EndChild() ImGuiWindow* window = GetCurrentWindow(); IM_ASSERT(window->Flags & ImGuiWindowFlags_ChildWindow); // Mismatched BeginChild()/EndChild() callss - if ((window->Flags & ImGuiWindowFlags_ComboBox) || window->BeginCount > 1) + if (window->BeginCount > 1) { ImGui::End(); } @@ -4425,7 +4423,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->DrawList->Clear(); window->DrawList->PushTextureID(g.Font->ContainerAtlas->TexID); ImRect fullscreen_rect(GetVisibleRect()); - if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & (ImGuiWindowFlags_ComboBox|ImGuiWindowFlags_Popup))) + if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Popup)) PushClipRect(parent_window->ClipRect.Min, parent_window->ClipRect.Max, true); else PushClipRect(fullscreen_rect.Min, fullscreen_rect.Max, true); @@ -4480,7 +4478,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->WindowRounding = (flags & ImGuiWindowFlags_ChildWindow) ? style.ChildRounding : ((flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiWindowFlags_Modal)) ? style.PopupRounding : style.WindowRounding; window->WindowBorderSize = (flags & ImGuiWindowFlags_ChildWindow) ? style.ChildBorderSize : ((flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiWindowFlags_Modal)) ? style.PopupBorderSize : style.WindowBorderSize; window->WindowPadding = style.WindowPadding; - if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & (ImGuiWindowFlags_AlwaysUseWindowPadding | ImGuiWindowFlags_ComboBox | ImGuiWindowFlags_Popup)) && window->WindowBorderSize == 0.0f) + if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & (ImGuiWindowFlags_AlwaysUseWindowPadding | ImGuiWindowFlags_Popup)) && window->WindowBorderSize == 0.0f) window->WindowPadding = ImVec2(0.0f, (flags & ImGuiWindowFlags_MenuBar) ? style.WindowPadding.y : 0.0f); const float window_rounding = window->WindowRounding; const float window_border_size = window->WindowBorderSize; @@ -9091,21 +9089,17 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboF if (!ItemAdd(total_bb, id)) return false; - const float arrow_size = SmallSquareSize(); - bool hovered, held; bool pressed = ButtonBehavior(frame_bb, id, &hovered, &held); - bool popup_open = IsPopupOpen(id); + const float arrow_size = SmallSquareSize(); const ImRect value_bb(frame_bb.Min, frame_bb.Max - ImVec2(arrow_size, 0.0f)); RenderFrame(frame_bb.Min, frame_bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding); RenderFrame(ImVec2(frame_bb.Max.x-arrow_size, frame_bb.Min.y), frame_bb.Max, GetColorU32(popup_open || hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button), true, style.FrameRounding); // FIXME-ROUNDING RenderTriangle(ImVec2(frame_bb.Max.x - arrow_size + style.FramePadding.y, frame_bb.Min.y + style.FramePadding.y), ImGuiDir_Down); - if (preview_value != NULL) RenderTextClipped(frame_bb.Min + style.FramePadding, value_bb.Max, preview_value, NULL, NULL, ImVec2(0.0f,0.0f)); - if (label_size.x > 0) RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label); From 457011660eb47c6d0b87dc0e6b5ab700caf5b770 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 8 Dec 2017 18:28:17 +0100 Subject: [PATCH 685/921] Mouse wheel scrolling doesn't change speed inside Combo box (uses to slow down from 5 to 3) but instead slow down on window that are smaller than the scroll speed. --- imgui.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index c01c9492b..735f9f968 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2449,9 +2449,10 @@ void ImGui::NewFrame() } else if (!g.IO.KeyCtrl && !(window->Flags & ImGuiWindowFlags_NoScrollWithMouse)) { - // Scroll - const int scroll_lines = (window->Flags & ImGuiWindowFlags_ComboBox) ? 3 : 5; - SetWindowScrollY(window, window->Scroll.y - g.IO.MouseWheel * window->CalcFontSize() * scroll_lines); + // Mouse wheel Scrolling + float scroll_amount = 5 * window->CalcFontSize(); + scroll_amount = (float)(int)ImMin(scroll_amount, (window->ContentsRegionRect.GetHeight() + window->WindowPadding.y * 2.0f) * 0.67f); + SetWindowScrollY(window, window->Scroll.y - g.IO.MouseWheel * scroll_amount); } } From c9f0275e2270fa39f631e47c67b35524b230a9d0 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 8 Dec 2017 18:32:12 +0100 Subject: [PATCH 686/921] Combo: Removed ImGuiWindowFlags_ComboBox flag. Moved internal window flags. --- imgui.cpp | 25 +++++++++++++++---------- imgui.h | 11 +++++------ imgui_demo.cpp | 2 +- 3 files changed, 21 insertions(+), 17 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 735f9f968..7bc95f5d6 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -656,7 +656,6 @@ static ImRect GetVisibleRect(); static void CloseInactivePopups(ImGuiWindow* ref_window); static void ClosePopupToLevel(int remaining); static ImGuiWindow* GetFrontMostModalRootWindow(); -static ImVec2 FindBestWindowPosForPopup(const ImVec2& base_pos, const ImVec2& size, ImGuiDir* last_dir, const ImRect& rect_to_avoid); static bool InputTextFilterCharacter(unsigned int* p_char, ImGuiInputTextFlags flags, ImGuiTextEditCallback callback, void* user_data); static int InputTextCalcTextLenAndLineCount(const char* text_begin, const char** out_text_end); @@ -4025,7 +4024,13 @@ static void CheckStacksSize(ImGuiWindow* window, bool write) IM_ASSERT(p_backup == window->DC.StackSizesBackup + IM_ARRAYSIZE(window->DC.StackSizesBackup)); } -static ImVec2 FindBestWindowPosForPopup(const ImVec2& base_pos, const ImVec2& size, ImGuiDir* last_dir, const ImRect& r_avoid, ImGuiWindowFlags flags) +enum ImGuiPopupPositionPolicy +{ + ImGuiPopupPositionPolicy_Default, + ImGuiPopupPositionPolicy_ComboBox +}; + +static ImVec2 FindBestWindowPosForPopup(const ImVec2& ref_pos, const ImVec2& size, ImGuiDir* last_dir, const ImRect& r_avoid, ImGuiPopupPositionPolicy policy = ImGuiPopupPositionPolicy_Default) { const ImGuiStyle& style = GImGui->Style; @@ -4034,12 +4039,12 @@ static ImVec2 FindBestWindowPosForPopup(const ImVec2& base_pos, const ImVec2& si ImVec2 safe_padding = style.DisplaySafeAreaPadding; ImRect r_outer(GetVisibleRect()); r_outer.Expand(ImVec2((size.x - r_outer.GetWidth() > safe_padding.x*2) ? -safe_padding.x : 0.0f, (size.y - r_outer.GetHeight() > safe_padding.y*2) ? -safe_padding.y : 0.0f)); - ImVec2 base_pos_clamped = ImClamp(base_pos, r_outer.Min, r_outer.Max - size); + ImVec2 base_pos_clamped = ImClamp(ref_pos, r_outer.Min, r_outer.Max - size); //GImGui->OverlayDrawList.AddRect(r_avoid.Min, r_avoid.Max, IM_COL32(255,0,0,255)); //GImGui->OverlayDrawList.AddRect(r_outer.Min, r_outer.Max, IM_COL32(0,255,0,255)); // Combo Box policy (we want a connecting edge) - if (flags & ImGuiWindowFlags_ComboBox) + if (policy == ImGuiPopupPositionPolicy_ComboBox) { const ImGuiDir dir_prefered_order[ImGuiDir_Count_] = { ImGuiDir_Down, ImGuiDir_Right, ImGuiDir_Left, ImGuiDir_Up }; for (int n = (*last_dir != ImGuiDir_None) ? -1 : 0; n < ImGuiDir_Count_; n++) @@ -4079,7 +4084,7 @@ static ImVec2 FindBestWindowPosForPopup(const ImVec2& base_pos, const ImVec2& si // Fallback, try to keep within display *last_dir = ImGuiDir_None; - ImVec2 pos = base_pos; + ImVec2 pos = ref_pos; pos.x = ImMax(ImMin(pos.x + size.x, r_outer.Max.x) - size.x, r_outer.Min.x); pos.y = ImMax(ImMin(pos.y + size.y, r_outer.Max.y) - size.y, r_outer.Min.y); return pos; @@ -4559,12 +4564,12 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) rect_to_avoid = ImRect(-FLT_MAX, parent_window->Pos.y + parent_window->TitleBarHeight(), FLT_MAX, parent_window->Pos.y + parent_window->TitleBarHeight() + parent_window->MenuBarHeight()); else rect_to_avoid = ImRect(parent_window->Pos.x + horizontal_overlap, -FLT_MAX, parent_window->Pos.x + parent_window->Size.x - horizontal_overlap - parent_window->ScrollbarSizes.x, FLT_MAX); - window->PosFloat = FindBestWindowPosForPopup(window->PosFloat, window->Size, &window->AutoPosLastDirection, rect_to_avoid, flags); + window->PosFloat = FindBestWindowPosForPopup(window->PosFloat, window->Size, &window->AutoPosLastDirection, rect_to_avoid); } else if ((flags & ImGuiWindowFlags_Popup) != 0 && !window_pos_set_by_api && window_just_appearing_after_hidden_for_resize) { ImRect rect_to_avoid(window->PosFloat.x - 1, window->PosFloat.y - 1, window->PosFloat.x + 1, window->PosFloat.y + 1); - window->PosFloat = FindBestWindowPosForPopup(window->PosFloat, window->Size, &window->AutoPosLastDirection, rect_to_avoid, flags); + window->PosFloat = FindBestWindowPosForPopup(window->PosFloat, window->Size, &window->AutoPosLastDirection, rect_to_avoid); } // Position tooltip (always follows mouse) @@ -4572,7 +4577,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) { ImVec2 ref_pos = g.IO.MousePos; ImRect rect_to_avoid(ref_pos.x - 16, ref_pos.y - 8, ref_pos.x + 24, ref_pos.y + 24); // FIXME: Completely hard-coded. Store boxes in mouse cursor data? Scale? Center on cursor hit-point? - window->PosFloat = FindBestWindowPosForPopup(ref_pos, window->Size, &window->AutoPosLastDirection, rect_to_avoid, flags); + window->PosFloat = FindBestWindowPosForPopup(ref_pos, window->Size, &window->AutoPosLastDirection, rect_to_avoid); if (window->AutoPosLastDirection == ImGuiDir_None) window->PosFloat = ref_pos + ImVec2(2,2); // If there's not enough room, for tooltip we prefer avoiding the cursor at all cost even if it means that part of the tooltip won't be visible. } @@ -9140,11 +9145,11 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboF ImVec2 size_expected = CalcSizeAfterConstraint(popup_window, CalcSizeAutoFit(popup_window, size_contents)); if (flags & ImGuiComboFlags_PopupAlignLeft) popup_window->AutoPosLastDirection = ImGuiDir_Left; - ImVec2 pos = FindBestWindowPosForPopup(frame_bb.GetBL(), size_expected, &popup_window->AutoPosLastDirection, frame_bb, ImGuiWindowFlags_ComboBox); + ImVec2 pos = FindBestWindowPosForPopup(frame_bb.GetBL(), size_expected, &popup_window->AutoPosLastDirection, frame_bb, ImGuiPopupPositionPolicy_ComboBox); SetNextWindowPos(pos); } - ImGuiWindowFlags window_flags = ImGuiWindowFlags_ComboBox | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_Popup | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoSavedSettings; + ImGuiWindowFlags window_flags = ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_Popup | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoSavedSettings; if (!Begin(name, NULL, window_flags)) { EndPopup(); diff --git a/imgui.h b/imgui.h index ae31f051c..6bf33b771 100644 --- a/imgui.h +++ b/imgui.h @@ -517,12 +517,11 @@ enum ImGuiWindowFlags_ ImGuiWindowFlags_ResizeFromAnySide = 1 << 17, // (WIP) Enable resize from any corners and borders. Your back-end needs to honor the different values of io.MouseCursor set by imgui. // [Internal] - ImGuiWindowFlags_ChildWindow = 1 << 22, // Don't use! For internal use by BeginChild() - ImGuiWindowFlags_ComboBox = 1 << 23, // Don't use! For internal use by ComboBox() - ImGuiWindowFlags_Tooltip = 1 << 24, // Don't use! For internal use by BeginTooltip() - ImGuiWindowFlags_Popup = 1 << 25, // Don't use! For internal use by BeginPopup() - ImGuiWindowFlags_Modal = 1 << 26, // Don't use! For internal use by BeginPopupModal() - ImGuiWindowFlags_ChildMenu = 1 << 27 // Don't use! For internal use by BeginMenu() + ImGuiWindowFlags_ChildWindow = 1 << 24, // Don't use! For internal use by BeginChild() + ImGuiWindowFlags_Tooltip = 1 << 25, // Don't use! For internal use by BeginTooltip() + ImGuiWindowFlags_Popup = 1 << 26, // Don't use! For internal use by BeginPopup() + ImGuiWindowFlags_Modal = 1 << 27, // Don't use! For internal use by BeginPopupModal() + ImGuiWindowFlags_ChildMenu = 1 << 28 // Don't use! For internal use by BeginMenu() }; // Flags for ImGui::InputText() diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 95608aff8..7c3c71e2e 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -318,7 +318,7 @@ void ImGui::ShowTestWindow(bool* p_open) static int item = 1; ImGui::Combo("combo", &item, "aaaa\0bbbb\0cccc\0dddd\0eeee\0\0"); // Combo using values packed in a single constant string (for really quick combo) - const char* items[] = { "AAAA", "BBBB", "CCCC", "DDDD", "EEEE", "FFFF", "GGGG", "HHHH", "IIII", "JJJJ", "KKKK" }; + const char* items[] = { "AAAA", "BBBB", "CCCC", "DDDD", "EEEE", "FFFF", "GGGG", "HHHH", "IIII", "JJJJ", "KKKK", "LLLLLLL", "MMMM", "OOOOOOO", "PPPP", "QQQQQQQQQQ", "RRR", "SSSS" }; static int item2 = -1; ImGui::Combo("combo scroll", &item2, items, IM_ARRAYSIZE(items)); // Combo using proper array. You can also pass a callback to retrieve array value, no need to create/copy an array just for that. From a8c7b1a2a2fdd9119ae72a815171a9ab25df61bc Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 9 Dec 2017 21:17:27 +0100 Subject: [PATCH 687/921] ColorEdit4: Made IsItemActive() return true when picker popup is active. (#1489) --- imgui.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 7bc95f5d6..5a0b2461a 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -10036,7 +10036,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag PopItemWidth(); } - bool picker_active = false; + ImGuiWindow* picker_active_window = NULL; if (!(flags & ImGuiColorEditFlags_NoSmallPreview)) { if (!(flags & ImGuiColorEditFlags_NoInputs)) @@ -10058,7 +10058,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag if (BeginPopup("picker")) { - picker_active = true; + picker_active_window = g.CurrentWindow; if (label != label_display_end) { TextUnformatted(label, label_display_end); @@ -10080,7 +10080,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag } // Convert back - if (!picker_active) + if (picker_active_window == NULL) { if (!value_changed_as_float) for (int n = 0; n < 4; n++) @@ -10100,6 +10100,10 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag PopID(); EndGroup(); + // When picker is being actively used, use its active id so IsItemActive() will function on ColorEdit4(). + if (picker_active_window && g.ActiveId != 0 && g.ActiveIdWindow == picker_active_window) + window->DC.LastItemId = g.ActiveId; + return value_changed; } From 0365c524a2f4641538ea3b9e5bde7c8342eec158 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 9 Dec 2017 21:25:20 +0100 Subject: [PATCH 688/921] ColorPicker4: Fixed returning true when holding mouse button on the sat/value/alpha locations. (#1489) --- imgui.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 5a0b2461a..f1c3af418 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9883,7 +9883,7 @@ void ImGui::ColorEditOptionsPopup(const float* col, ImGuiColorEditFlags flags) EndPopup(); } -static void ColorPickerOptionsPopup(ImGuiColorEditFlags flags, float* ref_col) +static void ColorPickerOptionsPopup(ImGuiColorEditFlags flags, const float* ref_col) { bool allow_opt_picker = !(flags & ImGuiColorEditFlags__PickerMask); bool allow_opt_alpha_bar = !(flags & ImGuiColorEditFlags_NoAlpha) && !(flags & ImGuiColorEditFlags_AlphaBar); @@ -10167,6 +10167,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl flags |= (g.ColorEditOptions & ImGuiColorEditFlags_AlphaBar); // Setup + int components = (flags & ImGuiColorEditFlags_NoAlpha) ? 3 : 4; bool alpha_bar = (flags & ImGuiColorEditFlags_AlphaBar) && !(flags & ImGuiColorEditFlags_NoAlpha); ImVec2 picker_pos = window->DC.CursorPos; float square_sz = SmallSquareSize(); @@ -10176,6 +10177,9 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl float bar1_pos_x = bar0_pos_x + bars_width + style.ItemInnerSpacing.x; float bars_triangles_half_sz = (float)(int)(bars_width * 0.20f); + float backup_initial_col[4]; + memcpy(backup_initial_col, col, components * sizeof(float)); + float wheel_thickness = sv_picker_size * 0.08f; float wheel_r_outer = sv_picker_size * 0.50f; float wheel_r_inner = wheel_r_outer - wheel_thickness; @@ -10291,7 +10295,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl ImVec4 ref_col_v4(ref_col[0], ref_col[1], ref_col[2], (flags & ImGuiColorEditFlags_NoAlpha) ? 1.0f : ref_col[3]); if (ColorButton("##original", ref_col_v4, (flags & (ImGuiColorEditFlags_HDR|ImGuiColorEditFlags_AlphaPreview|ImGuiColorEditFlags_AlphaPreviewHalf|ImGuiColorEditFlags_NoTooltip)), ImVec2(square_sz * 3, square_sz * 2))) { - memcpy(col, ref_col, ((flags & ImGuiColorEditFlags_NoAlpha) ? 3 : 4) * sizeof(float)); + memcpy(col, ref_col, components * sizeof(float)); value_changed = true; } } @@ -10421,7 +10425,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl EndGroup(); PopID(); - return value_changed; + return value_changed && memcmp(backup_initial_col, col, components * sizeof(float)); } // Horizontal separating line. From e23083a080909042d8eda880d14299080116c9d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Branimir=20Karad=C5=BEi=C4=87?= Date: Sat, 9 Dec 2017 13:47:54 -0800 Subject: [PATCH 689/921] =?UTF-8?q?Fixed=20warning:=20logical=20=E2=80=98a?= =?UTF-8?q?nd=E2=80=99=20of=20equal=20expressions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index f1c3af418..04105d524 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4517,7 +4517,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->Size = window->Collapsed ? window->TitleBarRect().GetSize() : window->SizeFull; if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Popup)) { - IM_ASSERT(window_size_x_set_by_api && window_size_x_set_by_api); // Submitted by BeginChild() + IM_ASSERT(window_size_x_set_by_api && window_size_y_set_by_api); // Submitted by BeginChild() window->Size = window->SizeFull; } From f72b002da876d783d72c63e0a4c41d2c7b519677 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 10 Dec 2017 16:05:47 +0100 Subject: [PATCH 690/921] Removed SetNextWindowContentWidth(), prefer using SetNextWindowContentSize(). Kept redirection function (will obsolete). (#246, #519, #1444) --- imgui.cpp | 8 +------- imgui.h | 4 ++-- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 04105d524..a9e4dce74 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -213,6 +213,7 @@ Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. Also read releases logs https://github.com/ocornut/imgui/releases for more details. + - 2017/12/10 (1.53) - removed SetNextWindowContentWidth(), prefer using SetNextWindowContentSize(). Kept redirection function (will obsolete). - 2017/11/27 (1.53) - renamed ImGuiTextBuffer::append() helper to appendf(), appendv() to appendfv(). If you copied the 'Log' demo in your code, it uses appendv() so that needs to be renamed. - 2017/11/18 (1.53) - Style, Begin: removed ImGuiWindowFlags_ShowBorders window flag. Borders are now fully set up in the ImGuiStyle structure (see e.g. style.FrameBorderSize, style.WindowBorderSize). Use ImGui::ShowStyleEditor() to look them up. Please note that the style system will keep evolving (hopefully stabilizing in Q1 2018), and so custom styles will probably subtly break over time. It is recommended you use the StyleColorsClassic(), StyleColorsDark(), StyleColorsLight() functions. @@ -5665,13 +5666,6 @@ void ImGui::SetNextWindowContentSize(const ImVec2& size) g.SetNextWindowContentSizeCond = ImGuiCond_Always; } -void ImGui::SetNextWindowContentWidth(float width) -{ - ImGuiContext& g = *GImGui; - g.SetNextWindowContentSizeVal = ImVec2(width, g.SetNextWindowContentSizeCond ? g.SetNextWindowContentSizeVal.y : 0.0f); - g.SetNextWindowContentSizeCond = ImGuiCond_Always; -} - void ImGui::SetNextWindowCollapsed(bool collapsed, ImGuiCond cond) { ImGuiContext& g = *GImGui; diff --git a/imgui.h b/imgui.h index 6bf33b771..5c426593a 100644 --- a/imgui.h +++ b/imgui.h @@ -159,8 +159,7 @@ namespace ImGui IMGUI_API void SetNextWindowPos(const ImVec2& pos, ImGuiCond cond = 0, const ImVec2& pivot = ImVec2(0,0)); // set next window position. call before Begin(). use pivot=(0.5f,0.5f) to center on given point, etc. IMGUI_API void SetNextWindowSize(const ImVec2& size, ImGuiCond cond = 0); // set next window size. set axis to 0.0f to force an auto-fit on this axis. call before Begin() IMGUI_API void SetNextWindowSizeConstraints(const ImVec2& size_min, const ImVec2& size_max, ImGuiSizeConstraintCallback custom_callback = NULL, void* custom_callback_data = NULL); // set next window size limits. use -1,-1 on either X/Y axis to preserve the current size. Use callback to apply non-trivial programmatic constraints. - IMGUI_API void SetNextWindowContentSize(const ImVec2& size); // set next window content size (enforce the range of scrollbars). set axis to 0.0f to leave it automatic. call before Begin() - IMGUI_API void SetNextWindowContentWidth(float width); // set next window content width (enforce the range of horizontal scrollbar). call before Begin() + IMGUI_API void SetNextWindowContentSize(const ImVec2& size); // set next window content size (~ enforce the range of scrollbars). set axis to 0.0f to leave it automatic. call before Begin() IMGUI_API void SetNextWindowCollapsed(bool collapsed, ImGuiCond cond = 0); // set next window collapsed state. call before Begin() IMGUI_API void SetNextWindowFocus(); // set next window to be focused / front-most. call before Begin() IMGUI_API void SetWindowPos(const ImVec2& pos, ImGuiCond cond = 0); // (not recommended) set current window position - call within Begin()/End(). prefer using SetNextWindowPos(), as this may incur tearing and side-effects. @@ -914,6 +913,7 @@ struct ImGuiIO #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS namespace ImGui { + static inline void SetNextWindowContentWidth(float width) { ImGui::SetNextWindowContentSize(ImVec2(width, 0.0f)); } // OBSOLETE 1.53+ (nb: original version preserved last Y value set by SetNextWindowContentSize()) static inline bool IsRootWindowOrAnyChildHovered(ImGuiHoveredFlags flags = 0) { return IsItemHovered(flags | ImGuiHoveredFlags_FlattenChilds); } // OBSOLETE 1.53+ use flags directly bool Begin(const char* name, bool* p_open, const ImVec2& size_on_first_use, float bg_alpha_override = -1.0f, ImGuiWindowFlags flags = 0); // OBSOLETE 1.52+. use SetNextWindowSize() instead if you want to set a window size. static inline void AlignFirstTextHeightToWidgets() { AlignTextToFramePadding(); } // OBSOLETE 1.52+ From 0872020c5c64cec0cfe5eaf060532865cb080dc2 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 10 Dec 2017 16:11:29 +0100 Subject: [PATCH 691/921] Comments --- imgui.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.h b/imgui.h index 5c426593a..8af775677 100644 --- a/imgui.h +++ b/imgui.h @@ -277,7 +277,7 @@ namespace ImGui // Widgets: Main IMGUI_API bool Button(const char* label, const ImVec2& size = ImVec2(0,0)); // button IMGUI_API bool SmallButton(const char* label); // button with FramePadding=(0,0) to easily embed within text - IMGUI_API bool InvisibleButton(const char* str_id, const ImVec2& size); + IMGUI_API bool InvisibleButton(const char* str_id, const ImVec2& size); // button behavior without the visuals, useful to build custom behaviors using the public api (along with IsItemActive, IsItemHovered, etc.) IMGUI_API void Image(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0,0), const ImVec2& uv1 = ImVec2(1,1), const ImVec4& tint_col = ImVec4(1,1,1,1), const ImVec4& border_col = ImVec4(0,0,0,0)); IMGUI_API bool ImageButton(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0,0), const ImVec2& uv1 = ImVec2(1,1), int frame_padding = -1, const ImVec4& bg_col = ImVec4(0,0,0,0), const ImVec4& tint_col = ImVec4(1,1,1,1)); // <0 frame_padding uses default frame padding settings. 0 for no padding IMGUI_API bool Checkbox(const char* label, bool* v); From b75acc21b09fdcb3a8f9d7a84ba6cc197519f09d Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 10 Dec 2017 16:48:18 +0100 Subject: [PATCH 692/921] Fix for border under title bar when WindowBorderSize == 0 and FrameBorderSize > 0 --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index a9e4dce74..ec20f7daf 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4766,7 +4766,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->DrawList->AddLine(border.Min, border.Max, GetColorU32(ImGuiCol_SeparatorActive), ImMax(1.0f, window_border_size)); } if (style.FrameBorderSize > 0 && !(flags & ImGuiWindowFlags_NoTitleBar)) - window->DrawList->AddLine(title_bar_rect.GetBL()+ImVec2(1,-1), title_bar_rect.GetBR()+ImVec2(-1,-1), GetColorU32(ImGuiCol_Border), style.FrameBorderSize); + window->DrawList->AddLine(title_bar_rect.GetBL() + ImVec2(style.WindowBorderSize, -1), title_bar_rect.GetBR() + ImVec2(-style.WindowBorderSize,-1), GetColorU32(ImGuiCol_Border), style.FrameBorderSize); } // Store a backup of SizeFull which we will use next frame to decide if we need scrollbars. From 20ba79aa56dd27fd9f52fd59f36bbd92d3ac23a4 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 10 Dec 2017 17:02:41 +0100 Subject: [PATCH 693/921] Demo: Added "No close" option. --- imgui_demo.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 7c3c71e2e..e1d7a99fb 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -170,6 +170,7 @@ void ImGui::ShowTestWindow(bool* p_open) static bool no_move = false; static bool no_resize = false; static bool no_collapse = false; + static bool no_close = false; // Demonstrate the various window flags. Typically you would just use the default. ImGuiWindowFlags window_flags = 0; @@ -179,6 +180,8 @@ void ImGui::ShowTestWindow(bool* p_open) if (no_move) window_flags |= ImGuiWindowFlags_NoMove; if (no_resize) window_flags |= ImGuiWindowFlags_NoResize; if (no_collapse) window_flags |= ImGuiWindowFlags_NoCollapse; + if (no_close) p_open = NULL; // Don't pass our bool* to Begin + ImGui::SetNextWindowSize(ImVec2(550,680), ImGuiCond_FirstUseEver); if (!ImGui::Begin("ImGui Demo", p_open, window_flags)) { @@ -241,6 +244,7 @@ void ImGui::ShowTestWindow(bool* p_open) ImGui::Checkbox("No move", &no_move); ImGui::SameLine(150); ImGui::Checkbox("No resize", &no_resize); ImGui::SameLine(300); ImGui::Checkbox("No collapse", &no_collapse); + ImGui::Checkbox("No close", &no_close); if (ImGui::TreeNode("Style")) { @@ -248,7 +252,7 @@ void ImGui::ShowTestWindow(bool* p_open) ImGui::TreePop(); } - if (ImGui::TreeNode("Logging")) + if (ImGui::TreeNode("Capture/Logging")) { ImGui::TextWrapped("The logging API redirects all text output so you can easily capture the content of a window or a block. Tree nodes can be automatically expanded. You can also call ImGui::LogText() to output directly to the log without a visual output."); ImGui::LogButtons(); From a9b01600ac309706ac6f798ca26abfa06d3c896e Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 10 Dec 2017 17:24:10 +0100 Subject: [PATCH 694/921] Internals: window->InnerRect includes removal of borders so it'll be easier to use from other locations. --- imgui.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index ec20f7daf..522d2b156 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4874,10 +4874,10 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // Inner rectangle // We set this up after processing the resize grip so that our clip rectangle doesn't lag by a frame // Note that if our window is collapsed we will end up with a null clipping rectangle which is the correct behavior. - window->InnerRect.Min.x = title_bar_rect.Min.x; - window->InnerRect.Min.y = title_bar_rect.Max.y + window->MenuBarHeight(); - window->InnerRect.Max.x = window->Pos.x + window->Size.x - window->ScrollbarSizes.x; - window->InnerRect.Max.y = window->Pos.y + window->Size.y - window->ScrollbarSizes.y; + window->InnerRect.Min.x = title_bar_rect.Min.x + window->WindowBorderSize; + window->InnerRect.Min.y = title_bar_rect.Max.y + window->MenuBarHeight() + (((flags & ImGuiWindowFlags_MenuBar) || !(flags & ImGuiWindowFlags_NoTitleBar)) ? style.FrameBorderSize : window->WindowBorderSize); + window->InnerRect.Max.x = window->Pos.x + window->Size.x - window->ScrollbarSizes.x - window->WindowBorderSize; + window->InnerRect.Max.y = window->Pos.y + window->Size.y - window->ScrollbarSizes.y - window->WindowBorderSize; //window->DrawList->AddRect(window->InnerRect.Min, window->InnerRect.Max, IM_COL32_WHITE); // After Begin() we fill the last item / hovered data using the title bar data. Make that a standard behavior (to allow usage of context menus on title bar only, etc.). @@ -4890,10 +4890,10 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // Force round operator last to ensure that e.g. (int)(max.x-min.x) in user's render code produce correct result. const float border_size = window->WindowBorderSize; ImRect clip_rect; - clip_rect.Min.x = ImFloor(0.5f + window->InnerRect.Min.x + ImMax(border_size, ImFloor(window->WindowPadding.x*0.5f))); - clip_rect.Min.y = ImFloor(0.5f + window->InnerRect.Min.y + border_size); - clip_rect.Max.x = ImFloor(0.5f + window->InnerRect.Max.x - ImMax(border_size, ImFloor(window->WindowPadding.x*0.5f))); - clip_rect.Max.y = ImFloor(0.5f + window->InnerRect.Max.y - border_size); + clip_rect.Min.x = ImFloor(0.5f + window->InnerRect.Min.x + ImMax(0.0f, ImFloor(window->WindowPadding.x*0.5f - border_size))); + clip_rect.Min.y = ImFloor(0.5f + window->InnerRect.Min.y); + clip_rect.Max.x = ImFloor(0.5f + window->InnerRect.Max.x - ImMax(0.0f, ImFloor(window->WindowPadding.x*0.5f - border_size))); + clip_rect.Max.y = ImFloor(0.5f + window->InnerRect.Max.y); PushClipRect(clip_rect.Min, clip_rect.Max, true); // Clear 'accessed' flag last thing (After PushClipRect which will set the flag. We want the flag to stay false when the default "Debug" window is unused) From 7ac1583411095fe8a82ccbc56d09777f87222e9d Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 10 Dec 2017 17:27:37 +0100 Subject: [PATCH 695/921] Scrollbar: Minor simplication of the code using InnerRect data. --- imgui.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 522d2b156..4aba5aa82 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4994,10 +4994,8 @@ void ImGui::Scrollbar(ImGuiLayoutType direction) const ImRect window_rect = window->Rect(); const float border_size = window->WindowBorderSize; ImRect bb = horizontal - ? ImRect(window->Pos.x + border_size, window_rect.Max.y - style.ScrollbarSize, window_rect.Max.x - other_scrollbar_size_w - border_size, window_rect.Max.y - border_size) - : ImRect(window_rect.Max.x - style.ScrollbarSize, window->Pos.y + border_size, window_rect.Max.x - border_size, window_rect.Max.y - other_scrollbar_size_w - border_size); - if (!horizontal) - bb.Min.y += window->TitleBarHeight() + ((window->Flags & ImGuiWindowFlags_MenuBar) ? window->MenuBarHeight() : 0.0f); + ? ImRect(window->InnerRect.Min.x, window_rect.Max.y - style.ScrollbarSize, window->InnerRect.Max.x, window_rect.Max.y - border_size) + : ImRect(window_rect.Max.x - style.ScrollbarSize, window->InnerRect.Min.y, window_rect.Max.x - border_size, window->InnerRect.Max.y); if (bb.GetWidth() <= 0.0f || bb.GetHeight() <= 0.0f) return; From eab6333a0b96bd30413bb17408303a5df438ffde Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 10 Dec 2017 17:36:30 +0100 Subject: [PATCH 696/921] SetNextWindowContentSize() adjust for client->window size, but the fate of borders isn't really clear for now (until now we always tried to make borders not affect layout, so if we want a 200x200 fully visible space with borders and zero window padding user need to include the borders) (#1490) --- imgui.cpp | 4 +++- imgui.h | 2 +- imgui_internal.h | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 4aba5aa82..88b6a0c29 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4388,7 +4388,9 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) } if (g.SetNextWindowContentSizeCond) { + // Adjust passed "client size" to become a "window size" window->SizeContentsExplicit = g.SetNextWindowContentSizeVal; + window->SizeContentsExplicit.y += window->TitleBarHeight() + window->MenuBarHeight(); g.SetNextWindowContentSizeCond = 0; } else if (first_begin_of_the_frame) @@ -5660,7 +5662,7 @@ void ImGui::SetNextWindowSizeConstraints(const ImVec2& size_min, const ImVec2& s void ImGui::SetNextWindowContentSize(const ImVec2& size) { ImGuiContext& g = *GImGui; - g.SetNextWindowContentSizeVal = size; + g.SetNextWindowContentSizeVal = size; // In Begin() we will add the size of window decorations (title bar, menu etc.) to that to form a SizeContents value. g.SetNextWindowContentSizeCond = ImGuiCond_Always; } diff --git a/imgui.h b/imgui.h index 8af775677..e57a81432 100644 --- a/imgui.h +++ b/imgui.h @@ -159,7 +159,7 @@ namespace ImGui IMGUI_API void SetNextWindowPos(const ImVec2& pos, ImGuiCond cond = 0, const ImVec2& pivot = ImVec2(0,0)); // set next window position. call before Begin(). use pivot=(0.5f,0.5f) to center on given point, etc. IMGUI_API void SetNextWindowSize(const ImVec2& size, ImGuiCond cond = 0); // set next window size. set axis to 0.0f to force an auto-fit on this axis. call before Begin() IMGUI_API void SetNextWindowSizeConstraints(const ImVec2& size_min, const ImVec2& size_max, ImGuiSizeConstraintCallback custom_callback = NULL, void* custom_callback_data = NULL); // set next window size limits. use -1,-1 on either X/Y axis to preserve the current size. Use callback to apply non-trivial programmatic constraints. - IMGUI_API void SetNextWindowContentSize(const ImVec2& size); // set next window content size (~ enforce the range of scrollbars). set axis to 0.0f to leave it automatic. call before Begin() + IMGUI_API void SetNextWindowContentSize(const ImVec2& size); // set next window content size (~ enforce the range of scrollbars). not including window decorations (title bar, menu bar, etc.). set an axis to 0.0f to leave it automatic. call before Begin() IMGUI_API void SetNextWindowCollapsed(bool collapsed, ImGuiCond cond = 0); // set next window collapsed state. call before Begin() IMGUI_API void SetNextWindowFocus(); // set next window to be focused / front-most. call before Begin() IMGUI_API void SetWindowPos(const ImVec2& pos, ImGuiCond cond = 0); // (not recommended) set current window position - call within Begin()/End(). prefer using SetNextWindowPos(), as this may incur tearing and side-effects. diff --git a/imgui_internal.h b/imgui_internal.h index 3774a8b83..3238c90a6 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -630,7 +630,7 @@ struct IMGUI_API ImGuiDrawContext ImVec2 CursorPos; ImVec2 CursorPosPrevLine; ImVec2 CursorStartPos; - ImVec2 CursorMaxPos; // Implicitly calculate the size of our contents, always extending. Saved into window->SizeContents at the end of the frame + ImVec2 CursorMaxPos; // Used to implicitly calculate the size of our contents, always growing during the frame. Turned into window->SizeContents at the beginning of next frame float CurrentLineHeight; float CurrentLineTextBaseOffset; float PrevLineHeight; @@ -716,7 +716,7 @@ struct IMGUI_API ImGuiWindow ImVec2 Size; // Current size (==SizeFull or collapsed title bar size) ImVec2 SizeFull; // Size when non collapsed ImVec2 SizeFullAtLastBegin; // Copy of SizeFull at the end of Begin. This is the reference value we'll use on the next frame to decide if we need scrollbars. - ImVec2 SizeContents; // Size of contents (== extents reach of the drawing cursor) from previous frame + ImVec2 SizeContents; // Size of contents (== extents reach of the drawing cursor) from previous frame. Include decoration, window title, border, menu, etc. ImVec2 SizeContentsExplicit; // Size of contents explicitly set by the user via SetNextWindowContentSize() ImRect ContentsRegionRect; // Maximum visible content position in window coordinates. ~~ (SizeContentsExplicit ? SizeContentsExplicit : Size - ScrollbarSizes) - CursorStartPos, per axis ImVec2 WindowPadding; // Window padding at the time of begin. From 080f61858f03f5dbea3611ef6f1027febe277d7b Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 10 Dec 2017 17:57:27 +0100 Subject: [PATCH 697/921] Sorted typedefs/enumations forward declarations in imgui.h --- imgui.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/imgui.h b/imgui.h index e57a81432..a65e71336 100644 --- a/imgui.h +++ b/imgui.h @@ -72,18 +72,18 @@ typedef unsigned int ImGuiID; // unique ID used by widgets (typically hash typedef unsigned short ImWchar; // character for keyboard input/display typedef void* ImTextureID; // user data to identify a texture (this is whatever to you want it to be! read the FAQ about ImTextureID in imgui.cpp) typedef int ImGuiCol; // enum: a color identifier for styling // enum ImGuiCol_ -typedef int ImGuiStyleVar; // enum: a variable identifier for styling // enum ImGuiStyleVar_ +typedef int ImGuiCond; // enum: a condition for Set*() // enum ImGuiCond_ typedef int ImGuiKey; // enum: a key identifier (ImGui-side enum) // enum ImGuiKey_ typedef int ImGuiMouseCursor; // enum: a mouse cursor identifier // enum ImGuiMouseCursor_ -typedef int ImGuiCond; // enum: a condition for Set*() // enum ImGuiCond_ -typedef int ImDrawCornerFlags; // flags: corner flags for AddRect*() etc. // enum ImDrawCornerFlags_ -typedef int ImGuiColorEditFlags; // flags: color edit flags for Color*() // enum ImGuiColorEditFlags_ -typedef int ImGuiWindowFlags; // flags: window flags for Begin*() // enum ImGuiWindowFlags_ +typedef int ImGuiStyleVar; // enum: a variable identifier for styling // enum ImGuiStyleVar_ +typedef int ImDrawCornerFlags; // flags: for ImDrawList::AddRect*() etc. // enum ImDrawCornerFlags_ +typedef int ImGuiColorEditFlags; // flags: for ColorEdit*(), ColorPicker*() // enum ImGuiColorEditFlags_ typedef int ImGuiColumnsFlags; // flags: for *Columns*() // enum ImGuiColumnsFlags_ +typedef int ImGuiHoveredFlags; // flags: for IsItemHovered() // enum ImGuiHoveredFlags_ typedef int ImGuiInputTextFlags; // flags: for InputText*() // enum ImGuiInputTextFlags_ typedef int ImGuiSelectableFlags; // flags: for Selectable() // enum ImGuiSelectableFlags_ -typedef int ImGuiTreeNodeFlags; // flags: for TreeNode*(), Collapsing*() // enum ImGuiTreeNodeFlags_ -typedef int ImGuiHoveredFlags; // flags: for IsItemHovered() // enum ImGuiHoveredFlags_ +typedef int ImGuiTreeNodeFlags; // flags: for TreeNode*(),CollapsingHeader()// enum ImGuiTreeNodeFlags_ +typedef int ImGuiWindowFlags; // flags: for Begin*() // enum ImGuiWindowFlags_ typedef int (*ImGuiTextEditCallback)(ImGuiTextEditCallbackData *data); typedef void (*ImGuiSizeConstraintCallback)(ImGuiSizeConstraintCallbackData* data); #ifdef _MSC_VER From e3e0326ea9d0fdac19d447301cc9953fc31b0f67 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 10 Dec 2017 18:08:59 +0100 Subject: [PATCH 698/921] Exposed BeginCombo() publicly. --- imgui.cpp | 8 +++++--- imgui.h | 25 +++++++++++++++++++++---- imgui_internal.h | 17 ----------------- 3 files changed, 26 insertions(+), 24 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 88b6a0c29..bef60f64c 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9166,7 +9166,7 @@ void ImGui::EndCombo() EndPopup(); } -// Combo box function. +// Old API, prefer using BeginCombo() nowadays if you can. bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(void*, int, const char**), void* data, int items_count, int popup_max_height_in_items) { ImGuiContext& g = *GImGui; @@ -9175,16 +9175,18 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi if (*current_item >= 0 && *current_item < items_count) items_getter(data, *current_item, &preview_text); + // The old Combo() API exposed "popup_max_height_in_items", however the new more general BeginCombo() API doesn't, so we emulate it here. if (popup_max_height_in_items != -1 && !g.SetNextWindowSizeConstraint) { float popup_max_height = CalcMaxPopupHeightFromItemCount(popup_max_height_in_items); SetNextWindowSizeConstraints(ImVec2(0,0), ImVec2(FLT_MAX, popup_max_height)); } + if (!BeginCombo(label, preview_text, 0)) return false; // Display items - // FIXME-OPT: Use clipper + // FIXME-OPT: Use clipper (if we can disable it on the appearing frame to make sure our call to SetScrollHere() is processed) bool value_changed = false; for (int i = 0; i < items_count; i++) { @@ -9236,7 +9238,7 @@ static bool Items_SingleStringGetter(void* data, int idx, const char** out_text) } // Combo box helper allowing to pass an array of strings. -bool ImGui::Combo(const char* label, int* current_item, const char* const* items, int items_count, int height_in_items) +bool ImGui::Combo(const char* label, int* current_item, const char* const items[], int items_count, int height_in_items) { const bool value_changed = Combo(label, current_item, Items_ArrayGetter, (void*)items, items_count, height_in_items); return value_changed; diff --git a/imgui.h b/imgui.h index a65e71336..a85d68b72 100644 --- a/imgui.h +++ b/imgui.h @@ -79,6 +79,7 @@ typedef int ImGuiStyleVar; // enum: a variable identifier for styling typedef int ImDrawCornerFlags; // flags: for ImDrawList::AddRect*() etc. // enum ImDrawCornerFlags_ typedef int ImGuiColorEditFlags; // flags: for ColorEdit*(), ColorPicker*() // enum ImGuiColorEditFlags_ typedef int ImGuiColumnsFlags; // flags: for *Columns*() // enum ImGuiColumnsFlags_ +typedef int ImGuiComboFlags; // flags: for BeginCombo() // enum ImGuiComboFlags_ typedef int ImGuiHoveredFlags; // flags: for IsItemHovered() // enum ImGuiHoveredFlags_ typedef int ImGuiInputTextFlags; // flags: for InputText*() // enum ImGuiInputTextFlags_ typedef int ImGuiSelectableFlags; // flags: for Selectable() // enum ImGuiSelectableFlags_ @@ -284,15 +285,20 @@ namespace ImGui IMGUI_API bool CheckboxFlags(const char* label, unsigned int* flags, unsigned int flags_value); IMGUI_API bool RadioButton(const char* label, bool active); IMGUI_API bool RadioButton(const char* label, int* v, int v_button); - IMGUI_API bool Combo(const char* label, int* current_item, const char* const* items, int items_count, int height_in_items = -1); - IMGUI_API bool Combo(const char* label, int* current_item, const char* items_separated_by_zeros, int height_in_items = -1); // separate items with \0, end item-list with \0\0 - IMGUI_API bool Combo(const char* label, int* current_item, bool (*items_getter)(void* data, int idx, const char** out_text), void* data, int items_count, int height_in_items = -1); IMGUI_API void PlotLines(const char* label, const float* values, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0,0), int stride = sizeof(float)); IMGUI_API void PlotLines(const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0,0)); IMGUI_API void PlotHistogram(const char* label, const float* values, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0,0), int stride = sizeof(float)); IMGUI_API void PlotHistogram(const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0,0)); IMGUI_API void ProgressBar(float fraction, const ImVec2& size_arg = ImVec2(-1,0), const char* overlay = NULL); + // Widgets: Combo Box + // The new BeginCombo()/EndCombo() api allows you to manage your contents and selection state however you want it. + IMGUI_API bool BeginCombo(const char* label, const char* preview_value, ImGuiComboFlags flags = 0); + IMGUI_API void EndCombo(); + IMGUI_API bool Combo(const char* label, int* current_item, const char* const items[], int items_count, int popup_max_height_in_items = -1); + IMGUI_API bool Combo(const char* label, int* current_item, const char* items_separated_by_zeros, int popup_max_height_in_items = -1); // Separate items with \0 within a string, end item-list with \0\0. e.g. "One\0Two\0Three\0" + IMGUI_API bool Combo(const char* label, int* current_item, bool(*items_getter)(void* data, int idx, const char** out_text), void* data, int items_count, int popup_max_height_in_items = -1); + // Widgets: Drags (tip: ctrl+click on a drag box to input with keyboard. manually input values aren't clamped, can go off-bounds) // For all the Float2/Float3/Float4/Int2/Int3/Int4 versions of every functions, note that a 'float v[X]' function argument is the same as 'float* v', the array syntax is just a way to document the number of elements that are expected to be accessible. You can pass address of your first element out of a contiguous set, e.g. &myvector.x 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 @@ -403,7 +409,7 @@ namespace ImGui IMGUI_API bool IsPopupOpen(const char* str_id); // return true if the popup is open IMGUI_API void CloseCurrentPopup(); // close the popup we have begin-ed into. clicking on a MenuItem or Selectable automatically close the current popup. - // Logging: all text output from interface is redirected to tty/file/clipboard. By default, tree nodes are automatically opened during logging. + // Logging/Capture: all text output from interface is captured to tty/file/clipboard. By default, tree nodes are automatically opened during logging. IMGUI_API void LogToTTY(int max_depth = -1); // start logging to tty IMGUI_API void LogToFile(int max_depth = -1, const char* filename = NULL); // start logging to file IMGUI_API void LogToClipboard(int max_depth = -1); // start logging to OS clipboard @@ -575,6 +581,17 @@ enum ImGuiSelectableFlags_ ImGuiSelectableFlags_AllowDoubleClick = 1 << 2 // Generate press events on double clicks too }; +// Flags for ImGui::BeginCombo() +enum ImGuiComboFlags_ +{ + ImGuiComboFlags_PopupAlignLeft = 1 << 0, // Align the popup toward the left by default + ImGuiComboFlags_HeightSmall = 1 << 1, // Max ~4 items visible. Tip: If you want your combo popup to be a specific size you can use SetNextWindowSizeConstraints() prior to calling BeginCombo() + ImGuiComboFlags_HeightRegular = 1 << 2, // Max ~8 items visible (default) + ImGuiComboFlags_HeightLarge = 1 << 3, // Max ~20 items visible + ImGuiComboFlags_HeightLargest = 1 << 4, // As many fitting items as possible + ImGuiComboFlags_HeightMask_ = ImGuiComboFlags_HeightSmall | ImGuiComboFlags_HeightRegular | ImGuiComboFlags_HeightLarge | ImGuiComboFlags_HeightLargest +}; + // Flags for ImGui::IsItemHovered(), ImGui::IsWindowHovered() enum ImGuiHoveredFlags_ { diff --git a/imgui_internal.h b/imgui_internal.h index 3238c90a6..18e44c443 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -48,7 +48,6 @@ typedef int ImGuiButtonFlags; // flags: for ButtonEx(), ButtonBehavior() typedef int ImGuiItemFlags; // flags: for PushItemFlag() // enum ImGuiItemFlags_ typedef int ImGuiSeparatorFlags; // flags: for Separator() - internal // enum ImGuiSeparatorFlags_ typedef int ImGuiSliderFlags; // flags: for SliderBehavior() // enum ImGuiSliderFlags_ -typedef int ImGuiComboFlags; // flags: for BeginCombo() // enum ImGuiComboFlags_ //------------------------------------------------------------------------- // STB libraries @@ -210,18 +209,6 @@ enum ImGuiSelectableFlagsPrivate_ ImGuiSelectableFlags_DrawFillAvailWidth = 1 << 6 }; -enum ImGuiComboFlags_ -{ - ImGuiComboFlags_PopupAlignLeft = 1 << 0, // Align the popup toward the left by default - - // If you want your combo popup to be a specific size you can use SetNextWindowSizeConstraints() prior to calling BeginCombo() - ImGuiComboFlags_HeightSmall = 1 << 1, // Max ~4 items visible - ImGuiComboFlags_HeightRegular = 1 << 2, // Max ~8 items visible (default) - ImGuiComboFlags_HeightLarge = 1 << 3, // Max ~20 items visible - ImGuiComboFlags_HeightLargest = 1 << 4, // As many fitting items as possible - ImGuiComboFlags_HeightMask_ = ImGuiComboFlags_HeightSmall | ImGuiComboFlags_HeightRegular | ImGuiComboFlags_HeightLarge | ImGuiComboFlags_HeightLargest -}; - enum ImGuiSeparatorFlags_ { ImGuiSeparatorFlags_Horizontal = 1 << 0, // Axis default to current layout type, so generally Horizontal unless e.g. in a menu bar @@ -859,10 +846,6 @@ namespace ImGui IMGUI_API void EndColumns(); // close columns IMGUI_API void PushColumnClipRect(int column_index = -1); - // FIXME-WIP: New Combo API - IMGUI_API bool BeginCombo(const char* label, const char* preview_value, ImGuiComboFlags flags = 0); - IMGUI_API void EndCombo(); - // NB: All position are in absolute pixels coordinates (never using window coordinates internally) // AVOID USING OUTSIDE OF IMGUI.CPP! NOT FOR PUBLIC CONSUMPTION. THOSE FUNCTIONS ARE A MESS. THEIR SIGNATURE AND BEHAVIOR WILL CHANGE, THEY NEED TO BE REFACTORED INTO SOMETHING DECENT. IMGUI_API void RenderText(ImVec2 pos, const char* text, const char* text_end = NULL, bool hide_text_after_hash = true); From 1096e14356270e842bbaecd3489e9b44479ad733 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 10 Dec 2017 18:34:32 +0100 Subject: [PATCH 699/921] ImFont: Added GetDebugName() helper. --- imgui.h | 1 + 1 file changed, 1 insertion(+) diff --git a/imgui.h b/imgui.h index a85d68b72..9c35c494d 100644 --- a/imgui.h +++ b/imgui.h @@ -1568,6 +1568,7 @@ struct ImFont IMGUI_API void SetFallbackChar(ImWchar c); float GetCharAdvance(ImWchar c) const { return ((int)c < IndexAdvanceX.Size) ? IndexAdvanceX[(int)c] : FallbackAdvanceX; } bool IsLoaded() const { return ContainerAtlas != NULL; } + const char* GetDebugName() const { return ConfigData ? ConfigData->Name : ""; } // 'max_width' stops rendering after a certain width (could be turned into a 2d size). FLT_MAX to disable. // 'wrap_width' enable automatic word-wrapping across multiple lines to fit into given width. 0.0f to disable. From 4b8857d536e533e6cbca764d43d54acb35a1930e Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 10 Dec 2017 18:45:05 +0100 Subject: [PATCH 700/921] Demo: About box tweaks. --- imgui_demo.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index e1d7a99fb..82dcac3d6 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -156,11 +156,11 @@ void ImGui::ShowTestWindow(bool* p_open) if (show_app_style_editor) { ImGui::Begin("Style Editor", &show_app_style_editor); ImGui::ShowStyleEditor(); ImGui::End(); } if (show_app_about) { - ImGui::Begin("About ImGui", &show_app_about, ImGuiWindowFlags_AlwaysAutoResize); + ImGui::Begin("About Dear ImGui", &show_app_about, ImGuiWindowFlags_AlwaysAutoResize); ImGui::Text("dear imgui, %s", ImGui::GetVersion()); ImGui::Separator(); - ImGui::Text("By Omar Cornut and all github contributors."); - ImGui::Text("ImGui is licensed under the MIT License, see LICENSE for more information."); + ImGui::Text("By Omar Cornut and all dear imgui contributors."); + ImGui::Text("Dear ImGui is licensed under the MIT License, see LICENSE for more information."); ImGui::End(); } @@ -222,7 +222,7 @@ void ImGui::ShowTestWindow(bool* p_open) { ImGui::MenuItem("Metrics", NULL, &show_app_metrics); ImGui::MenuItem("Style Editor", NULL, &show_app_style_editor); - ImGui::MenuItem("About ImGui", NULL, &show_app_about); + ImGui::MenuItem("About Dear ImGui", NULL, &show_app_about); ImGui::EndMenu(); } ImGui::EndMenuBar(); From 71296910a02fe9cc6488ee71daf293396c2a5786 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 10 Dec 2017 18:49:47 +0100 Subject: [PATCH 701/921] Demo: Tweaks and spacing. Stopped using rand() function in demo code. --- imgui_demo.cpp | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 82dcac3d6..fc8bbec95 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -80,7 +80,7 @@ static void ShowExampleAppLongText(bool* p_open); static void ShowExampleAppAutoResize(bool* p_open); static void ShowExampleAppConstrainedResize(bool* p_open); static void ShowExampleAppFixedOverlay(bool* p_open); -static void ShowExampleAppManipulatingWindowTitle(bool* p_open); +static void ShowExampleAppWindowTitles(bool* p_open); static void ShowExampleAppCustomRendering(bool* p_open); static void ShowExampleAppMainMenuBar(); static void ShowExampleMenuFile(); @@ -133,27 +133,27 @@ void ImGui::ShowTestWindow(bool* p_open) static bool show_app_auto_resize = false; static bool show_app_constrained_resize = false; static bool show_app_fixed_overlay = false; - static bool show_app_manipulating_window_title = false; + static bool show_app_window_titles = false; static bool show_app_custom_rendering = false; static bool show_app_style_editor = false; static bool show_app_metrics = false; static bool show_app_about = false; - if (show_app_main_menu_bar) ShowExampleAppMainMenuBar(); - if (show_app_console) ShowExampleAppConsole(&show_app_console); - if (show_app_log) ShowExampleAppLog(&show_app_log); - if (show_app_layout) ShowExampleAppLayout(&show_app_layout); - if (show_app_property_editor) ShowExampleAppPropertyEditor(&show_app_property_editor); - if (show_app_long_text) ShowExampleAppLongText(&show_app_long_text); - if (show_app_auto_resize) ShowExampleAppAutoResize(&show_app_auto_resize); - if (show_app_constrained_resize) ShowExampleAppConstrainedResize(&show_app_constrained_resize); - if (show_app_fixed_overlay) ShowExampleAppFixedOverlay(&show_app_fixed_overlay); - if (show_app_manipulating_window_title) ShowExampleAppManipulatingWindowTitle(&show_app_manipulating_window_title); - if (show_app_custom_rendering) ShowExampleAppCustomRendering(&show_app_custom_rendering); + if (show_app_main_menu_bar) ShowExampleAppMainMenuBar(); + if (show_app_console) ShowExampleAppConsole(&show_app_console); + if (show_app_log) ShowExampleAppLog(&show_app_log); + if (show_app_layout) ShowExampleAppLayout(&show_app_layout); + if (show_app_property_editor) ShowExampleAppPropertyEditor(&show_app_property_editor); + if (show_app_long_text) ShowExampleAppLongText(&show_app_long_text); + if (show_app_auto_resize) ShowExampleAppAutoResize(&show_app_auto_resize); + if (show_app_constrained_resize) ShowExampleAppConstrainedResize(&show_app_constrained_resize); + if (show_app_fixed_overlay) ShowExampleAppFixedOverlay(&show_app_fixed_overlay); + if (show_app_window_titles) ShowExampleAppWindowTitles(&show_app_window_titles); + if (show_app_custom_rendering) ShowExampleAppCustomRendering(&show_app_custom_rendering); - if (show_app_metrics) ImGui::ShowMetricsWindow(&show_app_metrics); - if (show_app_style_editor) { ImGui::Begin("Style Editor", &show_app_style_editor); ImGui::ShowStyleEditor(); ImGui::End(); } + if (show_app_metrics) { ImGui::ShowMetricsWindow(&show_app_metrics); } + if (show_app_style_editor) { ImGui::Begin("Style Editor", &show_app_style_editor); ImGui::ShowStyleEditor(); ImGui::End(); } if (show_app_about) { ImGui::Begin("About Dear ImGui", &show_app_about, ImGuiWindowFlags_AlwaysAutoResize); @@ -214,7 +214,7 @@ void ImGui::ShowTestWindow(bool* p_open) ImGui::MenuItem("Auto-resizing window", NULL, &show_app_auto_resize); ImGui::MenuItem("Constrained-resizing window", NULL, &show_app_constrained_resize); ImGui::MenuItem("Simple overlay", NULL, &show_app_fixed_overlay); - ImGui::MenuItem("Manipulating window title", NULL, &show_app_manipulating_window_title); + ImGui::MenuItem("Manipulating window titles", NULL, &show_app_window_titles); ImGui::MenuItem("Custom rendering", NULL, &show_app_custom_rendering); ImGui::EndMenu(); } @@ -2269,8 +2269,8 @@ static void ShowExampleAppFixedOverlay(bool* p_open) } // Demonstrate using "##" and "###" in identifiers to manipulate ID generation. -// Read section "How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs." about ID. -static void ShowExampleAppManipulatingWindowTitle(bool*) +// This apply to regular items as well. Read FAQ section "How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs." for details. +static void ShowExampleAppWindowTitles(bool*) { // By default, Windows are uniquely identified by their title. // You can use the "##" and "###" markers to manipulate the display/ID. @@ -2288,7 +2288,7 @@ static void ShowExampleAppManipulatingWindowTitle(bool*) // Using "###" to display a changing title but keep a static identifier "AnimatedTitle" char buf[128]; - sprintf(buf, "Animated title %c %d###AnimatedTitle", "|/-\\"[(int)(ImGui::GetTime()/0.25f)&3], rand()); + sprintf(buf, "Animated title %c %d###AnimatedTitle", "|/-\\"[(int)(ImGui::GetTime()/0.25f)&3], ImGui::GetFrameCount()); ImGui::SetNextWindowPos(ImVec2(100,300), ImGuiCond_FirstUseEver); ImGui::Begin(buf); ImGui::Text("This window has a changing title."); @@ -2774,7 +2774,7 @@ static void ShowExampleAppLog(bool* p_open) if (time - last_time >= 0.20f && !ImGui::GetIO().KeyCtrl) { const char* random_words[] = { "system", "info", "warning", "error", "fatal", "notice", "log" }; - log.AddLog("[%s] Hello, time is %.1f, rand() %d\n", random_words[rand() % IM_ARRAYSIZE(random_words)], time, (int)rand()); + log.AddLog("[%s] Hello, time is %.1f, frame count is %d\n", random_words[rand() % IM_ARRAYSIZE(random_words)], time, ImGui::GetFrameCount()); last_time = time; } From e67f3809ed7c9c0ea727fa148ddc45fd37c3b848 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Branimir=20Karad=C5=BEi=C4=87?= Date: Sun, 10 Dec 2017 17:20:28 -0800 Subject: [PATCH 702/921] Replaced obsolete function with new one. --- imgui_demo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index fc8bbec95..6c6952a3f 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1651,7 +1651,7 @@ void ImGui::ShowTestWindow(bool* p_open) if (ImGui::TreeNode("Horizontal Scrolling")) { - ImGui::SetNextWindowContentWidth(1500); + ImGui::SetNextWindowContentSize(ImVec2(1500.0f, 0.0f)); ImGui::BeginChild("##ScrollingRegion", ImVec2(0, ImGui::GetFontSize() * 20), false, ImGuiWindowFlags_HorizontalScrollbar); ImGui::Columns(10); int ITEMS_COUNT = 2000; From 6d93011fdf781ed18748af18d7434b5c245da456 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 11 Dec 2017 10:25:44 +0100 Subject: [PATCH 703/921] alloca fix to allow Clang with Microsoft CodeGen path --- imgui_draw.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 2c937e597..7a5bb2dee 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -22,6 +22,9 @@ #if !defined(alloca) #ifdef _WIN32 #include // alloca +#if !defined(alloca) +#define alloca _alloca // for clang with MS Codegen +#endif #elif defined(__GLIBC__) || defined(__sun) #include // alloca #else From 9fd15defe485b8341ffe9368207ebdc96d65fc45 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 11 Dec 2017 16:19:37 +0100 Subject: [PATCH 704/921] Added an implementation of SetItemDefaultFocus() in the master branch for combo patterns to use and be more forward-compatible. (#787) --- imgui.cpp | 15 ++++++++++++--- imgui.h | 9 +++++++-- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index bef60f64c..9a7e1b87f 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -5884,6 +5884,15 @@ void ImGui::SetScrollHere(float center_y_ratio) SetScrollFromPosY(target_y, center_y_ratio); } +// FIXME-NAV: This function is a placeholder for the upcoming Navigation branch + Focusing features. +// In the current branch this function will only set the scrolling, in the navigation branch it will also set your navigation cursor. +// Prefer using "SetItemDefaultFocus()" over "if (IsWindowAppearing()) SetScrollHere()" when applicable. +void ImGui::SetItemDefaultFocus() +{ + if (IsWindowAppearing()) + SetScrollHere(); +} + void ImGui::SetKeyboardFocusHere(int offset) { IM_ASSERT(offset >= -1); // -1 is allowed but not below @@ -9186,7 +9195,7 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi return false; // Display items - // FIXME-OPT: Use clipper (if we can disable it on the appearing frame to make sure our call to SetScrollHere() is processed) + // FIXME-OPT: Use clipper (but we need to disable it on the appearing frame to make sure our call to SetItemDefaultFocus() is processed) bool value_changed = false; for (int i = 0; i < items_count; i++) { @@ -9200,8 +9209,8 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi value_changed = true; *current_item = i; } - if (item_selected && IsWindowAppearing()) - SetScrollHere(); + if (item_selected) + SetItemDefaultFocus(); PopID(); } diff --git a/imgui.h b/imgui.h index 9c35c494d..a7e29bbe7 100644 --- a/imgui.h +++ b/imgui.h @@ -178,9 +178,8 @@ namespace ImGui IMGUI_API float GetScrollMaxY(); // get maximum scrolling amount ~~ ContentSize.Y - WindowSize.Y IMGUI_API void SetScrollX(float scroll_x); // set scrolling amount [0..GetScrollMaxX()] IMGUI_API void SetScrollY(float scroll_y); // set scrolling amount [0..GetScrollMaxY()] - IMGUI_API void SetScrollHere(float center_y_ratio = 0.5f); // adjust scrolling amount to make current cursor position visible. center_y_ratio=0.0: top, 0.5: center, 1.0: bottom. + IMGUI_API void SetScrollHere(float center_y_ratio = 0.5f); // adjust scrolling amount to make current cursor position visible. center_y_ratio=0.0: top, 0.5: center, 1.0: bottom. When using to make a "default/current item" visible, consider using SetItemDefaultFocus() instead. IMGUI_API void SetScrollFromPosY(float pos_y, float center_y_ratio = 0.5f); // adjust scrolling amount to make given position valid. use GetCursorPos() or GetCursorStartPos()+offset to get valid positions. - IMGUI_API void SetKeyboardFocusHere(int offset = 0); // focus keyboard on the next widget. Use positive 'offset' to access sub components of a multiple component widget. Use -1 to access previous widget. IMGUI_API void SetStateStorage(ImGuiStorage* tree); // replace tree state storage with our own (if you want to manipulate it yourself, typically clear subsection of it) IMGUI_API ImGuiStorage* GetStateStorage(); @@ -426,6 +425,12 @@ namespace ImGui IMGUI_API void StyleColorsDark(ImGuiStyle* dst = NULL); IMGUI_API void StyleColorsLight(ImGuiStyle* dst = NULL); + // Focus + // (FIXME: Those functions will be reworked after we merge the navigation branch + have a pass at focusing/tabbing features.) + // (Prefer using "SetItemDefaultFocus()" over "if (IsWindowAppearing()) SetScrollHere()" when applicable, to make your code more forward compatible when navigation branch is merged) + IMGUI_API void SetItemDefaultFocus(); // make last item the default focused item of a window (WIP navigation branch only). Pleaase use instead of SetScrollHere(). + IMGUI_API void SetKeyboardFocusHere(int offset = 0); // focus keyboard on the next widget. Use positive 'offset' to access sub components of a multiple component widget. Use -1 to access previous widget. + // Utilities IMGUI_API bool IsItemHovered(ImGuiHoveredFlags flags = 0); // is the last item hovered by mouse (and usable)? IMGUI_API bool IsItemActive(); // is the last item active? (e.g. button being held, text field being edited- items that don't interact will always return false) From f06f68f3cea7e2527ed66f7395d1662a4df50917 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 11 Dec 2017 16:22:52 +0100 Subject: [PATCH 705/921] Obsoleted old functions: SetScrollPosHere (marked obsolete in 1.42, July 2015). GetWindowFont(), GetWindowFontSize() (marked obsolete in 1.48, March 2016) --- imgui.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/imgui.h b/imgui.h index a7e29bbe7..c75a2a064 100644 --- a/imgui.h +++ b/imgui.h @@ -945,9 +945,6 @@ namespace ImGui static inline bool IsMouseHoveringAnyWindow() { return IsAnyWindowHovered(); } // OBSOLETE 1.51+ static inline bool IsMouseHoveringWindow() { return IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem); } // OBSOLETE 1.51+ static inline bool CollapsingHeader(const char* label, const char* str_id, bool framed = true, bool default_open = false) { (void)str_id; (void)framed; ImGuiTreeNodeFlags default_open_flags = 1 << 5; return CollapsingHeader(label, (default_open ? default_open_flags : 0)); } // OBSOLETE 1.49+ - static inline ImFont* GetWindowFont() { return GetFont(); } // OBSOLETE 1.48+ - static inline float GetWindowFontSize() { return GetFontSize(); } // OBSOLETE 1.48+ - static inline void SetScrollPosHere() { SetScrollHere(); } // OBSOLETE 1.42+ } #endif From 6b168b43ff85883469817038b09b8a8546a8e8b7 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 11 Dec 2017 19:47:23 +0100 Subject: [PATCH 706/921] Comments (#822) --- TODO.txt | 2 +- imgui.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/TODO.txt b/TODO.txt index 1271d346f..43df4dafc 100644 --- a/TODO.txt +++ b/TODO.txt @@ -24,7 +24,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - window: increase minimum size of a window with menus or fix the menu rendering so that it doesn't look odd. - window: double-clicking on title bar to minimize isn't consistent, perhaps move to single-click on left-most collapse icon? - window: expose contents size. (#1045) - - window: resize from borders and/or all corners. (#822) + - window: resize from borders: support some form of outer padding to make it easier to grab borders. (#822) - window: GetWindowSize() returns (0,0) when not calculated? (#1045) - window: refactor IsWindowFocused(), merge all three existing variants, add flags, similar to #1382. - window: freeze window flag: if not focused/hovered, return false, render with previous ImDrawList. and/or reduce refresh rate. diff --git a/imgui.h b/imgui.h index c75a2a064..3187f5ddd 100644 --- a/imgui.h +++ b/imgui.h @@ -756,8 +756,8 @@ enum ImGuiMouseCursor_ ImGuiMouseCursor_Arrow = 0, ImGuiMouseCursor_TextInput, // When hovering over InputText, etc. ImGuiMouseCursor_Move, // Unused - ImGuiMouseCursor_ResizeNS, // Unused - ImGuiMouseCursor_ResizeEW, // When hovering over a column + ImGuiMouseCursor_ResizeNS, // When hovering over an horizontal border + ImGuiMouseCursor_ResizeEW, // When hovering over a vertical border or a column ImGuiMouseCursor_ResizeNESW, // When hovering over the bottom-left corner of a window ImGuiMouseCursor_ResizeNWSE, // When hovering over the bottom-right corner of a window ImGuiMouseCursor_Count_ From 45f440bb7dbb226e6375ba8643b1efda87d8f78b Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 11 Dec 2017 22:39:10 +0100 Subject: [PATCH 707/921] Internals: Renamed ImGuiButtonFlags_FlattenChilds -> ImGuiButtonFlags_FlattenChildren, ImGuiButtonFlags_AllowOverlapMode -> ImGuiButtonFlags_AllowItemOverlap --- imgui.cpp | 14 +++++++------- imgui_internal.h | 12 ++++++------ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 9a7e1b87f..5e86bc012 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4659,7 +4659,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) ImRect resize_rect(corner, corner + grip.InnerDir * grip_hover_size); resize_rect.FixInverted(); bool hovered, held; - ButtonBehavior(resize_rect, window->GetID((void*)(intptr_t)resize_grip_n), &hovered, &held, ImGuiButtonFlags_FlattenChilds); + ButtonBehavior(resize_rect, window->GetID((void*)(intptr_t)resize_grip_n), &hovered, &held, ImGuiButtonFlags_FlattenChildren); if (hovered || held) g.MouseCursor = (resize_grip_n & 1) ? ImGuiMouseCursor_ResizeNESW : ImGuiMouseCursor_ResizeNWSE; @@ -4685,7 +4685,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) const float BORDER_APPEAR_TIMER = 0.05f; // Reduce visual noise bool hovered, held; ImRect border_rect = GetBorderRect(window, border_n, grip_hover_size, BORDER_SIZE); - ButtonBehavior(border_rect, window->GetID((void*)(intptr_t)(border_n+4)), &hovered, &held, ImGuiButtonFlags_FlattenChilds); + ButtonBehavior(border_rect, window->GetID((void*)(intptr_t)(border_n+4)), &hovered, &held, ImGuiButtonFlags_FlattenChildren); if ((hovered && g.HoveredIdTimer > BORDER_APPEAR_TIMER) || held) { g.MouseCursor = (border_n & 1) ? ImGuiMouseCursor_ResizeEW : ImGuiMouseCursor_ResizeNS; @@ -6147,17 +6147,17 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool flags |= ImGuiButtonFlags_PressedOnClickRelease; ImGuiWindow* backup_hovered_window = g.HoveredWindow; - if ((flags & ImGuiButtonFlags_FlattenChilds) && g.HoveredRootWindow == window) + if ((flags & ImGuiButtonFlags_FlattenChildren) && g.HoveredRootWindow == window) g.HoveredWindow = window; bool pressed = false; bool hovered = ItemHoverable(bb, id); - if ((flags & ImGuiButtonFlags_FlattenChilds) && g.HoveredRootWindow == window) + if ((flags & ImGuiButtonFlags_FlattenChildren) && g.HoveredRootWindow == window) g.HoveredWindow = backup_hovered_window; // AllowOverlap mode (rarely used) requires previous frame HoveredId to be null or to match. This allows using patterns where a later submitted widget overlaps a previous one. - if (hovered && (flags & ImGuiButtonFlags_AllowOverlapMode) && (g.HoveredIdPreviousFrame != id && g.HoveredIdPreviousFrame != 0)) + if (hovered && (flags & ImGuiButtonFlags_AllowItemOverlap) && (g.HoveredIdPreviousFrame != id && g.HoveredIdPreviousFrame != 0)) hovered = false; if (hovered) @@ -6613,7 +6613,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l // - OpenOnDoubleClick .............. double-click anywhere to open // - OpenOnArrow .................... single-click on arrow to open // - OpenOnDoubleClick|OpenOnArrow .. single-click on arrow or double-click anywhere to open - ImGuiButtonFlags button_flags = ImGuiButtonFlags_NoKeyModifiers | ((flags & ImGuiTreeNodeFlags_AllowOverlapMode) ? ImGuiButtonFlags_AllowOverlapMode : 0); + ImGuiButtonFlags button_flags = ImGuiButtonFlags_NoKeyModifiers | ((flags & ImGuiTreeNodeFlags_AllowOverlapMode) ? ImGuiButtonFlags_AllowItemOverlap : 0); if (flags & ImGuiTreeNodeFlags_OpenOnDoubleClick) button_flags |= ImGuiButtonFlags_PressedOnDoubleClick | ((flags & ImGuiTreeNodeFlags_OpenOnArrow) ? ImGuiButtonFlags_PressedOnClickRelease : 0); bool hovered, held, pressed = ButtonBehavior(interact_bb, id, &hovered, &held, button_flags); @@ -10517,7 +10517,7 @@ bool ImGui::SplitterBehavior(ImGuiID id, const ImRect& bb, ImGuiAxis axis, float bool hovered, held; ImRect bb_interact = bb; bb_interact.Expand(axis == ImGuiAxis_Y ? ImVec2(0.0f, hover_extend) : ImVec2(hover_extend, 0.0f)); - ButtonBehavior(bb_interact, id, &hovered, &held, ImGuiButtonFlags_FlattenChilds | ImGuiButtonFlags_AllowOverlapMode); + ButtonBehavior(bb_interact, id, &hovered, &held, ImGuiButtonFlags_FlattenChildren | ImGuiButtonFlags_AllowItemOverlap); if (g.ActiveId != id) SetItemAllowOverlap(); diff --git a/imgui_internal.h b/imgui_internal.h index 18e44c443..9c4cb3e48 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -176,12 +176,12 @@ enum ImGuiButtonFlags_ ImGuiButtonFlags_PressedOnClick = 1 << 2, // return true on click (default requires click+release) ImGuiButtonFlags_PressedOnRelease = 1 << 3, // return true on release (default requires click+release) ImGuiButtonFlags_PressedOnDoubleClick = 1 << 4, // return true on double-click (default requires click+release) - ImGuiButtonFlags_FlattenChilds = 1 << 5, // allow interactions even if a child window is overlapping - ImGuiButtonFlags_DontClosePopups = 1 << 6, // disable automatically closing parent popup on press // [UNUSED] - ImGuiButtonFlags_Disabled = 1 << 7, // disable interactions - ImGuiButtonFlags_AlignTextBaseLine = 1 << 8, // vertically align button to match text baseline (ButtonEx() only) - ImGuiButtonFlags_NoKeyModifiers = 1 << 9, // disable interaction if a key modifier is held - ImGuiButtonFlags_AllowOverlapMode = 1 << 10, // require previous frame HoveredId to either match id or be null before being usable + ImGuiButtonFlags_FlattenChildren = 1 << 5, // allow interactions even if a child window is overlapping + ImGuiButtonFlags_AllowItemOverlap = 1 << 6, // require previous frame HoveredId to either match id or be null before being usable, use along with SetItemAllowOverlap() + ImGuiButtonFlags_DontClosePopups = 1 << 7, // disable automatically closing parent popup on press // [UNUSED] + ImGuiButtonFlags_Disabled = 1 << 8, // disable interactions + ImGuiButtonFlags_AlignTextBaseLine = 1 << 9, // vertically align button to match text baseline (ButtonEx() only) + ImGuiButtonFlags_NoKeyModifiers = 1 << 10, // disable interaction if a key modifier is held ImGuiButtonFlags_NoHoldingActiveID = 1 << 11 // don't set ActiveId while holding the mouse (ImGuiButtonFlags_PressedOnClick only) }; From f93945540ff8191164e9e33d2bd13e14f3612b21 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 11 Dec 2017 22:41:33 +0100 Subject: [PATCH 708/921] Renamed ImGuiTreeNodeFlags_AllowOverlapMode to ImGuiTreeNodeFlags_AllowItemOverlap. (#600, #1330) --- imgui.cpp | 7 ++++--- imgui.h | 7 ++++++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 5e86bc012..58b70196b 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -213,6 +213,7 @@ Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. Also read releases logs https://github.com/ocornut/imgui/releases for more details. + - 2017/12/12 (1.53) - renamed ImGuiTreeNodeFlags_AllowOverlapMode to ImGuiTreeNodeFlags_AllowItemOverlap. Kept redirection enum (will obsolete). - 2017/12/10 (1.53) - removed SetNextWindowContentWidth(), prefer using SetNextWindowContentSize(). Kept redirection function (will obsolete). - 2017/11/27 (1.53) - renamed ImGuiTextBuffer::append() helper to appendf(), appendv() to appendfv(). If you copied the 'Log' demo in your code, it uses appendv() so that needs to be renamed. - 2017/11/18 (1.53) - Style, Begin: removed ImGuiWindowFlags_ShowBorders window flag. Borders are now fully set up in the ImGuiStyle structure (see e.g. style.FrameBorderSize, style.WindowBorderSize). Use ImGui::ShowStyleEditor() to look them up. @@ -6613,7 +6614,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l // - OpenOnDoubleClick .............. double-click anywhere to open // - OpenOnArrow .................... single-click on arrow to open // - OpenOnDoubleClick|OpenOnArrow .. single-click on arrow or double-click anywhere to open - ImGuiButtonFlags button_flags = ImGuiButtonFlags_NoKeyModifiers | ((flags & ImGuiTreeNodeFlags_AllowOverlapMode) ? ImGuiButtonFlags_AllowItemOverlap : 0); + ImGuiButtonFlags button_flags = ImGuiButtonFlags_NoKeyModifiers | ((flags & ImGuiTreeNodeFlags_AllowItemOverlap) ? ImGuiButtonFlags_AllowItemOverlap : 0); if (flags & ImGuiTreeNodeFlags_OpenOnDoubleClick) button_flags |= ImGuiButtonFlags_PressedOnDoubleClick | ((flags & ImGuiTreeNodeFlags_OpenOnArrow) ? ImGuiButtonFlags_PressedOnClickRelease : 0); bool hovered, held, pressed = ButtonBehavior(interact_bb, id, &hovered, &held, button_flags); @@ -6630,7 +6631,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l window->DC.StateStorage->SetInt(id, is_open); } } - if (flags & ImGuiTreeNodeFlags_AllowOverlapMode) + if (flags & ImGuiTreeNodeFlags_AllowItemOverlap) SetItemAllowOverlap(); // Render @@ -6696,7 +6697,7 @@ bool ImGui::CollapsingHeader(const char* label, bool* p_open, ImGuiTreeNodeFlags return false; ImGuiID id = window->GetID(label); - bool is_open = TreeNodeBehavior(id, flags | ImGuiTreeNodeFlags_CollapsingHeader | ImGuiTreeNodeFlags_NoTreePushOnOpen | (p_open ? ImGuiTreeNodeFlags_AllowOverlapMode : 0), label); + bool is_open = TreeNodeBehavior(id, flags | ImGuiTreeNodeFlags_CollapsingHeader | ImGuiTreeNodeFlags_NoTreePushOnOpen | (p_open ? ImGuiTreeNodeFlags_AllowItemOverlap : 0), label); if (p_open) { // Create a small overlapping close button // FIXME: We can evolve this into user accessible helpers to add extra buttons on title bars, headers, etc. diff --git a/imgui.h b/imgui.h index 3187f5ddd..bd53d6cf4 100644 --- a/imgui.h +++ b/imgui.h @@ -563,7 +563,7 @@ enum ImGuiTreeNodeFlags_ { ImGuiTreeNodeFlags_Selected = 1 << 0, // Draw as selected ImGuiTreeNodeFlags_Framed = 1 << 1, // Full colored frame (e.g. for CollapsingHeader) - ImGuiTreeNodeFlags_AllowOverlapMode = 1 << 2, // Hit testing to allow subsequent widgets to overlap this one + ImGuiTreeNodeFlags_AllowItemOverlap = 1 << 2, // Hit testing to allow subsequent widgets to overlap this one ImGuiTreeNodeFlags_NoTreePushOnOpen = 1 << 3, // Don't do a TreePush() when open (e.g. for CollapsingHeader) = no extra indent nor pushing on ID stack ImGuiTreeNodeFlags_NoAutoOpenOnLog = 1 << 4, // Don't automatically and temporarily open node when Logging is active (by default logging will automatically open tree nodes) ImGuiTreeNodeFlags_DefaultOpen = 1 << 5, // Default node to be open @@ -575,6 +575,11 @@ enum ImGuiTreeNodeFlags_ //ImGuITreeNodeFlags_SpanAllAvailWidth = 1 << 11, // FIXME: TODO: Extend hit box horizontally even if not framed //ImGuiTreeNodeFlags_NoScrollOnOpen = 1 << 12, // FIXME: TODO: Disable automatic scroll on TreePop() if node got just open and contents is not visible ImGuiTreeNodeFlags_CollapsingHeader = ImGuiTreeNodeFlags_Framed | ImGuiTreeNodeFlags_NoAutoOpenOnLog + + // Obsolete names (will be removed) +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS + , ImGuiTreeNodeFlags_AllowOverlapMode = ImGuiTreeNodeFlags_AllowItemOverlap +#endif }; // Flags for ImGui::Selectable() From 185c1eaaf341f9d8932c41b657d2eb66143b09cd Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 11 Dec 2017 22:54:03 +0100 Subject: [PATCH 709/921] Alignment + removed comments --- imgui.h | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/imgui.h b/imgui.h index bd53d6cf4..c33b04a52 100644 --- a/imgui.h +++ b/imgui.h @@ -506,7 +506,6 @@ namespace ImGui // Flags for ImGui::Begin() enum ImGuiWindowFlags_ { - // Default: 0 ImGuiWindowFlags_NoTitleBar = 1 << 0, // Disable title-bar ImGuiWindowFlags_NoResize = 1 << 1, // Disable user resizing with the lower-right grip ImGuiWindowFlags_NoMove = 1 << 2, // Disable user moving the window @@ -537,7 +536,6 @@ enum ImGuiWindowFlags_ // Flags for ImGui::InputText() enum ImGuiInputTextFlags_ { - // Default: 0 ImGuiInputTextFlags_CharsDecimal = 1 << 0, // Allow 0123456789.+-*/ ImGuiInputTextFlags_CharsHexadecimal = 1 << 1, // Allow 0123456789ABCDEFabcdef ImGuiInputTextFlags_CharsUppercase = 1 << 2, // Turn a..z into A..Z @@ -585,7 +583,6 @@ enum ImGuiTreeNodeFlags_ // Flags for ImGui::Selectable() enum ImGuiSelectableFlags_ { - // Default: 0 ImGuiSelectableFlags_DontClosePopups = 1 << 0, // Clicking this don't close parent popup window ImGuiSelectableFlags_SpanAllColumns = 1 << 1, // Selectable frame can span all columns (text will still fit in current column) ImGuiSelectableFlags_AllowDoubleClick = 1 << 2 // Generate press events on double clicks too @@ -594,12 +591,12 @@ enum ImGuiSelectableFlags_ // Flags for ImGui::BeginCombo() enum ImGuiComboFlags_ { - ImGuiComboFlags_PopupAlignLeft = 1 << 0, // Align the popup toward the left by default - ImGuiComboFlags_HeightSmall = 1 << 1, // Max ~4 items visible. Tip: If you want your combo popup to be a specific size you can use SetNextWindowSizeConstraints() prior to calling BeginCombo() - ImGuiComboFlags_HeightRegular = 1 << 2, // Max ~8 items visible (default) - ImGuiComboFlags_HeightLarge = 1 << 3, // Max ~20 items visible - ImGuiComboFlags_HeightLargest = 1 << 4, // As many fitting items as possible - ImGuiComboFlags_HeightMask_ = ImGuiComboFlags_HeightSmall | ImGuiComboFlags_HeightRegular | ImGuiComboFlags_HeightLarge | ImGuiComboFlags_HeightLargest + ImGuiComboFlags_PopupAlignLeft = 1 << 0, // Align the popup toward the left by default + ImGuiComboFlags_HeightSmall = 1 << 1, // Max ~4 items visible. Tip: If you want your combo popup to be a specific size you can use SetNextWindowSizeConstraints() prior to calling BeginCombo() + ImGuiComboFlags_HeightRegular = 1 << 2, // Max ~8 items visible (default) + ImGuiComboFlags_HeightLarge = 1 << 3, // Max ~20 items visible + ImGuiComboFlags_HeightLargest = 1 << 4, // As many fitting items as possible + ImGuiComboFlags_HeightMask_ = ImGuiComboFlags_HeightSmall | ImGuiComboFlags_HeightRegular | ImGuiComboFlags_HeightLarge | ImGuiComboFlags_HeightLargest }; // Flags for ImGui::IsItemHovered(), ImGui::IsWindowHovered() From 4a555d35f0ba48618942984fd7bdfe12422b43ae Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 11 Dec 2017 23:16:27 +0100 Subject: [PATCH 710/921] IsWindowHovered(): split ImGuiHoveredFlags_FlattenChild into separate ChildWindows and RootWindow flags. Allowing more combination and a better symetry with IsWindowFocused() flags. (#1382) --- imgui.cpp | 35 +++++++++++++++++++++++++++++------ imgui.h | 7 ++++--- imgui_demo.cpp | 12 ++++++++++-- imgui_internal.h | 1 + 4 files changed, 44 insertions(+), 11 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 58b70196b..61a1217c5 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -221,7 +221,7 @@ - 2017/11/18 (1.53) - Style: removed ImGuiCol_ComboBg in favor of combo boxes using ImGuiCol_PopupBg for consistency. - 2017/11/18 (1.53) - Style: renamed ImGuiCol_ChildWindowBg to ImGuiCol_ChildBg. - 2017/11/18 (1.53) - Style: renamed style.ChildWindowRounding to style.ChildRounding, ImGuiStyleVar_ChildWindowRounding to ImGuiStyleVar_ChildRounding. - - 2017/11/02 (1.53) - marked IsRootWindowOrAnyChildHovered() as obsolete is favor of using IsWindowHovered(ImGuiHoveredFlags_FlattenChilds); + - 2017/11/02 (1.53) - marked IsRootWindowOrAnyChildHovered() as obsolete is favor of using IsWindowHovered(ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows); - 2017/10/24 (1.52) - renamed IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCS/IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCS to IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS/IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS for consistency. - 2017/10/20 (1.52) - changed IsWindowHovered() default parameters behavior to return false if an item is active in another window (e.g. click-dragging item from another window to this window). You can use the newly introduced IsWindowHovered() flags to requests this specific behavior if you need it. - 2017/10/20 (1.52) - marked IsItemHoveredRect()/IsMouseHoveringWindow() as obsolete, in favor of using the newly introduced flags for IsItemHovered() and IsWindowHovered(). See https://github.com/ocornut/imgui/issues/1382 for details. @@ -2032,7 +2032,7 @@ bool ImGui::IsItemHovered(ImGuiHoveredFlags flags) // Test for bounding box overlap, as updated as ItemAdd() if (!window->DC.LastItemRectHoveredRect) return false; - IM_ASSERT((flags & ImGuiHoveredFlags_FlattenChilds) == 0); // Flags not supported by this function + IM_ASSERT((flags & (ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows)) == 0); // Flags not supported by this function // Test if we are hovering the right window (our window could be behind another window) // [2017/10/16] Reverted commit 344d48be3 and testing RootWindow instead. I believe it is correct to NOT test for RootWindow but this leaves us unable to use IsItemHovered() after EndChild() itself. @@ -5440,20 +5440,43 @@ const char* ImGui::GetStyleColorName(ImGuiCol idx) return "Unknown"; } +bool ImGui::IsWindowChildOf(ImGuiWindow* window, ImGuiWindow* potential_parent) +{ + if (window->RootWindow == potential_parent) + return true; + while (window != NULL) + { + if (window == potential_parent) + return true; + window = window->ParentWindow; + } + return false; +} + bool ImGui::IsWindowHovered(ImGuiHoveredFlags flags) { IM_ASSERT((flags & ImGuiHoveredFlags_AllowWhenOverlapped) == 0); // Flags not supported by this function ImGuiContext& g = *GImGui; - if (flags & ImGuiHoveredFlags_FlattenChilds) + switch (flags & (ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows)) { + case ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows: if (g.HoveredRootWindow != g.CurrentWindow->RootWindow) return false; - } - else - { + break; + case ImGuiHoveredFlags_RootWindow: + if (g.HoveredWindow != g.CurrentWindow->RootWindow) + return false; + break; + case ImGuiHoveredFlags_ChildWindows: + if (g.HoveredWindow == NULL || !IsWindowChildOf(g.HoveredWindow, g.CurrentWindow)) + return false; + break; + default: if (g.HoveredWindow != g.CurrentWindow) return false; + break; } + if (!IsWindowContentHoverable(g.HoveredRootWindow, flags)) return false; if (!(flags & ImGuiHoveredFlags_AllowWhenBlockedByActiveItem)) diff --git a/imgui.h b/imgui.h index c33b04a52..79c54c706 100644 --- a/imgui.h +++ b/imgui.h @@ -607,7 +607,8 @@ enum ImGuiHoveredFlags_ //ImGuiHoveredFlags_AllowWhenBlockedByModal = 1 << 1, // Return true even if a modal popup window is normally blocking access to this item/window. FIXME-TODO: Unavailable yet. ImGuiHoveredFlags_AllowWhenBlockedByActiveItem = 1 << 2, // Return true even if an active item is blocking access to this item/window ImGuiHoveredFlags_AllowWhenOverlapped = 1 << 3, // Return true even if the position is overlapped by another window - ImGuiHoveredFlags_FlattenChilds = 1 << 4, // Treat all child windows as the same window (for IsWindowHovered()) + ImGuiHoveredFlags_ChildWindows = 1 << 4, // IsWindowHovered() only: Return true if any children of the window is hovered + ImGuiHoveredFlags_RootWindow = 1 << 5, // IsWindowHovered() only: Test from root window (top most parent of the current hierarchy) ImGuiHoveredFlags_RectOnly = ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem | ImGuiHoveredFlags_AllowWhenOverlapped }; @@ -937,8 +938,8 @@ struct ImGuiIO #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS namespace ImGui { - static inline void SetNextWindowContentWidth(float width) { ImGui::SetNextWindowContentSize(ImVec2(width, 0.0f)); } // OBSOLETE 1.53+ (nb: original version preserved last Y value set by SetNextWindowContentSize()) - static inline bool IsRootWindowOrAnyChildHovered(ImGuiHoveredFlags flags = 0) { return IsItemHovered(flags | ImGuiHoveredFlags_FlattenChilds); } // OBSOLETE 1.53+ use flags directly + static inline void SetNextWindowContentWidth(float width) { SetNextWindowContentSize(ImVec2(width, 0.0f)); } // OBSOLETE 1.53+ (nb: original version preserved last Y value set by SetNextWindowContentSize()) + static inline bool IsRootWindowOrAnyChildHovered(ImGuiHoveredFlags flags = 0) { return IsItemHovered(flags | ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows); } // OBSOLETE 1.53+ use flags directly bool Begin(const char* name, bool* p_open, const ImVec2& size_on_first_use, float bg_alpha_override = -1.0f, ImGuiWindowFlags flags = 0); // OBSOLETE 1.52+. use SetNextWindowSize() instead if you want to set a window size. static inline void AlignFirstTextHeightToWidgets() { AlignTextToFramePadding(); } // OBSOLETE 1.52+ static inline void SetNextWindowPosCenter(ImGuiCond cond = 0) { SetNextWindowPos(ImVec2(GetIO().DisplaySize.x * 0.5f, GetIO().DisplaySize.y * 0.5f), cond, ImVec2(0.5f, 0.5f)); } // OBSOLETE 1.52+ diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 6c6952a3f..c82f99e50 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1788,11 +1788,15 @@ void ImGui::ShowTestWindow(bool* p_open) "IsWindowHovered() = %d\n" "IsWindowHovered(_AllowWhenBlockedByPopup) = %d\n" "IsWindowHovered(_AllowWhenBlockedByActiveItem) = %d\n" - "IsWindowHovered(_FlattenChilds) = %d\n", + "IsWindowHovered(_ChildWindows) = %d\n" + "IsWindowHovered(_ChildWindows|_RootWindow) = %d\n" + "IsWindowHovered(_RootWindow) = %d\n", ImGui::IsWindowHovered(), ImGui::IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup), ImGui::IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem), - ImGui::IsWindowHovered(ImGuiHoveredFlags_FlattenChilds)); + ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows), + ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows | ImGuiHoveredFlags_RootWindow), + ImGui::IsWindowHovered(ImGuiHoveredFlags_RootWindow)); // Testing IsItemHovered() function (because BulletText is an item itself and that would affect the output of IsItemHovered, we pass all lines in a single items to shorten the code) ImGui::Button("ITEM"); @@ -1808,6 +1812,10 @@ void ImGui::ShowTestWindow(bool* p_open) ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenOverlapped), ImGui::IsItemHovered(ImGuiHoveredFlags_RectOnly)); + ImGui::BeginChild("child", ImVec2(0,50), true); + ImGui::Text("This is a child window for testing IsWindowHovered() flags."); + ImGui::EndChild(); + ImGui::TreePop(); } diff --git a/imgui_internal.h b/imgui_internal.h index 9c4cb3e48..5a84f2f68 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -804,6 +804,7 @@ namespace ImGui IMGUI_API void FocusWindow(ImGuiWindow* window); IMGUI_API void BringWindowToFront(ImGuiWindow* window); IMGUI_API void BringWindowToBack(ImGuiWindow* window); + IMGUI_API bool IsWindowChildOf(ImGuiWindow* window, ImGuiWindow* potential_parent); IMGUI_API void Initialize(); From f42d7b89e2430e02905cdd284b20ae0fe7a558fd Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 12 Dec 2017 00:18:31 +0100 Subject: [PATCH 711/921] Internals: Removed misleading GetWindowParent() function. + renaming to clear confusing. --- imgui.cpp | 15 ++++----------- imgui_internal.h | 1 - 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 61a1217c5..cf83b2ea3 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1910,13 +1910,6 @@ static void SetCurrentWindow(ImGuiWindow* window) g.FontSize = window->CalcFontSize(); } -ImGuiWindow* ImGui::GetParentWindow() -{ - ImGuiContext& g = *GImGui; - IM_ASSERT(g.CurrentWindowStack.Size >= 2); - return g.CurrentWindowStack[(unsigned int)g.CurrentWindowStack.Size - 2]; -} - void ImGui::SetActiveID(ImGuiID id, ImGuiWindow* window) { ImGuiContext& g = *GImGui; @@ -3686,9 +3679,9 @@ void ImGui::EndTooltip() void ImGui::OpenPopupEx(ImGuiID id, bool reopen_existing) { ImGuiContext& g = *GImGui; - ImGuiWindow* window = g.CurrentWindow; + ImGuiWindow* parent_window = g.CurrentWindow; int current_stack_size = g.CurrentPopupStack.Size; - ImGuiPopupRef popup_ref = ImGuiPopupRef(id, window, window->GetID("##Menus"), g.IO.MousePos); // Tagged as new ref because constructor sets Window to NULL (we are passing the ParentWindow info here) + ImGuiPopupRef popup_ref = ImGuiPopupRef(id, parent_window, parent_window->GetID("##Menus"), g.IO.MousePos); // Tagged as new ref because constructor sets Window to NULL. if (g.OpenPopupStack.Size < current_stack_size + 1) g.OpenPopupStack.push_back(popup_ref); else if (reopen_existing || g.OpenPopupStack[current_stack_size].PopupId != id) @@ -3699,7 +3692,7 @@ void ImGui::OpenPopupEx(ImGuiID id, bool reopen_existing) // When reopening a popup we first refocus its parent, otherwise if its parent is itself a popup it would get closed by CloseInactivePopups(). // This is equivalent to what ClosePopupToLevel() does. if (g.OpenPopupStack[current_stack_size].PopupId == id) - FocusWindow(window); + FocusWindow(parent_window); } } @@ -9426,7 +9419,7 @@ bool ImGui::ListBoxHeader(const char* label, int items_count, int height_in_item void ImGui::ListBoxFooter() { - ImGuiWindow* parent_window = GetParentWindow(); + ImGuiWindow* parent_window = GetCurrentWindow()->ParentWindow; const ImRect bb = parent_window->DC.LastItemRect; const ImGuiStyle& style = GetStyle(); diff --git a/imgui_internal.h b/imgui_internal.h index 5a84f2f68..b1dab53fb 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -799,7 +799,6 @@ namespace ImGui // - You are calling ImGui functions after ImGui::Render() and before the next ImGui::NewFrame(), which is also illegal. inline ImGuiWindow* GetCurrentWindowRead() { ImGuiContext& g = *GImGui; return g.CurrentWindow; } inline ImGuiWindow* GetCurrentWindow() { ImGuiContext& g = *GImGui; g.CurrentWindow->WriteAccessed = true; return g.CurrentWindow; } - IMGUI_API ImGuiWindow* GetParentWindow(); IMGUI_API ImGuiWindow* FindWindowByName(const char* name); IMGUI_API void FocusWindow(ImGuiWindow* window); IMGUI_API void BringWindowToFront(ImGuiWindow* window); From c65124f415ae081b1aacaf299c539a32968809a7 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 12 Dec 2017 00:48:28 +0100 Subject: [PATCH 712/921] Internals: ParentWindow is now NULL for non-child windows and means what everyone expects. --- imgui.cpp | 13 +++++++------ imgui_internal.h | 2 +- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index cf83b2ea3..55fb5516f 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4338,7 +4338,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) SetWindowConditionAllowFlags(window, ImGuiCond_Appearing, true); // Parent window is latched only on the first call to Begin() of the frame, so further append-calls can be done from a different window stack - ImGuiWindow* parent_window = first_begin_of_the_frame ? (!g.CurrentWindowStack.empty() ? g.CurrentWindowStack.back() : NULL) : window->ParentWindow; + ImGuiWindow* parent_window = first_begin_of_the_frame ? ((flags & ImGuiWindowFlags_ChildWindow) && !g.CurrentWindowStack.empty() ? g.CurrentWindowStack.back() : NULL) : window->ParentWindow; IM_ASSERT(parent_window != NULL || !(flags & ImGuiWindowFlags_ChildWindow)); // Add to stack @@ -4409,8 +4409,8 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) { // Initialize window->ParentWindow = parent_window; - window->RootWindow = !(flags & ImGuiWindowFlags_ChildWindow) ? window : parent_window->RootWindow; - window->RootNonPopupWindow = !(flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_Popup)) || (flags & ImGuiWindowFlags_Modal) ? window : parent_window->RootNonPopupWindow; // Used to display TitleBgActive color and for selecting which window to use for NavWindowing + window->RootWindow = ((flags & ImGuiWindowFlags_ChildWindow) && parent_window) ? parent_window->RootWindow : window; + window->RootNonPopupWindow = !(flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_Popup)) || (flags & ImGuiWindowFlags_Modal) || (parent_window == NULL) ? window : parent_window->RootNonPopupWindow; // Used to display TitleBgActive color and for selecting which window to use for NavWindowing //window->RootNavWindow = window; //while (window->RootNavWindow->Flags & ImGuiWindowFlags_NavFlattened) // window->RootNavWindow = window->RootNavWindow->ParentWindow; @@ -4556,11 +4556,12 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // This is how we end up with child menus appearing (most-commonly) on the right of the parent menu. IM_ASSERT(window_pos_set_by_api); float horizontal_overlap = style.ItemSpacing.x; // We want some overlap to convey the relative depth of each popup (currently the amount of overlap it is hard-coded to style.ItemSpacing.x, may need to introduce another style value). + ImGuiWindow* parent_menu = g.CurrentWindowStack[g.CurrentWindowStack.Size - 2]; ImRect rect_to_avoid; - if (parent_window->DC.MenuBarAppending) - rect_to_avoid = ImRect(-FLT_MAX, parent_window->Pos.y + parent_window->TitleBarHeight(), FLT_MAX, parent_window->Pos.y + parent_window->TitleBarHeight() + parent_window->MenuBarHeight()); + if (parent_menu->DC.MenuBarAppending) + rect_to_avoid = ImRect(-FLT_MAX, parent_menu->Pos.y + parent_menu->TitleBarHeight(), FLT_MAX, parent_menu->Pos.y + parent_menu->TitleBarHeight() + parent_menu->MenuBarHeight()); else - rect_to_avoid = ImRect(parent_window->Pos.x + horizontal_overlap, -FLT_MAX, parent_window->Pos.x + parent_window->Size.x - horizontal_overlap - parent_window->ScrollbarSizes.x, FLT_MAX); + rect_to_avoid = ImRect(parent_menu->Pos.x + horizontal_overlap, -FLT_MAX, parent_menu->Pos.x + parent_menu->Size.x - horizontal_overlap - parent_menu->ScrollbarSizes.x, FLT_MAX); window->PosFloat = FindBestWindowPosForPopup(window->PosFloat, window->Size, &window->AutoPosLastDirection, rect_to_avoid); } else if ((flags & ImGuiWindowFlags_Popup) != 0 && !window_pos_set_by_api && window_just_appearing_after_hidden_for_resize) diff --git a/imgui_internal.h b/imgui_internal.h index b1dab53fb..417a0fb15 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -746,7 +746,7 @@ struct IMGUI_API ImGuiWindow ImGuiStorage StateStorage; float FontWindowScale; // Scale multiplier per-window ImDrawList* DrawList; - ImGuiWindow* ParentWindow; // Immediate parent in the window stack *regardless* of whether this window is a child window or not) + ImGuiWindow* ParentWindow; // If we are a child window, this is pointing to our parent. ImGuiWindow* RootWindow; // Generally point to ourself. If we are a child window, this is pointing to the first non-child parent window. ImGuiWindow* RootNonPopupWindow; // Generally point to ourself. Used to display TitleBgActive color and for selecting which window to use for NavWindowing From de4a851f954fbf50022d3b4715f8cac3c62f2416 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 12 Dec 2017 11:20:45 +0100 Subject: [PATCH 713/921] Font documentation update (#1498) --- extra_fonts/README.txt | 94 ++++++++++++++++++++++++++++++------------ 1 file changed, 67 insertions(+), 27 deletions(-) diff --git a/extra_fonts/README.txt b/extra_fonts/README.txt index 5d41a6bb8..2287f6eaa 100644 --- a/extra_fonts/README.txt +++ b/extra_fonts/README.txt @@ -1,25 +1,48 @@ - The code in imgui.cpp embeds a copy of 'ProggyClean.ttf' (by Tristan Grimmer) that is used by default. - We embed the font in source code so you can use Dear ImGui without any file system access. - You may also load external .TTF/.OTF files. - The files in this folder are suggested fonts, provided as a convenience. - (Note: .OTF support in stb_truetype.h currently doesn't appear to load every font) +The code in imgui.cpp embeds a copy of 'ProggyClean.ttf' (by Tristan Grimmer) that is used by default. +We embed the font in source code so you can use Dear ImGui without any file system access. +You may also load external .TTF/.OTF files. +The files in this folder are suggested fonts, provided as a convenience. +(Note: .OTF support in stb_truetype.h currently doesn't appear to load every font) - Fonts are rasterized in a single texture at the time of calling either of io.Fonts.GetTexDataAsAlpha8()/GetTexDataAsRGBA32()/Build(). +Fonts are rasterized in a single texture at the time of calling either of io.Fonts.GetTexDataAsAlpha8()/GetTexDataAsRGBA32()/Build(). +Also read dear imgui FAQ in imgui.cpp! ---------------------------------- +In this document: + +- Using Icons +- Fonts Loading Instructions +- FreeType rasterizer, Small font sizes +- Building Custom Glyph Ranges +- Remapping Codepoints +- Embedding Fonts in Source Code +- Credits/Licences for fonts included in this folder +- Links, Other fonts + + +--------------------------------------- USING ICONS ---------------------------------- +--------------------------------------- Using an icon font (such as FontAwesome: http://fontawesome.io) is an easy and practical way to use icons in your ImGui application. - A common pattern is to merge the icon font within your main font, so you can refer to the icons directly from your strings without having to change fonts back and forth. - To refer to the icon from your C++ code, you can use headers files created by Juliette Foucaut, at https://github.com/juliettef/IconFontCppHeaders - See Links below for other icons fonts and related tools. + A common pattern is to merge the icon font within your main font, so you can embed icons directly from your strings without + having to change fonts back and forth. + + To refer to the icon UTF-8 codepoints from your C++ code, you may use those headers files created by Juliette Foucaut: + https://github.com/juliettef/IconFontCppHeaders + + The C++11 version of those files uses the u8"" utf-8 encoding syntax + \u + #define ICON_FA_SEARCH u8"\uf002" + The pre-C++11 version has the values directly encoded as utf-8: + #define ICON_FA_SEARCH "\xEF\x80\x82" + + Example: // Merge icons into default tool font #include "IconsFontAwesome.h" ImGuiIO& io = ImGui::GetIO(); io.Fonts->AddFontDefault(); + ImFontConfig config; config.MergeMode = true; static const ImWchar icon_ranges[] = { ICON_MIN_FA, ICON_MAX_FA, 0 }; @@ -28,10 +51,12 @@ // Usage, e.g. ImGui::Text("%s Search", ICON_FA_SEARCH); + See Links below for other icons fonts and related tools. ---------------------------------- + +--------------------------------------- FONTS LOADING INSTRUCTIONS ---------------------------------- +--------------------------------------- Load default font with: @@ -43,7 +68,7 @@ ImGuiIO& io = ImGui::GetIO(); io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels); - Advanced options: + For advanced options create a ImFontConfig structure and pass it to the AddFont function (it will be copied internally) ImFontConfig config; config.OversampleH = 3; @@ -89,9 +114,23 @@ font->DisplayOffset.y += 1; // Render 1 pixel down ---------------------------------- +--------------------------------------- + FREETYPE RASTERIZER, SMALL FONT SIZES +--------------------------------------- + + Dear Imgui uses stb_truetype.h to rasterize fonts (with optional oversampling). + This technique and implementation are not ideal for fonts rendered at _small sizes_, which may appear a little blurry. + There is an implementation of the ImFontAtlas builder using FreeType that you can use: + + https://github.com/ocornut/imgui_club + + FreeType supports auto-hinting which tends to improve the readability of small fonts. + Note that this code currently creates textures that are unoptimally too large (could be fixed with some work) + + +--------------------------------------- BUILDING CUSTOM GLYPH RANGES ---------------------------------- +--------------------------------------- You can use the ImFontAtlas::GlyphRangesBuilder helper to create glyph ranges based on text input. For exemple: for a game where your script is known, if you can feed your entire script to it and only build the characters the game needs. @@ -105,9 +144,9 @@ io.Fonts->AddFontFromFileTTF("myfontfile.ttf", size_in_pixels, NULL, ranges.Data); ---------------------------------- +--------------------------------------- REMAPPING CODEPOINTS ---------------------------------- +--------------------------------------- All your strings needs to use UTF-8 encoding. Specifying literal in your source code using a local code page (such as CP-923 for Japanese, or CP-1251 for Cyrillic) will NOT work! In C++11 you can encode a string literal in UTF-8 by using the u8"hello" syntax. Otherwise you can convert yourself to UTF-8 or load text data from file already saved as UTF-8. @@ -117,9 +156,9 @@ You may also try to remap your local codepage characters to their Unicode codepoint using font->AddRemapChar(), but international users may have problems reading/editing your source code. ---------------------------------- - EMBEDDING FONT IN SOURCE CODE ---------------------------------- +--------------------------------------- + EMBEDDING FONTS IN SOURCE CODE +--------------------------------------- Compile and use 'binary_to_compressed_c.cpp' to create a compressed C style array that you can embed in source code. See the documentation in binary_to_compressed_c.cpp for instruction on how to use the tool. @@ -135,9 +174,9 @@ ImFont* font = io.Fonts->AddFontFromMemoryCompressedBase85TTF(compressed_data_base85, size_pixels, ...); ---------------------------------- - FONT FILES INCLUDED IN THIS FOLDER ---------------------------------- +--------------------------------------- + CREDITS/LICENSES FOR FONTS INCLUDED IN THIS FOLDER +--------------------------------------- Roboto-Medium.ttf Apache License 2.0 @@ -172,9 +211,9 @@ SIL OPEN FONT LICENSE Version 1.1 ---------------------------------- - LINKS & OTHER FONTS ---------------------------------- +--------------------------------------- + LINKS, OTHER FONTS +--------------------------------------- (Icons) Icon fonts https://fortawesome.github.io/Font-Awesome/ @@ -213,3 +252,4 @@ http://mplus-fonts.sourceforge.jp/mplus-outline-fonts/index-en.html Or use Arial Unicode or other Unicode fonts provided with Windows for full characters coverage (not sure of their licensing). + From fa179d0ad8e9b2706b5b7704cbc7b513b685e86e Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 12 Dec 2017 12:52:24 +0100 Subject: [PATCH 714/921] Reordered ImGuiHoveredFlags to match upcoming ImGuiFocusedFlags (#1382) --- imgui.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/imgui.h b/imgui.h index 79c54c706..495f6b369 100644 --- a/imgui.h +++ b/imgui.h @@ -603,12 +603,12 @@ enum ImGuiComboFlags_ enum ImGuiHoveredFlags_ { ImGuiHoveredFlags_Default = 0, // Return true if directly over the item/window, not obstructed by another window, not obstructed by an active popup or modal blocking inputs under them. - ImGuiHoveredFlags_AllowWhenBlockedByPopup = 1 << 0, // Return true even if a popup window is normally blocking access to this item/window - //ImGuiHoveredFlags_AllowWhenBlockedByModal = 1 << 1, // Return true even if a modal popup window is normally blocking access to this item/window. FIXME-TODO: Unavailable yet. - ImGuiHoveredFlags_AllowWhenBlockedByActiveItem = 1 << 2, // Return true even if an active item is blocking access to this item/window - ImGuiHoveredFlags_AllowWhenOverlapped = 1 << 3, // Return true even if the position is overlapped by another window - ImGuiHoveredFlags_ChildWindows = 1 << 4, // IsWindowHovered() only: Return true if any children of the window is hovered - ImGuiHoveredFlags_RootWindow = 1 << 5, // IsWindowHovered() only: Test from root window (top most parent of the current hierarchy) + ImGuiHoveredFlags_ChildWindows = 1 << 0, // IsWindowHovered() only: Return true if any children of the window is hovered + ImGuiHoveredFlags_RootWindow = 1 << 1, // IsWindowHovered() only: Test from root window (top most parent of the current hierarchy) + ImGuiHoveredFlags_AllowWhenBlockedByPopup = 1 << 2, // Return true even if a popup window is normally blocking access to this item/window + //ImGuiHoveredFlags_AllowWhenBlockedByModal = 1 << 3, // Return true even if a modal popup window is normally blocking access to this item/window. FIXME-TODO: Unavailable yet. + ImGuiHoveredFlags_AllowWhenBlockedByActiveItem = 1 << 4, // Return true even if an active item is blocking access to this item/window + ImGuiHoveredFlags_AllowWhenOverlapped = 1 << 5, // Return true even if the position is overlapped by another window ImGuiHoveredFlags_RectOnly = ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem | ImGuiHoveredFlags_AllowWhenOverlapped }; From 8d8f4934fb0a2a00e8011495cee761d2eb51598f Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 12 Dec 2017 13:11:40 +0100 Subject: [PATCH 715/921] Demo: mouse dragging demo tweaks --- imgui_demo.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index c82f99e50..e5c2e15f5 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1704,7 +1704,7 @@ void ImGui::ShowTestWindow(bool* p_open) { ImGuiIO& io = ImGui::GetIO(); ImGui::Checkbox("io.MouseDrawCursor", &io.MouseDrawCursor); - ImGui::SameLine(); ShowHelpMarker("Request ImGui to render a mouse cursor for you in software. Note that a mouse cursor rendered via regular GPU rendering will feel more laggy than hardware cursor, but will be more in sync with your other visuals."); + ImGui::SameLine(); ShowHelpMarker("Request ImGui to render a mouse cursor for you in software. Note that a mouse cursor rendered via your application GPU rendering path will feel more laggy than hardware cursor, but will be more in sync with your other visuals.\n\nSome desktop applications may use both kinds of cursors (e.g. enable software cursor only when resizing/dragging something)."); ImGui::Text("WantCaptureMouse: %d", io.WantCaptureMouse); ImGui::Text("WantCaptureKeyboard: %d", io.WantCaptureKeyboard); @@ -1823,7 +1823,8 @@ void ImGui::ShowTestWindow(bool* p_open) { ImGui::TextWrapped("You can use ImGui::GetMouseDragDelta(0) to query for the dragged amount on any widget."); for (int button = 0; button < 3; button++) - ImGui::Text("IsMouseDragging(%d) = %d", button, ImGui::IsMouseDragging(button)); + ImGui::Text("IsMouseDragging(%d):\n w/ default threshold: %d,\n w/ zero threshold: %d\n w/ large threshold: %d", + button, ImGui::IsMouseDragging(button), ImGui::IsMouseDragging(button, 0.0f), ImGui::IsMouseDragging(button, 20.0f)); ImGui::Button("Drag Me"); if (ImGui::IsItemActive()) { @@ -1832,6 +1833,9 @@ void ImGui::ShowTestWindow(bool* p_open) draw_list->PushClipRectFullScreen(); draw_list->AddLine(ImGui::CalcItemRectClosestPoint(io.MousePos, true, -2.0f), io.MousePos, ImColor(ImGui::GetStyle().Colors[ImGuiCol_Button]), 4.0f); draw_list->PopClipRect(); + + // Drag operations gets "unlocked" when the mouse has moved past a certain threshold (the default threshold is stored in io.MouseDragThreshold) + // You can request a lower or higher threshold using the second parameter of IsMouseDragging() and GetMouseDragDelta() ImVec2 value_raw = ImGui::GetMouseDragDelta(0, 0.0f); ImVec2 value_with_lock_threshold = ImGui::GetMouseDragDelta(0); ImVec2 mouse_delta = io.MouseDelta; From 08b72eb5c04429c6a34e99db4b5c1c2d5fe19964 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 12 Dec 2017 14:06:24 +0100 Subject: [PATCH 716/921] IsWindowFocused() refactor will flags. (#1382) Marked IsRootWindowFocused() as obsolete in favor of using IsWindowFocused(ImGuiFocusedFlags_RootWindow). Marked IsRootWindowOrAnyChildFocused() as obsolete in favor of using IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows). --- imgui.cpp | 29 ++++++++++++++--------------- imgui.h | 19 ++++++++++++++----- imgui_demo.cpp | 23 +++++++++++++++++++++-- 3 files changed, 49 insertions(+), 22 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 55fb5516f..f4ca2411c 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -213,6 +213,8 @@ Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. Also read releases logs https://github.com/ocornut/imgui/releases for more details. + - 2017/12/23 (1.53) - marked IsRootWindowFocused() as obsolete in favor of using IsWindowFocused(ImGuiFocusedFlags_RootWindow). + - marked IsRootWindowOrAnyChildFocused() as obsolete in favor of using IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows). - 2017/12/12 (1.53) - renamed ImGuiTreeNodeFlags_AllowOverlapMode to ImGuiTreeNodeFlags_AllowItemOverlap. Kept redirection enum (will obsolete). - 2017/12/10 (1.53) - removed SetNextWindowContentWidth(), prefer using SetNextWindowContentSize(). Kept redirection function (will obsolete). - 2017/11/27 (1.53) - renamed ImGuiTextBuffer::append() helper to appendf(), appendv() to appendfv(). If you copied the 'Log' demo in your code, it uses appendv() so that needs to be renamed. @@ -5479,25 +5481,22 @@ bool ImGui::IsWindowHovered(ImGuiHoveredFlags flags) return true; } -bool ImGui::IsWindowFocused() +bool ImGui::IsWindowFocused(ImGuiFocusedFlags flags) { ImGuiContext& g = *GImGui; IM_ASSERT(g.CurrentWindow); // Not inside a Begin()/End() - return g.NavWindow == g.CurrentWindow; -} -bool ImGui::IsRootWindowFocused() -{ - ImGuiContext& g = *GImGui; - IM_ASSERT(g.CurrentWindow); // Not inside a Begin()/End() - return g.NavWindow == g.CurrentWindow->RootWindow; -} - -bool ImGui::IsRootWindowOrAnyChildFocused() -{ - ImGuiContext& g = *GImGui; - IM_ASSERT(g.CurrentWindow); // Not inside a Begin()/End() - return g.NavWindow && g.NavWindow->RootWindow == g.CurrentWindow->RootWindow; + switch (flags & (ImGuiFocusedFlags_RootWindow | ImGuiHoveredFlags_ChildWindows)) + { + case ImGuiFocusedFlags_RootWindow | ImGuiHoveredFlags_ChildWindows: + return g.NavWindow && g.CurrentWindow->RootWindow == g.NavWindow->RootWindow; + case ImGuiFocusedFlags_RootWindow: + return g.CurrentWindow->RootWindow == g.NavWindow; + case ImGuiHoveredFlags_ChildWindows: + return g.NavWindow && IsWindowChildOf(g.NavWindow, g.CurrentWindow); + default: + return g.CurrentWindow == g.NavWindow; + } } float ImGui::GetWindowWidth() diff --git a/imgui.h b/imgui.h index 495f6b369..17f594694 100644 --- a/imgui.h +++ b/imgui.h @@ -80,7 +80,8 @@ typedef int ImDrawCornerFlags; // flags: for ImDrawList::AddRect*() etc. typedef int ImGuiColorEditFlags; // flags: for ColorEdit*(), ColorPicker*() // enum ImGuiColorEditFlags_ typedef int ImGuiColumnsFlags; // flags: for *Columns*() // enum ImGuiColumnsFlags_ typedef int ImGuiComboFlags; // flags: for BeginCombo() // enum ImGuiComboFlags_ -typedef int ImGuiHoveredFlags; // flags: for IsItemHovered() // enum ImGuiHoveredFlags_ +typedef int ImGuiFocusedFlags; // flags: for IsWindowFocused() // enum ImGuiFocusedFlags_ +typedef int ImGuiHoveredFlags; // flags: for IsItemHovered() etc. // enum ImGuiHoveredFlags_ typedef int ImGuiInputTextFlags; // flags: for InputText*() // enum ImGuiInputTextFlags_ typedef int ImGuiSelectableFlags; // flags: for Selectable() // enum ImGuiSelectableFlags_ typedef int ImGuiTreeNodeFlags; // flags: for TreeNode*(),CollapsingHeader()// enum ImGuiTreeNodeFlags_ @@ -442,10 +443,8 @@ namespace ImGui IMGUI_API ImVec2 GetItemRectMax(); // " IMGUI_API ImVec2 GetItemRectSize(); // " IMGUI_API void SetItemAllowOverlap(); // allow last item to be overlapped by a subsequent item. sometimes useful with invisible buttons, selectables, etc. to catch unused area. - IMGUI_API bool IsWindowFocused(); // is current Begin()-ed window focused? - IMGUI_API bool IsWindowHovered(ImGuiHoveredFlags flags = 0); // is current Begin()-ed window hovered (and typically: not blocked by a popup/modal)? - IMGUI_API bool IsRootWindowFocused(); // is current Begin()-ed root window focused (root = top-most parent of a child, otherwise self)? - IMGUI_API bool IsRootWindowOrAnyChildFocused(); // is current Begin()-ed root window or any of its child (including current window) focused? + IMGUI_API bool IsWindowFocused(ImGuiFocusedFlags flags = 0); // is current window focused? or its root/child, depending on flags. see flags for options. + IMGUI_API bool IsWindowHovered(ImGuiHoveredFlags flags = 0); // is current window hovered (and typically: not blocked by a popup/modal)? see flags for options. IMGUI_API bool IsAnyWindowHovered(); // is mouse hovering any visible window IMGUI_API bool IsRectVisible(const ImVec2& size); // test if rectangle (of given size, starting from cursor position) is visible / not clipped. IMGUI_API bool IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max); // test if rectangle (in screen space) is visible / not clipped. to perform coarse clipping on user's side. @@ -599,6 +598,14 @@ enum ImGuiComboFlags_ ImGuiComboFlags_HeightMask_ = ImGuiComboFlags_HeightSmall | ImGuiComboFlags_HeightRegular | ImGuiComboFlags_HeightLarge | ImGuiComboFlags_HeightLargest }; +// Flags for ImGui::IsWindowFocused() +enum ImGuiFocusedFlags_ +{ + ImGuiFocusedFlags_ChildWindows = 1 << 0, // IsWindowFocused(): Return true if any children of the window is focused + ImGuiFocusedFlags_RootWindow = 1 << 1, // IsWindowFocused(): Test from root window (top most parent of the current hierarchy) + ImGuiFocusedFlags_RootAndChildWindows = ImGuiFocusedFlags_RootWindow | ImGuiFocusedFlags_ChildWindows, +}; + // Flags for ImGui::IsItemHovered(), ImGui::IsWindowHovered() enum ImGuiHoveredFlags_ { @@ -938,6 +945,8 @@ struct ImGuiIO #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS namespace ImGui { + static inline bool IsRootWindowFocused() { return IsWindowFocused(ImGuiFocusedFlags_RootWindow); } // OBSOLETE 1.53+ + static inline bool IsRootWindowOrAnyChildFocused() { return IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows); } // OBSOLETE 1.53+ static inline void SetNextWindowContentWidth(float width) { SetNextWindowContentSize(ImVec2(width, 0.0f)); } // OBSOLETE 1.53+ (nb: original version preserved last Y value set by SetNextWindowContentSize()) static inline bool IsRootWindowOrAnyChildHovered(ImGuiHoveredFlags flags = 0) { return IsItemHovered(flags | ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows); } // OBSOLETE 1.53+ use flags directly bool Begin(const char* name, bool* p_open, const ImVec2& size_on_first_use, float bg_alpha_override = -1.0f, ImGuiWindowFlags flags = 0); // OBSOLETE 1.52+. use SetNextWindowSize() instead if you want to set a window size. diff --git a/imgui_demo.cpp b/imgui_demo.cpp index e5c2e15f5..293cc22d4 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1781,8 +1781,24 @@ void ImGui::ShowTestWindow(bool* p_open) ImGui::TreePop(); } - if (ImGui::TreeNode("Hovering")) + if (ImGui::TreeNode("Focused & Hovered Test")) { + static bool embed_all_inside_a_child_window = false; + ImGui::Checkbox("Embed everything inside a child window (for additional testing)", &embed_all_inside_a_child_window); + if (embed_all_inside_a_child_window) + ImGui::BeginChild("embeddingchild", ImVec2(0, ImGui::GetFontSize() * 25), true); + + // Testing IsWindowFocused() function with its various flags (note that the flags can be combined) + ImGui::BulletText( + "IsWindowFocused() = %d\n" + "IsWindowFocused(_ChildWindows) = %d\n" + "IsWindowFocused(_ChildWindows|_RootWindow) = %d\n" + "IsWindowFocused(_RootWindow) = %d\n", + ImGui::IsWindowFocused(), + ImGui::IsWindowFocused(ImGuiHoveredFlags_ChildWindows), + ImGui::IsWindowFocused(ImGuiHoveredFlags_ChildWindows | ImGuiHoveredFlags_RootWindow), + ImGui::IsWindowFocused(ImGuiHoveredFlags_RootWindow)); + // Testing IsWindowHovered() function with its various flags (note that the flags can be combined) ImGui::BulletText( "IsWindowHovered() = %d\n" @@ -1813,9 +1829,12 @@ void ImGui::ShowTestWindow(bool* p_open) ImGui::IsItemHovered(ImGuiHoveredFlags_RectOnly)); ImGui::BeginChild("child", ImVec2(0,50), true); - ImGui::Text("This is a child window for testing IsWindowHovered() flags."); + ImGui::Text("This is another child window for testing IsWindowHovered() flags."); ImGui::EndChild(); + if (embed_all_inside_a_child_window) + EndChild(); + ImGui::TreePop(); } From ee7f1921e88e827f8eec6eea2ba0d796190f574f Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 12 Dec 2017 00:57:45 +0100 Subject: [PATCH 717/921] Internals: Added GetSmallSquareSize() --- imgui.cpp | 18 ++++++------------ imgui_internal.h | 2 ++ 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index f4ca2411c..7b1ad34a1 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -8921,12 +8921,6 @@ bool ImGui::InputTextMultiline(const char* label, char* buf, size_t buf_size, co return InputTextEx(label, buf, (int)buf_size, size, flags | ImGuiInputTextFlags_Multiline, callback, user_data); } -static inline float SmallSquareSize() -{ - ImGuiContext& g = *GImGui; - return g.FontSize + g.Style.FramePadding.y * 2.0f; -} - // NB: scalar_format here must be a simple "%xx" format string with no prefix/suffix (unlike the Drag/Slider functions "display_format" argument) bool ImGui::InputScalarEx(const char* label, ImGuiDataType data_type, void* data_ptr, void* step_ptr, void* step_fast_ptr, const char* scalar_format, ImGuiInputTextFlags extra_flags) { @@ -8940,7 +8934,7 @@ bool ImGui::InputScalarEx(const char* label, ImGuiDataType data_type, void* data BeginGroup(); PushID(label); - const ImVec2 button_sz = ImVec2(SmallSquareSize(), SmallSquareSize()); + const ImVec2 button_sz = ImVec2(GetSmallSquareSize(), GetSmallSquareSize()); if (step_ptr) PushItemWidth(ImMax(1.0f, CalcItemWidth() - (button_sz.x + style.ItemInnerSpacing.x)*2)); @@ -9119,7 +9113,7 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboF bool pressed = ButtonBehavior(frame_bb, id, &hovered, &held); bool popup_open = IsPopupOpen(id); - const float arrow_size = SmallSquareSize(); + const float arrow_size = GetSmallSquareSize(); const ImRect value_bb(frame_bb.Min, frame_bb.Max - ImVec2(arrow_size, 0.0f)); RenderFrame(frame_bb.Min, frame_bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding); RenderFrame(ImVec2(frame_bb.Max.x-arrow_size, frame_bb.Min.y), frame_bb.Max, GetColorU32(popup_open || hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button), true, style.FrameRounding); // FIXME-ROUNDING @@ -9804,7 +9798,7 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl ImGuiContext& g = *GImGui; const ImGuiID id = window->GetID(desc_id); - float default_size = SmallSquareSize(); + float default_size = GetSmallSquareSize(); if (size.x == 0.0f) size.x = default_size; if (size.y == 0.0f) @@ -9914,7 +9908,7 @@ static void ColorPickerOptionsPopup(ImGuiColorEditFlags flags, const float* ref_ ImGuiContext& g = *GImGui; if (allow_opt_picker) { - ImVec2 picker_size(g.FontSize * 8, ImMax(g.FontSize * 8 - (SmallSquareSize() + g.Style.ItemInnerSpacing.x), 1.0f)); // FIXME: Picker size copied from main picker function + ImVec2 picker_size(g.FontSize * 8, ImMax(g.FontSize * 8 - (ImGui::GetSmallSquareSize() + g.Style.ItemInnerSpacing.x), 1.0f)); // FIXME: Picker size copied from main picker function ImGui::PushItemWidth(picker_size.x); for (int picker_type = 0; picker_type < 2; picker_type++) { @@ -9954,7 +9948,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag ImGuiContext& g = *GImGui; const ImGuiStyle& style = g.Style; - const float square_sz = SmallSquareSize(); + const float square_sz = GetSmallSquareSize(); const float w_extra = (flags & ImGuiColorEditFlags_NoSmallPreview) ? 0.0f : (square_sz + style.ItemInnerSpacing.x); const float w_items_all = CalcItemWidth() - w_extra; const char* label_display_end = FindRenderedTextEnd(label); @@ -10192,7 +10186,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl int components = (flags & ImGuiColorEditFlags_NoAlpha) ? 3 : 4; bool alpha_bar = (flags & ImGuiColorEditFlags_AlphaBar) && !(flags & ImGuiColorEditFlags_NoAlpha); ImVec2 picker_pos = window->DC.CursorPos; - float square_sz = SmallSquareSize(); + float square_sz = GetSmallSquareSize(); float bars_width = square_sz; // Arbitrary smallish width of Hue/Alpha picking bars float sv_picker_size = ImMax(bars_width * 1, CalcItemWidth() - (alpha_bar ? 2 : 1) * (bars_width + style.ItemInnerSpacing.x)); // Saturation/Value picking box float bar0_pos_x = picker_pos.x + sv_picker_size + style.ItemInnerSpacing.x; diff --git a/imgui_internal.h b/imgui_internal.h index 417a0fb15..41af164a2 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -829,6 +829,8 @@ namespace ImGui IMGUI_API void PushItemFlag(ImGuiItemFlags option, bool enabled); IMGUI_API void PopItemFlag(); + inline float GetSmallSquareSize() { ImGuiContext& g = *GImGui; return g.FontSize + g.Style.FramePadding.y * 2.0f; } + IMGUI_API void OpenPopupEx(ImGuiID id, bool reopen_existing); IMGUI_API void ClosePopup(ImGuiID id); IMGUI_API bool IsPopupOpen(ImGuiID id); From c22657985a8b33f07c91724aacc314c9deff14a0 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 12 Dec 2017 14:12:49 +0100 Subject: [PATCH 718/921] Added GetFrameHeight() function (used to be SmallSquareSize internally) --- imgui.cpp | 18 ++++++++++++------ imgui.h | 7 ++++--- imgui_internal.h | 2 -- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 7b1ad34a1..825313ba2 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -5748,6 +5748,12 @@ float ImGui::GetTextLineHeightWithSpacing() return g.FontSize + g.Style.ItemSpacing.y; } +float ImGui::GetFrameHeight() +{ + ImGuiContext& g = *GImGui; + return g.FontSize + g.Style.FramePadding.y * 2.0f; +} + float ImGui::GetItemsLineHeightWithSpacing() { ImGuiContext& g = *GImGui; @@ -8934,7 +8940,7 @@ bool ImGui::InputScalarEx(const char* label, ImGuiDataType data_type, void* data BeginGroup(); PushID(label); - const ImVec2 button_sz = ImVec2(GetSmallSquareSize(), GetSmallSquareSize()); + const ImVec2 button_sz = ImVec2(GetFrameHeight(), GetFrameHeight()); if (step_ptr) PushItemWidth(ImMax(1.0f, CalcItemWidth() - (button_sz.x + style.ItemInnerSpacing.x)*2)); @@ -9113,7 +9119,7 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboF bool pressed = ButtonBehavior(frame_bb, id, &hovered, &held); bool popup_open = IsPopupOpen(id); - const float arrow_size = GetSmallSquareSize(); + const float arrow_size = GetFrameHeight(); const ImRect value_bb(frame_bb.Min, frame_bb.Max - ImVec2(arrow_size, 0.0f)); RenderFrame(frame_bb.Min, frame_bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding); RenderFrame(ImVec2(frame_bb.Max.x-arrow_size, frame_bb.Min.y), frame_bb.Max, GetColorU32(popup_open || hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button), true, style.FrameRounding); // FIXME-ROUNDING @@ -9798,7 +9804,7 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl ImGuiContext& g = *GImGui; const ImGuiID id = window->GetID(desc_id); - float default_size = GetSmallSquareSize(); + float default_size = GetFrameHeight(); if (size.x == 0.0f) size.x = default_size; if (size.y == 0.0f) @@ -9908,7 +9914,7 @@ static void ColorPickerOptionsPopup(ImGuiColorEditFlags flags, const float* ref_ ImGuiContext& g = *GImGui; if (allow_opt_picker) { - ImVec2 picker_size(g.FontSize * 8, ImMax(g.FontSize * 8 - (ImGui::GetSmallSquareSize() + g.Style.ItemInnerSpacing.x), 1.0f)); // FIXME: Picker size copied from main picker function + ImVec2 picker_size(g.FontSize * 8, ImMax(g.FontSize * 8 - (ImGui::GetFrameHeight() + g.Style.ItemInnerSpacing.x), 1.0f)); // FIXME: Picker size copied from main picker function ImGui::PushItemWidth(picker_size.x); for (int picker_type = 0; picker_type < 2; picker_type++) { @@ -9948,7 +9954,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag ImGuiContext& g = *GImGui; const ImGuiStyle& style = g.Style; - const float square_sz = GetSmallSquareSize(); + const float square_sz = GetFrameHeight(); const float w_extra = (flags & ImGuiColorEditFlags_NoSmallPreview) ? 0.0f : (square_sz + style.ItemInnerSpacing.x); const float w_items_all = CalcItemWidth() - w_extra; const char* label_display_end = FindRenderedTextEnd(label); @@ -10186,7 +10192,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl int components = (flags & ImGuiColorEditFlags_NoAlpha) ? 3 : 4; bool alpha_bar = (flags & ImGuiColorEditFlags_AlphaBar) && !(flags & ImGuiColorEditFlags_NoAlpha); ImVec2 picker_pos = window->DC.CursorPos; - float square_sz = GetSmallSquareSize(); + float square_sz = GetFrameHeight(); float bars_width = square_sz; // Arbitrary smallish width of Hue/Alpha picking bars float sv_picker_size = ImMax(bars_width * 1, CalcItemWidth() - (alpha_bar ? 2 : 1) * (bars_width + style.ItemInnerSpacing.x)); // Saturation/Value picking box float bar0_pos_x = picker_pos.x + sv_picker_size + style.ItemInnerSpacing.x; diff --git a/imgui.h b/imgui.h index 17f594694..c8bd80cb2 100644 --- a/imgui.h +++ b/imgui.h @@ -232,9 +232,10 @@ namespace ImGui IMGUI_API ImVec2 GetCursorScreenPos(); // cursor position in absolute screen coordinates [0..io.DisplaySize] (useful to work with ImDrawList API) IMGUI_API void SetCursorScreenPos(const ImVec2& pos); // cursor position in absolute screen coordinates [0..io.DisplaySize] IMGUI_API void AlignTextToFramePadding(); // vertically align/lower upcoming text to FramePadding.y so that it will aligns to upcoming widgets (call if you have text on a line before regular widgets) - IMGUI_API float GetTextLineHeight(); // height of font == GetWindowFontSize() - IMGUI_API float GetTextLineHeightWithSpacing(); // distance (in pixels) between 2 consecutive lines of text == GetWindowFontSize() + GetStyle().ItemSpacing.y - IMGUI_API float GetItemsLineHeightWithSpacing(); // distance (in pixels) between 2 consecutive lines of standard height widgets == GetWindowFontSize() + GetStyle().FramePadding.y*2 + GetStyle().ItemSpacing.y + IMGUI_API float GetFrameHeight(); // ~ FontSize + style.FramePadding.y * 2 + IMGUI_API float GetTextLineHeight(); // ~ FontSize + IMGUI_API float GetTextLineHeightWithSpacing(); // ~ FontSize + style.ItemSpacing.y (distance in pixels between 2 consecutive lines of text) + IMGUI_API float GetItemsLineHeightWithSpacing(); // ~ FontSize + style.FramePadding.y * 2 + style.ItemSpacing.y (distance in pixels between 2 consecutive lines of framed widgets) // Columns // You can also use SameLine(pos_x) for simplified columns. The columns API is still work-in-progress and rather lacking. diff --git a/imgui_internal.h b/imgui_internal.h index 41af164a2..417a0fb15 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -829,8 +829,6 @@ namespace ImGui IMGUI_API void PushItemFlag(ImGuiItemFlags option, bool enabled); IMGUI_API void PopItemFlag(); - inline float GetSmallSquareSize() { ImGuiContext& g = *GImGui; return g.FontSize + g.Style.FramePadding.y * 2.0f; } - IMGUI_API void OpenPopupEx(ImGuiID id, bool reopen_existing); IMGUI_API void ClosePopup(ImGuiID id); IMGUI_API bool IsPopupOpen(ImGuiID id); From 6190ab008420087c6d0dbbb64e55d668e66a91c0 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 12 Dec 2017 14:14:58 +0100 Subject: [PATCH 719/921] Renamed GetItemsLineHeightWithSpacing() to GetFrameHeightWithSpacing() --- imgui.cpp | 7 ++++--- imgui.h | 6 +++--- imgui_demo.cpp | 6 +++--- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 825313ba2..1dd4d630f 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -213,8 +213,9 @@ Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. Also read releases logs https://github.com/ocornut/imgui/releases for more details. - - 2017/12/23 (1.53) - marked IsRootWindowFocused() as obsolete in favor of using IsWindowFocused(ImGuiFocusedFlags_RootWindow). - - marked IsRootWindowOrAnyChildFocused() as obsolete in favor of using IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows). + - 2017/12/13 (1.53) - renamed GetItemsLineHeightWithSpacing() to GetFrameHeightWithSpacing(). Kept redirection function (will obsolete). + - 2017/12/13 (1.53) - marked IsRootWindowFocused() as obsolete in favor of using IsWindowFocused(ImGuiFocusedFlags_RootWindow). Kept redirection function (will obsolete). + - marked IsRootWindowOrAnyChildFocused() as obsolete in favor of using IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows). Kept redirection function (will obsolete). - 2017/12/12 (1.53) - renamed ImGuiTreeNodeFlags_AllowOverlapMode to ImGuiTreeNodeFlags_AllowItemOverlap. Kept redirection enum (will obsolete). - 2017/12/10 (1.53) - removed SetNextWindowContentWidth(), prefer using SetNextWindowContentSize(). Kept redirection function (will obsolete). - 2017/11/27 (1.53) - renamed ImGuiTextBuffer::append() helper to appendf(), appendv() to appendfv(). If you copied the 'Log' demo in your code, it uses appendv() so that needs to be renamed. @@ -5754,7 +5755,7 @@ float ImGui::GetFrameHeight() return g.FontSize + g.Style.FramePadding.y * 2.0f; } -float ImGui::GetItemsLineHeightWithSpacing() +float ImGui::GetFrameHeightWithSpacing() { ImGuiContext& g = *GImGui; return g.FontSize + g.Style.FramePadding.y * 2.0f + g.Style.ItemSpacing.y; diff --git a/imgui.h b/imgui.h index c8bd80cb2..328f260b5 100644 --- a/imgui.h +++ b/imgui.h @@ -232,10 +232,10 @@ namespace ImGui IMGUI_API ImVec2 GetCursorScreenPos(); // cursor position in absolute screen coordinates [0..io.DisplaySize] (useful to work with ImDrawList API) IMGUI_API void SetCursorScreenPos(const ImVec2& pos); // cursor position in absolute screen coordinates [0..io.DisplaySize] IMGUI_API void AlignTextToFramePadding(); // vertically align/lower upcoming text to FramePadding.y so that it will aligns to upcoming widgets (call if you have text on a line before regular widgets) - IMGUI_API float GetFrameHeight(); // ~ FontSize + style.FramePadding.y * 2 IMGUI_API float GetTextLineHeight(); // ~ FontSize IMGUI_API float GetTextLineHeightWithSpacing(); // ~ FontSize + style.ItemSpacing.y (distance in pixels between 2 consecutive lines of text) - IMGUI_API float GetItemsLineHeightWithSpacing(); // ~ FontSize + style.FramePadding.y * 2 + style.ItemSpacing.y (distance in pixels between 2 consecutive lines of framed widgets) + IMGUI_API float GetFrameHeight(); // ~ FontSize + style.FramePadding.y * 2 + IMGUI_API float GetFrameHeightWithSpacing(); // ~ FontSize + style.FramePadding.y * 2 + style.ItemSpacing.y (distance in pixels between 2 consecutive lines of framed widgets) // Columns // You can also use SameLine(pos_x) for simplified columns. The columns API is still work-in-progress and rather lacking. @@ -1236,7 +1236,7 @@ struct ImGuiListClipper int ItemsCount, StepNo, DisplayStart, DisplayEnd; // items_count: Use -1 to ignore (you can call Begin later). Use INT_MAX if you don't know how many items you have (in which case the cursor won't be advanced in the final step). - // items_height: Use -1.0f to be calculated automatically on first step. Otherwise pass in the distance between your items, typically GetTextLineHeightWithSpacing() or GetItemsLineHeightWithSpacing(). + // items_height: Use -1.0f to be calculated automatically on first step. Otherwise pass in the distance between your items, typically GetTextLineHeightWithSpacing() or GetFrameHeightWithSpacing(). // If you don't specify an items_height, you NEED to call Step(). If you specify items_height you may call the old Begin()/End() api directly, but prefer calling Step(). ImGuiListClipper(int items_count = -1, float items_height = -1.0f) { Begin(items_count, items_height); } // NB: Begin() initialize every fields (as we allow user to call Begin/End multiple times on a same instance if they want). ~ImGuiListClipper() { IM_ASSERT(ItemsCount == -1); } // Assert if user forgot to call End() or Step() until false. diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 293cc22d4..1e7fcab1b 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1272,7 +1272,7 @@ void ImGui::ShowTestWindow(bool* p_open) ImGui::SliderInt("Lines", &lines, 1, 15); ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 3.0f); ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(2.0f, 1.0f)); - ImGui::BeginChild("scrolling", ImVec2(0, ImGui::GetItemsLineHeightWithSpacing()*7 + 30), true, ImGuiWindowFlags_HorizontalScrollbar); + ImGui::BeginChild("scrolling", ImVec2(0, ImGui::GetFrameHeightWithSpacing()*7 + 30), true, ImGuiWindowFlags_HorizontalScrollbar); for (int line = 0; line < lines; line++) { // Display random stuff (for the sake of this trivial demo we are using basic Button+SameLine. If you want to create your own time line for a real application you may be better off @@ -2521,7 +2521,7 @@ struct ExampleAppConsole ImGui::PopStyleVar(); ImGui::Separator(); - ImGui::BeginChild("ScrollingRegion", ImVec2(0, -ImGui::GetStyle().ItemSpacing.y - ImGui::GetItemsLineHeightWithSpacing()), false, ImGuiWindowFlags_HorizontalScrollbar); // Leave room for 1 separator + 1 InputText + ImGui::BeginChild("ScrollingRegion", ImVec2(0, -ImGui::GetStyle().ItemSpacing.y - ImGui::GetFrameHeightWithSpacing()), false, ImGuiWindowFlags_HorizontalScrollbar); // Leave room for 1 separator + 1 InputText if (ImGui::BeginPopupContextWindow()) { if (ImGui::Selectable("Clear")) ClearLog(); @@ -2843,7 +2843,7 @@ static void ShowExampleAppLayout(bool* p_open) // right ImGui::BeginGroup(); - ImGui::BeginChild("item view", ImVec2(0, -ImGui::GetItemsLineHeightWithSpacing())); // Leave room for 1 line below us + ImGui::BeginChild("item view", ImVec2(0, -ImGui::GetFrameHeightWithSpacing())); // Leave room for 1 line below us ImGui::Text("MyObject: %d", selected); ImGui::Separator(); ImGui::TextWrapped("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. "); From 7ec934f43910ff917239942aed36169996bfdadc Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 12 Dec 2017 15:33:26 +0100 Subject: [PATCH 720/921] Drag and Drop: Comments --- imgui.cpp | 4 +++- imgui.h | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 24d60b729..39290f60f 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -6685,7 +6685,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l toggled |= IsMouseHoveringRect(interact_bb.Min, ImVec2(interact_bb.Min.x + text_offset_x, interact_bb.Max.y)); if (flags & ImGuiTreeNodeFlags_OpenOnDoubleClick) toggled |= g.IO.MouseDoubleClicked[0]; - if (g.DragDropActive && is_open) // We don't nodes to be highlighted when holding ever after the node has been opened, but don't close them! + if (g.DragDropActive && is_open) // When using Drag and Drop "hold to open" we keep the node highlighted after opening, but never close it again. toggled = false; if (toggled) { @@ -9886,6 +9886,7 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl else window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_FrameBg), rounding); // Color button are often in need of some sort of border + // Drag and Drop Source if (g.ActiveId == id && BeginDragDropSource()) // NB: The ActiveId test is merely an optional micro-optimization { if (flags & ImGuiColorEditFlags_NoAlpha) @@ -9899,6 +9900,7 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl hovered = false; } + // Tooltip if (!(flags & ImGuiColorEditFlags_NoTooltip) && hovered) ColorTooltip(desc_id, &col.x, flags & (ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf)); diff --git a/imgui.h b/imgui.h index 3cdec0272..3622dfc80 100644 --- a/imgui.h +++ b/imgui.h @@ -421,6 +421,7 @@ namespace ImGui IMGUI_API void LogText(const char* fmt, ...) IM_FMTARGS(1); // pass text data straight to log (without being displayed) // Drag and Drop + // [BETA API] Missing Demo code. API may evolve. IMGUI_API bool BeginDragDropSource(ImGuiDragDropFlags flags = 0, int mouse_button = 0); // Call when the current item is active. If this return true, you can call SetDragDropPayload() + EndDragDropSource() IMGUI_API bool SetDragDropPayload(const char* type, const void* data, size_t data_size, ImGuiCond cond = 0); // Type is a user defined string of maximum 8 characters. Strings starting with '_' are reserved for dear imgui internal types. Data is copied and held by imgui. IMGUI_API void EndDragDropSource(); From e98df91dc47b8fc17cb2c0963ed9e85d9fc5ce0a Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 12 Dec 2017 15:44:22 +0100 Subject: [PATCH 721/921] Drag and Drop: Added ImGuiCol_DragDropTarget (#143, #707) --- imgui.cpp | 8 ++++---- imgui.h | 1 + imgui_draw.cpp | 4 +++- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 39290f60f..9e632e546 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -5454,6 +5454,7 @@ const char* ImGui::GetStyleColorName(ImGuiCol idx) case ImGuiCol_PlotHistogramHovered: return "PlotHistogramHovered"; case ImGuiCol_TextSelectedBg: return "TextSelectedBg"; case ImGuiCol_ModalWindowDarkening: return "ModalWindowDarkening"; + case ImGuiCol_DragDropTarget: return "DragDropTarget"; } IM_ASSERT(0); return "Unknown"; @@ -11345,12 +11346,11 @@ const ImGuiPayload* ImGui::AcceptDragDropPayload(const char* type, ImGuiDragDrop payload.Preview = was_accepted_previously; if (!(flags & ImGuiDragDropFlags_AcceptNoDrawDefaultRect) && payload.Preview) { - // FIXME-DRAG FIXME-STYLE: Settle on a proper default visuals for drop target, w/ ImGuiCol enum value probably. - r.Expand(5.0f); + // FIXME-DRAG: Settle on a proper default visuals for drop target. + r.Expand(3.5f); bool push_clip_rect = !window->ClipRect.Contains(r); if (push_clip_rect) window->DrawList->PushClipRectFullScreen(); - window->DrawList->AddRectFilled(r.Min, r.Max, IM_COL32(255, 255, 0, 20), 0.0f); - window->DrawList->AddRect(r.Min + ImVec2(1.5f,1.5f), r.Max - ImVec2(1.5f,1.5f), IM_COL32(255, 255, 0, 255), 0.0f, ~0, 2.0f); + window->DrawList->AddRect(r.Min, r.Max, GetColorU32(ImGuiCol_DragDropTarget), 0.0f, ~0, 2.0f); if (push_clip_rect) window->DrawList->PopClipRect(); } diff --git a/imgui.h b/imgui.h index 3622dfc80..5f7493165 100644 --- a/imgui.h +++ b/imgui.h @@ -719,6 +719,7 @@ enum ImGuiCol_ ImGuiCol_PlotHistogramHovered, ImGuiCol_TextSelectedBg, ImGuiCol_ModalWindowDarkening, // darken entire screen when a modal window is active + ImGuiCol_DragDropTarget, ImGuiCol_COUNT // Obsolete names (will be removed) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 7a5bb2dee..69e93689f 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -171,6 +171,7 @@ void ImGui::StyleColorsClassic(ImGuiStyle* dst) colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.60f, 0.00f, 1.00f); colors[ImGuiCol_TextSelectedBg] = ImVec4(0.00f, 0.00f, 1.00f, 0.35f); colors[ImGuiCol_ModalWindowDarkening] = ImVec4(0.20f, 0.20f, 0.20f, 0.35f); + colors[ImGuiCol_DragDropTarget] = ImVec4(1.00f, 1.00f, 0.00f, 0.90f); } void ImGui::StyleColorsDark(ImGuiStyle* dst) @@ -220,6 +221,7 @@ void ImGui::StyleColorsDark(ImGuiStyle* dst) colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.60f, 0.00f, 1.00f); colors[ImGuiCol_TextSelectedBg] = ImVec4(0.26f, 0.59f, 0.98f, 0.35f); colors[ImGuiCol_ModalWindowDarkening] = ImVec4(0.80f, 0.80f, 0.80f, 0.35f); + colors[ImGuiCol_DragDropTarget] = ImVec4(1.00f, 1.00f, 0.00f, 0.90f); } void ImGui::StyleColorsLight(ImGuiStyle* dst) @@ -271,9 +273,9 @@ void ImGui::StyleColorsLight(ImGuiStyle* dst) colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.45f, 0.00f, 1.00f); colors[ImGuiCol_TextSelectedBg] = ImVec4(0.26f, 0.59f, 0.98f, 0.35f); colors[ImGuiCol_ModalWindowDarkening] = ImVec4(0.20f, 0.20f, 0.20f, 0.35f); + colors[ImGuiCol_DragDropTarget] = ImVec4(0.26f, 0.59f, 0.98f, 0.95f); } - //----------------------------------------------------------------------------- // ImDrawList //----------------------------------------------------------------------------- From ef1a683ebe0e0e8bd0ac272f3bf5fc4ab22bcd16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Branimir=20Karad=C5=BEi=C4=87?= Date: Tue, 12 Dec 2017 08:54:51 -0800 Subject: [PATCH 722/921] Removed use of obsolete ImGui API. --- imgui_demo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 1e7fcab1b..4a039482f 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -2574,7 +2574,7 @@ struct ExampleAppConsole } // Demonstrate keeping auto focus on the input box - if (ImGui::IsItemHovered() || (ImGui::IsRootWindowOrAnyChildFocused() && !ImGui::IsAnyItemActive() && !ImGui::IsMouseClicked(0))) + if (ImGui::IsItemHovered() || (ImGui::IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows) && !ImGui::IsAnyItemActive() && !ImGui::IsMouseClicked(0))) ImGui::SetKeyboardFocusHere(-1); // Auto focus previous widget ImGui::End(); From d561a43a4d81259f32822a19b2a30e3883e48923 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 12 Dec 2017 18:17:18 +0100 Subject: [PATCH 723/921] Drag and Drop: Drop target infer a fallback ID from the rectangle. Avoid Preview being accepted on drop frame when drop target has no ID. (#143) --- imgui.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 9e632e546..033b1e513 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -11292,7 +11292,8 @@ bool ImGui::BeginDragDropTargetCustom(const ImRect& bb, ImGuiID id) ImGuiWindow* window = g.CurrentWindow; if (g.HoveredWindow == NULL || window->RootWindow != g.HoveredWindow->RootWindow) return false; - if (!IsMouseHoveringRect(bb.Min, bb.Max) || (id && id == g.DragDropPayload.SourceId)) + IM_ASSERT(id != 0); + if (!IsMouseHoveringRect(bb.Min, bb.Max) || (id == g.DragDropPayload.SourceId)) return false; g.DragDropTargetRect = bb; @@ -11301,7 +11302,7 @@ bool ImGui::BeginDragDropTargetCustom(const ImRect& bb, ImGuiID id) } // We don't use BeginDragDropTargetCustom() and duplicate its code because: -// 1) LastItemRectHoveredRect which handles items that pushes a temporarily clip rectangle in their code. Calling BeginDragDropTargetCustom(LastItemRect) would not handle it. +// 1) we use LastItemRectHoveredRect which handles items that pushes a temporarily clip rectangle in their code. Calling BeginDragDropTargetCustom(LastItemRect) would not handle them. // 2) and it's faster. as this code may be very frequently called, we want to early out as fast as we can. // Also note how the HoveredWindow test is positioned differently in both functions (in both functions we optimize for the cheapest early out case) bool ImGui::BeginDragDropTarget() @@ -11311,13 +11312,19 @@ bool ImGui::BeginDragDropTarget() return false; ImGuiWindow* window = g.CurrentWindow; - if (!window->DC.LastItemRectHoveredRect || (window->DC.LastItemId && window->DC.LastItemId == g.DragDropPayload.SourceId)) + if (!window->DC.LastItemRectHoveredRect) return false; if (g.HoveredWindow == NULL || window->RootWindow != g.HoveredWindow->RootWindow) return false; + ImGuiID id = window->DC.LastItemId; + if (id == 0) + id = window->GetIDFromRectangle(window->DC.LastItemRect); + if (g.DragDropPayload.SourceId == id) + return false; + g.DragDropTargetRect = window->DC.LastItemRect; - g.DragDropTargetId = window->DC.LastItemId; + g.DragDropTargetId = id; return true; } From 28bbf1ade6ba868d4f5fd89ff40b922f4323e573 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 12 Dec 2017 18:45:57 +0100 Subject: [PATCH 724/921] Fixed ParentWindow setup which broke Modal windows (fix c65124f415ae081b1aacaf299c539a32968809a7) --- imgui.cpp | 7 ++----- imgui_internal.h | 2 +- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 1dd4d630f..c0f31f0d9 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2387,10 +2387,7 @@ void ImGui::NewFrame() if (ImGuiWindow* modal_window = GetFrontMostModalRootWindow()) { g.ModalWindowDarkeningRatio = ImMin(g.ModalWindowDarkeningRatio + g.IO.DeltaTime * 6.0f, 1.0f); - ImGuiWindow* window = g.HoveredRootWindow; - while (window && window != modal_window) - window = window->ParentWindow; - if (!window) + if (g.HoveredRootWindow && !IsWindowChildOf(g.HoveredRootWindow, modal_window)) g.HoveredRootWindow = g.HoveredWindow = NULL; } else @@ -4341,7 +4338,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) SetWindowConditionAllowFlags(window, ImGuiCond_Appearing, true); // Parent window is latched only on the first call to Begin() of the frame, so further append-calls can be done from a different window stack - ImGuiWindow* parent_window = first_begin_of_the_frame ? ((flags & ImGuiWindowFlags_ChildWindow) && !g.CurrentWindowStack.empty() ? g.CurrentWindowStack.back() : NULL) : window->ParentWindow; + ImGuiWindow* parent_window = first_begin_of_the_frame ? ((flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_Popup)) && !g.CurrentWindowStack.empty() ? g.CurrentWindowStack.back() : NULL) : window->ParentWindow; IM_ASSERT(parent_window != NULL || !(flags & ImGuiWindowFlags_ChildWindow)); // Add to stack diff --git a/imgui_internal.h b/imgui_internal.h index 417a0fb15..adaa39fc5 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -746,7 +746,7 @@ struct IMGUI_API ImGuiWindow ImGuiStorage StateStorage; float FontWindowScale; // Scale multiplier per-window ImDrawList* DrawList; - ImGuiWindow* ParentWindow; // If we are a child window, this is pointing to our parent. + ImGuiWindow* ParentWindow; // If we are a child _or_ popup window, this is pointing to our parent. Otherwise NULL. ImGuiWindow* RootWindow; // Generally point to ourself. If we are a child window, this is pointing to the first non-child parent window. ImGuiWindow* RootNonPopupWindow; // Generally point to ourself. Used to display TitleBgActive color and for selecting which window to use for NavWindowing From 02e0a078f4ebe9c56ea689f6561c71573a2fe997 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 12 Dec 2017 18:46:42 +0100 Subject: [PATCH 725/921] Begin: Tidying up code to make it more readable. --- imgui.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index c0f31f0d9..acea4565c 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4409,8 +4409,11 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) { // Initialize window->ParentWindow = parent_window; - window->RootWindow = ((flags & ImGuiWindowFlags_ChildWindow) && parent_window) ? parent_window->RootWindow : window; - window->RootNonPopupWindow = !(flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_Popup)) || (flags & ImGuiWindowFlags_Modal) || (parent_window == NULL) ? window : parent_window->RootNonPopupWindow; // Used to display TitleBgActive color and for selecting which window to use for NavWindowing + window->RootWindow = window->RootNonPopupWindow = window; + if (parent_window && (flags & ImGuiWindowFlags_ChildWindow)) + window->RootWindow = parent_window->RootWindow; + if (parent_window && !(flags & ImGuiWindowFlags_Modal) && (flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_Popup))) + window->RootNonPopupWindow = parent_window->RootNonPopupWindow; //window->RootNavWindow = window; //while (window->RootNavWindow->Flags & ImGuiWindowFlags_NavFlattened) // window->RootNavWindow = window->RootNavWindow->ParentWindow; From 7faa5b16bb55d44b87605844d3b715743eebd617 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 12 Dec 2017 19:15:00 +0100 Subject: [PATCH 726/921] Tweak --- imgui.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index acea4565c..09f0442fe 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4338,7 +4338,8 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) SetWindowConditionAllowFlags(window, ImGuiCond_Appearing, true); // Parent window is latched only on the first call to Begin() of the frame, so further append-calls can be done from a different window stack - ImGuiWindow* parent_window = first_begin_of_the_frame ? ((flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_Popup)) && !g.CurrentWindowStack.empty() ? g.CurrentWindowStack.back() : NULL) : window->ParentWindow; + ImGuiWindow* parent_window_in_stack = g.CurrentWindowStack.empty() ? NULL : g.CurrentWindowStack.back(); + ImGuiWindow* parent_window = first_begin_of_the_frame ? ((flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_Popup)) ? parent_window_in_stack : NULL) : window->ParentWindow; IM_ASSERT(parent_window != NULL || !(flags & ImGuiWindowFlags_ChildWindow)); // Add to stack @@ -4559,7 +4560,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // This is how we end up with child menus appearing (most-commonly) on the right of the parent menu. IM_ASSERT(window_pos_set_by_api); float horizontal_overlap = style.ItemSpacing.x; // We want some overlap to convey the relative depth of each popup (currently the amount of overlap it is hard-coded to style.ItemSpacing.x, may need to introduce another style value). - ImGuiWindow* parent_menu = g.CurrentWindowStack[g.CurrentWindowStack.Size - 2]; + ImGuiWindow* parent_menu = parent_window_in_stack; ImRect rect_to_avoid; if (parent_menu->DC.MenuBarAppending) rect_to_avoid = ImRect(-FLT_MAX, parent_menu->Pos.y + parent_menu->TitleBarHeight(), FLT_MAX, parent_menu->Pos.y + parent_menu->TitleBarHeight() + parent_menu->MenuBarHeight()); From ab049c6fc02d68ba0741cb9789612a8a06d0164d Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 12 Dec 2017 20:34:16 +0100 Subject: [PATCH 727/921] Drag and Drop: Fix merge for IMGUI_DISABLE_OBSOLETE_FUNCTIONS --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 033b1e513..11b8dcbc0 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -6674,7 +6674,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l // - OpenOnDoubleClick .............. double-click anywhere to open // - OpenOnArrow .................... single-click on arrow to open // - OpenOnDoubleClick|OpenOnArrow .. single-click on arrow or double-click anywhere to open - ImGuiButtonFlags button_flags = ImGuiButtonFlags_NoKeyModifiers | ((flags & ImGuiTreeNodeFlags_AllowOverlapMode) ? ImGuiButtonFlags_AllowItemOverlap : 0); + ImGuiButtonFlags button_flags = ImGuiButtonFlags_NoKeyModifiers | ((flags & ImGuiTreeNodeFlags_AllowItemOverlap) ? ImGuiButtonFlags_AllowItemOverlap : 0); button_flags |= ImGuiButtonFlags_PressedOnDragDropHold; if (flags & ImGuiTreeNodeFlags_OpenOnDoubleClick) button_flags |= ImGuiButtonFlags_PressedOnDoubleClick | ((flags & ImGuiTreeNodeFlags_OpenOnArrow) ? ImGuiButtonFlags_PressedOnClickRelease : 0); From b174fcc9af7ee1c91f3e6fa16444b07c24e3cbfa Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 12 Dec 2017 23:35:04 +0100 Subject: [PATCH 728/921] Added IsAnyWindowFocused() (from Nav branch). --- imgui.cpp | 6 ++++++ imgui.h | 1 + 2 files changed, 7 insertions(+) diff --git a/imgui.cpp b/imgui.cpp index 7fcc21e79..0dd930bd4 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3399,6 +3399,12 @@ bool ImGui::IsAnyWindowHovered() return g.HoveredWindow != NULL; } +bool ImGui::IsAnyWindowFocused() +{ + ImGuiContext& g = *GImGui; + return g.NavWindow != NULL; +} + static bool IsKeyPressedMap(ImGuiKey key, bool repeat) { const int key_index = GImGui->IO.KeyMap[key]; diff --git a/imgui.h b/imgui.h index 5f7493165..b44f39369 100644 --- a/imgui.h +++ b/imgui.h @@ -457,6 +457,7 @@ namespace ImGui IMGUI_API void SetItemAllowOverlap(); // allow last item to be overlapped by a subsequent item. sometimes useful with invisible buttons, selectables, etc. to catch unused area. IMGUI_API bool IsWindowFocused(ImGuiFocusedFlags flags = 0); // is current window focused? or its root/child, depending on flags. see flags for options. IMGUI_API bool IsWindowHovered(ImGuiHoveredFlags flags = 0); // is current window hovered (and typically: not blocked by a popup/modal)? see flags for options. + IMGUI_API bool IsAnyWindowFocused(); IMGUI_API bool IsAnyWindowHovered(); // is mouse hovering any visible window IMGUI_API bool IsRectVisible(const ImVec2& size); // test if rectangle (of given size, starting from cursor position) is visible / not clipped. IMGUI_API bool IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max); // test if rectangle (in screen space) is visible / not clipped. to perform coarse clipping on user's side. From 7c7a7baf7683f03ed24a88ccfba34b93fe938e13 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 12 Dec 2017 23:36:25 +0100 Subject: [PATCH 729/921] Merged miscellaneous small stuff (from nav/dock branches). --- imgui.cpp | 29 +++++++++++++++++------------ imgui.h | 4 ++-- imgui_internal.h | 16 ++++++++++------ 3 files changed, 29 insertions(+), 20 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 0dd930bd4..dc418eba3 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1826,7 +1826,6 @@ ImGuiWindow::ImGuiWindow(const char* name) ID = ImHash(name, 0); IDStack.push_back(ID); Flags = 0; - OrderWithinParent = 0; PosFloat = Pos = ImVec2(0.0f, 0.0f); Size = SizeFull = ImVec2(0.0f, 0.0f); SizeContents = SizeContentsExplicit = ImVec2(0.0f, 0.0f); @@ -1845,6 +1844,8 @@ ImGuiWindow::ImGuiWindow(const char* name) SkipItems = false; Appearing = false; CloseButton = false; + BeginOrderWithinParent = -1; + BeginOrderWithinContext = -1; BeginCount = 0; PopupId = 0; AutoFitFramesX = AutoFitFramesY = -1; @@ -2271,7 +2272,7 @@ void ImGui::NewFrame() // Initialize on first frame if (!g.Initialized) - ImGui::Initialize(); + Initialize(); SetCurrentFont(GetDefaultFont()); IM_ASSERT(g.Font->IsLoaded()); @@ -2279,6 +2280,7 @@ void ImGui::NewFrame() g.Time += g.IO.DeltaTime; g.FrameCount += 1; g.TooltipOverrideCount = 0; + g.WindowsActiveCount = 0; g.OverlayDrawList.Clear(); g.OverlayDrawList.PushTextureID(g.IO.Fonts->TexID); g.OverlayDrawList.PushClipRectFullScreen(); @@ -2497,8 +2499,8 @@ void ImGui::NewFrame() // Create implicit window - we will only render it if the user has added something to it. // We don't use "Debug" to avoid colliding with user trying to create a "Debug" window with custom flags. - ImGui::SetNextWindowSize(ImVec2(400,400), ImGuiCond_FirstUseEver); - ImGui::Begin("Debug##Default"); + SetNextWindowSize(ImVec2(400,400), ImGuiCond_FirstUseEver); + Begin("Debug##Default"); } static void* SettingsHandlerWindow_ReadOpen(ImGuiContext&, const char* name) @@ -2785,7 +2787,7 @@ static int ChildWindowComparer(const void* lhs, const void* rhs) return d; if (int d = (a->Flags & ImGuiWindowFlags_Tooltip) - (b->Flags & ImGuiWindowFlags_Tooltip)) return d; - return (a->OrderWithinParent - b->OrderWithinParent); + return (a->BeginOrderWithinParent - b->BeginOrderWithinParent); } static void AddWindowToSortedBuffer(ImVector& out_sorted_windows, ImGuiWindow* window) @@ -3359,7 +3361,7 @@ void ImGui::CalcListClipping(int items_count, float items_height, int* out_items static ImGuiWindow* FindHoveredWindow(ImVec2 pos) { ImGuiContext& g = *GImGui; - for (int i = g.Windows.Size-1; i >= 0; i--) + for (int i = g.Windows.Size - 1; i >= 0; i--) { ImGuiWindow* window = g.Windows[i]; if (!window->Active) @@ -3598,7 +3600,8 @@ bool ImGui::IsItemClicked(int mouse_button) bool ImGui::IsAnyItemHovered() { - return GImGui->HoveredId != 0 || GImGui->HoveredIdPreviousFrame != 0; + ImGuiContext& g = *GImGui; + return g.HoveredId != 0 || g.HoveredIdPreviousFrame != 0; } bool ImGui::IsAnyItemActive() @@ -3914,8 +3917,9 @@ bool ImGui::BeginPopupContextItem(const char* str_id, int mouse_button) ImGuiWindow* window = GImGui->CurrentWindow; ImGuiID id = str_id ? window->GetID(str_id) : window->DC.LastItemId; // If user hasn't passed an ID, we can use the LastItemID. Using LastItemID as a Popup ID won't conflict! IM_ASSERT(id != 0); // However, you cannot pass a NULL str_id if the last item has no identifier (e.g. a Text() item) - if (IsMouseClicked(mouse_button) && IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup)) - OpenPopupEx(id, true); + if (IsMouseClicked(mouse_button)) + if (IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup)) + OpenPopupEx(id, true); return BeginPopupEx(id, ImGuiWindowFlags_AlwaysAutoResize); } @@ -4448,7 +4452,8 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // window->RootNavWindow = window->RootNavWindow->ParentWindow; window->Active = true; - window->OrderWithinParent = 0; + window->BeginOrderWithinParent = 0; + window->BeginOrderWithinContext = g.WindowsActiveCount++; window->BeginCount = 0; window->ClipRect = ImVec4(-FLT_MAX,-FLT_MAX,+FLT_MAX,+FLT_MAX); window->LastFrameActive = current_frame; @@ -4570,7 +4575,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // Position child window if (flags & ImGuiWindowFlags_ChildWindow) { - window->OrderWithinParent = parent_window->DC.ChildWindows.Size; + window->BeginOrderWithinParent = parent_window->DC.ChildWindows.Size; parent_window->DC.ChildWindows.push_back(window); } if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Popup) && !window_pos_set_by_api) @@ -6685,6 +6690,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l button_flags |= ImGuiButtonFlags_PressedOnDragDropHold; if (flags & ImGuiTreeNodeFlags_OpenOnDoubleClick) button_flags |= ImGuiButtonFlags_PressedOnDoubleClick | ((flags & ImGuiTreeNodeFlags_OpenOnArrow) ? ImGuiButtonFlags_PressedOnClickRelease : 0); + bool hovered, held, pressed = ButtonBehavior(interact_bb, id, &hovered, &held, button_flags); if (pressed && !(flags & ImGuiTreeNodeFlags_Leaf)) { @@ -6774,7 +6780,6 @@ bool ImGui::CollapsingHeader(const char* label, bool* p_open, ImGuiTreeNodeFlags ImGuiContext& g = *GImGui; float button_sz = g.FontSize * 0.5f; ImGuiItemHoveredDataBackup last_item_backup; - last_item_backup.Backup(); if (CloseButton(window->GetID((void*)(intptr_t)(id+1)), ImVec2(ImMin(window->DC.LastItemRect.Max.x, window->ClipRect.Max.x) - g.Style.FramePadding.x - button_sz, window->DC.LastItemRect.Min.y + g.Style.FramePadding.y + button_sz), button_sz)) *p_open = false; last_item_backup.Restore(); diff --git a/imgui.h b/imgui.h index b44f39369..6bbf2df58 100644 --- a/imgui.h +++ b/imgui.h @@ -79,8 +79,8 @@ typedef int ImGuiMouseCursor; // enum: a mouse cursor identifier typedef int ImGuiStyleVar; // enum: a variable identifier for styling // enum ImGuiStyleVar_ typedef int ImDrawCornerFlags; // flags: for ImDrawList::AddRect*() etc. // enum ImDrawCornerFlags_ typedef int ImGuiColorEditFlags; // flags: for ColorEdit*(), ColorPicker*() // enum ImGuiColorEditFlags_ -typedef int ImGuiDragDropFlags; // flags: for *DragDrop*() // enum ImGuiDragDropFlags_ typedef int ImGuiColumnsFlags; // flags: for *Columns*() // enum ImGuiColumnsFlags_ +typedef int ImGuiDragDropFlags; // flags: for *DragDrop*() // enum ImGuiDragDropFlags_ typedef int ImGuiComboFlags; // flags: for BeginCombo() // enum ImGuiComboFlags_ typedef int ImGuiFocusedFlags; // flags: for IsWindowFocused() // enum ImGuiFocusedFlags_ typedef int ImGuiHoveredFlags; // flags: for IsItemHovered() etc. // enum ImGuiHoveredFlags_ @@ -627,7 +627,7 @@ enum ImGuiHoveredFlags_ ImGuiHoveredFlags_RootWindow = 1 << 1, // IsWindowHovered() only: Test from root window (top most parent of the current hierarchy) ImGuiHoveredFlags_AllowWhenBlockedByPopup = 1 << 2, // Return true even if a popup window is normally blocking access to this item/window //ImGuiHoveredFlags_AllowWhenBlockedByModal = 1 << 3, // Return true even if a modal popup window is normally blocking access to this item/window. FIXME-TODO: Unavailable yet. - ImGuiHoveredFlags_AllowWhenBlockedByActiveItem = 1 << 4, // Return true even if an active item is blocking access to this item/window + ImGuiHoveredFlags_AllowWhenBlockedByActiveItem = 1 << 4, // Return true even if an active item is blocking access to this item/window. Useful for Drag and Drop patterns. ImGuiHoveredFlags_AllowWhenOverlapped = 1 << 5, // Return true even if the position is overlapped by another window ImGuiHoveredFlags_RectOnly = ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem | ImGuiHoveredFlags_AllowWhenOverlapped }; diff --git a/imgui_internal.h b/imgui_internal.h index 16b71bad3..5c0705ad7 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -183,7 +183,7 @@ enum ImGuiButtonFlags_ ImGuiButtonFlags_AllowItemOverlap = 1 << 6, // require previous frame HoveredId to either match id or be null before being usable, use along with SetItemAllowOverlap() ImGuiButtonFlags_DontClosePopups = 1 << 7, // disable automatically closing parent popup on press // [UNUSED] ImGuiButtonFlags_Disabled = 1 << 8, // disable interactions - ImGuiButtonFlags_AlignTextBaseLine = 1 << 9, // vertically align button to match text baseline (ButtonEx() only) + ImGuiButtonFlags_AlignTextBaseLine = 1 << 9, // vertically align button to match text baseline - ButtonEx() only // FIXME: Should be removed and handled by SmallButton(), not possible currently because of DC.CursorPosPrevLine ImGuiButtonFlags_NoKeyModifiers = 1 << 10, // disable interaction if a key modifier is held ImGuiButtonFlags_NoHoldingActiveID = 1 << 11, // don't set ActiveId while holding the mouse (ImGuiButtonFlags_PressedOnClick only) ImGuiButtonFlags_PressedOnDragDropHold = 1 << 12 // press when held into while we are drag and dropping another item (used by e.g. tree nodes, collapsing headers) @@ -207,8 +207,8 @@ enum ImGuiColumnsFlags_ enum ImGuiSelectableFlagsPrivate_ { // NB: need to be in sync with last value of ImGuiSelectableFlags_ - ImGuiSelectableFlags_Menu = 1 << 3, - ImGuiSelectableFlags_MenuItem = 1 << 4, + ImGuiSelectableFlags_Menu = 1 << 3, // -> PressedOnClick + ImGuiSelectableFlags_MenuItem = 1 << 4, // -> PressedOnRelease ImGuiSelectableFlags_Disabled = 1 << 5, ImGuiSelectableFlags_DrawFillAvailWidth = 1 << 6 }; @@ -439,6 +439,7 @@ struct ImGuiContext ImVector WindowsSortBuffer; ImVector CurrentWindowStack; ImGuiStorage WindowsById; + int WindowsActiveCount; ImGuiWindow* CurrentWindow; // Being drawn into ImGuiWindow* NavWindow; // Nav/focused window for navigation ImGuiWindow* HoveredWindow; // Will catch mouse inputs @@ -550,6 +551,7 @@ struct ImGuiContext Time = 0.0f; FrameCount = 0; FrameCountEnded = FrameCountRendered = -1; + WindowsActiveCount = 0; CurrentWindow = NULL; NavWindow = NULL; HoveredWindow = NULL; @@ -723,7 +725,6 @@ struct IMGUI_API ImGuiWindow char* Name; ImGuiID ID; // == ImHash(Name) ImGuiWindowFlags Flags; // See enum ImGuiWindowFlags_ - int OrderWithinParent; // Order within immediate parent window, if we are a child window. Otherwise 0. ImVec2 PosFloat; ImVec2 Pos; // Position rounded-up to nearest pixel ImVec2 Size; // Current size (==SizeFull or collapsed title bar size) @@ -748,6 +749,8 @@ struct IMGUI_API ImGuiWindow bool SkipItems; // Set when items can safely be all clipped (e.g. window not visible or collapsed) bool Appearing; // Set during the frame where the window is appearing (or re-appearing) bool CloseButton; // Set when the window has a close button (p_open != NULL) + int BeginOrderWithinParent; // Order within immediate parent window, if we are a child window. Otherwise 0. + int BeginOrderWithinContext; // Order within entire imgui context. This is mostly used for debugging submission order related issues. int BeginCount; // Number of Begin() during the current frame (generally 0 or 1, 1+ if appending via multiple Begin/End pairs) ImGuiID PopupId; // ID in the popup stack when this window is used as a popup/menu (because we use generic Name/ID for recycling) int AutoFitFramesX, AutoFitFramesY; @@ -809,8 +812,9 @@ struct ImGuiItemHoveredDataBackup ImRect LastItemRect; bool LastItemRectHoveredRect; - void Backup() { ImGuiWindow* window = GImGui->CurrentWindow; LastItemId = window->DC.LastItemId; LastItemRect = window->DC.LastItemRect; LastItemRectHoveredRect = window->DC.LastItemRectHoveredRect; } - void Restore() { ImGuiWindow* window = GImGui->CurrentWindow; window->DC.LastItemId = LastItemId; window->DC.LastItemRect = LastItemRect; window->DC.LastItemRectHoveredRect = LastItemRectHoveredRect; } + ImGuiItemHoveredDataBackup() { Backup(); } + void Backup() { ImGuiWindow* window = GImGui->CurrentWindow; LastItemId = window->DC.LastItemId; LastItemRect = window->DC.LastItemRect; LastItemRectHoveredRect = window->DC.LastItemRectHoveredRect; } + void Restore() const { ImGuiWindow* window = GImGui->CurrentWindow; window->DC.LastItemId = LastItemId; window->DC.LastItemRect = LastItemRect; window->DC.LastItemRectHoveredRect = LastItemRectHoveredRect; } }; //----------------------------------------------------------------------------- From 90788a12423fa169ffc17a41af19e98ccd975216 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 12 Dec 2017 23:36:42 +0100 Subject: [PATCH 730/921] ImVector: Added ImVector::contains() helper --- imgui.h | 1 + 1 file changed, 1 insertion(+) diff --git a/imgui.h b/imgui.h index 6bbf2df58..52a0239fe 100644 --- a/imgui.h +++ b/imgui.h @@ -1052,6 +1052,7 @@ public: inline iterator erase(const_iterator it) { IM_ASSERT(it >= Data && it < Data+Size); const ptrdiff_t off = it - Data; memmove(Data + off, Data + off + 1, ((size_t)Size - (size_t)off - 1) * sizeof(value_type)); Size--; return Data + off; } inline iterator insert(const_iterator it, const value_type& v) { IM_ASSERT(it >= Data && it <= Data+Size); const ptrdiff_t off = it - Data; if (Size == Capacity) reserve(Capacity ? Capacity * 2 : 4); if (off < (int)Size) memmove(Data + off + 1, Data + off, ((size_t)Size - (size_t)off) * sizeof(value_type)); Data[off] = v; Size++; return Data + off; } + inline bool contains(const value_type& v) const { const T* data = Data; const T* data_end = Data + Size; while (data < data_end) if (*data++ == v) return true; return false; } }; // Helper: execute a block of code at maximum once a frame. Convenient if you want to quickly create an UI within deep-nested code that runs multiple times every frame. From 8b59ed070895b319a5f11f816ad0feb682fed30e Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 12 Dec 2017 23:37:27 +0100 Subject: [PATCH 731/921] Drag and Drop: Exposed some internals. --- imgui.cpp | 9 +++++++-- imgui_internal.h | 2 ++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index dc418eba3..b032d549f 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -673,7 +673,6 @@ static bool DataTypeApplyOpFromText(const char* buf, const char* ini namespace ImGui { -static void ClearDragDrop(); static void FocusPreviousWindow(); } @@ -11151,7 +11150,7 @@ void ImGui::Value(const char* prefix, float v, const char* float_format) // DRAG AND DROP //----------------------------------------------------------------------------- -static void ImGui::ClearDragDrop() +void ImGui::ClearDragDrop() { ImGuiContext& g = *GImGui; g.DragDropActive = false; @@ -11340,6 +11339,12 @@ bool ImGui::BeginDragDropTarget() return true; } +bool ImGui::IsDragDropPayloadBeingAccepted() +{ + ImGuiContext& g = *GImGui; + return g.DragDropActive && g.DragDropAcceptIdPrev != 0; +} + const ImGuiPayload* ImGui::AcceptDragDropPayload(const char* type, ImGuiDragDropFlags flags) { ImGuiContext& g = *GImGui; diff --git a/imgui_internal.h b/imgui_internal.h index 5c0705ad7..b8f7e9920 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -873,6 +873,8 @@ namespace ImGui IMGUI_API bool SplitterBehavior(ImGuiID id, const ImRect& bb, ImGuiAxis axis, float* size1, float* size2, float min_size1, float min_size2, float hover_extend = 0.0f); IMGUI_API bool BeginDragDropTargetCustom(const ImRect& bb, ImGuiID id); + IMGUI_API void ClearDragDrop(); + IMGUI_API bool IsDragDropPayloadBeingAccepted(); // FIXME-WIP: New Columns API IMGUI_API void BeginColumns(const char* id, int count, ImGuiColumnsFlags flags = 0); // setup number of columns. use an identifier to distinguish multiple column sets. close with EndColumns(). From 027ffd91ead699e577dd294030158a4307d0b0df Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 12 Dec 2017 23:49:04 +0100 Subject: [PATCH 732/921] IsWindowFocused(): oops, that was bound to happen with loosely typed enums (this is sort of why I made both values identical - no direct side effects). --- imgui.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index b032d549f..c20916ef9 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -5521,13 +5521,13 @@ bool ImGui::IsWindowFocused(ImGuiFocusedFlags flags) ImGuiContext& g = *GImGui; IM_ASSERT(g.CurrentWindow); // Not inside a Begin()/End() - switch (flags & (ImGuiFocusedFlags_RootWindow | ImGuiHoveredFlags_ChildWindows)) + switch (flags & (ImGuiFocusedFlags_RootWindow | ImGuiFocusedFlags_ChildWindows)) { - case ImGuiFocusedFlags_RootWindow | ImGuiHoveredFlags_ChildWindows: + case ImGuiFocusedFlags_RootWindow | ImGuiFocusedFlags_ChildWindows: return g.NavWindow && g.CurrentWindow->RootWindow == g.NavWindow->RootWindow; case ImGuiFocusedFlags_RootWindow: return g.CurrentWindow->RootWindow == g.NavWindow; - case ImGuiHoveredFlags_ChildWindows: + case ImGuiFocusedFlags_ChildWindows: return g.NavWindow && IsWindowChildOf(g.NavWindow, g.CurrentWindow); default: return g.CurrentWindow == g.NavWindow; From 78320aa633a2bb107d3da7925d7f4ab1cdd65704 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 13 Dec 2017 18:37:58 +0100 Subject: [PATCH 733/921] Columns: Refactor: Moved columns data into their own data structure. Minimum changes now to ease diffing. (#125, #1499) --- imgui.cpp | 214 ++++++++++++++++++++++++++--------------------- imgui_internal.h | 70 +++++++++------- 2 files changed, 158 insertions(+), 126 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index c20916ef9..bc60f574a 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -627,8 +627,6 @@ // Forward Declarations //------------------------------------------------------------------------- -static float GetDraggedColumnOffset(int column_index); - static bool IsKeyPressedMap(ImGuiKey key, bool repeat = true); static ImFont* GetDefaultFont(); @@ -1744,8 +1742,8 @@ static void SetCursorPosYAndSetupDummyPrevLine(float pos_y, float line_height) ImGuiWindow* window = ImGui::GetCurrentWindow(); window->DC.CursorPosPrevLine.y = window->DC.CursorPos.y - line_height; // Setting those fields so that SetScrollHere() can properly function after the end of our clipper usage. window->DC.PrevLineHeight = (line_height - GImGui->Style.ItemSpacing.y); // If we end up needing more accurate data (to e.g. use SameLine) we may as well make the clipper have a fourth step to let user process and display the last item in their list. - if (window->DC.ColumnsCount > 1) - window->DC.ColumnsCellMinY = window->DC.CursorPos.y; // Setting this so that cell Y position are set properly + if (window->DC.ColumnsSet) + window->DC.ColumnsSet->ColumnsCellMinY = window->DC.CursorPos.y; // Setting this so that cell Y position are set properly } // Use case A: Begin() called from constructor with items_height<0, then called again from Sync() in StepNo 1 @@ -4833,11 +4831,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->DC.ItemFlagsStack.resize(0); window->DC.ItemWidthStack.resize(0); window->DC.TextWrapPosStack.resize(0); - window->DC.ColumnsCurrent = 0; - window->DC.ColumnsCount = 1; - window->DC.ColumnsStartPosY = window->DC.CursorPos.y; - window->DC.ColumnsStartMaxPosX = window->DC.CursorMaxPos.x; - window->DC.ColumnsCellMinY = window->DC.ColumnsCellMaxY = window->DC.ColumnsStartPosY; + window->DC.ColumnsSet = NULL; window->DC.TreeDepth = 0; window->DC.StateStorage = &window->StateStorage; window->DC.GroupStack.resize(0); @@ -4990,7 +4984,7 @@ void ImGui::End() ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; - if (window->DC.ColumnsCount != 1) // close columns set if any is open + if (window->DC.ColumnsSet != NULL) EndColumns(); PopClipRect(); // inner window clip rectangle @@ -5736,8 +5730,8 @@ ImVec2 ImGui::GetContentRegionMax() { ImGuiWindow* window = GetCurrentWindowRead(); ImVec2 mx = window->ContentsRegionRect.Max; - if (window->DC.ColumnsCount != 1) - mx.x = GetColumnOffset(window->DC.ColumnsCurrent + 1) - window->WindowPadding.x; + if (window->DC.ColumnsSet) + mx.x = GetColumnOffset(window->DC.ColumnsSet->ColumnsCurrent + 1) - window->WindowPadding.x; return mx; } @@ -9347,7 +9341,7 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl ImGuiContext& g = *GImGui; const ImGuiStyle& style = g.Style; - if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.ColumnsCount > 1) // FIXME-OPT: Avoid if vertically clipped. + if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.ColumnsSet) // FIXME-OPT: Avoid if vertically clipped. PopClipRect(); ImGuiID id = window->GetID(label); @@ -9378,7 +9372,7 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl bb_with_spacing.Max.y += spacing_D; if (!ItemAdd(bb_with_spacing, id)) { - if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.ColumnsCount > 1) + if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.ColumnsSet) PushColumnClipRect(); return false; } @@ -9400,7 +9394,7 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl RenderFrame(bb_with_spacing.Min, bb_with_spacing.Max, col, false, 0.0f); } - if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.ColumnsCount > 1) + if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.ColumnsSet) { PushColumnClipRect(); bb_with_spacing.Max.x -= (GetContentRegionMax().x - max_x); @@ -10552,7 +10546,7 @@ void ImGui::Separator() } // Horizontal Separator - if (window->DC.ColumnsCount > 1) + if (window->DC.ColumnsSet) PopClipRect(); float x1 = window->Pos.x; @@ -10564,7 +10558,7 @@ void ImGui::Separator() ItemSize(ImVec2(0.0f, 0.0f)); // NB: we don't provide our width so that it doesn't get feed back into AutoFit, we don't provide height to not alter layout. if (!ItemAdd(bb, 0)) { - if (window->DC.ColumnsCount > 1) + if (window->DC.ColumnsSet) PushColumnClipRect(); return; } @@ -10574,10 +10568,10 @@ void ImGui::Separator() if (g.LogEnabled) LogRenderedText(NULL, IM_NEWLINE "--------------------------------"); - if (window->DC.ColumnsCount > 1) + if (window->DC.ColumnsSet) { PushColumnClipRect(); - window->DC.ColumnsCellMinY = window->DC.CursorPos.y; + window->DC.ColumnsSet->ColumnsCellMinY = window->DC.CursorPos.y; } } @@ -10790,29 +10784,30 @@ void ImGui::NewLine() void ImGui::NextColumn() { ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems || window->DC.ColumnsCount <= 1) + if (window->SkipItems || window->DC.ColumnsSet == NULL) return; ImGuiContext& g = *GImGui; PopItemWidth(); PopClipRect(); - window->DC.ColumnsCellMaxY = ImMax(window->DC.ColumnsCellMaxY, window->DC.CursorPos.y); - if (++window->DC.ColumnsCurrent < window->DC.ColumnsCount) + ImGuiColumnsSet* columns = window->DC.ColumnsSet; + columns->ColumnsCellMaxY = ImMax(columns->ColumnsCellMaxY, window->DC.CursorPos.y); + if (++columns->ColumnsCurrent < columns->ColumnsCount) { // Columns 1+ cancel out IndentX - window->DC.ColumnsOffsetX = GetColumnOffset(window->DC.ColumnsCurrent) - window->DC.IndentX + g.Style.ItemSpacing.x; - window->DrawList->ChannelsSetCurrent(window->DC.ColumnsCurrent); + window->DC.ColumnsOffsetX = GetColumnOffset(columns->ColumnsCurrent) - window->DC.IndentX + g.Style.ItemSpacing.x; + window->DrawList->ChannelsSetCurrent(columns->ColumnsCurrent); } else { - window->DC.ColumnsCurrent = 0; window->DC.ColumnsOffsetX = 0.0f; - window->DC.ColumnsCellMinY = window->DC.ColumnsCellMaxY; + columns->ColumnsCurrent = 0; + columns->ColumnsCellMinY = columns->ColumnsCellMaxY; window->DrawList->ChannelsSetCurrent(0); } window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.IndentX + window->DC.ColumnsOffsetX); - window->DC.CursorPos.y = window->DC.ColumnsCellMinY; + window->DC.CursorPos.y = columns->ColumnsCellMinY; window->DC.CurrentLineHeight = 0.0f; window->DC.CurrentLineTextBaseOffset = 0.0f; @@ -10823,37 +10818,37 @@ void ImGui::NextColumn() int ImGui::GetColumnIndex() { ImGuiWindow* window = GetCurrentWindowRead(); - return window->DC.ColumnsCurrent; + return window->DC.ColumnsSet ? window->DC.ColumnsSet->ColumnsCurrent : 0; } int ImGui::GetColumnsCount() { ImGuiWindow* window = GetCurrentWindowRead(); - return window->DC.ColumnsCount; + return window->DC.ColumnsSet ? window->DC.ColumnsSet->ColumnsCount : 1; } -static float OffsetNormToPixels(ImGuiWindow* window, float offset_norm) +static float OffsetNormToPixels(const ImGuiColumnsSet* columns, float offset_norm) { - return offset_norm * (window->DC.ColumnsMaxX - window->DC.ColumnsMinX); + return offset_norm * (columns->ColumnsMaxX - columns->ColumnsMinX); } -static float PixelsToOffsetNorm(ImGuiWindow* window, float offset) +static float PixelsToOffsetNorm(const ImGuiColumnsSet* columns, float offset) { - return (offset - window->DC.ColumnsMinX) / (window->DC.ColumnsMaxX - window->DC.ColumnsMinX); + return (offset - columns->ColumnsMinX) / (columns->ColumnsMaxX - columns->ColumnsMinX); } -static float GetDraggedColumnOffset(int column_index) +static float GetDraggedColumnOffset(ImGuiColumnsSet* columns, int column_index) { // Active (dragged) column always follow mouse. The reason we need this is that dragging a column to the right edge of an auto-resizing // window creates a feedback loop because we store normalized positions. So while dragging we enforce absolute positioning. ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; IM_ASSERT(column_index > 0); // We cannot drag column 0. If you get this assert you may have a conflict between the ID of your columns and another widgets. - IM_ASSERT(g.ActiveId == window->DC.ColumnsSetId + ImGuiID(column_index)); + IM_ASSERT(g.ActiveId == columns->ColumnsSetId + ImGuiID(column_index)); float x = g.IO.MousePos.x - g.ActiveIdClickOffset.x - window->Pos.x; x = ImMax(x, ImGui::GetColumnOffset(column_index-1) + g.Style.ColumnsMinSpacing); - if ((window->DC.ColumnsFlags & ImGuiColumnsFlags_NoPreserveWidths)) + if ((columns->ColumnsFlags & ImGuiColumnsFlags_NoPreserveWidths)) x = ImMin(x, ImGui::GetColumnOffset(column_index+1) - g.Style.ColumnsMinSpacing); return x; @@ -10862,44 +10857,50 @@ static float GetDraggedColumnOffset(int column_index) float ImGui::GetColumnOffset(int column_index) { ImGuiWindow* window = GetCurrentWindowRead(); + ImGuiColumnsSet* columns = window->DC.ColumnsSet; + IM_ASSERT(columns != NULL); + if (column_index < 0) - column_index = window->DC.ColumnsCurrent; + column_index = columns->ColumnsCurrent; /* if (g.ActiveId) { ImGuiContext& g = *GImGui; - const ImGuiID column_id = window->DC.ColumnsSetId + ImGuiID(column_index); + const ImGuiID column_id = columns->ColumnsSetId + ImGuiID(column_index); if (g.ActiveId == column_id) - return GetDraggedColumnOffset(column_index); + return GetDraggedColumnOffset(columns, column_index); } */ - IM_ASSERT(column_index < window->DC.ColumnsData.Size); - const float t = window->DC.ColumnsData[column_index].OffsetNorm; - const float x_offset = ImLerp(window->DC.ColumnsMinX, window->DC.ColumnsMaxX, t); + IM_ASSERT(column_index < columns->ColumnsData.Size); + const float t = columns->ColumnsData[column_index].OffsetNorm; + const float x_offset = ImLerp(columns->ColumnsMinX, columns->ColumnsMaxX, t); return x_offset; } void ImGui::SetColumnOffset(int column_index, float offset) { ImGuiContext& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); + ImGuiWindow* window = g.CurrentWindow; + ImGuiColumnsSet* columns = window->DC.ColumnsSet; + IM_ASSERT(columns != NULL); + if (column_index < 0) - column_index = window->DC.ColumnsCurrent; + column_index = columns->ColumnsCurrent; - IM_ASSERT(column_index < window->DC.ColumnsData.Size); + IM_ASSERT(column_index < columns->ColumnsData.Size); - const bool preserve_width = !(window->DC.ColumnsFlags & ImGuiColumnsFlags_NoPreserveWidths) && (column_index < window->DC.ColumnsCount-1); + const bool preserve_width = !(columns->ColumnsFlags & ImGuiColumnsFlags_NoPreserveWidths) && (column_index < columns->ColumnsCount-1); const float width = preserve_width ? GetColumnWidth(column_index) : 0.0f; - if (!(window->DC.ColumnsFlags & ImGuiColumnsFlags_NoForceWithinWindow)) - offset = ImMin(offset, window->DC.ColumnsMaxX - g.Style.ColumnsMinSpacing * (window->DC.ColumnsCount - column_index)); - const float offset_norm = PixelsToOffsetNorm(window, offset); + if (!(columns->ColumnsFlags & ImGuiColumnsFlags_NoForceWithinWindow)) + offset = ImMin(offset, columns->ColumnsMaxX - g.Style.ColumnsMinSpacing * (columns->ColumnsCount - column_index)); + const float offset_norm = PixelsToOffsetNorm(columns, offset); - const ImGuiID column_id = window->DC.ColumnsSetId + ImGuiID(column_index); + const ImGuiID column_id = columns->ColumnsSetId + ImGuiID(column_index); window->DC.StateStorage->SetFloat(column_id, offset_norm); - window->DC.ColumnsData[column_index].OffsetNorm = offset_norm; + columns->ColumnsData[column_index].OffsetNorm = offset_norm; if (preserve_width) SetColumnOffset(column_index + 1, offset + ImMax(g.Style.ColumnsMinSpacing, width)); @@ -10908,70 +10909,91 @@ void ImGui::SetColumnOffset(int column_index, float offset) float ImGui::GetColumnWidth(int column_index) { ImGuiWindow* window = GetCurrentWindowRead(); - if (column_index < 0) - column_index = window->DC.ColumnsCurrent; + ImGuiColumnsSet* columns = window->DC.ColumnsSet; + IM_ASSERT(columns != NULL); - return OffsetNormToPixels(window, window->DC.ColumnsData[column_index+1].OffsetNorm - window->DC.ColumnsData[column_index].OffsetNorm); + if (column_index < 0) + column_index = columns->ColumnsCurrent; + return OffsetNormToPixels(columns, columns->ColumnsData[column_index+1].OffsetNorm - columns->ColumnsData[column_index].OffsetNorm); } void ImGui::SetColumnWidth(int column_index, float width) { ImGuiWindow* window = GetCurrentWindowRead(); - if (column_index < 0) - column_index = window->DC.ColumnsCurrent; + ImGuiColumnsSet* columns = window->DC.ColumnsSet; + IM_ASSERT(columns != NULL); + if (column_index < 0) + column_index = columns->ColumnsCurrent; SetColumnOffset(column_index+1, GetColumnOffset(column_index) + width); } void ImGui::PushColumnClipRect(int column_index) { ImGuiWindow* window = GetCurrentWindowRead(); + ImGuiColumnsSet* columns = window->DC.ColumnsSet; if (column_index < 0) - column_index = window->DC.ColumnsCurrent; + column_index = columns->ColumnsCurrent; - PushClipRect(window->DC.ColumnsData[column_index].ClipRect.Min, window->DC.ColumnsData[column_index].ClipRect.Max, false); + PushClipRect(columns->ColumnsData[column_index].ClipRect.Min, columns->ColumnsData[column_index].ClipRect.Max, false); } -void ImGui::BeginColumns(const char* id, int columns_count, ImGuiColumnsFlags flags) +static ImGuiColumnsSet* FindOrAddColumnsSet(ImGuiWindow* window, ImGuiID id) +{ + for (int n = 0; n < window->DC.ColumnsSets.Size; n++) + if (window->DC.ColumnsSets[n].ColumnsSetId == id) + return &window->DC.ColumnsSets[n]; + + window->DC.ColumnsSets.push_back(ImGuiColumnsSet()); + ImGuiColumnsSet* columns = &window->DC.ColumnsSets.back(); + columns->ColumnsSetId = id; + return columns; +} + +void ImGui::BeginColumns(const char* str_id, int columns_count, ImGuiColumnsFlags flags) { ImGuiContext& g = *GImGui; ImGuiWindow* window = GetCurrentWindow(); IM_ASSERT(columns_count > 1); - IM_ASSERT(window->DC.ColumnsCount == 1); // Nested columns are currently not supported + IM_ASSERT(window->DC.ColumnsSet == NULL); // Nested columns are currently not supported // Differentiate column ID with an arbitrary prefix for cases where users name their columns set the same as another widget. // In addition, when an identifier isn't explicitly provided we include the number of columns in the hash to make it uniquer. - PushID(0x11223347 + (id ? 0 : columns_count)); - window->DC.ColumnsSetId = window->GetID(id ? id : "columns"); + PushID(0x11223347 + (str_id ? 0 : columns_count)); + ImGuiID id = window->GetID(str_id ? str_id : "columns"); PopID(); + ImGuiColumnsSet* columns = FindOrAddColumnsSet(window, id); + IM_ASSERT(columns->ColumnsSetId == id); + window->DC.ColumnsSet = columns; + // Set state for first column - window->DC.ColumnsCurrent = 0; - window->DC.ColumnsCount = columns_count; - window->DC.ColumnsFlags = flags; + columns->ColumnsCurrent = 0; + columns->ColumnsCount = columns_count; + columns->ColumnsFlags = flags; const float content_region_width = (window->SizeContentsExplicit.x != 0.0f) ? (window->SizeContentsExplicit.x) : (window->Size.x -window->ScrollbarSizes.x); - window->DC.ColumnsMinX = window->DC.IndentX - g.Style.ItemSpacing.x; // Lock our horizontal range - //window->DC.ColumnsMaxX = content_region_width - window->Scroll.x -((window->Flags & ImGuiWindowFlags_NoScrollbar) ? 0 : g.Style.ScrollbarSize);// - window->WindowPadding().x; - window->DC.ColumnsMaxX = content_region_width - window->Scroll.x; - window->DC.ColumnsStartPosY = window->DC.CursorPos.y; - window->DC.ColumnsStartMaxPosX = window->DC.CursorMaxPos.x; - window->DC.ColumnsCellMinY = window->DC.ColumnsCellMaxY = window->DC.CursorPos.y; + columns->ColumnsMinX = window->DC.IndentX - g.Style.ItemSpacing.x; // Lock our horizontal range + //column->ColumnsMaxX = content_region_width - window->Scroll.x -((window->Flags & ImGuiWindowFlags_NoScrollbar) ? 0 : g.Style.ScrollbarSize);// - window->WindowPadding().x; + columns->ColumnsMaxX = content_region_width - window->Scroll.x; + columns->ColumnsStartPosY = window->DC.CursorPos.y; + columns->ColumnsStartMaxPosX = window->DC.CursorMaxPos.x; + columns->ColumnsCellMinY = columns->ColumnsCellMaxY = window->DC.CursorPos.y; window->DC.ColumnsOffsetX = 0.0f; window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.IndentX + window->DC.ColumnsOffsetX); // Cache column offsets - window->DC.ColumnsData.resize(columns_count + 1); + columns->ColumnsData.resize(columns_count + 1); for (int column_index = 0; column_index < columns_count + 1; column_index++) { - const ImGuiID column_id = window->DC.ColumnsSetId + ImGuiID(column_index); + const ImGuiID column_id = columns->ColumnsSetId + ImGuiID(column_index); KeepAliveID(column_id); - const float default_t = column_index / (float)window->DC.ColumnsCount; + const float default_t = column_index / (float)columns_count; float t = window->DC.StateStorage->GetFloat(column_id, default_t); - if (!(window->DC.ColumnsFlags & ImGuiColumnsFlags_NoForceWithinWindow)) - t = ImMin(t, PixelsToOffsetNorm(window, window->DC.ColumnsMaxX - g.Style.ColumnsMinSpacing * (window->DC.ColumnsCount - column_index))); - window->DC.ColumnsData[column_index].OffsetNorm = t; + if (!(columns->ColumnsFlags & ImGuiColumnsFlags_NoForceWithinWindow)) + t = ImMin(t, PixelsToOffsetNorm(columns, columns->ColumnsMaxX - g.Style.ColumnsMinSpacing * (columns->ColumnsCount - column_index))); + columns->ColumnsData[column_index].OffsetNorm = t; } // Cache clipping rectangles @@ -10979,11 +11001,11 @@ void ImGui::BeginColumns(const char* id, int columns_count, ImGuiColumnsFlags fl { float clip_x1 = ImFloor(0.5f + window->Pos.x + GetColumnOffset(column_index) - 1.0f); float clip_x2 = ImFloor(0.5f + window->Pos.x + GetColumnOffset(column_index + 1) - 1.0f); - window->DC.ColumnsData[column_index].ClipRect = ImRect(clip_x1, -FLT_MAX, clip_x2, +FLT_MAX); - window->DC.ColumnsData[column_index].ClipRect.ClipWith(window->ClipRect); + columns->ColumnsData[column_index].ClipRect = ImRect(clip_x1, -FLT_MAX, clip_x2, +FLT_MAX); + columns->ColumnsData[column_index].ClipRect.ClipWith(window->ClipRect); } - window->DrawList->ChannelsSplit(window->DC.ColumnsCount); + window->DrawList->ChannelsSplit(columns->ColumnsCount); PushColumnClipRect(); PushItemWidth(GetColumnWidth() * 0.65f); } @@ -10992,34 +11014,35 @@ void ImGui::EndColumns() { ImGuiContext& g = *GImGui; ImGuiWindow* window = GetCurrentWindow(); - IM_ASSERT(window->DC.ColumnsCount > 1); + ImGuiColumnsSet* columns = window->DC.ColumnsSet; + IM_ASSERT(columns != NULL); PopItemWidth(); PopClipRect(); window->DrawList->ChannelsMerge(); - window->DC.ColumnsCellMaxY = ImMax(window->DC.ColumnsCellMaxY, window->DC.CursorPos.y); - window->DC.CursorPos.y = window->DC.ColumnsCellMaxY; - if (!(window->DC.ColumnsFlags & ImGuiColumnsFlags_GrowParentContentsSize)) - window->DC.CursorMaxPos.x = ImMax(window->DC.ColumnsStartMaxPosX, window->DC.ColumnsMaxX); // Restore cursor max pos, as columns don't grow parent + columns->ColumnsCellMaxY = ImMax(columns->ColumnsCellMaxY, window->DC.CursorPos.y); + window->DC.CursorPos.y = columns->ColumnsCellMaxY; + if (!(columns->ColumnsFlags & ImGuiColumnsFlags_GrowParentContentsSize)) + window->DC.CursorMaxPos.x = ImMax(columns->ColumnsStartMaxPosX, columns->ColumnsMaxX); // Restore cursor max pos, as columns don't grow parent // Draw columns borders and handle resize - if (!(window->DC.ColumnsFlags & ImGuiColumnsFlags_NoBorder) && !window->SkipItems) + if (!(columns->ColumnsFlags & ImGuiColumnsFlags_NoBorder) && !window->SkipItems) { - const float y1 = window->DC.ColumnsStartPosY; + const float y1 = columns->ColumnsStartPosY; const float y2 = window->DC.CursorPos.y; int dragging_column = -1; - for (int i = 1; i < window->DC.ColumnsCount; i++) + for (int i = 1; i < columns->ColumnsCount; i++) { float x = window->Pos.x + GetColumnOffset(i); - const ImGuiID column_id = window->DC.ColumnsSetId + ImGuiID(i); + const ImGuiID column_id = columns->ColumnsSetId + ImGuiID(i); const float column_hw = 4.0f; // Half-width for interaction const ImRect column_rect(ImVec2(x - column_hw, y1), ImVec2(x + column_hw, y2)); if (IsClippedEx(column_rect, column_id, false)) continue; bool hovered = false, held = false; - if (!(window->DC.ColumnsFlags & ImGuiColumnsFlags_NoResize)) + if (!(columns->ColumnsFlags & ImGuiColumnsFlags_NoResize)) { ButtonBehavior(column_rect, column_id, &hovered, &held); if (hovered || held) @@ -11040,16 +11063,13 @@ void ImGui::EndColumns() // Apply dragging after drawing the column lines, so our rendered lines are in sync with how items were displayed during the frame. if (dragging_column != -1) { - float x = GetDraggedColumnOffset(dragging_column); + float x = GetDraggedColumnOffset(columns, dragging_column); SetColumnOffset(dragging_column, x); } } - window->DC.ColumnsSetId = 0; - window->DC.ColumnsCurrent = 0; - window->DC.ColumnsCount = 1; - window->DC.ColumnsFlags = 0; - window->DC.ColumnsData.resize(0); + columns->ColumnsData.resize(0); + window->DC.ColumnsSet = NULL; window->DC.ColumnsOffsetX = 0.0f; window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.IndentX + window->DC.ColumnsOffsetX); } @@ -11060,7 +11080,7 @@ void ImGui::Columns(int columns_count, const char* id, bool border) ImGuiWindow* window = GetCurrentWindow(); IM_ASSERT(columns_count >= 1); - if (window->DC.ColumnsCount != columns_count && window->DC.ColumnsCount != 1) + if (window->DC.ColumnsSet != NULL && window->DC.ColumnsSet->ColumnsCount != columns_count) EndColumns(); ImGuiColumnsFlags flags = (border ? 0 : ImGuiColumnsFlags_NoBorder); diff --git a/imgui_internal.h b/imgui_internal.h index b8f7e9920..30ac97073 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -331,14 +331,6 @@ struct ImGuiGroupData bool AdvanceCursor; }; -// Per column data for Columns() -struct ImGuiColumnData -{ - float OffsetNorm; // Column start offset, normalized 0.0 (far left) -> 1.0 (far right) - ImRect ClipRect; - //float IndentX; -}; - // Simple column measurement currently used for MenuItem() only. This is very short-sighted/throw-away code and NOT a generic helper. struct IMGUI_API ImGuiSimpleColumns { @@ -420,6 +412,42 @@ struct ImGuiPopupRef ImGuiPopupRef(ImGuiID id, ImGuiWindow* parent_window, ImGuiID parent_menu_set, const ImVec2& mouse_pos) { PopupId = id; Window = NULL; ParentWindow = parent_window; ParentMenuSet = parent_menu_set; MousePosOnOpen = mouse_pos; } }; +// Per column data for Columns() +struct ImGuiColumnData +{ + float OffsetNorm; // Column start offset, normalized 0.0 (far left) -> 1.0 (far right) + ImRect ClipRect; +}; + +struct ImGuiColumnsSet +{ + int ColumnsCurrent; + int ColumnsCount; + float ColumnsMinX; + float ColumnsMaxX; + float ColumnsStartPosY; + float ColumnsStartMaxPosX; // Backup of CursorMaxPos + float ColumnsCellMinY; + float ColumnsCellMaxY; + ImGuiColumnsFlags ColumnsFlags; + ImGuiID ColumnsSetId; + ImVector ColumnsData; + + ImGuiColumnsSet() { Clear(); } + void Clear() + { + ColumnsCurrent = 0; + ColumnsCount = 1; + ColumnsMinX = ColumnsMaxX = 0.0f; + ColumnsStartPosY = 0.0f; + ColumnsStartMaxPosX = 0.0f; + ColumnsCellMinY = ColumnsCellMaxY = 0.0f; + ColumnsFlags = 0; + ColumnsSetId = 0; + ColumnsData.clear(); + } +}; + // Main state for ImGui struct ImGuiContext { @@ -674,17 +702,8 @@ struct IMGUI_API ImGuiDrawContext float IndentX; // Indentation / start position from left of window (increased by TreePush/TreePop, etc.) float GroupOffsetX; float ColumnsOffsetX; // Offset to the current column (if ColumnsCurrent > 0). FIXME: This and the above should be a stack to allow use cases like Tree->Column->Tree. Need revamp columns API. - int ColumnsCurrent; - int ColumnsCount; - float ColumnsMinX; - float ColumnsMaxX; - float ColumnsStartPosY; - float ColumnsStartMaxPosX; // Backup of CursorMaxPos - float ColumnsCellMinY; - float ColumnsCellMaxY; - ImGuiColumnsFlags ColumnsFlags; - ImGuiID ColumnsSetId; - ImVector ColumnsData; + ImGuiColumnsSet* ColumnsSet; + ImVector ColumnsSets; ImGuiDrawContext() { @@ -708,14 +727,7 @@ struct IMGUI_API ImGuiDrawContext IndentX = 0.0f; GroupOffsetX = 0.0f; ColumnsOffsetX = 0.0f; - ColumnsCurrent = 0; - ColumnsCount = 1; - ColumnsMinX = ColumnsMaxX = 0.0f; - ColumnsStartPosY = 0.0f; - ColumnsStartMaxPosX = 0.0f; - ColumnsCellMinY = ColumnsCellMaxY = 0.0f; - ColumnsFlags = 0; - ColumnsSetId = 0; + ColumnsSet = NULL; } }; @@ -877,8 +889,8 @@ namespace ImGui IMGUI_API bool IsDragDropPayloadBeingAccepted(); // FIXME-WIP: New Columns API - IMGUI_API void BeginColumns(const char* id, int count, ImGuiColumnsFlags flags = 0); // setup number of columns. use an identifier to distinguish multiple column sets. close with EndColumns(). - IMGUI_API void EndColumns(); // close columns + IMGUI_API void BeginColumns(const char* str_id, int count, ImGuiColumnsFlags flags = 0); // setup number of columns. use an identifier to distinguish multiple column sets. close with EndColumns(). + IMGUI_API void EndColumns(); // close columns IMGUI_API void PushColumnClipRect(int column_index = -1); // NB: All position are in absolute pixels coordinates (never using window coordinates internally) From 3a31a75e3b9c184a8aab05c8c093bde833215eb6 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 13 Dec 2017 18:42:06 +0100 Subject: [PATCH 734/921] Columns: Refactor: Renamed all members. (#125, #1499) --- imgui.cpp | 124 +++++++++++++++++++++++------------------------ imgui_internal.h | 38 +++++++-------- 2 files changed, 80 insertions(+), 82 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index bc60f574a..38af18669 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1743,7 +1743,7 @@ static void SetCursorPosYAndSetupDummyPrevLine(float pos_y, float line_height) window->DC.CursorPosPrevLine.y = window->DC.CursorPos.y - line_height; // Setting those fields so that SetScrollHere() can properly function after the end of our clipper usage. window->DC.PrevLineHeight = (line_height - GImGui->Style.ItemSpacing.y); // If we end up needing more accurate data (to e.g. use SameLine) we may as well make the clipper have a fourth step to let user process and display the last item in their list. if (window->DC.ColumnsSet) - window->DC.ColumnsSet->ColumnsCellMinY = window->DC.CursorPos.y; // Setting this so that cell Y position are set properly + window->DC.ColumnsSet->CellMinY = window->DC.CursorPos.y; // Setting this so that cell Y position are set properly } // Use case A: Begin() called from constructor with items_height<0, then called again from Sync() in StepNo 1 @@ -5731,7 +5731,7 @@ ImVec2 ImGui::GetContentRegionMax() ImGuiWindow* window = GetCurrentWindowRead(); ImVec2 mx = window->ContentsRegionRect.Max; if (window->DC.ColumnsSet) - mx.x = GetColumnOffset(window->DC.ColumnsSet->ColumnsCurrent + 1) - window->WindowPadding.x; + mx.x = GetColumnOffset(window->DC.ColumnsSet->Current + 1) - window->WindowPadding.x; return mx; } @@ -10571,7 +10571,7 @@ void ImGui::Separator() if (window->DC.ColumnsSet) { PushColumnClipRect(); - window->DC.ColumnsSet->ColumnsCellMinY = window->DC.CursorPos.y; + window->DC.ColumnsSet->CellMinY = window->DC.CursorPos.y; } } @@ -10792,22 +10792,22 @@ void ImGui::NextColumn() PopClipRect(); ImGuiColumnsSet* columns = window->DC.ColumnsSet; - columns->ColumnsCellMaxY = ImMax(columns->ColumnsCellMaxY, window->DC.CursorPos.y); - if (++columns->ColumnsCurrent < columns->ColumnsCount) + columns->CellMaxY = ImMax(columns->CellMaxY, window->DC.CursorPos.y); + if (++columns->Current < columns->Count) { // Columns 1+ cancel out IndentX - window->DC.ColumnsOffsetX = GetColumnOffset(columns->ColumnsCurrent) - window->DC.IndentX + g.Style.ItemSpacing.x; - window->DrawList->ChannelsSetCurrent(columns->ColumnsCurrent); + window->DC.ColumnsOffsetX = GetColumnOffset(columns->Current) - window->DC.IndentX + g.Style.ItemSpacing.x; + window->DrawList->ChannelsSetCurrent(columns->Current); } else { window->DC.ColumnsOffsetX = 0.0f; - columns->ColumnsCurrent = 0; - columns->ColumnsCellMinY = columns->ColumnsCellMaxY; + columns->Current = 0; + columns->CellMinY = columns->CellMaxY; window->DrawList->ChannelsSetCurrent(0); } window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.IndentX + window->DC.ColumnsOffsetX); - window->DC.CursorPos.y = columns->ColumnsCellMinY; + window->DC.CursorPos.y = columns->CellMinY; window->DC.CurrentLineHeight = 0.0f; window->DC.CurrentLineTextBaseOffset = 0.0f; @@ -10818,23 +10818,23 @@ void ImGui::NextColumn() int ImGui::GetColumnIndex() { ImGuiWindow* window = GetCurrentWindowRead(); - return window->DC.ColumnsSet ? window->DC.ColumnsSet->ColumnsCurrent : 0; + return window->DC.ColumnsSet ? window->DC.ColumnsSet->Current : 0; } int ImGui::GetColumnsCount() { ImGuiWindow* window = GetCurrentWindowRead(); - return window->DC.ColumnsSet ? window->DC.ColumnsSet->ColumnsCount : 1; + return window->DC.ColumnsSet ? window->DC.ColumnsSet->Count : 1; } static float OffsetNormToPixels(const ImGuiColumnsSet* columns, float offset_norm) { - return offset_norm * (columns->ColumnsMaxX - columns->ColumnsMinX); + return offset_norm * (columns->MaxX - columns->MinX); } static float PixelsToOffsetNorm(const ImGuiColumnsSet* columns, float offset) { - return (offset - columns->ColumnsMinX) / (columns->ColumnsMaxX - columns->ColumnsMinX); + return (offset - columns->MinX) / (columns->MaxX - columns->MinX); } static float GetDraggedColumnOffset(ImGuiColumnsSet* columns, int column_index) @@ -10844,11 +10844,11 @@ static float GetDraggedColumnOffset(ImGuiColumnsSet* columns, int column_index) ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; IM_ASSERT(column_index > 0); // We cannot drag column 0. If you get this assert you may have a conflict between the ID of your columns and another widgets. - IM_ASSERT(g.ActiveId == columns->ColumnsSetId + ImGuiID(column_index)); + IM_ASSERT(g.ActiveId == columns->ID + ImGuiID(column_index)); float x = g.IO.MousePos.x - g.ActiveIdClickOffset.x - window->Pos.x; x = ImMax(x, ImGui::GetColumnOffset(column_index-1) + g.Style.ColumnsMinSpacing); - if ((columns->ColumnsFlags & ImGuiColumnsFlags_NoPreserveWidths)) + if ((columns->Flags & ImGuiColumnsFlags_NoPreserveWidths)) x = ImMin(x, ImGui::GetColumnOffset(column_index+1) - g.Style.ColumnsMinSpacing); return x; @@ -10861,7 +10861,7 @@ float ImGui::GetColumnOffset(int column_index) IM_ASSERT(columns != NULL); if (column_index < 0) - column_index = columns->ColumnsCurrent; + column_index = columns->Current; /* if (g.ActiveId) @@ -10873,9 +10873,9 @@ float ImGui::GetColumnOffset(int column_index) } */ - IM_ASSERT(column_index < columns->ColumnsData.Size); - const float t = columns->ColumnsData[column_index].OffsetNorm; - const float x_offset = ImLerp(columns->ColumnsMinX, columns->ColumnsMaxX, t); + IM_ASSERT(column_index < columns->Columns.Size); + const float t = columns->Columns[column_index].OffsetNorm; + const float x_offset = ImLerp(columns->MinX, columns->MaxX, t); return x_offset; } @@ -10887,20 +10887,20 @@ void ImGui::SetColumnOffset(int column_index, float offset) IM_ASSERT(columns != NULL); if (column_index < 0) - column_index = columns->ColumnsCurrent; + column_index = columns->Current; - IM_ASSERT(column_index < columns->ColumnsData.Size); + IM_ASSERT(column_index < columns->Columns.Size); - const bool preserve_width = !(columns->ColumnsFlags & ImGuiColumnsFlags_NoPreserveWidths) && (column_index < columns->ColumnsCount-1); + const bool preserve_width = !(columns->Flags & ImGuiColumnsFlags_NoPreserveWidths) && (column_index < columns->Count-1); const float width = preserve_width ? GetColumnWidth(column_index) : 0.0f; - if (!(columns->ColumnsFlags & ImGuiColumnsFlags_NoForceWithinWindow)) - offset = ImMin(offset, columns->ColumnsMaxX - g.Style.ColumnsMinSpacing * (columns->ColumnsCount - column_index)); + if (!(columns->Flags & ImGuiColumnsFlags_NoForceWithinWindow)) + offset = ImMin(offset, columns->MaxX - g.Style.ColumnsMinSpacing * (columns->Count - column_index)); const float offset_norm = PixelsToOffsetNorm(columns, offset); - const ImGuiID column_id = columns->ColumnsSetId + ImGuiID(column_index); + const ImGuiID column_id = columns->ID + ImGuiID(column_index); window->DC.StateStorage->SetFloat(column_id, offset_norm); - columns->ColumnsData[column_index].OffsetNorm = offset_norm; + columns->Columns[column_index].OffsetNorm = offset_norm; if (preserve_width) SetColumnOffset(column_index + 1, offset + ImMax(g.Style.ColumnsMinSpacing, width)); @@ -10913,8 +10913,8 @@ float ImGui::GetColumnWidth(int column_index) IM_ASSERT(columns != NULL); if (column_index < 0) - column_index = columns->ColumnsCurrent; - return OffsetNormToPixels(columns, columns->ColumnsData[column_index+1].OffsetNorm - columns->ColumnsData[column_index].OffsetNorm); + column_index = columns->Current; + return OffsetNormToPixels(columns, columns->Columns[column_index+1].OffsetNorm - columns->Columns[column_index].OffsetNorm); } void ImGui::SetColumnWidth(int column_index, float width) @@ -10924,7 +10924,7 @@ void ImGui::SetColumnWidth(int column_index, float width) IM_ASSERT(columns != NULL); if (column_index < 0) - column_index = columns->ColumnsCurrent; + column_index = columns->Current; SetColumnOffset(column_index+1, GetColumnOffset(column_index) + width); } @@ -10933,20 +10933,20 @@ void ImGui::PushColumnClipRect(int column_index) ImGuiWindow* window = GetCurrentWindowRead(); ImGuiColumnsSet* columns = window->DC.ColumnsSet; if (column_index < 0) - column_index = columns->ColumnsCurrent; + column_index = columns->Current; - PushClipRect(columns->ColumnsData[column_index].ClipRect.Min, columns->ColumnsData[column_index].ClipRect.Max, false); + PushClipRect(columns->Columns[column_index].ClipRect.Min, columns->Columns[column_index].ClipRect.Max, false); } static ImGuiColumnsSet* FindOrAddColumnsSet(ImGuiWindow* window, ImGuiID id) { for (int n = 0; n < window->DC.ColumnsSets.Size; n++) - if (window->DC.ColumnsSets[n].ColumnsSetId == id) + if (window->DC.ColumnsSets[n].ID == id) return &window->DC.ColumnsSets[n]; window->DC.ColumnsSets.push_back(ImGuiColumnsSet()); ImGuiColumnsSet* columns = &window->DC.ColumnsSets.back(); - columns->ColumnsSetId = id; + columns->ID = id; return columns; } @@ -10965,35 +10965,35 @@ void ImGui::BeginColumns(const char* str_id, int columns_count, ImGuiColumnsFlag PopID(); ImGuiColumnsSet* columns = FindOrAddColumnsSet(window, id); - IM_ASSERT(columns->ColumnsSetId == id); + IM_ASSERT(columns->ID == id); window->DC.ColumnsSet = columns; // Set state for first column - columns->ColumnsCurrent = 0; - columns->ColumnsCount = columns_count; - columns->ColumnsFlags = flags; + columns->Current = 0; + columns->Count = columns_count; + columns->Flags = flags; const float content_region_width = (window->SizeContentsExplicit.x != 0.0f) ? (window->SizeContentsExplicit.x) : (window->Size.x -window->ScrollbarSizes.x); - columns->ColumnsMinX = window->DC.IndentX - g.Style.ItemSpacing.x; // Lock our horizontal range + columns->MinX = window->DC.IndentX - g.Style.ItemSpacing.x; // Lock our horizontal range //column->ColumnsMaxX = content_region_width - window->Scroll.x -((window->Flags & ImGuiWindowFlags_NoScrollbar) ? 0 : g.Style.ScrollbarSize);// - window->WindowPadding().x; - columns->ColumnsMaxX = content_region_width - window->Scroll.x; - columns->ColumnsStartPosY = window->DC.CursorPos.y; - columns->ColumnsStartMaxPosX = window->DC.CursorMaxPos.x; - columns->ColumnsCellMinY = columns->ColumnsCellMaxY = window->DC.CursorPos.y; + columns->MaxX = content_region_width - window->Scroll.x; + columns->StartPosY = window->DC.CursorPos.y; + columns->StartMaxPosX = window->DC.CursorMaxPos.x; + columns->CellMinY = columns->CellMaxY = window->DC.CursorPos.y; window->DC.ColumnsOffsetX = 0.0f; window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.IndentX + window->DC.ColumnsOffsetX); // Cache column offsets - columns->ColumnsData.resize(columns_count + 1); + columns->Columns.resize(columns_count + 1); for (int column_index = 0; column_index < columns_count + 1; column_index++) { - const ImGuiID column_id = columns->ColumnsSetId + ImGuiID(column_index); + const ImGuiID column_id = columns->ID + ImGuiID(column_index); KeepAliveID(column_id); const float default_t = column_index / (float)columns_count; float t = window->DC.StateStorage->GetFloat(column_id, default_t); - if (!(columns->ColumnsFlags & ImGuiColumnsFlags_NoForceWithinWindow)) - t = ImMin(t, PixelsToOffsetNorm(columns, columns->ColumnsMaxX - g.Style.ColumnsMinSpacing * (columns->ColumnsCount - column_index))); - columns->ColumnsData[column_index].OffsetNorm = t; + if (!(columns->Flags & ImGuiColumnsFlags_NoForceWithinWindow)) + t = ImMin(t, PixelsToOffsetNorm(columns, columns->MaxX - g.Style.ColumnsMinSpacing * (columns->Count - column_index))); + columns->Columns[column_index].OffsetNorm = t; } // Cache clipping rectangles @@ -11001,11 +11001,11 @@ void ImGui::BeginColumns(const char* str_id, int columns_count, ImGuiColumnsFlag { float clip_x1 = ImFloor(0.5f + window->Pos.x + GetColumnOffset(column_index) - 1.0f); float clip_x2 = ImFloor(0.5f + window->Pos.x + GetColumnOffset(column_index + 1) - 1.0f); - columns->ColumnsData[column_index].ClipRect = ImRect(clip_x1, -FLT_MAX, clip_x2, +FLT_MAX); - columns->ColumnsData[column_index].ClipRect.ClipWith(window->ClipRect); + columns->Columns[column_index].ClipRect = ImRect(clip_x1, -FLT_MAX, clip_x2, +FLT_MAX); + columns->Columns[column_index].ClipRect.ClipWith(window->ClipRect); } - window->DrawList->ChannelsSplit(columns->ColumnsCount); + window->DrawList->ChannelsSplit(columns->Count); PushColumnClipRect(); PushItemWidth(GetColumnWidth() * 0.65f); } @@ -11021,28 +11021,28 @@ void ImGui::EndColumns() PopClipRect(); window->DrawList->ChannelsMerge(); - columns->ColumnsCellMaxY = ImMax(columns->ColumnsCellMaxY, window->DC.CursorPos.y); - window->DC.CursorPos.y = columns->ColumnsCellMaxY; - if (!(columns->ColumnsFlags & ImGuiColumnsFlags_GrowParentContentsSize)) - window->DC.CursorMaxPos.x = ImMax(columns->ColumnsStartMaxPosX, columns->ColumnsMaxX); // Restore cursor max pos, as columns don't grow parent + columns->CellMaxY = ImMax(columns->CellMaxY, window->DC.CursorPos.y); + window->DC.CursorPos.y = columns->CellMaxY; + if (!(columns->Flags & ImGuiColumnsFlags_GrowParentContentsSize)) + window->DC.CursorMaxPos.x = ImMax(columns->StartMaxPosX, columns->MaxX); // Restore cursor max pos, as columns don't grow parent // Draw columns borders and handle resize - if (!(columns->ColumnsFlags & ImGuiColumnsFlags_NoBorder) && !window->SkipItems) + if (!(columns->Flags & ImGuiColumnsFlags_NoBorder) && !window->SkipItems) { - const float y1 = columns->ColumnsStartPosY; + const float y1 = columns->StartPosY; const float y2 = window->DC.CursorPos.y; int dragging_column = -1; - for (int i = 1; i < columns->ColumnsCount; i++) + for (int i = 1; i < columns->Count; i++) { float x = window->Pos.x + GetColumnOffset(i); - const ImGuiID column_id = columns->ColumnsSetId + ImGuiID(i); + const ImGuiID column_id = columns->ID + ImGuiID(i); const float column_hw = 4.0f; // Half-width for interaction const ImRect column_rect(ImVec2(x - column_hw, y1), ImVec2(x + column_hw, y2)); if (IsClippedEx(column_rect, column_id, false)) continue; bool hovered = false, held = false; - if (!(columns->ColumnsFlags & ImGuiColumnsFlags_NoResize)) + if (!(columns->Flags & ImGuiColumnsFlags_NoResize)) { ButtonBehavior(column_rect, column_id, &hovered, &held); if (hovered || held) @@ -11068,7 +11068,7 @@ void ImGui::EndColumns() } } - columns->ColumnsData.resize(0); + columns->Columns.resize(0); window->DC.ColumnsSet = NULL; window->DC.ColumnsOffsetX = 0.0f; window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.IndentX + window->DC.ColumnsOffsetX); @@ -11080,7 +11080,7 @@ void ImGui::Columns(int columns_count, const char* id, bool border) ImGuiWindow* window = GetCurrentWindow(); IM_ASSERT(columns_count >= 1); - if (window->DC.ColumnsSet != NULL && window->DC.ColumnsSet->ColumnsCount != columns_count) + if (window->DC.ColumnsSet != NULL && window->DC.ColumnsSet->Count != columns_count) EndColumns(); ImGuiColumnsFlags flags = (border ? 0 : ImGuiColumnsFlags_NoBorder); diff --git a/imgui_internal.h b/imgui_internal.h index 30ac97073..ab990e508 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -421,30 +421,28 @@ struct ImGuiColumnData struct ImGuiColumnsSet { - int ColumnsCurrent; - int ColumnsCount; - float ColumnsMinX; - float ColumnsMaxX; - float ColumnsStartPosY; - float ColumnsStartMaxPosX; // Backup of CursorMaxPos - float ColumnsCellMinY; - float ColumnsCellMaxY; - ImGuiColumnsFlags ColumnsFlags; - ImGuiID ColumnsSetId; - ImVector ColumnsData; + ImGuiID ID; + ImGuiColumnsFlags Flags; + int Current; + int Count; + float MinX, MaxX; + float StartPosY; + float StartMaxPosX; // Backup of CursorMaxPos + float CellMinY, CellMaxY; + ImVector Columns; ImGuiColumnsSet() { Clear(); } void Clear() { - ColumnsCurrent = 0; - ColumnsCount = 1; - ColumnsMinX = ColumnsMaxX = 0.0f; - ColumnsStartPosY = 0.0f; - ColumnsStartMaxPosX = 0.0f; - ColumnsCellMinY = ColumnsCellMaxY = 0.0f; - ColumnsFlags = 0; - ColumnsSetId = 0; - ColumnsData.clear(); + ID = 0; + Flags = 0; + Current = 0; + Count = 1; + MinX = MaxX = 0.0f; + StartPosY = 0.0f; + StartMaxPosX = 0.0f; + CellMinY = CellMaxY = 0.0f; + Columns.clear(); } }; From b016215c80f64fef17b8aaad843167c3c8d3855b Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 13 Dec 2017 19:07:09 +0100 Subject: [PATCH 735/921] Columns: Refactor: Not using statestorage lookup anymore. (#125, #1499) --- imgui.cpp | 71 +++++++++++++++++++++++++----------------------- imgui_internal.h | 5 ++-- 2 files changed, 40 insertions(+), 36 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 38af18669..e12e6ea64 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -10847,9 +10847,9 @@ static float GetDraggedColumnOffset(ImGuiColumnsSet* columns, int column_index) IM_ASSERT(g.ActiveId == columns->ID + ImGuiID(column_index)); float x = g.IO.MousePos.x - g.ActiveIdClickOffset.x - window->Pos.x; - x = ImMax(x, ImGui::GetColumnOffset(column_index-1) + g.Style.ColumnsMinSpacing); + x = ImMax(x, ImGui::GetColumnOffset(column_index - 1) + g.Style.ColumnsMinSpacing); if ((columns->Flags & ImGuiColumnsFlags_NoPreserveWidths)) - x = ImMin(x, ImGui::GetColumnOffset(column_index+1) - g.Style.ColumnsMinSpacing); + x = ImMin(x, ImGui::GetColumnOffset(column_index + 1) - g.Style.ColumnsMinSpacing); return x; } @@ -10862,6 +10862,7 @@ float ImGui::GetColumnOffset(int column_index) if (column_index < 0) column_index = columns->Current; + IM_ASSERT(column_index < columns->Columns.Size); /* if (g.ActiveId) @@ -10873,7 +10874,6 @@ float ImGui::GetColumnOffset(int column_index) } */ - IM_ASSERT(column_index < columns->Columns.Size); const float t = columns->Columns[column_index].OffsetNorm; const float x_offset = ImLerp(columns->MinX, columns->MaxX, t); return x_offset; @@ -10888,7 +10888,6 @@ void ImGui::SetColumnOffset(int column_index, float offset) if (column_index < 0) column_index = columns->Current; - IM_ASSERT(column_index < columns->Columns.Size); const bool preserve_width = !(columns->Flags & ImGuiColumnsFlags_NoPreserveWidths) && (column_index < columns->Count-1); @@ -10896,11 +10895,7 @@ void ImGui::SetColumnOffset(int column_index, float offset) if (!(columns->Flags & ImGuiColumnsFlags_NoForceWithinWindow)) offset = ImMin(offset, columns->MaxX - g.Style.ColumnsMinSpacing * (columns->Count - column_index)); - const float offset_norm = PixelsToOffsetNorm(columns, offset); - - const ImGuiID column_id = columns->ID + ImGuiID(column_index); - window->DC.StateStorage->SetFloat(column_id, offset_norm); - columns->Columns[column_index].OffsetNorm = offset_norm; + columns->Columns[column_index].OffsetNorm = PixelsToOffsetNorm(columns, offset); if (preserve_width) SetColumnOffset(column_index + 1, offset + ImMax(g.Style.ColumnsMinSpacing, width)); @@ -10925,7 +10920,7 @@ void ImGui::SetColumnWidth(int column_index, float width) if (column_index < 0) column_index = columns->Current; - SetColumnOffset(column_index+1, GetColumnOffset(column_index) + width); + SetColumnOffset(column_index + 1, GetColumnOffset(column_index) + width); } void ImGui::PushColumnClipRect(int column_index) @@ -10964,15 +10959,15 @@ void ImGui::BeginColumns(const char* str_id, int columns_count, ImGuiColumnsFlag ImGuiID id = window->GetID(str_id ? str_id : "columns"); PopID(); + // Acquire storage for the columns set ImGuiColumnsSet* columns = FindOrAddColumnsSet(window, id); IM_ASSERT(columns->ID == id); - window->DC.ColumnsSet = columns; - - // Set state for first column columns->Current = 0; columns->Count = columns_count; columns->Flags = flags; + window->DC.ColumnsSet = columns; + // Set state for first column const float content_region_width = (window->SizeContentsExplicit.x != 0.0f) ? (window->SizeContentsExplicit.x) : (window->Size.x -window->ScrollbarSizes.x); columns->MinX = window->DC.IndentX - g.Style.ItemSpacing.x; // Lock our horizontal range //column->ColumnsMaxX = content_region_width - window->Scroll.x -((window->Flags & ImGuiWindowFlags_NoScrollbar) ? 0 : g.Style.ScrollbarSize);// - window->WindowPadding().x; @@ -10983,26 +10978,36 @@ void ImGui::BeginColumns(const char* str_id, int columns_count, ImGuiColumnsFlag window->DC.ColumnsOffsetX = 0.0f; window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.IndentX + window->DC.ColumnsOffsetX); - // Cache column offsets - columns->Columns.resize(columns_count + 1); - for (int column_index = 0; column_index < columns_count + 1; column_index++) + // Initialize defaults + if (columns->Columns.Size == 0) { - const ImGuiID column_id = columns->ID + ImGuiID(column_index); - KeepAliveID(column_id); - const float default_t = column_index / (float)columns_count; - float t = window->DC.StateStorage->GetFloat(column_id, default_t); - if (!(columns->Flags & ImGuiColumnsFlags_NoForceWithinWindow)) - t = ImMin(t, PixelsToOffsetNorm(columns, columns->MaxX - g.Style.ColumnsMinSpacing * (columns->Count - column_index))); - columns->Columns[column_index].OffsetNorm = t; + columns->Columns.reserve(columns_count + 1); + for (int n = 0; n < columns_count + 1; n++) + { + ImGuiColumnData column; + column.OffsetNorm = n / (float)columns_count; + columns->Columns.push_back(column); + } } + IM_ASSERT(columns->Columns.Size == columns_count + 1); - // Cache clipping rectangles - for (int column_index = 0; column_index < columns_count; column_index++) + for (int n = 0; n < columns_count + 1; n++) { - float clip_x1 = ImFloor(0.5f + window->Pos.x + GetColumnOffset(column_index) - 1.0f); - float clip_x2 = ImFloor(0.5f + window->Pos.x + GetColumnOffset(column_index + 1) - 1.0f); - columns->Columns[column_index].ClipRect = ImRect(clip_x1, -FLT_MAX, clip_x2, +FLT_MAX); - columns->Columns[column_index].ClipRect.ClipWith(window->ClipRect); + // Clamp + ImGuiColumnData* column = &columns->Columns[n]; + float t = column->OffsetNorm; + if (!(columns->Flags & ImGuiColumnsFlags_NoForceWithinWindow)) + t = ImMin(t, PixelsToOffsetNorm(columns, columns->MaxX - g.Style.ColumnsMinSpacing * (columns->Count - n))); + column->OffsetNorm = t; + + if (n == columns_count) + continue; + + // Compute clipping rectangles + float clip_x1 = ImFloor(0.5f + window->Pos.x + GetColumnOffset(n) - 1.0f); + float clip_x2 = ImFloor(0.5f + window->Pos.x + GetColumnOffset(n + 1) - 1.0f); + column->ClipRect = ImRect(clip_x1, -FLT_MAX, clip_x2, +FLT_MAX); + column->ClipRect.ClipWith(window->ClipRect); } window->DrawList->ChannelsSplit(columns->Count); @@ -11038,6 +11043,7 @@ void ImGui::EndColumns() const ImGuiID column_id = columns->ID + ImGuiID(i); const float column_hw = 4.0f; // Half-width for interaction const ImRect column_rect(ImVec2(x - column_hw, y1), ImVec2(x + column_hw, y2)); + KeepAliveID(column_id); if (IsClippedEx(column_rect, column_id, false)) continue; @@ -11053,8 +11059,7 @@ void ImGui::EndColumns() dragging_column = i; } - // Draw column - // We clip the Y boundaries CPU side because very long triangles are mishandled by some GPU drivers. + // Draw column (we clip the Y boundaries CPU side because very long triangles are mishandled by some GPU drivers.) const ImU32 col = GetColorU32(held ? ImGuiCol_SeparatorActive : hovered ? ImGuiCol_SeparatorHovered : ImGuiCol_Separator); const float xi = (float)(int)x; window->DrawList->AddLine(ImVec2(xi, ImMax(y1 + 1.0f, window->ClipRect.Min.y)), ImVec2(xi, ImMin(y2, window->ClipRect.Max.y)), col); @@ -11068,18 +11073,16 @@ void ImGui::EndColumns() } } - columns->Columns.resize(0); window->DC.ColumnsSet = NULL; window->DC.ColumnsOffsetX = 0.0f; window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.IndentX + window->DC.ColumnsOffsetX); } -// [2017/08: This is currently the only public API, while we are working on making BeginColumns/EndColumns user-facing] +// [2017/12: This is currently the only public API, while we are working on making BeginColumns/EndColumns user-facing] void ImGui::Columns(int columns_count, const char* id, bool border) { ImGuiWindow* window = GetCurrentWindow(); IM_ASSERT(columns_count >= 1); - if (window->DC.ColumnsSet != NULL && window->DC.ColumnsSet->Count != columns_count) EndColumns(); diff --git a/imgui_internal.h b/imgui_internal.h index ab990e508..e2975ecee 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -412,11 +412,12 @@ struct ImGuiPopupRef ImGuiPopupRef(ImGuiID id, ImGuiWindow* parent_window, ImGuiID parent_menu_set, const ImVec2& mouse_pos) { PopupId = id; Window = NULL; ParentWindow = parent_window; ParentMenuSet = parent_menu_set; MousePosOnOpen = mouse_pos; } }; -// Per column data for Columns() struct ImGuiColumnData { - float OffsetNorm; // Column start offset, normalized 0.0 (far left) -> 1.0 (far right) + float OffsetNorm; // Column start offset, normalized 0.0 (far left) -> 1.0 (far right) ImRect ClipRect; + + ImGuiColumnData() { OffsetNorm = 0.0f; } }; struct ImGuiColumnsSet From 4ae5c7e22716a4f1d0555b7f317d5850052506fa Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 13 Dec 2017 19:21:21 +0100 Subject: [PATCH 736/921] Columns: Refactor: Moved ColumnsSet[] to window out of DC as they are persistent data for most + fix for pre C++11 compilers. (#125, #1499) --- imgui.cpp | 10 +++++----- imgui_internal.h | 20 ++++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index e12e6ea64..e28b99393 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -10935,12 +10935,12 @@ void ImGui::PushColumnClipRect(int column_index) static ImGuiColumnsSet* FindOrAddColumnsSet(ImGuiWindow* window, ImGuiID id) { - for (int n = 0; n < window->DC.ColumnsSets.Size; n++) - if (window->DC.ColumnsSets[n].ID == id) - return &window->DC.ColumnsSets[n]; + for (int n = 0; n < window->ColumnsStorage.Size; n++) + if (window->ColumnsStorage[n].ID == id) + return &window->ColumnsStorage[n]; - window->DC.ColumnsSets.push_back(ImGuiColumnsSet()); - ImGuiColumnsSet* columns = &window->DC.ColumnsSets.back(); + window->ColumnsStorage.push_back(ImGuiColumnsSet()); + ImGuiColumnsSet* columns = &window->ColumnsStorage.back(); columns->ID = id; return columns; } diff --git a/imgui_internal.h b/imgui_internal.h index e2975ecee..f79f46b10 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -201,7 +201,7 @@ enum ImGuiColumnsFlags_ ImGuiColumnsFlags_NoResize = 1 << 1, // Disable resizing columns when clicking on the dividers ImGuiColumnsFlags_NoPreserveWidths = 1 << 2, // Disable column width preservation when adjusting columns ImGuiColumnsFlags_NoForceWithinWindow = 1 << 3, // Disable forcing columns to fit within window - ImGuiColumnsFlags_GrowParentContentsSize= 1 << 4, // (WIP) Restore pre-1.51 behavior of extending the parent window contents size but _without affecting the columns width at all_. Will eventually remove. + ImGuiColumnsFlags_GrowParentContentsSize= 1 << 4 // (WIP) Restore pre-1.51 behavior of extending the parent window contents size but _without affecting the columns width at all_. Will eventually remove. }; enum ImGuiSelectableFlagsPrivate_ @@ -403,19 +403,19 @@ struct ImGuiMouseCursorData // Storage for current popup stack struct ImGuiPopupRef { - ImGuiID PopupId; // Set on OpenPopup() - ImGuiWindow* Window; // Resolved on BeginPopup() - may stay unresolved if user never calls OpenPopup() - ImGuiWindow* ParentWindow; // Set on OpenPopup() - ImGuiID ParentMenuSet; // Set on OpenPopup() - ImVec2 MousePosOnOpen; // Copy of mouse position at the time of opening popup + ImGuiID PopupId; // Set on OpenPopup() + ImGuiWindow* Window; // Resolved on BeginPopup() - may stay unresolved if user never calls OpenPopup() + ImGuiWindow* ParentWindow; // Set on OpenPopup() + ImGuiID ParentMenuSet; // Set on OpenPopup() + ImVec2 MousePosOnOpen; // Copy of mouse position at the time of opening popup ImGuiPopupRef(ImGuiID id, ImGuiWindow* parent_window, ImGuiID parent_menu_set, const ImVec2& mouse_pos) { PopupId = id; Window = NULL; ParentWindow = parent_window; ParentMenuSet = parent_menu_set; MousePosOnOpen = mouse_pos; } }; struct ImGuiColumnData { - float OffsetNorm; // Column start offset, normalized 0.0 (far left) -> 1.0 (far right) - ImRect ClipRect; + float OffsetNorm; // Column start offset, normalized 0.0 (far left) -> 1.0 (far right) + ImRect ClipRect; ImGuiColumnData() { OffsetNorm = 0.0f; } }; @@ -701,8 +701,7 @@ struct IMGUI_API ImGuiDrawContext float IndentX; // Indentation / start position from left of window (increased by TreePush/TreePop, etc.) float GroupOffsetX; float ColumnsOffsetX; // Offset to the current column (if ColumnsCurrent > 0). FIXME: This and the above should be a stack to allow use cases like Tree->Column->Tree. Need revamp columns API. - ImGuiColumnsSet* ColumnsSet; - ImVector ColumnsSets; + ImGuiColumnsSet* ColumnsSet; // Current columns set ImGuiDrawContext() { @@ -784,6 +783,7 @@ struct IMGUI_API ImGuiWindow float ItemWidthDefault; ImGuiSimpleColumns MenuColumns; // Simplified columns storage for menu items ImGuiStorage StateStorage; + ImVector ColumnsStorage; float FontWindowScale; // Scale multiplier per-window ImDrawList* DrawList; ImGuiWindow* ParentWindow; // If we are a child _or_ popup window, this is pointing to our parent. Otherwise NULL. From e8e84a6ad68c339f3e1c537069655b6d228b7eae Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 13 Dec 2017 19:26:04 +0100 Subject: [PATCH 737/921] Columns: Added internal tracking of a few flag temporarily, to facilitate the work of third-parties who have columns patches. (#125) --- imgui.cpp | 3 +++ imgui_internal.h | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/imgui.cpp b/imgui.cpp index e28b99393..bd6282255 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -10979,6 +10979,7 @@ void ImGui::BeginColumns(const char* str_id, int columns_count, ImGuiColumnsFlag window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.IndentX + window->DC.ColumnsOffsetX); // Initialize defaults + columns->IsFirstFrame = (columns->Columns.Size == 0); if (columns->Columns.Size == 0) { columns->Columns.reserve(columns_count + 1); @@ -11032,6 +11033,7 @@ void ImGui::EndColumns() window->DC.CursorMaxPos.x = ImMax(columns->StartMaxPosX, columns->MaxX); // Restore cursor max pos, as columns don't grow parent // Draw columns borders and handle resize + columns->IsBeingResized = false; if (!(columns->Flags & ImGuiColumnsFlags_NoBorder) && !window->SkipItems) { const float y1 = columns->StartPosY; @@ -11070,6 +11072,7 @@ void ImGui::EndColumns() { float x = GetDraggedColumnOffset(columns, dragging_column); SetColumnOffset(dragging_column, x); + columns->IsBeingResized = true; } } diff --git a/imgui_internal.h b/imgui_internal.h index f79f46b10..ca1086b91 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -424,6 +424,8 @@ struct ImGuiColumnsSet { ImGuiID ID; ImGuiColumnsFlags Flags; + bool IsFirstFrame; + bool IsBeingResized; int Current; int Count; float MinX, MaxX; @@ -437,6 +439,8 @@ struct ImGuiColumnsSet { ID = 0; Flags = 0; + IsFirstFrame = false; + IsBeingResized = false; Current = 0; Count = 1; MinX = MaxX = 0.0f; From f7c5f420e7e87dd420a553eac5c2a1e55904d3ec Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 13 Dec 2017 19:44:54 +0100 Subject: [PATCH 738/921] BeginChild() fix using negative sizes as window position because of erroneous clamping. It was hard to notice until we added asserts for it. (#1500) --- imgui.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index bd6282255..0055b05f0 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3953,9 +3953,9 @@ static bool BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, b ImVec2 size = ImFloor(size_arg); const int auto_fit_axises = ((size.x == 0.0f) ? (1 << ImGuiAxis_X) : 0x00) | ((size.y == 0.0f) ? (1 << ImGuiAxis_Y) : 0x00); if (size.x <= 0.0f) - size.x = ImMax(content_avail.x, 4.0f) - fabsf(size.x); // Arbitrary minimum zero-ish child size of 4.0f (0.0f causing too much issues) + size.x = ImMax(content_avail.x + size.x, 4.0f); // Arbitrary minimum child size (0.0f causing too much issues) if (size.y <= 0.0f) - size.y = ImMax(content_avail.y, 4.0f) - fabsf(size.y); + size.y = ImMax(content_avail.y + size.y, 4.0f); const float backup_border_size = g.Style.ChildBorderSize; if (!border) From ba71e1c0e4afab77f263d2b5c5a445e85bca87a2 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 13 Dec 2017 21:48:56 +0100 Subject: [PATCH 739/921] Columns: Minor stylistic fixes. (#125) --- imgui.cpp | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 0055b05f0..91b777734 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -10879,6 +10879,17 @@ float ImGui::GetColumnOffset(int column_index) return x_offset; } +float ImGui::GetColumnWidth(int column_index) +{ + ImGuiWindow* window = GetCurrentWindowRead(); + ImGuiColumnsSet* columns = window->DC.ColumnsSet; + IM_ASSERT(columns != NULL); + + if (column_index < 0) + column_index = columns->Current; + return OffsetNormToPixels(columns, columns->Columns[column_index + 1].OffsetNorm - columns->Columns[column_index].OffsetNorm); +} + void ImGui::SetColumnOffset(int column_index, float offset) { ImGuiContext& g = *GImGui; @@ -10901,17 +10912,6 @@ void ImGui::SetColumnOffset(int column_index, float offset) SetColumnOffset(column_index + 1, offset + ImMax(g.Style.ColumnsMinSpacing, width)); } -float ImGui::GetColumnWidth(int column_index) -{ - ImGuiWindow* window = GetCurrentWindowRead(); - ImGuiColumnsSet* columns = window->DC.ColumnsSet; - IM_ASSERT(columns != NULL); - - if (column_index < 0) - column_index = columns->Current; - return OffsetNormToPixels(columns, columns->Columns[column_index+1].OffsetNorm - columns->Columns[column_index].OffsetNorm); -} - void ImGui::SetColumnWidth(int column_index, float width) { ImGuiWindow* window = GetCurrentWindowRead(); @@ -11039,10 +11039,10 @@ void ImGui::EndColumns() const float y1 = columns->StartPosY; const float y2 = window->DC.CursorPos.y; int dragging_column = -1; - for (int i = 1; i < columns->Count; i++) + for (int n = 1; n < columns->Count; n++) { - float x = window->Pos.x + GetColumnOffset(i); - const ImGuiID column_id = columns->ID + ImGuiID(i); + float x = window->Pos.x + GetColumnOffset(n); + const ImGuiID column_id = columns->ID + ImGuiID(n); const float column_hw = 4.0f; // Half-width for interaction const ImRect column_rect(ImVec2(x - column_hw, y1), ImVec2(x + column_hw, y2)); KeepAliveID(column_id); @@ -11058,7 +11058,7 @@ void ImGui::EndColumns() if (held && g.ActiveIdIsJustActivated) g.ActiveIdClickOffset.x -= column_hw; // Store from center of column line (we used a 8 wide rect for columns clicking). This is used by GetDraggedColumnOffset(). if (held) - dragging_column = i; + dragging_column = n; } // Draw column (we clip the Y boundaries CPU side because very long triangles are mishandled by some GPU drivers.) From ddbcda8c1bc6987d0adae2ac9bc7a1aad14c10f0 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 13 Dec 2017 21:51:23 +0100 Subject: [PATCH 740/921] Columns: Column width data is no longer lost while dragging toward the right side. (#1499, #125) --- imgui.cpp | 23 ++++++++++++++++++++--- imgui_internal.h | 5 +++-- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 91b777734..cf21d0e98 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -10879,6 +10879,19 @@ float ImGui::GetColumnOffset(int column_index) return x_offset; } +static float GetColumnWidthEx(ImGuiColumnsSet* columns, int column_index, bool before_resize = false) +{ + if (column_index < 0) + column_index = columns->Current; + + float offset_norm; + if (before_resize) + offset_norm = columns->Columns[column_index + 1].OffsetNormBeforeResize - columns->Columns[column_index].OffsetNormBeforeResize; + else + offset_norm = columns->Columns[column_index + 1].OffsetNorm - columns->Columns[column_index].OffsetNorm; + return OffsetNormToPixels(columns, offset_norm); +} + float ImGui::GetColumnWidth(int column_index) { ImGuiWindow* window = GetCurrentWindowRead(); @@ -10902,7 +10915,7 @@ void ImGui::SetColumnOffset(int column_index, float offset) IM_ASSERT(column_index < columns->Columns.Size); const bool preserve_width = !(columns->Flags & ImGuiColumnsFlags_NoPreserveWidths) && (column_index < columns->Count-1); - const float width = preserve_width ? GetColumnWidth(column_index) : 0.0f; + const float width = preserve_width ? GetColumnWidthEx(columns, column_index, columns->IsBeingResized) : 0.0f; if (!(columns->Flags & ImGuiColumnsFlags_NoForceWithinWindow)) offset = ImMin(offset, columns->MaxX - g.Style.ColumnsMinSpacing * (columns->Count - column_index)); @@ -11033,7 +11046,7 @@ void ImGui::EndColumns() window->DC.CursorMaxPos.x = ImMax(columns->StartMaxPosX, columns->MaxX); // Restore cursor max pos, as columns don't grow parent // Draw columns borders and handle resize - columns->IsBeingResized = false; + bool is_being_resized = false; if (!(columns->Flags & ImGuiColumnsFlags_NoBorder) && !window->SkipItems) { const float y1 = columns->StartPosY; @@ -11070,11 +11083,15 @@ void ImGui::EndColumns() // Apply dragging after drawing the column lines, so our rendered lines are in sync with how items were displayed during the frame. if (dragging_column != -1) { + if (!columns->IsBeingResized) + for (int n = 0; n < columns->Count + 1; n++) + columns->Columns[n].OffsetNormBeforeResize = columns->Columns[n].OffsetNorm; + columns->IsBeingResized = is_being_resized = true; float x = GetDraggedColumnOffset(columns, dragging_column); SetColumnOffset(dragging_column, x); - columns->IsBeingResized = true; } } + columns->IsBeingResized = is_being_resized; window->DC.ColumnsSet = NULL; window->DC.ColumnsOffsetX = 0.0f; diff --git a/imgui_internal.h b/imgui_internal.h index ca1086b91..f0d598b49 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -414,10 +414,11 @@ struct ImGuiPopupRef struct ImGuiColumnData { - float OffsetNorm; // Column start offset, normalized 0.0 (far left) -> 1.0 (far right) + float OffsetNorm; // Column start offset, normalized 0.0 (far left) -> 1.0 (far right) + float OffsetNormBeforeResize; ImRect ClipRect; - ImGuiColumnData() { OffsetNorm = 0.0f; } + ImGuiColumnData() { OffsetNorm = OffsetNormBeforeResize = 0.0f; } }; struct ImGuiColumnsSet From 39058160825eff27d0e39a2c0d56b11bcec9f09e Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 13 Dec 2017 21:59:16 +0100 Subject: [PATCH 741/921] Added ShowFontSelector(), ShowStyleSelector(). (#707) --- imgui.h | 4 +++- imgui_demo.cpp | 49 +++++++++++++++++++++++++++++++++++++------------ 2 files changed, 40 insertions(+), 13 deletions(-) diff --git a/imgui.h b/imgui.h index 52a0239fe..c05d92c6e 100644 --- a/imgui.h +++ b/imgui.h @@ -133,10 +133,12 @@ namespace ImGui IMGUI_API void EndFrame(); // ends the ImGui frame. automatically called by Render(), so most likely don't need to ever call that yourself directly. If you don't need to render you may call EndFrame() but you'll have wasted CPU already. If you don't need to render, better to not create any imgui windows instead! IMGUI_API void Shutdown(); - // Demo/Debug/Info + // Demo, Debug, Informations IMGUI_API void ShowTestWindow(bool* p_open = NULL); // create demo/test window. demonstrate most ImGui features. call this to learn about the library! try to make it always available in your application! IMGUI_API void ShowMetricsWindow(bool* p_open = NULL); // create metrics window. display ImGui internals: draw commands (with individual draw calls and vertices), window list, basic internal state, etc. IMGUI_API void ShowStyleEditor(ImGuiStyle* ref = NULL); // add style editor block (not a window). you can pass in a reference ImGuiStyle structure to compare to, revert to and save to (else it uses the default style) + IMGUI_API bool ShowStyleSelector(const char* label); + IMGUI_API void ShowFontSelector(const char* label); IMGUI_API void ShowUserGuide(); // add basic help/info block (not a window): how to manipulate ImGui as a end-user (mouse/keyboard controls). // Window diff --git a/imgui_demo.cpp b/imgui_demo.cpp index f45a85826..50aecce9a 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1903,6 +1903,41 @@ void ImGui::ShowTestWindow(bool* p_open) ImGui::End(); } +bool ImGui::ShowStyleSelector(const char* label) +{ + static int style_idx = 0; + if (ImGui::Combo(label, &style_idx, "Classic\0Dark\0Light\0")) + { + switch (style_idx) + { + case 0: ImGui::StyleColorsClassic(); break; + case 1: ImGui::StyleColorsDark(); break; + case 2: ImGui::StyleColorsLight(); break; + } + return true; + } + return false; +} + +void ImGui::ShowFontSelector(const char* label) +{ + ImGuiIO& io = ImGui::GetIO(); + ImFont* font_current = ImGui::GetFont(); + if (ImGui::BeginCombo(label, font_current->GetDebugName())) + { + for (int n = 0; n < io.Fonts->Fonts.Size; n++) + if (ImGui::Selectable(io.Fonts->Fonts[n]->GetDebugName(), io.Fonts->Fonts[n] == font_current)) + io.FontDefault = io.Fonts->Fonts[n]; + ImGui::EndCombo(); + } + ImGui::SameLine(); + ShowHelpMarker( + "- Load additional fonts with io.Fonts->AddFontFromFileTTF().\n" + "- The font atlas is built when calling io.Fonts->GetTexDataAsXXXX() or io.Fonts->Build().\n" + "- Read FAQ and documentation in extra_fonts/ for more details.\n" + "- If you need to add/remove fonts at runtime (e.g. for DPI change), do it before calling NewFrame()."); +} + void ImGui::ShowStyleEditor(ImGuiStyle* ref) { // You can pass in a reference ImGuiStyle structure to compare to, revert to and save to (else it compares to an internally stored reference) @@ -1919,18 +1954,9 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.50f); - // Default Styles Selector - static int style_idx = 0; - if (ImGui::Combo("Colors##Selector", &style_idx, "Classic\0Dark\0Light\0")) - { - switch (style_idx) - { - case 0: ImGui::StyleColorsClassic(); break; - case 1: ImGui::StyleColorsDark(); break; - case 2: ImGui::StyleColorsLight(); break; - } + if (ImGui::ShowStyleSelector("Colors##Selector")) ref_saved_style = style; - } + ImGui::ShowFontSelector("Fonts##Selector"); // Simplified Settings if (ImGui::SliderFloat("FrameRounding", &style.FrameRounding, 0.0f, 12.0f, "%.0f")) @@ -2050,7 +2076,6 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) } bool fonts_opened = ImGui::TreeNode("Fonts", "Fonts (%d)", ImGui::GetIO().Fonts->Fonts.Size); - ImGui::SameLine(); ShowHelpMarker("Tip: Load fonts with io.Fonts->AddFontFromFileTTF()\nbefore calling io.Fonts->GetTex* functions."); if (fonts_opened) { ImFontAtlas* atlas = ImGui::GetIO().Fonts; From f265e16b840f3352fc54f0d3a03bfb5bfd1b8b17 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 13 Dec 2017 22:05:48 +0100 Subject: [PATCH 742/921] Revert "Scrollbar: Minor simplication of the code using InnerRect data." > Introduced sheering on the scrollbar rectangle because InnerRect isn't setup at this point. This reverts commit 7ac1583411095fe8a82ccbc56d09777f87222e9d. --- imgui.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index cf21d0e98..69f04d8c0 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -5021,8 +5021,10 @@ void ImGui::Scrollbar(ImGuiLayoutType direction) const ImRect window_rect = window->Rect(); const float border_size = window->WindowBorderSize; ImRect bb = horizontal - ? ImRect(window->InnerRect.Min.x, window_rect.Max.y - style.ScrollbarSize, window->InnerRect.Max.x, window_rect.Max.y - border_size) - : ImRect(window_rect.Max.x - style.ScrollbarSize, window->InnerRect.Min.y, window_rect.Max.x - border_size, window->InnerRect.Max.y); + ? ImRect(window->Pos.x + border_size, window_rect.Max.y - style.ScrollbarSize, window_rect.Max.x - other_scrollbar_size_w - border_size, window_rect.Max.y - border_size) + : ImRect(window_rect.Max.x - style.ScrollbarSize, window->Pos.y + border_size, window_rect.Max.x - border_size, window_rect.Max.y - other_scrollbar_size_w - border_size); + if (!horizontal) + bb.Min.y += window->TitleBarHeight() + ((window->Flags & ImGuiWindowFlags_MenuBar) ? window->MenuBarHeight() : 0.0f); if (bb.GetWidth() <= 0.0f || bb.GetHeight() <= 0.0f) return; From 5f397582025e3559b19c16a432a068020bc459b2 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 13 Dec 2017 22:21:49 +0100 Subject: [PATCH 743/921] Minor tweaks, comments, spacing fixes --- imgui.h | 54 +++++++++++++++++++++++++++--------------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/imgui.h b/imgui.h index c05d92c6e..bbbeaef46 100644 --- a/imgui.h +++ b/imgui.h @@ -367,7 +367,7 @@ namespace ImGui IMGUI_API void TreePop(); // ~ Unindent()+PopId() IMGUI_API void TreeAdvanceToLabelPos(); // advance cursor x position by GetTreeNodeToLabelSpacing() IMGUI_API float GetTreeNodeToLabelSpacing(); // horizontal distance preceding label when using TreeNode*() or Bullet() == (g.FontSize + style.FramePadding.x*2) for a regular unframed TreeNode - IMGUI_API void SetNextTreeNodeOpen(bool is_open, ImGuiCond cond = 0); // set next TreeNode/CollapsingHeader open state. + IMGUI_API void SetNextTreeNodeOpen(bool is_open, ImGuiCond cond = 0); // set next TreeNode/CollapsingHeader open state. IMGUI_API bool CollapsingHeader(const char* label, ImGuiTreeNodeFlags flags = 0); // if returning 'true' the header is open. doesn't indent nor push on ID stack. user doesn't have to call TreePop(). IMGUI_API bool CollapsingHeader(const char* label, bool* p_open, ImGuiTreeNodeFlags flags = 0); // when 'p_open' isn't NULL, display an additional small close button on upper right of the header @@ -376,9 +376,9 @@ namespace ImGui IMGUI_API bool Selectable(const char* label, bool* p_selected, ImGuiSelectableFlags flags = 0, const ImVec2& size = ImVec2(0,0)); IMGUI_API bool ListBox(const char* label, int* current_item, const char* const* items, int items_count, int height_in_items = -1); IMGUI_API bool ListBox(const char* label, int* current_item, bool (*items_getter)(void* data, int idx, const char** out_text), void* data, int items_count, int height_in_items = -1); - IMGUI_API bool ListBoxHeader(const char* label, const ImVec2& size = ImVec2(0,0)); // use if you want to reimplement ListBox() will custom data or interactions. make sure to call ListBoxFooter() afterwards. + IMGUI_API bool ListBoxHeader(const char* label, const ImVec2& size = ImVec2(0,0)); // use if you want to reimplement ListBox() will custom data or interactions. make sure to call ListBoxFooter() afterwards. IMGUI_API bool ListBoxHeader(const char* label, int items_count, int height_in_items = -1); // " - IMGUI_API void ListBoxFooter(); // terminate the scrolling region + IMGUI_API void ListBoxFooter(); // terminate the scrolling region // Widgets: Value() Helpers. Output single value in "name: value" format (tip: freely declare more in your code to handle your types. you can add functions to the ImGui namespace) IMGUI_API void Value(const char* prefix, bool b); @@ -424,11 +424,11 @@ namespace ImGui // Drag and Drop // [BETA API] Missing Demo code. API may evolve. - IMGUI_API bool BeginDragDropSource(ImGuiDragDropFlags flags = 0, int mouse_button = 0); // Call when the current item is active. If this return true, you can call SetDragDropPayload() + EndDragDropSource() - IMGUI_API bool SetDragDropPayload(const char* type, const void* data, size_t data_size, ImGuiCond cond = 0); // Type is a user defined string of maximum 8 characters. Strings starting with '_' are reserved for dear imgui internal types. Data is copied and held by imgui. + IMGUI_API bool BeginDragDropSource(ImGuiDragDropFlags flags = 0, int mouse_button = 0); // call when the current item is active. If this return true, you can call SetDragDropPayload() + EndDragDropSource() + IMGUI_API bool SetDragDropPayload(const char* type, const void* data, size_t size, ImGuiCond cond = 0);// type is a user defined string of maximum 8 characters. Strings starting with '_' are reserved for dear imgui internal types. Data is copied and held by imgui. IMGUI_API void EndDragDropSource(); - IMGUI_API bool BeginDragDropTarget(); // Call after submitting an item that may receive an item. If this returns true, you can call AcceptDragDropPayload() + EndDragDropTarget() - IMGUI_API const ImGuiPayload* AcceptDragDropPayload(const char* type, ImGuiDragDropFlags flags = 0); // Accept contents of a given type. If ImGuiDragDropFlags_AcceptBeforeDelivery is set you can peek into the payload before the mouse button is released. + IMGUI_API bool BeginDragDropTarget(); // call after submitting an item that may receive an item. If this returns true, you can call AcceptDragDropPayload() + EndDragDropTarget() + IMGUI_API const ImGuiPayload* AcceptDragDropPayload(const char* type, ImGuiDragDropFlags flags = 0); // accept contents of a given type. If ImGuiDragDropFlags_AcceptBeforeDelivery is set you can peek into the payload before the mouse button is released. IMGUI_API void EndDragDropTarget(); // Clipping @@ -447,15 +447,15 @@ namespace ImGui IMGUI_API void SetKeyboardFocusHere(int offset = 0); // focus keyboard on the next widget. Use positive 'offset' to access sub components of a multiple component widget. Use -1 to access previous widget. // Utilities - IMGUI_API bool IsItemHovered(ImGuiHoveredFlags flags = 0); // is the last item hovered by mouse (and usable)? + IMGUI_API bool IsItemHovered(ImGuiHoveredFlags flags = 0); // is the last item hovered? (and usable, aka not blocked by a popup, etc.). See ImGuiHoveredFlags for more options. IMGUI_API bool IsItemActive(); // is the last item active? (e.g. button being held, text field being edited- items that don't interact will always return false) IMGUI_API bool IsItemClicked(int mouse_button = 0); // is the last item clicked? (e.g. button/node just clicked on) IMGUI_API bool IsItemVisible(); // is the last item visible? (aka not out of sight due to clipping/scrolling.) IMGUI_API bool IsAnyItemHovered(); IMGUI_API bool IsAnyItemActive(); - IMGUI_API ImVec2 GetItemRectMin(); // get bounding rect of last item in screen space + IMGUI_API ImVec2 GetItemRectMin(); // get bounding rectangle of last item, in screen space IMGUI_API ImVec2 GetItemRectMax(); // " - IMGUI_API ImVec2 GetItemRectSize(); // " + IMGUI_API ImVec2 GetItemRectSize(); // get size of last item, in screen space IMGUI_API void SetItemAllowOverlap(); // allow last item to be overlapped by a subsequent item. sometimes useful with invisible buttons, selectables, etc. to catch unused area. IMGUI_API bool IsWindowFocused(ImGuiFocusedFlags flags = 0); // is current window focused? or its root/child, depending on flags. see flags for options. IMGUI_API bool IsWindowHovered(ImGuiHoveredFlags flags = 0); // is current window hovered (and typically: not blocked by a popup/modal)? see flags for options. @@ -648,7 +648,7 @@ enum ImGuiDragDropFlags_ ImGuiDragDropFlags_AcceptPeekOnly = ImGuiDragDropFlags_AcceptBeforeDelivery | ImGuiDragDropFlags_AcceptNoDrawDefaultRect // For peeking ahead and inspecting the payload before delivery. }; -// Standard Drag and Drop payload types. Types starting with '_' are defined by Dear ImGui. +// Standard Drag and Drop payload types. You can define you own payload types using 8-characters long strings. Types starting with '_' are defined by Dear ImGui. #define IMGUI_PAYLOAD_TYPE_COLOR_3F "_COL3F" // float[3] // Standard type for colors, without alpha. User code may use this type. #define IMGUI_PAYLOAD_TYPE_COLOR_4F "_COL4F" // float[4] // Standard type for colors. User code may use this type. @@ -733,7 +733,7 @@ enum ImGuiCol_ }; // Enumeration for PushStyleVar() / PopStyleVar() to temporarily modify the ImGuiStyle structure. -// NB: the enum only refers to fields of ImGuiStyle which makes sense to be pushed/poped inside UI code. During initialization, feel free to just poke into ImGuiStyle directly. +// NB: the enum only refers to fields of ImGuiStyle which makes sense to be pushed/popped inside UI code. During initialization, feel free to just poke into ImGuiStyle directly. // NB: if changing this enum, you need to update the associated internal table GStyleVarInfo[] accordingly. This is where we link enum values to members offset/type. enum ImGuiStyleVar_ { @@ -979,18 +979,18 @@ struct ImGuiIO #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS namespace ImGui { - static inline bool IsRootWindowFocused() { return IsWindowFocused(ImGuiFocusedFlags_RootWindow); } // OBSOLETE 1.53+ - static inline bool IsRootWindowOrAnyChildFocused() { return IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows); } // OBSOLETE 1.53+ - static inline void SetNextWindowContentWidth(float width) { SetNextWindowContentSize(ImVec2(width, 0.0f)); } // OBSOLETE 1.53+ (nb: original version preserved last Y value set by SetNextWindowContentSize()) - static inline bool IsRootWindowOrAnyChildHovered(ImGuiHoveredFlags flags = 0) { return IsItemHovered(flags | ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows); } // OBSOLETE 1.53+ use flags directly - bool Begin(const char* name, bool* p_open, const ImVec2& size_on_first_use, float bg_alpha_override = -1.0f, ImGuiWindowFlags flags = 0); // OBSOLETE 1.52+. use SetNextWindowSize() instead if you want to set a window size. - static inline void AlignFirstTextHeightToWidgets() { AlignTextToFramePadding(); } // OBSOLETE 1.52+ - static inline void SetNextWindowPosCenter(ImGuiCond cond = 0) { SetNextWindowPos(ImVec2(GetIO().DisplaySize.x * 0.5f, GetIO().DisplaySize.y * 0.5f), cond, ImVec2(0.5f, 0.5f)); } // OBSOLETE 1.52+ - static inline bool IsItemHoveredRect() { return IsItemHovered(ImGuiHoveredFlags_RectOnly); } // OBSOLETE 1.51+ - static inline bool IsPosHoveringAnyWindow(const ImVec2&) { IM_ASSERT(0); return false; } // OBSOLETE 1.51+. This was partly broken. You probably wanted to use ImGui::GetIO().WantCaptureMouse instead. - static inline bool IsMouseHoveringAnyWindow() { return IsAnyWindowHovered(); } // OBSOLETE 1.51+ - static inline bool IsMouseHoveringWindow() { return IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem); } // OBSOLETE 1.51+ - static inline bool CollapsingHeader(const char* label, const char* str_id, bool framed = true, bool default_open = false) { (void)str_id; (void)framed; ImGuiTreeNodeFlags default_open_flags = 1 << 5; return CollapsingHeader(label, (default_open ? default_open_flags : 0)); } // OBSOLETE 1.49+ + static inline bool IsRootWindowFocused() { return IsWindowFocused(ImGuiFocusedFlags_RootWindow); } // OBSOLETE 1.53+ + static inline bool IsRootWindowOrAnyChildFocused() { return IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows); } // OBSOLETE 1.53+ + static inline void SetNextWindowContentWidth(float width) { SetNextWindowContentSize(ImVec2(width, 0.0f)); } // OBSOLETE 1.53+ (nb: original version preserved last Y value set by SetNextWindowContentSize()) + static inline bool IsRootWindowOrAnyChildHovered(ImGuiHoveredFlags flags = 0) { return IsItemHovered(flags | ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows); } // OBSOLETE 1.53+ use flags directly + bool Begin(const char* name, bool* p_open, const ImVec2& size_on_first_use, float bg_alpha_override = -1.0f, ImGuiWindowFlags flags = 0); // OBSOLETE 1.52+. use SetNextWindowSize() instead if you want to set a window size. + static inline void AlignFirstTextHeightToWidgets() { AlignTextToFramePadding(); } // OBSOLETE 1.52+ + static inline void SetNextWindowPosCenter(ImGuiCond cond = 0) { SetNextWindowPos(ImVec2(GetIO().DisplaySize.x * 0.5f, GetIO().DisplaySize.y * 0.5f), cond, ImVec2(0.5f, 0.5f)); } // OBSOLETE 1.52+ + static inline bool IsItemHoveredRect() { return IsItemHovered(ImGuiHoveredFlags_RectOnly); } // OBSOLETE 1.51+ + static inline bool IsPosHoveringAnyWindow(const ImVec2&) { IM_ASSERT(0); return false; } // OBSOLETE 1.51+. This was partly broken. You probably wanted to use ImGui::GetIO().WantCaptureMouse instead. + static inline bool IsMouseHoveringAnyWindow() { return IsAnyWindowHovered(); } // OBSOLETE 1.51+ + static inline bool IsMouseHoveringWindow() { return IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem); } // OBSOLETE 1.51+ + static inline bool CollapsingHeader(const char* label, const char* str_id, bool framed = true, bool default_open = false) { (void)str_id; (void)framed; ImGuiTreeNodeFlags default_open_flags = 1 << 5; return CollapsingHeader(label, (default_open ? default_open_flags : 0)); } // OBSOLETE 1.49+ } #endif @@ -1205,8 +1205,8 @@ struct ImGuiTextEditCallbackData struct ImGuiSizeConstraintCallbackData { void* UserData; // Read-only. What user passed to SetNextWindowSizeConstraints() - ImVec2 Pos; // Read-only. Window position, for reference. - ImVec2 CurrentSize; // Read-only. Current window size. + ImVec2 Pos; // Read-only. Window position, for reference. + ImVec2 CurrentSize; // Read-only. Current window size. ImVec2 DesiredSize; // Read-write. Desired size, based on user's mouse position. Write to this field to restrain resizing. }; @@ -1313,7 +1313,7 @@ struct ImGuiListClipper // The expected behavior from your rendering function is 'if (cmd.UserCallback != NULL) cmd.UserCallback(parent_list, cmd); else RenderTriangles()' typedef void (*ImDrawCallback)(const ImDrawList* parent_list, const ImDrawCmd* cmd); -// Typically, 1 command = 1 gpu draw call (unless command is a callback) +// Typically, 1 command = 1 GPU draw call (unless command is a callback) struct ImDrawCmd { unsigned int ElemCount; // Number of indices (multiple of 3) to be rendered as triangles. Vertices are stored in the callee ImDrawList's vtx_buffer[] array, indices in idx_buffer[]. From 45bca7851d194ff4393c6a884c282020f93291b0 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 13 Dec 2017 22:30:16 +0100 Subject: [PATCH 744/921] Added ImGuiHoveredFlags_RootAndChildWindows helper for consistency with focused flags. (#1382) --- imgui.cpp | 6 +++--- imgui.h | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 69f04d8c0..75d06b3b4 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -214,8 +214,8 @@ Also read releases logs https://github.com/ocornut/imgui/releases for more details. - 2017/12/13 (1.53) - renamed GetItemsLineHeightWithSpacing() to GetFrameHeightWithSpacing(). Kept redirection function (will obsolete). - - 2017/12/13 (1.53) - marked IsRootWindowFocused() as obsolete in favor of using IsWindowFocused(ImGuiFocusedFlags_RootWindow). Kept redirection function (will obsolete). - - marked IsRootWindowOrAnyChildFocused() as obsolete in favor of using IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows). Kept redirection function (will obsolete). + - 2017/12/13 (1.53) - obsoleted IsRootWindowFocused() in favor of using IsWindowFocused(ImGuiFocusedFlags_RootWindow). Kept redirection function (will obsolete). + - obsoleted IsRootWindowOrAnyChildFocused() in favor of using IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows). Kept redirection function (will obsolete). - 2017/12/12 (1.53) - renamed ImGuiTreeNodeFlags_AllowOverlapMode to ImGuiTreeNodeFlags_AllowItemOverlap. Kept redirection enum (will obsolete). - 2017/12/10 (1.53) - removed SetNextWindowContentWidth(), prefer using SetNextWindowContentSize(). Kept redirection function (will obsolete). - 2017/11/27 (1.53) - renamed ImGuiTextBuffer::append() helper to appendf(), appendv() to appendfv(). If you copied the 'Log' demo in your code, it uses appendv() so that needs to be renamed. @@ -224,7 +224,7 @@ - 2017/11/18 (1.53) - Style: removed ImGuiCol_ComboBg in favor of combo boxes using ImGuiCol_PopupBg for consistency. - 2017/11/18 (1.53) - Style: renamed ImGuiCol_ChildWindowBg to ImGuiCol_ChildBg. - 2017/11/18 (1.53) - Style: renamed style.ChildWindowRounding to style.ChildRounding, ImGuiStyleVar_ChildWindowRounding to ImGuiStyleVar_ChildRounding. - - 2017/11/02 (1.53) - marked IsRootWindowOrAnyChildHovered() as obsolete is favor of using IsWindowHovered(ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows); + - 2017/11/02 (1.53) - obsoleted IsRootWindowOrAnyChildHovered() in favor of using IsWindowHovered(ImGuiHoveredFlags_RootAndChildWindows); - 2017/10/24 (1.52) - renamed IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCS/IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCS to IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS/IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS for consistency. - 2017/10/20 (1.52) - changed IsWindowHovered() default parameters behavior to return false if an item is active in another window (e.g. click-dragging item from another window to this window). You can use the newly introduced IsWindowHovered() flags to requests this specific behavior if you need it. - 2017/10/20 (1.52) - marked IsItemHoveredRect()/IsMouseHoveringWindow() as obsolete, in favor of using the newly introduced flags for IsItemHovered() and IsWindowHovered(). See https://github.com/ocornut/imgui/issues/1382 for details. diff --git a/imgui.h b/imgui.h index bbbeaef46..0e54fc9fc 100644 --- a/imgui.h +++ b/imgui.h @@ -631,7 +631,8 @@ enum ImGuiHoveredFlags_ //ImGuiHoveredFlags_AllowWhenBlockedByModal = 1 << 3, // Return true even if a modal popup window is normally blocking access to this item/window. FIXME-TODO: Unavailable yet. ImGuiHoveredFlags_AllowWhenBlockedByActiveItem = 1 << 4, // Return true even if an active item is blocking access to this item/window. Useful for Drag and Drop patterns. ImGuiHoveredFlags_AllowWhenOverlapped = 1 << 5, // Return true even if the position is overlapped by another window - ImGuiHoveredFlags_RectOnly = ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem | ImGuiHoveredFlags_AllowWhenOverlapped + ImGuiHoveredFlags_RectOnly = ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem | ImGuiHoveredFlags_AllowWhenOverlapped, + ImGuiHoveredFlags_RootAndChildWindows = ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows }; // Flags for ImGui::BeginDragDropSource(), ImGui::AcceptDragDropPayload() From fa68cb53648f05e8a3df6fe68c2a567f178bcb28 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 13 Dec 2017 23:07:07 +0100 Subject: [PATCH 745/921] Demo: Console: Tweak. --- imgui_demo.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 50aecce9a..a1c09f4a8 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -2563,7 +2563,8 @@ struct ExampleAppConsole ImGui::PopStyleVar(); ImGui::Separator(); - ImGui::BeginChild("ScrollingRegion", ImVec2(0, -ImGui::GetStyle().ItemSpacing.y - ImGui::GetFrameHeightWithSpacing()), false, ImGuiWindowFlags_HorizontalScrollbar); // Leave room for 1 separator + 1 InputText + const float footer_height_to_reserve = ImGui::GetStyle().ItemSpacing.y + ImGui::GetFrameHeightWithSpacing(); // 1 separator, 1 input text + ImGui::BeginChild("ScrollingRegion", ImVec2(0, -footer_height_to_reserve), false, ImGuiWindowFlags_HorizontalScrollbar); // Leave room for 1 separator + 1 InputText if (ImGui::BeginPopupContextWindow()) { if (ImGui::Selectable("Clear")) ClearLog(); From 07ed9f8451c67fb665523b1521465a5804460e1b Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 14 Dec 2017 11:08:16 +0100 Subject: [PATCH 746/921] TODO list update --- TODO.txt | 41 ++++++++++++++++++----------------------- 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/TODO.txt b/TODO.txt index 43df4dafc..41270c4d9 100644 --- a/TODO.txt +++ b/TODO.txt @@ -15,8 +15,9 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - window: auto-fit feedback loop when user relies on any dynamic layout (window width multiplier, column) appears weird to end-user. clarify. - window: allow resizing of child windows (possibly given min/max for each axis?.) - window: background options for child windows, border option (disable rounding). - - window: resizing from any sides? + mouse cursor directives for app. (#822) -!- window: begin with *p_open == false should return false. + - window: resizing from any sides? done. > need backends to honor mouse cursors properly. (#822) + - window: resize from borders: support some form of outer padding to make it easier to grab borders. (#822) + - window: begin with *p_open == false should return false. - window: get size/pos helpers given names (see discussion in #249) - window: a collapsed window can be stuck behind the main menu bar? - window: when window is very small, prioritize resize button over close button. @@ -24,9 +25,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - window: increase minimum size of a window with menus or fix the menu rendering so that it doesn't look odd. - window: double-clicking on title bar to minimize isn't consistent, perhaps move to single-click on left-most collapse icon? - window: expose contents size. (#1045) - - window: resize from borders: support some form of outer padding to make it easier to grab borders. (#822) - window: GetWindowSize() returns (0,0) when not calculated? (#1045) - - window: refactor IsWindowFocused(), merge all three existing variants, add flags, similar to #1382. - window: freeze window flag: if not focused/hovered, return false, render with previous ImDrawList. and/or reduce refresh rate. !- scrolling: allow immediately effective change of scroll after Begin() if we haven't appended items yet. - scrolling/clipping: separator on the initial position of a window is not visible (cursorpos.y <= clippos.y). (2017-08-20: can't repro) @@ -38,6 +37,8 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - drawlist: avoid passing null (-9999,+9999) rectangle to end-user, instead perhaps pass rectangle based on io.DisplaySize? - drawlist: primtiives/helpers to manipulate vertices post submission, so e.g. a quad/rect can be resized to fit later submitted content, _without_ using the ChannelSplit api - drawlist: non-AA strokes have gaps between points (#593, #288), especially RenderCheckmark(). + - drawlist: would be good to be able to deep copy a draw list (ImVector= op?). + - drawlist/opt: AddRect() axis aligned pixel aligned (no-aa) could use 8 triangles instead of 16 and no normal calculation. - main: considering adding an Init() function? some constructs are awkward in the implementation because of the lack of them. - main: find a way to preserve relative orders of multiple reappearing windows (so an app toggling between "modes" e.g. fullscreen vs all tools) won't lose relative ordering. @@ -47,7 +48,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - widgets: display mode: widget-label, label-widget (aligned on column or using fixed size), label-newline-tab-widget etc. (#395) - widgets: clean up widgets internal toward exposing everything and stabilizing imgui_internals.h. - - widgets: add disabled and read-only modes (#211) + - widgets: add visauls for Disabled/ReadOnly mode and expose publicly (#211) - widgets: add always-allow-overlap mode. - widgets: alignment options in style (e.g. center Selectable, Right-Align within Button, etc.) #1260 - widgets: activate by identifier (trigger button, focus given id) @@ -80,7 +81,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - layout: horizontal flow until no space left (#404) - layout: more generic alignment state (left/right/centered) for single items? - layout: clean up the InputFloatN/SliderFloatN/ColorEdit4 layout code. item width should include frame padding. - - layout: BeginGroup() needs a border option. + - layout: BeginGroup() needs a border option. (~#1496) - layout: vertical alignement of mixed height items (e.g. buttons) within a same line (#1284) - columns: sizing policy (e.g. for each column: fixed size, %, fill, distribute default size among fills) (#513, #125) @@ -135,22 +136,19 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - drag float: up/down axis - drag float: added leeway on edge (e.g. a few invisible steps past the clamp limits) - - combo: sparse combo boxes (via function call?) / iterators - - combo: active item type could be anything else e.g. void* - - combo: use clipper - - combo: contents should extends to fit label if combo widget is small - - combo: option for ComboEx to not return true when unchanged (#1182) + - combo: use clipper: make it easier to disable clipper with a single flag. + - combo: option for BeginCombo to not return true when unchanged (#1182) - combo/listbox: keyboard control. need InputText-like non-active focus + key handling. considering keyboard for custom listbox (pr #203) - listbox: multiple selection. - listbox: unselect option (#1208) - - listbox: make it easier/more natural to implement range-select (need some sort of info/ref about the last clicked/focused item that user can translate to an index?) + - listbox: make it easier/more natural to implement range-select (need some sort of info/ref about the last clicked/focused item that user can translate to an index?) (wip stash) - listbox: user may want to initial scroll to focus on the one selected value? - listbox: expose hovered item for a basic ListBox - listbox: keyboard navigation. - listbox: scrolling should track modified selection. !- popups/menus: clarify usage of popups id, how MenuItem/Selectable closing parent popups affects the ID, etc. this is quite fishy needs improvement! (#331, #402) - - popups: reopening context menu at new position should be the behavior by default? (equivalent to internal OpenPopupEx() with reopen_existing=true) + - popups: reopening context menu at new position should be the behavior by default? (equivalent to internal OpenPopupEx() with reopen_existing=true) (~#1497) - popups: if the popup functions took explicit ImGuiID it would allow the user to manage the scope of those ID. (#331) - popups: clicking outside (to close popup) and holding shouldn't drag window below. - popups: add variant using global identifier similar to Begin/End (#402) @@ -184,12 +182,10 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - settings: api for per-tool simple persistent data (bool,int,float,columns sizes,etc.) in .ini file (#437) - stb: add defines to disable stb implementations -!- style: better default styles. -!- style: move border to style structure, remove _ShowBorder flag. +!- style: better default styles. (#707) - style: border types: out-screen, in-screen, etc. (#447) - style/optimization: store rounded corners in texture to use 1 quad per corner (filled and wireframe) to lower the cost of rounding. - style: add window shadow (fading away from the window. Paint-style calculation of vertices alpha after drawlist would be easier) - - style: color-box not always square? - style: a concept of "compact style" that the end-user can easily rely on (e.g. PushStyleCompact()?) that maps to other settings? avoid implementing duplicate helpers such as SmallCheckbox(), etc. - style: try to make PushStyleVar() more robust to incorrect parameters (to be more friendly to edit & continues situation). - style: global scale setting. @@ -207,14 +203,16 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - filters: handle wildcards (with implicit leading/trailing *), regexps - filters: fuzzy matches (may use code at blog.forrestthewoods.com/4cffeed33fdb) - - drag'n drop, dragging helpers, demo (carry dragging info, visualize drag source before clicking, drop target, etc.) (#143, #479) + - drag and drop: add demo. (#143, #479) + - drag and drop: test with reordering nodes (in a list, or a tree node). (#143) + - drag and drop: test integrating with os drag and drop. - node/graph editor (#306) - pie menus patterns (#434) - - markup: simple markup language for color change? + - markup: simple markup language for color change? (#902) + - font: better vertical centering (based e.g on height of lowercase 'x'?). currently Roboto-Medium size 16 px isn't currently centered. - font: free the Alpha buffer if user only requested RGBA. !- font: better CalcTextSizeA() API, at least for simple use cases. current one is horrible (perhaps have simple vs extended versions). - - font: better vertical centering (based e.g on height of lowercase 'x'?). currently Roboto-Medium size 16 px isn't currently centered. - font: enforce monospace through ImFontConfig (for icons?) + create dual ImFont output from same input, reusing rasterized data but with different glyphs/AdvanceX - font: finish CustomRectRegister() to allow mapping unicode codepoint to custom texture data - font: PushFontSize API (#1018) @@ -246,17 +244,14 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - misc: idle refresh: expose cursor blink animation timer for backend to be able to lower framerate. - misc: make the ImGuiCond values linear (non-power-of-two). internal storage for ImGuiWindow can use integers to combine into flags (Why?) - misc: provide a way to compile out the entire implementation while providing a dummy API (e.g. #define IMGUI_DUMMY_IMPL) - - misc: provide HoveredTime and ActivatedTime to ease the creation of animations. - misc: fix for compilation settings where stdcall isn't the default (e.g. vectorcall) (#1230) - - misc: detect user not calling Render() and suggest to call EndFrame()? - remote: make a system like RemoteImGui first-class citizen/project (#75) - demo: add vertical separator demo - - demo: add a virtual scrolling example? + - demo: add virtual scrolling example? - examples: directx9: save/restore device state more thoroughly. - examples: window minimize, maximize (#583) - examples: provide a zero-framerate/idle example. - - examples: document WantCaptureKeyboard, WantCaptureMouse in example apps. (#446) - examples: glfw: could go idle when minimized? if (glfwGetWindowAttrib(window, GLFW_ICONIFIED)) { glfwWaitEvents(); continue; } // the problem is that DeltaTime will be super high on resume, perhaps provide a way to let impl know (#440) - optimization: replace vsnprintf with stb_printf? or enable the defines/infrastructure to allow it (#1038) - optimization: add clipping for multi-component widgets (SliderFloatX, ColorEditX, etc.). one problem is that nav branch can't easily clip parent group when there is a move request. From ac8e708c3e710164551d81a4020885a77ed0f4b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Branimir=20Karad=C5=BEi=C4=87?= Date: Thu, 14 Dec 2017 09:08:18 -0800 Subject: [PATCH 747/921] Fixed unused variable warning. --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 75d06b3b4..56b396105 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -11434,7 +11434,7 @@ const ImGuiPayload* ImGui::AcceptDragDropPayload(const char* type, ImGuiDragDrop // We don't really use/need this now, but added it for the sake of consistency and because we might need it later. void ImGui::EndDragDropTarget() { - ImGuiContext& g = *GImGui; + ImGuiContext& g = *GImGui; (void)g; IM_ASSERT(g.DragDropActive); } From eefea0588a6a26033e92ad20955126e4f926842f Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 14 Dec 2017 18:42:41 +0100 Subject: [PATCH 748/921] Using the ImGuiWindowFlags_NoScrollWithMouse flag on a child window forwards the mouse wheel event to the parent window, unless either ImGuiWindowFlags_NoInputs or ImGuiWindowFlags_NoScrollbar are also set. (#1380, #1502) --- imgui.cpp | 17 +++++++++++++---- imgui.h | 2 +- imgui_demo.cpp | 8 ++++++-- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 56b396105..06fc032df 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -213,6 +213,7 @@ Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. Also read releases logs https://github.com/ocornut/imgui/releases for more details. + - 2017/12/14 (1.53) - using the ImGuiWindowFlags_NoScrollWithMouse flag on a child window forwards the mouse wheel event to the parent window, unless either ImGuiWindowFlags_NoInputs or ImGuiWindowFlags_NoScrollbar are also set. - 2017/12/13 (1.53) - renamed GetItemsLineHeightWithSpacing() to GetFrameHeightWithSpacing(). Kept redirection function (will obsolete). - 2017/12/13 (1.53) - obsoleted IsRootWindowFocused() in favor of using IsWindowFocused(ImGuiFocusedFlags_RootWindow). Kept redirection function (will obsolete). - obsoleted IsRootWindowOrAnyChildFocused() in favor of using IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows). Kept redirection function (will obsolete). @@ -2462,12 +2463,20 @@ void ImGui::NewFrame() window->Size *= scale; window->SizeFull *= scale; } - else if (!g.IO.KeyCtrl && !(window->Flags & ImGuiWindowFlags_NoScrollWithMouse)) + else if (!g.IO.KeyCtrl) { // Mouse wheel Scrolling - float scroll_amount = 5 * window->CalcFontSize(); - scroll_amount = (float)(int)ImMin(scroll_amount, (window->ContentsRegionRect.GetHeight() + window->WindowPadding.y * 2.0f) * 0.67f); - SetWindowScrollY(window, window->Scroll.y - g.IO.MouseWheel * scroll_amount); + // If a child window has the ImGuiWindowFlags_NoScrollWithMouse flag, we give a chance to scroll its parent (unless either ImGuiWindowFlags_NoInputs or ImGuiWindowFlags_NoScrollbar are also set). + ImGuiWindow* scroll_window = window; + while ((scroll_window->Flags & ImGuiWindowFlags_ChildWindow) && (scroll_window->Flags & ImGuiWindowFlags_NoScrollWithMouse) && !(scroll_window->Flags & ImGuiWindowFlags_NoScrollbar) && !(scroll_window->Flags & ImGuiWindowFlags_NoInputs) && scroll_window->ParentWindow) + scroll_window = scroll_window->ParentWindow; + + if (!(scroll_window->Flags & ImGuiWindowFlags_NoScrollWithMouse) && !(scroll_window->Flags & ImGuiWindowFlags_NoInputs)) + { + float scroll_amount = 5 * scroll_window->CalcFontSize(); + scroll_amount = (float)(int)ImMin(scroll_amount, (scroll_window->ContentsRegionRect.GetHeight() + scroll_window->WindowPadding.y * 2.0f) * 0.67f); + SetWindowScrollY(scroll_window, scroll_window->Scroll.y - g.IO.MouseWheel * scroll_amount); + } } } diff --git a/imgui.h b/imgui.h index 0e54fc9fc..73d9b5864 100644 --- a/imgui.h +++ b/imgui.h @@ -524,7 +524,7 @@ enum ImGuiWindowFlags_ ImGuiWindowFlags_NoResize = 1 << 1, // Disable user resizing with the lower-right grip ImGuiWindowFlags_NoMove = 1 << 2, // Disable user moving the window ImGuiWindowFlags_NoScrollbar = 1 << 3, // Disable scrollbars (window can still scroll with mouse or programatically) - ImGuiWindowFlags_NoScrollWithMouse = 1 << 4, // Disable user vertically scrolling with mouse wheel + ImGuiWindowFlags_NoScrollWithMouse = 1 << 4, // Disable user vertically scrolling with mouse wheel. On child window, mouse wheel will be forwarded to the parent unless NoScrollbar is also set. ImGuiWindowFlags_NoCollapse = 1 << 5, // Disable user collapsing window by double-clicking on it ImGuiWindowFlags_AlwaysAutoResize = 1 << 6, // Resize every window to its content every frame //ImGuiWindowFlags_ShowBorders = 1 << 7, // Show borders around windows and items (OBSOLETE! Use e.g. style.FrameBorderSize=1.0f to enable borders). diff --git a/imgui_demo.cpp b/imgui_demo.cpp index a1c09f4a8..a2bf1be56 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -997,6 +997,9 @@ void ImGui::ShowTestWindow(bool* p_open) { if (ImGui::TreeNode("Child regions")) { + static bool disable_mouse_wheel = false; + ImGui::Checkbox("Disable Mouse Wheel", &disable_mouse_wheel); + ImGui::Text("Without border"); static int line = 50; bool goto_line = ImGui::Button("Goto"); @@ -1004,7 +1007,8 @@ void ImGui::ShowTestWindow(bool* p_open) ImGui::PushItemWidth(100); goto_line |= ImGui::InputInt("##Line", &line, 0, 0, ImGuiInputTextFlags_EnterReturnsTrue); ImGui::PopItemWidth(); - ImGui::BeginChild("Sub1", ImVec2(ImGui::GetWindowContentRegionWidth() * 0.5f,300), false, ImGuiWindowFlags_HorizontalScrollbar); + + ImGui::BeginChild("Sub1", ImVec2(ImGui::GetWindowContentRegionWidth() * 0.5f,300), false, ImGuiWindowFlags_HorizontalScrollbar | (disable_mouse_wheel ? ImGuiWindowFlags_NoScrollWithMouse : 0)); for (int i = 0; i < 100; i++) { ImGui::Text("%04d: scrollable region", i); @@ -1018,7 +1022,7 @@ void ImGui::ShowTestWindow(bool* p_open) ImGui::SameLine(); ImGui::PushStyleVar(ImGuiStyleVar_ChildRounding, 5.0f); - ImGui::BeginChild("Sub2", ImVec2(0,300), true); + ImGui::BeginChild("Sub2", ImVec2(0,300), true, (disable_mouse_wheel ? ImGuiWindowFlags_NoScrollWithMouse : 0)); ImGui::Text("With border"); ImGui::Columns(2); for (int i = 0; i < 100; i++) From 51433e26af14f1e240f9769142861243a1e5db4b Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 15 Dec 2017 10:15:51 +0100 Subject: [PATCH 749/921] Drag and Drop: Renamed to ImGuiDragDropFlags_SourceNoAutoTooltip to ImGuiDragDropFlags_SourceNoPreviewTooltip (#143) --- imgui.cpp | 4 ++-- imgui.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 06fc032df..cff66bf57 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -11269,7 +11269,7 @@ bool ImGui::BeginDragDropSource(ImGuiDragDropFlags flags, int mouse_button) g.DragDropMouseButton = mouse_button; } - if (!(flags & ImGuiDragDropFlags_SourceNoAutoTooltip)) + if (!(flags & ImGuiDragDropFlags_SourceNoPreviewTooltip)) { // FIXME-DRAG //SetNextWindowPos(g.IO.MousePos - g.ActiveIdClickOffset - g.Style.WindowPadding); @@ -11292,7 +11292,7 @@ void ImGui::EndDragDropSource() ImGuiContext& g = *GImGui; IM_ASSERT(g.DragDropActive); - if (!(g.DragDropSourceFlags & ImGuiDragDropFlags_SourceNoAutoTooltip)) + if (!(g.DragDropSourceFlags & ImGuiDragDropFlags_SourceNoPreviewTooltip)) { EndTooltip(); PopStyleColor(); diff --git a/imgui.h b/imgui.h index 73d9b5864..c05759aae 100644 --- a/imgui.h +++ b/imgui.h @@ -639,7 +639,7 @@ enum ImGuiHoveredFlags_ enum ImGuiDragDropFlags_ { // BeginDragDropSource() flags - ImGuiDragDropFlags_SourceNoAutoTooltip = 1 << 0, // By default, a successful call to BeginDragDropSource opens a tooltip so you can display a preview or description of the dragged contents. This flag disable this behavior. + ImGuiDragDropFlags_SourceNoPreviewTooltip = 1 << 0, // By default, a successful call to BeginDragDropSource opens a tooltip so you can display a preview or description of the source contents. This flag disable this behavior. ImGuiDragDropFlags_SourceNoDisableHover = 1 << 1, // By default, when dragging we clear data so that IsItemHovered() will return true, to avoid subsequent user code submitting tooltips. This flag disable this behavior so you can still call IsItemHovered() on the source item. ImGuiDragDropFlags_SourceNoHoldToOpenOthers = 1 << 2, // Disable the behavior that allows to open tree nodes and collapsing header by holding over them while dragging a source item. ImGuiDragDropFlags_SourceAllowNullID = 1 << 3, // Allow items such as Text(), Image() that have no unique identifier to be used as drag source, by manufacturing a temporary identifier based on their window-relative position. This is extremely unusual within the dear imgui ecosystem and so we made it explicit. From 6effcf21d62e41c5ef658fdf6839f6e955030cfc Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 15 Dec 2017 11:09:18 +0100 Subject: [PATCH 750/921] Drag and Drop: Source can also inhibit the preview on target, useful for extern sources that only exists for one frame. (#143) --- imgui.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/imgui.cpp b/imgui.cpp index cff66bf57..90316a8d8 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -11422,6 +11422,7 @@ const ImGuiPayload* ImGui::AcceptDragDropPayload(const char* type, ImGuiDragDrop // Render default drop visuals payload.Preview = was_accepted_previously; + flags |= (g.DragDropSourceFlags & ImGuiDragDropFlags_AcceptNoDrawDefaultRect); // Source can also inhibit the preview (useful for external sources that lives for 1 frame) if (!(flags & ImGuiDragDropFlags_AcceptNoDrawDefaultRect) && payload.Preview) { // FIXME-DRAG: Settle on a proper default visuals for drop target. From 0c6e260f739e9094f82c3a7555aed8292b5dc9ab Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 15 Dec 2017 11:16:10 +0100 Subject: [PATCH 751/921] Drag and Drop: Added ImGuiDragDropFlags_SourceExtern to facilitate interfacing with WM_DROPFILES (#143) --- imgui.cpp | 83 +++++++++++++++++++++++++++++++++---------------------- imgui.h | 1 + 2 files changed, 51 insertions(+), 33 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 90316a8d8..c73e74722 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -11220,50 +11220,67 @@ bool ImGui::BeginDragDropSource(ImGuiDragDropFlags flags, int mouse_button) { ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; - if (g.IO.MouseDown[mouse_button] == false) - return false; - ImGuiID id = window->DC.LastItemId; - if (id == 0) + bool source_drag_active = false; + ImGuiID source_id = 0; + ImGuiID source_parent_id = 0; + if (!(flags & ImGuiDragDropFlags_SourceExtern)) { - // If you want to use BeginDragDropSource() on an item with no unique identifier for interaction, such as Text() or Image(), you need to: - // A) Read the explanation below, B) Use the ImGuiDragDropFlags_SourceAllowNullID flag, C) Swallow your programmer pride. - if (!(flags & ImGuiDragDropFlags_SourceAllowNullID)) - { - IM_ASSERT(0); + source_id = window->DC.LastItemId; + if (source_id != 0 && g.ActiveId != source_id) // Early out for most common case + return false; + if (g.IO.MouseDown[mouse_button] == false) return false; - } - // Magic fallback (=somehow reprehensible) to handle items with no assigned ID, e.g. Text(), Image() - // We build a throwaway ID based on current ID stack + relative AABB of items in window. - // THE IDENTIFIER WON'T SURVIVE ANY REPOSITIONING OF THE WIDGET, so if your widget moves your dragging operation will be canceled. - // We don't need to maintain/call ClearActiveID() as releasing the button will early out this function and trigger !ActiveIdIsAlive. - bool is_hovered = window->DC.LastItemRectHoveredRect; - if (!is_hovered && (g.ActiveId == 0 || g.ActiveIdWindow != window)) - return false; - id = window->DC.LastItemId = window->GetIDFromRectangle(window->DC.LastItemRect); - if (is_hovered) - SetHoveredID(id); - if (is_hovered && g.IO.MouseClicked[mouse_button]) + if (source_id == 0) { - SetActiveID(id, window); - FocusWindow(window); + // If you want to use BeginDragDropSource() on an item with no unique identifier for interaction, such as Text() or Image(), you need to: + // A) Read the explanation below, B) Use the ImGuiDragDropFlags_SourceAllowNullID flag, C) Swallow your programmer pride. + if (!(flags & ImGuiDragDropFlags_SourceAllowNullID)) + { + IM_ASSERT(0); + return false; + } + + // Magic fallback (=somehow reprehensible) to handle items with no assigned ID, e.g. Text(), Image() + // We build a throwaway ID based on current ID stack + relative AABB of items in window. + // THE IDENTIFIER WON'T SURVIVE ANY REPOSITIONING OF THE WIDGET, so if your widget moves your dragging operation will be canceled. + // We don't need to maintain/call ClearActiveID() as releasing the button will early out this function and trigger !ActiveIdIsAlive. + bool is_hovered = window->DC.LastItemRectHoveredRect; + if (!is_hovered && (g.ActiveId == 0 || g.ActiveIdWindow != window)) + return false; + source_id = window->DC.LastItemId = window->GetIDFromRectangle(window->DC.LastItemRect); + if (is_hovered) + SetHoveredID(source_id); + if (is_hovered && g.IO.MouseClicked[mouse_button]) + { + SetActiveID(source_id, window); + FocusWindow(window); + } + if (g.ActiveId == source_id) // Allow the underlying widget to display/return hovered during the mouse release frame, else we would get a flicker. + g.ActiveIdAllowOverlap = is_hovered; } - if (g.ActiveId == id) // Allow the underlying widget to display/return hovered during the mouse release frame, else we would get a flicker. - g.ActiveIdAllowOverlap = is_hovered; + if (g.ActiveId != source_id) + return false; + source_parent_id = window->IDStack.back(); + source_drag_active = IsMouseDragging(mouse_button); + } + else + { + window = NULL; + source_id = ImHash("#SourceExtern", 0); + source_drag_active = true; } - if (g.ActiveId != id) - return false; - if (IsMouseDragging(mouse_button)) + if (source_drag_active) { if (!g.DragDropActive) { - IM_ASSERT(id != 0); + IM_ASSERT(source_id != 0); ClearDragDrop(); ImGuiPayload& payload = g.DragDropPayload; - payload.SourceId = id; - payload.SourceParentId = window->IDStack.back(); + payload.SourceId = source_id; + payload.SourceParentId = source_parent_id; g.DragDropActive = true; g.DragDropSourceFlags = flags; g.DragDropMouseButton = mouse_button; @@ -11279,7 +11296,7 @@ bool ImGui::BeginDragDropSource(ImGuiDragDropFlags flags, int mouse_button) BeginTooltipEx(ImGuiWindowFlags_NoInputs); } - if (!(flags & ImGuiDragDropFlags_SourceNoDisableHover)) + if (!(flags & ImGuiDragDropFlags_SourceNoDisableHover) && !(flags & ImGuiDragDropFlags_SourceExtern)) window->DC.LastItemRectHoveredRect = false; return true; @@ -11434,7 +11451,7 @@ const ImGuiPayload* ImGui::AcceptDragDropPayload(const char* type, ImGuiDragDrop } g.DragDropAcceptFrameCount = g.FrameCount; - payload.Delivery = was_accepted_previously && IsMouseReleased(g.DragDropMouseButton); + payload.Delivery = was_accepted_previously && !IsMouseDown(g.DragDropMouseButton); // For extern drag sources affecting os window focus, it's easier to just test !IsMouseDown() instead of IsMouseReleased() if (!payload.Delivery && !(flags & ImGuiDragDropFlags_AcceptBeforeDelivery)) return NULL; diff --git a/imgui.h b/imgui.h index c05759aae..eea0e6a46 100644 --- a/imgui.h +++ b/imgui.h @@ -643,6 +643,7 @@ enum ImGuiDragDropFlags_ ImGuiDragDropFlags_SourceNoDisableHover = 1 << 1, // By default, when dragging we clear data so that IsItemHovered() will return true, to avoid subsequent user code submitting tooltips. This flag disable this behavior so you can still call IsItemHovered() on the source item. ImGuiDragDropFlags_SourceNoHoldToOpenOthers = 1 << 2, // Disable the behavior that allows to open tree nodes and collapsing header by holding over them while dragging a source item. ImGuiDragDropFlags_SourceAllowNullID = 1 << 3, // Allow items such as Text(), Image() that have no unique identifier to be used as drag source, by manufacturing a temporary identifier based on their window-relative position. This is extremely unusual within the dear imgui ecosystem and so we made it explicit. + ImGuiDragDropFlags_SourceExtern = 1 << 4, // External source (from outside of imgui), won't attempt to read current item/window info. Will always return true. Only one Extern source can be active simultaneously. // AcceptDragDropPayload() flags ImGuiDragDropFlags_AcceptBeforeDelivery = 1 << 10, // AcceptDragDropPayload() will returns true even before the mouse button is released. You can then call IsDelivery() to test if the payload needs to be delivered. ImGuiDragDropFlags_AcceptNoDrawDefaultRect = 1 << 11, // Do not draw the default highlight rectangle when hovering over target. From b9391d16921ccfada8aa8ea9d245b2116ef2b1a1 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 15 Dec 2017 15:44:27 +0100 Subject: [PATCH 752/921] Columns: Internal: Columns have their no set of flags so NoResize can be setup by internal code. (#125) --- imgui.cpp | 10 +++++----- imgui_internal.h | 3 ++- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index c73e74722..00c53aa2e 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -10807,15 +10807,15 @@ void ImGui::NextColumn() if (++columns->Current < columns->Count) { // Columns 1+ cancel out IndentX - window->DC.ColumnsOffsetX = GetColumnOffset(columns->Current) - window->DC.IndentX + g.Style.ItemSpacing.x; + window->DC.ColumnsOffsetX = columns->Columns[columns->Current].LockedOffset - window->DC.IndentX + g.Style.ItemSpacing.x; window->DrawList->ChannelsSetCurrent(columns->Current); } else { window->DC.ColumnsOffsetX = 0.0f; + window->DrawList->ChannelsSetCurrent(0); columns->Current = 0; columns->CellMinY = columns->CellMaxY; - window->DrawList->ChannelsSetCurrent(0); } window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.IndentX + window->DC.ColumnsOffsetX); window->DC.CursorPos.y = columns->CellMinY; @@ -11018,7 +11018,7 @@ void ImGui::BeginColumns(const char* str_id, int columns_count, ImGuiColumnsFlag for (int n = 0; n < columns_count + 1; n++) { - // Clamp + // Clamp position ImGuiColumnData* column = &columns->Columns[n]; float t = column->OffsetNorm; if (!(columns->Flags & ImGuiColumnsFlags_NoForceWithinWindow)) @@ -11028,7 +11028,7 @@ void ImGui::BeginColumns(const char* str_id, int columns_count, ImGuiColumnsFlag if (n == columns_count) continue; - // Compute clipping rectangles + // Compute clipping rectangle float clip_x1 = ImFloor(0.5f + window->Pos.x + GetColumnOffset(n) - 1.0f); float clip_x2 = ImFloor(0.5f + window->Pos.x + GetColumnOffset(n + 1) - 1.0f); column->ClipRect = ImRect(clip_x1, -FLT_MAX, clip_x2, +FLT_MAX); @@ -11081,7 +11081,7 @@ void ImGui::EndColumns() g.MouseCursor = ImGuiMouseCursor_ResizeEW; if (held && g.ActiveIdIsJustActivated) g.ActiveIdClickOffset.x -= column_hw; // Store from center of column line (we used a 8 wide rect for columns clicking). This is used by GetDraggedColumnOffset(). - if (held) + if (held && !(columns->Columns[n].Flags & ImGuiColumnsFlags_NoResize)) dragging_column = n; } diff --git a/imgui_internal.h b/imgui_internal.h index f0d598b49..ed19ba664 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -416,9 +416,10 @@ struct ImGuiColumnData { float OffsetNorm; // Column start offset, normalized 0.0 (far left) -> 1.0 (far right) float OffsetNormBeforeResize; + ImGuiColumnsFlags Flags; // Not exposed ImRect ClipRect; - ImGuiColumnData() { OffsetNorm = OffsetNormBeforeResize = 0.0f; } + ImGuiColumnData() { OffsetNorm = OffsetNormBeforeResize = 0.0f; Flags = 0; } }; struct ImGuiColumnsSet From b1d90b565d9e1364254b974715824a46f9caea8c Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 15 Dec 2017 17:09:41 +0100 Subject: [PATCH 753/921] Columns: Fixed previous commit (wrong chunk commited) (#125) --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 00c53aa2e..ac5c5b979 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -10807,7 +10807,7 @@ void ImGui::NextColumn() if (++columns->Current < columns->Count) { // Columns 1+ cancel out IndentX - window->DC.ColumnsOffsetX = columns->Columns[columns->Current].LockedOffset - window->DC.IndentX + g.Style.ItemSpacing.x; + window->DC.ColumnsOffsetX = GetColumnOffset(columns->Current) - window->DC.IndentX + g.Style.ItemSpacing.x; window->DrawList->ChannelsSetCurrent(columns->Current); } else From abaf347deb2ef23b6bdc58c342a802cc18d3581f Mon Sep 17 00:00:00 2001 From: ibachar Date: Sun, 17 Dec 2017 15:27:56 +0200 Subject: [PATCH 754/921] Added a flag for text input to disable undo / redo --- imgui.cpp | 9 +++++---- imgui.h | 1 + 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index ac5c5b979..11589f3c2 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -8405,6 +8405,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 const bool is_multiline = (flags & ImGuiInputTextFlags_Multiline) != 0; const bool is_editable = (flags & ImGuiInputTextFlags_ReadOnly) == 0; const bool is_password = (flags & ImGuiInputTextFlags_Password) != 0; + const bool disable_undo = (flags & ImGuiInputTextFlags_DisableUndo) != 0; if (is_multiline) // Open group before calling GetID() because groups tracks id created during their spawn BeginGroup(); @@ -8631,10 +8632,10 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 if (InputTextFilterCharacter(&c, flags, callback, user_data)) edit_state.OnKeyPressed((int)c); } - else if (IsKeyPressedMap(ImGuiKey_Escape)) { clear_active_id = cancel_edit = true; } - else if (is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_Z) && is_editable) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_UNDO); edit_state.ClearSelection(); } - else if (is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_Y) && is_editable) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_REDO); edit_state.ClearSelection(); } - else if (is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_A)) { edit_state.SelectAll(); edit_state.CursorFollow = true; } + else if (IsKeyPressedMap(ImGuiKey_Escape)) { clear_active_id = cancel_edit = true; } + else if (is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_Z) && is_editable && !disable_undo) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_UNDO); edit_state.ClearSelection(); } + else if (is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_Y) && is_editable && !disable_undo) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_REDO); edit_state.ClearSelection(); } + else if (is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_A)) { edit_state.SelectAll(); edit_state.CursorFollow = true; } else if (is_shortcut_key_only && !is_password && ((IsKeyPressedMap(ImGuiKey_X) && is_editable) || IsKeyPressedMap(ImGuiKey_C)) && (!is_multiline || edit_state.HasSelection())) { // Cut, Copy diff --git a/imgui.h b/imgui.h index eea0e6a46..5c36b1417 100644 --- a/imgui.h +++ b/imgui.h @@ -566,6 +566,7 @@ enum ImGuiInputTextFlags_ ImGuiInputTextFlags_AlwaysInsertMode = 1 << 13, // Insert mode ImGuiInputTextFlags_ReadOnly = 1 << 14, // Read-only mode ImGuiInputTextFlags_Password = 1 << 15, // Password mode, display all characters as '*' + ImGuiInputTextFlags_DisableUndo = 1 << 16, // Disable undo / redo // [Internal] ImGuiInputTextFlags_Multiline = 1 << 20 // For internal use by InputTextMultiline() }; From 55c0d2b9ab2fdc7cd694a8fa2334e749c31e4ed1 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 20 Dec 2017 16:25:03 +0100 Subject: [PATCH 755/921] InputText: renamed ImGuiInputTextFlags_DisableUndo to ImGuiInputTextFlags_NoUndoRedo (#1506, #1508) --- imgui.cpp | 6 +++--- imgui.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 11589f3c2..5d2a61a7c 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -8405,7 +8405,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 const bool is_multiline = (flags & ImGuiInputTextFlags_Multiline) != 0; const bool is_editable = (flags & ImGuiInputTextFlags_ReadOnly) == 0; const bool is_password = (flags & ImGuiInputTextFlags_Password) != 0; - const bool disable_undo = (flags & ImGuiInputTextFlags_DisableUndo) != 0; + const bool is_undoable = (flags & ImGuiInputTextFlags_NoUndoRedo) == 0; if (is_multiline) // Open group before calling GetID() because groups tracks id created during their spawn BeginGroup(); @@ -8633,8 +8633,8 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 edit_state.OnKeyPressed((int)c); } else if (IsKeyPressedMap(ImGuiKey_Escape)) { clear_active_id = cancel_edit = true; } - else if (is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_Z) && is_editable && !disable_undo) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_UNDO); edit_state.ClearSelection(); } - else if (is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_Y) && is_editable && !disable_undo) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_REDO); edit_state.ClearSelection(); } + else if (is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_Z) && is_editable && is_undoable) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_UNDO); edit_state.ClearSelection(); } + else if (is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_Y) && is_editable && is_undoable) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_REDO); edit_state.ClearSelection(); } else if (is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_A)) { edit_state.SelectAll(); edit_state.CursorFollow = true; } else if (is_shortcut_key_only && !is_password && ((IsKeyPressedMap(ImGuiKey_X) && is_editable) || IsKeyPressedMap(ImGuiKey_C)) && (!is_multiline || edit_state.HasSelection())) { diff --git a/imgui.h b/imgui.h index 5c36b1417..4e5203e21 100644 --- a/imgui.h +++ b/imgui.h @@ -566,7 +566,7 @@ enum ImGuiInputTextFlags_ ImGuiInputTextFlags_AlwaysInsertMode = 1 << 13, // Insert mode ImGuiInputTextFlags_ReadOnly = 1 << 14, // Read-only mode ImGuiInputTextFlags_Password = 1 << 15, // Password mode, display all characters as '*' - ImGuiInputTextFlags_DisableUndo = 1 << 16, // Disable undo / redo + ImGuiInputTextFlags_NoUndoRedo = 1 << 16, // Disable undo/redo. Note that input text owns the text data while active, if you want to provide your own undo/redo stack you need e.g. to call ClearActiveID(). // [Internal] ImGuiInputTextFlags_Multiline = 1 << 20 // For internal use by InputTextMultiline() }; From b366dd932267251421e7eb4a01a05a193625cd28 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 20 Dec 2017 17:40:58 +0100 Subject: [PATCH 756/921] BeginPopup: Moved flags into individual BeginPopupXXX calls/implementations and outside of BeginPopupex(). Removed _NoResize flag which is extraneous with AlwaysAutoResize. --- imgui.cpp | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 5d2a61a7c..2ffd8ed78 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3828,15 +3828,13 @@ bool ImGui::BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_flags) return false; } - ImGuiWindowFlags flags = extra_flags|ImGuiWindowFlags_Popup|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings; - char name[20]; - if (flags & ImGuiWindowFlags_ChildMenu) + if (extra_flags & ImGuiWindowFlags_ChildMenu) ImFormatString(name, IM_ARRAYSIZE(name), "##Menu_%02d", g.CurrentPopupStack.Size); // Recycle windows based on depth else ImFormatString(name, IM_ARRAYSIZE(name), "##Popup_%08x", id); // Not recycling, so we can close/open during the same frame - bool is_open = Begin(name, NULL, flags); + bool is_open = Begin(name, NULL, extra_flags | ImGuiWindowFlags_Popup); if (!is_open) // NB: Begin can return false when the popup is completely clipped (e.g. zero size display) EndPopup(); @@ -3851,7 +3849,7 @@ bool ImGui::BeginPopup(const char* str_id) ClearSetNextWindowData(); // We behave like Begin() and need to consume those values return false; } - return BeginPopupEx(g.CurrentWindow->GetID(str_id), ImGuiWindowFlags_AlwaysAutoResize); + return BeginPopupEx(g.CurrentWindow->GetID(str_id), ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoSavedSettings); } bool ImGui::IsPopupOpen(ImGuiID id) @@ -3926,7 +3924,7 @@ bool ImGui::BeginPopupContextItem(const char* str_id, int mouse_button) if (IsMouseClicked(mouse_button)) if (IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup)) OpenPopupEx(id, true); - return BeginPopupEx(id, ImGuiWindowFlags_AlwaysAutoResize); + return BeginPopupEx(id, ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoSavedSettings); } bool ImGui::BeginPopupContextWindow(const char* str_id, int mouse_button, bool also_over_items) @@ -3938,7 +3936,7 @@ bool ImGui::BeginPopupContextWindow(const char* str_id, int mouse_button, bool a if (IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup)) if (also_over_items || !IsAnyItemHovered()) OpenPopupEx(id, true); - return BeginPopupEx(id, ImGuiWindowFlags_AlwaysAutoResize); + return BeginPopupEx(id, ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoSavedSettings); } bool ImGui::BeginPopupContextVoid(const char* str_id, int mouse_button) @@ -3948,7 +3946,7 @@ bool ImGui::BeginPopupContextVoid(const char* str_id, int mouse_button) ImGuiID id = GImGui->CurrentWindow->GetID(str_id); if (!IsAnyWindowHovered() && IsMouseClicked(mouse_button)) OpenPopupEx(id, true); - return BeginPopupEx(id, ImGuiWindowFlags_AlwaysAutoResize); + return BeginPopupEx(id, ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoSavedSettings); } static bool BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, bool border, ImGuiWindowFlags extra_flags) @@ -9754,7 +9752,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled) if (menu_is_open) { SetNextWindowPos(popup_pos, ImGuiCond_Always); - ImGuiWindowFlags flags = ImGuiWindowFlags_AlwaysAutoResize | ((window->Flags & (ImGuiWindowFlags_Popup|ImGuiWindowFlags_ChildMenu)) ? ImGuiWindowFlags_ChildMenu|ImGuiWindowFlags_ChildWindow : ImGuiWindowFlags_ChildMenu); + ImGuiWindowFlags flags = ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoSavedSettings | ((window->Flags & (ImGuiWindowFlags_Popup|ImGuiWindowFlags_ChildMenu)) ? ImGuiWindowFlags_ChildMenu|ImGuiWindowFlags_ChildWindow : ImGuiWindowFlags_ChildMenu); menu_is_open = BeginPopupEx(id, flags); // menu_is_open can be 'false' when the popup is completely clipped (e.g. zero size display) } From 6193f46af28e3ea22730286664e7573bfd7714a8 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 21 Dec 2017 11:18:30 +0100 Subject: [PATCH 757/921] Active Modal window always set the WantCaptureKeyboard flag (#744) --- imgui.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 2ffd8ed78..3c9c1997c 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2406,7 +2406,8 @@ void ImGui::NewFrame() g.HoveredWindow = (g.MovingWindow && !(g.MovingWindow->Flags & ImGuiWindowFlags_NoInputs)) ? g.MovingWindow : FindHoveredWindow(g.IO.MousePos); g.HoveredRootWindow = g.HoveredWindow ? g.HoveredWindow->RootWindow : NULL; - if (ImGuiWindow* modal_window = GetFrontMostModalRootWindow()) + ImGuiWindow* modal_window = GetFrontMostModalRootWindow(); + if (modal_window != NULL) { g.ModalWindowDarkeningRatio = ImMin(g.ModalWindowDarkeningRatio + g.IO.DeltaTime * 6.0f, 1.0f); if (g.HoveredRootWindow && !IsWindowChildOf(g.HoveredRootWindow, modal_window)) @@ -2435,7 +2436,10 @@ void ImGui::NewFrame() g.IO.WantCaptureMouse = (g.WantCaptureMouseNextFrame != 0); else g.IO.WantCaptureMouse = (mouse_avail_to_imgui && (g.HoveredWindow != NULL || mouse_any_down)) || (!g.OpenPopupStack.empty()); - g.IO.WantCaptureKeyboard = (g.WantCaptureKeyboardNextFrame != -1) ? (g.WantCaptureKeyboardNextFrame != 0) : (g.ActiveId != 0); + if (g.WantCaptureKeyboardNextFrame != -1) + g.IO.WantCaptureKeyboard = (g.WantCaptureKeyboardNextFrame != 0); + else + g.IO.WantCaptureKeyboard = (g.ActiveId != 0) || (modal_window != NULL); g.IO.WantTextInput = (g.WantTextInputNextFrame != -1) ? (g.WantTextInputNextFrame != 0) : 0; g.MouseCursor = ImGuiMouseCursor_Arrow; g.WantCaptureMouseNextFrame = g.WantCaptureKeyboardNextFrame = g.WantTextInputNextFrame = -1; From 230f826ef560eddecf86c47eec0eac04d1cbf249 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 21 Dec 2017 14:50:58 +0100 Subject: [PATCH 758/921] ImDrawList: Comments --- imgui.cpp | 2 +- imgui.h | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 3c9c1997c..5fcd9ee5f 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -735,7 +735,7 @@ ImGuiStyle::ImGuiStyle() DisplaySafeAreaPadding = ImVec2(4,4); // If you cannot see the edge of your screen (e.g. on a TV) increase the safe area padding. Covers popups/tooltips as well regular windows. AntiAliasedLines = true; // Enable anti-aliasing on lines/borders. Disable if you are really short on CPU/GPU. AntiAliasedShapes = true; // Enable anti-aliasing on filled shapes (rounded rectangles, circles, etc.) - CurveTessellationTol = 1.25f; // Tessellation tolerance. Decrease for highly tessellated curves (higher quality, more polygons), increase to reduce quality. + CurveTessellationTol = 1.25f; // Tessellation tolerance when using PathBezierCurveTo() without a specific number of segments. Decrease for highly tessellated curves (higher quality, more polygons), increase to reduce quality. ImGui::StyleColorsClassic(this); } diff --git a/imgui.h b/imgui.h index 4e5203e21..55ac7b208 100644 --- a/imgui.h +++ b/imgui.h @@ -854,7 +854,7 @@ struct ImGuiStyle ImVec2 DisplaySafeAreaPadding; // If you cannot see the edge of your screen (e.g. on a TV) increase the safe area padding. Covers popups/tooltips as well regular windows. bool AntiAliasedLines; // Enable anti-aliasing on lines/borders. Disable if you are really tight on CPU/GPU. bool AntiAliasedShapes; // Enable anti-aliasing on filled shapes (rounded rectangles, circles, etc.) - float CurveTessellationTol; // Tessellation tolerance. Decrease for highly tessellated curves (higher quality, more polygons), increase to reduce quality. + float CurveTessellationTol; // Tessellation tolerance when using PathBezierCurveTo() without a specific number of segments. Decrease for highly tessellated curves (higher quality, more polygons), increase to reduce quality. ImVec4 Colors[ImGuiCol_COUNT]; IMGUI_API ImGuiStyle(); @@ -1372,15 +1372,14 @@ enum ImDrawCornerFlags_ // Draw command list // This is the low-level list of polygons that ImGui functions are filling. At the end of the frame, all command lists are passed to your ImGuiIO::RenderDrawListFn function for rendering. -// At the moment, each ImGui window contains its own ImDrawList but they could potentially be merged in the future. -// If you want to add custom rendering within a window, you can use ImGui::GetWindowDrawList() to access the current draw list and add your own primitives. +// Each ImGui window contains its own ImDrawList. You can use ImGui::GetWindowDrawList() to access the current window draw list and draw custom primitives. // You can interleave normal ImGui:: calls and adding primitives to the current draw list. // All positions are generally in pixel coordinates (top-left at (0,0), bottom-right at io.DisplaySize), however you are totally free to apply whatever transformation matrix to want to the data (if you apply such transformation you'll want to apply it to ClipRect as well) -// Primitives are always added to the list and not culled (culling is done at higher-level by ImGui:: functions). +// Important: Primitives are always added to the list and not culled (culling is done at higher-level by ImGui:: functions), if you use this API a lot consider coarse culling your drawn objects. struct ImDrawList { // This is what you have to render - ImVector CmdBuffer; // Commands. Typically 1 command = 1 GPU draw call. + ImVector CmdBuffer; // Draw commands. Typically 1 command = 1 GPU draw call, unless the command is a callback. ImVector IdxBuffer; // Index buffer. Each command consume ImDrawCmd::ElemCount of those ImVector VtxBuffer; // Vertex buffer. From 531c11d5c72890f324c9734ef5c860408b8a7f3d Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 21 Dec 2017 18:50:27 +0100 Subject: [PATCH 759/921] ImDrawList: Small refactor toward removing dependency on GImGui + PushClipRectFullscreen now correctly uses data provided by imgui which can takes account of DisplaySize + Removed static variable in PathArcToFast() which caused linking issues to some. --- imgui.cpp | 25 +++++++++++++------- imgui.h | 7 ++++-- imgui_draw.cpp | 59 ++++++++++++++++++++++++------------------------ imgui_internal.h | 23 +++++++++++++++---- 4 files changed, 71 insertions(+), 43 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 5fcd9ee5f..dbed5341c 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1818,7 +1818,7 @@ bool ImGuiListClipper::Step() // ImGuiWindow //----------------------------------------------------------------------------- -ImGuiWindow::ImGuiWindow(const char* name) +ImGuiWindow::ImGuiWindow(ImGuiContext* context, const char* name) { Name = ImStrdup(name); ID = ImHash(name, 0); @@ -1859,7 +1859,7 @@ ImGuiWindow::ImGuiWindow(const char* name) FontWindowScale = 1.0f; DrawList = (ImDrawList*)ImGui::MemAlloc(sizeof(ImDrawList)); - IM_PLACEMENT_NEW(DrawList) ImDrawList(); + IM_PLACEMENT_NEW(DrawList) ImDrawList(&context->DrawListSharedData); DrawList->_OwnerName = Name; ParentWindow = NULL; RootWindow = NULL; @@ -2254,6 +2254,11 @@ ImDrawList* ImGui::GetOverlayDrawList() return &GImGui->OverlayDrawList; } +ImDrawListSharedData* ImGui::GetDrawListSharedData() +{ + return &GImGui->DrawListSharedData; +} + void ImGui::NewFrame() { ImGuiContext& g = *GImGui; @@ -2274,6 +2279,8 @@ void ImGui::NewFrame() SetCurrentFont(GetDefaultFont()); IM_ASSERT(g.Font->IsLoaded()); + g.DrawListSharedData.ClipRectFullscreen = ImVec4(0.0f, 0.0f, g.IO.DisplaySize.x, g.IO.DisplaySize.y); + g.DrawListSharedData.CurveTessellationTol = g.Style.CurveTessellationTol; g.Time += g.IO.DeltaTime; g.FrameCount += 1; @@ -4145,7 +4152,7 @@ static ImGuiWindow* CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFl // Create window the first time ImGuiWindow* window = (ImGuiWindow*)ImGui::MemAlloc(sizeof(ImGuiWindow)); - IM_PLACEMENT_NEW(window) ImGuiWindow(name); + IM_PLACEMENT_NEW(window) ImGuiWindow(&g, name); window->Flags = flags; g.WindowsById.SetVoidPtr(window->ID, window); @@ -5243,7 +5250,11 @@ static void SetCurrentFont(ImFont* font) g.Font = font; g.FontBaseSize = g.IO.FontGlobalScale * g.Font->FontSize * g.Font->Scale; g.FontSize = g.CurrentWindow ? g.CurrentWindow->CalcFontSize() : 0.0f; - g.FontTexUvWhitePixel = g.Font->ContainerAtlas->TexUvWhitePixel; + + ImFontAtlas* atlas = g.Font->ContainerAtlas; + g.DrawListSharedData.TexUvWhitePixel = atlas->TexUvWhitePixel; + g.DrawListSharedData.Font = g.Font; + g.DrawListSharedData.FontSize = g.FontSize; } void ImGui::PushFont(ImFont* font) @@ -5820,7 +5831,7 @@ float ImGui::GetFontSize() ImVec2 ImGui::GetFontTexUvWhitePixel() { - return GImGui->FontTexUvWhitePixel; + return GImGui->DrawListSharedData.TexUvWhitePixel; } void ImGui::SetWindowFontScale(float scale) @@ -10489,7 +10500,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl ImVec2 tra = wheel_center + ImRotate(triangle_pa, cos_hue_angle, sin_hue_angle); ImVec2 trb = wheel_center + ImRotate(triangle_pb, cos_hue_angle, sin_hue_angle); ImVec2 trc = wheel_center + ImRotate(triangle_pc, cos_hue_angle, sin_hue_angle); - ImVec2 uv_white = g.FontTexUvWhitePixel; + ImVec2 uv_white = GetFontTexUvWhitePixel(); draw_list->PrimReserve(6, 6); draw_list->PrimVtx(tra, uv_white, hue_color32); draw_list->PrimVtx(trb, uv_white, hue_color32); @@ -11609,7 +11620,6 @@ void ImGui::ShowMetricsWindow(bool* p_open) return; ImDrawList* overlay_draw_list = &GImGui->OverlayDrawList; // Render additional visuals into the top-most draw list - overlay_draw_list->PushClipRectFullScreen(); int elem_offset = 0; for (const ImDrawCmd* pcmd = draw_list->CmdBuffer.begin(); pcmd < draw_list->CmdBuffer.end(); elem_offset += pcmd->ElemCount, pcmd++) { @@ -11652,7 +11662,6 @@ void ImGui::ShowMetricsWindow(bool* p_open) } ImGui::TreePop(); } - overlay_draw_list->PopClipRect(); ImGui::TreePop(); } diff --git a/imgui.h b/imgui.h index 55ac7b208..c24a86035 100644 --- a/imgui.h +++ b/imgui.h @@ -50,6 +50,7 @@ struct ImDrawChannel; // Temporary storage for outputting drawing struct ImDrawCmd; // A single draw command within a parent ImDrawList (generally maps to 1 GPU draw call) struct ImDrawData; // All draw command lists required to render the frame struct ImDrawList; // A single draw command list (generally one per window) +struct ImDrawListSharedData; // Data shared among multiple draw lists (typically owned by parent ImGui context, but you may create one yourself) struct ImDrawVert; // A single vertex (20 bytes by default, override layout with IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT) struct ImFont; // Runtime data for a single font within a parent ImFontAtlas struct ImFontAtlas; // Runtime data for multiple fonts, bake multiple fonts into a single texture, TTF/OTF font loader @@ -466,6 +467,7 @@ namespace ImGui IMGUI_API float GetTime(); IMGUI_API int GetFrameCount(); IMGUI_API ImDrawList* GetOverlayDrawList(); // this draw list will be the last rendered one, useful to quickly draw overlays shapes/text + IMGUI_API ImDrawListSharedData* GetDrawListSharedData(); IMGUI_API const char* GetStyleColorName(ImGuiCol idx); IMGUI_API ImVec2 CalcItemRectClosestPoint(const ImVec2& pos, bool on_edge = false, float outward = +0.0f); // utility to find the closest point the last item bounding rectangle edge. useful to visually link items IMGUI_API ImVec2 CalcTextSize(const char* text, const char* text_end = NULL, bool hide_text_after_double_hash = false, float wrap_width = -1.0f); @@ -1325,7 +1327,7 @@ struct ImDrawCmd ImDrawCallback UserCallback; // If != NULL, call the function instead of rendering the vertices. clip_rect and texture_id will be set normally. void* UserCallbackData; // The draw callback code can access this. - ImDrawCmd() { ElemCount = 0; ClipRect.x = ClipRect.y = -8192.0f; ClipRect.z = ClipRect.w = +8192.0f; TextureId = NULL; UserCallback = NULL; UserCallbackData = NULL; } + ImDrawCmd() { ElemCount = 0; ClipRect.x = ClipRect.y = ClipRect.z = ClipRect.w = 0.0f; TextureId = NULL; UserCallback = NULL; UserCallbackData = NULL; } }; // Vertex index (override with '#define ImDrawIdx unsigned int' inside in imconfig.h) @@ -1384,6 +1386,7 @@ struct ImDrawList ImVector VtxBuffer; // Vertex buffer. // [Internal, used while building lists] + const ImDrawListSharedData* _Data; // Pointer to shared draw data (you can use ImGui::GetDrawListSharedData() to get the one from current ImGui context) const char* _OwnerName; // Pointer to owner window's name for debugging unsigned int _VtxCurrentIdx; // [Internal] == VtxBuffer.Size ImDrawVert* _VtxWritePtr; // [Internal] point within VtxBuffer.Data after each add command (to avoid using the ImVector<> operators too much) @@ -1395,7 +1398,7 @@ struct ImDrawList int _ChannelsCount; // [Internal] number of active channels (1+) ImVector _Channels; // [Internal] draw channels for columns API (not resized down so _ChannelsCount may be smaller than _Channels.Size) - ImDrawList() { _OwnerName = NULL; Clear(); } + ImDrawList(const ImDrawListSharedData* shared_data) { _Data = shared_data; _OwnerName = NULL; Clear(); } ~ImDrawList() { ClearFreeMemory(); } IMGUI_API void PushClipRect(ImVec2 clip_rect_min, ImVec2 clip_rect_max, bool intersect_with_current_clip_rect = false); // Render-level scissoring. This is passed down to your render function but not used for CPU-side coarse clipping. Prefer using higher-level ImGui::PushClipRect() to affect logic (hit-testing and widget culling) IMGUI_API void PushClipRectFullScreen(); diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 69e93689f..03ff863c3 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -277,10 +277,27 @@ void ImGui::StyleColorsLight(ImGuiStyle* dst) } //----------------------------------------------------------------------------- -// ImDrawList +// ImDrawListData //----------------------------------------------------------------------------- -static const ImVec4 GNullClipRect(-8192.0f, -8192.0f, +8192.0f, +8192.0f); // Large values that are easy to encode in a few bits+shift +ImDrawListSharedData::ImDrawListSharedData() +{ + Font = NULL; + FontSize = 0.0f; + CurveTessellationTol = 0.0f; + ClipRectFullscreen = ImVec4(-8192.0f, -8192.0f, +8192.0f, +8192.0f); + + // Const data + for (int i = 0; i < IM_ARRAYSIZE(CircleVtx12); i++) + { + const float a = ((float)i * 2 * IM_PI) / (float)IM_ARRAYSIZE(CircleVtx12); + CircleVtx12[i] = ImVec2(cosf(a), sinf(a)); + } +} + +//----------------------------------------------------------------------------- +// ImDrawList +//----------------------------------------------------------------------------- void ImDrawList::Clear() { @@ -321,7 +338,7 @@ void ImDrawList::ClearFreeMemory() } // Using macros because C++ is a terrible language, we want guaranteed inline, no code in header, and no overhead in Debug builds -#define GetCurrentClipRect() (_ClipRectStack.Size ? _ClipRectStack.Data[_ClipRectStack.Size-1] : GNullClipRect) +#define GetCurrentClipRect() (_ClipRectStack.Size ? _ClipRectStack.Data[_ClipRectStack.Size-1] : _Data->ClipRectFullscreen) #define GetCurrentTextureId() (_TextureIdStack.Size ? _TextureIdStack.Data[_TextureIdStack.Size-1] : NULL) void ImDrawList::AddDrawCmd() @@ -412,8 +429,7 @@ void ImDrawList::PushClipRect(ImVec2 cr_min, ImVec2 cr_max, bool intersect_with_ void ImDrawList::PushClipRectFullScreen() { - PushClipRect(ImVec2(GNullClipRect.x, GNullClipRect.y), ImVec2(GNullClipRect.z, GNullClipRect.w)); - //PushClipRect(GetVisibleRect()); // FIXME-OPT: This would be more correct but we're not supposed to access ImGuiContext from here? + PushClipRect(ImVec2(_Data->ClipRectFullscreen.x, _Data->ClipRectFullscreen.y), ImVec2(_Data->ClipRectFullscreen.z, _Data->ClipRectFullscreen.w)); } void ImDrawList::PopClipRect() @@ -533,7 +549,7 @@ void ImDrawList::PrimReserve(int idx_count, int vtx_count) // Fully unrolled with inline call to keep our debug builds decently fast. void ImDrawList::PrimRect(const ImVec2& a, const ImVec2& c, ImU32 col) { - ImVec2 b(c.x, a.y), d(a.x, c.y), uv(GImGui->FontTexUvWhitePixel); + ImVec2 b(c.x, a.y), d(a.x, c.y), uv(_Data->TexUvWhitePixel); ImDrawIdx idx = (ImDrawIdx)_VtxCurrentIdx; _IdxWritePtr[0] = idx; _IdxWritePtr[1] = (ImDrawIdx)(idx+1); _IdxWritePtr[2] = (ImDrawIdx)(idx+2); _IdxWritePtr[3] = idx; _IdxWritePtr[4] = (ImDrawIdx)(idx+2); _IdxWritePtr[5] = (ImDrawIdx)(idx+3); @@ -581,7 +597,7 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32 if (points_count < 2) return; - const ImVec2 uv = GImGui->FontTexUvWhitePixel; + const ImVec2 uv = _Data->TexUvWhitePixel; anti_aliased &= GImGui->Style.AntiAliasedLines; //if (ImGui::GetIO().KeyCtrl) anti_aliased = false; // Debug @@ -759,7 +775,7 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32 void ImDrawList::AddConvexPolyFilled(const ImVec2* points, const int points_count, ImU32 col, bool anti_aliased) { - const ImVec2 uv = GImGui->FontTexUvWhitePixel; + const ImVec2 uv = _Data->TexUvWhitePixel; anti_aliased &= GImGui->Style.AntiAliasedShapes; //if (ImGui::GetIO().KeyCtrl) anti_aliased = false; // Debug @@ -842,20 +858,6 @@ void ImDrawList::AddConvexPolyFilled(const ImVec2* points, const int points_coun void ImDrawList::PathArcToFast(const ImVec2& centre, float radius, int a_min_of_12, int a_max_of_12) { - static ImVec2 circle_vtx[12]; - static bool circle_vtx_builds = false; - const int circle_vtx_count = IM_ARRAYSIZE(circle_vtx); - if (!circle_vtx_builds) - { - for (int i = 0; i < circle_vtx_count; i++) - { - const float a = ((float)i / (float)circle_vtx_count) * 2*IM_PI; - circle_vtx[i].x = cosf(a); - circle_vtx[i].y = sinf(a); - } - circle_vtx_builds = true; - } - if (radius == 0.0f || a_min_of_12 > a_max_of_12) { _Path.push_back(centre); @@ -864,7 +866,7 @@ void ImDrawList::PathArcToFast(const ImVec2& centre, float radius, int a_min_of_ _Path.reserve(_Path.Size + (a_max_of_12 - a_min_of_12 + 1)); for (int a = a_min_of_12; a <= a_max_of_12; a++) { - const ImVec2& c = circle_vtx[a % circle_vtx_count]; + const ImVec2& c = _Data->CircleVtx12[a % IM_ARRAYSIZE(_Data->CircleVtx12)]; _Path.push_back(ImVec2(centre.x + c.x * radius, centre.y + c.y * radius)); } } @@ -916,7 +918,7 @@ void ImDrawList::PathBezierCurveTo(const ImVec2& p2, const ImVec2& p3, const ImV if (num_segments == 0) { // Auto-tessellated - PathBezierToCasteljau(&_Path, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y, GImGui->Style.CurveTessellationTol, 0); + PathBezierToCasteljau(&_Path, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y, _Data->CurveTessellationTol, 0); } else { @@ -998,7 +1000,7 @@ void ImDrawList::AddRectFilledMultiColor(const ImVec2& a, const ImVec2& c, ImU32 if (((col_upr_left | col_upr_right | col_bot_right | col_bot_left) & IM_COL32_A_MASK) == 0) return; - const ImVec2 uv = GImGui->FontTexUvWhitePixel; + const ImVec2 uv = _Data->TexUvWhitePixel; PrimReserve(6, 4); PrimWriteIdx((ImDrawIdx)(_VtxCurrentIdx)); PrimWriteIdx((ImDrawIdx)(_VtxCurrentIdx+1)); PrimWriteIdx((ImDrawIdx)(_VtxCurrentIdx+2)); PrimWriteIdx((ImDrawIdx)(_VtxCurrentIdx)); PrimWriteIdx((ImDrawIdx)(_VtxCurrentIdx+2)); PrimWriteIdx((ImDrawIdx)(_VtxCurrentIdx+3)); @@ -1094,12 +1096,11 @@ void ImDrawList::AddText(const ImFont* font, float font_size, const ImVec2& pos, if (text_begin == text_end) return; - // IMPORTANT: This is one of the few instance of breaking the encapsulation of ImDrawList, as we pull this from ImGui state, but it is just SO useful. - // Might just move Font/FontSize to ImDrawList? + // Pull default font/size from the shared ImDrawListSharedData instance if (font == NULL) - font = GImGui->Font; + font = _Data->Font; if (font_size == 0.0f) - font_size = GImGui->FontSize; + font_size = _Data->FontSize; IM_ASSERT(font->ContainerAtlas->TexID == _TextureIdStack.back()); // Use high-level ImGui::PushFont() or low-level ImDrawList::PushTextureId() to change font. diff --git a/imgui_internal.h b/imgui_internal.h index ed19ba664..ca1563671 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -453,6 +453,21 @@ struct ImGuiColumnsSet } }; +struct ImDrawListSharedData +{ + ImVec2 TexUvWhitePixel; // UV of white pixel in the atlas + ImFont* Font; // Current/default font (optional, for simplified AddText overload) + float FontSize; // Current/default font size (optional, for simplified AddText overload) + float CurveTessellationTol; + ImVec4 ClipRectFullscreen; // Value for PushClipRectFullscreen() + + // Const data + // FIXME: Bake rounded corners fill/borders in atlas + ImVec2 CircleVtx12[12]; + + ImDrawListSharedData(); +}; + // Main state for ImGui struct ImGuiContext { @@ -462,7 +477,7 @@ struct ImGuiContext ImFont* Font; // (Shortcut) == FontStack.empty() ? IO.Font : FontStack.back() float FontSize; // (Shortcut) == FontBaseSize * g.CurrentWindow->FontWindowScale == window->FontSize(). Text height for current window. float FontBaseSize; // (Shortcut) == IO.FontGlobalScale * Font->Scale * Font->FontSize. Base text height. - ImVec2 FontTexUvWhitePixel; // (Shortcut) == Font->TexUvWhitePixel + ImDrawListSharedData DrawListSharedData; float Time; int FrameCount; @@ -574,12 +589,11 @@ struct ImGuiContext int WantTextInputNextFrame; char TempBuffer[1024*3+1]; // temporary text buffer - ImGuiContext() + ImGuiContext() : OverlayDrawList(NULL) { Initialized = false; Font = NULL; FontSize = FontBaseSize = 0.0f; - FontTexUvWhitePixel = ImVec2(0.0f, 0.0f); Time = 0.0f; FrameCount = 0; @@ -639,6 +653,7 @@ struct ImGuiContext OsImePosRequest = OsImePosSet = ImVec2(-1.0f, -1.0f); ModalWindowDarkeningRatio = 0.0f; + OverlayDrawList._Data = &DrawListSharedData; OverlayDrawList._OwnerName = "##Overlay"; // Give it a name for debugging MouseCursor = ImGuiMouseCursor_Arrow; memset(MouseCursorData, 0, sizeof(MouseCursorData)); @@ -805,7 +820,7 @@ struct IMGUI_API ImGuiWindow int FocusIdxTabRequestNext; // " public: - ImGuiWindow(const char* name); + ImGuiWindow(ImGuiContext* context, const char* name); ~ImGuiWindow(); ImGuiID GetID(const char* str, const char* str_end = NULL); From 14cb8177d0939fcdf59252192e7cd68162213c43 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 21 Dec 2017 19:01:53 +0100 Subject: [PATCH 760/921] ImDrawList: Removed 'bool anti_aliased = true' final parameter of ImDrawList::AddPolyline() and ImDrawList::AddConvexPolyFilled(). Anti-aliasing is controlled via the regular style.AntiAliased flags. --- imgui.cpp | 9 ++++++++- imgui.h | 8 ++++---- imgui_draw.cpp | 8 ++++---- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index dbed5341c..e3000c929 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -213,6 +213,7 @@ Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. Also read releases logs https://github.com/ocornut/imgui/releases for more details. + - 2017/12/21 (1.53) - removed 'bool anti_aliased = true' final parameter of ImDrawList::AddPolyline() and ImDrawList::AddConvexPolyFilled(). Anti-aliasing is controlled via the regular style.AntiAliased flags. - 2017/12/14 (1.53) - using the ImGuiWindowFlags_NoScrollWithMouse flag on a child window forwards the mouse wheel event to the parent window, unless either ImGuiWindowFlags_NoInputs or ImGuiWindowFlags_NoScrollbar are also set. - 2017/12/13 (1.53) - renamed GetItemsLineHeightWithSpacing() to GetFrameHeightWithSpacing(). Kept redirection function (will obsolete). - 2017/12/13 (1.53) - obsoleted IsRootWindowFocused() in favor of using IsWindowFocused(ImGuiFocusedFlags_RootWindow). Kept redirection function (will obsolete). @@ -11658,7 +11659,13 @@ void ImGui::ShowMetricsWindow(bool* p_open) } ImGui::Selectable(buf, false); if (ImGui::IsItemHovered()) - overlay_draw_list->AddPolyline(triangles_pos, 3, IM_COL32(255,255,0,255), true, 1.0f, false); // Add triangle without AA, more readable for large-thin triangle + { + ImGuiStyle& style = ImGui::GetStyle(); + bool backup_aa_lines = style.AntiAliasedLines; + style.AntiAliasedLines = false; // Disable AA on triangle outlines at is more readable for very large and thin triangles. + overlay_draw_list->AddPolyline(triangles_pos, 3, IM_COL32(255,255,0,255), true, 1.0f); + style.AntiAliasedLines = backup_aa_lines; + } } ImGui::TreePop(); } diff --git a/imgui.h b/imgui.h index c24a86035..2185d0665 100644 --- a/imgui.h +++ b/imgui.h @@ -1424,16 +1424,16 @@ struct ImDrawList IMGUI_API void AddImage(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& uv_a = ImVec2(0,0), const ImVec2& uv_b = ImVec2(1,1), ImU32 col = 0xFFFFFFFF); IMGUI_API void AddImageQuad(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, const ImVec2& uv_a = ImVec2(0,0), const ImVec2& uv_b = ImVec2(1,0), const ImVec2& uv_c = ImVec2(1,1), const ImVec2& uv_d = ImVec2(0,1), ImU32 col = 0xFFFFFFFF); IMGUI_API void AddImageRounded(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& uv_a, const ImVec2& uv_b, ImU32 col, float rounding, int rounding_corners = ImDrawCornerFlags_All); - IMGUI_API void AddPolyline(const ImVec2* points, const int num_points, ImU32 col, bool closed, float thickness, bool anti_aliased); - IMGUI_API void AddConvexPolyFilled(const ImVec2* points, const int num_points, ImU32 col, bool anti_aliased); + IMGUI_API void AddPolyline(const ImVec2* points, const int num_points, ImU32 col, bool closed, float thickness); + IMGUI_API void AddConvexPolyFilled(const ImVec2* points, const int num_points, ImU32 col); IMGUI_API void AddBezierCurve(const ImVec2& pos0, const ImVec2& cp0, const ImVec2& cp1, const ImVec2& pos1, ImU32 col, float thickness, int num_segments = 0); // Stateful path API, add points then finish with PathFill() or PathStroke() inline void PathClear() { _Path.resize(0); } inline void PathLineTo(const ImVec2& pos) { _Path.push_back(pos); } inline void PathLineToMergeDuplicate(const ImVec2& pos) { if (_Path.Size == 0 || memcmp(&_Path[_Path.Size-1], &pos, 8) != 0) _Path.push_back(pos); } - inline void PathFillConvex(ImU32 col) { AddConvexPolyFilled(_Path.Data, _Path.Size, col, true); PathClear(); } - inline void PathStroke(ImU32 col, bool closed, float thickness = 1.0f) { AddPolyline(_Path.Data, _Path.Size, col, closed, thickness, true); PathClear(); } + inline void PathFillConvex(ImU32 col) { AddConvexPolyFilled(_Path.Data, _Path.Size, col); PathClear(); } + inline void PathStroke(ImU32 col, bool closed, float thickness = 1.0f) { AddPolyline(_Path.Data, _Path.Size, col, closed, thickness); PathClear(); } IMGUI_API void PathArcTo(const ImVec2& centre, float radius, float a_min, float a_max, int num_segments = 10); IMGUI_API void PathArcToFast(const ImVec2& centre, float radius, int a_min_of_12, int a_max_of_12); // Use precomputed angles for a 12 steps circle IMGUI_API void PathBezierCurveTo(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, int num_segments = 0); diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 03ff863c3..1136e274a 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -592,13 +592,13 @@ void ImDrawList::PrimQuadUV(const ImVec2& a, const ImVec2& b, const ImVec2& c, c } // TODO: Thickness anti-aliased lines cap are missing their AA fringe. -void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32 col, bool closed, float thickness, bool anti_aliased) +void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32 col, bool closed, float thickness) { if (points_count < 2) return; const ImVec2 uv = _Data->TexUvWhitePixel; - anti_aliased &= GImGui->Style.AntiAliasedLines; + bool anti_aliased = GImGui->Style.AntiAliasedLines; //if (ImGui::GetIO().KeyCtrl) anti_aliased = false; // Debug int count = points_count; @@ -773,10 +773,10 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32 } } -void ImDrawList::AddConvexPolyFilled(const ImVec2* points, const int points_count, ImU32 col, bool anti_aliased) +void ImDrawList::AddConvexPolyFilled(const ImVec2* points, const int points_count, ImU32 col) { const ImVec2 uv = _Data->TexUvWhitePixel; - anti_aliased &= GImGui->Style.AntiAliasedShapes; + bool anti_aliased = GImGui->Style.AntiAliasedShapes; //if (ImGui::GetIO().KeyCtrl) anti_aliased = false; // Debug if (anti_aliased) From d139bd088df3547377b2ad5e788547447fe18299 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 21 Dec 2017 19:27:06 +0100 Subject: [PATCH 761/921] Begin: Moved modal darkening draw block --- imgui.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index e3000c929..1490d042d 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4661,16 +4661,16 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->Scroll = CalcNextScrollFromScrollTargetAndClamp(window); window->ScrollTarget = ImVec2(FLT_MAX, FLT_MAX); - // Modal window darkens what is behind them - if ((flags & ImGuiWindowFlags_Modal) != 0 && window == GetFrontMostModalRootWindow()) - window->DrawList->AddRectFilled(fullscreen_rect.Min, fullscreen_rect.Max, GetColorU32(ImGuiCol_ModalWindowDarkening, g.ModalWindowDarkeningRatio)); - // Apply focus, new windows appears in front bool want_focus = false; if (window_just_activated_by_user && !(flags & ImGuiWindowFlags_NoFocusOnAppearing)) if (!(flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_Tooltip)) || (flags & ImGuiWindowFlags_Popup)) want_focus = true; + // Draw modal window background (darkens what is behind them) + if ((flags & ImGuiWindowFlags_Modal) != 0 && window == GetFrontMostModalRootWindow()) + window->DrawList->AddRectFilled(fullscreen_rect.Min, fullscreen_rect.Max, GetColorU32(ImGuiCol_ModalWindowDarkening, g.ModalWindowDarkeningRatio)); + // Draw window + handle manual resize ImRect title_bar_rect = window->TitleBarRect(); if (window->Collapsed) @@ -11644,6 +11644,8 @@ void ImGui::ShowMetricsWindow(bool* p_open) } if (!pcmd_node_open) continue; + + // Display individual triangles/vertices. Hover on to get the corresponding triangle highlighted. ImGuiListClipper clipper(pcmd->ElemCount/3); // Manually coarse clip our print out of individual vertices to save CPU, only items that may be visible. while (clipper.Step()) for (int prim = clipper.DisplayStart, vtx_i = elem_offset + clipper.DisplayStart*3; prim < clipper.DisplayEnd; prim++) From 996dfb21cf0a2be4b2e09356dc4df9c1ff47ce6c Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 21 Dec 2017 19:48:51 +0100 Subject: [PATCH 762/921] ImDrawList: Added ImDrawListFlags for AA settings. ImDrawList doesn't directly depends on GImGui anymore. --- TODO.txt | 4 +--- imgui.cpp | 16 +++++++++------- imgui.h | 10 +++++++++- imgui_demo.cpp | 2 +- imgui_draw.cpp | 9 +++------ 5 files changed, 23 insertions(+), 18 deletions(-) diff --git a/TODO.txt b/TODO.txt index 41270c4d9..c052aeb5c 100644 --- a/TODO.txt +++ b/TODO.txt @@ -30,12 +30,10 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i !- scrolling: allow immediately effective change of scroll after Begin() if we haven't appended items yet. - scrolling/clipping: separator on the initial position of a window is not visible (cursorpos.y <= clippos.y). (2017-08-20: can't repro) - - drawlist: move Font, FontSize, FontTexUvWhitePixel inside ImDrawList and make it self-contained (apart from drawing settings?) - - drawlist: make it easier to toggle AA per primitive, so we can use e.g. non-AA fill + AA borders more naturally - drawlist: end-user probably can't call Clear() directly because we expect a texture to be pushed in the stack. - drawlist: maintaining bounding box per command would allow to merge draw command when clipping isn't relied on (typical non-scrolling window or non-overflowing column would merge with previous command). - - drawlist: avoid passing null (-9999,+9999) rectangle to end-user, instead perhaps pass rectangle based on io.DisplaySize? - drawlist: primtiives/helpers to manipulate vertices post submission, so e.g. a quad/rect can be resized to fit later submitted content, _without_ using the ChannelSplit api + - drawlist: make it easier to toggle AA per primitive, so we can use e.g. non-AA fill + AA borders more naturally - drawlist: non-AA strokes have gaps between points (#593, #288), especially RenderCheckmark(). - drawlist: would be good to be able to deep copy a draw list (ImVector= op?). - drawlist/opt: AddRect() axis aligned pixel aligned (no-aa) could use 8 triangles instead of 16 and no normal calculation. diff --git a/imgui.cpp b/imgui.cpp index 1490d042d..ce3c09c03 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -213,7 +213,8 @@ Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. Also read releases logs https://github.com/ocornut/imgui/releases for more details. - - 2017/12/21 (1.53) - removed 'bool anti_aliased = true' final parameter of ImDrawList::AddPolyline() and ImDrawList::AddConvexPolyFilled(). Anti-aliasing is controlled via the regular style.AntiAliased flags. + - 2017/12/21 (1.53) - renamed style.AntiAliasedShapes to style.AntiAliasedFill for consistency and as a way to explicitly break code that manipulate those flag at runtime. You can now manipulate ImDrawList::Flags + - 2017/12/21 (1.53) - removed 'bool anti_aliased = true' final parameter of ImDrawList::AddPolyline() and ImDrawList::AddConvexPolyFilled(). Prefer manipulating ImDrawList::Flags. - 2017/12/14 (1.53) - using the ImGuiWindowFlags_NoScrollWithMouse flag on a child window forwards the mouse wheel event to the parent window, unless either ImGuiWindowFlags_NoInputs or ImGuiWindowFlags_NoScrollbar are also set. - 2017/12/13 (1.53) - renamed GetItemsLineHeightWithSpacing() to GetFrameHeightWithSpacing(). Kept redirection function (will obsolete). - 2017/12/13 (1.53) - obsoleted IsRootWindowFocused() in favor of using IsWindowFocused(ImGuiFocusedFlags_RootWindow). Kept redirection function (will obsolete). @@ -735,7 +736,7 @@ ImGuiStyle::ImGuiStyle() DisplayWindowPadding = ImVec2(22,22); // Window positions are clamped to be visible within the display area by at least this amount. Only covers regular windows. DisplaySafeAreaPadding = ImVec2(4,4); // If you cannot see the edge of your screen (e.g. on a TV) increase the safe area padding. Covers popups/tooltips as well regular windows. AntiAliasedLines = true; // Enable anti-aliasing on lines/borders. Disable if you are really short on CPU/GPU. - AntiAliasedShapes = true; // Enable anti-aliasing on filled shapes (rounded rectangles, circles, etc.) + AntiAliasedFill = true; // Enable anti-aliasing on filled shapes (rounded rectangles, circles, etc.) CurveTessellationTol = 1.25f; // Tessellation tolerance when using PathBezierCurveTo() without a specific number of segments. Decrease for highly tessellated curves (higher quality, more polygons), increase to reduce quality. ImGui::StyleColorsClassic(this); @@ -2290,6 +2291,7 @@ void ImGui::NewFrame() g.OverlayDrawList.Clear(); g.OverlayDrawList.PushTextureID(g.IO.Fonts->TexID); g.OverlayDrawList.PushClipRectFullScreen(); + g.OverlayDrawList.Flags = (g.Style.AntiAliasedLines ? ImDrawListFlags_AntiAliasedLines : 0) | (g.Style.AntiAliasedFill ? ImDrawListFlags_AntiAliasedFill : 0); // Mark rendering data as invalid to prevent user who may have a handle on it to use it g.RenderDrawData.Valid = false; @@ -4475,8 +4477,9 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->LastFrameActive = current_frame; window->IDStack.resize(1); - // Clear draw list, setup texture, outer clipping rectangle + // Setup draw list and outer clipping rectangle window->DrawList->Clear(); + window->DrawList->Flags = (g.Style.AntiAliasedLines ? ImDrawListFlags_AntiAliasedLines : 0) | (g.Style.AntiAliasedFill ? ImDrawListFlags_AntiAliasedFill : 0); window->DrawList->PushTextureID(g.Font->ContainerAtlas->TexID); ImRect fullscreen_rect(GetVisibleRect()); if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Popup)) @@ -11662,11 +11665,10 @@ void ImGui::ShowMetricsWindow(bool* p_open) ImGui::Selectable(buf, false); if (ImGui::IsItemHovered()) { - ImGuiStyle& style = ImGui::GetStyle(); - bool backup_aa_lines = style.AntiAliasedLines; - style.AntiAliasedLines = false; // Disable AA on triangle outlines at is more readable for very large and thin triangles. + ImDrawListFlags backup_flags = overlay_draw_list->Flags; + overlay_draw_list->Flags &= ~ImDrawListFlags_AntiAliasedLines; // Disable AA on triangle outlines at is more readable for very large and thin triangles. overlay_draw_list->AddPolyline(triangles_pos, 3, IM_COL32(255,255,0,255), true, 1.0f); - style.AntiAliasedLines = backup_aa_lines; + overlay_draw_list->Flags = backup_flags; } } ImGui::TreePop(); diff --git a/imgui.h b/imgui.h index 2185d0665..c313080ad 100644 --- a/imgui.h +++ b/imgui.h @@ -79,6 +79,7 @@ typedef int ImGuiKey; // enum: a key identifier (ImGui-side enum) typedef int ImGuiMouseCursor; // enum: a mouse cursor identifier // enum ImGuiMouseCursor_ typedef int ImGuiStyleVar; // enum: a variable identifier for styling // enum ImGuiStyleVar_ typedef int ImDrawCornerFlags; // flags: for ImDrawList::AddRect*() etc. // enum ImDrawCornerFlags_ +typedef int ImDrawListFlags; // flags: for ImDrawList // enum ImDrawListFlags_ typedef int ImGuiColorEditFlags; // flags: for ColorEdit*(), ColorPicker*() // enum ImGuiColorEditFlags_ typedef int ImGuiColumnsFlags; // flags: for *Columns*() // enum ImGuiColumnsFlags_ typedef int ImGuiDragDropFlags; // flags: for *DragDrop*() // enum ImGuiDragDropFlags_ @@ -855,7 +856,7 @@ struct ImGuiStyle ImVec2 DisplayWindowPadding; // Window positions are clamped to be visible within the display area by at least this amount. Only covers regular windows. ImVec2 DisplaySafeAreaPadding; // If you cannot see the edge of your screen (e.g. on a TV) increase the safe area padding. Covers popups/tooltips as well regular windows. bool AntiAliasedLines; // Enable anti-aliasing on lines/borders. Disable if you are really tight on CPU/GPU. - bool AntiAliasedShapes; // Enable anti-aliasing on filled shapes (rounded rectangles, circles, etc.) + bool AntiAliasedFill; // Enable anti-aliasing on filled shapes (rounded rectangles, circles, etc.) float CurveTessellationTol; // Tessellation tolerance when using PathBezierCurveTo() without a specific number of segments. Decrease for highly tessellated curves (higher quality, more polygons), increase to reduce quality. ImVec4 Colors[ImGuiCol_COUNT]; @@ -1372,6 +1373,12 @@ enum ImDrawCornerFlags_ ImDrawCornerFlags_All = 0xF // In your function calls you may use ~0 (= all bits sets) instead of ImDrawCornerFlags_All, as a convenience }; +enum ImDrawListFlags_ +{ + ImDrawListFlags_AntiAliasedLines = 1 << 0, + ImDrawListFlags_AntiAliasedFill = 1 << 1 +}; + // Draw command list // This is the low-level list of polygons that ImGui functions are filling. At the end of the frame, all command lists are passed to your ImGuiIO::RenderDrawListFn function for rendering. // Each ImGui window contains its own ImDrawList. You can use ImGui::GetWindowDrawList() to access the current window draw list and draw custom primitives. @@ -1386,6 +1393,7 @@ struct ImDrawList ImVector VtxBuffer; // Vertex buffer. // [Internal, used while building lists] + ImDrawListFlags Flags; // Flags, you may poke into these to adjust anti-aliasing settings per-primitive. const ImDrawListSharedData* _Data; // Pointer to shared draw data (you can use ImGui::GetDrawListSharedData() to get the one from current ImGui context) const char* _OwnerName; // Pointer to owner window's name for debugging unsigned int _VtxCurrentIdx; // [Internal] == VtxBuffer.Size diff --git a/imgui_demo.cpp b/imgui_demo.cpp index a2bf1be56..4f2705db1 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1983,7 +1983,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) if (ImGui::TreeNode("Rendering")) { ImGui::Checkbox("Anti-aliased lines", &style.AntiAliasedLines); ImGui::SameLine(); ShowHelpMarker("When disabling anti-aliasing lines, you'll probably want to disable borders in your style as well."); - ImGui::Checkbox("Anti-aliased shapes", &style.AntiAliasedShapes); + ImGui::Checkbox("Anti-aliased fill", &style.AntiAliasedFill); ImGui::PushItemWidth(100); ImGui::DragFloat("Curve Tessellation Tolerance", &style.CurveTessellationTol, 0.02f, 0.10f, FLT_MAX, NULL, 2.0f); if (style.CurveTessellationTol < 0.0f) style.CurveTessellationTol = 0.10f; diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 1136e274a..2ce3c0bdc 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -304,6 +304,7 @@ void ImDrawList::Clear() CmdBuffer.resize(0); IdxBuffer.resize(0); VtxBuffer.resize(0); + Flags = ImDrawListFlags_AntiAliasedLines | ImDrawListFlags_AntiAliasedFill; _VtxCurrentIdx = 0; _VtxWritePtr = NULL; _IdxWritePtr = NULL; @@ -598,15 +599,13 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32 return; const ImVec2 uv = _Data->TexUvWhitePixel; - bool anti_aliased = GImGui->Style.AntiAliasedLines; - //if (ImGui::GetIO().KeyCtrl) anti_aliased = false; // Debug int count = points_count; if (!closed) count = points_count-1; const bool thick_line = thickness > 1.0f; - if (anti_aliased) + if (Flags & ImDrawListFlags_AntiAliasedLines) { // Anti-aliased stroke const float AA_SIZE = 1.0f; @@ -776,10 +775,8 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32 void ImDrawList::AddConvexPolyFilled(const ImVec2* points, const int points_count, ImU32 col) { const ImVec2 uv = _Data->TexUvWhitePixel; - bool anti_aliased = GImGui->Style.AntiAliasedShapes; - //if (ImGui::GetIO().KeyCtrl) anti_aliased = false; // Debug - if (anti_aliased) + if (Flags & ImDrawListFlags_AntiAliasedFill) { // Anti-aliased Fill const float AA_SIZE = 1.0f; From c8c872c75380f4094665bbebd22089c445fcf9ee Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 21 Dec 2017 13:43:09 +0100 Subject: [PATCH 763/921] Internals: String functions uses size_t in their signature --- imgui.cpp | 18 +++++++++--------- imgui_internal.h | 8 ++++---- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index ce3c09c03..272859c32 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -911,17 +911,17 @@ int ImStricmp(const char* str1, const char* str2) return d; } -int ImStrnicmp(const char* str1, const char* str2, int count) +int ImStrnicmp(const char* str1, const char* str2, size_t count) { int d = 0; while (count > 0 && (d = toupper(*str2) - toupper(*str1)) == 0 && *str1) { str1++; str2++; count--; } return d; } -void ImStrncpy(char* dst, const char* src, int count) +void ImStrncpy(char* dst, const char* src, size_t count) { if (count < 1) return; - strncpy(dst, src, (size_t)count); + strncpy(dst, src, count); dst[count-1] = 0; } @@ -992,7 +992,7 @@ static const char* ImAtoi(const char* src, int* output) // Ideally we would test for only one of those limits at runtime depending on the behavior the vsnprintf(), but trying to deduct it at compile time sounds like a pandora can of worm. // B) When buf==NULL vsnprintf() will return the output size. #ifndef IMGUI_DISABLE_FORMAT_STRING_FUNCTIONS -int ImFormatString(char* buf, int buf_size, const char* fmt, ...) +int ImFormatString(char* buf, size_t buf_size, const char* fmt, ...) { va_list args; va_start(args, fmt); @@ -1000,19 +1000,19 @@ int ImFormatString(char* buf, int buf_size, const char* fmt, ...) va_end(args); if (buf == NULL) return w; - if (w == -1 || w >= buf_size) - w = buf_size - 1; + if (w == -1 || w >= (int)buf_size) + w = (int)buf_size - 1; buf[w] = 0; return w; } -int ImFormatStringV(char* buf, int buf_size, const char* fmt, va_list args) +int ImFormatStringV(char* buf, size_t buf_size, const char* fmt, va_list args) { int w = vsnprintf(buf, buf_size, fmt, args); if (buf == NULL) return w; - if (w == -1 || w >= buf_size) - w = buf_size - 1; + if (w == -1 || w >= (int)buf_size) + w = (int)buf_size - 1; buf[w] = 0; return w; } diff --git a/imgui_internal.h b/imgui_internal.h index ca1563671..060b20041 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -103,15 +103,15 @@ IMGUI_API void ImTriangleBarycentricCoords(const ImVec2& a, const ImVec // Helpers: String IMGUI_API int ImStricmp(const char* str1, const char* str2); -IMGUI_API int ImStrnicmp(const char* str1, const char* str2, int count); -IMGUI_API void ImStrncpy(char* dst, const char* src, int count); +IMGUI_API int ImStrnicmp(const char* str1, const char* str2, size_t count); +IMGUI_API void ImStrncpy(char* dst, const char* src, size_t count); IMGUI_API char* ImStrdup(const char* str); IMGUI_API char* ImStrchrRange(const char* str_begin, const char* str_end, char c); IMGUI_API int ImStrlenW(const ImWchar* str); IMGUI_API const ImWchar*ImStrbolW(const ImWchar* buf_mid_line, const ImWchar* buf_begin); // Find beginning-of-line IMGUI_API const char* ImStristr(const char* haystack, const char* haystack_end, const char* needle, const char* needle_end); -IMGUI_API int ImFormatString(char* buf, int buf_size, const char* fmt, ...) IM_FMTARGS(3); -IMGUI_API int ImFormatStringV(char* buf, int buf_size, const char* fmt, va_list args) IM_FMTLIST(3); +IMGUI_API int ImFormatString(char* buf, size_t buf_size, const char* fmt, ...) IM_FMTARGS(3); +IMGUI_API int ImFormatStringV(char* buf, size_t buf_size, const char* fmt, va_list args) IM_FMTLIST(3); // Helpers: Math // We are keeping those not leaking to the user by default, in the case the user has implicit cast operators between ImVec2 and its own types (when IM_VEC2_CLASS_EXTRA is defined) From 8d21ee56d2a4ae50a5ca4c84442280251d945e84 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 22 Dec 2017 20:19:48 +0100 Subject: [PATCH 764/921] ImDrawList, Font: Fixed bug introduced in 531c11d5c72890f324c9734ef5c860408b8a7f3d (#1519) --- imgui.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 272859c32..943b63ecc 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1922,7 +1922,7 @@ static void SetCurrentWindow(ImGuiWindow* window) ImGuiContext& g = *GImGui; g.CurrentWindow = window; if (window) - g.FontSize = window->CalcFontSize(); + g.FontSize = g.DrawListSharedData.FontSize = window->CalcFontSize(); } void ImGui::SetActiveID(ImGuiID id, ImGuiWindow* window) @@ -5843,7 +5843,7 @@ void ImGui::SetWindowFontScale(float scale) ImGuiContext& g = *GImGui; ImGuiWindow* window = GetCurrentWindow(); window->FontWindowScale = scale; - g.FontSize = window->CalcFontSize(); + g.FontSize = g.DrawListSharedData.FontSize = window->CalcFontSize(); } // User generally sees positions in window coordinates. Internally we store CursorPos in absolute screen coordinates because it is more convenient. From e1a103b251f219d567c60f8cffda100a057523c1 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 22 Dec 2017 13:41:41 +0100 Subject: [PATCH 765/921] Drag and Drop: Disable tracking mouse button ownership when an external drag source is active, to make it easier to achieve drag and drop over multiple OS windows. (#143) --- imgui.cpp | 5 +++-- imgui_demo.cpp | 5 ++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 943b63ecc..81a37d7ad 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2456,8 +2456,9 @@ void ImGui::NewFrame() g.OsImePosRequest = ImVec2(1.0f, 1.0f); // OS Input Method Editor showing on top-left of our window by default // If mouse was first clicked outside of ImGui bounds we also cancel out hovering. - // FIXME: For patterns of drag and drop between "application" and "imgui" we may need to rework/remove this test (first committed 311c0ca9 on 2015/02) - if (!mouse_avail_to_imgui) + // FIXME: For patterns of drag and drop across OS windows, we may need to rework/remove this test (first committed 311c0ca9 on 2015/02) + bool mouse_dragging_extern_payload = g.DragDropActive && (g.DragDropSourceFlags & ImGuiDragDropFlags_SourceExtern) != 0; + if (!mouse_avail_to_imgui && !mouse_dragging_extern_payload) g.HoveredWindow = g.HoveredRootWindow = NULL; // Scale & Scrolling diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 4f2705db1..fb0cff59f 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1734,7 +1734,10 @@ void ImGui::ShowTestWindow(bool* p_open) if (ImGui::TreeNode("Keyboard & Mouse State")) { - ImGui::Text("Mouse pos: (%g, %g)", io.MousePos.x, io.MousePos.y); + if (ImGui::IsMousePosValid()) + ImGui::Text("Mouse pos: (%g, %g)", io.MousePos.x, io.MousePos.y); + else + ImGui::Text("Mouse pos: "); ImGui::Text("Mouse down:"); for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) if (io.MouseDownDuration[i] >= 0.0f) { ImGui::SameLine(); ImGui::Text("b%d (%.02f secs)", i, io.MouseDownDuration[i]); } ImGui::Text("Mouse clicked:"); for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) if (ImGui::IsMouseClicked(i)) { ImGui::SameLine(); ImGui::Text("b%d", i); } ImGui::Text("Mouse dbl-clicked:"); for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) if (ImGui::IsMouseDoubleClicked(i)) { ImGui::SameLine(); ImGui::Text("b%d", i); } From 471bcf8b5e5caa341293fb0b0e79daf19357189b Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 22 Dec 2017 19:35:58 +0100 Subject: [PATCH 766/921] Columns: Fixed dragging when using a same of columns multiple times in the frame. (#125) --- imgui.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 81a37d7ad..2a1f5e8f8 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -10867,6 +10867,8 @@ static float PixelsToOffsetNorm(const ImGuiColumnsSet* columns, float offset) return (offset - columns->MinX) / (columns->MaxX - columns->MinX); } +static inline float GetColumnsRectHalfWidth() { return 4.0f; } + static float GetDraggedColumnOffset(ImGuiColumnsSet* columns, int column_index) { // Active (dragged) column always follow mouse. The reason we need this is that dragging a column to the right edge of an auto-resizing @@ -10876,7 +10878,7 @@ static float GetDraggedColumnOffset(ImGuiColumnsSet* columns, int column_index) IM_ASSERT(column_index > 0); // We cannot drag column 0. If you get this assert you may have a conflict between the ID of your columns and another widgets. IM_ASSERT(g.ActiveId == columns->ID + ImGuiID(column_index)); - float x = g.IO.MousePos.x - g.ActiveIdClickOffset.x - window->Pos.x; + float x = g.IO.MousePos.x - g.ActiveIdClickOffset.x + GetColumnsRectHalfWidth() - window->Pos.x; x = ImMax(x, ImGui::GetColumnOffset(column_index - 1) + g.Style.ColumnsMinSpacing); if ((columns->Flags & ImGuiColumnsFlags_NoPreserveWidths)) x = ImMin(x, ImGui::GetColumnOffset(column_index + 1) - g.Style.ColumnsMinSpacing); @@ -11086,7 +11088,7 @@ void ImGui::EndColumns() { float x = window->Pos.x + GetColumnOffset(n); const ImGuiID column_id = columns->ID + ImGuiID(n); - const float column_hw = 4.0f; // Half-width for interaction + const float column_hw = GetColumnsRectHalfWidth(); // Half-width for interaction const ImRect column_rect(ImVec2(x - column_hw, y1), ImVec2(x + column_hw, y2)); KeepAliveID(column_id); if (IsClippedEx(column_rect, column_id, false)) @@ -11098,8 +11100,6 @@ void ImGui::EndColumns() ButtonBehavior(column_rect, column_id, &hovered, &held); if (hovered || held) g.MouseCursor = ImGuiMouseCursor_ResizeEW; - if (held && g.ActiveIdIsJustActivated) - g.ActiveIdClickOffset.x -= column_hw; // Store from center of column line (we used a 8 wide rect for columns clicking). This is used by GetDraggedColumnOffset(). if (held && !(columns->Columns[n].Flags & ImGuiColumnsFlags_NoResize)) dragging_column = n; } From 46dcd9aa50148a0904f084713f38a0c53b1980d0 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 22 Dec 2017 19:45:15 +0100 Subject: [PATCH 767/921] Columns: Made PixelsToOffsetNorm() properly symetrical to OffsetNormToPixels() (#125) --- imgui.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 2a1f5e8f8..dd580538c 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -10864,7 +10864,7 @@ static float OffsetNormToPixels(const ImGuiColumnsSet* columns, float offset_nor static float PixelsToOffsetNorm(const ImGuiColumnsSet* columns, float offset) { - return (offset - columns->MinX) / (columns->MaxX - columns->MinX); + return offset / (columns->MaxX - columns->MinX); } static inline float GetColumnsRectHalfWidth() { return 4.0f; } @@ -10951,7 +10951,7 @@ void ImGui::SetColumnOffset(int column_index, float offset) if (!(columns->Flags & ImGuiColumnsFlags_NoForceWithinWindow)) offset = ImMin(offset, columns->MaxX - g.Style.ColumnsMinSpacing * (columns->Count - column_index)); - columns->Columns[column_index].OffsetNorm = PixelsToOffsetNorm(columns, offset); + columns->Columns[column_index].OffsetNorm = PixelsToOffsetNorm(columns, offset - columns->MinX); if (preserve_width) SetColumnOffset(column_index + 1, offset + ImMax(g.Style.ColumnsMinSpacing, width)); @@ -11015,7 +11015,7 @@ void ImGui::BeginColumns(const char* str_id, int columns_count, ImGuiColumnsFlag // Set state for first column const float content_region_width = (window->SizeContentsExplicit.x != 0.0f) ? (window->SizeContentsExplicit.x) : (window->Size.x -window->ScrollbarSizes.x); columns->MinX = window->DC.IndentX - g.Style.ItemSpacing.x; // Lock our horizontal range - //column->ColumnsMaxX = content_region_width - window->Scroll.x -((window->Flags & ImGuiWindowFlags_NoScrollbar) ? 0 : g.Style.ScrollbarSize);// - window->WindowPadding().x; + //column->MaxX = content_region_width - window->Scroll.x - ((window->Flags & ImGuiWindowFlags_NoScrollbar) ? 0 : g.Style.ScrollbarSize);// - window->WindowPadding().x; columns->MaxX = content_region_width - window->Scroll.x; columns->StartPosY = window->DC.CursorPos.y; columns->StartMaxPosX = window->DC.CursorMaxPos.x; @@ -11043,7 +11043,7 @@ void ImGui::BeginColumns(const char* str_id, int columns_count, ImGuiColumnsFlag ImGuiColumnData* column = &columns->Columns[n]; float t = column->OffsetNorm; if (!(columns->Flags & ImGuiColumnsFlags_NoForceWithinWindow)) - t = ImMin(t, PixelsToOffsetNorm(columns, columns->MaxX - g.Style.ColumnsMinSpacing * (columns->Count - n))); + t = ImMin(t, PixelsToOffsetNorm(columns, (columns->MaxX - columns->MinX) - g.Style.ColumnsMinSpacing * (columns->Count - n))); column->OffsetNorm = t; if (n == columns_count) From cf9b893841ba8e9e380332825605735423d3cab0 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 23 Dec 2017 13:40:01 +0100 Subject: [PATCH 768/921] Examples: Added null_example/ which is helpful for quick testing on multiple compilers/settings without relyong on graphics library. --- examples/null_example/build_win32.bat | 3 +++ examples/null_example/main.cpp | 33 +++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 examples/null_example/build_win32.bat create mode 100644 examples/null_example/main.cpp diff --git a/examples/null_example/build_win32.bat b/examples/null_example/build_win32.bat new file mode 100644 index 000000000..7bb78232a --- /dev/null +++ b/examples/null_example/build_win32.bat @@ -0,0 +1,3 @@ +@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. +mkdir Debug +cl /nologo /Zi /MD /I ..\.. *.cpp ..\..\*.cpp /FeDebug/null_example.exe /FoDebug/ /link gdi32.lib shell32.lib diff --git a/examples/null_example/main.cpp b/examples/null_example/main.cpp new file mode 100644 index 000000000..b12f75c96 --- /dev/null +++ b/examples/null_example/main.cpp @@ -0,0 +1,33 @@ +// ImGui - null/dummy example application (compile and link imgui with no inputs, no outputs) +#include +#include + +int main(int, char**) +{ + ImGuiIO& io = ImGui::GetIO(); + + // Build atlas + unsigned char* tex_pixels = NULL; + int tex_w, tex_h; + io.Fonts->GetTexDataAsRGBA32(&tex_pixels, &tex_w, &tex_h); + + for (int n = 0; n < 50; n++) + { + printf("NewFrame() %d\n", n); + io.DisplaySize = ImVec2(1920, 1080); + io.DeltaTime = 1.0f / 60.0f; + ImGui::NewFrame(); + + static float f = 0.0f; + ImGui::Text("Hello, world!"); + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / io.Framerate, io.Framerate); + ImGui::ShowTestWindow(NULL); + + ImGui::Render(); + } + + printf("Shutdown()\n"); + ImGui::Shutdown(); + return 0; +} From 1f26652944d0a04dc9716578dcddef6ed3b67de1 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 23 Dec 2017 14:07:03 +0100 Subject: [PATCH 769/921] Various zealous warning fixes (thanks Clang). --- imgui.cpp | 9 ++++----- imgui.h | 2 +- imgui_draw.cpp | 5 ++--- imgui_internal.h | 2 +- 4 files changed, 8 insertions(+), 10 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index dd580538c..26c3b698e 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -586,7 +586,6 @@ #include "imgui.h" #define IMGUI_DEFINE_MATH_OPERATORS -#define IMGUI_DEFINE_PLACEMENT_NEW #include "imgui_internal.h" #include // toupper, isprint @@ -3272,16 +3271,16 @@ void ImGui::RenderTriangle(ImVec2 p_min, ImGuiDir dir, float scale) switch (dir) { case ImGuiDir_Up: - r = -r; // ...fall through, no break! case ImGuiDir_Down: + if (dir == ImGuiDir_Up) r = -r; center.y -= r * 0.25f; a = ImVec2(0,1) * r; b = ImVec2(-0.866f,-0.5f) * r; c = ImVec2(+0.866f,-0.5f) * r; break; case ImGuiDir_Left: - r = -r; // ...fall through, no break! case ImGuiDir_Right: + if (dir == ImGuiDir_Left) r = -r; center.x -= r * 0.25f; a = ImVec2(1,0) * r; b = ImVec2(-0.500f,+0.866f) * r; @@ -10254,7 +10253,7 @@ static void RenderArrow(ImDrawList* draw_list, ImVec2 pos, ImVec2 half_sz, ImGui case ImGuiDir_Right: draw_list->AddTriangleFilled(ImVec2(pos.x - half_sz.x, pos.y + half_sz.y), ImVec2(pos.x - half_sz.x, pos.y - half_sz.y), pos, col); return; case ImGuiDir_Up: draw_list->AddTriangleFilled(ImVec2(pos.x + half_sz.x, pos.y + half_sz.y), ImVec2(pos.x - half_sz.x, pos.y + half_sz.y), pos, col); return; case ImGuiDir_Down: draw_list->AddTriangleFilled(ImVec2(pos.x - half_sz.x, pos.y - half_sz.y), ImVec2(pos.x + half_sz.x, pos.y - half_sz.y), pos, col); return; - default: return; // Fix warning for ImGuiDir_None + default: break; // Fix warning for ImGuiDir_None } } @@ -11491,7 +11490,7 @@ void ImGui::EndDragDropTarget() #if defined(_WIN32) && !defined(_WINDOWS_) && (!defined(IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS) || !defined(IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS)) #undef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN -#include +#include #endif // Win32 API clipboard implementation diff --git a/imgui.h b/imgui.h index c313080ad..11213d69c 100644 --- a/imgui.h +++ b/imgui.h @@ -622,7 +622,7 @@ enum ImGuiFocusedFlags_ { ImGuiFocusedFlags_ChildWindows = 1 << 0, // IsWindowFocused(): Return true if any children of the window is focused ImGuiFocusedFlags_RootWindow = 1 << 1, // IsWindowFocused(): Test from root window (top most parent of the current hierarchy) - ImGuiFocusedFlags_RootAndChildWindows = ImGuiFocusedFlags_RootWindow | ImGuiFocusedFlags_ChildWindows, + ImGuiFocusedFlags_RootAndChildWindows = ImGuiFocusedFlags_RootWindow | ImGuiFocusedFlags_ChildWindows }; // Flags for ImGui::IsItemHovered(), ImGui::IsWindowHovered() diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 2ce3c0bdc..48500c7ce 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -15,7 +15,6 @@ #include "imgui.h" #define IMGUI_DEFINE_MATH_OPERATORS -#define IMGUI_DEFINE_PLACEMENT_NEW #include "imgui_internal.h" #include // vsnprintf, sscanf, printf @@ -1254,8 +1253,8 @@ void ImGui::ShadeVertsLinearUV(ImDrawVert* vert_start, ImDrawVert* vert_end, con const ImVec2 size = b - a; const ImVec2 uv_size = uv_b - uv_a; const ImVec2 scale = ImVec2( - size.x ? (uv_size.x / size.x) : 0.0f, - size.y ? (uv_size.y / size.y) : 0.0f); + size.x != 0.0f ? (uv_size.x / size.x) : 0.0f, + size.y != 0.0f ? (uv_size.y / size.y) : 0.0f); if (clamp) { diff --git a/imgui_internal.h b/imgui_internal.h index 060b20041..1e0f8ae1f 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -230,7 +230,7 @@ enum ImGuiAxis { ImGuiAxis_None = -1, ImGuiAxis_X = 0, - ImGuiAxis_Y = 1, + ImGuiAxis_Y = 1 }; enum ImGuiPlotType From b263bc568931b7065926a06e6a293fc05279c6e5 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 23 Dec 2017 14:07:27 +0100 Subject: [PATCH 770/921] Examples: DirectX: Using IM_ARRAYSIZE() --- examples/directx10_example/imgui_impl_dx10.cpp | 2 +- examples/directx11_example/imgui_impl_dx11.cpp | 2 +- examples/directx9_example/imgui_impl_dx9.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/directx10_example/imgui_impl_dx10.cpp b/examples/directx10_example/imgui_impl_dx10.cpp index 4670f0537..59152673b 100644 --- a/examples/directx10_example/imgui_impl_dx10.cpp +++ b/examples/directx10_example/imgui_impl_dx10.cpp @@ -228,7 +228,7 @@ void ImGui_ImplDX10_RenderDrawLists(ImDrawData* draw_data) static bool IsAnyMouseButtonDown() { ImGuiIO& io = ImGui::GetIO(); - for (int n = 0; n < ARRAYSIZE(io.MouseDown); n++) + for (int n = 0; n < IM_ARRAYSIZE(io.MouseDown); n++) if (io.MouseDown[n]) return true; return false; diff --git a/examples/directx11_example/imgui_impl_dx11.cpp b/examples/directx11_example/imgui_impl_dx11.cpp index df02577bb..af6e54f49 100644 --- a/examples/directx11_example/imgui_impl_dx11.cpp +++ b/examples/directx11_example/imgui_impl_dx11.cpp @@ -235,7 +235,7 @@ void ImGui_ImplDX11_RenderDrawLists(ImDrawData* draw_data) static bool IsAnyMouseButtonDown() { ImGuiIO& io = ImGui::GetIO(); - for (int n = 0; n < ARRAYSIZE(io.MouseDown); n++) + for (int n = 0; n < IM_ARRAYSIZE(io.MouseDown); n++) if (io.MouseDown[n]) return true; return false; diff --git a/examples/directx9_example/imgui_impl_dx9.cpp b/examples/directx9_example/imgui_impl_dx9.cpp index 24f53ba3a..484e84cde 100644 --- a/examples/directx9_example/imgui_impl_dx9.cpp +++ b/examples/directx9_example/imgui_impl_dx9.cpp @@ -174,7 +174,7 @@ void ImGui_ImplDX9_RenderDrawLists(ImDrawData* draw_data) static bool IsAnyMouseButtonDown() { ImGuiIO& io = ImGui::GetIO(); - for (int n = 0; n < ARRAYSIZE(io.MouseDown); n++) + for (int n = 0; n < IM_ARRAYSIZE(io.MouseDown); n++) if (io.MouseDown[n]) return true; return false; From 6172e932728a0fa629d910c1a1534d66a59e386a Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 23 Dec 2017 14:49:23 +0100 Subject: [PATCH 771/921] ImVector: Added assignments and = operators + comments. --- imgui.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/imgui.h b/imgui.h index 11213d69c..25c8721a7 100644 --- a/imgui.h +++ b/imgui.h @@ -1005,7 +1005,7 @@ namespace ImGui //----------------------------------------------------------------------------- // 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). -// 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! +// Our implementation does NOT call C++ constructors/destructors. This is intentional and we do not require it. Do not use this class as a straight std::vector replacement in your code! template class ImVector { @@ -1020,6 +1020,8 @@ public: ImVector() { Size = Capacity = 0; Data = NULL; } ~ImVector() { if (Data) ImGui::MemFree(Data); } + ImVector(const ImVector& rhs) { Size = Capacity = 0; Data = NULL; if (rhs.Size) { resize(rhs.Size); memcpy(Data, rhs.Data, (size_t)rhs.Size * sizeof(T)); } } + ImVector& operator=(const ImVector& rhs) { resize(rhs.Size); if (rhs.Size) memcpy(Data, rhs.Data, (size_t)rhs.Size * sizeof(T)); return *this; } inline bool empty() const { return Size == 0; } inline int size() const { return Size; } From 8e8b5498f74715cf2caa2feaf28657c438ff7b36 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 23 Dec 2017 14:51:28 +0100 Subject: [PATCH 772/921] ImVector: insert() uses grow_capacity() - had inconsistent resize policy --- imgui.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.h b/imgui.h index 25c8721a7..35bfb60e2 100644 --- a/imgui.h +++ b/imgui.h @@ -1061,7 +1061,7 @@ public: inline void push_front(const value_type& v) { if (Size == 0) push_back(v); else insert(Data, v); } inline iterator erase(const_iterator it) { IM_ASSERT(it >= Data && it < Data+Size); const ptrdiff_t off = it - Data; memmove(Data + off, Data + off + 1, ((size_t)Size - (size_t)off - 1) * sizeof(value_type)); Size--; return Data + off; } - inline iterator insert(const_iterator it, const value_type& v) { IM_ASSERT(it >= Data && it <= Data+Size); const ptrdiff_t off = it - Data; if (Size == Capacity) reserve(Capacity ? Capacity * 2 : 4); if (off < (int)Size) memmove(Data + off + 1, Data + off, ((size_t)Size - (size_t)off) * sizeof(value_type)); Data[off] = v; Size++; return Data + off; } + inline iterator insert(const_iterator it, const value_type& v) { IM_ASSERT(it >= Data && it <= Data+Size); const ptrdiff_t off = it - Data; if (Size == Capacity) reserve(_grow_capacity(Size + 1)); if (off < (int)Size) memmove(Data + off + 1, Data + off, ((size_t)Size - (size_t)off) * sizeof(value_type)); Data[off] = v; Size++; return Data + off; } inline bool contains(const value_type& v) const { const T* data = Data; const T* data_end = Data + Size; while (data < data_end) if (*data++ == v) return true; return false; } }; From 69879dd4f3e25c2d64dff233ef4bda32e6514237 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 23 Dec 2017 14:51:36 +0100 Subject: [PATCH 773/921] ImVector: Spacing. --- imgui.h | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/imgui.h b/imgui.h index 35bfb60e2..a644337dc 100644 --- a/imgui.h +++ b/imgui.h @@ -1018,10 +1018,10 @@ public: typedef value_type* iterator; typedef const value_type* const_iterator; - ImVector() { Size = Capacity = 0; Data = NULL; } - ~ImVector() { if (Data) ImGui::MemFree(Data); } - ImVector(const ImVector& rhs) { Size = Capacity = 0; Data = NULL; if (rhs.Size) { resize(rhs.Size); memcpy(Data, rhs.Data, (size_t)rhs.Size * sizeof(T)); } } - ImVector& operator=(const ImVector& rhs) { resize(rhs.Size); if (rhs.Size) memcpy(Data, rhs.Data, (size_t)rhs.Size * sizeof(T)); return *this; } + inline ImVector() { Size = Capacity = 0; Data = NULL; } + inline ~ImVector() { if (Data) ImGui::MemFree(Data); } + inline ImVector(const ImVector& rhs) { Size = Capacity = 0; Data = NULL; if (rhs.Size) { resize(rhs.Size); memcpy(Data, rhs.Data, (size_t)rhs.Size * sizeof(T)); } } + inline ImVector& operator=(const ImVector& rhs) { resize(rhs.Size); if (rhs.Size) memcpy(Data, rhs.Data, (size_t)rhs.Size * sizeof(T)); return *this; } inline bool empty() const { return Size == 0; } inline int size() const { return Size; } @@ -1037,8 +1037,8 @@ public: inline const_iterator end() const { return Data + Size; } inline value_type& front() { IM_ASSERT(Size > 0); return Data[0]; } inline const value_type& front() const { IM_ASSERT(Size > 0); return Data[0]; } - inline value_type& back() { IM_ASSERT(Size > 0); return Data[Size-1]; } - inline const value_type& back() const { IM_ASSERT(Size > 0); return Data[Size-1]; } + inline value_type& back() { IM_ASSERT(Size > 0); return Data[Size - 1]; } + inline const value_type& back() const { IM_ASSERT(Size > 0); return Data[Size - 1]; } inline void swap(ImVector& rhs) { int rhs_size = rhs.Size; rhs.Size = Size; Size = rhs_size; int rhs_cap = rhs.Capacity; rhs.Capacity = Capacity; Capacity = rhs_cap; value_type* rhs_data = rhs.Data; rhs.Data = Data; Data = rhs_data; } inline int _grow_capacity(int size) const { int new_capacity = Capacity ? (Capacity + Capacity/2) : 8; return new_capacity > size ? new_capacity : size; } @@ -1047,7 +1047,8 @@ public: inline void resize(int new_size, const T& v){ if (new_size > Capacity) reserve(_grow_capacity(new_size)); if (new_size > Size) for (int n = Size; n < new_size; n++) Data[n] = v; Size = new_size; } inline void reserve(int new_capacity) { - if (new_capacity <= Capacity) return; + if (new_capacity <= Capacity) + return; T* new_data = (value_type*)ImGui::MemAlloc((size_t)new_capacity * sizeof(T)); if (Data) memcpy(new_data, Data, (size_t)Size * sizeof(T)); @@ -1056,7 +1057,7 @@ public: Capacity = new_capacity; } - inline void push_back(const value_type& v) { if (Size == Capacity) reserve(_grow_capacity(Size+1)); Data[Size++] = v; } + inline void push_back(const value_type& v) { if (Size == Capacity) reserve(_grow_capacity(Size + 1)); Data[Size++] = v; } inline void pop_back() { IM_ASSERT(Size > 0); Size--; } inline void push_front(const value_type& v) { if (Size == 0) push_back(v); else insert(Data, v); } From 53b24ff79afd2b39d67580c77a68fb7a004def66 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 23 Dec 2017 15:02:36 +0100 Subject: [PATCH 774/921] Removed reliance on ImU64 type for the ImDrawList assert. (#1184) --- imgui.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 26c3b698e..147db31d4 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2846,15 +2846,17 @@ static void AddDrawListToRenderList(ImVector& out_render_list, ImDr IM_ASSERT(draw_list->IdxBuffer.Size == 0 || draw_list->_IdxWritePtr == draw_list->IdxBuffer.Data + draw_list->IdxBuffer.Size); IM_ASSERT((int)draw_list->_VtxCurrentIdx == draw_list->VtxBuffer.Size); - // Check that draw_list doesn't use more vertices than indexable in a single draw call (default ImDrawIdx = unsigned short = 2 bytes = 64K vertices per window) - // If this assert triggers because you are drawing lots of stuff manually, you can: - // A) Add '#define ImDrawIdx unsigned int' in imconfig.h to set the index size to 4 bytes. You'll need to handle the 4-bytes indices to your renderer. - // For example, the OpenGL example code detect index size at compile-time by doing: - // 'glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer_offset);' + // Check that draw_list doesn't use more vertices than indexable in a single draw call (default ImDrawIdx = unsigned short = 2 bytes = 64K vertices per ImDrawList = per window) + // If this assert triggers because you are drawing lots of stuff manually: + // A) Make sure you are coarse clipping, because ImDrawList let all your vertices pass. You can use thre Metrics window to inspect draw list contents. + // B) If you need/want meshes with more than 64K vertices, uncomment the '#define ImDrawIdx unsigned int' line in imconfig.h to set the index size to 4 bytes. + // You'll need to handle the 4-bytes indices to your renderer. For example, the OpenGL example code detect index size at compile-time by doing: + // glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer_offset); // Your own engine or render API may use different parameters or function calls to specify index sizes. 2 and 4 bytes indices are generally supported by most API. - // B) If for some reason you cannot use 4 bytes indices or don't want to, a workaround is to call BeginChild()/EndChild() before reaching the 64K limit to split your draw commands in multiple draw lists. - IM_ASSERT(((ImU64)draw_list->_VtxCurrentIdx >> (sizeof(ImDrawIdx)*8)) == 0); // Too many vertices in same ImDrawList. See comment above. - + // C) If for some reason you cannot use 4 bytes indices or don't want to, a workaround is to call BeginChild()/EndChild() before reaching the 64K limit to split your draw commands in multiple draw lists. + if (sizeof(ImDrawIdx) == 2) + IM_ASSERT(draw_list->_VtxCurrentIdx < (1 << 16) && "Too many vertices in ImDrawList using 16-bit indices. Read comment above"); + out_render_list.push_back(draw_list); GImGui->IO.MetricsRenderVertices += draw_list->VtxBuffer.Size; GImGui->IO.MetricsRenderIndices += draw_list->IdxBuffer.Size; From 983d8f5f8ea6c8deac1f8f60389d4b1c8549e9c7 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 23 Dec 2017 15:15:27 +0100 Subject: [PATCH 775/921] Various zealous warning fixes (Clang). --- imgui.cpp | 5 +++-- imgui_demo.cpp | 3 ++- imgui_draw.cpp | 2 ++ 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 147db31d4..649d2e765 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3288,7 +3288,8 @@ void ImGui::RenderTriangle(ImVec2 p_min, ImGuiDir dir, float scale) b = ImVec2(-0.500f,+0.866f) * r; c = ImVec2(-0.500f,-0.866f) * r; break; - default: + case ImGuiDir_None: + case ImGuiDir_Count_: IM_ASSERT(0); break; } @@ -10255,7 +10256,7 @@ static void RenderArrow(ImDrawList* draw_list, ImVec2 pos, ImVec2 half_sz, ImGui case ImGuiDir_Right: draw_list->AddTriangleFilled(ImVec2(pos.x - half_sz.x, pos.y + half_sz.y), ImVec2(pos.x - half_sz.x, pos.y - half_sz.y), pos, col); return; case ImGuiDir_Up: draw_list->AddTriangleFilled(ImVec2(pos.x + half_sz.x, pos.y + half_sz.y), ImVec2(pos.x - half_sz.x, pos.y + half_sz.y), pos, col); return; case ImGuiDir_Down: draw_list->AddTriangleFilled(ImVec2(pos.x - half_sz.x, pos.y - half_sz.y), ImVec2(pos.x + half_sz.x, pos.y - half_sz.y), pos, col); return; - default: break; // Fix warning for ImGuiDir_None + case ImGuiDir_None: case ImGuiDir_Count_: break; // Fix warnings } } diff --git a/imgui_demo.cpp b/imgui_demo.cpp index fb0cff59f..0624bdd3e 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1304,7 +1304,8 @@ void ImGui::ShowTestWindow(bool* p_open) if (n > 0) ImGui::SameLine(); ImGui::PushID(n + line * 1000); char num_buf[16]; - const char* label = (!(n%15)) ? "FizzBuzz" : (!(n%3)) ? "Fizz" : (!(n%5)) ? "Buzz" : (sprintf(num_buf, "%d", n), num_buf); + sprintf(num_buf, "%d", n); + const char* label = (!(n%15)) ? "FizzBuzz" : (!(n%3)) ? "Fizz" : (!(n%5)) ? "Buzz" : num_buf; float hue = n*0.05f; ImGui::PushStyleColor(ImGuiCol_Button, (ImVec4)ImColor::HSV(hue, 0.6f, 0.6f)); ImGui::PushStyleColor(ImGuiCol_ButtonHovered, (ImVec4)ImColor::HSV(hue, 0.7f, 0.7f)); diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 48500c7ce..02cf42cca 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -42,6 +42,7 @@ #pragma clang diagnostic ignored "-Wfloat-equal" // warning : comparing floating point with == or != is unsafe // storing and comparing against same constants ok. #pragma clang diagnostic ignored "-Wglobal-constructors" // warning : declaration requires a global destructor // similar to above, not sure what the exact difference it. #pragma clang diagnostic ignored "-Wsign-conversion" // warning : implicit conversion changes signedness // +#pragma clang diagnostic ignored "-Wcomma" // warning : possible misuse of comma operator here // #if __has_warning("-Wreserved-id-macro") #pragma clang diagnostic ignored "-Wreserved-id-macro" // warning : macro name is a reserved identifier // #endif @@ -77,6 +78,7 @@ namespace IMGUI_STB_NAMESPACE #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-function" #pragma clang diagnostic ignored "-Wmissing-prototypes" +#pragma clang diagnostic ignored "-Wimplicit-fallthrough" #endif #ifdef __GNUC__ From a5739a0aa30f35271213157b994a0fcb0cd773b9 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 23 Dec 2017 15:19:48 +0100 Subject: [PATCH 776/921] Fixed warning with Clang+MSVC using __int64 to define the helper ImU64 type (#1184) --- imgui.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.h b/imgui.h index a644337dc..de9177c94 100644 --- a/imgui.h +++ b/imgui.h @@ -92,7 +92,7 @@ typedef int ImGuiTreeNodeFlags; // flags: for TreeNode*(),CollapsingHeader() typedef int ImGuiWindowFlags; // flags: for Begin*() // enum ImGuiWindowFlags_ typedef int (*ImGuiTextEditCallback)(ImGuiTextEditCallbackData *data); typedef void (*ImGuiSizeConstraintCallback)(ImGuiSizeConstraintCallbackData* data); -#ifdef _MSC_VER +#if defined(_MSC_VER) && !defined(__clang__) typedef unsigned __int64 ImU64; // 64-bit unsigned integer #else typedef unsigned long long ImU64; // 64-bit unsigned integer From 9cda86d55a80c9f032af84f657b9fe8e6c7f3f52 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 23 Dec 2017 16:24:33 +0100 Subject: [PATCH 777/921] Internals: Added IM_NEW, IM_DELETE helper macros (#1517, #484, #504) --- imgui.cpp | 28 ++++++++-------------------- imgui_draw.cpp | 8 +------- imgui_internal.h | 12 ++++++++---- 3 files changed, 17 insertions(+), 31 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 649d2e765..6173f7121 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1859,8 +1859,7 @@ ImGuiWindow::ImGuiWindow(ImGuiContext* context, const char* name) ItemWidthDefault = 0.0f; FontWindowScale = 1.0f; - DrawList = (ImDrawList*)ImGui::MemAlloc(sizeof(ImDrawList)); - IM_PLACEMENT_NEW(DrawList) ImDrawList(&context->DrawListSharedData); + DrawList = IM_NEW(ImDrawList)(&context->DrawListSharedData); DrawList->_OwnerName = Name; ParentWindow = NULL; RootWindow = NULL; @@ -1873,11 +1872,8 @@ ImGuiWindow::ImGuiWindow(ImGuiContext* context, const char* name) ImGuiWindow::~ImGuiWindow() { - DrawList->~ImDrawList(); - ImGui::MemFree(DrawList); - DrawList = NULL; - ImGui::MemFree(Name); - Name = NULL; + IM_DELETE(DrawList); + IM_DELETE(Name); } ImGuiID ImGuiWindow::GetID(const char* str, const char* str_end) @@ -2579,8 +2575,7 @@ static void SettingsHandlerWindow_WriteAll(ImGuiContext& g, ImGuiTextBuffer* buf void ImGui::Initialize() { ImGuiContext& g = *GImGui; - g.LogClipboard = (ImGuiTextBuffer*)ImGui::MemAlloc(sizeof(ImGuiTextBuffer)); - IM_PLACEMENT_NEW(g.LogClipboard) ImGuiTextBuffer(); + g.LogClipboard = IM_NEW(ImGuiTextBuffer)(); // Add .ini handle for ImGuiWindow type ImGuiSettingsHandler ini_handler; @@ -2613,10 +2608,7 @@ void ImGui::Shutdown() SaveIniSettingsToDisk(g.IO.IniFilename); for (int i = 0; i < g.Windows.Size; i++) - { - g.Windows[i]->~ImGuiWindow(); - ImGui::MemFree(g.Windows[i]); - } + IM_DELETE(g.Windows[i]); g.Windows.clear(); g.WindowsSortBuffer.clear(); g.CurrentWindow = NULL; @@ -2628,7 +2620,7 @@ void ImGui::Shutdown() g.ActiveIdWindow = NULL; g.MovingWindow = NULL; for (int i = 0; i < g.SettingsWindows.Size; i++) - ImGui::MemFree(g.SettingsWindows[i].Name); + IM_DELETE(g.SettingsWindows[i].Name); g.ColorModifiers.clear(); g.StyleModifiers.clear(); g.FontStack.clear(); @@ -2653,10 +2645,7 @@ void ImGui::Shutdown() g.LogFile = NULL; } if (g.LogClipboard) - { - g.LogClipboard->~ImGuiTextBuffer(); - ImGui::MemFree(g.LogClipboard); - } + IM_DELETE(g.LogClipboard); g.Initialized = false; } @@ -4157,8 +4146,7 @@ static ImGuiWindow* CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFl ImGuiContext& g = *GImGui; // Create window the first time - ImGuiWindow* window = (ImGuiWindow*)ImGui::MemAlloc(sizeof(ImGuiWindow)); - IM_PLACEMENT_NEW(window) ImGuiWindow(&g, name); + ImGuiWindow* window = IM_NEW(ImGuiWindow)(&g, name); window->Flags = flags; g.WindowsById.SetVoidPtr(window->ID, window); diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 02cf42cca..793aeffbc 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1461,15 +1461,9 @@ ImFont* ImFontAtlas::AddFont(const ImFontConfig* font_cfg) // Create new font if (!font_cfg->MergeMode) - { - ImFont* font = (ImFont*)ImGui::MemAlloc(sizeof(ImFont)); - IM_PLACEMENT_NEW(font) ImFont(); - Fonts.push_back(font); - } + Fonts.push_back(IM_NEW(ImFont)); else - { IM_ASSERT(!Fonts.empty()); // When using MergeMode make sure that a font has already been added before. You can use ImGui::GetIO().Fonts->AddFontDefault() to add the default imgui font. - } ConfigData.push_back(*font_cfg); ImFontConfig& new_font_cfg = ConfigData.back(); diff --git a/imgui_internal.h b/imgui_internal.h index 1e0f8ae1f..c08f5082c 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -160,10 +160,14 @@ static inline ImVec2 ImMul(const ImVec2& lhs, const ImVec2& rhs) // We call C++ constructor on own allocated memory via the placement "new(ptr) Type()" syntax. // Defining a custom placement new() with a dummy parameter allows us to bypass including which on some platforms complains when user has disabled exceptions. -struct ImPlacementNewDummy {}; -inline void* operator new(size_t, ImPlacementNewDummy, void* ptr) { return ptr; } -inline void operator delete(void*, ImPlacementNewDummy, void*) {} -#define IM_PLACEMENT_NEW(_PTR) new(ImPlacementNewDummy(), _PTR) +struct ImNewAllocDummy {}; +struct ImNewPlacementDummy {}; +inline void* operator new(size_t, ImNewPlacementDummy, void* ptr) { return ptr; } +inline void operator delete(void*, ImNewPlacementDummy, void*) {} // This is only required so we can use the symetrical new() +inline void operator delete(void* p, ImNewAllocDummy) { ImGui::MemFree(p); } +#define IM_PLACEMENT_NEW(_PTR) new(ImNewPlacementDummy(), _PTR) +#define IM_NEW(_TYPE) new(ImNewPlacementDummy(), ImGui::MemAlloc(sizeof(_TYPE))) _TYPE +#define IM_DELETE(_PTR) delete(ImNewAllocDummy(), _PTR), _PTR = NULL //----------------------------------------------------------------------------- // Types From d976e4ea23d389a757800cef79261ad3296fb2c5 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 23 Dec 2017 16:27:16 +0100 Subject: [PATCH 778/921] Internals: Missing IM_DELETE usage (#1517) --- imgui_draw.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 793aeffbc..2ffdf4be3 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1403,10 +1403,7 @@ void ImFontAtlas::ClearTexData() void ImFontAtlas::ClearFonts() { for (int i = 0; i < Fonts.Size; i++) - { - Fonts[i]->~ImFont(); - ImGui::MemFree(Fonts[i]); - } + IM_DELETE(Fonts[i]); Fonts.clear(); } From e9ceef4762a801737ead8f4d3d492f4f8c153306 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 23 Dec 2017 20:37:36 +0100 Subject: [PATCH 779/921] ImVector: Revert 6172e932728a0fa629d910c1a1534d66a59e386a actually problematic with our current use (because we don't construct the instances). --- imgui.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/imgui.h b/imgui.h index de9177c94..33580dc2a 100644 --- a/imgui.h +++ b/imgui.h @@ -1018,10 +1018,8 @@ public: typedef value_type* iterator; typedef const value_type* const_iterator; - inline ImVector() { Size = Capacity = 0; Data = NULL; } - inline ~ImVector() { if (Data) ImGui::MemFree(Data); } - inline ImVector(const ImVector& rhs) { Size = Capacity = 0; Data = NULL; if (rhs.Size) { resize(rhs.Size); memcpy(Data, rhs.Data, (size_t)rhs.Size * sizeof(T)); } } - inline ImVector& operator=(const ImVector& rhs) { resize(rhs.Size); if (rhs.Size) memcpy(Data, rhs.Data, (size_t)rhs.Size * sizeof(T)); return *this; } + inline ImVector() { Size = Capacity = 0; Data = NULL; } + inline ~ImVector() { if (Data) ImGui::MemFree(Data); } inline bool empty() const { return Size == 0; } inline int size() const { return Size; } From bb8dfe4a3432a6e705a26c21cc5a3e859b93350f Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 23 Dec 2017 23:10:26 +0100 Subject: [PATCH 780/921] Fixed incorrect IM_DELETE macro (9cda86d55a80c9f032af84f657b9fe8e6c7f3f52) (#1517, #484, #504) --- imgui_internal.h | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/imgui_internal.h b/imgui_internal.h index c08f5082c..e161a6f14 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -160,14 +160,12 @@ static inline ImVec2 ImMul(const ImVec2& lhs, const ImVec2& rhs) // We call C++ constructor on own allocated memory via the placement "new(ptr) Type()" syntax. // Defining a custom placement new() with a dummy parameter allows us to bypass including which on some platforms complains when user has disabled exceptions. -struct ImNewAllocDummy {}; struct ImNewPlacementDummy {}; inline void* operator new(size_t, ImNewPlacementDummy, void* ptr) { return ptr; } inline void operator delete(void*, ImNewPlacementDummy, void*) {} // This is only required so we can use the symetrical new() -inline void operator delete(void* p, ImNewAllocDummy) { ImGui::MemFree(p); } -#define IM_PLACEMENT_NEW(_PTR) new(ImNewPlacementDummy(), _PTR) -#define IM_NEW(_TYPE) new(ImNewPlacementDummy(), ImGui::MemAlloc(sizeof(_TYPE))) _TYPE -#define IM_DELETE(_PTR) delete(ImNewAllocDummy(), _PTR), _PTR = NULL +#define IM_PLACEMENT_NEW(_PTR) new(ImNewPlacementDummy(), _PTR) +#define IM_NEW(_TYPE) new(ImNewPlacementDummy(), ImGui::MemAlloc(sizeof(_TYPE))) _TYPE +template void IM_DELETE(T*& p) { if (p) { p->~T(); ImGui::MemFree(p); p = NULL; } } //----------------------------------------------------------------------------- // Types From cead20753580ad503f028afb46401f2e982af1c2 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 24 Dec 2017 17:58:41 +0100 Subject: [PATCH 781/921] Comments --- imgui.cpp | 4 ++-- imgui_demo.cpp | 4 ++++ imgui_draw.cpp | 1 + 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 6173f7121..393b4e503 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -213,8 +213,8 @@ Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. Also read releases logs https://github.com/ocornut/imgui/releases for more details. - - 2017/12/21 (1.53) - renamed style.AntiAliasedShapes to style.AntiAliasedFill for consistency and as a way to explicitly break code that manipulate those flag at runtime. You can now manipulate ImDrawList::Flags - - 2017/12/21 (1.53) - removed 'bool anti_aliased = true' final parameter of ImDrawList::AddPolyline() and ImDrawList::AddConvexPolyFilled(). Prefer manipulating ImDrawList::Flags. + - 2017/12/21 (1.53) - ImDrawList: renamed style.AntiAliasedShapes to style.AntiAliasedFill for consistency and as a way to explicitly break code that manipulate those flag at runtime. You can now manipulate ImDrawList::Flags + - 2017/12/21 (1.53) - ImDrawList: removed 'bool anti_aliased = true' final parameter of ImDrawList::AddPolyline() and ImDrawList::AddConvexPolyFilled(). Prefer manipulating ImDrawList::Flags if you need to toggle them during the frame. - 2017/12/14 (1.53) - using the ImGuiWindowFlags_NoScrollWithMouse flag on a child window forwards the mouse wheel event to the parent window, unless either ImGuiWindowFlags_NoInputs or ImGuiWindowFlags_NoScrollbar are also set. - 2017/12/13 (1.53) - renamed GetItemsLineHeightWithSpacing() to GetFrameHeightWithSpacing(). Kept redirection function (will obsolete). - 2017/12/13 (1.53) - obsoleted IsRootWindowFocused() in favor of using IsWindowFocused(ImGuiFocusedFlags_RootWindow). Kept redirection function (will obsolete). diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 0624bdd3e..0b329edc2 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1911,6 +1911,8 @@ void ImGui::ShowTestWindow(bool* p_open) ImGui::End(); } +// Demo helper function to select among default colors. See ShowStyleEditor() for more advanced options. +// Here we use the simplified Combo() api that packs items into a single literal string. Useful for quick combo boxes where the choices are known locally. bool ImGui::ShowStyleSelector(const char* label) { static int style_idx = 0; @@ -1927,6 +1929,8 @@ bool ImGui::ShowStyleSelector(const char* label) return false; } +// Demo helper function to select among loaded fonts. +// Here we use the regular BeginCombo()/EndCombo() api which is more the more flexible one. void ImGui::ShowFontSelector(const char* label) { ImGuiIO& io = ImGui::GetIO(); diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 2ffdf4be3..bba523a38 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -225,6 +225,7 @@ void ImGui::StyleColorsDark(ImGuiStyle* dst) colors[ImGuiCol_DragDropTarget] = ImVec4(1.00f, 1.00f, 0.00f, 0.90f); } +// Those light colors are better suited with a thicker font than the default one + FrameBorder void ImGui::StyleColorsLight(ImGuiStyle* dst) { ImGuiStyle* style = dst ? dst : &ImGui::GetStyle(); From 1b86e7343fea755e8a948fd1102d549665c4c134 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 24 Dec 2017 18:16:22 +0100 Subject: [PATCH 782/921] Renamed the emblematic ShowTestWindow() function to ShowDemoWindow(). Kept redirection function (will obsolete). --- README.md | 2 +- examples/allegro5_example/main.cpp | 10 +++++----- .../apple_example/imguiex-ios/debug_hud.cpp | 6 +++--- .../apple_example/imguiex-ios/debug_hud.h | 2 +- examples/directx10_example/main.cpp | 10 +++++----- examples/directx11_example/main.cpp | 10 +++++----- examples/directx9_example/main.cpp | 10 +++++----- examples/marmalade_example/main.cpp | 10 +++++----- examples/null_example/main.cpp | 2 +- examples/opengl2_example/main.cpp | 10 +++++----- examples/opengl3_example/main.cpp | 10 +++++----- examples/sdl_opengl2_example/main.cpp | 10 +++++----- examples/sdl_opengl3_example/main.cpp | 10 +++++----- examples/vulkan_example/main.cpp | 10 +++++----- imconfig.h | 6 +++--- imgui.cpp | 7 ++++--- imgui.h | 5 +++-- imgui_demo.cpp | 20 +++++++++++-------- 18 files changed, 78 insertions(+), 72 deletions(-) diff --git a/README.md b/README.md index 29fcab16e..6ababf5b3 100644 --- a/README.md +++ b/README.md @@ -140,7 +140,7 @@ Frequently Asked Question (FAQ) Where is the documentation? - The documentation is at the top of imgui.cpp + effectively imgui.h. -- Example code is in imgui_demo.cpp and particularly the ImGui::ShowTestWindow() function. It covers most features of ImGui so you can read the code and call the function itself to see its output. +- Example code is in imgui_demo.cpp and particularly the ImGui::ShowDemoWindow() function. It covers most features of ImGui so you can read the code and call the function itself to see its output. - Standalone example applications using e.g. OpenGL/DirectX are provided in the examples/ folder. - We obviously needs better documentation! Consider contributing or becoming a [Patron](http://www.patreon.com/imgui) to promote this effort. diff --git a/examples/allegro5_example/main.cpp b/examples/allegro5_example/main.cpp index 4eb9a4aa9..f9abe756e 100644 --- a/examples/allegro5_example/main.cpp +++ b/examples/allegro5_example/main.cpp @@ -41,7 +41,7 @@ int main(int, char**) //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); //IM_ASSERT(font != NULL); - bool show_test_window = true; + bool show_demo_window = true; bool show_another_window = false; ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); @@ -75,7 +75,7 @@ int main(int, char**) ImGui::Text("Hello, world!"); ImGui::SliderFloat("float", &f, 0.0f, 1.0f); ImGui::ColorEdit3("clear color", (float*)&clear_color); - if (ImGui::Button("Test Window")) show_test_window ^= 1; + if (ImGui::Button("Demo Window")) show_demo_window ^= 1; if (ImGui::Button("Another Window")) show_another_window ^= 1; ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f/ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); } @@ -88,11 +88,11 @@ int main(int, char**) ImGui::End(); } - // 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow(). - if (show_test_window) + // 3. Show the ImGui demo window. Most of the sample code is in ImGui::ShowDemoWindow(). + if (show_demo_window) { ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); - ImGui::ShowTestWindow(&show_test_window); + ImGui::ShowDemoWindow(&show_demo_window); } // Rendering diff --git a/examples/apple_example/imguiex-ios/debug_hud.cpp b/examples/apple_example/imguiex-ios/debug_hud.cpp index fff26eee9..c451322a2 100644 --- a/examples/apple_example/imguiex-ios/debug_hud.cpp +++ b/examples/apple_example/imguiex-ios/debug_hud.cpp @@ -9,7 +9,7 @@ void DebugHUD_InitDefaults( DebugHUD *hud ) { - hud->show_test_window = true; + hud->show_demo_window = true; hud->show_example_window = true; hud->rotation_speed = 15.0f; @@ -26,10 +26,10 @@ void DebugHUD_InitDefaults( DebugHUD *hud ) void DebugHUD_DoInterface(DebugHUD *hud) { - if (hud->show_test_window) + if (hud->show_demo_window) { ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); - ImGui::ShowTestWindow(&hud->show_test_window ); + ImGui::ShowDemoWindow(&hud->show_demo_window ); } if (hud->show_example_window) diff --git a/examples/apple_example/imguiex-ios/debug_hud.h b/examples/apple_example/imguiex-ios/debug_hud.h index 17122f5e3..601376c3e 100644 --- a/examples/apple_example/imguiex-ios/debug_hud.h +++ b/examples/apple_example/imguiex-ios/debug_hud.h @@ -6,7 +6,7 @@ typedef struct DebugHUD { - bool show_test_window; + bool show_demo_window; bool show_example_window; float rotation_speed; float cubeColor1[4]; diff --git a/examples/directx10_example/main.cpp b/examples/directx10_example/main.cpp index 3ece69f90..1d7da4b06 100644 --- a/examples/directx10_example/main.cpp +++ b/examples/directx10_example/main.cpp @@ -141,7 +141,7 @@ int main(int, char**) //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); //IM_ASSERT(font != NULL); - bool show_test_window = true; + bool show_demo_window = true; bool show_another_window = false; ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); @@ -169,7 +169,7 @@ int main(int, char**) ImGui::Text("Hello, world!"); ImGui::SliderFloat("float", &f, 0.0f, 1.0f); ImGui::ColorEdit3("clear color", (float*)&clear_color); - if (ImGui::Button("Test Window")) show_test_window ^= 1; + if (ImGui::Button("Demo Window")) show_demo_window ^= 1; if (ImGui::Button("Another Window")) show_another_window ^= 1; ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); } @@ -182,11 +182,11 @@ int main(int, char**) ImGui::End(); } - // 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow(). - if (show_test_window) + // 3. Show the ImGui demo window. Most of the sample code is in ImGui::ShowDemoWindow(). + if (show_demo_window) { ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); // Normally user code doesn't need/want to call it because positions are saved in .ini file anyway. Here we just want to make the demo initial state a bit more friendly! - ImGui::ShowTestWindow(&show_test_window); + ImGui::ShowDemoWindow(&show_demo_window); } // Rendering diff --git a/examples/directx11_example/main.cpp b/examples/directx11_example/main.cpp index 9bd8637cf..1c6f84a20 100644 --- a/examples/directx11_example/main.cpp +++ b/examples/directx11_example/main.cpp @@ -144,7 +144,7 @@ int main(int, char**) //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); //IM_ASSERT(font != NULL); - bool show_test_window = true; + bool show_demo_window = true; bool show_another_window = false; ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); @@ -172,7 +172,7 @@ int main(int, char**) ImGui::Text("Hello, world!"); ImGui::SliderFloat("float", &f, 0.0f, 1.0f); ImGui::ColorEdit3("clear color", (float*)&clear_color); - if (ImGui::Button("Test Window")) show_test_window ^= 1; + if (ImGui::Button("Demo Window")) show_demo_window ^= 1; if (ImGui::Button("Another Window")) show_another_window ^= 1; ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); } @@ -185,11 +185,11 @@ int main(int, char**) ImGui::End(); } - // 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow(). - if (show_test_window) + // 3. Show the ImGui demo window. Most of the sample code is in ImGui::ShowDemoWindow(). + if (show_demo_window) { ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); // Normally user code doesn't need/want to call it because positions are saved in .ini file anyway. Here we just want to make the demo initial state a bit more friendly! - ImGui::ShowTestWindow(&show_test_window); + ImGui::ShowDemoWindow(&show_demo_window); } // Rendering diff --git a/examples/directx9_example/main.cpp b/examples/directx9_example/main.cpp index af53ddb30..7ada228dd 100644 --- a/examples/directx9_example/main.cpp +++ b/examples/directx9_example/main.cpp @@ -93,7 +93,7 @@ int main(int, char**) //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); //IM_ASSERT(font != NULL); - bool show_test_window = true; + bool show_demo_window = true; bool show_another_window = false; ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); @@ -123,7 +123,7 @@ int main(int, char**) ImGui::Text("Hello, world!"); ImGui::SliderFloat("float", &f, 0.0f, 1.0f); ImGui::ColorEdit3("clear color", (float*)&clear_color); - if (ImGui::Button("Test Window")) show_test_window ^= 1; + if (ImGui::Button("Demo Window")) show_demo_window ^= 1; if (ImGui::Button("Another Window")) show_another_window ^= 1; ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); } @@ -136,11 +136,11 @@ int main(int, char**) ImGui::End(); } - // 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow(). - if (show_test_window) + // 3. Show the ImGui demo window. Most of the sample code is in ImGui::ShowDemoWindow(). + if (show_demo_window) { ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); - ImGui::ShowTestWindow(&show_test_window); + ImGui::ShowDemoWindow(&show_demo_window); } // Rendering diff --git a/examples/marmalade_example/main.cpp b/examples/marmalade_example/main.cpp index f87b3bc51..032e41981 100644 --- a/examples/marmalade_example/main.cpp +++ b/examples/marmalade_example/main.cpp @@ -33,7 +33,7 @@ int main(int, char**) //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); //IM_ASSERT(font != NULL); - bool show_test_window = true; + bool show_demo_window = true; bool show_another_window = false; ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); @@ -58,7 +58,7 @@ int main(int, char**) ImGui::Text("Hello, world!"); ImGui::SliderFloat("float", &f, 0.0f, 1.0f); ImGui::ColorEdit3("clear color", (float*)&clear_color); - if (ImGui::Button("Test Window")) show_test_window ^= 1; + if (ImGui::Button("Demo Window")) show_demo_window ^= 1; if (ImGui::Button("Another Window")) show_another_window ^= 1; ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); } @@ -71,11 +71,11 @@ int main(int, char**) ImGui::End(); } - // 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow(). - if (show_test_window) + // 3. Show the ImGui demo window. Most of the sample code is in ImGui::ShowDemoWindow(). + if (show_demo_window) { ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); - ImGui::ShowTestWindow(&show_test_window); + ImGui::ShowDemoWindow(&show_demo_window); } // Rendering diff --git a/examples/null_example/main.cpp b/examples/null_example/main.cpp index b12f75c96..04c1bda40 100644 --- a/examples/null_example/main.cpp +++ b/examples/null_example/main.cpp @@ -22,7 +22,7 @@ int main(int, char**) ImGui::Text("Hello, world!"); ImGui::SliderFloat("float", &f, 0.0f, 1.0f); ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / io.Framerate, io.Framerate); - ImGui::ShowTestWindow(NULL); + ImGui::ShowDemoWindow(NULL); ImGui::Render(); } diff --git a/examples/opengl2_example/main.cpp b/examples/opengl2_example/main.cpp index ed8f1a7b6..35c8d19c7 100644 --- a/examples/opengl2_example/main.cpp +++ b/examples/opengl2_example/main.cpp @@ -45,7 +45,7 @@ int main(int, char**) //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); //IM_ASSERT(font != NULL); - bool show_test_window = true; + bool show_demo_window = true; bool show_another_window = false; ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); @@ -66,7 +66,7 @@ int main(int, char**) ImGui::Text("Hello, world!"); ImGui::SliderFloat("float", &f, 0.0f, 1.0f); ImGui::ColorEdit3("clear color", (float*)&clear_color); - if (ImGui::Button("Test Window")) show_test_window ^= 1; + if (ImGui::Button("Demo Window")) show_demo_window ^= 1; if (ImGui::Button("Another Window")) show_another_window ^= 1; ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); } @@ -79,11 +79,11 @@ int main(int, char**) ImGui::End(); } - // 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow(). - if (show_test_window) + // 3. Show the ImGui demo window. Most of the sample code is in ImGui::ShowDemoWindow(). + if (show_demo_window) { ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); - ImGui::ShowTestWindow(&show_test_window); + ImGui::ShowDemoWindow(&show_demo_window); } // Rendering diff --git a/examples/opengl3_example/main.cpp b/examples/opengl3_example/main.cpp index 062843d6b..d10d58305 100644 --- a/examples/opengl3_example/main.cpp +++ b/examples/opengl3_example/main.cpp @@ -50,7 +50,7 @@ int main(int, char**) //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); //IM_ASSERT(font != NULL); - bool show_test_window = true; + bool show_demo_window = true; bool show_another_window = false; ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); @@ -71,7 +71,7 @@ int main(int, char**) ImGui::Text("Hello, world!"); ImGui::SliderFloat("float", &f, 0.0f, 1.0f); ImGui::ColorEdit3("clear color", (float*)&clear_color); - if (ImGui::Button("Test Window")) show_test_window ^= 1; + if (ImGui::Button("Demo Window")) show_demo_window ^= 1; if (ImGui::Button("Another Window")) show_another_window ^= 1; ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); } @@ -84,11 +84,11 @@ int main(int, char**) ImGui::End(); } - // 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow(). - if (show_test_window) + // 3. Show the ImGui demo window. Most of the sample code is in ImGui::ShowDemoWindow(). + if (show_demo_window) { ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); - ImGui::ShowTestWindow(&show_test_window); + ImGui::ShowDemoWindow(&show_demo_window); } // Rendering diff --git a/examples/sdl_opengl2_example/main.cpp b/examples/sdl_opengl2_example/main.cpp index 77241a5ba..cc7c5fb7b 100644 --- a/examples/sdl_opengl2_example/main.cpp +++ b/examples/sdl_opengl2_example/main.cpp @@ -51,7 +51,7 @@ int main(int, char**) //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); //IM_ASSERT(font != NULL); - bool show_test_window = true; + bool show_demo_window = true; bool show_another_window = false; ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); @@ -79,7 +79,7 @@ int main(int, char**) ImGui::Text("Hello, world!"); ImGui::SliderFloat("float", &f, 0.0f, 1.0f); ImGui::ColorEdit3("clear color", (float*)&clear_color); - if (ImGui::Button("Test Window")) show_test_window ^= 1; + if (ImGui::Button("Demo Window")) show_demo_window ^= 1; if (ImGui::Button("Another Window")) show_another_window ^= 1; ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); } @@ -92,11 +92,11 @@ int main(int, char**) ImGui::End(); } - // 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow(). - if (show_test_window) + // 3. Show the ImGui demo window. Most of the sample code is in ImGui::ShowDemoWindow(). + if (show_demo_window) { ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); - ImGui::ShowTestWindow(&show_test_window); + ImGui::ShowDemoWindow(&show_demo_window); } // Rendering diff --git a/examples/sdl_opengl3_example/main.cpp b/examples/sdl_opengl3_example/main.cpp index e51b32089..a9e75fd4c 100644 --- a/examples/sdl_opengl3_example/main.cpp +++ b/examples/sdl_opengl3_example/main.cpp @@ -51,7 +51,7 @@ int main(int, char**) //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); //IM_ASSERT(font != NULL); - bool show_test_window = true; + bool show_demo_window = true; bool show_another_window = false; ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); @@ -79,7 +79,7 @@ int main(int, char**) ImGui::Text("Hello, world!"); ImGui::SliderFloat("float", &f, 0.0f, 1.0f); ImGui::ColorEdit3("clear color", (float*)&clear_color); - if (ImGui::Button("Test Window")) show_test_window ^= 1; + if (ImGui::Button("Demo Window")) show_demo_window ^= 1; if (ImGui::Button("Another Window")) show_another_window ^= 1; ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); } @@ -92,11 +92,11 @@ int main(int, char**) ImGui::End(); } - // 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow(). - if (show_test_window) + // 3. Show the ImGui demo window. Most of the sample code is in ImGui::ShowDemoWindow(). + if (show_demo_window) { ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); - ImGui::ShowTestWindow(&show_test_window); + ImGui::ShowDemoWindow(&show_demo_window); } // Rendering diff --git a/examples/vulkan_example/main.cpp b/examples/vulkan_example/main.cpp index 9d54976a3..ec83035f9 100644 --- a/examples/vulkan_example/main.cpp +++ b/examples/vulkan_example/main.cpp @@ -668,7 +668,7 @@ int main(int, char**) ImGui_ImplGlfwVulkan_InvalidateFontUploadObjects(); } - bool show_test_window = true; + bool show_demo_window = true; bool show_another_window = false; ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); @@ -700,7 +700,7 @@ int main(int, char**) ImGui::Text("Hello, world!"); ImGui::SliderFloat("float", &f, 0.0f, 1.0f); ImGui::ColorEdit3("clear color", (float*)&clear_color); - if (ImGui::Button("Test Window")) show_test_window ^= 1; + if (ImGui::Button("Demo Window")) show_demo_window ^= 1; if (ImGui::Button("Another Window")) show_another_window ^= 1; ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); } @@ -713,11 +713,11 @@ int main(int, char**) ImGui::End(); } - // 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow(). - if (show_test_window) + // 3. Show the ImGui demo window. Most of the sample code is in ImGui::ShowDemoWindow(). + if (show_demo_window) { ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); - ImGui::ShowTestWindow(&show_test_window); + ImGui::ShowDemoWindow(&show_demo_window); } g_ClearValue.color.float32[0] = clear_color.x; diff --git a/imconfig.h b/imconfig.h index 85eff5fd4..824a81afe 100644 --- a/imconfig.h +++ b/imconfig.h @@ -23,9 +23,9 @@ //#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS //#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS -//---- Don't implement test window functionality (ShowTestWindow()/ShowStyleEditor()/ShowUserGuide() methods will be empty) -//---- It is very strongly recommended to NOT disable the test windows. Please read the comment at the top of imgui_demo.cpp to learn why. -//#define IMGUI_DISABLE_TEST_WINDOWS +//---- Don't implement demo windows functionality (ShowDemoWindow()/ShowStyleEditor()/ShowUserGuide() methods will be empty) +//---- It is very strongly recommended to NOT disable the demo windows. Please read the comment at the top of imgui_demo.cpp to learn why. +//#define IMGUI_DISABLE_DEMO_WINDOWS //---- Don't implement ImFormatString(), ImFormatStringV() so you can reimplement them yourself. //#define IMGUI_DISABLE_FORMAT_STRING_FUNCTIONS diff --git a/imgui.cpp b/imgui.cpp index 393b4e503..14b2bd8c3 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1,7 +1,7 @@ // dear imgui, v1.53 WIP // (main code and documentation) -// See ImGui::ShowTestWindow() in imgui_demo.cpp for demo code. +// Call and read ImGui::ShowDemoWindow() in imgui_demo.cpp for demo code. // Newcomers, read 'Programmer guide' below for notes on how to setup Dear ImGui in your codebase. // Get latest version at https://github.com/ocornut/imgui // Releases change-log at https://github.com/ocornut/imgui/releases @@ -86,7 +86,7 @@ - Read the FAQ below this section! - Your code creates the UI, if your code doesn't run the UI is gone! == very dynamic UI, no construction/destructions steps, less data retention on your side, no state duplication, less sync, less bugs. - - Call and read ImGui::ShowTestWindow() for demo code demonstrating most features. + - Call and read ImGui::ShowDemoWindow() for demo code demonstrating most features. - You can learn about immediate-mode gui principles at http://www.johno.se/book/imgui.html or watch http://mollyrocket.com/861 HOW TO UPDATE TO A NEWER VERSION OF DEAR IMGUI @@ -213,6 +213,7 @@ Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. Also read releases logs https://github.com/ocornut/imgui/releases for more details. + - 2017/12/24 (1.53) - renamed the emblematic ShowTestWindow() function to ShowDemoWindow(). Kept redirection function (will obsolete). - 2017/12/21 (1.53) - ImDrawList: renamed style.AntiAliasedShapes to style.AntiAliasedFill for consistency and as a way to explicitly break code that manipulate those flag at runtime. You can now manipulate ImDrawList::Flags - 2017/12/21 (1.53) - ImDrawList: removed 'bool anti_aliased = true' final parameter of ImDrawList::AddPolyline() and ImDrawList::AddConvexPolyFilled(). Prefer manipulating ImDrawList::Flags if you need to toggle them during the frame. - 2017/12/14 (1.53) - using the ImGuiWindowFlags_NoScrollWithMouse flag on a child window forwards the mouse wheel event to the parent window, unless either ImGuiWindowFlags_NoInputs or ImGuiWindowFlags_NoScrollbar are also set. @@ -576,7 +577,7 @@ - tip: the ImGuiOnceUponAFrame helper will allow run the block of code only once a frame. You can use it to quickly add custom UI in the middle of a deep nested inner loop in your code. - tip: you can call Render() multiple times (e.g for VR renders). - - tip: call and read the ShowTestWindow() code in imgui_demo.cpp for more example of how to use ImGui! + - tip: call and read the ShowDemoWindow() code in imgui_demo.cpp for more example of how to use ImGui! */ diff --git a/imgui.h b/imgui.h index 33580dc2a..10d46ab05 100644 --- a/imgui.h +++ b/imgui.h @@ -2,7 +2,7 @@ // (headers) // See imgui.cpp file for documentation. -// See ImGui::ShowTestWindow() in imgui_demo.cpp for demo code. +// Call and read ImGui::ShowDemoWindow() in imgui_demo.cpp for demo code. // Read 'Programmer guide' in imgui.cpp for notes on how to setup ImGui in your codebase. // Get latest version at https://github.com/ocornut/imgui @@ -136,7 +136,7 @@ namespace ImGui IMGUI_API void Shutdown(); // Demo, Debug, Informations - IMGUI_API void ShowTestWindow(bool* p_open = NULL); // create demo/test window. demonstrate most ImGui features. call this to learn about the library! try to make it always available in your application! + IMGUI_API void ShowDemoWindow(bool* p_open = NULL); // create demo/test window (previously called ShowTestWindow). demonstrate most ImGui features. call this to learn about the library! try to make it always available in your application! IMGUI_API void ShowMetricsWindow(bool* p_open = NULL); // create metrics window. display ImGui internals: draw commands (with individual draw calls and vertices), window list, basic internal state, etc. IMGUI_API void ShowStyleEditor(ImGuiStyle* ref = NULL); // add style editor block (not a window). you can pass in a reference ImGuiStyle structure to compare to, revert to and save to (else it uses the default style) IMGUI_API bool ShowStyleSelector(const char* label); @@ -985,6 +985,7 @@ struct ImGuiIO #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS namespace ImGui { + static inline void ShowTestWindow() { return ShowDemoWindow(); } // OBSOLETE 1.53+ static inline bool IsRootWindowFocused() { return IsWindowFocused(ImGuiFocusedFlags_RootWindow); } // OBSOLETE 1.53+ static inline bool IsRootWindowOrAnyChildFocused() { return IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows); } // OBSOLETE 1.53+ static inline void SetNextWindowContentWidth(float width) { SetNextWindowContentSize(ImVec2(width, 0.0f)); } // OBSOLETE 1.53+ (nb: original version preserved last Y value set by SetNextWindowContentSize()) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 0b329edc2..204a17220 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -3,11 +3,11 @@ // Message to the person tempted to delete this file when integrating ImGui into their code base: // Don't do it! Do NOT remove this file from your project! It is useful reference code that you and other users will want to refer to. -// Everything in this file will be stripped out by the linker if you don't call ImGui::ShowTestWindow(). -// During development, you can call ImGui::ShowTestWindow() in your code to learn about various features of ImGui. Have it wired in a debug menu! +// Everything in this file will be stripped out by the linker if you don't call ImGui::ShowDemoWindow(). +// During development, you can call ImGui::ShowDemoWindow() in your code to learn about various features of ImGui. Have it wired in a debug menu! // Removing this file from your project is hindering access to documentation for everyone in your team, likely leading you to poorer usage of the library. -// Note that you can #define IMGUI_DISABLE_TEST_WINDOWS in imconfig.h for the same effect. -// If you want to link core ImGui in your public builds but not those test windows, #define IMGUI_DISABLE_TEST_WINDOWS in imconfig.h and those functions will be empty. +// Note that you can #define IMGUI_DISABLE_DEMO_WINDOWS in imconfig.h for the same effect. +// If you want to link core ImGui in your public builds but not those demo windows, #define IMGUI_DISABLE_DEMO_WINDOWS in imconfig.h and those functions will be empty. // For any other case, if you have ImGui available you probably want this to be available for reference and execution. // Thank you, // -Your beloved friend, imgui_demo.cpp (that you won't delete) @@ -70,7 +70,11 @@ // DEMO CODE //----------------------------------------------------------------------------- -#ifndef IMGUI_DISABLE_TEST_WINDOWS +#if !defined(IMGUI_DISABLE_OBSOLETE_FUNCTIONS) && defined(IMGUI_DISABLE_TEST_WINDOWS) && !defined(IMGUI_DISABLE_DEMO_WINDOWS) // Obsolete name since 1.53, TEST->DEMO +#define IMGUI_DISABLE_DEMO_WINDOWS +#endif + +#if !defined(IMGUI_DISABLE_DEMO_WINDOWS) static void ShowExampleAppConsole(bool* p_open); static void ShowExampleAppLog(bool* p_open); @@ -121,7 +125,7 @@ void ImGui::ShowUserGuide() } // Demonstrate most ImGui features (big function!) -void ImGui::ShowTestWindow(bool* p_open) +void ImGui::ShowDemoWindow(bool* p_open) { // Examples apps static bool show_app_main_menu_bar = false; @@ -231,7 +235,7 @@ void ImGui::ShowTestWindow(bool* p_open) ImGui::Spacing(); if (ImGui::CollapsingHeader("Help")) { - ImGui::TextWrapped("This window is being created by the ShowTestWindow() function. Please refer to the code in imgui_demo.cpp for reference.\n\n"); + ImGui::TextWrapped("This window is being created by the ShowDemoWindow() function. Please refer to the code in imgui_demo.cpp for reference.\n\n"); ImGui::Text("USER GUIDE:"); ImGui::ShowUserGuide(); } @@ -3041,7 +3045,7 @@ static void ShowExampleAppLongText(bool* p_open) // End of Demo code #else -void ImGui::ShowTestWindow(bool*) {} +void ImGui::ShowDemoWindow(bool*) {} void ImGui::ShowUserGuide() {} void ImGui::ShowStyleEditor(ImGuiStyle*) {} From ce13426a1adefa70c8614e7b34f78c867ed19cc8 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 24 Dec 2017 18:45:11 +0100 Subject: [PATCH 783/921] Examples: Comments, synched some minor drift between examples + stronger suggestion to use StyleColorsDark(). --- examples/allegro5_example/main.cpp | 24 ++++++----- .../apple_example/imguiex-ios/debug_hud.cpp | 2 +- examples/directx10_example/main.cpp | 20 ++++++---- examples/directx11_example/main.cpp | 20 ++++++---- examples/directx9_example/main.cpp | 20 ++++++---- examples/marmalade_example/main.cpp | 40 +++++++++++-------- examples/opengl2_example/main.cpp | 20 ++++++---- examples/opengl3_example/main.cpp | 20 ++++++---- examples/sdl_opengl2_example/main.cpp | 20 ++++++---- examples/sdl_opengl3_example/main.cpp | 20 ++++++---- examples/vulkan_example/main.cpp | 20 ++++++---- 11 files changed, 143 insertions(+), 83 deletions(-) diff --git a/examples/allegro5_example/main.cpp b/examples/allegro5_example/main.cpp index f9abe756e..3c9c9770e 100644 --- a/examples/allegro5_example/main.cpp +++ b/examples/allegro5_example/main.cpp @@ -25,6 +25,10 @@ int main(int, char**) // Setup ImGui binding ImGui_ImplA5_Init(display); + // Setup style + ImGui::StyleColorsClassic(); + //ImGui::StyleColorsDark(); + // Load Fonts // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. @@ -69,15 +73,17 @@ int main(int, char**) ImGui_ImplA5_NewFrame(); // 1. Show a simple window. - // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug". + // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets automatically appears in a window called "Debug". { - static float f; - ImGui::Text("Hello, world!"); - ImGui::SliderFloat("float", &f, 0.0f, 1.0f); - ImGui::ColorEdit3("clear color", (float*)&clear_color); - if (ImGui::Button("Demo Window")) show_demo_window ^= 1; - if (ImGui::Button("Another Window")) show_another_window ^= 1; - ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f/ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); + static float f = 0.0f; + ImGui::Text("Hello, world!"); // Some text (you can use a format string too) + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float as a slider from 0.0f to 1.0f + ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats as a color + if (ImGui::Button("Demo Window")) // Use buttons to toggle our bools. We could use Checkbox() as well. + show_demo_window ^= 1; + if (ImGui::Button("Another Window")) + show_another_window ^= 1; + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); } // 2. Show another simple window. In most cases you will use an explicit Begin/End pair to name the window. @@ -91,7 +97,7 @@ int main(int, char**) // 3. Show the ImGui demo window. Most of the sample code is in ImGui::ShowDemoWindow(). if (show_demo_window) { - ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); + ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); // Normally user code doesn't need/want to call this because positions are saved in .ini file anyway. Here we just want to make the demo initial state a bit more friendly! ImGui::ShowDemoWindow(&show_demo_window); } diff --git a/examples/apple_example/imguiex-ios/debug_hud.cpp b/examples/apple_example/imguiex-ios/debug_hud.cpp index c451322a2..c81f273d1 100644 --- a/examples/apple_example/imguiex-ios/debug_hud.cpp +++ b/examples/apple_example/imguiex-ios/debug_hud.cpp @@ -28,7 +28,7 @@ void DebugHUD_DoInterface(DebugHUD *hud) { if (hud->show_demo_window) { - ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); + ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); // Normally user code doesn't need/want to call this because positions are saved in .ini file anyway. Here we just want to make the demo initial state a bit more friendly! ImGui::ShowDemoWindow(&hud->show_demo_window ); } diff --git a/examples/directx10_example/main.cpp b/examples/directx10_example/main.cpp index 1d7da4b06..ecfc156a5 100644 --- a/examples/directx10_example/main.cpp +++ b/examples/directx10_example/main.cpp @@ -125,6 +125,10 @@ int main(int, char**) // Setup ImGui binding ImGui_ImplDX10_Init(hwnd, g_pd3dDevice); + // Setup style + ImGui::StyleColorsClassic(); + //ImGui::StyleColorsDark(); + // Load Fonts // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. @@ -163,14 +167,16 @@ int main(int, char**) ImGui_ImplDX10_NewFrame(); // 1. Show a simple window. - // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug". + // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets automatically appears in a window called "Debug". { static float f = 0.0f; - ImGui::Text("Hello, world!"); - ImGui::SliderFloat("float", &f, 0.0f, 1.0f); - ImGui::ColorEdit3("clear color", (float*)&clear_color); - if (ImGui::Button("Demo Window")) show_demo_window ^= 1; - if (ImGui::Button("Another Window")) show_another_window ^= 1; + ImGui::Text("Hello, world!"); // Some text (you can use a format string too) + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float as a slider from 0.0f to 1.0f + ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats as a color + if (ImGui::Button("Demo Window")) // Use buttons to toggle our bools. We could use Checkbox() as well. + show_demo_window ^= 1; + if (ImGui::Button("Another Window")) + show_another_window ^= 1; ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); } @@ -185,7 +191,7 @@ int main(int, char**) // 3. Show the ImGui demo window. Most of the sample code is in ImGui::ShowDemoWindow(). if (show_demo_window) { - ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); // Normally user code doesn't need/want to call it because positions are saved in .ini file anyway. Here we just want to make the demo initial state a bit more friendly! + ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); // Normally user code doesn't need/want to call this because positions are saved in .ini file anyway. Here we just want to make the demo initial state a bit more friendly! ImGui::ShowDemoWindow(&show_demo_window); } diff --git a/examples/directx11_example/main.cpp b/examples/directx11_example/main.cpp index 1c6f84a20..d7eb1df24 100644 --- a/examples/directx11_example/main.cpp +++ b/examples/directx11_example/main.cpp @@ -128,6 +128,10 @@ int main(int, char**) // Setup ImGui binding ImGui_ImplDX11_Init(hwnd, g_pd3dDevice, g_pd3dDeviceContext); + // Setup style + ImGui::StyleColorsClassic(); + //ImGui::StyleColorsDark(); + // Load Fonts // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. @@ -166,14 +170,16 @@ int main(int, char**) ImGui_ImplDX11_NewFrame(); // 1. Show a simple window. - // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug". + // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets automatically appears in a window called "Debug". { static float f = 0.0f; - ImGui::Text("Hello, world!"); - ImGui::SliderFloat("float", &f, 0.0f, 1.0f); - ImGui::ColorEdit3("clear color", (float*)&clear_color); - if (ImGui::Button("Demo Window")) show_demo_window ^= 1; - if (ImGui::Button("Another Window")) show_another_window ^= 1; + ImGui::Text("Hello, world!"); // Some text (you can use a format string too) + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float as a slider from 0.0f to 1.0f + ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats as a color + if (ImGui::Button("Demo Window")) // Use buttons to toggle our bools. We could use Checkbox() as well. + show_demo_window ^= 1; + if (ImGui::Button("Another Window")) + show_another_window ^= 1; ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); } @@ -188,7 +194,7 @@ int main(int, char**) // 3. Show the ImGui demo window. Most of the sample code is in ImGui::ShowDemoWindow(). if (show_demo_window) { - ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); // Normally user code doesn't need/want to call it because positions are saved in .ini file anyway. Here we just want to make the demo initial state a bit more friendly! + ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); // Normally user code doesn't need/want to call this because positions are saved in .ini file anyway. Here we just want to make the demo initial state a bit more friendly! ImGui::ShowDemoWindow(&show_demo_window); } diff --git a/examples/directx9_example/main.cpp b/examples/directx9_example/main.cpp index 7ada228dd..09a109d98 100644 --- a/examples/directx9_example/main.cpp +++ b/examples/directx9_example/main.cpp @@ -77,6 +77,10 @@ int main(int, char**) // Setup ImGui binding ImGui_ImplDX9_Init(hwnd, g_pd3dDevice); + // Setup style + ImGui::StyleColorsClassic(); + //ImGui::StyleColorsDark(); + // Load Fonts // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. @@ -117,14 +121,16 @@ int main(int, char**) ImGui_ImplDX9_NewFrame(); // 1. Show a simple window. - // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug". + // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets automatically appears in a window called "Debug". { static float f = 0.0f; - ImGui::Text("Hello, world!"); - ImGui::SliderFloat("float", &f, 0.0f, 1.0f); - ImGui::ColorEdit3("clear color", (float*)&clear_color); - if (ImGui::Button("Demo Window")) show_demo_window ^= 1; - if (ImGui::Button("Another Window")) show_another_window ^= 1; + ImGui::Text("Hello, world!"); // Some text (you can use a format string too) + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float as a slider from 0.0f to 1.0f + ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats as a color + if (ImGui::Button("Demo Window")) // Use buttons to toggle our bools. We could use Checkbox() as well. + show_demo_window ^= 1; + if (ImGui::Button("Another Window")) + show_another_window ^= 1; ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); } @@ -139,7 +145,7 @@ int main(int, char**) // 3. Show the ImGui demo window. Most of the sample code is in ImGui::ShowDemoWindow(). if (show_demo_window) { - ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); + ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); // Normally user code doesn't need/want to call this because positions are saved in .ini file anyway. Here we just want to make the demo initial state a bit more friendly! ImGui::ShowDemoWindow(&show_demo_window); } diff --git a/examples/marmalade_example/main.cpp b/examples/marmalade_example/main.cpp index 032e41981..2b5edb77f 100644 --- a/examples/marmalade_example/main.cpp +++ b/examples/marmalade_example/main.cpp @@ -17,6 +17,10 @@ int main(int, char**) // Setup ImGui binding ImGui_Marmalade_Init(true); + // Setup style + ImGui::StyleColorsClassic(); + //ImGui::StyleColorsDark(); + // Load Fonts // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. @@ -40,26 +44,28 @@ int main(int, char**) // Main loop while (true) { - if (s3eDeviceCheckQuitRequest()) - break; + if (s3eDeviceCheckQuitRequest()) + break; - // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. - // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. - // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. - // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. - s3eKeyboardUpdate(); - s3ePointerUpdate(); - ImGui_Marmalade_NewFrame(); + // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. + // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. + // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. + // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. + s3eKeyboardUpdate(); + s3ePointerUpdate(); + ImGui_Marmalade_NewFrame(); // 1. Show a simple window. - // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug". + // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets automatically appears in a window called "Debug". { static float f = 0.0f; - ImGui::Text("Hello, world!"); - ImGui::SliderFloat("float", &f, 0.0f, 1.0f); - ImGui::ColorEdit3("clear color", (float*)&clear_color); - if (ImGui::Button("Demo Window")) show_demo_window ^= 1; - if (ImGui::Button("Another Window")) show_another_window ^= 1; + ImGui::Text("Hello, world!"); // Some text (you can use a format string too) + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float as a slider from 0.0f to 1.0f + ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats as a color + if (ImGui::Button("Demo Window")) // Use buttons to toggle our bools. We could use Checkbox() as well. + show_demo_window ^= 1; + if (ImGui::Button("Another Window")) + show_another_window ^= 1; ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); } @@ -74,12 +80,12 @@ int main(int, char**) // 3. Show the ImGui demo window. Most of the sample code is in ImGui::ShowDemoWindow(). if (show_demo_window) { - ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); + ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); // Normally user code doesn't need/want to call this because positions are saved in .ini file anyway. Here we just want to make the demo initial state a bit more friendly! ImGui::ShowDemoWindow(&show_demo_window); } // Rendering - IwGxSetColClear(clear_color.x*255,clear_color.y*255,clear_color.z*255,clear_color.w*255) ; + IwGxSetColClear(clear_color.x * 255, clear_color.y * 255, clear_color.z * 255, clear_color.w * 255); IwGxClear(); ImGui::Render(); IwGxSwapBuffers(); diff --git a/examples/opengl2_example/main.cpp b/examples/opengl2_example/main.cpp index 35c8d19c7..ef098e54a 100644 --- a/examples/opengl2_example/main.cpp +++ b/examples/opengl2_example/main.cpp @@ -29,6 +29,10 @@ int main(int, char**) // Setup ImGui binding ImGui_ImplGlfwGL2_Init(window, true); + // Setup style + ImGui::StyleColorsClassic(); + //ImGui::StyleColorsDark(); + // Load Fonts // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. @@ -60,14 +64,16 @@ int main(int, char**) ImGui_ImplGlfwGL2_NewFrame(); // 1. Show a simple window. - // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug". + // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets automatically appears in a window called "Debug". { static float f = 0.0f; - ImGui::Text("Hello, world!"); - ImGui::SliderFloat("float", &f, 0.0f, 1.0f); - ImGui::ColorEdit3("clear color", (float*)&clear_color); - if (ImGui::Button("Demo Window")) show_demo_window ^= 1; - if (ImGui::Button("Another Window")) show_another_window ^= 1; + ImGui::Text("Hello, world!"); // Some text (you can use a format string too) + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float as a slider from 0.0f to 1.0f + ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats as a color + if (ImGui::Button("Demo Window")) // Use buttons to toggle our bools. We could use Checkbox() as well. + show_demo_window ^= 1; + if (ImGui::Button("Another Window")) + show_another_window ^= 1; ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); } @@ -82,7 +88,7 @@ int main(int, char**) // 3. Show the ImGui demo window. Most of the sample code is in ImGui::ShowDemoWindow(). if (show_demo_window) { - ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); + ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); // Normally user code doesn't need/want to call this because positions are saved in .ini file anyway. Here we just want to make the demo initial state a bit more friendly! ImGui::ShowDemoWindow(&show_demo_window); } diff --git a/examples/opengl3_example/main.cpp b/examples/opengl3_example/main.cpp index d10d58305..9e9a3fb6c 100644 --- a/examples/opengl3_example/main.cpp +++ b/examples/opengl3_example/main.cpp @@ -34,6 +34,10 @@ int main(int, char**) // Setup ImGui binding ImGui_ImplGlfwGL3_Init(window, true); + // Setup style + ImGui::StyleColorsClassic(); + //ImGui::StyleColorsDark(); + // Load Fonts // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. @@ -65,14 +69,16 @@ int main(int, char**) ImGui_ImplGlfwGL3_NewFrame(); // 1. Show a simple window. - // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug". + // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets automatically appears in a window called "Debug". { static float f = 0.0f; - ImGui::Text("Hello, world!"); - ImGui::SliderFloat("float", &f, 0.0f, 1.0f); - ImGui::ColorEdit3("clear color", (float*)&clear_color); - if (ImGui::Button("Demo Window")) show_demo_window ^= 1; - if (ImGui::Button("Another Window")) show_another_window ^= 1; + ImGui::Text("Hello, world!"); // Some text (you can use a format string too) + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float as a slider from 0.0f to 1.0f + ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats as a color + if (ImGui::Button("Demo Window")) // Use buttons to toggle our bools. We could use Checkbox() as well. + show_demo_window ^= 1; + if (ImGui::Button("Another Window")) + show_another_window ^= 1; ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); } @@ -87,7 +93,7 @@ int main(int, char**) // 3. Show the ImGui demo window. Most of the sample code is in ImGui::ShowDemoWindow(). if (show_demo_window) { - ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); + ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); // Normally user code doesn't need/want to call this because positions are saved in .ini file anyway. Here we just want to make the demo initial state a bit more friendly! ImGui::ShowDemoWindow(&show_demo_window); } diff --git a/examples/sdl_opengl2_example/main.cpp b/examples/sdl_opengl2_example/main.cpp index cc7c5fb7b..1396fcca0 100644 --- a/examples/sdl_opengl2_example/main.cpp +++ b/examples/sdl_opengl2_example/main.cpp @@ -35,6 +35,10 @@ int main(int, char**) // Setup ImGui binding ImGui_ImplSdlGL2_Init(window); + // Setup style + ImGui::StyleColorsClassic(); + //ImGui::StyleColorsDark(); + // Load Fonts // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. @@ -73,14 +77,16 @@ int main(int, char**) ImGui_ImplSdlGL2_NewFrame(window); // 1. Show a simple window - // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug". + // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets automatically appears in a window called "Debug". { static float f = 0.0f; - ImGui::Text("Hello, world!"); - ImGui::SliderFloat("float", &f, 0.0f, 1.0f); - ImGui::ColorEdit3("clear color", (float*)&clear_color); - if (ImGui::Button("Demo Window")) show_demo_window ^= 1; - if (ImGui::Button("Another Window")) show_another_window ^= 1; + ImGui::Text("Hello, world!"); // Some text (you can use a format string too) + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float as a slider from 0.0f to 1.0f + ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats as a color + if (ImGui::Button("Demo Window")) // Use buttons to toggle our bools. We could use Checkbox() as well. + show_demo_window ^= 1; + if (ImGui::Button("Another Window")) + show_another_window ^= 1; ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); } @@ -95,7 +101,7 @@ int main(int, char**) // 3. Show the ImGui demo window. Most of the sample code is in ImGui::ShowDemoWindow(). if (show_demo_window) { - ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); + ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); // Normally user code doesn't need/want to call this because positions are saved in .ini file anyway. Here we just want to make the demo initial state a bit more friendly! ImGui::ShowDemoWindow(&show_demo_window); } diff --git a/examples/sdl_opengl3_example/main.cpp b/examples/sdl_opengl3_example/main.cpp index a9e75fd4c..7ee60389c 100644 --- a/examples/sdl_opengl3_example/main.cpp +++ b/examples/sdl_opengl3_example/main.cpp @@ -35,6 +35,10 @@ int main(int, char**) // Setup ImGui binding ImGui_ImplSdlGL3_Init(window); + // Setup style + ImGui::StyleColorsClassic(); + //ImGui::StyleColorsDark(); + // Load Fonts // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. @@ -73,14 +77,16 @@ int main(int, char**) ImGui_ImplSdlGL3_NewFrame(window); // 1. Show a simple window. - // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug". + // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets automatically appears in a window called "Debug". { static float f = 0.0f; - ImGui::Text("Hello, world!"); - ImGui::SliderFloat("float", &f, 0.0f, 1.0f); - ImGui::ColorEdit3("clear color", (float*)&clear_color); - if (ImGui::Button("Demo Window")) show_demo_window ^= 1; - if (ImGui::Button("Another Window")) show_another_window ^= 1; + ImGui::Text("Hello, world!"); // Some text (you can use a format string too) + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float as a slider from 0.0f to 1.0f + ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats as a color + if (ImGui::Button("Demo Window")) // Use buttons to toggle our bools. We could use Checkbox() as well. + show_demo_window ^= 1; + if (ImGui::Button("Another Window")) + show_another_window ^= 1; ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); } @@ -95,7 +101,7 @@ int main(int, char**) // 3. Show the ImGui demo window. Most of the sample code is in ImGui::ShowDemoWindow(). if (show_demo_window) { - ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); + ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); // Normally user code doesn't need/want to call this because positions are saved in .ini file anyway. Here we just want to make the demo initial state a bit more friendly! ImGui::ShowDemoWindow(&show_demo_window); } diff --git a/examples/vulkan_example/main.cpp b/examples/vulkan_example/main.cpp index ec83035f9..81f420a01 100644 --- a/examples/vulkan_example/main.cpp +++ b/examples/vulkan_example/main.cpp @@ -625,6 +625,10 @@ int main(int, char**) init_data.check_vk_result = check_vk_result; ImGui_ImplGlfwVulkan_Init(window, true, &init_data); + // Setup style + ImGui::StyleColorsClassic(); + //ImGui::StyleColorsDark(); + // Load Fonts // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. @@ -694,14 +698,16 @@ int main(int, char**) ImGui_ImplGlfwVulkan_NewFrame(); // 1. Show a simple window. - // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug". + // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets automatically appears in a window called "Debug". { static float f = 0.0f; - ImGui::Text("Hello, world!"); - ImGui::SliderFloat("float", &f, 0.0f, 1.0f); - ImGui::ColorEdit3("clear color", (float*)&clear_color); - if (ImGui::Button("Demo Window")) show_demo_window ^= 1; - if (ImGui::Button("Another Window")) show_another_window ^= 1; + ImGui::Text("Hello, world!"); // Some text (you can use a format string too) + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float as a slider from 0.0f to 1.0f + ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats as a color + if (ImGui::Button("Demo Window")) // Use buttons to toggle our bools. We could use Checkbox() as well. + show_demo_window ^= 1; + if (ImGui::Button("Another Window")) + show_another_window ^= 1; ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); } @@ -716,7 +722,7 @@ int main(int, char**) // 3. Show the ImGui demo window. Most of the sample code is in ImGui::ShowDemoWindow(). if (show_demo_window) { - ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); + ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); // Normally user code doesn't need/want to call this because positions are saved in .ini file anyway. Here we just want to make the demo initial state a bit more friendly! ImGui::ShowDemoWindow(&show_demo_window); } From 3a4a2bb27c0f893843c23f4eb033b57e421fb745 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 24 Dec 2017 18:49:19 +0100 Subject: [PATCH 784/921] Examples: Vulkan: Tweak --- examples/vulkan_example/main.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/examples/vulkan_example/main.cpp b/examples/vulkan_example/main.cpp index 81f420a01..6c4ef33fe 100644 --- a/examples/vulkan_example/main.cpp +++ b/examples/vulkan_example/main.cpp @@ -726,11 +726,7 @@ int main(int, char**) ImGui::ShowDemoWindow(&show_demo_window); } - g_ClearValue.color.float32[0] = clear_color.x; - g_ClearValue.color.float32[1] = clear_color.y; - g_ClearValue.color.float32[2] = clear_color.z; - g_ClearValue.color.float32[3] = clear_color.w; - + memcpy(&g_ClearValue.color.float32[0], &clear_color, 4 * sizeof(float)); frame_begin(); ImGui_ImplGlfwVulkan_Render(g_CommandBuffer[g_FrameIndex]); frame_end(); From 8d54b1b7aff34111b6f64c0e076eb0b7a981ad9a Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 24 Dec 2017 18:59:14 +0100 Subject: [PATCH 785/921] Misc comments, removed duplicated IM_ARRAYSIZE macro in imgui_demo.cpp (it is now declared in imgui.h) --- imgui.cpp | 2 +- imgui_demo.cpp | 17 ++++++++--------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 14b2bd8c3..a2214220b 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -8,7 +8,7 @@ // Gallery (please post your screenshots/video there!): https://github.com/ocornut/imgui/issues/1269 // Developed by Omar Cornut and every direct or indirect contributors to the GitHub. // This library is free but I need your support to sustain development and maintenance. -// If you work for a company, please consider financial support, e.g: https://www.patreon.com/imgui +// If you work for a company, please consider financial support, see Readme. For individuals: https://www.patreon.com/imgui /* diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 204a17220..7a6a0fa21 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -7,16 +7,16 @@ // During development, you can call ImGui::ShowDemoWindow() in your code to learn about various features of ImGui. Have it wired in a debug menu! // Removing this file from your project is hindering access to documentation for everyone in your team, likely leading you to poorer usage of the library. // Note that you can #define IMGUI_DISABLE_DEMO_WINDOWS in imconfig.h for the same effect. -// If you want to link core ImGui in your public builds but not those demo windows, #define IMGUI_DISABLE_DEMO_WINDOWS in imconfig.h and those functions will be empty. -// For any other case, if you have ImGui available you probably want this to be available for reference and execution. +// If you want to link core ImGui in your final builds but not those demo windows, #define IMGUI_DISABLE_DEMO_WINDOWS in imconfig.h and those functions will be empty. +// In other situation, when you have ImGui available you probably want this to be available for reference and execution. // Thank you, // -Your beloved friend, imgui_demo.cpp (that you won't delete) -// Message to beginner C/C++ programmer about the meaning of 'static': in this demo code, we frequently we use 'static' variables inside functions. -// We do this as a way to gather code and data in the same place, make the demo code faster to read, faster to write, and smaller. A static variable persist across calls, -// so it is essentially like a global variable but declared inside the scope of the function. +// Message to beginner C/C++ programmers. About the meaning of 'static': in this demo code, we frequently we use 'static' variables inside functions. +// We do this as a way to gather code and data in the same place, just to make the demo code faster to read, faster to write, and use less code. +// A static variable persist across calls, so it is essentially like a global variable but declared inside the scope of the function. // It also happens to be a convenient way of storing simple UI related information as long as your function doesn't need to be reentrant or used in threads. -// This may be a pattern you want to use in your code (simple is beautiful!), but most of the real data you would be editing is likely to be stored outside your function. +// This might be a pattern you occasionally want to use in your code, but most of the real data you would be editing is likely to be stored outside your function. #if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) #define _CRT_SECURE_NO_WARNINGS @@ -52,18 +52,17 @@ #pragma GCC diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function #pragma GCC diagnostic ignored "-Wconversion" // warning: conversion to 'xxxx' from 'xxxx' may alter its value #if (__GNUC__ >= 6) -#pragma GCC diagnostic ignored "-Wmisleading-indentation" // warning: this 'if' clause does not guard this statement // GCC 6.0+ only. See #883 on github. +#pragma GCC diagnostic ignored "-Wmisleading-indentation" // warning: this 'if' clause does not guard this statement // GCC 6.0+ only. See #883 on GitHub. #endif #endif -// Play it nice with Windows users. Notepad in 2015 still doesn't display text data with Unix-style \n. +// Play it nice with Windows users. Notepad in 2017 still doesn't display text data with Unix-style \n. #ifdef _WIN32 #define IM_NEWLINE "\r\n" #else #define IM_NEWLINE "\n" #endif -#define IM_ARRAYSIZE(_ARR) ((int)(sizeof(_ARR)/sizeof(*_ARR))) #define IM_MAX(_A,_B) (((_A) >= (_B)) ? (_A) : (_B)) //----------------------------------------------------------------------------- From 78f48bb795e5ea54ec2f8e232dc1f06315af340b Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 25 Dec 2017 14:54:54 +0100 Subject: [PATCH 786/921] Examples: DirectX10,DirectX11: Moved call to OMSetRenderTargets() in main loop so example code can integrate more nicely with other code. --- examples/directx10_example/main.cpp | 2 +- examples/directx11_example/main.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/directx10_example/main.cpp b/examples/directx10_example/main.cpp index ecfc156a5..38f4054ea 100644 --- a/examples/directx10_example/main.cpp +++ b/examples/directx10_example/main.cpp @@ -27,7 +27,6 @@ void CreateRenderTarget() render_target_view_desc.ViewDimension = D3D10_RTV_DIMENSION_TEXTURE2D; g_pSwapChain->GetBuffer(0, __uuidof(ID3D10Texture2D), (LPVOID*)&pBackBuffer); g_pd3dDevice->CreateRenderTargetView(pBackBuffer, &render_target_view_desc, &g_mainRenderTargetView); - g_pd3dDevice->OMSetRenderTargets(1, &g_mainRenderTargetView, NULL); pBackBuffer->Release(); } @@ -196,6 +195,7 @@ int main(int, char**) } // Rendering + g_pd3dDevice->OMSetRenderTargets(1, &g_mainRenderTargetView, NULL); g_pd3dDevice->ClearRenderTargetView(g_mainRenderTargetView, (float*)&clear_color); ImGui::Render(); diff --git a/examples/directx11_example/main.cpp b/examples/directx11_example/main.cpp index d7eb1df24..79e7bb169 100644 --- a/examples/directx11_example/main.cpp +++ b/examples/directx11_example/main.cpp @@ -27,7 +27,6 @@ void CreateRenderTarget() render_target_view_desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; g_pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer); g_pd3dDevice->CreateRenderTargetView(pBackBuffer, &render_target_view_desc, &g_mainRenderTargetView); - g_pd3dDeviceContext->OMSetRenderTargets(1, &g_mainRenderTargetView, NULL); pBackBuffer->Release(); } @@ -199,6 +198,7 @@ int main(int, char**) } // Rendering + g_pd3dDeviceContext->OMSetRenderTargets(1, &g_mainRenderTargetView, NULL); g_pd3dDeviceContext->ClearRenderTargetView(g_mainRenderTargetView, (float*)&clear_color); ImGui::Render(); From 3849bb4470aebb4ff276113170f26cc82f990f49 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 25 Dec 2017 16:03:58 +0100 Subject: [PATCH 787/921] Moving window doesn't use accumulating MouseDelta so straying out of boundaries keeps moved window at the same spot. --- imgui.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index a2214220b..d8eba7a59 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2379,9 +2379,10 @@ void ImGui::NewFrame() IM_ASSERT(g.MovingWindow->MoveId == g.MovingWindowMoveId); if (g.IO.MouseDown[0]) { - g.MovingWindow->RootWindow->PosFloat += g.IO.MouseDelta; - if (g.IO.MouseDelta.x != 0.0f || g.IO.MouseDelta.y != 0.0f) + ImVec2 pos = g.IO.MousePos - g.ActiveIdClickOffset; + if (g.MovingWindow->RootWindow->PosFloat.x != pos.x || g.MovingWindow->RootWindow->PosFloat.y != pos.y) MarkIniSettingsDirty(g.MovingWindow->RootWindow); + g.MovingWindow->RootWindow->PosFloat = pos; FocusWindow(g.MovingWindow); } else @@ -2930,6 +2931,7 @@ void ImGui::EndFrame() g.MovingWindow = g.HoveredWindow; g.MovingWindowMoveId = g.MovingWindow->MoveId; SetActiveID(g.MovingWindowMoveId, g.HoveredRootWindow); + g.ActiveIdClickOffset = g.IO.MousePos - g.MovingWindow->RootWindow->Pos; } } else if (g.NavWindow != NULL && GetFrontMostModalRootWindow() == NULL) From 3d48f5b8c296aba88c5df6b76dfc23f5f32fe581 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 25 Dec 2017 17:40:47 +0100 Subject: [PATCH 788/921] Demo: BeginCombo() demo code --- imgui.h | 1 + imgui_demo.cpp | 26 +++++++++++++++++++++----- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/imgui.h b/imgui.h index 10d46ab05..bd9571cfb 100644 --- a/imgui.h +++ b/imgui.h @@ -300,6 +300,7 @@ namespace ImGui // Widgets: Combo Box // The new BeginCombo()/EndCombo() api allows you to manage your contents and selection state however you want it. + // The old Combo() api are helpers over BeginCombo()/EndCombo() which are kept available for convenience purpose. IMGUI_API bool BeginCombo(const char* label, const char* preview_value, ImGuiComboFlags flags = 0); IMGUI_API void EndCombo(); IMGUI_API bool Combo(const char* label, int* current_item, const char* const items[], int items_count, int popup_max_height_in_items = -1); diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 7a6a0fa21..966d80c52 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -322,12 +322,28 @@ void ImGui::ShowDemoWindow(bool* p_open) ImGui::LabelText("label", "Value"); - static int item = 1; - ImGui::Combo("combo", &item, "aaaa\0bbbb\0cccc\0dddd\0eeee\0\0"); // Combo using values packed in a single constant string (for really quick combo) + { + // Simplified one-liner Combo() API, using values packed in a single constant string + static int current_item_1 = 1; + ImGui::Combo("combo", ¤t_item_1, "aaaa\0bbbb\0cccc\0dddd\0eeee\0\0"); + //ImGui::Combo("combo w/ array of char*", ¤t_item_2_idx, items, IM_ARRAYSIZE(items)); // Combo using proper array. You can also pass a callback to retrieve array value, no need to create/copy an array just for that. - const char* items[] = { "AAAA", "BBBB", "CCCC", "DDDD", "EEEE", "FFFF", "GGGG", "HHHH", "IIII", "JJJJ", "KKKK", "LLLLLLL", "MMMM", "OOOOOOO", "PPPP", "QQQQQQQQQQ", "RRR", "SSSS" }; - static int item2 = -1; - ImGui::Combo("combo scroll", &item2, items, IM_ARRAYSIZE(items)); // Combo using proper array. You can also pass a callback to retrieve array value, no need to create/copy an array just for that. + // General BeginCombo() API, you have full control over your selection data and display type + const char* items[] = { "AAAA", "BBBB", "CCCC", "DDDD", "EEEE", "FFFF", "GGGG", "HHHH", "IIII", "JJJJ", "KKKK", "LLLLLLL", "MMMM", "OOOOOOO", "PPPP", "QQQQQQQQQQ", "RRR", "SSSS" }; + static const char* current_item_2 = NULL; + if (ImGui::BeginCombo("combo 2", current_item_2)) // The second parameter is the label previewed before opening the combo. + { + for (int n = 0; n < IM_ARRAYSIZE(items); n++) + { + bool is_selected = (current_item_2 == items[n]); // You can store your selection however you want, outside or inside your objects + if (ImGui::Selectable(items[n], is_selected)) + current_item_2 = items[n]; + if (is_selected) + ImGui::SetItemDefaultFocus(); // Set the initial focus when opening the combo (scrolling + for keyboard navigation support in the upcoming navigation branch) + } + ImGui::EndCombo(); + } + } { static char str0[128] = "Hello, world!"; From e916310b2e1f9cacbb2b9ce192a3dfb359e4b509 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 25 Dec 2017 17:41:41 +0100 Subject: [PATCH 789/921] Version 1.53 --- imgui.cpp | 2 +- imgui.h | 4 ++-- imgui_demo.cpp | 2 +- imgui_draw.cpp | 2 +- imgui_internal.h | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index d8eba7a59..075fb8c46 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.53 WIP +// dear imgui, v1.53 // (main code and documentation) // Call and read ImGui::ShowDemoWindow() in imgui_demo.cpp for demo code. diff --git a/imgui.h b/imgui.h index bd9571cfb..22e213985 100644 --- a/imgui.h +++ b/imgui.h @@ -1,4 +1,4 @@ -// dear imgui, v1.53 WIP +// dear imgui, v1.53 // (headers) // See imgui.cpp file for documentation. @@ -16,7 +16,7 @@ #include // ptrdiff_t, NULL #include // memset, memmove, memcpy, strlen, strchr, strcpy, strcmp -#define IMGUI_VERSION "1.53 WIP" +#define IMGUI_VERSION "1.53" // Define attributes of all API symbols declarations, e.g. for DLL under Windows. #ifndef IMGUI_API diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 966d80c52..d739dfa4e 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.53 WIP +// dear imgui, v1.53 // (demo code) // Message to the person tempted to delete this file when integrating ImGui into their code base: diff --git a/imgui_draw.cpp b/imgui_draw.cpp index bba523a38..6efb6bc62 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.53 WIP +// dear imgui, v1.53 // (drawing and font code) // Contains implementation for diff --git a/imgui_internal.h b/imgui_internal.h index e161a6f14..804353902 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1,4 +1,4 @@ -// dear imgui, v1.53 WIP +// dear imgui, v1.53 // (internals) // You may use this file to debug, understand or extend ImGui features but we don't provide any guarantee of forward compatibility! From 9511f22e8b07d8f2456c256c742c6048c585aba4 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 25 Dec 2017 18:47:44 +0100 Subject: [PATCH 790/921] Demo: Console: More friendly to text color changes. --- imgui_demo.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index d739dfa4e..a5864fefb 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -2616,12 +2616,13 @@ struct ExampleAppConsole ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(4,1)); // Tighten spacing if (copy_to_clipboard) ImGui::LogToClipboard(); + ImVec4 col_default_text = ImGui::GetStyleColorVec4(ImGuiCol_Text); for (int i = 0; i < Items.Size; i++) { const char* item = Items[i]; if (!filter.PassFilter(item)) continue; - ImVec4 col = ImVec4(1.0f,1.0f,1.0f,1.0f); // A better implementation may store a type per-item. For the sample let's just parse the text. + ImVec4 col = col_default_text; if (strstr(item, "[error]")) col = ImColor(1.0f,0.4f,0.4f,1.0f); else if (strncmp(item, "# ", 2) == 0) col = ImColor(1.0f,0.78f,0.58f,1.0f); ImGui::PushStyleColor(ImGuiCol_Text, col); From 149523a10185a0e4f7e6832198277cf35b27d7e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Branimir=20Karad=C5=BEi=C4=87?= Date: Mon, 25 Dec 2017 12:31:23 -0800 Subject: [PATCH 791/921] =?UTF-8?q?Fixing=20error:=20declaration=20of=20?= =?UTF-8?q?=E2=80=98size=E2=80=99=20shadows=20a=20member=20of=20'this'=20[?= =?UTF-8?q?-Werror=3Dshadow]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- imgui.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.h b/imgui.h index 22e213985..2304dad10 100644 --- a/imgui.h +++ b/imgui.h @@ -1041,7 +1041,7 @@ public: inline const value_type& back() const { IM_ASSERT(Size > 0); return Data[Size - 1]; } inline void swap(ImVector& rhs) { int rhs_size = rhs.Size; rhs.Size = Size; Size = rhs_size; int rhs_cap = rhs.Capacity; rhs.Capacity = Capacity; Capacity = rhs_cap; value_type* rhs_data = rhs.Data; rhs.Data = Data; Data = rhs_data; } - inline int _grow_capacity(int size) const { int new_capacity = Capacity ? (Capacity + Capacity/2) : 8; return new_capacity > size ? new_capacity : size; } + inline int _grow_capacity(int sz) const { int new_capacity = Capacity ? (Capacity + Capacity/2) : 8; return new_capacity > sz ? new_capacity : sz; } inline void resize(int new_size) { if (new_size > Capacity) reserve(_grow_capacity(new_size)); Size = new_size; } inline void resize(int new_size, const T& v){ if (new_size > Capacity) reserve(_grow_capacity(new_size)); if (new_size > Size) for (int n = Size; n < new_size; n++) Data[n] = v; Size = new_size; } From d9034bf2d81f72b283b108abde5b3118b5ace1a6 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 26 Dec 2017 15:36:55 +0100 Subject: [PATCH 792/921] ListBox() changed signature of ListBox() to match Combo(). Still not very happy about not using const char** anymore. (#931) --- imgui.cpp | 2 +- imgui.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 075fb8c46..dee18b4ea 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9502,7 +9502,7 @@ void ImGui::ListBoxFooter() EndGroup(); } -bool ImGui::ListBox(const char* label, int* current_item, const char* const* items, int items_count, int height_items) +bool ImGui::ListBox(const char* label, int* current_item, const char* const items[], int items_count, int height_items) { const bool value_changed = ListBox(label, current_item, Items_ArrayGetter, (void*)items, items_count, height_items); return value_changed; diff --git a/imgui.h b/imgui.h index 2304dad10..1b1e92b35 100644 --- a/imgui.h +++ b/imgui.h @@ -377,7 +377,7 @@ namespace ImGui // Widgets: Selectable / Lists IMGUI_API bool Selectable(const char* label, bool selected = false, ImGuiSelectableFlags flags = 0, const ImVec2& size = ImVec2(0,0)); // size.x==0.0: use remaining width, size.x>0.0: specify width. size.y==0.0: use label height, size.y>0.0: specify height IMGUI_API bool Selectable(const char* label, bool* p_selected, ImGuiSelectableFlags flags = 0, const ImVec2& size = ImVec2(0,0)); - IMGUI_API bool ListBox(const char* label, int* current_item, const char* const* items, int items_count, int height_in_items = -1); + IMGUI_API bool ListBox(const char* label, int* current_item, const char* const items[], int items_count, int height_in_items = -1); IMGUI_API bool ListBox(const char* label, int* current_item, bool (*items_getter)(void* data, int idx, const char** out_text), void* data, int items_count, int height_in_items = -1); IMGUI_API bool ListBoxHeader(const char* label, const ImVec2& size = ImVec2(0,0)); // use if you want to reimplement ListBox() will custom data or interactions. make sure to call ListBoxFooter() afterwards. IMGUI_API bool ListBoxHeader(const char* label, int items_count, int height_in_items = -1); // " From 7fd805497a5291c7adb6a77fc7fb564422e34344 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 26 Dec 2017 20:30:22 +0100 Subject: [PATCH 793/921] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 6ababf5b3..608468329 100644 --- a/README.md +++ b/README.md @@ -60,6 +60,7 @@ Languages: - ChaiScript: https://github.com/JuJuBoSc/imgui-chaiscript - D (DerelictImgui): https://github.com/Extrawurst/DerelictImgui - Go (go-imgui): https://github.com/Armored-Dragon/go-imgui +- Haxe/hxcpp (linc_imgui): https://github.com/Aidan63/linc_imgui - Lua: https://github.com/patrickriordan/imgui_lua_bindings - Odin: https://github.com/ThisDrunkDane/odin-dear_imgui - Pascal (imgui-pas): https://github.com/dpethes/imgui-pas From 6e30c33642f06e77f6f38c8f15e4447a745c6645 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 26 Dec 2017 21:04:17 +0100 Subject: [PATCH 794/921] Demo dinaries update --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 608468329..bf3099460 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ Binaries/Demo ------------- You should be able to build the examples from sources (tested on Windows/Mac/Linux). If you don't, let me know! If you want to have a quick look at some Dear ImGui features, you can download Windows binaries of the demo app here: -- [imgui-demo-binaries-20171013.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20171013.zip) (Windows binaries, Dear ImGui 1.52 WIP built 2017/10/13, 5 executables) +- [imgui-demo-binaries-20171226.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20171226.zip) (Windows binaries, Dear ImGui 1.53 built 2017/12/26, 5 executables) Bindings -------- From 49eed6e2d132e8fb27af3760061b8558e8bbb654 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 28 Dec 2017 15:17:35 +0100 Subject: [PATCH 795/921] Version 1.54 WIP --- imgui.cpp | 2 +- imgui.h | 4 ++-- imgui_demo.cpp | 2 +- imgui_draw.cpp | 2 +- imgui_internal.h | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index dee18b4ea..e0f1af4b9 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.53 +// dear imgui, v1.54 WIP // (main code and documentation) // Call and read ImGui::ShowDemoWindow() in imgui_demo.cpp for demo code. diff --git a/imgui.h b/imgui.h index 1b1e92b35..711e0271f 100644 --- a/imgui.h +++ b/imgui.h @@ -1,4 +1,4 @@ -// dear imgui, v1.53 +// dear imgui, v1.54 WIP // (headers) // See imgui.cpp file for documentation. @@ -16,7 +16,7 @@ #include // ptrdiff_t, NULL #include // memset, memmove, memcpy, strlen, strchr, strcpy, strcmp -#define IMGUI_VERSION "1.53" +#define IMGUI_VERSION "1.54 WIP" // Define attributes of all API symbols declarations, e.g. for DLL under Windows. #ifndef IMGUI_API diff --git a/imgui_demo.cpp b/imgui_demo.cpp index a5864fefb..94531a107 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.53 +// dear imgui, v1.54 WIP // (demo code) // Message to the person tempted to delete this file when integrating ImGui into their code base: diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 6efb6bc62..b56d90cfc 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.53 +// dear imgui, v1.54 WIP // (drawing and font code) // Contains implementation for diff --git a/imgui_internal.h b/imgui_internal.h index 804353902..797d66d62 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1,4 +1,4 @@ -// dear imgui, v1.53 +// dear imgui, v1.54 WIP // (internals) // You may use this file to debug, understand or extend ImGui features but we don't provide any guarantee of forward compatibility! From 563d04fdb118c72a9add2d2f8e98639eae6d1feb Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 28 Dec 2017 15:29:06 +0100 Subject: [PATCH 796/921] TreeNode: node with the ImGuiTreeNodeFlags_Leaf flag correctly disable highlight when DragDrop is active. (#143, #581) --- imgui.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index e0f1af4b9..50059632e 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -6702,7 +6702,8 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l // - OpenOnArrow .................... single-click on arrow to open // - OpenOnDoubleClick|OpenOnArrow .. single-click on arrow or double-click anywhere to open ImGuiButtonFlags button_flags = ImGuiButtonFlags_NoKeyModifiers | ((flags & ImGuiTreeNodeFlags_AllowItemOverlap) ? ImGuiButtonFlags_AllowItemOverlap : 0); - button_flags |= ImGuiButtonFlags_PressedOnDragDropHold; + if (!(flags & ImGuiTreeNodeFlags_Leaf)) + button_flags |= ImGuiButtonFlags_PressedOnDragDropHold; if (flags & ImGuiTreeNodeFlags_OpenOnDoubleClick) button_flags |= ImGuiButtonFlags_PressedOnDoubleClick | ((flags & ImGuiTreeNodeFlags_OpenOnArrow) ? ImGuiButtonFlags_PressedOnClickRelease : 0); From 06bea369c0ce977c1cb71e085d860a6644330297 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 28 Dec 2017 16:54:16 +0100 Subject: [PATCH 797/921] DragDrop: Added IsDragDropActive() helper which is useful for binding to decide how to handle mouse inputs. --- imgui.cpp | 6 ++++++ imgui.h | 1 + 2 files changed, 7 insertions(+) diff --git a/imgui.cpp b/imgui.cpp index 50059632e..45ed8ad8d 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -11478,6 +11478,12 @@ void ImGui::EndDragDropTarget() IM_ASSERT(g.DragDropActive); } +bool ImGui::IsDragDropActive() +{ + ImGuiContext& g = *GImGui; + return g.DragDropActive; +} + //----------------------------------------------------------------------------- // PLATFORM DEPENDENT HELPERS //----------------------------------------------------------------------------- diff --git a/imgui.h b/imgui.h index 711e0271f..4972443a2 100644 --- a/imgui.h +++ b/imgui.h @@ -433,6 +433,7 @@ namespace ImGui IMGUI_API bool BeginDragDropTarget(); // call after submitting an item that may receive an item. If this returns true, you can call AcceptDragDropPayload() + EndDragDropTarget() IMGUI_API const ImGuiPayload* AcceptDragDropPayload(const char* type, ImGuiDragDropFlags flags = 0); // accept contents of a given type. If ImGuiDragDropFlags_AcceptBeforeDelivery is set you can peek into the payload before the mouse button is released. IMGUI_API void EndDragDropTarget(); + IMGUI_API bool IsDragDropActive(); // Clipping IMGUI_API void PushClipRect(const ImVec2& clip_rect_min, const ImVec2& clip_rect_max, bool intersect_with_current_clip_rect); From e985baa35ddda960b48d87e9d384cdc77a691913 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 28 Dec 2017 17:05:52 +0100 Subject: [PATCH 798/921] Combo: When peeking into the popup window for alignment we check if the window was active, which is more correct. (no known issue in current codebase, but we'll need that change for later) --- imgui.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 45ed8ad8d..3c6df7011 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9230,14 +9230,15 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboF // Peak into expected window size so we can position it if (ImGuiWindow* popup_window = FindWindowByName(name)) - { - ImVec2 size_contents = CalcSizeContents(popup_window); - ImVec2 size_expected = CalcSizeAfterConstraint(popup_window, CalcSizeAutoFit(popup_window, size_contents)); - if (flags & ImGuiComboFlags_PopupAlignLeft) - popup_window->AutoPosLastDirection = ImGuiDir_Left; - ImVec2 pos = FindBestWindowPosForPopup(frame_bb.GetBL(), size_expected, &popup_window->AutoPosLastDirection, frame_bb, ImGuiPopupPositionPolicy_ComboBox); - SetNextWindowPos(pos); - } + if (popup_window->WasActive) + { + ImVec2 size_contents = CalcSizeContents(popup_window); + ImVec2 size_expected = CalcSizeAfterConstraint(popup_window, CalcSizeAutoFit(popup_window, size_contents)); + if (flags & ImGuiComboFlags_PopupAlignLeft) + popup_window->AutoPosLastDirection = ImGuiDir_Left; + ImVec2 pos = FindBestWindowPosForPopup(frame_bb.GetBL(), size_expected, &popup_window->AutoPosLastDirection, frame_bb, ImGuiPopupPositionPolicy_ComboBox); + SetNextWindowPos(pos); + } ImGuiWindowFlags window_flags = ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_Popup | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoSavedSettings; if (!Begin(name, NULL, window_flags)) From 90ff4ae5d16c2200cf6fdad2825ebb473d906899 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 28 Dec 2017 23:08:48 +0100 Subject: [PATCH 799/921] BeginPopupModal(): the conditional test for SetNextWindowPos() was polling the wrong window, which in practice made the test succeed all the time. --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 3c6df7011..10ef65be3 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3885,7 +3885,7 @@ bool ImGui::BeginPopupModal(const char* name, bool* p_open, ImGuiWindowFlags ext } // Center modal windows by default - if ((window->SetWindowPosAllowFlags & g.SetNextWindowPosCond) == 0) + if (g.SetNextWindowPosCond == 0) SetNextWindowPos(g.IO.DisplaySize * 0.5f, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f)); ImGuiWindowFlags flags = extra_flags|ImGuiWindowFlags_Popup|ImGuiWindowFlags_Modal|ImGuiWindowFlags_NoCollapse|ImGuiWindowFlags_NoSavedSettings; From 4ba2e8574433b049ce643eb13fc2fbfb3d222d33 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 28 Dec 2017 23:50:37 +0100 Subject: [PATCH 800/921] Demo: Tweak. Comments. Metrics: Added some Drag and Drop info. --- imgui.cpp | 9 +++++---- imgui_demo.cpp | 1 + 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 10ef65be3..2e16fb3f2 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2914,7 +2914,7 @@ void ImGui::EndFrame() IM_ASSERT(g.CurrentWindowStack.Size == 1); // Mismatched Begin()/End() calls if (g.CurrentWindow && !g.CurrentWindow->WriteAccessed) g.CurrentWindow->Active = false; - ImGui::End(); + End(); if (g.ActiveId == 0 && g.HoveredId == 0) { @@ -3715,7 +3715,7 @@ void ImGui::BeginTooltip() void ImGui::EndTooltip() { IM_ASSERT(GetCurrentWindowRead()->Flags & ImGuiWindowFlags_Tooltip); // Mismatched BeginTooltip()/EndTooltip() calls - ImGui::End(); + End(); } // Mark popup as open (toggle toward open state). @@ -4011,7 +4011,7 @@ void ImGui::EndChild() IM_ASSERT(window->Flags & ImGuiWindowFlags_ChildWindow); // Mismatched BeginChild()/EndChild() callss if (window->BeginCount > 1) { - ImGui::End(); + End(); } else { @@ -4021,7 +4021,7 @@ void ImGui::EndChild() sz.x = ImMax(4.0f, sz.x); if (window->AutoFitChildAxises & (1 << ImGuiAxis_Y)) sz.y = ImMax(4.0f, sz.y); - ImGui::End(); + End(); ImGuiWindow* parent_window = GetCurrentWindow(); ImRect bb(parent_window->DC.CursorPos, parent_window->DC.CursorPos + sz); @@ -11730,6 +11730,7 @@ void ImGui::ShowMetricsWindow(bool* p_open) ImGui::Text("ActiveId: 0x%08X/0x%08X (%.2f sec)", g.ActiveId, g.ActiveIdPreviousFrame, g.ActiveIdTimer); ImGui::Text("ActiveIdWindow: '%s'", g.ActiveIdWindow ? g.ActiveIdWindow->Name : "NULL"); ImGui::Text("NavWindow: '%s'", g.NavWindow ? g.NavWindow->Name : "NULL"); + ImGui::Text("DragDrop: %d, SourceId = 0x%08X, Payload \"%s\" (%d bytes)", g.DragDropActive, g.DragDropPayload.SourceId, g.DragDropPayload.DataType, g.DragDropPayload.DataSize); ImGui::TreePop(); } } diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 94531a107..1ccc2990e 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -2365,6 +2365,7 @@ static void ShowExampleAppFixedOverlay(bool* p_open) if (ImGui::MenuItem("Top-right", NULL, corner == 1)) corner = 1; if (ImGui::MenuItem("Bottom-left", NULL, corner == 2)) corner = 2; if (ImGui::MenuItem("Bottom-right", NULL, corner == 3)) corner = 3; + if (p_open && ImGui::MenuItem("Close")) *p_open = false; ImGui::EndPopup(); } ImGui::End(); From 4fbdb50dca435741531d775f2ea6239ccf13e151 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 28 Dec 2017 23:51:58 +0100 Subject: [PATCH 801/921] MenuBar: Fixed menu bar pushing a clipping rect outside of its allocated bound (usually unnoticeable). --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 2e16fb3f2..479e8eaf0 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9632,7 +9632,7 @@ bool ImGui::BeginMenuBar() // We remove 1 worth of rounding to Max.x to that text in long menus don't tend to display over the lower-right rounded area, which looks particularly glitchy. ImRect bar_rect = window->MenuBarRect(); ImRect clip_rect(ImFloor(bar_rect.Min.x + 0.5f), ImFloor(bar_rect.Min.y + window->WindowBorderSize + 0.5f), ImFloor(ImMax(bar_rect.Min.x, bar_rect.Max.x - window->WindowRounding) + 0.5f), ImFloor(bar_rect.Max.y + 0.5f)); - clip_rect.ClipWith(window->Rect()); + clip_rect.ClipWith(window->WindowRectClipped); PushClipRect(clip_rect.Min, clip_rect.Max, false); window->DC.CursorPos = ImVec2(bar_rect.Min.x + window->DC.MenuBarOffsetX, bar_rect.Min.y);// + g.Style.FramePadding.y); From 9f8632b131e1bd282f733ab31301dd8c49515e4a Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 29 Dec 2017 15:03:36 +0100 Subject: [PATCH 802/921] Examples: Comments about invalid mouse pos. --- examples/marmalade_example/imgui_impl_marmalade.cpp | 2 +- examples/opengl2_example/imgui_impl_glfw.cpp | 2 +- examples/opengl3_example/imgui_impl_glfw_gl3.cpp | 2 +- examples/sdl_opengl2_example/imgui_impl_sdl.cpp | 2 +- examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp | 2 +- examples/vulkan_example/imgui_impl_glfw_vulkan.cpp | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/marmalade_example/imgui_impl_marmalade.cpp b/examples/marmalade_example/imgui_impl_marmalade.cpp index 6ecffa736..cae1be185 100644 --- a/examples/marmalade_example/imgui_impl_marmalade.cpp +++ b/examples/marmalade_example/imgui_impl_marmalade.cpp @@ -273,7 +273,7 @@ void ImGui_Marmalade_NewFrame() double mouse_x, mouse_y; mouse_x = s3ePointerGetX(); mouse_y = s3ePointerGetY(); - io.MousePos = ImVec2((float)mouse_x/g_scale.x, (float)mouse_y/g_scale.y); // Mouse position in screen coordinates (set to -1,-1 if no mouse / on another screen, etc.) + io.MousePos = ImVec2((float)mouse_x/g_scale.x, (float)mouse_y/g_scale.y); // Mouse position (set to -FLT_MAX,-FLT_MAX if no mouse / on another screen, etc.) for (int i = 0; i < 3; i++) { diff --git a/examples/opengl2_example/imgui_impl_glfw.cpp b/examples/opengl2_example/imgui_impl_glfw.cpp index 364d92889..33df611e7 100644 --- a/examples/opengl2_example/imgui_impl_glfw.cpp +++ b/examples/opengl2_example/imgui_impl_glfw.cpp @@ -281,7 +281,7 @@ void ImGui_ImplGlfwGL2_NewFrame() { double mouse_x, mouse_y; glfwGetCursorPos(g_Window, &mouse_x, &mouse_y); - io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Get mouse position in screen coordinates (set to -1,-1 if no mouse / on another screen, etc.) + io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); } } else diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp index 7d924fcf1..6c439fa18 100644 --- a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp +++ b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp @@ -393,7 +393,7 @@ void ImGui_ImplGlfwGL3_NewFrame() { double mouse_x, mouse_y; glfwGetCursorPos(g_Window, &mouse_x, &mouse_y); - io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Get mouse position in screen coordinates (set to -1,-1 if no mouse / on another screen, etc.) + io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); } } else diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl.cpp b/examples/sdl_opengl2_example/imgui_impl_sdl.cpp index 66f3ed5a8..baf5c0176 100644 --- a/examples/sdl_opengl2_example/imgui_impl_sdl.cpp +++ b/examples/sdl_opengl2_example/imgui_impl_sdl.cpp @@ -276,7 +276,7 @@ void ImGui_ImplSdlGL2_NewFrame(SDL_Window *window) int mx, my; Uint32 mouseMask = SDL_GetMouseState(&mx, &my); if (SDL_GetWindowFlags(window) & SDL_WINDOW_MOUSE_FOCUS) - io.MousePos = ImVec2((float)mx, (float)my); // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.) + io.MousePos = ImVec2((float)mx, (float)my); else io.MousePos = ImVec2(-FLT_MAX,-FLT_MAX); diff --git a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp index 68e27a68c..93849cf8b 100644 --- a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp +++ b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp @@ -387,7 +387,7 @@ void ImGui_ImplSdlGL3_NewFrame(SDL_Window* window) int mx, my; Uint32 mouseMask = SDL_GetMouseState(&mx, &my); if (SDL_GetWindowFlags(window) & SDL_WINDOW_MOUSE_FOCUS) - io.MousePos = ImVec2((float)mx, (float)my); // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.) + io.MousePos = ImVec2((float)mx, (float)my); else io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); diff --git a/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp b/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp index 1d12e3f77..8eb35ec3c 100644 --- a/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp +++ b/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp @@ -811,7 +811,7 @@ void ImGui_ImplGlfwVulkan_NewFrame() { double mouse_x, mouse_y; glfwGetCursorPos(g_Window, &mouse_x, &mouse_y); - io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position in screen coordinates (set to -1,-1 if no mouse / on another screen, etc.) + io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); } else { From 2dd2ca0096767721fa5b845f5dc733bbf2e10822 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 29 Dec 2017 17:59:13 +0100 Subject: [PATCH 803/921] Removed CalcItemRectClosestPoint() which was weird and not really used by anyone except demo code. If you need it it's easy to replicate on your side. Removed internal corresponding ImRect::GetClosestPoint() for now. Essentially revert dcaafffe0ed21c9b03530a911785ded80e14358f. --- imgui.cpp | 9 +-------- imgui.h | 2 +- imgui_demo.cpp | 2 +- imgui_internal.h | 10 ---------- 4 files changed, 3 insertions(+), 20 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 479e8eaf0..4b8f8aa47 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -213,6 +213,7 @@ Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. Also read releases logs https://github.com/ocornut/imgui/releases for more details. + - 2017/12/29 (1.54) - removed CalcItemRectClosestPoint() which was weird and not really used by anyone except demo code. If you need it it's easy to replicate on your side. - 2017/12/24 (1.53) - renamed the emblematic ShowTestWindow() function to ShowDemoWindow(). Kept redirection function (will obsolete). - 2017/12/21 (1.53) - ImDrawList: renamed style.AntiAliasedShapes to style.AntiAliasedFill for consistency and as a way to explicitly break code that manipulate those flag at runtime. You can now manipulate ImDrawList::Flags - 2017/12/21 (1.53) - ImDrawList: removed 'bool anti_aliased = true' final parameter of ImDrawList::AddPolyline() and ImDrawList::AddConvexPolyFilled(). Prefer manipulating ImDrawList::Flags if you need to toggle them during the frame. @@ -3658,14 +3659,6 @@ ImVec2 ImGui::GetItemRectSize() return window->DC.LastItemRect.GetSize(); } -ImVec2 ImGui::CalcItemRectClosestPoint(const ImVec2& pos, bool on_edge, float outward) -{ - ImGuiWindow* window = GetCurrentWindowRead(); - ImRect rect = window->DC.LastItemRect; - rect.Expand(outward); - return rect.GetClosestPoint(pos, on_edge); -} - static ImRect GetVisibleRect() { ImGuiContext& g = *GImGui; diff --git a/imgui.h b/imgui.h index 4972443a2..79ce272c7 100644 --- a/imgui.h +++ b/imgui.h @@ -472,7 +472,6 @@ namespace ImGui IMGUI_API ImDrawList* GetOverlayDrawList(); // this draw list will be the last rendered one, useful to quickly draw overlays shapes/text IMGUI_API ImDrawListSharedData* GetDrawListSharedData(); IMGUI_API const char* GetStyleColorName(ImGuiCol idx); - IMGUI_API ImVec2 CalcItemRectClosestPoint(const ImVec2& pos, bool on_edge = false, float outward = +0.0f); // utility to find the closest point the last item bounding rectangle edge. useful to visually link items IMGUI_API ImVec2 CalcTextSize(const char* text, const char* text_end = NULL, bool hide_text_after_double_hash = false, float wrap_width = -1.0f); IMGUI_API void CalcListClipping(int items_count, float items_height, int* out_items_display_start, int* out_items_display_end); // calculate coarse clipping for large list of evenly sized items. Prefer using the ImGuiListClipper higher-level helper if you can. @@ -987,6 +986,7 @@ struct ImGuiIO #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS namespace ImGui { + static inline ImVec2 CalcItemRectClosestPoint(const ImVec2& pos, bool on_edge = false, float outward = +0.0f) { (void)on_edge; (void)outward; return pos; } // OBSOLETE 1.54+ static inline void ShowTestWindow() { return ShowDemoWindow(); } // OBSOLETE 1.53+ static inline bool IsRootWindowFocused() { return IsWindowFocused(ImGuiFocusedFlags_RootWindow); } // OBSOLETE 1.53+ static inline bool IsRootWindowOrAnyChildFocused() { return IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows); } // OBSOLETE 1.53+ diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 1ccc2990e..c9d47d4df 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1894,7 +1894,7 @@ void ImGui::ShowDemoWindow(bool* p_open) // Draw a line between the button and the mouse cursor ImDrawList* draw_list = ImGui::GetWindowDrawList(); draw_list->PushClipRectFullScreen(); - draw_list->AddLine(ImGui::CalcItemRectClosestPoint(io.MousePos, true, -2.0f), io.MousePos, ImColor(ImGui::GetStyle().Colors[ImGuiCol_Button]), 4.0f); + draw_list->AddLine(io.MouseClickedPos[0], io.MousePos, ImGui::GetColorU32(ImGuiCol_Button), 4.0f); draw_list->PopClipRect(); // Drag operations gets "unlocked" when the mouse has moved past a certain threshold (the default threshold is stored in io.MouseDragThreshold) diff --git a/imgui_internal.h b/imgui_internal.h index 797d66d62..fc0ef6029 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -290,16 +290,6 @@ struct IMGUI_API ImRect void Floor() { Min.x = (float)(int)Min.x; Min.y = (float)(int)Min.y; Max.x = (float)(int)Max.x; Max.y = (float)(int)Max.y; } void FixInverted() { if (Min.x > Max.x) ImSwap(Min.x, Max.x); if (Min.y > Max.y) ImSwap(Min.y, Max.y); } bool IsFinite() const { return Min.x != FLT_MAX; } - ImVec2 GetClosestPoint(ImVec2 p, bool on_edge) const - { - if (!on_edge && Contains(p)) - return p; - if (p.x > Max.x) p.x = Max.x; - else if (p.x < Min.x) p.x = Min.x; - if (p.y > Max.y) p.y = Max.y; - else if (p.y < Min.y) p.y = Min.y; - return p; - } }; // Stacked color modifier, backup of modified data so we can restore it From eef9120e07331f251b53eb9ef8387dbd7c70bf8e Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 29 Dec 2017 18:14:36 +0100 Subject: [PATCH 804/921] Reorganized comments in the IMGUI_DISABLE_OBSOLETE_FUNCTIONS function. Added an IM_ASSERT(0). --- imgui.h | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/imgui.h b/imgui.h index 79ce272c7..f5ac95f89 100644 --- a/imgui.h +++ b/imgui.h @@ -980,26 +980,31 @@ struct ImGuiIO }; //----------------------------------------------------------------------------- -// Obsolete functions (Will be removed! Also see 'API BREAKING CHANGES' section in imgui.cpp) +// Obsolete functions (Will be removed! Read 'API BREAKING CHANGES' section in imgui.cpp for details) //----------------------------------------------------------------------------- #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS namespace ImGui { - static inline ImVec2 CalcItemRectClosestPoint(const ImVec2& pos, bool on_edge = false, float outward = +0.0f) { (void)on_edge; (void)outward; return pos; } // OBSOLETE 1.54+ - static inline void ShowTestWindow() { return ShowDemoWindow(); } // OBSOLETE 1.53+ - static inline bool IsRootWindowFocused() { return IsWindowFocused(ImGuiFocusedFlags_RootWindow); } // OBSOLETE 1.53+ - static inline bool IsRootWindowOrAnyChildFocused() { return IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows); } // OBSOLETE 1.53+ - static inline void SetNextWindowContentWidth(float width) { SetNextWindowContentSize(ImVec2(width, 0.0f)); } // OBSOLETE 1.53+ (nb: original version preserved last Y value set by SetNextWindowContentSize()) - static inline bool IsRootWindowOrAnyChildHovered(ImGuiHoveredFlags flags = 0) { return IsItemHovered(flags | ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows); } // OBSOLETE 1.53+ use flags directly - bool Begin(const char* name, bool* p_open, const ImVec2& size_on_first_use, float bg_alpha_override = -1.0f, ImGuiWindowFlags flags = 0); // OBSOLETE 1.52+. use SetNextWindowSize() instead if you want to set a window size. - static inline void AlignFirstTextHeightToWidgets() { AlignTextToFramePadding(); } // OBSOLETE 1.52+ - static inline void SetNextWindowPosCenter(ImGuiCond cond = 0) { SetNextWindowPos(ImVec2(GetIO().DisplaySize.x * 0.5f, GetIO().DisplaySize.y * 0.5f), cond, ImVec2(0.5f, 0.5f)); } // OBSOLETE 1.52+ - static inline bool IsItemHoveredRect() { return IsItemHovered(ImGuiHoveredFlags_RectOnly); } // OBSOLETE 1.51+ - static inline bool IsPosHoveringAnyWindow(const ImVec2&) { IM_ASSERT(0); return false; } // OBSOLETE 1.51+. This was partly broken. You probably wanted to use ImGui::GetIO().WantCaptureMouse instead. - static inline bool IsMouseHoveringAnyWindow() { return IsAnyWindowHovered(); } // OBSOLETE 1.51+ - static inline bool IsMouseHoveringWindow() { return IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem); } // OBSOLETE 1.51+ - static inline bool CollapsingHeader(const char* label, const char* str_id, bool framed = true, bool default_open = false) { (void)str_id; (void)framed; ImGuiTreeNodeFlags default_open_flags = 1 << 5; return CollapsingHeader(label, (default_open ? default_open_flags : 0)); } // OBSOLETE 1.49+ + // OBSOLETED in 1.54 (from Dec 2017) + static inline ImVec2 CalcItemRectClosestPoint(const ImVec2& pos, bool on_edge = false, float outward = 0.f) { (void)on_edge; (void)outward; IM_ASSERT(0); return pos; } + // OBSOLETED in 1.53 (between Oct 2017 and Dec 2017) + static inline void ShowTestWindow() { return ShowDemoWindow(); } + static inline bool IsRootWindowFocused() { return IsWindowFocused(ImGuiFocusedFlags_RootWindow); } + static inline bool IsRootWindowOrAnyChildFocused() { return IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows); } + static inline void SetNextWindowContentWidth(float w) { SetNextWindowContentSize(ImVec2(w, 0.0f)); } + // OBSOLETED in 1.52 (between Aug 2017 and Oct 2017) + bool Begin(const char* name, bool* p_open, const ImVec2& size_on_first_use, float bg_alpha_override = -1.0f, ImGuiWindowFlags flags = 0); // Use SetNextWindowSize() instead if you want to set a window size. + static inline bool IsRootWindowOrAnyChildHovered() { return IsItemHovered(ImGuiHoveredFlags_RootAndChildWindows); } // Use flags directly! + static inline void AlignFirstTextHeightToWidgets() { AlignTextToFramePadding(); } + static inline void SetNextWindowPosCenter(ImGuiCond c=0) { ImGuiIO& io = GetIO(); SetNextWindowPos(ImVec2(io.DisplaySize.x * 0.5f, io.DisplaySize.y * 0.5f), c, ImVec2(0.5f, 0.5f)); } + // OBSOLETED in 1.51 (between Jun 2017 and Aug 2017) + static inline bool IsItemHoveredRect() { return IsItemHovered(ImGuiHoveredFlags_RectOnly); } + static inline bool IsPosHoveringAnyWindow(const ImVec2&) { IM_ASSERT(0); return false; } // This was misleading and partly broken. You probably want to use the ImGui::GetIO().WantCaptureMouse flag instead. + static inline bool IsMouseHoveringAnyWindow() { return IsAnyWindowHovered(); } + static inline bool IsMouseHoveringWindow() { return IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem); } + // OBSOLETED IN 1.49 (between Apr 2016 and May 2016) + static inline bool CollapsingHeader(const char* label, const char* str_id, bool framed = true, bool default_open = false) { (void)str_id; (void)framed; ImGuiTreeNodeFlags default_open_flags = 1 << 5; return CollapsingHeader(label, (default_open ? default_open_flags : 0)); } } #endif From fbf2435f38725d2f9e38faf83cd72d2540af0b5d Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 29 Dec 2017 17:18:31 +0100 Subject: [PATCH 805/921] Exposed IM_OFFSETOF() helper in imgui.h --- imgui.h | 1 + imgui_internal.h | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/imgui.h b/imgui.h index f5ac95f89..a8dd3435b 100644 --- a/imgui.h +++ b/imgui.h @@ -39,6 +39,7 @@ #define IM_FMTLIST(FMT) #endif #define IM_ARRAYSIZE(_ARR) ((int)(sizeof(_ARR)/sizeof(*_ARR))) +#define IM_OFFSETOF(_TYPE,_ELM) ((size_t)&(((_TYPE*)0)->_ELM)) #if defined(__clang__) #pragma clang diagnostic push diff --git a/imgui_internal.h b/imgui_internal.h index fc0ef6029..49e1e012b 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -77,8 +77,7 @@ extern IMGUI_API ImGuiContext* GImGui; // Current implicit ImGui context pointe // Helpers //----------------------------------------------------------------------------- -#define IM_PI 3.14159265358979323846f -#define IM_OFFSETOF(_TYPE,_ELM) ((size_t)&(((_TYPE*)0)->_ELM)) +#define IM_PI 3.14159265358979323846f // Helpers: UTF-8 <> wchar IMGUI_API int ImTextStrToUtf8(char* buf, int buf_size, const ImWchar* in_text, const ImWchar* in_text_end); // return output UTF-8 bytes count From 6ec00a366a59ad91781d4743238ebae18142f0b2 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 29 Dec 2017 18:28:04 +0100 Subject: [PATCH 806/921] Internals: ImRect: Minor formatting tweaks. --- imgui_internal.h | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/imgui_internal.h b/imgui_internal.h index 49e1e012b..7f538adec 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -269,26 +269,26 @@ struct IMGUI_API ImRect ImRect(const ImVec4& v) : Min(v.x, v.y), Max(v.z, v.w) {} ImRect(float x1, float y1, float x2, float y2) : Min(x1, y1), Max(x2, y2) {} - ImVec2 GetCenter() const { return ImVec2((Min.x+Max.x)*0.5f, (Min.y+Max.y)*0.5f); } - ImVec2 GetSize() const { return ImVec2(Max.x-Min.x, Max.y-Min.y); } - float GetWidth() const { return Max.x-Min.x; } - float GetHeight() const { return Max.y-Min.y; } - ImVec2 GetTL() const { return Min; } // Top-left - ImVec2 GetTR() const { return ImVec2(Max.x, Min.y); } // Top-right - ImVec2 GetBL() const { return ImVec2(Min.x, Max.y); } // Bottom-left - ImVec2 GetBR() const { return Max; } // Bottom-right - bool Contains(const ImVec2& p) const { return p.x >= Min.x && p.y >= Min.y && p.x < Max.x && p.y < Max.y; } - bool Contains(const ImRect& r) const { return r.Min.x >= Min.x && r.Min.y >= Min.y && r.Max.x < Max.x && r.Max.y < Max.y; } - bool Overlaps(const ImRect& r) const { return r.Min.y < Max.y && r.Max.y > Min.y && r.Min.x < Max.x && r.Max.x > Min.x; } - void Add(const ImVec2& rhs) { if (Min.x > rhs.x) Min.x = rhs.x; if (Min.y > rhs.y) Min.y = rhs.y; if (Max.x < rhs.x) Max.x = rhs.x; if (Max.y < rhs.y) Max.y = rhs.y; } - void Add(const ImRect& rhs) { if (Min.x > rhs.Min.x) Min.x = rhs.Min.x; if (Min.y > rhs.Min.y) Min.y = rhs.Min.y; if (Max.x < rhs.Max.x) Max.x = rhs.Max.x; if (Max.y < rhs.Max.y) Max.y = rhs.Max.y; } - void Expand(const float amount) { Min.x -= amount; Min.y -= amount; Max.x += amount; Max.y += amount; } - void Expand(const ImVec2& amount) { Min.x -= amount.x; Min.y -= amount.y; Max.x += amount.x; Max.y += amount.y; } - void Translate(const ImVec2& v) { Min.x += v.x; Min.y += v.y; Max.x += v.x; Max.y += v.y; } - void ClipWith(const ImRect& clip) { if (Min.x < clip.Min.x) Min.x = clip.Min.x; if (Min.y < clip.Min.y) Min.y = clip.Min.y; if (Max.x > clip.Max.x) Max.x = clip.Max.x; if (Max.y > clip.Max.y) Max.y = clip.Max.y; } - void Floor() { Min.x = (float)(int)Min.x; Min.y = (float)(int)Min.y; Max.x = (float)(int)Max.x; Max.y = (float)(int)Max.y; } - void FixInverted() { if (Min.x > Max.x) ImSwap(Min.x, Max.x); if (Min.y > Max.y) ImSwap(Min.y, Max.y); } - bool IsFinite() const { return Min.x != FLT_MAX; } + ImVec2 GetCenter() const { return ImVec2((Min.x + Max.x) * 0.5f, (Min.y + Max.y) * 0.5f); } + ImVec2 GetSize() const { return ImVec2(Max.x - Min.x, Max.y - Min.y); } + float GetWidth() const { return Max.x - Min.x; } + float GetHeight() const { return Max.y - Min.y; } + ImVec2 GetTL() const { return Min; } // Top-left + ImVec2 GetTR() const { return ImVec2(Max.x, Min.y); } // Top-right + ImVec2 GetBL() const { return ImVec2(Min.x, Max.y); } // Bottom-left + ImVec2 GetBR() const { return Max; } // Bottom-right + bool Contains(const ImVec2& p) const { return p.x >= Min.x && p.y >= Min.y && p.x < Max.x && p.y < Max.y; } + bool Contains(const ImRect& r) const { return r.Min.x >= Min.x && r.Min.y >= Min.y && r.Max.x < Max.x && r.Max.y < Max.y; } + bool Overlaps(const ImRect& r) const { return r.Min.y < Max.y && r.Max.y > Min.y && r.Min.x < Max.x && r.Max.x > Min.x; } + void Add(const ImVec2& p) { if (Min.x > p.x) Min.x = p.x; if (Min.y > p.y) Min.y = p.y; if (Max.x < p.x) Max.x = p.x; if (Max.y < p.y) Max.y = p.y; } + void Add(const ImRect& r) { if (Min.x > r.Min.x) Min.x = r.Min.x; if (Min.y > r.Min.y) Min.y = r.Min.y; if (Max.x < r.Max.x) Max.x = r.Max.x; if (Max.y < r.Max.y) Max.y = r.Max.y; } + void Expand(const float amount) { Min.x -= amount; Min.y -= amount; Max.x += amount; Max.y += amount; } + void Expand(const ImVec2& amount) { Min.x -= amount.x; Min.y -= amount.y; Max.x += amount.x; Max.y += amount.y; } + void Translate(const ImVec2& v) { Min.x += v.x; Min.y += v.y; Max.x += v.x; Max.y += v.y; } + void ClipWith(const ImRect& r) { if (Min.x < r.Min.x) Min.x = r.Min.x; if (Min.y < r.Min.y) Min.y = r.Min.y; if (Max.x > r.Max.x) Max.x = r.Max.x; if (Max.y > r.Max.y) Max.y = r.Max.y; } + void Floor() { Min.x = (float)(int)Min.x; Min.y = (float)(int)Min.y; Max.x = (float)(int)Max.x; Max.y = (float)(int)Max.y; } + void FixInverted() { if (Min.x > Max.x) ImSwap(Min.x, Max.x); if (Min.y > Max.y) ImSwap(Min.y, Max.y); } + bool IsFinite() const { return Min.x != FLT_MAX; } }; // Stacked color modifier, backup of modified data so we can restore it From 4af84ac781bff28ca063fae6bc3d2683e502517f Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 30 Dec 2017 23:10:11 +0100 Subject: [PATCH 807/921] ImFontAtlas: Handle stb_truetype failure more gracefully, GetTexDataAsRGBA32() won't crash during conversion. (#1527) --- imgui_draw.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index b56d90cfc..3de85da86 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1439,11 +1439,14 @@ void ImFontAtlas::GetTexDataAsRGBA32(unsigned char** out_pixels, int* out_wid { unsigned char* pixels; GetTexDataAsAlpha8(&pixels, NULL, NULL); - TexPixelsRGBA32 = (unsigned int*)ImGui::MemAlloc((size_t)(TexWidth * TexHeight * 4)); - const unsigned char* src = pixels; - unsigned int* dst = TexPixelsRGBA32; - for (int n = TexWidth * TexHeight; n > 0; n--) - *dst++ = IM_COL32(255, 255, 255, (unsigned int)(*src++)); + if (pixels) + { + TexPixelsRGBA32 = (unsigned int*)ImGui::MemAlloc((size_t)(TexWidth * TexHeight * 4)); + const unsigned char* src = pixels; + unsigned int* dst = TexPixelsRGBA32; + for (int n = TexWidth * TexHeight; n > 0; n--) + *dst++ = IM_COL32(255, 255, 255, (unsigned int)(*src++)); + } } *out_pixels = (unsigned char*)TexPixelsRGBA32; @@ -1683,6 +1686,7 @@ bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas) IM_ASSERT(font_offset >= 0); if (!stbtt_InitFont(&tmp.FontInfo, (unsigned char*)cfg.FontData, font_offset)) { + atlas->TexWidth = atlas->TexHeight = 0; // Reset output on failure ImGui::MemFree(tmp_array); return false; } From 170bcb2d7c247595761bfb07b36755aa6541f4cf Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 29 Dec 2017 20:56:52 +0100 Subject: [PATCH 808/921] Internals: NewFrame: Shuffled some code around (to minimize upcoming patches) --- imgui.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 4b8f8aa47..b9ceb11df 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2276,15 +2276,16 @@ void ImGui::NewFrame() if (!g.Initialized) Initialize(); + g.Time += g.IO.DeltaTime; + g.FrameCount += 1; + g.TooltipOverrideCount = 0; + g.WindowsActiveCount = 0; + SetCurrentFont(GetDefaultFont()); IM_ASSERT(g.Font->IsLoaded()); g.DrawListSharedData.ClipRectFullscreen = ImVec4(0.0f, 0.0f, g.IO.DisplaySize.x, g.IO.DisplaySize.y); g.DrawListSharedData.CurveTessellationTol = g.Style.CurveTessellationTol; - g.Time += g.IO.DeltaTime; - g.FrameCount += 1; - g.TooltipOverrideCount = 0; - g.WindowsActiveCount = 0; g.OverlayDrawList.Clear(); g.OverlayDrawList.PushTextureID(g.IO.Fonts->TexID); g.OverlayDrawList.PushClipRectFullScreen(); From 561e9f286eee47f3a651f2bb3a1f6d021179e7ee Mon Sep 17 00:00:00 2001 From: Cory McWilliams Date: Tue, 2 Jan 2018 10:46:20 -0500 Subject: [PATCH 809/921] Fix a memory leak of ImGuiColumnsSet's Columns vector. ImVector doesn't call destructors. --- imgui.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/imgui.cpp b/imgui.cpp index b9ceb11df..2b6b699a7 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1876,6 +1876,8 @@ ImGuiWindow::~ImGuiWindow() { IM_DELETE(DrawList); IM_DELETE(Name); + for (int i = 0; i != ColumnsStorage.Size; i++) + ColumnsStorage[i].~ImGuiColumnsSet(); } ImGuiID ImGuiWindow::GetID(const char* str, const char* str_end) From 856ee17ed8f73023701cb9642bfe02902be1777a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Branimir=20Karad=C5=BEi=C4=87?= Date: Tue, 2 Jan 2018 16:20:51 -0800 Subject: [PATCH 810/921] Fixed Android clang warning. --- imgui_draw.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 3de85da86..c7232af8f 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -42,7 +42,9 @@ #pragma clang diagnostic ignored "-Wfloat-equal" // warning : comparing floating point with == or != is unsafe // storing and comparing against same constants ok. #pragma clang diagnostic ignored "-Wglobal-constructors" // warning : declaration requires a global destructor // similar to above, not sure what the exact difference it. #pragma clang diagnostic ignored "-Wsign-conversion" // warning : implicit conversion changes signedness // +#if __has_warning("-Wcomma") #pragma clang diagnostic ignored "-Wcomma" // warning : possible misuse of comma operator here // +#endif #if __has_warning("-Wreserved-id-macro") #pragma clang diagnostic ignored "-Wreserved-id-macro" // warning : macro name is a reserved identifier // #endif From 04b44398eb2602d40c5688c1f092b7340bf30f82 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 3 Jan 2018 12:12:41 +0100 Subject: [PATCH 811/921] Internals: refactored g.SetNextWindow fields into g.NextWindow. structure (so it can be more easily transported/copied) --- imgui.cpp | 116 +++++++++++++++++++++++------------------------ imgui_internal.h | 69 +++++++++++++++------------- 2 files changed, 95 insertions(+), 90 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 2b6b699a7..1e257e0da 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2632,8 +2632,8 @@ void ImGui::Shutdown() g.FontStack.clear(); g.OpenPopupStack.clear(); g.CurrentPopupStack.clear(); - g.SetNextWindowSizeConstraintCallback = NULL; - g.SetNextWindowSizeConstraintCallbackUserData = NULL; + g.NextWindow.SizeConstraintCallback = NULL; + g.NextWindow.SizeConstraintCallbackUserData = NULL; for (int i = 0; i < IM_ARRAYSIZE(g.RenderDrawLists); i++) g.RenderDrawLists[i].clear(); g.OverlayDrawList.ClearFreeMemory(); @@ -3820,8 +3820,8 @@ static inline void ClearSetNextWindowData() { // FIXME-OPT ImGuiContext& g = *GImGui; - g.SetNextWindowPosCond = g.SetNextWindowSizeCond = g.SetNextWindowContentSizeCond = g.SetNextWindowCollapsedCond = 0; - g.SetNextWindowSizeConstraint = g.SetNextWindowFocus = false; + g.NextWindow.PosCond = g.NextWindow.SizeCond = g.NextWindow.ContentSizeCond = g.NextWindow.CollapsedCond = 0; + g.NextWindow.SizeConstraint = g.NextWindow.Focus = false; } bool ImGui::BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_flags) @@ -3881,7 +3881,7 @@ bool ImGui::BeginPopupModal(const char* name, bool* p_open, ImGuiWindowFlags ext } // Center modal windows by default - if (g.SetNextWindowPosCond == 0) + if (g.NextWindow.PosCond == 0) SetNextWindowPos(g.IO.DisplaySize * 0.5f, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f)); ImGuiWindowFlags flags = extra_flags|ImGuiWindowFlags_Popup|ImGuiWindowFlags_Modal|ImGuiWindowFlags_NoCollapse|ImGuiWindowFlags_NoSavedSettings; @@ -4193,20 +4193,20 @@ static ImGuiWindow* CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFl static ImVec2 CalcSizeAfterConstraint(ImGuiWindow* window, ImVec2 new_size) { ImGuiContext& g = *GImGui; - if (g.SetNextWindowSizeConstraint) + if (g.NextWindow.SizeConstraint) { // Using -1,-1 on either X/Y axis to preserve the current size. - ImRect cr = g.SetNextWindowSizeConstraintRect; + ImRect cr = g.NextWindow.SizeConstraintRect; new_size.x = (cr.Min.x >= 0 && cr.Max.x >= 0) ? ImClamp(new_size.x, cr.Min.x, cr.Max.x) : window->SizeFull.x; new_size.y = (cr.Min.y >= 0 && cr.Max.y >= 0) ? ImClamp(new_size.y, cr.Min.y, cr.Max.y) : window->SizeFull.y; - if (g.SetNextWindowSizeConstraintCallback) + if (g.NextWindow.SizeConstraintCallback) { ImGuiSizeConstraintCallbackData data; - data.UserData = g.SetNextWindowSizeConstraintCallbackUserData; + data.UserData = g.NextWindow.SizeConstraintCallbackUserData; data.Pos = window->Pos; data.CurrentSize = window->SizeFull; data.DesiredSize = new_size; - g.SetNextWindowSizeConstraintCallback(&data); + g.NextWindow.SizeConstraintCallback(&data); new_size = data.DesiredSize; } } @@ -4352,7 +4352,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) ImGuiWindow* window = FindWindowByName(name); if (!window) { - ImVec2 size_on_first_use = (g.SetNextWindowSizeCond != 0) ? g.SetNextWindowSizeVal : ImVec2(0.0f, 0.0f); // Any condition flag will do since we are creating a new window here. + ImVec2 size_on_first_use = (g.NextWindow.SizeCond != 0) ? g.NextWindow.SizeVal : ImVec2(0.0f, 0.0f); // Any condition flag will do since we are creating a new window here. window = CreateNewWindow(name, size_on_first_use, flags); } @@ -4397,50 +4397,50 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // Process SetNextWindow***() calls bool window_pos_set_by_api = false; bool window_size_x_set_by_api = false, window_size_y_set_by_api = false; - if (g.SetNextWindowPosCond) + if (g.NextWindow.PosCond) { - window_pos_set_by_api = (window->SetWindowPosAllowFlags & g.SetNextWindowPosCond) != 0; - if (window_pos_set_by_api && ImLengthSqr(g.SetNextWindowPosPivot) > 0.00001f) + window_pos_set_by_api = (window->SetWindowPosAllowFlags & g.NextWindow.PosCond) != 0; + if (window_pos_set_by_api && ImLengthSqr(g.NextWindow.PosPivotVal) > 0.00001f) { // May be processed on the next frame if this is our first frame and we are measuring size // FIXME: Look into removing the branch so everything can go through this same code path for consistency. - window->SetWindowPosVal = g.SetNextWindowPosVal; - window->SetWindowPosPivot = g.SetNextWindowPosPivot; + window->SetWindowPosVal = g.NextWindow.PosVal; + window->SetWindowPosPivot = g.NextWindow.PosPivotVal; window->SetWindowPosAllowFlags &= ~(ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing); } else { - SetWindowPos(window, g.SetNextWindowPosVal, g.SetNextWindowPosCond); + SetWindowPos(window, g.NextWindow.PosVal, g.NextWindow.PosCond); } - g.SetNextWindowPosCond = 0; + g.NextWindow.PosCond = 0; } - if (g.SetNextWindowSizeCond) + if (g.NextWindow.SizeCond) { - window_size_x_set_by_api = (window->SetWindowSizeAllowFlags & g.SetNextWindowSizeCond) != 0 && (g.SetNextWindowSizeVal.x > 0.0f); - window_size_y_set_by_api = (window->SetWindowSizeAllowFlags & g.SetNextWindowSizeCond) != 0 && (g.SetNextWindowSizeVal.y > 0.0f); - SetWindowSize(window, g.SetNextWindowSizeVal, g.SetNextWindowSizeCond); - g.SetNextWindowSizeCond = 0; + window_size_x_set_by_api = (window->SetWindowSizeAllowFlags & g.NextWindow.SizeCond) != 0 && (g.NextWindow.SizeVal.x > 0.0f); + window_size_y_set_by_api = (window->SetWindowSizeAllowFlags & g.NextWindow.SizeCond) != 0 && (g.NextWindow.SizeVal.y > 0.0f); + SetWindowSize(window, g.NextWindow.SizeVal, g.NextWindow.SizeCond); + g.NextWindow.SizeCond = 0; } - if (g.SetNextWindowContentSizeCond) + if (g.NextWindow.ContentSizeCond) { // Adjust passed "client size" to become a "window size" - window->SizeContentsExplicit = g.SetNextWindowContentSizeVal; + window->SizeContentsExplicit = g.NextWindow.ContentSizeVal; window->SizeContentsExplicit.y += window->TitleBarHeight() + window->MenuBarHeight(); - g.SetNextWindowContentSizeCond = 0; + g.NextWindow.ContentSizeCond = 0; } else if (first_begin_of_the_frame) { window->SizeContentsExplicit = ImVec2(0.0f, 0.0f); } - if (g.SetNextWindowCollapsedCond) + if (g.NextWindow.CollapsedCond) { - SetWindowCollapsed(window, g.SetNextWindowCollapsedVal, g.SetNextWindowCollapsedCond); - g.SetNextWindowCollapsedCond = 0; + SetWindowCollapsed(window, g.NextWindow.CollapsedVal, g.NextWindow.CollapsedCond); + g.NextWindow.CollapsedCond = 0; } - if (g.SetNextWindowFocus) + if (g.NextWindow.Focus) { SetWindowFocus(); - g.SetNextWindowFocus = false; + g.NextWindow.Focus = false; } if (window->Appearing) SetWindowConditionAllowFlags(window, ImGuiCond_Appearing, false); @@ -4940,7 +4940,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->WriteAccessed = false; window->BeginCount++; - g.SetNextWindowSizeConstraint = false; + g.NextWindow.SizeConstraint = false; // Child window can be out of sight and have "negative" clip windows. // Mark them as collapsed so commands are skipped earlier (we can't manually collapse because they have no title bar). @@ -5702,45 +5702,45 @@ void ImGui::SetWindowFocus(const char* name) void ImGui::SetNextWindowPos(const ImVec2& pos, ImGuiCond cond, const ImVec2& pivot) { ImGuiContext& g = *GImGui; - g.SetNextWindowPosVal = pos; - g.SetNextWindowPosPivot = pivot; - g.SetNextWindowPosCond = cond ? cond : ImGuiCond_Always; + g.NextWindow.PosVal = pos; + g.NextWindow.PosPivotVal = pivot; + g.NextWindow.PosCond = cond ? cond : ImGuiCond_Always; } void ImGui::SetNextWindowSize(const ImVec2& size, ImGuiCond cond) { ImGuiContext& g = *GImGui; - g.SetNextWindowSizeVal = size; - g.SetNextWindowSizeCond = cond ? cond : ImGuiCond_Always; + g.NextWindow.SizeVal = size; + g.NextWindow.SizeCond = cond ? cond : ImGuiCond_Always; } void ImGui::SetNextWindowSizeConstraints(const ImVec2& size_min, const ImVec2& size_max, ImGuiSizeConstraintCallback custom_callback, void* custom_callback_user_data) { ImGuiContext& g = *GImGui; - g.SetNextWindowSizeConstraint = true; - g.SetNextWindowSizeConstraintRect = ImRect(size_min, size_max); - g.SetNextWindowSizeConstraintCallback = custom_callback; - g.SetNextWindowSizeConstraintCallbackUserData = custom_callback_user_data; + g.NextWindow.SizeConstraint = true; + g.NextWindow.SizeConstraintRect = ImRect(size_min, size_max); + g.NextWindow.SizeConstraintCallback = custom_callback; + g.NextWindow.SizeConstraintCallbackUserData = custom_callback_user_data; } void ImGui::SetNextWindowContentSize(const ImVec2& size) { ImGuiContext& g = *GImGui; - g.SetNextWindowContentSizeVal = size; // In Begin() we will add the size of window decorations (title bar, menu etc.) to that to form a SizeContents value. - g.SetNextWindowContentSizeCond = ImGuiCond_Always; + g.NextWindow.ContentSizeVal = size; // In Begin() we will add the size of window decorations (title bar, menu etc.) to that to form a SizeContents value. + g.NextWindow.ContentSizeCond = ImGuiCond_Always; } void ImGui::SetNextWindowCollapsed(bool collapsed, ImGuiCond cond) { ImGuiContext& g = *GImGui; - g.SetNextWindowCollapsedVal = collapsed; - g.SetNextWindowCollapsedCond = cond ? cond : ImGuiCond_Always; + g.NextWindow.CollapsedVal = collapsed; + g.NextWindow.CollapsedCond = cond ? cond : ImGuiCond_Always; } void ImGui::SetNextWindowFocus() { ImGuiContext& g = *GImGui; - g.SetNextWindowFocus = true; + g.NextWindow.Focus = true; } // In window space (not screen space!) @@ -6615,11 +6615,11 @@ bool ImGui::TreeNodeBehaviorIsOpen(ImGuiID id, ImGuiTreeNodeFlags flags) ImGuiStorage* storage = window->DC.StateStorage; bool is_open; - if (g.SetNextTreeNodeOpenCond != 0) + if (g.NextTreeNodeOpenCond != 0) { - if (g.SetNextTreeNodeOpenCond & ImGuiCond_Always) + if (g.NextTreeNodeOpenCond & ImGuiCond_Always) { - is_open = g.SetNextTreeNodeOpenVal; + is_open = g.NextTreeNodeOpenVal; storage->SetInt(id, is_open); } else @@ -6628,7 +6628,7 @@ bool ImGui::TreeNodeBehaviorIsOpen(ImGuiID id, ImGuiTreeNodeFlags flags) const int stored_value = storage->GetInt(id, -1); if (stored_value == -1) { - is_open = g.SetNextTreeNodeOpenVal; + is_open = g.NextTreeNodeOpenVal; storage->SetInt(id, is_open); } else @@ -6636,7 +6636,7 @@ bool ImGui::TreeNodeBehaviorIsOpen(ImGuiID id, ImGuiTreeNodeFlags flags) is_open = stored_value != 0; } } - g.SetNextTreeNodeOpenCond = 0; + g.NextTreeNodeOpenCond = 0; } else { @@ -6903,8 +6903,8 @@ void ImGui::SetNextTreeNodeOpen(bool is_open, ImGuiCond cond) ImGuiContext& g = *GImGui; if (g.CurrentWindow->SkipItems) return; - g.SetNextTreeNodeOpenVal = is_open; - g.SetNextTreeNodeOpenCond = cond ? cond : ImGuiCond_Always; + g.NextTreeNodeOpenVal = is_open; + g.NextTreeNodeOpenCond = cond ? cond : ImGuiCond_Always; } void ImGui::PushID(const char* str_id) @@ -9163,8 +9163,8 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboF { // Always consume the SetNextWindowSizeConstraint() call in our early return paths ImGuiContext& g = *GImGui; - bool backup_has_next_window_size_constraint = g.SetNextWindowSizeConstraint; - g.SetNextWindowSizeConstraint = false; + bool backup_has_next_window_size_constraint = g.NextWindow.SizeConstraint; + g.NextWindow.SizeConstraint = false; ImGuiWindow* window = GetCurrentWindow(); if (window->SkipItems) @@ -9206,8 +9206,8 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboF if (backup_has_next_window_size_constraint) { - g.SetNextWindowSizeConstraint = true; - g.SetNextWindowSizeConstraintRect.Min.x = ImMax(g.SetNextWindowSizeConstraintRect.Min.x, w); + g.NextWindow.SizeConstraint = true; + g.NextWindow.SizeConstraintRect.Min.x = ImMax(g.NextWindow.SizeConstraintRect.Min.x, w); } else { @@ -9269,7 +9269,7 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi items_getter(data, *current_item, &preview_text); // The old Combo() API exposed "popup_max_height_in_items", however the new more general BeginCombo() API doesn't, so we emulate it here. - if (popup_max_height_in_items != -1 && !g.SetNextWindowSizeConstraint) + if (popup_max_height_in_items != -1 && !g.NextWindow.SizeConstraint) { float popup_max_height = CalcMaxPopupHeightFromItemCount(popup_max_height_in_items); SetNextWindowSizeConstraints(ImVec2(0,0), ImVec2(FLT_MAX, popup_max_height)); diff --git a/imgui_internal.h b/imgui_internal.h index 7f538adec..7877e3ffe 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -459,6 +459,38 @@ struct ImDrawListSharedData ImDrawListSharedData(); }; +// Storage for SetNexWindow** functions +struct ImGuiNextWindowData +{ + ImGuiCond PosCond; + ImGuiCond SizeCond; + ImGuiCond ContentSizeCond; + ImGuiCond CollapsedCond; + ImVec2 PosVal; + ImVec2 PosPivotVal; + ImVec2 SizeVal; + ImVec2 ContentSizeVal; + bool CollapsedVal; + ImRect SizeConstraintRect; // Valid if 'SetNextWindowSizeConstraint' is true + ImGuiSizeConstraintCallback SizeConstraintCallback; + void* SizeConstraintCallbackUserData; + bool SizeConstraint; + bool Focus; + + ImGuiNextWindowData() + { + PosCond = SizeCond = ContentSizeCond = CollapsedCond = 0; + PosVal = PosPivotVal = SizeVal = ImVec2(0.0f, 0.0f); + ContentSizeVal = ImVec2(0.0f, 0.0f); + CollapsedVal = false; + SizeConstraintRect = ImRect(); + SizeConstraintCallback = NULL; + SizeConstraintCallbackUserData = NULL; + SizeConstraint = false; + Focus = false; + } +}; + // Main state for ImGui struct ImGuiContext { @@ -502,24 +534,9 @@ struct ImGuiContext ImVector FontStack; // Stack for PushFont()/PopFont() ImVector OpenPopupStack; // Which popups are open (persistent) ImVector CurrentPopupStack; // Which level of BeginPopup() we are in (reset every frame) - - // Storage for SetNexWindow** and SetNextTreeNode*** functions - ImVec2 SetNextWindowPosVal; - ImVec2 SetNextWindowPosPivot; - ImVec2 SetNextWindowSizeVal; - ImVec2 SetNextWindowContentSizeVal; - bool SetNextWindowCollapsedVal; - ImGuiCond SetNextWindowPosCond; - ImGuiCond SetNextWindowSizeCond; - ImGuiCond SetNextWindowContentSizeCond; - ImGuiCond SetNextWindowCollapsedCond; - ImRect SetNextWindowSizeConstraintRect; // Valid if 'SetNextWindowSizeConstraint' is true - ImGuiSizeConstraintCallback SetNextWindowSizeConstraintCallback; - void* SetNextWindowSizeConstraintCallbackUserData; - bool SetNextWindowSizeConstraint; - bool SetNextWindowFocus; - bool SetNextTreeNodeOpenVal; - ImGuiCond SetNextTreeNodeOpenCond; + ImGuiNextWindowData NextWindow; // Storage for SetNextWindow** functions + bool NextTreeNodeOpenVal; // Storage for SetNextTreeNode** functions + ImGuiCond NextTreeNodeOpenCond; // Render ImDrawData RenderDrawData; // Main ImDrawData instance to pass render information to the user @@ -609,20 +626,8 @@ struct ImGuiContext MovingWindow = NULL; MovingWindowMoveId = 0; - SetNextWindowPosVal = ImVec2(0.0f, 0.0f); - SetNextWindowSizeVal = ImVec2(0.0f, 0.0f); - SetNextWindowCollapsedVal = false; - SetNextWindowPosCond = 0; - SetNextWindowSizeCond = 0; - SetNextWindowContentSizeCond = 0; - SetNextWindowCollapsedCond = 0; - SetNextWindowSizeConstraintRect = ImRect(); - SetNextWindowSizeConstraintCallback = NULL; - SetNextWindowSizeConstraintCallbackUserData = NULL; - SetNextWindowSizeConstraint = false; - SetNextWindowFocus = false; - SetNextTreeNodeOpenVal = false; - SetNextTreeNodeOpenCond = 0; + NextTreeNodeOpenVal = false; + NextTreeNodeOpenCond = 0; DragDropActive = false; DragDropSourceFlags = 0; From e339949de1c01f3eb2f2d4815f5e8f0f44287229 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 3 Jan 2018 12:22:02 +0100 Subject: [PATCH 812/921] Internals: NextWindow: Using ImGuiCond for consistency. --- imgui.cpp | 25 ++++++++++++------------- imgui_internal.h | 8 +++----- 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 1e257e0da..b303170e5 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3820,8 +3820,7 @@ static inline void ClearSetNextWindowData() { // FIXME-OPT ImGuiContext& g = *GImGui; - g.NextWindow.PosCond = g.NextWindow.SizeCond = g.NextWindow.ContentSizeCond = g.NextWindow.CollapsedCond = 0; - g.NextWindow.SizeConstraint = g.NextWindow.Focus = false; + g.NextWindow.PosCond = g.NextWindow.SizeCond = g.NextWindow.ContentSizeCond = g.NextWindow.CollapsedCond = g.NextWindow.SizeConstraintCond = g.NextWindow.FocusCond = 0; } bool ImGui::BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_flags) @@ -4193,7 +4192,7 @@ static ImGuiWindow* CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFl static ImVec2 CalcSizeAfterConstraint(ImGuiWindow* window, ImVec2 new_size) { ImGuiContext& g = *GImGui; - if (g.NextWindow.SizeConstraint) + if (g.NextWindow.SizeConstraintCond != 0) { // Using -1,-1 on either X/Y axis to preserve the current size. ImRect cr = g.NextWindow.SizeConstraintRect; @@ -4437,10 +4436,10 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) SetWindowCollapsed(window, g.NextWindow.CollapsedVal, g.NextWindow.CollapsedCond); g.NextWindow.CollapsedCond = 0; } - if (g.NextWindow.Focus) + if (g.NextWindow.FocusCond) { SetWindowFocus(); - g.NextWindow.Focus = false; + g.NextWindow.FocusCond = 0; } if (window->Appearing) SetWindowConditionAllowFlags(window, ImGuiCond_Appearing, false); @@ -4940,7 +4939,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->WriteAccessed = false; window->BeginCount++; - g.NextWindow.SizeConstraint = false; + g.NextWindow.SizeConstraintCond = 0; // Child window can be out of sight and have "negative" clip windows. // Mark them as collapsed so commands are skipped earlier (we can't manually collapse because they have no title bar). @@ -5717,7 +5716,7 @@ void ImGui::SetNextWindowSize(const ImVec2& size, ImGuiCond cond) void ImGui::SetNextWindowSizeConstraints(const ImVec2& size_min, const ImVec2& size_max, ImGuiSizeConstraintCallback custom_callback, void* custom_callback_user_data) { ImGuiContext& g = *GImGui; - g.NextWindow.SizeConstraint = true; + g.NextWindow.SizeConstraintCond = ImGuiCond_Always; g.NextWindow.SizeConstraintRect = ImRect(size_min, size_max); g.NextWindow.SizeConstraintCallback = custom_callback; g.NextWindow.SizeConstraintCallbackUserData = custom_callback_user_data; @@ -5740,7 +5739,7 @@ void ImGui::SetNextWindowCollapsed(bool collapsed, ImGuiCond cond) void ImGui::SetNextWindowFocus() { ImGuiContext& g = *GImGui; - g.NextWindow.Focus = true; + g.NextWindow.FocusCond = ImGuiCond_Always; } // In window space (not screen space!) @@ -9163,8 +9162,8 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboF { // Always consume the SetNextWindowSizeConstraint() call in our early return paths ImGuiContext& g = *GImGui; - bool backup_has_next_window_size_constraint = g.NextWindow.SizeConstraint; - g.NextWindow.SizeConstraint = false; + ImGuiCond backup_next_window_size_constraint = g.NextWindow.SizeConstraintCond; + g.NextWindow.SizeConstraintCond = 0; ImGuiWindow* window = GetCurrentWindow(); if (window->SkipItems) @@ -9204,9 +9203,9 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboF if (!popup_open) return false; - if (backup_has_next_window_size_constraint) + if (backup_next_window_size_constraint) { - g.NextWindow.SizeConstraint = true; + g.NextWindow.SizeConstraintCond = backup_next_window_size_constraint; g.NextWindow.SizeConstraintRect.Min.x = ImMax(g.NextWindow.SizeConstraintRect.Min.x, w); } else @@ -9269,7 +9268,7 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi items_getter(data, *current_item, &preview_text); // The old Combo() API exposed "popup_max_height_in_items", however the new more general BeginCombo() API doesn't, so we emulate it here. - if (popup_max_height_in_items != -1 && !g.NextWindow.SizeConstraint) + if (popup_max_height_in_items != -1 && !g.NextWindow.SizeConstraintCond) { float popup_max_height = CalcMaxPopupHeightFromItemCount(popup_max_height_in_items); SetNextWindowSizeConstraints(ImVec2(0,0), ImVec2(FLT_MAX, popup_max_height)); diff --git a/imgui_internal.h b/imgui_internal.h index 7877e3ffe..f66e99eb2 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -466,6 +466,8 @@ struct ImGuiNextWindowData ImGuiCond SizeCond; ImGuiCond ContentSizeCond; ImGuiCond CollapsedCond; + ImGuiCond SizeConstraintCond; + ImGuiCond FocusCond; ImVec2 PosVal; ImVec2 PosPivotVal; ImVec2 SizeVal; @@ -474,20 +476,16 @@ struct ImGuiNextWindowData ImRect SizeConstraintRect; // Valid if 'SetNextWindowSizeConstraint' is true ImGuiSizeConstraintCallback SizeConstraintCallback; void* SizeConstraintCallbackUserData; - bool SizeConstraint; - bool Focus; ImGuiNextWindowData() { - PosCond = SizeCond = ContentSizeCond = CollapsedCond = 0; + PosCond = SizeCond = ContentSizeCond = CollapsedCond = SizeConstraintCond = FocusCond = 0; PosVal = PosPivotVal = SizeVal = ImVec2(0.0f, 0.0f); ContentSizeVal = ImVec2(0.0f, 0.0f); CollapsedVal = false; SizeConstraintRect = ImRect(); SizeConstraintCallback = NULL; SizeConstraintCallbackUserData = NULL; - SizeConstraint = false; - Focus = false; } }; From 7fcbd4550010d53ec294fc7aa239ea97f76dfdf4 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 3 Jan 2018 12:28:16 +0100 Subject: [PATCH 813/921] Internals: NextWindow: Renamed, moved functions to member. --- imgui.cpp | 110 +++++++++++++++++++++-------------------------- imgui_internal.h | 7 ++- 2 files changed, 56 insertions(+), 61 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index b303170e5..ae85abf06 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -642,7 +642,6 @@ static void SetWindowSize(ImGuiWindow* window, const ImVec2& size, I static void SetWindowCollapsed(ImGuiWindow* window, bool collapsed, ImGuiCond cond); static ImGuiWindow* FindHoveredWindow(ImVec2 pos); static ImGuiWindow* CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFlags flags); -static void ClearSetNextWindowData(); static void CheckStacksSize(ImGuiWindow* window, bool write); static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window); @@ -2632,8 +2631,6 @@ void ImGui::Shutdown() g.FontStack.clear(); g.OpenPopupStack.clear(); g.CurrentPopupStack.clear(); - g.NextWindow.SizeConstraintCallback = NULL; - g.NextWindow.SizeConstraintCallbackUserData = NULL; for (int i = 0; i < IM_ARRAYSIZE(g.RenderDrawLists); i++) g.RenderDrawLists[i].clear(); g.OverlayDrawList.ClearFreeMemory(); @@ -3816,19 +3813,12 @@ void ImGui::CloseCurrentPopup() ClosePopupToLevel(popup_idx); } -static inline void ClearSetNextWindowData() -{ - // FIXME-OPT - ImGuiContext& g = *GImGui; - g.NextWindow.PosCond = g.NextWindow.SizeCond = g.NextWindow.ContentSizeCond = g.NextWindow.CollapsedCond = g.NextWindow.SizeConstraintCond = g.NextWindow.FocusCond = 0; -} - bool ImGui::BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_flags) { ImGuiContext& g = *GImGui; if (!IsPopupOpen(id)) { - ClearSetNextWindowData(); // We behave like Begin() and need to consume those values + g.NextWindowData.Clear(); // We behave like Begin() and need to consume those values return false; } @@ -3850,7 +3840,7 @@ bool ImGui::BeginPopup(const char* str_id) ImGuiContext& g = *GImGui; if (g.OpenPopupStack.Size <= g.CurrentPopupStack.Size) // Early out for performance { - ClearSetNextWindowData(); // We behave like Begin() and need to consume those values + g.NextWindowData.Clear(); // We behave like Begin() and need to consume those values return false; } return BeginPopupEx(g.CurrentWindow->GetID(str_id), ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoSavedSettings); @@ -3875,12 +3865,12 @@ bool ImGui::BeginPopupModal(const char* name, bool* p_open, ImGuiWindowFlags ext const ImGuiID id = window->GetID(name); if (!IsPopupOpen(id)) { - ClearSetNextWindowData(); // We behave like Begin() and need to consume those values + g.NextWindowData.Clear(); // We behave like Begin() and need to consume those values return false; } // Center modal windows by default - if (g.NextWindow.PosCond == 0) + if (g.NextWindowData.PosCond == 0) SetNextWindowPos(g.IO.DisplaySize * 0.5f, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f)); ImGuiWindowFlags flags = extra_flags|ImGuiWindowFlags_Popup|ImGuiWindowFlags_Modal|ImGuiWindowFlags_NoCollapse|ImGuiWindowFlags_NoSavedSettings; @@ -4192,20 +4182,20 @@ static ImGuiWindow* CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFl static ImVec2 CalcSizeAfterConstraint(ImGuiWindow* window, ImVec2 new_size) { ImGuiContext& g = *GImGui; - if (g.NextWindow.SizeConstraintCond != 0) + if (g.NextWindowData.SizeConstraintCond != 0) { // Using -1,-1 on either X/Y axis to preserve the current size. - ImRect cr = g.NextWindow.SizeConstraintRect; + ImRect cr = g.NextWindowData.SizeConstraintRect; new_size.x = (cr.Min.x >= 0 && cr.Max.x >= 0) ? ImClamp(new_size.x, cr.Min.x, cr.Max.x) : window->SizeFull.x; new_size.y = (cr.Min.y >= 0 && cr.Max.y >= 0) ? ImClamp(new_size.y, cr.Min.y, cr.Max.y) : window->SizeFull.y; - if (g.NextWindow.SizeConstraintCallback) + if (g.NextWindowData.SizeConstraintCallback) { ImGuiSizeConstraintCallbackData data; - data.UserData = g.NextWindow.SizeConstraintCallbackUserData; + data.UserData = g.NextWindowData.SizeConstraintCallbackUserData; data.Pos = window->Pos; data.CurrentSize = window->SizeFull; data.DesiredSize = new_size; - g.NextWindow.SizeConstraintCallback(&data); + g.NextWindowData.SizeConstraintCallback(&data); new_size = data.DesiredSize; } } @@ -4351,7 +4341,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) ImGuiWindow* window = FindWindowByName(name); if (!window) { - ImVec2 size_on_first_use = (g.NextWindow.SizeCond != 0) ? g.NextWindow.SizeVal : ImVec2(0.0f, 0.0f); // Any condition flag will do since we are creating a new window here. + ImVec2 size_on_first_use = (g.NextWindowData.SizeCond != 0) ? g.NextWindowData.SizeVal : ImVec2(0.0f, 0.0f); // Any condition flag will do since we are creating a new window here. window = CreateNewWindow(name, size_on_first_use, flags); } @@ -4396,50 +4386,50 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // Process SetNextWindow***() calls bool window_pos_set_by_api = false; bool window_size_x_set_by_api = false, window_size_y_set_by_api = false; - if (g.NextWindow.PosCond) + if (g.NextWindowData.PosCond) { - window_pos_set_by_api = (window->SetWindowPosAllowFlags & g.NextWindow.PosCond) != 0; - if (window_pos_set_by_api && ImLengthSqr(g.NextWindow.PosPivotVal) > 0.00001f) + window_pos_set_by_api = (window->SetWindowPosAllowFlags & g.NextWindowData.PosCond) != 0; + if (window_pos_set_by_api && ImLengthSqr(g.NextWindowData.PosPivotVal) > 0.00001f) { // May be processed on the next frame if this is our first frame and we are measuring size // FIXME: Look into removing the branch so everything can go through this same code path for consistency. - window->SetWindowPosVal = g.NextWindow.PosVal; - window->SetWindowPosPivot = g.NextWindow.PosPivotVal; + window->SetWindowPosVal = g.NextWindowData.PosVal; + window->SetWindowPosPivot = g.NextWindowData.PosPivotVal; window->SetWindowPosAllowFlags &= ~(ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing); } else { - SetWindowPos(window, g.NextWindow.PosVal, g.NextWindow.PosCond); + SetWindowPos(window, g.NextWindowData.PosVal, g.NextWindowData.PosCond); } - g.NextWindow.PosCond = 0; + g.NextWindowData.PosCond = 0; } - if (g.NextWindow.SizeCond) + if (g.NextWindowData.SizeCond) { - window_size_x_set_by_api = (window->SetWindowSizeAllowFlags & g.NextWindow.SizeCond) != 0 && (g.NextWindow.SizeVal.x > 0.0f); - window_size_y_set_by_api = (window->SetWindowSizeAllowFlags & g.NextWindow.SizeCond) != 0 && (g.NextWindow.SizeVal.y > 0.0f); - SetWindowSize(window, g.NextWindow.SizeVal, g.NextWindow.SizeCond); - g.NextWindow.SizeCond = 0; + window_size_x_set_by_api = (window->SetWindowSizeAllowFlags & g.NextWindowData.SizeCond) != 0 && (g.NextWindowData.SizeVal.x > 0.0f); + window_size_y_set_by_api = (window->SetWindowSizeAllowFlags & g.NextWindowData.SizeCond) != 0 && (g.NextWindowData.SizeVal.y > 0.0f); + SetWindowSize(window, g.NextWindowData.SizeVal, g.NextWindowData.SizeCond); + g.NextWindowData.SizeCond = 0; } - if (g.NextWindow.ContentSizeCond) + if (g.NextWindowData.ContentSizeCond) { // Adjust passed "client size" to become a "window size" - window->SizeContentsExplicit = g.NextWindow.ContentSizeVal; + window->SizeContentsExplicit = g.NextWindowData.ContentSizeVal; window->SizeContentsExplicit.y += window->TitleBarHeight() + window->MenuBarHeight(); - g.NextWindow.ContentSizeCond = 0; + g.NextWindowData.ContentSizeCond = 0; } else if (first_begin_of_the_frame) { window->SizeContentsExplicit = ImVec2(0.0f, 0.0f); } - if (g.NextWindow.CollapsedCond) + if (g.NextWindowData.CollapsedCond) { - SetWindowCollapsed(window, g.NextWindow.CollapsedVal, g.NextWindow.CollapsedCond); - g.NextWindow.CollapsedCond = 0; + SetWindowCollapsed(window, g.NextWindowData.CollapsedVal, g.NextWindowData.CollapsedCond); + g.NextWindowData.CollapsedCond = 0; } - if (g.NextWindow.FocusCond) + if (g.NextWindowData.FocusCond) { SetWindowFocus(); - g.NextWindow.FocusCond = 0; + g.NextWindowData.FocusCond = 0; } if (window->Appearing) SetWindowConditionAllowFlags(window, ImGuiCond_Appearing, false); @@ -4939,7 +4929,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->WriteAccessed = false; window->BeginCount++; - g.NextWindow.SizeConstraintCond = 0; + g.NextWindowData.SizeConstraintCond = 0; // Child window can be out of sight and have "negative" clip windows. // Mark them as collapsed so commands are skipped earlier (we can't manually collapse because they have no title bar). @@ -5701,45 +5691,45 @@ void ImGui::SetWindowFocus(const char* name) void ImGui::SetNextWindowPos(const ImVec2& pos, ImGuiCond cond, const ImVec2& pivot) { ImGuiContext& g = *GImGui; - g.NextWindow.PosVal = pos; - g.NextWindow.PosPivotVal = pivot; - g.NextWindow.PosCond = cond ? cond : ImGuiCond_Always; + g.NextWindowData.PosVal = pos; + g.NextWindowData.PosPivotVal = pivot; + g.NextWindowData.PosCond = cond ? cond : ImGuiCond_Always; } void ImGui::SetNextWindowSize(const ImVec2& size, ImGuiCond cond) { ImGuiContext& g = *GImGui; - g.NextWindow.SizeVal = size; - g.NextWindow.SizeCond = cond ? cond : ImGuiCond_Always; + g.NextWindowData.SizeVal = size; + g.NextWindowData.SizeCond = cond ? cond : ImGuiCond_Always; } void ImGui::SetNextWindowSizeConstraints(const ImVec2& size_min, const ImVec2& size_max, ImGuiSizeConstraintCallback custom_callback, void* custom_callback_user_data) { ImGuiContext& g = *GImGui; - g.NextWindow.SizeConstraintCond = ImGuiCond_Always; - g.NextWindow.SizeConstraintRect = ImRect(size_min, size_max); - g.NextWindow.SizeConstraintCallback = custom_callback; - g.NextWindow.SizeConstraintCallbackUserData = custom_callback_user_data; + g.NextWindowData.SizeConstraintCond = ImGuiCond_Always; + g.NextWindowData.SizeConstraintRect = ImRect(size_min, size_max); + g.NextWindowData.SizeConstraintCallback = custom_callback; + g.NextWindowData.SizeConstraintCallbackUserData = custom_callback_user_data; } void ImGui::SetNextWindowContentSize(const ImVec2& size) { ImGuiContext& g = *GImGui; - g.NextWindow.ContentSizeVal = size; // In Begin() we will add the size of window decorations (title bar, menu etc.) to that to form a SizeContents value. - g.NextWindow.ContentSizeCond = ImGuiCond_Always; + g.NextWindowData.ContentSizeVal = size; // In Begin() we will add the size of window decorations (title bar, menu etc.) to that to form a SizeContents value. + g.NextWindowData.ContentSizeCond = ImGuiCond_Always; } void ImGui::SetNextWindowCollapsed(bool collapsed, ImGuiCond cond) { ImGuiContext& g = *GImGui; - g.NextWindow.CollapsedVal = collapsed; - g.NextWindow.CollapsedCond = cond ? cond : ImGuiCond_Always; + g.NextWindowData.CollapsedVal = collapsed; + g.NextWindowData.CollapsedCond = cond ? cond : ImGuiCond_Always; } void ImGui::SetNextWindowFocus() { ImGuiContext& g = *GImGui; - g.NextWindow.FocusCond = ImGuiCond_Always; + g.NextWindowData.FocusCond = ImGuiCond_Always; } // In window space (not screen space!) @@ -9162,8 +9152,8 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboF { // Always consume the SetNextWindowSizeConstraint() call in our early return paths ImGuiContext& g = *GImGui; - ImGuiCond backup_next_window_size_constraint = g.NextWindow.SizeConstraintCond; - g.NextWindow.SizeConstraintCond = 0; + ImGuiCond backup_next_window_size_constraint = g.NextWindowData.SizeConstraintCond; + g.NextWindowData.SizeConstraintCond = 0; ImGuiWindow* window = GetCurrentWindow(); if (window->SkipItems) @@ -9205,8 +9195,8 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboF if (backup_next_window_size_constraint) { - g.NextWindow.SizeConstraintCond = backup_next_window_size_constraint; - g.NextWindow.SizeConstraintRect.Min.x = ImMax(g.NextWindow.SizeConstraintRect.Min.x, w); + g.NextWindowData.SizeConstraintCond = backup_next_window_size_constraint; + g.NextWindowData.SizeConstraintRect.Min.x = ImMax(g.NextWindowData.SizeConstraintRect.Min.x, w); } else { @@ -9268,7 +9258,7 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi items_getter(data, *current_item, &preview_text); // The old Combo() API exposed "popup_max_height_in_items", however the new more general BeginCombo() API doesn't, so we emulate it here. - if (popup_max_height_in_items != -1 && !g.NextWindow.SizeConstraintCond) + if (popup_max_height_in_items != -1 && !g.NextWindowData.SizeConstraintCond) { float popup_max_height = CalcMaxPopupHeightFromItemCount(popup_max_height_in_items); SetNextWindowSizeConstraints(ImVec2(0,0), ImVec2(FLT_MAX, popup_max_height)); diff --git a/imgui_internal.h b/imgui_internal.h index f66e99eb2..9faade5cc 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -487,6 +487,11 @@ struct ImGuiNextWindowData SizeConstraintCallback = NULL; SizeConstraintCallbackUserData = NULL; } + + void Clear() + { + PosCond = SizeCond = ContentSizeCond = CollapsedCond = SizeConstraintCond = FocusCond = 0; + } }; // Main state for ImGui @@ -532,7 +537,7 @@ struct ImGuiContext ImVector FontStack; // Stack for PushFont()/PopFont() ImVector OpenPopupStack; // Which popups are open (persistent) ImVector CurrentPopupStack; // Which level of BeginPopup() we are in (reset every frame) - ImGuiNextWindowData NextWindow; // Storage for SetNextWindow** functions + ImGuiNextWindowData NextWindowData; // Storage for SetNextWindow** functions bool NextTreeNodeOpenVal; // Storage for SetNextTreeNode** functions ImGuiCond NextTreeNodeOpenCond; From 3c6fbe08491418f367cb8d9a7c6215a3bb3c2f93 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 3 Jan 2018 12:31:56 +0100 Subject: [PATCH 814/921] Renamed ImGuiSizeConstraintCallback to ImGuiSizeCallback, ImGuiSizeConstraintCallbackData to ImGuiSizeCallbackData. --- imgui.cpp | 15 ++++++++------- imgui.h | 8 ++++---- imgui_demo.cpp | 4 ++-- imgui_internal.h | 8 ++++---- 4 files changed, 18 insertions(+), 17 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index ae85abf06..b616af838 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -213,6 +213,7 @@ Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. Also read releases logs https://github.com/ocornut/imgui/releases for more details. + - 2018/01/03 (1.54) - renamed ImGuiSizeConstraintCallback to ImGuiSizeCallback, ImGuiSizeConstraintCallbackData to ImGuiSizeCallbackData. - 2017/12/29 (1.54) - removed CalcItemRectClosestPoint() which was weird and not really used by anyone except demo code. If you need it it's easy to replicate on your side. - 2017/12/24 (1.53) - renamed the emblematic ShowTestWindow() function to ShowDemoWindow(). Kept redirection function (will obsolete). - 2017/12/21 (1.53) - ImDrawList: renamed style.AntiAliasedShapes to style.AntiAliasedFill for consistency and as a way to explicitly break code that manipulate those flag at runtime. You can now manipulate ImDrawList::Flags @@ -4188,14 +4189,14 @@ static ImVec2 CalcSizeAfterConstraint(ImGuiWindow* window, ImVec2 new_size) ImRect cr = g.NextWindowData.SizeConstraintRect; new_size.x = (cr.Min.x >= 0 && cr.Max.x >= 0) ? ImClamp(new_size.x, cr.Min.x, cr.Max.x) : window->SizeFull.x; new_size.y = (cr.Min.y >= 0 && cr.Max.y >= 0) ? ImClamp(new_size.y, cr.Min.y, cr.Max.y) : window->SizeFull.y; - if (g.NextWindowData.SizeConstraintCallback) + if (g.NextWindowData.SizeCallback) { - ImGuiSizeConstraintCallbackData data; - data.UserData = g.NextWindowData.SizeConstraintCallbackUserData; + ImGuiSizeCallbackData data; + data.UserData = g.NextWindowData.SizeCallbackUserData; data.Pos = window->Pos; data.CurrentSize = window->SizeFull; data.DesiredSize = new_size; - g.NextWindowData.SizeConstraintCallback(&data); + g.NextWindowData.SizeCallback(&data); new_size = data.DesiredSize; } } @@ -5703,13 +5704,13 @@ void ImGui::SetNextWindowSize(const ImVec2& size, ImGuiCond cond) g.NextWindowData.SizeCond = cond ? cond : ImGuiCond_Always; } -void ImGui::SetNextWindowSizeConstraints(const ImVec2& size_min, const ImVec2& size_max, ImGuiSizeConstraintCallback custom_callback, void* custom_callback_user_data) +void ImGui::SetNextWindowSizeConstraints(const ImVec2& size_min, const ImVec2& size_max, ImGuiSizeCallback custom_callback, void* custom_callback_user_data) { ImGuiContext& g = *GImGui; g.NextWindowData.SizeConstraintCond = ImGuiCond_Always; g.NextWindowData.SizeConstraintRect = ImRect(size_min, size_max); - g.NextWindowData.SizeConstraintCallback = custom_callback; - g.NextWindowData.SizeConstraintCallbackUserData = custom_callback_user_data; + g.NextWindowData.SizeCallback = custom_callback; + g.NextWindowData.SizeCallbackUserData = custom_callback_user_data; } void ImGui::SetNextWindowContentSize(const ImVec2& size) diff --git a/imgui.h b/imgui.h index a8dd3435b..4e9b2e797 100644 --- a/imgui.h +++ b/imgui.h @@ -64,7 +64,7 @@ struct ImGuiStyle; // Runtime data for styling/colors struct ImGuiTextFilter; // Parse and apply text filters. In format "aaaaa[,bbbb][,ccccc]" struct ImGuiTextBuffer; // Text buffer for logging/accumulating text struct ImGuiTextEditCallbackData; // Shared state of ImGui::InputText() when using custom ImGuiTextEditCallback (rare/advanced use) -struct ImGuiSizeConstraintCallbackData;// Structure used to constraint window size in custom ways when using custom ImGuiSizeConstraintCallback (rare/advanced use) +struct ImGuiSizeCallbackData; // Structure used to constraint window size in custom ways when using custom ImGuiSizeCallback (rare/advanced use) struct ImGuiListClipper; // Helper to manually clip large list of items struct ImGuiPayload; // User data payload for drag and drop operations struct ImGuiContext; // ImGui context (opaque) @@ -92,7 +92,7 @@ typedef int ImGuiSelectableFlags; // flags: for Selectable() typedef int ImGuiTreeNodeFlags; // flags: for TreeNode*(),CollapsingHeader()// enum ImGuiTreeNodeFlags_ typedef int ImGuiWindowFlags; // flags: for Begin*() // enum ImGuiWindowFlags_ typedef int (*ImGuiTextEditCallback)(ImGuiTextEditCallbackData *data); -typedef void (*ImGuiSizeConstraintCallback)(ImGuiSizeConstraintCallbackData* data); +typedef void (*ImGuiSizeCallback)(ImGuiSizeCallbackData* data); #if defined(_MSC_VER) && !defined(__clang__) typedef unsigned __int64 ImU64; // 64-bit unsigned integer #else @@ -167,7 +167,7 @@ namespace ImGui IMGUI_API void SetNextWindowPos(const ImVec2& pos, ImGuiCond cond = 0, const ImVec2& pivot = ImVec2(0,0)); // set next window position. call before Begin(). use pivot=(0.5f,0.5f) to center on given point, etc. IMGUI_API void SetNextWindowSize(const ImVec2& size, ImGuiCond cond = 0); // set next window size. set axis to 0.0f to force an auto-fit on this axis. call before Begin() - IMGUI_API void SetNextWindowSizeConstraints(const ImVec2& size_min, const ImVec2& size_max, ImGuiSizeConstraintCallback custom_callback = NULL, void* custom_callback_data = NULL); // set next window size limits. use -1,-1 on either X/Y axis to preserve the current size. Use callback to apply non-trivial programmatic constraints. + IMGUI_API void SetNextWindowSizeConstraints(const ImVec2& size_min, const ImVec2& size_max, ImGuiSizeCallback custom_callback = NULL, void* custom_callback_data = NULL); // set next window size limits. use -1,-1 on either X/Y axis to preserve the current size. Use callback to apply non-trivial programmatic constraints. IMGUI_API void SetNextWindowContentSize(const ImVec2& size); // set next window content size (~ enforce the range of scrollbars). not including window decorations (title bar, menu bar, etc.). set an axis to 0.0f to leave it automatic. call before Begin() IMGUI_API void SetNextWindowCollapsed(bool collapsed, ImGuiCond cond = 0); // set next window collapsed state. call before Begin() IMGUI_API void SetNextWindowFocus(); // set next window to be focused / front-most. call before Begin() @@ -1218,7 +1218,7 @@ struct ImGuiTextEditCallbackData // Resizing callback data to apply custom constraint. As enabled by SetNextWindowSizeConstraints(). Callback is called during the next Begin(). // NB: For basic min/max size constraint on each axis you don't need to use the callback! The SetNextWindowSizeConstraints() parameters are enough. -struct ImGuiSizeConstraintCallbackData +struct ImGuiSizeCallbackData { void* UserData; // Read-only. What user passed to SetNextWindowSizeConstraints() ImVec2 Pos; // Read-only. Window position, for reference. diff --git a/imgui_demo.cpp b/imgui_demo.cpp index c9d47d4df..4a5c32dec 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -2303,8 +2303,8 @@ static void ShowExampleAppConstrainedResize(bool* p_open) { struct CustomConstraints // Helper functions to demonstrate programmatic constraints { - static void Square(ImGuiSizeConstraintCallbackData* data) { data->DesiredSize = ImVec2(IM_MAX(data->DesiredSize.x, data->DesiredSize.y), IM_MAX(data->DesiredSize.x, data->DesiredSize.y)); } - static void Step(ImGuiSizeConstraintCallbackData* data) { float step = (float)(int)(intptr_t)data->UserData; data->DesiredSize = ImVec2((int)(data->DesiredSize.x / step + 0.5f) * step, (int)(data->DesiredSize.y / step + 0.5f) * step); } + static void Square(ImGuiSizeCallbackData* data) { data->DesiredSize = ImVec2(IM_MAX(data->DesiredSize.x, data->DesiredSize.y), IM_MAX(data->DesiredSize.x, data->DesiredSize.y)); } + static void Step(ImGuiSizeCallbackData* data) { float step = (float)(int)(intptr_t)data->UserData; data->DesiredSize = ImVec2((int)(data->DesiredSize.x / step + 0.5f) * step, (int)(data->DesiredSize.y / step + 0.5f) * step); } }; static bool auto_resize = false; diff --git a/imgui_internal.h b/imgui_internal.h index 9faade5cc..8481f3ac0 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -474,8 +474,8 @@ struct ImGuiNextWindowData ImVec2 ContentSizeVal; bool CollapsedVal; ImRect SizeConstraintRect; // Valid if 'SetNextWindowSizeConstraint' is true - ImGuiSizeConstraintCallback SizeConstraintCallback; - void* SizeConstraintCallbackUserData; + ImGuiSizeCallback SizeCallback; + void* SizeCallbackUserData; ImGuiNextWindowData() { @@ -484,8 +484,8 @@ struct ImGuiNextWindowData ContentSizeVal = ImVec2(0.0f, 0.0f); CollapsedVal = false; SizeConstraintRect = ImRect(); - SizeConstraintCallback = NULL; - SizeConstraintCallbackUserData = NULL; + SizeCallback = NULL; + SizeCallbackUserData = NULL; } void Clear() From 05ec0b07365b36319ed6ef301c723634c7f8777d Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 3 Jan 2018 14:30:40 +0100 Subject: [PATCH 815/921] Casing tweaks + clarify license copyright (simpler/safer?) (#1346) --- LICENSE.txt | 2 +- imgui.cpp | 2 +- imgui_demo.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/LICENSE.txt b/LICENSE.txt index 5a9b98b83..24fcd01a7 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2014-2017 Omar Cornut and ImGui contributors +Copyright (c) 2014-2017 Omar Cornut Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/imgui.cpp b/imgui.cpp index b616af838..6f57bb40e 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -11588,7 +11588,7 @@ void ImGui::ShowMetricsWindow(bool* p_open) { if (ImGui::Begin("ImGui Metrics", p_open)) { - ImGui::Text("ImGui %s", ImGui::GetVersion()); + ImGui::Text("Dear ImGui %s", ImGui::GetVersion()); ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); ImGui::Text("%d vertices, %d indices (%d triangles)", ImGui::GetIO().MetricsRenderVertices, ImGui::GetIO().MetricsRenderIndices, ImGui::GetIO().MetricsRenderIndices / 3); ImGui::Text("%d allocations", ImGui::GetIO().MetricsAllocs); diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 4a5c32dec..4bcc516a4 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -160,7 +160,7 @@ void ImGui::ShowDemoWindow(bool* p_open) if (show_app_about) { ImGui::Begin("About Dear ImGui", &show_app_about, ImGuiWindowFlags_AlwaysAutoResize); - ImGui::Text("dear imgui, %s", ImGui::GetVersion()); + ImGui::Text("Dear ImGui, %s", ImGui::GetVersion()); ImGui::Separator(); ImGui::Text("By Omar Cornut and all dear imgui contributors."); ImGui::Text("Dear ImGui is licensed under the MIT License, see LICENSE for more information."); From 79d38e5aded9c30956cb147cf71e9935f7bb4202 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 3 Jan 2018 14:31:13 +0100 Subject: [PATCH 816/921] Updated copyright date for 2018 --- LICENSE.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE.txt b/LICENSE.txt index 24fcd01a7..21b6ee7e2 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2014-2017 Omar Cornut +Copyright (c) 2014-2018 Omar Cornut Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From f9b2058d5a264c184f8c935eded18926f90d9226 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 3 Jan 2018 14:35:11 +0100 Subject: [PATCH 817/921] Internals: Renamed ImGuiSimpleColumns to ImGuiMenuColumns to avoid confusion. Reduced internal buffer size (we only use 3 slots). --- imgui.cpp | 8 ++++---- imgui_internal.h | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 6f57bb40e..71a40d1fe 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1693,7 +1693,7 @@ void ImGuiTextBuffer::appendf(const char* fmt, ...) // ImGuiSimpleColumns (internal use only) //----------------------------------------------------------------------------- -ImGuiSimpleColumns::ImGuiSimpleColumns() +ImGuiMenuColumns::ImGuiMenuColumns() { Count = 0; Spacing = Width = NextWidth = 0.0f; @@ -1701,7 +1701,7 @@ ImGuiSimpleColumns::ImGuiSimpleColumns() memset(NextWidths, 0, sizeof(NextWidths)); } -void ImGuiSimpleColumns::Update(int count, float spacing, bool clear) +void ImGuiMenuColumns::Update(int count, float spacing, bool clear) { IM_ASSERT(Count <= IM_ARRAYSIZE(Pos)); Count = count; @@ -1718,7 +1718,7 @@ void ImGuiSimpleColumns::Update(int count, float spacing, bool clear) } } -float ImGuiSimpleColumns::DeclColumns(float w0, float w1, float w2) // not using va_arg because they promote float to double +float ImGuiMenuColumns::DeclColumns(float w0, float w1, float w2) // not using va_arg because they promote float to double { NextWidth = 0.0f; NextWidths[0] = ImMax(NextWidths[0], w0); @@ -1729,7 +1729,7 @@ float ImGuiSimpleColumns::DeclColumns(float w0, float w1, float w2) // not using return ImMax(Width, NextWidth); } -float ImGuiSimpleColumns::CalcExtraSpace(float avail_w) +float ImGuiMenuColumns::CalcExtraSpace(float avail_w) { return ImMax(0.0f, avail_w - Width); } diff --git a/imgui_internal.h b/imgui_internal.h index 8481f3ac0..babda0b5d 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -35,7 +35,7 @@ struct ImRect; struct ImGuiColMod; struct ImGuiStyleMod; struct ImGuiGroupData; -struct ImGuiSimpleColumns; +struct ImGuiMenuColumns; struct ImGuiDrawContext; struct ImGuiTextEditState; struct ImGuiMouseCursorData; @@ -323,14 +323,14 @@ struct ImGuiGroupData }; // Simple column measurement currently used for MenuItem() only. This is very short-sighted/throw-away code and NOT a generic helper. -struct IMGUI_API ImGuiSimpleColumns +struct IMGUI_API ImGuiMenuColumns { int Count; float Spacing; float Width, NextWidth; - float Pos[8], NextWidths[8]; + float Pos[4], NextWidths[4]; - ImGuiSimpleColumns(); + ImGuiMenuColumns(); void Update(int count, float spacing, bool clear); float DeclColumns(float w0, float w1, float w2); float CalcExtraSpace(float avail_w); @@ -801,7 +801,7 @@ struct IMGUI_API ImGuiWindow ImRect InnerRect; int LastFrameActive; float ItemWidthDefault; - ImGuiSimpleColumns MenuColumns; // Simplified columns storage for menu items + ImGuiMenuColumns MenuColumns; // Simplified columns storage for menu items ImGuiStorage StateStorage; ImVector ColumnsStorage; float FontWindowScale; // Scale multiplier per-window From 33f7769d85fc12c5255919a59d88ec8d540e2589 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 3 Jan 2018 14:38:01 +0100 Subject: [PATCH 818/921] Columns: Clear offsets data when columns count changed. (#1525) --- imgui.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 71a40d1fe..c4239190c 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -11004,6 +11004,10 @@ void ImGui::BeginColumns(const char* str_id, int columns_count, ImGuiColumnsFlag window->DC.ColumnsOffsetX = 0.0f; window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.IndentX + window->DC.ColumnsOffsetX); + // Clear data if columns count changed + if (columns->Columns.Size != 0 && columns->Columns.Size != columns_count + 1) + columns->Columns.resize(0); + // Initialize defaults columns->IsFirstFrame = (columns->Columns.Size == 0); if (columns->Columns.Size == 0) @@ -11016,7 +11020,6 @@ void ImGui::BeginColumns(const char* str_id, int columns_count, ImGuiColumnsFlag columns->Columns.push_back(column); } } - IM_ASSERT(columns->Columns.Size == columns_count + 1); for (int n = 0; n < columns_count + 1; n++) { From 9fbecac87eda2265a6384f9e146493f5750ef0c2 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 3 Jan 2018 15:11:14 +0100 Subject: [PATCH 819/921] Demo: Improved Selectable() examples. (#1528) --- imgui.h | 4 ++-- imgui_demo.cpp | 52 +++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 45 insertions(+), 11 deletions(-) diff --git a/imgui.h b/imgui.h index 4e9b2e797..87d3ae380 100644 --- a/imgui.h +++ b/imgui.h @@ -376,8 +376,8 @@ namespace ImGui IMGUI_API bool CollapsingHeader(const char* label, bool* p_open, ImGuiTreeNodeFlags flags = 0); // when 'p_open' isn't NULL, display an additional small close button on upper right of the header // Widgets: Selectable / Lists - IMGUI_API bool Selectable(const char* label, bool selected = false, ImGuiSelectableFlags flags = 0, const ImVec2& size = ImVec2(0,0)); // size.x==0.0: use remaining width, size.x>0.0: specify width. size.y==0.0: use label height, size.y>0.0: specify height - IMGUI_API bool Selectable(const char* label, bool* p_selected, ImGuiSelectableFlags flags = 0, const ImVec2& size = ImVec2(0,0)); + IMGUI_API bool Selectable(const char* label, bool selected = false, ImGuiSelectableFlags flags = 0, const ImVec2& size = ImVec2(0,0)); // "bool selected" carry the selection state (read-only). Selectable() is clicked is returns true so you can modify your selection state. size.x==0.0: use remaining width, size.x>0.0: specify width. size.y==0.0: use label height, size.y>0.0: specify height + IMGUI_API bool Selectable(const char* label, bool* p_selected, ImGuiSelectableFlags flags = 0, const ImVec2& size = ImVec2(0,0)); // "bool* p_selected" point to the selection state (read-write), as a convenient helper. IMGUI_API bool ListBox(const char* label, int* current_item, const char* const items[], int items_count, int height_in_items = -1); IMGUI_API bool ListBox(const char* label, int* current_item, bool (*items_getter)(void* data, int idx, const char** out_text), void* data, int items_count, int height_in_items = -1); IMGUI_API bool ListBoxHeader(const char* label, const ImVec2& size = ImVec2(0,0)); // use if you want to reimplement ListBox() will custom data or interactions. make sure to call ListBoxFooter() afterwards. diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 4bcc516a4..9f11de36c 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -609,24 +609,58 @@ void ImGui::ShowDemoWindow(bool* p_open) if (ImGui::TreeNode("Selectables")) { + // Selectable() has 2 overloads: + // - The one taking "bool selected" as a read-only selection information. When Selectable() has been clicked is returns true and you can alter selection state accordingly. + // - The one taking "bool* p_selected" as a read-write selection information (convenient in some cases) + // The earlier is more flexible, as in real application your selection may be stored in a different manner (in flags within objects, as an external list, etc). if (ImGui::TreeNode("Basic")) { - static bool selected[4] = { false, true, false, false }; - ImGui::Selectable("1. I am selectable", &selected[0]); - ImGui::Selectable("2. I am selectable", &selected[1]); + static bool selection[5] = { false, true, false, false, false }; + ImGui::Selectable("1. I am selectable", &selection[0]); + ImGui::Selectable("2. I am selectable", &selection[1]); ImGui::Text("3. I am not selectable"); - ImGui::Selectable("4. I am selectable", &selected[2]); - if (ImGui::Selectable("5. I am double clickable", selected[3], ImGuiSelectableFlags_AllowDoubleClick)) + ImGui::Selectable("4. I am selectable", &selection[3]); + if (ImGui::Selectable("5. I am double clickable", selection[4], ImGuiSelectableFlags_AllowDoubleClick)) if (ImGui::IsMouseDoubleClicked(0)) - selected[3] = !selected[3]; + selection[4] = !selection[4]; ImGui::TreePop(); } - if (ImGui::TreeNode("Rendering more text into the same block")) + if (ImGui::TreeNode("Selection State: Single Selection")) { + static int selected = -1; + for (int n = 0; n < 5; n++) + { + char buf[32]; + sprintf(buf, "Object %d", n); + if (ImGui::Selectable(buf, selected == n)) + selected = n; + } + ImGui::TreePop(); + } + if (ImGui::TreeNode("Selection State: Multiple Selection")) + { + ShowHelpMarker("Hold CTRL and click to select multiple items."); + static bool selection[5] = { false, false, false, false, false }; + for (int n = 0; n < 5; n++) + { + char buf[32]; + sprintf(buf, "Object %d", n); + if (ImGui::Selectable(buf, selection[n])) + { + if (!ImGui::GetIO().KeyCtrl) // Clear selection when CTRL is not held + memset(selection, 0, sizeof(selection)); + selection[n] ^= 1; + } + } + ImGui::TreePop(); + } + if (ImGui::TreeNode("Rendering more text into the same line")) + { + // Using the Selectable() override that takes "bool* p_selected" parameter and toggle your booleans automatically. static bool selected[3] = { false, false, false }; - ImGui::Selectable("main.c", &selected[0]); ImGui::SameLine(300); ImGui::Text(" 2,345 bytes"); + ImGui::Selectable("main.c", &selected[0]); ImGui::SameLine(300); ImGui::Text(" 2,345 bytes"); ImGui::Selectable("Hello.cpp", &selected[1]); ImGui::SameLine(300); ImGui::Text("12,345 bytes"); - ImGui::Selectable("Hello.h", &selected[2]); ImGui::SameLine(300); ImGui::Text(" 2,345 bytes"); + ImGui::Selectable("Hello.h", &selected[2]); ImGui::SameLine(300); ImGui::Text(" 2,345 bytes"); ImGui::TreePop(); } if (ImGui::TreeNode("In columns")) From a7deb3a3943c9fe8b0acb34bc65bc1ec5343d524 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 3 Jan 2018 15:36:51 +0100 Subject: [PATCH 820/921] Demo: Minor tweaks. --- imgui_demo.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 9f11de36c..76a8fa551 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -413,7 +413,7 @@ void ImGui::ShowDemoWindow(bool* p_open) { ImGui::Text("blah blah"); ImGui::SameLine(); - if (ImGui::SmallButton("print")) printf("Child %d pressed", i); + if (ImGui::SmallButton("button")) { }; ImGui::TreePop(); } ImGui::TreePop(); @@ -807,14 +807,14 @@ void ImGui::ShowDemoWindow(bool* p_open) { static ImVec4 color = ImColor(114, 144, 154, 200); - static bool hdr = false; static bool alpha_preview = true; static bool alpha_half_preview = false; static bool options_menu = true; - ImGui::Checkbox("With HDR", &hdr); ImGui::SameLine(); ShowHelpMarker("Currently all this does is to lift the 0..1 limits on dragging widgets."); + static bool hdr = false; ImGui::Checkbox("With Alpha Preview", &alpha_preview); ImGui::Checkbox("With Half Alpha Preview", &alpha_half_preview); ImGui::Checkbox("With Options Menu", &options_menu); ImGui::SameLine(); ShowHelpMarker("Right-click on the individual color widget to show options."); + ImGui::Checkbox("With HDR", &hdr); ImGui::SameLine(); ShowHelpMarker("Currently all this does is to lift the 0..1 limits on dragging widgets."); int misc_flags = (hdr ? ImGuiColorEditFlags_HDR : 0) | (alpha_half_preview ? ImGuiColorEditFlags_AlphaPreviewHalf : (alpha_preview ? ImGuiColorEditFlags_AlphaPreview : 0)) | (options_menu ? 0 : ImGuiColorEditFlags_NoOptions); ImGui::Text("Color widget:"); From 0a0b252bb6982e8033d9e321dfc75a1ff572bf60 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 3 Jan 2018 16:56:41 +0100 Subject: [PATCH 821/921] DragDrop: Removed IsDragDropActive() (introduced a few days ago, revert 06bea369c0ce977c1cb71e085d860a6644330297) as our use case doesn't need it anymore. Will add it if there is a real need. --- imgui.cpp | 6 ------ imgui.h | 1 - 2 files changed, 7 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index c4239190c..d764d60c9 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -11468,12 +11468,6 @@ void ImGui::EndDragDropTarget() IM_ASSERT(g.DragDropActive); } -bool ImGui::IsDragDropActive() -{ - ImGuiContext& g = *GImGui; - return g.DragDropActive; -} - //----------------------------------------------------------------------------- // PLATFORM DEPENDENT HELPERS //----------------------------------------------------------------------------- diff --git a/imgui.h b/imgui.h index 87d3ae380..fc9791a74 100644 --- a/imgui.h +++ b/imgui.h @@ -434,7 +434,6 @@ namespace ImGui IMGUI_API bool BeginDragDropTarget(); // call after submitting an item that may receive an item. If this returns true, you can call AcceptDragDropPayload() + EndDragDropTarget() IMGUI_API const ImGuiPayload* AcceptDragDropPayload(const char* type, ImGuiDragDropFlags flags = 0); // accept contents of a given type. If ImGuiDragDropFlags_AcceptBeforeDelivery is set you can peek into the payload before the mouse button is released. IMGUI_API void EndDragDropTarget(); - IMGUI_API bool IsDragDropActive(); // Clipping IMGUI_API void PushClipRect(const ImVec2& clip_rect_min, const ImVec2& clip_rect_max, bool intersect_with_current_clip_rect); From b2ec0741f101493d76967b2a869a01382a74b72f Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 15 Dec 2017 20:59:00 +0100 Subject: [PATCH 822/921] Internals: Settings api tweaks --- imgui.cpp | 26 +++++++++++++++----------- imgui_internal.h | 11 +++++++---- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index d764d60c9..336c43f78 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2525,7 +2525,7 @@ void ImGui::NewFrame() Begin("Debug##Default"); } -static void* SettingsHandlerWindow_ReadOpen(ImGuiContext&, const char* name) +static void* SettingsHandlerWindow_ReadOpen(ImGuiContext*, ImGuiSettingsHandler*, const char* name) { ImGuiWindowSettings* settings = ImGui::FindWindowSettings(ImHash(name, 0)); if (!settings) @@ -2533,7 +2533,7 @@ static void* SettingsHandlerWindow_ReadOpen(ImGuiContext&, const char* name) return (void*)settings; } -static void SettingsHandlerWindow_ReadLine(ImGuiContext&, void* entry, const char* line) +static void SettingsHandlerWindow_ReadLine(ImGuiContext*, ImGuiSettingsHandler*, void* entry, const char* line) { ImGuiWindowSettings* settings = (ImGuiWindowSettings*)entry; float x, y; @@ -2543,9 +2543,10 @@ static void SettingsHandlerWindow_ReadLine(ImGuiContext&, void* entry, const cha else if (sscanf(line, "Collapsed=%d", &i) == 1) settings->Collapsed = (i != 0); } -static void SettingsHandlerWindow_WriteAll(ImGuiContext& g, ImGuiTextBuffer* buf) +static void SettingsHandlerWindow_WriteAll(ImGuiContext* imgui_ctx, ImGuiSettingsHandler* handler, ImGuiTextBuffer* buf) { // Gather data from windows that were active during this session + ImGuiContext& g = *imgui_ctx; for (int i = 0; i != g.Windows.Size; i++) { ImGuiWindow* window = g.Windows[i]; @@ -2570,7 +2571,7 @@ static void SettingsHandlerWindow_WriteAll(ImGuiContext& g, ImGuiTextBuffer* buf const char* name = settings->Name; if (const char* p = strstr(name, "###")) // Skip to the "###" marker if any. We don't skip past to match the behavior of GetID() name = p; - buf->appendf("[Window][%s]\n", name); + buf->appendf("[%s][%s]\n", handler->TypeName, name); buf->appendf("Pos=%d,%d\n", (int)settings->Pos.x, (int)settings->Pos.y); buf->appendf("Size=%d,%d\n", (int)settings->Size.x, (int)settings->Size.y); buf->appendf("Collapsed=%d\n", settings->Collapsed); @@ -2684,9 +2685,10 @@ static void LoadIniSettingsFromDisk(const char* ini_filename) ImGui::MemFree(file_data); } -ImGuiSettingsHandler* ImGui::FindSettingsHandler(ImGuiID type_hash) +ImGuiSettingsHandler* ImGui::FindSettingsHandler(const char* type_name) { ImGuiContext& g = *GImGui; + const ImGuiID type_hash = ImHash(type_name, 0, 0); for (int handler_n = 0; handler_n < g.SettingsHandlers.Size; handler_n++) if (g.SettingsHandlers[handler_n].TypeHash == type_hash) return &g.SettingsHandlers[handler_n]; @@ -2702,7 +2704,7 @@ static void LoadIniSettingsFromMemory(const char* buf_readonly) ImGuiContext& g = *GImGui; void* entry_data = NULL; - const ImGuiSettingsHandler* entry_handler = NULL; + ImGuiSettingsHandler* entry_handler = NULL; char* line_end = NULL; for (char* line = buf; line < buf_end; line = line_end + 1) @@ -2733,14 +2735,13 @@ static void LoadIniSettingsFromMemory(const char* buf_readonly) *type_end = 0; // Overwrite first ']' name_start++; // Skip second '[' } - const ImGuiID type_hash = ImHash(type_start, 0, 0); - entry_handler = ImGui::FindSettingsHandler(type_hash); - entry_data = entry_handler ? entry_handler->ReadOpenFn(g, name_start) : NULL; + entry_handler = ImGui::FindSettingsHandler(type_start); + entry_data = entry_handler ? entry_handler->ReadOpenFn(&g, entry_handler, name_start) : NULL; } else if (entry_handler != NULL && entry_data != NULL) { // Let type handler parse the line - entry_handler->ReadLineFn(g, entry_data, line); + entry_handler->ReadLineFn(&g, entry_handler, entry_data, line); } } ImGui::MemFree(buf); @@ -2770,7 +2771,10 @@ static void SaveIniSettingsToMemory(ImVector& out_buf) ImGuiTextBuffer buf; for (int handler_n = 0; handler_n < g.SettingsHandlers.Size; handler_n++) - g.SettingsHandlers[handler_n].WriteAllFn(g, &buf); + { + ImGuiSettingsHandler* handler = &g.SettingsHandlers[handler_n]; + handler->WriteAllFn(&g, handler, &buf); + } buf.Buf.pop_back(); // Remove extra zero-terminator used by ImGuiTextBuffer out_buf.swap(buf.Buf); diff --git a/imgui_internal.h b/imgui_internal.h index babda0b5d..6a2513d28 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -376,9 +376,12 @@ struct ImGuiSettingsHandler { const char* TypeName; // Short description stored in .ini file. Disallowed characters: '[' ']' ImGuiID TypeHash; // == ImHash(TypeName, 0, 0) - void* (*ReadOpenFn)(ImGuiContext& ctx, const char* name); - void (*ReadLineFn)(ImGuiContext& ctx, void* entry, const char* line); - void (*WriteAllFn)(ImGuiContext& ctx, ImGuiTextBuffer* out_buf); + void* (*ReadOpenFn)(ImGuiContext* ctx, ImGuiSettingsHandler* handler, const char* name); + void (*ReadLineFn)(ImGuiContext* ctx, ImGuiSettingsHandler* handler, void* entry, const char* line); + void (*WriteAllFn)(ImGuiContext* ctx, ImGuiSettingsHandler* handler, ImGuiTextBuffer* out_buf); + void* UserData; + + ImGuiSettingsHandler() { memset(this, 0, sizeof(*this)); } }; // Mouse cursor data (used when io.MouseDrawCursor is set) @@ -870,7 +873,7 @@ namespace ImGui IMGUI_API void Initialize(); IMGUI_API void MarkIniSettingsDirty(); - IMGUI_API ImGuiSettingsHandler* FindSettingsHandler(ImGuiID type_id); + IMGUI_API ImGuiSettingsHandler* FindSettingsHandler(const char* type_name); IMGUI_API ImGuiWindowSettings* FindWindowSettings(ImGuiID id); IMGUI_API void SetActiveID(ImGuiID id, ImGuiWindow* window); From 4b1240b2e1371ce76de0e6cd30f53bfd88df4ecc Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 23 Nov 2017 18:18:56 +0100 Subject: [PATCH 823/921] Fixed non-popup child windows not honoring the HiddenFrames flag (can't see a reason). Docking relies on this. --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 336c43f78..b0564cba5 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2867,7 +2867,7 @@ static void AddWindowToRenderList(ImVector& out_render_list, ImGuiW ImGuiWindow* child = window->DC.ChildWindows[i]; if (!child->Active) // clipped children may have been marked not active continue; - if ((child->Flags & ImGuiWindowFlags_Popup) && child->HiddenFrames > 0) + if (child->HiddenFrames > 0) continue; AddWindowToRenderList(out_render_list, child); } From 4fc9f440732d8a5694550b98cb4030135457c230 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 3 Jan 2018 20:45:06 +0100 Subject: [PATCH 824/921] Merge of minor left-overs from private work branch to reduce drifts. Should be functionally a no-op. --- imgui.cpp | 25 +++++++++++++------------ imgui_internal.h | 2 +- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index b0564cba5..3728a890e 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4339,9 +4339,6 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) IM_ASSERT(g.Initialized); // Forgot to call ImGui::NewFrame() IM_ASSERT(g.FrameCountEnded != g.FrameCount); // Called ImGui::Render() or ImGui::EndFrame() and haven't called ImGui::NewFrame() again yet - if (flags & ImGuiWindowFlags_NoInputs) - flags |= ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize; - // Find or create ImGuiWindow* window = FindWindowByName(name); if (!window) @@ -4350,6 +4347,12 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window = CreateNewWindow(name, size_on_first_use, flags); } + // Automatically disable manual moving/resizing when NoInputs is set + if (flags & ImGuiWindowFlags_NoInputs) + flags |= ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize; + //if (flags & ImGuiWindowFlags_NavFlattened) + // IM_ASSERT(flags & ImGuiWindowFlags_ChildWindow); + const int current_frame = g.FrameCount; const bool first_begin_of_the_frame = (window->LastFrameActive != current_frame); if (first_begin_of_the_frame) @@ -4877,18 +4880,16 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) } // Title text (FIXME: refactor text alignment facilities along with RenderText helpers) - const ImVec2 text_size = CalcTextSize(name, NULL, true); - ImVec2 text_min = window->Pos; - ImVec2 text_max = window->Pos + ImVec2(window->Size.x, style.FramePadding.y*2 + text_size.y); - ImRect clip_rect; - clip_rect.Max = ImVec2(window->Pos.x + window->Size.x - (p_open ? title_bar_rect.GetHeight() - 3 : style.FramePadding.x), text_max.y); // Match the size of CloseWindowButton() + ImVec2 text_size = CalcTextSize(name, NULL, true); + ImRect text_r = title_bar_rect; float pad_left = (flags & ImGuiWindowFlags_NoCollapse) == 0 ? (style.FramePadding.x + g.FontSize + style.ItemInnerSpacing.x) : style.FramePadding.x; float pad_right = (p_open != NULL) ? (style.FramePadding.x + g.FontSize + style.ItemInnerSpacing.x) : style.FramePadding.x; if (style.WindowTitleAlign.x > 0.0f) pad_right = ImLerp(pad_right, pad_left, style.WindowTitleAlign.x); - text_min.x += pad_left; - text_max.x -= pad_right; - clip_rect.Min = ImVec2(text_min.x, window->Pos.y); - RenderTextClipped(text_min, text_max, name, NULL, &text_size, style.WindowTitleAlign, &clip_rect); + text_r.Min.x += pad_left; + text_r.Max.x -= pad_right; + ImRect clip_rect = text_r; + clip_rect.Max.x = window->Pos.x + window->Size.x - (p_open ? title_bar_rect.GetHeight() - 3 : style.FramePadding.x); // Match the size of CloseButton() + RenderTextClipped(text_r.Min, text_r.Max, name, NULL, &text_size, style.WindowTitleAlign, &clip_rect); } // Save clipped aabb so we can access it in constant-time in FindHoveredWindow() diff --git a/imgui_internal.h b/imgui_internal.h index 6a2513d28..c80970250 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -775,7 +775,7 @@ struct IMGUI_API ImGuiWindow ImVec2 ScrollTargetCenterRatio; // 0.0f = scroll so that target position is at top, 0.5f = scroll so that target position is centered bool ScrollbarX, ScrollbarY; ImVec2 ScrollbarSizes; - bool Active; // Set to true on Begin() + bool Active; // Set to true on Begin(), unless Collapsed bool WasActive; bool WriteAccessed; // Set to true when any widget access the current window bool Collapsed; // Set when collapsing window to become only title-bar From ecbfdd3143e60802c15d5341f664723ffb273d90 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 4 Jan 2018 11:06:12 +0100 Subject: [PATCH 825/921] Added extraneous initialization to NULL. (#1527). --- imgui_draw.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index c7232af8f..0cb7cd82f 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1439,7 +1439,7 @@ void ImFontAtlas::GetTexDataAsRGBA32(unsigned char** out_pixels, int* out_wid // Although it is likely to be the most commonly used format, our font rendering is 1 channel / 8 bpp if (!TexPixelsRGBA32) { - unsigned char* pixels; + unsigned char* pixels = NULL; GetTexDataAsAlpha8(&pixels, NULL, NULL); if (pixels) { From 4c90529c62ecb765a8b4315d91f69af157ee12df Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 4 Jan 2018 11:42:05 +0100 Subject: [PATCH 826/921] Examples: Visual Studio projects: Disabled extraneous function-level check in Release build. --- examples/directx10_example/directx10_example.vcxproj | 2 ++ examples/directx11_example/directx11_example.vcxproj | 2 ++ examples/directx9_example/directx9_example.vcxproj | 2 ++ examples/opengl2_example/opengl2_example.vcxproj | 2 ++ examples/opengl3_example/opengl3_example.vcxproj | 2 ++ 5 files changed, 10 insertions(+) diff --git a/examples/directx10_example/directx10_example.vcxproj b/examples/directx10_example/directx10_example.vcxproj index c4f15c569..8583e1dec 100644 --- a/examples/directx10_example/directx10_example.vcxproj +++ b/examples/directx10_example/directx10_example.vcxproj @@ -110,6 +110,7 @@ true true ..\..;%(AdditionalIncludeDirectories);$(DXSDK_DIR)Include; + false true @@ -127,6 +128,7 @@ true true ..\..;%(AdditionalIncludeDirectories);$(DXSDK_DIR)Include; + false true diff --git a/examples/directx11_example/directx11_example.vcxproj b/examples/directx11_example/directx11_example.vcxproj index 944c8e863..7099a7bd4 100644 --- a/examples/directx11_example/directx11_example.vcxproj +++ b/examples/directx11_example/directx11_example.vcxproj @@ -110,6 +110,7 @@ true true ..\..;%(AdditionalIncludeDirectories);$(DXSDK_DIR)Include; + false true @@ -127,6 +128,7 @@ true true ..\..;%(AdditionalIncludeDirectories);$(DXSDK_DIR)Include; + false true diff --git a/examples/directx9_example/directx9_example.vcxproj b/examples/directx9_example/directx9_example.vcxproj index c10731dee..6fe7c9cec 100644 --- a/examples/directx9_example/directx9_example.vcxproj +++ b/examples/directx9_example/directx9_example.vcxproj @@ -110,6 +110,7 @@ true true ..\..;%(AdditionalIncludeDirectories);$(DXSDK_DIR)Include; + false true @@ -127,6 +128,7 @@ true true ..\..;%(AdditionalIncludeDirectories);$(DXSDK_DIR)Include; + false true diff --git a/examples/opengl2_example/opengl2_example.vcxproj b/examples/opengl2_example/opengl2_example.vcxproj index bea2104d1..a6cbebd63 100644 --- a/examples/opengl2_example/opengl2_example.vcxproj +++ b/examples/opengl2_example/opengl2_example.vcxproj @@ -116,6 +116,7 @@ true true $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + false true @@ -135,6 +136,7 @@ true true $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + false true diff --git a/examples/opengl3_example/opengl3_example.vcxproj b/examples/opengl3_example/opengl3_example.vcxproj index 8d8bec90f..d481c943a 100644 --- a/examples/opengl3_example/opengl3_example.vcxproj +++ b/examples/opengl3_example/opengl3_example.vcxproj @@ -116,6 +116,7 @@ true true $(SolutionDir)\libs\glfw\include;$(SolutionDir)\libs\gl3w;..\..;%(AdditionalIncludeDirectories) + false true @@ -135,6 +136,7 @@ true true $(SolutionDir)\libs\glfw\include;$(SolutionDir)\libs\gl3w;..\..;%(AdditionalIncludeDirectories) + false true From 007f4034c907defdf781a1d34ad1f769b0374436 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 5 Jan 2018 15:33:24 +0100 Subject: [PATCH 827/921] Internals: Added LastActiveId, LastActiveIdTimer. (#1537) --- imgui.cpp | 8 ++++++++ imgui_internal.h | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/imgui.cpp b/imgui.cpp index 3728a890e..82dc2d6ef 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1929,7 +1929,14 @@ void ImGui::SetActiveID(ImGuiID id, ImGuiWindow* window) ImGuiContext& g = *GImGui; g.ActiveIdIsJustActivated = (g.ActiveId != id); if (g.ActiveIdIsJustActivated) + { g.ActiveIdTimer = 0.0f; + if (id != 0) + { + g.LastActiveId = id; + g.LastActiveIdTimer = 0.0f; + } + } g.ActiveId = id; g.ActiveIdAllowOverlap = false; g.ActiveIdIsAlive |= (id != 0); @@ -2308,6 +2315,7 @@ void ImGui::NewFrame() ClearActiveID(); if (g.ActiveId) g.ActiveIdTimer += g.IO.DeltaTime; + g.LastActiveIdTimer += g.IO.DeltaTime; g.ActiveIdPreviousFrame = g.ActiveId; g.ActiveIdIsAlive = false; g.ActiveIdIsJustActivated = false; diff --git a/imgui_internal.h b/imgui_internal.h index c80970250..cfc84437f 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -533,6 +533,8 @@ struct ImGuiContext bool ActiveIdAllowOverlap; // Active widget allows another widget to steal active id (generally for overlapping widgets, but not always) ImVec2 ActiveIdClickOffset; // Clicked offset from upper-left corner, if applicable (currently only set by ButtonBehavior) ImGuiWindow* ActiveIdWindow; + ImGuiID LastActiveId; // Store the last non-zero ActiveID, useful for animation. + float LastActiveIdTimer; ImGuiWindow* MovingWindow; // Track the child window we clicked on to move a window. ImGuiID MovingWindowMoveId; // == MovingWindow->MoveId ImVector ColorModifiers; // Stack for PushStyleColor()/PopStyleColor() @@ -629,6 +631,8 @@ struct ImGuiContext ActiveIdAllowOverlap = false; ActiveIdClickOffset = ImVec2(-1,-1); ActiveIdWindow = NULL; + LastActiveId = 0; + LastActiveIdTimer = 0.0f; MovingWindow = NULL; MovingWindowMoveId = 0; From 95b773370fceeaa5cbfadd6353b08a05381edcbc Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 5 Jan 2018 17:39:53 +0100 Subject: [PATCH 828/921] Revert "Internals: Added LastActiveId, LastActiveIdTimer. (#1537)" Will come up with a better design later. This reverts commit 007f4034c907defdf781a1d34ad1f769b0374436. --- imgui.cpp | 8 -------- imgui_internal.h | 4 ---- 2 files changed, 12 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 82dc2d6ef..3728a890e 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1929,14 +1929,7 @@ void ImGui::SetActiveID(ImGuiID id, ImGuiWindow* window) ImGuiContext& g = *GImGui; g.ActiveIdIsJustActivated = (g.ActiveId != id); if (g.ActiveIdIsJustActivated) - { g.ActiveIdTimer = 0.0f; - if (id != 0) - { - g.LastActiveId = id; - g.LastActiveIdTimer = 0.0f; - } - } g.ActiveId = id; g.ActiveIdAllowOverlap = false; g.ActiveIdIsAlive |= (id != 0); @@ -2315,7 +2308,6 @@ void ImGui::NewFrame() ClearActiveID(); if (g.ActiveId) g.ActiveIdTimer += g.IO.DeltaTime; - g.LastActiveIdTimer += g.IO.DeltaTime; g.ActiveIdPreviousFrame = g.ActiveId; g.ActiveIdIsAlive = false; g.ActiveIdIsJustActivated = false; diff --git a/imgui_internal.h b/imgui_internal.h index cfc84437f..c80970250 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -533,8 +533,6 @@ struct ImGuiContext bool ActiveIdAllowOverlap; // Active widget allows another widget to steal active id (generally for overlapping widgets, but not always) ImVec2 ActiveIdClickOffset; // Clicked offset from upper-left corner, if applicable (currently only set by ButtonBehavior) ImGuiWindow* ActiveIdWindow; - ImGuiID LastActiveId; // Store the last non-zero ActiveID, useful for animation. - float LastActiveIdTimer; ImGuiWindow* MovingWindow; // Track the child window we clicked on to move a window. ImGuiID MovingWindowMoveId; // == MovingWindow->MoveId ImVector ColorModifiers; // Stack for PushStyleColor()/PopStyleColor() @@ -631,8 +629,6 @@ struct ImGuiContext ActiveIdAllowOverlap = false; ActiveIdClickOffset = ImVec2(-1,-1); ActiveIdWindow = NULL; - LastActiveId = 0; - LastActiveIdTimer = 0.0f; MovingWindow = NULL; MovingWindowMoveId = 0; From 20ae6439eaf7bee14872fedd07b0188cc0a9afee Mon Sep 17 00:00:00 2001 From: Nick Dandoulakis Date: Fri, 5 Jan 2018 22:16:35 +0200 Subject: [PATCH 829/921] CS_DBLCLKS support for Directx9 --- examples/directx9_example/imgui_impl_dx9.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/examples/directx9_example/imgui_impl_dx9.cpp b/examples/directx9_example/imgui_impl_dx9.cpp index 484e84cde..de00f88d2 100644 --- a/examples/directx9_example/imgui_impl_dx9.cpp +++ b/examples/directx9_example/imgui_impl_dx9.cpp @@ -192,13 +192,16 @@ IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wPa switch (msg) { case WM_LBUTTONDOWN: + case WM_LBUTTONDBLCLK: case WM_RBUTTONDOWN: + case WM_RBUTTONDBLCLK: case WM_MBUTTONDOWN: + case WM_MBUTTONDBLCLK: { int button = 0; - if (msg == WM_LBUTTONDOWN) button = 0; - if (msg == WM_RBUTTONDOWN) button = 1; - if (msg == WM_MBUTTONDOWN) button = 2; + if (msg == WM_LBUTTONDOWN || msg == WM_LBUTTONDBLCLK) button = 0; + if (msg == WM_RBUTTONDOWN || msg == WM_RBUTTONDBLCLK) button = 1; + if (msg == WM_MBUTTONDOWN || msg == WM_MBUTTONDBLCLK) button = 2; if (!IsAnyMouseButtonDown() && GetCapture() == NULL) SetCapture(hwnd); io.MouseDown[button] = true; From 583e97b2975989dbe1762ee61a4fd4eb84541f0b Mon Sep 17 00:00:00 2001 From: Nick Dandoulakis Date: Fri, 5 Jan 2018 22:25:30 +0200 Subject: [PATCH 830/921] CS_DBLCLKS support for DirectX 10 --- examples/directx10_example/imgui_impl_dx10.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/examples/directx10_example/imgui_impl_dx10.cpp b/examples/directx10_example/imgui_impl_dx10.cpp index 59152673b..6338be725 100644 --- a/examples/directx10_example/imgui_impl_dx10.cpp +++ b/examples/directx10_example/imgui_impl_dx10.cpp @@ -246,13 +246,16 @@ IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wPa switch (msg) { case WM_LBUTTONDOWN: + case WM_LBUTTONDBLCLK: case WM_RBUTTONDOWN: + case WM_RBUTTONDBLCLK: case WM_MBUTTONDOWN: + case WM_MBUTTONDBLCLK: { int button = 0; - if (msg == WM_LBUTTONDOWN) button = 0; - if (msg == WM_RBUTTONDOWN) button = 1; - if (msg == WM_MBUTTONDOWN) button = 2; + if (msg == WM_LBUTTONDOWN || msg == WM_LBUTTONDBLCLK) button = 0; + if (msg == WM_RBUTTONDOWN || msg == WM_RBUTTONDBLCLK) button = 1; + if (msg == WM_MBUTTONDOWN || msg == WM_MBUTTONDBLCLK) button = 2; if (!IsAnyMouseButtonDown() && GetCapture() == NULL) SetCapture(hwnd); io.MouseDown[button] = true; From bfc25bc8a3c017084c7fc23c955e0c33e13e0226 Mon Sep 17 00:00:00 2001 From: Nick Dandoulakis Date: Fri, 5 Jan 2018 22:28:27 +0200 Subject: [PATCH 831/921] CS_DBLCLKS support for DirectX 11 --- examples/directx11_example/imgui_impl_dx11.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/examples/directx11_example/imgui_impl_dx11.cpp b/examples/directx11_example/imgui_impl_dx11.cpp index af6e54f49..7016301b2 100644 --- a/examples/directx11_example/imgui_impl_dx11.cpp +++ b/examples/directx11_example/imgui_impl_dx11.cpp @@ -253,13 +253,16 @@ IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wPa switch (msg) { case WM_LBUTTONDOWN: + case WM_LBUTTONDBLCLK: case WM_RBUTTONDOWN: + case WM_RBUTTONDBLCLK: case WM_MBUTTONDOWN: + case WM_MBUTTONDBLCLK: { int button = 0; - if (msg == WM_LBUTTONDOWN) button = 0; - if (msg == WM_RBUTTONDOWN) button = 1; - if (msg == WM_MBUTTONDOWN) button = 2; + if (msg == WM_LBUTTONDOWN || msg == WM_LBUTTONDBLCLK) button = 0; + if (msg == WM_RBUTTONDOWN || msg == WM_RBUTTONDBLCLK) button = 1; + if (msg == WM_MBUTTONDOWN || msg == WM_MBUTTONDBLCLK) button = 2; if (!IsAnyMouseButtonDown() && GetCapture() == NULL) SetCapture(hwnd); io.MouseDown[button] = true; From 407955d9fbcfe5391e5f28790f21c15f85d06c90 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 5 Jan 2018 22:05:02 +0100 Subject: [PATCH 832/921] Examples: Using IM_OFFSETOF macro. + Comments --- examples/allegro5_example/imgui_impl_a5.cpp | 8 +++----- examples/apple_example/imguiex-ios/imgui_impl_ios.mm | 9 ++++----- examples/opengl2_example/imgui_impl_glfw.cpp | 8 +++----- examples/opengl3_example/imgui_impl_glfw_gl3.cpp | 8 +++----- examples/sdl_opengl2_example/imgui_impl_sdl.cpp | 8 +++----- examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp | 8 +++----- imgui.h | 2 +- 7 files changed, 20 insertions(+), 31 deletions(-) diff --git a/examples/allegro5_example/imgui_impl_a5.cpp b/examples/allegro5_example/imgui_impl_a5.cpp index 0d3859239..7a7d4cc1e 100644 --- a/examples/allegro5_example/imgui_impl_a5.cpp +++ b/examples/allegro5_example/imgui_impl_a5.cpp @@ -28,8 +28,6 @@ static double g_Time = 0.0; static ALLEGRO_MOUSE_CURSOR* g_MouseCursorInvisible = NULL; static ALLEGRO_VERTEX_DECL* g_VertexDecl = NULL; -#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) - struct ImDrawVertAllegro { ImVec2 pos; @@ -162,9 +160,9 @@ bool ImGui_ImplA5_Init(ALLEGRO_DISPLAY* display) // We still use a custom declaration to use 'ALLEGRO_PRIM_TEX_COORD' instead of 'ALLEGRO_PRIM_TEX_COORD_PIXEL' else we can't do a reliable conversion. ALLEGRO_VERTEX_ELEMENT elems[] = { - { ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_2, OFFSETOF(ImDrawVertAllegro, pos) }, - { ALLEGRO_PRIM_TEX_COORD, ALLEGRO_PRIM_FLOAT_2, OFFSETOF(ImDrawVertAllegro, uv) }, - { ALLEGRO_PRIM_COLOR_ATTR, 0, OFFSETOF(ImDrawVertAllegro, col) }, + { ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_2, IM_OFFSETOF(ImDrawVertAllegro, pos) }, + { ALLEGRO_PRIM_TEX_COORD, ALLEGRO_PRIM_FLOAT_2, IM_OFFSETOF(ImDrawVertAllegro, uv) }, + { ALLEGRO_PRIM_COLOR_ATTR, 0, IM_OFFSETOF(ImDrawVertAllegro, col) }, { 0, 0, 0 } }; g_VertexDecl = al_create_vertex_decl(elems, sizeof(ImDrawVertAllegro)); diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.mm b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm index bfcae7cd1..7fd7466c9 100644 --- a/examples/apple_example/imguiex-ios/imgui_impl_ios.mm +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm @@ -793,11 +793,10 @@ bool ImGui_ImplIOS_CreateDeviceObjects() glEnableVertexAttribArray(g_AttribLocationUV); glEnableVertexAttribArray(g_AttribLocationColor); -#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) - glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos)); - glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv)); - glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col)); -#undef OFFSETOF + glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, pos)); + glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, uv)); + glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, col)); + glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); diff --git a/examples/opengl2_example/imgui_impl_glfw.cpp b/examples/opengl2_example/imgui_impl_glfw.cpp index 33df611e7..a635cc9af 100644 --- a/examples/opengl2_example/imgui_impl_glfw.cpp +++ b/examples/opengl2_example/imgui_impl_glfw.cpp @@ -77,15 +77,14 @@ void ImGui_ImplGlfwGL2_RenderDrawLists(ImDrawData* draw_data) glLoadIdentity(); // Render command lists - #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) for (int n = 0; n < draw_data->CmdListsCount; n++) { const ImDrawList* cmd_list = draw_data->CmdLists[n]; const ImDrawVert* vtx_buffer = cmd_list->VtxBuffer.Data; const ImDrawIdx* idx_buffer = cmd_list->IdxBuffer.Data; - glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + OFFSETOF(ImDrawVert, pos))); - glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + OFFSETOF(ImDrawVert, uv))); - glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + OFFSETOF(ImDrawVert, col))); + glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + IM_OFFSETOF(ImDrawVert, pos))); + glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + IM_OFFSETOF(ImDrawVert, uv))); + glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + IM_OFFSETOF(ImDrawVert, col))); for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) { @@ -103,7 +102,6 @@ void ImGui_ImplGlfwGL2_RenderDrawLists(ImDrawData* draw_data) idx_buffer += pcmd->ElemCount; } } - #undef OFFSETOF // Restore modified state glDisableClientState(GL_COLOR_ARRAY); diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp index 6c439fa18..a608e370b 100644 --- a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp +++ b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp @@ -269,11 +269,9 @@ bool ImGui_ImplGlfwGL3_CreateDeviceObjects() glEnableVertexAttribArray(g_AttribLocationUV); glEnableVertexAttribArray(g_AttribLocationColor); -#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) - glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos)); - glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv)); - glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col)); -#undef OFFSETOF + glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, pos)); + glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, uv)); + glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, col)); ImGui_ImplGlfwGL3_CreateFontsTexture(); diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl.cpp b/examples/sdl_opengl2_example/imgui_impl_sdl.cpp index baf5c0176..c997d36de 100644 --- a/examples/sdl_opengl2_example/imgui_impl_sdl.cpp +++ b/examples/sdl_opengl2_example/imgui_impl_sdl.cpp @@ -70,15 +70,14 @@ void ImGui_ImplSdl_RenderDrawLists(ImDrawData* draw_data) glLoadIdentity(); // Render command lists - #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) for (int n = 0; n < draw_data->CmdListsCount; n++) { const ImDrawList* cmd_list = draw_data->CmdLists[n]; const ImDrawVert* vtx_buffer = cmd_list->VtxBuffer.Data; const ImDrawIdx* idx_buffer = cmd_list->IdxBuffer.Data; - glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + OFFSETOF(ImDrawVert, pos))); - glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + OFFSETOF(ImDrawVert, uv))); - glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + OFFSETOF(ImDrawVert, col))); + glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + IM_OFFSETOF(ImDrawVert, pos))); + glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + IM_OFFSETOF(ImDrawVert, uv))); + glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + IM_OFFSETOF(ImDrawVert, col))); for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) { @@ -96,7 +95,6 @@ void ImGui_ImplSdl_RenderDrawLists(ImDrawData* draw_data) idx_buffer += pcmd->ElemCount; } } - #undef OFFSETOF // Restore modified state glDisableClientState(GL_COLOR_ARRAY); diff --git a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp index 93849cf8b..4cdbe0f1b 100644 --- a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp +++ b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp @@ -273,11 +273,9 @@ bool ImGui_ImplSdlGL3_CreateDeviceObjects() glEnableVertexAttribArray(g_AttribLocationUV); glEnableVertexAttribArray(g_AttribLocationColor); -#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) - glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos)); - glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv)); - glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col)); -#undef OFFSETOF + glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, pos)); + glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, uv)); + glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, col)); ImGui_ImplSdlGL3_CreateFontsTexture(); diff --git a/imgui.h b/imgui.h index fc9791a74..bb717eb4d 100644 --- a/imgui.h +++ b/imgui.h @@ -39,7 +39,7 @@ #define IM_FMTLIST(FMT) #endif #define IM_ARRAYSIZE(_ARR) ((int)(sizeof(_ARR)/sizeof(*_ARR))) -#define IM_OFFSETOF(_TYPE,_ELM) ((size_t)&(((_TYPE*)0)->_ELM)) +#define IM_OFFSETOF(_TYPE,_MEMBER) ((size_t)&(((_TYPE*)0)->_MEMBER)) // Offset of _MEMBER within _TYPE. Standardized as offsetof() in modern C++. #if defined(__clang__) #pragma clang diagnostic push From 3d24a9eb405f024dd0be17608e9a912b0862efa7 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 5 Jan 2018 22:32:27 +0100 Subject: [PATCH 833/921] Examples: DirectX9/10/11: Comments about CS_DBLCLKS + formatting tweaks. (#1538) --- examples/directx10_example/imgui_impl_dx10.cpp | 10 ++++------ examples/directx11_example/imgui_impl_dx11.cpp | 10 ++++------ examples/directx9_example/imgui_impl_dx9.cpp | 10 ++++------ 3 files changed, 12 insertions(+), 18 deletions(-) diff --git a/examples/directx10_example/imgui_impl_dx10.cpp b/examples/directx10_example/imgui_impl_dx10.cpp index 6338be725..d181f7a5d 100644 --- a/examples/directx10_example/imgui_impl_dx10.cpp +++ b/examples/directx10_example/imgui_impl_dx10.cpp @@ -240,17 +240,15 @@ static bool IsAnyMouseButtonDown() // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. // PS: In this Win32 handler, we use the capture API (GetCapture/SetCapture/ReleaseCapture) to be able to read mouse coordinations when dragging mouse outside of our window bounds. +// PS: We treat DBLCLK messages as regular mouse down messages, so this code will work on windows classes that have the CS_DBLCLKS flag set. Our own example app code doesn't set this flag. IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { ImGuiIO& io = ImGui::GetIO(); switch (msg) { - case WM_LBUTTONDOWN: - case WM_LBUTTONDBLCLK: - case WM_RBUTTONDOWN: - case WM_RBUTTONDBLCLK: - case WM_MBUTTONDOWN: - case WM_MBUTTONDBLCLK: + case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK: + case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK: + case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK: { int button = 0; if (msg == WM_LBUTTONDOWN || msg == WM_LBUTTONDBLCLK) button = 0; diff --git a/examples/directx11_example/imgui_impl_dx11.cpp b/examples/directx11_example/imgui_impl_dx11.cpp index 7016301b2..833a0bb07 100644 --- a/examples/directx11_example/imgui_impl_dx11.cpp +++ b/examples/directx11_example/imgui_impl_dx11.cpp @@ -247,17 +247,15 @@ static bool IsAnyMouseButtonDown() // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. // PS: In this Win32 handler, we use the capture API (GetCapture/SetCapture/ReleaseCapture) to be able to read mouse coordinations when dragging mouse outside of our window bounds. +// PS: We treat DBLCLK messages as regular mouse down messages, so this code will work on windows classes that have the CS_DBLCLKS flag set. Our own example app code doesn't set this flag. IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { ImGuiIO& io = ImGui::GetIO(); switch (msg) { - case WM_LBUTTONDOWN: - case WM_LBUTTONDBLCLK: - case WM_RBUTTONDOWN: - case WM_RBUTTONDBLCLK: - case WM_MBUTTONDOWN: - case WM_MBUTTONDBLCLK: + case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK: + case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK: + case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK: { int button = 0; if (msg == WM_LBUTTONDOWN || msg == WM_LBUTTONDBLCLK) button = 0; diff --git a/examples/directx9_example/imgui_impl_dx9.cpp b/examples/directx9_example/imgui_impl_dx9.cpp index de00f88d2..40f675aff 100644 --- a/examples/directx9_example/imgui_impl_dx9.cpp +++ b/examples/directx9_example/imgui_impl_dx9.cpp @@ -186,17 +186,15 @@ static bool IsAnyMouseButtonDown() // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. // PS: In this Win32 handler, we use the capture API (GetCapture/SetCapture/ReleaseCapture) to be able to read mouse coordinations when dragging mouse outside of our window bounds. +// PS: We treat DBLCLK messages as regular mouse down messages, so this code will work on windows classes that have the CS_DBLCLKS flag set. Our own example app code doesn't set this flag. IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { ImGuiIO& io = ImGui::GetIO(); switch (msg) { - case WM_LBUTTONDOWN: - case WM_LBUTTONDBLCLK: - case WM_RBUTTONDOWN: - case WM_RBUTTONDBLCLK: - case WM_MBUTTONDOWN: - case WM_MBUTTONDBLCLK: + case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK: + case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK: + case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK: { int button = 0; if (msg == WM_LBUTTONDOWN || msg == WM_LBUTTONDBLCLK) button = 0; From 2874aabb9305645ff2e2de0615ce067573d80527 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 7 Jan 2018 12:29:54 +0100 Subject: [PATCH 834/921] Internals: BringWindowToFront() iterate front to back, faster in majority of use cases. --- imgui.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 3728a890e..fef9e11cd 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -5123,10 +5123,10 @@ void ImGui::BringWindowToFront(ImGuiWindow* window) ImGuiContext& g = *GImGui; if (g.Windows.back() == window) return; - for (int i = 0; i < g.Windows.Size; i++) + for (int i = g.Windows.Size - 2; i >= 0; i--) // We can ignore the front most window if (g.Windows[i] == window) { - g.Windows.erase(g.Windows.begin() + i); + g.Windows.erase(g.Windows.Data + i); g.Windows.push_back(window); break; } From 5fd19f037fdb4d2054002e787055b910278832fd Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 7 Jan 2018 12:34:52 +0100 Subject: [PATCH 835/921] Internals: renamed FocusPreviousWindow() to FocusfrontMostActiveWindow() --- imgui.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index fef9e11cd..bf40902b8 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -675,7 +675,7 @@ static bool DataTypeApplyOpFromText(const char* buf, const char* ini namespace ImGui { -static void FocusPreviousWindow(); +static void FocusFrontMostActiveWindow(); } //----------------------------------------------------------------------------- @@ -2511,7 +2511,7 @@ void ImGui::NewFrame() // Closing the focused window restore focus to the first active root window in descending z-order if (g.NavWindow && !g.NavWindow->WasActive) - FocusPreviousWindow(); + FocusFrontMostActiveWindow(); // No window should be open at the beginning of the frame. // But in order to allow the user to call NewFrame() multiple times without calling Render(), we are doing an explicit clear. @@ -5172,7 +5172,7 @@ void ImGui::FocusWindow(ImGuiWindow* window) BringWindowToFront(window); } -void ImGui::FocusPreviousWindow() +void ImGui::FocusFrontMostActiveWindow() { ImGuiContext& g = *GImGui; for (int i = g.Windows.Size - 1; i >= 0; i--) From a34490239c5f58ddbf47c6c07b95441a9f6db982 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 7 Jan 2018 13:51:36 +0100 Subject: [PATCH 836/921] Internals: Popup: Separating MousePosOnOpen and PopupPosOnOpen. They are equal in the master branch but different in the navigation branch. --- imgui.cpp | 6 ++++-- imgui_internal.h | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index bf40902b8..2f2443a21 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3725,7 +3725,9 @@ void ImGui::OpenPopupEx(ImGuiID id, bool reopen_existing) ImGuiContext& g = *GImGui; ImGuiWindow* parent_window = g.CurrentWindow; int current_stack_size = g.CurrentPopupStack.Size; - ImGuiPopupRef popup_ref = ImGuiPopupRef(id, parent_window, parent_window->GetID("##Menus"), g.IO.MousePos); // Tagged as new ref because constructor sets Window to NULL. + ImVec2 mouse_pos = g.IO.MousePos; + ImVec2 popup_pos = mouse_pos; // NB: In the Navigation branch popup_pos may not use mouse_pos. + ImGuiPopupRef popup_ref = ImGuiPopupRef(id, parent_window, parent_window->GetID("##Menus"), popup_pos, mouse_pos); // Tagged as new ref because constructor sets Window to NULL. if (g.OpenPopupStack.Size < current_stack_size + 1) g.OpenPopupStack.push_back(popup_ref); else if (reopen_existing || g.OpenPopupStack[current_stack_size].PopupId != id) @@ -4479,7 +4481,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // Popup first latch mouse position, will position itself when it appears next frame window->AutoPosLastDirection = ImGuiDir_None; if ((flags & ImGuiWindowFlags_Popup) != 0 && !window_pos_set_by_api) - window->PosFloat = g.IO.MousePos; + window->PosFloat = g.CurrentPopupStack.back().PopupPosOnOpen; } // Collapse window by double-clicking on title bar diff --git a/imgui_internal.h b/imgui_internal.h index c80970250..bdadc464e 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -401,9 +401,10 @@ struct ImGuiPopupRef ImGuiWindow* Window; // Resolved on BeginPopup() - may stay unresolved if user never calls OpenPopup() ImGuiWindow* ParentWindow; // Set on OpenPopup() ImGuiID ParentMenuSet; // Set on OpenPopup() + ImVec2 PopupPosOnOpen; // Preferred popup position (typically == MousePosOnOpen when using mouse) ImVec2 MousePosOnOpen; // Copy of mouse position at the time of opening popup - ImGuiPopupRef(ImGuiID id, ImGuiWindow* parent_window, ImGuiID parent_menu_set, const ImVec2& mouse_pos) { PopupId = id; Window = NULL; ParentWindow = parent_window; ParentMenuSet = parent_menu_set; MousePosOnOpen = mouse_pos; } + ImGuiPopupRef(ImGuiID id, ImGuiWindow* parent_window, ImGuiID parent_menu_set, const ImVec2& popup_pos, const ImVec2& mouse_pos) { PopupId = id; Window = NULL; ParentWindow = parent_window; ParentMenuSet = parent_menu_set; PopupPosOnOpen = popup_pos; MousePosOnOpen = mouse_pos; } }; struct ImGuiColumnData From d730a763f6d84dd8d235c427295a321d75385bc7 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 7 Jan 2018 14:32:42 +0100 Subject: [PATCH 837/921] Internal: Reworked FocusFrontMostActiveWindow() so it fits the Nav branch usage as well. --- imgui.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 2f2443a21..75b6aa40c 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -675,7 +675,7 @@ static bool DataTypeApplyOpFromText(const char* buf, const char* ini namespace ImGui { -static void FocusFrontMostActiveWindow(); +static void FocusFrontMostActiveWindow(ImGuiWindow* ignore_window); } //----------------------------------------------------------------------------- @@ -2511,7 +2511,7 @@ void ImGui::NewFrame() // Closing the focused window restore focus to the first active root window in descending z-order if (g.NavWindow && !g.NavWindow->WasActive) - FocusFrontMostActiveWindow(); + FocusFrontMostActiveWindow(NULL); // No window should be open at the beginning of the frame. // But in order to allow the user to call NewFrame() multiple times without calling Render(), we are doing an explicit clear. @@ -5174,11 +5174,11 @@ void ImGui::FocusWindow(ImGuiWindow* window) BringWindowToFront(window); } -void ImGui::FocusFrontMostActiveWindow() +void ImGui::FocusFrontMostActiveWindow(ImGuiWindow* ignore_window) { ImGuiContext& g = *GImGui; for (int i = g.Windows.Size - 1; i >= 0; i--) - if (g.Windows[i]->WasActive && !(g.Windows[i]->Flags & ImGuiWindowFlags_ChildWindow)) + if (g.Windows[i] != ignore_window && g.Windows[i]->WasActive && !(g.Windows[i]->Flags & ImGuiWindowFlags_ChildWindow)) { FocusWindow(g.Windows[i]); return; From c337cdcfd3b153541e685d4ad53b908f2d901f2e Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 7 Jan 2018 15:02:09 +0100 Subject: [PATCH 838/921] Internal: ButtonBehavior: Tweak to update g.ActiveIdClickOffset more consistently --- imgui.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 75b6aa40c..d952e287f 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -6253,20 +6253,14 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool { SetActiveID(id, window); // Hold on ID FocusWindow(window); - g.ActiveIdClickOffset = g.IO.MousePos - bb.Min; } if (((flags & ImGuiButtonFlags_PressedOnClick) && g.IO.MouseClicked[0]) || ((flags & ImGuiButtonFlags_PressedOnDoubleClick) && g.IO.MouseDoubleClicked[0])) { pressed = true; if (flags & ImGuiButtonFlags_NoHoldingActiveID) - { ClearActiveID(); - } else - { SetActiveID(id, window); // Hold on ID - g.ActiveIdClickOffset = g.IO.MousePos - bb.Min; - } FocusWindow(window); } if ((flags & ImGuiButtonFlags_PressedOnRelease) && g.IO.MouseReleased[0]) @@ -6286,6 +6280,8 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool bool held = false; if (g.ActiveId == id) { + if (g.ActiveIdIsJustActivated) + g.ActiveIdClickOffset = g.IO.MousePos - bb.Min; if (g.IO.MouseDown[0]) { held = true; From 63e4677b8148d67336e9807334a4401a93bf9d82 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 7 Jan 2018 15:22:54 +0100 Subject: [PATCH 839/921] Popup: BeginPopupContextItem(), BeginPopupContextWindow(), BeginPopupContextVoid(), OpenPopupOnItemClick() all react on mouse release instead of mouse click. Note that they don't use the full ButtonBehavior() or tracking aabb on both click and release. Applications I've tried seems to behave inconsistently there but on-release-without-tracking is both fairly common and doesn't require extra code for the id tracking. (~#439) --- imgui.cpp | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index d952e287f..e63341b41 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3904,7 +3904,7 @@ void ImGui::EndPopup() bool ImGui::OpenPopupOnItemClick(const char* str_id, int mouse_button) { ImGuiWindow* window = GImGui->CurrentWindow; - if (IsMouseClicked(mouse_button) && IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup)) + if (IsMouseReleased(mouse_button) && IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup)) { ImGuiID id = str_id ? window->GetID(str_id) : window->DC.LastItemId; // If user hasn't passed an ID, we can use the LastItemID. Using LastItemID as a Popup ID won't conflict! IM_ASSERT(id != 0); // However, you cannot pass a NULL str_id if the last item has no identifier (e.g. a Text() item) @@ -3922,9 +3922,8 @@ bool ImGui::BeginPopupContextItem(const char* str_id, int mouse_button) ImGuiWindow* window = GImGui->CurrentWindow; ImGuiID id = str_id ? window->GetID(str_id) : window->DC.LastItemId; // If user hasn't passed an ID, we can use the LastItemID. Using LastItemID as a Popup ID won't conflict! IM_ASSERT(id != 0); // However, you cannot pass a NULL str_id if the last item has no identifier (e.g. a Text() item) - if (IsMouseClicked(mouse_button)) - if (IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup)) - OpenPopupEx(id, true); + if (IsMouseReleased(mouse_button) && IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup)) + OpenPopupEx(id, true); return BeginPopupEx(id, ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoSavedSettings); } @@ -3933,10 +3932,9 @@ bool ImGui::BeginPopupContextWindow(const char* str_id, int mouse_button, bool a if (!str_id) str_id = "window_context"; ImGuiID id = GImGui->CurrentWindow->GetID(str_id); - if (IsMouseClicked(mouse_button)) - if (IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup)) - if (also_over_items || !IsAnyItemHovered()) - OpenPopupEx(id, true); + if (IsMouseReleased(mouse_button) && IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup)) + if (also_over_items || !IsAnyItemHovered()) + OpenPopupEx(id, true); return BeginPopupEx(id, ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoSavedSettings); } @@ -3945,7 +3943,7 @@ bool ImGui::BeginPopupContextVoid(const char* str_id, int mouse_button) if (!str_id) str_id = "void_context"; ImGuiID id = GImGui->CurrentWindow->GetID(str_id); - if (!IsAnyWindowHovered() && IsMouseClicked(mouse_button)) + if (IsMouseReleased(mouse_button) && !IsAnyWindowHovered()) OpenPopupEx(id, true); return BeginPopupEx(id, ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoSavedSettings); } From e09852fc49c8aa12f44702f3c9aa85c7c5472003 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 7 Jan 2018 15:34:15 +0100 Subject: [PATCH 840/921] Popups: Revert aca23fd3f0eb1b6fb109840f5fc942c49312d096 (Oct 20, 2017). Because 1) I can't seem to find a default. 2) The if is definitively faulty and would have been all true. 3) It looks like possibly the following commit 6ab737a4bb288d553f4de3e3841e393ef96d32a0 could have made this unnecessary. Not absolutly certain. (~#439) --- imgui.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index e63341b41..7d6c3f9be 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3737,8 +3737,8 @@ void ImGui::OpenPopupEx(ImGuiID id, bool reopen_existing) // When reopening a popup we first refocus its parent, otherwise if its parent is itself a popup it would get closed by CloseInactivePopups(). // This is equivalent to what ClosePopupToLevel() does. - if (g.OpenPopupStack[current_stack_size].PopupId == id) - FocusWindow(parent_window); + //if (g.OpenPopupStack[current_stack_size].PopupId == id) + // FocusWindow(parent_window); } } From 369189b675c456116a932848d781beeb4b439bd0 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 7 Jan 2018 15:40:46 +0100 Subject: [PATCH 841/921] Internals: Popup: Explicitely setting up ImGuiPopupRef reduces confusion. --- imgui.cpp | 10 +++++++--- imgui_internal.h | 2 -- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 7d6c3f9be..41d75c6bd 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3725,9 +3725,13 @@ void ImGui::OpenPopupEx(ImGuiID id, bool reopen_existing) ImGuiContext& g = *GImGui; ImGuiWindow* parent_window = g.CurrentWindow; int current_stack_size = g.CurrentPopupStack.Size; - ImVec2 mouse_pos = g.IO.MousePos; - ImVec2 popup_pos = mouse_pos; // NB: In the Navigation branch popup_pos may not use mouse_pos. - ImGuiPopupRef popup_ref = ImGuiPopupRef(id, parent_window, parent_window->GetID("##Menus"), popup_pos, mouse_pos); // Tagged as new ref because constructor sets Window to NULL. + ImGuiPopupRef popup_ref; // Tagged as new ref as Window will be set back to NULL if we write this into OpenPopupStack. + popup_ref.PopupId = id; + popup_ref.Window = NULL; + popup_ref.ParentWindow = parent_window; + popup_ref.ParentMenuSet = parent_window->GetID("##Menus"); + popup_ref.MousePosOnOpen = g.IO.MousePos; + popup_ref.PopupPosOnOpen = g.IO.MousePos; // NB: In the Navigation branch popup_pos may not use mouse_pos. if (g.OpenPopupStack.Size < current_stack_size + 1) g.OpenPopupStack.push_back(popup_ref); else if (reopen_existing || g.OpenPopupStack[current_stack_size].PopupId != id) diff --git a/imgui_internal.h b/imgui_internal.h index bdadc464e..771d4e073 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -403,8 +403,6 @@ struct ImGuiPopupRef ImGuiID ParentMenuSet; // Set on OpenPopup() ImVec2 PopupPosOnOpen; // Preferred popup position (typically == MousePosOnOpen when using mouse) ImVec2 MousePosOnOpen; // Copy of mouse position at the time of opening popup - - ImGuiPopupRef(ImGuiID id, ImGuiWindow* parent_window, ImGuiID parent_menu_set, const ImVec2& popup_pos, const ImVec2& mouse_pos) { PopupId = id; Window = NULL; ParentWindow = parent_window; ParentMenuSet = parent_menu_set; PopupPosOnOpen = popup_pos; MousePosOnOpen = mouse_pos; } }; struct ImGuiColumnData From 3678307cd953e51913d1d1076f8124a96c34e0a3 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 7 Jan 2018 15:56:14 +0100 Subject: [PATCH 842/921] Popup, Menus: Tweaks and comments. --- imgui.cpp | 4 ++-- imgui_internal.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 41d75c6bd..b3c7a8038 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3729,7 +3729,7 @@ void ImGui::OpenPopupEx(ImGuiID id, bool reopen_existing) popup_ref.PopupId = id; popup_ref.Window = NULL; popup_ref.ParentWindow = parent_window; - popup_ref.ParentMenuSet = parent_window->GetID("##Menus"); + popup_ref.ParentIdOnOpen = parent_window->IDStack.back(); popup_ref.MousePosOnOpen = g.IO.MousePos; popup_ref.PopupPosOnOpen = g.IO.MousePos; // NB: In the Navigation branch popup_pos may not use mouse_pos. if (g.OpenPopupStack.Size < current_stack_size + 1) @@ -9664,7 +9664,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled) bool pressed; bool menu_is_open = IsPopupOpen(id); - bool menuset_is_open = !(window->Flags & ImGuiWindowFlags_Popup) && (g.OpenPopupStack.Size > g.CurrentPopupStack.Size && g.OpenPopupStack[g.CurrentPopupStack.Size].ParentMenuSet == window->GetID("##Menus")); + bool menuset_is_open = !(window->Flags & ImGuiWindowFlags_Popup) && (g.OpenPopupStack.Size > g.CurrentPopupStack.Size && g.OpenPopupStack[g.CurrentPopupStack.Size].ParentIdOnOpen == window->IDStack.back()); ImGuiWindow* backed_nav_window = g.NavWindow; if (menuset_is_open) g.NavWindow = window; // Odd hack to allow hovering across menus of a same menu-set (otherwise we wouldn't be able to hover parent) diff --git a/imgui_internal.h b/imgui_internal.h index 771d4e073..f355a4922 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -400,7 +400,7 @@ struct ImGuiPopupRef ImGuiID PopupId; // Set on OpenPopup() ImGuiWindow* Window; // Resolved on BeginPopup() - may stay unresolved if user never calls OpenPopup() ImGuiWindow* ParentWindow; // Set on OpenPopup() - ImGuiID ParentMenuSet; // Set on OpenPopup() + ImGuiID ParentIdOnOpen; // Set on OpenPopup(), we need this to differenciate multiple menu sets from each others (e.g. inside menu bar vs loose menu items) ImVec2 PopupPosOnOpen; // Preferred popup position (typically == MousePosOnOpen when using mouse) ImVec2 MousePosOnOpen; // Copy of mouse position at the time of opening popup }; From 69ff65f054eddba4936473be814d58305913479f Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 7 Jan 2018 16:11:25 +0100 Subject: [PATCH 843/921] Internals: Popup: Renaming fields. --- imgui.cpp | 12 ++++++------ imgui_internal.h | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index b3c7a8038..9eef1ba4d 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3550,7 +3550,7 @@ ImVec2 ImGui::GetMousePosOnOpeningCurrentPopup() { ImGuiContext& g = *GImGui; if (g.CurrentPopupStack.Size > 0) - return g.OpenPopupStack[g.CurrentPopupStack.Size-1].MousePosOnOpen; + return g.OpenPopupStack[g.CurrentPopupStack.Size-1].OpenMousePos; return g.IO.MousePos; } @@ -3729,9 +3729,9 @@ void ImGui::OpenPopupEx(ImGuiID id, bool reopen_existing) popup_ref.PopupId = id; popup_ref.Window = NULL; popup_ref.ParentWindow = parent_window; - popup_ref.ParentIdOnOpen = parent_window->IDStack.back(); - popup_ref.MousePosOnOpen = g.IO.MousePos; - popup_ref.PopupPosOnOpen = g.IO.MousePos; // NB: In the Navigation branch popup_pos may not use mouse_pos. + popup_ref.OpenParentId = parent_window->IDStack.back(); + popup_ref.OpenMousePos = g.IO.MousePos; + popup_ref.OpenPopupPos = g.IO.MousePos; // NB: In the Navigation branch popup_pos may not use mouse_pos. if (g.OpenPopupStack.Size < current_stack_size + 1) g.OpenPopupStack.push_back(popup_ref); else if (reopen_existing || g.OpenPopupStack[current_stack_size].PopupId != id) @@ -4483,7 +4483,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // Popup first latch mouse position, will position itself when it appears next frame window->AutoPosLastDirection = ImGuiDir_None; if ((flags & ImGuiWindowFlags_Popup) != 0 && !window_pos_set_by_api) - window->PosFloat = g.CurrentPopupStack.back().PopupPosOnOpen; + window->PosFloat = g.CurrentPopupStack.back().OpenPopupPos; } // Collapse window by double-clicking on title bar @@ -9664,7 +9664,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled) bool pressed; bool menu_is_open = IsPopupOpen(id); - bool menuset_is_open = !(window->Flags & ImGuiWindowFlags_Popup) && (g.OpenPopupStack.Size > g.CurrentPopupStack.Size && g.OpenPopupStack[g.CurrentPopupStack.Size].ParentIdOnOpen == window->IDStack.back()); + bool menuset_is_open = !(window->Flags & ImGuiWindowFlags_Popup) && (g.OpenPopupStack.Size > g.CurrentPopupStack.Size && g.OpenPopupStack[g.CurrentPopupStack.Size].OpenParentId == window->IDStack.back()); ImGuiWindow* backed_nav_window = g.NavWindow; if (menuset_is_open) g.NavWindow = window; // Odd hack to allow hovering across menus of a same menu-set (otherwise we wouldn't be able to hover parent) diff --git a/imgui_internal.h b/imgui_internal.h index f355a4922..4ff50d8f5 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -400,9 +400,9 @@ struct ImGuiPopupRef ImGuiID PopupId; // Set on OpenPopup() ImGuiWindow* Window; // Resolved on BeginPopup() - may stay unresolved if user never calls OpenPopup() ImGuiWindow* ParentWindow; // Set on OpenPopup() - ImGuiID ParentIdOnOpen; // Set on OpenPopup(), we need this to differenciate multiple menu sets from each others (e.g. inside menu bar vs loose menu items) - ImVec2 PopupPosOnOpen; // Preferred popup position (typically == MousePosOnOpen when using mouse) - ImVec2 MousePosOnOpen; // Copy of mouse position at the time of opening popup + ImGuiID OpenParentId; // Set on OpenPopup(), we need this to differenciate multiple menu sets from each others (e.g. inside menu bar vs loose menu items) + ImVec2 OpenPopupPos; // Set on OpenPopup(), preferred popup position (typically == OpenMousePos when using mouse) + ImVec2 OpenMousePos; // Set on OpenPopup(), copy of mouse position at the time of opening popup }; struct ImGuiColumnData From deab2ab015c4d66a9cdd51971e616a6ac444bad1 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 7 Jan 2018 16:15:54 +0100 Subject: [PATCH 844/921] Popups: Gently handle the user mistakenly calling OpenPopup() every frame. (when reopen_existing is true). (#1497) --- imgui.cpp | 18 +++++++++++++++--- imgui_internal.h | 1 + 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 9eef1ba4d..d735e0266 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3729,15 +3729,27 @@ void ImGui::OpenPopupEx(ImGuiID id, bool reopen_existing) popup_ref.PopupId = id; popup_ref.Window = NULL; popup_ref.ParentWindow = parent_window; + popup_ref.OpenFrameCount = g.FrameCount; popup_ref.OpenParentId = parent_window->IDStack.back(); popup_ref.OpenMousePos = g.IO.MousePos; - popup_ref.OpenPopupPos = g.IO.MousePos; // NB: In the Navigation branch popup_pos may not use mouse_pos. + popup_ref.OpenPopupPos = g.IO.MousePos; // NB: In the Navigation branch OpenPopupPos doesn't use the mouse position, hence the separation here. + if (g.OpenPopupStack.Size < current_stack_size + 1) + { g.OpenPopupStack.push_back(popup_ref); + } else if (reopen_existing || g.OpenPopupStack[current_stack_size].PopupId != id) { - g.OpenPopupStack.resize(current_stack_size+1); - g.OpenPopupStack[current_stack_size] = popup_ref; + // Close child popups if any + g.OpenPopupStack.resize(current_stack_size + 1); + + // Gently handle the user mistakenly calling OpenPopup() every frame. It is a programming mistake! However, if we were to run the regular code path, the ui + // would become completely unusable because the popup will always be in hidden-while-calculating-size state _while_ claiming focus. Which would be a very confusing + // situation for the programmer. Instead, we silently allow the popup to proceed, it will keep reappearing and the programming error will be more obvious to understand. + if (g.OpenPopupStack[current_stack_size].PopupId == id && g.OpenPopupStack[current_stack_size].OpenFrameCount == g.FrameCount - 1) + g.OpenPopupStack[current_stack_size].OpenFrameCount = popup_ref.OpenFrameCount; + else + g.OpenPopupStack[current_stack_size] = popup_ref; // When reopening a popup we first refocus its parent, otherwise if its parent is itself a popup it would get closed by CloseInactivePopups(). // This is equivalent to what ClosePopupToLevel() does. diff --git a/imgui_internal.h b/imgui_internal.h index 4ff50d8f5..be4284d24 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -400,6 +400,7 @@ struct ImGuiPopupRef ImGuiID PopupId; // Set on OpenPopup() ImGuiWindow* Window; // Resolved on BeginPopup() - may stay unresolved if user never calls OpenPopup() ImGuiWindow* ParentWindow; // Set on OpenPopup() + int OpenFrameCount; // Set on OpenPopup() ImGuiID OpenParentId; // Set on OpenPopup(), we need this to differenciate multiple menu sets from each others (e.g. inside menu bar vs loose menu items) ImVec2 OpenPopupPos; // Set on OpenPopup(), preferred popup position (typically == OpenMousePos when using mouse) ImVec2 OpenMousePos; // Set on OpenPopup(), copy of mouse position at the time of opening popup From 3fc7cf190def6ac51cb5791f3ad8cee7a79c4026 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 7 Jan 2018 16:20:02 +0100 Subject: [PATCH 845/921] OpenPopup(): Always reopen existing popup. Removed OpenPopupEx() bool reopen_existing which is always true. This also makes the public API on par with OpenPopupEx(). (#1497, #1533) --- imgui.cpp | 16 ++++++++-------- imgui_internal.h | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index d735e0266..4a21fe4de 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3720,7 +3720,7 @@ void ImGui::EndTooltip() // Popups are closed when user click outside, or activate a pressable item, or CloseCurrentPopup() is called within a BeginPopup()/EndPopup() block. // Popup identifiers are relative to the current ID-stack (so OpenPopup and BeginPopup needs to be at the same level). // One open popup per level of the popup hierarchy (NB: when assigning we reset the Window member of ImGuiPopupRef to NULL) -void ImGui::OpenPopupEx(ImGuiID id, bool reopen_existing) +void ImGui::OpenPopupEx(ImGuiID id) { ImGuiContext& g = *GImGui; ImGuiWindow* parent_window = g.CurrentWindow; @@ -3738,7 +3738,7 @@ void ImGui::OpenPopupEx(ImGuiID id, bool reopen_existing) { g.OpenPopupStack.push_back(popup_ref); } - else if (reopen_existing || g.OpenPopupStack[current_stack_size].PopupId != id) + else { // Close child popups if any g.OpenPopupStack.resize(current_stack_size + 1); @@ -3761,7 +3761,7 @@ void ImGui::OpenPopupEx(ImGuiID id, bool reopen_existing) void ImGui::OpenPopup(const char* str_id) { ImGuiContext& g = *GImGui; - OpenPopupEx(g.CurrentWindow->GetID(str_id), false); + OpenPopupEx(g.CurrentWindow->GetID(str_id)); } static void CloseInactivePopups(ImGuiWindow* ref_window) @@ -3924,7 +3924,7 @@ bool ImGui::OpenPopupOnItemClick(const char* str_id, int mouse_button) { ImGuiID id = str_id ? window->GetID(str_id) : window->DC.LastItemId; // If user hasn't passed an ID, we can use the LastItemID. Using LastItemID as a Popup ID won't conflict! IM_ASSERT(id != 0); // However, you cannot pass a NULL str_id if the last item has no identifier (e.g. a Text() item) - OpenPopupEx(id, true); + OpenPopupEx(id); return true; } return false; @@ -3939,7 +3939,7 @@ bool ImGui::BeginPopupContextItem(const char* str_id, int mouse_button) ImGuiID id = str_id ? window->GetID(str_id) : window->DC.LastItemId; // If user hasn't passed an ID, we can use the LastItemID. Using LastItemID as a Popup ID won't conflict! IM_ASSERT(id != 0); // However, you cannot pass a NULL str_id if the last item has no identifier (e.g. a Text() item) if (IsMouseReleased(mouse_button) && IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup)) - OpenPopupEx(id, true); + OpenPopupEx(id); return BeginPopupEx(id, ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoSavedSettings); } @@ -3950,7 +3950,7 @@ bool ImGui::BeginPopupContextWindow(const char* str_id, int mouse_button, bool a ImGuiID id = GImGui->CurrentWindow->GetID(str_id); if (IsMouseReleased(mouse_button) && IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup)) if (also_over_items || !IsAnyItemHovered()) - OpenPopupEx(id, true); + OpenPopupEx(id); return BeginPopupEx(id, ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoSavedSettings); } @@ -3960,7 +3960,7 @@ bool ImGui::BeginPopupContextVoid(const char* str_id, int mouse_button) str_id = "void_context"; ImGuiID id = GImGui->CurrentWindow->GetID(str_id); if (IsMouseReleased(mouse_button) && !IsAnyWindowHovered()) - OpenPopupEx(id, true); + OpenPopupEx(id); return BeginPopupEx(id, ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoSavedSettings); } @@ -9204,7 +9204,7 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboF if (pressed && !popup_open) { - OpenPopupEx(id, false); + OpenPopupEx(id); popup_open = true; } diff --git a/imgui_internal.h b/imgui_internal.h index be4284d24..9216793b6 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -894,7 +894,7 @@ namespace ImGui IMGUI_API void PushItemFlag(ImGuiItemFlags option, bool enabled); IMGUI_API void PopItemFlag(); - IMGUI_API void OpenPopupEx(ImGuiID id, bool reopen_existing); + IMGUI_API void OpenPopupEx(ImGuiID id); IMGUI_API void ClosePopup(ImGuiID id); IMGUI_API bool IsPopupOpen(ImGuiID id); IMGUI_API bool BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_flags); From a8e5542d78a184f06a4a455a0e6914bea59e6a88 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 7 Jan 2018 18:13:01 +0100 Subject: [PATCH 846/921] BeginPopup: Exposed extra_flags publicly. (#1533) --- imgui.cpp | 4 ++-- imgui.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 4a21fe4de..844b63f8c 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3858,7 +3858,7 @@ bool ImGui::BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_flags) return is_open; } -bool ImGui::BeginPopup(const char* str_id) +bool ImGui::BeginPopup(const char* str_id, ImGuiWindowFlags extra_flags) { ImGuiContext& g = *GImGui; if (g.OpenPopupStack.Size <= g.CurrentPopupStack.Size) // Early out for performance @@ -3866,7 +3866,7 @@ bool ImGui::BeginPopup(const char* str_id) g.NextWindowData.Clear(); // We behave like Begin() and need to consume those values return false; } - return BeginPopupEx(g.CurrentWindow->GetID(str_id), ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoSavedSettings); + return BeginPopupEx(g.CurrentWindow->GetID(str_id), extra_flags|ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoSavedSettings); } bool ImGui::IsPopupOpen(ImGuiID id) diff --git a/imgui.h b/imgui.h index bb717eb4d..215a745e5 100644 --- a/imgui.h +++ b/imgui.h @@ -409,7 +409,7 @@ namespace ImGui // Popups IMGUI_API void OpenPopup(const char* str_id); // call to mark popup as open (don't call every frame!). popups are closed when user click outside, or if CloseCurrentPopup() is called within a BeginPopup()/EndPopup() block. By default, Selectable()/MenuItem() are calling CloseCurrentPopup(). Popup identifiers are relative to the current ID-stack (so OpenPopup and BeginPopup needs to be at the same level). IMGUI_API bool OpenPopupOnItemClick(const char* str_id = NULL, int mouse_button = 1); // helper to open popup when clicked on last item. return true when just opened. - IMGUI_API bool BeginPopup(const char* str_id); // return true if the popup is open, and you can start outputting to it. only call EndPopup() if BeginPopup() returned true! + IMGUI_API bool BeginPopup(const char* str_id, ImGuiWindowFlags extra_flags = 0); // return true if the popup is open, and you can start outputting to it. only call EndPopup() if BeginPopup() returned true! IMGUI_API bool BeginPopupModal(const char* name, bool* p_open = NULL, ImGuiWindowFlags extra_flags = 0); // modal dialog (block interactions behind the modal window, can't close the modal window by clicking outside) IMGUI_API bool BeginPopupContextItem(const char* str_id = NULL, int mouse_button = 1); // helper to open and begin popup when clicked on last item. if you can pass a NULL str_id only if the previous item had an id. If you want to use that on a non-interactive item such as Text() you need to pass in an explicit ID here. read comments in .cpp! IMGUI_API bool BeginPopupContextWindow(const char* str_id = NULL, int mouse_button = 1, bool also_over_items = true); // helper to open and begin popup when clicked on current window. From 168200f91525bfd440cd30c7dadb2dc0992fd257 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 7 Jan 2018 18:15:43 +0100 Subject: [PATCH 847/921] Popups: Comments, reorganize bits of the header section, renamed parameters. --- imgui.cpp | 9 ++++----- imgui.h | 6 +++--- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 844b63f8c..b70574125 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3858,7 +3858,7 @@ bool ImGui::BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_flags) return is_open; } -bool ImGui::BeginPopup(const char* str_id, ImGuiWindowFlags extra_flags) +bool ImGui::BeginPopup(const char* str_id, ImGuiWindowFlags flags) { ImGuiContext& g = *GImGui; if (g.OpenPopupStack.Size <= g.CurrentPopupStack.Size) // Early out for performance @@ -3866,7 +3866,7 @@ bool ImGui::BeginPopup(const char* str_id, ImGuiWindowFlags extra_flags) g.NextWindowData.Clear(); // We behave like Begin() and need to consume those values return false; } - return BeginPopupEx(g.CurrentWindow->GetID(str_id), extra_flags|ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoSavedSettings); + return BeginPopupEx(g.CurrentWindow->GetID(str_id), flags|ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoSavedSettings); } bool ImGui::IsPopupOpen(ImGuiID id) @@ -3881,7 +3881,7 @@ bool ImGui::IsPopupOpen(const char* str_id) return g.OpenPopupStack.Size > g.CurrentPopupStack.Size && g.OpenPopupStack[g.CurrentPopupStack.Size].PopupId == g.CurrentWindow->GetID(str_id); } -bool ImGui::BeginPopupModal(const char* name, bool* p_open, ImGuiWindowFlags extra_flags) +bool ImGui::BeginPopupModal(const char* name, bool* p_open, ImGuiWindowFlags flags) { ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; @@ -3896,8 +3896,7 @@ bool ImGui::BeginPopupModal(const char* name, bool* p_open, ImGuiWindowFlags ext if (g.NextWindowData.PosCond == 0) SetNextWindowPos(g.IO.DisplaySize * 0.5f, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f)); - ImGuiWindowFlags flags = extra_flags|ImGuiWindowFlags_Popup|ImGuiWindowFlags_Modal|ImGuiWindowFlags_NoCollapse|ImGuiWindowFlags_NoSavedSettings; - bool is_open = Begin(name, p_open, flags); + bool is_open = Begin(name, p_open, flags | ImGuiWindowFlags_Popup | ImGuiWindowFlags_Modal | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoSavedSettings); if (!is_open || (p_open && !*p_open)) // NB: is_open can be 'false' when the popup is completely clipped (e.g. zero size display) { EndPopup(); diff --git a/imgui.h b/imgui.h index 215a745e5..d6c5f7b46 100644 --- a/imgui.h +++ b/imgui.h @@ -408,13 +408,13 @@ namespace ImGui // Popups IMGUI_API void OpenPopup(const char* str_id); // call to mark popup as open (don't call every frame!). popups are closed when user click outside, or if CloseCurrentPopup() is called within a BeginPopup()/EndPopup() block. By default, Selectable()/MenuItem() are calling CloseCurrentPopup(). Popup identifiers are relative to the current ID-stack (so OpenPopup and BeginPopup needs to be at the same level). - IMGUI_API bool OpenPopupOnItemClick(const char* str_id = NULL, int mouse_button = 1); // helper to open popup when clicked on last item. return true when just opened. - IMGUI_API bool BeginPopup(const char* str_id, ImGuiWindowFlags extra_flags = 0); // return true if the popup is open, and you can start outputting to it. only call EndPopup() if BeginPopup() returned true! - IMGUI_API bool BeginPopupModal(const char* name, bool* p_open = NULL, ImGuiWindowFlags extra_flags = 0); // modal dialog (block interactions behind the modal window, can't close the modal window by clicking outside) + IMGUI_API bool BeginPopup(const char* str_id, ImGuiWindowFlags flags = 0); // return true if the popup is open, and you can start outputting to it. only call EndPopup() if BeginPopup() returned true! IMGUI_API bool BeginPopupContextItem(const char* str_id = NULL, int mouse_button = 1); // helper to open and begin popup when clicked on last item. if you can pass a NULL str_id only if the previous item had an id. If you want to use that on a non-interactive item such as Text() you need to pass in an explicit ID here. read comments in .cpp! IMGUI_API bool BeginPopupContextWindow(const char* str_id = NULL, int mouse_button = 1, bool also_over_items = true); // helper to open and begin popup when clicked on current window. IMGUI_API bool BeginPopupContextVoid(const char* str_id = NULL, int mouse_button = 1); // helper to open and begin popup when clicked in void (where there are no imgui windows). + IMGUI_API bool BeginPopupModal(const char* name, bool* p_open = NULL, ImGuiWindowFlags flags = 0); // modal dialog (regular window with title bar, block interactions behind the modal window, can't close the modal window by clicking outside) IMGUI_API void EndPopup(); + IMGUI_API bool OpenPopupOnItemClick(const char* str_id = NULL, int mouse_button = 1); // helper to open popup when clicked on last item. return true when just opened. IMGUI_API bool IsPopupOpen(const char* str_id); // return true if the popup is open IMGUI_API void CloseCurrentPopup(); // close the popup we have begin-ed into. clicking on a MenuItem or Selectable automatically close the current popup. From 7484c6344991c91cbec90d439f5e386a4b0dbd2e Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 7 Jan 2018 19:05:42 +0100 Subject: [PATCH 848/921] Examples: OpenGL3+SDL: Changed GLSL shader version to 150 (#1466, #1504) --- examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp index 4cdbe0f1b..5c0208ac3 100644 --- a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp +++ b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp @@ -221,7 +221,7 @@ bool ImGui_ImplSdlGL3_CreateDeviceObjects() glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array); const GLchar *vertex_shader = - "#version 330\n" + "#version 150\n" "uniform mat4 ProjMtx;\n" "in vec2 Position;\n" "in vec2 UV;\n" @@ -236,7 +236,7 @@ bool ImGui_ImplSdlGL3_CreateDeviceObjects() "}\n"; const GLchar* fragment_shader = - "#version 330\n" + "#version 150\n" "uniform sampler2D Texture;\n" "in vec2 Frag_UV;\n" "in vec4 Frag_Color;\n" From 39cb56c39e662a330b278061fb5ab59813c0c911 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 7 Jan 2018 19:06:20 +0100 Subject: [PATCH 849/921] Examples: OpenGL3+GLFW: Using 3.2 context + GLSL version 150 (#1466) --- examples/opengl3_example/imgui_impl_glfw_gl3.cpp | 4 ++-- examples/opengl3_example/main.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp index a608e370b..3307d5310 100644 --- a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp +++ b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp @@ -217,7 +217,7 @@ bool ImGui_ImplGlfwGL3_CreateDeviceObjects() glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array); const GLchar *vertex_shader = - "#version 330\n" + "#version 150\n" "uniform mat4 ProjMtx;\n" "in vec2 Position;\n" "in vec2 UV;\n" @@ -232,7 +232,7 @@ bool ImGui_ImplGlfwGL3_CreateDeviceObjects() "}\n"; const GLchar* fragment_shader = - "#version 330\n" + "#version 150\n" "uniform sampler2D Texture;\n" "in vec2 Frag_UV;\n" "in vec4 Frag_Color;\n" diff --git a/examples/opengl3_example/main.cpp b/examples/opengl3_example/main.cpp index 9e9a3fb6c..6beb855dc 100644 --- a/examples/opengl3_example/main.cpp +++ b/examples/opengl3_example/main.cpp @@ -21,7 +21,7 @@ int main(int, char**) if (!glfwInit()) return 1; glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); #if __APPLE__ glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); From ce95b848250af5386f099ece3ceec15062f57065 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 8 Jan 2018 15:30:39 +0100 Subject: [PATCH 850/921] Added ImGuiKey_Insert for future use. Setup in all example bindings. (#1541) --- examples/allegro5_example/imgui_impl_a5.cpp | 1 + examples/apple_example/imguiex-ios/imgui_impl_ios.mm | 1 + examples/directx10_example/imgui_impl_dx10.cpp | 1 + examples/directx11_example/imgui_impl_dx11.cpp | 1 + examples/directx9_example/imgui_impl_dx9.cpp | 1 + examples/marmalade_example/imgui_impl_marmalade.cpp | 1 + examples/opengl2_example/imgui_impl_glfw.cpp | 1 + examples/opengl3_example/imgui_impl_glfw_gl3.cpp | 1 + examples/sdl_opengl2_example/imgui_impl_sdl.cpp | 1 + examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp | 1 + examples/vulkan_example/imgui_impl_glfw_vulkan.cpp | 1 + imgui.h | 1 + 12 files changed, 12 insertions(+) diff --git a/examples/allegro5_example/imgui_impl_a5.cpp b/examples/allegro5_example/imgui_impl_a5.cpp index 7a7d4cc1e..d3ccffd23 100644 --- a/examples/allegro5_example/imgui_impl_a5.cpp +++ b/examples/allegro5_example/imgui_impl_a5.cpp @@ -177,6 +177,7 @@ bool ImGui_ImplA5_Init(ALLEGRO_DISPLAY* display) io.KeyMap[ImGuiKey_PageDown] = ALLEGRO_KEY_PGDN; io.KeyMap[ImGuiKey_Home] = ALLEGRO_KEY_HOME; io.KeyMap[ImGuiKey_End] = ALLEGRO_KEY_END; + io.KeyMap[ImGuiKey_Insert] = ALLEGRO_KEY_INSERT; io.KeyMap[ImGuiKey_Delete] = ALLEGRO_KEY_DELETE; io.KeyMap[ImGuiKey_Backspace] = ALLEGRO_KEY_BACKSPACE; io.KeyMap[ImGuiKey_Enter] = ALLEGRO_KEY_ENTER; diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.mm b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm index 7fd7466c9..9db45d0f2 100644 --- a/examples/apple_example/imguiex-ios/imgui_impl_ios.mm +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm @@ -488,6 +488,7 @@ void ImGui_ClipboardCallback(uSynergyCookie cookie, enum uSynergyClipboardFormat io.KeyMap[ImGuiKey_DownArrow] = kVK_DownArrow+1; io.KeyMap[ImGuiKey_Home] = kVK_Home+1; io.KeyMap[ImGuiKey_End] = kVK_End+1; + io.KeyMap[ImGuiKey_Insert] = kVK_Help+1; io.KeyMap[ImGuiKey_Delete] = kVK_ForwardDelete+1; io.KeyMap[ImGuiKey_Backspace] = kVK_Delete+1; io.KeyMap[ImGuiKey_Enter] = kVK_Return+1; diff --git a/examples/directx10_example/imgui_impl_dx10.cpp b/examples/directx10_example/imgui_impl_dx10.cpp index d181f7a5d..4f7117a7b 100644 --- a/examples/directx10_example/imgui_impl_dx10.cpp +++ b/examples/directx10_example/imgui_impl_dx10.cpp @@ -545,6 +545,7 @@ bool ImGui_ImplDX10_Init(void* hwnd, ID3D10Device* device) io.KeyMap[ImGuiKey_PageDown] = VK_NEXT; io.KeyMap[ImGuiKey_Home] = VK_HOME; io.KeyMap[ImGuiKey_End] = VK_END; + io.KeyMap[ImGuiKey_Insert] = VK_INSERT; io.KeyMap[ImGuiKey_Delete] = VK_DELETE; io.KeyMap[ImGuiKey_Backspace] = VK_BACK; io.KeyMap[ImGuiKey_Enter] = VK_RETURN; diff --git a/examples/directx11_example/imgui_impl_dx11.cpp b/examples/directx11_example/imgui_impl_dx11.cpp index 833a0bb07..5df7bf1f0 100644 --- a/examples/directx11_example/imgui_impl_dx11.cpp +++ b/examples/directx11_example/imgui_impl_dx11.cpp @@ -547,6 +547,7 @@ bool ImGui_ImplDX11_Init(void* hwnd, ID3D11Device* device, ID3D11DeviceContex io.KeyMap[ImGuiKey_PageDown] = VK_NEXT; io.KeyMap[ImGuiKey_Home] = VK_HOME; io.KeyMap[ImGuiKey_End] = VK_END; + io.KeyMap[ImGuiKey_Insert] = VK_INSERT; io.KeyMap[ImGuiKey_Delete] = VK_DELETE; io.KeyMap[ImGuiKey_Backspace] = VK_BACK; io.KeyMap[ImGuiKey_Enter] = VK_RETURN; diff --git a/examples/directx9_example/imgui_impl_dx9.cpp b/examples/directx9_example/imgui_impl_dx9.cpp index 40f675aff..18ec0d9b5 100644 --- a/examples/directx9_example/imgui_impl_dx9.cpp +++ b/examples/directx9_example/imgui_impl_dx9.cpp @@ -264,6 +264,7 @@ bool ImGui_ImplDX9_Init(void* hwnd, IDirect3DDevice9* device) io.KeyMap[ImGuiKey_PageDown] = VK_NEXT; io.KeyMap[ImGuiKey_Home] = VK_HOME; io.KeyMap[ImGuiKey_End] = VK_END; + io.KeyMap[ImGuiKey_Insert] = VK_INSERT; io.KeyMap[ImGuiKey_Delete] = VK_DELETE; io.KeyMap[ImGuiKey_Backspace] = VK_BACK; io.KeyMap[ImGuiKey_Enter] = VK_RETURN; diff --git a/examples/marmalade_example/imgui_impl_marmalade.cpp b/examples/marmalade_example/imgui_impl_marmalade.cpp index cae1be185..39623cc4d 100644 --- a/examples/marmalade_example/imgui_impl_marmalade.cpp +++ b/examples/marmalade_example/imgui_impl_marmalade.cpp @@ -220,6 +220,7 @@ bool ImGui_Marmalade_Init(bool install_callbacks) io.KeyMap[ImGuiKey_PageDown] = s3eKeyPageDown; io.KeyMap[ImGuiKey_Home] = s3eKeyHome; io.KeyMap[ImGuiKey_End] = s3eKeyEnd; + io.KeyMap[ImGuiKey_Insert] = s3eKeyInsert; io.KeyMap[ImGuiKey_Delete] = s3eKeyDelete; io.KeyMap[ImGuiKey_Backspace] = s3eKeyBackspace; io.KeyMap[ImGuiKey_Enter] = s3eKeyEnter; diff --git a/examples/opengl2_example/imgui_impl_glfw.cpp b/examples/opengl2_example/imgui_impl_glfw.cpp index a635cc9af..d2eb657f6 100644 --- a/examples/opengl2_example/imgui_impl_glfw.cpp +++ b/examples/opengl2_example/imgui_impl_glfw.cpp @@ -211,6 +211,7 @@ bool ImGui_ImplGlfwGL2_Init(GLFWwindow* window, bool install_callbacks) io.KeyMap[ImGuiKey_PageDown] = GLFW_KEY_PAGE_DOWN; io.KeyMap[ImGuiKey_Home] = GLFW_KEY_HOME; io.KeyMap[ImGuiKey_End] = GLFW_KEY_END; + io.KeyMap[ImGuiKey_Insert] = GLFW_KEY_INSERT; io.KeyMap[ImGuiKey_Delete] = GLFW_KEY_DELETE; io.KeyMap[ImGuiKey_Backspace] = GLFW_KEY_BACKSPACE; io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER; diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp index 3307d5310..f35b2654c 100644 --- a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp +++ b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp @@ -323,6 +323,7 @@ bool ImGui_ImplGlfwGL3_Init(GLFWwindow* window, bool install_callbacks) io.KeyMap[ImGuiKey_PageDown] = GLFW_KEY_PAGE_DOWN; io.KeyMap[ImGuiKey_Home] = GLFW_KEY_HOME; io.KeyMap[ImGuiKey_End] = GLFW_KEY_END; + io.KeyMap[ImGuiKey_Insert] = GLFW_KEY_INSERT; io.KeyMap[ImGuiKey_Delete] = GLFW_KEY_DELETE; io.KeyMap[ImGuiKey_Backspace] = GLFW_KEY_BACKSPACE; io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER; diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl.cpp b/examples/sdl_opengl2_example/imgui_impl_sdl.cpp index c997d36de..ac9200837 100644 --- a/examples/sdl_opengl2_example/imgui_impl_sdl.cpp +++ b/examples/sdl_opengl2_example/imgui_impl_sdl.cpp @@ -214,6 +214,7 @@ bool ImGui_ImplSdlGL2_Init(SDL_Window* window) io.KeyMap[ImGuiKey_PageDown] = SDL_SCANCODE_PAGEDOWN; io.KeyMap[ImGuiKey_Home] = SDL_SCANCODE_HOME; io.KeyMap[ImGuiKey_End] = SDL_SCANCODE_END; + io.KeyMap[ImGuiKey_Insert] = SDLK_INSERT; io.KeyMap[ImGuiKey_Delete] = SDLK_DELETE; io.KeyMap[ImGuiKey_Backspace] = SDLK_BACKSPACE; io.KeyMap[ImGuiKey_Enter] = SDLK_RETURN; diff --git a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp index 5c0208ac3..f9e970f38 100644 --- a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp +++ b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp @@ -325,6 +325,7 @@ bool ImGui_ImplSdlGL3_Init(SDL_Window* window) io.KeyMap[ImGuiKey_PageDown] = SDL_SCANCODE_PAGEDOWN; io.KeyMap[ImGuiKey_Home] = SDL_SCANCODE_HOME; io.KeyMap[ImGuiKey_End] = SDL_SCANCODE_END; + io.KeyMap[ImGuiKey_Insert] = SDLK_INSERT; io.KeyMap[ImGuiKey_Delete] = SDLK_DELETE; io.KeyMap[ImGuiKey_Backspace] = SDLK_BACKSPACE; io.KeyMap[ImGuiKey_Enter] = SDLK_RETURN; diff --git a/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp b/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp index 8eb35ec3c..0af380cc6 100644 --- a/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp +++ b/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp @@ -750,6 +750,7 @@ bool ImGui_ImplGlfwVulkan_Init(GLFWwindow* window, bool install_callbacks, Im io.KeyMap[ImGuiKey_PageDown] = GLFW_KEY_PAGE_DOWN; io.KeyMap[ImGuiKey_Home] = GLFW_KEY_HOME; io.KeyMap[ImGuiKey_End] = GLFW_KEY_END; + io.KeyMap[ImGuiKey_Insert] = GLFW_KEY_INSERT; io.KeyMap[ImGuiKey_Delete] = GLFW_KEY_DELETE; io.KeyMap[ImGuiKey_Backspace] = GLFW_KEY_BACKSPACE; io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER; diff --git a/imgui.h b/imgui.h index d6c5f7b46..02832422e 100644 --- a/imgui.h +++ b/imgui.h @@ -671,6 +671,7 @@ enum ImGuiKey_ ImGuiKey_PageDown, ImGuiKey_Home, // for text edit ImGuiKey_End, // for text edit + ImGuiKey_Insert, // for text edit ImGuiKey_Delete, // for text edit ImGuiKey_Backspace, // for text edit ImGuiKey_Enter, // for text edit From fd4d63a0c5f8ed9004d967b5aa011e31be6ba763 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 8 Jan 2018 15:54:41 +0100 Subject: [PATCH 851/921] InputText: Moved code for checking clipboard shortcut so we can expand on it. (#1541) --- TODO.txt | 1 + imgui.cpp | 16 +++++++++------- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/TODO.txt b/TODO.txt index c052aeb5c..a9bc641e7 100644 --- a/TODO.txt +++ b/TODO.txt @@ -64,6 +64,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - input text: add discard flag (e.g. ImGuiInputTextFlags_DiscardActiveBuffer) or make it easier to clear active focus for text replacement during edition (#725) - input text: display bug when clicking a drag/slider after an input text in a different window has all-selected text (order dependant). actually a very old bug but no one appears to have noticed it. - input text multi-line: don't directly call AddText() which does an unnecessary vertex reserve for character count prior to clipping. and/or more line-based clipping to AddText(). and/or reorganize TextUnformatted/RenderText for more efficiency for large text (e.g TextUnformatted could clip and log separately, etc). + - input text multi-line: support for cut/paste without selection (cut/paste the current line) - input text multi-line: line numbers? status bar? (follow up on #200) - input text multi-line: behave better when user changes input buffer while editing is active (even though it is illegal behavior). namely, the change of buffer can create a scrollbar glitch (#725) - input text multi-line: better horizontal scrolling support (#383, #1224) diff --git a/imgui.cpp b/imgui.cpp index b70574125..1f3afb5d5 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -8610,6 +8610,10 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 const bool is_wordmove_key_down = io.OptMacOSXBehaviors ? io.KeyAlt : io.KeyCtrl; // OS X style: Text editing cursor movement using Alt instead of Ctrl const bool is_startend_key_down = io.OptMacOSXBehaviors && io.KeySuper && !io.KeyCtrl && !io.KeyAlt; // OS X style: Line/Text Start and End using Cmd+Arrows instead of Home/End + const bool is_paste = (is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_V)) && is_editable; + const bool is_cut = (is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_X)) && is_editable && !is_password && (!is_multiline || edit_state.HasSelection()); + const bool is_copy = (is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_C)) && !is_password && (!is_multiline || edit_state.HasSelection()); + if (IsKeyPressedMap(ImGuiKey_LeftArrow)) { edit_state.OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_LINESTART : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDLEFT : STB_TEXTEDIT_K_LEFT) | k_mask); } else if (IsKeyPressedMap(ImGuiKey_RightArrow)) { edit_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) SetWindowScrollY(draw_window, ImMax(draw_window->Scroll.y - g.FontSize, 0.0f)); else edit_state.OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_TEXTSTART : STB_TEXTEDIT_K_UP) | k_mask); } @@ -8650,13 +8654,9 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 else if (is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_Z) && is_editable && is_undoable) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_UNDO); edit_state.ClearSelection(); } else if (is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_Y) && is_editable && is_undoable) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_REDO); edit_state.ClearSelection(); } else if (is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_A)) { edit_state.SelectAll(); edit_state.CursorFollow = true; } - else if (is_shortcut_key_only && !is_password && ((IsKeyPressedMap(ImGuiKey_X) && is_editable) || IsKeyPressedMap(ImGuiKey_C)) && (!is_multiline || edit_state.HasSelection())) + else if (is_cut || is_copy) { // Cut, Copy - const bool cut = IsKeyPressedMap(ImGuiKey_X); - if (cut && !edit_state.HasSelection()) - edit_state.SelectAll(); - if (io.SetClipboardTextFn) { const int ib = edit_state.HasSelection() ? ImMin(edit_state.StbState.select_start, edit_state.StbState.select_end) : 0; @@ -8666,13 +8666,15 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 SetClipboardText(edit_state.TempTextBuffer.Data); } - if (cut) + if (is_cut) { + if (!edit_state.HasSelection()) + edit_state.SelectAll(); edit_state.CursorFollow = true; stb_textedit_cut(&edit_state, &edit_state.StbState); } } - else if (is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_V) && is_editable) + else if (is_paste) { // Paste if (const char* clipboard = GetClipboardText()) From 933ee6cd5dac25c9103b6bcb1a4030be38a04aa1 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 8 Jan 2018 16:01:02 +0100 Subject: [PATCH 852/921] InputText: Added alternative clipboard shortcuts: Shift+Delete (cut), Ctrl+Insert (copy), Shift+Insert (paste). (#1541) --- imgui.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 1f3afb5d5..5faa45699 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -8609,10 +8609,12 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 const bool is_shortcut_key_only = (io.OptMacOSXBehaviors ? (io.KeySuper && !io.KeyCtrl) : (io.KeyCtrl && !io.KeySuper)) && !io.KeyAlt && !io.KeyShift; // OS X style: Shortcuts using Cmd/Super instead of Ctrl const bool is_wordmove_key_down = io.OptMacOSXBehaviors ? io.KeyAlt : io.KeyCtrl; // OS X style: Text editing cursor movement using Alt instead of Ctrl const bool is_startend_key_down = io.OptMacOSXBehaviors && io.KeySuper && !io.KeyCtrl && !io.KeyAlt; // OS X style: Line/Text Start and End using Cmd+Arrows instead of Home/End + const bool is_ctrl_key_only = io.KeyCtrl && !io.KeyShift && !io.KeyAlt && !io.KeySuper; + const bool is_shift_key_only = io.KeyShift && !io.KeyCtrl && !io.KeyAlt && !io.KeySuper; - const bool is_paste = (is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_V)) && is_editable; - const bool is_cut = (is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_X)) && is_editable && !is_password && (!is_multiline || edit_state.HasSelection()); - const bool is_copy = (is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_C)) && !is_password && (!is_multiline || edit_state.HasSelection()); + const bool is_cut = ((is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_X)) || (is_shift_key_only && IsKeyPressedMap(ImGuiKey_Delete))) && is_editable && !is_password && (!is_multiline || edit_state.HasSelection()); + const bool is_copy = ((is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_C)) || (is_ctrl_key_only && IsKeyPressedMap(ImGuiKey_Insert))) && !is_password && (!is_multiline || edit_state.HasSelection()); + const bool is_paste = ((is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_V)) || (is_shift_key_only && IsKeyPressedMap(ImGuiKey_Insert))) && is_editable; if (IsKeyPressedMap(ImGuiKey_LeftArrow)) { edit_state.OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_LINESTART : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDLEFT : STB_TEXTEDIT_K_LEFT) | k_mask); } else if (IsKeyPressedMap(ImGuiKey_RightArrow)) { edit_state.OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_LINEEND : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDRIGHT : STB_TEXTEDIT_K_RIGHT) | k_mask); } From 92d75c44bc3468e2495027652391a6ba928979bb Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 8 Jan 2018 23:59:12 +0100 Subject: [PATCH 853/921] Internals: ImVec2 versions of ImMin, ImMax inline float version for a faster full-on-debug-no-inline experience. --- imgui_internal.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/imgui_internal.h b/imgui_internal.h index 9216793b6..4e7054870 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -134,8 +134,8 @@ static inline int ImMin(int lhs, int rhs) static inline int ImMax(int lhs, int rhs) { return lhs >= rhs ? lhs : rhs; } static inline float ImMin(float lhs, float rhs) { return lhs < rhs ? lhs : rhs; } static inline float ImMax(float lhs, float rhs) { return lhs >= rhs ? lhs : rhs; } -static inline ImVec2 ImMin(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(ImMin(lhs.x,rhs.x), ImMin(lhs.y,rhs.y)); } -static inline ImVec2 ImMax(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(ImMax(lhs.x,rhs.x), ImMax(lhs.y,rhs.y)); } +static inline ImVec2 ImMin(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x < rhs.x ? lhs.x : rhs.x, lhs.y < rhs.y ? lhs.y : rhs.y); } +static inline ImVec2 ImMax(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x >= rhs.x ? lhs.x : rhs.x, lhs.y >= rhs.y ? lhs.y : rhs.y); } static inline int ImClamp(int v, int mn, int mx) { return (v < mn) ? mn : (v > mx) ? mx : v; } static inline float ImClamp(float v, float mn, float mx) { return (v < mn) ? mn : (v > mx) ? mx : v; } static inline ImVec2 ImClamp(const ImVec2& f, const ImVec2& mn, ImVec2 mx) { return ImVec2(ImClamp(f.x,mn.x,mx.x), ImClamp(f.y,mn.y,mx.y)); } From 0cabd810712938178e8c90baf45ac0b00bb44e63 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 8 Jan 2018 23:59:51 +0100 Subject: [PATCH 854/921] Internals: Rect: Added ClipWillFull helper + comments on variations. --- imgui_internal.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/imgui_internal.h b/imgui_internal.h index 4e7054870..4958b5ae3 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -285,7 +285,8 @@ struct IMGUI_API ImRect void Expand(const float amount) { Min.x -= amount; Min.y -= amount; Max.x += amount; Max.y += amount; } void Expand(const ImVec2& amount) { Min.x -= amount.x; Min.y -= amount.y; Max.x += amount.x; Max.y += amount.y; } void Translate(const ImVec2& v) { Min.x += v.x; Min.y += v.y; Max.x += v.x; Max.y += v.y; } - void ClipWith(const ImRect& r) { if (Min.x < r.Min.x) Min.x = r.Min.x; if (Min.y < r.Min.y) Min.y = r.Min.y; if (Max.x > r.Max.x) Max.x = r.Max.x; if (Max.y > r.Max.y) Max.y = r.Max.y; } + void ClipWith(const ImRect& r) { Min = ImMax(Min, r.Min); Max = ImMin(Max, r.Max); } // Simple version, may lead to an inverted rectangle, which is fine for Contains/Overlaps test but not for display. + void ClipWithFull(const ImRect& r) { Min = ImClamp(Min, r.Min, r.Max); Max = ImClamp(Max, r.Min, r.Max); } // Full version, ensure both points are fully clipped. void Floor() { Min.x = (float)(int)Min.x; Min.y = (float)(int)Min.y; Max.x = (float)(int)Max.x; Max.y = (float)(int)Max.y; } void FixInverted() { if (Min.x > Max.x) ImSwap(Min.x, Max.x); if (Min.y > Max.y) ImSwap(Min.y, Max.y); } bool IsFinite() const { return Min.x != FLT_MAX; } From f610e25682a94d9d593e4691b03d48f7be7ceec1 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 10 Jan 2018 16:11:29 +0100 Subject: [PATCH 855/921] Internals: Using ImFloor().when appropriate. --- imgui.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 5faa45699..5dd329c3b 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4163,14 +4163,13 @@ static ImGuiWindow* CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFl { // Retrieve settings from .ini file // Use SetWindowPos() or SetNextWindowPos() with the appropriate condition flag to change the initial position of a window. - window->PosFloat = ImVec2(60, 60); - window->Pos = ImVec2((float)(int)window->PosFloat.x, (float)(int)window->PosFloat.y); + window->Pos = window->PosFloat = ImVec2(60, 60); if (ImGuiWindowSettings* settings = ImGui::FindWindowSettings(window->ID)) { SetWindowConditionAllowFlags(window, ImGuiCond_FirstUseEver, false); window->PosFloat = settings->Pos; - window->Pos = ImVec2((float)(int)window->PosFloat.x, (float)(int)window->PosFloat.y); + window->Pos = ImFloor(window->PosFloat); window->Collapsed = settings->Collapsed; if (ImLengthSqr(settings->Size) > 0.00001f) size = settings->Size; @@ -4494,7 +4493,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // Popup first latch mouse position, will position itself when it appears next frame window->AutoPosLastDirection = ImGuiDir_None; if ((flags & ImGuiWindowFlags_Popup) != 0 && !window_pos_set_by_api) - window->PosFloat = g.CurrentPopupStack.back().OpenPopupPos; + window->Pos = window->PosFloat = g.CurrentPopupStack.back().OpenPopupPos; } // Collapse window by double-clicking on title bar @@ -4648,7 +4647,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->PosFloat = ImMin(window->PosFloat, g.IO.DisplaySize - padding); } } - window->Pos = ImVec2((float)(int)window->PosFloat.x, (float)(int)window->PosFloat.y); + window->Pos = ImFloor(window->PosFloat); // Default item width. Make it proportional to window size if window manually resizes if (window->Size.x > 0.0f && !(flags & ImGuiWindowFlags_Tooltip) && !(flags & ImGuiWindowFlags_AlwaysAutoResize)) @@ -4765,7 +4764,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) } if (pos_target.x != FLT_MAX) { - window->Pos = window->PosFloat = ImVec2((float)(int)pos_target.x, (float)(int)pos_target.y); + window->Pos = window->PosFloat = ImFloor(pos_target); MarkIniSettingsDirty(window); } @@ -5593,7 +5592,7 @@ static void SetWindowPos(ImGuiWindow* window, const ImVec2& pos, ImGuiCond cond) // Set const ImVec2 old_pos = window->Pos; window->PosFloat = pos; - window->Pos = ImVec2((float)(int)window->PosFloat.x, (float)(int)window->PosFloat.y); + window->Pos = ImFloor(pos); window->DC.CursorPos += (window->Pos - old_pos); // As we happen to move the window while it is being appended to (which is a bad idea - will smear) let's at least offset the cursor window->DC.CursorMaxPos += (window->Pos - old_pos); // And more importantly we need to adjust this so size calculation doesn't get affected. } From 6c583315e695a8ced6751a0ebb0780f238c1100b Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 10 Jan 2018 18:56:51 +0100 Subject: [PATCH 856/921] Begin: Moving some code around for the benefits of the wip viewport branch. --- imgui.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 5dd329c3b..7c1b9a17f 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4478,6 +4478,13 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->LastFrameActive = current_frame; window->IDStack.resize(1); + // Lock window rounding, border size and rounding so that altering the border sizes for children doesn't have side-effects. + window->WindowRounding = (flags & ImGuiWindowFlags_ChildWindow) ? style.ChildRounding : ((flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiWindowFlags_Modal)) ? style.PopupRounding : style.WindowRounding; + window->WindowBorderSize = (flags & ImGuiWindowFlags_ChildWindow) ? style.ChildBorderSize : ((flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiWindowFlags_Modal)) ? style.PopupBorderSize : style.WindowBorderSize; + window->WindowPadding = style.WindowPadding; + if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & (ImGuiWindowFlags_AlwaysUseWindowPadding | ImGuiWindowFlags_Popup)) && window->WindowBorderSize == 0.0f) + window->WindowPadding = ImVec2(0.0f, (flags & ImGuiWindowFlags_MenuBar) ? style.WindowPadding.y : 0.0f); + // Setup draw list and outer clipping rectangle window->DrawList->Clear(); window->DrawList->Flags = (g.Style.AntiAliasedLines ? ImDrawListFlags_AntiAliasedLines : 0) | (g.Style.AntiAliasedFill ? ImDrawListFlags_AntiAliasedFill : 0); @@ -4534,15 +4541,6 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) } } - // Lock window rounding, border size and rounding so that altering the border sizes for children doesn't have side-effects. - window->WindowRounding = (flags & ImGuiWindowFlags_ChildWindow) ? style.ChildRounding : ((flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiWindowFlags_Modal)) ? style.PopupRounding : style.WindowRounding; - window->WindowBorderSize = (flags & ImGuiWindowFlags_ChildWindow) ? style.ChildBorderSize : ((flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiWindowFlags_Modal)) ? style.PopupBorderSize : style.WindowBorderSize; - window->WindowPadding = style.WindowPadding; - if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & (ImGuiWindowFlags_AlwaysUseWindowPadding | ImGuiWindowFlags_Popup)) && window->WindowBorderSize == 0.0f) - window->WindowPadding = ImVec2(0.0f, (flags & ImGuiWindowFlags_MenuBar) ? style.WindowPadding.y : 0.0f); - const float window_rounding = window->WindowRounding; - const float window_border_size = window->WindowBorderSize; - // Calculate auto-fit size, handle automatic resize const ImVec2 size_auto_fit = CalcSizeAutoFit(window, window->SizeContents); ImVec2 size_full_modified(FLT_MAX, FLT_MAX); @@ -4676,6 +4674,8 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->DrawList->AddRectFilled(fullscreen_rect.Min, fullscreen_rect.Max, GetColorU32(ImGuiCol_ModalWindowDarkening, g.ModalWindowDarkeningRatio)); // Draw window + handle manual resize + const float window_rounding = window->WindowRounding; + const float window_border_size = window->WindowBorderSize; ImRect title_bar_rect = window->TitleBarRect(); if (window->Collapsed) { From 483f9b0d07f3688911bd3e0d0500771103e44624 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 10 Jan 2018 22:55:29 +0100 Subject: [PATCH 857/921] Internals: Begin: Moved DrawList setup code below, the viewport system will need to push the outer clipping rectangle as late as possible. --- imgui.cpp | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 7c1b9a17f..13a12a552 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4485,16 +4485,6 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & (ImGuiWindowFlags_AlwaysUseWindowPadding | ImGuiWindowFlags_Popup)) && window->WindowBorderSize == 0.0f) window->WindowPadding = ImVec2(0.0f, (flags & ImGuiWindowFlags_MenuBar) ? style.WindowPadding.y : 0.0f); - // Setup draw list and outer clipping rectangle - window->DrawList->Clear(); - window->DrawList->Flags = (g.Style.AntiAliasedLines ? ImDrawListFlags_AntiAliasedLines : 0) | (g.Style.AntiAliasedFill ? ImDrawListFlags_AntiAliasedFill : 0); - window->DrawList->PushTextureID(g.Font->ContainerAtlas->TexID); - ImRect fullscreen_rect(GetVisibleRect()); - if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Popup)) - PushClipRect(parent_window->ClipRect.Min, parent_window->ClipRect.Max, true); - else - PushClipRect(fullscreen_rect.Min, fullscreen_rect.Max, true); - if (window_just_activated_by_user) { // Popup first latch mouse position, will position itself when it appears next frame @@ -4669,6 +4659,18 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) if (!(flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_Tooltip)) || (flags & ImGuiWindowFlags_Popup)) want_focus = true; + // DRAWING + + // Setup draw list and outer clipping rectangle + window->DrawList->Clear(); + window->DrawList->Flags = (g.Style.AntiAliasedLines ? ImDrawListFlags_AntiAliasedLines : 0) | (g.Style.AntiAliasedFill ? ImDrawListFlags_AntiAliasedFill : 0); + window->DrawList->PushTextureID(g.Font->ContainerAtlas->TexID); + ImRect fullscreen_rect(GetVisibleRect()); + if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Popup)) + PushClipRect(parent_window->ClipRect.Min, parent_window->ClipRect.Max, true); + else + PushClipRect(fullscreen_rect.Min, fullscreen_rect.Max, true); + // Draw modal window background (darkens what is behind them) if ((flags & ImGuiWindowFlags_Modal) != 0 && window == GetFrontMostModalRootWindow()) window->DrawList->AddRectFilled(fullscreen_rect.Min, fullscreen_rect.Max, GetColorU32(ImGuiCol_ModalWindowDarkening, g.ModalWindowDarkeningRatio)); From 1eee10778be403a9942727e89eaf22c5c0a7b0c5 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 10 Jan 2018 23:06:51 +0100 Subject: [PATCH 858/921] Internals: Begin: Refactor some code into an UpdateManualResize() function. --- imgui.cpp | 171 +++++++++++++++++++++++++++++------------------------- 1 file changed, 91 insertions(+), 80 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 13a12a552..cf5cfb77c 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -675,6 +675,7 @@ static bool DataTypeApplyOpFromText(const char* buf, const char* ini namespace ImGui { +static void UpdateManualResize(ImGuiWindow* window, const ImVec2& size_auto_fit, int* border_held, ImU32 resize_grip_col[4]); static void FocusFrontMostActiveWindow(ImGuiWindow* ignore_window); } @@ -4338,6 +4339,93 @@ static ImRect GetBorderRect(ImGuiWindow* window, int border_n, float perp_paddin return ImRect(); } +// Handle resize for: Resize Grips, Borders, Gamepad +static void ImGui::UpdateManualResize(ImGuiWindow* window, const ImVec2& size_auto_fit, int* border_held, ImU32 resize_grip_col[4]) +{ + ImGuiContext& g = *GImGui; + ImGuiWindowFlags flags = window->Flags; + if ((flags & ImGuiWindowFlags_NoResize) || (flags & ImGuiWindowFlags_AlwaysAutoResize) || window->AutoFitFramesX > 0 || window->AutoFitFramesY > 0) + return; + + const int resize_grip_count = (flags & ImGuiWindowFlags_ResizeFromAnySide) ? 2 : 1; // 4 + const int resize_border_count = (flags & ImGuiWindowFlags_ResizeFromAnySide) ? 4 : 0; + const float grip_draw_size = (float)(int)ImMax(g.FontSize * 1.35f, window->WindowRounding + 1.0f + g.FontSize * 0.2f); + const float grip_hover_size = (float)(int)(grip_draw_size * 0.75f); + + ImVec2 pos_target(FLT_MAX, FLT_MAX); + ImVec2 size_target(FLT_MAX, FLT_MAX); + + // Manual resize grips + PushID("#RESIZE"); + for (int resize_grip_n = 0; resize_grip_n < resize_grip_count; resize_grip_n++) + { + const ImGuiResizeGripDef& grip = resize_grip_def[resize_grip_n]; + const ImVec2 corner = ImLerp(window->Pos, window->Pos + window->Size, grip.CornerPos); + + // Using the FlattenChilds button flag we make the resize button accessible even if we are hovering over a child window + ImRect resize_rect(corner, corner + grip.InnerDir * grip_hover_size); + resize_rect.FixInverted(); + bool hovered, held; + ButtonBehavior(resize_rect, window->GetID((void*)(intptr_t)resize_grip_n), &hovered, &held, ImGuiButtonFlags_FlattenChildren); + if (hovered || held) + g.MouseCursor = (resize_grip_n & 1) ? ImGuiMouseCursor_ResizeNESW : ImGuiMouseCursor_ResizeNWSE; + + if (g.HoveredWindow == window && held && g.IO.MouseDoubleClicked[0] && resize_grip_n == 0) + { + // Manual auto-fit when double-clicking + size_target = CalcSizeAfterConstraint(window, size_auto_fit); + ClearActiveID(); + } + else if (held) + { + // Resize from any of the four corners + // We don't use an incremental MouseDelta but rather compute an absolute target size based on mouse position + ImVec2 corner_target = g.IO.MousePos - g.ActiveIdClickOffset + resize_rect.GetSize() * grip.CornerPos; // Corner of the window corresponding to our corner grip + CalcResizePosSizeFromAnyCorner(window, corner_target, grip.CornerPos, &pos_target, &size_target); + } + if (resize_grip_n == 0 || held || hovered) + resize_grip_col[resize_grip_n] = GetColorU32(held ? ImGuiCol_ResizeGripActive : hovered ? ImGuiCol_ResizeGripHovered : ImGuiCol_ResizeGrip); + } + for (int border_n = 0; border_n < resize_border_count; border_n++) + { + const float BORDER_SIZE = 5.0f; // FIXME: Only works _inside_ window because of HoveredWindow check. + const float BORDER_APPEAR_TIMER = 0.05f; // Reduce visual noise + bool hovered, held; + ImRect border_rect = GetBorderRect(window, border_n, grip_hover_size, BORDER_SIZE); + ButtonBehavior(border_rect, window->GetID((void*)(intptr_t)(border_n + 4)), &hovered, &held, ImGuiButtonFlags_FlattenChildren); + if ((hovered && g.HoveredIdTimer > BORDER_APPEAR_TIMER) || held) + { + g.MouseCursor = (border_n & 1) ? ImGuiMouseCursor_ResizeEW : ImGuiMouseCursor_ResizeNS; + if (held) *border_held = border_n; + } + if (held) + { + ImVec2 border_target = window->Pos; + ImVec2 border_posn; + if (border_n == 0) { border_posn = ImVec2(0, 0); border_target.y = (g.IO.MousePos.y - g.ActiveIdClickOffset.y); } + if (border_n == 1) { border_posn = ImVec2(1, 0); border_target.x = (g.IO.MousePos.x - g.ActiveIdClickOffset.x + BORDER_SIZE); } + if (border_n == 2) { border_posn = ImVec2(0, 1); border_target.y = (g.IO.MousePos.y - g.ActiveIdClickOffset.y + BORDER_SIZE); } + if (border_n == 3) { border_posn = ImVec2(0, 0); border_target.x = (g.IO.MousePos.x - g.ActiveIdClickOffset.x); } + CalcResizePosSizeFromAnyCorner(window, border_target, border_posn, &pos_target, &size_target); + } + } + PopID(); + + // Apply back modified position/size to window + if (size_target.x != FLT_MAX) + { + window->SizeFull = size_target; + MarkIniSettingsDirty(window); + } + if (pos_target.x != FLT_MAX) + { + window->Pos = window->PosFloat = ImFloor(pos_target); + MarkIniSettingsDirty(window); + } + + window->Size = window->SizeFull; +} + // Push a new ImGui window to add widgets to. // - A default window called "Debug" is automatically stacked at the beginning of every frame so you can use widgets without explicitly calling a Begin/End pair. // - Begin/End can be called multiple times during the frame with the same window name to append content. @@ -4693,86 +4781,9 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) int border_held = -1; ImU32 resize_grip_col[4] = { 0 }; const int resize_grip_count = (flags & ImGuiWindowFlags_ResizeFromAnySide) ? 2 : 1; // 4 - const int resize_border_count = (flags & ImGuiWindowFlags_ResizeFromAnySide) ? 4 : 0; - - const float grip_draw_size = (float)(int)ImMax(g.FontSize * 1.35f, window_rounding + 1.0f + g.FontSize * 0.2f); - const float grip_hover_size = (float)(int)(grip_draw_size * 0.75f); - if (!(flags & ImGuiWindowFlags_AlwaysAutoResize) && window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0 && !(flags & ImGuiWindowFlags_NoResize)) - { - ImVec2 pos_target(FLT_MAX, FLT_MAX); - ImVec2 size_target(FLT_MAX, FLT_MAX); - - // Manual resize grips - PushID("#RESIZE"); - for (int resize_grip_n = 0; resize_grip_n < resize_grip_count; resize_grip_n++) - { - const ImGuiResizeGripDef& grip = resize_grip_def[resize_grip_n]; - const ImVec2 corner = ImLerp(window->Pos, window->Pos + window->Size, grip.CornerPos); - - // Using the FlattenChilds button flag we make the resize button accessible even if we are hovering over a child window - ImRect resize_rect(corner, corner + grip.InnerDir * grip_hover_size); - resize_rect.FixInverted(); - bool hovered, held; - ButtonBehavior(resize_rect, window->GetID((void*)(intptr_t)resize_grip_n), &hovered, &held, ImGuiButtonFlags_FlattenChildren); - if (hovered || held) - g.MouseCursor = (resize_grip_n & 1) ? ImGuiMouseCursor_ResizeNESW : ImGuiMouseCursor_ResizeNWSE; - - if (g.HoveredWindow == window && held && g.IO.MouseDoubleClicked[0] && resize_grip_n == 0) - { - // Manual auto-fit when double-clicking - size_target = CalcSizeAfterConstraint(window, size_auto_fit); - ClearActiveID(); - } - else if (held) - { - // Resize from any of the four corners - // We don't use an incremental MouseDelta but rather compute an absolute target size based on mouse position - ImVec2 corner_target = g.IO.MousePos - g.ActiveIdClickOffset + resize_rect.GetSize() * grip.CornerPos; // Corner of the window corresponding to our corner grip - CalcResizePosSizeFromAnyCorner(window, corner_target, grip.CornerPos, &pos_target, &size_target); - } - if (resize_grip_n == 0 || held || hovered) - resize_grip_col[resize_grip_n] = GetColorU32(held ? ImGuiCol_ResizeGripActive : hovered ? ImGuiCol_ResizeGripHovered : ImGuiCol_ResizeGrip); - } - for (int border_n = 0; border_n < resize_border_count; border_n++) - { - const float BORDER_SIZE = 5.0f; // FIXME: Only works _inside_ window because of HoveredWindow check. - const float BORDER_APPEAR_TIMER = 0.05f; // Reduce visual noise - bool hovered, held; - ImRect border_rect = GetBorderRect(window, border_n, grip_hover_size, BORDER_SIZE); - ButtonBehavior(border_rect, window->GetID((void*)(intptr_t)(border_n+4)), &hovered, &held, ImGuiButtonFlags_FlattenChildren); - if ((hovered && g.HoveredIdTimer > BORDER_APPEAR_TIMER) || held) - { - g.MouseCursor = (border_n & 1) ? ImGuiMouseCursor_ResizeEW : ImGuiMouseCursor_ResizeNS; - if (held) border_held = border_n; - } - if (held) - { - ImVec2 border_target = window->Pos; - ImVec2 border_posn; - if (border_n == 0) { border_posn = ImVec2(0, 0); border_target.y = (g.IO.MousePos.y - g.ActiveIdClickOffset.y); } - if (border_n == 1) { border_posn = ImVec2(1, 0); border_target.x = (g.IO.MousePos.x - g.ActiveIdClickOffset.x + BORDER_SIZE); } - if (border_n == 2) { border_posn = ImVec2(0, 1); border_target.y = (g.IO.MousePos.y - g.ActiveIdClickOffset.y + BORDER_SIZE); } - if (border_n == 3) { border_posn = ImVec2(0, 0); border_target.x = (g.IO.MousePos.x - g.ActiveIdClickOffset.x); } - CalcResizePosSizeFromAnyCorner(window, border_target, border_posn, &pos_target, &size_target); - } - } - PopID(); - - // Apply back modified position/size to window - if (size_target.x != FLT_MAX) - { - window->SizeFull = size_target; - MarkIniSettingsDirty(window); - } - if (pos_target.x != FLT_MAX) - { - window->Pos = window->PosFloat = ImFloor(pos_target); - MarkIniSettingsDirty(window); - } - - window->Size = window->SizeFull; - title_bar_rect = window->TitleBarRect(); - } + const float grip_draw_size = (float)(int)ImMax(g.FontSize * 1.35f, window->WindowRounding + 1.0f + g.FontSize * 0.2f); + UpdateManualResize(window, size_auto_fit, &border_held, &resize_grip_col[0]); + title_bar_rect = window->TitleBarRect(); // Window background, Default Alpha ImU32 bg_col = GetColorU32(GetWindowBgColorIdxFromFlags(flags)); From a63fbbca8b4340de08afa3360fb768edb0e4ef2d Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 11 Jan 2018 13:49:32 +0100 Subject: [PATCH 859/921] Added ImGuiHoveredFlags_AnyWindow, ImGuiFocusedFlags_AnyWindow. Obsoleted IsAnyWindowHovered()/IsAnyWindowFocused() in favor of IsWindowHovered(ImGuiHoveredFlags_AnyWindow)/IsWindowFocused(ImGuiFocusedFlags_AnyWindow). Added to demo. (#1382) --- imgui.cpp | 66 ++++++++++++++++++++++++++------------------------ imgui.h | 18 ++++++++------ imgui_demo.cpp | 16 +++++++----- 3 files changed, 54 insertions(+), 46 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index cf5cfb77c..0a23f73c7 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -213,6 +213,8 @@ Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. Also read releases logs https://github.com/ocornut/imgui/releases for more details. + - 2018/01/11 (1.54) - obsoleted IsAnyWindowHovered() in favor of IsWindowHovered(ImGuiHoveredFlags_AnyWindow). Kept redirection function (will obsolete). + - 2018/01/11 (1.54) - obsoleted IsAnyWindowFocused() in favor of IsWindowFocused(ImGuiFocusedFlags_AnyWindow). Kept redirection function (will obsolete). - 2018/01/03 (1.54) - renamed ImGuiSizeConstraintCallback to ImGuiSizeCallback, ImGuiSizeConstraintCallbackData to ImGuiSizeCallbackData. - 2017/12/29 (1.54) - removed CalcItemRectClosestPoint() which was weird and not really used by anyone except demo code. If you need it it's easy to replicate on your side. - 2017/12/24 (1.53) - renamed the emblematic ShowTestWindow() function to ShowDemoWindow(). Kept redirection function (will obsolete). @@ -3417,18 +3419,6 @@ bool ImGui::IsMouseHoveringRect(const ImVec2& r_min, const ImVec2& r_max, bool c return rect_for_touch.Contains(g.IO.MousePos); } -bool ImGui::IsAnyWindowHovered() -{ - ImGuiContext& g = *GImGui; - return g.HoveredWindow != NULL; -} - -bool ImGui::IsAnyWindowFocused() -{ - ImGuiContext& g = *GImGui; - return g.NavWindow != NULL; -} - static bool IsKeyPressedMap(ImGuiKey key, bool repeat) { const int key_index = GImGui->IO.KeyMap[key]; @@ -3959,7 +3949,7 @@ bool ImGui::BeginPopupContextVoid(const char* str_id, int mouse_button) if (!str_id) str_id = "void_context"; ImGuiID id = GImGui->CurrentWindow->GetID(str_id); - if (IsMouseReleased(mouse_button) && !IsAnyWindowHovered()) + if (IsMouseReleased(mouse_button) && !IsWindowHovered(ImGuiHoveredFlags_AnyWindow)) OpenPopupEx(id); return BeginPopupEx(id, ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoSavedSettings); } @@ -5522,24 +5512,33 @@ bool ImGui::IsWindowHovered(ImGuiHoveredFlags flags) { IM_ASSERT((flags & ImGuiHoveredFlags_AllowWhenOverlapped) == 0); // Flags not supported by this function ImGuiContext& g = *GImGui; - switch (flags & (ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows)) + + if (flags & ImGuiHoveredFlags_AnyWindow) { - case ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows: - if (g.HoveredRootWindow != g.CurrentWindow->RootWindow) + if (g.HoveredWindow == NULL) return false; - break; - case ImGuiHoveredFlags_RootWindow: - if (g.HoveredWindow != g.CurrentWindow->RootWindow) - return false; - break; - case ImGuiHoveredFlags_ChildWindows: - if (g.HoveredWindow == NULL || !IsWindowChildOf(g.HoveredWindow, g.CurrentWindow)) - return false; - break; - default: - if (g.HoveredWindow != g.CurrentWindow) - return false; - break; + } + else + { + switch (flags & (ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows)) + { + case ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows: + if (g.HoveredRootWindow != g.CurrentWindow->RootWindow) + return false; + break; + case ImGuiHoveredFlags_RootWindow: + if (g.HoveredWindow != g.CurrentWindow->RootWindow) + return false; + break; + case ImGuiHoveredFlags_ChildWindows: + if (g.HoveredWindow == NULL || !IsWindowChildOf(g.HoveredWindow, g.CurrentWindow)) + return false; + break; + default: + if (g.HoveredWindow != g.CurrentWindow) + return false; + break; + } } if (!IsWindowContentHoverable(g.HoveredRootWindow, flags)) @@ -5555,16 +5554,19 @@ bool ImGui::IsWindowFocused(ImGuiFocusedFlags flags) ImGuiContext& g = *GImGui; IM_ASSERT(g.CurrentWindow); // Not inside a Begin()/End() + if (flags & ImGuiFocusedFlags_AnyWindow) + return g.NavWindow != NULL; + switch (flags & (ImGuiFocusedFlags_RootWindow | ImGuiFocusedFlags_ChildWindows)) { case ImGuiFocusedFlags_RootWindow | ImGuiFocusedFlags_ChildWindows: - return g.NavWindow && g.CurrentWindow->RootWindow == g.NavWindow->RootWindow; + return g.NavWindow && g.NavWindow->RootWindow == g.CurrentWindow->RootWindow; case ImGuiFocusedFlags_RootWindow: - return g.CurrentWindow->RootWindow == g.NavWindow; + return g.NavWindow == g.CurrentWindow->RootWindow; case ImGuiFocusedFlags_ChildWindows: return g.NavWindow && IsWindowChildOf(g.NavWindow, g.CurrentWindow); default: - return g.CurrentWindow == g.NavWindow; + return g.NavWindow == g.CurrentWindow; } } diff --git a/imgui.h b/imgui.h index 02832422e..59ce6663c 100644 --- a/imgui.h +++ b/imgui.h @@ -463,8 +463,6 @@ namespace ImGui IMGUI_API void SetItemAllowOverlap(); // allow last item to be overlapped by a subsequent item. sometimes useful with invisible buttons, selectables, etc. to catch unused area. IMGUI_API bool IsWindowFocused(ImGuiFocusedFlags flags = 0); // is current window focused? or its root/child, depending on flags. see flags for options. IMGUI_API bool IsWindowHovered(ImGuiHoveredFlags flags = 0); // is current window hovered (and typically: not blocked by a popup/modal)? see flags for options. - IMGUI_API bool IsAnyWindowFocused(); - IMGUI_API bool IsAnyWindowHovered(); // is mouse hovering any visible window IMGUI_API bool IsRectVisible(const ImVec2& size); // test if rectangle (of given size, starting from cursor position) is visible / not clipped. IMGUI_API bool IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max); // test if rectangle (in screen space) is visible / not clipped. to perform coarse clipping on user's side. IMGUI_API float GetTime(); @@ -623,6 +621,7 @@ enum ImGuiFocusedFlags_ { ImGuiFocusedFlags_ChildWindows = 1 << 0, // IsWindowFocused(): Return true if any children of the window is focused ImGuiFocusedFlags_RootWindow = 1 << 1, // IsWindowFocused(): Test from root window (top most parent of the current hierarchy) + ImGuiFocusedFlags_AnyWindow = 1 << 2, // IsWindowFocused(): Return true if any window is focused ImGuiFocusedFlags_RootAndChildWindows = ImGuiFocusedFlags_RootWindow | ImGuiFocusedFlags_ChildWindows }; @@ -632,10 +631,11 @@ enum ImGuiHoveredFlags_ ImGuiHoveredFlags_Default = 0, // Return true if directly over the item/window, not obstructed by another window, not obstructed by an active popup or modal blocking inputs under them. ImGuiHoveredFlags_ChildWindows = 1 << 0, // IsWindowHovered() only: Return true if any children of the window is hovered ImGuiHoveredFlags_RootWindow = 1 << 1, // IsWindowHovered() only: Test from root window (top most parent of the current hierarchy) - ImGuiHoveredFlags_AllowWhenBlockedByPopup = 1 << 2, // Return true even if a popup window is normally blocking access to this item/window - //ImGuiHoveredFlags_AllowWhenBlockedByModal = 1 << 3, // Return true even if a modal popup window is normally blocking access to this item/window. FIXME-TODO: Unavailable yet. - ImGuiHoveredFlags_AllowWhenBlockedByActiveItem = 1 << 4, // Return true even if an active item is blocking access to this item/window. Useful for Drag and Drop patterns. - ImGuiHoveredFlags_AllowWhenOverlapped = 1 << 5, // Return true even if the position is overlapped by another window + ImGuiHoveredFlags_AnyWindow = 1 << 2, // IsWindowHovered() only: Return true if any window is hovered + ImGuiHoveredFlags_AllowWhenBlockedByPopup = 1 << 3, // Return true even if a popup window is normally blocking access to this item/window + //ImGuiHoveredFlags_AllowWhenBlockedByModal = 1 << 4, // Return true even if a modal popup window is normally blocking access to this item/window. FIXME-TODO: Unavailable yet. + ImGuiHoveredFlags_AllowWhenBlockedByActiveItem = 1 << 5, // Return true even if an active item is blocking access to this item/window. Useful for Drag and Drop patterns. + ImGuiHoveredFlags_AllowWhenOverlapped = 1 << 6, // Return true even if the position is overlapped by another window ImGuiHoveredFlags_RectOnly = ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem | ImGuiHoveredFlags_AllowWhenOverlapped, ImGuiHoveredFlags_RootAndChildWindows = ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows }; @@ -988,6 +988,8 @@ struct ImGuiIO namespace ImGui { // OBSOLETED in 1.54 (from Dec 2017) + static bool IsAnyWindowFocused() { return IsWindowFocused(ImGuiFocusedFlags_AnyWindow); } + static bool IsAnyWindowHovered() { return IsWindowHovered(ImGuiHoveredFlags_AnyWindow); } static inline ImVec2 CalcItemRectClosestPoint(const ImVec2& pos, bool on_edge = false, float outward = 0.f) { (void)on_edge; (void)outward; IM_ASSERT(0); return pos; } // OBSOLETED in 1.53 (between Oct 2017 and Dec 2017) static inline void ShowTestWindow() { return ShowDemoWindow(); } @@ -996,13 +998,13 @@ namespace ImGui static inline void SetNextWindowContentWidth(float w) { SetNextWindowContentSize(ImVec2(w, 0.0f)); } // OBSOLETED in 1.52 (between Aug 2017 and Oct 2017) bool Begin(const char* name, bool* p_open, const ImVec2& size_on_first_use, float bg_alpha_override = -1.0f, ImGuiWindowFlags flags = 0); // Use SetNextWindowSize() instead if you want to set a window size. - static inline bool IsRootWindowOrAnyChildHovered() { return IsItemHovered(ImGuiHoveredFlags_RootAndChildWindows); } // Use flags directly! + static inline bool IsRootWindowOrAnyChildHovered() { return IsItemHovered(ImGuiHoveredFlags_RootAndChildWindows); } static inline void AlignFirstTextHeightToWidgets() { AlignTextToFramePadding(); } static inline void SetNextWindowPosCenter(ImGuiCond c=0) { ImGuiIO& io = GetIO(); SetNextWindowPos(ImVec2(io.DisplaySize.x * 0.5f, io.DisplaySize.y * 0.5f), c, ImVec2(0.5f, 0.5f)); } // OBSOLETED in 1.51 (between Jun 2017 and Aug 2017) static inline bool IsItemHoveredRect() { return IsItemHovered(ImGuiHoveredFlags_RectOnly); } static inline bool IsPosHoveringAnyWindow(const ImVec2&) { IM_ASSERT(0); return false; } // This was misleading and partly broken. You probably want to use the ImGui::GetIO().WantCaptureMouse flag instead. - static inline bool IsMouseHoveringAnyWindow() { return IsAnyWindowHovered(); } + static inline bool IsMouseHoveringAnyWindow() { return IsWindowHovered(ImGuiHoveredFlags_AnyWindow); } static inline bool IsMouseHoveringWindow() { return IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem); } // OBSOLETED IN 1.49 (between Apr 2016 and May 2016) static inline bool CollapsingHeader(const char* label, const char* str_id, bool framed = true, bool default_open = false) { (void)str_id; (void)framed; ImGuiTreeNodeFlags default_open_flags = 1 << 5; return CollapsingHeader(label, (default_open ? default_open_flags : 0)); } diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 76a8fa551..11dc87c6b 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1871,11 +1871,13 @@ void ImGui::ShowDemoWindow(bool* p_open) "IsWindowFocused() = %d\n" "IsWindowFocused(_ChildWindows) = %d\n" "IsWindowFocused(_ChildWindows|_RootWindow) = %d\n" - "IsWindowFocused(_RootWindow) = %d\n", + "IsWindowFocused(_RootWindow) = %d\n" + "IsWindowFocused(_AnyWindow) = %d\n", ImGui::IsWindowFocused(), - ImGui::IsWindowFocused(ImGuiHoveredFlags_ChildWindows), - ImGui::IsWindowFocused(ImGuiHoveredFlags_ChildWindows | ImGuiHoveredFlags_RootWindow), - ImGui::IsWindowFocused(ImGuiHoveredFlags_RootWindow)); + ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows), + ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows | ImGuiFocusedFlags_RootWindow), + ImGui::IsWindowFocused(ImGuiFocusedFlags_RootWindow), + ImGui::IsWindowFocused(ImGuiFocusedFlags_AnyWindow)); // Testing IsWindowHovered() function with its various flags (note that the flags can be combined) ImGui::BulletText( @@ -1884,13 +1886,15 @@ void ImGui::ShowDemoWindow(bool* p_open) "IsWindowHovered(_AllowWhenBlockedByActiveItem) = %d\n" "IsWindowHovered(_ChildWindows) = %d\n" "IsWindowHovered(_ChildWindows|_RootWindow) = %d\n" - "IsWindowHovered(_RootWindow) = %d\n", + "IsWindowHovered(_RootWindow) = %d\n" + "IsWindowHovered(_AnyWindow) = %d\n", ImGui::IsWindowHovered(), ImGui::IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup), ImGui::IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem), ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows), ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows | ImGuiHoveredFlags_RootWindow), - ImGui::IsWindowHovered(ImGuiHoveredFlags_RootWindow)); + ImGui::IsWindowHovered(ImGuiHoveredFlags_RootWindow), + ImGui::IsWindowHovered(ImGuiHoveredFlags_AnyWindow)); // Testing IsItemHovered() function (because BulletText is an item itself and that would affect the output of IsItemHovered, we pass all lines in a single items to shorten the code) ImGui::Button("ITEM"); From 398a4e1865db8225f7e1367dba17223ca57e1291 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 11 Jan 2018 13:58:25 +0100 Subject: [PATCH 860/921] Made obsolete IsAnyWindowHovered()/IsAnyWindowFocused() static inline. static only tends to trigger warnings. (#1382) --- imgui.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/imgui.h b/imgui.h index 59ce6663c..674254082 100644 --- a/imgui.h +++ b/imgui.h @@ -988,8 +988,8 @@ struct ImGuiIO namespace ImGui { // OBSOLETED in 1.54 (from Dec 2017) - static bool IsAnyWindowFocused() { return IsWindowFocused(ImGuiFocusedFlags_AnyWindow); } - static bool IsAnyWindowHovered() { return IsWindowHovered(ImGuiHoveredFlags_AnyWindow); } + static inline bool IsAnyWindowFocused() { return IsWindowFocused(ImGuiFocusedFlags_AnyWindow); } + static inline bool IsAnyWindowHovered() { return IsWindowHovered(ImGuiHoveredFlags_AnyWindow); } static inline ImVec2 CalcItemRectClosestPoint(const ImVec2& pos, bool on_edge = false, float outward = 0.f) { (void)on_edge; (void)outward; IM_ASSERT(0); return pos; } // OBSOLETED in 1.53 (between Oct 2017 and Dec 2017) static inline void ShowTestWindow() { return ShowDemoWindow(); } From 12aa3cb09ed83aa478a0bfa6afbbb8b0c003bbf6 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 11 Jan 2018 15:22:33 +0100 Subject: [PATCH 861/921] Demo: Tweaks format. --- imgui_demo.cpp | 44 +++++++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 11dc87c6b..1e1421eb1 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1061,33 +1061,39 @@ void ImGui::ShowDemoWindow(bool* p_open) goto_line |= ImGui::InputInt("##Line", &line, 0, 0, ImGuiInputTextFlags_EnterReturnsTrue); ImGui::PopItemWidth(); - ImGui::BeginChild("Sub1", ImVec2(ImGui::GetWindowContentRegionWidth() * 0.5f,300), false, ImGuiWindowFlags_HorizontalScrollbar | (disable_mouse_wheel ? ImGuiWindowFlags_NoScrollWithMouse : 0)); - for (int i = 0; i < 100; i++) + // Child 1: no border, enable horizontal scrollbar { - ImGui::Text("%04d: scrollable region", i); - if (goto_line && line == i) + ImGui::BeginChild("Child1", ImVec2(ImGui::GetWindowContentRegionWidth() * 0.5f, 300), false, ImGuiWindowFlags_HorizontalScrollbar | (disable_mouse_wheel ? ImGuiWindowFlags_NoScrollWithMouse : 0)); + for (int i = 0; i < 100; i++) + { + ImGui::Text("%04d: scrollable region", i); + if (goto_line && line == i) + ImGui::SetScrollHere(); + } + if (goto_line && line >= 100) ImGui::SetScrollHere(); + ImGui::EndChild(); } - if (goto_line && line >= 100) - ImGui::SetScrollHere(); - ImGui::EndChild(); ImGui::SameLine(); - ImGui::PushStyleVar(ImGuiStyleVar_ChildRounding, 5.0f); - ImGui::BeginChild("Sub2", ImVec2(0,300), true, (disable_mouse_wheel ? ImGuiWindowFlags_NoScrollWithMouse : 0)); - ImGui::Text("With border"); - ImGui::Columns(2); - for (int i = 0; i < 100; i++) + // Child 2: rounded border { - if (i == 50) - ImGui::NextColumn(); - char buf[32]; - sprintf(buf, "%08x", i*5731); - ImGui::Button(buf, ImVec2(-1.0f, 0.0f)); + ImGui::PushStyleVar(ImGuiStyleVar_ChildRounding, 5.0f); + ImGui::BeginChild("Child2", ImVec2(0,300), true, (disable_mouse_wheel ? ImGuiWindowFlags_NoScrollWithMouse : 0)); + ImGui::Text("With border"); + ImGui::Columns(2); + for (int i = 0; i < 100; i++) + { + if (i == 50) + ImGui::NextColumn(); + char buf[32]; + sprintf(buf, "%08x", i*5731); + ImGui::Button(buf, ImVec2(-1.0f, 0.0f)); + } + ImGui::EndChild(); + ImGui::PopStyleVar(); } - ImGui::EndChild(); - ImGui::PopStyleVar(); ImGui::TreePop(); } From a8bbb0b7ddc13e71b075f02db069d7a66041abda Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 11 Jan 2018 15:47:07 +0100 Subject: [PATCH 862/921] Demo: Using IM_COL32() instead of ImColor() in ImDrawList centric contexts. --- imgui_demo.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 1e1421eb1..9cebf88b3 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1401,8 +1401,8 @@ void ImGui::ShowDemoWindow(bool* p_open) ImVec4 clip_rect(pos.x, pos.y, pos.x+size.x, pos.y+size.y); ImGui::InvisibleButton("##dummy", size); if (ImGui::IsItemActive() && ImGui::IsMouseDragging()) { offset.x += ImGui::GetIO().MouseDelta.x; offset.y += ImGui::GetIO().MouseDelta.y; } - ImGui::GetWindowDrawList()->AddRectFilled(pos, ImVec2(pos.x+size.x,pos.y+size.y), ImColor(90,90,120,255)); - ImGui::GetWindowDrawList()->AddText(ImGui::GetFont(), ImGui::GetFontSize()*2.0f, ImVec2(pos.x+offset.x,pos.y+offset.y), ImColor(255,255,255,255), "Line 1 hello\nLine 2 clip me!", NULL, 0.0f, &clip_rect); + ImGui::GetWindowDrawList()->AddRectFilled(pos, ImVec2(pos.x+size.x,pos.y+size.y), IM_COL32(90,90,120,255)); + ImGui::GetWindowDrawList()->AddText(ImGui::GetFont(), ImGui::GetFontSize()*2.0f, ImVec2(pos.x+offset.x,pos.y+offset.y), IM_COL32(255,255,255,255), "Line 1 hello\nLine 2 clip me!", NULL, 0.0f, &clip_rect); ImGui::TreePop(); } } @@ -2490,7 +2490,7 @@ static void ShowExampleAppCustomRendering(bool* p_open) draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, 10.0f); x += sz+spacing; draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, 10.0f, ImDrawCornerFlags_TopLeft|ImDrawCornerFlags_BotRight); x += sz+spacing; draw_list->AddTriangleFilled(ImVec2(x+sz*0.5f, y), ImVec2(x+sz,y+sz-0.5f), ImVec2(x,y+sz-0.5f), col32); x += sz+spacing; - draw_list->AddRectFilledMultiColor(ImVec2(x, y), ImVec2(x+sz, y+sz), ImColor(0,0,0), ImColor(255,0,0), ImColor(255,255,0), ImColor(0,255,0)); + draw_list->AddRectFilledMultiColor(ImVec2(x, y), ImVec2(x+sz, y+sz), IM_COL32(0,0,0,255), IM_COL32(255,0,0,255), IM_COL32(255,255,0,255), IM_COL32(0,255,0,255)); ImGui::Dummy(ImVec2((sz+spacing)*8, (sz+spacing)*3)); } ImGui::Separator(); @@ -2509,8 +2509,8 @@ static void ShowExampleAppCustomRendering(bool* p_open) ImVec2 canvas_size = ImGui::GetContentRegionAvail(); // Resize canvas to what's available if (canvas_size.x < 50.0f) canvas_size.x = 50.0f; if (canvas_size.y < 50.0f) canvas_size.y = 50.0f; - draw_list->AddRectFilledMultiColor(canvas_pos, ImVec2(canvas_pos.x + canvas_size.x, canvas_pos.y + canvas_size.y), ImColor(50,50,50), ImColor(50,50,60), ImColor(60,60,70), ImColor(50,50,60)); - draw_list->AddRect(canvas_pos, ImVec2(canvas_pos.x + canvas_size.x, canvas_pos.y + canvas_size.y), ImColor(255,255,255)); + draw_list->AddRectFilledMultiColor(canvas_pos, ImVec2(canvas_pos.x + canvas_size.x, canvas_pos.y + canvas_size.y), IM_COL32(50,50,50,255), IM_COL32(50,50,60,255), IM_COL32(60,60,70,255), IM_COL32(50,50,60,255)); + draw_list->AddRect(canvas_pos, ImVec2(canvas_pos.x + canvas_size.x, canvas_pos.y + canvas_size.y), IM_COL32(255,255,255,255)); bool adding_preview = false; ImGui::InvisibleButton("canvas", canvas_size); @@ -2519,7 +2519,7 @@ static void ShowExampleAppCustomRendering(bool* p_open) { adding_preview = true; points.push_back(mouse_pos_in_canvas); - if (!ImGui::GetIO().MouseDown[0]) + if (!ImGui::IsMouseDown(0)) adding_line = adding_preview = false; } if (ImGui::IsItemHovered()) From 651538e13bef974e5cc7db3fbd0e78fe78f98f63 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 11 Jan 2018 16:43:03 +0100 Subject: [PATCH 863/921] Clicking on a window with the ImGuiWIndowFlags_NoMove flags takes an ActiveId so we can't hover something else. (ref #1381, #1337) --- imgui.cpp | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 0a23f73c7..23cded818 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2386,11 +2386,14 @@ void ImGui::NewFrame() IM_ASSERT(g.MovingWindow->MoveId == g.MovingWindowMoveId); if (g.IO.MouseDown[0]) { - ImVec2 pos = g.IO.MousePos - g.ActiveIdClickOffset; - if (g.MovingWindow->RootWindow->PosFloat.x != pos.x || g.MovingWindow->RootWindow->PosFloat.y != pos.y) - MarkIniSettingsDirty(g.MovingWindow->RootWindow); - g.MovingWindow->RootWindow->PosFloat = pos; - FocusWindow(g.MovingWindow); + if (!(g.MovingWindow->Flags & ImGuiWindowFlags_NoMove) && !(g.MovingWindow->RootWindow->Flags & ImGuiWindowFlags_NoMove)) + { + ImVec2 pos = g.IO.MousePos - g.ActiveIdClickOffset; + if (g.MovingWindow->RootWindow->PosFloat.x != pos.x || g.MovingWindow->RootWindow->PosFloat.y != pos.y) + MarkIniSettingsDirty(g.MovingWindow->RootWindow); + g.MovingWindow->RootWindow->PosFloat = pos; + FocusWindow(g.MovingWindow); + } } else { @@ -2934,14 +2937,13 @@ void ImGui::EndFrame() { if (g.HoveredRootWindow != NULL) { + // Mark for moving even if the _NoMove flag is set (the tests will be done during actual moving) + // Because we always want to set an ActiveId, without it dragging away from a window with _NoMove would activate hover on other windows. FocusWindow(g.HoveredWindow); - if (!(g.HoveredWindow->Flags & ImGuiWindowFlags_NoMove) && !(g.HoveredRootWindow->Flags & ImGuiWindowFlags_NoMove)) - { - g.MovingWindow = g.HoveredWindow; - g.MovingWindowMoveId = g.MovingWindow->MoveId; - SetActiveID(g.MovingWindowMoveId, g.HoveredRootWindow); - g.ActiveIdClickOffset = g.IO.MousePos - g.MovingWindow->RootWindow->Pos; - } + g.MovingWindow = g.HoveredWindow; + g.MovingWindowMoveId = g.MovingWindow->MoveId; + SetActiveID(g.MovingWindowMoveId, g.HoveredRootWindow); + g.ActiveIdClickOffset = g.IO.MousePos - g.HoveredRootWindow->Pos; } else if (g.NavWindow != NULL && GetFrontMostModalRootWindow() == NULL) { From 7d2a068dea877efb6007a183494d20c813971f0f Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 11 Jan 2018 17:33:37 +0100 Subject: [PATCH 864/921] Begin: Shuffling bits of code around. --- imgui.cpp | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 23cded818..9135add8c 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4565,14 +4565,6 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & (ImGuiWindowFlags_AlwaysUseWindowPadding | ImGuiWindowFlags_Popup)) && window->WindowBorderSize == 0.0f) window->WindowPadding = ImVec2(0.0f, (flags & ImGuiWindowFlags_MenuBar) ? style.WindowPadding.y : 0.0f); - if (window_just_activated_by_user) - { - // Popup first latch mouse position, will position itself when it appears next frame - window->AutoPosLastDirection = ImGuiDir_None; - if ((flags & ImGuiWindowFlags_Popup) != 0 && !window_pos_set_by_api) - window->Pos = window->PosFloat = g.CurrentPopupStack.back().OpenPopupPos; - } - // Collapse window by double-clicking on title bar // At this point we don't have a clipping rectangle setup yet, so we can use the title bar area for hit detection and drawing if (!(flags & ImGuiWindowFlags_NoTitleBar) && !(flags & ImGuiWindowFlags_NoCollapse)) @@ -4660,14 +4652,23 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // POSITION + // Popup latch its initial position, will position itself when it appears next frame + if (window_just_activated_by_user) + { + window->AutoPosLastDirection = ImGuiDir_None; + if ((flags & ImGuiWindowFlags_Popup) != 0 && !window_pos_set_by_api) + window->Pos = window->PosFloat = g.CurrentPopupStack.back().OpenPopupPos; + } + // Position child window if (flags & ImGuiWindowFlags_ChildWindow) { window->BeginOrderWithinParent = parent_window->DC.ChildWindows.Size; parent_window->DC.ChildWindows.push_back(window); + + if (!(flags & ImGuiWindowFlags_Popup) && !window_pos_set_by_api) + window->Pos = window->PosFloat = parent_window->DC.CursorPos; } - if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Popup) && !window_pos_set_by_api) - window->Pos = window->PosFloat = parent_window->DC.CursorPos; const bool window_pos_with_pivot = (window->SetWindowPosVal.x != FLT_MAX && window->HiddenFrames == 0); if (window_pos_with_pivot) From b74f24c3e5980562e1be99758c239c009b18fcfe Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 11 Jan 2018 18:08:14 +0100 Subject: [PATCH 865/921] Revert "Clicking on a window with the ImGuiWIndowFlags_NoMove flags takes an ActiveId so we can't hover something else. (ref #1381, #1337)" This reverts commit 651538e13bef974e5cc7db3fbd0e78fe78f98f63. --- imgui.cpp | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 9135add8c..c86906360 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2386,14 +2386,11 @@ void ImGui::NewFrame() IM_ASSERT(g.MovingWindow->MoveId == g.MovingWindowMoveId); if (g.IO.MouseDown[0]) { - if (!(g.MovingWindow->Flags & ImGuiWindowFlags_NoMove) && !(g.MovingWindow->RootWindow->Flags & ImGuiWindowFlags_NoMove)) - { - ImVec2 pos = g.IO.MousePos - g.ActiveIdClickOffset; - if (g.MovingWindow->RootWindow->PosFloat.x != pos.x || g.MovingWindow->RootWindow->PosFloat.y != pos.y) - MarkIniSettingsDirty(g.MovingWindow->RootWindow); - g.MovingWindow->RootWindow->PosFloat = pos; - FocusWindow(g.MovingWindow); - } + ImVec2 pos = g.IO.MousePos - g.ActiveIdClickOffset; + if (g.MovingWindow->RootWindow->PosFloat.x != pos.x || g.MovingWindow->RootWindow->PosFloat.y != pos.y) + MarkIniSettingsDirty(g.MovingWindow->RootWindow); + g.MovingWindow->RootWindow->PosFloat = pos; + FocusWindow(g.MovingWindow); } else { @@ -2937,13 +2934,14 @@ void ImGui::EndFrame() { if (g.HoveredRootWindow != NULL) { - // Mark for moving even if the _NoMove flag is set (the tests will be done during actual moving) - // Because we always want to set an ActiveId, without it dragging away from a window with _NoMove would activate hover on other windows. FocusWindow(g.HoveredWindow); - g.MovingWindow = g.HoveredWindow; - g.MovingWindowMoveId = g.MovingWindow->MoveId; - SetActiveID(g.MovingWindowMoveId, g.HoveredRootWindow); - g.ActiveIdClickOffset = g.IO.MousePos - g.HoveredRootWindow->Pos; + if (!(g.HoveredWindow->Flags & ImGuiWindowFlags_NoMove) && !(g.HoveredRootWindow->Flags & ImGuiWindowFlags_NoMove)) + { + g.MovingWindow = g.HoveredWindow; + g.MovingWindowMoveId = g.MovingWindow->MoveId; + SetActiveID(g.MovingWindowMoveId, g.HoveredRootWindow); + g.ActiveIdClickOffset = g.IO.MousePos - g.MovingWindow->RootWindow->Pos; + } } else if (g.NavWindow != NULL && GetFrontMostModalRootWindow() == NULL) { From 6a1011cf53dfea417e82eee5c84a137b39a7eebd Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 11 Jan 2018 18:16:16 +0100 Subject: [PATCH 866/921] MovingWindow: Proper fix for 651538e attempt, without altering MovingWindow which has side-effects. Clicking on a window with the ImGuiWIndowFlags_NoMove flags takes an ActiveId so we can't hover something else. (ref #1381, #1337) --- imgui.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index c86906360..bd0be8626 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2378,10 +2378,10 @@ void ImGui::NewFrame() g.FramerateSecPerFrameIdx = (g.FramerateSecPerFrameIdx + 1) % IM_ARRAYSIZE(g.FramerateSecPerFrame); g.IO.Framerate = 1.0f / (g.FramerateSecPerFrameAccum / (float)IM_ARRAYSIZE(g.FramerateSecPerFrame)); - // Handle user moving window with mouse (at the beginning of the frame to avoid input lag or sheering). Only valid for root windows. + // Handle user moving window with mouse (at the beginning of the frame to avoid input lag or sheering). if (g.MovingWindowMoveId && g.MovingWindowMoveId == g.ActiveId) { - KeepAliveID(g.MovingWindowMoveId); + KeepAliveID(g.ActiveId); IM_ASSERT(g.MovingWindow && g.MovingWindow->RootWindow); IM_ASSERT(g.MovingWindow->MoveId == g.MovingWindowMoveId); if (g.IO.MouseDown[0]) @@ -2401,6 +2401,13 @@ void ImGui::NewFrame() } else { + // When clicking/dragging from a window that has the _NoMove flag, we still set the ActiveId in order to prevent hovering others. + if (g.ActiveIdWindow && g.ActiveIdWindow->MoveId == g.ActiveId) + { + KeepAliveID(g.ActiveId); + if (!g.IO.MouseDown[0]) + ClearActiveID(); + } g.MovingWindow = NULL; g.MovingWindowMoveId = 0; } @@ -2934,13 +2941,14 @@ void ImGui::EndFrame() { if (g.HoveredRootWindow != NULL) { + // Set ActiveId even if the _NoMove flag is set, without it dragging away from a window with _NoMove would activate hover on other windows. FocusWindow(g.HoveredWindow); + SetActiveID(g.HoveredWindow->MoveId, g.HoveredWindow); + g.ActiveIdClickOffset = g.IO.MousePos - g.HoveredRootWindow->Pos; if (!(g.HoveredWindow->Flags & ImGuiWindowFlags_NoMove) && !(g.HoveredRootWindow->Flags & ImGuiWindowFlags_NoMove)) { g.MovingWindow = g.HoveredWindow; g.MovingWindowMoveId = g.MovingWindow->MoveId; - SetActiveID(g.MovingWindowMoveId, g.HoveredRootWindow); - g.ActiveIdClickOffset = g.IO.MousePos - g.MovingWindow->RootWindow->Pos; } } else if (g.NavWindow != NULL && GetFrontMostModalRootWindow() == NULL) From 5e9ae92ae978081ed200ec7914248d5767d66321 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 11 Jan 2018 23:17:34 +0100 Subject: [PATCH 867/921] Begin: Handle manual resize (grip, border, gamepad) before setting up window DrawList main clipping rectangle. Sane (and required for viewport code). (#822, #1542) --- imgui.cpp | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index bd0be8626..4f62a426c 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -677,7 +677,7 @@ static bool DataTypeApplyOpFromText(const char* buf, const char* ini namespace ImGui { -static void UpdateManualResize(ImGuiWindow* window, const ImVec2& size_auto_fit, int* border_held, ImU32 resize_grip_col[4]); +static void UpdateManualResize(ImGuiWindow* window, const ImVec2& size_auto_fit, int* border_held, int resize_grip_count, ImU32 resize_grip_col[4]); static void FocusFrontMostActiveWindow(ImGuiWindow* ignore_window); } @@ -4338,14 +4338,13 @@ static ImRect GetBorderRect(ImGuiWindow* window, int border_n, float perp_paddin } // Handle resize for: Resize Grips, Borders, Gamepad -static void ImGui::UpdateManualResize(ImGuiWindow* window, const ImVec2& size_auto_fit, int* border_held, ImU32 resize_grip_col[4]) +static void ImGui::UpdateManualResize(ImGuiWindow* window, const ImVec2& size_auto_fit, int* border_held, int resize_grip_count, ImU32 resize_grip_col[4]) { ImGuiContext& g = *GImGui; ImGuiWindowFlags flags = window->Flags; if ((flags & ImGuiWindowFlags_NoResize) || (flags & ImGuiWindowFlags_AlwaysAutoResize) || window->AutoFitFramesX > 0 || window->AutoFitFramesY > 0) return; - const int resize_grip_count = (flags & ImGuiWindowFlags_ResizeFromAnySide) ? 2 : 1; // 4 const int resize_border_count = (flags & ImGuiWindowFlags_ResizeFromAnySide) ? 4 : 0; const float grip_draw_size = (float)(int)ImMax(g.FontSize * 1.35f, window->WindowRounding + 1.0f + g.FontSize * 0.2f); const float grip_hover_size = (float)(int)(grip_draw_size * 0.75f); @@ -4746,6 +4745,13 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) if (!(flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_Tooltip)) || (flags & ImGuiWindowFlags_Popup)) want_focus = true; + // Handle manual resize: Resize Grips, Borders, Gamepad + int border_held = -1; + ImU32 resize_grip_col[4] = { 0 }; + const int resize_grip_count = (flags & ImGuiWindowFlags_ResizeFromAnySide) ? 2 : 1; // 4 + const float grip_draw_size = (float)(int)ImMax(g.FontSize * 1.35f, window->WindowRounding + 1.0f + g.FontSize * 0.2f); + UpdateManualResize(window, size_auto_fit, &border_held, resize_grip_count, &resize_grip_col[0]); + // DRAWING // Setup draw list and outer clipping rectangle @@ -4776,14 +4782,6 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) } else { - // Handle resize for: Resize Grips, Borders, Gamepad - int border_held = -1; - ImU32 resize_grip_col[4] = { 0 }; - const int resize_grip_count = (flags & ImGuiWindowFlags_ResizeFromAnySide) ? 2 : 1; // 4 - const float grip_draw_size = (float)(int)ImMax(g.FontSize * 1.35f, window->WindowRounding + 1.0f + g.FontSize * 0.2f); - UpdateManualResize(window, size_auto_fit, &border_held, &resize_grip_col[0]); - title_bar_rect = window->TitleBarRect(); - // Window background, Default Alpha ImU32 bg_col = GetColorU32(GetWindowBgColorIdxFromFlags(flags)); window->DrawList->AddRectFilled(window->Pos+ImVec2(0,window->TitleBarHeight()), window->Pos+window->Size, bg_col, window_rounding, (flags & ImGuiWindowFlags_NoTitleBar) ? ImDrawCornerFlags_All : ImDrawCornerFlags_Bot); From cc173d7619180cfaf211dcc338b02c7938e0d221 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 11 Jan 2018 23:21:24 +0100 Subject: [PATCH 868/921] Begin: FIx previous commit - no need to call on collapsed window. Handle manual resize (grip, border, gamepad) before setting up window DrawList main clipping rectangle. Sane (and required for viewport code). (#822, #1542) --- imgui.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 4f62a426c..1a1be7949 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4750,7 +4750,8 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) ImU32 resize_grip_col[4] = { 0 }; const int resize_grip_count = (flags & ImGuiWindowFlags_ResizeFromAnySide) ? 2 : 1; // 4 const float grip_draw_size = (float)(int)ImMax(g.FontSize * 1.35f, window->WindowRounding + 1.0f + g.FontSize * 0.2f); - UpdateManualResize(window, size_auto_fit, &border_held, resize_grip_count, &resize_grip_col[0]); + if (!window->Collapsed) + UpdateManualResize(window, size_auto_fit, &border_held, resize_grip_count, &resize_grip_col[0]); // DRAWING From 16285603f272ea565653652e51fb49573054776f Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 12 Jan 2018 19:11:11 +0100 Subject: [PATCH 869/921] Internals: Initializing fields in same order as declaration order + fixed uninitialized DragDropAcceptIdCurrRectSurface (was harmless) --- imgui_internal.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/imgui_internal.h b/imgui_internal.h index 4958b5ae3..51702eab9 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -632,14 +632,20 @@ struct ImGuiContext ActiveIdWindow = NULL; MovingWindow = NULL; MovingWindowMoveId = 0; - NextTreeNodeOpenVal = false; NextTreeNodeOpenCond = 0; + ModalWindowDarkeningRatio = 0.0f; + OverlayDrawList._Data = &DrawListSharedData; + OverlayDrawList._OwnerName = "##Overlay"; // Give it a name for debugging + MouseCursor = ImGuiMouseCursor_Arrow; + memset(MouseCursorData, 0, sizeof(MouseCursorData)); + DragDropActive = false; DragDropSourceFlags = 0; DragDropMouseButton = -1; DragDropTargetId = 0; + DragDropAcceptIdCurrRectSurface = 0.0f; DragDropAcceptIdPrev = DragDropAcceptIdCurr = 0; DragDropAcceptFrameCount = -1; memset(DragDropPayloadBufLocal, 0, sizeof(DragDropPayloadBufLocal)); @@ -655,12 +661,6 @@ struct ImGuiContext TooltipOverrideCount = 0; OsImePosRequest = OsImePosSet = ImVec2(-1.0f, -1.0f); - ModalWindowDarkeningRatio = 0.0f; - OverlayDrawList._Data = &DrawListSharedData; - OverlayDrawList._OwnerName = "##Overlay"; // Give it a name for debugging - MouseCursor = ImGuiMouseCursor_Arrow; - memset(MouseCursorData, 0, sizeof(MouseCursorData)); - SettingsDirtyTimer = 0.0f; LogEnabled = false; From 1493de4f8173a54e2aa726a2b9a654aa43a735a3 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 12 Jan 2018 19:53:27 +0100 Subject: [PATCH 870/921] Internals: Merge of harmless stuff from Navigation stuff. Added GetHoveredID() internal helper. --- imgui.cpp | 11 +++++++++-- imgui_demo.cpp | 3 ++- imgui_internal.h | 1 + 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 1a1be7949..910101143 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1952,6 +1952,12 @@ void ImGui::SetHoveredID(ImGuiID id) g.HoveredIdTimer = (id != 0 && g.HoveredIdPreviousFrame == id) ? (g.HoveredIdTimer + g.IO.DeltaTime) : 0.0f; } +ImGuiID ImGui::GetHoveredID() +{ + ImGuiContext& g = *GImGui; + return g.HoveredId ? g.HoveredId : g.HoveredIdPreviousFrame; +} + void ImGui::KeepAliveID(ImGuiID id) { ImGuiContext& g = *GImGui; @@ -4773,6 +4779,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) const float window_rounding = window->WindowRounding; const float window_border_size = window->WindowBorderSize; ImRect title_bar_rect = window->TitleBarRect(); + const bool window_is_focused = want_focus || (g.NavWindow && window->RootNonPopupWindow == g.NavWindow->RootNonPopupWindow); if (window->Collapsed) { // Title bar only @@ -4788,7 +4795,6 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->DrawList->AddRectFilled(window->Pos+ImVec2(0,window->TitleBarHeight()), window->Pos+window->Size, bg_col, window_rounding, (flags & ImGuiWindowFlags_NoTitleBar) ? ImDrawCornerFlags_All : ImDrawCornerFlags_Bot); // Title bar - const bool window_is_focused = want_focus || (g.NavWindow && window->RootNonPopupWindow == g.NavWindow->RootNonPopupWindow); if (!(flags & ImGuiWindowFlags_NoTitleBar)) window->DrawList->AddRectFilled(title_bar_rect.Min, title_bar_rect.Max, GetColorU32(window_is_focused ? ImGuiCol_TitleBgActive : ImGuiCol_TitleBg), window_rounding, ImDrawCornerFlags_Top); @@ -6358,7 +6364,8 @@ bool ImGui::ButtonEx(const char* label, const ImVec2& size_arg, ImGuiButtonFlags if (!ItemAdd(bb, id)) return false; - if (window->DC.ItemFlags & ImGuiItemFlags_ButtonRepeat) flags |= ImGuiButtonFlags_Repeat; + if (window->DC.ItemFlags & ImGuiItemFlags_ButtonRepeat) + flags |= ImGuiButtonFlags_Repeat; bool hovered, held; bool pressed = ButtonBehavior(bb, id, &hovered, &held, flags); diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 9cebf88b3..87e4f57cf 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1552,7 +1552,7 @@ void ImGui::ShowDemoWindow(bool* p_open) ImGui::OpenPopup("Stacked 2"); if (ImGui::BeginPopupModal("Stacked 2")) { - ImGui::Text("Hello from Stacked The Second"); + ImGui::Text("Hello from Stacked The Second!"); if (ImGui::Button("Close")) ImGui::CloseCurrentPopup(); ImGui::EndPopup(); @@ -1857,6 +1857,7 @@ void ImGui::ShowDemoWindow(bool* p_open) ImGui::InputText("3 (tab skip)", buf, IM_ARRAYSIZE(buf)); if (ImGui::IsItemActive()) has_focus = 3; ImGui::PopAllowKeyboardFocus(); + if (has_focus) ImGui::Text("Item with focus: %d", has_focus); else diff --git a/imgui_internal.h b/imgui_internal.h index 51702eab9..87a4a131a 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -880,6 +880,7 @@ namespace ImGui IMGUI_API void SetActiveID(ImGuiID id, ImGuiWindow* window); IMGUI_API void ClearActiveID(); IMGUI_API void SetHoveredID(ImGuiID id); + IMGUI_API ImGuiID GetHoveredID(); IMGUI_API void KeepAliveID(ImGuiID id); IMGUI_API void ItemSize(const ImVec2& size, float text_offset_y = 0.0f); From daa38f2ad0c8cbb7582a833051ab60055a54d0c6 Mon Sep 17 00:00:00 2001 From: Crunkle Date: Sun, 14 Jan 2018 03:31:22 +0000 Subject: [PATCH 871/921] Fix cross compilers --- imgui.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/imgui.cpp b/imgui.cpp index 910101143..ff6b871d4 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -11524,7 +11524,11 @@ void ImGui::EndDragDropTarget() #if defined(_WIN32) && !defined(_WINDOWS_) && (!defined(IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS) || !defined(IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS)) #undef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN +#ifndef __MINGW32__ #include +#else +#include +#endif #endif // Win32 API clipboard implementation From 514d30d8cdd659b6af3c93512583a00ee18ecbaf Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 14 Jan 2018 14:13:54 +0100 Subject: [PATCH 872/921] MovingWindow: Track click offset based on MovingWindow and not its RootWindow. Followup to 3849bb4470aebb4ff276113170f26cc82f990f49. Comments + adding a local to ease patch #1345. --- imgui.cpp | 15 +++++++++++---- imgui_internal.h | 2 +- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index ff6b871d4..fee26e2ff 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2392,10 +2392,17 @@ void ImGui::NewFrame() IM_ASSERT(g.MovingWindow->MoveId == g.MovingWindowMoveId); if (g.IO.MouseDown[0]) { + // MovingWindow = window we clicked on, could be a child window. We track it to preserve Focus and so that ActiveIdWindow == MovingWindow and ActiveId == MovingWindow->MoveId for consistency. + // actually_moving_window = MovingWindow->RootWindow. + ImGuiWindow* actually_moving_window = g.MovingWindow->RootWindow; ImVec2 pos = g.IO.MousePos - g.ActiveIdClickOffset; - if (g.MovingWindow->RootWindow->PosFloat.x != pos.x || g.MovingWindow->RootWindow->PosFloat.y != pos.y) - MarkIniSettingsDirty(g.MovingWindow->RootWindow); - g.MovingWindow->RootWindow->PosFloat = pos; + if (actually_moving_window != g.MovingWindow) + pos += actually_moving_window->PosFloat - g.MovingWindow->PosFloat; + if (actually_moving_window->PosFloat.x != pos.x || actually_moving_window->PosFloat.y != pos.y) + { + MarkIniSettingsDirty(actually_moving_window); + actually_moving_window->PosFloat = pos; + } FocusWindow(g.MovingWindow); } else @@ -2950,7 +2957,7 @@ void ImGui::EndFrame() // Set ActiveId even if the _NoMove flag is set, without it dragging away from a window with _NoMove would activate hover on other windows. FocusWindow(g.HoveredWindow); SetActiveID(g.HoveredWindow->MoveId, g.HoveredWindow); - g.ActiveIdClickOffset = g.IO.MousePos - g.HoveredRootWindow->Pos; + g.ActiveIdClickOffset = g.IO.MousePos - g.HoveredWindow->Pos; if (!(g.HoveredWindow->Flags & ImGuiWindowFlags_NoMove) && !(g.HoveredRootWindow->Flags & ImGuiWindowFlags_NoMove)) { g.MovingWindow = g.HoveredWindow; diff --git a/imgui_internal.h b/imgui_internal.h index 87a4a131a..797f70758 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -534,7 +534,7 @@ struct ImGuiContext bool ActiveIdAllowOverlap; // Active widget allows another widget to steal active id (generally for overlapping widgets, but not always) ImVec2 ActiveIdClickOffset; // Clicked offset from upper-left corner, if applicable (currently only set by ButtonBehavior) ImGuiWindow* ActiveIdWindow; - ImGuiWindow* MovingWindow; // Track the child window we clicked on to move a window. + ImGuiWindow* MovingWindow; // Track the window we clicked on (in order to preserve focus). The actually window that is moved is generally MovingWindow->RootWindow. ImGuiID MovingWindowMoveId; // == MovingWindow->MoveId ImVector ColorModifiers; // Stack for PushStyleColor()/PopStyleColor() ImVector StyleModifiers; // Stack for PushStyleVar()/PopStyleVar() From 06eef2ce6fe3e41fec1a60eb37dbb8f97a0a89c9 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 15 Jan 2018 17:25:11 +0100 Subject: [PATCH 873/921] Internals: DrawData: renamed fields only (committing separately so that next commit is less nosiy). --- imgui.cpp | 60 ++++++++++++++++++++++++------------------------ imgui_internal.h | 4 ++-- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index fee26e2ff..4457ee5fd 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2246,7 +2246,7 @@ ImGuiStyle& ImGui::GetStyle() // Same value as passed to your RenderDrawListsFn() function. valid after Render() and until the next call to NewFrame() ImDrawData* ImGui::GetDrawData() { - return GImGui->RenderDrawData.Valid ? &GImGui->RenderDrawData : NULL; + return GImGui->DrawData.Valid ? &GImGui->DrawData : NULL; } float ImGui::GetTime() @@ -2303,9 +2303,9 @@ void ImGui::NewFrame() g.OverlayDrawList.Flags = (g.Style.AntiAliasedLines ? ImDrawListFlags_AntiAliasedLines : 0) | (g.Style.AntiAliasedFill ? ImDrawListFlags_AntiAliasedFill : 0); // Mark rendering data as invalid to prevent user who may have a handle on it to use it - g.RenderDrawData.Valid = false; - g.RenderDrawData.CmdLists = NULL; - g.RenderDrawData.CmdListsCount = g.RenderDrawData.TotalVtxCount = g.RenderDrawData.TotalIdxCount = 0; + g.DrawData.Valid = false; + g.DrawData.CmdLists = NULL; + g.DrawData.CmdListsCount = g.DrawData.TotalVtxCount = g.DrawData.TotalIdxCount = 0; // Clear reference to active widget if the widget isn't alive anymore if (!g.HoveredIdPreviousFrame) @@ -2656,8 +2656,8 @@ void ImGui::Shutdown() g.FontStack.clear(); g.OpenPopupStack.clear(); g.CurrentPopupStack.clear(); - for (int i = 0; i < IM_ARRAYSIZE(g.RenderDrawLists); i++) - g.RenderDrawLists[i].clear(); + for (int i = 0; i < IM_ARRAYSIZE(g.DrawDataLists); i++) + g.DrawDataLists[i].clear(); g.OverlayDrawList.ClearFreeMemory(); g.PrivateClipboard.clear(); g.InputTextState.Text.clear(); @@ -2902,11 +2902,11 @@ static void AddWindowToRenderListSelectLayer(ImGuiWindow* window) ImGuiContext& g = *GImGui; g.IO.MetricsActiveWindows++; if (window->Flags & ImGuiWindowFlags_Popup) - AddWindowToRenderList(g.RenderDrawLists[1], window); + AddWindowToRenderList(g.DrawDataLists[1], window); else if (window->Flags & ImGuiWindowFlags_Tooltip) - AddWindowToRenderList(g.RenderDrawLists[2], window); + AddWindowToRenderList(g.DrawDataLists[2], window); else - AddWindowToRenderList(g.RenderDrawLists[0], window); + AddWindowToRenderList(g.DrawDataLists[0], window); } // When using this function it is sane to ensure that float are perfectly rounded to integer values, to that e.g. (int)(max.x-min.x) in user's render produce correct result. @@ -3031,8 +3031,8 @@ void ImGui::Render() { // Gather windows to render g.IO.MetricsRenderVertices = g.IO.MetricsRenderIndices = g.IO.MetricsActiveWindows = 0; - for (int i = 0; i < IM_ARRAYSIZE(g.RenderDrawLists); i++) - g.RenderDrawLists[i].resize(0); + for (int i = 0; i < IM_ARRAYSIZE(g.DrawDataLists); i++) + g.DrawDataLists[i].resize(0); for (int i = 0; i != g.Windows.Size; i++) { ImGuiWindow* window = g.Windows[i]; @@ -3041,17 +3041,17 @@ void ImGui::Render() } // Flatten layers - int n = g.RenderDrawLists[0].Size; + int n = g.DrawDataLists[0].Size; int flattened_size = n; - for (int i = 1; i < IM_ARRAYSIZE(g.RenderDrawLists); i++) - flattened_size += g.RenderDrawLists[i].Size; - g.RenderDrawLists[0].resize(flattened_size); - for (int i = 1; i < IM_ARRAYSIZE(g.RenderDrawLists); i++) + for (int i = 1; i < IM_ARRAYSIZE(g.DrawDataLists); i++) + flattened_size += g.DrawDataLists[i].Size; + g.DrawDataLists[0].resize(flattened_size); + for (int i = 1; i < IM_ARRAYSIZE(g.DrawDataLists); i++) { - ImVector& layer = g.RenderDrawLists[i]; + ImVector& layer = g.DrawDataLists[i]; if (layer.empty()) continue; - memcpy(&g.RenderDrawLists[0][n], &layer[0], layer.Size * sizeof(ImDrawList*)); + memcpy(&g.DrawDataLists[0][n], &layer[0], layer.Size * sizeof(ImDrawList*)); n += layer.Size; } @@ -3070,18 +3070,18 @@ void ImGui::Render() g.OverlayDrawList.PopTextureID(); } if (!g.OverlayDrawList.VtxBuffer.empty()) - AddDrawListToRenderList(g.RenderDrawLists[0], &g.OverlayDrawList); + AddDrawListToRenderList(g.DrawDataLists[0], &g.OverlayDrawList); // Setup draw data - g.RenderDrawData.Valid = true; - g.RenderDrawData.CmdLists = (g.RenderDrawLists[0].Size > 0) ? &g.RenderDrawLists[0][0] : NULL; - g.RenderDrawData.CmdListsCount = g.RenderDrawLists[0].Size; - g.RenderDrawData.TotalVtxCount = g.IO.MetricsRenderVertices; - g.RenderDrawData.TotalIdxCount = g.IO.MetricsRenderIndices; + g.DrawData.Valid = true; + g.DrawData.CmdLists = (g.DrawDataLists[0].Size > 0) ? &g.DrawDataLists[0][0] : NULL; + g.DrawData.CmdListsCount = g.DrawDataLists[0].Size; + g.DrawData.TotalVtxCount = g.IO.MetricsRenderVertices; + g.DrawData.TotalIdxCount = g.IO.MetricsRenderIndices; // Render. If user hasn't set a callback then they may retrieve the draw data via GetDrawData() - if (g.RenderDrawData.CmdListsCount > 0 && g.IO.RenderDrawListsFn != NULL) - g.IO.RenderDrawListsFn(&g.RenderDrawData); + if (g.DrawData.CmdListsCount > 0 && g.IO.RenderDrawListsFn != NULL) + g.IO.RenderDrawListsFn(&g.DrawData); } } @@ -11749,11 +11749,11 @@ void ImGui::ShowMetricsWindow(bool* p_open) ImGuiContext& g = *GImGui; // Access private state Funcs::NodeWindows(g.Windows, "Windows"); - if (ImGui::TreeNode("DrawList", "Active DrawLists (%d)", g.RenderDrawLists[0].Size)) + if (ImGui::TreeNode("DrawList", "Active DrawLists (%d)", g.DrawDataLists[0].Size)) { - for (int layer = 0; layer < IM_ARRAYSIZE(g.RenderDrawLists); layer++) - for (int i = 0; i < g.RenderDrawLists[layer].Size; i++) - Funcs::NodeDrawList(g.RenderDrawLists[0][i], "DrawList"); + for (int layer = 0; layer < IM_ARRAYSIZE(g.DrawDataLists); layer++) + for (int i = 0; i < g.DrawDataLists[layer].Size; i++) + Funcs::NodeDrawList(g.DrawDataLists[0][i], "DrawList"); ImGui::TreePop(); } if (ImGui::TreeNode("Popups", "Open Popups Stack (%d)", g.OpenPopupStack.Size)) diff --git a/imgui_internal.h b/imgui_internal.h index 797f70758..aba8c4192 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -546,8 +546,8 @@ struct ImGuiContext ImGuiCond NextTreeNodeOpenCond; // Render - ImDrawData RenderDrawData; // Main ImDrawData instance to pass render information to the user - ImVector RenderDrawLists[3]; + ImDrawData DrawData; // Main ImDrawData instance to pass render information to the user + ImVector DrawDataLists[3]; float ModalWindowDarkeningRatio; ImDrawList OverlayDrawList; // Optional software render of mouse cursors, if io.MouseDrawCursor is set + a few debug overlays ImGuiMouseCursor MouseCursor; From 061d8df0336589ffee5061cec356496088f1fd8e Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 15 Jan 2018 17:29:18 +0100 Subject: [PATCH 874/921] MIssing IMGUI_API for a type with non-inline methods. --- imgui_internal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui_internal.h b/imgui_internal.h index aba8c4192..a0909f888 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -448,7 +448,7 @@ struct ImGuiColumnsSet } }; -struct ImDrawListSharedData +struct IMGUI_API ImDrawListSharedData { ImVec2 TexUvWhitePixel; // UV of white pixel in the atlas ImFont* Font; // Current/default font (optional, for simplified AddText overload) From 038453258e0dc03b159d9e8c16a98b092aedbc5f Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 15 Jan 2018 17:48:07 +0100 Subject: [PATCH 875/921] Internals: DrawData: Refactored chunks into a ImDrawDataBuilder we can reuse. --- imgui.cpp | 115 +++++++++++++++++++++++++---------------------- imgui_internal.h | 12 ++++- 2 files changed, 72 insertions(+), 55 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 4457ee5fd..89afeced7 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -648,9 +648,9 @@ static ImGuiWindow* CreateNewWindow(const char* name, ImVec2 size, ImGuiWind static void CheckStacksSize(ImGuiWindow* window, bool write); static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window); -static void AddDrawListToRenderList(ImVector& out_render_list, ImDrawList* draw_list); -static void AddWindowToRenderList(ImVector& out_render_list, ImGuiWindow* window); -static void AddWindowToSortedBuffer(ImVector& out_sorted_windows, ImGuiWindow* window); +static void AddDrawListToRenderList(ImVector* out_render_list, ImDrawList* draw_list); +static void AddWindowToRenderList(ImVector* out_render_list, ImGuiWindow* window); +static void AddWindowToSortedBuffer(ImVector* out_sorted_windows, ImGuiWindow* window); static ImGuiWindowSettings* AddWindowSettings(const char* name); @@ -2656,8 +2656,7 @@ void ImGui::Shutdown() g.FontStack.clear(); g.OpenPopupStack.clear(); g.CurrentPopupStack.clear(); - for (int i = 0; i < IM_ARRAYSIZE(g.DrawDataLists); i++) - g.DrawDataLists[i].clear(); + g.DrawDataBuilder.ClearFreeMemory(); g.OverlayDrawList.ClearFreeMemory(); g.PrivateClipboard.clear(); g.InputTextState.Text.clear(); @@ -2847,7 +2846,7 @@ static void AddWindowToSortedBuffer(ImVector& out_sorted_windows, } } -static void AddDrawListToRenderList(ImVector& out_render_list, ImDrawList* draw_list) +static void AddDrawListToRenderList(ImVector* out_render_list, ImDrawList* draw_list) { if (draw_list->CmdBuffer.empty()) return; @@ -2866,9 +2865,9 @@ static void AddDrawListToRenderList(ImVector& out_render_list, ImDr IM_ASSERT(draw_list->IdxBuffer.Size == 0 || draw_list->_IdxWritePtr == draw_list->IdxBuffer.Data + draw_list->IdxBuffer.Size); IM_ASSERT((int)draw_list->_VtxCurrentIdx == draw_list->VtxBuffer.Size); - // Check that draw_list doesn't use more vertices than indexable in a single draw call (default ImDrawIdx = unsigned short = 2 bytes = 64K vertices per ImDrawList = per window) + // Check that draw_list doesn't use more vertices than indexable (default ImDrawIdx = unsigned short = 2 bytes = 64K vertices per ImDrawList = per window) // If this assert triggers because you are drawing lots of stuff manually: - // A) Make sure you are coarse clipping, because ImDrawList let all your vertices pass. You can use thre Metrics window to inspect draw list contents. + // A) Make sure you are coarse clipping, because ImDrawList let all your vertices pass. You can use the Metrics window to inspect draw list contents. // B) If you need/want meshes with more than 64K vertices, uncomment the '#define ImDrawIdx unsigned int' line in imconfig.h to set the index size to 4 bytes. // You'll need to handle the 4-bytes indices to your renderer. For example, the OpenGL example code detect index size at compile-time by doing: // glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer_offset); @@ -2877,36 +2876,61 @@ static void AddDrawListToRenderList(ImVector& out_render_list, ImDr if (sizeof(ImDrawIdx) == 2) IM_ASSERT(draw_list->_VtxCurrentIdx < (1 << 16) && "Too many vertices in ImDrawList using 16-bit indices. Read comment above"); - out_render_list.push_back(draw_list); - GImGui->IO.MetricsRenderVertices += draw_list->VtxBuffer.Size; - GImGui->IO.MetricsRenderIndices += draw_list->IdxBuffer.Size; + out_render_list->push_back(draw_list); } -static void AddWindowToRenderList(ImVector& out_render_list, ImGuiWindow* window) +static void AddWindowToRenderList(ImVector* out_render_list, ImGuiWindow* window) { AddDrawListToRenderList(out_render_list, window->DrawList); for (int i = 0; i < window->DC.ChildWindows.Size; i++) { ImGuiWindow* child = window->DC.ChildWindows[i]; - if (!child->Active) // clipped children may have been marked not active - continue; - if (child->HiddenFrames > 0) - continue; - AddWindowToRenderList(out_render_list, child); + if (child->Active && child->HiddenFrames <= 0) // clipped children may have been marked not active + AddWindowToRenderList(out_render_list, child); } } -static void AddWindowToRenderListSelectLayer(ImGuiWindow* window) +static void AddWindowToDrawDataSelectLayer(ImDrawDataBuilder* builder, ImGuiWindow* window) { - // FIXME: Generalize this with a proper layering system so e.g. user can draw in specific layers, below text, .. ImGuiContext& g = *GImGui; g.IO.MetricsActiveWindows++; - if (window->Flags & ImGuiWindowFlags_Popup) - AddWindowToRenderList(g.DrawDataLists[1], window); - else if (window->Flags & ImGuiWindowFlags_Tooltip) - AddWindowToRenderList(g.DrawDataLists[2], window); + if (window->Flags & ImGuiWindowFlags_Tooltip) + AddWindowToRenderList(&builder->Layers[2], window); + else if (window->Flags & ImGuiWindowFlags_Popup) + AddWindowToRenderList(&builder->Layers[1], window); else - AddWindowToRenderList(g.DrawDataLists[0], window); + AddWindowToRenderList(&builder->Layers[0], window); +} + +void ImDrawDataBuilder::FlattenIntoSingleLayer() +{ + int n = Layers[0].Size; + int size = n; + for (int i = 1; i < IM_ARRAYSIZE(Layers); i++) + size += Layers[i].Size; + Layers[0].resize(size); + for (int layer_n = 1; layer_n < IM_ARRAYSIZE(Layers); layer_n++) + { + ImVector& layer = Layers[layer_n]; + if (layer.empty()) + continue; + memcpy(&Layers[0][n], &layer[0], layer.Size * sizeof(ImDrawList*)); + n += layer.Size; + layer.resize(0); + } +} + +void ImDrawDataBuilder::SetupDrawData(ImDrawData* out_draw_data) +{ + out_draw_data->Valid = true; + out_draw_data->CmdLists = (Layers[0].Size > 0) ? Layers[0].Data : NULL; + out_draw_data->CmdListsCount = Layers[0].Size; + out_draw_data->TotalVtxCount = out_draw_data->TotalIdxCount = 0; + for (int n = 0; n < Layers[0].Size; n++) + { + out_draw_data->TotalVtxCount += Layers[0][n]->VtxBuffer.Size; + out_draw_data->TotalIdxCount += Layers[0][n]->IdxBuffer.Size; + } } // When using this function it is sane to ensure that float are perfectly rounded to integer values, to that e.g. (int)(max.x-min.x) in user's render produce correct result. @@ -3031,29 +3055,14 @@ void ImGui::Render() { // Gather windows to render g.IO.MetricsRenderVertices = g.IO.MetricsRenderIndices = g.IO.MetricsActiveWindows = 0; - for (int i = 0; i < IM_ARRAYSIZE(g.DrawDataLists); i++) - g.DrawDataLists[i].resize(0); + g.DrawDataBuilder.Clear(); for (int i = 0; i != g.Windows.Size; i++) { ImGuiWindow* window = g.Windows[i]; if (window->Active && window->HiddenFrames <= 0 && (window->Flags & (ImGuiWindowFlags_ChildWindow)) == 0) - AddWindowToRenderListSelectLayer(window); - } - - // Flatten layers - int n = g.DrawDataLists[0].Size; - int flattened_size = n; - for (int i = 1; i < IM_ARRAYSIZE(g.DrawDataLists); i++) - flattened_size += g.DrawDataLists[i].Size; - g.DrawDataLists[0].resize(flattened_size); - for (int i = 1; i < IM_ARRAYSIZE(g.DrawDataLists); i++) - { - ImVector& layer = g.DrawDataLists[i]; - if (layer.empty()) - continue; - memcpy(&g.DrawDataLists[0][n], &layer[0], layer.Size * sizeof(ImDrawList*)); - n += layer.Size; + AddWindowToDrawDataSelectLayer(&g.DrawDataBuilder, window); } + g.DrawDataBuilder.FlattenIntoSingleLayer(); // Draw software mouse cursor if requested if (g.IO.MouseDrawCursor) @@ -3070,14 +3079,12 @@ void ImGui::Render() g.OverlayDrawList.PopTextureID(); } if (!g.OverlayDrawList.VtxBuffer.empty()) - AddDrawListToRenderList(g.DrawDataLists[0], &g.OverlayDrawList); + AddDrawListToRenderList(&g.DrawDataBuilder.Layers[0], &g.OverlayDrawList); - // Setup draw data - g.DrawData.Valid = true; - g.DrawData.CmdLists = (g.DrawDataLists[0].Size > 0) ? &g.DrawDataLists[0][0] : NULL; - g.DrawData.CmdListsCount = g.DrawDataLists[0].Size; - g.DrawData.TotalVtxCount = g.IO.MetricsRenderVertices; - g.DrawData.TotalIdxCount = g.IO.MetricsRenderIndices; + // Setup ImDrawData structure for end-user + g.DrawDataBuilder.SetupDrawData(&g.DrawData); + g.IO.MetricsRenderVertices = g.DrawData.TotalVtxCount; + g.IO.MetricsRenderIndices = g.DrawData.TotalIdxCount; // Render. If user hasn't set a callback then they may retrieve the draw data via GetDrawData() if (g.DrawData.CmdListsCount > 0 && g.IO.RenderDrawListsFn != NULL) @@ -11747,13 +11754,13 @@ void ImGui::ShowMetricsWindow(bool* p_open) } }; - ImGuiContext& g = *GImGui; // Access private state + // Access private state, we are going to display the draw lists from last frame + ImGuiContext& g = *GImGui; Funcs::NodeWindows(g.Windows, "Windows"); - if (ImGui::TreeNode("DrawList", "Active DrawLists (%d)", g.DrawDataLists[0].Size)) + if (ImGui::TreeNode("DrawList", "Active DrawLists (%d)", g.DrawDataBuilder.Layers[0].Size)) { - for (int layer = 0; layer < IM_ARRAYSIZE(g.DrawDataLists); layer++) - for (int i = 0; i < g.DrawDataLists[layer].Size; i++) - Funcs::NodeDrawList(g.DrawDataLists[0][i], "DrawList"); + for (int i = 0; i < g.DrawDataBuilder.Layers[0].Size; i++) + Funcs::NodeDrawList(g.DrawDataBuilder.Layers[0][i], "DrawList"); ImGui::TreePop(); } if (ImGui::TreeNode("Popups", "Open Popups Stack (%d)", g.OpenPopupStack.Size)) diff --git a/imgui_internal.h b/imgui_internal.h index a0909f888..2c67cfcd3 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -463,6 +463,16 @@ struct IMGUI_API ImDrawListSharedData ImDrawListSharedData(); }; +struct ImDrawDataBuilder +{ + ImVector Layers[3]; // Layered for: regular, popup, tooltip + + void Clear() { for (int n = 0; n < IM_ARRAYSIZE(Layers); n++) Layers[n].resize(0); } + void ClearFreeMemory() { for (int n = 0; n < IM_ARRAYSIZE(Layers); n++) Layers[n].clear(); } + IMGUI_API void FlattenIntoSingleLayer(); + IMGUI_API void SetupDrawData(ImDrawData* out_draw_data); +}; + // Storage for SetNexWindow** functions struct ImGuiNextWindowData { @@ -547,7 +557,7 @@ struct ImGuiContext // Render ImDrawData DrawData; // Main ImDrawData instance to pass render information to the user - ImVector DrawDataLists[3]; + ImDrawDataBuilder DrawDataBuilder; float ModalWindowDarkeningRatio; ImDrawList OverlayDrawList; // Optional software render of mouse cursors, if io.MouseDrawCursor is set + a few debug overlays ImGuiMouseCursor MouseCursor; From 0c06b43e6b5b0cb01a31c1985bd5009cf61ebc71 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 15 Jan 2018 17:55:38 +0100 Subject: [PATCH 876/921] Metrics: Tweaks to hover-window-drawlist to see window bounding box. --- imgui.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 89afeced7..1937e96fb 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -11662,7 +11662,7 @@ void ImGui::ShowMetricsWindow(bool* p_open) struct Funcs { - static void NodeDrawList(ImDrawList* draw_list, const char* label) + static void NodeDrawList(ImGuiWindow* window, ImDrawList* draw_list, const char* label) { bool node_open = ImGui::TreeNode(draw_list, "%s: '%s' %d vtx, %d indices, %d cmds", label, draw_list->_OwnerName ? draw_list->_OwnerName : "", draw_list->VtxBuffer.Size, draw_list->IdxBuffer.Size, draw_list->CmdBuffer.Size); if (draw_list == ImGui::GetWindowDrawList()) @@ -11672,10 +11672,13 @@ void ImGui::ShowMetricsWindow(bool* p_open) if (node_open) ImGui::TreePop(); return; } + + ImDrawList* overlay_draw_list = &GImGui->OverlayDrawList; // Render additional visuals into the top-most draw list + if (window && ImGui::IsItemHovered()) + overlay_draw_list->AddRect(window->Pos, window->Pos + window->Size, IM_COL32(255, 255, 0, 255)); if (!node_open) return; - ImDrawList* overlay_draw_list = &GImGui->OverlayDrawList; // Render additional visuals into the top-most draw list int elem_offset = 0; for (const ImDrawCmd* pcmd = draw_list->CmdBuffer.begin(); pcmd < draw_list->CmdBuffer.end(); elem_offset += pcmd->ElemCount, pcmd++) { @@ -11741,10 +11744,8 @@ void ImGui::ShowMetricsWindow(bool* p_open) { if (!ImGui::TreeNode(window, "%s '%s', %d @ 0x%p", label, window->Name, window->Active || window->WasActive, window)) return; - NodeDrawList(window->DrawList, "DrawList"); + NodeDrawList(window, window->DrawList, "DrawList"); ImGui::BulletText("Pos: (%.1f,%.1f), Size: (%.1f,%.1f), SizeContents (%.1f,%.1f)", window->Pos.x, window->Pos.y, window->Size.x, window->Size.y, window->SizeContents.x, window->SizeContents.y); - if (ImGui::IsItemHovered()) - GImGui->OverlayDrawList.AddRect(window->Pos, window->Pos + window->Size, IM_COL32(255,255,0,255)); ImGui::BulletText("Scroll: (%.2f/%.2f,%.2f/%.2f)", window->Scroll.x, GetScrollMaxX(window), window->Scroll.y, GetScrollMaxY(window)); ImGui::BulletText("Active: %d, WriteAccessed: %d", window->Active, window->WriteAccessed); if (window->RootWindow != window) NodeWindow(window->RootWindow, "RootWindow"); @@ -11760,7 +11761,7 @@ void ImGui::ShowMetricsWindow(bool* p_open) if (ImGui::TreeNode("DrawList", "Active DrawLists (%d)", g.DrawDataBuilder.Layers[0].Size)) { for (int i = 0; i < g.DrawDataBuilder.Layers[0].Size; i++) - Funcs::NodeDrawList(g.DrawDataBuilder.Layers[0][i], "DrawList"); + Funcs::NodeDrawList(NULL, g.DrawDataBuilder.Layers[0][i], "DrawList"); ImGui::TreePop(); } if (ImGui::TreeNode("Popups", "Open Popups Stack (%d)", g.OpenPopupStack.Size)) From 1182174d818802e2c2692b515f0710224a53ffb6 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 15 Jan 2018 18:00:13 +0100 Subject: [PATCH 877/921] Internals: DrawData: We don't need an intermediate layer for popups. --- imgui.cpp | 2 -- imgui_internal.h | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 1937e96fb..f33ab67fe 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2895,8 +2895,6 @@ static void AddWindowToDrawDataSelectLayer(ImDrawDataBuilder* builder, ImGuiWind ImGuiContext& g = *GImGui; g.IO.MetricsActiveWindows++; if (window->Flags & ImGuiWindowFlags_Tooltip) - AddWindowToRenderList(&builder->Layers[2], window); - else if (window->Flags & ImGuiWindowFlags_Popup) AddWindowToRenderList(&builder->Layers[1], window); else AddWindowToRenderList(&builder->Layers[0], window); diff --git a/imgui_internal.h b/imgui_internal.h index 2c67cfcd3..81230757f 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -465,7 +465,7 @@ struct IMGUI_API ImDrawListSharedData struct ImDrawDataBuilder { - ImVector Layers[3]; // Layered for: regular, popup, tooltip + ImVector Layers[2]; // Global layers for: regular, tooltip void Clear() { for (int n = 0; n < IM_ARRAYSIZE(Layers); n++) Layers[n].resize(0); } void ClearFreeMemory() { for (int n = 0; n < IM_ARRAYSIZE(Layers); n++) Layers[n].clear(); } From 28a76af185b180a3cc8fa210635746a93941a9a8 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 15 Jan 2018 19:09:10 +0100 Subject: [PATCH 878/921] Internal: DrawData: Tidying, renaming. --- imgui.cpp | 44 +++++++++++++++++++++----------------------- imgui.h | 3 ++- imgui_internal.h | 1 - 3 files changed, 23 insertions(+), 25 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index f33ab67fe..f1f54e6bc 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -648,8 +648,8 @@ static ImGuiWindow* CreateNewWindow(const char* name, ImVec2 size, ImGuiWind static void CheckStacksSize(ImGuiWindow* window, bool write); static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window); -static void AddDrawListToRenderList(ImVector* out_render_list, ImDrawList* draw_list); -static void AddWindowToRenderList(ImVector* out_render_list, ImGuiWindow* window); +static void AddDrawListToDrawData(ImVector* out_render_list, ImDrawList* draw_list); +static void AddWindowToDrawData(ImVector* out_render_list, ImGuiWindow* window); static void AddWindowToSortedBuffer(ImVector* out_sorted_windows, ImGuiWindow* window); static ImGuiWindowSettings* AddWindowSettings(const char* name); @@ -2303,9 +2303,7 @@ void ImGui::NewFrame() g.OverlayDrawList.Flags = (g.Style.AntiAliasedLines ? ImDrawListFlags_AntiAliasedLines : 0) | (g.Style.AntiAliasedFill ? ImDrawListFlags_AntiAliasedFill : 0); // Mark rendering data as invalid to prevent user who may have a handle on it to use it - g.DrawData.Valid = false; - g.DrawData.CmdLists = NULL; - g.DrawData.CmdListsCount = g.DrawData.TotalVtxCount = g.DrawData.TotalIdxCount = 0; + g.DrawData.Clear(); // Clear reference to active widget if the widget isn't alive anymore if (!g.HoveredIdPreviousFrame) @@ -2846,7 +2844,7 @@ static void AddWindowToSortedBuffer(ImVector& out_sorted_windows, } } -static void AddDrawListToRenderList(ImVector* out_render_list, ImDrawList* draw_list) +static void AddDrawListToDrawData(ImVector* out_render_list, ImDrawList* draw_list) { if (draw_list->CmdBuffer.empty()) return; @@ -2879,25 +2877,25 @@ static void AddDrawListToRenderList(ImVector* out_render_list, ImDr out_render_list->push_back(draw_list); } -static void AddWindowToRenderList(ImVector* out_render_list, ImGuiWindow* window) +static void AddWindowToDrawData(ImVector* out_render_list, ImGuiWindow* window) { - AddDrawListToRenderList(out_render_list, window->DrawList); + AddDrawListToDrawData(out_render_list, window->DrawList); for (int i = 0; i < window->DC.ChildWindows.Size; i++) { ImGuiWindow* child = window->DC.ChildWindows[i]; if (child->Active && child->HiddenFrames <= 0) // clipped children may have been marked not active - AddWindowToRenderList(out_render_list, child); + AddWindowToDrawData(out_render_list, child); } } -static void AddWindowToDrawDataSelectLayer(ImDrawDataBuilder* builder, ImGuiWindow* window) +static void AddWindowToDrawDataSelectLayer(ImGuiWindow* window) { ImGuiContext& g = *GImGui; g.IO.MetricsActiveWindows++; if (window->Flags & ImGuiWindowFlags_Tooltip) - AddWindowToRenderList(&builder->Layers[1], window); + AddWindowToDrawData(&g.DrawDataBuilder.Layers[1], window); else - AddWindowToRenderList(&builder->Layers[0], window); + AddWindowToDrawData(&g.DrawDataBuilder.Layers[0], window); } void ImDrawDataBuilder::FlattenIntoSingleLayer() @@ -2918,16 +2916,16 @@ void ImDrawDataBuilder::FlattenIntoSingleLayer() } } -void ImDrawDataBuilder::SetupDrawData(ImDrawData* out_draw_data) +static void SetupDrawData(ImVector* draw_lists, ImDrawData* out_draw_data) { out_draw_data->Valid = true; - out_draw_data->CmdLists = (Layers[0].Size > 0) ? Layers[0].Data : NULL; - out_draw_data->CmdListsCount = Layers[0].Size; + out_draw_data->CmdLists = (draw_lists->Size > 0) ? draw_lists->Data : NULL; + out_draw_data->CmdListsCount = draw_lists->Size; out_draw_data->TotalVtxCount = out_draw_data->TotalIdxCount = 0; - for (int n = 0; n < Layers[0].Size; n++) + for (int n = 0; n < draw_lists->Size; n++) { - out_draw_data->TotalVtxCount += Layers[0][n]->VtxBuffer.Size; - out_draw_data->TotalIdxCount += Layers[0][n]->IdxBuffer.Size; + out_draw_data->TotalVtxCount += draw_lists->Data[n]->VtxBuffer.Size; + out_draw_data->TotalIdxCount += draw_lists->Data[n]->IdxBuffer.Size; } } @@ -3054,11 +3052,11 @@ void ImGui::Render() // Gather windows to render g.IO.MetricsRenderVertices = g.IO.MetricsRenderIndices = g.IO.MetricsActiveWindows = 0; g.DrawDataBuilder.Clear(); - for (int i = 0; i != g.Windows.Size; i++) + for (int n = 0; n != g.Windows.Size; n++) { - ImGuiWindow* window = g.Windows[i]; + ImGuiWindow* window = g.Windows[n]; if (window->Active && window->HiddenFrames <= 0 && (window->Flags & (ImGuiWindowFlags_ChildWindow)) == 0) - AddWindowToDrawDataSelectLayer(&g.DrawDataBuilder, window); + AddWindowToDrawDataSelectLayer(window); } g.DrawDataBuilder.FlattenIntoSingleLayer(); @@ -3077,10 +3075,10 @@ void ImGui::Render() g.OverlayDrawList.PopTextureID(); } if (!g.OverlayDrawList.VtxBuffer.empty()) - AddDrawListToRenderList(&g.DrawDataBuilder.Layers[0], &g.OverlayDrawList); + AddDrawListToDrawData(&g.DrawDataBuilder.Layers[0], &g.OverlayDrawList); // Setup ImDrawData structure for end-user - g.DrawDataBuilder.SetupDrawData(&g.DrawData); + SetupDrawData(&g.DrawDataBuilder.Layers[0], &g.DrawData); g.IO.MetricsRenderVertices = g.DrawData.TotalVtxCount; g.IO.MetricsRenderIndices = g.DrawData.TotalIdxCount; diff --git a/imgui.h b/imgui.h index 674254082..ee6f01354 100644 --- a/imgui.h +++ b/imgui.h @@ -1495,7 +1495,8 @@ struct ImDrawData int TotalIdxCount; // For convenience, sum of all cmd_lists idx_buffer.Size // Functions - ImDrawData() { Valid = false; CmdLists = NULL; CmdListsCount = TotalVtxCount = TotalIdxCount = 0; } + ImDrawData() { Clear(); } + void Clear() { Valid = false; CmdLists = NULL; CmdListsCount = TotalVtxCount = TotalIdxCount = 0; } // Draw lists are owned by the ImGuiContext and only pointed to here. IMGUI_API void DeIndexAllBuffers(); // For backward compatibility or convenience: convert all buffers from indexed to de-indexed, in case you cannot render indexed. Note: this is slow and most likely a waste of resources. Always prefer indexed rendering! IMGUI_API void ScaleClipRects(const ImVec2& sc); // Helper to scale the ClipRect field of each ImDrawCmd. Use if your final output buffer is at a different scale than ImGui expects, or if there is a difference between your window resolution and framebuffer resolution. }; diff --git a/imgui_internal.h b/imgui_internal.h index 81230757f..0f90942c9 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -470,7 +470,6 @@ struct ImDrawDataBuilder void Clear() { for (int n = 0; n < IM_ARRAYSIZE(Layers); n++) Layers[n].resize(0); } void ClearFreeMemory() { for (int n = 0; n < IM_ARRAYSIZE(Layers); n++) Layers[n].clear(); } IMGUI_API void FlattenIntoSingleLayer(); - IMGUI_API void SetupDrawData(ImDrawData* out_draw_data); }; // Storage for SetNexWindow** functions From 7ccbb765e2c0acc84b3e5d7335050e0af8bb555f Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 17 Jan 2018 12:15:00 +0100 Subject: [PATCH 879/921] InputText: Cursor X position not lost when clicking outside on an item that's submitted after the InputText(). It was only noticeable when restoring focus programmatically. (#1418, #1554) --- imgui.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index f1f54e6bc..904fe8610 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -8607,8 +8607,11 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 } else if (io.MouseClicked[0] && !edit_state.SelectedAllMouseLock) { - stb_textedit_click(&edit_state, &edit_state.StbState, mouse_x, mouse_y); - edit_state.CursorAnimReset(); + if (hovered) + { + stb_textedit_click(&edit_state, &edit_state.StbState, mouse_x, mouse_y); + edit_state.CursorAnimReset(); + } } else if (io.MouseDown[0] && !edit_state.SelectedAllMouseLock && (io.MouseDelta.x != 0.0f || io.MouseDelta.y != 0.0f)) { From cc15512bfc2a3abb88d7c8969ecf6d67611e1b96 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 17 Jan 2018 12:15:24 +0100 Subject: [PATCH 880/921] InputText: Minor tweak. --- imgui_internal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui_internal.h b/imgui_internal.h index 0f90942c9..6873a2931 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -357,7 +357,7 @@ struct IMGUI_API ImGuiTextEditState void CursorClamp() { StbState.cursor = ImMin(StbState.cursor, CurLenW); StbState.select_start = ImMin(StbState.select_start, CurLenW); StbState.select_end = ImMin(StbState.select_end, CurLenW); } bool HasSelection() const { return StbState.select_start != StbState.select_end; } void ClearSelection() { StbState.select_start = StbState.select_end = StbState.cursor; } - void SelectAll() { StbState.select_start = 0; StbState.select_end = CurLenW; StbState.cursor = StbState.select_end; StbState.has_preferred_x = false; } + void SelectAll() { StbState.select_start = 0; StbState.cursor = StbState.select_end = CurLenW; StbState.has_preferred_x = false; } void OnKeyPressed(int key); }; From d1f726cd9db6445e18090e488c8ee8ca4fe6e09c Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 17 Jan 2018 12:46:07 +0100 Subject: [PATCH 881/921] Comments about Begin/End pair and handling of return value. --- imgui.h | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/imgui.h b/imgui.h index ee6f01354..91671ead3 100644 --- a/imgui.h +++ b/imgui.h @@ -145,11 +145,11 @@ namespace ImGui IMGUI_API void ShowUserGuide(); // add basic help/info block (not a window): how to manipulate ImGui as a end-user (mouse/keyboard controls). // Window - IMGUI_API bool Begin(const char* name, bool* p_open = NULL, ImGuiWindowFlags flags = 0); // push window to the stack and start appending to it. see .cpp for details. return false when window is collapsed, so you can early out in your code. 'bool* p_open' creates a widget on the upper-right to close the window (which sets your bool to false). - IMGUI_API void End(); // finish appending to current window, pop it off the window stack. - IMGUI_API bool BeginChild(const char* str_id, const ImVec2& size = ImVec2(0,0), bool border = false, ImGuiWindowFlags extra_flags = 0); // begin a scrolling region. size==0.0f: use remaining window size, size<0.0f: use remaining window size minus abs(size). size>0.0f: fixed size. each axis can use a different mode, e.g. ImVec2(0,400). - IMGUI_API bool BeginChild(ImGuiID id, const ImVec2& size = ImVec2(0,0), bool border = false, ImGuiWindowFlags extra_flags = 0); // " - IMGUI_API void EndChild(); + IMGUI_API bool Begin(const char* name, bool* p_open = NULL, ImGuiWindowFlags flags = 0); // push window to the stack and start appending to it. see .cpp for details. return false when window is collapsed (so you can early out in your code) but you always need to call End() regardless. 'bool* p_open' creates a widget on the upper-right to close the window (which sets your bool to false). + IMGUI_API void End(); // always call even if Begin() return false (which indicates a collapsed window)! finish appending to current window, pop it off the window stack. + IMGUI_API bool BeginChild(const char* str_id, const ImVec2& size = ImVec2(0,0), bool border = false, ImGuiWindowFlags flags = 0); // begin a scrolling region. size==0.0f: use remaining window size, size<0.0f: use remaining window size minus abs(size). size>0.0f: fixed size. each axis can use a different mode, e.g. ImVec2(0,400). + IMGUI_API bool BeginChild(ImGuiID id, const ImVec2& size = ImVec2(0,0), bool border = false, ImGuiWindowFlags flags = 0); // " + IMGUI_API void EndChild(); // always call even if BeginChild() return false (which indicates a collapsed or clipping child window) IMGUI_API ImVec2 GetContentRegionMax(); // current content boundaries (typically window boundaries including scrolling, or current column boundaries), in windows coordinates IMGUI_API ImVec2 GetContentRegionAvail(); // == GetContentRegionMax() - GetCursorPos() IMGUI_API float GetContentRegionAvailWidth(); // @@ -303,7 +303,7 @@ namespace ImGui // The new BeginCombo()/EndCombo() api allows you to manage your contents and selection state however you want it. // The old Combo() api are helpers over BeginCombo()/EndCombo() which are kept available for convenience purpose. IMGUI_API bool BeginCombo(const char* label, const char* preview_value, ImGuiComboFlags flags = 0); - IMGUI_API void EndCombo(); + IMGUI_API void EndCombo(); // only call EndCombo() if BeginCombo() returns true! IMGUI_API bool Combo(const char* label, int* current_item, const char* const items[], int items_count, int popup_max_height_in_items = -1); IMGUI_API bool Combo(const char* label, int* current_item, const char* items_separated_by_zeros, int popup_max_height_in_items = -1); // Separate items with \0 within a string, end item-list with \0\0. e.g. "One\0Two\0Three\0" IMGUI_API bool Combo(const char* label, int* current_item, bool(*items_getter)(void* data, int idx, const char** out_text), void* data, int items_count, int popup_max_height_in_items = -1); @@ -397,23 +397,23 @@ namespace ImGui IMGUI_API void EndTooltip(); // Menus - IMGUI_API bool BeginMainMenuBar(); // create and append to a full screen menu-bar. only call EndMainMenuBar() if this returns true! - IMGUI_API void EndMainMenuBar(); - IMGUI_API bool BeginMenuBar(); // append to menu-bar of current window (requires ImGuiWindowFlags_MenuBar flag set on parent window). only call EndMenuBar() if this returns true! - IMGUI_API void EndMenuBar(); + IMGUI_API bool BeginMainMenuBar(); // create and append to a full screen menu-bar. + IMGUI_API void EndMainMenuBar(); // only call EndMainMenuBar() if BeginMainMenuBar() returns true! + IMGUI_API bool BeginMenuBar(); // append to menu-bar of current window (requires ImGuiWindowFlags_MenuBar flag set on parent window). + IMGUI_API void EndMenuBar(); // only call EndMenuBar() if BeginMenuBar() returns true! IMGUI_API bool BeginMenu(const char* label, bool enabled = true); // create a sub-menu entry. only call EndMenu() if this returns true! - IMGUI_API void EndMenu(); + IMGUI_API void EndMenu(); // only call EndBegin() if BeginMenu() returns true! IMGUI_API bool MenuItem(const char* label, const char* shortcut = NULL, bool selected = false, bool enabled = true); // return true when activated. shortcuts are displayed for convenience but not processed by ImGui at the moment IMGUI_API bool MenuItem(const char* label, const char* shortcut, bool* p_selected, bool enabled = true); // return true when activated + toggle (*p_selected) if p_selected != NULL // Popups IMGUI_API void OpenPopup(const char* str_id); // call to mark popup as open (don't call every frame!). popups are closed when user click outside, or if CloseCurrentPopup() is called within a BeginPopup()/EndPopup() block. By default, Selectable()/MenuItem() are calling CloseCurrentPopup(). Popup identifiers are relative to the current ID-stack (so OpenPopup and BeginPopup needs to be at the same level). - IMGUI_API bool BeginPopup(const char* str_id, ImGuiWindowFlags flags = 0); // return true if the popup is open, and you can start outputting to it. only call EndPopup() if BeginPopup() returned true! + IMGUI_API bool BeginPopup(const char* str_id, ImGuiWindowFlags flags = 0); // return true if the popup is open, and you can start outputting to it. only call EndPopup() if BeginPopup() returns true! IMGUI_API bool BeginPopupContextItem(const char* str_id = NULL, int mouse_button = 1); // helper to open and begin popup when clicked on last item. if you can pass a NULL str_id only if the previous item had an id. If you want to use that on a non-interactive item such as Text() you need to pass in an explicit ID here. read comments in .cpp! IMGUI_API bool BeginPopupContextWindow(const char* str_id = NULL, int mouse_button = 1, bool also_over_items = true); // helper to open and begin popup when clicked on current window. IMGUI_API bool BeginPopupContextVoid(const char* str_id = NULL, int mouse_button = 1); // helper to open and begin popup when clicked in void (where there are no imgui windows). IMGUI_API bool BeginPopupModal(const char* name, bool* p_open = NULL, ImGuiWindowFlags flags = 0); // modal dialog (regular window with title bar, block interactions behind the modal window, can't close the modal window by clicking outside) - IMGUI_API void EndPopup(); + IMGUI_API void EndPopup(); // only call EndPopup() if BeginPopupXXX() returns true! IMGUI_API bool OpenPopupOnItemClick(const char* str_id = NULL, int mouse_button = 1); // helper to open popup when clicked on last item. return true when just opened. IMGUI_API bool IsPopupOpen(const char* str_id); // return true if the popup is open IMGUI_API void CloseCurrentPopup(); // close the popup we have begin-ed into. clicking on a MenuItem or Selectable automatically close the current popup. @@ -430,10 +430,10 @@ namespace ImGui // [BETA API] Missing Demo code. API may evolve. IMGUI_API bool BeginDragDropSource(ImGuiDragDropFlags flags = 0, int mouse_button = 0); // call when the current item is active. If this return true, you can call SetDragDropPayload() + EndDragDropSource() IMGUI_API bool SetDragDropPayload(const char* type, const void* data, size_t size, ImGuiCond cond = 0);// type is a user defined string of maximum 8 characters. Strings starting with '_' are reserved for dear imgui internal types. Data is copied and held by imgui. - IMGUI_API void EndDragDropSource(); + IMGUI_API void EndDragDropSource(); // only call EndDragDropSource() if BeginDragDropSource() returns true! IMGUI_API bool BeginDragDropTarget(); // call after submitting an item that may receive an item. If this returns true, you can call AcceptDragDropPayload() + EndDragDropTarget() IMGUI_API const ImGuiPayload* AcceptDragDropPayload(const char* type, ImGuiDragDropFlags flags = 0); // accept contents of a given type. If ImGuiDragDropFlags_AcceptBeforeDelivery is set you can peek into the payload before the mouse button is released. - IMGUI_API void EndDragDropTarget(); + IMGUI_API void EndDragDropTarget(); // only call EndDragDropTarget() if BeginDragDropTarget() returns true! // Clipping IMGUI_API void PushClipRect(const ImVec2& clip_rect_min, const ImVec2& clip_rect_max, bool intersect_with_current_clip_rect); @@ -473,8 +473,8 @@ namespace ImGui IMGUI_API ImVec2 CalcTextSize(const char* text, const char* text_end = NULL, bool hide_text_after_double_hash = false, float wrap_width = -1.0f); IMGUI_API void CalcListClipping(int items_count, float items_height, int* out_items_display_start, int* out_items_display_end); // calculate coarse clipping for large list of evenly sized items. Prefer using the ImGuiListClipper higher-level helper if you can. - IMGUI_API bool BeginChildFrame(ImGuiID id, const ImVec2& size, ImGuiWindowFlags extra_flags = 0); // helper to create a child window / scrolling region that looks like a normal widget frame - IMGUI_API void EndChildFrame(); + IMGUI_API bool BeginChildFrame(ImGuiID id, const ImVec2& size, ImGuiWindowFlags flags = 0); // helper to create a child window / scrolling region that looks like a normal widget frame + IMGUI_API void EndChildFrame(); // always call EndChildFrame() regardless of BeginChildFrame() return values (which indicates a collapsed/clipped window) IMGUI_API ImVec4 ColorConvertU32ToFloat4(ImU32 in); IMGUI_API ImU32 ColorConvertFloat4ToU32(const ImVec4& in); From 60d5dc79029e4d9c778c9635987c1f11260ce87e Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 18 Jan 2018 10:01:36 +0100 Subject: [PATCH 882/921] Examples: SDL: Fixed mapping of Insert key (#1555, fix bug introduced in #1541) --- examples/sdl_opengl2_example/imgui_impl_sdl.cpp | 2 +- examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl.cpp b/examples/sdl_opengl2_example/imgui_impl_sdl.cpp index ac9200837..689c7ad37 100644 --- a/examples/sdl_opengl2_example/imgui_impl_sdl.cpp +++ b/examples/sdl_opengl2_example/imgui_impl_sdl.cpp @@ -214,7 +214,7 @@ bool ImGui_ImplSdlGL2_Init(SDL_Window* window) io.KeyMap[ImGuiKey_PageDown] = SDL_SCANCODE_PAGEDOWN; io.KeyMap[ImGuiKey_Home] = SDL_SCANCODE_HOME; io.KeyMap[ImGuiKey_End] = SDL_SCANCODE_END; - io.KeyMap[ImGuiKey_Insert] = SDLK_INSERT; + io.KeyMap[ImGuiKey_Insert] = SDL_SCANCODE_INSERT; io.KeyMap[ImGuiKey_Delete] = SDLK_DELETE; io.KeyMap[ImGuiKey_Backspace] = SDLK_BACKSPACE; io.KeyMap[ImGuiKey_Enter] = SDLK_RETURN; diff --git a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp index f9e970f38..b16a0300c 100644 --- a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp +++ b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp @@ -325,7 +325,7 @@ bool ImGui_ImplSdlGL3_Init(SDL_Window* window) io.KeyMap[ImGuiKey_PageDown] = SDL_SCANCODE_PAGEDOWN; io.KeyMap[ImGuiKey_Home] = SDL_SCANCODE_HOME; io.KeyMap[ImGuiKey_End] = SDL_SCANCODE_END; - io.KeyMap[ImGuiKey_Insert] = SDLK_INSERT; + io.KeyMap[ImGuiKey_Insert] = SDL_SCANCODE_INSERT; io.KeyMap[ImGuiKey_Delete] = SDLK_DELETE; io.KeyMap[ImGuiKey_Backspace] = SDLK_BACKSPACE; io.KeyMap[ImGuiKey_Enter] = SDLK_RETURN; From 932d3f01988276e5a9ee969b3faaf443c21c118d Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 18 Jan 2018 10:06:58 +0100 Subject: [PATCH 883/921] NewFrame(): Added an assert to detect incorrect filling of the io.KeyMap[] array earlier. (#1555) + comments. --- imgui.cpp | 2 ++ imgui.h | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 904fe8610..bd218caf2 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2282,6 +2282,8 @@ void ImGui::NewFrame() IM_ASSERT(g.Style.CurveTessellationTol > 0.0f && "Invalid style setting"); IM_ASSERT(g.Style.Alpha >= 0.0f && g.Style.Alpha <= 1.0f && "Invalid style setting. Alpha cannot be negative (allows us to avoid a few clamps in color computations)"); IM_ASSERT((g.FrameCount == 0 || g.FrameCountEnded == g.FrameCount) && "Forgot to call Render() or EndFrame() at the end of the previous frame?"); + for (int n = 0; n < ImGuiKey_COUNT; n++) + IM_ASSERT(g.IO.KeyMap[n] >= -1 && g.IO.KeyMap[n] < IM_ARRAYSIZE(g.IO.KeysDown) && "io.KeyMap[] contains an out of bound value (need to be 0..512, or -1 for unmapped key)"); // Initialize on first frame if (!g.Initialized) diff --git a/imgui.h b/imgui.h index 91671ead3..c6bf05ded 100644 --- a/imgui.h +++ b/imgui.h @@ -881,8 +881,8 @@ struct ImGuiIO const char* LogFilename; // = "imgui_log.txt" // Path to .log file (default parameter to ImGui::LogToFile when no file is specified). float MouseDoubleClickTime; // = 0.30f // Time for a double-click, in seconds. float MouseDoubleClickMaxDist; // = 6.0f // Distance threshold to stay in to validate a double-click, in pixels. - float MouseDragThreshold; // = 6.0f // Distance threshold before considering we are dragging - int KeyMap[ImGuiKey_COUNT]; // // Map of indices into the KeysDown[512] entries array + float MouseDragThreshold; // = 6.0f // Distance threshold before considering we are dragging. + int KeyMap[ImGuiKey_COUNT]; // // Map of indices into the KeysDown[512] entries array which represent your "native" keyboard state. float KeyRepeatDelay; // = 0.250f // When holding a key/button, time before it starts repeating, in seconds (for buttons in Repeat mode, etc.). float KeyRepeatRate; // = 0.050f // When holding a key/button, rate at which it repeats, in seconds. void* UserData; // = NULL // Store your own data for retrieval by callbacks. @@ -936,7 +936,7 @@ struct ImGuiIO bool KeyShift; // Keyboard modifier pressed: Shift bool KeyAlt; // Keyboard modifier pressed: Alt bool KeySuper; // Keyboard modifier pressed: Cmd/Super/Windows - bool KeysDown[512]; // Keyboard keys that are pressed (in whatever storage order you naturally have access to keyboard data) + bool KeysDown[512]; // Keyboard keys that are pressed (ideally left in the "native" order your engine has access to keyboard keys, so you can use your own defines/enums for keys). ImWchar InputCharacters[16+1]; // List of characters input (translated by user from keypress+keyboard state). Fill using AddInputCharacter() helper. // Functions From 63d47e8328db78784c99685ee3b9f1e57e6a1aff Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 18 Jan 2018 17:32:34 +0100 Subject: [PATCH 884/921] Drag and Drop: Increased payload type string to 12 characters instead of 8.(#143) --- imgui.cpp | 2 +- imgui.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index bd218caf2..7b65d37af 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -11397,7 +11397,7 @@ bool ImGui::SetDragDropPayload(const char* type, const void* data, size_t data_s cond = ImGuiCond_Always; IM_ASSERT(type != NULL); - IM_ASSERT(strlen(type) < IM_ARRAYSIZE(payload.DataType)); // Payload type can be at most 8 characters longs + IM_ASSERT(strlen(type) < IM_ARRAYSIZE(payload.DataType) && "Payload type can be at most 12 characters long"); IM_ASSERT((data != NULL && data_size > 0) || (data == NULL && data_size == 0)); IM_ASSERT(cond == ImGuiCond_Always || cond == ImGuiCond_Once); IM_ASSERT(payload.SourceId != 0); // Not called between BeginDragDropSource() and EndDragDropSource() diff --git a/imgui.h b/imgui.h index c6bf05ded..33c66b454 100644 --- a/imgui.h +++ b/imgui.h @@ -429,7 +429,7 @@ namespace ImGui // Drag and Drop // [BETA API] Missing Demo code. API may evolve. IMGUI_API bool BeginDragDropSource(ImGuiDragDropFlags flags = 0, int mouse_button = 0); // call when the current item is active. If this return true, you can call SetDragDropPayload() + EndDragDropSource() - IMGUI_API bool SetDragDropPayload(const char* type, const void* data, size_t size, ImGuiCond cond = 0);// type is a user defined string of maximum 8 characters. Strings starting with '_' are reserved for dear imgui internal types. Data is copied and held by imgui. + IMGUI_API bool SetDragDropPayload(const char* type, const void* data, size_t size, ImGuiCond cond = 0);// type is a user defined string of maximum 12 characters. Strings starting with '_' are reserved for dear imgui internal types. Data is copied and held by imgui. IMGUI_API void EndDragDropSource(); // only call EndDragDropSource() if BeginDragDropSource() returns true! IMGUI_API bool BeginDragDropTarget(); // call after submitting an item that may receive an item. If this returns true, you can call AcceptDragDropPayload() + EndDragDropTarget() IMGUI_API const ImGuiPayload* AcceptDragDropPayload(const char* type, ImGuiDragDropFlags flags = 0); // accept contents of a given type. If ImGuiDragDropFlags_AcceptBeforeDelivery is set you can peek into the payload before the mouse button is released. @@ -1239,7 +1239,7 @@ struct ImGuiPayload ImGuiID SourceId; // Source item id ImGuiID SourceParentId; // Source parent id (if available) int DataFrameCount; // Data timestamp - char DataType[8 + 1]; // Data type tag (short user-supplied string) + char DataType[12 + 1]; // Data type tag (short user-supplied string, 12 characters max) bool Preview; // Set when AcceptDragDropPayload() was called and mouse has been hovering the target item (nb: handle overlapping drag targets) bool Delivery; // Set when AcceptDragDropPayload() was called and mouse button is released over the target item. From c2ffce3e5aef30d17fdc89c3afa3ee55ed9376b6 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 18 Jan 2018 17:39:40 +0100 Subject: [PATCH 885/921] Drag and Drop: Fix comment. Removed IMGUI_PAYLOAD_TYPE_DOCKABLE from master branch. (#143) --- imgui.h | 2 +- imgui_internal.h | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/imgui.h b/imgui.h index 33c66b454..f5d8eb029 100644 --- a/imgui.h +++ b/imgui.h @@ -655,7 +655,7 @@ enum ImGuiDragDropFlags_ ImGuiDragDropFlags_AcceptPeekOnly = ImGuiDragDropFlags_AcceptBeforeDelivery | ImGuiDragDropFlags_AcceptNoDrawDefaultRect // For peeking ahead and inspecting the payload before delivery. }; -// Standard Drag and Drop payload types. You can define you own payload types using 8-characters long strings. Types starting with '_' are defined by Dear ImGui. +// Standard Drag and Drop payload types. You can define you own payload types using 12-characters long strings. Types starting with '_' are defined by Dear ImGui. #define IMGUI_PAYLOAD_TYPE_COLOR_3F "_COL3F" // float[3] // Standard type for colors, without alpha. User code may use this type. #define IMGUI_PAYLOAD_TYPE_COLOR_4F "_COL4F" // float[4] // Standard type for colors. User code may use this type. diff --git a/imgui_internal.h b/imgui_internal.h index 6873a2931..4a5edfc1f 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -170,9 +170,6 @@ template void IM_DELETE(T*& p) { if (p) { p->~T(); ImGui::MemFree(p // Types //----------------------------------------------------------------------------- -// Internal Drag and Drop payload types. String starting with '_' are reserved for Dear ImGui. -#define IMGUI_PAYLOAD_TYPE_DOCKABLE "_IMDOCK" // ImGuiWindow* // [Internal] Docking/tabs - enum ImGuiButtonFlags_ { ImGuiButtonFlags_Repeat = 1 << 0, // hold to repeat From 74dc70c543107c14ddd9e635908958c90524abef Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 19 Jan 2018 09:16:26 +0100 Subject: [PATCH 886/921] DragFloat: Fix/workaround for backends which do not preserve a valid mouse position when dragged out of bounds. (#1559) --- imgui.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 7b65d37af..7dbc92c15 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3580,6 +3580,7 @@ bool ImGui::IsMousePosValid(const ImVec2* mouse_pos) return mouse_pos->x >= MOUSE_INVALID && mouse_pos->y >= MOUSE_INVALID; } +// NB: This is only valid if IsMousePosValid(). Backends in theory should always keep mouse position valid when dragging even outside the client window. ImVec2 ImGui::GetMouseDragDelta(int button, float lock_threshold) { ImGuiContext& g = *GImGui; @@ -7622,16 +7623,19 @@ bool ImGui::DragBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v_s float v_cur = g.DragCurrentValue; const ImVec2 mouse_drag_delta = GetMouseDragDelta(0, 1.0f); float adjust_delta = 0.0f; - //if (g.ActiveIdSource == ImGuiInputSource_Mouse) + if (IsMousePosValid()) { - adjust_delta = mouse_drag_delta.x - g.DragLastMouseDelta.x; - if (g.IO.KeyShift && g.DragSpeedScaleFast >= 0.0f) - adjust_delta *= g.DragSpeedScaleFast; - if (g.IO.KeyAlt && g.DragSpeedScaleSlow >= 0.0f) - adjust_delta *= g.DragSpeedScaleSlow; + //if (g.ActiveIdSource == ImGuiInputSource_Mouse) + { + adjust_delta = mouse_drag_delta.x - g.DragLastMouseDelta.x; + if (g.IO.KeyShift && g.DragSpeedScaleFast >= 0.0f) + adjust_delta *= g.DragSpeedScaleFast; + if (g.IO.KeyAlt && g.DragSpeedScaleSlow >= 0.0f) + adjust_delta *= g.DragSpeedScaleSlow; + } + g.DragLastMouseDelta.x = mouse_drag_delta.x; } adjust_delta *= v_speed; - g.DragLastMouseDelta.x = mouse_drag_delta.x; if (fabsf(adjust_delta) > 0.0f) { From ce17e0f27496ad09dcfc2ca8f605ed2494ed909d Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 19 Jan 2018 09:25:31 +0100 Subject: [PATCH 887/921] Examples: SDL: Using SDL_WINDOW_INPUT_FOCUS instead of SDL_WINDOW_MOUSE_FOCUS (which is ~~hovered). We should use SDL_CaptureMouse + SDL_WINDOW_MOUSE_CAPTURE_FLAG which requires SDL 2.0.4 will give it a try shortly. (#1559) --- examples/sdl_opengl2_example/imgui_impl_sdl.cpp | 2 +- examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl.cpp b/examples/sdl_opengl2_example/imgui_impl_sdl.cpp index 689c7ad37..205840b6e 100644 --- a/examples/sdl_opengl2_example/imgui_impl_sdl.cpp +++ b/examples/sdl_opengl2_example/imgui_impl_sdl.cpp @@ -274,7 +274,7 @@ void ImGui_ImplSdlGL2_NewFrame(SDL_Window *window) // (we already got mouse wheel, keyboard keys & characters from SDL_PollEvent()) int mx, my; Uint32 mouseMask = SDL_GetMouseState(&mx, &my); - if (SDL_GetWindowFlags(window) & SDL_WINDOW_MOUSE_FOCUS) + if (SDL_GetWindowFlags(window) & SDL_WINDOW_INPUT_FOCUS) io.MousePos = ImVec2((float)mx, (float)my); else io.MousePos = ImVec2(-FLT_MAX,-FLT_MAX); diff --git a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp index b16a0300c..037f07239 100644 --- a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp +++ b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp @@ -385,7 +385,7 @@ void ImGui_ImplSdlGL3_NewFrame(SDL_Window* window) // (we already got mouse wheel, keyboard keys & characters from SDL_PollEvent()) int mx, my; Uint32 mouseMask = SDL_GetMouseState(&mx, &my); - if (SDL_GetWindowFlags(window) & SDL_WINDOW_MOUSE_FOCUS) + if (SDL_GetWindowFlags(window) & SDL_WINDOW_INPUT_FOCUS) io.MousePos = ImVec2((float)mx, (float)my); else io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); From 15fd5b6c4c77e8f168d854118dd80d7a49808410 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 19 Jan 2018 09:43:28 +0100 Subject: [PATCH 888/921] Examples: SDL: Minor renaming. --- examples/sdl_opengl2_example/imgui_impl_sdl.cpp | 8 ++++---- examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl.cpp b/examples/sdl_opengl2_example/imgui_impl_sdl.cpp index 205840b6e..263017dcb 100644 --- a/examples/sdl_opengl2_example/imgui_impl_sdl.cpp +++ b/examples/sdl_opengl2_example/imgui_impl_sdl.cpp @@ -273,15 +273,15 @@ void ImGui_ImplSdlGL2_NewFrame(SDL_Window *window) // Setup inputs // (we already got mouse wheel, keyboard keys & characters from SDL_PollEvent()) int mx, my; - Uint32 mouseMask = SDL_GetMouseState(&mx, &my); + Uint32 mouse_buttons = SDL_GetMouseState(&mx, &my); if (SDL_GetWindowFlags(window) & SDL_WINDOW_INPUT_FOCUS) io.MousePos = ImVec2((float)mx, (float)my); else io.MousePos = ImVec2(-FLT_MAX,-FLT_MAX); - io.MouseDown[0] = g_MousePressed[0] || (mouseMask & SDL_BUTTON(SDL_BUTTON_LEFT)) != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. - io.MouseDown[1] = g_MousePressed[1] || (mouseMask & SDL_BUTTON(SDL_BUTTON_RIGHT)) != 0; - io.MouseDown[2] = g_MousePressed[2] || (mouseMask & SDL_BUTTON(SDL_BUTTON_MIDDLE)) != 0; + io.MouseDown[0] = g_MousePressed[0] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_LEFT)) != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. + io.MouseDown[1] = g_MousePressed[1] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_RIGHT)) != 0; + io.MouseDown[2] = g_MousePressed[2] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_MIDDLE)) != 0; g_MousePressed[0] = g_MousePressed[1] = g_MousePressed[2] = false; io.MouseWheel = g_MouseWheel; diff --git a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp index 037f07239..e9a1393cd 100644 --- a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp +++ b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp @@ -384,15 +384,15 @@ void ImGui_ImplSdlGL3_NewFrame(SDL_Window* window) // Setup inputs // (we already got mouse wheel, keyboard keys & characters from SDL_PollEvent()) int mx, my; - Uint32 mouseMask = SDL_GetMouseState(&mx, &my); + Uint32 mouse_buttons = SDL_GetMouseState(&mx, &my); if (SDL_GetWindowFlags(window) & SDL_WINDOW_INPUT_FOCUS) io.MousePos = ImVec2((float)mx, (float)my); else io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); - io.MouseDown[0] = g_MousePressed[0] || (mouseMask & SDL_BUTTON(SDL_BUTTON_LEFT)) != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. - io.MouseDown[1] = g_MousePressed[1] || (mouseMask & SDL_BUTTON(SDL_BUTTON_RIGHT)) != 0; - io.MouseDown[2] = g_MousePressed[2] || (mouseMask & SDL_BUTTON(SDL_BUTTON_MIDDLE)) != 0; + io.MouseDown[0] = g_MousePressed[0] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_LEFT)) != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. + io.MouseDown[1] = g_MousePressed[1] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_RIGHT)) != 0; + io.MouseDown[2] = g_MousePressed[2] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_MIDDLE)) != 0; g_MousePressed[0] = g_MousePressed[1] = g_MousePressed[2] = false; io.MouseWheel = g_MouseWheel; From 79dca9d5e6f127f6dd236ca7146f28b55550489f Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 19 Jan 2018 09:45:27 +0100 Subject: [PATCH 889/921] Examples: SDL+GL2: Renamed imgui_impl_sdl.* to imgui_impl_sdl_gl2.* for consistency and to emphasis on GL2-ness. --- examples/sdl_opengl2_example/build_win32.bat | 2 +- .../{imgui_impl_sdl.cpp => imgui_impl_sdl_gl2.cpp} | 6 +++--- .../{imgui_impl_sdl.h => imgui_impl_sdl_gl2.h} | 0 examples/sdl_opengl2_example/main.cpp | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) rename examples/sdl_opengl2_example/{imgui_impl_sdl.cpp => imgui_impl_sdl_gl2.cpp} (97%) rename examples/sdl_opengl2_example/{imgui_impl_sdl.h => imgui_impl_sdl_gl2.h} (100%) diff --git a/examples/sdl_opengl2_example/build_win32.bat b/examples/sdl_opengl2_example/build_win32.bat index 3cf81e60a..799561dec 100644 --- a/examples/sdl_opengl2_example/build_win32.bat +++ b/examples/sdl_opengl2_example/build_win32.bat @@ -1,3 +1,3 @@ @REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. mkdir Debug -cl /nologo /Zi /MD /I ..\.. /I ..\libs\gl3w /I %SDL_DIR%\include main.cpp imgui_impl_sdl.cpp ..\..\imgui*.cpp ..\libs\gl3w\GL\gl3w.c /FeDebug/sdl_opengl2_example.exe /FoDebug/ /link /libpath:%SDL_DIR%\lib\x86 SDL2.lib SDL2main.lib opengl32.lib /subsystem:console +cl /nologo /Zi /MD /I ..\.. /I ..\libs\gl3w /I %SDL_DIR%\include main.cpp imgui_impl_sdl_gl2.cpp ..\..\imgui*.cpp ..\libs\gl3w\GL\gl3w.c /FeDebug/sdl_opengl2_example.exe /FoDebug/ /link /libpath:%SDL_DIR%\lib\x86 SDL2.lib SDL2main.lib opengl32.lib /subsystem:console diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl.cpp b/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp similarity index 97% rename from examples/sdl_opengl2_example/imgui_impl_sdl.cpp rename to examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp index 263017dcb..154a6d238 100644 --- a/examples/sdl_opengl2_example/imgui_impl_sdl.cpp +++ b/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp @@ -19,7 +19,7 @@ #include #include #include -#include "imgui_impl_sdl.h" +#include "imgui_impl_sdl_gl2.h" // Data static double g_Time = 0.0f; @@ -30,7 +30,7 @@ static GLuint g_FontTexture = 0; // This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) // Note that this implementation is little overcomplicated because we are saving/setting up/restoring every OpenGL state explicitly, in order to be able to run within any OpenGL engine that doesn't do so. // If text or lines are blurry when integrating ImGui in your engine: in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) -void ImGui_ImplSdl_RenderDrawLists(ImDrawData* draw_data) +void ImGui_ImplSdlGL2_RenderDrawLists(ImDrawData* draw_data) { // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) ImGuiIO& io = ImGui::GetIO(); @@ -226,7 +226,7 @@ bool ImGui_ImplSdlGL2_Init(SDL_Window* window) io.KeyMap[ImGuiKey_Y] = SDLK_y; io.KeyMap[ImGuiKey_Z] = SDLK_z; - io.RenderDrawListsFn = ImGui_ImplSdl_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. + io.RenderDrawListsFn = ImGui_ImplSdlGL2_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. io.SetClipboardTextFn = ImGui_ImplSdl_SetClipboardText; io.GetClipboardTextFn = ImGui_ImplSdl_GetClipboardText; io.ClipboardUserData = NULL; diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl.h b/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.h similarity index 100% rename from examples/sdl_opengl2_example/imgui_impl_sdl.h rename to examples/sdl_opengl2_example/imgui_impl_sdl_gl2.h diff --git a/examples/sdl_opengl2_example/main.cpp b/examples/sdl_opengl2_example/main.cpp index 1396fcca0..21b567a83 100644 --- a/examples/sdl_opengl2_example/main.cpp +++ b/examples/sdl_opengl2_example/main.cpp @@ -7,7 +7,7 @@ // See imgui_impl_sdl.cpp for details. #include -#include "imgui_impl_sdl.h" +#include "imgui_impl_sdl_gl2.h" #include #include #include From ba99900023000e6c7bb6001100744549f869f53b Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 19 Jan 2018 09:48:23 +0100 Subject: [PATCH 890/921] Examples: GLFW+GL2: Renamed imgui_impl_glfw.* to imgui_impl_glfw_gl2.* for consistency and to emphasis on GL2-ness. --- examples/opengl2_example/Makefile | 2 +- .../{imgui_impl_glfw.cpp => imgui_impl_glfw_gl2.cpp} | 2 +- .../{imgui_impl_glfw.h => imgui_impl_glfw_gl2.h} | 0 examples/opengl2_example/main.cpp | 2 +- examples/opengl2_example/opengl2_example.vcxproj | 4 ++-- examples/opengl2_example/opengl2_example.vcxproj.filters | 4 ++-- 6 files changed, 7 insertions(+), 7 deletions(-) rename examples/opengl2_example/{imgui_impl_glfw.cpp => imgui_impl_glfw_gl2.cpp} (99%) rename examples/opengl2_example/{imgui_impl_glfw.h => imgui_impl_glfw_gl2.h} (100%) diff --git a/examples/opengl2_example/Makefile b/examples/opengl2_example/Makefile index 932aebede..f10c59a8d 100644 --- a/examples/opengl2_example/Makefile +++ b/examples/opengl2_example/Makefile @@ -11,7 +11,7 @@ #CXX = g++ EXE = opengl2_example -OBJS = main.o imgui_impl_glfw.o +OBJS = main.o imgui_impl_glfw_gl2.o OBJS += ../../imgui.o ../../imgui_demo.o ../../imgui_draw.o UNAME_S := $(shell uname -s) diff --git a/examples/opengl2_example/imgui_impl_glfw.cpp b/examples/opengl2_example/imgui_impl_glfw_gl2.cpp similarity index 99% rename from examples/opengl2_example/imgui_impl_glfw.cpp rename to examples/opengl2_example/imgui_impl_glfw_gl2.cpp index d2eb657f6..4ce831d9b 100644 --- a/examples/opengl2_example/imgui_impl_glfw.cpp +++ b/examples/opengl2_example/imgui_impl_glfw_gl2.cpp @@ -16,7 +16,7 @@ // https://github.com/ocornut/imgui #include -#include "imgui_impl_glfw.h" +#include "imgui_impl_glfw_gl2.h" // GLFW #include diff --git a/examples/opengl2_example/imgui_impl_glfw.h b/examples/opengl2_example/imgui_impl_glfw_gl2.h similarity index 100% rename from examples/opengl2_example/imgui_impl_glfw.h rename to examples/opengl2_example/imgui_impl_glfw_gl2.h diff --git a/examples/opengl2_example/main.cpp b/examples/opengl2_example/main.cpp index ef098e54a..6359f5b62 100644 --- a/examples/opengl2_example/main.cpp +++ b/examples/opengl2_example/main.cpp @@ -7,7 +7,7 @@ // See imgui_impl_glfw.cpp for details. #include -#include "imgui_impl_glfw.h" +#include "imgui_impl_glfw_gl2.h" #include #include diff --git a/examples/opengl2_example/opengl2_example.vcxproj b/examples/opengl2_example/opengl2_example.vcxproj index a6cbebd63..237eba7da 100644 --- a/examples/opengl2_example/opengl2_example.vcxproj +++ b/examples/opengl2_example/opengl2_example.vcxproj @@ -153,14 +153,14 @@ - + - + diff --git a/examples/opengl2_example/opengl2_example.vcxproj.filters b/examples/opengl2_example/opengl2_example.vcxproj.filters index f2282bf69..3cc7ee9e1 100644 --- a/examples/opengl2_example/opengl2_example.vcxproj.filters +++ b/examples/opengl2_example/opengl2_example.vcxproj.filters @@ -16,7 +16,7 @@ imgui - + sources @@ -33,7 +33,7 @@ imgui - + sources From 00351ee2ab7562e07aaec70c3923a58385b6f760 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 19 Jan 2018 09:53:55 +0100 Subject: [PATCH 891/921] Examples: SDL: Minor renaming. --- examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp b/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp index 154a6d238..802a31be6 100644 --- a/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp +++ b/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp @@ -111,12 +111,12 @@ void ImGui_ImplSdlGL2_RenderDrawLists(ImDrawData* draw_data) glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], (GLsizei)last_scissor_box[3]); } -static const char* ImGui_ImplSdl_GetClipboardText(void*) +static const char* ImGui_ImplSdlGL2_GetClipboardText(void*) { return SDL_GetClipboardText(); } -static void ImGui_ImplSdl_SetClipboardText(void*, const char* text) +static void ImGui_ImplSdlGL2_SetClipboardText(void*, const char* text) { SDL_SetClipboardText(text); } @@ -227,8 +227,8 @@ bool ImGui_ImplSdlGL2_Init(SDL_Window* window) io.KeyMap[ImGuiKey_Z] = SDLK_z; io.RenderDrawListsFn = ImGui_ImplSdlGL2_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. - io.SetClipboardTextFn = ImGui_ImplSdl_SetClipboardText; - io.GetClipboardTextFn = ImGui_ImplSdl_GetClipboardText; + io.SetClipboardTextFn = ImGui_ImplSdlGL2_SetClipboardText; + io.GetClipboardTextFn = ImGui_ImplSdlGL2_GetClipboardText; io.ClipboardUserData = NULL; #ifdef _WIN32 @@ -267,7 +267,7 @@ void ImGui_ImplSdlGL2_NewFrame(SDL_Window *window) // Setup time step Uint32 time = SDL_GetTicks(); double current_time = time / 1000.0; - io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f); + io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f / 60.0f); g_Time = current_time; // Setup inputs From f3e510a9bf508337244433f8c1dcc6c120dcc990 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 19 Jan 2018 10:46:54 +0100 Subject: [PATCH 892/921] Examples: SDL: Using SDL_CaptureMouse() to retrieve coordinates outside of client area when dragging. (#1559) Digging into sdl window/mouse stuff will also be useful for multi-viewport work. --- .../imgui_impl_sdl_gl2.cpp | 28 +++++++++++------ .../imgui_impl_sdl_gl3.cpp | 30 ++++++++++++------- 2 files changed, 39 insertions(+), 19 deletions(-) diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp b/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp index 802a31be6..6bcd4c388 100644 --- a/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp +++ b/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp @@ -270,23 +270,33 @@ void ImGui_ImplSdlGL2_NewFrame(SDL_Window *window) io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f / 60.0f); g_Time = current_time; - // Setup inputs - // (we already got mouse wheel, keyboard keys & characters from SDL_PollEvent()) + // Setup mouse inputs (we already got mouse wheel, keyboard keys & characters from our event handler) int mx, my; Uint32 mouse_buttons = SDL_GetMouseState(&mx, &my); - if (SDL_GetWindowFlags(window) & SDL_WINDOW_INPUT_FOCUS) - io.MousePos = ImVec2((float)mx, (float)my); - else - io.MousePos = ImVec2(-FLT_MAX,-FLT_MAX); - + io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); + io.MouseWheel = g_MouseWheel; io.MouseDown[0] = g_MousePressed[0] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_LEFT)) != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. io.MouseDown[1] = g_MousePressed[1] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_RIGHT)) != 0; io.MouseDown[2] = g_MousePressed[2] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_MIDDLE)) != 0; g_MousePressed[0] = g_MousePressed[1] = g_MousePressed[2] = false; - - io.MouseWheel = g_MouseWheel; g_MouseWheel = 0.0f; + // We need to use SDL_CaptureMouse() to easily retrieve mouse coordinates outside of the client area. This is only supported from SDL 2.0.4 (released Jan 2016) +#if (SDL_MAJOR_VERSION >= 2) && (SDL_MINOR_VERSION >= 0) && (SDL_PATCHLEVEL >= 4) + if ((SDL_GetWindowFlags(window) & (SDL_WINDOW_MOUSE_FOCUS | SDL_WINDOW_MOUSE_CAPTURE)) != 0) + io.MousePos = ImVec2((float)mx, (float)my); + bool any_mouse_button_down = false; + for (int n = 0; n < IM_ARRAYSIZE(io.MouseDown); n++) + any_mouse_button_down |= io.MouseDown[n]; + if (any_mouse_button_down && (SDL_GetWindowFlags(window) & SDL_WINDOW_MOUSE_CAPTURE) == 0) + SDL_CaptureMouse(SDL_TRUE); + if (!any_mouse_button_down && (SDL_GetWindowFlags(window) & SDL_WINDOW_MOUSE_CAPTURE) != 0) + SDL_CaptureMouse(SDL_FALSE); +#else + if ((SDL_GetWindowFlags(window) & SDL_WINDOW_INPUT_FOCUS) != 0) + io.MousePos = ImVec2((float)mx, (float)my); +#endif + // Hide OS mouse cursor if ImGui is drawing it SDL_ShowCursor(io.MouseDrawCursor ? 0 : 1); diff --git a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp index e9a1393cd..ef1957a5d 100644 --- a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp +++ b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp @@ -381,23 +381,33 @@ void ImGui_ImplSdlGL3_NewFrame(SDL_Window* window) io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f / 60.0f); g_Time = current_time; - // Setup inputs - // (we already got mouse wheel, keyboard keys & characters from SDL_PollEvent()) + // Setup mouse inputs (we already got mouse wheel, keyboard keys & characters from our event handler) int mx, my; Uint32 mouse_buttons = SDL_GetMouseState(&mx, &my); - if (SDL_GetWindowFlags(window) & SDL_WINDOW_INPUT_FOCUS) - io.MousePos = ImVec2((float)mx, (float)my); - else - io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); - - io.MouseDown[0] = g_MousePressed[0] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_LEFT)) != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. + io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); + io.MouseWheel = g_MouseWheel; + io.MouseDown[0] = g_MousePressed[0] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_LEFT)) != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. io.MouseDown[1] = g_MousePressed[1] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_RIGHT)) != 0; io.MouseDown[2] = g_MousePressed[2] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_MIDDLE)) != 0; g_MousePressed[0] = g_MousePressed[1] = g_MousePressed[2] = false; - - io.MouseWheel = g_MouseWheel; g_MouseWheel = 0.0f; + // We need to use SDL_CaptureMouse() to easily retrieve mouse coordinates outside of the client area. This is only supported from SDL 2.0.4 (released Jan 2016) +#if (SDL_MAJOR_VERSION >= 2) && (SDL_MINOR_VERSION >= 0) && (SDL_PATCHLEVEL >= 4) + if ((SDL_GetWindowFlags(window) & (SDL_WINDOW_MOUSE_FOCUS | SDL_WINDOW_MOUSE_CAPTURE)) != 0) + io.MousePos = ImVec2((float)mx, (float)my); + bool any_mouse_button_down = false; + for (int n = 0; n < IM_ARRAYSIZE(io.MouseDown); n++) + any_mouse_button_down |= io.MouseDown[n]; + if (any_mouse_button_down && (SDL_GetWindowFlags(window) & SDL_WINDOW_MOUSE_CAPTURE) == 0) + SDL_CaptureMouse(SDL_TRUE); + if (!any_mouse_button_down && (SDL_GetWindowFlags(window) & SDL_WINDOW_MOUSE_CAPTURE) != 0) + SDL_CaptureMouse(SDL_FALSE); +#else + if ((SDL_GetWindowFlags(window) & SDL_WINDOW_INPUT_FOCUS) != 0) + io.MousePos = ImVec2((float)mx, (float)my); +#endif + // Hide OS mouse cursor if ImGui is drawing it SDL_ShowCursor(io.MouseDrawCursor ? 0 : 1); From 0978f00911df253196b0a013b77adc4c8202fdcb Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 19 Jan 2018 15:06:39 +0100 Subject: [PATCH 893/921] MovingWindow: Track click offset based on root window (undo 514d30d8cdd659b6af3c93512583a00ee18ecbaf). This should not affect the patch used for #1345 as the RootWindow for Child+Tooltip window points to itself now. --- imgui.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 7dbc92c15..41ce93da7 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2393,11 +2393,8 @@ void ImGui::NewFrame() if (g.IO.MouseDown[0]) { // MovingWindow = window we clicked on, could be a child window. We track it to preserve Focus and so that ActiveIdWindow == MovingWindow and ActiveId == MovingWindow->MoveId for consistency. - // actually_moving_window = MovingWindow->RootWindow. ImGuiWindow* actually_moving_window = g.MovingWindow->RootWindow; ImVec2 pos = g.IO.MousePos - g.ActiveIdClickOffset; - if (actually_moving_window != g.MovingWindow) - pos += actually_moving_window->PosFloat - g.MovingWindow->PosFloat; if (actually_moving_window->PosFloat.x != pos.x || actually_moving_window->PosFloat.y != pos.y) { MarkIniSettingsDirty(actually_moving_window); @@ -2979,7 +2976,7 @@ void ImGui::EndFrame() // Set ActiveId even if the _NoMove flag is set, without it dragging away from a window with _NoMove would activate hover on other windows. FocusWindow(g.HoveredWindow); SetActiveID(g.HoveredWindow->MoveId, g.HoveredWindow); - g.ActiveIdClickOffset = g.IO.MousePos - g.HoveredWindow->Pos; + g.ActiveIdClickOffset = g.IO.MousePos - g.HoveredRootWindow->Pos; if (!(g.HoveredWindow->Flags & ImGuiWindowFlags_NoMove) && !(g.HoveredRootWindow->Flags & ImGuiWindowFlags_NoMove)) { g.MovingWindow = g.HoveredWindow; From 42a612d7c9fa69fc87e0fd37eef800e7b875add1 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 19 Jan 2018 15:33:35 +0100 Subject: [PATCH 894/921] Begin: Removed asserts that got in the way of some flags combination. (#1345) --- imgui.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 41ce93da7..b38120bde 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4649,12 +4649,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // Apply minimum/maximum window size constraints and final size window->SizeFull = CalcSizeAfterConstraint(window, window->SizeFull); - window->Size = window->Collapsed ? window->TitleBarRect().GetSize() : window->SizeFull; - if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Popup)) - { - IM_ASSERT(window_size_x_set_by_api && window_size_y_set_by_api); // Submitted by BeginChild() - window->Size = window->SizeFull; - } + window->Size = window->Collapsed && !(flags & ImGuiWindowFlags_ChildWindow) ? window->TitleBarRect().GetSize() : window->SizeFull; // SCROLLBAR STATUS From e5a6e85f6d24da8506f8141f258c9f4f0c9d3281 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 19 Jan 2018 15:37:25 +0100 Subject: [PATCH 895/921] Basic undocumented/unsupported combination of Child+Tooltip. The full feature needs substancially more work but this is enough for simplest cases. (#1345) --- imgui.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index b38120bde..ca142754d 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4560,10 +4560,12 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // When reusing window again multiple times a frame, just append content (don't need to setup again) if (first_begin_of_the_frame) { + const bool is_pinned_child_tooltip = (flags & ImGuiWindowFlags_ChildWindow) && (flags & ImGuiWindowFlags_Tooltip); // FIXME-WIP: Undocumented behavior of Child+Tooltip for pinned tooltip (#1345) + // Initialize window->ParentWindow = parent_window; window->RootWindow = window->RootNonPopupWindow = window; - if (parent_window && (flags & ImGuiWindowFlags_ChildWindow)) + if (parent_window && (flags & ImGuiWindowFlags_ChildWindow) && !is_pinned_child_tooltip) window->RootWindow = parent_window->RootWindow; if (parent_window && !(flags & ImGuiWindowFlags_Modal) && (flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_Popup))) window->RootNonPopupWindow = parent_window->RootNonPopupWindow; @@ -4681,8 +4683,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) { window->BeginOrderWithinParent = parent_window->DC.ChildWindows.Size; parent_window->DC.ChildWindows.push_back(window); - - if (!(flags & ImGuiWindowFlags_Popup) && !window_pos_set_by_api) + if (!(flags & ImGuiWindowFlags_Popup) && !window_pos_set_by_api && !is_pinned_child_tooltip) window->Pos = window->PosFloat = parent_window->DC.CursorPos; } @@ -4713,7 +4714,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) } // Position tooltip (always follows mouse) - if ((flags & ImGuiWindowFlags_Tooltip) != 0 && !window_pos_set_by_api) + if ((flags & ImGuiWindowFlags_Tooltip) != 0 && !window_pos_set_by_api && !is_pinned_child_tooltip) { ImVec2 ref_pos = g.IO.MousePos; ImRect rect_to_avoid(ref_pos.x - 16, ref_pos.y - 8, ref_pos.x + 24, ref_pos.y + 24); // FIXME: Completely hard-coded. Store boxes in mouse cursor data? Scale? Center on cursor hit-point? @@ -4771,7 +4772,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->DrawList->Flags = (g.Style.AntiAliasedLines ? ImDrawListFlags_AntiAliasedLines : 0) | (g.Style.AntiAliasedFill ? ImDrawListFlags_AntiAliasedFill : 0); window->DrawList->PushTextureID(g.Font->ContainerAtlas->TexID); ImRect fullscreen_rect(GetVisibleRect()); - if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Popup)) + if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Popup) && !is_pinned_child_tooltip) PushClipRect(parent_window->ClipRect.Min, parent_window->ClipRect.Max, true); else PushClipRect(fullscreen_rect.Min, fullscreen_rect.Max, true); From d4bf9b46863be00c7c968051430d6c5b429a04f7 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 19 Jan 2018 15:47:10 +0100 Subject: [PATCH 896/921] Renaming for consistency. --- imgui.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index ca142754d..9205dac6a 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4560,12 +4560,12 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // When reusing window again multiple times a frame, just append content (don't need to setup again) if (first_begin_of_the_frame) { - const bool is_pinned_child_tooltip = (flags & ImGuiWindowFlags_ChildWindow) && (flags & ImGuiWindowFlags_Tooltip); // FIXME-WIP: Undocumented behavior of Child+Tooltip for pinned tooltip (#1345) + const bool window_is_child_tooltip = (flags & ImGuiWindowFlags_ChildWindow) && (flags & ImGuiWindowFlags_Tooltip); // FIXME-WIP: Undocumented behavior of Child+Tooltip for pinned tooltip (#1345) // Initialize window->ParentWindow = parent_window; window->RootWindow = window->RootNonPopupWindow = window; - if (parent_window && (flags & ImGuiWindowFlags_ChildWindow) && !is_pinned_child_tooltip) + if (parent_window && (flags & ImGuiWindowFlags_ChildWindow) && !window_is_child_tooltip) window->RootWindow = parent_window->RootWindow; if (parent_window && !(flags & ImGuiWindowFlags_Modal) && (flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_Popup))) window->RootNonPopupWindow = parent_window->RootNonPopupWindow; @@ -4683,7 +4683,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) { window->BeginOrderWithinParent = parent_window->DC.ChildWindows.Size; parent_window->DC.ChildWindows.push_back(window); - if (!(flags & ImGuiWindowFlags_Popup) && !window_pos_set_by_api && !is_pinned_child_tooltip) + if (!(flags & ImGuiWindowFlags_Popup) && !window_pos_set_by_api && !window_is_child_tooltip) window->Pos = window->PosFloat = parent_window->DC.CursorPos; } @@ -4714,7 +4714,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) } // Position tooltip (always follows mouse) - if ((flags & ImGuiWindowFlags_Tooltip) != 0 && !window_pos_set_by_api && !is_pinned_child_tooltip) + if ((flags & ImGuiWindowFlags_Tooltip) != 0 && !window_pos_set_by_api && !window_is_child_tooltip) { ImVec2 ref_pos = g.IO.MousePos; ImRect rect_to_avoid(ref_pos.x - 16, ref_pos.y - 8, ref_pos.x + 24, ref_pos.y + 24); // FIXME: Completely hard-coded. Store boxes in mouse cursor data? Scale? Center on cursor hit-point? @@ -4772,7 +4772,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->DrawList->Flags = (g.Style.AntiAliasedLines ? ImDrawListFlags_AntiAliasedLines : 0) | (g.Style.AntiAliasedFill ? ImDrawListFlags_AntiAliasedFill : 0); window->DrawList->PushTextureID(g.Font->ContainerAtlas->TexID); ImRect fullscreen_rect(GetVisibleRect()); - if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Popup) && !is_pinned_child_tooltip) + if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Popup) && !window_is_child_tooltip) PushClipRect(parent_window->ClipRect.Min, parent_window->ClipRect.Max, true); else PushClipRect(fullscreen_rect.Min, fullscreen_rect.Max, true); From 0b1fecb792ffe00313b43a01f4dadb41e69850e7 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 20 Jan 2018 12:36:16 +0100 Subject: [PATCH 897/921] Horizontal mouse wheel: renamed io.MouseHorizWheel to io.MouseWheelH. Reorganized the code in NewFrame(). Examples: Updated GLFW+GL and SDL+GL accordingly. (#1463) --- .../opengl2_example/imgui_impl_glfw_gl2.cpp | 13 ++-- .../opengl3_example/imgui_impl_glfw_gl3.cpp | 13 ++-- .../imgui_impl_sdl_gl2.cpp | 21 +++---- .../imgui_impl_sdl_gl3.cpp | 21 +++---- imgui.cpp | 60 +++++++++---------- imgui.h | 4 +- 6 files changed, 59 insertions(+), 73 deletions(-) diff --git a/examples/opengl2_example/imgui_impl_glfw_gl2.cpp b/examples/opengl2_example/imgui_impl_glfw_gl2.cpp index 2b7efc146..8dcd71e9f 100644 --- a/examples/opengl2_example/imgui_impl_glfw_gl2.cpp +++ b/examples/opengl2_example/imgui_impl_glfw_gl2.cpp @@ -31,8 +31,7 @@ static GLFWwindow* g_Window = NULL; static double g_Time = 0.0f; static bool g_MouseJustPressed[3] = { false, false, false }; -static float g_MouseHorizWheel = 0.0f; -static float g_MouseWheel = 0.0f; +static ImVec2 g_MouseWheel = ImVec2(0.0f, 0.0f); static GLuint g_FontTexture = 0; // This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) @@ -137,8 +136,8 @@ void ImGui_ImplGlfwGL2_MouseButtonCallback(GLFWwindow*, int button, int action, void ImGui_ImplGlfwGL2_ScrollCallback(GLFWwindow*, double xoffset, double yoffset) { - g_MouseHorizWheel += (float)xoffset; // Use fractional mouse wheel. - g_MouseWheel += (float)yoffset; + g_MouseWheel.x += (float)xoffset; // Use fractional mouse wheel. + g_MouseWheel.y += (float)yoffset; } void ImGui_ImplGlfwGL2_KeyCallback(GLFWwindow*, int key, int, int action, int mods) @@ -297,9 +296,9 @@ void ImGui_ImplGlfwGL2_NewFrame() g_MouseJustPressed[i] = false; } - io.MouseHorizWheel = g_MouseHorizWheel; - io.MouseWheel = g_MouseWheel; - g_MouseHorizWheel = g_MouseWheel = 0.0f; + io.MouseWheel = g_MouseWheel.y; + io.MouseWheelH = g_MouseWheel.x; + g_MouseWheel.x = g_MouseWheel.x = 0.0f; // Hide OS mouse cursor if ImGui is drawing it glfwSetInputMode(g_Window, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL); diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp index 8808d8bb1..79a62531f 100644 --- a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp +++ b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp @@ -25,8 +25,7 @@ static GLFWwindow* g_Window = NULL; static double g_Time = 0.0f; static bool g_MouseJustPressed[3] = { false, false, false }; -static float g_MouseHorizWheel = 0.0f; -static float g_MouseWheel = 0.0f; +static ImVec2 g_MouseWheel = ImVec2(0.0f, 0.0f); static GLuint g_FontTexture = 0; static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; @@ -158,8 +157,8 @@ void ImGui_ImplGlfwGL3_MouseButtonCallback(GLFWwindow*, int button, int action, void ImGui_ImplGlfwGL3_ScrollCallback(GLFWwindow*, double xoffset, double yoffset) { - g_MouseHorizWheel += (float)xoffset; // Use fractional mouse wheel. - g_MouseWheel += (float)yoffset; + g_MouseWheel.x += (float)xoffset; // Use fractional mouse wheel. + g_MouseWheel.y += (float)yoffset; } void ImGui_ImplGlfwGL3_KeyCallback(GLFWwindow*, int key, int, int action, int mods) @@ -409,9 +408,9 @@ void ImGui_ImplGlfwGL3_NewFrame() g_MouseJustPressed[i] = false; } - io.MouseHorizWheel = g_MouseHorizWheel; - io.MouseWheel = g_MouseWheel; - g_MouseHorizWheel = g_MouseWheel = 0.0f; + io.MouseWheel = g_MouseWheel.y; + io.MouseWheelH = g_MouseWheel.x; + g_MouseWheel.x = g_MouseWheel.x = 0.0f; // Hide OS mouse cursor if ImGui is drawing it glfwSetInputMode(g_Window, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL); diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp b/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp index e1adbe86a..d55af2b7f 100644 --- a/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp +++ b/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp @@ -24,8 +24,7 @@ // Data static double g_Time = 0.0f; static bool g_MousePressed[3] = { false, false, false }; -static float g_MouseHorizWheel = 0.0f; -static float g_MouseWheel = 0.0f; +static ImVec2 g_MouseWheel = ImVec2(0.0f, 0.0f); static GLuint g_FontTexture = 0; // This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) @@ -133,14 +132,10 @@ bool ImGui_ImplSdlGL2_ProcessEvent(SDL_Event* event) { case SDL_MOUSEWHEEL: { - if (event->wheel.x > 0) - g_MouseHorizWheel = 1; - if (event->wheel.x < 0) - g_MouseHorizWheel = -1; - if (event->wheel.y > 0) - g_MouseWheel = 1; - if (event->wheel.y < 0) - g_MouseWheel = -1; + if (event->wheel.x > 0) g_MouseWheel.x = +1; + if (event->wheel.x < 0) g_MouseWheel.x = -1; + if (event->wheel.y > 0) g_MouseWheel.y = +1; + if (event->wheel.y < 0) g_MouseWheel.y = -1; return true; } case SDL_MOUSEBUTTONDOWN: @@ -279,13 +274,13 @@ void ImGui_ImplSdlGL2_NewFrame(SDL_Window *window) int mx, my; Uint32 mouse_buttons = SDL_GetMouseState(&mx, &my); io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); - io.MouseWheel = g_MouseWheel; - io.MouseHorizWheel = g_MouseHorizWheel; + io.MouseWheel = g_MouseWheel.y; + io.MouseWheelH = g_MouseWheel.x; io.MouseDown[0] = g_MousePressed[0] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_LEFT)) != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. io.MouseDown[1] = g_MousePressed[1] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_RIGHT)) != 0; io.MouseDown[2] = g_MousePressed[2] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_MIDDLE)) != 0; g_MousePressed[0] = g_MousePressed[1] = g_MousePressed[2] = false; - g_MouseWheel = g_MouseHorizWheel = 0.0f; + g_MouseWheel.x = g_MouseWheel.x = 0.0f; // We need to use SDL_CaptureMouse() to easily retrieve mouse coordinates outside of the client area. This is only supported from SDL 2.0.4 (released Jan 2016) #if (SDL_MAJOR_VERSION >= 2) && (SDL_MINOR_VERSION >= 0) && (SDL_PATCHLEVEL >= 4) diff --git a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp index 264ac64b0..0a07cd082 100644 --- a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp +++ b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp @@ -19,8 +19,7 @@ // Data static double g_Time = 0.0f; static bool g_MousePressed[3] = { false, false, false }; -static float g_MouseHorizWheel = 0.0f; -static float g_MouseWheel = 0.0f; +static ImVec2 g_MouseWheel = ImVec2(0.0f, 0.0f); static GLuint g_FontTexture = 0; static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; @@ -155,14 +154,10 @@ bool ImGui_ImplSdlGL3_ProcessEvent(SDL_Event* event) { case SDL_MOUSEWHEEL: { - if (event->wheel.x > 0) - g_MouseHorizWheel = 1; - if (event->wheel.x < 0) - g_MouseHorizWheel = -1; - if (event->wheel.y > 0) - g_MouseWheel = 1; - if (event->wheel.y < 0) - g_MouseWheel = -1; + if (event->wheel.x > 0) g_MouseWheel.x = +1; + if (event->wheel.x < 0) g_MouseWheel.x = -1; + if (event->wheel.y > 0) g_MouseWheel.y = +1; + if (event->wheel.y < 0) g_MouseWheel.y = -1; return true; } case SDL_MOUSEBUTTONDOWN: @@ -390,13 +385,13 @@ void ImGui_ImplSdlGL3_NewFrame(SDL_Window* window) int mx, my; Uint32 mouse_buttons = SDL_GetMouseState(&mx, &my); io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); - io.MouseWheel = g_MouseWheel; - io.MouseHorizWheel = g_MouseHorizWheel; + io.MouseWheel = g_MouseWheel.y; + io.MouseWheelH = g_MouseWheel.x; io.MouseDown[0] = g_MousePressed[0] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_LEFT)) != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. io.MouseDown[1] = g_MousePressed[1] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_RIGHT)) != 0; io.MouseDown[2] = g_MousePressed[2] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_MIDDLE)) != 0; g_MousePressed[0] = g_MousePressed[1] = g_MousePressed[2] = false; - g_MouseHorizWheel = g_MouseWheel = 0.0f; + g_MouseWheel.x = g_MouseWheel.x = 0.0f; // We need to use SDL_CaptureMouse() to easily retrieve mouse coordinates outside of the client area. This is only supported from SDL 2.0.4 (released Jan 2016) #if (SDL_MAJOR_VERSION >= 2) && (SDL_MINOR_VERSION >= 0) && (SDL_PATCHLEVEL >= 4) diff --git a/imgui.cpp b/imgui.cpp index 781e1ff3e..0020c2c1b 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2483,47 +2483,45 @@ void ImGui::NewFrame() if (!mouse_avail_to_imgui && !mouse_dragging_extern_payload) g.HoveredWindow = g.HoveredRootWindow = NULL; - // Scale & Scrolling - if (g.HoveredWindow && g.IO.MouseWheel != 0.0f && !g.HoveredWindow->Collapsed) + // Mouse wheel scrolling, scale + if (g.HoveredWindow && !g.HoveredWindow->Collapsed && (g.IO.MouseWheel != 0.0f || g.IO.MouseWheelH != 0.0f)) { + // If a child window has the ImGuiWindowFlags_NoScrollWithMouse flag, we give a chance to scroll its parent (unless either ImGuiWindowFlags_NoInputs or ImGuiWindowFlags_NoScrollbar are also set). ImGuiWindow* window = g.HoveredWindow; - if (g.IO.KeyCtrl && g.IO.FontAllowUserScaling) - { - // Zoom / Scale window - const float new_font_scale = ImClamp(window->FontWindowScale + g.IO.MouseWheel * 0.10f, 0.50f, 2.50f); - const float scale = new_font_scale / window->FontWindowScale; - window->FontWindowScale = new_font_scale; + ImGuiWindow* scroll_window = window; + while ((scroll_window->Flags & ImGuiWindowFlags_ChildWindow) && (scroll_window->Flags & ImGuiWindowFlags_NoScrollWithMouse) && !(scroll_window->Flags & ImGuiWindowFlags_NoScrollbar) && !(scroll_window->Flags & ImGuiWindowFlags_NoInputs) && scroll_window->ParentWindow) + scroll_window = scroll_window->ParentWindow; + const bool scroll_allowed = !(scroll_window->Flags & ImGuiWindowFlags_NoScrollWithMouse) && !(scroll_window->Flags & ImGuiWindowFlags_NoInputs); - const ImVec2 offset = window->Size * (1.0f - scale) * (g.IO.MousePos - window->Pos) / window->Size; - window->Pos += offset; - window->PosFloat += offset; - window->Size *= scale; - window->SizeFull *= scale; - } - else if (!g.IO.KeyCtrl) + if (g.IO.MouseWheel != 0.0f) { - // Mouse wheel Scrolling - // If a child window has the ImGuiWindowFlags_NoScrollWithMouse flag, we give a chance to scroll its parent (unless either ImGuiWindowFlags_NoInputs or ImGuiWindowFlags_NoScrollbar are also set). - ImGuiWindow* scroll_window = window; - while ((scroll_window->Flags & ImGuiWindowFlags_ChildWindow) && (scroll_window->Flags & ImGuiWindowFlags_NoScrollWithMouse) && !(scroll_window->Flags & ImGuiWindowFlags_NoScrollbar) && !(scroll_window->Flags & ImGuiWindowFlags_NoInputs) && scroll_window->ParentWindow) - scroll_window = scroll_window->ParentWindow; - - if (!(scroll_window->Flags & ImGuiWindowFlags_NoScrollWithMouse) && !(scroll_window->Flags & ImGuiWindowFlags_NoInputs)) + if (g.IO.KeyCtrl && g.IO.FontAllowUserScaling) { + // Zoom / Scale window + const float new_font_scale = ImClamp(window->FontWindowScale + g.IO.MouseWheel * 0.10f, 0.50f, 2.50f); + const float scale = new_font_scale / window->FontWindowScale; + window->FontWindowScale = new_font_scale; + + const ImVec2 offset = window->Size * (1.0f - scale) * (g.IO.MousePos - window->Pos) / window->Size; + window->Pos += offset; + window->PosFloat += offset; + window->Size *= scale; + window->SizeFull *= scale; + } + else if (!g.IO.KeyCtrl && scroll_allowed) + { + // Mouse wheel vertical scrolling float scroll_amount = 5 * scroll_window->CalcFontSize(); scroll_amount = (float)(int)ImMin(scroll_amount, (scroll_window->ContentsRegionRect.GetHeight() + scroll_window->WindowPadding.y * 2.0f) * 0.67f); SetWindowScrollY(scroll_window, scroll_window->Scroll.y - g.IO.MouseWheel * scroll_amount); } } - } - - // Horizontal wheel scrolling; for consistency, only allowed if Ctrl is not pressed. - if (g.HoveredWindow && g.IO.MouseHorizWheel != 0.0f && !g.HoveredWindow->Collapsed) - { - ImGuiWindow* window = g.HoveredWindow; - if (!g.IO.KeyCtrl && !(window->Flags & ImGuiWindowFlags_NoScrollWithMouse)) + if (g.IO.MouseWheelH != 0.0f && scroll_allowed) { - SetWindowScrollX(window, window->Scroll.x - g.IO.MouseHorizWheel * 10.f); + // Mouse wheel horizontal scrolling (for hardware that supports it) + float scroll_amount = scroll_window->CalcFontSize(); + if (!g.IO.KeyCtrl && !(window->Flags & ImGuiWindowFlags_NoScrollWithMouse)) + SetWindowScrollX(window, window->Scroll.x - g.IO.MouseWheelH * scroll_amount); } } @@ -3040,7 +3038,7 @@ void ImGui::EndFrame() g.Windows.swap(g.WindowsSortBuffer); // Clear Input data for next frame - g.IO.MouseWheel = 0.0f; + g.IO.MouseWheel = g.IO.MouseWheelH = 0.0f; memset(g.IO.InputCharacters, 0, sizeof(g.IO.InputCharacters)); g.FrameCountEnded = g.FrameCount; diff --git a/imgui.h b/imgui.h index 01fe3f777..f8d36ba41 100644 --- a/imgui.h +++ b/imgui.h @@ -930,8 +930,8 @@ struct ImGuiIO ImVec2 MousePos; // Mouse position, in pixels. Set to ImVec2(-FLT_MAX,-FLT_MAX) if mouse is unavailable (on another screen, etc.) bool MouseDown[5]; // Mouse buttons: left, right, middle + extras. ImGui itself mostly only uses left button (BeginPopupContext** are using right button). Others buttons allows us to track if the mouse is being used by your application + available to user as a convenience via IsMouse** API. - float MouseWheel; // Mouse wheel: 1 unit scrolls about 5 lines text. - float MouseHorizWheel; // Horizontal mouse wheel + float MouseWheel; // Mouse wheel: 1 unit scrolls about 5 lines text. + float MouseWheelH; // Mouse wheel (Horizontal). Most users don't have a mouse with an horizontal wheel, may not be filled by all back ends. bool MouseDrawCursor; // Request ImGui to draw a mouse cursor for you (if you are on a platform without a mouse cursor). bool KeyCtrl; // Keyboard modifier pressed: Control bool KeyShift; // Keyboard modifier pressed: Shift From 7dea158175615dc8939c57a06641bac911e33e8c Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 20 Jan 2018 12:36:59 +0100 Subject: [PATCH 898/921] Examples: Allegro, Apple, DirectX9/10/11, Glfw+Vulkan :Added support for horizontal mouse wheel. (#1463) --- examples/allegro5_example/imgui_impl_a5.cpp | 1 + examples/apple_example/imguiex-ios/imgui_impl_ios.mm | 4 ++-- examples/directx10_example/imgui_impl_dx10.cpp | 3 +++ examples/directx11_example/imgui_impl_dx11.cpp | 3 +++ examples/directx9_example/imgui_impl_dx9.cpp | 3 +++ examples/vulkan_example/imgui_impl_glfw_vulkan.cpp | 12 +++++++----- 6 files changed, 19 insertions(+), 7 deletions(-) diff --git a/examples/allegro5_example/imgui_impl_a5.cpp b/examples/allegro5_example/imgui_impl_a5.cpp index d3ccffd23..62f7af672 100644 --- a/examples/allegro5_example/imgui_impl_a5.cpp +++ b/examples/allegro5_example/imgui_impl_a5.cpp @@ -215,6 +215,7 @@ bool ImGui_ImplA5_ProcessEvent(ALLEGRO_EVENT *ev) { case ALLEGRO_EVENT_MOUSE_AXES: io.MouseWheel += ev->mouse.dz; + io.MouseWheelH += ev->mouse.dw; return true; case ALLEGRO_EVENT_KEY_CHAR: if (ev->keyboard.display == g_Display) diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.mm b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm index 9db45d0f2..5b56d3ca3 100644 --- a/examples/apple_example/imguiex-ios/imgui_impl_ios.mm +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm @@ -587,9 +587,9 @@ void ImGui_ClipboardCallback(uSynergyCookie cookie, enum uSynergyClipboardFormat io.MouseDown[i] = g_MousePressed[i]; } - // This is an arbitrary scaling factor that works for me. Not sure what units these - // mousewheel values from synergy are supposed to be in + // This is an arbitrary scaling factor that works for me. Not sure what units these mousewheel values from synergy are supposed to be in. io.MouseWheel = g_mouseWheelY / 500.0; + io.MouseWheelH = g_mouseWheelX / 500.0; } else { diff --git a/examples/directx10_example/imgui_impl_dx10.cpp b/examples/directx10_example/imgui_impl_dx10.cpp index 4f7117a7b..14a47c4af 100644 --- a/examples/directx10_example/imgui_impl_dx10.cpp +++ b/examples/directx10_example/imgui_impl_dx10.cpp @@ -275,6 +275,9 @@ IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wPa case WM_MOUSEWHEEL: io.MouseWheel += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f; return 0; + case WM_MOUSEHWHEEL: + io.MouseWheelH += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f; + return 0; case WM_MOUSEMOVE: io.MousePos.x = (signed short)(lParam); io.MousePos.y = (signed short)(lParam >> 16); diff --git a/examples/directx11_example/imgui_impl_dx11.cpp b/examples/directx11_example/imgui_impl_dx11.cpp index 5df7bf1f0..4963fc12e 100644 --- a/examples/directx11_example/imgui_impl_dx11.cpp +++ b/examples/directx11_example/imgui_impl_dx11.cpp @@ -282,6 +282,9 @@ IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wPa case WM_MOUSEWHEEL: io.MouseWheel += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f; return 0; + case WM_MOUSEHWHEEL: + io.MouseWheelH += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f; + return 0; case WM_MOUSEMOVE: io.MousePos.x = (signed short)(lParam); io.MousePos.y = (signed short)(lParam >> 16); diff --git a/examples/directx9_example/imgui_impl_dx9.cpp b/examples/directx9_example/imgui_impl_dx9.cpp index 18ec0d9b5..a4e676914 100644 --- a/examples/directx9_example/imgui_impl_dx9.cpp +++ b/examples/directx9_example/imgui_impl_dx9.cpp @@ -221,6 +221,9 @@ IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wPa case WM_MOUSEWHEEL: io.MouseWheel += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f; return 0; + case WM_MOUSEHWHEEL: + io.MouseWheelH += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f; + return 0; case WM_MOUSEMOVE: io.MousePos.x = (signed short)(lParam); io.MousePos.y = (signed short)(lParam >> 16); diff --git a/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp b/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp index 0af380cc6..5e678144e 100644 --- a/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp +++ b/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp @@ -25,7 +25,7 @@ static GLFWwindow* g_Window = NULL; static double g_Time = 0.0f; static bool g_MousePressed[3] = { false, false, false }; -static float g_MouseWheel = 0.0f; +static ImVec2 g_MouseWheel = ImVec2(0.0f, 0.0f); // Vulkan Data static VkAllocationCallbacks* g_Allocator = NULL; @@ -330,9 +330,10 @@ void ImGui_ImplGlfwVulkan_MouseButtonCallback(GLFWwindow*, int button, int actio g_MousePressed[button] = true; } -void ImGui_ImplGlfwVulkan_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset) +void ImGui_ImplGlfwVulkan_ScrollCallback(GLFWwindow*, double xoffset, double yoffset) { - g_MouseWheel += (float)yoffset; // Use fractional mouse wheel. + g_MouseWheel.x += (float)xoffset; // Use fractional mouse wheel. + g_MouseWheel.y += (float)yoffset; } void ImGui_ImplGlfwVulkan_KeyCallback(GLFWwindow*, int key, int, int action, int mods) @@ -825,8 +826,9 @@ void ImGui_ImplGlfwVulkan_NewFrame() g_MousePressed[i] = false; } - io.MouseWheel = g_MouseWheel; - g_MouseWheel = 0.0f; + io.MouseWheel = g_MouseWheel.y; + io.MouseWheelH = g_MouseWheel.x; + g_MouseWheel.x = g_MouseWheel.x = 0.0f; // Hide OS mouse cursor if ImGui is drawing it glfwSetInputMode(g_Window, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL); From 7e7c017b7556d1c2bcc2eccd92f6572b75af059f Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 20 Jan 2018 12:45:31 +0100 Subject: [PATCH 899/921] Examples: Simplified mouse wheel handling. (#1463) --- .../marmalade_example/imgui_impl_marmalade.cpp | 8 ++------ .../opengl2_example/imgui_impl_glfw_gl2.cpp | 10 +++------- .../opengl3_example/imgui_impl_glfw_gl3.cpp | 10 +++------- .../sdl_opengl2_example/imgui_impl_sdl_gl2.cpp | 12 ++++-------- .../sdl_opengl3_example/imgui_impl_sdl_gl3.cpp | 12 ++++-------- .../vulkan_example/imgui_impl_glfw_vulkan.cpp | 18 +++++++----------- 6 files changed, 23 insertions(+), 47 deletions(-) diff --git a/examples/marmalade_example/imgui_impl_marmalade.cpp b/examples/marmalade_example/imgui_impl_marmalade.cpp index 39623cc4d..36fc8328c 100644 --- a/examples/marmalade_example/imgui_impl_marmalade.cpp +++ b/examples/marmalade_example/imgui_impl_marmalade.cpp @@ -21,7 +21,6 @@ // Data static double g_Time = 0.0f; static bool g_MousePressed[3] = { false, false, false }; -static float g_MouseWheel = 0.0f; static CIwTexture* g_FontTexture = NULL; static char* g_ClipboardText = NULL; static bool g_osdKeyboardEnabled = false; @@ -128,9 +127,9 @@ int32 ImGui_Marmalade_PointerButtonEventCallback(void* SystemData, void* pUserDa if (pEvent->m_Button == S3E_POINTER_BUTTON_MIDDLEMOUSE) g_MousePressed[2] = true; if (pEvent->m_Button == S3E_POINTER_BUTTON_MOUSEWHEELUP) - g_MouseWheel += pEvent->m_y; + io.MouseWheel += pEvent->m_y; if (pEvent->m_Button == S3E_POINTER_BUTTON_MOUSEWHEELDOWN) - g_MouseWheel += pEvent->m_y; + io.MouseWheel += pEvent->m_y; } return 0; @@ -282,9 +281,6 @@ void ImGui_Marmalade_NewFrame() g_MousePressed[i] = false; } - io.MouseWheel = g_MouseWheel; - g_MouseWheel = 0.0f; - // TODO: Hide OS mouse cursor if ImGui is drawing it // s3ePointerSetInt(S3E_POINTER_HIDE_CURSOR,(io.MouseDrawCursor ? 0 : 1)); diff --git a/examples/opengl2_example/imgui_impl_glfw_gl2.cpp b/examples/opengl2_example/imgui_impl_glfw_gl2.cpp index 8dcd71e9f..e5fe2f47b 100644 --- a/examples/opengl2_example/imgui_impl_glfw_gl2.cpp +++ b/examples/opengl2_example/imgui_impl_glfw_gl2.cpp @@ -31,7 +31,6 @@ static GLFWwindow* g_Window = NULL; static double g_Time = 0.0f; static bool g_MouseJustPressed[3] = { false, false, false }; -static ImVec2 g_MouseWheel = ImVec2(0.0f, 0.0f); static GLuint g_FontTexture = 0; // This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) @@ -136,8 +135,9 @@ void ImGui_ImplGlfwGL2_MouseButtonCallback(GLFWwindow*, int button, int action, void ImGui_ImplGlfwGL2_ScrollCallback(GLFWwindow*, double xoffset, double yoffset) { - g_MouseWheel.x += (float)xoffset; // Use fractional mouse wheel. - g_MouseWheel.y += (float)yoffset; + ImGuiIO& io = ImGui::GetIO(); + io.MouseWheelH += (float)xoffset; + io.MouseWheel += (float)yoffset; } void ImGui_ImplGlfwGL2_KeyCallback(GLFWwindow*, int key, int, int action, int mods) @@ -296,10 +296,6 @@ void ImGui_ImplGlfwGL2_NewFrame() g_MouseJustPressed[i] = false; } - io.MouseWheel = g_MouseWheel.y; - io.MouseWheelH = g_MouseWheel.x; - g_MouseWheel.x = g_MouseWheel.x = 0.0f; - // Hide OS mouse cursor if ImGui is drawing it glfwSetInputMode(g_Window, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL); diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp index 79a62531f..a71fc515d 100644 --- a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp +++ b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp @@ -25,7 +25,6 @@ static GLFWwindow* g_Window = NULL; static double g_Time = 0.0f; static bool g_MouseJustPressed[3] = { false, false, false }; -static ImVec2 g_MouseWheel = ImVec2(0.0f, 0.0f); static GLuint g_FontTexture = 0; static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; @@ -157,8 +156,9 @@ void ImGui_ImplGlfwGL3_MouseButtonCallback(GLFWwindow*, int button, int action, void ImGui_ImplGlfwGL3_ScrollCallback(GLFWwindow*, double xoffset, double yoffset) { - g_MouseWheel.x += (float)xoffset; // Use fractional mouse wheel. - g_MouseWheel.y += (float)yoffset; + ImGuiIO& io = ImGui::GetIO(); + io.MouseWheelH += (float)xoffset; + io.MouseWheel += (float)yoffset; } void ImGui_ImplGlfwGL3_KeyCallback(GLFWwindow*, int key, int, int action, int mods) @@ -408,10 +408,6 @@ void ImGui_ImplGlfwGL3_NewFrame() g_MouseJustPressed[i] = false; } - io.MouseWheel = g_MouseWheel.y; - io.MouseWheelH = g_MouseWheel.x; - g_MouseWheel.x = g_MouseWheel.x = 0.0f; - // Hide OS mouse cursor if ImGui is drawing it glfwSetInputMode(g_Window, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL); diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp b/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp index d55af2b7f..76def29c3 100644 --- a/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp +++ b/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp @@ -24,7 +24,6 @@ // Data static double g_Time = 0.0f; static bool g_MousePressed[3] = { false, false, false }; -static ImVec2 g_MouseWheel = ImVec2(0.0f, 0.0f); static GLuint g_FontTexture = 0; // This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) @@ -132,10 +131,10 @@ bool ImGui_ImplSdlGL2_ProcessEvent(SDL_Event* event) { case SDL_MOUSEWHEEL: { - if (event->wheel.x > 0) g_MouseWheel.x = +1; - if (event->wheel.x < 0) g_MouseWheel.x = -1; - if (event->wheel.y > 0) g_MouseWheel.y = +1; - if (event->wheel.y < 0) g_MouseWheel.y = -1; + if (event->wheel.x > 0) io.MouseWheelH += 1; + if (event->wheel.x < 0) io.MouseWheelH -= 1; + if (event->wheel.y > 0) io.MouseWheel += 1; + if (event->wheel.y < 0) io.MouseWheel -= 1; return true; } case SDL_MOUSEBUTTONDOWN: @@ -274,13 +273,10 @@ void ImGui_ImplSdlGL2_NewFrame(SDL_Window *window) int mx, my; Uint32 mouse_buttons = SDL_GetMouseState(&mx, &my); io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); - io.MouseWheel = g_MouseWheel.y; - io.MouseWheelH = g_MouseWheel.x; io.MouseDown[0] = g_MousePressed[0] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_LEFT)) != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. io.MouseDown[1] = g_MousePressed[1] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_RIGHT)) != 0; io.MouseDown[2] = g_MousePressed[2] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_MIDDLE)) != 0; g_MousePressed[0] = g_MousePressed[1] = g_MousePressed[2] = false; - g_MouseWheel.x = g_MouseWheel.x = 0.0f; // We need to use SDL_CaptureMouse() to easily retrieve mouse coordinates outside of the client area. This is only supported from SDL 2.0.4 (released Jan 2016) #if (SDL_MAJOR_VERSION >= 2) && (SDL_MINOR_VERSION >= 0) && (SDL_PATCHLEVEL >= 4) diff --git a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp index 0a07cd082..35d9cdde1 100644 --- a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp +++ b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp @@ -19,7 +19,6 @@ // Data static double g_Time = 0.0f; static bool g_MousePressed[3] = { false, false, false }; -static ImVec2 g_MouseWheel = ImVec2(0.0f, 0.0f); static GLuint g_FontTexture = 0; static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; @@ -154,10 +153,10 @@ bool ImGui_ImplSdlGL3_ProcessEvent(SDL_Event* event) { case SDL_MOUSEWHEEL: { - if (event->wheel.x > 0) g_MouseWheel.x = +1; - if (event->wheel.x < 0) g_MouseWheel.x = -1; - if (event->wheel.y > 0) g_MouseWheel.y = +1; - if (event->wheel.y < 0) g_MouseWheel.y = -1; + if (event->wheel.x > 0) io.MouseWheelH += 1; + if (event->wheel.x < 0) io.MouseWheelH -= 1; + if (event->wheel.y > 0) io.MouseWheel += 1; + if (event->wheel.y < 0) io.MouseWheel -= 1; return true; } case SDL_MOUSEBUTTONDOWN: @@ -385,13 +384,10 @@ void ImGui_ImplSdlGL3_NewFrame(SDL_Window* window) int mx, my; Uint32 mouse_buttons = SDL_GetMouseState(&mx, &my); io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); - io.MouseWheel = g_MouseWheel.y; - io.MouseWheelH = g_MouseWheel.x; io.MouseDown[0] = g_MousePressed[0] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_LEFT)) != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. io.MouseDown[1] = g_MousePressed[1] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_RIGHT)) != 0; io.MouseDown[2] = g_MousePressed[2] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_MIDDLE)) != 0; g_MousePressed[0] = g_MousePressed[1] = g_MousePressed[2] = false; - g_MouseWheel.x = g_MouseWheel.x = 0.0f; // We need to use SDL_CaptureMouse() to easily retrieve mouse coordinates outside of the client area. This is only supported from SDL 2.0.4 (released Jan 2016) #if (SDL_MAJOR_VERSION >= 2) && (SDL_MINOR_VERSION >= 0) && (SDL_PATCHLEVEL >= 4) diff --git a/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp b/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp index 5e678144e..b9e6d78f2 100644 --- a/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp +++ b/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp @@ -24,8 +24,7 @@ // GLFW Data static GLFWwindow* g_Window = NULL; static double g_Time = 0.0f; -static bool g_MousePressed[3] = { false, false, false }; -static ImVec2 g_MouseWheel = ImVec2(0.0f, 0.0f); +static bool g_MouseJustPressed[3] = { false, false, false }; // Vulkan Data static VkAllocationCallbacks* g_Allocator = NULL; @@ -327,13 +326,14 @@ static void ImGui_ImplGlfwVulkan_SetClipboardText(void* user_data, const char* t void ImGui_ImplGlfwVulkan_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/) { if (action == GLFW_PRESS && button >= 0 && button < 3) - g_MousePressed[button] = true; + g_MouseJustPressed[button] = true; } void ImGui_ImplGlfwVulkan_ScrollCallback(GLFWwindow*, double xoffset, double yoffset) { - g_MouseWheel.x += (float)xoffset; // Use fractional mouse wheel. - g_MouseWheel.y += (float)yoffset; + ImGuiIO& io = ImGui::GetIO(); + io.MouseWheelH += (float)xoffset; + io.MouseWheel += (float)yoffset; } void ImGui_ImplGlfwVulkan_KeyCallback(GLFWwindow*, int key, int, int action, int mods) @@ -822,14 +822,10 @@ void ImGui_ImplGlfwVulkan_NewFrame() for (int i = 0; i < 3; i++) { - io.MouseDown[i] = g_MousePressed[i] || glfwGetMouseButton(g_Window, i) != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. - g_MousePressed[i] = false; + io.MouseDown[i] = g_MouseJustPressed[i] || glfwGetMouseButton(g_Window, i) != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. + g_MouseJustPressed[i] = false; } - io.MouseWheel = g_MouseWheel.y; - io.MouseWheelH = g_MouseWheel.x; - g_MouseWheel.x = g_MouseWheel.x = 0.0f; - // Hide OS mouse cursor if ImGui is drawing it glfwSetInputMode(g_Window, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL); From cd1409f4bf411fe63eaf5bf4de47f137a3aa388d Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 20 Jan 2018 20:25:12 +0100 Subject: [PATCH 900/921] ImFontAtlas: Moved mouse cursor data out of ImGuiContext, fix drawing them with multiple context. Also remove the last remaining undesirable dependency on GImGui in imgui_draw.cpp, finishing the work recently done with ImDrawListSharedData. Hurra! (#939) --- imgui.cpp | 15 +++++++-------- imgui.h | 5 ++++- imgui_draw.cpp | 37 ++++++++++++++++++++----------------- imgui_internal.h | 13 ------------- 4 files changed, 31 insertions(+), 39 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 0020c2c1b..c34190b40 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3069,17 +3069,16 @@ void ImGui::Render() g.DrawDataBuilder.FlattenIntoSingleLayer(); // Draw software mouse cursor if requested - if (g.IO.MouseDrawCursor) + ImVec2 offset, size, uv[4]; + if (g.IO.MouseDrawCursor && g.IO.Fonts->GetMouseCursorTexData(g.MouseCursor, &offset, &size, &uv[0], &uv[2])) { - const ImGuiMouseCursorData& cursor_data = g.MouseCursorData[g.MouseCursor]; - const ImVec2 pos = g.IO.MousePos - cursor_data.HotOffset; - const ImVec2 size = cursor_data.Size; + const ImVec2 pos = g.IO.MousePos - offset; const ImTextureID tex_id = g.IO.Fonts->TexID; g.OverlayDrawList.PushTextureID(tex_id); - g.OverlayDrawList.AddImage(tex_id, pos+ImVec2(1,0), pos+ImVec2(1,0) + size, cursor_data.TexUvMin[1], cursor_data.TexUvMax[1], IM_COL32(0,0,0,48)); // Shadow - g.OverlayDrawList.AddImage(tex_id, pos+ImVec2(2,0), pos+ImVec2(2,0) + size, cursor_data.TexUvMin[1], cursor_data.TexUvMax[1], IM_COL32(0,0,0,48)); // Shadow - g.OverlayDrawList.AddImage(tex_id, pos, pos + size, cursor_data.TexUvMin[1], cursor_data.TexUvMax[1], IM_COL32(0,0,0,255)); // Black border - g.OverlayDrawList.AddImage(tex_id, pos, pos + size, cursor_data.TexUvMin[0], cursor_data.TexUvMax[0], IM_COL32(255,255,255,255)); // White fill + g.OverlayDrawList.AddImage(tex_id, pos+ImVec2(1,0), pos+ImVec2(1,0) + size, uv[2], uv[3], IM_COL32(0,0,0,48)); // Shadow + g.OverlayDrawList.AddImage(tex_id, pos+ImVec2(2,0), pos+ImVec2(2,0) + size, uv[2], uv[3], IM_COL32(0,0,0,48)); // Shadow + g.OverlayDrawList.AddImage(tex_id, pos, pos + size, uv[2], uv[3], IM_COL32(0,0,0,255)); // Black border + g.OverlayDrawList.AddImage(tex_id, pos, pos + size, uv[0], uv[1], IM_COL32(255,255,255,255)); // White fill g.OverlayDrawList.PopTextureID(); } if (!g.OverlayDrawList.VtxBuffer.empty()) diff --git a/imgui.h b/imgui.h index f8d36ba41..57ffff181 100644 --- a/imgui.h +++ b/imgui.h @@ -1611,9 +1611,12 @@ struct ImFontAtlas IMGUI_API int AddCustomRectRegular(unsigned int id, int width, int height); // Id needs to be >= 0x10000. Id >= 0x80000000 are reserved for ImGui and ImDrawList IMGUI_API int AddCustomRectFontGlyph(ImFont* font, ImWchar id, int width, int height, float advance_x, const ImVec2& offset = ImVec2(0,0)); // Id needs to be < 0x10000 to register a rectangle to map into a specific font. - IMGUI_API void CalcCustomRectUV(const CustomRect* rect, ImVec2* out_uv_min, ImVec2* out_uv_max); const CustomRect* GetCustomRectByIndex(int index) const { if (index < 0) return NULL; return &CustomRects[index]; } + // Internals + IMGUI_API void CalcCustomRectUV(const CustomRect* rect, ImVec2* out_uv_min, ImVec2* out_uv_max); + IMGUI_API bool GetMouseCursorTexData(ImGuiMouseCursor cursor, ImVec2* out_offset, ImVec2* out_size, ImVec2 out_uv_border[2], ImVec2 out_uv_fill[2]); + //------------------------------------------- // Members //------------------------------------------- diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 0cb7cd82f..9d99bf19b 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1352,7 +1352,6 @@ static const ImVec2 FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[ImGuiMouseCursor_Count_][ { ImVec2(55,0), ImVec2(17,17), ImVec2( 9, 9) }, // ImGuiMouseCursor_ResizeNWSE }; - ImFontAtlas::ImFontAtlas() { TexID = NULL; @@ -1609,6 +1608,26 @@ void ImFontAtlas::CalcCustomRectUV(const CustomRect* rect, ImVec2* out_uv_min, I *out_uv_max = ImVec2((float)(rect->X + rect->Width) / TexWidth, (float)(rect->Y + rect->Height) / TexHeight); } +bool ImFontAtlas::GetMouseCursorTexData(ImGuiMouseCursor cursor_type, ImVec2* out_offset, ImVec2* out_size, ImVec2 out_uv_border[2], ImVec2 out_uv_fill[2]) +{ + if (cursor_type <= ImGuiMouseCursor_None || cursor_type >= ImGuiMouseCursor_Count_) + return false; + + ImFontAtlas::CustomRect& r = CustomRects[CustomRectIds[0]]; + IM_ASSERT(r.ID == FONT_ATLAS_DEFAULT_TEX_DATA_ID); + ImVec2 uv_scale(1.0f / TexWidth, 1.0f / TexHeight); + ImVec2 pos = FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[cursor_type][0] + ImVec2((float)r.X, (float)r.Y); + ImVec2 size = FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[cursor_type][1]; + *out_size = size; + *out_offset = FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[cursor_type][2]; + out_uv_border[0] = (pos) * uv_scale; + out_uv_border[1] = (pos + size) * uv_scale; + pos.x += FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF + 1; + out_uv_fill[0] = (pos) * uv_scale; + out_uv_fill[1] = (pos + size) * uv_scale; + return true; +} + bool ImFontAtlas::Build() { return ImFontAtlasBuildWithStbTruetype(this); @@ -1891,22 +1910,6 @@ static void ImFontAtlasBuildRenderDefaultTexData(ImFontAtlas* atlas) } const ImVec2 tex_uv_scale(1.0f / atlas->TexWidth, 1.0f / atlas->TexHeight); atlas->TexUvWhitePixel = ImVec2((r.X + 0.5f) * tex_uv_scale.x, (r.Y + 0.5f) * tex_uv_scale.y); - - // Setup mouse cursors - for (int type = 0; type < ImGuiMouseCursor_Count_; type++) - { - ImGuiMouseCursorData& cursor_data = GImGui->MouseCursorData[type]; - ImVec2 pos = FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[type][0] + ImVec2((float)r.X, (float)r.Y); - const ImVec2 size = FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[type][1]; - cursor_data.Type = type; - cursor_data.Size = size; - cursor_data.HotOffset = FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[type][2]; - cursor_data.TexUvMin[0] = (pos) * tex_uv_scale; - cursor_data.TexUvMax[0] = (pos + size) * tex_uv_scale; - pos.x += FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF + 1; - cursor_data.TexUvMin[1] = (pos) * tex_uv_scale; - cursor_data.TexUvMax[1] = (pos + size) * tex_uv_scale; - } } void ImFontAtlasBuildFinish(ImFontAtlas* atlas) diff --git a/imgui_internal.h b/imgui_internal.h index 4a5edfc1f..d6d19a426 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -38,7 +38,6 @@ struct ImGuiGroupData; struct ImGuiMenuColumns; struct ImGuiDrawContext; struct ImGuiTextEditState; -struct ImGuiMouseCursorData; struct ImGuiPopupRef; struct ImGuiWindow; struct ImGuiWindowSettings; @@ -382,16 +381,6 @@ struct ImGuiSettingsHandler ImGuiSettingsHandler() { memset(this, 0, sizeof(*this)); } }; -// Mouse cursor data (used when io.MouseDrawCursor is set) -struct ImGuiMouseCursorData -{ - ImGuiMouseCursor Type; - ImVec2 HotOffset; - ImVec2 Size; - ImVec2 TexUvMin[2]; - ImVec2 TexUvMax[2]; -}; - // Storage for current popup stack struct ImGuiPopupRef { @@ -557,7 +546,6 @@ struct ImGuiContext float ModalWindowDarkeningRatio; ImDrawList OverlayDrawList; // Optional software render of mouse cursors, if io.MouseDrawCursor is set + a few debug overlays ImGuiMouseCursor MouseCursor; - ImGuiMouseCursorData MouseCursorData[ImGuiMouseCursor_Count_]; // Drag and Drop bool DragDropActive; @@ -645,7 +633,6 @@ struct ImGuiContext OverlayDrawList._Data = &DrawListSharedData; OverlayDrawList._OwnerName = "##Overlay"; // Give it a name for debugging MouseCursor = ImGuiMouseCursor_Arrow; - memset(MouseCursorData, 0, sizeof(MouseCursorData)); DragDropActive = false; DragDropSourceFlags = 0; From 5eb293c87970b37f7890c89b9e21250e1fd24450 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 20 Jan 2018 20:32:23 +0100 Subject: [PATCH 901/921] ImFontAtlas: Added TexUvScale (= 1.0f / (float)TexWidth, 1.0f / (float)TexHeight) --- imgui.h | 1 + imgui_draw.cpp | 23 ++++++++++++----------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/imgui.h b/imgui.h index 57ffff181..6d411738a 100644 --- a/imgui.h +++ b/imgui.h @@ -1631,6 +1631,7 @@ struct ImFontAtlas unsigned int* TexPixelsRGBA32; // 4 component per pixel, each component is unsigned 8-bit. Total size = TexWidth * TexHeight * 4 int TexWidth; // Texture width calculated during Build(). int TexHeight; // Texture height calculated during Build(). + ImVec2 TexUvScale; // = (1.0f/TexWidth, 1.0f/TexHeight) ImVec2 TexUvWhitePixel; // Texture coordinates to a white pixel ImVector Fonts; // Hold all the fonts returned by AddFont*. Fonts[0] is the default font upon calling ImGui::NewFrame(), use ImGui::PushFont()/PopFont() to change the current font. ImVector CustomRects; // Rectangles for packing custom texture data into the atlas. diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 9d99bf19b..216cf3fd7 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1360,7 +1360,8 @@ ImFontAtlas::ImFontAtlas() TexPixelsAlpha8 = NULL; TexPixelsRGBA32 = NULL; TexWidth = TexHeight = 0; - TexUvWhitePixel = ImVec2(0, 0); + TexUvScale = ImVec2(0.0f, 0.0f); + TexUvWhitePixel = ImVec2(0.0f, 0.0f); for (int n = 0; n < IM_ARRAYSIZE(CustomRectIds); n++) CustomRectIds[n] = -1; } @@ -1604,8 +1605,8 @@ void ImFontAtlas::CalcCustomRectUV(const CustomRect* rect, ImVec2* out_uv_min, I { IM_ASSERT(TexWidth > 0 && TexHeight > 0); // Font atlas needs to be built before we can calculate UV coordinates IM_ASSERT(rect->IsPacked()); // Make sure the rectangle has been packed - *out_uv_min = ImVec2((float)rect->X / TexWidth, (float)rect->Y / TexHeight); - *out_uv_max = ImVec2((float)(rect->X + rect->Width) / TexWidth, (float)(rect->Y + rect->Height) / TexHeight); + *out_uv_min = ImVec2((float)rect->X * TexUvScale.x, (float)rect->Y * TexUvScale.y); + *out_uv_max = ImVec2((float)(rect->X + rect->Width) * TexUvScale.x, (float)(rect->Y + rect->Height) * TexUvScale.y); } bool ImFontAtlas::GetMouseCursorTexData(ImGuiMouseCursor cursor_type, ImVec2* out_offset, ImVec2* out_size, ImVec2 out_uv_border[2], ImVec2 out_uv_fill[2]) @@ -1615,16 +1616,15 @@ bool ImFontAtlas::GetMouseCursorTexData(ImGuiMouseCursor cursor_type, ImVec2* ou ImFontAtlas::CustomRect& r = CustomRects[CustomRectIds[0]]; IM_ASSERT(r.ID == FONT_ATLAS_DEFAULT_TEX_DATA_ID); - ImVec2 uv_scale(1.0f / TexWidth, 1.0f / TexHeight); ImVec2 pos = FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[cursor_type][0] + ImVec2((float)r.X, (float)r.Y); ImVec2 size = FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[cursor_type][1]; *out_size = size; *out_offset = FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[cursor_type][2]; - out_uv_border[0] = (pos) * uv_scale; - out_uv_border[1] = (pos + size) * uv_scale; + out_uv_border[0] = (pos) * TexUvScale; + out_uv_border[1] = (pos + size) * TexUvScale; pos.x += FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF + 1; - out_uv_fill[0] = (pos) * uv_scale; - out_uv_fill[1] = (pos + size) * uv_scale; + out_uv_fill[0] = (pos) * TexUvScale; + out_uv_fill[1] = (pos + size) * TexUvScale; return true; } @@ -1658,7 +1658,8 @@ bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas) atlas->TexID = NULL; atlas->TexWidth = atlas->TexHeight = 0; - atlas->TexUvWhitePixel = ImVec2(0, 0); + atlas->TexUvScale = ImVec2(0.0f, 0.0f); + atlas->TexUvWhitePixel = ImVec2(0.0f, 0.0f); atlas->ClearTexData(); // Count glyphs/ranges @@ -1767,6 +1768,7 @@ bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas) // Create texture atlas->TexHeight = ImUpperPowerOfTwo(atlas->TexHeight); + atlas->TexUvScale = ImVec2(1.0f / atlas->TexWidth, 1.0f / atlas->TexHeight); atlas->TexPixelsAlpha8 = (unsigned char*)ImGui::MemAlloc(atlas->TexWidth * atlas->TexHeight); memset(atlas->TexPixelsAlpha8, 0, atlas->TexWidth * atlas->TexHeight); spc.pixels = atlas->TexPixelsAlpha8; @@ -1908,8 +1910,7 @@ static void ImFontAtlasBuildRenderDefaultTexData(ImFontAtlas* atlas) atlas->TexPixelsAlpha8[offset0] = FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS[n] == '.' ? 0xFF : 0x00; atlas->TexPixelsAlpha8[offset1] = FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS[n] == 'X' ? 0xFF : 0x00; } - const ImVec2 tex_uv_scale(1.0f / atlas->TexWidth, 1.0f / atlas->TexHeight); - atlas->TexUvWhitePixel = ImVec2((r.X + 0.5f) * tex_uv_scale.x, (r.Y + 0.5f) * tex_uv_scale.y); + atlas->TexUvWhitePixel = ImVec2((r.X + 0.5f) * atlas->TexUvScale.x, (r.Y + 0.5f) * atlas->TexUvScale.y); } void ImFontAtlasBuildFinish(ImFontAtlas* atlas) From 7c8a19978d52384d277e67b77e61f24a00b9ea23 Mon Sep 17 00:00:00 2001 From: Panos Karabelas Date: Sun, 21 Jan 2018 16:02:09 +0000 Subject: [PATCH 902/921] Simplified return of ImGui::IsKeyReleased() --- imgui.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index c34190b40..c41c8b52a 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3507,9 +3507,7 @@ bool ImGui::IsKeyReleased(int user_key_index) ImGuiContext& g = *GImGui; if (user_key_index < 0) return false; IM_ASSERT(user_key_index >= 0 && user_key_index < IM_ARRAYSIZE(g.IO.KeysDown)); - if (g.IO.KeysDownDurationPrev[user_key_index] >= 0.0f && !g.IO.KeysDown[user_key_index]) - return true; - return false; + return g.IO.KeysDownDurationPrev[user_key_index] >= 0.0f && !g.IO.KeysDown[user_key_index]; } bool ImGui::IsMouseDown(int button) From ac5b7a1bdf2e7fa40fc467c90d58b5cf0fed3928 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 21 Jan 2018 19:53:02 +0100 Subject: [PATCH 903/921] Comments --- imgui.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index c41c8b52a..637721af7 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -164,7 +164,7 @@ - A minimal render function skeleton may be: - void void MyRenderFunction(ImDrawData* draw_data)(ImDrawData* draw_data) + void void MyRenderFunction(ImDrawData* draw_data) { // TODO: Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled // TODO: Setup viewport, orthographic projection matrix @@ -2278,8 +2278,8 @@ void ImGui::NewFrame() // (We pass an error message in the assert expression as a trick to get it visible to programmers who are not using a debugger, as most assert handlers display their argument) IM_ASSERT(g.IO.DeltaTime >= 0.0f && "Need a positive DeltaTime (zero is tolerated but will cause some timing issues)"); IM_ASSERT(g.IO.DisplaySize.x >= 0.0f && g.IO.DisplaySize.y >= 0.0f && "Invalid DisplaySize value"); - IM_ASSERT(g.IO.Fonts->Fonts.Size > 0 && "Font Atlas not created. Did you call io.Fonts->GetTexDataAsRGBA32 / GetTexDataAsAlpha8 ?"); - IM_ASSERT(g.IO.Fonts->Fonts[0]->IsLoaded() && "Font Atlas not created. Did you call io.Fonts->GetTexDataAsRGBA32 / GetTexDataAsAlpha8 ?"); + IM_ASSERT(g.IO.Fonts->Fonts.Size > 0 && "Font Atlas not built. Did you call io.Fonts->GetTexDataAsRGBA32() / GetTexDataAsAlpha8() ?"); + IM_ASSERT(g.IO.Fonts->Fonts[0]->IsLoaded() && "Font Atlas not built. Did you call io.Fonts->GetTexDataAsRGBA32() / GetTexDataAsAlpha8() ?"); IM_ASSERT(g.Style.CurveTessellationTol > 0.0f && "Invalid style setting"); IM_ASSERT(g.Style.Alpha >= 0.0f && g.Style.Alpha <= 1.0f && "Invalid style setting. Alpha cannot be negative (allows us to avoid a few clamps in color computations)"); IM_ASSERT((g.FrameCount == 0 || g.FrameCountEnded == g.FrameCount) && "Forgot to call Render() or EndFrame() at the end of the previous frame?"); From 5097368bd519774f1d0faeff90ac6010954dfc57 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 22 Jan 2018 11:59:40 +0100 Subject: [PATCH 904/921] Tweaked FAQ. --- README.md | 9 ++++--- imgui.cpp | 78 ++++++++++++++++++++++++++++++------------------------- 2 files changed, 48 insertions(+), 39 deletions(-) diff --git a/README.md b/README.md index bf3099460..c76e6a8f8 100644 --- a/README.md +++ b/README.md @@ -153,10 +153,9 @@ I occasionally tag [Releases](https://github.com/ocornut/imgui/releases) but it The library started its life and is best known as "ImGui" only due to the fact that I didn't give it a proper name when I released it. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations. It seemed confusing and unfair to hog the name. To reduce the ambiguity without affecting existing codebases, I have decided on an alternate, longer name "dear imgui" that people can use to refer to this specific library in ambiguous situations. -What is ImTextureID and how do I display an image? -
I integrated Dear ImGui in my engine and the text or lines are blurry.. -
I integrated Dear ImGui in my engine and some elements are disappearing when I move windows around.. -
How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on labels/IDs. +How can I help +
How can I display an image? What is ImTextureID, how does it works? +
How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on labels and the ID stack.
How can I tell when Dear ImGui wants my mouse/keyboard inputs VS when I can pass them to my application?
How can I load a different font than the default?
How can I easily use icons in my application? @@ -164,6 +163,8 @@ The library started its life and is best known as "ImGui" only due to the fact t
How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic?
How can I preserve my Dear ImGui context across reloading a DLL? (loss of the global/static variables)
How can I use the drawing facilities without an Dear ImGui window? (using ImDrawList API) +
I integrated Dear ImGui in my engine and the text or lines are blurry.. +
I integrated Dear ImGui in my engine and some elements are disappearing when I move windows around.. See the FAQ in imgui.cpp for answers. diff --git a/imgui.cpp b/imgui.cpp index 637721af7..302a6712f 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -23,10 +23,8 @@ - ISSUES & TODO LIST - FREQUENTLY ASKED QUESTIONS (FAQ), TIPS - How can I help? - - What is ImTextureID and how do I display an image? - - I integrated Dear ImGui in my engine and the text or lines are blurry.. - - I integrated Dear ImGui in my engine and some elements are clipping or disappearing when I move windows around.. - - How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on labels/IDs. + - How can I dipslay an image? What is ImTextureID, how does it works? + - How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on labels and the ID stack. - How can I tell when Dear ImGui wants my mouse/keyboard inputs VS when I can pass them to my application? - How can I load a different font than the default? - How can I easily use icons in my application? @@ -34,6 +32,8 @@ - How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic? - How can I preserve my Dear ImGui context across reloading a DLL? (loss of the global/static variables) - How can I use the drawing facilities without an ImGui window? (using ImDrawList API) + - I integrated Dear ImGui in my engine and the text or lines are blurry.. + - I integrated Dear ImGui in my engine and some elements are clipping or disappearing when I move windows around.. - ISSUES & TODO-LIST - CODE @@ -374,10 +374,14 @@ ====================================== Q: How can I help? - A: - If you are experienced enough with Dear ImGui and with C/C++, look at the todo list and see how you want/can help! - - Become a Patron/donate! Convince your company to become a Patron or provide serious funding for development time! See http://www.patreon.com/imgui + A: - If you are experienced with Dear ImGui and C++, look at the github issues, or TODO.txt and see how you want/can help! + - Convince your company to fund development time! Individual users: you can also become a Patron (patreon.com/imgui) or donate on PayPal! See README. + - Disclose your usage of dear imgui via a dev blog post, a tweet, a screenshot, a mention somewhere etc. + You may post screenshot or links in the gallery threads (github.com/ocornut/imgui/issues/1269). Visuals are ideal as they inspire other programmers. + But even without visuals, disclosing your use of dear imgui help the library grow credibility, and help other teams and programmers with taking decisions. + - If you have issues or if you need to hack into the library, even if you don't expect any support it is useful that you share your issues (on github or privately). - Q: What is ImTextureID and how do I display an image? + Q: How can I display an image? What is ImTextureID, how does it works? A: ImTextureID is a void* used to pass renderer-agnostic texture references around until it hits your render function. Dear ImGui knows nothing about what those bits represent, it just passes them around. It is up to you to decide what you want the void* to carry! It could be an identifier to your OpenGL texture (cast GLuint to void*), a pointer to your custom engine material (cast MyMaterial* to void*), etc. @@ -386,26 +390,19 @@ (c++ tip: OpenGL uses integers to identify textures. You can safely store an integer into a void*, just cast it to void*, don't take it's address!) To display a custom image/texture within an ImGui window, you may use ImGui::Image(), ImGui::ImageButton(), ImDrawList::AddImage() functions. Dear ImGui will generate the geometry and draw calls using the ImTextureID that you passed and which your renderer can use. + You may call ImGui::ShowMetricsWindow() to explore active draw lists and visualize/understand how the draw data is generated. It is your responsibility to get textures uploaded to your GPU. - Q: I integrated Dear ImGui in my engine and the text or lines are blurry.. - A: In your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f). - Also make sure your orthographic projection matrix and io.DisplaySize matches your actual framebuffer dimension. - - Q: I integrated Dear ImGui in my engine and some elements are clipping or disappearing when I move windows around.. - A: You are probably mishandling the clipping rectangles in your render function. - Rectangles provided by ImGui are defined as (x1=left,y1=top,x2=right,y2=bottom) and NOT as (x1,y1,width,height). - Q: Can I have multiple widgets with the same label? Can I have widget without a label? - A: Yes. A primer on the use of labels/IDs in Dear ImGui.. + A: Yes. A primer on labels and the ID stack... - - Elements that are not clickable, such as Text() items don't need an ID. + - Elements that are typically not clickable, such as Text() items don't need an ID. - Interactive widgets require state to be carried over multiple frames (most typically Dear ImGui often needs to remember what is the "active" widget). to do so they need a unique ID. unique ID are typically derived from a string label, an integer index or a pointer. - Button("OK"); // Label = "OK", ID = hash of "OK" - Button("Cancel"); // Label = "Cancel", ID = hash of "Cancel" + Button("OK"); // Label = "OK", ID = hash of "OK" + Button("Cancel"); // Label = "Cancel", ID = hash of "Cancel" - ID are uniquely scoped within windows, tree nodes, etc. so no conflict can happen if you have two buttons called "OK" in two different windows or in two different locations of a tree. @@ -413,34 +410,35 @@ - If you have a same ID twice in the same location, you'll have a conflict: Button("OK"); - Button("OK"); // ID collision! Both buttons will be treated as the same. + Button("OK"); // ID collision! Both buttons will be treated as the same. Fear not! this is easy to solve and there are many ways to solve it! - - When passing a label you can optionally specify extra unique ID information within string itself. - This helps solving the simpler collision cases. Use "##" to pass a complement to the ID that won't be visible to the end-user: + - When passing a label you can optionally specify extra unique ID information within string itself. + Use "##" to pass a complement to the ID that won't be visible to the end-user. + This helps solving the simple collision cases when you know which items are going to be created. - Button("Play"); // Label = "Play", ID = hash of "Play" - Button("Play##foo1"); // Label = "Play", ID = hash of "Play##foo1" (different from above) - Button("Play##foo2"); // Label = "Play", ID = hash of "Play##foo2" (different from above) + Button("Play"); // Label = "Play", ID = hash of "Play" + Button("Play##foo1"); // Label = "Play", ID = hash of "Play##foo1" (different from above) + Button("Play##foo2"); // Label = "Play", ID = hash of "Play##foo2" (different from above) - If you want to completely hide the label, but still need an ID: - Checkbox("##On", &b); // Label = "", ID = hash of "##On" (no label!) + Checkbox("##On", &b); // Label = "", ID = hash of "##On" (no label!) - Occasionally/rarely you might want change a label while preserving a constant ID. This allows you to animate labels. - For example you may want to include varying information in a window title bar (and windows are uniquely identified by their ID.. obviously) + For example you may want to include varying information in a window title bar, but windows are uniquely identified by their ID.. Use "###" to pass a label that isn't part of ID: Button("Hello###ID"; // Label = "Hello", ID = hash of "ID" Button("World###ID"; // Label = "World", ID = hash of "ID" (same as above) - sprintf(buf, "My game (%f FPS)###MyGame"); + sprintf(buf, "My game (%f FPS)###MyGame", fps); Begin(buf); // Variable label, ID = hash of "MyGame" - Use PushID() / PopID() to create scopes and avoid ID conflicts within the same Window. This is the most convenient way of distinguishing ID if you are iterating and creating many UI elements. - You can push a pointer, a string or an integer value. Remember that ID are formed from the concatenation of everything in the ID stack! + You can push a pointer, a string or an integer value. Remember that ID are formed from the concatenation of _everything_ in the ID stack! for (int i = 0; i < 100; i++) { @@ -570,16 +568,25 @@ so you don't rely on the default globals. Q: How can I use the drawing facilities without an ImGui window? (using ImDrawList API) - A: The easiest way is to create a dummy window. Call Begin() with NoTitleBar|NoResize|NoMove|NoScrollbar|NoSavedSettings|NoInputs flag, - zero background alpha, then retrieve the ImDrawList* via GetWindowDrawList() and draw to it in any way you like. - You can also perfectly create a standalone ImDrawList instance _but_ you need ImGui to be initialized because ImDrawList pulls from ImGui - data to retrieve the coordinates of the white pixel. + A: - You can create a dummy window. Call Begin() with NoTitleBar|NoResize|NoMove|NoScrollbar|NoSavedSettings|NoInputs flag, + push a ImGuiCol_WindowBg with zero alpha, then retrieve the ImDrawList* via GetWindowDrawList() and draw to it in any way you like. + - You can call ImGui::GetOverlayDrawList() and use this draw list to display contents over every other imgui windows. + - You can create your own ImDrawList instance. You'll need to initialize them ImGui::GetDrawListSharedData(), or create your own ImDrawListSharedData. + + Q: I integrated Dear ImGui in my engine and the text or lines are blurry.. + A: In your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f). + Also make sure your orthographic projection matrix and io.DisplaySize matches your actual framebuffer dimension. + + Q: I integrated Dear ImGui in my engine and some elements are clipping or disappearing when I move windows around.. + A: You are probably mishandling the clipping rectangles in your render function. + Rectangles provided by ImGui are defined as (x1=left,y1=top,x2=right,y2=bottom) and NOT as (x1,y1,width,height). + - tip: you can call Begin() multiple times with the same name during the same frame, it will keep appending to the same window. - this is also useful to set yourself in the context of another window (to get/set other settings) + this is also useful to set yourself in the context of another window (to get/set other settings) - tip: you can create widgets without a Begin()/End() block, they will go in an implicit window called "Debug". - tip: the ImGuiOnceUponAFrame helper will allow run the block of code only once a frame. You can use it to quickly add custom UI in the middle - of a deep nested inner loop in your code. + of a deep nested inner loop in your code. - tip: you can call Render() multiple times (e.g for VR renders). - tip: call and read the ShowDemoWindow() code in imgui_demo.cpp for more example of how to use ImGui! @@ -3914,6 +3921,7 @@ bool ImGui::BeginPopupModal(const char* name, bool* p_open, ImGuiWindowFlags fla } // Center modal windows by default + // FIXME: Should test for (PosCond & window->SetWindowPosAllowFlags) with the upcoming window. if (g.NextWindowData.PosCond == 0) SetNextWindowPos(g.IO.DisplaySize * 0.5f, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f)); From 1acb1554191dfa2f2d28198f8124906eb9d77e4a Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 22 Jan 2018 14:30:49 +0100 Subject: [PATCH 905/921] Internals: Moved unnecessary MovingWindowMoveId field. --- imgui.cpp | 8 +------- imgui_internal.h | 2 -- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 302a6712f..5dff60a01 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2393,11 +2393,10 @@ void ImGui::NewFrame() g.IO.Framerate = 1.0f / (g.FramerateSecPerFrameAccum / (float)IM_ARRAYSIZE(g.FramerateSecPerFrame)); // Handle user moving window with mouse (at the beginning of the frame to avoid input lag or sheering). - if (g.MovingWindowMoveId && g.MovingWindowMoveId == g.ActiveId) + if (g.MovingWindow && g.MovingWindow->MoveId == g.ActiveId) { KeepAliveID(g.ActiveId); IM_ASSERT(g.MovingWindow && g.MovingWindow->RootWindow); - IM_ASSERT(g.MovingWindow->MoveId == g.MovingWindowMoveId); if (g.IO.MouseDown[0]) { // MovingWindow = window we clicked on, could be a child window. We track it to preserve Focus and so that ActiveIdWindow == MovingWindow and ActiveId == MovingWindow->MoveId for consistency. @@ -2414,7 +2413,6 @@ void ImGui::NewFrame() { ClearActiveID(); g.MovingWindow = NULL; - g.MovingWindowMoveId = 0; } } else @@ -2427,7 +2425,6 @@ void ImGui::NewFrame() ClearActiveID(); } g.MovingWindow = NULL; - g.MovingWindowMoveId = 0; } // Delay saving settings so we don't spam disk too much @@ -2994,10 +2991,7 @@ void ImGui::EndFrame() SetActiveID(g.HoveredWindow->MoveId, g.HoveredWindow); g.ActiveIdClickOffset = g.IO.MousePos - g.HoveredRootWindow->Pos; if (!(g.HoveredWindow->Flags & ImGuiWindowFlags_NoMove) && !(g.HoveredRootWindow->Flags & ImGuiWindowFlags_NoMove)) - { g.MovingWindow = g.HoveredWindow; - g.MovingWindowMoveId = g.MovingWindow->MoveId; - } } else if (g.NavWindow != NULL && GetFrontMostModalRootWindow() == NULL) { diff --git a/imgui_internal.h b/imgui_internal.h index d6d19a426..7fe6dffa9 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -530,7 +530,6 @@ struct ImGuiContext ImVec2 ActiveIdClickOffset; // Clicked offset from upper-left corner, if applicable (currently only set by ButtonBehavior) ImGuiWindow* ActiveIdWindow; ImGuiWindow* MovingWindow; // Track the window we clicked on (in order to preserve focus). The actually window that is moved is generally MovingWindow->RootWindow. - ImGuiID MovingWindowMoveId; // == MovingWindow->MoveId ImVector ColorModifiers; // Stack for PushStyleColor()/PopStyleColor() ImVector StyleModifiers; // Stack for PushStyleVar()/PopStyleVar() ImVector FontStack; // Stack for PushFont()/PopFont() @@ -625,7 +624,6 @@ struct ImGuiContext ActiveIdClickOffset = ImVec2(-1,-1); ActiveIdWindow = NULL; MovingWindow = NULL; - MovingWindowMoveId = 0; NextTreeNodeOpenVal = false; NextTreeNodeOpenCond = 0; From 9076366c172f7375f4f869dc7e4b1d5a8667df25 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 23 Jan 2018 09:57:49 +0100 Subject: [PATCH 906/921] Style: Exposed ImGuiStyleVar_WindowTitleAlign, ImGuiStyleVar_ScrollbarSize, ImGuiStyleVar_ScrollbarRounding, ImGuiStyleVar_GrabRounding + added an assert to reduce accidental breakage. (#1181) --- imgui.cpp | 7 ++++++- imgui.h | 4 ++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 5dff60a01..3f0ad4e5d 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -5400,13 +5400,14 @@ struct ImGuiStyleVarInfo void* GetVarPtr(ImGuiStyle* style) const { return (void*)((unsigned char*)style + Offset); } }; -static const ImGuiStyleVarInfo GStyleVarInfo[ImGuiStyleVar_Count_] = +static const ImGuiStyleVarInfo GStyleVarInfo[] = { { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, Alpha) }, // ImGuiStyleVar_Alpha { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowPadding) }, // ImGuiStyleVar_WindowPadding { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowRounding) }, // ImGuiStyleVar_WindowRounding { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowBorderSize) }, // ImGuiStyleVar_WindowBorderSize { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowMinSize) }, // ImGuiStyleVar_WindowMinSize + { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowTitleAlign) }, // ImGuiStyleVar_WindowTitleAlign { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, ChildRounding) }, // ImGuiStyleVar_ChildRounding { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, ChildBorderSize) }, // ImGuiStyleVar_ChildBorderSize { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, PopupRounding) }, // ImGuiStyleVar_PopupRounding @@ -5417,13 +5418,17 @@ static const ImGuiStyleVarInfo GStyleVarInfo[ImGuiStyleVar_Count_] = { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, ItemSpacing) }, // ImGuiStyleVar_ItemSpacing { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, ItemInnerSpacing) }, // ImGuiStyleVar_ItemInnerSpacing { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, IndentSpacing) }, // ImGuiStyleVar_IndentSpacing + { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, ScrollbarSize) }, // ImGuiStyleVar_ScrollbarSize + { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, ScrollbarRounding) }, // ImGuiStyleVar_ScrollbarRounding { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, GrabMinSize) }, // ImGuiStyleVar_GrabMinSize + { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, GrabRounding) }, // ImGuiStyleVar_GrabRounding { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, ButtonTextAlign) }, // ImGuiStyleVar_ButtonTextAlign }; static const ImGuiStyleVarInfo* GetStyleVarInfo(ImGuiStyleVar idx) { IM_ASSERT(idx >= 0 && idx < ImGuiStyleVar_Count_); + IM_ASSERT(IM_ARRAYSIZE(GStyleVarInfo) == ImGuiStyleVar_Count_); return &GStyleVarInfo[idx]; } diff --git a/imgui.h b/imgui.h index 6d411738a..6b2d5c6fb 100644 --- a/imgui.h +++ b/imgui.h @@ -751,6 +751,7 @@ enum ImGuiStyleVar_ ImGuiStyleVar_WindowRounding, // float WindowRounding ImGuiStyleVar_WindowBorderSize, // float WindowBorderSize ImGuiStyleVar_WindowMinSize, // ImVec2 WindowMinSize + ImGuiStyleVar_WindowTitleAlign, // ImVec2 WindowTitleAlign ImGuiStyleVar_ChildRounding, // float ChildRounding ImGuiStyleVar_ChildBorderSize, // float ChildBorderSize ImGuiStyleVar_PopupRounding, // float PopupRounding @@ -761,7 +762,10 @@ enum ImGuiStyleVar_ ImGuiStyleVar_ItemSpacing, // ImVec2 ItemSpacing ImGuiStyleVar_ItemInnerSpacing, // ImVec2 ItemInnerSpacing ImGuiStyleVar_IndentSpacing, // float IndentSpacing + ImGuiStyleVar_ScrollbarSize, // float ScrollbarSize + ImGuiStyleVar_ScrollbarRounding, // float ScrollbarRounding ImGuiStyleVar_GrabMinSize, // float GrabMinSize + ImGuiStyleVar_GrabRounding, // float GrabRounding ImGuiStyleVar_ButtonTextAlign, // ImVec2 ButtonTextAlign ImGuiStyleVar_Count_ From db2ba13154e9c87b189f90e66bf2afd099d59045 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 12 Jan 2018 20:07:01 +0100 Subject: [PATCH 907/921] Internals: Exposed SetCurrentFont() in imgui_internal.h --- imgui.cpp | 3 +-- imgui_internal.h | 2 ++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 3f0ad4e5d..965ea6999 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -644,7 +644,6 @@ static bool IsKeyPressedMap(ImGuiKey key, bool repeat = true); static ImFont* GetDefaultFont(); -static void SetCurrentFont(ImFont* font); static void SetCurrentWindow(ImGuiWindow* window); static void SetWindowScrollX(ImGuiWindow* window, float new_scroll_x); static void SetWindowScrollY(ImGuiWindow* window, float new_scroll_y); @@ -5276,7 +5275,7 @@ static ImFont* GetDefaultFont() return g.IO.FontDefault ? g.IO.FontDefault : g.IO.Fonts->Fonts[0]; } -static void SetCurrentFont(ImFont* font) +void ImGui::SetCurrentFont(ImFont* font) { ImGuiContext& g = *GImGui; IM_ASSERT(font && font->IsLoaded()); // Font Atlas not created. Did you call io.Fonts->GetTexDataAsRGBA32 / GetTexDataAsAlpha8 ? diff --git a/imgui_internal.h b/imgui_internal.h index 7fe6dffa9..1acb45ec1 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -887,6 +887,8 @@ namespace ImGui IMGUI_API void PushItemFlag(ImGuiItemFlags option, bool enabled); IMGUI_API void PopItemFlag(); + IMGUI_API void SetCurrentFont(ImFont* font); + IMGUI_API void OpenPopupEx(ImGuiID id); IMGUI_API void ClosePopup(ImGuiID id); IMGUI_API bool IsPopupOpen(ImGuiID id); From 2645ab5f7f0be479abe45490e186db44e7083018 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 23 Jan 2018 17:05:15 +0100 Subject: [PATCH 908/921] Comments + added legacy renamed GetItemsLineHeightWithSpacing() as stated in the doc, fixes 6190ab008420087c6d0dbbb64e55d668e66a91c0 --- imgui.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/imgui.h b/imgui.h index 6b2d5c6fb..2ec07ec0d 100644 --- a/imgui.h +++ b/imgui.h @@ -1001,6 +1001,7 @@ namespace ImGui static inline bool IsRootWindowFocused() { return IsWindowFocused(ImGuiFocusedFlags_RootWindow); } static inline bool IsRootWindowOrAnyChildFocused() { return IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows); } static inline void SetNextWindowContentWidth(float w) { SetNextWindowContentSize(ImVec2(w, 0.0f)); } + static inline float GetItemsLineHeightWithSpacing() { return GetFrameHeightWithSpacing(); } // OBSOLETED in 1.52 (between Aug 2017 and Oct 2017) bool Begin(const char* name, bool* p_open, const ImVec2& size_on_first_use, float bg_alpha_override = -1.0f, ImGuiWindowFlags flags = 0); // Use SetNextWindowSize() instead if you want to set a window size. static inline bool IsRootWindowOrAnyChildHovered() { return IsItemHovered(ImGuiHoveredFlags_RootAndChildWindows); } @@ -1423,6 +1424,7 @@ struct ImDrawList int _ChannelsCount; // [Internal] number of active channels (1+) ImVector _Channels; // [Internal] draw channels for columns API (not resized down so _ChannelsCount may be smaller than _Channels.Size) + // If you want to create ImDrawList instances, pass them ImGui::GetDrawListSharedData() or create and use your own ImDrawListSharedData (so you can use ImDrawList without ImGui) ImDrawList(const ImDrawListSharedData* shared_data) { _Data = shared_data; _OwnerName = NULL; Clear(); } ~ImDrawList() { ClearFreeMemory(); } IMGUI_API void PushClipRect(ImVec2 clip_rect_min, ImVec2 clip_rect_max, bool intersect_with_current_clip_rect = false); // Render-level scissoring. This is passed down to your render function but not used for CPU-side coarse clipping. Prefer using higher-level ImGui::PushClipRect() to affect logic (hit-testing and widget culling) From 9a76fd30fd21d0c4f6403b27a235b883ece71f28 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 23 Jan 2018 19:13:49 +0100 Subject: [PATCH 909/921] Added SetNextWindowBgAlpha() helper. (#1567) particularly helpul with the marking of the old 5-parameters version of Begin() as obsolete. --- imgui.cpp | 31 +++++++++++++++---------------- imgui.h | 1 + imgui_demo.cpp | 3 +-- imgui_internal.h | 7 +++++-- 4 files changed, 22 insertions(+), 20 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 965ea6999..1c32c3220 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4803,8 +4803,10 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) } else { - // Window background, Default Alpha + // Window background ImU32 bg_col = GetColorU32(GetWindowBgColorIdxFromFlags(flags)); + if (g.NextWindowData.BgAlphaCond != 0) + bg_col = (bg_col & ~IM_COL32_A_MASK) | (IM_F32_TO_INT8_SAT(g.NextWindowData.BgAlphaVal) << IM_COL32_A_SHIFT); window->DrawList->AddRectFilled(window->Pos+ImVec2(0,window->TitleBarHeight()), window->Pos+window->Size, bg_col, window_rounding, (flags & ImGuiWindowFlags_NoTitleBar) ? ImDrawCornerFlags_All : ImDrawCornerFlags_Bot); // Title bar @@ -5010,22 +5012,12 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us { // Old API feature: we could pass the initial window size as a parameter, however this was very misleading because in most cases it would only affect the window when it didn't have storage in the .ini file. if (size_on_first_use.x != 0.0f || size_on_first_use.y != 0.0f) - SetNextWindowSize(size_on_first_use, ImGuiCond_FirstUseEver); + ImGui::SetNextWindowSize(size_on_first_use, ImGuiCond_FirstUseEver); - // Old API feature: we could override the window background alpha with a parameter. This is actually tricky to reproduce manually because: - // (1) there are multiple variants of WindowBg (popup, tooltip, etc.) and (2) you can't call PushStyleColor before Begin and PopStyleColor just after Begin() because of how CheckStackSizes() behave. - // The user-side solution is to do backup = GetStyleColorVec4(ImGuiCol_xxxBG), PushStyleColor(ImGuiCol_xxxBg), Begin, PushStyleColor(ImGuiCol_xxxBg, backup), [...], PopStyleColor(), End(); PopStyleColor() - which is super awkward. - // The alpha override was rarely used but for now we'll leave the Begin() variant around for a bit. We may either lift the constraint on CheckStackSizes() either add a SetNextWindowBgAlpha() helper that does it magically. - ImGuiContext& g = *GImGui; - const ImGuiCol bg_color_idx = GetWindowBgColorIdxFromFlags(flags); - const ImVec4 bg_color_backup = g.Style.Colors[bg_color_idx]; - if (bg_alpha_override >= 0.0f) - g.Style.Colors[bg_color_idx].w = bg_alpha_override; + // Old API feature: override the window background alpha with a parameter. + ImGui::SetNextWindowBgAlpha(bg_alpha_override); - bool ret = Begin(name, p_open, flags); - - if (bg_alpha_override >= 0.0f) - g.Style.Colors[bg_color_idx] = bg_color_backup; + bool ret = ImGui::Begin(name, p_open, flags); return ret; } #endif // IMGUI_DISABLE_OBSOLETE_FUNCTIONS @@ -5803,7 +5795,14 @@ void ImGui::SetNextWindowCollapsed(bool collapsed, ImGuiCond cond) void ImGui::SetNextWindowFocus() { ImGuiContext& g = *GImGui; - g.NextWindowData.FocusCond = ImGuiCond_Always; + g.NextWindowData.FocusCond = ImGuiCond_Always; // Using a Cond member for consistency (may transition all of them to single flag set for fast Clear() op) +} + +void ImGui::SetNextWindowBgAlpha(float alpha) +{ + ImGuiContext& g = *GImGui; + g.NextWindowData.BgAlphaVal = alpha; + g.NextWindowData.BgAlphaCond = ImGuiCond_Always; // Using a Cond member for consistency (may transition all of them to single flag set for fast Clear() op) } // In window space (not screen space!) diff --git a/imgui.h b/imgui.h index 2ec07ec0d..2486ffd03 100644 --- a/imgui.h +++ b/imgui.h @@ -171,6 +171,7 @@ namespace ImGui IMGUI_API void SetNextWindowContentSize(const ImVec2& size); // set next window content size (~ enforce the range of scrollbars). not including window decorations (title bar, menu bar, etc.). set an axis to 0.0f to leave it automatic. call before Begin() IMGUI_API void SetNextWindowCollapsed(bool collapsed, ImGuiCond cond = 0); // set next window collapsed state. call before Begin() IMGUI_API void SetNextWindowFocus(); // set next window to be focused / front-most. call before Begin() + IMGUI_API void SetNextWindowBgAlpha(float alpha); // set next window background color alpha. helper to easily modify ImGuiCol_WindowBg/ChildBg/PopupBg. IMGUI_API void SetWindowPos(const ImVec2& pos, ImGuiCond cond = 0); // (not recommended) set current window position - call within Begin()/End(). prefer using SetNextWindowPos(), as this may incur tearing and side-effects. IMGUI_API void SetWindowSize(const ImVec2& size, ImGuiCond cond = 0); // (not recommended) set current window size - call within Begin()/End(). set to ImVec2(0,0) to force an auto-fit. prefer using SetNextWindowSize(), as this may incur tearing and minor side-effects. IMGUI_API void SetWindowCollapsed(bool collapsed, ImGuiCond cond = 0); // (not recommended) set current window collapsed state. prefer using SetNextWindowCollapsed(). diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 87e4f57cf..9c49281fb 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -2398,7 +2398,7 @@ static void ShowExampleAppFixedOverlay(bool* p_open) ImVec2 window_pos = ImVec2((corner & 1) ? ImGui::GetIO().DisplaySize.x - DISTANCE : DISTANCE, (corner & 2) ? ImGui::GetIO().DisplaySize.y - DISTANCE : DISTANCE); ImVec2 window_pos_pivot = ImVec2((corner & 1) ? 1.0f : 0.0f, (corner & 2) ? 1.0f : 0.0f); ImGui::SetNextWindowPos(window_pos, ImGuiCond_Always, window_pos_pivot); - ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(0.0f, 0.0f, 0.0f, 0.3f)); // Transparent background + ImGui::SetNextWindowBgAlpha(0.3f); // Transparent background if (ImGui::Begin("Example: Fixed Overlay", p_open, ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoSavedSettings)) { ImGui::Text("Simple overlay\nin the corner of the screen.\n(right-click to change position)"); @@ -2415,7 +2415,6 @@ static void ShowExampleAppFixedOverlay(bool* p_open) } ImGui::End(); } - ImGui::PopStyleColor(); } // Demonstrate using "##" and "###" in identifiers to manipulate ID generation. diff --git a/imgui_internal.h b/imgui_internal.h index 1acb45ec1..b30dde60d 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -467,6 +467,7 @@ struct ImGuiNextWindowData ImGuiCond CollapsedCond; ImGuiCond SizeConstraintCond; ImGuiCond FocusCond; + ImGuiCond BgAlphaCond; ImVec2 PosVal; ImVec2 PosPivotVal; ImVec2 SizeVal; @@ -475,21 +476,23 @@ struct ImGuiNextWindowData ImRect SizeConstraintRect; // Valid if 'SetNextWindowSizeConstraint' is true ImGuiSizeCallback SizeCallback; void* SizeCallbackUserData; + float BgAlphaVal; ImGuiNextWindowData() { - PosCond = SizeCond = ContentSizeCond = CollapsedCond = SizeConstraintCond = FocusCond = 0; + PosCond = SizeCond = ContentSizeCond = CollapsedCond = SizeConstraintCond = FocusCond = BgAlphaCond = 0; PosVal = PosPivotVal = SizeVal = ImVec2(0.0f, 0.0f); ContentSizeVal = ImVec2(0.0f, 0.0f); CollapsedVal = false; SizeConstraintRect = ImRect(); SizeCallback = NULL; SizeCallbackUserData = NULL; + BgAlphaVal = FLT_MAX; } void Clear() { - PosCond = SizeCond = ContentSizeCond = CollapsedCond = SizeConstraintCond = FocusCond = 0; + PosCond = SizeCond = ContentSizeCond = CollapsedCond = SizeConstraintCond = FocusCond = BgAlphaCond = 0; } }; From f6ee8d30fb29a40888118e1e1e1dcc7bf14dc3c5 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 23 Jan 2018 19:21:17 +0100 Subject: [PATCH 910/921] Comments (#1567) --- imgui.cpp | 13 ++++++------- imgui.h | 2 +- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 1c32c3220..a852867b1 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -5006,19 +5006,18 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) return !window->SkipItems; } -// Old Begin() API with 5 parameters, avoid calling this version directly! Use SetNextWindowSize()+Begin() instead. +// Old Begin() API with 5 parameters, avoid calling this version directly! Use SetNextWindowSize()/SetNextWindowBgAlpha() + Begin() instead. #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS -bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_use, float bg_alpha_override, ImGuiWindowFlags flags) +bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_first_use, float bg_alpha_override, ImGuiWindowFlags flags) { - // Old API feature: we could pass the initial window size as a parameter, however this was very misleading because in most cases it would only affect the window when it didn't have storage in the .ini file. - if (size_on_first_use.x != 0.0f || size_on_first_use.y != 0.0f) - ImGui::SetNextWindowSize(size_on_first_use, ImGuiCond_FirstUseEver); + // Old API feature: we could pass the initial window size as a parameter. This was misleading because it only had an effect if the window didn't have data in the .ini file. + if (size_first_use.x != 0.0f || size_first_use.y != 0.0f) + ImGui::SetNextWindowSize(size_first_use, ImGuiCond_FirstUseEver); // Old API feature: override the window background alpha with a parameter. ImGui::SetNextWindowBgAlpha(bg_alpha_override); - bool ret = ImGui::Begin(name, p_open, flags); - return ret; + return ImGui::Begin(name, p_open, flags); } #endif // IMGUI_DISABLE_OBSOLETE_FUNCTIONS diff --git a/imgui.h b/imgui.h index 2486ffd03..a0453eeac 100644 --- a/imgui.h +++ b/imgui.h @@ -1004,7 +1004,7 @@ namespace ImGui static inline void SetNextWindowContentWidth(float w) { SetNextWindowContentSize(ImVec2(w, 0.0f)); } static inline float GetItemsLineHeightWithSpacing() { return GetFrameHeightWithSpacing(); } // OBSOLETED in 1.52 (between Aug 2017 and Oct 2017) - bool Begin(const char* name, bool* p_open, const ImVec2& size_on_first_use, float bg_alpha_override = -1.0f, ImGuiWindowFlags flags = 0); // Use SetNextWindowSize() instead if you want to set a window size. + bool Begin(const char* name, bool* p_open, const ImVec2& size_on_first_use, float bg_alpha_override = -1.0f, ImGuiWindowFlags flags = 0); // Use SetNextWindowSize(size, ImGuiCond_FirstUseEver) + SetNextWindowBgAlpha() instead. static inline bool IsRootWindowOrAnyChildHovered() { return IsItemHovered(ImGuiHoveredFlags_RootAndChildWindows); } static inline void AlignFirstTextHeightToWidgets() { AlignTextToFramePadding(); } static inline void SetNextWindowPosCenter(ImGuiCond c=0) { ImGuiIO& io = GetIO(); SetNextWindowPos(ImVec2(io.DisplaySize.x * 0.5f, io.DisplaySize.y * 0.5f), c, ImVec2(0.5f, 0.5f)); } From 37ee99983fe94bc292d6c76c35a2bccf45c3d92e Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 24 Jan 2018 15:09:02 +0100 Subject: [PATCH 911/921] Clear BgAlphaCond properly after consuming it. Fixes 9a76fd30fd21d0c4f6403b27a235b883ece71f28 (#1567) --- imgui.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/imgui.cpp b/imgui.cpp index a852867b1..8d9c1a1d4 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4806,7 +4806,10 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // Window background ImU32 bg_col = GetColorU32(GetWindowBgColorIdxFromFlags(flags)); if (g.NextWindowData.BgAlphaCond != 0) + { bg_col = (bg_col & ~IM_COL32_A_MASK) | (IM_F32_TO_INT8_SAT(g.NextWindowData.BgAlphaVal) << IM_COL32_A_SHIFT); + g.NextWindowData.BgAlphaCond = 0; + } window->DrawList->AddRectFilled(window->Pos+ImVec2(0,window->TitleBarHeight()), window->Pos+window->Size, bg_col, window_rounding, (flags & ImGuiWindowFlags_NoTitleBar) ? ImDrawCornerFlags_All : ImDrawCornerFlags_Bot); // Title bar From 5148937d4dbcad9e8564375dfb29dce5b8bb6a38 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 24 Jan 2018 17:39:21 +0100 Subject: [PATCH 912/921] Fixed old Begin() calling SetNextWindowBgAlpha() with negative values. (#1567, #1568) --- imgui.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 8d9c1a1d4..b5aa30e1f 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -5018,7 +5018,8 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_first_use, ImGui::SetNextWindowSize(size_first_use, ImGuiCond_FirstUseEver); // Old API feature: override the window background alpha with a parameter. - ImGui::SetNextWindowBgAlpha(bg_alpha_override); + if (bg_alpha_override >= 0.0f) + ImGui::SetNextWindowBgAlpha(bg_alpha_override); return ImGui::Begin(name, p_open, flags); } From 277f6e7842e2a1464bde74457cce1ae21068cadd Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 24 Jan 2018 18:40:23 +0100 Subject: [PATCH 913/921] Examples: Comments --- examples/README.txt | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/examples/README.txt b/examples/README.txt index 1f00756f1..cf99c5dc3 100644 --- a/examples/README.txt +++ b/examples/README.txt @@ -1,10 +1,13 @@ -Those are standalone ready-to-build applications to demonstrate ImGui. +Those are standalone ready-to-build applications to demonstrate Dear ImGui. Binaries of some of those demos: http://www.miracleworld.net/imgui/binaries -Third party languages and frameworks bindings: https://github.com/ocornut/imgui/wiki/Links -(languages: C, .net, rust, D, Python, Lua..) -(frameworks: DX12, Vulkan, Cinder, OpenGLES, openFrameworks, Cocos2d-x, SFML, Flexium, NanoRT, Irrlicht..) -(extras: RemoteImGui, ImWindow, imgui_wm..) +Third party languages and frameworks bindings: + https://github.com/ocornut/imgui/wiki/Links +(languages: C, C#, ChaiScript, D, Go, Haxe, Odin, Python, Rust, Lua, Pascal) +(frameworks: DX12, OpenGLES, FreeGlut, Cinder, Cocos2d-x, SFML, GML/GameMaker Studio, Irrlicht, Ogre, + OpenSceneGraph, openFrameworks, LOVE, NanoRT, Qt3d, SFML, Unreal Engine 4, etc.) +(extras: RemoteImGui, ImWindow, imgui_wm, etc.) + TL;DR; - Newcomers, read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup ImGui in your codebase. @@ -19,14 +22,14 @@ TL;DR; existing rendering backends, don't feel forced to rewrite them with your own engine API, or you can do that later when you already got things to work. -ImGui is highly portable and only requires a few things to run: +Dear ImGui is highly portable and only requires a few things to run and render. - Providing mouse/keyboard inputs - Load the font atlas texture into graphics memory - Providing a render function to render indexed textured triangles - Optional: clipboard support, mouse cursor supports, Windows IME support, etc. So this is essentially what those examples are doing + the obligatory cruft for portability. -Unfortunately in 2016 it is still tedious to create and maintain portable build files using external +Unfortunately in 2018 it is still tedious to create and maintain portable build files using external libraries (the kind we're using here to create a window and render 3D triangles) without relying on third party software. For most examples here I choose to provide: - Makefiles for Linux/OSX @@ -36,14 +39,15 @@ Please let me know if they don't work with your setup! You can probably just import the imgui_impl_xxx.cpp/.h files into your own codebase or compile those directly with a command-line compiler. -ImGui has zero frame of lag for most behaviors and one frame of lag for some behaviors. -At 60 FPS your experience should be pleasant. Consider that OS mouse cursors are typically drawn through -a specific hardware accelerated route and may feel smoother than other GPU rendered contents. You may -experiment with the io.MouseDrawCursor flag to request ImGui to draw a mouse cursor itself, to visualize -the lag between a hardware cursor and a software cursor. It might be beneficial to the user experience -to switch to a software rendered cursor when an interactive drag is in progress. -Also note that some setup or GPU drivers may be causing extra lag (possibly by enforcing triple buffering), -leaving you with no option but sadness/anger (Intel GPU drivers were reported as such). +Dear ImGui has zero to one frame of lag for most behaviors, at 60 FPS your experience should be pleasant. +Consider that OS mouse cursors are typically drawn through a specific hardware accelerated route and may +feel smoother than other GPU rendered contents. You may experiment with the io.MouseDrawCursor flag to +request ImGui to draw a mouse cursor itself, to visualize the lag between a hardware cursor and a software +cursor. It might be beneficial to the user experience to switch to a software rendered cursor when an +interactive drag is in progress. +Also note that some setup or GPU drivers may be causing extra lag (possibly by enforcing triple buffering), +leaving you with little option but sadness (Intel GPU drivers were reported as such). + opengl2_example/ **DO NOT USE THIS CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL (SHADERS, VBO, VAO, etc.)** @@ -99,4 +103,4 @@ vulkan_example/ Vulkan example. This is quite long and tedious, because: Vulkan. -TODO: Apple, SDL GL/GL3, Allegro, Marmalade, Vulkan examples do not honor the io.WantMoveMouse flag. +TODO: Apple, SDL GL2/GL3, Allegro, Marmalade, Vulkan examples do not honor the io.WantMoveMouse flag. From c2e92ab61bf4ead7f1b219debbf993f3c6247818 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 24 Jan 2018 18:40:54 +0100 Subject: [PATCH 914/921] Added imgui.natvis helper for visual studio users. Added to examples projects. --- .../directx10_example.vcxproj | 1 + .../directx10_example.vcxproj.filters | 3 ++ .../directx11_example.vcxproj | 1 + .../directx11_example.vcxproj.filters | 3 ++ .../directx9_example/directx9_example.vcxproj | 1 + .../directx9_example.vcxproj.filters | 3 ++ examples/libs/imgui.natvis | 35 +++++++++++++++++++ .../opengl2_example/opengl2_example.vcxproj | 1 + .../opengl2_example.vcxproj.filters | 3 ++ .../opengl3_example/opengl3_example.vcxproj | 1 + .../opengl3_example.vcxproj.filters | 3 ++ 11 files changed, 55 insertions(+) create mode 100644 examples/libs/imgui.natvis diff --git a/examples/directx10_example/directx10_example.vcxproj b/examples/directx10_example/directx10_example.vcxproj index 8583e1dec..3a403518e 100644 --- a/examples/directx10_example/directx10_example.vcxproj +++ b/examples/directx10_example/directx10_example.vcxproj @@ -153,6 +153,7 @@
+ diff --git a/examples/directx10_example/directx10_example.vcxproj.filters b/examples/directx10_example/directx10_example.vcxproj.filters index 15e924c44..5a358463e 100644 --- a/examples/directx10_example/directx10_example.vcxproj.filters +++ b/examples/directx10_example/directx10_example.vcxproj.filters @@ -41,5 +41,8 @@ + + sources + \ No newline at end of file diff --git a/examples/directx11_example/directx11_example.vcxproj b/examples/directx11_example/directx11_example.vcxproj index 7099a7bd4..347b4f007 100644 --- a/examples/directx11_example/directx11_example.vcxproj +++ b/examples/directx11_example/directx11_example.vcxproj @@ -153,6 +153,7 @@ + diff --git a/examples/directx11_example/directx11_example.vcxproj.filters b/examples/directx11_example/directx11_example.vcxproj.filters index 5cd0ca415..a79484cc1 100644 --- a/examples/directx11_example/directx11_example.vcxproj.filters +++ b/examples/directx11_example/directx11_example.vcxproj.filters @@ -41,5 +41,8 @@ + + sources + \ No newline at end of file diff --git a/examples/directx9_example/directx9_example.vcxproj b/examples/directx9_example/directx9_example.vcxproj index 6fe7c9cec..e63bd35b5 100644 --- a/examples/directx9_example/directx9_example.vcxproj +++ b/examples/directx9_example/directx9_example.vcxproj @@ -153,6 +153,7 @@ + diff --git a/examples/directx9_example/directx9_example.vcxproj.filters b/examples/directx9_example/directx9_example.vcxproj.filters index 5cf028343..b0843b397 100644 --- a/examples/directx9_example/directx9_example.vcxproj.filters +++ b/examples/directx9_example/directx9_example.vcxproj.filters @@ -42,5 +42,8 @@ + + sources + \ No newline at end of file diff --git a/examples/libs/imgui.natvis b/examples/libs/imgui.natvis new file mode 100644 index 000000000..807129ad0 --- /dev/null +++ b/examples/libs/imgui.natvis @@ -0,0 +1,35 @@ + + + + + + + + {{Size={Size} Capacity={Capacity}}} + + + Size + Data + + + + + + {{x={x,g} y={y,g}}} + + + + {{x={x,g} y={y,g} z={z,g} w={w,g}}} + + + + {{Min=({Min.x,g} {Min.y,g}) Max=({Max.x,g} {Max.y,g}) Size=({Max.x-Min.x,g} {Max.y-Min.y,g})}} + + Min + Max + Max.x - Min.x + Max.x - Min.x + + + + \ No newline at end of file diff --git a/examples/opengl2_example/opengl2_example.vcxproj b/examples/opengl2_example/opengl2_example.vcxproj index 237eba7da..bf1a3ed4e 100644 --- a/examples/opengl2_example/opengl2_example.vcxproj +++ b/examples/opengl2_example/opengl2_example.vcxproj @@ -163,6 +163,7 @@ + diff --git a/examples/opengl2_example/opengl2_example.vcxproj.filters b/examples/opengl2_example/opengl2_example.vcxproj.filters index 3cc7ee9e1..35fd6ffaf 100644 --- a/examples/opengl2_example/opengl2_example.vcxproj.filters +++ b/examples/opengl2_example/opengl2_example.vcxproj.filters @@ -42,5 +42,8 @@ + + sources + \ No newline at end of file diff --git a/examples/opengl3_example/opengl3_example.vcxproj b/examples/opengl3_example/opengl3_example.vcxproj index d481c943a..2a78226f7 100644 --- a/examples/opengl3_example/opengl3_example.vcxproj +++ b/examples/opengl3_example/opengl3_example.vcxproj @@ -166,6 +166,7 @@ + diff --git a/examples/opengl3_example/opengl3_example.vcxproj.filters b/examples/opengl3_example/opengl3_example.vcxproj.filters index f19cd16b2..c743ace31 100644 --- a/examples/opengl3_example/opengl3_example.vcxproj.filters +++ b/examples/opengl3_example/opengl3_example.vcxproj.filters @@ -54,5 +54,8 @@ + + sources + \ No newline at end of file From 6f27d6b5b892a5a762c1d0db27434ccd46f75626 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 24 Jan 2018 18:52:26 +0100 Subject: [PATCH 915/921] Natvis: Made ImGuiWindow display shorter. --- examples/libs/imgui.natvis | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/examples/libs/imgui.natvis b/examples/libs/imgui.natvis index 807129ad0..eb32708d9 100644 --- a/examples/libs/imgui.natvis +++ b/examples/libs/imgui.natvis @@ -31,5 +31,10 @@ Max.x - Min.x + + + {{Name={Name,s}}} + {{Name={Name,s}} Inactive} + \ No newline at end of file From 8c57d8cc1e34c2cbf0529296cec8280876b58d9d Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 24 Jan 2018 19:10:09 +0100 Subject: [PATCH 916/921] Natvis: Fix ImRect expanded height display being broken and dumb. (#1569) --- examples/libs/imgui.natvis | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/libs/imgui.natvis b/examples/libs/imgui.natvis index eb32708d9..38c676c75 100644 --- a/examples/libs/imgui.natvis +++ b/examples/libs/imgui.natvis @@ -28,7 +28,7 @@ Min Max Max.x - Min.x - Max.x - Min.x + Max.y - Min.y From 2c7324da56fc4ceec73eeb603c4222c9ff66ade7 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 25 Jan 2018 12:38:15 +0100 Subject: [PATCH 917/921] TODO list, added uSynergy README --- TODO.txt | 4 ++++ examples/libs/usynergy/README.txt | 8 ++++++++ 2 files changed, 12 insertions(+) create mode 100644 examples/libs/usynergy/README.txt diff --git a/TODO.txt b/TODO.txt index a9bc641e7..3a6535a03 100644 --- a/TODO.txt +++ b/TODO.txt @@ -162,6 +162,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - shortcuts,menus: global-style shortcut api e.g. "Save (CTRL+S)" -> explicit flag for recursing into closed menu - shortcuts: programmatically access shortcuts "Focus("&Save")) - menus: menubars: main menu-bar could affect clamping of windows position (~ akin to modifying DisplayMin) + - menus: hovering from menu to menu on a menu-bar has 1 frame without any menu, which is a little annoying. ideally either 0 either longer. - text: selectable text (for copy) as a generic feature (ItemFlags?) - text: proper alignment options in imgui_internal.h @@ -175,6 +176,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - tree node: try to apply scrolling at time of TreePop() if node was just opened and end of node is past scrolling limits? - tree node / selectable render mismatch which is visible if you use them both next to each other (e.g. cf. property viewer) - tree node: tweak color scheme to distinguish headers from selected tree node (#581) + - tree node: leaf/non-leaf highlight mismatch. !- settings: expose enough to save/load .ini from RAM instead of fopen - settings: write more decent code to allow saving/loading new fields: columns, selected tree nodes? @@ -246,6 +248,8 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - misc: fix for compilation settings where stdcall isn't the default (e.g. vectorcall) (#1230) - remote: make a system like RemoteImGui first-class citizen/project (#75) + - natvis: more the imgui.natvis file in a better location. perhaps reorganize extra_fonts/? (#1569) + - demo: add vertical separator demo - demo: add virtual scrolling example? - examples: directx9: save/restore device state more thoroughly. diff --git a/examples/libs/usynergy/README.txt b/examples/libs/usynergy/README.txt new file mode 100644 index 000000000..c86b90965 --- /dev/null +++ b/examples/libs/usynergy/README.txt @@ -0,0 +1,8 @@ + +uSynergy client -- Implementation for the embedded Synergy client library +version 1.0.0, July 7th, 2012 +Copyright (c) 2012 Alex Evans + +This is a copy of the files once found at: + https://github.com/symless/synergy-core/tree/790d108a56ada9caad8e56ff777d444485a69da9/src/micro + From c226e02ca02dd42ba4ccfc0650cabba484c7366e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Pasquier?= Date: Thu, 25 Jan 2018 13:27:57 +0100 Subject: [PATCH 918/921] Fix sdl_opengl2_example filename in README.md's build instructions --- examples/sdl_opengl2_example/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/sdl_opengl2_example/README.md b/examples/sdl_opengl2_example/README.md index deae32392..a1a44a584 100644 --- a/examples/sdl_opengl2_example/README.md +++ b/examples/sdl_opengl2_example/README.md @@ -5,18 +5,18 @@ ``` set SDL2DIR=path_to_your_sdl2_folder -cl /Zi /MD /I %SDL2DIR%\include /I ..\.. main.cpp imgui_impl_sdl.cpp ..\..\imgui*.cpp /link /LIBPATH:%SDL2DIR%\lib SDL2.lib SDL2main.lib opengl32.lib /subsystem:console +cl /Zi /MD /I %SDL2DIR%\include /I ..\.. main.cpp imgui_impl_sdl_gl2.cpp ..\..\imgui*.cpp /link /LIBPATH:%SDL2DIR%\lib SDL2.lib SDL2main.lib opengl32.lib /subsystem:console ``` - On Linux and similar Unixes ``` -c++ `sdl2-config --cflags` -I ../.. main.cpp imgui_impl_sdl.cpp ../../imgui*.cpp `sdl2-config --libs` -lGL -o sdl2example +c++ `sdl2-config --cflags` -I ../.. main.cpp imgui_impl_sdl_gl2.cpp ../../imgui*.cpp `sdl2-config --libs` -lGL -o sdl2example ``` - On Mac OS X ``` brew install sdl2 -c++ `sdl2-config --cflags` -I ../.. main.cpp imgui_impl_sdl.cpp ../../imgui*.cpp `sdl2-config --libs` -framework OpenGl -o sdl2example +c++ `sdl2-config --cflags` -I ../.. main.cpp imgui_impl_sdl_gl2.cpp ../../imgui*.cpp `sdl2-config --libs` -framework OpenGl -o sdl2example ``` From 94ed44b5cbdeec85c3d4961c0382b7393b7b509c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Pasquier?= Date: Thu, 25 Jan 2018 13:33:35 +0100 Subject: [PATCH 919/921] Fix allegro5_example build instructions --- examples/allegro5_example/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/allegro5_example/README.md b/examples/allegro5_example/README.md index d891982b7..dcd83b8a9 100644 --- a/examples/allegro5_example/README.md +++ b/examples/allegro5_example/README.md @@ -4,7 +4,7 @@ - On Ubuntu 14.04+ ```bash -g++ -I ../imgui main.cpp imgui_impl_a5.cpp ../imgui/imgui*.cpp -lallegro -lallegro_primitives +g++ -I ../.. main.cpp imgui_impl_a5.cpp ../../imgui*.cpp -lallegro -lallegro_primitives -o allegro5_example ``` - On Windows with Visual Studio's CLI From 8bf0c89c0daa1189faccb7ff1c77d32180bf7bd7 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 25 Jan 2018 14:24:57 +0100 Subject: [PATCH 920/921] Internals: ImRect::Contains(ImRect&) include boundaries (whereas Contains(ImVec2) should not). --- imgui_internal.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/imgui_internal.h b/imgui_internal.h index b30dde60d..a00a88a09 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -273,9 +273,9 @@ struct IMGUI_API ImRect ImVec2 GetTR() const { return ImVec2(Max.x, Min.y); } // Top-right ImVec2 GetBL() const { return ImVec2(Min.x, Max.y); } // Bottom-left ImVec2 GetBR() const { return Max; } // Bottom-right - bool Contains(const ImVec2& p) const { return p.x >= Min.x && p.y >= Min.y && p.x < Max.x && p.y < Max.y; } - bool Contains(const ImRect& r) const { return r.Min.x >= Min.x && r.Min.y >= Min.y && r.Max.x < Max.x && r.Max.y < Max.y; } - bool Overlaps(const ImRect& r) const { return r.Min.y < Max.y && r.Max.y > Min.y && r.Min.x < Max.x && r.Max.x > Min.x; } + bool Contains(const ImVec2& p) const { return p.x >= Min.x && p.y >= Min.y && p.x < Max.x && p.y < Max.y; } + bool Contains(const ImRect& r) const { return r.Min.x >= Min.x && r.Min.y >= Min.y && r.Max.x <= Max.x && r.Max.y <= Max.y; } + bool Overlaps(const ImRect& r) const { return r.Min.y < Max.y && r.Max.y > Min.y && r.Min.x < Max.x && r.Max.x > Min.x; } void Add(const ImVec2& p) { if (Min.x > p.x) Min.x = p.x; if (Min.y > p.y) Min.y = p.y; if (Max.x < p.x) Max.x = p.x; if (Max.y < p.y) Max.y = p.y; } void Add(const ImRect& r) { if (Min.x > r.Min.x) Min.x = r.Min.x; if (Min.y > r.Min.y) Min.y = r.Min.y; if (Max.x < r.Max.x) Max.x = r.Max.x; if (Max.y < r.Max.y) Max.y = r.Max.y; } void Expand(const float amount) { Min.x -= amount; Min.y -= amount; Max.x += amount; Max.y += amount; } From 5d31e1696f83601ae1b323dc4e51d532c4eb238a Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 25 Jan 2018 15:37:24 +0100 Subject: [PATCH 921/921] Fix SetNextWindowContentSize() with 0.0f on Y axis (or SetNextWindowContentWidth()) overwriting the contents size. Broken in eab6333a0b96bd30413bb17408303a5df438ffde. (#1363) --- imgui.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index b5aa30e1f..076eb4b5c 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4544,7 +4544,8 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) { // Adjust passed "client size" to become a "window size" window->SizeContentsExplicit = g.NextWindowData.ContentSizeVal; - window->SizeContentsExplicit.y += window->TitleBarHeight() + window->MenuBarHeight(); + if (window->SizeContentsExplicit.y != 0.0f) + window->SizeContentsExplicit.y += window->TitleBarHeight() + window->MenuBarHeight(); g.NextWindowData.ContentSizeCond = 0; } else if (first_begin_of_the_frame)