Skip to content

Commit

Permalink
Fix ocornut#2722 - ColorPicker / ColorEdit Widget Wrong Conversion fr…
Browse files Browse the repository at this point in the history
…om HSV to RGB

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.
  • Loading branch information
rokups committed Aug 31, 2019
1 parent 0537ac0 commit a806a3c
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 0 deletions.
2 changes: 2 additions & 0 deletions imgui_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -1012,6 +1012,8 @@ struct ImGuiContext
ImGuiID TempInputTextId; // Temporary text input when CTRL+clicking on a slider, etc.
ImGuiColorEditFlags ColorEditOptions; // Store user options for color edit widgets
ImVec4 ColorPickerRef;
float ColorPickerLastHue;
float ColorPickerLastActiveColor[3];
bool DragCurrentAccumDirty;
float DragCurrentAccum; // Accumulator for dragging modification. Always high-precision, not rounded by end-user precision settings
float DragSpeedDefaultRatio; // If speed == 0.0f, uses (max-min) * DragSpeedDefaultRatio
Expand Down
17 changes: 17 additions & 0 deletions imgui_widgets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4197,7 +4197,12 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag
if ((flags & ImGuiColorEditFlags_InputHSV) && (flags & ImGuiColorEditFlags_DisplayRGB))
ColorConvertHSVtoRGB(f[0], f[1], f[2], f[0], f[1], f[2]);
else if ((flags & ImGuiColorEditFlags_InputRGB) && (flags & ImGuiColorEditFlags_DisplayHSV))
{
bool restore_hue = memcmp(g.ColorPickerLastActiveColor, f, sizeof(float) * 3) == 0;
ColorConvertRGBtoHSV(f[0], f[1], f[2], f[0], f[1], f[2]);
if (restore_hue)
f[0] = g.ColorPickerLastHue;
}
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;
Expand Down Expand Up @@ -4324,7 +4329,11 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag
for (int n = 0; n < 4; n++)
f[n] = i[n] / 255.0f;
if ((flags & ImGuiColorEditFlags_DisplayHSV) && (flags & ImGuiColorEditFlags_InputRGB))
{
g.ColorPickerLastHue = f[0];
ColorConvertHSVtoRGB(f[0], f[1], f[2], f[0], f[1], f[2]);
memcpy(g.ColorPickerLastActiveColor, f, sizeof(float) * 3);
}
if ((flags & ImGuiColorEditFlags_DisplayRGB) && (flags & ImGuiColorEditFlags_InputHSV))
ColorConvertRGBtoHSV(f[0], f[1], f[2], f[0], f[1], f[2]);

Expand Down Expand Up @@ -4501,7 +4510,11 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl
float H = col[0], S = col[1], V = col[2];
float R = col[0], G = col[1], B = col[2];
if (flags & ImGuiColorEditFlags_InputRGB)
{
ColorConvertRGBtoHSV(R, G, B, H, S, V);
if (memcmp(g.ColorPickerLastActiveColor, col, sizeof(float) * 3) == 0)
H = g.ColorPickerLastHue;
}
else if (flags & ImGuiColorEditFlags_InputHSV)
ColorConvertHSVtoRGB(H, S, V, R, G, B);

Expand Down Expand Up @@ -4624,7 +4637,9 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl
{
if (flags & ImGuiColorEditFlags_InputRGB)
{
g.ColorPickerLastHue = H;
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]);
memcpy(g.ColorPickerLastActiveColor, col, sizeof(float) * 3);
}
else if (flags & ImGuiColorEditFlags_InputHSV)
{
Expand Down Expand Up @@ -4677,7 +4692,9 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl
R = col[0];
G = col[1];
B = col[2];
float preserve_hue = H;
ColorConvertRGBtoHSV(R, G, B, H, S, V);
H = preserve_hue; // Avoids picker losing hue value for 1 frame glitch.
}
else if (flags & ImGuiColorEditFlags_InputHSV)
{
Expand Down

0 comments on commit a806a3c

Please sign in to comment.