ImGui ToggleButton nasıl yapılır?

364164

Hectopat
Katılım
4 Eylül 2020
Mesajlar
2.138
Makaleler
1
Çözümler
9
Şöyle bir şey yapmak istiyorum.
imgui_toggle_button_1


Ama nasıl kullanacağımı anlamadım. Nasıl buton olarak kullanabilirim?
 
Bu şekilde kullanabilirsin.

C++:
#include "imgui_internal.h"
void ToggleButton(const char* str_id, bool* v)
{
    ImVec2 p = ImGui::GetCursorScreenPos();
    ImDrawList* draw_list = ImGui::GetWindowDrawList();

    float height = ImGui::GetFrameHeight();
    float width = height * 1.55f;
    float radius = height * 0.50f;

    ImGui::InvisibleButton(str_id, ImVec2(width, height));
    if (ImGui::IsItemClicked())
        *v = !*v;

    float t = *v ? 1.0f : 0.0f;

    ImGuiContext& g = *GImGui;
    float ANIM_SPEED = 0.08f;
    if (g.LastActiveId == g.CurrentWindow->GetID(str_id))// && g.LastActiveIdTimer < ANIM_SPEED)
    {
        float t_anim = ImSaturate(g.LastActiveIdTimer / ANIM_SPEED);
        t = *v ? (t_anim) : (1.0f - t_anim);
    }

    ImU32 col_bg;
    if (ImGui::IsItemHovered())
        col_bg = ImGui::GetColorU32(ImLerp(ImVec4(0.78f, 0.78f, 0.78f, 1.0f), ImVec4(0.64f, 0.83f, 0.34f, 1.0f), t));
    else
        col_bg = ImGui::GetColorU32(ImLerp(ImVec4(0.85f, 0.85f, 0.85f, 1.0f), ImVec4(0.56f, 0.83f, 0.26f, 1.0f), t));

    draw_list->AddRectFilled(p, ImVec2(p.x + width, p.y + height), col_bg, height * 0.5f);
    draw_list->AddCircleFilled(ImVec2(p.x + radius + t * (width - radius * 2.0f), p.y + radius), radius - 1.5f, IM_COL32(255, 255, 255, 255));
}

C++:
bool status=false; //global değişken
void display_render()
{
    ImGui::Begin("Hello, world!"); 
    ToggleButton("button", &status); // fonksiyon burada çağrılır, tıklamaya göre status true ya da false olur, değişken global scope'da tanımlanmalı. ya da main fonk. içinde tanımlanıp render fonksiyonuna da geçirilebilir.
    ImGui::End();
}
 
Bu şekilde kullanabilirsin.

C++:
#include "imgui_internal.h"
void ToggleButton(const char* str_id, bool* v)
{
    ImVec2 p = ImGui::GetCursorScreenPos();
    ImDrawList* draw_list = ImGui::GetWindowDrawList();

    float height = ImGui::GetFrameHeight();
    float width = height * 1.55f;
    float radius = height * 0.50f;

    ImGui::InvisibleButton(str_id, ImVec2(width, height));
    if (ImGui::IsItemClicked())
        *v = !*v;

    float t = *v ? 1.0f : 0.0f;

    ImGuiContext& g = *GImGui;
    float ANIM_SPEED = 0.08f;
    if (g.LastActiveId == g.CurrentWindow->GetID(str_id))// && g.LastActiveIdTimer < ANIM_SPEED)
    {
        float t_anim = ImSaturate(g.LastActiveIdTimer / ANIM_SPEED);
        t = *v ? (t_anim) : (1.0f - t_anim);
    }

    ImU32 col_bg;
    if (ImGui::IsItemHovered())
        col_bg = ImGui::GetColorU32(ImLerp(ImVec4(0.78f, 0.78f, 0.78f, 1.0f), ImVec4(0.64f, 0.83f, 0.34f, 1.0f), t));
    else
        col_bg = ImGui::GetColorU32(ImLerp(ImVec4(0.85f, 0.85f, 0.85f, 1.0f), ImVec4(0.56f, 0.83f, 0.26f, 1.0f), t));

    draw_list->AddRectFilled(p, ImVec2(p.x + width, p.y + height), col_bg, height * 0.5f);
    draw_list->AddCircleFilled(ImVec2(p.x + radius + t * (width - radius * 2.0f), p.y + radius), radius - 1.5f, IM_COL32(255, 255, 255, 255));
}

