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); // персональный id компонента
const ImVec2 label_size = CalcTextSize(label, NULL, true); // размер текста названия чекбока ImVec2(x, y)
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);
}
const ImRect check_bb(pos, pos + ImVec2(square_sz, square_sz)); // чек бб - сам чекбокс без текста
RenderNavHighlight(total_bb, id);
RenderFrame(check_bb.Min, check_bb.Max, GetColorU32((held && hovered) ? ImGuiCol_FrameBgActive : hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg), true, style.FrameRounding); // отрисовка фрейма чекбока, эту функцию можно изменять или удалить и использовать по своему
ImU32 check_col = GetColorU32(ImGuiCol_CheckMark); // цвет галочки
bool mixed_value = (window->DC.ItemFlags & ImGuiItemFlags_MixedValue) != 0;
if (mixed_value)
{
// Undocumented tristate/mixed/indeterminate checkbox (#2644)
// This may seem awkwardly designed because the aim is to make ImGuiItemFlags_MixedValue supported by all widgets (not just checkbox)
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);
}
else if (*v)
{
const float pad = ImMax(1.0f, IM_FLOOR(square_sz / 6.0f)); // жирность галочки
RenderCheckMark(window->DrawList, check_bb.Min + ImVec2(pad, pad), check_col, square_sz - pad * 2.0f); // сам рендер галочки, можно взять допутсим вместо галочки RenderFrame, пример ниже
// RenderFrame(check_bb.Min + ImVec2(1, 1), check_bb.Max - ImVec2(1, 1), GetColorU32((held && hovered) ? ImGuiCol_FrameBgActive : hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg), true, style.FrameRounding); // замена галочки на квадрат | ImVec2(1, 1) - отступы от краёв фрейма
}
ImVec2 label_pos = ImVec2(check_bb.Max.x + style.ItemInnerSpacing.x, check_bb.Min.y + style.FramePadding.y); // получение позиции текста, в данном случае он рендерится после чекбокса(т.к. check_bb.Min - мин координаты фрейма чекбокса, check_bb.Max - макс координаты фрейма чекбокса)
if (g.LogEnabled)
LogRenderedText(&label_pos, mixed_value ? "[~]" : *v ? "[x]" : "[ ]");
if (label_size.x > 0.0f)
RenderText(label_pos, label); // рендер самого название чекбокса
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.ItemFlags | ImGuiItemStatusFlags_Checkable | (*v ? ImGuiItemStatusFlags_Checked : 0));
return pressed;
}