From 3b5ee67114bf789c93db23b7a3611302dce7142e Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Mon, 29 May 2023 16:44:50 +0200 Subject: Add initial theming support --- src/drawing.c | 108 +++++++++++++++++++++++++++--------------------------- src/globals.c | 18 +++------ src/main.c | 4 +- src/renderer_m0.c | 52 +++++++++++++++++++++----- src/sequencer.c | 1 + src/settings.c | 22 +++++++++-- src/settings.h | 7 ++++ 7 files changed, 133 insertions(+), 79 deletions(-) (limited to 'src') diff --git a/src/drawing.c b/src/drawing.c index 3264ad8..622b468 100644 --- a/src/drawing.c +++ b/src/drawing.c @@ -23,7 +23,7 @@ draw_channels(void) { case 2: { active = patterns[pattern_selection_loc].ch3.active; } break; case 3: { active = patterns[pattern_selection_loc].ch4.active; } break; } - u8 clr = active ? colors[i] : COL_GREY; + u8 clr = active ? colors[i] : COL_OFF; size_t y = CHAN_START_Y + i * CHAN_OFFSET_Y; draw_channel_sprite(CHAN_START_X, y, clr, i); } @@ -150,7 +150,7 @@ draw_bank_buttons() { 'A', 'B', 'C', 'D', }; for (int i = 0; i < 4; i++) { - int color = COL_GREY; + int color = COL_OFF; if (i == current_bank) { color = COL_FG; } @@ -175,12 +175,12 @@ draw_pattern_buttons() { 'E', 'F', 'G', 'H', }; for (int i = 0; i < 8; i++) { - int color = COL_GREY; + int color = COL_OFF; if (i == current_pattern) { color = COL_FG; } if (i == next_pattern && current_pattern != next_pattern) { - color = COL_BLUE; + color = COL_ACC_0; } draw_rect(x, y, x + PAT_W, y + PAT_H, color); txt_drawc(pat_names[i], x + 4, y + 2, color); @@ -203,18 +203,18 @@ draw_play() { size_t x = PLAY_START_X; size_t y = PLAY_START_Y; draw_filled_rect(x, y, x + R_COL_W, y + PLAY_STOP_H, COL_BG); - draw_rect(x, y, x + R_COL_W, y + PLAY_STOP_H, COL_CYAN); + draw_rect(x, y, x + R_COL_W, y + PLAY_STOP_H, COL_ACC_2); if (play_status == 1) { // Pause button - draw_filled_rect(x + 10, y + 3, x + 11, y + 7, COL_CYAN); - draw_filled_rect(x + 13, y + 3, x + 14, y + 7, COL_CYAN); + draw_filled_rect(x + 10, y + 3, x + 11, y + 7, COL_ACC_2); + draw_filled_rect(x + 13, y + 3, x + 14, y + 7, COL_ACC_2); } else { // Play button x += 1; - draw_line(x + 10, y + 2, x + 10, y + 8, COL_CYAN); - draw_line(x + 11, y + 3, x + 11, y + 7, COL_CYAN); - draw_line(x + 12, y + 4, x + 12, y + 6, COL_CYAN); - draw_line(x + 13, y + 5, x + 13, y + 5, COL_CYAN); + draw_line(x + 10, y + 2, x + 10, y + 8, COL_ACC_2); + draw_line(x + 11, y + 3, x + 11, y + 7, COL_ACC_2); + draw_line(x + 12, y + 4, x + 12, y + 6, COL_ACC_2); + draw_line(x + 13, y + 5, x + 13, y + 5, COL_ACC_2); } } @@ -222,8 +222,8 @@ void draw_stop() { size_t x = STOP_START_X; size_t y = STOP_START_Y; - draw_rect(x, y, x + R_COL_W, y + PLAY_STOP_H, COL_RED); - draw_filled_rect(x + 10, y + 3, x + 14, y + 7, COL_RED); + draw_rect(x, y, x + R_COL_W, y + PLAY_STOP_H, COL_ACC_1); + draw_filled_rect(x + 10, y + 3, x + 14, y + 7, COL_ACC_1); } void @@ -528,7 +528,7 @@ void draw_parameters_wave(ChannelWaveParams *params, bool global) { u8 col_fg = COL_FG; if (global && input_handler == handle_channel_selection) { - col_fg = COL_GREY; + col_fg = COL_OFF; } // Draw current wave data. @@ -540,8 +540,8 @@ draw_parameters_wave(ChannelWaveParams *params, bool global) { size_t y = PARAMS_START_Y + 13; // Wave Patterns. - draw_wave_pattern(wave_a, x, y, COL_WAVE_A); - draw_wave_pattern(wave_b, x + 70, y, COL_WAVE_B); + draw_wave_pattern(wave_a, x, y, COL_ACC_1); + draw_wave_pattern(wave_b, x + 70, y, COL_ACC_2); // Wave text. x -= 2; @@ -624,7 +624,7 @@ draw_parameters_square(ChannelSquareParams *params, bool sweep, bool global) { size_t x_offset = sweep ? 0 : 30; u8 col_fg = COL_FG; if (global && input_handler == handle_channel_selection) { - col_fg = COL_GREY; + col_fg = COL_OFF; } // Duty cycle. @@ -673,18 +673,18 @@ draw_parameters_square(ChannelSquareParams *params, bool sweep, bool global) { x5 += 20; } break; } - draw_line(x0, y0, x1, y0, COL_RED); - draw_line(x1, y1, x1, y0, COL_RED); - draw_line(x1, y1, x2, y1, COL_RED); - draw_line(x2, y1, x2, y0, COL_RED); - draw_line(x2, y0, x3, y0, COL_RED); - draw_line(x3, y1, x3, y0, COL_RED); - draw_line(x3, y1, x4, y1, COL_RED); - draw_line(x4, y1, x4, y0, COL_RED); - draw_line(x4, y0, x5, y0, COL_RED); + draw_line(x0, y0, x1, y0, COL_ACC_1); + draw_line(x1, y1, x1, y0, COL_ACC_1); + draw_line(x1, y1, x2, y1, COL_ACC_1); + draw_line(x2, y1, x2, y0, COL_ACC_1); + draw_line(x2, y0, x3, y0, COL_ACC_1); + draw_line(x3, y1, x3, y0, COL_ACC_1); + draw_line(x3, y1, x4, y1, COL_ACC_1); + draw_line(x4, y1, x4, y0, COL_ACC_1); + draw_line(x4, y0, x5, y0, COL_ACC_1); // Bounding box. - draw_rect(x, y - 3, x + 24, y + 18, COL_RED); + draw_rect(x, y - 3, x + 24, y + 18, COL_ACC_1); } // Param box. @@ -717,7 +717,7 @@ draw_parameters_square(ChannelSquareParams *params, bool sweep, bool global) { size_t y0 = PARAMS_START_Y + PARAMS_H - 47; size_t x1 = x0 + 79; size_t y1 = y0 + 21; - draw_rect(x0, y0, x1, y1, COL_CYAN); + draw_rect(x0, y0, x1, y1, COL_ACC_2); } size_t x = PARAMS_START_X + 42 + x_offset; @@ -731,10 +731,10 @@ draw_parameters_square(ChannelSquareParams *params, bool sweep, bool global) { // Env. if (params->env_time == 0) { - draw_line(x1, y0, x2, y0, COL_CYAN); + draw_line(x1, y0, x2, y0, COL_ACC_2); } else { - draw_line(x0, y0, x1, y1, COL_CYAN); - draw_line(x1, y1, x2, y2, COL_CYAN); + draw_line(x0, y0, x1, y1, COL_ACC_2); + draw_line(x1, y1, x2, y2, COL_ACC_2); } } @@ -894,7 +894,7 @@ draw_parameters_noise(ChannelNoiseParams* params, bool global) { size_t x_offset = 30; u8 col_fg = COL_FG; if (global && input_handler == handle_channel_selection) { - col_fg = COL_GREY; + col_fg = COL_OFF; } // Bit mode. @@ -927,7 +927,7 @@ draw_parameters_noise(ChannelNoiseParams* params, bool global) { size_t y0 = PARAMS_START_Y + PARAMS_H - 47; size_t x1 = x0 + 79; size_t y1 = y0 + 21; - draw_rect(x0, y0, x1, y1, COL_CYAN); + draw_rect(x0, y0, x1, y1, COL_ACC_2); } size_t x = PARAMS_START_X + 42 + x_offset; @@ -941,10 +941,10 @@ draw_parameters_noise(ChannelNoiseParams* params, bool global) { // Env. if (params->env_time == 0) { - draw_line(x1, y0, x2, y0, COL_CYAN); + draw_line(x1, y0, x2, y0, COL_ACC_2); } else { - draw_line(x0, y0, x1, y1, COL_CYAN); - draw_line(x1, y1, x2, y2, COL_CYAN); + draw_line(x0, y0, x1, y1, COL_ACC_2); + draw_line(x1, y1, x2, y2, COL_ACC_2); } } @@ -1073,42 +1073,42 @@ clear_cursors(void) { draw_pattern_cursor(last_pattern_loc, COL_BG); draw_right_col_cursor(last_right_col_loc, COL_BG); for (size_t i = 0; i < 16; i++) { - draw_current_step(i, COL_GREY); + draw_current_step(i, COL_OFF); } } void draw_cursors(void) { clear_cursors(); - draw_current_step(step_counter, COL_RED); + draw_current_step(step_counter, COL_ACC_1); if (input_handler == handle_trigger_selection) { - draw_trig_cursor(trig_selection_loc, COL_CURSOR); + draw_trig_cursor(trig_selection_loc, COL_ACC_0); } if (input_handler == handle_channel_selection) { - draw_channel_cursor(channel_selection_loc, COL_CURSOR); + draw_channel_cursor(channel_selection_loc, COL_ACC_0); } else { - draw_channel_cursor(channel_selection_loc, COL_GREY); + draw_channel_cursor(channel_selection_loc, COL_OFF); } if (input_handler == handle_pattern_selection) { - draw_pattern_cursor(pattern_selection_loc, COL_CURSOR); + draw_pattern_cursor(pattern_selection_loc, COL_ACC_0); } else { - draw_pattern_cursor(pattern_selection_loc, COL_GREY); + draw_pattern_cursor(pattern_selection_loc, COL_OFF); } if (input_handler == handle_right_col_selection) { - draw_right_col_cursor(right_col_selection_loc, COL_CURSOR); + draw_right_col_cursor(right_col_selection_loc, COL_ACC_0); } if (input_handler == handle_param_selection_sq1 || input_handler == handle_param_selection_sq2 || input_handler == handle_param_selection_wave || input_handler == handle_param_selection_noise) { - draw_params_cursor(param_selection_loc, COL_CURSOR); - draw_trig_cursor(trig_selection_loc, COL_GREY); + draw_params_cursor(param_selection_loc, COL_ACC_0); + draw_trig_cursor(trig_selection_loc, COL_OFF); } if (input_handler == handle_param_selection_ch1 || input_handler == handle_param_selection_ch2 || input_handler == handle_param_selection_ch3 || input_handler == handle_param_selection_ch4) { - draw_params_cursor(param_selection_loc, COL_CURSOR); + draw_params_cursor(param_selection_loc, COL_ACC_0); } } @@ -1124,17 +1124,17 @@ draw_piano_notes(void) { switch (channel_selection_loc) { case 0: { if (pat->ch1.active && pat->ch1.notes[step].active) { - draw_note(pat->ch1.notes[step].note, COL_NOTE_PRESSED); + draw_note(pat->ch1.notes[step].note, COL_OFF); } } break; case 1: { if (pat->ch2.active && pat->ch2.notes[step].active) { - draw_note(pat->ch2.notes[step].note, COL_NOTE_PRESSED); + draw_note(pat->ch2.notes[step].note, COL_OFF); } } break; case 2: { if (pat->ch3.active && pat->ch3.notes[step].active) { - draw_note(pat->ch3.notes[step].note, COL_NOTE_PRESSED); + draw_note(pat->ch3.notes[step].note, COL_OFF); } } break; } @@ -1146,20 +1146,20 @@ draw_piano_notes(void) { input_handler == handle_param_selection_noise) { // Show currently selected trigger note. TriggerNote *trig = get_current_trig(); - draw_note(trig->note, COL_NOTE_PRESSED); + draw_note(trig->note, COL_OFF); } else { // Show last/current played notes in all channels. if (play_status == 1) { Pattern *pat = &patterns[current_pattern]; u8 step = (step_counter - 1) % 16; if (pat->ch3.active && pat->ch3.notes[step].active) { - draw_note(pat->ch3.notes[step].note, COL_NOTE_PRESSED); + draw_note(pat->ch3.notes[step].note, COL_OFF); } if (pat->ch2.active && pat->ch2.notes[step].active) { - draw_note(pat->ch2.notes[step].note, COL_NOTE_PRESSED); + draw_note(pat->ch2.notes[step].note, COL_OFF); } if (pat->ch1.active && pat->ch1.notes[step].active) { - draw_note(pat->ch1.notes[step].note, COL_NOTE_PRESSED); + draw_note(pat->ch1.notes[step].note, COL_OFF); } } } diff --git a/src/globals.c b/src/globals.c index 7396968..7ad5e5a 100644 --- a/src/globals.c +++ b/src/globals.c @@ -23,18 +23,12 @@ bool clear_screen = true; // Color indexes. // -#define COL_BG 0 -#define COL_FG 1 -#define COL_RED 2 -#define COL_BLUE 3 -#define COL_CYAN 4 -#define COL_GREY 5 - -// Theme colors. -#define COL_CURSOR COL_BLUE -#define COL_NOTE_PRESSED COL_GREY -#define COL_WAVE_A COL_RED -#define COL_WAVE_B COL_CYAN +#define COL_BG 0 +#define COL_FG 1 +#define COL_ACC_0 2 +#define COL_ACC_1 3 +#define COL_ACC_2 4 +#define COL_OFF 5 #define CHAN_W 19 #define CHAN_H 8 diff --git a/src/main.c b/src/main.c index 3012d9b..f0fc7c3 100644 --- a/src/main.c +++ b/src/main.c @@ -12,10 +12,12 @@ WITH REGARD TO THIS SOFTWARE. // TODO: A list of features I would like to get to implement in the near future. // // UI tweaks. +// + Theming support, with a number of pre-configured themes and custom colors. +// - Add more default themes +// - Add custom user themes // - Notification support for feedback when doing some operations // (copying/pasting) // - Animations for cursor movement/current step highlight. (A fade out maybe?) -// - Theming support, with a number of pre-configured themes and custom colors. // - Add panning support. We could send ch1-3 to the left and ch4 to the right // to act as metronome and achieve analog sync. // diff --git a/src/renderer_m0.c b/src/renderer_m0.c index eb19718..9373b73 100644 --- a/src/renderer_m0.c +++ b/src/renderer_m0.c @@ -782,6 +782,48 @@ txt_drawc_small(char c, size_t x, size_t y, u8 clr) { // Initialization. // +Palette themes[] = { + { + COLOR_BLACK, // BG + COLOR_WHITE, // FG + COLOR_BLUE, // ACC_0 + COLOR_RED, // ACC_1 + COLOR_CYAN, // ACC_2 + COLOR_GREY, // COL_OFF + }, + { + RGB15(31, 31, 31), // BG + RGB15( 8, 8, 8), // FG + RGB15( 2, 17, 31), // ACC_0 + RGB15(31, 0, 10), // ACC_1 + RGB15( 0, 27, 30), // ACC_2 + RGB15(16, 17, 19), // COL_OFF + }, + { + RGB15( 0, 0, 31), // BG + RGB15(31, 31, 31), // FG + RGB15( 0, 31, 14), // ACC_0 + RGB15(24, 7, 19), // ACC_1 + RGB15(31, 17, 27), // ACC_2 + RGB15(22, 22, 31), // COL_OFF + }, + { + RGB15(11, 24, 31), // BG + RGB15(31, 31, 31), // FG + RGB15(8, 17, 22), // COL_OFF + RGB15(29, 17, 22), // ACC_1 + RGB15(29, 17, 22), // ACC_1 + RGB15(25, 27, 29), // COL_OFF + }, +}; + +void +swap_palette(int idx) { + for (size_t i = 0; i < 16; i++) { + PAL_BUFFER_BG[i] = themes[idx][i]; + } +} + void renderer_init(void) { // Initialize display mode and bg palette. @@ -815,15 +857,7 @@ renderer_init(void) { BG_H_SCROLL_1 = -240; // Initialize default palette. - PAL_BUFFER_BG[0] = COLOR_BLACK; - PAL_BUFFER_BG[1] = COLOR_WHITE; - PAL_BUFFER_BG[2] = COLOR_RED; - PAL_BUFFER_BG[3] = COLOR_BLUE; - PAL_BUFFER_BG[4] = COLOR_CYAN; - PAL_BUFFER_BG[5] = COLOR_GREY; - PAL_BUFFER_BG[6] = COLOR_WHITE; - PAL_BUFFER_BG[7] = COLOR_GREEN; - PAL_BUFFER_BG[8] = COLOR_PURPLE; + swap_palette(0); // Initialize text engine. txt_init(txt_drawc); diff --git a/src/sequencer.c b/src/sequencer.c index 52e0e01..115d848 100644 --- a/src/sequencer.c +++ b/src/sequencer.c @@ -1014,6 +1014,7 @@ sequencer_init(void) { settings = metadata.settings; load_bank(metadata.current_bank); } + swap_palette(settings.theme); // Initialize input handler. input_handler = handle_trigger_selection; diff --git a/src/settings.c b/src/settings.c index fca5696..15d4bdf 100644 --- a/src/settings.c +++ b/src/settings.c @@ -8,9 +8,9 @@ void draw_settings_cursor(void) { int x = 6; int y = 17 + settings_cursor_loc * 12; - draw_line(x + 1, y + 3, x + 1, y + 7, COL_CYAN); - draw_line(x + 2, y + 4, x + 2, y + 6, COL_CYAN); - draw_line(x + 3, y + 5, x + 3, y + 5, COL_CYAN); + draw_line(x + 1, y + 3, x + 1, y + 7, COL_ACC_0); + draw_line(x + 2, y + 4, x + 2, y + 6, COL_ACC_0); + draw_line(x + 3, y + 5, x + 3, y + 5, COL_ACC_0); } void @@ -40,6 +40,14 @@ handle_settings_input(void) { settings.sync++; } } break; + case 1: { + if ((settings.theme + 1) >= THEME_NUM) { + settings.theme = 0; + } else { + settings.theme++; + } + swap_palette(settings.theme); + } break; } save_metadata(); clear_screen = true; @@ -53,6 +61,14 @@ handle_settings_input(void) { settings.sync--; } } break; + case 1: { + if (settings.theme == 0) { + settings.theme = THEME_NUM - 1; + } else { + settings.theme--; + } + swap_palette(settings.theme); + } break; } save_metadata(); clear_screen = true; diff --git a/src/settings.h b/src/settings.h index 57b61a5..c742db9 100644 --- a/src/settings.h +++ b/src/settings.h @@ -20,10 +20,17 @@ char * sync_setting_str[] = { typedef enum ThemeSetting { THEME_DEFAULT = 0, + THEME_INVERTED, + THEME_CLASSIC_BLUE, + THEME_HUMAN_RIGHTS, + THEME_NUM, } ThemeSetting; char * theme_setting_str[] = { "DEFAULT", + "INVERTED", + "CLASSIC BLUE", + "HUMAN RIGHTS", }; typedef enum CursorSetting { -- cgit v1.2.1