diff --git a/gui.c b/gui.c index c7a8377..462899c 100644 --- a/gui.c +++ b/gui.c @@ -51,6 +51,26 @@ static char plugin_uri_input[256]; static int plugin_uri_input_len = 0; static int selected_channel = 0; +/* --------------------------------------------------------------------------- + * zoom mode state + * ------------------------------------------------------------------------- */ +static int zoom_enabled = 0; /* 0 = normal, 1 = zoomed */ +static int zoom_level = 0; /* 0 = 1x, 1 = 2x, 2 = 4x */ +static int zoom_focus_scene = 0; /* which scene is focused when zoomed */ +static int zoom_focus_channel = 0; /* which channel is focused when zoomed */ +static const int zoom_levels[] = {1, 2, 4}; +static const char *zoom_labels[] = {"1x", "2x", "4x"}; + +/* --------------------------------------------------------------------------- + * zoom mode state + * ------------------------------------------------------------------------- */ +static int zoom_enabled = 0; /* 0 = normal, 1 = zoomed */ +static int zoom_level = 0; /* 0 = 1x, 1 = 2x, 2 = 4x */ +static int zoom_focus_scene = 0; /* which scene is focused when zoomed */ +static int zoom_focus_channel = 0; /* which channel is focused when zoomed */ +static const int zoom_levels[] = {1, 2, 4}; +static const char *zoom_labels[] = {"1x", "2x", "4x"}; + /* --------------------------------------------------------------------------- * drawing helpers (stubs for microui) * ------------------------------------------------------------------------- */ @@ -121,6 +141,92 @@ static void gui_update(void) } } + /* Zoom mode controls */ + mu_layout_row(ctx, 2, (int[]) { 60, -1 }, 0); + mu_label(ctx, "Zoom:"); + if (mu_button(ctx, zoom_enabled ? "Disable" : "Enable")) { + zoom_enabled = !zoom_enabled; + if (!zoom_enabled) { + zoom_focus_scene = 0; + zoom_focus_channel = 0; + } + } + + if (zoom_enabled) { + mu_layout_row(ctx, 2, (int[]) { 60, -1 }, 0); + mu_label(ctx, "Level:"); + if (mu_button(ctx, zoom_labels[zoom_level])) { + zoom_level = (zoom_level + 1) % 3; + } + + mu_layout_row(ctx, 2, (int[]) { 60, -1 }, 0); + mu_label(ctx, "Scene:"); + { + char buf[32]; + snprintf(buf, sizeof(buf), "%d", zoom_focus_scene + 1); + if (mu_button(ctx, buf)) { + /* click to reset? no action needed */ + } + } + + mu_layout_row(ctx, 2, (int[]) { 60, -1 }, 0); + mu_label(ctx, "Channel:"); + { + char buf[32]; + snprintf(buf, sizeof(buf), "%d", zoom_focus_channel + 1); + if (mu_button(ctx, buf)) { + /* click to reset? no action needed */ + } + } + + /* Navigation hint */ + mu_layout_row(ctx, 1, (int[]) { -1 }, 0); + mu_label(ctx, "Use arrow keys to navigate when zoomed"); + } + + /* Zoom mode controls */ + mu_layout_row(ctx, 2, (int[]) { 60, -1 }, 0); + mu_label(ctx, "Zoom:"); + if (mu_button(ctx, zoom_enabled ? "Disable" : "Enable")) { + zoom_enabled = !zoom_enabled; + if (!zoom_enabled) { + zoom_focus_scene = 0; + zoom_focus_channel = 0; + } + } + + if (zoom_enabled) { + mu_layout_row(ctx, 2, (int[]) { 60, -1 }, 0); + mu_label(ctx, "Level:"); + if (mu_button(ctx, zoom_labels[zoom_level])) { + zoom_level = (zoom_level + 1) % 3; + } + + mu_layout_row(ctx, 2, (int[]) { 60, -1 }, 0); + mu_label(ctx, "Scene:"); + { + char buf[32]; + snprintf(buf, sizeof(buf), "%d", zoom_focus_scene + 1); + if (mu_button(ctx, buf)) { + /* click to reset? no action needed */ + } + } + + mu_layout_row(ctx, 2, (int[]) { 60, -1 }, 0); + mu_label(ctx, "Channel:"); + { + char buf[32]; + snprintf(buf, sizeof(buf), "%d", zoom_focus_channel + 1); + if (mu_button(ctx, buf)) { + /* click to reset? no action needed */ + } + } + + /* Navigation hint */ + mu_layout_row(ctx, 1, (int[]) { -1 }, 0); + mu_label(ctx, "Use arrow keys to navigate when zoomed"); + } + /* Plugin URI input */ mu_layout_row(ctx, 2, (int[]) { 60, -1 }, 0); mu_label(ctx, "URI:"); @@ -209,17 +315,45 @@ int gui_main(Engine *engine) g_engine->dispatch(action); } break; + case 'z': + case 'Z': + zoom_enabled = !zoom_enabled; + if (!zoom_enabled) { + zoom_focus_scene = 0; + zoom_focus_channel = 0; + } + break; case KEY_UP: - bpm = fminf(bpm + 5.0f, 300.0f); + if (zoom_enabled) { + int step = zoom_levels[zoom_level]; + zoom_focus_scene = (zoom_focus_scene - step + MAX_SCENES) % MAX_SCENES; + } else { + bpm = fminf(bpm + 5.0f, 300.0f); + } break; case KEY_DOWN: - bpm = fmaxf(bpm - 5.0f, 20.0f); + if (zoom_enabled) { + int step = zoom_levels[zoom_level]; + zoom_focus_scene = (zoom_focus_scene + step) % MAX_SCENES; + } else { + bpm = fmaxf(bpm - 5.0f, 20.0f); + } break; case KEY_LEFT: - loop_length = (loop_length > 1) ? loop_length - 1 : 1; + if (zoom_enabled) { + int step = zoom_levels[zoom_level]; + zoom_focus_channel = (zoom_focus_channel - step + MAX_CHANNELS) % MAX_CHANNELS; + } else { + loop_length = (loop_length > 1) ? loop_length - 1 : 1; + } break; case KEY_RIGHT: - loop_length = (loop_length < 64) ? loop_length + 1 : 64; + if (zoom_enabled) { + int step = zoom_levels[zoom_level]; + zoom_focus_channel = (zoom_focus_channel + step) % MAX_CHANNELS; + } else { + loop_length = (loop_length < 64) ? loop_length + 1 : 64; + } break; default: break;