C++:
bool status=false; //global değişken
void display_render()
{
    ImGui::Begin("Hello, world!");
    ToggleButton("button", &status); // fonksiyon burada çağrılır, tıklamaya göre status true ya da false olur, değişken global scope'da tanımlanmalı. ya da main fonk. içinde tanımlanıp render fonksiyonuna da geçirilebilir.
    ImGui::End();
}
Hocam ToggleButton'un yanına yazı nasıl ekleyebilirim? Yazı içine giriyor/kayboluyor.
 
SameLine değerini yazdığın yazıya göre ayarlarsın, yerini değiştirmek istiyorsan koddaki sıralamayı değiştirmen yeterli.
C++:
ImGui::Begin("Hello, world!");
ImGui::Text("Toggle: ");
ImGui::SameLine(70);
ToggleButton("button", &status);
ImGui::End();
 
SameLine değerini yazdığın yazıya göre ayarlarsın, yerini değiştirmek istiyorsan koddaki sıralamayı değiştirmen yeterli.
C++:
ImGui::Begin("Hello, world!");
ImGui::Text("Toggle: ");
ImGui::SameLine(70);
ToggleButton("button", &status);
ImGui::End();
Anladım hocam.

Hocam linkteki olayı nasıl yapacağım anlamadım. Yardım edebilir misiniz?
 
IMGUI_DEFINE_MATH_OPERATORS bunu imgui_internal.h dosyasından önce tanımlamalısın.
C++:
#define IMGUI_DEFINE_MATH_OPERATORS
#include "imgui_internal.h"

Verdikleri kodda GetContentRegionAvailWidth() kullanılmış ancak güncel sürümde kaldırılmış bunun yerine GetContentRegionAvail().x ekledim.

C++:
static ImVector<ImRect> s_GroupPanelLabelStack;
void BeginGroupPanel(const char* name, const ImVec2& size)
{
    ImGui::BeginGroup();
    auto cursorPos = ImGui::GetCursorScreenPos();
    auto itemSpacing = ImGui::GetStyle().ItemSpacing;
    ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 0.0f));
    ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f));
    auto frameHeight = ImGui::GetFrameHeight();
    ImGui::BeginGroup();
    ImVec2 effectiveSize = size;
    if (size.x < 0.0f)
        effectiveSize.x = ImGui::GetContentRegionAvail().x ;
    else
        effectiveSize.x = size.x;
    ImGui::Dummy(ImVec2(effectiveSize.x, 0.0f));
    ImGui::Dummy(ImVec2(frameHeight * 0.5f, 0.0f));
    ImGui::SameLine(0.0f, 0.0f);
    ImGui::BeginGroup();
    ImGui::Dummy(ImVec2(frameHeight * 0.5f, 0.0f));
    ImGui::SameLine(0.0f, 0.0f);
    ImGui::TextUnformatted(name);
    auto labelMin = ImGui::GetItemRectMin();
    auto labelMax = ImGui::GetItemRectMax();
    ImGui::SameLine(0.0f, 0.0f);
    ImGui::Dummy(ImVec2(0.0, frameHeight + itemSpacing.y));
    ImGui::BeginGroup();
    //ImGui::GetWindowDrawList()->AddRect(labelMin, labelMax, IM_COL32(255, 0, 255, 255));
    ImGui::PopStyleVar(2);
#if IMGUI_VERSION_NUM >= 17301
    ImGui::GetCurrentWindow()->ContentRegionRect.Max.x -= frameHeight * 0.5f;
    ImGui::GetCurrentWindow()->WorkRect.Max.x          -= frameHeight * 0.5f;
    ImGui::GetCurrentWindow()->InnerRect.Max.x         -= frameHeight * 0.5f;
#else
    ImGui::GetCurrentWindow()->ContentsRegionRect.Max.x -= frameHeight * 0.5f;
