command: highlight selected list items with color

Instead of printing circles in show-text ${playlist}, ${chapter-list}
and ${edition-list}, introduce --osd-selected-color and
--osd-selected-outline-color to reduce clutter, make the selected item
easier to differentiate, and have visual consistency with select.lua.

The defaults are taken from the style of the selected item in the
console. These new options are also used there, replacing the hardcoded
styles. Due to being user-configurable, selected item styles are changed
to take priority over default item styles.

The default selected style is yellow and bold. The bold (hardcoded)
allows differentiating the selected item with color blindness. There is
also a separate --osd-selected-outline-color option defaulting to black,
since without it if the user changes --osd-outline-color yellow text
becomes unreadable without a black border. --osd-selected-back-color is
omitted for now.

Text and background colors are inverted for the selected item in the
terminal. This is hardcoded, adding an option is overkill.

A disadvantage of this commit is that if you run print-text ${playlist}
with a VO, the selected style ASS is printed to the terminal (but ASS
printed in the console is interpreted). This commit avoids printing the
reset ASS sequence for non-selected items to reduce clutter in this
case.
This commit is contained in:
Guido Cella
2024-11-26 22:15:45 +01:00
committed by Kacper Michajłow
parent d54a45d075
commit b9e6030053
8 changed files with 75 additions and 19 deletions

View File

@@ -0,0 +1 @@
add `--osd-selected-color` and `--osd-selected-outline-color` options

View File

@@ -4592,6 +4592,14 @@ OSD
Specify the color used for OSD.
See ``--sub-color`` for details.
``--osd-selected-color=<color>``
The color of the selected item in lists.
See ``--sub-color`` for details.
``--osd-selected-outline-color=<color>``
The outline color of the selected item in lists.
See ``--sub-color`` for details.
``--osd-fractions``
Show OSD times with fractions of seconds (in millisecond precision). Useful
to see the exact timestamp of a video frame.

View File

@@ -397,6 +397,8 @@ const struct m_sub_options mp_osd_render_sub_opts = {
{"osd-bar", OPT_SUBSTRUCT(osd_bar_style, osd_bar_style_conf)},
{"osd-scale", OPT_FLOAT(osd_scale), M_RANGE(0, 100)},
{"osd-scale-by-window", OPT_BOOL(osd_scale_by_window)},
{"osd-selected-color", OPT_COLOR(osd_selected_color)},
{"osd-selected-outline-color", OPT_COLOR(osd_selected_outline_color)},
{"force-rgba-osd-rendering", OPT_BOOL(force_rgba_osd)},
{0}
},
@@ -404,6 +406,8 @@ const struct m_sub_options mp_osd_render_sub_opts = {
.defaults = &(OPT_BASE_STRUCT){
.osd_scale = 1,
.osd_scale_by_window = true,
.osd_selected_color = {250, 189, 47, 255},
.osd_selected_outline_color = {0, 0, 0, 255},
},
.change_flags = UPDATE_OSD,
};

View File

