102 Patches: Detours to the Rescue
C reference for DttR maintainers and modders.
Loading...
Searching...
No Matches
gui_widgets.c
Go to the documentation of this file.
1#include "gui_internal.h"
2
3#include <math.h>
4
11
13 igDummy((ImVec2_c){0.0f, DTTR_ImGuiDialog_ScaledFloat(ctx, height)});
14}
15
19);
20
21typedef struct {
22 const char *id;
23 const char *label;
24 const char *tooltip;
27
28static const char *const FOOTER_HINT_TEXT = "Ctrl+S to save your changes.";
29
35
39
43
49
51 const float content_width = fmaxf(
54 );
55 return (int)(DTTR_CONFIG_UI_PANEL_PADDING_X * 2.0f + content_width);
56}
57
58static int choice_index(const DTTR_ConfigChoice *choices, int choice_count, int value) {
59 for (int i = 0; i < choice_count; i++) {
60 if (choices[i].value == value) {
61 return i;
62 }
63 }
64
65 return 0;
66}
67
69 const char *label,
70 int *value,
72 const char *const *tooltips
73) {
74 int choice_count = 0;
75 const DTTR_ConfigChoice *choice_list = DTTR_Config_Choices(choices, &choice_count);
76 const int current = choice_index(choice_list, choice_count, *value);
77 const char *preview = choice_count > 0 ? choice_list[current].label : "Unknown";
78 const ImVec2_c combo_popup_padding = {
79 igGetStyle()->WindowPadding.x,
81 };
82
83 igPushStyleVar_Vec2(ImGuiStyleVar_WindowPadding, combo_popup_padding);
84 const bool open = igBeginCombo(label, preview, ImGuiComboFlags_None);
85 igPopStyleVar(1);
86
87 if (!open) {
88 return false;
89 }
90
91 bool changed = false;
92
93 for (int i = 0; i < choice_count; i++) {
94 const bool selected = i == current;
95
96 if (igSelectable_Bool(
97 choice_list[i].label,
98 selected,
99 ImGuiSelectableFlags_None,
100 (ImVec2_c){0.0f, 0.0f}
101 )) {
102 *value = choice_list[i].value;
103 changed = true;
104 }
105
106 show_tooltip(tooltips ? tooltips[i] : NULL);
107 }
108
109 igEndCombo();
110 return changed;
111}
112
113static void draw_wrapped_tooltip_segment(const char *start, const char *end) {
114 if (!start || start == end) {
115 return;
116 }
117
118 igTextWrapped("%.*s", (int)(end - start), start);
119}
120
121static void draw_inline_tooltip_segment(const char *start, const char *end) {
122 if (!start || start == end) {
123 return;
124 }
125
126 igSameLine(0.0f, 0.0f);
127 igTextUnformatted(start, end);
128}
129
130static void draw_default_inline_text(const char *start, const char *end) {
131 if (!start || start == end) {
132 return;
133 }
134
135 igSameLine(0.0f, 0.0f);
136 igTextColored(
138 "%.*s",
139 (int)(end - start),
140 start
141 );
142}
143
145 const char *default_value_start,
146 const char *default_value_end
147) {
148 const char *release_suffix = strstr(default_value_start, " (release), ");
149
150 if (release_suffix && release_suffix < default_value_end) {
151 const char *debug_start = release_suffix + strlen(" (release), ");
152 const char *debug_suffix = strstr(debug_start, " (debug)");
153
154 if (debug_suffix && debug_suffix < default_value_end) {
155 draw_default_inline_text(default_value_start, release_suffix);
156 draw_inline_tooltip_segment(release_suffix, debug_start);
157 draw_default_inline_text(debug_start, debug_suffix);
158 draw_inline_tooltip_segment(debug_suffix, default_value_end);
159 return;
160 }
161 }
162
163 draw_default_inline_text(default_value_start, default_value_end);
164}
165
166void show_tooltip(const char *text) {
167 if (!text || !text[0]) {
168 return;
169 }
170
171 const ImVec2_c tooltip_padding = {
172 igGetStyle()->WindowPadding.x,
174 };
175
176 igPushStyleVar_Vec2(ImGuiStyleVar_WindowPadding, tooltip_padding);
177
178 if (!igBeginItemTooltip()) {
179 igPopStyleVar(1);
180 return;
181 }
182
183 igPushTextWrapPos(DTTR_CONFIG_UI_TOOLTIP_WRAP_W);
184 const char *default_text = strstr(text, "Default:");
185
186 if (default_text) {
187 const char *default_value_start = default_text + strlen("Default:");
188
189 while (*default_value_start == ' ') {
190 default_value_start++;
191 }
192
193 const char *description_end = default_text;
194 while (description_end > text && description_end[-1] == ' ') {
195 description_end--;
196 }
197
198 const char *default_value_end = default_value_start + strlen(default_value_start);
199
200 if (default_value_end > default_value_start && default_value_end[-1] == '.') {
201 default_value_end--;
202 }
203
204 draw_wrapped_tooltip_segment(text, description_end);
205 draw_wrapped_tooltip_segment(default_text, default_value_start);
206 draw_default_tooltip_value(default_value_start, default_value_end);
207
208 if (*default_value_end) {
209 igSameLine(0.0f, 0.0f);
210 igTextUnformatted(default_value_end, NULL);
211 }
212 } else {
213 igTextWrapped("%s", text);
214 }
215
216 igPopTextWrapPos();
217 igEndTooltip();
218 igPopStyleVar(1);
219}
220
223 const char *id,
224 const char *label,
225 float width
226) {
227 const ImVec2_c size = {
229 igGetFrameHeight(),
230 };
231
232 return DTTR_ImGuiDialog_Button(ctx, id, label, size);
233}
234
235typedef struct {
236 ImGuiCol target;
237 ImVec4_c color;
239
241 {ImGuiCol_FrameBg, DTTR_IMGUI_COLOR_STACK_FRAME_BG},
242 {ImGuiCol_FrameBgHovered, DTTR_IMGUI_COLOR_BUTTON_BG_HOVERED},
243 {ImGuiCol_FrameBgActive, DTTR_IMGUI_COLOR_BUTTON_BG_ACTIVE},
244 {ImGuiCol_Button, DTTR_IMGUI_COLOR_BUTTON_BG},
245 {ImGuiCol_ButtonHovered, DTTR_IMGUI_COLOR_BUTTON_BG_HOVERED},
246 {ImGuiCol_ButtonActive, DTTR_IMGUI_COLOR_BUTTON_BG_ACTIVE},
247 {ImGuiCol_Header, DTTR_IMGUI_COLOR_BUTTON_BG},
248 {ImGuiCol_HeaderHovered, DTTR_IMGUI_COLOR_BUTTON_BG_HOVERED},
249 {ImGuiCol_HeaderActive, DTTR_IMGUI_COLOR_BUTTON_BG_ACTIVE},
250 {ImGuiCol_Tab, DTTR_IMGUI_COLOR_BUTTON_BG},
251 {ImGuiCol_TabHovered, DTTR_IMGUI_COLOR_BUTTON_BG_HOVERED},
252 {ImGuiCol_TabSelected, DTTR_CONFIG_UI_SELECTED_TAB_BG},
253 {ImGuiCol_TabDimmed, DTTR_IMGUI_COLOR_STACK_FRAME_BG},
254 {ImGuiCol_TabDimmedSelected, DTTR_CONFIG_UI_SELECTED_TAB_BG},
255 {ImGuiCol_MenuBarBg, DTTR_IMGUI_COLOR_STACK_FRAME_BG},
256 {ImGuiCol_PopupBg, DTTR_IMGUI_COLOR_STACK_FRAME_BG},
257 {ImGuiCol_Border, DTTR_CONFIG_UI_BORDER_COLOR},
258 {ImGuiCol_Separator, DTTR_CONFIG_UI_SEPARATOR_COLOR},
259 {ImGuiCol_SeparatorHovered, DTTR_CONFIG_UI_SEPARATOR_COLOR},
260 {ImGuiCol_SeparatorActive, DTTR_CONFIG_UI_SEPARATOR_COLOR},
261 {ImGuiCol_TableBorderStrong, DTTR_CONFIG_UI_TABLE_BORDER_COLOR},
262 {ImGuiCol_TableBorderLight, DTTR_CONFIG_UI_BORDER_COLOR},
263};
264
266 for (size_t i = 0; i < SDL_arraysize(CONFIG_THEME_COLORS); i++) {
267 igPushStyleColor_Vec4(CONFIG_THEME_COLORS[i].target, CONFIG_THEME_COLORS[i].color);
268 }
269}
270
271void pop_config_theme() { igPopStyleColor((int)SDL_arraysize(CONFIG_THEME_COLORS)); }
272
274 const config_ui_state *state,
275 char *buffer,
276 size_t buffer_size
277) {
278 const bool changed = config_has_unsaved_changes(state);
279 const bool status_visible = state->status[0]
280 && SDL_GetTicks() < state->status_expires_at_ms;
281
282 if (!changed && !status_visible) {
283 if (buffer_size > 0) {
284 buffer[0] = '\0';
285 }
286
287 return false;
288 }
289
290 if (changed && status_visible) {
291 snprintf(buffer, buffer_size, "Unsaved changes.\n%s", state->status);
292 } else if (changed) {
293 snprintf(buffer, buffer_size, "Unsaved changes.");
294 } else {
295 snprintf(buffer, buffer_size, "%s", state->status);
296 }
297
298 return true;
299}
300
301static float status_text_height(const char *status_text) {
302 if (!status_text || !status_text[0]) {
303 return 0.0f;
304 }
305
306 int line_count = 1;
307
308 for (const char *p = status_text; *p; p++) {
309 if (*p == '\n') {
310 line_count++;
311 }
312 }
313
314 return igGetTextLineHeight()
315 + (float)(line_count - 1) * igGetTextLineHeightWithSpacing();
316}
317
321) {
322 char status_text[sizeof(state->status) + sizeof("Unsaved changes.\n")];
323 const bool has_status = format_status_text(state, status_text, sizeof(status_text));
324 float height = igGetTextLineHeight();
325
326 if (has_status) {
327 height += igGetStyle()->ItemSpacing.y + status_text_height(status_text);
328 }
329
330 return height;
331}
332
336) {
337 const float footer_height = config_footer_height(ctx, state);
338 const ImGuiWindowFlags content_flags = ImGuiWindowFlags_NoScrollbar
339 | ImGuiWindowFlags_NoScrollWithMouse;
340 return igBeginChild_Str(
341 "##config_content",
342 (ImVec2_c){0.0f, -footer_height},
343 ImGuiChildFlags_None,
344 content_flags
345 );
346}
347
348void end_config_content_region() { igEndChild(); }
349
351 char status_text[sizeof(state->status) + sizeof("Unsaved changes.\n")];
352 if (format_status_text(state, status_text, sizeof(status_text))) {
353 igPushStyleColor_Vec4(ImGuiCol_Text, DTTR_CONFIG_UI_STATUS_TEXT_COLOR);
354 igTextWrapped("%s", status_text);
355 igPopStyleColor(1);
356 }
357
358 igPushStyleColor_Vec4(ImGuiCol_Text, DTTR_CONFIG_UI_HINT_TEXT_COLOR);
359 igTextWrapped("%s", FOOTER_HINT_TEXT);
360 igPopStyleColor(1);
361}
362
364 const ImVec2_c padding = {
367 };
368
369 const ImVec2_c item_spacing = {
372 };
373
374 igPushStyleVar_Vec2(ImGuiStyleVar_WindowPadding, padding);
375 igPushStyleVar_Vec2(ImGuiStyleVar_ItemSpacing, item_spacing);
376 const ImGuiWindowFlags panel_flags = ImGuiWindowFlags_NoScrollbar
377 | ImGuiWindowFlags_NoScrollWithMouse;
378 return igBeginChild_Str(
379 "##config_panel",
380 (ImVec2_c){0.0f, 0.0f},
381 ImGuiChildFlags_AlwaysUseWindowPadding,
382 panel_flags
383 );
384}
385
387 igEndChild();
388 igPopStyleVar(2);
389}
390
391static ImVec2_c table_cell_padding(const DTTR_ImGuiDialogContext *ctx, float padding_x) {
392 return (ImVec2_c){
395 };
396}
397
400 const char *id,
401 int column_count,
402 float cell_padding_x,
403 float table_width
404) {
405 igPushStyleVar_Vec2(
406 ImGuiStyleVar_CellPadding,
407 table_cell_padding(ctx, cell_padding_x)
408 );
409 igPushStyleVar_Vec2(
410 ImGuiStyleVar_ItemSpacing,
411 (ImVec2_c){igGetStyle()->ItemSpacing.x, 0.0f}
412 );
413
414 if (igBeginTable(
415 id,
416 column_count,
418 (ImVec2_c){table_width, 0.0f},
419 0.0f
420 )) {
421 return true;
422 }
423
424 igPopStyleVar(2);
425 return false;
426}
427
430 const char *id,
431 ImGuiTableColumnFlags flags,
432 float width
433) {
434 igTableSetupColumn(id, flags, DTTR_ImGuiDialog_ScaledFloat(ctx, width), 0);
435}
436
439 int column,
440 const char *text
441) {
442 if (!igTableSetColumnIndex(column)) {
443 return;
444 }
445
446 igSetCursorPosX(
447 igGetCursorPosX()
449 );
450 igTextUnformatted(text, NULL);
451}
452
454 igTableNextRow(ImGuiTableRowFlags_Headers, 0.0f);
455 igTableSetBgColor(
456 ImGuiTableBgTarget_RowBg0,
457 igGetColorU32_Col(ImGuiCol_TableHeaderBg, 1.0f),
458 -1
459 );
460}
461
464 const char *id,
465 float label_width,
466 float input_width,
467 float table_width,
468 float cell_padding_x
469) {
470 if (!begin_config_table(ctx, id, 2, cell_padding_x, table_width)) {
471 return false;
472 }
473
475 ctx,
476 "Setting",
477 ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_IndentDisable
478 | ImGuiTableColumnFlags_NoHeaderLabel,
479 label_width
480 );
482 ctx,
483 "Value",
484 ImGuiTableColumnFlags_WidthStretch | ImGuiTableColumnFlags_NoHeaderLabel,
485 input_width
486 );
488 append_table_header_text(ctx, 0, "Setting");
489 append_table_header_text(ctx, 1, "Value");
490 return true;
491}
492
495 const char *id,
496 float label_width,
497 float input_width,
498 float table_width
499) {
501 ctx,
502 id,
503 label_width,
504 input_width,
505 table_width,
507 );
508}
509
512 const char *id,
513 float label_width,
514 float input_width
515) {
516 return begin_settings_table_with_width(ctx, id, label_width, input_width, 0.0f);
517}
518
520 igEndTable();
521 igPopStyleVar(2);
522}
523
526 ctx,
527 "##gamepad_button_table",
528 5,
530 0.0f
531 )) {
532 return false;
533 }
534
536 ctx,
537 "In-Game Action",
538 ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_IndentDisable
539 | ImGuiTableColumnFlags_NoHeaderLabel,
541 );
543 ctx,
544 "Gamepad Input",
545 ImGuiTableColumnFlags_WidthStretch | ImGuiTableColumnFlags_NoHeaderLabel,
547 );
549 ctx,
550 "Bind",
551 ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoHeaderLabel
552 | ImGuiTableColumnFlags_NoHeaderWidth,
554 );
556 ctx,
557 "Clear",
558 ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoHeaderLabel
559 | ImGuiTableColumnFlags_NoHeaderWidth,
561 );
563 ctx,
564 "Reset",
565 ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoHeaderLabel
566 | ImGuiTableColumnFlags_NoHeaderWidth,
568 );
570 append_table_header_text(ctx, 0, "In-Game Action");
571 append_table_header_text(ctx, 1, "Gamepad Input");
572 return true;
573}
574
575void begin_config_table_row() { igTableNextRow(ImGuiTableRowFlags_None, 0.0f); }
576
579 igTableNextColumn();
580}
581
582float table_input_width(const DTTR_ImGuiDialogContext *ctx, float input_width) {
583 const float available = igGetContentRegionAvail().x;
584 return available > 1.0f ? available : DTTR_ImGuiDialog_ScaledFloat(ctx, input_width);
585}
586
587float path_text_input_width(const DTTR_ImGuiDialogContext *ctx, int button_count) {
589 const float trailing_width = DTTR_ImGuiDialog_ScaledFloat(
590 ctx,
591 (float)button_count * DTTR_CONFIG_UI_PATH_BUTTON_W
592 + (float)button_count * DTTR_CONFIG_UI_PATH_BUTTON_SPACING
593 );
594
595 const float text_width = width > trailing_width + 1.0f ? width - trailing_width
596 : width;
597 return text_width > 1.0f ? text_width : 1.0f;
598}
599
600static ImVec4_c config_label_text_color(config_label_state label_state) {
601 switch (label_state) {
607 default:
609 }
610}
611
613 const char *label,
614 const char *tooltip,
615 config_label_state label_state
616) {
617 igTextColored(
618 config_label_text_color(label_state),
619 "%s%s",
620 label_state == CONFIG_LABEL_UNSAVED ? "* " : "",
621 label
622 );
623 show_tooltip(tooltip);
624}
625
628 const char *label,
629 float input_width,
630 const char *tooltip,
631 config_label_state label_state
632) {
633 igAlignTextToFramePadding();
634 draw_config_label(label, tooltip, label_state);
635 igTableNextColumn();
636 igSetNextItemWidth(table_input_width(ctx, input_width));
637}
638
642 const char *id,
643 const char *label,
644 const char *tooltip,
645 config_path_dialog_fn open_dialog
646) {
648
650 open_dialog(ctx, state);
651 }
652
653 show_tooltip(tooltip);
654}
655
659 const config_path_picker_button *buttons,
660 int button_count
661) {
662 for (int i = 0; i < button_count; i++) {
663 if (!buttons[i].open_dialog) {
664 continue;
665 }
666
668 ctx,
669 state,
670 buttons[i].id,
671 buttons[i].label,
672 buttons[i].tooltip,
673 buttons[i].open_dialog
674 );
675 }
676}
677
681 const char *label,
682 const char *id,
683 char *buf,
684 size_t buf_size,
685 const char *tooltip,
686 config_label_state label_state,
687 const config_path_picker_button *buttons,
688 int button_count
689) {
691 begin_labeled_control(ctx, label, DTTR_CONFIG_UI_PATH_INPUT_W, tooltip, label_state);
692 igSetNextItemWidth(path_text_input_width(ctx, button_count));
693 const bool edited = igInputText(
694 id,
695 buf,
696 buf_size,
697 ImGuiInputTextFlags_None,
698 NULL,
699 NULL
700 );
701 show_tooltip(tooltip);
702 draw_path_picker_buttons(ctx, state, buttons, button_count);
703 return edited;
704}
705
708 const char *label,
709 const char *id,
710 char *buf,
711 size_t buf_size,
712 const char *tooltip,
713 config_label_state label_state
714) {
716 begin_labeled_control(ctx, label, DTTR_CONFIG_UI_INPUT_W, tooltip, label_state);
717 const bool edited = igInputText(
718 id,
719 buf,
720 buf_size,
721 ImGuiInputTextFlags_None,
722 NULL,
723 NULL
724 );
725 show_tooltip(tooltip);
726 return edited;
727}
728
732 const char *label,
733 const char *id,
734 char *buf,
735 size_t buf_size,
736 const char *tooltip,
737 config_label_state label_state
738) {
739 static const config_path_picker_button buttons[] = {
740 {
741 "##open_dir",
742 "Open Dir",
743 "Select an extracted or installed game directory.",
745 },
746 {
747 "##open_iso",
748 "Open ISO",
749 "Select an original game ISO.",
751 },
752 };
753
755 ctx,
756 state,
757 label,
758 id,
759 buf,
760 buf_size,
761 tooltip,
762 label_state,
763 buttons,
764 (int)SDL_arraysize(buttons)
765 );
766}
767
771 const char *label,
772 const char *id,
773 char *buf,
774 size_t buf_size,
775 const char *tooltip,
776 config_label_state label_state
777) {
778 static const config_path_picker_button buttons[] = {
779 {
780 "##open_log",
781 "Open Log",
782 "Select a DttR log file path.",
784 },
785 };
786
788 ctx,
789 state,
790 label,
791 id,
792 buf,
793 buf_size,
794 tooltip,
795 label_state,
796 buttons,
797 (int)SDL_arraysize(buttons)
798 );
799}
800
803 const char *label,
804 const char *id,
805 int *value,
806 int step,
807 int step_fast,
808 const char *tooltip,
809 config_label_state label_state
810) {
812 begin_labeled_control(ctx, label, DTTR_CONFIG_UI_INPUT_W, tooltip, label_state);
813 const bool edited = igInputInt(id, value, step, step_fast, ImGuiInputTextFlags_None);
814 show_tooltip(tooltip);
815 return edited;
816}
817
820 const char *label,
821 const char *id,
822 float *value,
823 const char *tooltip,
824 config_label_state label_state
825) {
827 begin_labeled_control(ctx, label, DTTR_CONFIG_UI_INPUT_W, tooltip, label_state);
828 const bool edited = igInputFloat(
829 id,
830 value,
831 0.05f,
832 0.25f,
833 "%.3f",
834 ImGuiInputTextFlags_None
835 );
836 show_tooltip(tooltip);
837 return edited;
838}
839
842 const char *label,
843 const char *id,
844 bool *value,
845 const char *tooltip,
846 config_label_state label_state
847) {
849 begin_labeled_control(ctx, label, DTTR_CONFIG_UI_INPUT_W, tooltip, label_state);
850 const bool edited = igCheckbox(id, value);
851 show_tooltip(tooltip);
852 return edited;
853}
854
857 const char *label,
858 const char *id,
859 int *value,
860 DTTR_ConfigChoiceList choices,
861 const char *const *tooltips,
862 const char *tooltip,
863 config_label_state label_state
864) {
866 begin_labeled_control(ctx, label, DTTR_CONFIG_UI_INPUT_W, tooltip, label_state);
867 const bool edited = choice_combo(id, value, choices, tooltips);
868 show_tooltip(tooltip);
869 return edited;
870}
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
const DTTR_BackendState * state
DTTR_Graphics_COM_Direct3DDevice7 void DWORD flags DWORD void DWORD DWORD color
void void * ctx
DTTR_Graphics_COM_Direct3DDevice7 void DWORD flags DWORD void DWORD flags
const DWORD size
DTTR_Graphics_COM_DirectDrawSurface7 DWORD flags void NULL
DTTR_Graphics_COM_DirectDrawSurface7 DWORD DWORD void void DWORD flags DTTR_Graphics_COM_DirectDrawSurface7 void void *cb void * target
DTTR_ConfigChoiceList
const DTTR_ConfigChoice * DTTR_Config_Choices(DTTR_ConfigChoiceList list, int *count)
Definition parse.c:212
float DTTR_ImGuiDialog_ScaledFloat(const DTTR_ImGuiDialogContext *ctx, float value)
bool DTTR_ImGuiDialog_Button(const DTTR_ImGuiDialogContext *ctx, const char *id, const char *label, ImVec2_c size)
#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_STACK_FRAME_BG
Definition dttr_imgui.h:11
#define DTTR_IMGUI_COLOR_BUTTON_BG_ACTIVE
Definition dttr_imgui.h:14
void open_log_file_dialog(const DTTR_ImGuiDialogContext *ctx, config_ui_state *state)
void open_pcdogs_iso_dialog(const DTTR_ImGuiDialogContext *ctx, config_ui_state *state)
Definition gui_dialogs.c:96
void open_pcdogs_dir_dialog(const DTTR_ImGuiDialogContext *ctx, config_ui_state *state)
Definition gui_dialogs.c:85
#define DTTR_CONFIG_UI_PATH_BUTTON_W
#define DTTR_CONFIG_UI_SEPARATOR_COLOR
#define DTTR_CONFIG_UI_PATH_BUTTON_SPACING
#define DTTR_CONFIG_UI_GAMEPAD_SOURCE_W
#define DTTR_CONFIG_UI_BORDER_COLOR
config_label_state
@ CONFIG_LABEL_DEFAULT
@ CONFIG_LABEL_SAVED_CHANGED
@ CONFIG_LABEL_UNSAVED
bool config_has_unsaved_changes(const config_ui_state *state)
Definition gui_state.c:286
#define DTTR_CONFIG_UI_HINT_TEXT_COLOR
#define DTTR_CONFIG_UI_HEADER_TEXT_INSET_X
#define DTTR_CONFIG_UI_STATUS_TEXT_COLOR
#define DTTR_CONFIG_UI_TABLE_CELL_PADDING_X
#define DTTR_CONFIG_UI_SELECTED_TAB_BG
#define DTTR_CONFIG_UI_PATH_INPUT_W
#define DTTR_CONFIG_UI_SAVED_CHANGED_LABEL_TEXT_COLOR
#define DTTR_CONFIG_UI_TABLE_CELL_PADDING_Y
#define DTTR_CONFIG_UI_PANEL_PADDING_Y
#define DTTR_CONFIG_UI_LABEL_W
#define DTTR_CONFIG_UI_GAMEPAD_BUTTON_W
#define DTTR_CONFIG_UI_PANEL_PADDING_X
#define DTTR_CONFIG_UI_COMBO_POPUP_PADDING_Y
#define DTTR_CONFIG_UI_CHANGED_LABEL_TEXT_COLOR
#define DTTR_CONFIG_UI_INPUT_W
#define DTTR_CONFIG_UI_LABEL_TEXT_COLOR
#define DTTR_CONFIG_UI_ITEM_SPACING_X
#define DTTR_CONFIG_UI_TOOLTIP_PADDING_Y
#define DTTR_CONFIG_UI_TABLE_BORDER_COLOR
#define DTTR_CONFIG_UI_TOOLTIP_WRAP_W
#define CONFIG_TABLE_FLAGS
#define DTTR_CONFIG_UI_ITEM_SPACING_Y
#define DTTR_CONFIG_UI_TOOLTIP_DEFAULT_TEXT_COLOR
static void setup_scaled_table_column(const DTTR_ImGuiDialogContext *ctx, const char *id, ImGuiTableColumnFlags flags, float width)
float path_text_input_width(const DTTR_ImGuiDialogContext *ctx, int button_count)
static bool begin_config_table(const DTTR_ImGuiDialogContext *ctx, const char *id, int column_count, float cell_padding_x, float table_width)
bool choice_combo(const char *label, int *value, DTTR_ConfigChoiceList choices, const char *const *tooltips)
Definition gui_widgets.c:68
bool begin_settings_table_with_width(const DTTR_ImGuiDialogContext *ctx, const char *id, float label_width, float input_width, float table_width)
float table_input_width(const DTTR_ImGuiDialogContext *ctx, float input_width)
static const config_theme_color CONFIG_THEME_COLORS[]
static void begin_labeled_control(const DTTR_ImGuiDialogContext *ctx, const char *label, float input_width, const char *tooltip, config_label_state label_state)
bool begin_padded_panel(const DTTR_ImGuiDialogContext *ctx)
bool labeled_input_float(const DTTR_ImGuiDialogContext *ctx, const char *label, const char *id, float *value, const char *tooltip, config_label_state label_state)
static void draw_wrapped_tooltip_segment(const char *start, const char *end)
bool themed_row_button(const DTTR_ImGuiDialogContext *ctx, const char *id, const char *label, float width)
static bool begin_settings_table_with_cell_padding(const DTTR_ImGuiDialogContext *ctx, const char *id, float label_width, float input_width, float table_width, float cell_padding_x)
void same_path_button_row(const DTTR_ImGuiDialogContext *ctx)
Definition gui_widgets.c:5
bool begin_gamepad_button_table(const DTTR_ImGuiDialogContext *ctx)
static void append_table_header_text(const DTTR_ImGuiDialogContext *ctx, int column, const char *text)
bool labeled_input_int(const DTTR_ImGuiDialogContext *ctx, const char *label, const char *id, int *value, int step, int step_fast, const char *tooltip, config_label_state label_state)
void(* config_path_dialog_fn)(const DTTR_ImGuiDialogContext *ctx, config_ui_state *state)
Definition gui_widgets.c:16
static bool format_status_text(const config_ui_state *state, char *buffer, size_t buffer_size)
bool labeled_checkbox(const DTTR_ImGuiDialogContext *ctx, const char *label, const char *id, bool *value, const char *tooltip, config_label_state label_state)
bool begin_settings_table(const DTTR_ImGuiDialogContext *ctx, const char *id, float label_width, float input_width)
static void draw_default_inline_text(const char *start, const char *end)
bool begin_config_content_region(const DTTR_ImGuiDialogContext *ctx, const config_ui_state *state)
void draw_config_label(const char *label, const char *tooltip, config_label_state label_state)
void show_tooltip(const char *text)
void add_scaled_vertical_spacing(const DTTR_ImGuiDialogContext *ctx, float height)
Definition gui_widgets.c:12
static void draw_inline_tooltip_segment(const char *start, const char *end)
void draw_footer_text(const DTTR_ImGuiDialogContext *ctx, const config_ui_state *state)
static void draw_default_tooltip_value(const char *default_value_start, const char *default_value_end)
static bool labeled_path_picker_with_dialog(const DTTR_ImGuiDialogContext *ctx, config_ui_state *state, const char *label, const char *id, char *buf, size_t buf_size, const char *tooltip, config_label_state label_state, const config_path_picker_button *buttons, int button_count)
static float config_path_control_width()
Definition gui_widgets.c:30
void pop_config_theme()
void begin_config_table_row()
static void draw_path_picker_button(const DTTR_ImGuiDialogContext *ctx, config_ui_state *state, const char *id, const char *label, const char *tooltip, config_path_dialog_fn open_dialog)
static ImVec2_c table_cell_padding(const DTTR_ImGuiDialogContext *ctx, float padding_x)
void begin_setting_row()
static void draw_path_picker_buttons(const DTTR_ImGuiDialogContext *ctx, config_ui_state *state, const config_path_picker_button *buttons, int button_count)
void end_settings_table()
static void begin_table_header_row()
bool labeled_log_path_picker(const DTTR_ImGuiDialogContext *ctx, config_ui_state *state, const char *label, const char *id, char *buf, size_t buf_size, const char *tooltip, config_label_state label_state)
int config_window_width()
Definition gui_widgets.c:50
static const char *const FOOTER_HINT_TEXT
Definition gui_widgets.c:28
static float config_standard_content_width()
Definition gui_widgets.c:40
float config_standard_input_width()
Definition gui_widgets.c:36
static ImVec4_c config_label_text_color(config_label_state label_state)
static float status_text_height(const char *status_text)
bool labeled_input_text(const DTTR_ImGuiDialogContext *ctx, const char *label, const char *id, char *buf, size_t buf_size, const char *tooltip, config_label_state label_state)
void push_config_theme()
void end_config_content_region()
static float config_gamepad_content_width()
Definition gui_widgets.c:44
void end_padded_panel()
bool labeled_path_picker(const DTTR_ImGuiDialogContext *ctx, config_ui_state *state, const char *label, const char *id, char *buf, size_t buf_size, const char *tooltip, config_label_state label_state)
bool labeled_choice_combo(const DTTR_ImGuiDialogContext *ctx, const char *label, const char *id, int *value, DTTR_ConfigChoiceList choices, const char *const *tooltips, const char *tooltip, config_label_state label_state)
static int choice_index(const DTTR_ConfigChoice *choices, int choice_count, int value)
Definition gui_widgets.c:58
float config_footer_height(const DTTR_ImGuiDialogContext *ctx, const config_ui_state *state)
const char * label
config_path_dialog_fn open_dialog
Definition gui_widgets.c:25