diff options
| author | 2025-04-08 19:29:43 -0400 | |
|---|---|---|
| committer | 2025-04-08 19:29:43 -0400 | |
| commit | 832b3ab11fd6457c59aed9d5bf12ba40c117f15d (patch) | |
| tree | 5d2d80755553fb2a7d71fd735f9566ba1997b3db /src | |
| parent | a6d104090ef752126766ef237db1ff1dc6b966f0 (diff) | |
| download | camu-832b3ab11fd6457c59aed9d5bf12ba40c117f15d.tar.gz camu-832b3ab11fd6457c59aed9d5bf12ba40c117f15d.tar.bz2 camu-832b3ab11fd6457c59aed9d5bf12ba40c117f15d.zip | |
More cmc ui tweaking
Signed-off-by: Andrew Opalach <andrew@akon.city>
Diffstat (limited to 'src')
| -rw-r--r-- | src/fruits/cmc/cmc.c | 1 | ||||
| -rw-r--r-- | src/fruits/cmc/ui/pane_list.c | 114 | ||||
| -rw-r--r-- | src/fruits/cmc/ui/ui.c | 2 | ||||
| -rw-r--r-- | src/fruits/cmsrv/ui.c | 2 | ||||
| -rw-r--r-- | src/liana/list.c | 2 | ||||
| -rw-r--r-- | src/liana/server.c | 3 | ||||
| -rw-r--r-- | src/server/server.c | 13 | ||||
| -rw-r--r-- | src/sink/desktop.c | 66 | ||||
| -rw-r--r-- | src/sink/util.h | 21 |
9 files changed, 152 insertions, 72 deletions
diff --git a/src/fruits/cmc/cmc.c b/src/fruits/cmc/cmc.c index 4278663..6e62a4a 100644 --- a/src/fruits/cmc/cmc.c +++ b/src/fruits/cmc/cmc.c @@ -178,6 +178,7 @@ static void client_callback(void *userdata, u8 op, void *opaque) } break; } + case LIANA_META_ENTRY_PAUSED: case LIANA_META_ENTRY_SEEKED: { u32 id = nn_packet_read_u32(packet); struct cmc_list_entry *entry; diff --git a/src/fruits/cmc/ui/pane_list.c b/src/fruits/cmc/ui/pane_list.c index 557f5f3..695ff60 100644 --- a/src/fruits/cmc/ui/pane_list.c +++ b/src/fruits/cmc/ui/pane_list.c @@ -1,6 +1,7 @@ #include <nnwt/thread.h> #include "../../liana/list.h" +#include "../../sink/util.h" #include "../cmc.h" @@ -232,53 +233,104 @@ static void render_list_entries(struct cmc_ui *ui, struct cmc_list_tab *tab, s32 static void render_now_playing(struct cmc_ui *ui, struct cmc_list_tab *tab, u32 y, u32 height) { - u32 width = ncplane_dim_x(ui->lp.n); - if (tab && tab->list->entries.count > 0) { - struct cmc_list *list = tab->list; - struct cmc_list_entry *entry = al_array_at(list->entries, list->current); - f32 percent = 1.0; - if (entry->duration > 0) { - u64 pos = entry->offset; - u64 now = nn_get_timestamp(); - if (entry->start != LIANA_TIMESTAMP_INVALID && now > entry->start) { - pos += now - entry->start; - } - percent = MIN(pos / (f32)entry->duration, 1.f); + struct ncplane *n = ui->lp.n; + u32 width = ncplane_dim_x(n); + + struct cmc_list_entry *entry = NULL; + if (tab->list->entries.count > (u32)tab->list->current) { + entry = al_array_at(tab->list->entries, tab->list->current); + } + + u64 pos = 0; + u64 duration = 0; + u64 remaining = 0; + u32 y_off = height - 6; + + ncplane_set_styles(n, NCSTYLE_BOLD); + if (entry) { + pos = entry->offset; + duration = entry->duration; + u64 now = nn_get_timestamp(); + bool paused = entry->start == LIANA_TIMESTAMP_INVALID; + if (!paused && now > entry->start) { + pos += now - entry->start; } - for (u32 i = 0; i < (width - 2) * percent; i++) { - ncplane_putchar_yx(ui->lp.n, height - 6, i + 1, '-'); + pos = MIN(pos, duration); + remaining = duration - pos; + //ncplane_putstr_yx(n, y_off, 2, "▸"); + //ncplane_putstr_yx(n, y_off, 2, "▶"); + //ncplane_putstr_yx(n, y_off, 2, "⏵ "); + //ncplane_putstr_yx(n, y_off, 2, "|"); + //ncplane_putstr_yx(n, y_off, 2, "|"); + //ncplane_putstr_yx(n, y_off, 2, "⏵"); + //ncplane_putstr_yx(n, y_off, 2, "⏸"); + if (remaining == 0) { + ncplane_putstr_yx(n, y_off - 1, 2, "∨"); + } else { + ncplane_putstr_yx(n, y_off - 1, 2, paused ? "^": ">"); } - cmc_ui_putnwstr_yx(ui->lp.n, height - 7, 2, entry->name.length, &entry->name); + } else { + ncplane_putstr_yx(n, y_off - 1, 2, "∨"); + } + ncplane_set_styles(n, NCSTYLE_NONE); + + f32 percent = 1.f; + if (duration > 0) percent = MIN(pos / (f32)duration, 1.f); + for (u32 i = 0; i < (width - 2) * percent; i++) { + ncplane_putchar_yx(n, y_off, i + 1, '-'); + } + + y_off--; + + char timestr[16] = { 0 }; // max = 829128280:01:49\0 + s32 offset = camu_print_time(timestr, sizeof(timestr), pos, true, 4); + ncplane_putstr_yx(n, y_off, 4, timestr); + ncplane_putstr_yx(n, y_off, 4 + offset, "⎹"); + + if (entry) { + cmc_ui_putnwstr_yx(n, y_off, 6 + offset, MIN(entry->name.length, (u32)40), &entry->name); + } + + bool show_remaining = true; + if (show_remaining) { + offset = camu_print_time(timestr, sizeof(timestr), remaining, true, 4); + } else { + offset = camu_print_time(timestr, sizeof(timestr), duration, true, 4); } - ncplane_putchar_yx(ui->lp.n, height - 5, 2, 'A'); - ncplane_putchar_yx(ui->lp.n, height - 4, 2, 'A'); - ncplane_putchar_yx(ui->lp.n, height - 3, 2, 'A'); - ncplane_putchar_yx(ui->lp.n, height - 2, 2, 'A'); + ncplane_putstr_yx(n, y_off, width - 4 - offset, "⎸"); + // "=" Duration, "+" Segment, "-" Remaining. + if (show_remaining) { + ncplane_putstr_yx(n, y_off, width - 3 - offset, "-"); + } else { + ncplane_putstr_yx(n, y_off, width - 3 - offset, "="); + } + ncplane_putstr_yx(n, y_off, width - 2 - offset, timestr); + + ncplane_putchar_yx(n, height - 5, 2, 'A'); + ncplane_putchar_yx(n, height - 4, 2, 'A'); + ncplane_putchar_yx(n, height - 3, 2, 'A'); + ncplane_putchar_yx(n, height - 2, 2, 'A'); + /* char buf[24]; al_snprintf(buf, sizeof(buf), "%u, %u | %u, %u", ui->last_mouse_x, ui->last_mouse_y, width, height); - ncplane_putstr_yx(ui->lp.n, height - 5, 1, buf); + ncplane_putstr_yx(n, height - 5, 5, buf); */ + u64 c = 0; ncchannels_set_fg_default(&c); - ncplane_cursor_move_yx(ui->lp.n, y, 0); - ncplane_light_box(ui->lp.n, NCSTYLE_NONE, c, height - 1, width - 1, 0); + ncplane_cursor_move_yx(n, y, 0); + ncplane_light_box(n, NCSTYLE_NONE, c, height - 1, width - 1, 0); } void cmc_lp_render(struct cmc_ui *ui) { u32 height = ncplane_dim_y(ui->lp.n); - struct cmc_list_tab *tab = NULL; - if (ui->lp.tabs.count > 0) { - tab = &al_array_at(ui->lp.tabs, ui->lp.current); - } + if (ui->lp.tabs.count <= ui->lp.current) return; + struct cmc_list_tab *tab = &al_array_at(ui->lp.tabs, ui->lp.current); tab->page_length = height - 8; - - if (tab) { - render_list_entries(ui, tab, tab->page_length); - } - + render_list_entries(ui, tab, tab->page_length); render_now_playing(ui, tab, tab->page_length, height); } diff --git a/src/fruits/cmc/ui/ui.c b/src/fruits/cmc/ui/ui.c index bd76e56..10357c0 100644 --- a/src/fruits/cmc/ui/ui.c +++ b/src/fruits/cmc/ui/ui.c @@ -244,7 +244,7 @@ bool cmc_ui_init(struct cmc_ui *ui, struct nn_event_loop *loop, struct cmc *c) nn_poll_start(&ui->input_poll, ui->loop); nn_timer_init(&ui->render_timer, ui->loop, render_timer_callback, ui); - nn_timer_set_repeat(&ui->render_timer, NNWT_TS_FROM_USEC(300000)); + nn_timer_set_repeat(&ui->render_timer, NNWT_TS_FROM_USEC(200000)); nn_timer_again(&ui->render_timer); return true; diff --git a/src/fruits/cmsrv/ui.c b/src/fruits/cmsrv/ui.c index dced71d..0a41bfc 100644 --- a/src/fruits/cmsrv/ui.c +++ b/src/fruits/cmsrv/ui.c @@ -117,7 +117,7 @@ static void erase_lists(struct cmsrv_ui *ui) struct ncplane *n = ui->lists.n; if (n) { ncplane_erase(n); - notcurses_render(ui->nc); + //notcurses_render(ui->nc); } } diff --git a/src/liana/list.c b/src/liana/list.c index 7d3d722..1c7c6c9 100644 --- a/src/liana/list.c +++ b/src/liana/list.c @@ -390,6 +390,8 @@ static void handle_toggle_pause(struct lia_list *list, s32 sequence, f64 pts) al_array_foreach(list->sinks, i, sink) { sink_toggle_pause(sink, entry, sequence, &time); } + + signal_meta(list, entry, LIANA_META_ENTRY_PAUSED); } static void handle_seek(struct lia_list *list, s32 sequence, u32 id, u64 pos) diff --git a/src/liana/server.c b/src/liana/server.c index 6ab3532..abf4154 100644 --- a/src/liana/server.c +++ b/src/liana/server.c @@ -459,8 +459,7 @@ static void duration_signal_callback(void *userdata) void lia_node_get_duration(struct lia_node *node) { - // It's vital we don't block during handler->init(), this is very wasteful though. - // We should be able to reuse this initialized handler with a sort of "connection pool". + // It is vital we don't block during handler->init(). nn_signal_init(&node->signal, node->server->loop, duration_signal_callback, node); nn_signal_start(&node->signal); cch_entry_get_handle(node->entry, &node->handle); diff --git a/src/server/server.c b/src/server/server.c index 467067a..47f9995 100644 --- a/src/server/server.c +++ b/src/server/server.c @@ -275,6 +275,18 @@ static void send_clients_order_changed(struct camu_server *server, struct lia_li } } +static void send_clients_entry_paused(struct camu_server *server, struct lia_list *list, struct lia_list_entry *entry) +{ + struct camu_server_client *client; + al_array_foreach(server->clients, i, client) { + struct nn_packet *packet = nn_rpc_get_packet(client->conn->rpc, CAMU_CLIENT_META); + nn_packet_write_u8(packet, LIANA_META_ENTRY_PAUSED); + nn_packet_write_str(packet, &list->name); + write_list_entry(entry, packet); + nn_rpc_connection_command(client->conn, packet, NULL, NULL); + } +} + static void send_clients_entry_seeked(struct camu_server *server, struct lia_list *list, struct lia_list_entry *entry) { struct camu_server_client *client; @@ -437,6 +449,7 @@ static void list_callback(void *userdata, u8 op, struct lia_list_entry *entry, v send_clients_order_changed(server, list); break; case LIANA_META_ENTRY_PAUSED: + send_clients_entry_paused(server, list, entry); break; case LIANA_META_ENTRY_SEEKED: send_clients_entry_seeked(server, list, entry); diff --git a/src/sink/desktop.c b/src/sink/desktop.c index fa8d623..fcb7cf1 100644 --- a/src/sink/desktop.c +++ b/src/sink/desktop.c @@ -15,6 +15,7 @@ #endif #include "desktop.h" +#include "util.h" #ifdef CAMU_SCREEN_DEBUG_KEY #include "input_simulator.h" #endif @@ -30,13 +31,13 @@ static u8 sink_callback(void *userdata, u8 op, u8 type, void *opaque) case CAMU_SINK_AUDIO: { struct camu_audio_buffer *buf = (struct camu_audio_buffer *)opaque; camu_mixer_add_buffer(mixer, buf); - info("Audio buffer added."); + log_info("Audio buffer added."); break; } case CAMU_SINK_VIDEO: { struct camu_video_buffer *buf = (struct camu_video_buffer *)opaque; camu_screen_add_buffer(scr, buf); - info("Video buffer added."); + log_info("Video buffer added."); break; } } @@ -46,13 +47,13 @@ static u8 sink_callback(void *userdata, u8 op, u8 type, void *opaque) case CAMU_SINK_AUDIO: { struct camu_audio_buffer *buf = (struct camu_audio_buffer *)opaque; camu_mixer_remove_buffer(mixer, buf); - info("Audio buffer removed."); + log_info("Audio buffer removed."); break; } case CAMU_SINK_VIDEO: { struct camu_video_buffer *buf = (struct camu_video_buffer *)opaque; camu_screen_remove_buffer(scr, buf); - info("Video buffer removed."); + log_info("Video buffer removed."); break; } } @@ -61,12 +62,12 @@ static u8 sink_callback(void *userdata, u8 op, u8 type, void *opaque) switch (type) { case CAMU_SINK_AUDIO: camu_mixer_resume(mixer); - info("Audio started."); + log_info("Audio started."); break; case CAMU_SINK_VIDEO: camu_screen_set_state(scr, CAMU_SCREEN_PLAYING); camu_screen_wake(scr); - info("Video started."); + log_info("Video started."); break; } break; @@ -74,11 +75,11 @@ static u8 sink_callback(void *userdata, u8 op, u8 type, void *opaque) switch (type) { case CAMU_SINK_AUDIO: camu_mixer_pause(mixer); - info("Audio stopped."); + log_info("Audio stopped."); break; case CAMU_SINK_VIDEO: camu_screen_set_state(scr, CAMU_SCREEN_PAUSED); - info("Video stopped."); + log_info("Video stopped."); break; } break; @@ -109,50 +110,41 @@ static u8 sink_callback(void *userdata, u8 op, u8 type, void *opaque) return CAMU_SINK_OK; } -static char status[128]; +static char status[64]; static void print_status(struct camu_sink *sink) { struct camu_sink_entry *current = camu_sink_get_current(sink); if (!current) { - info("Not playing."); camu_sink_return_current(sink); - return; + goto notplaying; } - f64 pts = camu_clock_get_last_pts(¤t->clock); - f64 duration = current->client.duration / 1000000.0; + u64 pts = camu_clock_get_last_pts(¤t->clock) * 1000000u; + u64 duration = current->client.duration; + pts = MIN(duration, pts); bool paused = current->paused; camu_sink_return_current(sink); - s32 text = 0; - if (paused) { - text += al_snprintf(status + text, sizeof(status) - text, "⏸ "); - } else { - text += al_snprintf(status + text, sizeof(status) - text, "⏵ "); + u64 remaining = duration - pts; + if (remaining == 0) { + goto notplaying; } - text += al_snprintf(status + text, sizeof(status) - text, "["); + bool show_hour = duration > 60u * 60u * 1000000u; + s32 offset = al_snprintf(status, sizeof(status), paused ? "⏸ " : "⏵ "); + offset += al_snprintf(status + offset, sizeof(status) - offset, "["); + offset += camu_print_time(status + offset, sizeof(status) - offset, pts, show_hour, 2); + offset += al_snprintf(status + offset, sizeof(status) - offset, "/"); + offset += camu_print_time(status + offset, sizeof(status) - offset, duration, show_hour, 2); + offset += al_snprintf(status + offset, sizeof(status) - offset, "]"); + status[offset] = '\0'; - u32 minute = (u32)(pts / 60); - u32 hour = minute / 60; - minute -= hour * 60; - bool show_hour = duration >= 60.0 * 60.0; - if (show_hour) text += al_snprintf(status + text, sizeof(status) - text, "%.2d:", hour); - text += al_snprintf(status + text, sizeof(status) - text, "%.2d:%.2d/", minute, (u32)pts % 60); - - minute = (u32)(duration / 60); - hour = minute / 60; - minute -= hour * 60; - if (show_hour) text += al_snprintf(status + text, sizeof(status) - text, "%.2d:", hour); - text += al_snprintf(status + text, sizeof(status) - text, "%.2d:%.2d", minute, (u32)duration % 60); - - text += al_snprintf(status + text, sizeof(status) - text, "]"); - - status[text] = '\0'; - - info("%s", status); + log_info("%s", status); + return; +notplaying: + log_info("Not playing."); } static void screen_callback(void *userdata, u8 op, void *opaque) diff --git a/src/sink/util.h b/src/sink/util.h new file mode 100644 index 0000000..d9dd4cc --- /dev/null +++ b/src/sink/util.h @@ -0,0 +1,21 @@ +#pragma once + +#include <al/lib.h> + +static inline s32 camu_print_time(char *buf, size_t size, u64 nanoseconds, bool always_show_hour, u32 hour_padding) +{ + u32 hours = nanoseconds / 3600000000u; + u32 minutes = nanoseconds / 60000000u; + bool show_hour = always_show_hour || minutes >= 60u; + u32 seconds = nanoseconds / 1000000u; + seconds -= minutes * 60u; + minutes -= hours * 60u; + s32 offset = 0; + if (show_hour) { + static const char *padding_table[] = { "%.2u:", "%.3u:", "%.4u:" }; + hour_padding = CLAMP(hour_padding, 2u, 4u) - 2u; + offset += al_snprintf(buf, size, padding_table[hour_padding], hours); + } + offset += al_snprintf(buf + offset, size - offset, "%.2u:%.2u", minutes, seconds); + return offset; +} |