From 3926bd08e17325b5408333ab53e9140a8227e555 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 29 Jul 2017 17:23:32 +0800 Subject: [PATCH] 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 80031edd..3467c4b3 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 55a553ba..98be6611 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 30e5748d..fec43cdd 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(); }