From f8fede1d8bc2eb2eb5776d3d8426a436622dd96c Mon Sep 17 00:00:00 2001 From: ocornut Date: Sun, 21 Feb 2016 23:23:30 +0100 Subject: [PATCH 001/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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/350] 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 509df3e2790f9fb6162d9cb2a4f2f3dd6465fdb8 Mon Sep 17 00:00:00 2001 From: Marcell Kiss Date: Sat, 11 Feb 2017 12:08:59 +0100 Subject: [PATCH 010/350] 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 011/350] 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 012/350] 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 013/350] 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 014/350] 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 015/350] 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 016/350] 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 017/350] 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 018/350] 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 019/350] 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 020/350] 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 021/350] 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 022/350] 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 023/350] 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 024/350] 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 50b4b29beb5c48a9dde38dd0e240054b9a68b31e Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 26 Apr 2017 18:16:59 +0200 Subject: [PATCH 025/350] 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 026/350] 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 027/350] 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 028/350] 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 029/350] 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 030/350] 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 031/350] 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 032/350] 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 033/350] 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 034/350] 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 035/350] 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 036/350] 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 037/350] 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 038/350] 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 039/350] 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 040/350] 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 041/350] 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 042/350] 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 043/350] 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 044/350] 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 045/350] 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 046/350] 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 047/350] 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 048/350] 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 049/350] 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 050/350] 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 051/350] 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 052/350] 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 053/350] 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 054/350] 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 055/350] 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 056/350] 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 057/350] 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 058/350] 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 059/350] 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 060/350] 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 061/350] 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 062/350] 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 063/350] 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 064/350] 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 065/350] 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 066/350] 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 067/350] 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 068/350] 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 069/350] 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 070/350] 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 071/350] 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 072/350] 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 073/350] 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 074/350] 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 075/350] 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 076/350] 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 077/350] 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 078/350] 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 079/350] 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 080/350] 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 081/350] 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 082/350] 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 083/350] 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 084/350] 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 085/350] 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 086/350] 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 087/350] 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 088/350] 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 089/350] 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 090/350] 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 091/350] 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 092/350] 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 093/350] 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 094/350] 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 095/350] 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 096/350] 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 097/350] 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 098/350] 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 099/350] 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 100/350] 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 101/350] 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 102/350] 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 103/350] 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 104/350] 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 105/350] 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 106/350] 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 107/350] 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 108/350] 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 109/350] 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 110/350] 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 111/350] 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 112/350] 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 113/350] 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 114/350] 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 115/350] 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 116/350] 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 117/350] 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 118/350] 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 119/350] 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 120/350] 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 121/350] 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 122/350] 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 123/350] 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 124/350] 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 125/350] 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 126/350] 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 127/350] 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 128/350] 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 129/350] 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 130/350] 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 131/350] 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 132/350] 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 133/350] 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 134/350] 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 135/350] 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 136/350] 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 137/350] 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 138/350] 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 139/350] 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 140/350] 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 141/350] 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 142/350] 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 143/350] 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 144/350] 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 145/350] 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 146/350] 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 147/350] 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 148/350] 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 149/350] 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 150/350] 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 151/350] 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 152/350] 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 153/350] 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 154/350] 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 155/350] 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 156/350] 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 157/350] 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 158/350] 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 159/350] 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 160/350] 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 161/350] 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 162/350] 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 163/350] 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 164/350] 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 165/350] 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 166/350] 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 167/350] 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 168/350] 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 169/350] 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 170/350] 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 171/350] 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 172/350] 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 173/350] 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 174/350] 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 175/350] 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 176/350] 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 177/350] 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 178/350] 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 179/350] 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 180/350] 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 181/350] 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 182/350] 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 183/350] 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 184/350] 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 185/350] 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 186/350] 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 187/350] 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 188/350] 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 189/350] 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 190/350] 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 191/350] 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 192/350] 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 193/350] 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 194/350] 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 195/350] 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 196/350] 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 197/350] 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 198/350] 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 199/350] 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 200/350] 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 201/350] 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 202/350] 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 203/350] 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 204/350] 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 205/350] 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 206/350] 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 207/350] 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 208/350] 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 209/350] 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 210/350] 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 211/350] 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 212/350] 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 213/350] 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 214/350] 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 215/350] 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 216/350] 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 217/350] 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 218/350] 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 219/350] 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 220/350] 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 221/350] 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 222/350] 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 223/350] 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 224/350] 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 225/350] 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 226/350] 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 227/350] 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 228/350] 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 229/350] (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 230/350] 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 231/350] 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 232/350] 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 233/350] 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 234/350] 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 235/350] 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 236/350] 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 237/350] 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 238/350] 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 239/350] 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 240/350] 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 241/350] 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 242/350] 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 243/350] 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 244/350] 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 245/350] 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 246/350] 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 247/350] 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 248/350] 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 249/350] 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 250/350] 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 251/350] 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 252/350] 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 253/350] 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 254/350] 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 255/350] 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 256/350] 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 257/350] 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 258/350] 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 259/350] 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 260/350] 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 261/350] 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 262/350] 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 263/350] 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 264/350] 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 265/350] 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 266/350] 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 267/350] 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 268/350] 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 269/350] (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 270/350] 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 271/350] 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 272/350] 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 273/350] 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 274/350] 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 275/350] 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 276/350] 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 277/350] 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 278/350] 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 279/350] 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 280/350] 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 281/350] 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 282/350] 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 283/350] 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 284/350] 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 285/350] 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 286/350] 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 287/350] 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 288/350] 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 289/350] 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 290/350] 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 291/350] 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 292/350] 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 293/350] 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 294/350] 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 295/350] 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 296/350] 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 297/350] 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 298/350] 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 299/350] 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 300/350] 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 301/350] 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 302/350] 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 303/350] 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 304/350] 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 305/350] 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 306/350] 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 307/350] 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 308/350] 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 309/350] 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 310/350] 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 311/350] 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 312/350] 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 313/350] 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 314/350] 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 315/350] 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 316/350] 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 317/350] 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 318/350] 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 319/350] 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 320/350] 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 321/350] 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 322/350] 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 323/350] 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 324/350] 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 325/350] 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 326/350] 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 327/350] 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 328/350] 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 329/350] 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 330/350] 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 331/350] 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 332/350] 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 333/350] 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 334/350] 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 335/350] 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 336/350] 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 337/350] 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 338/350] 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 339/350] 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 340/350] 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 341/350] 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 342/350] 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 343/350] 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 344/350] 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 345/350] 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 346/350] 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 347/350] 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 348/350] 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 349/350] 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 350/350] 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();