1 /* 2 Copyright © 2022, Inochi2D Project 3 Distributed under the 2-Clause BSD License, see LICENSE file. 4 5 Authors: Luna Nielsen 6 */ 7 module creator.widgets.viewport; 8 import creator.widgets; 9 import inochi2d.math; 10 11 private { 12 struct ViewportToolAreaData { 13 ImVec2 contentSize; 14 } 15 } 16 17 /** 18 Starts a generalized tool area that resizes to fit its contents 19 */ 20 void incBeginViewportToolArea(string id_str, ImGuiDir hdir, ImGuiDir vdir = ImGuiDir.Up, bool pad = true) { 21 igSetItemAllowOverlap(); 22 igPushID(id_str.ptr, id_str.ptr+id_str.length); 23 auto storage = igGetStateStorage(); 24 auto win = igGetCurrentWindow(); 25 auto style = igGetStyle(); 26 auto id = igGetID("CONTENT_SIZE"); 27 28 // NOTE: Since this data is needed *before* we enter the child window 29 // we need to access it now, when we're writing to the values later 30 // we'll want to end the child FIRST before accessing it. 31 ViewportToolAreaData* data = cast(ViewportToolAreaData*)ImGuiStorage_GetVoidPtr(storage, id); 32 if (!data) { 33 data = cast(ViewportToolAreaData*)igMemAlloc(ViewportToolAreaData.sizeof); 34 data.contentSize = ImVec2(1, 1); 35 ImGuiStorage_SetVoidPtr(storage, id, data); 36 } 37 38 float paddingX = pad ? style.FramePadding.x : 0; 39 float paddingY = pad ? style.FramePadding.y : 0; 40 41 // Depending on whether we're on the right or the left we want the tool area to display slightly offset 42 // on the top left or top right, this ensures that. 43 igSetCursorScreenPos( 44 ImVec2( 45 hdir == ImGuiDir.Right ? win.InnerRect.Min.x - (paddingX+data.contentSize.x) : win.InnerRect.Max.x + paddingX, 46 vdir == ImGuiDir.Down ? win.InnerRect.Min.y - (paddingY+data.contentSize.y) : win.InnerRect.Max.y + paddingY, 47 ) 48 ); 49 50 igPushStyleVar(ImGuiStyleVar.FrameRounding, 0); 51 52 enum FLAGS = ImGuiWindowFlags.NoScrollbar | ImGuiWindowFlags.NoScrollWithMouse; 53 igBeginChild("CONTENT_CHILD", ImVec2(data.contentSize.x, data.contentSize.y), false, FLAGS); 54 } 55 56 void incEndViewportToolArea() { 57 auto win = igGetCurrentWindow(); 58 59 // End the child 60 igEndChild(); 61 62 // Pop style vars 63 igPopStyleVar(); 64 65 // NOTE: now that we're outside the child we can actually set the ViewportToolAreaData. 66 // Since we set the state storage outside of the child in the beginning 67 auto storage = igGetStateStorage(); 68 auto id = igGetID("CONTENT_SIZE"); 69 ViewportToolAreaData* data = cast(ViewportToolAreaData*)ImGuiStorage_GetVoidPtr(storage, id); 70 if (data) data.contentSize = ImVec2(clamp(win.ContentSize.x, 1, float.max), clamp(win.ContentSize.y, 1, float.max)); 71 72 // Finally pop the user specified ID which the state storage is stored inside 73 igPopID(); 74 }