diff options
author | Guido Cella <guido@guidocella.xyz> | 2025-02-04 11:50:01 +0100 |
---|---|---|
committer | sfan5 <sfan5@live.de> | 2025-02-17 16:35:27 +0000 |
commit | d8d2367c245e43b6855b053317661961338ce3a5 (patch) | |
tree | 779d2cea17cf674d1bebee066f4949d0deba9380 /player | |
parent | cfb9a9bdb5c2eb16a52b007d32e61940489518db (diff) | |
download | mpv-d8d2367c245e43b6855b053317661961338ce3a5.tar.bz2 mpv-d8d2367c245e43b6855b053317661961338ce3a5.tar.xz |
console.lua: center the select menu in the window
The newly added max width calculation allows positioning the select menu
in the center of the window.
The input line is moved above the items so that the selected item stays
near the input line as you type instead of jumping from top to bottom as
the matches decrease.
Keep aligning to the bottom left to search the command history to not
change the layout abruptly, the same reason the monospace font is kept.
Diffstat (limited to 'player')
-rw-r--r-- | player/lua/console.lua | 52 |
1 files changed, 33 insertions, 19 deletions
diff --git a/player/lua/console.lua b/player/lua/console.lua index 928fc07962..5ec868d4e4 100644 --- a/player/lua/console.lua +++ b/player/lua/console.lua @@ -319,16 +319,18 @@ local function calculate_max_item_width() end end - local width_overlay = mp.create_osd_overlay('ass-events') + local osd_w, osd_h = get_scaled_osd_dimensions() local font = get_font() + local width_overlay = mp.create_osd_overlay('ass-events') width_overlay.compute_bounds = true width_overlay.hidden = true - width_overlay.res_x, width_overlay.res_y = get_scaled_osd_dimensions() + width_overlay.res_x = osd_w + width_overlay.res_y = osd_h width_overlay.data = '{\\fs' .. opts.font_size .. (font and '\\fn' .. font or '') .. '\\b1\\q2}' .. ass_escape(longest_item) local result = width_overlay:update() - max_item_width = result.x1 - result.x0 + max_item_width = math.min(result.x1 - result.x0, osd_w - get_margin_x() * 2) end local function should_highlight_completion(i) @@ -594,19 +596,29 @@ local function render() end local ass = assdraw.ass_new() - local osd_w, osd_h = get_scaled_osd_dimensions() + local line_height = get_line_height() + local max_lines = calculate_max_log_lines() - local x = get_margin_x() - local y = osd_h * (1 - global_margins.b) - get_margin_y() + local x, y, alignment, clipping_coordinates + if selectable_items and not searching_history then + x = (osd_w - max_item_width) / 2 + y = osd_h / 2 - (math.min(#selectable_items, max_lines) + 1.5) * line_height / 2 + alignment = 7 + clipping_coordinates = '0,0,' .. x + max_item_width .. ',' .. osd_h + else + x = get_margin_x() + y = osd_h * (1 - global_margins.b) - get_margin_y() + alignment = 1 + -- Avoid drawing below topbar OSC when there are wrapped lines. + local coordinate_top = math.floor(global_margins.t * osd_h + 0.5) + clipping_coordinates = '0,' .. coordinate_top .. ',' .. osd_w .. ',' .. osd_h + end local font = get_font() -- Use the same blur value as the rest of the OSD. 288 is the OSD's -- PlayResY. local blur = mp.get_property_native('osd-blur') * osd_h / 288 - local coordinate_top = math.floor(global_margins.t * osd_h + 0.5) - local clipping_coordinates = '0,' .. coordinate_top .. ',' .. - osd_w .. ',' .. osd_h local style = '{\\r' .. (font and '\\fn' .. font or '') .. @@ -636,7 +648,6 @@ local function render() -- Render log messages as ASS. -- This will render at most screeny / font_size - 1 messages. - local max_lines = calculate_max_log_lines() local completion_ass = '' if next(completion_buffer) then -- Estimate how many characters fit in one line @@ -658,7 +669,6 @@ local function render() local log_ass = '' local log_buffer = log_buffers[id] - local line_height = get_line_height() item_positions = {} -- Disable background-box for selectable items to not draw separate @@ -667,7 +677,7 @@ local function render() style = style .. '{\\4a&Hff&}' ass:new_event() - ass:an(1) + ass:an(alignment) ass:pos(x, y) ass:append('{\\1a&Hff&}') ass:draw_start() @@ -679,14 +689,17 @@ local function render() local log_item = style .. log_buffer[i].style .. ass_escape(log_buffer[i].text) if selectable_items then - local item_y = y - (1.5 + #log_buffer - i) * line_height + local item_y = alignment == 7 + and y + (1 + i) * line_height + or y - (1.5 + #log_buffer - i) * line_height ass:new_event() - ass:an(1) + ass:an(4) ass:pos(x, item_y) ass:append(log_item) if #matches <= max_lines or i > 1 then -- skip the counter - item_positions[#item_positions + 1] = { item_y - line_height, item_y } + item_positions[#item_positions + 1] = + { item_y - line_height / 2, item_y + line_height / 2 } end else log_ass = log_ass .. log_item .. '\\N' @@ -694,10 +707,11 @@ local function render() end ass:new_event() - ass:an(1) + ass:an(alignment) ass:pos(x, y) - ass:append(log_ass .. '\\N') - ass:append(completion_ass) + if not selectable_items then + ass:append(log_ass .. '\\N' .. completion_ass) + end ass:append(style .. ass_escape(prompt) .. ' ' .. before_cur) ass:append(cglyph) ass:append(style .. after_cur) @@ -705,7 +719,7 @@ local function render() -- Redraw the cursor with the REPL text invisible. This will make the -- cursor appear in front of the text. ass:new_event() - ass:an(1) + ass:an(alignment) ass:pos(x, y) ass:append(style .. '{\\alpha&HFF&}' .. ass_escape(prompt) .. ' ' .. before_cur) ass:append(cglyph) |