mirror of
https://github.com/ocornut/imgui.git
synced 2024-11-23 21:09:01 +08:00
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
This commit is contained in:
parent
ab97b42935
commit
f8fede1d8b
375
imgui.cpp
375
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,123 +8523,151 @@ 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);
|
||||
|
||||
ImGuiColorEditMode edit_mode = window->DC.ColorEditMode;
|
||||
if (edit_mode == ImGuiColorEditMode_UserSelect || edit_mode == ImGuiColorEditMode_UserSelectShowButton)
|
||||
edit_mode = g.ColorEditModeStorage.GetInt(id, 0) % 3;
|
||||
// If no mode is specified default to RGB
|
||||
if (!(flags & ImGuiColorEditFlags_ModeMask_))
|
||||
flags |= ImGuiColorEditFlags_RGB;
|
||||
|
||||
// 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 + 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)));
|
||||
// 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] =
|
||||
{
|
||||
{ "%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();
|
||||
}
|
||||
break;
|
||||
case ImGuiColorEditMode_HEX:
|
||||
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 Hexadecimal Input
|
||||
const float w_slider_all = w_full - square_sz;
|
||||
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 - style.ItemInnerSpacing.x);
|
||||
if (ImGui::InputText("##Text", buf, IM_ARRAYSIZE(buf), ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsUppercase))
|
||||
{
|
||||
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::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;
|
||||
ImGui::PopItemWidth();
|
||||
ImGui::PopItemWidth();
|
||||
}
|
||||
|
||||
ImGui::SameLine(0, style.ItemInnerSpacing.x);
|
||||
|
||||
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]));
|
||||
|
||||
if (window->DC.ColorEditMode == ImGuiColorEditMode_UserSelectShowButton)
|
||||
else if (flags & ImGuiColorEditFlags_HEX)
|
||||
{
|
||||
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!
|
||||
// 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))
|
||||
{
|
||||
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::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))
|
||||
{
|
||||
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();
|
||||
}
|
||||
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]));
|
||||
}
|
||||
|
||||
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]);
|
||||
|
||||
if (value_changed)
|
||||
if (!picker_active)
|
||||
{
|
||||
col[0] = f[0];
|
||||
col[1] = f[1];
|
||||
col[2] = f[2];
|
||||
if (alpha)
|
||||
col[3] = f[3];
|
||||
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();
|
||||
@ -8652,10 +8676,147 @@ bool ImGui::ColorEdit4(const char* label, float col[4], bool alpha)
|
||||
return value_changed;
|
||||
}
|
||||
|
||||
void ImGui::ColorEditMode(ImGuiColorEditMode mode)
|
||||
bool ImGui::ColorPicker3(const char* label, float col[3], ImGuiColorEditFlags flags)
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
window->DC.ColorEditMode = mode;
|
||||
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);
|
||||
|
||||
// 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())
|
||||
{
|
||||
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, style.ItemInnerSpacing.x);
|
||||
ImGui::TextUnformatted(label, label_display_end);
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
// Horizontal separating line.
|
||||
|
27
imgui.h
27
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()
|
||||
|
@ -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];
|
||||
|
@ -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<bool> AllowKeyboardFocusStack;
|
||||
ImVector<bool> ButtonRepeatStack;
|
||||
ImVector<ImGuiGroupData>GroupStack;
|
||||
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;
|
||||
|
Loading…
Reference in New Issue
Block a user