فهرست منبع

ColorPicker / ColorEdit: restore Hue when zeroing Saturation. (#2722, #2770)
Issue is fixed by storing last active color picker color and last hue value when active color picker takes rgb as input. Then if current color picker color matches last active color - hue value will be restored. IDs are not used because ColorEdit4() and ColorWidget4() may call each other in hard-to-predict ways and they both push their own IDs on to the stack. We need hue restoration to happen in entire stack of these widgets if topmost widget used hue restoration. Since these widgets operate on exact same color value - color was chosen as a factor deciding which widgets should restore hue.

Rokas Kupstys 6 سال پیش
والد
کامیت
accb0261b8
2فایلهای تغییر یافته به همراه20 افزوده شده و 0 حذف شده
  1. 2 0
      imgui_internal.h
  2. 18 0
      imgui_widgets.cpp

+ 2 - 0
imgui_internal.h

@@ -1012,6 +1012,8 @@ struct ImGuiContext
     ImFont                  InputTextPasswordFont;
     ImFont                  InputTextPasswordFont;
     ImGuiID                 TempInputTextId;                    // Temporary text input when CTRL+clicking on a slider, etc.
     ImGuiID                 TempInputTextId;                    // Temporary text input when CTRL+clicking on a slider, etc.
     ImGuiColorEditFlags     ColorEditOptions;                   // Store user options for color edit widgets
     ImGuiColorEditFlags     ColorEditOptions;                   // Store user options for color edit widgets
+    float                   ColorEditLastHue;
+    float                   ColorEditLastActiveColor[3];
     ImVec4                  ColorPickerRef;
     ImVec4                  ColorPickerRef;
     bool                    DragCurrentAccumDirty;
     bool                    DragCurrentAccumDirty;
     float                   DragCurrentAccum;                   // Accumulator for dragging modification. Always high-precision, not rounded by end-user precision settings
     float                   DragCurrentAccum;                   // Accumulator for dragging modification. Always high-precision, not rounded by end-user precision settings

+ 18 - 0
imgui_widgets.cpp

@@ -4200,7 +4200,12 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag
     if ((flags & ImGuiColorEditFlags_InputHSV) && (flags & ImGuiColorEditFlags_DisplayRGB))
     if ((flags & ImGuiColorEditFlags_InputHSV) && (flags & ImGuiColorEditFlags_DisplayRGB))
         ColorConvertHSVtoRGB(f[0], f[1], f[2], f[0], f[1], f[2]);
         ColorConvertHSVtoRGB(f[0], f[1], f[2], f[0], f[1], f[2]);
     else if ((flags & ImGuiColorEditFlags_InputRGB) && (flags & ImGuiColorEditFlags_DisplayHSV))
     else if ((flags & ImGuiColorEditFlags_InputRGB) && (flags & ImGuiColorEditFlags_DisplayHSV))
+    {
         ColorConvertRGBtoHSV(f[0], f[1], f[2], f[0], f[1], f[2]);
         ColorConvertRGBtoHSV(f[0], f[1], f[2], f[0], f[1], f[2]);
+        // Hue is lost when converting from greyscale rgb (saturation=0). Restore it.
+        if (f[1] == 0 && memcmp(g.ColorEditLastActiveColor, col, sizeof(float) * 3) == 0)
+            f[0] = g.ColorEditLastHue;
+    }
     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]) };
     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 = false;
@@ -4327,7 +4332,11 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag
             for (int n = 0; n < 4; n++)
             for (int n = 0; n < 4; n++)
                 f[n] = i[n] / 255.0f;
                 f[n] = i[n] / 255.0f;
         if ((flags & ImGuiColorEditFlags_DisplayHSV) && (flags & ImGuiColorEditFlags_InputRGB))
         if ((flags & ImGuiColorEditFlags_DisplayHSV) && (flags & ImGuiColorEditFlags_InputRGB))
+        {
+            g.ColorEditLastHue = f[0];
             ColorConvertHSVtoRGB(f[0], f[1], f[2], f[0], f[1], f[2]);
             ColorConvertHSVtoRGB(f[0], f[1], f[2], f[0], f[1], f[2]);
+            memcpy(g.ColorEditLastActiveColor, f, sizeof(float) * 3);
+        }
         if ((flags & ImGuiColorEditFlags_DisplayRGB) && (flags & ImGuiColorEditFlags_InputHSV))
         if ((flags & ImGuiColorEditFlags_DisplayRGB) && (flags & ImGuiColorEditFlags_InputHSV))
             ColorConvertRGBtoHSV(f[0], f[1], f[2], f[0], f[1], f[2]);
             ColorConvertRGBtoHSV(f[0], f[1], f[2], f[0], f[1], f[2]);
 
 
@@ -4504,7 +4513,12 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl
     float H = col[0], S = col[1], V = col[2];
     float H = col[0], S = col[1], V = col[2];
     float R = col[0], G = col[1], B = col[2];
     float R = col[0], G = col[1], B = col[2];
     if (flags & ImGuiColorEditFlags_InputRGB)
     if (flags & ImGuiColorEditFlags_InputRGB)
+    {
         ColorConvertRGBtoHSV(R, G, B, H, S, V);
         ColorConvertRGBtoHSV(R, G, B, H, S, V);
+        // Hue is lost when converting from greyscale rgb (saturation=0). Restore it.
+        if (S == 0 && memcmp(g.ColorEditLastActiveColor, col, sizeof(float) * 3) == 0)
+            H = g.ColorEditLastHue;
+    }
     else if (flags & ImGuiColorEditFlags_InputHSV)
     else if (flags & ImGuiColorEditFlags_InputHSV)
         ColorConvertHSVtoRGB(H, S, V, R, G, B);
         ColorConvertHSVtoRGB(H, S, V, R, G, B);
 
 
@@ -4628,6 +4642,8 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl
         if (flags & ImGuiColorEditFlags_InputRGB)
         if (flags & ImGuiColorEditFlags_InputRGB)
         {
         {
             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]);
             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]);
+            g.ColorEditLastHue = H;
+            memcpy(g.ColorEditLastActiveColor, col, sizeof(float) * 3);
         }
         }
         else if (flags & ImGuiColorEditFlags_InputHSV)
         else if (flags & ImGuiColorEditFlags_InputHSV)
         {
         {
@@ -4680,7 +4696,9 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl
             R = col[0];
             R = col[0];
             G = col[1];
             G = col[1];
             B = col[2];
             B = col[2];
+            float preserve_hue = H;
             ColorConvertRGBtoHSV(R, G, B, H, S, V);
             ColorConvertRGBtoHSV(R, G, B, H, S, V);
+            H = preserve_hue;                           // Avoids picker losing hue value for 1 frame glitch.
         }
         }
         else if (flags & ImGuiColorEditFlags_InputHSV)
         else if (flags & ImGuiColorEditFlags_InputHSV)
         {
         {