102 Patches: Detours to the Rescue
C reference for DttR maintainers and modders.
Loading...
Searching...
No Matches
imgui_dialog.c
Go to the documentation of this file.
1#include <dttr_imgui.h>
2
3#include <glad/gl.h>
4
5static const ImGuiWindowFlags ROOT_WINDOW_FLAGS = ImGuiWindowFlags_NoDecoration
6 | ImGuiWindowFlags_NoMove
7 | ImGuiWindowFlags_NoSavedSettings;
8
9static bool sdl_video_ready;
10
12 if (ctx && ctx->imgui_context) {
13 igSetCurrentContext(ctx->imgui_context);
14 }
15}
16
18 if (!ctx) {
19 return;
20 }
21
22 igSetCurrentContext(ctx->previous_imgui_context);
23}
24
26 igSetCursorPosY(igGetCursorPosY() + DTTR_ImGuiDialog_ScaledFloat(ctx, amount));
27}
28
30 return ctx && ctx->desktop_scale > 0.0f ? ctx->desktop_scale : 1.0f;
31}
32
34 return value * context_scale(ctx);
35}
36
37static int scaled_int(const DTTR_ImGuiDialogContext *ctx, float value) {
38 const int scaled = (int)(DTTR_ImGuiDialog_ScaledFloat(ctx, value) + 0.5f);
39 return scaled > 0 ? scaled : 1;
40}
41
43 if (!ctx || !ctx->window || ctx->logical_window_width <= 0
44 || ctx->logical_window_height <= 0) {
45 return;
46 }
47
48 SDL_SetWindowSize(
49 ctx->window,
50 scaled_int(ctx, (float)ctx->logical_window_width),
51 scaled_int(ctx, (float)ctx->logical_window_height)
52 );
53}
54
56 if (!ctx || !ctx->window) {
57 return false;
58 }
59
60 const float old_scale = context_scale(ctx);
61 const bool style_changed = DTTR_ImGui_ApplyWindowDesktopScale(
62 &ctx->imgui_scale,
63 ctx->window
64 );
65 ctx->desktop_scale = DTTR_ImGui_GetCurrentDesktopScale(&ctx->imgui_scale);
66 const bool scale_changed = style_changed
67 || DTTR_ImGui_ScaleChanged(old_scale, ctx->desktop_scale);
68 if (scale_changed) {
70 }
71
72 return scale_changed;
73}
74
75static void set_gl_attributes() {
76 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
77 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
78 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
79 SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 0);
80 SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 0);
81}
82
83static bool init_sdl_video() {
84 if (sdl_video_ready) {
85 return true;
86 }
87
88 if (!SDL_InitSubSystem(SDL_INIT_VIDEO)) {
89 return false;
90 }
91
92 sdl_video_ready = true;
93 return true;
94}
95
97 ctx->previous_imgui_context = igGetCurrentContext();
98 ctx->imgui_context = igCreateContext(NULL);
100 ctx->imgui_context_ready = true;
101
102 ImGuiIO *io = igGetIO_Nil();
103 io->IniFilename = NULL;
104 io->LogFilename = NULL;
105 io->ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
106
107 igStyleColorsDark(NULL);
109 if (!ImGui_ImplSDL3_InitForOpenGL(ctx->window, ctx->gl_context)) {
110 return false;
111 }
112
113 ctx->imgui_sdl_ready = true;
114 if (!ImGui_ImplOpenGL3_Init("#version 130")) {
115 return false;
116 }
117
118 ctx->imgui_gl_ready = true;
119 return true;
120}
121
124 const char *title,
125 int width,
126 int height
127) {
128 if (!ctx) {
129 return false;
130 }
131
133 if (!init_sdl_video()) {
134 return false;
135 }
136
137 ctx->logical_window_width = width;
138 ctx->logical_window_height = height;
139
141
142 ctx->window = SDL_CreateWindow(
143 title,
144 width,
145 height,
146 SDL_WINDOW_OPENGL | SDL_WINDOW_HIDDEN
147 );
148 if (!ctx->window) {
149 goto fail;
150 }
151
152 ctx->gl_context = SDL_GL_CreateContext(ctx->window);
153 if (!ctx->gl_context || !SDL_GL_MakeCurrent(ctx->window, ctx->gl_context)) {
154 goto fail;
155 }
156
157 SDL_GL_SetSwapInterval(1);
158 if (!gladLoadGL((GLADloadfunc)SDL_GL_GetProcAddress)) {
159 goto fail;
160 }
161
162 if (!init_dialog_imgui(ctx)) {
163 goto fail;
164 }
165
166 SDL_ShowWindow(ctx->window);
167 return true;
168
169fail:
171 return false;
172}
173
175 if (!ctx) {
176 return;
177 }
178
180 if (ctx->imgui_gl_ready) {
181 ImGui_ImplOpenGL3_Shutdown();
182 }
183
184 if (ctx->imgui_sdl_ready) {
185 ImGui_ImplSDL3_Shutdown();
186 }
187
188 if (ctx->imgui_context_ready) {
189 igDestroyContext(ctx->imgui_context);
190 }
191
193 if (ctx->gl_context) {
194 SDL_GL_DestroyContext(ctx->gl_context);
195 }
196
197 if (ctx->window) {
198 SDL_DestroyWindow(ctx->window);
199 }
200
202}
203
205 if (!sdl_video_ready) {
206 return;
207 }
208
209 SDL_QuitSubSystem(SDL_INIT_VIDEO);
210 SDL_Quit();
211 sdl_video_ready = false;
212}
213
216 ImGui_ImplOpenGL3_NewFrame();
217 ImGui_ImplSDL3_NewFrame();
218 igNewFrame();
219}
220
223 int width;
224 int height;
225 SDL_GetWindowSizeInPixels(ctx->window, &width, &height);
226
227 igRender();
228 glViewport(0, 0, width, height);
229 glClearColor(0.06f, 0.07f, 0.09f, 1.0f);
230 glClear(GL_COLOR_BUFFER_BIT);
231 ImGui_ImplOpenGL3_RenderDrawData(igGetDrawData());
232 SDL_GL_SwapWindow(ctx->window);
233}
234
237 const SDL_Event *event,
238 bool *running
239) {
240 if (!event) {
241 return;
242 }
243
245 ImGui_ImplSDL3_ProcessEvent(event);
246 if (event->type != SDL_EVENT_QUIT) {
247 return;
248 }
249
250 if (running) {
251 *running = false;
252 }
253}
254
257 while (SDL_PollEvent(&event)) {
259 if (running && !*running) {
260 break;
261 }
262 }
263}
264
267 int width;
268 int height;
269 SDL_GetWindowSize(ctx->window, &width, &height);
270 igSetNextWindowPos((ImVec2_c){0.0f, 0.0f}, ImGuiCond_Always, (ImVec2_c){0.0f, 0.0f});
271 igSetNextWindowSize((ImVec2_c){(float)width, (float)height}, ImGuiCond_Always);
272}
273
276 const char *title,
277 ImGuiWindowFlags flags
278) {
280 igPushStyleVar_Vec2(ImGuiStyleVar_WindowPadding, (ImVec2_c){0.0f, 0.0f});
281 return igBegin(title, NULL, ROOT_WINDOW_FLAGS | flags);
282}
283
285 igEnd();
286 igPopStyleVar(1);
287}
288
291 const char *id,
292 const char *label,
293 ImVec2_c size
294) {
295 igPushID_Str(id);
296 igPushStyleColor_Vec4(ImGuiCol_Text, DTTR_IMGUI_COLOR_BUTTON_TEXT);
297 igPushStyleColor_Vec4(ImGuiCol_Button, DTTR_IMGUI_COLOR_BUTTON_BG);
298 igPushStyleColor_Vec4(ImGuiCol_ButtonHovered, DTTR_IMGUI_COLOR_BUTTON_BG_HOVERED);
299 igPushStyleColor_Vec4(ImGuiCol_ButtonActive, DTTR_IMGUI_COLOR_BUTTON_BG_ACTIVE);
300 igPushStyleVar_Float(
301 ImGuiStyleVar_FrameRounding,
303 );
304 const bool clicked = igButton(label, size);
305 igPopStyleVar(1);
306 igPopStyleColor(4);
307 igPopID();
308 return clicked;
309}
310
311void DTTR_ImGuiDialog_CenterNextItem(float item_width) {
312 const float window_width = igGetWindowWidth();
313 if (window_width > item_width) {
314 igSetCursorPosX((window_width - item_width) * 0.5f);
315 }
316}
317
318static void draw_centered_text(const char *text) {
319 const ImVec2_c size = igCalcTextSize(text, NULL, false, -1.0f);
321 igTextUnformatted(text, NULL);
322}
323
326 const char *title,
327 const char *version
328) {
330 const ImGuiStyle *style = igGetStyle();
331 const float title_font_size = (style ? style->FontSizeBase : 0.0f) * 1.35f;
332 igPushFont(NULL, title_font_size);
333 draw_centered_text(title);
334 igPopFont();
336 draw_centered_text(version);
338}
339
342 const char *message,
343 float padding_x,
344 float padding_y
345) {
346 igSetCursorPosX(DTTR_ImGuiDialog_ScaledFloat(ctx, padding_x));
348 igPushTextWrapPos(igGetWindowWidth() - DTTR_ImGuiDialog_ScaledFloat(ctx, padding_x));
349 igTextWrapped("%s", message ? message : "");
350 igPopTextWrapPos();
352}
353
356 int width,
357 float padding_y
358) {
359 const int scaled_width = scaled_int(ctx, (float)width);
360 const int height = (int)(igGetCursorPosY()
361 + DTTR_ImGuiDialog_ScaledFloat(ctx, padding_y) + 0.5f);
362 SDL_SetWindowSize(ctx->window, scaled_width, height);
363}
DTTR_Graphics_COM_Direct3DDevice7 DWORD block DTTR_Graphics_COM_Direct3DDevice7 DWORD block DTTR_Graphics_COM_Direct3DDevice7 void void void void DWORD f DTTR_Graphics_COM_Direct3DDevice7 DWORD idx float
void void * ctx
DTTR_Graphics_COM_Direct3DDevice7 void DWORD flags DWORD void DWORD flags
const DWORD size
void void DWORD HANDLE event
DTTR_Graphics_COM_DirectDrawSurface7 DWORD flags void NULL
#define DTTR_IMGUI_COLOR_BUTTON_TEXT
Definition dttr_imgui.h:15
static float DTTR_ImGui_GetCurrentDesktopScale(const DTTR_ImGuiDesktopScaleState *state)
Definition dttr_imgui.h:38
static bool DTTR_ImGui_ScaleChanged(float a, float b)
Definition dttr_imgui.h:46
static bool DTTR_ImGui_ApplyWindowDesktopScale(DTTR_ImGuiDesktopScaleState *state, SDL_Window *window)
Definition dttr_imgui.h:77
#define DTTR_IMGUI_COLOR_BUTTON_BG
Definition dttr_imgui.h:12
#define DTTR_IMGUI_COLOR_BUTTON_BG_HOVERED
Definition dttr_imgui.h:13
#define DTTR_IMGUI_COLOR_BUTTON_BG_ACTIVE
Definition dttr_imgui.h:14
union SDL_Event SDL_Event
Definition dttr_mods.h:19
static void resize_dialog_window_for_scale(DTTR_ImGuiDialogContext *ctx)
void DTTR_ImGuiDialog_End(DTTR_ImGuiDialogContext *ctx)
void DTTR_ImGuiDialog_DrawHeader(const DTTR_ImGuiDialogContext *ctx, const char *title, const char *version)
void DTTR_ImGuiDialog_CenterNextItem(float item_width)
void DTTR_ImGuiDialog_Render(DTTR_ImGuiDialogContext *ctx)
bool DTTR_ImGuiDialog_RefreshScale(DTTR_ImGuiDialogContext *ctx)
bool DTTR_ImGuiDialog_BeginRoot(DTTR_ImGuiDialogContext *ctx, const char *title, ImGuiWindowFlags flags)
static int scaled_int(const DTTR_ImGuiDialogContext *ctx, float value)
float DTTR_ImGuiDialog_ScaledFloat(const DTTR_ImGuiDialogContext *ctx, float value)
void DTTR_ImGuiDialog_OffsetCursorY(const DTTR_ImGuiDialogContext *ctx, float amount)
void DTTR_ImGuiDialog_DrawPaddedText(const DTTR_ImGuiDialogContext *ctx, const char *message, float padding_x, float padding_y)
static bool sdl_video_ready
Definition imgui_dialog.c:9
static void begin_full_window(const DTTR_ImGuiDialogContext *ctx)
static void draw_centered_text(const char *text)
static void use_dialog_imgui_context(const DTTR_ImGuiDialogContext *ctx)
void DTTR_ImGuiDialog_ProcessEvents(const DTTR_ImGuiDialogContext *ctx, bool *running)
bool DTTR_ImGuiDialog_Button(const DTTR_ImGuiDialogContext *ctx, const char *id, const char *label, ImVec2_c size)
void DTTR_ImGuiDialog_EndRoot()
static bool init_dialog_imgui(DTTR_ImGuiDialogContext *ctx)
void DTTR_ImGuiDialog_NewFrame(const DTTR_ImGuiDialogContext *ctx)
void DTTR_ImGuiDialog_ProcessEvent(const DTTR_ImGuiDialogContext *ctx, const SDL_Event *event, bool *running)
static const ImGuiWindowFlags ROOT_WINDOW_FLAGS
Definition imgui_dialog.c:5
static bool init_sdl_video()
static float context_scale(const DTTR_ImGuiDialogContext *ctx)
static void set_gl_attributes()
void DTTR_ImGuiDialog_FitWindowToContent(DTTR_ImGuiDialogContext *ctx, int width, float padding_y)
void DTTR_ImGuiDialog_Shutdown()
static void restore_previous_imgui_context(const DTTR_ImGuiDialogContext *ctx)
bool DTTR_ImGuiDialog_Begin(DTTR_ImGuiDialogContext *ctx, const char *title, int width, int height)