| 22 | |
| 23 | namespace ImGui { |
| 24 | void uiSpinner(const char* label, const float indicator_radius, const ImVec4& main_color, const ImVec4& backdrop_color, const int circle_count, const float speed) { |
| 25 | ImGuiWindow* window = GetCurrentWindow(); |
| 26 | if (window->SkipItems) { |
| 27 | return; |
| 28 | } |
| 29 | |
| 30 | ImGuiContext& g = *GImGui; |
| 31 | const ImGuiID id = window->GetID(label); |
| 32 | |
| 33 | const ImVec2 pos = window->DC.CursorPos; |
| 34 | const float circle_radius = indicator_radius / 10.0f; |
| 35 | const ImRect bb(pos, ImVec2(pos.x + indicator_radius * 2.0f, |
| 36 | pos.y + indicator_radius * 2.0f)); |
| 37 | ItemSize(bb, ImGui::GetStyle().FramePadding.y); |
| 38 | if (!ItemAdd(bb, id)) { |
| 39 | return; |
| 40 | } |
| 41 | const float t = (float)g.Time; |
| 42 | const auto degree_offset = 2.0f * IM_PI / circle_count; |
| 43 | for (int i = 0; i < circle_count; ++i) { |
| 44 | const auto x = indicator_radius * std::sin(degree_offset * i); |
| 45 | const auto y = indicator_radius * std::cos(degree_offset * i); |
| 46 | const auto growth = std::max(0.0f, std::sin(t * speed - i * degree_offset)); |
| 47 | ImVec4 color; |
| 48 | color.x = main_color.x * growth + backdrop_color.x * (1.0f - growth); |
| 49 | color.y = main_color.y * growth + backdrop_color.y * (1.0f - growth); |
| 50 | color.z = main_color.z * growth + backdrop_color.z * (1.0f - growth); |
| 51 | color.w = 1.0f; |
| 52 | window->DrawList->AddCircleFilled(ImVec2(pos.x + indicator_radius + x, |
| 53 | pos.y + indicator_radius - y), |
| 54 | circle_radius + growth * circle_radius, |
| 55 | GetColorU32(color)); |
| 56 | } |
| 57 | } |
| 58 | |
| 59 | float GetSpinnerWidth() { |
| 60 | return GetCurrentContext()->Font->FontSize*2.0f; |
no test coverage detected