add mvi not as submodule
This commit is contained in:
parent
49ebf8a1e1
commit
e6714de34b
16 changed files with 1547 additions and 0 deletions
73
.config/mvi/scripts/detect-image.lua
Normal file
73
.config/mvi/scripts/detect-image.lua
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
local opts = {
|
||||
command_on_first_image_loaded="",
|
||||
command_on_image_loaded="",
|
||||
command_on_non_image_loaded="",
|
||||
}
|
||||
local options = require 'mp.options'
|
||||
local msg = require 'mp.msg'
|
||||
|
||||
options.read_options(opts, nil, function() end)
|
||||
|
||||
function run_maybe(str)
|
||||
if str ~= "" then
|
||||
mp.command(str)
|
||||
end
|
||||
end
|
||||
|
||||
local was_image = false
|
||||
|
||||
function set_image(is_image)
|
||||
if is_image and not was_image then
|
||||
msg.info("First image detected")
|
||||
run_maybe(opts.command_on_first_image_loaded)
|
||||
end
|
||||
if is_image then
|
||||
msg.info("Image detected")
|
||||
run_maybe(opts.command_on_image_loaded)
|
||||
end
|
||||
if not is_image and was_image then
|
||||
msg.info("Non-image detected")
|
||||
run_maybe(opts.command_on_non_image_loaded)
|
||||
end
|
||||
was_image = is_image
|
||||
end
|
||||
|
||||
local properties = {}
|
||||
|
||||
function properties_changed()
|
||||
local dwidth = properties["dwidth"]
|
||||
local tracks = properties["track-list"]
|
||||
local path = properties["path"]
|
||||
local framecount = properties["estimated-frame-count"]
|
||||
|
||||
if not path or path == "" then return end
|
||||
if not tracks or #tracks == 0 then return end
|
||||
local audio_tracks = 0
|
||||
for _, track in ipairs(tracks) do
|
||||
if track.type == "audio" then
|
||||
audio_tracks = audio_tracks + 1
|
||||
end
|
||||
end
|
||||
|
||||
-- only do things when state is consistent
|
||||
if not framecount and audio_tracks > 0 then
|
||||
set_image(false)
|
||||
elseif framecount and dwidth and dwidth > 0 then
|
||||
-- png have 0 frames, jpg 1 ¯\_(ツ)_/¯
|
||||
set_image((framecount == 0 or framecount == 1) and audio_tracks == 0)
|
||||
end
|
||||
end
|
||||
|
||||
function observe(propname)
|
||||
mp.observe_property(propname, "native", function(_, val)
|
||||
if val ~= properties[propname] then
|
||||
properties[propname] = val
|
||||
msg.verbose("Property " .. propname .. " changed")
|
||||
properties_changed()
|
||||
end
|
||||
end)
|
||||
end
|
||||
observe("estimated-frame-count")
|
||||
observe("track-list")
|
||||
observe("dwidth")
|
||||
observe("path")
|
||||
176
.config/mvi/scripts/equalizer.lua
Normal file
176
.config/mvi/scripts/equalizer.lua
Normal file
|
|
@ -0,0 +1,176 @@
|
|||
local opts = {
|
||||
bars = 'brightness,contrast,gamma,saturation,hue',
|
||||
draw_icons = true,
|
||||
}
|
||||
|
||||
local msg = require 'mp.msg'
|
||||
local assdraw = require 'mp.assdraw'
|
||||
local options = require 'mp.options'
|
||||
local utils = require 'mp.utils'
|
||||
|
||||
options.read_options(opts, nil, function(c)
|
||||
end)
|
||||
|
||||
local enabled = false
|
||||
local active_bars = {}
|
||||
local bar_being_dragged = nil
|
||||
local stale = false
|
||||
|
||||
function split_comma(input)
|
||||
local ret = {}
|
||||
for str in string.gmatch(input, "([^,]+)") do
|
||||
ret[#ret + 1] = str
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
function get_position_normalized(x, y, bar)
|
||||
return (x - bar.x) / bar.w, (y - bar.y) / bar.h
|
||||
end
|
||||
|
||||
function handle_mouse_move()
|
||||
if not bar_being_dragged then return end
|
||||
local bar = bar_being_dragged
|
||||
local mx, my = mp.get_mouse_pos()
|
||||
local nx, _ = get_position_normalized(mx, my, bar)
|
||||
nx = math.max(0, math.min(nx, 1))
|
||||
local val = math.floor(nx * (bar.max_value - bar.min_value) + bar.min_value + 0.5)
|
||||
mp.set_property_number(bar.property, val)
|
||||
-- the observe_property call will take care of setting the value
|
||||
end
|
||||
|
||||
function handle_mouse_left(table)
|
||||
if table["event"] == "down" then
|
||||
local mx, my = mp.get_mouse_pos()
|
||||
for _, bar in ipairs(active_bars) do
|
||||
local nx, ny = get_position_normalized(mx, my, bar)
|
||||
if nx >= 0 and ny >= 0 and nx <= 1 and ny <= 1 then
|
||||
bar_being_dragged = bar
|
||||
local val = math.floor(nx * (bar.max_value - bar.min_value) + bar.min_value + 0.5)
|
||||
mp.set_property_number(bar.property, val)
|
||||
mp.add_forced_key_binding("mouse_move", "mouse_move", handle_mouse_move)
|
||||
break
|
||||
end
|
||||
end
|
||||
elseif table["event"] == "up" then
|
||||
mp.remove_key_binding("mouse_move")
|
||||
bar_being_dragged = nil
|
||||
end
|
||||
end
|
||||
|
||||
function property_changed(prop, val)
|
||||
for _, bar in ipairs(active_bars) do
|
||||
if bar.property == prop then
|
||||
bar.value = val
|
||||
stale = true
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function idle_handler()
|
||||
if not stale then return end
|
||||
stale = false
|
||||
local a = assdraw.ass_new()
|
||||
a:new_event()
|
||||
a:append(string.format('{\\an0\\bord2\\shad0\\1a&00&\\1c&%s&}', '888888'))
|
||||
a:pos(0, 0)
|
||||
a:draw_start()
|
||||
for _, bar in ipairs(active_bars) do
|
||||
a:rect_cw(bar.x, bar.y, bar.x + bar.w, bar.y + bar.h)
|
||||
end
|
||||
a:new_event()
|
||||
a:append(string.format('{\\an0\\bord2\\shad0\\1a&00&\\1c&%s&}', 'dddddd'))
|
||||
a:pos(0, 0)
|
||||
a:draw_start()
|
||||
for _, bar in ipairs(active_bars) do
|
||||
if bar.value > bar.min_value then
|
||||
local val_norm = (bar.value - bar.min_value) / (bar.max_value - bar.min_value)
|
||||
a:rect_cw(bar.x, bar.y, bar.x + val_norm * bar.w, bar.y + bar.h)
|
||||
end
|
||||
end
|
||||
for _, bar in ipairs(active_bars) do
|
||||
a:new_event()
|
||||
a:append("{\\an6\\fs40\\bord2}")
|
||||
a:pos(bar.x - 8, bar.y + bar.h/2 - 2)
|
||||
a:append(bar.property:sub(1,1):upper() .. bar.property:sub(2,-1))
|
||||
end
|
||||
local ww, wh = mp.get_osd_size()
|
||||
mp.set_osd_ass(ww, wh, a.text)
|
||||
end
|
||||
|
||||
function fix_position()
|
||||
local ww, wh = mp.get_osd_size()
|
||||
for i, bar in ipairs(active_bars) do
|
||||
bar.x = ww / 5
|
||||
bar.y = wh / 2 + i * 50
|
||||
bar.w = ww - 2 * (ww / 5)
|
||||
bar.h = 30
|
||||
end
|
||||
end
|
||||
|
||||
function dimensions_changed()
|
||||
stale = true
|
||||
fix_position()
|
||||
end
|
||||
|
||||
function enable()
|
||||
if enabled then return end
|
||||
enabled = true
|
||||
mp.add_forced_key_binding("MBTN_LEFT", "mouse_left", handle_mouse_left, {complex=true})
|
||||
for i, prop in ipairs(split_comma(opts.bars)) do
|
||||
local prop_info = mp.get_property_native("option-info/" .. prop)
|
||||
if not prop_info then
|
||||
msg.warn("Property \'" .. prop .. "\' does not exist")
|
||||
elseif not prop_info.type == 'Integer' then
|
||||
msg.warn("Property \'" .. prop .. "\' is not an integer")
|
||||
else
|
||||
mp.observe_property(prop, 'native', property_changed)
|
||||
active_bars[#active_bars + 1] = {
|
||||
property = prop,
|
||||
value = mp.get_property_number(prop),
|
||||
min_value = prop_info.min,
|
||||
max_value = prop_info.max,
|
||||
}
|
||||
end
|
||||
end
|
||||
stale = true
|
||||
fix_position()
|
||||
mp.observe_property("osd-dimensions", "native", dimensions_changed)
|
||||
mp.register_idle(idle_handler)
|
||||
end
|
||||
|
||||
function disable()
|
||||
if not enabled then return end
|
||||
enabled = false
|
||||
active_bars = {}
|
||||
bar_being_dragged = nil
|
||||
mp.remove_key_binding("mouse_left")
|
||||
mp.remove_key_binding("mouse_move")
|
||||
mp.unobserve_property(property_changed)
|
||||
mp.unobserve_property(dimensions_changed)
|
||||
mp.unregister_idle(idle_handler)
|
||||
mp.set_osd_ass(1280, 720, "")
|
||||
end
|
||||
|
||||
function toggle()
|
||||
if enabled then
|
||||
disable()
|
||||
else
|
||||
enable()
|
||||
end
|
||||
end
|
||||
|
||||
function reset()
|
||||
for _, prop in ipairs(split_comma(opts.bars)) do
|
||||
local prop_info = mp.get_property_native("option-info/" .. prop)
|
||||
if prop_info and prop_info["default-value"] then
|
||||
mp.set_property(prop_info["name"], prop_info["default-value"])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
mp.add_key_binding(nil, "equalizer-enable", enable)
|
||||
mp.add_key_binding(nil, "equalizer-disable", disable)
|
||||
mp.add_key_binding(nil, "equalizer-toggle", toggle)
|
||||
mp.add_key_binding(nil, "equalizer-reset", reset)
|
||||
14
.config/mvi/scripts/freeze-window.lua
Normal file
14
.config/mvi/scripts/freeze-window.lua
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
-- credit to TheAMM
|
||||
|
||||
local size_changed = false
|
||||
|
||||
mp.register_idle(function()
|
||||
if not size_changed then return end
|
||||
local ww, wh = mp.get_osd_size()
|
||||
if not ww or ww <= 0 or not wh or wh <= 0 then return end
|
||||
mp.set_property("geometry", string.format("%dx%d", ww, wh))
|
||||
size_changed = false
|
||||
end)
|
||||
|
||||
mp.observe_property("osd-width", "native", function() size_changed = true end)
|
||||
mp.observe_property("osd-height", "native", function() size_changed = true end)
|
||||
277
.config/mvi/scripts/image-positioning.lua
Normal file
277
.config/mvi/scripts/image-positioning.lua
Normal file
|
|
@ -0,0 +1,277 @@
|
|||
local opts = {
|
||||
drag_to_pan_margin = 50,
|
||||
drag_to_pan_move_if_full_view=false,
|
||||
|
||||
pan_follows_cursor_margin = 50,
|
||||
|
||||
cursor_centric_zoom_margin = 50,
|
||||
cursor_centric_zoom_auto_center = true,
|
||||
cursor_centric_zoom_dezoom_if_full_view = false,
|
||||
}
|
||||
local options = require 'mp.options'
|
||||
local msg = require 'mp.msg'
|
||||
local assdraw = require 'mp.assdraw'
|
||||
|
||||
options.read_options(opts, nil, function() end)
|
||||
|
||||
function clamp(value, low, high)
|
||||
if value <= low then
|
||||
return low
|
||||
elseif value >= high then
|
||||
return high
|
||||
else
|
||||
return value
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local cleanup = nil -- function set up by drag-to-pan/pan-follows cursor and must be called to clean lingering state
|
||||
|
||||
function drag_to_pan_handler(table)
|
||||
if cleanup then
|
||||
cleanup()
|
||||
cleanup = nil
|
||||
end
|
||||
if table["event"] == "down" then
|
||||
local dim = mp.get_property_native("osd-dimensions")
|
||||
if not dim then return end
|
||||
local mouse_pos_origin, video_pan_origin = {}, {}
|
||||
local moved = false
|
||||
mouse_pos_origin[1], mouse_pos_origin[2] = mp.get_mouse_pos()
|
||||
video_pan_origin[1] = mp.get_property_number("video-pan-x")
|
||||
video_pan_origin[2] = mp.get_property_number("video-pan-y")
|
||||
local video_size = { dim.w - dim.ml - dim.mr, dim.h - dim.mt - dim.mb }
|
||||
local margin = opts.drag_to_pan_margin
|
||||
local move_up = true
|
||||
local move_lateral = true
|
||||
if not opts.drag_to_pan_move_if_full_view then
|
||||
if dim.ml >= 0 and dim.mr >= 0 then
|
||||
move_lateral = false
|
||||
end
|
||||
if dim.mt >= 0 and dim.mb >= 0 then
|
||||
move_up = false
|
||||
end
|
||||
end
|
||||
if not move_up and not move_lateral then return end
|
||||
local idle = function()
|
||||
if moved then
|
||||
local mX, mY = mp.get_mouse_pos()
|
||||
local pX = video_pan_origin[1]
|
||||
local pY = video_pan_origin[2]
|
||||
if move_lateral then
|
||||
pX = video_pan_origin[1] + (mX - mouse_pos_origin[1]) / video_size[1]
|
||||
if 2 * margin > dim.ml + dim.mr then
|
||||
pX = clamp(pX,
|
||||
(-margin + dim.w / 2) / video_size[1] - 0.5,
|
||||
(margin - dim.w / 2) / video_size[1] + 0.5)
|
||||
else
|
||||
pX = clamp(pX,
|
||||
(margin - dim.w / 2) / video_size[1] + 0.5,
|
||||
(-margin + dim.w / 2) / video_size[1] - 0.5)
|
||||
end
|
||||
end
|
||||
if move_up then
|
||||
pY = video_pan_origin[2] + (mY - mouse_pos_origin[2]) / video_size[2]
|
||||
if 2 * margin > dim.mt + dim.mb then
|
||||
pY = clamp(pY,
|
||||
(-margin + dim.h / 2) / video_size[2] - 0.5,
|
||||
(margin - dim.h / 2) / video_size[2] + 0.5)
|
||||
else
|
||||
pY = clamp(pY,
|
||||
(margin - dim.h / 2) / video_size[2] + 0.5,
|
||||
(-margin + dim.h / 2) / video_size[2] - 0.5)
|
||||
end
|
||||
end
|
||||
mp.command("no-osd set video-pan-x " .. clamp(pX, -3, 3) .. "; no-osd set video-pan-y " .. clamp(pY, -3, 3))
|
||||
moved = false
|
||||
end
|
||||
end
|
||||
mp.register_idle(idle)
|
||||
mp.add_forced_key_binding("mouse_move", "image-viewer-mouse-move", function() moved = true end)
|
||||
cleanup = function()
|
||||
mp.remove_key_binding("image-viewer-mouse-move")
|
||||
mp.unregister_idle(idle)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function pan_follows_cursor_handler(table)
|
||||
if cleanup then
|
||||
cleanup()
|
||||
cleanup = nil
|
||||
end
|
||||
if table["event"] == "down" then
|
||||
local dim = mp.get_property_native("osd-dimensions")
|
||||
if not dim then return end
|
||||
local video_size = { dim.w - dim.ml - dim.mr, dim.h - dim.mt - dim.mb }
|
||||
local moved = true
|
||||
local idle = function()
|
||||
if moved then
|
||||
local mX, mY = mp.get_mouse_pos()
|
||||
local x = math.min(1, math.max(- 2 * mX / dim.w + 1, -1))
|
||||
local y = math.min(1, math.max(- 2 * mY / dim.h + 1, -1))
|
||||
local command = ""
|
||||
local margin = opts.pan_follows_cursor_margin
|
||||
if dim.ml + dim.mr < 0 then
|
||||
command = command .. "no-osd set video-pan-x " .. clamp(x * (2 * margin - dim.ml - dim.mr) / (2 * video_size[1]), -3, 3) .. ";"
|
||||
elseif mp.get_property_number("video-pan-x") ~= 0 then
|
||||
command = command .. "no-osd set video-pan-x " .. "0;"
|
||||
end
|
||||
if dim.mt + dim.mb < 0 then
|
||||
command = command .. "no-osd set video-pan-y " .. clamp(y * (2 * margin - dim.mt - dim.mb) / (2 * video_size[2]), -3, 3) .. ";"
|
||||
elseif mp.get_property_number("video-pan-y") ~= 0 then
|
||||
command = command .. "no-osd set video-pan-y " .. "0;"
|
||||
end
|
||||
if command ~= "" then
|
||||
mp.command(command)
|
||||
end
|
||||
moved = false
|
||||
end
|
||||
end
|
||||
mp.register_idle(idle)
|
||||
mp.add_forced_key_binding("mouse_move", "image-viewer-mouse-move", function() moved = true end)
|
||||
cleanup = function()
|
||||
mp.remove_key_binding("image-viewer-mouse-move")
|
||||
mp.unregister_idle(idle)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function cursor_centric_zoom_handler(amt)
|
||||
local zoom_inc = tonumber(amt)
|
||||
if not zoom_inc or zoom_inc == 0 then return end
|
||||
local dim = mp.get_property_native("osd-dimensions")
|
||||
if not dim then return end
|
||||
|
||||
local margin = opts.cursor_centric_zoom_margin
|
||||
|
||||
local video_size = { dim.w - dim.ml - dim.mr, dim.h - dim.mt - dim.mb }
|
||||
|
||||
-- the size in pixels of the (in|de)crement
|
||||
local diff_width = (2 ^ zoom_inc - 1) * video_size[1]
|
||||
local diff_height = (2 ^ zoom_inc - 1) * video_size[2]
|
||||
if not opts.cursor_centric_zoom_dezoom_if_full_view and
|
||||
zoom_inc < 0 and
|
||||
video_size[1] + diff_width + 2 * margin <= dim.w and
|
||||
video_size[2] + diff_height + 2 * margin <= dim.h
|
||||
then
|
||||
-- the zoom decrement is too much, reduce it such that the full image is visible, no more, no less
|
||||
-- in addition, this should take care of trying too zoom out while everything is already visible
|
||||
local new_zoom_inc_x = math.log((dim.w - 2 * margin) / video_size[1]) / math.log(2)
|
||||
local new_zoom_inc_y = math.log((dim.h - 2 * margin) / video_size[2]) / math.log(2)
|
||||
local new_zoom_inc = math.min(0, math.min(new_zoom_inc_x, new_zoom_inc_y))
|
||||
zoom_inc = new_zoom_inc
|
||||
diff_width = (2 ^ zoom_inc - 1) * video_size[1]
|
||||
diff_height = (2 ^ zoom_inc - 1) * video_size[2]
|
||||
end
|
||||
local new_width = video_size[1] + diff_width
|
||||
local new_height = video_size[2] + diff_height
|
||||
|
||||
local mouse_pos_origin = {}
|
||||
mouse_pos_origin[1], mouse_pos_origin[2] = mp.get_mouse_pos()
|
||||
local new_pan_x, new_pan_y
|
||||
|
||||
-- some additional constraints:
|
||||
-- if image can be fully visible (in either direction), set pan to 0
|
||||
-- if border would show on either side, then prefer adjusting the pan even if not cursor-centric
|
||||
local auto_c = opts.cursor_centric_zoom_auto_center
|
||||
if auto_c and new_width <= dim.w then
|
||||
new_pan_x = 0
|
||||
else
|
||||
local pan_x = mp.get_property("video-pan-x")
|
||||
local rx = (dim.ml + video_size[1] / 2 - mouse_pos_origin[1]) / (video_size[1] / 2)
|
||||
new_pan_x = (pan_x * video_size[1] + rx * diff_width / 2) / new_width
|
||||
if auto_c then
|
||||
new_pan_x = clamp(new_pan_x, (dim.w - 2 * margin) / (2 * new_width) - 0.5, - (dim.w - 2 * margin) / (2 * new_width) + 0.5)
|
||||
end
|
||||
end
|
||||
|
||||
if auto_c and new_height <= dim.h then
|
||||
new_pan_y = 0
|
||||
else
|
||||
local pan_y = mp.get_property("video-pan-y")
|
||||
local ry = (dim.mt + video_size[2] / 2 - mouse_pos_origin[2]) / (video_size[2] / 2)
|
||||
new_pan_y = (pan_y * video_size[2] + ry * diff_height / 2) / new_height
|
||||
if auto_c then
|
||||
new_pan_y = clamp(new_pan_y, (dim.h - 2 * margin) / (2 * new_height) - 0.5, - (dim.h - 2 * margin) / (2 * new_height) + 0.5)
|
||||
end
|
||||
end
|
||||
|
||||
local zoom_origin = mp.get_property("video-zoom")
|
||||
mp.command("no-osd set video-zoom " .. zoom_origin + zoom_inc .. "; no-osd set video-pan-x " .. clamp(new_pan_x, -3, 3) .. "; no-osd set video-pan-y " .. clamp(new_pan_y, -3, 3))
|
||||
end
|
||||
|
||||
function align_border(x, y)
|
||||
local dim = mp.get_property_native("osd-dimensions")
|
||||
if not dim then return end
|
||||
local video_size = { dim.w - dim.ml - dim.mr, dim.h - dim.mt - dim.mb }
|
||||
local x, y = tonumber(x), tonumber(y)
|
||||
local command = ""
|
||||
if x then
|
||||
command = command .. "no-osd set video-pan-x " .. clamp(- x * (dim.ml + dim.mr) / (2 * video_size[1]), -3, 3) .. ";"
|
||||
end
|
||||
if y then
|
||||
command = command .. "no-osd set video-pan-y " .. clamp(- y * (dim.mt + dim.mb) / (2 * video_size[2]), -3, 3) .. ";"
|
||||
end
|
||||
if command ~= "" then
|
||||
mp.command(command)
|
||||
end
|
||||
end
|
||||
|
||||
function pan_image(axis, amount, zoom_invariant, image_constrained)
|
||||
amount = tonumber(amount)
|
||||
if not amount or amount == 0 or axis ~= "x" and axis ~= "y" then return end
|
||||
if zoom_invariant == "yes" then
|
||||
amount = amount / 2 ^ mp.get_property_number("video-zoom")
|
||||
end
|
||||
local prop = "video-pan-" .. axis
|
||||
local old_pan = mp.get_property_number(prop)
|
||||
if image_constrained == "yes" then
|
||||
local dim = mp.get_property_native("osd-dimensions")
|
||||
if not dim then return end
|
||||
local margin =
|
||||
(axis == "x" and amount > 0) and dim.ml
|
||||
or (axis == "x" and amount < 0) and dim.mr
|
||||
or (amount > 0) and dim.mt
|
||||
or (amount < 0) and dim.mb
|
||||
local vid_size = (axis == "x") and (dim.w - dim.ml - dim.mr) or (dim.h - dim.mt - dim.mb)
|
||||
local pixels_moved = math.abs(amount) * vid_size
|
||||
-- the margin is already visible, no point going further
|
||||
if margin >= 0 then
|
||||
return
|
||||
elseif margin + pixels_moved > 0 then
|
||||
amount = -(math.abs(amount) / amount) * margin / vid_size
|
||||
end
|
||||
end
|
||||
mp.set_property_number(prop, old_pan + amount)
|
||||
end
|
||||
|
||||
function rotate_video(amt)
|
||||
local rot = mp.get_property_number("video-rotate")
|
||||
rot = (rot + amt) % 360
|
||||
mp.set_property_number("video-rotate", rot)
|
||||
end
|
||||
|
||||
function reset_pan_if_visible()
|
||||
local dim = mp.get_property_native("osd-dimensions")
|
||||
if not dim then return end
|
||||
local command = ""
|
||||
if (dim.ml + dim.mr >= 0) then
|
||||
command = command .. "no-osd set video-pan-x 0" .. ";"
|
||||
end
|
||||
if (dim.mt + dim.mb >= 0) then
|
||||
command = command .. "no-osd set video-pan-y 0" .. ";"
|
||||
end
|
||||
if command ~= "" then
|
||||
mp.command(command)
|
||||
end
|
||||
end
|
||||
|
||||
mp.add_key_binding(nil, "drag-to-pan", drag_to_pan_handler, {complex = true})
|
||||
mp.add_key_binding(nil, "pan-follows-cursor", pan_follows_cursor_handler, {complex = true})
|
||||
mp.add_key_binding(nil, "cursor-centric-zoom", cursor_centric_zoom_handler)
|
||||
mp.add_key_binding(nil, "align-border", align_border)
|
||||
mp.add_key_binding(nil, "pan-image", pan_image)
|
||||
mp.add_key_binding(nil, "rotate-video", rotate_video)
|
||||
mp.add_key_binding(nil, "reset-pan-if-visible", reset_pan_if_visible)
|
||||
mp.add_key_binding(nil, "force-print-filename", force_print_filename)
|
||||
201
.config/mvi/scripts/minimap.lua
Normal file
201
.config/mvi/scripts/minimap.lua
Normal file
|
|
@ -0,0 +1,201 @@
|
|||
local opts = {
|
||||
enabled = true,
|
||||
center = "92,92",
|
||||
scale = 12,
|
||||
max_size = "16,16",
|
||||
image_opacity = "88",
|
||||
image_color = "BBBBBB",
|
||||
view_opacity = "BB",
|
||||
view_color = "222222",
|
||||
view_above_image = true,
|
||||
hide_when_full_image_in_view = true,
|
||||
}
|
||||
|
||||
local msg = require 'mp.msg'
|
||||
local assdraw = require 'mp.assdraw'
|
||||
local options = require 'mp.options'
|
||||
|
||||
options.read_options(opts, nil, function(c)
|
||||
if c["enabled"] then
|
||||
if opts.enabled then
|
||||
enable()
|
||||
else
|
||||
disable()
|
||||
end
|
||||
end
|
||||
mark_stale()
|
||||
end)
|
||||
|
||||
function split_comma(input)
|
||||
local ret = {}
|
||||
for str in string.gmatch(input, "([^,]+)") do
|
||||
ret[#ret + 1] = tonumber(str)
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
local active = false
|
||||
local refresh = true
|
||||
|
||||
function draw_ass(ass)
|
||||
local ww, wh = mp.get_osd_size()
|
||||
mp.set_osd_ass(ww, wh, ass)
|
||||
end
|
||||
|
||||
function mark_stale()
|
||||
refresh = true
|
||||
end
|
||||
|
||||
function refresh_minimap()
|
||||
if not refresh then return end
|
||||
refresh = false
|
||||
|
||||
local dim = mp.get_property_native("osd-dimensions")
|
||||
if not dim then
|
||||
draw_ass("")
|
||||
return
|
||||
end
|
||||
local ww, wh = dim.w, dim.h
|
||||
|
||||
if not (ww > 0 and wh > 0) then return end
|
||||
if opts.hide_when_full_image_in_view then
|
||||
if dim.mt >= 0 and dim.mb >= 0 and dim.ml >= 0 and dim.mr >= 0 then
|
||||
draw_ass("")
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local center = split_comma(opts.center)
|
||||
center[1] = center[1] * 0.01 * ww
|
||||
center[2] = center[2] * 0.01 * wh
|
||||
local cutoff = split_comma(opts.max_size)
|
||||
cutoff[1] = cutoff[1] * 0.01 * ww * 0.5
|
||||
cutoff[2] = cutoff[2] * 0.01 * wh * 0.5
|
||||
|
||||
local a = assdraw.ass_new()
|
||||
local draw = function(x, y, w, h, opacity, color)
|
||||
a:new_event()
|
||||
a:pos(center[1], center[2])
|
||||
a:append("{\\bord0}")
|
||||
a:append("{\\shad0}")
|
||||
a:append("{\\c&" .. color .. "&}")
|
||||
a:append("{\\2a&HFF}")
|
||||
a:append("{\\3a&HFF}")
|
||||
a:append("{\\4a&HFF}")
|
||||
a:append("{\\1a&H" .. opacity .. "}")
|
||||
w = w * 0.5
|
||||
h = h * 0.5
|
||||
a:draw_start()
|
||||
local rounded = {true,true,true,true} -- tl, tr, br, bl
|
||||
local x0,y0,x1,y1 = x-w, y-h, x+w, y+h
|
||||
if x0 < -cutoff[1] then
|
||||
x0 = -cutoff[1]
|
||||
rounded[4] = false
|
||||
rounded[1] = false
|
||||
end
|
||||
if y0 < -cutoff[2] then
|
||||
y0 = -cutoff[2]
|
||||
rounded[1] = false
|
||||
rounded[2] = false
|
||||
end
|
||||
if x1 > cutoff[1] then
|
||||
x1 = cutoff[1]
|
||||
rounded[2] = false
|
||||
rounded[3] = false
|
||||
end
|
||||
if y1 > cutoff[2] then
|
||||
y1 = cutoff[2]
|
||||
rounded[3] = false
|
||||
rounded[4] = false
|
||||
end
|
||||
|
||||
local r = 3
|
||||
local c = 0.551915024494 * r
|
||||
if rounded[0] then
|
||||
a:move_to(x0 + r, y0)
|
||||
else
|
||||
a:move_to(x0,y0)
|
||||
end
|
||||
if rounded[1] then
|
||||
a:line_to(x1 - r, y0)
|
||||
a:bezier_curve(x1 - r + c, y0, x1, y0 + r - c, x1, y0 + r)
|
||||
else
|
||||
a:line_to(x1, y0)
|
||||
end
|
||||
if rounded[2] then
|
||||
a:line_to(x1, y1 - r)
|
||||
a:bezier_curve(x1, y1 - r + c, x1 - r + c, y1, x1 - r, y1)
|
||||
else
|
||||
a:line_to(x1, y1)
|
||||
end
|
||||
if rounded[3] then
|
||||
a:line_to(x0 + r, y1)
|
||||
a:bezier_curve(x0 + r - c, y1, x0, y1 - r + c, x0, y1 - r)
|
||||
else
|
||||
a:line_to(x0, y1)
|
||||
end
|
||||
if rounded[4] then
|
||||
a:line_to(x0, y0 + r)
|
||||
a:bezier_curve(x0, y0 + r - c, x0 + r - c, y0, x0 + r, y0)
|
||||
else
|
||||
a:line_to(x0, y0)
|
||||
end
|
||||
a:draw_stop()
|
||||
end
|
||||
local image = function()
|
||||
draw((dim.ml/2 - dim.mr/2) / opts.scale,
|
||||
(dim.mt/2 - dim.mb/2) / opts.scale,
|
||||
(ww - dim.ml - dim.mr) / opts.scale,
|
||||
(wh - dim.mt - dim.mb) / opts.scale,
|
||||
opts.image_opacity,
|
||||
opts.image_color)
|
||||
end
|
||||
local view = function()
|
||||
draw(0,
|
||||
0,
|
||||
ww / opts.scale,
|
||||
wh / opts.scale,
|
||||
opts.view_opacity,
|
||||
opts.view_color)
|
||||
end
|
||||
if opts.view_above_image then
|
||||
image()
|
||||
view()
|
||||
else
|
||||
view()
|
||||
image()
|
||||
end
|
||||
draw_ass(a.text)
|
||||
end
|
||||
|
||||
function enable()
|
||||
if active then return end
|
||||
active = true
|
||||
mp.observe_property("osd-dimensions", nil, mark_stale)
|
||||
mp.register_idle(refresh_minimap)
|
||||
mark_stale()
|
||||
end
|
||||
|
||||
function disable()
|
||||
if not active then return end
|
||||
active = false
|
||||
mp.unobserve_property(mark_stale)
|
||||
mp.unregister_idle(refresh_minimap)
|
||||
draw_ass("")
|
||||
end
|
||||
|
||||
function toggle()
|
||||
if active then
|
||||
disable()
|
||||
else
|
||||
enable()
|
||||
end
|
||||
end
|
||||
|
||||
if opts.enabled then
|
||||
enable()
|
||||
end
|
||||
|
||||
mp.add_key_binding(nil, "minimap-enable", enable)
|
||||
mp.add_key_binding(nil, "minimap-disable", disable)
|
||||
mp.add_key_binding(nil, "minimap-toggle", toggle)
|
||||
314
.config/mvi/scripts/ruler.lua
Normal file
314
.config/mvi/scripts/ruler.lua
Normal file
|
|
@ -0,0 +1,314 @@
|
|||
local opts = {
|
||||
show_distance = true,
|
||||
show_coordinates = true,
|
||||
coordinates_space = "image",
|
||||
show_angles = "degrees",
|
||||
line_width = 2,
|
||||
dots_radius = 3,
|
||||
font_size = 36,
|
||||
line_color = "33",
|
||||
confirm_bindings = "MBTN_LEFT,ENTER",
|
||||
exit_bindings = "ESC",
|
||||
set_first_point_on_begin = false,
|
||||
clear_on_second_point_set = false,
|
||||
}
|
||||
|
||||
local options = require 'mp.options'
|
||||
local msg = require 'mp.msg'
|
||||
local assdraw = require 'mp.assdraw'
|
||||
|
||||
local state = 0 -- {0,1,2,3} = {inactive,setting first point,setting second point,done}
|
||||
local first_point = nil -- in normalized video space coordinates
|
||||
local second_point = nil -- in normalized video space coordinates
|
||||
local video_dimensions_stale = false
|
||||
|
||||
function split(input)
|
||||
local ret = {}
|
||||
for str in string.gmatch(input, "([^,]+)") do
|
||||
ret[#ret + 1] = str
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
local confirm_bindings = split(opts.confirm_bindings)
|
||||
local exit_bindings = split(opts.exit_bindings)
|
||||
|
||||
options.read_options(opts, nil, function()
|
||||
if state ~= 0 then
|
||||
remove_bindings()
|
||||
end
|
||||
confirm_bindings = split(opts.confirm_bindings)
|
||||
exit_bindings = split(opts.exit_bindings)
|
||||
if state ~= 0 then
|
||||
add_bindings()
|
||||
mark_stale()
|
||||
end
|
||||
end)
|
||||
|
||||
function draw_ass(ass)
|
||||
local ww, wh = mp.get_osd_size()
|
||||
mp.set_osd_ass(ww, wh, ass)
|
||||
end
|
||||
|
||||
|
||||
function cursor_video_space_normalized(dim)
|
||||
local mx, my = mp.get_mouse_pos()
|
||||
local ret = {}
|
||||
ret[1] = (mx - dim.ml) / (dim.w - dim.ml - dim.mr)
|
||||
ret[2] = (my - dim.mt) / (dim.h - dim.mt - dim.mb)
|
||||
return ret
|
||||
end
|
||||
|
||||
function refresh()
|
||||
if not video_dimensions_stale then return end
|
||||
video_dimensions_stale = false
|
||||
|
||||
local dim = mp.get_property_native("osd-dimensions")
|
||||
local out_params = mp.get_property_native("video-out-params")
|
||||
if not dim or not out_params then
|
||||
draw_ass("")
|
||||
return
|
||||
end
|
||||
local vid_width = out_params.dw
|
||||
local vid_height = out_params.dh
|
||||
|
||||
function video_space_normalized_to_video(point)
|
||||
local ret = {}
|
||||
ret[1] = point[1] * vid_width
|
||||
ret[2] = point[2] * vid_height
|
||||
return ret
|
||||
end
|
||||
function video_space_normalized_to_screen(point)
|
||||
local ret = {}
|
||||
ret[1] = point[1] * (dim.w - dim.ml - dim.mr) + dim.ml
|
||||
ret[2] = point[2] * (dim.h - dim.mt - dim.mb) + dim.mt
|
||||
return ret
|
||||
end
|
||||
|
||||
local line_start = {}
|
||||
local line_end = {}
|
||||
if second_point then
|
||||
line_start.image = video_space_normalized_to_video(first_point)
|
||||
line_start.screen = video_space_normalized_to_screen(first_point)
|
||||
line_end.image = video_space_normalized_to_video(second_point)
|
||||
line_end.screen = video_space_normalized_to_screen(second_point)
|
||||
elseif first_point then
|
||||
line_start.image = video_space_normalized_to_video(first_point)
|
||||
line_start.screen = video_space_normalized_to_screen(first_point)
|
||||
line_end.image = video_space_normalized_to_video(cursor_video_space_normalized(dim))
|
||||
line_end.screen = {}
|
||||
line_end.screen[1], line_end.screen[2] = mp.get_mouse_pos()
|
||||
else
|
||||
local mx, my = mp.get_mouse_pos()
|
||||
line_start.image = video_space_normalized_to_video(cursor_video_space_normalized(dim))
|
||||
line_start.screen = {}
|
||||
line_start.screen[1], line_start.screen[2] = mp.get_mouse_pos()
|
||||
line_end = line_start
|
||||
end
|
||||
local distinct = (math.abs(line_start.screen[1] - line_end.screen[1]) >= 1
|
||||
or math.abs(line_start.screen[2] - line_end.screen[2]) >= 1)
|
||||
|
||||
local a = assdraw:ass_new()
|
||||
local draw_setup = function(bord)
|
||||
a:new_event()
|
||||
a:pos(0,0)
|
||||
a:append("{\\bord" .. bord .. "}")
|
||||
a:append("{\\shad0}")
|
||||
local r = opts.line_color
|
||||
a:append("{\\3c&H".. r .. r .. r .. "&}")
|
||||
a:append("{\\1a&HFF}")
|
||||
a:append("{\\2a&HFF}")
|
||||
a:append("{\\3a&H00}")
|
||||
a:append("{\\4a&HFF}")
|
||||
a:draw_start()
|
||||
end
|
||||
local dot = function(pos, size)
|
||||
draw_setup(size)
|
||||
a:move_to(pos[1], pos[2]-0.5)
|
||||
a:line_to(pos[1], pos[2]+0.5)
|
||||
end
|
||||
local line = function(from, to, size)
|
||||
draw_setup(size)
|
||||
a:move_to(from[1], from[2])
|
||||
a:line_to(to[1], to[2])
|
||||
end
|
||||
if distinct then
|
||||
dot(line_start.screen, opts.dots_radius)
|
||||
line(line_start.screen, line_end.screen, opts.line_width)
|
||||
dot(line_end.screen, opts.dots_radius)
|
||||
else
|
||||
dot(line_start.screen, opts.dots_radius)
|
||||
end
|
||||
|
||||
local line_info = function()
|
||||
if not opts.show_distance then return end
|
||||
a:new_event()
|
||||
a:append("{\\fs36}{\\bord1}")
|
||||
a:pos((line_start.screen[1] + line_end.screen[1]) / 2, (line_start.screen[2] + line_end.screen[2]) / 2)
|
||||
local an = 1
|
||||
if line_start.image[1] < line_end.image[1] then an = an + 2 end
|
||||
if line_start.image[2] < line_end.image[2] then an = an + 6 end
|
||||
a:an(an)
|
||||
local image = math.sqrt(math.pow(line_start.image[1] - line_end.image[1], 2) + math.pow(line_start.image[2] - line_end.image[2], 2))
|
||||
local screen = math.sqrt(math.pow(line_start.screen[1] - line_end.screen[1], 2) + math.pow(line_start.screen[2] - line_end.screen[2], 2))
|
||||
if opts.coordinates_space == "both" then
|
||||
a:append(string.format("image: %.1f\\Nscreen: %.1f", image, screen))
|
||||
elseif opts.coordinates_space == "image" then
|
||||
a:append(string.format("%.1f", image))
|
||||
elseif opts.coordinates_space == "window" then
|
||||
a:append(string.format("%.1f", screen))
|
||||
end
|
||||
end
|
||||
local dot_info = function(pos, opposite)
|
||||
if not opts.show_coordinates then return end
|
||||
a:new_event()
|
||||
a:append("{\\fs" .. opts.font_size .."}{\\bord1}")
|
||||
a:pos(pos.screen[1], pos.screen[2])
|
||||
local an
|
||||
if distinct then
|
||||
an = 1
|
||||
if line_start.image[1] > line_end.image[1] then an = an + 2 end
|
||||
if line_start.image[2] < line_end.image[2] then an = an + 6 end
|
||||
else
|
||||
an = 7
|
||||
end
|
||||
if opposite then
|
||||
an = 9 + 1 - an
|
||||
end
|
||||
a:an(an)
|
||||
if opts.coordinates_space == "both" then
|
||||
a:append(string.format("image: %.1f, %.1f\\Nscreen: %i, %i",
|
||||
pos.image[1], pos.image[2], pos.screen[1], pos.screen[2]))
|
||||
elseif opts.coordinates_space == "image" then
|
||||
a:append(string.format("%.1f, %.1f", pos.image[1], pos.image[2]))
|
||||
elseif opts.coordinates_space == "window" then
|
||||
a:append(string.format("%i, %i", pos.screen[1], pos.screen[2]))
|
||||
end
|
||||
end
|
||||
dot_info(line_start, true)
|
||||
if distinct then
|
||||
line_info()
|
||||
dot_info(line_end, false)
|
||||
end
|
||||
if distinct and opts.show_angles ~= "no" then
|
||||
local dist = 50
|
||||
local pos_from_angle = function(mult, angle)
|
||||
return {
|
||||
line_start.screen[1] + mult * dist * math.cos(angle),
|
||||
line_start.screen[2] + mult * dist * math.sin(angle),
|
||||
}
|
||||
end
|
||||
local extended = { line_start.screen[1], line_start.screen[2] }
|
||||
if line_end.screen[1] > line_start.screen[1] then
|
||||
extended[1] = extended[1] + dist
|
||||
else
|
||||
extended[1] = extended[1] - dist
|
||||
end
|
||||
line(line_start.screen, extended, math.max(0, opts.line_width-0.5))
|
||||
local angle = math.atan(math.abs(line_start.image[2] - line_end.image[2]) / math.abs(line_start.image[1] - line_end.image[1]))
|
||||
local fix_angle
|
||||
local an
|
||||
if line_end.image[2] < line_start.image[2] and line_end.image[1] > line_start.image[1] then
|
||||
-- upper-right
|
||||
an = 4
|
||||
fix_angle = function(angle) return - angle end
|
||||
elseif line_end.image[2] < line_start.image[2] then
|
||||
-- upper-left
|
||||
an = 6
|
||||
fix_angle = function(angle) return math.pi + angle end
|
||||
elseif line_end.image[1] < line_start.image[1] then
|
||||
-- bottom-left
|
||||
an = 6
|
||||
fix_angle = function(angle) return math.pi - angle end
|
||||
else
|
||||
-- bottom-right
|
||||
an = 4
|
||||
fix_angle = function(angle) return angle end
|
||||
end
|
||||
-- should implement this https://math.stackexchange.com/questions/873224/calculate-control-points-of-cubic-bezier-curve-approximating-a-part-of-a-circle
|
||||
local cp1 = pos_from_angle(1, fix_angle(angle*1/4))
|
||||
local cp2 = pos_from_angle(1, fix_angle(angle*3/4))
|
||||
local p2 = pos_from_angle(1, fix_angle(angle))
|
||||
a:bezier_curve(cp1[1], cp1[2], cp2[1], cp2[2], p2[1], p2[2])
|
||||
|
||||
a:new_event()
|
||||
a:append("{\\fs" .. opts.font_size .."}{\\bord1}")
|
||||
local text_pos = pos_from_angle(1.1, fix_angle(angle*2/3)) -- you'd think /2 would make more sense, but *2/3 looks better
|
||||
a:pos(text_pos[1], text_pos[2])
|
||||
a:an(an)
|
||||
if opts.show_angles == "both" then
|
||||
a:append(string.format("%.2f\\N%.1f°", angle, angle / math.pi * 180))
|
||||
elseif opts.show_angles == "degrees" then
|
||||
a:append(string.format("%.1f°", angle / math.pi * 180))
|
||||
elseif opts.show_angles == "radians" then
|
||||
a:append(string.format("%.2f", angle))
|
||||
end
|
||||
end
|
||||
|
||||
draw_ass(a.text)
|
||||
end
|
||||
|
||||
function mark_stale()
|
||||
video_dimensions_stale = true
|
||||
end
|
||||
|
||||
function add_bindings()
|
||||
mp.add_forced_key_binding("mouse_move", "ruler-mouse-move", mark_stale)
|
||||
for _, key in ipairs(confirm_bindings) do
|
||||
mp.add_forced_key_binding(key, "ruler-next-" .. key, next_step)
|
||||
end
|
||||
for _, key in ipairs(exit_bindings) do
|
||||
mp.add_forced_key_binding(key, "ruler-stop-" .. key, stop)
|
||||
end
|
||||
end
|
||||
|
||||
function remove_bindings()
|
||||
for _, key in ipairs(confirm_bindings) do
|
||||
mp.remove_key_binding("ruler-next-" .. key)
|
||||
end
|
||||
for _, key in ipairs(exit_bindings) do
|
||||
mp.remove_key_binding("ruler-stop-" .. key)
|
||||
end
|
||||
mp.remove_key_binding("ruler-mouse-move")
|
||||
end
|
||||
|
||||
function next_step()
|
||||
if state == 0 then
|
||||
state = 1
|
||||
mp.register_idle(refresh)
|
||||
mp.observe_property("osd-dimensions", nil, mark_stale)
|
||||
mark_stale()
|
||||
add_bindings()
|
||||
if opts.set_first_point_on_begin then
|
||||
next_step()
|
||||
end
|
||||
elseif state == 1 then
|
||||
local dim = mp.get_property_native("osd-dimensions")
|
||||
if not dim then return end
|
||||
state = 2
|
||||
first_point = cursor_video_space_normalized(dim)
|
||||
elseif state == 2 then
|
||||
local dim = mp.get_property_native("osd-dimensions")
|
||||
if not dim then return end
|
||||
state = 3
|
||||
second_point = cursor_video_space_normalized(dim)
|
||||
if opts.clear_on_second_point_set then
|
||||
next_step()
|
||||
end
|
||||
else
|
||||
stop()
|
||||
end
|
||||
end
|
||||
|
||||
function stop()
|
||||
if state == 0 then return end
|
||||
mp.unregister_idle(refresh)
|
||||
mp.unobserve_property(mark_stale)
|
||||
remove_bindings()
|
||||
state = 0
|
||||
first_point = nil
|
||||
second_point = nil
|
||||
draw_ass("")
|
||||
end
|
||||
|
||||
mp.add_key_binding(nil, "ruler", next_step)
|
||||
142
.config/mvi/scripts/status-line.lua
Normal file
142
.config/mvi/scripts/status-line.lua
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
local opts = {
|
||||
enabled = true,
|
||||
size = 36,
|
||||
margin = 10,
|
||||
text_top_left = "",
|
||||
text_top_right = "",
|
||||
text_bottom_left = "${filename} [${playlist-pos-1}/${playlist-count}]",
|
||||
text_bottom_right = "[${dwidth:X}x${dheight:X}]",
|
||||
}
|
||||
|
||||
local msg = require 'mp.msg'
|
||||
local assdraw = require 'mp.assdraw'
|
||||
local options = require 'mp.options'
|
||||
|
||||
options.read_options(opts, nil, function(c)
|
||||
if c["enabled"] then
|
||||
if opts.enabled then
|
||||
enable()
|
||||
else
|
||||
disable()
|
||||
end
|
||||
end
|
||||
if c["size"] or c["margin"] then
|
||||
mark_stale()
|
||||
end
|
||||
if c["text_top_left"] or
|
||||
c["text_top_right"] or
|
||||
c["text_bottom_left"] or
|
||||
c["text_bottom_right"]
|
||||
then
|
||||
observe_properties()
|
||||
mark_stale()
|
||||
end
|
||||
end)
|
||||
|
||||
local stale = true
|
||||
local active = false
|
||||
|
||||
function draw_ass(ass)
|
||||
local ww, wh = mp.get_osd_size()
|
||||
mp.set_osd_ass(ww, wh, ass)
|
||||
end
|
||||
|
||||
function refresh()
|
||||
if not stale then return end
|
||||
stale = false
|
||||
local a = assdraw:ass_new()
|
||||
local draw_text = function(text, an, x, y)
|
||||
if text == "" then return end
|
||||
local expanded = mp.command_native({ "expand-text", text})
|
||||
if not expanded then
|
||||
msg.error("Error expanding status-line")
|
||||
return
|
||||
end
|
||||
msg.verbose("Status-line changed to: " .. expanded)
|
||||
a:new_event()
|
||||
a:an(an)
|
||||
a:pos(x,y)
|
||||
a:append("{\\fs".. opts.size.. "}{\\bord1.0}")
|
||||
a:append(expanded)
|
||||
end
|
||||
local w,h = mp.get_osd_size()
|
||||
local m = opts.margin
|
||||
draw_text(opts.text_top_left, 7, m, m)
|
||||
draw_text(opts.text_top_right, 9, w-m, m)
|
||||
draw_text(opts.text_bottom_left, 1, m, h-m)
|
||||
draw_text(opts.text_bottom_right, 3, w-m, h-m)
|
||||
draw_ass(a.text)
|
||||
end
|
||||
|
||||
function mark_stale()
|
||||
stale = true
|
||||
end
|
||||
|
||||
function observe_properties()
|
||||
mp.unobserve_property(mark_stale)
|
||||
if not active then return end
|
||||
for _, str in ipairs({
|
||||
opts.text_top_left,
|
||||
opts.text_top_right,
|
||||
opts.text_bottom_left,
|
||||
opts.text_bottom_right,
|
||||
}) do
|
||||
local start = 0
|
||||
while true do
|
||||
local s, e, cap = string.find(str, "%${[?!]?([%l%d-/]*)", start)
|
||||
if not s then break end
|
||||
msg.verbose("Observing property " .. cap)
|
||||
mp.observe_property(cap, nil, mark_stale)
|
||||
start = e
|
||||
end
|
||||
end
|
||||
mp.observe_property("osd-width", nil, mark_stale)
|
||||
mp.observe_property("osd-height", nil, mark_stale)
|
||||
end
|
||||
|
||||
function enable()
|
||||
if active then return end
|
||||
active = true
|
||||
observe_properties()
|
||||
mp.register_idle(refresh)
|
||||
mark_stale()
|
||||
end
|
||||
|
||||
|
||||
function disable()
|
||||
if not active then return end
|
||||
active = false
|
||||
observe_properties()
|
||||
mp.unregister_idle(refresh)
|
||||
draw_ass("")
|
||||
end
|
||||
|
||||
function toggle()
|
||||
if active then
|
||||
disable()
|
||||
else
|
||||
enable()
|
||||
end
|
||||
end
|
||||
|
||||
if opts.enabled then
|
||||
enable()
|
||||
end
|
||||
|
||||
mp.add_key_binding(nil, "status-line-enable", enable)
|
||||
mp.add_key_binding(nil, "status-line-disable", disable)
|
||||
mp.add_key_binding(nil, "status-line-toggle", toggle)
|
||||
|
||||
-- TODO remove
|
||||
mp.add_key_binding(nil, "enable-status-line", function()
|
||||
msg.warn("This binding is deprecated, use 'status-line-enable' instead")
|
||||
enable()
|
||||
end)
|
||||
mp.add_key_binding(nil, "disable-status-line", function()
|
||||
msg.warn("This binding is deprecated, use 'status-line-disable' instead")
|
||||
disable()
|
||||
end)
|
||||
mp.add_key_binding(nil, "toggle-status-line", function()
|
||||
msg.warn("This binding is deprecated, use 'status-line-toggle' instead")
|
||||
toggle()
|
||||
end)
|
||||
Loading…
Add table
Add a link
Reference in a new issue