mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-10-20 23:23:30 +02:00
Labels: - every button, field, tooltip and message of the editor reread for a beginner: short nouns for the fields with the sentence in the tooltip, the less used options under More settings, one glossary (field of work, template, track, grade), sides told from directions, degrees and per mille as signs, messages built from one format string - plural forms through STR_P; the last entry of a po file is read too, and the Polish plural rule is in the header - lang/editor_pl.po: the code pass entries merged, 391 entries no code uses and 3 duplicates dropped - roads: the notes and errors naming a road translated; the build options and the layout fold the texture length, kerb sizes, traffic share, roundabout part, height over the ground and junction speed limit under More settings, the lanes start folded Grade lines fitted to the terrain model (NMT), a line or the whole scenery at once: - fit_ground: a robust fit on nodes 5 m apart; the ground parting from the line (a bridge, a viaduct, a wall) is gone past rather than followed, the bends keep off the switches as far as their curves reach, a run of bends the same way is one point of intersection, a curve with no room is as sharp as the room lets it be - the ends of the line and the other paths of its switches leading into lines fitted already bound the line by what the tracks between can climb; ends meeting in the plan, laid apart in height by hand, are joined before the run - apply_profile: the paths are split where split_path takes the parameter (a straight was cut in the wrong place, into pieces of a few centimetres the game takes for zero length), no piece shorter than the margin; the paths off the ends of the route are brought to its height - Bytom: 1600 lines, grade breaks at the joints 89 -> 20; Tarnowskie Gory: 848 lines, 223 -> 3; no step over 2 cm
407 lines
16 KiB
C++
407 lines
16 KiB
C++
/*
|
|
This Source Code Form is subject to the
|
|
terms of the Mozilla Public License, v.
|
|
2.0. If a copy of the MPL was not
|
|
distributed with this file, You can
|
|
obtain one at
|
|
http://mozilla.org/MPL/2.0/.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <algorithm>
|
|
#include <cmath>
|
|
#include <cstdio>
|
|
#include <cstring>
|
|
#include <deque>
|
|
#include <functional>
|
|
#include <initializer_list>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "imgui/imgui.h"
|
|
#include "utilities/translation.h"
|
|
|
|
float constexpr kDragPixels{5.0f};
|
|
|
|
inline void item_tooltip(char const *Text)
|
|
{
|
|
if (ImGui::IsItemHovered())
|
|
ImGui::SetTooltip("%s", STR_C(Text));
|
|
}
|
|
|
|
// grid points without a height (or another value) take the one of the nearest point which has it (by steps along the grid)
|
|
template <typename Value_> inline void fill_from_nearest(std::vector<Value_> &Heights, std::vector<char> &Found, std::size_t const Side)
|
|
{
|
|
std::deque<std::size_t> queue;
|
|
for (std::size_t index = 0; index < Found.size(); ++index)
|
|
if (Found[index] != 0)
|
|
queue.push_back(index);
|
|
while (false == queue.empty())
|
|
{
|
|
auto const index = queue.front();
|
|
queue.pop_front();
|
|
auto const ix = index % Side, iz = index / Side;
|
|
auto const visit = [&](std::size_t const Next) {
|
|
if (Found[Next] != 0)
|
|
return;
|
|
Found[Next] = 1;
|
|
Heights[Next] = Heights[index];
|
|
queue.push_back(Next);
|
|
};
|
|
if (ix > 0)
|
|
visit(index - 1);
|
|
if (ix + 1 < Side)
|
|
visit(index + 1);
|
|
if (iz > 0)
|
|
visit(index - Side);
|
|
if (iz + 1 < Side)
|
|
visit(index + Side);
|
|
}
|
|
}
|
|
|
|
// the families of the track tools, each with its colour: building the track, equipping it, checking it
|
|
inline ImU32 family_colour(int const Family, float const Alpha = 1.0f)
|
|
{
|
|
static ImVec4 const colours[]{{0.30f, 0.60f, 0.95f, 1.0f}, {0.95f, 0.66f, 0.22f, 1.0f}, {0.25f, 0.80f, 0.66f, 1.0f}};
|
|
auto colour{colours[std::clamp(Family, 0, 2)]};
|
|
colour.w = Alpha;
|
|
return ImGui::ColorConvertFloat4ToU32(colour);
|
|
}
|
|
|
|
inline char const *family_name(int const Family)
|
|
{
|
|
static char const *const names[]{"Building", "Equipment", "Checks"};
|
|
return STR_C(names[std::clamp(Family, 0, 2)]);
|
|
}
|
|
|
|
// a numbered step of the work in a panel: the number in a circle, its name, a line to the edge of the panel
|
|
inline void step_heading(int const Number, char const *Text)
|
|
{
|
|
ImGui::Spacing();
|
|
auto *draw{ImGui::GetWindowDrawList()};
|
|
auto const at{ImGui::GetCursorScreenPos()};
|
|
auto const height{ImGui::GetTextLineHeight()};
|
|
auto const radius{std::round(height * 0.6f)};
|
|
ImVec2 const centre{at.x + radius, at.y + radius};
|
|
draw->AddCircleFilled(centre, radius, ImGui::GetColorU32(ImGuiCol_CheckMark), 20);
|
|
char digit[8];
|
|
std::snprintf(digit, sizeof(digit), "%d", Number);
|
|
auto const size{ImGui::CalcTextSize(digit)};
|
|
draw->AddText(ImVec2(std::round(centre.x - size.x * 0.5f), std::round(centre.y - size.y * 0.5f)), IM_COL32(16, 18, 22, 255), digit);
|
|
ImGui::Dummy(ImVec2(radius * 2.0f, radius * 2.0f));
|
|
ImGui::SameLine(0.0f, radius * 0.6f);
|
|
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + radius - height * 0.5f);
|
|
ImGui::TextUnformatted(Text);
|
|
auto const end{ImGui::GetItemRectMax().x + radius * 0.6f};
|
|
auto const edge{ImGui::GetWindowPos().x + ImGui::GetWindowContentRegionMax().x};
|
|
if (edge > end)
|
|
draw->AddLine(ImVec2(end, centre.y), ImVec2(edge, centre.y), ImGui::GetColorU32(ImGuiCol_Separator));
|
|
ImGui::Spacing();
|
|
}
|
|
|
|
// a toggle drawn as a pill: a swatch of the colour of what it shows and its name, lit while on
|
|
inline bool pill_toggle(char const *Label, ImU32 const Swatch, bool &Value)
|
|
{
|
|
auto const text{ImGui::CalcTextSize(Label)};
|
|
auto const height{ImGui::GetFrameHeight()};
|
|
auto const swatch{std::round(height * 0.7f)};
|
|
auto const pad{std::round(height * 0.35f)};
|
|
ImVec2 const size{pad + swatch + pad * 0.6f + text.x + pad, height};
|
|
auto const at{ImGui::GetCursorScreenPos()};
|
|
ImGui::PushID(Label);
|
|
auto const clicked{ImGui::InvisibleButton("##pill", size)};
|
|
ImGui::PopID();
|
|
if (clicked)
|
|
Value = !Value;
|
|
auto const hovered{ImGui::IsItemHovered()};
|
|
auto *draw{ImGui::GetWindowDrawList()};
|
|
ImVec2 const end{at.x + size.x, at.y + size.y};
|
|
draw->AddRectFilled(at, end, ImGui::GetColorU32(Value ? (hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Header) : (hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg)), height * 0.5f);
|
|
auto const middle{at.y + height * 0.5f};
|
|
auto const colour{Value ? Swatch : (Swatch & ~IM_COL32_A_MASK) | IM_COL32(0, 0, 0, 70)};
|
|
draw->AddLine(ImVec2(at.x + pad, middle), ImVec2(at.x + pad + swatch, middle), colour, std::max(2.0f, height * 0.16f));
|
|
draw->AddText(ImVec2(at.x + pad + swatch + pad * 0.6f, std::round(middle - text.y * 0.5f)), ImGui::GetColorU32(Value ? ImGuiCol_Text : ImGuiCol_TextDisabled), Label);
|
|
return clicked;
|
|
}
|
|
|
|
// a choice of a few as one bar of segments across the panel, the chosen one lit; true when the choice changed
|
|
struct segment_option
|
|
{
|
|
int value;
|
|
char const *label;
|
|
char const *tooltip{nullptr};
|
|
};
|
|
inline bool segmented(char const *Id, int &Value, std::initializer_list<segment_option> Options)
|
|
{
|
|
auto const count{static_cast<float>(Options.size())};
|
|
auto const width{ImGui::GetContentRegionAvail().x};
|
|
auto const height{ImGui::GetFrameHeight()};
|
|
auto const at{ImGui::GetCursorScreenPos()};
|
|
auto *draw{ImGui::GetWindowDrawList()};
|
|
auto const rounding{height * 0.5f};
|
|
draw->AddRectFilled(at, ImVec2(at.x + width, at.y + height), ImGui::GetColorU32(ImGuiCol_FrameBg), rounding);
|
|
ImGui::PushID(Id);
|
|
bool changed{false};
|
|
float index{0.0f};
|
|
for (auto const &option : Options)
|
|
{
|
|
auto const left{std::round(at.x + width * index / count)};
|
|
auto const right{std::round(at.x + width * (index + 1.0f) / count)};
|
|
ImGui::SetCursorScreenPos(ImVec2(left, at.y));
|
|
ImGui::PushID(option.value);
|
|
if (ImGui::InvisibleButton("##segment", ImVec2(std::max(1.0f, right - left), height)) && Value != option.value)
|
|
{
|
|
Value = option.value;
|
|
changed = true;
|
|
}
|
|
auto const hovered{ImGui::IsItemHovered()};
|
|
if (option.tooltip != nullptr && hovered)
|
|
ImGui::SetTooltip("%s", STR_C(option.tooltip));
|
|
ImGui::PopID();
|
|
auto const chosen{Value == option.value};
|
|
if (chosen || hovered)
|
|
draw->AddRectFilled(ImVec2(left + 2.0f, at.y + 2.0f), ImVec2(right - 2.0f, at.y + height - 2.0f), chosen ? family_colour(0, 0.8f) : ImGui::GetColorU32(ImGuiCol_FrameBgHovered), rounding - 2.0f);
|
|
auto const text{ImGui::CalcTextSize(option.label)};
|
|
draw->PushClipRect(ImVec2(left + 4.0f, at.y), ImVec2(right - 4.0f, at.y + height), true);
|
|
draw->AddText(ImVec2(std::round(std::max(left + 6.0f, (left + right - text.x) * 0.5f)), std::round(at.y + (height - text.y) * 0.5f)), ImGui::GetColorU32(chosen ? ImGuiCol_Text : ImGuiCol_TextDisabled), option.label);
|
|
draw->PopClipRect();
|
|
index += 1.0f;
|
|
}
|
|
ImGui::PopID();
|
|
ImGui::SetCursorScreenPos(at);
|
|
ImGui::Dummy(ImVec2(width, height));
|
|
return changed;
|
|
}
|
|
|
|
// values picked with a click, as round chips which go on to the next line at the edge of the panel; true when one was picked
|
|
inline bool value_chips(char const *Id, double &Value, std::initializer_list<double> Values, char const *Format)
|
|
{
|
|
auto const edge{ImGui::GetWindowPos().x + ImGui::GetWindowContentRegionMax().x};
|
|
auto const gap{std::round(ImGui::GetStyle().ItemSpacing.x * 0.6f)};
|
|
ImGui::PushID(Id);
|
|
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, ImGui::GetFrameHeight() * 0.5f);
|
|
bool changed{false};
|
|
bool first{true};
|
|
for (auto const value : Values)
|
|
{
|
|
char text[32];
|
|
std::snprintf(text, sizeof(text), Format, value);
|
|
auto const width{ImGui::CalcTextSize(text).x + ImGui::GetStyle().FramePadding.x * 2.0f};
|
|
if (false == first)
|
|
{
|
|
ImGui::SameLine(0.0f, gap);
|
|
if (ImGui::GetCursorScreenPos().x + width > edge)
|
|
ImGui::NewLine();
|
|
}
|
|
first = false;
|
|
auto const chosen{std::abs(Value - value) < 1e-6};
|
|
ImGui::PushStyleColor(ImGuiCol_Button, chosen ? family_colour(0, 0.8f) : ImGui::GetColorU32(ImGuiCol_FrameBg));
|
|
ImGui::PushStyleColor(ImGuiCol_Text, ImGui::GetColorU32(chosen ? ImGuiCol_Text : ImGuiCol_TextDisabled));
|
|
if (ImGui::Button(text))
|
|
{
|
|
Value = value;
|
|
changed = true;
|
|
}
|
|
ImGui::PopStyleColor(2);
|
|
}
|
|
ImGui::PopStyleVar();
|
|
ImGui::PopID();
|
|
return changed;
|
|
}
|
|
|
|
// one of a few named choices as round chips which go on to the next line at the edge of the panel, where a tab bar
|
|
// would cut the names; true when one was picked
|
|
inline bool choice_chips(char const *Id, int &Value, std::vector<segment_option> const &Options)
|
|
{
|
|
auto const edge{ImGui::GetWindowPos().x + ImGui::GetWindowContentRegionMax().x};
|
|
auto const gap{std::round(ImGui::GetStyle().ItemSpacing.x * 0.6f)};
|
|
ImGui::PushID(Id);
|
|
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, ImGui::GetFrameHeight() * 0.5f);
|
|
bool changed{false};
|
|
bool first{true};
|
|
for (auto const &option : Options)
|
|
{
|
|
auto const width{ImGui::CalcTextSize(option.label).x + ImGui::GetStyle().FramePadding.x * 2.0f};
|
|
if (false == first)
|
|
{
|
|
ImGui::SameLine(0.0f, gap);
|
|
if (ImGui::GetCursorScreenPos().x + width > edge)
|
|
ImGui::NewLine();
|
|
}
|
|
first = false;
|
|
auto const chosen{Value == option.value};
|
|
ImGui::PushID(option.value);
|
|
ImGui::PushStyleColor(ImGuiCol_Button, chosen ? family_colour(0, 0.8f) : ImGui::GetColorU32(ImGuiCol_FrameBg));
|
|
if (ImGui::Button(option.label) && false == chosen)
|
|
{
|
|
Value = option.value;
|
|
changed = true;
|
|
}
|
|
if (option.tooltip != nullptr)
|
|
item_tooltip(option.tooltip);
|
|
ImGui::PopStyleColor();
|
|
ImGui::PopID();
|
|
}
|
|
ImGui::PopStyleVar();
|
|
ImGui::PopID();
|
|
return changed;
|
|
}
|
|
|
|
// values at a glance as tiles: the value in its colour over its name, a bar of the colour at the left, on to the next row
|
|
// at the edge of the panel
|
|
struct metric_tile
|
|
{
|
|
std::string value;
|
|
char const *label;
|
|
ImU32 colour;
|
|
};
|
|
inline void metric_tiles(std::initializer_list<metric_tile> Tiles)
|
|
{
|
|
auto const font{ImGui::GetFontSize()};
|
|
auto const height{std::round(font * 2.5f)};
|
|
auto const edge{ImGui::GetWindowPos().x + ImGui::GetWindowContentRegionMax().x};
|
|
auto const gap{std::round(font * 0.3f)};
|
|
auto *list{ImGui::GetWindowDrawList()};
|
|
bool first{true};
|
|
for (auto const &entry : Tiles)
|
|
{
|
|
auto const value{ImGui::CalcTextSize(entry.value.c_str())};
|
|
auto const label{ImGui::CalcTextSize(entry.label)};
|
|
auto const width{std::max(std::round(font * 5.0f), std::max(value.x, label.x) + font)};
|
|
if (false == first)
|
|
{
|
|
ImGui::SameLine(0.0f, gap);
|
|
if (ImGui::GetCursorScreenPos().x + width > edge)
|
|
ImGui::NewLine();
|
|
}
|
|
first = false;
|
|
auto const at{ImGui::GetCursorScreenPos()};
|
|
ImGui::Dummy(ImVec2(width, height));
|
|
list->AddRectFilled(at, ImVec2(at.x + width, at.y + height), ImGui::GetColorU32(ImGuiCol_FrameBg), std::round(font * 0.3f));
|
|
list->AddRectFilled(at, ImVec2(at.x + 3.0f, at.y + height), entry.colour, 2.0f, ImDrawFlags_RoundCornersLeft);
|
|
list->AddText(ImVec2(at.x + font * 0.5f, at.y + height * 0.12f), entry.colour, entry.value.c_str());
|
|
list->AddText(ImVec2(at.x + font * 0.5f, at.y + height * 0.12f + value.y), ImGui::GetColorU32(ImGuiCol_TextDisabled), entry.label);
|
|
}
|
|
}
|
|
|
|
// a choice as a tile: a sketch drawn by Sketch into the box on the left (in the colours of the main line and of what it makes),
|
|
// the name beside it; lit while chosen, true when clicked
|
|
inline bool sketch_tile(char const *Id, char const *Label, bool const Chosen, float const Width, std::function<void(ImDrawList &, ImVec2, ImVec2, ImU32, ImU32)> const &Sketch)
|
|
{
|
|
auto const font{ImGui::GetFontSize()};
|
|
auto const height{std::round(font * 2.4f)};
|
|
auto const top{ImGui::GetCursorScreenPos()};
|
|
auto const clicked{ImGui::InvisibleButton(Id, ImVec2(Width, height))};
|
|
auto const hovered{ImGui::IsItemHovered()};
|
|
auto *list{ImGui::GetWindowDrawList()};
|
|
auto const accent{family_colour(0)};
|
|
ImVec2 const bottom{top.x + Width, top.y + height};
|
|
auto const rounding{std::round(font * 0.35f)};
|
|
list->AddRectFilled(top, bottom, Chosen ? (accent & ~IM_COL32_A_MASK) | IM_COL32(0, 0, 0, 46) : ImGui::GetColorU32(hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg), rounding);
|
|
list->AddRect(top, bottom, Chosen ? accent : ImGui::GetColorU32(ImGuiCol_Border), rounding, 0, Chosen ? 2.0f : 1.0f);
|
|
auto const pad{std::round(font * 0.4f)};
|
|
auto const side{std::round(font * 2.2f)};
|
|
ImVec2 const low{top.x + pad, top.y + pad};
|
|
ImVec2 const high{top.x + pad + side, bottom.y - pad};
|
|
Sketch(*list, low, high, Chosen ? accent : ImGui::GetColorU32(ImGuiCol_Text, 0.7f), Chosen ? IM_COL32(255, 210, 60, 255) : ImGui::GetColorU32(ImGuiCol_Text, 0.45f));
|
|
auto const text_left{high.x + pad};
|
|
auto const wrap{bottom.x - pad - text_left};
|
|
auto const size{ImGui::CalcTextSize(Label, nullptr, false, wrap)};
|
|
list->AddText(nullptr, 0.0f, ImVec2(text_left, std::round(top.y + (height - size.y) * 0.5f)), ImGui::GetColorU32(Chosen ? ImGuiCol_Text : ImGuiCol_TextDisabled), Label, nullptr, wrap);
|
|
return clicked;
|
|
}
|
|
|
|
// the state of something as a rounded chip in its colour; true when clicked
|
|
inline bool state_chip(char const *Label, ImVec4 const &Colour)
|
|
{
|
|
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, ImGui::GetFrameHeight() * 0.5f);
|
|
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(Colour.x * 0.3f, Colour.y * 0.3f, Colour.z * 0.3f, 0.9f));
|
|
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(Colour.x * 0.45f, Colour.y * 0.45f, Colour.z * 0.45f, 1.0f));
|
|
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(Colour.x * 0.55f, Colour.y * 0.55f, Colour.z * 0.55f, 1.0f));
|
|
ImGui::PushStyleColor(ImGuiCol_Text, Colour);
|
|
auto const clicked{ImGui::Button(Label)};
|
|
ImGui::PopStyleColor(4);
|
|
ImGui::PopStyleVar();
|
|
return clicked;
|
|
}
|
|
|
|
// fields as rows of a table: the name wrapped in a column on the left, the field as wide as the rest of the panel;
|
|
// field_row takes the untranslated "Name##id" (a literal: the translations are cached by the pointer, a name made at run
|
|
// time goes with Translate false) and leaves the cursor where the field goes
|
|
inline bool begin_fields(char const *Id, float const Names = 0.42f)
|
|
{
|
|
if (false == ImGui::BeginTable(Id, 2, ImGuiTableFlags_SizingStretchProp))
|
|
return false;
|
|
ImGui::TableSetupColumn("##name", ImGuiTableColumnFlags_WidthStretch, Names);
|
|
ImGui::TableSetupColumn("##field", ImGuiTableColumnFlags_WidthStretch, 1.0f - Names);
|
|
return true;
|
|
}
|
|
inline void field_row(char const *Label, bool const Translate = true)
|
|
{
|
|
ImGui::TableNextRow();
|
|
ImGui::TableNextColumn();
|
|
ImGui::AlignTextToFramePadding();
|
|
auto const *text{Translate ? STR_C(Label) : Label};
|
|
ImGui::PushTextWrapPos(0.0f);
|
|
ImGui::TextUnformatted(text, std::strstr(text, "##"));
|
|
ImGui::PopTextWrapPos();
|
|
ImGui::TableNextColumn();
|
|
ImGui::SetNextItemWidth(-FLT_MIN);
|
|
}
|
|
|
|
// switches of a few things as round chips which go on to the next line at the edge of the panel, lit while on;
|
|
// the index of the one clicked, or -1
|
|
struct toggle_option
|
|
{
|
|
char const *label;
|
|
bool *value;
|
|
char const *tooltip{nullptr};
|
|
};
|
|
inline int toggle_chips(char const *Id, std::initializer_list<toggle_option> Options)
|
|
{
|
|
auto const edge{ImGui::GetWindowPos().x + ImGui::GetWindowContentRegionMax().x};
|
|
auto const gap{std::round(ImGui::GetStyle().ItemSpacing.x * 0.6f)};
|
|
auto const mark{std::round(ImGui::GetFontSize() * 0.45f)};
|
|
ImGui::PushID(Id);
|
|
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, ImGui::GetFrameHeight() * 0.5f);
|
|
int clicked{-1};
|
|
int index{0};
|
|
for (auto const &option : Options)
|
|
{
|
|
auto const on{*option.value};
|
|
auto const width{ImGui::CalcTextSize(option.label).x + ImGui::GetStyle().FramePadding.x * 2.0f + mark * 1.6f};
|
|
if (index > 0)
|
|
{
|
|
ImGui::SameLine(0.0f, gap);
|
|
if (ImGui::GetCursorScreenPos().x + width > edge)
|
|
ImGui::NewLine();
|
|
}
|
|
auto const at{ImGui::GetCursorScreenPos()};
|
|
ImGui::PushID(index);
|
|
ImGui::PushStyleColor(ImGuiCol_Button, on ? family_colour(0, 0.8f) : ImGui::GetColorU32(ImGuiCol_FrameBg));
|
|
ImGui::PushStyleColor(ImGuiCol_Text, ImGui::GetColorU32(on ? ImGuiCol_Text : ImGuiCol_TextDisabled));
|
|
ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(1.0f, 0.5f));
|
|
if (ImGui::Button(option.label, ImVec2(width, 0.0f)))
|
|
{
|
|
*option.value = !on;
|
|
clicked = index;
|
|
}
|
|
ImGui::PopStyleVar();
|
|
ImGui::PopStyleColor(2);
|
|
if (option.tooltip != nullptr && ImGui::IsItemHovered())
|
|
ImGui::SetTooltip("%s", STR_C(option.tooltip));
|
|
ImGui::PopID();
|
|
auto const middle{ImVec2(at.x + ImGui::GetStyle().FramePadding.x + mark * 0.5f, at.y + ImGui::GetFrameHeight() * 0.5f)};
|
|
auto *draw{ImGui::GetWindowDrawList()};
|
|
if (*option.value)
|
|
draw->AddCircleFilled(middle, mark * 0.5f, IM_COL32(255, 210, 60, 255));
|
|
else
|
|
draw->AddCircle(middle, mark * 0.5f, ImGui::GetColorU32(ImGuiCol_TextDisabled), 0, 1.5f);
|
|
++index;
|
|
}
|
|
ImGui::PopStyleVar();
|
|
ImGui::PopID();
|
|
return clicked;
|
|
}
|