#endif
    ImGui::GetCurrentWindow()->Size.x                   -= frameHeight;
    auto itemWidth = ImGui::CalcItemWidth();
    ImGui::PushItemWidth(ImMax(0.0f, itemWidth - frameHeight));
    s_GroupPanelLabelStack.push_back(ImRect(labelMin, labelMax));
}
void EndGroupPanel()
{
    ImGui::PopItemWidth();
    auto itemSpacing = ImGui::GetStyle().ItemSpacing;
    ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 0.0f));
    ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f));
    auto frameHeight = ImGui::GetFrameHeight();
    ImGui::EndGroup();
    //ImGui::GetWindowDrawList()->AddRectFilled(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), IM_COL32(0, 255, 0, 64), 4.0f);
    ImGui::EndGroup();
    ImGui::SameLine(0.0f, 0.0f);
    ImGui::Dummy(ImVec2(frameHeight * 0.5f, 0.0f));
    ImGui::Dummy(ImVec2(0.0, frameHeight - frameHeight * 0.5f - itemSpacing.y));
    ImGui::EndGroup();
    auto itemMin = ImGui::GetItemRectMin();
    auto itemMax = ImGui::GetItemRectMax();
    //ImGui::GetWindowDrawList()->AddRectFilled(itemMin, itemMax, IM_COL32(255, 0, 0, 64), 4.0f);
    auto labelRect = s_GroupPanelLabelStack.back();
    s_GroupPanelLabelStack.pop_back();
    ImVec2 halfFrame = ImVec2(frameHeight * 0.25f, frameHeight) * 0.5f;
    ImRect frameRect = ImRect(itemMin + halfFrame, itemMax - ImVec2(halfFrame.x, 0.0f));
    labelRect.Min.x -= itemSpacing.x;
    labelRect.Max.x += itemSpacing.x;
    for (int i = 0; i < 4; ++i)
    {
        switch (i)
        {
            // left half-plane
            case 0: ImGui::PushClipRect(ImVec2(-FLT_MAX, -FLT_MAX), ImVec2(labelRect.Min.x, FLT_MAX), true); break;
            // right half-plane
            case 1: ImGui::PushClipRect(ImVec2(labelRect.Max.x, -FLT_MAX), ImVec2(FLT_MAX, FLT_MAX), true); break;
            // top
            case 2: ImGui::PushClipRect(ImVec2(labelRect.Min.x, -FLT_MAX), ImVec2(labelRect.Max.x, labelRect.Min.y), true); break;
            // bottom
            case 3: ImGui::PushClipRect(ImVec2(labelRect.Min.x, labelRect.Max.y), ImVec2(labelRect.Max.x, FLT_MAX), true); break;
        }
        ImGui::GetWindowDrawList()->AddRect(
            frameRect.Min, frameRect.Max,
            ImColor(ImGui::GetStyleColorVec4(ImGuiCol_Border)),
            halfFrame.x);
        ImGui::PopClipRect();
    }
    ImGui::PopStyleVar(2);
#if IMGUI_VERSION_NUM >= 17301
    ImGui::GetCurrentWindow()->ContentRegionRect.Max.x += frameHeight * 0.5f;
    ImGui::GetCurrentWindow()->WorkRect.Max.x          += frameHeight * 0.5f;
    ImGui::GetCurrentWindow()->InnerRect.Max.x         += frameHeight * 0.5f;
#else
    ImGui::GetCurrentWindow()->ContentsRegionRect.Max.x += frameHeight * 0.5f;
#endif
    ImGui::GetCurrentWindow()->Size.x                   += frameHeight;
    ImGui::Dummy(ImVec2(0.0f, 0.0f));
    ImGui::EndGroup();
}

Bu şekilde kullanabilirsin, iki fonksiyon çağrısı arasında kalanlar bir groupbox'a dahil olacak.

C++:
bool status=false;
void my_display_code()
{
    BeginGroupPanel("Group Box", ImVec2(0.0f, 0.0f));
    ImGui::Text("Toggle: ");
    ImGui::SameLine(70);
    ToggleButton("button", &status, clicked);
    EndGroupPanel();

}

Bu arada her farklı soru için yeni konu açmalısın, bu konudaki sorun çözüldüyse raporlayabilirsin.
 

Technopat Haberler

Yeni konular

Yeni mesajlar

Geri
Yukarı