| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 |
- #pragma once
- #include "imgui_internal.h"
- #include <cmath>
- //https://github.com/ocornut/imgui/issues/1901
- namespace ImGui
- {
- bool inline BufferingBar(const char *label, float value, const ImVec2 &size_arg,
- const ImU32 &bg_col = ImGui::GetColorU32(ImGuiCol_FrameBg),
- const ImU32 &fg_col = ImGui::GetColorU32(ImGuiCol_PlotHistogram))
- {
- ImGuiWindow *window = GetCurrentWindow();
- if (window->SkipItems)
- return false;
- ImGuiContext &g = *GImGui;
- const ImGuiStyle &style = g.Style;
- const ImGuiID id = window->GetID(label);
- ImVec2 pos = window->DC.CursorPos;
- ImVec2 size = size_arg;
- size.x -= style.FramePadding.x * 2;
- const ImRect bb(pos, ImVec2(pos.x + size.x, pos.y + size.y));
- ItemSize(bb, style.FramePadding.y);
- if (!ItemAdd(bb, id))
- return false;
- // Render
- const float circleStart = size.x * 0.7f;
- const float circleEnd = size.x;
- const float circleWidth = circleEnd - circleStart;
- window->DrawList->AddRectFilled(bb.Min, ImVec2(pos.x + circleStart, bb.Max.y), bg_col);
- window->DrawList->AddRectFilled(bb.Min, ImVec2(pos.x + circleStart * value, bb.Max.y), fg_col);
- const float t = g.Time;
- const float r = size.y / 2;
- const float speed = 1.5f;
- const float a = speed * 0;
- const float b = speed * 0.333f;
- const float c = speed * 0.666f;
- const float o1 = (circleWidth + r) * (t + a - speed * (int)((t + a) / speed)) / speed;
- const float o2 = (circleWidth + r) * (t + b - speed * (int)((t + b) / speed)) / speed;
- const float o3 = (circleWidth + r) * (t + c - speed * (int)((t + c) / speed)) / speed;
- window->DrawList->AddCircleFilled(ImVec2(pos.x + circleEnd - o1, bb.Min.y + r), r, bg_col);
- window->DrawList->AddCircleFilled(ImVec2(pos.x + circleEnd - o2, bb.Min.y + r), r, bg_col);
- window->DrawList->AddCircleFilled(ImVec2(pos.x + circleEnd - o3, bb.Min.y + r), r, bg_col);
- }
- bool inline Spinner(const char *label, float radius, int thickness, const ImU32 &color =
- ImGui::GetColorU32(ImGuiCol_PlotHistogram))
- {
- ImGuiWindow *window = GetCurrentWindow();
- if (window->SkipItems)
- return false;
- ImGuiContext &g = *GImGui;
- const ImGuiStyle &style = g.Style;
- const ImGuiID id = window->GetID(label);
- ImVec2 pos = window->DC.CursorPos;
- ImVec2 size((radius) * 2, (radius + style.FramePadding.y) * 2);
- const ImRect bb(pos, ImVec2(pos.x + size.x, pos.y + size.y));
- ItemSize(bb, style.FramePadding.y);
- if (!ItemAdd(bb, id))
- return false;
- // Render
- window->DrawList->PathClear();
- int num_segments = 30;
- int start = std::abs(ImSin(g.Time * 1.8f) * (num_segments - 5));
- const float a_min = IM_PI * 2.0f * ((float)start) / (float)num_segments;
- const float a_max = IM_PI * 2.0f * ((float)num_segments - 3) / (float)num_segments;
- const ImVec2 centre = ImVec2(pos.x + radius, pos.y + radius + style.FramePadding.y);
- for (int i = 0; i < num_segments; i++)
- {
- const float a = a_min + ((float)i / (float)num_segments) * (a_max - a_min);
- window->DrawList->PathLineTo(ImVec2(centre.x + ImCos(a + g.Time * 8) * radius,
- centre.y + ImSin(a + g.Time * 8) * radius));
- }
- window->DrawList->PathStroke(color, false, thickness);
- }
- //todo refactor colors
- void inline LoadingIndicatorCircle(const char *label, const float indicator_radius,
- const int circle_count, const float speed,
- const ImU32 &bg_col = ImGui::GetColorU32(ImGuiCol_FrameBg),
- const ImU32 &fg_col = ImGui::GetColorU32(ImGuiCol_PlotHistogram)
- )
- {
- ImGuiWindow *window = GetCurrentWindow();
- if (window->SkipItems)
- {
- return;
- }
- ImGuiContext &g = *GImGui;
- const ImGuiID id = window->GetID(label);
- auto style = ImGui::GetStyle();
- const ImVec2 pos = window->DC.CursorPos;
- const float circle_radius = indicator_radius / 10.0f;
- const ImRect bb(pos, ImVec2(pos.x + indicator_radius * 2.0f,
- pos.y + indicator_radius * 2.0f));
- ItemSize(bb, style.FramePadding.y);
- if (!ItemAdd(bb, id))
- {
- return;
- }
- const float t = g.Time;
- const auto degree_offset = 2.0f * IM_PI / circle_count;
- for (int i = 0; i < circle_count; ++i)
- {
- const auto x = indicator_radius * std::sin(degree_offset * i);
- const auto y = indicator_radius * std::cos(degree_offset * i);
- const auto growth = std::max(0.0f, std::sin(t * speed - i * degree_offset));
- auto main_color = ColorConvertU32ToFloat4(fg_col);
- auto backdrop_color = ColorConvertU32ToFloat4(bg_col);
- ImVec4 color;
- color.x = main_color.x * growth + backdrop_color.x * (1.0f - growth);
- color.y = main_color.y * growth + backdrop_color.y * (1.0f - growth);
- color.z = main_color.z * growth + backdrop_color.z * (1.0f - growth);
- color.w = 1.0f;
- window->DrawList->AddCircleFilled(ImVec2(pos.x + indicator_radius + x,
- pos.y + indicator_radius - y),
- circle_radius + growth * circle_radius,
- GetColorU32(color));
- }
- }
- }
|