Исходник Написал красивый Slider для ImGui

Забаненный
Статус
Оффлайн
Регистрация
9 Фев 2021
Сообщения
181
Реакции[?]
97
Поинты[?]
1K
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Думаю это повод для гордости, написал slider с чистого 0, скомпилировал с 34 раза, получилось очень даже ничего.
Код:
struct slider_state
{
    float speed;
    float value;
};

bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max, const char* format, ImGuiSliderFlags flags)
{

    ImGuiWindow* window = GetCurrentWindow();
    if (window->SkipItems)
        return false;

    ImGuiContext& g = *GImGui;
    const ImGuiStyle& style = g.Style;
    const ImGuiID id = window->GetID(label);
    const float w = CalcItemWidth();
    const ImVec2 label_size = CalcTextSize(label, NULL, true);
    const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(160 + w, label_size.y + style.FramePadding.y * 2.0f));
    const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f));

    ItemSize(total_bb, style.FramePadding.y);
    if (!ItemAdd(total_bb, id, &frame_bb))
        return false;

    if (format == NULL)
        format = DataTypeGetInfo(data_type)->PrintFmt;
    else if (data_type == ImGuiDataType_S32 && strcmp(format, "%d") != 0)
        format = PatchFormatStringFloatToInt(format);

    const bool hovered = ItemHoverable(frame_bb, id);
    const bool temp_input_allowed = (flags & ImGuiSliderFlags_NoInput) == 0;
    bool temp_input_is_active = temp_input_allowed && TempInputIsActive(id);
    if (!temp_input_is_active)
    {
        const bool focus_requested = temp_input_allowed && FocusableItemRegister(window, id);
        const bool clicked = (hovered && g.IO.MouseClicked[0]);
        if (focus_requested || clicked || g.NavActivateId == id || g.NavInputId == id)
        {
            SetActiveID(id, window);
            SetFocusID(id, window);
            FocusWindow(window);
            g.ActiveIdUsingNavDirMask |= (1 << ImGuiDir_Left) | (1 << ImGuiDir_Right);
            if (temp_input_allowed && (focus_requested || (clicked && g.IO.KeyCtrl) || g.NavInputId == id))
            {
                temp_input_is_active = true;
                FocusableItemUnregister(window);
            }
        }
    }

    if (temp_input_is_active)
    {
        window->DrawList->AddRectFilledMultiColor(ImVec2(frame_bb.Min.x + 0, frame_bb.Min.y + 22), ImVec2(total_bb.Min.x + 160 + w, total_bb.Min.y + 31), ImColor(0.023f, 0.023f, 0.023f, 0.000f), ImColor(0.023f, 0.023f, 0.023f, 0.000f), ImColor(0.209f, 0.209f, 0.209f, 1.000f), ImColor(0.209f, 0.209f, 0.209f, 1.000f));

        const bool is_clamp_input = (flags & ImGuiSliderFlags_AlwaysClamp) != 0;
        return TempInputScalar(frame_bb, id, label, data_type, p_data, format, is_clamp_input ? p_min : NULL, is_clamp_input ? p_max : NULL);
    }

    ImRect grab_bb;
    const bool value_changed = SliderBehavior(frame_bb, id, data_type, p_data, p_min, p_max, format, flags, &grab_bb);
    if (value_changed)
        MarkItemEdited(id);

    const ImU32 frame_col = GetColorU32(g.HoveredId == id ? ImGuiCol_FrameBg : ImGuiCol_FrameBg);
    RenderNavHighlight(frame_bb, id);

    static std::map<ImGuiID, slider_state> filing;
    auto it_filing = filing.find(id);

    if (it_filing == filing.end())
    {
        filing.insert({ id, {0.f, 0.f} });
        it_filing = filing.find(id);
    }
    if ((frame_bb.Min.x + it_filing->second.value) < grab_bb.Min.x) {
        it_filing->second.speed = (grab_bb.Min.x - (frame_bb.Min.x + it_filing->second.value)) / 8.f; // Значение плавности шарика и покрывающий линии
        it_filing->second.value += it_filing->second.speed;
    }
    else if ((frame_bb.Min.x + it_filing->second.value) > grab_bb.Min.x) {
        it_filing->second.speed = ((frame_bb.Min.x + it_filing->second.value - grab_bb.Min.x)) / 8.f; // Значение плавности шарика и покрывающий линии
        it_filing->second.value -= it_filing->second.speed;
    }

    window->DrawList->AddRectFilled(ImVec2(frame_bb.Min.x + 0, frame_bb.Min.y + 17), ImVec2(total_bb.Min.x + 160 + w, total_bb.Min.y + 19), ImColor(0.09f, 0.09f, 0.09f, 1.00f), 0, 0); // Линия начального покрытия
    window->DrawList->AddRectFilledMultiColor(ImVec2(frame_bb.Min.x - 1, frame_bb.Min.y + 17), ImVec2(frame_bb.Min.x + it_filing->second.value + 8, total_bb.Min.y + 19), ImColor(0.221f, 0.221f, 0.221f, 1.000f),ImColor(0.387f, 0.387f, 0.387f, 1.000f),ImColor(0.392f, 0.392f, 0.392f, 1.000f),ImColor(0.221f, 0.221f, 0.221f, 1.000f)); // Покрывающая линия

    static std::map<ImGuiID, float> nameanim_animation0; // Контейнер map (Анимация шарика)
    auto it_nameanim0 = nameanim_animation0.find(id);
    if (it_nameanim0 == nameanim_animation0.end())
    {
        nameanim_animation0.insert({ id, 11.f }); // Изначальное значение шарика
        it_nameanim0 = nameanim_animation0.find(id);
    }

    it_nameanim0->second = ImClamp(it_nameanim0->second + (0.8f * ImGui::GetIO().DeltaTime * (hovered || IsItemActive() ? 11.f : -11.0f)), 11.f, 13.f);
    it_nameanim0->second *= style.Alpha;

    // hovered - Когда мышь находиться в зоне слайдера, происходит какое то действие
    // IsItemActive() - Когда мышь находиться в зоне слайдера в активированном состоянии (Зажата) происходит действие

    if (grab_bb.Max.x > grab_bb.Min.x) {

        window->DrawList->AddCircleFilled(ImVec2(frame_bb.Min.x + it_filing->second.value + 5, grab_bb.Min.y + 15), it_nameanim0->second, ImColor(0.221f, 0.221f, 0.221f, 1.000f), 24);

    }

    // Отрисовка анимаций текста и прочее

    static std::map<ImGuiID, float> nameanim_animation;
    auto it_nameanim = nameanim_animation.find(id);
    if (it_nameanim == nameanim_animation.end())
    {
        nameanim_animation.insert({ id, 0.f });
        it_nameanim = nameanim_animation.find(id);
    }

    it_nameanim->second = ImClamp(it_nameanim->second + (5.f * ImGui::GetIO().DeltaTime * (hovered || IsItemActive() ? 1.f : -0.2f)), 0.f, 1.f);
    it_nameanim->second *= style.Alpha;

    char value_buf[64];
    const char* value_buf_end = value_buf + DataTypeFormatString(value_buf, IM_ARRAYSIZE(value_buf), data_type, p_data, format);

    ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.00f, 1.00f, 1.00f, it_nameanim->second));
    RenderTextClipped(ImVec2(frame_bb.Min.x + it_filing->second.value - w + 10, frame_bb.Min.y - 36), ImVec2(frame_bb.Min.x + it_filing->second.value + w, frame_bb.Min.y + 13), value_buf, value_buf_end, NULL, ImVec2(0.5f, 0.5f));
    ImGui::PopStyleColor(1);

    if (label_size.x > 0.0f)

        RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x - 356, frame_bb.Min.y + style.FramePadding.y + 1.0f), label);

    for (int i = 0; i < 3; i++)
        ImGui::Spacing();

    IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.ItemFlags);
    return value_changed;
}
Только без хейта, я его писал в пустом блокноте без шпор, и готовился к этому очень долгое время.

