summaryrefslogtreecommitdiff
path: root/ar/.config/mpv/script-modules/scroll-list.lua
diff options
context:
space:
mode:
authorTheSiahxyz <164138827+TheSiahxyz@users.noreply.github.com>2026-03-14 00:07:41 +0900
committerTheSiahxyz <164138827+TheSiahxyz@users.noreply.github.com>2026-03-14 00:07:41 +0900
commit5e954f3dfb4304341c1a50a1f9310f58dcf39682 (patch)
treef4e5c1fdc9ee24b662fd9f4f43da4621a012c29a /ar/.config/mpv/script-modules/scroll-list.lua
parenta13bf1ecb918bcf80ecb8bb9663ac7a84d576243 (diff)
updates
Diffstat (limited to 'ar/.config/mpv/script-modules/scroll-list.lua')
-rw-r--r--ar/.config/mpv/script-modules/scroll-list.lua457
1 files changed, 274 insertions, 183 deletions
diff --git a/ar/.config/mpv/script-modules/scroll-list.lua b/ar/.config/mpv/script-modules/scroll-list.lua
index 5d8f9fa..c1088f1 100644
--- a/ar/.config/mpv/script-modules/scroll-list.lua
+++ b/ar/.config/mpv/script-modules/scroll-list.lua
@@ -1,293 +1,384 @@
-local mp = require 'mp'
+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"
+ 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
+ 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
+ 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
+ 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'
+ 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
+ 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()
+ 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)
+ 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
+ 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()
+ 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()
+ 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
+ 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
+ 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
+ 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
+ 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
+ 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
+ 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
+ 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
+ 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
+ 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()
+ 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()
+ 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()
+ self:remove_keybinds()
+ self:close_list()
end
--toggles the list
function scroll_list:toggle()
- if self.hidden then self:open()
- else self:close() end
+ 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
+ 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)
+ return ipairs(self.list)
end
--append item to the end of the list
function scroll_list:insert(item)
- self.list[#self.list + 1] = 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
+ __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)
+ 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()