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.controller; 8 import creator.widgets; 9 import inochi2d; 10 11 bool incController(string str_id, ref Parameter param, ImVec2 size) { 12 ImGuiWindow* window = igGetCurrentWindow(); 13 if (window.SkipItems) return false; 14 15 ImVec2 avail; 16 igGetContentRegionAvail(&avail); 17 if (size.x <= 0) size.x = avail.x-size.x; 18 if (!param.isVec2) size.y = 32; 19 else if (size.y <= 0) size.y = avail.y-size.y; 20 21 ImGuiContext* ctx = igGetCurrentContext(); 22 ImGuiStyle style = ctx.Style; 23 ImGuiID id = ImGuiWindow_GetID_Str(window, str_id.ptr, str_id.ptr+str_id.length); 24 ImGuiStorage* storage = igGetStateStorage(); 25 26 // Handle padding 27 ImVec2 pos = window.DC.CursorPos; 28 size.x -= style.FramePadding.x*2; 29 30 // Apply size to "canvas" 31 ImRect bb = ImRect(pos, ImVec2(pos.x+size.x, pos.y+size.y)); 32 ImRect inner_bb = ImRect(ImVec2(pos.x+8, pos.y+8), ImVec2(pos.x+size.x-8, pos.y+size.y-8)); 33 ImRect clamp_bb = ImRect( 34 ImVec2(inner_bb.Min.x+4, inner_bb.Min.y+4), 35 ImVec2(inner_bb.Max.x-4, inner_bb.Max.y-4) 36 ); 37 igItemSize_Rect(bb, style.FramePadding.y); 38 if (!igItemAdd(bb, id, null)) 39 return false; 40 ImDrawList* drawList = igGetWindowDrawList(); 41 42 if (igIsItemHovered()) { 43 if (igIsMouseClicked(ImGuiMouseButton.Left, false)) { 44 ImGuiStorage_SetBool(storage, id, true); 45 } 46 } 47 48 if (!igIsMouseDown(ImGuiMouseButton.Left)) { 49 ImGuiStorage_SetBool(storage, id, false); 50 } 51 52 // Get clamped mouse position 53 ImVec2 mpos; 54 igGetMousePos(&mpos); 55 mpos.x = clamp(mpos.x, clamp_bb.Min.x, clamp_bb.Max.x); 56 mpos.y = clamp(mpos.y, clamp_bb.Min.y, clamp_bb.Max.y); 57 58 if (param.isVec2) { 59 float oldSize = style.FrameBorderSize; 60 igPushStyleVar_Float(ImGuiStyleVar.FrameBorderSize, 1); 61 igRenderFrameBorder(inner_bb.Min, inner_bb.Max, style.FrameRounding); 62 igPopStyleVar(1); 63 64 if (ImGuiStorage_GetBool(storage, id, false)) { 65 66 // Calculate the proper value 67 param.handle.x = (((mpos.x-clamp_bb.Min.x)/clamp_bb.Max.x)*2); 68 param.handle.y = (((mpos.y-clamp_bb.Min.y)/clamp_bb.Max.y)*2); 69 param.handle = clamp(param.handle, vec2(-1, -1), vec2(1, 1)); 70 } 71 72 // Draw our selector circle 73 ImDrawList_AddCircleFilled( 74 drawList, 75 ImVec2( 76 clamp_bb.Min.x + (clamp_bb.Max.x*((param.handle.x+1)/2)), 77 clamp_bb.Min.y + (clamp_bb.Max.y*((param.handle.y+1)/2)) 78 ), 79 4, 80 igGetColorU32_Vec4(ImVec4(1, 0, 0, 1)), 81 12 82 ); 83 } else { 84 ImDrawList_AddLine( 85 drawList, 86 ImVec2( 87 inner_bb.Min.x, 88 inner_bb.Min.y 89 ), 90 ImVec2( 91 inner_bb.Min.x, 92 inner_bb.Max.y 93 ), 94 igGetColorU32_Col(ImGuiCol.Border, 1), 95 2 96 ); 97 98 ImDrawList_AddLine( 99 drawList, 100 ImVec2( 101 inner_bb.Min.x, 102 pos.y+(size.y/2) 103 ), 104 ImVec2( 105 inner_bb.Max.x, 106 pos.y+(size.y/2) 107 ), 108 igGetColorU32_Col(ImGuiCol.Border, 1), 109 2 110 ); 111 112 ImDrawList_AddLine( 113 drawList, 114 ImVec2( 115 inner_bb.Max.x, 116 inner_bb.Min.y 117 ), 118 ImVec2( 119 inner_bb.Max.x, 120 inner_bb.Max.y 121 ), 122 igGetColorU32_Col(ImGuiCol.Border, 1), 123 2 124 ); 125 126 if (ImGuiStorage_GetBool(storage, id, false)) { 127 128 // Calculate the proper value 129 param.handle.x = ( 130 ( 131 (mpos.x-clamp_bb.Min.x)/clamp_bb.Max.x 132 )*2)-1; 133 param.handle = clamp(param.handle, vec2(-1, -1), vec2(1, 1)); 134 } 135 136 // Draw our selector circle 137 ImDrawList_AddCircleFilled( 138 drawList, 139 ImVec2( 140 clamp_bb.Min.x + (clamp_bb.Max.x*((param.handle.x+1)/2)), 141 pos.y+(size.y/2) 142 ), 143 4, 144 igGetColorU32_Vec4(ImVec4(1, 0, 0, 1)), 145 12 146 ); 147 } 148 return true; 149 }