console.lua: default to a proportional font for select

In the select menu there are no completions to align in a grid, so the
better looking proportional font of --osd-font can be used by default.
It is also easier to read for the visually impaired.

The text width calculation is no longer performed if the console is only
opened through select, it is only performed the first time something is
completed. This avoids having to pass an argument to get_font() to make
it use the monospace font regardless of selectable_items.

Fixes #15176.
This commit is contained in:
Guido Cella 2024-10-26 12:08:24 +02:00 committed by Kacper Michajłow
parent cb8e3ba959
commit aa66f0dced
2 changed files with 56 additions and 36 deletions

View File

@ -147,11 +147,14 @@ Configurable Options
~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~
``font`` ``font``
Default: unset (picks a hardcoded font depending on detected platform) Default: a monospace font depending on the platform
Set the font used for the REPL and the console. Set the font used for the console.
This has to be a monospaced font for the completion suggestions to be A monospaced font is necessary to align completion suggestions correctly in
aligned correctly. a grid.
If the console was opened by calling ``mp.input.select`` and no font was
configured, ``--osd-font`` is used, as alignment is not necessary in that
case.
``font_size`` ``font_size``
Default: 24 Default: 24

View File

@ -15,17 +15,6 @@
local utils = require 'mp.utils' local utils = require 'mp.utils'
local assdraw = require 'mp.assdraw' local assdraw = require 'mp.assdraw'
-- Default options
local opts = {
font = "",
font_size = 24,
border_size = 1.5,
scale_with_window = "auto",
case_sensitive = true,
history_dedup = true,
font_hw_ratio = 'auto',
}
local function detect_platform() local function detect_platform()
local platform = mp.get_property_native('platform') local platform = mp.get_property_native('platform')
if platform == 'darwin' or platform == 'windows' then if platform == 'darwin' or platform == 'windows' then
@ -36,16 +25,18 @@ local function detect_platform()
return 'x11' return 'x11'
end end
-- Pick a better default font for Windows and macOS
local platform = detect_platform() local platform = detect_platform()
if platform == 'windows' then
opts.font = 'Consolas' -- Default options
opts.case_sensitive = false local opts = {
elseif platform == 'darwin' then font = "",
opts.font = 'Menlo' font_size = 16,
else border_size = 1,
opts.font = 'monospace' scale_with_window = "auto",
end case_sensitive = platform ~= 'windows' and true or false,
history_dedup = true,
font_hw_ratio = 'auto',
}
-- Apply user-set options -- Apply user-set options
require 'mp.options'.read_options(opts) require 'mp.options'.read_options(opts)
@ -117,6 +108,28 @@ local default_item
local set_active local set_active
local function get_font()
if opts.font ~= '' then
return opts.font
end
if selectable_items and not searching_history then
return
end
-- Pick a better default font for Windows and macOS
if platform == 'windows' then
return 'Consolas'
end
if platform == 'darwin' then
return 'Menlo'
end
return 'monospace'
end
-- Naive helper function to find the next UTF-8 character in 'str' after 'pos' -- Naive helper function to find the next UTF-8 character in 'str' after 'pos'
-- by skipping continuation bytes. Assumes 'str' contains valid UTF-8. -- by skipping continuation bytes. Assumes 'str' contains valid UTF-8.
local function next_utf8(str, pos) local function next_utf8(str, pos)
@ -184,7 +197,7 @@ local function normalized_text_width(text, size, horizontal)
for i = 1, repetitions_left do for i = 1, repetitions_left do
size = size * 0.8 size = size * 0.8
local ass = assdraw.ass_new() local ass = assdraw.ass_new()
ass.text = template:format(align, size, opts.font, rotation, text) ass.text = template:format(align, size, get_font(), rotation, text)
local _, _, x1, y1 = measure_bounds(ass.text) local _, _, x1, y1 = measure_bounds(ass.text)
-- Check if nothing got clipped -- Check if nothing got clipped
if x1 and x1 < osd_width and y1 < osd_height then if x1 and x1 < osd_width and y1 < osd_height then
@ -507,10 +520,12 @@ local function update()
screenx .. ',' .. screeny screenx .. ',' .. screeny
local ass = assdraw.ass_new() local ass = assdraw.ass_new()
local has_shadow = mp.get_property('osd-border-style'):find('box$') == nil local has_shadow = mp.get_property('osd-border-style'):find('box$') == nil
local font = get_font()
local style = '{\\r' .. local style = '{\\r' ..
'\\1a&H00&\\3a&H00&\\1c&Heeeeee&\\3c&H111111&' .. '\\1a&H00&\\3a&H00&\\1c&Heeeeee&\\3c&H111111&' ..
(has_shadow and '\\4a&H99&\\4c&H000000&' or '') .. (has_shadow and '\\4a&H99&\\4c&H000000&' or '') ..
'\\fn' .. opts.font .. '\\fs' .. opts.font_size .. (font and '\\fn' .. font or '') ..
'\\fs' .. opts.font_size ..
'\\bord' .. opts.border_size .. '\\xshad0\\yshad1\\fsp0' .. '\\bord' .. opts.border_size .. '\\xshad0\\yshad1\\fsp0' ..
(selectable_items and '\\q2' or '\\q1') .. (selectable_items and '\\q2' or '\\q1') ..
'\\clip(' .. clipping_coordinates .. ')}' '\\clip(' .. clipping_coordinates .. ')}'
@ -534,20 +549,24 @@ local function update()
-- This will render at most screeny / font_size - 1 messages. -- This will render at most screeny / font_size - 1 messages.
local lines_max = calculate_max_log_lines() local lines_max = calculate_max_log_lines()
-- Estimate how many characters fit in one line local suggestion_ass = ''
local width_max = math.floor((screenx - bottom_left_margin - if next(suggestion_buffer) then
mp.get_property_native('osd-margin-x') * 2 * screeny / 720) / -- Estimate how many characters fit in one line
opts.font_size * get_font_hw_ratio()) local width_max = math.floor((screenx - bottom_left_margin -
mp.get_property_native('osd-margin-x') * 2 * screeny / 720)
/ opts.font_size * get_font_hw_ratio())
local suggestions, rows = format_table(suggestion_buffer, width_max, lines_max) local suggestions, rows = format_table(suggestion_buffer, width_max, lines_max)
local suggestion_ass = style .. styles.suggestion .. suggestions lines_max = lines_max - rows
suggestion_ass = style .. styles.suggestion .. suggestions .. '\\N'
end
populate_log_with_matches() populate_log_with_matches()
local log_ass = '' local log_ass = ''
local log_buffer = log_buffers[id] local log_buffer = log_buffers[id]
local log_messages = #log_buffer local log_messages = #log_buffer
local log_max_lines = math.max(0, lines_max - rows) local log_max_lines = math.max(0, lines_max)
if log_max_lines < log_messages then if log_max_lines < log_messages then
log_messages = log_max_lines log_messages = log_max_lines
end end
@ -560,9 +579,7 @@ local function update()
ass:an(1) ass:an(1)
ass:pos(bottom_left_margin, screeny - bottom_left_margin - global_margins.b * screeny) ass:pos(bottom_left_margin, screeny - bottom_left_margin - global_margins.b * screeny)
ass:append(log_ass .. '\\N') ass:append(log_ass .. '\\N')
if #suggestions > 0 then ass:append(suggestion_ass)
ass:append(suggestion_ass .. '\\N')
end
ass:append(style .. ass_escape(prompt) .. ' ' .. before_cur) ass:append(style .. ass_escape(prompt) .. ' ' .. before_cur)
ass:append(cglyph) ass:append(cglyph)
ass:append(style .. after_cur) ass:append(style .. after_cur)