summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Opalach <andrew@akon.city> 2025-04-08 19:29:43 -0400
committerAndrew Opalach <andrew@akon.city> 2025-04-08 19:29:43 -0400
commit832b3ab11fd6457c59aed9d5bf12ba40c117f15d (patch)
tree5d2d80755553fb2a7d71fd735f9566ba1997b3db
parenta6d104090ef752126766ef237db1ff1dc6b966f0 (diff)
downloadcamu-832b3ab11fd6457c59aed9d5bf12ba40c117f15d.tar.gz
camu-832b3ab11fd6457c59aed9d5bf12ba40c117f15d.tar.bz2
camu-832b3ab11fd6457c59aed9d5bf12ba40c117f15d.zip
More cmc ui tweaking
Signed-off-by: Andrew Opalach <andrew@akon.city>
-rw-r--r--src/fruits/cmc/cmc.c1
-rw-r--r--src/fruits/cmc/ui/pane_list.c114
-rw-r--r--src/fruits/cmc/ui/ui.c2
-rw-r--r--src/fruits/cmsrv/ui.c2
-rw-r--r--src/liana/list.c2
-rw-r--r--src/liana/server.c3
-rw-r--r--src/server/server.c13
-rw-r--r--src/sink/desktop.c66
-rw-r--r--src/sink/util.h21
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(&current->clock);
- f64 duration = current->client.duration / 1000000.0;
+ u64 pts = camu_clock_get_last_pts(&current->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;
+}