1 module creator.widgets.shadow; 2 import bindbc.imgui; 3 import std.stdio : writeln; 4 5 /** 6 Creates drawlist 7 */ 8 ImDrawList* incCreateWindowDrawList() { 9 return ImDrawList_ImDrawList(igGetDrawListSharedData()); 10 } 11 12 /** 13 destroys drawlist 14 */ 15 void incDestroyWindowDrawList(ImDrawList* drawList) { 16 ImDrawList_destroy(drawList); 17 } 18 19 private { 20 T* prepend(T)(ref ImVector!T vec, ref ImVector!T other) { 21 import core.stdc.string : memcpy; 22 if (other.Size == 0) return &vec.Data[vec.Size]; 23 24 // First reserve space to make sure the data will fit. 25 // NOTE: We need to *reserve* space, not resize 26 // If we used resize, vec.Size would be wrong and we would 27 // Get garbage data likely to crash the app. 28 int newSize = vec.Size+other.Size; 29 if (newSize > vec.Capacity) vec.reserve(vec._grow_capacity(newSize)); 30 31 memcpy(vec.Data+other.Size, vec.Data, vec.Size*T.sizeof); 32 memcpy(vec.Data, other.Data, other.Size*T.sizeof); 33 34 // Apply the new size based on the previous sizes. 35 vec.Size = newSize; 36 return &vec.Data[vec.Size]; 37 } 38 39 void prepend(ImDrawList* self, ImDrawList* other) { 40 41 // Offset draw buffer 42 ImDrawCmd* cmd = &self.CmdBuffer.Data[0]; 43 cmd.VtxOffset += other.VtxBuffer.size; 44 cmd.IdxOffset += other.IdxBuffer.size; 45 46 // Copy state from origin 47 ImDrawCmd* ocmd = &other.CmdBuffer.Data[0]; 48 ocmd.TextureId = cmd.TextureId; 49 ocmd.ClipRect = cmd.ClipRect; 50 51 // Prepend 52 self.CmdBuffer.prepend(other.CmdBuffer); 53 self._VtxWritePtr = self.VtxBuffer.prepend(other.VtxBuffer); 54 self._IdxWritePtr = self.IdxBuffer.prepend(other.IdxBuffer); 55 self._VtxCurrentIdx = other.VtxBuffer.Size; 56 self._Path.prepend(other._Path); 57 self._TextureIdStack.prepend(other._TextureIdStack); 58 self._ClipRectStack.prepend(other._ClipRectStack); 59 } 60 } 61 62 /** 63 Renders a shadow at the specified spot 64 */ 65 void incRenderWindowShadow(ImDrawList* drawList, ImRect area, float falloff=16, float startShade=0.25) { 66 ImDrawList__ResetForNewFrame(drawList); 67 auto outDrawList = igGetWindowDrawList(); 68 auto style = igGetStyle(); 69 70 float inset = style.WindowRounding; 71 uint iColor = igGetColorU32(ImVec4(0, 0, 0, startShade)); 72 uint oColor = igGetColorU32(ImVec4(0, 0, 0, 0)); 73 74 ImVec2 shadowInnerMin = ImVec2(area.Min.x-inset, area.Min.y-inset); 75 ImVec2 shadowInnerMax = ImVec2(area.Max.x+inset, area.Max.y+inset); 76 ImVec2 realMin = ImVec2(shadowInnerMin.x+falloff, shadowInnerMin.y+falloff); 77 ImVec2 realMax = ImVec2(shadowInnerMax.x-falloff, shadowInnerMax.y-falloff); 78 79 igPushClipRect(realMin, realMax, false); 80 81 // CENTER 82 ImDrawList_AddRectFilled( 83 drawList, 84 shadowInnerMin, 85 shadowInnerMax, 86 iColor 87 ); 88 89 // CORNERS 90 91 // LEFT TOP 92 // XX 93 // XO 94 ImDrawList_AddRectFilledMultiColor( 95 drawList, 96 ImVec2(realMax.x, realMax.y), 97 ImVec2(shadowInnerMax.x, shadowInnerMax.y), 98 oColor, 99 oColor, 100 iColor, 101 oColor, 102 ); 103 104 // RIGHT TOP 105 // XX 106 // OX 107 ImDrawList_AddRectFilledMultiColor( 108 drawList, 109 ImVec2(realMin.x, realMax.y), 110 ImVec2(shadowInnerMin.x, shadowInnerMax.y), 111 oColor, 112 oColor, 113 iColor, 114 oColor, 115 ); 116 117 // LEFT BOTTOM 118 // XO 119 // XX 120 ImDrawList_AddRectFilledMultiColor( 121 drawList, 122 ImVec2(realMax.x, realMin.y), 123 ImVec2(shadowInnerMax.x, shadowInnerMin.y), 124 oColor, 125 oColor, 126 iColor, 127 oColor, 128 ); 129 130 // RIGHT BOTTOM 131 // OX 132 // XX 133 ImDrawList_AddRectFilledMultiColor( 134 drawList, 135 ImVec2(realMin.x, realMin.y), 136 ImVec2(shadowInnerMin.x, shadowInnerMin.y), 137 oColor, 138 oColor, 139 iColor, 140 oColor, 141 ); 142 143 144 // CAPS 145 146 // LEFT 147 // XO 148 // XO 149 ImDrawList_AddRectFilledMultiColor( 150 drawList, 151 ImVec2(realMax.x, shadowInnerMin.y), 152 ImVec2(shadowInnerMax.x, shadowInnerMax.y), 153 oColor, 154 iColor, 155 iColor, 156 oColor, 157 ); 158 159 // RIGHT 160 // OX 161 // OX 162 ImDrawList_AddRectFilledMultiColor( 163 drawList, 164 ImVec2(shadowInnerMin.x, shadowInnerMin.y), 165 ImVec2(realMin.x, shadowInnerMax.y), 166 iColor, 167 oColor, 168 oColor, 169 iColor, 170 ); 171 172 // TOP 173 // XX 174 // OO 175 ImDrawList_AddRectFilledMultiColor( 176 drawList, 177 ImVec2(shadowInnerMin.x, realMax.y), 178 ImVec2(shadowInnerMax.x, shadowInnerMax.y), 179 oColor, 180 oColor, 181 iColor, 182 iColor, 183 ); 184 185 // BOTTOM 186 // OO 187 // XX 188 ImDrawList_AddRectFilledMultiColor( 189 drawList, 190 ImVec2(shadowInnerMin.x, shadowInnerMin.y), 191 ImVec2(shadowInnerMax.x, realMin.y), 192 iColor, 193 iColor, 194 oColor, 195 oColor, 196 ); 197 198 igPopClipRect(); 199 200 outDrawList.prepend(drawList); 201 }