1 //------------------------------------------------------------------------------
2 //  imgui.d
3 //
4 //  Using cimgui + sokol, based on https://github.com/floooh/sokol-zig-imgui-sample
5 //------------------------------------------------------------------------------
6 
7 module examples.imgui;
8 
9 import sg = sokol.gfx;
10 import sgapp = sokol.glue;
11 import sapp = sokol.app;
12 import imgui = sokol.imgui;
13 import log = sokol.log;
14 
15 extern (C):
16 @safe:
17 
18 struct State
19 {
20     sg.PassAction pass_action = {
21         colors: [
22             {
23                 load_action: sg.LoadAction.Clear,
24                 clear_value: {r: 0.0, g: 0.5, b: 1.0, a: 1.0},
25             }
26         ]
27     };
28 }
29 
30 static State state;
31 
32 void init() @safe @nogc nothrow
33 {
34     sg.Desc gfx = {
35         environment: sgapp.environment,
36         logger: {func: &log.slog_func}
37     };
38     sg.setup(gfx);
39     imgui.Desc imgui_desc = {0};
40     imgui.setup(imgui_desc);
41 }
42 
43 void frame() @trusted @nogc nothrow
44 {
45     imgui.FrameDesc imgui_desc = {
46         width: sapp.width(),
47         height: sapp.height(),
48         delta_time: sapp.frameDuration(),
49         dpi_scale: sapp.dpiScale(),
50     };
51     imgui.newFrame(imgui_desc);
52 
53     /*=== UI CODE STARTS HERE ===*/
54     const ImVec2 window_pos = {10, 10};
55     const ImVec2 window_pos_pivot = {0, 0};
56     const ImVec2 window_size = {400, 100};
57     igSetNextWindowPos(window_pos, ImGuiCond_.ImGuiCond_Once, window_pos_pivot);
58     igSetNextWindowSize(window_size, ImGuiCond_.ImGuiCond_Once);
59     igBegin("Hello Dear ImGui!".ptr, null, ImGuiWindowFlags_.ImGuiWindowFlags_None);
60     const(char)* label = "Background";
61     float[3] rgb = [
62         state.pass_action.colors[0].clear_value.r,
63         state.pass_action.colors[0].clear_value.g,
64         state.pass_action.colors[0].clear_value.b
65     ];
66     igColorEdit3(label, rgb, ImGuiColorEditFlags_.ImGuiColorEditFlags_None);
67     igEnd();
68     /*=== UI CODE ENDS HERE ===*/
69 
70     sg.Pass pass = {action: state.pass_action, swapchain: sgapp.swapchain};
71     sg.beginPass(pass);
72     imgui.render;
73     sg.endPass;
74     sg.commit;
75 }
76 
77 void event(const(sapp.Event)* ev) @trusted @nogc nothrow
78 {
79     imgui.simgui_handle_event(ev);
80 }
81 
82 void cleanup() @safe @nogc nothrow
83 {
84     imgui.shutdown;
85     sg.shutdown;
86 }
87 
88 void main() @safe @nogc nothrow
89 {
90     sapp.Desc runner = {
91         window_title: "imgui.d",
92         init_cb: &init,
93         frame_cb: &frame,
94         cleanup_cb: &cleanup,
95         event_cb: &event,
96         width: 800,
97         height: 600,
98         icon: {sokol_default: true},
99         logger: {func: &log.func}
100     };
101     sapp.run(runner);
102 }
103 
104 // -- CIMGUI -- //
105 @nogc nothrow:
106 extern (C) bool igBegin(scope const(char)* name, scope bool* p_open, ImGuiWindowFlags flags);
107 extern (C) void igEnd();
108 extern (C) void igSetNextWindowPos(const ImVec2 pos, ImGuiCond cond, const ImVec2 pivot);
109 extern (C) void igSetNextWindowSize(const ImVec2 size, ImGuiCond cond);
110 extern (C) bool igColorEdit3(scope const(char)* label, ref float[3] col, ImGuiColorEditFlags flags);
111 
112 extern (C):
113 struct ImVec2
114 {
115     float x = 0.0f;
116     float y = 0.0f;
117 }
118 
119 enum ImGuiColorEditFlags_
120 {
121     ImGuiColorEditFlags_None = 0,
122     ImGuiColorEditFlags_NoAlpha = 1 << 1,
123     ImGuiColorEditFlags_NoPicker = 1 << 2,
124     ImGuiColorEditFlags_NoOptions = 1 << 3,
125     ImGuiColorEditFlags_NoSmallPreview = 1 << 4,
126     ImGuiColorEditFlags_NoInputs = 1 << 5,
127     ImGuiColorEditFlags_NoTooltip = 1 << 6,
128     ImGuiColorEditFlags_NoLabel = 1 << 7,
129     ImGuiColorEditFlags_NoSidePreview = 1 << 8,
130     ImGuiColorEditFlags_NoDragDrop = 1 << 9,
131     ImGuiColorEditFlags_NoBorder = 1 << 10,
132     ImGuiColorEditFlags_AlphaBar = 1 << 16,
133     ImGuiColorEditFlags_AlphaPreview = 1 << 17,
134     ImGuiColorEditFlags_AlphaPreviewHalf = 1 << 18,
135     ImGuiColorEditFlags_HDR = 1 << 19,
136     ImGuiColorEditFlags_DisplayRGB = 1 << 20,
137     ImGuiColorEditFlags_DisplayHSV = 1 << 21,
138     ImGuiColorEditFlags_DisplayHex = 1 << 22,
139     ImGuiColorEditFlags_Uint8 = 1 << 23,
140     ImGuiColorEditFlags_Float = 1 << 24,
141     ImGuiColorEditFlags_PickerHueBar = 1 << 25,
142     ImGuiColorEditFlags_PickerHueWheel = 1 << 26,
143     ImGuiColorEditFlags_InputRGB = 1 << 27,
144     ImGuiColorEditFlags_InputHSV = 1 << 28,
145     ImGuiColorEditFlags_DefaultOptions_
146         = ImGuiColorEditFlags_Uint8 | ImGuiColorEditFlags_DisplayRGB
147         | ImGuiColorEditFlags_InputRGB | ImGuiColorEditFlags_PickerHueBar,
148     ImGuiColorEditFlags_DisplayMask_ = ImGuiColorEditFlags_DisplayRGB
149         | ImGuiColorEditFlags_DisplayHSV | ImGuiColorEditFlags_DisplayHex,
150     ImGuiColorEditFlags_DataTypeMask_ = ImGuiColorEditFlags_Uint8 | ImGuiColorEditFlags_Float,
151     ImGuiColorEditFlags_PickerMask_
152         = ImGuiColorEditFlags_PickerHueWheel | ImGuiColorEditFlags_PickerHueBar,
153     ImGuiColorEditFlags_InputMask_ = ImGuiColorEditFlags_InputRGB | ImGuiColorEditFlags_InputHSV
154 }
155 
156 enum ImGuiWindowFlags_
157 {
158     ImGuiWindowFlags_None = 0,
159     ImGuiWindowFlags_NoTitleBar = 1 << 0,
160     ImGuiWindowFlags_NoResize = 1 << 1,
161     ImGuiWindowFlags_NoMove = 1 << 2,
162     ImGuiWindowFlags_NoScrollbar = 1 << 3,
163     ImGuiWindowFlags_NoScrollWithMouse = 1 << 4,
164     ImGuiWindowFlags_NoCollapse = 1 << 5,
165     ImGuiWindowFlags_AlwaysAutoResize = 1 << 6,
166     ImGuiWindowFlags_NoBackground = 1 << 7,
167     ImGuiWindowFlags_NoSavedSettings = 1 << 8,
168     ImGuiWindowFlags_NoMouseInputs = 1 << 9,
169     ImGuiWindowFlags_MenuBar = 1 << 10,
170     ImGuiWindowFlags_HorizontalScrollbar = 1 << 11,
171     ImGuiWindowFlags_NoFocusOnAppearing = 1 << 12,
172     ImGuiWindowFlags_NoBringToFrontOnFocus = 1 << 13,
173     ImGuiWindowFlags_AlwaysVerticalScrollbar = 1 << 14,
174     ImGuiWindowFlags_AlwaysHorizontalScrollbar = 1 << 15,
175     ImGuiWindowFlags_AlwaysUseWindowPadding = 1 << 16,
176     ImGuiWindowFlags_NoNavInputs = 1 << 18,
177     ImGuiWindowFlags_NoNavFocus = 1 << 19,
178     ImGuiWindowFlags_UnsavedDocument = 1 << 20,
179     ImGuiWindowFlags_NoNav = ImGuiWindowFlags_NoNavInputs | ImGuiWindowFlags_NoNavFocus,
180     ImGuiWindowFlags_NoDecoration = ImGuiWindowFlags_NoTitleBar
181         | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoCollapse,
182     ImGuiWindowFlags_NoInputs = ImGuiWindowFlags_NoMouseInputs
183         | ImGuiWindowFlags_NoNavInputs | ImGuiWindowFlags_NoNavFocus,
184     ImGuiWindowFlags_NavFlattened = 1 << 23,
185     ImGuiWindowFlags_ChildWindow = 1 << 24,
186     ImGuiWindowFlags_Tooltip = 1 << 25,
187     ImGuiWindowFlags_Popup = 1 << 26,
188     ImGuiWindowFlags_Modal = 1 << 27,
189     ImGuiWindowFlags_ChildMenu = 1 << 28
190 }
191 
192 enum ImGuiCond_
193 {
194     ImGuiCond_None = 0,
195     ImGuiCond_Always = 1 << 0,
196     ImGuiCond_Once = 1 << 1,
197     ImGuiCond_FirstUseEver = 1 << 2,
198     ImGuiCond_Appearing = 1 << 3
199 }
200 
201 alias ImGuiCond = int;
202 alias ImGuiColorEditFlags = int;
203 alias ImGuiWindowFlags = int;