Spinner (modified code from issue #1901)

using ComVec4 = const ImVec4 &;
auto Spinner(float radius, float thickness, int num_segments, ComVec4 color) {
	auto window = GetCurrentWindow();
	if (window->SkipItems)
		return;

	auto &g = *GImGui;
	const auto &style = g.Style;
	auto &&pos = ImGui::GetCursorPos();
	ImVec2 size{radius * 2, radius * 2};
	const ImRect bb{pos, pos + size};
	ItemSize(bb);
	if (!ItemAdd(bb, 0))
		return;

	window->DrawList->PathClear();
	int start = static_cast<int>(abs(ImSin(static_cast<float>(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 auto &&centre = pos + radius;
	for (auto i = 0; i < num_segments; i++) {
		const float a = a_min + ((float) i / (float) num_segments) * (a_max - a_min);
		auto time = static_cast<float>(g.Time);
		window->DrawList->PathLineTo({centre.x + ImCos(a + time * 8) * radius,
		                              centre.y + ImSin(a + time * 8) * radius});
	}
	window->DrawList->PathStroke(GetColorU32(color), false, thickness);
}

Test code:

static float val{};
ImGui::Spinner(16);
ImGui::BufferingBar(val, {400, 10});
ImGui::SliderFloat("Buffering Bar Value", &val, 0, 1);

Screenshot:

Can you please modify the spinner function with a parameter for speed.

0 => Not spinning
0.5=>Halfspeed
1=>Max speed

Also if possible add another parameter where one can choose the text at the center
i.e β€œ80%”

The resulting function could be like this

/* ImGui::Spinner(char * name,char * Text,float speed,float size, float radius,  const ImU32& color); */
ImGui::Spinner("##spinner","80% Complete",0.224, 9, col);

I really need this ti work and be something close to this one. 44051219-ec0f68bc-9f41-11e8-953c-176a43d7b1c5

Thanks in advance.

ImGui::SetCursorPos and ImGui::Text are your friends.

auto ImGui::Spinner(float radius, float thickness, int num_segments, float speed, ComVec4 color) -> void {
	auto window = GetCurrentWindow();
	if (window->SkipItems)
		return;

	auto &g = *GImGui;
	const auto &style = g.Style;
	auto &&pos = ImGui::GetCursorPos();
	ImVec2 size{radius * 2, radius * 2};
	const ImRect bb{pos, pos + size};
	ItemSize(bb);
	if (!ItemAdd(bb, 0))
		return;

	auto time = static_cast<float>(g.Time) * speed;
	window->DrawList->PathClear();
	int start = static_cast<int>(abs(ImSin(time) * (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 auto &&centre = pos + radius;
	for (auto i = 0; i < num_segments; i++) {
		const float a = a_min + ((float) i / (float) num_segments) * (a_max - a_min);
		window->DrawList->PathLineTo({centre.x + ImCos(a + time * 8) * radius,
		                              centre.y + ImSin(a + time * 8) * radius});
	}
	window->DrawList->PathStroke(GetColorU32(color), false, thickness);
}

Added speed argument, defaultly 1.8f. If you make it i.e. 3.6f it’ll rotate twice the speed.

1 Like

Thank you so much.
This code will help me a lot.