Theme tweaks
This commit is contained in:
parent
c840dc0134
commit
215439621c
7 changed files with 794 additions and 110 deletions
40
src/app.c
40
src/app.c
|
|
@ -162,6 +162,28 @@ static void handle_event(App *app, const SDL_Event *event) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (app->theme_picker_open) {
|
||||
switch (event->key.keysym.sym) {
|
||||
case SDLK_ESCAPE:
|
||||
case SDLK_b:
|
||||
app->theme_picker_open = 0;
|
||||
return;
|
||||
case SDLK_UP:
|
||||
app->theme_picker_selection = (app->theme_picker_selection + GUIDE_THEME_COUNT - 1) % GUIDE_THEME_COUNT;
|
||||
return;
|
||||
case SDLK_DOWN:
|
||||
app->theme_picker_selection = (app->theme_picker_selection + 1) % GUIDE_THEME_COUNT;
|
||||
return;
|
||||
case SDLK_RETURN:
|
||||
case SDLK_KP_ENTER:
|
||||
app->theme_index = app->theme_picker_selection;
|
||||
app->theme_picker_open = 0;
|
||||
return;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
switch (event->key.keysym.sym) {
|
||||
case SDLK_ESCAPE:
|
||||
if (app->mode == MODE_GUIDE) {
|
||||
|
|
@ -176,6 +198,13 @@ static void handle_event(App *app, const SDL_Event *event) {
|
|||
case SDLK_f:
|
||||
toggle_fullscreen(app);
|
||||
break;
|
||||
case SDLK_b:
|
||||
if (app->mode == MODE_FULLSCREEN) {
|
||||
app->mode = MODE_GUIDE;
|
||||
}
|
||||
app->theme_picker_open = !app->theme_picker_open;
|
||||
app->theme_picker_selection = app->theme_index;
|
||||
break;
|
||||
case SDLK_UP:
|
||||
tune_relative(app, -1);
|
||||
break;
|
||||
|
|
@ -192,6 +221,7 @@ int app_init(App *app) {
|
|||
app->running = 1;
|
||||
app->mode = MODE_FULLSCREEN;
|
||||
app->last_blackout_state = 1;
|
||||
app->theme_index = 0;
|
||||
|
||||
configure_runtime_environment();
|
||||
log_runtime_environment("startup-before-sdl");
|
||||
|
|
@ -302,6 +332,7 @@ void app_run(App *app) {
|
|||
app->texture_height,
|
||||
output_width,
|
||||
output_height,
|
||||
&GUIDE_THEMES[app->theme_index],
|
||||
&app->fonts,
|
||||
&app->ui_cache,
|
||||
&app->channels,
|
||||
|
|
@ -309,6 +340,15 @@ void app_run(App *app) {
|
|||
app->app_start_ticks,
|
||||
now_ticks,
|
||||
now_wall);
|
||||
if (app->theme_picker_open) {
|
||||
ui_render_theme_picker(app->renderer,
|
||||
&app->fonts,
|
||||
output_width,
|
||||
output_height,
|
||||
&GUIDE_THEMES[app->theme_index],
|
||||
app->theme_index,
|
||||
app->theme_picker_selection);
|
||||
}
|
||||
} else {
|
||||
if (!in_blackout) {
|
||||
player_resume_audio(&app->player);
|
||||
|
|
|
|||
|
|
@ -17,6 +17,9 @@ typedef struct App {
|
|||
AppMode mode;
|
||||
int running;
|
||||
int is_fullscreen;
|
||||
int theme_index;
|
||||
int theme_picker_open;
|
||||
int theme_picker_selection;
|
||||
int startup_handoff_active;
|
||||
int last_blackout_state;
|
||||
Uint32 startup_handoff_until;
|
||||
|
|
|
|||
BIN
src/app.o
BIN
src/app.o
Binary file not shown.
523
src/theme.h
523
src/theme.h
|
|
@ -8,6 +8,54 @@ typedef enum AppMode {
|
|||
MODE_GUIDE = 1
|
||||
} AppMode;
|
||||
|
||||
typedef struct GuideTheme {
|
||||
const char *name;
|
||||
SDL_Color background_top;
|
||||
SDL_Color background_mid;
|
||||
SDL_Color background_bottom;
|
||||
SDL_Color panel_fill;
|
||||
SDL_Color panel_text;
|
||||
SDL_Color panel_border;
|
||||
SDL_Color status_divider;
|
||||
SDL_Color status_text;
|
||||
SDL_Color status_top;
|
||||
SDL_Color status_mid;
|
||||
SDL_Color status_bottom;
|
||||
SDL_Color ribbon_top;
|
||||
SDL_Color ribbon_mid;
|
||||
SDL_Color ribbon_bottom;
|
||||
SDL_Color ribbon_text;
|
||||
SDL_Color row_top;
|
||||
SDL_Color row_mid;
|
||||
SDL_Color row_bottom;
|
||||
SDL_Color row_active_top;
|
||||
SDL_Color row_active_mid;
|
||||
SDL_Color row_active_bottom;
|
||||
SDL_Color row_text;
|
||||
SDL_Color row_active_text;
|
||||
SDL_Color block_top;
|
||||
SDL_Color block_mid;
|
||||
SDL_Color block_bottom;
|
||||
SDL_Color block_active_top;
|
||||
SDL_Color block_active_mid;
|
||||
SDL_Color block_active_bottom;
|
||||
SDL_Color block_text;
|
||||
SDL_Color block_active_text;
|
||||
SDL_Color selection_edge;
|
||||
SDL_Color grid_line;
|
||||
SDL_Color row_line_hi;
|
||||
SDL_Color row_line_lo;
|
||||
SDL_Color footer_top;
|
||||
SDL_Color footer_mid;
|
||||
SDL_Color footer_bottom;
|
||||
SDL_Color footer_text;
|
||||
SDL_Color pill_light;
|
||||
SDL_Color pill_shadow;
|
||||
SDL_Color gloss;
|
||||
SDL_Color scanline;
|
||||
int rounded_radius;
|
||||
} GuideTheme;
|
||||
|
||||
static const SDL_Color COLOR_DEEP_BLUE = {0x00, 0x33, 0x99, 0xff};
|
||||
static const SDL_Color COLOR_HIGHLIGHT_YELLOW = {0xff, 0xd7, 0x00, 0xff};
|
||||
static const SDL_Color COLOR_HINT_RED = {0xcc, 0x00, 0x00, 0xff};
|
||||
|
|
@ -67,4 +115,479 @@ static const SDL_Color COLOR_PILL_SHADOW = {0x00, 0x00, 0x00, 0x40};
|
|||
#define GUIDE_X_START 258
|
||||
#define GUIDE_INFO_HEIGHT 184
|
||||
|
||||
#define GUIDE_THEME_COUNT 10
|
||||
|
||||
static const GuideTheme GUIDE_THEMES[GUIDE_THEME_COUNT] = {
|
||||
{
|
||||
.name = "CLASSIC PASSPORT",
|
||||
.background_top = {0xb8,0xc4,0xd0,0xff},
|
||||
.background_mid = {0x90,0x9e,0xae,0xff},
|
||||
.background_bottom = {0x6b,0x7b,0x8c,0xff},
|
||||
.panel_fill = {0xff,0xd7,0x00,0xff},
|
||||
.panel_text = {0xff,0xff,0xff,0xff},
|
||||
.panel_border = {0x5a,0x6a,0x7a,0xff},
|
||||
.status_divider = {0x5a,0x6a,0x7a,0xff},
|
||||
.status_text = {0x11,0x18,0x24,0xff},
|
||||
.status_top = {0xee,0xf2,0xf6,0xff},
|
||||
.status_mid = {0xd7,0xe0,0xe8,0xff},
|
||||
.status_bottom = {0xbf,0xca,0xd4,0xff},
|
||||
.ribbon_top = {0x3f,0x5c,0x8c,0xff},
|
||||
.ribbon_mid = {0x2d,0x4b,0x73,0xff},
|
||||
.ribbon_bottom = {0x1e,0x3a,0x5f,0xff},
|
||||
.ribbon_text = {0xff,0xff,0xff,0xff},
|
||||
.row_top = {0x58,0x67,0x78,0xff},
|
||||
.row_mid = {0x4a,0x55,0x68,0xff},
|
||||
.row_bottom = {0x3d,0x48,0x59,0xff},
|
||||
.row_active_top = {0x2a,0x49,0x72,0xff},
|
||||
.row_active_mid = {0x1e,0x3a,0x5f,0xff},
|
||||
.row_active_bottom = {0x17,0x2c,0x49,0xff},
|
||||
.row_text = {0xff,0xff,0xff,0xff},
|
||||
.row_active_text = {0xff,0xd7,0x00,0xff},
|
||||
.block_top = {0x5a,0x67,0x80,0xff},
|
||||
.block_mid = {0x4a,0x55,0x68,0xff},
|
||||
.block_bottom = {0x3f,0x49,0x59,0xff},
|
||||
.block_active_top = {0x4a,0x90,0xe2,0xff},
|
||||
.block_active_mid = {0x2e,0x4a,0x6f,0xff},
|
||||
.block_active_bottom = {0x1f,0x33,0x4f,0xff},
|
||||
.block_text = {0xff,0xff,0xff,0xff},
|
||||
.block_active_text = {0xff,0xff,0xff,0xff},
|
||||
.selection_edge = {0x4a,0x90,0xe2,0xff},
|
||||
.grid_line = {0x5a,0x6a,0x7a,0xaa},
|
||||
.row_line_hi = {0x7a,0x8a,0x9a,0xff},
|
||||
.row_line_lo = {0x34,0x42,0x50,0xff},
|
||||
.footer_top = {0xf3,0xf3,0xf3,0xff},
|
||||
.footer_mid = {0xdd,0xdd,0xdd,0xff},
|
||||
.footer_bottom = {0xc5,0xcc,0xd6,0xff},
|
||||
.footer_text = {0x11,0x18,0x24,0xff},
|
||||
.pill_light = {0xfa,0xfb,0xff,0xff},
|
||||
.pill_shadow = {0x00,0x00,0x00,0x40},
|
||||
.gloss = {0xff,0xff,0xff,0x80},
|
||||
.scanline = {0x00,0x00,0x00,26},
|
||||
.rounded_radius = 8
|
||||
},
|
||||
{
|
||||
.name = "LATE NIGHT CABLE",
|
||||
.background_top = {0x1a,0x1a,0x2e,0xff},
|
||||
.background_mid = {0x17,0x20,0x36,0xff},
|
||||
.background_bottom = {0x16,0x21,0x3e,0xff},
|
||||
.panel_fill = {0xd4,0xaf,0x37,0xff},
|
||||
.panel_text = {0xea,0xea,0xea,0xff},
|
||||
.panel_border = {0x54,0x50,0x62,0xff},
|
||||
.status_divider = {0x70,0x60,0x60,0xff},
|
||||
.status_text = {0x10,0x10,0x16,0xff},
|
||||
.status_top = {0xe8,0xe6,0xdd,0xff},
|
||||
.status_mid = {0xd7,0xd3,0xc8,0xff},
|
||||
.status_bottom = {0xc3,0xbd,0xb0,0xff},
|
||||
.ribbon_top = {0x30,0x1f,0x57,0xff},
|
||||
.ribbon_mid = {0x21,0x1d,0x47,0xff},
|
||||
.ribbon_bottom = {0x14,0x18,0x3a,0xff},
|
||||
.ribbon_text = {0xea,0xea,0xea,0xff},
|
||||
.row_top = {0x22,0x26,0x44,0xff},
|
||||
.row_mid = {0x18,0x22,0x3f,0xff},
|
||||
.row_bottom = {0x14,0x1b,0x33,0xff},
|
||||
.row_active_top = {0x16,0x2a,0x4d,0xff},
|
||||
.row_active_mid = {0x0f,0x34,0x60,0xff},
|
||||
.row_active_bottom = {0x0a,0x1d,0x35,0xff},
|
||||
.row_text = {0xa0,0xa0,0xa0,0xff},
|
||||
.row_active_text = {0xea,0xea,0xea,0xff},
|
||||
.block_top = {0x20,0x28,0x4b,0xff},
|
||||
.block_mid = {0x1a,0x21,0x3e,0xff},
|
||||
.block_bottom = {0x12,0x17,0x2e,0xff},
|
||||
.block_active_top = {0x69,0x47,0x96,0xff},
|
||||
.block_active_mid = {0x53,0x34,0x83,0xff},
|
||||
.block_active_bottom = {0x36,0x1f,0x5f,0xff},
|
||||
.block_text = {0xea,0xea,0xea,0xff},
|
||||
.block_active_text = {0xea,0xea,0xea,0xff},
|
||||
.selection_edge = {0xe9,0x45,0x60,0xff},
|
||||
.grid_line = {0x64,0x68,0x7a,0xaa},
|
||||
.row_line_hi = {0x3b,0x3d,0x55,0xff},
|
||||
.row_line_lo = {0x0b,0x10,0x22,0xff},
|
||||
.footer_top = {0xe6,0xe6,0xe6,0xff},
|
||||
.footer_mid = {0xcf,0xcf,0xcf,0xff},
|
||||
.footer_bottom = {0xb1,0xb1,0xb1,0xff},
|
||||
.footer_text = {0x10,0x10,0x16,0xff},
|
||||
.pill_light = {0xf4,0xf4,0xf8,0xff},
|
||||
.pill_shadow = {0x00,0x00,0x00,0x40},
|
||||
.gloss = {0xff,0xff,0xff,0x70},
|
||||
.scanline = {0x00,0x00,0x00,26},
|
||||
.rounded_radius = 8
|
||||
},
|
||||
{
|
||||
.name = "SPORTS CENTER",
|
||||
.background_top = {0x1e,0x3a,0x8a,0xff},
|
||||
.background_mid = {0x1a,0x31,0x72,0xff},
|
||||
.background_bottom = {0x17,0x25,0x54,0xff},
|
||||
.panel_fill = {0xff,0x6b,0x00,0xff},
|
||||
.panel_text = {0xff,0xff,0xff,0xff},
|
||||
.panel_border = {0x17,0x25,0x54,0xff},
|
||||
.status_divider = {0x88,0x88,0x88,0xff},
|
||||
.status_text = {0x12,0x18,0x24,0xff},
|
||||
.status_top = {0xf0,0xf3,0xf7,0xff},
|
||||
.status_mid = {0xe2,0xe8,0xee,0xff},
|
||||
.status_bottom = {0xcf,0xd8,0xe3,0xff},
|
||||
.ribbon_top = {0x2a,0x49,0x94,0xff},
|
||||
.ribbon_mid = {0x1f,0x40,0x84,0xff},
|
||||
.ribbon_bottom = {0x17,0x25,0x54,0xff},
|
||||
.ribbon_text = {0xff,0xff,0xff,0xff},
|
||||
.row_top = {0x2b,0x4a,0x9f,0xff},
|
||||
.row_mid = {0x20,0x43,0x90,0xff},
|
||||
.row_bottom = {0x17,0x31,0x71,0xff},
|
||||
.row_active_top = {0xdc,0x26,0x26,0xff},
|
||||
.row_active_mid = {0xb9,0x1c,0x1c,0xff},
|
||||
.row_active_bottom = {0x7f,0x1d,0x1d,0xff},
|
||||
.row_text = {0xff,0xff,0xff,0xff},
|
||||
.row_active_text = {0xff,0xcc,0x00,0xff},
|
||||
.block_top = {0x39,0x7a,0xf0,0xff},
|
||||
.block_mid = {0x25,0x63,0xeb,0xff},
|
||||
.block_bottom = {0x1e,0x40,0xaf,0xff},
|
||||
.block_active_top = {0xff,0x89,0x40,0xff},
|
||||
.block_active_mid = {0xff,0x6b,0x00,0xff},
|
||||
.block_active_bottom = {0xdc,0x26,0x26,0xff},
|
||||
.block_text = {0xff,0xff,0xff,0xff},
|
||||
.block_active_text = {0xff,0xff,0xff,0xff},
|
||||
.selection_edge = {0xff,0xff,0xff,0xff},
|
||||
.grid_line = {0x85,0xa0,0xff,0xaa},
|
||||
.row_line_hi = {0x6a,0x8d,0xff,0xff},
|
||||
.row_line_lo = {0x0e,0x1b,0x43,0xff},
|
||||
.footer_top = {0xf1,0xf3,0xf7,0xff},
|
||||
.footer_mid = {0xe3,0xe7,0xec,0xff},
|
||||
.footer_bottom = {0xc7,0xd0,0xdd,0xff},
|
||||
.footer_text = {0x12,0x18,0x24,0xff},
|
||||
.pill_light = {0xff,0xff,0xff,0xff},
|
||||
.pill_shadow = {0x00,0x00,0x00,0x40},
|
||||
.gloss = {0xff,0xff,0xff,0x70},
|
||||
.scanline = {0x00,0x00,0x00,26},
|
||||
.rounded_radius = 8
|
||||
},
|
||||
{
|
||||
.name = "VAPORWAVE 95",
|
||||
.background_top = {0x2d,0x1b,0x4e,0xff},
|
||||
.background_mid = {0x23,0x16,0x45,0xff},
|
||||
.background_bottom = {0x1a,0x10,0x3c,0xff},
|
||||
.panel_fill = {0xff,0x10,0xf0,0xff},
|
||||
.panel_text = {0xe0,0xf7,0xfa,0xff},
|
||||
.panel_border = {0xff,0x10,0xf0,0xff},
|
||||
.status_divider = {0x00,0xff,0xf9,0xff},
|
||||
.status_text = {0xe0,0xf7,0xfa,0xff},
|
||||
.status_top = {0x4a,0x2d,0x73,0xff},
|
||||
.status_mid = {0x3a,0x22,0x62,0xff},
|
||||
.status_bottom = {0x28,0x16,0x49,0xff},
|
||||
.ribbon_top = {0x5a,0x1e,0x87,0xff},
|
||||
.ribbon_mid = {0x4a,0x14,0x8c,0xff},
|
||||
.ribbon_bottom = {0x31,0x10,0x61,0xff},
|
||||
.ribbon_text = {0xe0,0xf7,0xfa,0xff},
|
||||
.row_top = {0x57,0x27,0x8c,0xff},
|
||||
.row_mid = {0x4b,0x1f,0x7e,0xff},
|
||||
.row_bottom = {0x2f,0x12,0x57,0xff},
|
||||
.row_active_top = {0x5e,0x1d,0x8e,0xff},
|
||||
.row_active_mid = {0x4a,0x14,0x8c,0xff},
|
||||
.row_active_bottom = {0x2d,0x0e,0x52,0xff},
|
||||
.row_text = {0xe0,0xf7,0xfa,0xff},
|
||||
.row_active_text = {0x00,0xff,0xf9,0xff},
|
||||
.block_top = {0x8a,0x2b,0xbe,0xff},
|
||||
.block_mid = {0x6a,0x1b,0x9a,0xff},
|
||||
.block_bottom = {0x48,0x15,0x72,0xff},
|
||||
.block_active_top = {0xff,0x4d,0xf4,0xff},
|
||||
.block_active_mid = {0xff,0x10,0xf0,0xff},
|
||||
.block_active_bottom = {0xb0,0x00,0xa5,0xff},
|
||||
.block_text = {0xe0,0xf7,0xfa,0xff},
|
||||
.block_active_text = {0x1a,0x10,0x3c,0xff},
|
||||
.selection_edge = {0x00,0xff,0xf9,0xff},
|
||||
.grid_line = {0x00,0xff,0xf9,0xaa},
|
||||
.row_line_hi = {0x8f,0x59,0xb6,0xff},
|
||||
.row_line_lo = {0x18,0x0a,0x37,0xff},
|
||||
.footer_top = {0xec,0xe7,0xf6,0xff},
|
||||
.footer_mid = {0xda,0xd1,0xea,0xff},
|
||||
.footer_bottom = {0xc4,0xb8,0xdb,0xff},
|
||||
.footer_text = {0x21,0x14,0x39,0xff},
|
||||
.pill_light = {0xff,0xf2,0xff,0xff},
|
||||
.pill_shadow = {0x00,0x00,0x00,0x40},
|
||||
.gloss = {0xff,0xff,0xff,0x70},
|
||||
.scanline = {0x00,0x00,0x00,26},
|
||||
.rounded_radius = 8
|
||||
},
|
||||
{
|
||||
.name = "TERMINAL GREEN",
|
||||
.background_top = {0x0c,0x0c,0x0c,0xff},
|
||||
.background_mid = {0x12,0x12,0x12,0xff},
|
||||
.background_bottom = {0x1a,0x1a,0x1a,0xff},
|
||||
.panel_fill = {0x0f,0x38,0x0f,0xff},
|
||||
.panel_text = {0x33,0xff,0x00,0xff},
|
||||
.panel_border = {0x33,0xff,0x00,0xff},
|
||||
.status_divider = {0x1b,0x4d,0x1b,0xff},
|
||||
.status_text = {0x33,0xff,0x00,0xff},
|
||||
.status_top = {0x10,0x18,0x10,0xff},
|
||||
.status_mid = {0x0d,0x14,0x0d,0xff},
|
||||
.status_bottom = {0x0a,0x10,0x0a,0xff},
|
||||
.ribbon_top = {0x12,0x2f,0x12,0xff},
|
||||
.ribbon_mid = {0x10,0x28,0x10,0xff},
|
||||
.ribbon_bottom = {0x0c,0x1f,0x0c,0xff},
|
||||
.ribbon_text = {0x33,0xff,0x00,0xff},
|
||||
.row_top = {0x15,0x2d,0x15,0xff},
|
||||
.row_mid = {0x10,0x23,0x10,0xff},
|
||||
.row_bottom = {0x0b,0x19,0x0b,0xff},
|
||||
.row_active_top = {0x12,0x3c,0x12,0xff},
|
||||
.row_active_mid = {0x0f,0x38,0x0f,0xff},
|
||||
.row_active_bottom = {0x08,0x1a,0x08,0xff},
|
||||
.row_text = {0x33,0xff,0x00,0xff},
|
||||
.row_active_text = {0x33,0xff,0x00,0xff},
|
||||
.block_top = {0x2a,0x66,0x2a,0xff},
|
||||
.block_mid = {0x1b,0x4d,0x1b,0xff},
|
||||
.block_bottom = {0x0f,0x2f,0x0f,0xff},
|
||||
.block_active_top = {0x45,0xff,0x24,0xff},
|
||||
.block_active_mid = {0x33,0xff,0x00,0xff},
|
||||
.block_active_bottom = {0x15,0x6e,0x15,0xff},
|
||||
.block_text = {0x33,0xff,0x00,0xff},
|
||||
.block_active_text = {0x0c,0x0c,0x0c,0xff},
|
||||
.selection_edge = {0x33,0xff,0x00,0xff},
|
||||
.grid_line = {0x33,0xff,0x00,0xaa},
|
||||
.row_line_hi = {0x27,0x55,0x27,0xff},
|
||||
.row_line_lo = {0x04,0x0c,0x04,0xff},
|
||||
.footer_top = {0x1b,0x1b,0x1b,0xff},
|
||||
.footer_mid = {0x16,0x16,0x16,0xff},
|
||||
.footer_bottom = {0x0f,0x0f,0x0f,0xff},
|
||||
.footer_text = {0x33,0xff,0x00,0xff},
|
||||
.pill_light = {0xdb,0xff,0xdb,0xff},
|
||||
.pill_shadow = {0x00,0x00,0x00,0x40},
|
||||
.gloss = {0xbb,0xff,0xbb,0x55},
|
||||
.scanline = {0x00,0x00,0x00,51},
|
||||
.rounded_radius = 8
|
||||
},
|
||||
{
|
||||
.name = "SATURDAY MORNING",
|
||||
.background_top = {0xff,0x6b,0x9d,0xff},
|
||||
.background_mid = {0xed,0x72,0x7b,0xff},
|
||||
.background_bottom = {0xc4,0x45,0x69,0xff},
|
||||
.panel_fill = {0x66,0xff,0x00,0xff},
|
||||
.panel_text = {0xff,0xff,0xff,0xff},
|
||||
.panel_border = {0x8b,0x3c,0x45,0xff},
|
||||
.status_divider = {0xff,0xee,0x88,0xff},
|
||||
.status_text = {0x11,0x11,0x11,0xff},
|
||||
.status_top = {0xff,0xe0,0xb8,0xff},
|
||||
.status_mid = {0xff,0xc9,0xa5,0xff},
|
||||
.status_bottom = {0xff,0xaf,0x8a,0xff},
|
||||
.ribbon_top = {0xff,0xa1,0x52,0xff},
|
||||
.ribbon_mid = {0xff,0x8c,0x42,0xff},
|
||||
.ribbon_bottom = {0xd8,0x61,0x20,0xff},
|
||||
.ribbon_text = {0xff,0xff,0xff,0xff},
|
||||
.row_top = {0xff,0x9d,0x68,0xff},
|
||||
.row_mid = {0xf2,0x7d,0x54,0xff},
|
||||
.row_bottom = {0xc4,0x45,0x69,0xff},
|
||||
.row_active_top = {0xff,0xa3,0x4f,0xff},
|
||||
.row_active_mid = {0xff,0x8c,0x42,0xff},
|
||||
.row_active_bottom = {0xd8,0x5f,0x10,0xff},
|
||||
.row_text = {0xff,0xff,0xff,0xff},
|
||||
.row_active_text = {0xff,0xff,0x00,0xff},
|
||||
.block_top = {0x7b,0xe0,0xd9,0xff},
|
||||
.block_mid = {0x4e,0xcd,0xc4,0xff},
|
||||
.block_bottom = {0x23,0x92,0x93,0xff},
|
||||
.block_active_top = {0xff,0xf5,0x96,0xff},
|
||||
.block_active_mid = {0xff,0xe6,0x6d,0xff},
|
||||
.block_active_bottom = {0xd8,0xb8,0x25,0xff},
|
||||
.block_text = {0xff,0xff,0xff,0xff},
|
||||
.block_active_text = {0x20,0x10,0x10,0xff},
|
||||
.selection_edge = {0xff,0xff,0x00,0xff},
|
||||
.grid_line = {0xff,0xed,0xa1,0xaa},
|
||||
.row_line_hi = {0xff,0xdb,0xaf,0xff},
|
||||
.row_line_lo = {0xa8,0x45,0x4e,0xff},
|
||||
.footer_top = {0xfb,0xfb,0xfb,0xff},
|
||||
.footer_mid = {0xea,0xea,0xea,0xff},
|
||||
.footer_bottom = {0xd2,0xd2,0xd2,0xff},
|
||||
.footer_text = {0x11,0x11,0x11,0xff},
|
||||
.pill_light = {0xff,0xff,0xff,0xff},
|
||||
.pill_shadow = {0x00,0x00,0x00,0x40},
|
||||
.gloss = {0xff,0xff,0xff,0x70},
|
||||
.scanline = {0x00,0x00,0x00,26},
|
||||
.rounded_radius = 12
|
||||
},
|
||||
{
|
||||
.name = "PREMIUM MOVIE",
|
||||
.background_top = {0x2c,0x0b,0x0e,0xff},
|
||||
.background_mid = {0x21,0x08,0x0b,0xff},
|
||||
.background_bottom = {0x1a,0x05,0x08,0xff},
|
||||
.panel_fill = {0xf4,0xe4,0xc1,0xff},
|
||||
.panel_text = {0xff,0xf8,0xdc,0xff},
|
||||
.panel_border = {0x6b,0x4a,0x3d,0xff},
|
||||
.status_divider = {0x90,0x6a,0x57,0xff},
|
||||
.status_text = {0x2a,0x10,0x10,0xff},
|
||||
.status_top = {0xf8,0xf0,0xde,0xff},
|
||||
.status_mid = {0xec,0xe0,0xc8,0xff},
|
||||
.status_bottom = {0xd6,0xc4,0xa4,0xff},
|
||||
.ribbon_top = {0x58,0x0c,0x13,0xff},
|
||||
.ribbon_mid = {0x42,0x08,0x0d,0xff},
|
||||
.ribbon_bottom = {0x2d,0x05,0x08,0xff},
|
||||
.ribbon_text = {0xff,0xf8,0xdc,0xff},
|
||||
.row_top = {0x52,0x10,0x18,0xff},
|
||||
.row_mid = {0x39,0x09,0x0f,0xff},
|
||||
.row_bottom = {0x20,0x04,0x07,0xff},
|
||||
.row_active_top = {0xa1,0x17,0x17,0xff},
|
||||
.row_active_mid = {0x8b,0x00,0x00,0xff},
|
||||
.row_active_bottom = {0x4a,0x04,0x04,0xff},
|
||||
.row_text = {0xff,0xf8,0xdc,0xff},
|
||||
.row_active_text = {0xff,0xd7,0x00,0xff},
|
||||
.block_top = {0x62,0x13,0x13,0xff},
|
||||
.block_mid = {0x4a,0x04,0x04,0xff},
|
||||
.block_bottom = {0x2d,0x02,0x02,0xff},
|
||||
.block_active_top = {0xf9,0xed,0xcd,0xff},
|
||||
.block_active_mid = {0xf4,0xe4,0xc1,0xff},
|
||||
.block_active_bottom = {0xb8,0xa2,0x74,0xff},
|
||||
.block_text = {0xff,0xf8,0xdc,0xff},
|
||||
.block_active_text = {0x1a,0x05,0x08,0xff},
|
||||
.selection_edge = {0xff,0xd7,0x00,0xff},
|
||||
.grid_line = {0xaa,0x72,0x72,0xaa},
|
||||
.row_line_hi = {0x7d,0x3b,0x3b,0xff},
|
||||
.row_line_lo = {0x10,0x02,0x03,0xff},
|
||||
.footer_top = {0xf4,0xf0,0xea,0xff},
|
||||
.footer_mid = {0xe8,0xdd,0xcd,0xff},
|
||||
.footer_bottom = {0xce,0xbb,0xaa,0xff},
|
||||
.footer_text = {0x2a,0x10,0x10,0xff},
|
||||
.pill_light = {0xff,0xff,0xff,0xff},
|
||||
.pill_shadow = {0x00,0x00,0x00,0x40},
|
||||
.gloss = {0xff,0xff,0xff,0x70},
|
||||
.scanline = {0x00,0x00,0x00,26},
|
||||
.rounded_radius = 8
|
||||
},
|
||||
{
|
||||
.name = "ARCTIC BLUE",
|
||||
.background_top = {0xe0,0xf2,0xfe,0xff},
|
||||
.background_mid = {0xcf,0xec,0xfd,0xff},
|
||||
.background_bottom = {0xba,0xe6,0xfd,0xff},
|
||||
.panel_fill = {0xf0,0xf9,0xff,0xff},
|
||||
.panel_text = {0x0c,0x4a,0x6e,0xff},
|
||||
.panel_border = {0x7d,0xb9,0xe0,0xff},
|
||||
.status_divider = {0x86,0xc8,0xf0,0xff},
|
||||
.status_text = {0x0c,0x4a,0x6e,0xff},
|
||||
.status_top = {0xf7,0xfc,0xff,0xff},
|
||||
.status_mid = {0xe8,0xf5,0xfd,0xff},
|
||||
.status_bottom = {0xd7,0xec,0xfa,0xff},
|
||||
.ribbon_top = {0x64,0xa9,0xcf,0xff},
|
||||
.ribbon_mid = {0x48,0x93,0xc0,0xff},
|
||||
.ribbon_bottom = {0x03,0x69,0xa1,0xff},
|
||||
.ribbon_text = {0xf0,0xf9,0xff,0xff},
|
||||
.row_top = {0xd9,0xf0,0xfe,0xff},
|
||||
.row_mid = {0xc8,0xe8,0xfd,0xff},
|
||||
.row_bottom = {0xb3,0xdd,0xf8,0xff},
|
||||
.row_active_top = {0x2a,0x86,0xba,0xff},
|
||||
.row_active_mid = {0x03,0x69,0xa1,0xff},
|
||||
.row_active_bottom = {0x04,0x4d,0x7a,0xff},
|
||||
.row_text = {0x0c,0x4a,0x6e,0xff},
|
||||
.row_active_text = {0xf0,0xf9,0xff,0xff},
|
||||
.block_top = {0xec,0xf8,0xff,0xff},
|
||||
.block_mid = {0xe0,0xf2,0xfe,0xff},
|
||||
.block_bottom = {0xb8,0xe5,0xfb,0xff},
|
||||
.block_active_top = {0x9b,0xe4,0xfb,0xff},
|
||||
.block_active_mid = {0x7d,0xd3,0xfc,0xff},
|
||||
.block_active_bottom = {0x4a,0xae,0xe0,0xff},
|
||||
.block_text = {0x0c,0x4a,0x6e,0xff},
|
||||
.block_active_text = {0x0c,0x4a,0x6e,0xff},
|
||||
.selection_edge = {0xff,0xff,0xff,0xff},
|
||||
.grid_line = {0x7d,0xd3,0xfc,0xaa},
|
||||
.row_line_hi = {0xf0,0xf9,0xff,0xff},
|
||||
.row_line_lo = {0x7d,0xd3,0xfc,0xff},
|
||||
.footer_top = {0xf8,0xfb,0xfe,0xff},
|
||||
.footer_mid = {0xec,0xf6,0xfc,0xff},
|
||||
.footer_bottom = {0xd6,0xed,0xf8,0xff},
|
||||
.footer_text = {0x0c,0x4a,0x6e,0xff},
|
||||
.pill_light = {0xff,0xff,0xff,0xff},
|
||||
.pill_shadow = {0x00,0x00,0x00,0x28},
|
||||
.gloss = {0xff,0xff,0xff,0x80},
|
||||
.scanline = {0x00,0x00,0x00,18},
|
||||
.rounded_radius = 8
|
||||
},
|
||||
{
|
||||
.name = "WOOD PANELING",
|
||||
.background_top = {0x8b,0x45,0x13,0xff},
|
||||
.background_mid = {0x75,0x4a,0x20,0xff},
|
||||
.background_bottom = {0x65,0x43,0x21,0xff},
|
||||
.panel_fill = {0xda,0x8e,0x00,0xff},
|
||||
.panel_text = {0xff,0xf8,0xdc,0xff},
|
||||
.panel_border = {0x5a,0x34,0x18,0xff},
|
||||
.status_divider = {0x7b,0x59,0x2f,0xff},
|
||||
.status_text = {0x4a,0x2a,0x12,0xff},
|
||||
.status_top = {0xe9,0xd7,0xb6,0xff},
|
||||
.status_mid = {0xd9,0xc2,0x9b,0xff},
|
||||
.status_bottom = {0xc5,0xaa,0x7f,0xff},
|
||||
.ribbon_top = {0x8a,0x6d,0x32,0xff},
|
||||
.ribbon_mid = {0x76,0x58,0x2a,0xff},
|
||||
.ribbon_bottom = {0x4a,0x37,0x28,0xff},
|
||||
.ribbon_text = {0xff,0xf8,0xdc,0xff},
|
||||
.row_top = {0x7a,0x57,0x35,0xff},
|
||||
.row_mid = {0x6b,0x44,0x23,0xff},
|
||||
.row_bottom = {0x58,0x38,0x1b,0xff},
|
||||
.row_active_top = {0x5a,0x4a,0x16,0xff},
|
||||
.row_active_mid = {0x4a,0x37,0x28,0xff},
|
||||
.row_active_bottom = {0x2d,0x20,0x17,0xff},
|
||||
.row_text = {0xff,0xf8,0xdc,0xff},
|
||||
.row_active_text = {0xda,0x8e,0x00,0xff},
|
||||
.block_top = {0x90,0x61,0x34,0xff},
|
||||
.block_mid = {0x6b,0x44,0x23,0xff},
|
||||
.block_bottom = {0x4f,0x32,0x18,0xff},
|
||||
.block_active_top = {0xe7,0xc8,0x93,0xff},
|
||||
.block_active_mid = {0xde,0xb8,0x87,0xff},
|
||||
.block_active_bottom = {0xa4,0x74,0x46,0xff},
|
||||
.block_text = {0xff,0xf8,0xdc,0xff},
|
||||
.block_active_text = {0xff,0xf8,0xdc,0xff},
|
||||
.selection_edge = {0xda,0x8e,0x00,0xff},
|
||||
.grid_line = {0xc2,0x98,0x6b,0xaa},
|
||||
.row_line_hi = {0xc6,0xa1,0x5d,0xff},
|
||||
.row_line_lo = {0x42,0x26,0x10,0xff},
|
||||
.footer_top = {0xf1,0xe6,0xd3,0xff},
|
||||
.footer_mid = {0xe8,0xd9,0xbd,0xff},
|
||||
.footer_bottom = {0xd8,0xc1,0x97,0xff},
|
||||
.footer_text = {0x4a,0x2a,0x12,0xff},
|
||||
.pill_light = {0xff,0xfc,0xf0,0xff},
|
||||
.pill_shadow = {0x00,0x00,0x00,0x40},
|
||||
.gloss = {0xff,0xff,0xff,0x60},
|
||||
.scanline = {0x00,0x00,0x00,26},
|
||||
.rounded_radius = 8
|
||||
},
|
||||
{
|
||||
.name = "CYBERPUNK NEON",
|
||||
.background_top = {0x0d,0x02,0x21,0xff},
|
||||
.background_mid = {0x1a,0x0a,0x34,0xff},
|
||||
.background_bottom = {0x26,0x14,0x47,0xff},
|
||||
.panel_fill = {0xff,0xf0,0x1f,0xff},
|
||||
.panel_text = {0xff,0xff,0xff,0xff},
|
||||
.panel_border = {0x00,0xf6,0xed,0xff},
|
||||
.status_divider = {0x00,0xf6,0xed,0xff},
|
||||
.status_text = {0xff,0xff,0xff,0xff},
|
||||
.status_top = {0x1e,0x10,0x36,0xff},
|
||||
.status_mid = {0x18,0x0c,0x2f,0xff},
|
||||
.status_bottom = {0x10,0x07,0x21,0xff},
|
||||
.ribbon_top = {0x4d,0x21,0x7f,0xff},
|
||||
.ribbon_mid = {0x35,0x13,0x6a,0xff},
|
||||
.ribbon_bottom = {0x1d,0x08,0x42,0xff},
|
||||
.ribbon_text = {0xff,0xff,0xff,0xff},
|
||||
.row_top = {0x30,0x10,0x56,0xff},
|
||||
.row_mid = {0x25,0x0d,0x49,0xff},
|
||||
.row_bottom = {0x16,0x08,0x2f,0xff},
|
||||
.row_active_top = {0xff,0x55,0x7f,0xff},
|
||||
.row_active_mid = {0xff,0x38,0x64,0xff},
|
||||
.row_active_bottom = {0xa0,0x11,0x3b,0xff},
|
||||
.row_text = {0xff,0xff,0xff,0xff},
|
||||
.row_active_text = {0xff,0xf0,0x1f,0xff},
|
||||
.block_top = {0x5b,0x20,0xce,0xff},
|
||||
.block_mid = {0x3a,0x0c,0xa3,0xff},
|
||||
.block_bottom = {0x1f,0x06,0x5b,0xff},
|
||||
.block_active_top = {0x00,0xff,0xf0,0xff},
|
||||
.block_active_mid = {0x00,0xf6,0xed,0xff},
|
||||
.block_active_bottom = {0x09,0x7b,0x95,0xff},
|
||||
.block_text = {0xff,0xff,0xff,0xff},
|
||||
.block_active_text = {0xff,0xff,0xff,0xff},
|
||||
.selection_edge = {0xff,0xf0,0x1f,0xff},
|
||||
.grid_line = {0x00,0xf6,0xed,0xaa},
|
||||
.row_line_hi = {0x67,0x2c,0xb2,0xff},
|
||||
.row_line_lo = {0x0a,0x03,0x18,0xff},
|
||||
.footer_top = {0xf3,0xf0,0xf9,0xff},
|
||||
.footer_mid = {0xe7,0xe2,0xf1,0xff},
|
||||
.footer_bottom = {0xc6,0xc0,0xd6,0xff},
|
||||
.footer_text = {0x1a,0x10,0x29,0xff},
|
||||
.pill_light = {0xff,0xff,0xff,0xff},
|
||||
.pill_shadow = {0x00,0x00,0x00,0x40},
|
||||
.gloss = {0xff,0xff,0xff,0x70},
|
||||
.scanline = {0x00,0x00,0x00,26},
|
||||
.rounded_radius = 8
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
330
src/ui.c
330
src/ui.c
|
|
@ -43,6 +43,36 @@ static void set_draw_color(SDL_Renderer *renderer, SDL_Color color) {
|
|||
SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, color.a);
|
||||
}
|
||||
|
||||
static SDL_Color color_with_alpha(SDL_Color color, Uint8 alpha) {
|
||||
color.a = alpha;
|
||||
return color;
|
||||
}
|
||||
|
||||
static SDL_Color blend_color(SDL_Color from, SDL_Color to, int weight_to_255) {
|
||||
SDL_Color blended;
|
||||
int weight_from = 255 - weight_to_255;
|
||||
|
||||
blended.r = (Uint8) ((from.r * weight_from + to.r * weight_to_255) / 255);
|
||||
blended.g = (Uint8) ((from.g * weight_from + to.g * weight_to_255) / 255);
|
||||
blended.b = (Uint8) ((from.b * weight_from + to.b * weight_to_255) / 255);
|
||||
blended.a = 255;
|
||||
return blended;
|
||||
}
|
||||
|
||||
static int color_luma(SDL_Color color) {
|
||||
return (299 * color.r + 587 * color.g + 114 * color.b) / 1000;
|
||||
}
|
||||
|
||||
static SDL_Color readable_text_color(SDL_Color background) {
|
||||
return color_luma(background) < 120 ? COLOR_TEXT_LIGHT : COLOR_TEXT_DARK;
|
||||
}
|
||||
|
||||
static SDL_Color secondary_text_color(SDL_Color primary, SDL_Color background) {
|
||||
SDL_Color secondary = blend_color(primary, background, 110);
|
||||
secondary.a = 255;
|
||||
return secondary;
|
||||
}
|
||||
|
||||
static SDL_Texture *text_to_texture(SDL_Renderer *renderer, TTF_Font *font, const char *text, SDL_Color color, int *width, int *height) {
|
||||
SDL_Surface *surface;
|
||||
SDL_Texture *texture;
|
||||
|
|
@ -92,6 +122,9 @@ static void fill_three_stop_gradient(SDL_Renderer *renderer,
|
|||
return;
|
||||
}
|
||||
|
||||
top = blend_color(top, middle, 140);
|
||||
bottom = blend_color(bottom, middle, 140);
|
||||
|
||||
split = rect->h / 2;
|
||||
for (int i = 0; i < rect->h; ++i) {
|
||||
SDL_Color from = i < split ? top : middle;
|
||||
|
|
@ -115,23 +148,23 @@ static void fill_rect_alpha(SDL_Renderer *renderer, const SDL_Rect *rect, SDL_Co
|
|||
|
||||
static void draw_panel_shadow(SDL_Renderer *renderer, const SDL_Rect *rect) {
|
||||
SDL_Rect shadow = {rect->x + 6, rect->y + 6, rect->w, rect->h};
|
||||
fill_rect_alpha(renderer, &shadow, COLOR_PANEL_SHADOW);
|
||||
fill_rect_alpha(renderer, &shadow, color_with_alpha(COLOR_PANEL_SHADOW, 48));
|
||||
}
|
||||
|
||||
static void draw_gloss_line(SDL_Renderer *renderer, const SDL_Rect *rect) {
|
||||
static void draw_gloss_line(SDL_Renderer *renderer, const SDL_Rect *rect, SDL_Color gloss_color) {
|
||||
SDL_Rect gloss = {rect->x + 4, rect->y + 1, SDL_max(rect->w - 8, 0), 2};
|
||||
if (gloss.w > 0) {
|
||||
fill_rect_alpha(renderer, &gloss, COLOR_GLOSS);
|
||||
fill_rect_alpha(renderer, &gloss, gloss_color);
|
||||
}
|
||||
}
|
||||
|
||||
static void draw_panel_bevel(SDL_Renderer *renderer, const SDL_Rect *rect) {
|
||||
static void draw_panel_bevel(SDL_Renderer *renderer, const SDL_Rect *rect, SDL_Color gloss_color) {
|
||||
SDL_Rect top_white = {rect->x + 8, rect->y, SDL_max(rect->w - 16, 0), 1};
|
||||
SDL_Rect top_black = {rect->x + 8, rect->y + 1, SDL_max(rect->w - 16, 0), 1};
|
||||
|
||||
if (top_white.w > 0) {
|
||||
fill_rect_alpha(renderer, &top_white, (SDL_Color){255, 255, 255, 128});
|
||||
fill_rect_alpha(renderer, &top_black, (SDL_Color){0, 0, 0, 51});
|
||||
fill_rect_alpha(renderer, &top_white, color_with_alpha(gloss_color, 72));
|
||||
fill_rect_alpha(renderer, &top_black, (SDL_Color){0, 0, 0, 28});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -142,37 +175,36 @@ static void stroke_rect_alpha(SDL_Renderer *renderer, const SDL_Rect *rect, SDL_
|
|||
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE);
|
||||
}
|
||||
|
||||
static void draw_selection_glow(SDL_Renderer *renderer, const SDL_Rect *rect) {
|
||||
static void draw_selection_glow(SDL_Renderer *renderer, const SDL_Rect *rect, SDL_Color edge) {
|
||||
SDL_Rect outer = *rect;
|
||||
SDL_Rect inner = {rect->x + 1, rect->y + 1, rect->w - 2, rect->h - 2};
|
||||
stroke_rect_alpha(renderer, &outer, (SDL_Color){0xff, 0xd7, 0x00, 120});
|
||||
stroke_rect_alpha(renderer, &outer, color_with_alpha(edge, 62));
|
||||
if (inner.w > 0 && inner.h > 0) {
|
||||
stroke_rect_alpha(renderer, &inner, (SDL_Color){0xff, 0xd7, 0x00, 70});
|
||||
stroke_rect_alpha(renderer, &inner, color_with_alpha(edge, 34));
|
||||
}
|
||||
}
|
||||
|
||||
static void draw_rounded_top_panel(SDL_Renderer *renderer, const SDL_Rect *rect, SDL_Color fill_color) {
|
||||
static void draw_rounded_top_panel(SDL_Renderer *renderer, const SDL_Rect *rect, SDL_Color fill_color, SDL_Color border_color, int radius) {
|
||||
SDL_Rect body;
|
||||
SDL_Rect top;
|
||||
|
||||
if (!rect || rect->w < 8 || rect->h < 8) {
|
||||
if (!rect || rect->w < radius || rect->h < radius) {
|
||||
return;
|
||||
}
|
||||
|
||||
body = (SDL_Rect){rect->x, rect->y + 8, rect->w, rect->h - 8};
|
||||
top = (SDL_Rect){rect->x + 8, rect->y, rect->w - 16, 8};
|
||||
body = (SDL_Rect){rect->x, rect->y + radius, rect->w, rect->h - radius};
|
||||
top = (SDL_Rect){rect->x + radius, rect->y, rect->w - radius * 2, radius};
|
||||
fill_rect(renderer, &body, fill_color);
|
||||
fill_rect(renderer, &top, fill_color);
|
||||
fill_rect(renderer, &(SDL_Rect){rect->x + 4, rect->y + 2, rect->w - 8, 6}, fill_color);
|
||||
fill_rect(renderer, &(SDL_Rect){rect->x + 2, rect->y + 4, rect->w - 4, 4}, fill_color);
|
||||
fill_rect(renderer, &(SDL_Rect){rect->x + 1, rect->y + 6, rect->w - 2, 2}, fill_color);
|
||||
fill_rect(renderer, &(SDL_Rect){rect->x + radius / 2, rect->y + 2, rect->w - radius, radius - 2}, fill_color);
|
||||
fill_rect(renderer, &(SDL_Rect){rect->x + 2, rect->y + radius / 2, rect->w - 4, radius / 2}, fill_color);
|
||||
|
||||
set_draw_color(renderer, COLOR_BORDER_DARK);
|
||||
SDL_RenderDrawLine(renderer, rect->x + 8, rect->y, rect->x + rect->w - 9, rect->y);
|
||||
SDL_RenderDrawLine(renderer, rect->x + 4, rect->y + 2, rect->x + 5, rect->y + 1);
|
||||
SDL_RenderDrawLine(renderer, rect->x + rect->w - 6, rect->y + 1, rect->x + rect->w - 5, rect->y + 2);
|
||||
SDL_RenderDrawLine(renderer, rect->x + 1, rect->y + 6, rect->x + 1, rect->y + rect->h - 2);
|
||||
SDL_RenderDrawLine(renderer, rect->x + rect->w - 2, rect->y + 6, rect->x + rect->w - 2, rect->y + rect->h - 2);
|
||||
set_draw_color(renderer, border_color);
|
||||
SDL_RenderDrawLine(renderer, rect->x + radius, rect->y, rect->x + rect->w - radius - 1, rect->y);
|
||||
SDL_RenderDrawLine(renderer, rect->x + radius / 2, rect->y + 2, rect->x + radius / 2 + 1, rect->y + 1);
|
||||
SDL_RenderDrawLine(renderer, rect->x + rect->w - radius / 2 - 2, rect->y + 1, rect->x + rect->w - radius / 2 - 1, rect->y + 2);
|
||||
SDL_RenderDrawLine(renderer, rect->x + 1, rect->y + radius - 2, rect->x + 1, rect->y + rect->h - 2);
|
||||
SDL_RenderDrawLine(renderer, rect->x + rect->w - 2, rect->y + radius - 2, rect->x + rect->w - 2, rect->y + rect->h - 2);
|
||||
SDL_RenderDrawLine(renderer, rect->x + 1, rect->y + rect->h - 1, rect->x + rect->w - 2, rect->y + rect->h - 1);
|
||||
}
|
||||
|
||||
|
|
@ -188,13 +220,17 @@ static void draw_beveled_bar(SDL_Renderer *renderer,
|
|||
}
|
||||
|
||||
fill_three_stop_gradient(renderer, rect, top, mid, bottom);
|
||||
SDL_SetRenderDrawColor(renderer, top_edge.r, top_edge.g, top_edge.b, 255);
|
||||
top_edge = blend_color(top_edge, mid, 170);
|
||||
bottom_edge = blend_color(bottom_edge, mid, 170);
|
||||
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
|
||||
SDL_SetRenderDrawColor(renderer, top_edge.r, top_edge.g, top_edge.b, 110);
|
||||
SDL_RenderDrawLine(renderer, rect->x, rect->y, rect->x + rect->w - 1, rect->y);
|
||||
SDL_SetRenderDrawColor(renderer, bottom_edge.r, bottom_edge.g, bottom_edge.b, 255);
|
||||
SDL_SetRenderDrawColor(renderer, bottom_edge.r, bottom_edge.g, bottom_edge.b, 110);
|
||||
SDL_RenderDrawLine(renderer, rect->x, rect->y + rect->h - 1, rect->x + rect->w - 1, rect->y + rect->h - 1);
|
||||
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE);
|
||||
}
|
||||
|
||||
static void draw_pill_button(SDL_Renderer *renderer, const SDL_Rect *rect, SDL_Color fill, SDL_Color border) {
|
||||
static void draw_pill_button(SDL_Renderer *renderer, const GuideTheme *theme, const SDL_Rect *rect, SDL_Color fill, SDL_Color border) {
|
||||
SDL_Rect shadow;
|
||||
|
||||
if (!rect || rect->w < 10 || rect->h < 10) {
|
||||
|
|
@ -202,8 +238,8 @@ static void draw_pill_button(SDL_Renderer *renderer, const SDL_Rect *rect, SDL_C
|
|||
}
|
||||
|
||||
shadow = (SDL_Rect){rect->x + 2, rect->y + 2, rect->w, rect->h};
|
||||
fill_rect_alpha(renderer, &shadow, COLOR_PILL_SHADOW);
|
||||
draw_beveled_bar(renderer, rect, COLOR_PILL_LIGHT, fill, fill, COLOR_GLOSS, border);
|
||||
fill_rect_alpha(renderer, &shadow, theme->pill_shadow);
|
||||
draw_beveled_bar(renderer, rect, theme->pill_light, fill, fill, theme->gloss, border);
|
||||
set_draw_color(renderer, border);
|
||||
SDL_RenderDrawLine(renderer, rect->x + 4, rect->y, rect->x + rect->w - 5, rect->y);
|
||||
SDL_RenderDrawLine(renderer, rect->x + 4, rect->y + rect->h - 1, rect->x + rect->w - 5, rect->y + rect->h - 1);
|
||||
|
|
@ -325,58 +361,63 @@ static void format_clock_label(char *buffer, size_t buffer_size, time_t now, int
|
|||
strftime(buffer, buffer_size, "%I:%M %p", &local_time);
|
||||
}
|
||||
|
||||
static void draw_timeline_header_cached(SDL_Renderer *renderer, const UiCache *cache, SDL_Rect rect) {
|
||||
static void draw_timeline_header_cached(SDL_Renderer *renderer, const UiCache *cache, const GuideTheme *theme, SDL_Rect rect) {
|
||||
int segments = 4;
|
||||
|
||||
draw_beveled_bar(renderer,
|
||||
&rect,
|
||||
COLOR_RIBBON_TOP,
|
||||
(SDL_Color){0x36, 0x2d, 0x83, 0xff},
|
||||
COLOR_RIBBON_BOTTOM,
|
||||
COLOR_GLOSS,
|
||||
COLOR_BORDER_DARK);
|
||||
theme->ribbon_top,
|
||||
theme->ribbon_mid,
|
||||
theme->ribbon_bottom,
|
||||
theme->gloss,
|
||||
theme->panel_border);
|
||||
|
||||
for (int i = 0; i < segments; ++i) {
|
||||
int x = rect.x + (rect.w * i) / segments;
|
||||
int centered_x = x - cache->timeline_labels[i].width / 2;
|
||||
draw_cached_text(renderer, &cache->timeline_labels[i], centered_x, rect.y + 10);
|
||||
set_draw_color(renderer, COLOR_GRID_LINE);
|
||||
set_draw_color(renderer, theme->grid_line);
|
||||
SDL_RenderDrawLine(renderer, x, rect.y + rect.h - 2, x, rect.y + rect.h + 5 * 76);
|
||||
}
|
||||
}
|
||||
|
||||
static void draw_status_bar(SDL_Renderer *renderer,
|
||||
TTF_Font *font,
|
||||
const GuideTheme *theme,
|
||||
const Channel *selected_channel,
|
||||
const SDL_Rect *rect,
|
||||
time_t now_wall) {
|
||||
char clock_text[32];
|
||||
char channel_text[160];
|
||||
SDL_Color text_color;
|
||||
|
||||
if (!rect) {
|
||||
return;
|
||||
}
|
||||
|
||||
text_color = readable_text_color(theme->status_mid);
|
||||
|
||||
draw_beveled_bar(renderer,
|
||||
rect,
|
||||
COLOR_BUTTON_BAR_TOP,
|
||||
COLOR_HEADER_SILVER,
|
||||
COLOR_BUTTON_BAR_BOTTOM,
|
||||
COLOR_GLOSS,
|
||||
COLOR_BORDER_DARK);
|
||||
blend_color(theme->status_top, theme->status_mid, 220),
|
||||
theme->status_mid,
|
||||
blend_color(theme->status_bottom, theme->status_mid, 220),
|
||||
color_with_alpha(theme->gloss, 36),
|
||||
theme->panel_border);
|
||||
format_time_compact(clock_text, sizeof(clock_text), now_wall);
|
||||
draw_text_clipped(renderer, font, clock_text, rect, rect->x + 12, rect->y + 10, COLOR_PANEL_TEXT);
|
||||
set_draw_color(renderer, COLOR_STATUS_DIVIDER);
|
||||
draw_text_clipped(renderer, font, clock_text, rect, rect->x + 12, rect->y + 10, text_color);
|
||||
set_draw_color(renderer, theme->status_divider);
|
||||
SDL_RenderDrawLine(renderer, rect->x + rect->w / 2, rect->y + 8, rect->x + rect->w / 2, rect->y + rect->h - 8);
|
||||
|
||||
if (selected_channel) {
|
||||
snprintf(channel_text, sizeof(channel_text), "%s %d", selected_channel->name, selected_channel->number);
|
||||
draw_text_clipped(renderer, font, channel_text, rect, rect->x + rect->w - 260, rect->y + 10, COLOR_PANEL_TEXT);
|
||||
draw_text_clipped(renderer, font, channel_text, rect, rect->x + rect->w - 260, rect->y + 10, text_color);
|
||||
}
|
||||
}
|
||||
|
||||
static void draw_info_panel(SDL_Renderer *renderer,
|
||||
const UiFonts *fonts,
|
||||
const GuideTheme *theme,
|
||||
const Channel *selected_channel,
|
||||
const SDL_Rect *rect,
|
||||
Uint64 app_start_ticks,
|
||||
|
|
@ -397,11 +438,11 @@ static void draw_info_panel(SDL_Renderer *renderer,
|
|||
}
|
||||
|
||||
draw_panel_shadow(renderer, rect);
|
||||
draw_rounded_top_panel(renderer, rect, COLOR_HEADER_SILVER);
|
||||
draw_rounded_top_panel(renderer, rect, theme->panel_fill, theme->panel_border, theme->rounded_radius > 0 ? theme->rounded_radius : 8);
|
||||
accent = (SDL_Rect){rect->x + 1, rect->y + 1, rect->w - 2, 38};
|
||||
fill_rect(renderer, &accent, COLOR_HEADER_SILVER);
|
||||
draw_panel_bevel(renderer, rect);
|
||||
stroke_rect(renderer, rect, COLOR_BORDER_DARK);
|
||||
fill_rect(renderer, &accent, theme->panel_fill);
|
||||
draw_panel_bevel(renderer, rect, theme->gloss);
|
||||
stroke_rect(renderer, rect, theme->panel_border);
|
||||
|
||||
program = channel_resolve_program(selected_channel, app_start_ticks, now_ticks, &program_seek, NULL);
|
||||
if (!program) {
|
||||
|
|
@ -419,66 +460,73 @@ static void draw_info_panel(SDL_Renderer *renderer,
|
|||
selected_channel->description[0] != '\0' ? selected_channel->description : "Local programming lineup.");
|
||||
|
||||
clip_rect = (SDL_Rect){rect->x + 16, rect->y + 12, rect->w - 32, rect->h - 24};
|
||||
draw_text_clipped(renderer, fonts->large, selected_channel->name, &clip_rect, rect->x + 18, rect->y + 44, COLOR_PANEL_TEXT);
|
||||
draw_text_clipped(renderer, fonts->medium, program->program_title, &clip_rect, rect->x + 18, rect->y + 88, COLOR_PANEL_TEXT);
|
||||
draw_text_clipped(renderer, fonts->small, time_range, &clip_rect, rect->x + 18, rect->y + 124, COLOR_PANEL_TEXT);
|
||||
draw_text_clipped(renderer, fonts->small, description, &clip_rect, rect->x + 18, rect->y + 148, COLOR_PANEL_TEXT);
|
||||
draw_text_clipped(renderer, fonts->large, selected_channel->name, &clip_rect, rect->x + 18, rect->y + 44, theme->panel_text);
|
||||
draw_text_clipped(renderer, fonts->medium, program->program_title, &clip_rect, rect->x + 18, rect->y + 88, theme->panel_text);
|
||||
draw_text_clipped(renderer, fonts->small, time_range, &clip_rect, rect->x + 18, rect->y + 124, theme->panel_text);
|
||||
draw_text_clipped(renderer, fonts->small, description, &clip_rect, rect->x + 18, rect->y + 148, theme->panel_text);
|
||||
}
|
||||
|
||||
static void draw_grid_background(SDL_Renderer *renderer, const SDL_Rect *grid_rect, int row_height, double pixels_per_minute) {
|
||||
static void draw_grid_background(SDL_Renderer *renderer, const GuideTheme *theme, const SDL_Rect *grid_rect, int row_height, double pixels_per_minute) {
|
||||
fill_three_stop_gradient(renderer,
|
||||
grid_rect,
|
||||
(SDL_Color){0x34, 0x26, 0x88, 0xff},
|
||||
(SDL_Color){0x1b, 0x2f, 0x8f, 0xff},
|
||||
(SDL_Color){0x00, 0x11, 0x33, 0xff});
|
||||
theme->background_top,
|
||||
theme->background_mid,
|
||||
theme->background_bottom);
|
||||
|
||||
for (int minute = 0; minute <= 90; minute += 30) {
|
||||
int x = GUIDE_X_START + (int) (minute * pixels_per_minute);
|
||||
set_draw_color(renderer, COLOR_GRID_LINE);
|
||||
set_draw_color(renderer, theme->grid_line);
|
||||
SDL_RenderDrawLine(renderer, x, grid_rect->y, x, grid_rect->y + grid_rect->h);
|
||||
}
|
||||
|
||||
for (int row = 0; row <= GUIDE_VISIBLE_ROWS; ++row) {
|
||||
int y = grid_rect->y + row * row_height;
|
||||
set_draw_color(renderer, COLOR_ROW_LINE_HI);
|
||||
set_draw_color(renderer, theme->row_line_hi);
|
||||
SDL_RenderDrawLine(renderer, grid_rect->x, y, grid_rect->x + grid_rect->w, y);
|
||||
if (y + row_height - 1 <= grid_rect->y + grid_rect->h) {
|
||||
set_draw_color(renderer, COLOR_ROW_LINE_LO);
|
||||
set_draw_color(renderer, theme->row_line_lo);
|
||||
SDL_RenderDrawLine(renderer, grid_rect->x, y + row_height - 1, grid_rect->x + grid_rect->w, y + row_height - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void draw_footer_legend(SDL_Renderer *renderer, const UiCache *cache, int window_width, int window_height) {
|
||||
static void draw_footer_legend(SDL_Renderer *renderer,
|
||||
const UiFonts *fonts,
|
||||
const GuideTheme *theme,
|
||||
int window_width,
|
||||
int window_height) {
|
||||
SDL_Rect footer = {0, window_height - 54, window_width, 54};
|
||||
SDL_Rect chip = {window_width / 2 - 180, window_height - 38, 34, 20};
|
||||
SDL_Color footer_text = readable_text_color(theme->footer_mid);
|
||||
|
||||
fill_three_stop_gradient(renderer, &footer, COLOR_BUTTON_BAR_TOP, COLOR_HEADER_SILVER, COLOR_BUTTON_BAR_BOTTOM);
|
||||
draw_gloss_line(renderer, &footer);
|
||||
stroke_rect(renderer, &footer, COLOR_BORDER_DARK);
|
||||
fill_three_stop_gradient(renderer,
|
||||
&footer,
|
||||
blend_color(theme->footer_top, theme->footer_mid, 240),
|
||||
theme->footer_mid,
|
||||
blend_color(theme->footer_bottom, theme->footer_mid, 240));
|
||||
draw_gloss_line(renderer, &footer, color_with_alpha(theme->gloss, 20));
|
||||
stroke_rect(renderer, &footer, theme->panel_border);
|
||||
|
||||
draw_pill_button(renderer, &chip, COLOR_HIGHLIGHT_YELLOW, COLOR_BORDER_DARK);
|
||||
draw_cached_text(renderer, &cache->footer_a, chip.x + 11, chip.y + 1);
|
||||
draw_cached_text(renderer, &cache->footer_time, chip.x + 42, chip.y - 1);
|
||||
draw_pill_button(renderer, theme, &chip, theme->panel_fill, theme->panel_border);
|
||||
draw_text_clipped(renderer, fonts->medium, "A", &footer, chip.x + 11, chip.y + 1, footer_text);
|
||||
draw_text_clipped(renderer, fonts->small, "TIME", &footer, chip.x + 42, chip.y - 1, footer_text);
|
||||
|
||||
chip.x += 144;
|
||||
draw_pill_button(renderer, &chip, COLOR_BLOCK_UNSELECTED, COLOR_BORDER_DARK);
|
||||
draw_cached_text(renderer, &cache->footer_b, chip.x + 11, chip.y + 1);
|
||||
draw_cached_text(renderer, &cache->footer_theme, chip.x + 42, chip.y - 1);
|
||||
draw_pill_button(renderer, theme, &chip, theme->block_mid, theme->panel_border);
|
||||
draw_text_clipped(renderer, fonts->medium, "B", &footer, chip.x + 11, chip.y + 1, footer_text);
|
||||
draw_text_clipped(renderer, fonts->small, "THEME", &footer, chip.x + 42, chip.y - 1, footer_text);
|
||||
|
||||
chip.x += 150;
|
||||
draw_pill_button(renderer, &chip, COLOR_HINT_RED, COLOR_BORDER_DARK);
|
||||
draw_cached_text(renderer, &cache->footer_c, chip.x + 11, chip.y + 1);
|
||||
draw_cached_text(renderer, &cache->footer_title, chip.x + 42, chip.y - 1);
|
||||
draw_pill_button(renderer, theme, &chip, theme->row_active_mid, theme->panel_border);
|
||||
draw_text_clipped(renderer, fonts->medium, "C", &footer, chip.x + 11, chip.y + 1, footer_text);
|
||||
draw_text_clipped(renderer, fonts->small, "TITLE", &footer, chip.x + 42, chip.y - 1, footer_text);
|
||||
}
|
||||
|
||||
static void draw_scanline_overlay(SDL_Renderer *renderer, int width, int height) {
|
||||
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
|
||||
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 26);
|
||||
for (int y = 0; y < height; y += 2) {
|
||||
SDL_RenderDrawLine(renderer, 0, y, width, y);
|
||||
}
|
||||
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE);
|
||||
static void draw_scanline_overlay(SDL_Renderer *renderer, int width, int height, const GuideTheme *theme) {
|
||||
(void) renderer;
|
||||
(void) width;
|
||||
(void) height;
|
||||
(void) theme;
|
||||
}
|
||||
|
||||
void ui_render_no_media(SDL_Renderer *renderer, const UiCache *cache, int window_width, int window_height) {
|
||||
|
|
@ -506,6 +554,7 @@ void ui_render_guide(SDL_Renderer *renderer,
|
|||
int texture_height,
|
||||
int window_width,
|
||||
int window_height,
|
||||
const GuideTheme *theme,
|
||||
const UiFonts *fonts,
|
||||
UiCache *cache,
|
||||
const ChannelList *channels,
|
||||
|
|
@ -535,26 +584,26 @@ void ui_render_guide(SDL_Renderer *renderer,
|
|||
|
||||
fill_three_stop_gradient(renderer,
|
||||
&full,
|
||||
(SDL_Color){0x2a, 0x2e, 0x8f, 0xff},
|
||||
COLOR_GUIDE_TOP,
|
||||
COLOR_GUIDE_BOTTOM);
|
||||
draw_info_panel(renderer, fonts, selected_channel, &info_panel, app_start_ticks, now_ticks, now_wall);
|
||||
theme->background_top,
|
||||
theme->background_mid,
|
||||
theme->background_bottom);
|
||||
draw_info_panel(renderer, fonts, theme, selected_channel, &info_panel, app_start_ticks, now_ticks, now_wall);
|
||||
draw_panel_shadow(renderer, &preview);
|
||||
fill_rect(renderer, &preview, COLOR_BLACK);
|
||||
draw_video(renderer, video_texture, texture_width, texture_height, preview);
|
||||
draw_status_bar(renderer, fonts->medium, selected_channel, &status_bar, now_wall);
|
||||
draw_status_bar(renderer, fonts->medium, theme, selected_channel, &status_bar, now_wall);
|
||||
|
||||
if (cache->timeline_label_slot != now_wall / 60) {
|
||||
char label[32];
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
format_clock_label(label, sizeof(label), now_wall, (int) ((TIMELINE_VISIBLE_SECONDS / 60.0 / 4) * i));
|
||||
text_texture_destroy(&cache->timeline_labels[i]);
|
||||
text_texture_init(&cache->timeline_labels[i], renderer, fonts->small, label, COLOR_TEXT_LIGHT);
|
||||
text_texture_init(&cache->timeline_labels[i], renderer, fonts->small, label, theme->ribbon_text);
|
||||
}
|
||||
cache->timeline_label_slot = now_wall / 60;
|
||||
}
|
||||
draw_timeline_header_cached(renderer, cache, header_row);
|
||||
draw_grid_background(renderer, &grid, row_height, pixels_per_minute);
|
||||
draw_timeline_header_cached(renderer, cache, theme, header_row);
|
||||
draw_grid_background(renderer, theme, &grid, row_height, pixels_per_minute);
|
||||
|
||||
if (start_index < 0) {
|
||||
start_index = 0;
|
||||
|
|
@ -574,19 +623,19 @@ void ui_render_guide(SDL_Renderer *renderer,
|
|||
|
||||
draw_beveled_bar(renderer,
|
||||
&row_rect,
|
||||
is_selected ? COLOR_ROW_ACTIVE_TOP : COLOR_ROW_TOP,
|
||||
is_selected ? COLOR_ROW_ACTIVE_MID : COLOR_ROW_MID,
|
||||
is_selected ? COLOR_ROW_ACTIVE_BOTTOM : COLOR_ROW_BOTTOM,
|
||||
COLOR_GLOSS,
|
||||
COLOR_BORDER_DARK);
|
||||
is_selected ? theme->row_active_top : theme->row_top,
|
||||
is_selected ? theme->row_active_mid : theme->row_mid,
|
||||
is_selected ? theme->row_active_bottom : theme->row_bottom,
|
||||
theme->gloss,
|
||||
theme->panel_border);
|
||||
fill_rect_alpha(renderer, &inset, (SDL_Color){255, 255, 255, is_selected ? 12 : 6});
|
||||
draw_beveled_bar(renderer,
|
||||
&sidebar,
|
||||
is_selected ? COLOR_ROW_ACTIVE_TOP : COLOR_ROW_TOP,
|
||||
is_selected ? COLOR_ROW_ACTIVE_MID : COLOR_ROW_MID,
|
||||
is_selected ? COLOR_ROW_ACTIVE_BOTTOM : COLOR_ROW_BOTTOM,
|
||||
COLOR_GLOSS,
|
||||
COLOR_BORDER_DARK);
|
||||
is_selected ? theme->row_active_top : theme->row_top,
|
||||
is_selected ? theme->row_active_mid : theme->row_mid,
|
||||
is_selected ? theme->row_active_bottom : theme->row_bottom,
|
||||
theme->gloss,
|
||||
theme->panel_border);
|
||||
|
||||
if (!channels || channel_index >= channels->count) {
|
||||
continue;
|
||||
|
|
@ -616,26 +665,36 @@ void ui_render_guide(SDL_Renderer *renderer,
|
|||
title_rect = (SDL_Rect){block.x + 8, block.y + 8, block.w - 16, block.h - 16};
|
||||
|
||||
if (is_selected) {
|
||||
draw_text_clipped(renderer, fonts->medium, channel->name, &sidebar, 20, row_rect.y + 12, COLOR_ACTIVE_TEXT);
|
||||
draw_text_clipped(renderer, fonts->medium, channel->name, &sidebar, 20, row_rect.y + 12, theme->row_active_text);
|
||||
{
|
||||
char number[16];
|
||||
snprintf(number, sizeof(number), "%d", channel->number);
|
||||
draw_text_clipped(renderer, fonts->medium, number, &sidebar, 176, row_rect.y + 12, COLOR_ACTIVE_TEXT);
|
||||
draw_text_clipped(renderer, fonts->medium, number, &sidebar, 176, row_rect.y + 12, theme->row_active_text);
|
||||
}
|
||||
} else {
|
||||
draw_cached_text(renderer, &cache->channels[channel_index].name_medium, 20, row_rect.y + 12);
|
||||
draw_cached_text(renderer, &cache->channels[channel_index].number_medium, 176, row_rect.y + 12);
|
||||
draw_text_clipped(renderer, fonts->medium, channel->name, &sidebar, 20, row_rect.y + 12, theme->row_text);
|
||||
{
|
||||
char number[16];
|
||||
snprintf(number, sizeof(number), "%d", channel->number);
|
||||
draw_text_clipped(renderer, fonts->medium, number, &sidebar, 176, row_rect.y + 12, theme->row_text);
|
||||
}
|
||||
}
|
||||
draw_text_clipped(renderer, fonts->small, program->file_name, &sidebar, 20, row_rect.y + 38, COLOR_PALE_BLUE);
|
||||
draw_text_clipped(renderer,
|
||||
fonts->small,
|
||||
program->file_name,
|
||||
&sidebar,
|
||||
20,
|
||||
row_rect.y + 38,
|
||||
secondary_text_color(theme->row_text, is_selected ? theme->row_active_mid : theme->row_mid));
|
||||
|
||||
SDL_RenderSetClipRect(renderer, &clip);
|
||||
draw_beveled_bar(renderer,
|
||||
&block,
|
||||
is_selected ? COLOR_BLOCK_ACTIVE_TOP : COLOR_BLOCK_TOP,
|
||||
is_selected ? COLOR_BLOCK_ACTIVE_MID : COLOR_BLOCK_MID,
|
||||
is_selected ? COLOR_BLOCK_ACTIVE_BOTTOM : COLOR_BLOCK_BOTTOM,
|
||||
is_selected ? COLOR_SELECTION_EDGE : COLOR_GLOSS,
|
||||
COLOR_BORDER_DARK);
|
||||
is_selected ? theme->block_active_top : theme->block_top,
|
||||
is_selected ? theme->block_active_mid : theme->block_mid,
|
||||
is_selected ? theme->block_active_bottom : theme->block_bottom,
|
||||
is_selected ? theme->selection_edge : theme->gloss,
|
||||
theme->panel_border);
|
||||
fit_text_with_ellipsis(is_selected ? fonts->medium : fonts->small,
|
||||
program->program_title,
|
||||
title_rect.w,
|
||||
|
|
@ -647,19 +706,70 @@ void ui_render_guide(SDL_Renderer *renderer,
|
|||
&title_rect,
|
||||
title_rect.x,
|
||||
title_rect.y,
|
||||
is_selected ? COLOR_TEXT_DARK : COLOR_TEXT_LIGHT);
|
||||
is_selected ? theme->block_active_text : theme->block_text);
|
||||
SDL_RenderSetClipRect(renderer, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (selected_channel && active_channel >= 0 && start_index <= active_channel && active_channel < start_index + GUIDE_VISIBLE_ROWS) {
|
||||
SDL_Rect highlight = {0, grid.y + (active_channel - start_index) * row_height, window_width, row_height};
|
||||
draw_selection_glow(renderer, &highlight);
|
||||
draw_selection_glow(renderer, &(SDL_Rect){guide_x_start, highlight.y + (int) (6 * scale_y), timeline_w, row_height - (int) (12 * scale_y)});
|
||||
draw_selection_glow(renderer, &highlight, theme->selection_edge);
|
||||
draw_selection_glow(renderer, &(SDL_Rect){guide_x_start, highlight.y + (int) (6 * scale_y), timeline_w, row_height - (int) (12 * scale_y)}, theme->selection_edge);
|
||||
}
|
||||
|
||||
draw_footer_legend(renderer, cache, window_width, window_height);
|
||||
draw_scanline_overlay(renderer, window_width, window_height);
|
||||
draw_footer_legend(renderer, fonts, theme, window_width, window_height);
|
||||
draw_scanline_overlay(renderer, window_width, window_height, theme);
|
||||
}
|
||||
|
||||
void ui_render_theme_picker(SDL_Renderer *renderer,
|
||||
const UiFonts *fonts,
|
||||
int window_width,
|
||||
int window_height,
|
||||
const GuideTheme *active_theme,
|
||||
int current_theme_index,
|
||||
int selected_theme_index) {
|
||||
SDL_Rect overlay = {0, 0, window_width, window_height};
|
||||
SDL_Rect modal = {window_width / 2 - 250, window_height / 2 - 180, 500, 360};
|
||||
SDL_Rect title_bar = {modal.x, modal.y, modal.w, 38};
|
||||
|
||||
(void) current_theme_index;
|
||||
fill_rect_alpha(renderer, &overlay, (SDL_Color){0, 0, 0, 120});
|
||||
draw_panel_shadow(renderer, &modal);
|
||||
draw_rounded_top_panel(renderer, &modal, active_theme->panel_fill, active_theme->panel_border, active_theme->rounded_radius > 0 ? active_theme->rounded_radius : 8);
|
||||
fill_rect(renderer, &(SDL_Rect){modal.x, modal.y + 38, modal.w, modal.h - 38}, active_theme->footer_mid);
|
||||
draw_beveled_bar(renderer, &title_bar, active_theme->ribbon_top, active_theme->ribbon_mid, active_theme->ribbon_bottom, active_theme->gloss, active_theme->panel_border);
|
||||
draw_text_clipped(renderer, fonts->medium, "THEME SELECT", &modal, modal.x + 16, modal.y + 10, active_theme->ribbon_text);
|
||||
|
||||
for (int i = 0; i < GUIDE_THEME_COUNT; ++i) {
|
||||
SDL_Rect item = {modal.x + 18, modal.y + 52 + i * 28, modal.w - 36, 24};
|
||||
SDL_Rect swatch = {modal.x + modal.w - 118, item.y + 4, 92, 14};
|
||||
char label[96];
|
||||
const GuideTheme *theme = &GUIDE_THEMES[i];
|
||||
|
||||
if (i == selected_theme_index) {
|
||||
draw_beveled_bar(renderer, &item, theme->row_active_top, theme->row_active_mid, theme->row_active_bottom, theme->gloss, theme->panel_border);
|
||||
draw_selection_glow(renderer, &item, theme->selection_edge);
|
||||
}
|
||||
|
||||
snprintf(label, sizeof(label), "%c %s", i == selected_theme_index ? '>' : ' ', theme->name);
|
||||
draw_text_clipped(renderer,
|
||||
fonts->small,
|
||||
label,
|
||||
&item,
|
||||
item.x + 8,
|
||||
item.y + 4,
|
||||
i == selected_theme_index ? theme->row_active_text : active_theme->panel_text);
|
||||
fill_three_stop_gradient(renderer, &swatch, theme->background_top, theme->background_mid, theme->background_bottom);
|
||||
stroke_rect(renderer, &swatch, theme->panel_border);
|
||||
}
|
||||
|
||||
draw_text_clipped(renderer,
|
||||
fonts->small,
|
||||
"ENTER APPLY ESC CANCEL B CLOSE",
|
||||
&modal,
|
||||
modal.x + 18,
|
||||
modal.y + modal.h - 28,
|
||||
active_theme->panel_text);
|
||||
}
|
||||
|
||||
int ui_cache_init(UiCache *cache, SDL_Renderer *renderer, const UiFonts *fonts, const ChannelList *channels) {
|
||||
|
|
|
|||
8
src/ui.h
8
src/ui.h
|
|
@ -58,6 +58,7 @@ void ui_render_guide(SDL_Renderer *renderer,
|
|||
int texture_height,
|
||||
int window_width,
|
||||
int window_height,
|
||||
const GuideTheme *theme,
|
||||
const UiFonts *fonts,
|
||||
UiCache *cache,
|
||||
const ChannelList *channels,
|
||||
|
|
@ -65,6 +66,13 @@ void ui_render_guide(SDL_Renderer *renderer,
|
|||
Uint64 app_start_ticks,
|
||||
Uint64 now_ticks,
|
||||
time_t now_wall);
|
||||
void ui_render_theme_picker(SDL_Renderer *renderer,
|
||||
const UiFonts *fonts,
|
||||
int window_width,
|
||||
int window_height,
|
||||
const GuideTheme *active_theme,
|
||||
int current_theme_index,
|
||||
int selected_theme_index);
|
||||
void ui_render_no_media(SDL_Renderer *renderer, const UiCache *cache, int window_width, int window_height);
|
||||
int ui_load_fonts(UiFonts *fonts);
|
||||
void ui_destroy_fonts(UiFonts *fonts);
|
||||
|
|
|
|||
BIN
src/ui.o
BIN
src/ui.o
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue