add preference menu
This commit is contained in:
210
src/main.cpp
210
src/main.cpp
@@ -110,6 +110,9 @@ struct AppState {
|
|||||||
// Corner radius selection
|
// Corner radius selection
|
||||||
S32 radius_sel;
|
S32 radius_sel;
|
||||||
|
|
||||||
|
// Settings dialog tab
|
||||||
|
S32 settings_tab; // 0=Audio, 1=Midi, 2=Keyboard Shortcuts, 3=Appearance
|
||||||
|
|
||||||
// Knob demo state
|
// Knob demo state
|
||||||
F32 demo_knob_unsigned;
|
F32 demo_knob_unsigned;
|
||||||
F32 demo_knob_signed;
|
F32 demo_knob_signed;
|
||||||
@@ -453,9 +456,6 @@ static void build_main_panel(AppState *app) {
|
|||||||
.layoutDirection = CLAY_LEFT_TO_RIGHT,
|
.layoutDirection = CLAY_LEFT_TO_RIGHT,
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
if (ui_button("BtnSettings", "Settings")) {
|
|
||||||
app->show_settings_window = 1;
|
|
||||||
}
|
|
||||||
if (ui_button("BtnAbout", "About")) {
|
if (ui_button("BtnAbout", "About")) {
|
||||||
app->show_about_window = 1;
|
app->show_about_window = 1;
|
||||||
}
|
}
|
||||||
@@ -882,107 +882,122 @@ static const F32 radius_values[] = { 0.0f, 4.0f, 6.0f, 10.0f };
|
|||||||
static void settings_window_content(void *user_data) {
|
static void settings_window_content(void *user_data) {
|
||||||
AppState *app = (AppState *)user_data;
|
AppState *app = (AppState *)user_data;
|
||||||
|
|
||||||
ui_label("SettingsLblTheme", "Theme");
|
static const char *settings_tabs[] = { "Audio", "MIDI", "Keyboard Shortcuts", "Appearance" };
|
||||||
static const char *theme_options[] = { "Dark", "Light" };
|
ui_tab_bar("SettingsTabs", settings_tabs, 4, &app->settings_tab);
|
||||||
CLAY(CLAY_ID("SettingsThemeWrap"),
|
|
||||||
.layout = { .sizing = { .width = CLAY_SIZING_FIXED(uis(180)), .height = CLAY_SIZING_FIT() } }
|
|
||||||
) {
|
|
||||||
ui_dropdown("SettingsTheme", theme_options, 2, &app->settings_theme_sel);
|
|
||||||
}
|
|
||||||
|
|
||||||
ui_label("SettingsLblAccent", "Accent Color");
|
// Tab content area with some top padding
|
||||||
static const char *accent_options[] = { "Blue", "Turquoise", "Orange", "Purple", "Pink", "Red", "Green" };
|
CLAY(CLAY_ID("SettingsTabContent"),
|
||||||
CLAY(CLAY_ID("SettingsAccentWrap"),
|
|
||||||
.layout = { .sizing = { .width = CLAY_SIZING_FIXED(uis(180)), .height = CLAY_SIZING_FIT() } }
|
|
||||||
) {
|
|
||||||
ui_dropdown("SettingsAccent", accent_options, 7, &app->accent_sel);
|
|
||||||
}
|
|
||||||
|
|
||||||
ui_label("SettingsLblRadius", "Corner Radius");
|
|
||||||
static const char *radius_options[] = { "None", "Small", "Medium", "Large" };
|
|
||||||
// radius_values defined at file scope (used by theme change handler too)
|
|
||||||
CLAY(CLAY_ID("SettingsRadiusWrap"),
|
|
||||||
.layout = { .sizing = { .width = CLAY_SIZING_FIXED(uis(180)), .height = CLAY_SIZING_FIT() } }
|
|
||||||
) {
|
|
||||||
if (ui_dropdown("SettingsRadius", radius_options, 4, &app->radius_sel)) {
|
|
||||||
g_theme.corner_radius = radius_values[app->radius_sel];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ui_checkbox("SettingsVsync", "V-Sync", &app->settings_vsync);
|
|
||||||
ui_checkbox("SettingsAutosave", "Autosave", &app->settings_autosave);
|
|
||||||
|
|
||||||
// Separator
|
|
||||||
CLAY(CLAY_ID("SettingsSep1"),
|
|
||||||
.layout = { .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(1) },
|
|
||||||
.padding = { 0, 0, uip(6), uip(6) } },
|
|
||||||
.backgroundColor = g_theme.border
|
|
||||||
) {}
|
|
||||||
|
|
||||||
// Audio device dropdown
|
|
||||||
ui_label("SettingsLblAudio", "Audio Device");
|
|
||||||
|
|
||||||
static const char *audio_options[AUDIO_MAX_DEVICES + 1];
|
|
||||||
S32 audio_count = audio_get_device_count(app->audio);
|
|
||||||
audio_options[0] = "None";
|
|
||||||
for (S32 i = 0; i < audio_count && i < AUDIO_MAX_DEVICES; i++) {
|
|
||||||
AudioDeviceInfo *dev = audio_get_device(app->audio, i);
|
|
||||||
audio_options[i + 1] = dev ? dev->name : "???";
|
|
||||||
}
|
|
||||||
|
|
||||||
CLAY(CLAY_ID("SettingsAudioWrap"),
|
|
||||||
.layout = { .sizing = { .width = CLAY_SIZING_FIXED(uis(220)), .height = CLAY_SIZING_FIT() } }
|
|
||||||
) {
|
|
||||||
ui_dropdown("SettingsAudio", audio_options, audio_count + 1, &app->audio_device_sel);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle device selection change
|
|
||||||
if (app->audio_device_sel != app->audio_device_prev) {
|
|
||||||
audio_close_device(app->audio);
|
|
||||||
if (app->audio_device_sel > 0) {
|
|
||||||
audio_open_device(app->audio, app->audio_device_sel - 1);
|
|
||||||
}
|
|
||||||
app->audio_device_prev = app->audio_device_sel;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test tone button + status
|
|
||||||
CLAY(CLAY_ID("SettingsAudioBtnRow"),
|
|
||||||
.layout = {
|
.layout = {
|
||||||
.sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIT() },
|
.sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIT() },
|
||||||
.childGap = uip(8),
|
.padding = { 0, 0, uip(8), 0 },
|
||||||
.childAlignment = { .y = CLAY_ALIGN_Y_CENTER },
|
.childGap = uip(6),
|
||||||
.layoutDirection = CLAY_LEFT_TO_RIGHT,
|
.layoutDirection = CLAY_TOP_TO_BOTTOM,
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
B32 device_open = (app->audio_device_sel > 0);
|
if (app->settings_tab == 0) {
|
||||||
B32 tone_playing = audio_is_test_tone_playing(app->audio);
|
// === Audio tab ===
|
||||||
|
ui_label("SettingsLblAudio", "Audio Device");
|
||||||
|
|
||||||
if (device_open && !tone_playing) {
|
static const char *audio_options[AUDIO_MAX_DEVICES + 1];
|
||||||
if (ui_button("BtnTestTone", "Play Test Tone")) {
|
S32 audio_count = audio_get_device_count(app->audio);
|
||||||
audio_play_test_tone(app->audio);
|
audio_options[0] = "None";
|
||||||
|
for (S32 i = 0; i < audio_count && i < AUDIO_MAX_DEVICES; i++) {
|
||||||
|
AudioDeviceInfo *dev = audio_get_device(app->audio, i);
|
||||||
|
audio_options[i + 1] = dev ? dev->name : "???";
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// Disabled button appearance
|
CLAY(CLAY_ID("SettingsAudioWrap"),
|
||||||
Clay_ElementId btn_eid = CLAY_ID("BtnTestToneDisabled");
|
.layout = { .sizing = { .width = CLAY_SIZING_FIXED(uis(260)), .height = CLAY_SIZING_FIT() } }
|
||||||
CLAY(btn_eid,
|
|
||||||
.layout = {
|
|
||||||
.sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIXED(uis(28)) },
|
|
||||||
.padding = { uip(12), uip(12), 0, 0 },
|
|
||||||
.childAlignment = { .y = CLAY_ALIGN_Y_CENTER },
|
|
||||||
},
|
|
||||||
.backgroundColor = g_theme.disabled_bg,
|
|
||||||
.cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS)
|
|
||||||
) {
|
) {
|
||||||
static Clay_TextElementConfig disabled_text = {};
|
ui_dropdown("SettingsAudio", audio_options, audio_count + 1, &app->audio_device_sel);
|
||||||
disabled_text.textColor = g_theme.disabled_text;
|
|
||||||
disabled_text.fontSize = FONT_SIZE_NORMAL;
|
|
||||||
disabled_text.wrapMode = CLAY_TEXT_WRAP_NONE;
|
|
||||||
CLAY_TEXT(CLAY_STRING("Play Test Tone"), &disabled_text);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (tone_playing) {
|
if (app->audio_device_sel != app->audio_device_prev) {
|
||||||
ui_label("SettingsLblPlaying", "Playing...");
|
audio_close_device(app->audio);
|
||||||
|
if (app->audio_device_sel > 0) {
|
||||||
|
audio_open_device(app->audio, app->audio_device_sel - 1);
|
||||||
|
}
|
||||||
|
app->audio_device_prev = app->audio_device_sel;
|
||||||
|
}
|
||||||
|
|
||||||
|
CLAY(CLAY_ID("SettingsAudioBtnRow"),
|
||||||
|
.layout = {
|
||||||
|
.sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIT() },
|
||||||
|
.childGap = uip(8),
|
||||||
|
.childAlignment = { .y = CLAY_ALIGN_Y_CENTER },
|
||||||
|
.layoutDirection = CLAY_LEFT_TO_RIGHT,
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
B32 device_open = (app->audio_device_sel > 0);
|
||||||
|
B32 tone_playing = audio_is_test_tone_playing(app->audio);
|
||||||
|
|
||||||
|
if (device_open && !tone_playing) {
|
||||||
|
if (ui_button("BtnTestTone", "Play Test Tone")) {
|
||||||
|
audio_play_test_tone(app->audio);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Clay_ElementId btn_eid = CLAY_ID("BtnTestToneDisabled");
|
||||||
|
CLAY(btn_eid,
|
||||||
|
.layout = {
|
||||||
|
.sizing = { .width = CLAY_SIZING_FIT(), .height = CLAY_SIZING_FIXED(uis(28)) },
|
||||||
|
.padding = { uip(12), uip(12), 0, 0 },
|
||||||
|
.childAlignment = { .y = CLAY_ALIGN_Y_CENTER },
|
||||||
|
},
|
||||||
|
.backgroundColor = g_theme.disabled_bg,
|
||||||
|
.cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS)
|
||||||
|
) {
|
||||||
|
static Clay_TextElementConfig disabled_text = {};
|
||||||
|
disabled_text.textColor = g_theme.disabled_text;
|
||||||
|
disabled_text.fontSize = FONT_SIZE_NORMAL;
|
||||||
|
disabled_text.wrapMode = CLAY_TEXT_WRAP_NONE;
|
||||||
|
CLAY_TEXT(CLAY_STRING("Play Test Tone"), &disabled_text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tone_playing) {
|
||||||
|
ui_label("SettingsLblPlaying", "Playing...");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ui_checkbox("SettingsVsync", "V-Sync", &app->settings_vsync);
|
||||||
|
|
||||||
|
} else if (app->settings_tab == 1) {
|
||||||
|
// === MIDI tab ===
|
||||||
|
ui_label("SettingsLblMidi", "MIDI settings will go here.");
|
||||||
|
|
||||||
|
} else if (app->settings_tab == 2) {
|
||||||
|
// === Keyboard Shortcuts tab ===
|
||||||
|
ui_label("SettingsLblKeys", "Keyboard shortcut settings will go here.");
|
||||||
|
|
||||||
|
} else if (app->settings_tab == 3) {
|
||||||
|
// === Appearance tab ===
|
||||||
|
ui_label("SettingsLblTheme", "Theme");
|
||||||
|
static const char *theme_options[] = { "Dark", "Light" };
|
||||||
|
CLAY(CLAY_ID("SettingsThemeWrap"),
|
||||||
|
.layout = { .sizing = { .width = CLAY_SIZING_FIXED(uis(220)), .height = CLAY_SIZING_FIT() } }
|
||||||
|
) {
|
||||||
|
ui_dropdown("SettingsTheme", theme_options, 2, &app->settings_theme_sel);
|
||||||
|
}
|
||||||
|
|
||||||
|
ui_label("SettingsLblAccent", "Accent Color");
|
||||||
|
static const char *accent_options[] = { "Blue", "Turquoise", "Orange", "Purple", "Pink", "Red", "Green" };
|
||||||
|
CLAY(CLAY_ID("SettingsAccentWrap"),
|
||||||
|
.layout = { .sizing = { .width = CLAY_SIZING_FIXED(uis(220)), .height = CLAY_SIZING_FIT() } }
|
||||||
|
) {
|
||||||
|
ui_dropdown("SettingsAccent", accent_options, 7, &app->accent_sel);
|
||||||
|
}
|
||||||
|
|
||||||
|
ui_label("SettingsLblRadius", "Corner Radius");
|
||||||
|
static const char *radius_options[] = { "None", "Small", "Medium", "Large" };
|
||||||
|
CLAY(CLAY_ID("SettingsRadiusWrap"),
|
||||||
|
.layout = { .sizing = { .width = CLAY_SIZING_FIXED(uis(220)), .height = CLAY_SIZING_FIT() } }
|
||||||
|
) {
|
||||||
|
if (ui_dropdown("SettingsRadius", radius_options, 4, &app->radius_sel)) {
|
||||||
|
g_theme.corner_radius = radius_values[app->radius_sel];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ui_checkbox("SettingsAutosave", "Autosave", &app->settings_autosave);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1868,8 +1883,8 @@ static void build_ui(AppState *app) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Draggable windows (rendered as floating elements above normal UI)
|
// Draggable windows (rendered as floating elements above normal UI)
|
||||||
ui_window("WinSettings", "Settings", &app->show_settings_window,
|
ui_window("WinSettings", "Preferences", &app->show_settings_window,
|
||||||
Vec2F32{100, 100}, Vec2F32{280, 0},
|
Vec2F32{100, 100}, Vec2F32{480, 0},
|
||||||
settings_window_content, app);
|
settings_window_content, app);
|
||||||
|
|
||||||
ui_window("WinAbout", "About", &app->show_about_window,
|
ui_window("WinAbout", "About", &app->show_about_window,
|
||||||
@@ -2097,6 +2112,7 @@ int main(int argc, char **argv) {
|
|||||||
case MENU_VIEW_PROPERTIES:app.show_props = !app.show_props; break;
|
case MENU_VIEW_PROPERTIES:app.show_props = !app.show_props; break;
|
||||||
case MENU_VIEW_LOG: app.show_log = !app.show_log; break;
|
case MENU_VIEW_LOG: app.show_log = !app.show_log; break;
|
||||||
case MENU_VIEW_MIDI_DEVICES: app.show_midi_devices = !app.show_midi_devices; break;
|
case MENU_VIEW_MIDI_DEVICES: app.show_midi_devices = !app.show_midi_devices; break;
|
||||||
|
case MENU_PREFERENCES_EDIT: app.show_settings_window = 1; break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ enum MenuCmd {
|
|||||||
MENU_VIEW_LOG,
|
MENU_VIEW_LOG,
|
||||||
MENU_VIEW_DEMO,
|
MENU_VIEW_DEMO,
|
||||||
MENU_VIEW_MIDI_DEVICES,
|
MENU_VIEW_MIDI_DEVICES,
|
||||||
|
MENU_PREFERENCES_EDIT,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void setup_menus(PlatformWindow *window) {
|
static void setup_menus(PlatformWindow *window) {
|
||||||
@@ -40,10 +41,15 @@ static void setup_menus(PlatformWindow *window) {
|
|||||||
{ "MIDI Devices", MENU_VIEW_MIDI_DEVICES },
|
{ "MIDI Devices", MENU_VIEW_MIDI_DEVICES },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
PlatformMenuItem prefs_items[] = {
|
||||||
|
{ "Edit Preferences", MENU_PREFERENCES_EDIT },
|
||||||
|
};
|
||||||
|
|
||||||
PlatformMenu menus[] = {
|
PlatformMenu menus[] = {
|
||||||
{ "File", file_items, sizeof(file_items) / sizeof(file_items[0]) },
|
{ "File", file_items, sizeof(file_items) / sizeof(file_items[0]) },
|
||||||
{ "Import", import_items, sizeof(import_items) / sizeof(import_items[0]) },
|
{ "Import", import_items, sizeof(import_items) / sizeof(import_items[0]) },
|
||||||
{ "View", view_items, sizeof(view_items) / sizeof(view_items[0]) },
|
{ "View", view_items, sizeof(view_items) / sizeof(view_items[0]) },
|
||||||
|
{ "Preferences", prefs_items, sizeof(prefs_items) / sizeof(prefs_items[0]) },
|
||||||
};
|
};
|
||||||
|
|
||||||
platform_set_menu(window, menus, sizeof(menus) / sizeof(menus[0]));
|
platform_set_menu(window, menus, sizeof(menus) / sizeof(menus[0]));
|
||||||
|
|||||||
Reference in New Issue
Block a user