1 /* 2 Copyright © 2020, Inochi2D Project 3 Distributed under the 2-Clause BSD License, see LICENSE file. 4 5 Authors: Luna Nielsen 6 */ 7 module creator.widgets.progress; 8 import creator.widgets; 9 import inochi2d.math; 10 11 // 12 // BORROWED AND MODIFIED FROM 13 // https://github.com/ocornut/imgui/issues/1901 14 // 15 16 bool incBufferBar(string label, float value, ImVec2 size, ImU32 bgColor, ImU32 fgColor) { 17 ImGuiWindow* window = igGetCurrentWindow(); 18 if (window.SkipItems) return false; 19 20 ImVec2 avail; 21 igGetContentRegionAvail(&avail); 22 if (size.x <= 0) size.x = avail.x-size.x; 23 if (size.y == 0) size.y = 64; 24 25 value = clamp(value, 0, 1); 26 27 28 ImGuiContext* ctx = igGetCurrentContext(); 29 ImGuiStyle style = ctx.Style; 30 ImGuiID id = ImGuiWindow_GetID_Str(window, label.ptr, label.ptr+label.length); 31 32 ImVec2 pos = window.DC.CursorPos; 33 size.x -= style.FramePadding.x*2; 34 35 ImRect bb = ImRect(ImVec2(pos.x, pos.y+((size.y/2)-2)), ImVec2(pos.x+size.x, pos.y+((size.y/2)+2))); 36 ImRect obb = ImRect(pos, ImVec2(pos.x+size.x, pos.y+size.y)); 37 igItemSize_Rect(obb, style.FramePadding.y); 38 if (!igItemAdd(obb, id, null)) 39 return false; 40 41 float circleStart = size.x; // * 0.7f; 42 float circleEnd = size.x; 43 float circleWidth = circleEnd-circleStart; 44 45 ImDrawList_AddRectFilled(igGetWindowDrawList(), bb.Min, ImVec2(pos.x + circleStart, bb.Max.y), bgColor, 8, ImDrawFlags.RoundCornersAll); 46 ImDrawList_AddRectFilled(igGetWindowDrawList(), bb.Min, ImVec2(pos.x + circleStart*value, bb.Max.y), fgColor, 8, ImDrawFlags.RoundCornersAll); 47 48 49 igNewLine(); 50 return false; 51 } 52 53 /** 54 Creates a spinner 55 */ 56 bool incSpinner(string label, float radius, int thickness, ImU32 color) { 57 ImGuiWindow* window = igGetCurrentWindow(); 58 if (window.SkipItems) return false; 59 60 // If radius less or equal to 0 is passed do normal imgui behaviour 61 ImVec2 avail; 62 igGetContentRegionAvail(&avail); 63 if (radius <= 0) radius = (min(avail.x, avail.y)/2) - radius; 64 65 66 ImGuiContext* ctx = igGetCurrentContext(); 67 ImGuiStyle style = ctx.Style; 68 ImGuiID id = ImGuiWindow_GetID_Str(window, label.ptr, label.ptr+label.length); 69 70 ImVec2 pos = ImVec2(window.DC.CursorPos.x, window.DC.CursorPos.y); 71 ImVec2 size = ImVec2((radius*2), ((radius+style.FramePadding.y)*2)); 72 ImRect bb = ImRect(pos, ImVec2(pos.x+size.x, pos.y+size.y)); 73 igItemSize_Rect(bb, style.FramePadding.y); 74 if (!igItemAdd(bb, id)) 75 return false; 76 77 // Render 78 ImDrawList_PathClear(igGetWindowDrawList()); 79 80 enum SEGMENTS = 45; 81 float start = abs(sin(ctx.Time*1.4f)*(SEGMENTS-5)); 82 83 const float aMin = PI*2 * (cast(float)start / cast(float)SEGMENTS); 84 const float aMax = PI*2 * ((cast(float)SEGMENTS-3) / cast(float)SEGMENTS); 85 86 ImVec2 center = ImVec2(pos.x+radius, pos.y+radius+style.FramePadding.y); 87 88 for (int i = 0; i < SEGMENTS; i++) { 89 const float a = aMin + (cast(float)i / cast(float)SEGMENTS) * (aMax-aMin); 90 ImDrawList_PathLineTo(igGetWindowDrawList(), ImVec2( 91 center.x + cos(a+ctx.Time*8) * (radius-thickness), 92 center.y + sin(a+ctx.Time*8) * (radius-thickness) 93 )); 94 } 95 96 ImDrawList_PathStroke(igGetWindowDrawList(), color, ImDrawFlags.None, thickness); 97 igNewLine(); 98 return false; 99 }