From fef8aac523c460d0646c5918aa427a539b40a82b Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 30 Jul 2017 16:15:52 +0800 Subject: [PATCH] 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 3467c4b3..7fdb41d2 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 ba4c7807..dcf3664e 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 e3295dc7..8525544b 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