@@ -137,6 +137,8 @@ struct mp_subtitle_shared_opts {
struct mp_osd_render_opts {
float osd_scale;
bool osd_scale_by_window;
struct m_color osd_selected_color;
struct m_color osd_selected_outline_color;
struct osd_style_opts *osd_style;
struct osd_bar_style_opts *osd_bar_style;
bool force_rgba_osd;

View File

@@ -38,6 +38,9 @@
#define TERM_ESC_ENABLE_MOUSE "\033[?1003h"
#define TERM_ESC_DISABLE_MOUSE "\033[?1003l"
#define TERM_ESC_REVERSE_COLORS "\033[7m"
#define TERM_ESC_CLEAR_COLORS "\033[0m"
struct input_ctx;
/* Global initialization for terminal output. */

View File

@@ -45,6 +45,7 @@
#include "common/common.h"
#include "input/input.h"
#include "input/keycodes.h"
#include "sub/osd_state.h"
#include "stream/stream.h"
#include "demux/demux.h"
#include "demux/stheader.h"
@@ -306,6 +307,32 @@ void mark_seek(struct MPContext *mpctx)
cmd->last_seek_time = now;
}
static char *append_selected_style(struct MPContext *mpctx, char *str)
{
if (!mpctx->video_out || !mpctx->opts->video_osd)
return talloc_strdup_append(str, TERM_ESC_REVERSE_COLORS);
return talloc_asprintf_append(str,
"%s{\\b1\\1c&H%x%x%x&\\1a&H%x&\\3c&H%x%x%x&\\3a&H%x&}%s",
OSD_ASS_0,
mpctx->video_out->osd->opts->osd_selected_color.b,
mpctx->video_out->osd->opts->osd_selected_color.g,
mpctx->video_out->osd->opts->osd_selected_color.r,
255 - mpctx->video_out->osd->opts->osd_selected_color.a,
mpctx->video_out->osd->opts->osd_selected_outline_color.b,
mpctx->video_out->osd->opts->osd_selected_outline_color.g,
mpctx->video_out->osd->opts->osd_selected_outline_color.r,
255 - mpctx->video_out->osd->opts->osd_selected_outline_color.a,
OSD_ASS_1);
}
static const char *get_style_reset(struct MPContext *mpctx)
{
return mpctx->video_out && mpctx->opts->video_osd
? OSD_ASS_0"{\\r}"OSD_ASS_1
: TERM_ESC_CLEAR_COLORS;
}
static char *skip_n_lines(char *text, int lines)
{
while (text && lines > 0) {
@@ -1055,13 +1082,14 @@ static int mp_property_list_chapters(void *ctx, struct m_property *prop,
}
for (n = 0; n < count; n++) {
if (n == cur)
res = append_selected_style(mpctx, res);
char *name = chapter_name(mpctx, n);
double t = chapter_start_time(mpctx, n);
char* time = mp_format_time(t, false);
res = talloc_asprintf_append(res, "%s", time);
res = talloc_asprintf_append(res, "%s %s%s\n", time, name,
n == cur ? get_style_reset(mpctx) : "");
talloc_free(time);
const char *m = n == cur ? list_current : list_normal;
res = talloc_asprintf_append(res, " %s%s\n", m, name);
}
*(char **)arg = count ? cut_osd_list(mpctx, "Chapters", res, cur) : res;
@@ -1166,13 +1194,14 @@ static int property_list_editions(void *ctx, struct m_property *prop,
for (int n = 0; n < num_editions; n++) {
struct demux_edition *ed = &editions[n];
res = talloc_strdup_append(res, n == current ? list_current
: list_normal);
if (n == current)
res = append_selected_style(mpctx, res);
res = talloc_asprintf_append(res, "%d: ", n);
char *title = mp_tags_get_str(ed->metadata, "title");
if (!title)
title = "unnamed";
res = talloc_asprintf_append(res, "'%s'\n", title);
res = talloc_asprintf_append(res, "'%s'%s\n", title,
n == current ? get_style_reset(mpctx) : "");
}
*(char **)arg = res;
@@ -3343,8 +3372,9 @@ static int mp_property_playlist(void *ctx, struct m_property *prop,
for (int n = 0; n < pl->num_entries; n++) {
struct playlist_entry *e = pl->entries[n];
res = talloc_strdup_append(res, pl->current == e ? list_current
: list_normal);
if (pl->current == e)
res = append_selected_style(mpctx, res);
const char *reset = pl->current == e ? get_style_reset(mpctx) : "";
char *p = e->title;
if (!p || mpctx->opts->playlist_entry_name > 0) {
p = e->filename;
@@ -3355,9 +3385,9 @@ static int mp_property_playlist(void *ctx, struct m_property *prop,
}
}
if (!e->title || p == e->title || mpctx->opts->playlist_entry_name == 1) {
res = talloc_asprintf_append(res, "%s\n", p);
res = talloc_asprintf_append(res, "%s%s\n", p, reset);
} else {
res = talloc_asprintf_append(res, "%s (%s)\n", e->title, p);
res = talloc_asprintf_append(res, "%s (%s)%s\n", e->title, p, reset);
}
}

View File

@@ -389,6 +389,11 @@ local function fuzzy_find(needle, haystacks, case_sensitive)
return result
end
local function mpv_color_to_ass(color)
return color:sub(8,9) .. color:sub(6,7) .. color:sub(4,5),
string.format('%x', 255 - tonumber('0x' .. color:sub(2,3)))
end
local function populate_log_with_matches()
if not selectable_items or selected_match == 0 then
return
@@ -430,13 +435,17 @@ local function populate_log_with_matches()
local style = ''
local terminal_style = ''
if i == selected_match then
style = styles.selected_suggestion
terminal_style = terminal_styles.selected_suggestion
end
if matches[i].index == default_item then
style = style .. styles.default_item
terminal_style = terminal_style .. terminal_styles.default_item
style = styles.default_item
terminal_style = terminal_styles.default_item
end
if i == selected_match then
local color, alpha = mpv_color_to_ass(mp.get_property('osd-selected-color'))
local outline_color, outline_alpha =
mpv_color_to_ass(mp.get_property('osd-selected-outline-color'))
style = style .. "{\\b1\\1c&H" .. color .. "&\\1a&H" .. alpha ..
"&\\3c&H" .. outline_color .. "&\\3a&H" .. outline_alpha .. "&}"
terminal_style = terminal_style .. terminal_styles.selected_suggestion
end
log[#log + 1] = {

View File

@@ -41,7 +41,6 @@
#define DEFAULT_WIDTH 80
#define DEFAULT_HEIGHT 25
static const bstr TERM_ESC_CLEAR_COLORS = bstr0_lit("\033[0m");
static const bstr TERM_ESC_COLOR256_BG = bstr0_lit("\033[48;5");
static const bstr TERM_ESC_COLOR256_FG = bstr0_lit("\033[38;5");
static const bstr TERM_ESC_COLOR24BIT_BG = bstr0_lit("\033[48;2");
@@ -160,7 +159,7 @@ static void write_plain(bstr *frame,
if (buffering <= VO_TCT_BUFFER_PIXEL)
print_buffer(frame);
}
bstr_xappend(NULL, frame, TERM_ESC_CLEAR_COLORS);
bstr_xappend(NULL, frame, (bstr)bstr0_lit(TERM_ESC_CLEAR_COLORS));
if (buffering <= VO_TCT_BUFFER_LINE)
print_buffer(frame);
}
@@ -197,7 +196,7 @@ static void write_half_blocks(bstr *frame,
if (buffering <= VO_TCT_BUFFER_PIXEL)
print_buffer(frame);
}
bstr_xappend(NULL, frame, TERM_ESC_CLEAR_COLORS);
bstr_xappend(NULL, frame, (bstr)bstr0_lit(TERM_ESC_CLEAR_COLORS));
if (buffering <= VO_TCT_BUFFER_LINE)
print_buffer(frame);
}