From f8fede1d8bc2eb2eb5776d3d8426a436622dd96c Mon Sep 17 00:00:00 2001 From: ocornut Date: Sun, 21 Feb 2016 23:23:30 +0100 Subject: [PATCH 01/76] 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 | 363 ++++++++++++++++++++++++++++++++++------------- imgui.h | 27 ++-- imgui_demo.cpp | 13 +- imgui_internal.h | 3 +- 4 files changed, 285 insertions(+), 121 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,137 +8523,302 @@ 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); + + // If no mode is specified default to RGB + if (!(flags & ImGuiColorEditFlags_ModeMask_)) + flags |= ImGuiColorEditFlags_RGB; - ImGuiColorEditMode edit_mode = window->DC.ColorEditMode; - if (edit_mode == ImGuiColorEditMode_UserSelect || edit_mode == ImGuiColorEditMode_UserSelectShowButton) - edit_mode = g.ColorEditModeStorage.GetInt(id, 0) % 3; + // 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_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] = { - // 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))); - - 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(); + { "%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; - case ImGuiColorEditMode_HEX: + ImGui::PopItemWidth(); + ImGui::PopItemWidth(); + } + else if (flags & ImGuiColorEditFlags_HEX) + { + // 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)) { - // RGB Hexadecimal Input - const float w_slider_all = w_full - square_sz; - char buf[64]; + value_changed |= true; + char* p = buf; + while (*p == '#' || ImCharIsSpace(*p)) + p++; + i[0] = i[1] = i[2] = i[3] = 0; if (alpha) - ImFormatString(buf, IM_ARRAYSIZE(buf), "#%02X%02X%02X%02X", i[0], i[1], i[2], i[3]); + 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 - 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)) + 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)) { - 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::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(); } - break; + 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])); } - ImGui::SameLine(0, style.ItemInnerSpacing.x); + if (label != label_display_end) + { + ImGui::SameLine(0, style.ItemInnerSpacing.x); + ImGui::TextUnformatted(label, label_display_end); + } - 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])); + // Convert back + if (!picker_active) + { + 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(); + ImGui::EndGroup(); + + return value_changed; +} + +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)) + 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); - if (window->DC.ColorEditMode == ImGuiColorEditMode_UserSelectShowButton) + // 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()) { - 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! + 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, (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]); + // 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) { - col[0] = f[0]; - col[1] = f[1]; - col[2] = f[2]; - if (alpha) - col[3] = f[3]; + 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]); + } } - ImGui::PopID(); + // 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; } -void ImGui::ColorEditMode(ImGuiColorEditMode mode) -{ - ImGuiWindow* window = GetCurrentWindow(); - window->DC.ColorEditMode = mode; -} - // Horizontal separating line. void ImGui::Separator() { 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 02/76] 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 03/76] 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 04/76] 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 05/76] 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 06/76] 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 97bedd704c495b0759260045744b837e645ea70e Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 21 Jul 2017 03:06:25 +0800 Subject: [PATCH 07/76] 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 08/76] 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 09/76] 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 10/76] 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 11/76] 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 12/76] 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 13/76] 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 14/76] 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 15/76] 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 16/76] 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 4def2ce339ec9e04b0a02fa3e0a28c8cec5fbe2d Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 23 Jul 2017 17:55:39 +0800 Subject: [PATCH 17/76] 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 18/76] 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 19/76] 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 20/76] 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 21/76] 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 95fe11b5bf14f72fc70762347c583d089e619a65 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 26 Jul 2017 14:34:59 +0800 Subject: [PATCH 22/76] 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 23/76] 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 24/76] 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 25/76] 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 26/76] 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 27/76] 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 28/76] 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 29/76] 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 only:"); + 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); + ImGui::ColorEdit4("MyColor##3", (float*)&color, ImGuiColorEditFlags_NoInputs|ImGuiColorEditFlags_NoLabel|(alpha_preview ? 0 : ImGuiColorEditFlags_NoAlphaPreview)); + + ImGui::Text("Color button only:"); + 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 30/76] 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 31/76] 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 32/76] 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 33/76] 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 34/76] 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 35/76] 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 36/76] 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 37/76] 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 38/76] 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 39/76] 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 40/76] 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 41/76] 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 42/76] 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 43/76] 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 44/76] 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 45/76] 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 46/76] 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 47/76] 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 48/76] 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 49/76] 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 50/76] 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 51/76] 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 52/76] 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 53/76] 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 54/76] 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 55/76] 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 56/76] 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 57/76] 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 58/76] 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 59/76] 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 60/76] 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 61/76] 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 62/76] 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 63/76] 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 64/76] ColorPicker: Reordered drawing code to match left-to-right display. Extra comments. (#346) --- imgui.cpp | 47 +++++++++++++++++++++-------------------------- 1 file changed, 21 insertions(+), 26 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 } } + 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)); + + // 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); + + // 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 - 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) }; + 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_colors[i], hue_colors[i], hue_colors[i + 1], hue_colors[i + 1]); - } + 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 - 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)); + 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); } - // 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.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); - EndGroup(); PopID(); From e63ebd997ff7c1d341e5cffd940a64b506aed8ff Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 31 Jul 2017 12:25:27 +0800 Subject: [PATCH 65/76] 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 66/76] 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 67/76] ColorPicker: Rearrange code to introduce alternate HSV picker/selector with simpler diff. (#346) --- imgui.cpp | 78 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 42 insertions(+), 36 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); - - // 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 - 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); + 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 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 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 68/76] 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 69/76] 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 70/76] 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 71/76] 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 72/76] 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 f4c0134f9f62cd6ebbfec9690e98580d24559238 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 6 Aug 2017 18:08:58 +0800 Subject: [PATCH 73/76] 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 d952a8d3bf4f35b99f50ca497f62ad7ae94dcb28 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 8 Aug 2017 14:49:45 +0800 Subject: [PATCH 74/76] 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 75/76] Added SetColorEditOptions(). ColorPicker4: context menu to select picker type and alpha bar. Reorganized flags (again!). (#346) --- imgui.cpp | 166 +++++++++++++++++++++++++++++++++-------------- imgui.h | 47 ++++++++------ imgui_demo.cpp | 8 +++ imgui_internal.h | 3 +- 4 files changed, 152 insertions(+), 72 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 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; - 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_)); + 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 - if (flags & ImGuiColorEditFlags_NoInputs) - flags = (flags & (~ImGuiColorEditFlags_InputsModeMask_)) | ImGuiColorEditFlags_RGB | ImGuiColorEditFlags_NoOptions; + BeginGroup(); + PushID(label); - // If no mode is specified, defaults to RGB - if (!(flags & ImGuiColorEditFlags_InputsModeMask_)) - flags |= ImGuiColorEditFlags_RGB; + // If we're not showing any slider there's no point in doing any HSV conversions + if (flags & ImGuiColorEditFlags_NoInputs) + flags = (flags & (~ImGuiColorEditFlags__InputsMask)) | ImGuiColorEditFlags_RGB | ImGuiColorEditFlags_NoOptions; - // 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 76/76] 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