mirror of
https://github.com/gaitas13/dotfiles.git
synced 2025-12-06 07:15:37 +01:00
changed mpv settings and added ivtc on D key
This commit is contained in:
parent
a1849bbeb4
commit
9b3cc564d2
5 changed files with 844 additions and 37 deletions
|
|
@ -1 +1,2 @@
|
||||||
#d script-message cycle-profiles "bwdifdeint;deinterlace-no"
|
#d script-message cycle-profiles "bwdifdeint;deinterlace-no" #only needed if using hwdec that has its own deinterlacer and is not bwdif
|
||||||
|
D vf toggle "pullup,dejudder"
|
||||||
|
|
|
||||||
421
.config/mpv/scripts/dvd-browser.lua
Normal file
421
.config/mpv/scripts/dvd-browser.lua
Normal file
|
|
@ -0,0 +1,421 @@
|
||||||
|
--[[
|
||||||
|
mpv-dvd-browser
|
||||||
|
|
||||||
|
This script uses the `lsdvd` commandline utility to allow users to view and select titles
|
||||||
|
for DVDs from directly within mpv. The browser is interractive and allows for both playing
|
||||||
|
the selected title, or appending it to the playlist.
|
||||||
|
|
||||||
|
For full documentation see: https://github.com/CogentRedTester/mpv-dvd-browser
|
||||||
|
]]--
|
||||||
|
|
||||||
|
local mp = require 'mp'
|
||||||
|
local msg = require 'mp.msg'
|
||||||
|
local opt = require 'mp.options'
|
||||||
|
local utils = require 'mp.utils'
|
||||||
|
|
||||||
|
local o = {
|
||||||
|
lsdvd = 'lsdvd',
|
||||||
|
|
||||||
|
--path to the dvd device to send to lsdvd, leaving this blank will set the script to
|
||||||
|
--use the --dvd-device option.
|
||||||
|
--It is recommended that this be left blank unless using wsl
|
||||||
|
dvd_device = "",
|
||||||
|
|
||||||
|
--number of titles to display on the screen at once
|
||||||
|
num_entries = 20,
|
||||||
|
|
||||||
|
--by default the player enters an infinite loop, usually of the DVD menu screen, after moving
|
||||||
|
--past the last second of the file. If this option is enabled, then the script will
|
||||||
|
--automatically configure mpv to end playback before entering the loop
|
||||||
|
escape_loop = true,
|
||||||
|
|
||||||
|
--changes default mpv behaviour and loads the first title instead of the longest when
|
||||||
|
--the title isn't specified
|
||||||
|
start_from_first_title = true,
|
||||||
|
|
||||||
|
---------------------
|
||||||
|
--playlist options:
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
--adds the previous and subsequent titles to the playlist when playing a dvd
|
||||||
|
--only does this when there is only one item in the playlist
|
||||||
|
create_playlist = true,
|
||||||
|
|
||||||
|
--when dvd:// (no specified title) is loaded the script will always insert all of the
|
||||||
|
--titles into the playlist, regardless of the playlist length
|
||||||
|
--similar to loading a directory or playlist file
|
||||||
|
treat_root_as_playlist = true,
|
||||||
|
|
||||||
|
------------------------------------------
|
||||||
|
--wsl options for limitted windows support
|
||||||
|
------------------------------------------
|
||||||
|
wsl = false,
|
||||||
|
wsl_password = "",
|
||||||
|
|
||||||
|
--------------
|
||||||
|
--ass options
|
||||||
|
---------------
|
||||||
|
ass_header = "{\\q2\\fs35\\c&00ccff&}",
|
||||||
|
ass_body = "{\\q2\\fs25\\c&Hffffff&}",
|
||||||
|
ass_selected = "{\\c&Hfce788&}",
|
||||||
|
ass_playing = "{\\c&H33ff66&}",
|
||||||
|
ass_footerheader = "{\\c&00ccff&\\fs16}",
|
||||||
|
ass_cursor = "{\\c&00ccff&}",
|
||||||
|
ass_length = "{\\fs20\\c&aaaaaa&}"
|
||||||
|
}
|
||||||
|
|
||||||
|
opt.read_options(o, 'dvd_browser')
|
||||||
|
|
||||||
|
--[[
|
||||||
|
lsdvd returns a JSON object with a number of details about the dvd
|
||||||
|
some notable values are:
|
||||||
|
title = title of the dvd
|
||||||
|
longest_track = longest track on the dvd
|
||||||
|
device = path to the dvd mount point
|
||||||
|
track = array of 'titles'/tracks on the disc
|
||||||
|
length = length of each title
|
||||||
|
ix = numerical id of the title starting from 1
|
||||||
|
chapter = array of chapters in the title
|
||||||
|
num_chapters = length of chapters array (added by me)
|
||||||
|
]]--
|
||||||
|
|
||||||
|
--if the script name includes file_browser, then the script is being loaded
|
||||||
|
--as an addon, and hence we can skip loading several things
|
||||||
|
local STANDALONE = not mp.get_script_name():find("file_browser")
|
||||||
|
|
||||||
|
local list = {}
|
||||||
|
if STANDALONE then
|
||||||
|
package.path = mp.command_native( {"expand-path", "~~/script-modules/?.lua;" } ) .. package.path
|
||||||
|
list = require "scroll-list"
|
||||||
|
|
||||||
|
list.header_style = o.ass_header
|
||||||
|
list.list_style = o.ass_body
|
||||||
|
list.wrapper_style = o.ass_footerheader
|
||||||
|
list.empty_text = "insert DVD"
|
||||||
|
end
|
||||||
|
|
||||||
|
local dvd = {}
|
||||||
|
local state = {
|
||||||
|
playing_disc = false,
|
||||||
|
selected = 1,
|
||||||
|
flag_update = false
|
||||||
|
}
|
||||||
|
|
||||||
|
--automatically match to the current dvd device
|
||||||
|
if (o.dvd_device == "") then
|
||||||
|
mp.observe_property('dvd-device', 'string', function(_, device)
|
||||||
|
if device == "" then device = "/dev/dvd" end
|
||||||
|
o.dvd_device = device
|
||||||
|
|
||||||
|
--we set this to false to force a dvd rescan
|
||||||
|
state.playing_disc = false
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function get_header_str()
|
||||||
|
local title
|
||||||
|
if dvd == nil then title = ""
|
||||||
|
else title = dvd.title end
|
||||||
|
return '📀 dvd://'..title
|
||||||
|
end
|
||||||
|
|
||||||
|
local function get_line_str(v)
|
||||||
|
return "Title "..(v.ix-1)..o.ass_length.." ["..v.length.."] "..v.num_chapters.." chapters"
|
||||||
|
end
|
||||||
|
|
||||||
|
function list:format_header()
|
||||||
|
self.ass.data = o.ass_header..get_header_str().."\\N ---------------------------------------------------- \\N"
|
||||||
|
end
|
||||||
|
|
||||||
|
--simple function to append to the ass string
|
||||||
|
function list:format_line(i, v)
|
||||||
|
self:append(o.ass_body)
|
||||||
|
|
||||||
|
--the below text contains unicode whitespace characters
|
||||||
|
if i == list.selected then self:append(o.ass_cursor..[[➤\h]]..o.ass_selected)
|
||||||
|
else self:append([[\h\h\h\h]]) end
|
||||||
|
|
||||||
|
--prints the currently-playing icon and style
|
||||||
|
if mp.get_property('filename', "0") == tostring(i-1) then
|
||||||
|
self:append(o.ass_playing)
|
||||||
|
end
|
||||||
|
|
||||||
|
self:append(get_line_str(v))
|
||||||
|
self:newline()
|
||||||
|
end
|
||||||
|
|
||||||
|
--sends a call to lsdvd to read the contents of the disc
|
||||||
|
local function read_disc()
|
||||||
|
msg.verbose('reading contents of ' .. o.dvd_device)
|
||||||
|
|
||||||
|
local args
|
||||||
|
if o.wsl then
|
||||||
|
msg.verbose('wsl compatibility mode enabled')
|
||||||
|
|
||||||
|
--if wsl password is not set then we'll assume the user has mounted manually
|
||||||
|
if o.wsl_password ~= "" then
|
||||||
|
local dvd_device = mp.get_property('dvd-device', ''):gsub([[\]], [[/]])
|
||||||
|
msg.verbose('mounting '..dvd_device..' at '..o.dvd_device)
|
||||||
|
|
||||||
|
mp.command_native({
|
||||||
|
name = 'subprocess',
|
||||||
|
playback_only = false,
|
||||||
|
args = {'wsl', 'echo', o.wsl_password, '|', 'sudo', '-S', 'mount', '-t', 'drvfs', dvd_device, o.dvd_device}
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
--setting wsl arguments
|
||||||
|
args = {'wsl', o.lsdvd, o.dvd_device, '-Oy', '-c'}
|
||||||
|
else
|
||||||
|
args = {o.lsdvd, o.dvd_device, '-Oy', '-c'}
|
||||||
|
end
|
||||||
|
|
||||||
|
local cmd = mp.command_native({
|
||||||
|
name = 'subprocess',
|
||||||
|
playback_only = false,
|
||||||
|
capture_stdout = true,
|
||||||
|
capture_stderr = true,
|
||||||
|
args = args
|
||||||
|
})
|
||||||
|
|
||||||
|
--making the python string JSON compatible
|
||||||
|
local result = cmd.stdout:gsub("'", '"')
|
||||||
|
result = result:gsub('lsdvd = ', '')
|
||||||
|
dvd = utils.parse_json(result)
|
||||||
|
|
||||||
|
if (not dvd) then
|
||||||
|
msg.error(cmd.stderr)
|
||||||
|
state.playing_disc = false
|
||||||
|
return
|
||||||
|
end
|
||||||
|
msg.trace(utils.to_string(dvd))
|
||||||
|
|
||||||
|
--creating a fallback for the title
|
||||||
|
-- if dvd.title == "unknown" then dvd.title = "dvd://" end
|
||||||
|
|
||||||
|
--making modifications to all the entries
|
||||||
|
for i = 1, #dvd.track do
|
||||||
|
local v = dvd.track[i]
|
||||||
|
|
||||||
|
--saving the chapter count
|
||||||
|
v.num_chapters = #v.chapter
|
||||||
|
|
||||||
|
--modifying the length
|
||||||
|
local l = v.length
|
||||||
|
local lstr = tostring(l)
|
||||||
|
|
||||||
|
--adding the microseconds as is
|
||||||
|
local index = tostring(l):find([[.[^.]*$]])
|
||||||
|
local str
|
||||||
|
if index == 1 then str = "00"
|
||||||
|
else
|
||||||
|
str = tostring(lstr:sub(index+1))
|
||||||
|
str = string.format('%02d', str)
|
||||||
|
end
|
||||||
|
l = math.floor(l)
|
||||||
|
|
||||||
|
local seconds = l%60
|
||||||
|
str = string.format('%02d', seconds) .. '.' .. str
|
||||||
|
l = (l - seconds)/60
|
||||||
|
|
||||||
|
local mins = l%60
|
||||||
|
str = string.format('%02d', mins) .. ':' .. str
|
||||||
|
l = (l-mins)/60
|
||||||
|
|
||||||
|
local hours = l%24
|
||||||
|
str = string.format('%02d', hours) .. ':' .. str
|
||||||
|
|
||||||
|
msg.debug('changing length string for title '..(i-1)..' to '..str)
|
||||||
|
v.length = str
|
||||||
|
end
|
||||||
|
|
||||||
|
state.playing_disc = true
|
||||||
|
list.list = dvd.track
|
||||||
|
end
|
||||||
|
|
||||||
|
--this function updates dvd information and updates the browser
|
||||||
|
local function update()
|
||||||
|
read_disc()
|
||||||
|
list:update()
|
||||||
|
end
|
||||||
|
|
||||||
|
--appends the specified playlist item along with the desired options
|
||||||
|
local function load_dvd_title(title, flag)
|
||||||
|
local i = title.ix-1
|
||||||
|
mp.commandv("loadfile", "dvd://"..i, flag)
|
||||||
|
end
|
||||||
|
|
||||||
|
--handles actions when dvd:// paths are played directly
|
||||||
|
--updates dvd information and inserts disc titles into the playlist
|
||||||
|
local function load_disc()
|
||||||
|
local path = mp.get_property('stream-open-filename', '')
|
||||||
|
|
||||||
|
if path:find('dvd://') ~= 1 then
|
||||||
|
state.playing_disc = false
|
||||||
|
return
|
||||||
|
end
|
||||||
|
msg.verbose('playing dvd')
|
||||||
|
|
||||||
|
--if we have not stopped playing a disc then there's no need to parse the disc again
|
||||||
|
if not state.playing_disc then read_disc() end
|
||||||
|
|
||||||
|
--if we still can't detect a disc then return
|
||||||
|
if (not state.playing_disc) then return end
|
||||||
|
|
||||||
|
--if we successfully loaded info about the disc it's time to do some other stuff:
|
||||||
|
--this code block finds the default title of the disc
|
||||||
|
local curr_title
|
||||||
|
|
||||||
|
--if the user specified a title number we use that
|
||||||
|
if path ~= "dvd://" then
|
||||||
|
--treating whatever comes after "dvd://" as the title number
|
||||||
|
curr_title = tonumber(path:sub(7))
|
||||||
|
|
||||||
|
--if dvd:// was sent and this option is set we set the default ourselves
|
||||||
|
elseif o.start_from_first_title then
|
||||||
|
mp.set_property('stream-open-filename', "dvd://0")
|
||||||
|
curr_title = 0
|
||||||
|
|
||||||
|
--otherwise if just dvd:// was sent we need to find the longest title
|
||||||
|
else
|
||||||
|
curr_title = dvd.longest_track
|
||||||
|
end
|
||||||
|
|
||||||
|
mp.set_property('file-local-options/title', dvd.title.." - Title "..curr_title)
|
||||||
|
|
||||||
|
--if o.create_playlist is false then the function can end here
|
||||||
|
if not o.create_playlist then return end
|
||||||
|
|
||||||
|
--offsetting curr_title by one to account for lua arrays being 1-based
|
||||||
|
curr_title = curr_title+1
|
||||||
|
local length = mp.get_property_number('playlist-count', 1)
|
||||||
|
|
||||||
|
--load files in the playlist under the specified conditions
|
||||||
|
if (path == "dvd://" and o.treat_root_as_playlist) or length == 1 then
|
||||||
|
local pos = mp.get_property_number('playlist-pos', 1)
|
||||||
|
|
||||||
|
--add all of the files to the playlist
|
||||||
|
for i = 1, #dvd.track do
|
||||||
|
if i ~= curr_title then
|
||||||
|
load_dvd_title(dvd.track[i], "append")
|
||||||
|
length = length + 1
|
||||||
|
|
||||||
|
--we need slightly different behaviour when prepending vs appending a playlist entry
|
||||||
|
if (i < curr_title) then
|
||||||
|
mp.commandv("playlist-move", length-1, pos)
|
||||||
|
pos = pos+1
|
||||||
|
elseif (i > curr_title) then
|
||||||
|
mp.commandv("playlist-move", length-1, pos+(i-curr_title))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--if the path is dvd, then we actually need to fully replace this entry in the playlist,
|
||||||
|
--otherwise the whole disc will be added to the playlist again if moving back to this entry
|
||||||
|
if (path == "dvd://") then
|
||||||
|
msg.verbose('replacing dvd:// with playlist')
|
||||||
|
|
||||||
|
load_dvd_title(dvd.track[curr_title], "append")
|
||||||
|
length = length+1
|
||||||
|
mp.commandv('playlist-move', length-1, pos+1)
|
||||||
|
mp.commandv('playlist-remove', 'current')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--opens the currently selected file
|
||||||
|
local function open_file(flag)
|
||||||
|
load_dvd_title(dvd.track[list.selected], flag)
|
||||||
|
|
||||||
|
if flag == 'replace' then
|
||||||
|
list:close()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--opens the browser and declares dynamic keybinds
|
||||||
|
function list:open()
|
||||||
|
self.hidden = false
|
||||||
|
if not state.playing_disc then
|
||||||
|
update()
|
||||||
|
else
|
||||||
|
self:open_list()
|
||||||
|
end
|
||||||
|
self:add_keybinds()
|
||||||
|
end
|
||||||
|
|
||||||
|
list.keybinds = {
|
||||||
|
{"ESC", "exit", function() list:close() end, {}},
|
||||||
|
{"ENTER", "open", function() open_file('replace') end, {}},
|
||||||
|
{"Shift+ENTER", "append_playlist", function() open_file('append') end, {}},
|
||||||
|
{'DOWN', 'scroll_down', function() list:scroll_down() end, {repeatable = true}},
|
||||||
|
{'UP', 'scroll_up', function() list:scroll_up() end, {repeatable = true}},
|
||||||
|
{'Ctrl+r', 'reload', function() read_disc() ; list:update() end, {}}
|
||||||
|
}
|
||||||
|
|
||||||
|
--modifies track length to escape infinite loop
|
||||||
|
if o.escape_loop then
|
||||||
|
mp.add_hook('on_preloaded', 50, function()
|
||||||
|
if mp.get_property("path", ""):find("dvd://") ~= 1 then return end
|
||||||
|
if mp.get_property('end', 'none') ~= 'none' then return end
|
||||||
|
|
||||||
|
local chapters = mp.get_property_native('chapter-list')
|
||||||
|
if not chapters then return end
|
||||||
|
|
||||||
|
local num_chapters = #chapters
|
||||||
|
|
||||||
|
-- occurs if there are no chapters
|
||||||
|
if not chapters[num_chapters] then return end
|
||||||
|
if (mp.get_property_number('duration', 0) - (chapters[num_chapters].time or 0)) > 1 then return end
|
||||||
|
|
||||||
|
msg.verbose('modifying end of the title to escape infinite loop')
|
||||||
|
mp.set_property('file-local-options/end', "#"..num_chapters)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
--if we're playing a disc then read it and modify playlist appropriately
|
||||||
|
mp.add_hook('on_load', 50, load_disc)
|
||||||
|
|
||||||
|
--if these events are disabled then the list gui functions are never called
|
||||||
|
if STANDALONE then
|
||||||
|
mp.observe_property('path', 'string', function(_,path)
|
||||||
|
if state.playing_disc then list:update() end
|
||||||
|
end)
|
||||||
|
|
||||||
|
mp.register_script_message('browse-dvd', function() list:open() end)
|
||||||
|
|
||||||
|
mp.add_key_binding('MENU', 'dvd-browser', function() list:toggle() end)
|
||||||
|
end
|
||||||
|
|
||||||
|
--module functions when loading as file_browser addon
|
||||||
|
local dvd_module = {
|
||||||
|
priority = 50
|
||||||
|
}
|
||||||
|
|
||||||
|
function dvd_module:can_parse(directory)
|
||||||
|
return directory:sub(1,6) == "dvd://" or directory == self.get_dvd_device()
|
||||||
|
end
|
||||||
|
|
||||||
|
function dvd_module:parse()
|
||||||
|
read_disc()
|
||||||
|
local list = {}
|
||||||
|
|
||||||
|
if dvd then
|
||||||
|
for i = 1, #dvd.track do
|
||||||
|
list[i] = {
|
||||||
|
ass = get_line_str(dvd.track[i]),
|
||||||
|
name = tostring(dvd.track[i].ix-1),
|
||||||
|
path = "dvd://"..(dvd.track[i].ix-1),
|
||||||
|
type = "file"
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return list, {
|
||||||
|
empty_text = "insert DVD",
|
||||||
|
directory_label = get_header_str(),
|
||||||
|
filtered = true,
|
||||||
|
sorted = true
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
return dvd_module
|
||||||
65
.config/mpv/scripts/dvd_browser.conf
Normal file
65
.config/mpv/scripts/dvd_browser.conf
Normal file
|
|
@ -0,0 +1,65 @@
|
||||||
|
#################################################################
|
||||||
|
######### Default configuration file for mpv-dvd-browser ########
|
||||||
|
####### https://github.com/CogentRedTester/mpv-dvd-browser ######
|
||||||
|
#################################################################
|
||||||
|
|
||||||
|
#path to the lsdvd executable
|
||||||
|
#searches the system path by default
|
||||||
|
lsdvd=lsdvd
|
||||||
|
|
||||||
|
#path to the dvd device to send to lsdvd, leaving this blank will set the script to
|
||||||
|
#use the --dvd-device option.
|
||||||
|
#It is recommended that this be left blank unless using wsl
|
||||||
|
dvd_device=
|
||||||
|
|
||||||
|
#number of titles to display on the screen at once
|
||||||
|
num_entries=20
|
||||||
|
|
||||||
|
#by default the player enters an infinite loop, usually of the DVD menu screen, after moving
|
||||||
|
#past the last second of the file. If this option is enabled, then the script will
|
||||||
|
#automatically configure mpv to end playback before entering the loop
|
||||||
|
escape_loop=yes
|
||||||
|
|
||||||
|
#changes default mpv behaviour and loads the first title instead of the longest when
|
||||||
|
#the title isn't specified
|
||||||
|
start_from_first_title=yes
|
||||||
|
|
||||||
|
########################
|
||||||
|
### playlist options ###
|
||||||
|
########################
|
||||||
|
|
||||||
|
#adds the previous and subsequent titles to the playlist when playing a dvd
|
||||||
|
#only does this when there is only one item in the playlist
|
||||||
|
create_playlist=yes
|
||||||
|
|
||||||
|
#when dvd:// (no specified title) is loaded the script will always insert all of the
|
||||||
|
#titles into the playlist, regardless of the playlist length
|
||||||
|
#similar to loading a directory or playlist file
|
||||||
|
treat_root_as_playlist=yes
|
||||||
|
|
||||||
|
##################################################
|
||||||
|
#### wsl options for limitted windows support ####
|
||||||
|
##################################################
|
||||||
|
|
||||||
|
#enable wsl compatibility mode
|
||||||
|
wsl=no
|
||||||
|
|
||||||
|
#your WSL user password for running the `sudo mount` command
|
||||||
|
#leaving this blank will disable the auto-mounting command
|
||||||
|
wsl_password=
|
||||||
|
|
||||||
|
|
||||||
|
###########################################################################################
|
||||||
|
# ass tags to change the look of the menu
|
||||||
|
# For information see: http://docs.aegisub.org/3.2/ASS_Tags/
|
||||||
|
#
|
||||||
|
# It's recommended not to put these in your config file unless you know what you're doing,
|
||||||
|
# otherwise any improvements I make to the default theme will be overwritten
|
||||||
|
###########################################################################################
|
||||||
|
ass_header={\q2\fs35\c&00ccff&}
|
||||||
|
ass_body={\q2\fs25\c&Hffffff&}
|
||||||
|
ass_selected={\c&Hfce788&}
|
||||||
|
ass_playing={\c&H33ff66&}
|
||||||
|
ass_footerheader={\c&00ccff&\fs16}
|
||||||
|
ass_cursor={\c&00ccff&}
|
||||||
|
ass_length={\fs20\c&aaaaaa&}
|
||||||
|
|
@ -19,6 +19,7 @@ local ext = {
|
||||||
local double_page_check = false
|
local double_page_check = false
|
||||||
local first_start = true
|
local first_start = true
|
||||||
local filedims = {}
|
local filedims = {}
|
||||||
|
local format = {}
|
||||||
local initiated = false
|
local initiated = false
|
||||||
local input = ""
|
local input = ""
|
||||||
local jump = false
|
local jump = false
|
||||||
|
|
@ -34,11 +35,11 @@ local opts = {
|
||||||
double = false,
|
double = false,
|
||||||
manga = true,
|
manga = true,
|
||||||
pan_size = 0.05,
|
pan_size = 0.05,
|
||||||
similar_height_threshold = 50,
|
similar_height_threshold = 200,
|
||||||
skip_size = 10,
|
skip_size = 10,
|
||||||
trigger_zone = 0.05,
|
trigger_zone = 0.05,
|
||||||
zoom_multiplier = 1,
|
|
||||||
}
|
}
|
||||||
|
local lavfi_format = {}
|
||||||
local lavfi_scale = {}
|
local lavfi_scale = {}
|
||||||
local similar_height = {}
|
local similar_height = {}
|
||||||
local valid_width = {}
|
local valid_width = {}
|
||||||
|
|
@ -50,25 +51,6 @@ function add_tracks(start, finish)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function calculate_zoom_level(dims, pages)
|
|
||||||
local display_width = mp.get_property_number("display-width")
|
|
||||||
local display_height = mp.get_property_number("display-height")
|
|
||||||
local display_dpi = mp.get_property_number("display-hidpi-scale")
|
|
||||||
|
|
||||||
display_width = display_width / display_dpi
|
|
||||||
display_height = display_height / display_dpi
|
|
||||||
|
|
||||||
dims[0] = tonumber(dims[0])
|
|
||||||
dims[1] = tonumber(dims[1]) * opts.continuous_size
|
|
||||||
|
|
||||||
local scaled_width = display_height/dims[1] * dims[0]
|
|
||||||
if display_width >= opts.continuous_size*scaled_width then
|
|
||||||
return pages
|
|
||||||
else
|
|
||||||
return display_width / scaled_width
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function check_aspect_ratio(index)
|
function check_aspect_ratio(index)
|
||||||
local a = filedims[index]
|
local a = filedims[index]
|
||||||
local b = filedims[index+1]
|
local b = filedims[index+1]
|
||||||
|
|
@ -106,6 +88,14 @@ function check_double_page_dims(index)
|
||||||
double_page_check = false
|
double_page_check = false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function check_gray_format(name)
|
||||||
|
if name and string.sub(name, 1, 4) == "gray" then
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function check_images()
|
function check_images()
|
||||||
local audio = mp.get_property("audio-params")
|
local audio = mp.get_property("audio-params")
|
||||||
local image = mp.get_property_bool("current-tracks/video/image")
|
local image = mp.get_property_bool("current-tracks/video/image")
|
||||||
|
|
@ -128,6 +118,9 @@ function set_custom_title(last_index)
|
||||||
end
|
end
|
||||||
|
|
||||||
function create_modes()
|
function create_modes()
|
||||||
|
if first_start and not opts.auto_start then
|
||||||
|
return
|
||||||
|
end
|
||||||
local index = mp.get_property_number("playlist-pos")
|
local index = mp.get_property_number("playlist-pos")
|
||||||
local len = mp.get_property_number("playlist-count")
|
local len = mp.get_property_number("playlist-count")
|
||||||
local pages
|
local pages
|
||||||
|
|
@ -143,7 +136,7 @@ function create_modes()
|
||||||
finish = len - 1
|
finish = len - 1
|
||||||
end
|
end
|
||||||
add_tracks(index, finish)
|
add_tracks(index, finish)
|
||||||
store_file_dims(index, finish)
|
store_file_props(index, finish)
|
||||||
if opts.double then
|
if opts.double then
|
||||||
check_double_page_dims(index)
|
check_double_page_dims(index)
|
||||||
set_lavfi_complex_double()
|
set_lavfi_complex_double()
|
||||||
|
|
@ -160,7 +153,7 @@ function create_modes()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function store_file_dims(start, finish)
|
function store_file_props(start, finish)
|
||||||
local len = mp.get_property_number("playlist-count")
|
local len = mp.get_property_number("playlist-count")
|
||||||
local needs_dims = false
|
local needs_dims = false
|
||||||
for i=start, finish do
|
for i=start, finish do
|
||||||
|
|
@ -191,12 +184,21 @@ function store_file_dims(start, finish)
|
||||||
dims[0] = width
|
dims[0] = width
|
||||||
dims[1] = height
|
dims[1] = height
|
||||||
filedims[i+start] = dims
|
filedims[i+start] = dims
|
||||||
|
format[i+start] = mp.get_property("track-list/"..tostring(i).."/format-name")
|
||||||
|
-- special case any yuvj formats to avoid ffmpeg deprecation warning spam
|
||||||
|
if format[i+start] and string.sub(format[i+start], 1, 4) == "yuvj" then
|
||||||
|
format[i+start] = string.gsub(format[i+start], "j", "")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
for i=start, finish - 1 do
|
for i=start, finish - 1 do
|
||||||
valid_width[i] = check_aspect_ratio(i)
|
valid_width[i] = check_aspect_ratio(i)
|
||||||
if filedims[i][1] ~= filedims[i+1][1] then
|
if filedims[i][1] ~= filedims[i+1][1] then
|
||||||
lavfi_scale[i] = true
|
lavfi_scale[i] = true
|
||||||
end
|
end
|
||||||
|
if format[i] ~= format[i+1] and check_gray_format(format[i]) or check_gray_format(format[i+1]) then
|
||||||
|
-- if one page is gray, we need to forcibly convert it
|
||||||
|
lavfi_format[i] = check_gray_format(format[i]) and format[i+1] or format[i]
|
||||||
|
end
|
||||||
if math.abs(filedims[i][1] - filedims[i+1][1]) < opts.similar_height_threshold then
|
if math.abs(filedims[i][1] - filedims[i+1][1]) < opts.similar_height_threshold then
|
||||||
similar_height[i] = true
|
similar_height[i] = true
|
||||||
else
|
else
|
||||||
|
|
@ -232,6 +234,27 @@ function set_lavfi_complex_continuous(arg, finish)
|
||||||
local index = mp.get_property_number("playlist-pos")
|
local index = mp.get_property_number("playlist-pos")
|
||||||
local pages = finish - index
|
local pages = finish - index
|
||||||
local max_width = find_max_width(pages)
|
local max_width = find_max_width(pages)
|
||||||
|
local has_gray = false
|
||||||
|
local has_color = false
|
||||||
|
local color_format = ""
|
||||||
|
for i=0, pages do
|
||||||
|
if check_gray_format(format[index+i]) then
|
||||||
|
has_gray = true
|
||||||
|
else
|
||||||
|
has_color = true
|
||||||
|
color_format = format[index+i]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- if at least one page is color, any gray pages must be converted
|
||||||
|
if has_gray and has_color then
|
||||||
|
for i=0, pages do
|
||||||
|
if check_gray_format(format[index+i]) then
|
||||||
|
local split_format = string.gsub(split[i], "]", "_format]")
|
||||||
|
vstack = vstack..split[i].." format="..color_format.. " "..split_format.."; "
|
||||||
|
split[i] = split_format
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
for i=0, pages do
|
for i=0, pages do
|
||||||
if filedims[index+i][0] ~= max_width then
|
if filedims[index+i][0] ~= max_width then
|
||||||
local split_pad = string.gsub(split[i], "]", "_pad]")
|
local split_pad = string.gsub(split[i], "]", "_pad]")
|
||||||
|
|
@ -245,8 +268,6 @@ function set_lavfi_complex_continuous(arg, finish)
|
||||||
vstack = vstack.."vstack=inputs="..tostring(pages + 1).." [vo]"
|
vstack = vstack.."vstack=inputs="..tostring(pages + 1).." [vo]"
|
||||||
mp.set_property("lavfi-complex", vstack)
|
mp.set_property("lavfi-complex", vstack)
|
||||||
local index = mp.get_property_number("playlist-pos")
|
local index = mp.get_property_number("playlist-pos")
|
||||||
local zoom_level = calculate_zoom_level(filedims[index], pages+1)
|
|
||||||
mp.set_property_number("video-zoom", opts.zoom_multiplier * log2(zoom_level))
|
|
||||||
mp.set_property_number("video-pan-y", 0)
|
mp.set_property_number("video-pan-y", 0)
|
||||||
if upwards then
|
if upwards then
|
||||||
mp.set_property_number("video-align-y", 1)
|
mp.set_property_number("video-align-y", 1)
|
||||||
|
|
@ -265,18 +286,26 @@ function set_lavfi_complex_double()
|
||||||
end
|
end
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
local hstack
|
local hstack = ""
|
||||||
local external_vid = "[vid2]"
|
local vid1 = "[vid1]"
|
||||||
|
local vid2 = "[vid2]"
|
||||||
|
if lavfi_format[index] then
|
||||||
|
if check_gray_format(format[index]) then
|
||||||
|
hstack = vid1.." format="..lavfi_format[index].." [vid1_format]; "
|
||||||
|
vid1 = "[vid1_format]"
|
||||||
|
else
|
||||||
|
hstack = vid2.." format="..lavfi_format[index].." [vid2_format]; "
|
||||||
|
vid2 = "[vid2_format]"
|
||||||
|
end
|
||||||
|
end
|
||||||
if lavfi_scale[index] then
|
if lavfi_scale[index] then
|
||||||
external_vid = string.sub(external_vid, 0, 5).."_scale]"
|
hstack = hstack..vid2.." scale="..filedims[index][0].."x"..filedims[index][1]..":flags=lanczos [vid2_scale]; "
|
||||||
|
vid2 = "[vid2_scale]"
|
||||||
end
|
end
|
||||||
if opts.manga then
|
if opts.manga then
|
||||||
hstack = external_vid.." [vid1] hstack [vo]"
|
hstack = hstack..vid2.." "..vid1.. " hstack [vo]"
|
||||||
else
|
else
|
||||||
hstack = "[vid1] "..external_vid.." hstack [vo]"
|
hstack = hstack..vid1.." "..vid2.. " hstack [vo]"
|
||||||
end
|
|
||||||
if lavfi_scale[index] then
|
|
||||||
hstack = "[vid2] scale="..filedims[index][0].."x"..filedims[index][1]..":flags=lanczos [vid2_scale]; "..hstack
|
|
||||||
end
|
end
|
||||||
mp.set_property("lavfi-complex", hstack)
|
mp.set_property("lavfi-complex", hstack)
|
||||||
end
|
end
|
||||||
|
|
@ -631,6 +660,7 @@ function toggle_reader()
|
||||||
set_properties()
|
set_properties()
|
||||||
mp.observe_property("playlist-count", number, remove_non_images)
|
mp.observe_property("playlist-count", number, remove_non_images)
|
||||||
mp.osd_message("Manga Reader Started")
|
mp.osd_message("Manga Reader Started")
|
||||||
|
mp.add_hook("on_preloaded", 50, create_modes)
|
||||||
mp.add_key_binding("c", "toggle-continuous-mode", toggle_continuous_mode)
|
mp.add_key_binding("c", "toggle-continuous-mode", toggle_continuous_mode)
|
||||||
mp.add_key_binding("d", "toggle-double-page", toggle_double_page)
|
mp.add_key_binding("d", "toggle-double-page", toggle_double_page)
|
||||||
mp.add_key_binding("m", "toggle-manga-mode", toggle_manga_mode)
|
mp.add_key_binding("m", "toggle-manga-mode", toggle_manga_mode)
|
||||||
|
|
@ -642,7 +672,6 @@ function toggle_reader()
|
||||||
restore_properties()
|
restore_properties()
|
||||||
mp.unobserve_property(check_y_pos)
|
mp.unobserve_property(check_y_pos)
|
||||||
mp.unobserve_property(remove_non_images)
|
mp.unobserve_property(remove_non_images)
|
||||||
mp.set_property_number("video-zoom", 0)
|
|
||||||
mp.set_property_number("video-align-y", 0)
|
mp.set_property_number("video-align-y", 0)
|
||||||
mp.set_property_number("video-pan-y", 0)
|
mp.set_property_number("video-pan-y", 0)
|
||||||
mp.set_property("lavfi-complex", "")
|
mp.set_property("lavfi-complex", "")
|
||||||
|
|
@ -723,7 +752,6 @@ function toggle_continuous_mode()
|
||||||
opts.continuous = false
|
opts.continuous = false
|
||||||
mp.unobserve_property(check_y_pos)
|
mp.unobserve_property(check_y_pos)
|
||||||
mp.set_property("lavfi-complex", "")
|
mp.set_property("lavfi-complex", "")
|
||||||
mp.set_property_number("video-zoom", 0)
|
|
||||||
mp.set_property_number("video-align-y", 0)
|
mp.set_property_number("video-align-y", 0)
|
||||||
mp.set_property_number("video-pan-y", 0)
|
mp.set_property_number("video-pan-y", 0)
|
||||||
else
|
else
|
||||||
|
|
@ -764,7 +792,6 @@ function toggle_manga_mode()
|
||||||
mp.commandv("playlist-play-index", index)
|
mp.commandv("playlist-play-index", index)
|
||||||
end
|
end
|
||||||
|
|
||||||
mp.add_hook("on_preloaded", 50, create_modes)
|
|
||||||
mp.register_event("file-loaded", init)
|
mp.register_event("file-loaded", init)
|
||||||
mp.add_key_binding("y", "toggle-reader", toggle_reader)
|
mp.add_key_binding("y", "toggle-reader", toggle_reader)
|
||||||
require "mp.options".read_options(opts, "manga-reader")
|
require "mp.options".read_options(opts, "manga-reader")
|
||||||
|
|
|
||||||
293
.config/mpv/scripts/scroll-list.lua
Normal file
293
.config/mpv/scripts/scroll-list.lua
Normal file
|
|
@ -0,0 +1,293 @@
|
||||||
|
local mp = require 'mp'
|
||||||
|
local scroll_list = {
|
||||||
|
global_style = [[]],
|
||||||
|
header_style = [[{\q2\fs35\c&00ccff&}]],
|
||||||
|
list_style = [[{\q2\fs25\c&Hffffff&}]],
|
||||||
|
wrapper_style = [[{\c&00ccff&\fs16}]],
|
||||||
|
cursor_style = [[{\c&00ccff&}]],
|
||||||
|
selected_style = [[{\c&Hfce788&}]],
|
||||||
|
|
||||||
|
cursor = [[➤\h]],
|
||||||
|
indent = [[\h\h\h\h]],
|
||||||
|
|
||||||
|
num_entries = 16,
|
||||||
|
wrap = false,
|
||||||
|
empty_text = "no entries"
|
||||||
|
}
|
||||||
|
|
||||||
|
--formats strings for ass handling
|
||||||
|
--this function is based on a similar function from https://github.com/mpv-player/mpv/blob/master/player/lua/console.lua#L110
|
||||||
|
function scroll_list.ass_escape(str, replace_newline)
|
||||||
|
if replace_newline == true then replace_newline = "\\\239\187\191n" end
|
||||||
|
|
||||||
|
--escape the invalid single characters
|
||||||
|
str = str:gsub('[\\{}\n]', {
|
||||||
|
-- There is no escape for '\' in ASS (I think?) but '\' is used verbatim if
|
||||||
|
-- it isn't followed by a recognised character, so add a zero-width
|
||||||
|
-- non-breaking space
|
||||||
|
['\\'] = '\\\239\187\191',
|
||||||
|
['{'] = '\\{',
|
||||||
|
['}'] = '\\}',
|
||||||
|
-- Precede newlines with a ZWNBSP to prevent ASS's weird collapsing of
|
||||||
|
-- consecutive newlines
|
||||||
|
['\n'] = '\239\187\191\\N',
|
||||||
|
})
|
||||||
|
|
||||||
|
-- Turn leading spaces into hard spaces to prevent ASS from stripping them
|
||||||
|
str = str:gsub('\\N ', '\\N\\h')
|
||||||
|
str = str:gsub('^ ', '\\h')
|
||||||
|
|
||||||
|
if replace_newline then
|
||||||
|
str = str:gsub("\\N", replace_newline)
|
||||||
|
end
|
||||||
|
return str
|
||||||
|
end
|
||||||
|
|
||||||
|
--format and return the header string
|
||||||
|
function scroll_list:format_header_string(str)
|
||||||
|
return str
|
||||||
|
end
|
||||||
|
|
||||||
|
--appends the entered text to the overlay
|
||||||
|
function scroll_list:append(text)
|
||||||
|
if text == nil then return end
|
||||||
|
self.ass.data = self.ass.data .. text
|
||||||
|
end
|
||||||
|
|
||||||
|
--appends a newline character to the osd
|
||||||
|
function scroll_list:newline()
|
||||||
|
self.ass.data = self.ass.data .. '\\N'
|
||||||
|
end
|
||||||
|
|
||||||
|
--re-parses the list into an ass string
|
||||||
|
--if the list is closed then it flags an update on the next open
|
||||||
|
function scroll_list:update()
|
||||||
|
if self.hidden then self.flag_update = true
|
||||||
|
else self:update_ass() end
|
||||||
|
end
|
||||||
|
|
||||||
|
--prints the header to the overlay
|
||||||
|
function scroll_list:format_header()
|
||||||
|
self:append(self.header_style)
|
||||||
|
self:append(self:format_header_string(self.header))
|
||||||
|
self:newline()
|
||||||
|
end
|
||||||
|
|
||||||
|
--formats each line of the list and prints it to the overlay
|
||||||
|
function scroll_list:format_line(index, item)
|
||||||
|
self:append(self.list_style)
|
||||||
|
|
||||||
|
if index == self.selected then self:append(self.cursor_style..self.cursor..self.selected_style)
|
||||||
|
else self:append(self.indent) end
|
||||||
|
|
||||||
|
self:append(item.style)
|
||||||
|
self:append(item.ass)
|
||||||
|
self:newline()
|
||||||
|
end
|
||||||
|
|
||||||
|
--refreshes the ass text using the contents of the list
|
||||||
|
function scroll_list:update_ass()
|
||||||
|
self.ass.data = self.global_style
|
||||||
|
self:format_header()
|
||||||
|
|
||||||
|
if #self.list < 1 then
|
||||||
|
self:append(self.empty_text)
|
||||||
|
self.ass:update()
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local start = 1
|
||||||
|
local finish = start+self.num_entries-1
|
||||||
|
|
||||||
|
--handling cursor positioning
|
||||||
|
local mid = math.ceil(self.num_entries/2)+1
|
||||||
|
if self.selected+mid > finish then
|
||||||
|
local offset = self.selected - finish + mid
|
||||||
|
|
||||||
|
--if we've overshot the end of the list then undo some of the offset
|
||||||
|
if finish + offset > #self.list then
|
||||||
|
offset = offset - ((finish+offset) - #self.list)
|
||||||
|
end
|
||||||
|
|
||||||
|
start = start + offset
|
||||||
|
finish = finish + offset
|
||||||
|
end
|
||||||
|
|
||||||
|
--making sure that we don't overstep the boundaries
|
||||||
|
if start < 1 then start = 1 end
|
||||||
|
local overflow = finish < #self.list
|
||||||
|
--this is necessary when the number of items in the dir is less than the max
|
||||||
|
if not overflow then finish = #self.list end
|
||||||
|
|
||||||
|
--adding a header to show there are items above in the list
|
||||||
|
if start > 1 then self:append(self.wrapper_style..(start-1)..' item(s) above\\N\\N') end
|
||||||
|
|
||||||
|
for i=start, finish do
|
||||||
|
self:format_line(i, self.list[i])
|
||||||
|
end
|
||||||
|
|
||||||
|
if overflow then self:append('\\N'..self.wrapper_style..#self.list-finish..' item(s) remaining') end
|
||||||
|
self.ass:update()
|
||||||
|
end
|
||||||
|
|
||||||
|
--moves the selector down the list
|
||||||
|
function scroll_list:scroll_down()
|
||||||
|
if self.selected < #self.list then
|
||||||
|
self.selected = self.selected + 1
|
||||||
|
self:update_ass()
|
||||||
|
elseif self.wrap then
|
||||||
|
self.selected = 1
|
||||||
|
self:update_ass()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--moves the selector up the list
|
||||||
|
function scroll_list:scroll_up()
|
||||||
|
if self.selected > 1 then
|
||||||
|
self.selected = self.selected - 1
|
||||||
|
self:update_ass()
|
||||||
|
elseif self.wrap then
|
||||||
|
self.selected = #self.list
|
||||||
|
self:update_ass()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--moves the selector to the list next page
|
||||||
|
function scroll_list:move_pagedown()
|
||||||
|
if #self.list > self.num_entries then
|
||||||
|
self.selected = self.selected + self.num_entries
|
||||||
|
if self.selected > #self.list then self.selected = #self.list end
|
||||||
|
self:update_ass()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--moves the selector to the list previous page
|
||||||
|
function scroll_list:move_pageup()
|
||||||
|
if #self.list > self.num_entries then
|
||||||
|
self.selected = self.selected - self.num_entries
|
||||||
|
if self.selected < 1 then self.selected = 1 end
|
||||||
|
self:update_ass()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--moves the selector to the list begin
|
||||||
|
function scroll_list:move_begin()
|
||||||
|
if #self.list > 1 then
|
||||||
|
self.selected = 1
|
||||||
|
self:update_ass()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--moves the selector to the list end
|
||||||
|
function scroll_list:move_end()
|
||||||
|
if #self.list > 1 then
|
||||||
|
self.selected = #self.list
|
||||||
|
self:update_ass()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--adds the forced keybinds
|
||||||
|
function scroll_list:add_keybinds()
|
||||||
|
for _,v in ipairs(self.keybinds) do
|
||||||
|
mp.add_forced_key_binding(v[1], 'dynamic/'..self.ass.id..'/'..v[2], v[3], v[4])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--removes the forced keybinds
|
||||||
|
function scroll_list:remove_keybinds()
|
||||||
|
for _,v in ipairs(self.keybinds) do
|
||||||
|
mp.remove_key_binding('dynamic/'..self.ass.id..'/'..v[2])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--opens the list and sets the hidden flag
|
||||||
|
function scroll_list:open_list()
|
||||||
|
self.hidden = false
|
||||||
|
if not self.flag_update then self.ass:update()
|
||||||
|
else self.flag_update = false ; self:update_ass() end
|
||||||
|
end
|
||||||
|
|
||||||
|
--closes the list and sets the hidden flag
|
||||||
|
function scroll_list:close_list()
|
||||||
|
self.hidden = true
|
||||||
|
self.ass:remove()
|
||||||
|
end
|
||||||
|
|
||||||
|
--modifiable function that opens the list
|
||||||
|
function scroll_list:open()
|
||||||
|
if self.hidden then self:add_keybinds() end
|
||||||
|
self:open_list()
|
||||||
|
end
|
||||||
|
|
||||||
|
--modifiable function that closes the list
|
||||||
|
function scroll_list:close()
|
||||||
|
self:remove_keybinds()
|
||||||
|
self:close_list()
|
||||||
|
end
|
||||||
|
|
||||||
|
--toggles the list
|
||||||
|
function scroll_list:toggle()
|
||||||
|
if self.hidden then self:open()
|
||||||
|
else self:close() end
|
||||||
|
end
|
||||||
|
|
||||||
|
--clears the list in-place
|
||||||
|
function scroll_list:clear()
|
||||||
|
local i = 1
|
||||||
|
while self.list[i] do
|
||||||
|
self.list[i] = nil
|
||||||
|
i = i + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--added alias for ipairs(list.list) for lua 5.1
|
||||||
|
function scroll_list:ipairs()
|
||||||
|
return ipairs(self.list)
|
||||||
|
end
|
||||||
|
|
||||||
|
--append item to the end of the list
|
||||||
|
function scroll_list:insert(item)
|
||||||
|
self.list[#self.list + 1] = item
|
||||||
|
end
|
||||||
|
|
||||||
|
local metatable = {
|
||||||
|
__index = function(t, key)
|
||||||
|
if scroll_list[key] ~= nil then return scroll_list[key]
|
||||||
|
elseif key == "__current" then return t.list[t.selected]
|
||||||
|
elseif type(key) == "number" then return t.list[key] end
|
||||||
|
end,
|
||||||
|
__newindex = function(t, key, value)
|
||||||
|
if type(key) == "number" then rawset(t.list, key, value)
|
||||||
|
else rawset(t, key, value) end
|
||||||
|
end,
|
||||||
|
__scroll_list = scroll_list,
|
||||||
|
__len = function(t) return #t.list end,
|
||||||
|
__ipairs = function(t) return ipairs(t.list) end
|
||||||
|
}
|
||||||
|
|
||||||
|
--creates a new list object
|
||||||
|
function scroll_list:new()
|
||||||
|
local vars
|
||||||
|
vars = {
|
||||||
|
ass = mp.create_osd_overlay('ass-events'),
|
||||||
|
hidden = true,
|
||||||
|
flag_update = true,
|
||||||
|
|
||||||
|
header = "header \\N ----------------------------------------------",
|
||||||
|
list = {},
|
||||||
|
selected = 1,
|
||||||
|
|
||||||
|
keybinds = {
|
||||||
|
{'DOWN', 'scroll_down', function() vars:scroll_down() end, {repeatable = true}},
|
||||||
|
{'UP', 'scroll_up', function() vars:scroll_up() end, {repeatable = true}},
|
||||||
|
{'PGDWN', 'move_pagedown', function() vars:move_pagedown() end, {}},
|
||||||
|
{'PGUP', 'move_pageup', function() vars:move_pageup() end, {}},
|
||||||
|
{'HOME', 'move_begin', function() vars:move_begin() end, {}},
|
||||||
|
{'END', 'move_end', function() vars:move_end() end, {}},
|
||||||
|
{'ESC', 'close_browser', function() vars:close() end, {}}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return setmetatable(vars, metatable)
|
||||||
|
end
|
||||||
|
|
||||||
|
return scroll_list:new()
|
||||||
Loading…
Add table
Reference in a new issue