bool ImGui::Checkbox(const char* label, bool* v)
{
ImGuiWindow* window = GetCurrentWindow();
if (window->SkipItems)
return false;
ImGuiContext& g = *GImGui;
const ImGuiStyle& style = g.Style;
const ImGuiID id = window->GetID(label);
const ImVec2 label_size = CalcTextSize(label, NULL, true);
const float square_sz = GetFrameHeight();
const ImVec2 pos = window->DC.CursorPos;
const ImRect total_bb(pos, pos + ImVec2(square_sz + (label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f), label_size.y + style.FramePadding.y * 2.0f));
ItemSize(total_bb, style.FramePadding.y);
if (!ItemAdd(total_bb, id))
{
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.ItemFlags | ImGuiItemStatusFlags_Checkable | (*v ? ImGuiItemStatusFlags_Checked : 0));
return false;
}
bool hovered, held;
bool pressed = ButtonBehavior(total_bb, id, &hovered, &held);
if (pressed)
{
*v = !(*v);
MarkItemEdited(id);
}
float deltatime = 1.5f * ImGui::GetIO().DeltaTime;
static std::map<ImGuiID, float> hover_animation;
auto it_hover = hover_animation.find(id);
if (it_hover == hover_animation.end())
{
hover_animation.insert({ id, 0.f });
it_hover = hover_animation.find(id);
}
it_hover->second = clamp(it_hover->second + (3.f * ImGui::GetIO().DeltaTime * (hovered ? 1.f : -1.f)), 0.0f, 1.f);
const ImVec4 hover_act = (ImVec4)ImColor(255, 74, 74);
const ImVec4 hover_dis = (ImVec4)ImColor(255, 100, 100);
static std::map<ImGuiID, ImVec4> hover_color;
auto it_hcolor = hover_color.find(id);
if (it_hcolor == hover_color.end())
{
hover_color.insert({ id, hover_dis });
it_hcolor = hover_color.find(id);
}
if (*v)
{
ImVec4 to = hover_dis;
if (it_hcolor->second.x != to.x)
{
if (it_hcolor->second.x < to.x)
it_hcolor->second.x = ImMin(it_hcolor->second.x + deltatime, to.x);
else if (it_hcolor->second.x > to.x)
it_hcolor->second.x = ImMax(to.x, it_hcolor->second.x - deltatime);
}
if (it_hcolor->second.y != to.y)
{
if (it_hcolor->second.y < to.y)
it_hcolor->second.y = ImMin(it_hcolor->second.y + deltatime, to.y);
else if (it_hcolor->second.y > to.y)
it_hcolor->second.y = ImMax(to.y, it_hcolor->second.y - deltatime);
}
if (it_hcolor->second.z != to.z)
{
if (it_hcolor->second.z < to.z)
it_hcolor->second.z = ImMin(it_hcolor->second.z + deltatime, to.z);
else if (it_hcolor->second.z > to.z)
it_hcolor->second.z = ImMax(to.z, it_hcolor->second.z - deltatime);
}
}
else
{
ImVec4 to = hovered ? hover_dis : hover_act;
if (it_hcolor->second.x != to.x)
{
if (it_hcolor->second.x < to.x)
it_hcolor->second.x = ImMin(it_hcolor->second.x + deltatime, to.x);
else if (it_hcolor->second.x > to.x)
it_hcolor->second.x = ImMax(to.x, it_hcolor->second.x - deltatime);
}
if (it_hcolor->second.y != to.y)
{
if (it_hcolor->second.y < to.y)
it_hcolor->second.y = ImMin(it_hcolor->second.y + deltatime, to.y);
else if (it_hcolor->second.y > to.y)
it_hcolor->second.y = ImMax(to.y, it_hcolor->second.y - deltatime);
}
if (it_hcolor->second.z != to.z)
{
if (it_hcolor->second.z < to.z)
it_hcolor->second.z = ImMin(it_hcolor->second.z + deltatime, to.z);
else if (it_hcolor->second.z > to.z)
it_hcolor->second.z = ImMax(to.z, it_hcolor->second.z - deltatime);
}
}
static std::map<ImGuiID, float> filled_animation;
auto it_filled = filled_animation.find(id);
if (it_filled == filled_animation.end())
{
filled_animation.insert({ id, 0.f });
it_filled = filled_animation.find(id);
}
it_filled->second = clamp(it_filled->second + (2.2f * ImGui::GetIO().DeltaTime * ((*v) ? 1.f : -1.f)), 0.0f, 1.f);
const ImRect check_bb(pos, pos + ImVec2(square_sz, square_sz));
RenderNavHighlight(total_bb, id);
RenderFrame(check_bb.Min - ImVec2(1, 1), check_bb.Max + ImVec2(1, 1), GetColorU32(ImGuiCol_FrameBgActive, it_hover->second), true, style.FrameRounding);
RenderFrame(check_bb.Min, check_bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding);
ImU32 check_col = GetColorU32(ImGuiCol_Text, it_filled->second);
bool mixed_value = (window->DC.ItemFlags & ImGuiItemFlags_MixedValue) != 0;
if (mixed_value)
{
ImVec2 pad(ImMax(1.0f, IM_FLOOR(square_sz / 3.6f)), ImMax(1.0f, IM_FLOOR(square_sz / 3.6f)));
window->DrawList->AddRectFilled(check_bb.Min + pad, check_bb.Max - pad, check_col, style.FrameRounding);
}
const float pad = ImMax(1.0f, IM_FLOOR(square_sz / 4.0f));
ImGui::PushFont(g_pMenuFont);
RenderCheckMark(window->DrawList, check_bb.Min + ImVec2(pad, pad), check_col, square_sz - pad * 2.0f);
ImGui::PopFont();
ImGui::PushFont(g_pMenuFont);
if (g.LogEnabled)
LogRenderedText(&total_bb.Min, mixed_value ? "[~]" : *v ? "[x]" : "[ ]");
if (label_size.x > 0.0f)
RenderText(ImVec2(check_bb.Max.x + style.ItemInnerSpacing.x, check_bb.Min.y + style.FramePadding.y), label);
ImGui::PopFont();
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.ItemFlags | ImGuiItemStatusFlags_Checkable | (*v ? ImGuiItemStatusFlags_Checked : 0));
return pressed;
}