p.s если кому то нужен CheckBox подобного типа в лс.
 
Забаненный
Статус
Оффлайн
Регистрация
18 Июл 2020
Сообщения
902
Реакции[?]
200
Поинты[?]
1K
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
анимации прикольные, а круг чет слишком большой
1658914166923.png
 
Забаненный
Статус
Оффлайн
Регистрация
9 Фев 2021
Сообщения
181
Реакции[?]
97
Поинты[?]
1K
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
[HvH ✡ Player] aka B1gPaster
Участник
Статус
Оффлайн
Регистрация
28 Дек 2017
Сообщения
943
Реакции[?]
265
Поинты[?]
0
Анимация приклоненная но в сурс куда вставил там текст залазит на слайдер не хочу сейчас разбираться но ты молодец :seemsgood:
 
Забаненный
Статус
Оффлайн
Регистрация
9 Фев 2021
Сообщения
181
Реакции[?]
97
Поинты[?]
1K
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Анимация приклоненная но в сурс куда вставил там текст залазит на слайдер не хочу сейчас разбираться но ты молодец :seemsgood:
Это из за шрифта, просто сделай поменьше или в настройках передвинь текст чуть выше
 
[HvH ✡ Player] aka B1gPaster
Участник
Статус
Оффлайн
Регистрация
28 Дек 2017
Сообщения
943
Реакции[?]
265
Поинты[?]
0
Забаненный
Статус
Оффлайн
Регистрация
9 Фев 2021
Сообщения
181
Реакции[?]
97
Поинты[?]
1K
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Virus analysis
Забаненный
Статус
Оффлайн
Регистрация
24 Июн 2022
Сообщения
113
Реакции[?]
54
Поинты[?]
0
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Сверху Снизу