diff options
author | David Vazgenovich Shakaryan <dvshakaryan@gmail.com> | 2025-05-06 11:50:01 -0700 |
---|---|---|
committer | David Vazgenovich Shakaryan <dvshakaryan@gmail.com> | 2025-05-06 11:50:01 -0700 |
commit | c329d7c8f923588da3a4adc711bac6f790958580 (patch) | |
tree | d9dd315690a7c83366f93041c6f685dc01477a79 /main.lua | |
parent | 182fbe88b9563cdffc5f442b56389d938eb79787 (diff) | |
download | mpv-iptv-menu-c329d7c8f923588da3a4adc711bac6f790958580.tar.gz mpv-iptv-menu-c329d7c8f923588da3a4adc711bac6f790958580.tar.xz |
consolidate menu state
Diffstat (limited to 'main.lua')
-rw-r--r-- | main.lua | 94 |
1 files changed, 46 insertions, 48 deletions
@@ -14,19 +14,15 @@ local osd_bg = mp.create_osd_overlay('ass-events') osd_bg.z = -1 osd_bg.data = '{\\alpha&H50&\\c&H&\\pos(0,0)}' .. '{\\p1}m 0 0 l 9999 0 9999 720 0 720{\\p0}' -local key_bindings = {} local categories = {} local streams = {} local depth = 0 local menus = {} -local menu_top = {} -local menu_pos = {} -local menu_titles = {} - local search_text = '' local search_active = false +local key_bindings = {} local function load_json_file(path) local f = io.open(script_dir .. '/' .. path, 'r') @@ -39,6 +35,7 @@ local function load_data() categories = load_json_file('categories.json') for _, v in ipairs(categories) do v.type = 'category' + v.name = v.category_name end streams = load_json_file('streams.json') @@ -49,6 +46,7 @@ end local function osd_menu_lines() if depth > 1 then + -- leaves an extra line for padding between titles and options return osd_lines - depth else return osd_lines @@ -60,25 +58,23 @@ local function update_osd() if depth > 1 then for i = 2, depth do - out[#out+1] = '{\\c&H999999&} » [' .. menu_titles[i] .. + out[#out+1] = '{\\c&H999999&} » [' .. menus[i].title .. ']{\\c}' end out[#out+1] = ' ' -- space character for correct line height end - for i = menu_top[depth], math.min( - menu_top[depth] + osd_menu_lines() - 1, - #menus[depth]) do - local opt = menus[depth][i] - local str + local menu = menus[depth] + for i = menu.page_pos, math.min( + menu.page_pos + osd_menu_lines() - 1, #menu.options) do + local opt = menu.options[i] + local str = opt.name if opt.type == 'category' then - str = '[' .. opt.category_name .. ']' - else - str = opt.name + str = '[' .. str .. ']' end - if i == menu_pos[depth] and not search_active then + if i == menu.cursor_pos and not search_active then str = '{\\c&HFF00&}* ' .. str .. '{\\c}' elseif opt.type == 'category' then str = '{\\c&H99DDFF&}' .. str .. '{\\c}' @@ -89,14 +85,17 @@ local function update_osd() -- \q2 disables line wrapping osd.data = '{\\q2\\fs' .. font_size .. '\\pos(' .. osd_padding .. - ',' .. osd_padding .. '}' .. table.concat(out, '\\N') + ',' .. osd_padding .. ')}' .. table.concat(out, '\\N') osd:update() osd_bg:update() end local function advance_cursor(n, opts) - pos = math.max(1, math.min(menu_pos[depth] + n, #menus[depth])) - top = menu_top[depth] + local menu = menus[depth] + local lines = osd_menu_lines() + + local pos = math.max(1, math.min(menu.cursor_pos + n, #menu.options)) + local top = menu.page_pos if opts and opts.advance_page then top = top + n end @@ -104,14 +103,14 @@ local function advance_cursor(n, opts) -- move page to keep selected option visible if pos < top then top = pos - elseif pos > top + osd_menu_lines() - 1 then - top = pos - osd_menu_lines() + 1 + elseif pos > top + lines - 1 then + top = pos - lines + 1 end - top = math.max(1, math.min(top, #menus[depth] - osd_menu_lines() + 1)) + top = math.max(1, math.min(top, #menu.options - lines + 1)) - menu_pos[depth] = pos - menu_top[depth] = top + menu.cursor_pos = pos + menu.page_pos = top update_osd() end @@ -139,28 +138,32 @@ local function last_option() advance_cursor(math.huge) end -local function push_menu(menu, title) +local function push_menu(options, title) + menu = { + title=title, + options=options or {}, + cursor_pos=1, + page_pos=1, + } + depth = depth + 1 - menus[depth] = menu or {} - menu_top[depth] = 1 - menu_pos[depth] = 1 - menu_titles[depth] = title + menus[depth] = menu end local function add_category_menu(category_id, category_name) - local menu = {} + local options = {} for _, v in ipairs(categories) do if tostring(v.parent_id) == category_id then - menu[#menu+1] = v + options[#options+1] = v end end for _, v in ipairs(streams) do if v.category_id == category_id then - menu[#menu+1] = v + options[#options+1] = v end end - push_menu(menu, category_name) + push_menu(options, category_name) update_osd() end @@ -170,10 +173,11 @@ local function play_stream(stream_id) end local function select_option() - local opt = menus[depth][menu_pos[depth]] + local menu = menus[depth] + local opt = menu.options[menu.cursor_pos] if opt.type == 'category' then - add_category_menu(opt.category_id, opt.category_name) + add_category_menu(opt.category_id, opt.name) else play_stream(opt.stream_id) end @@ -199,26 +203,20 @@ local function unbind_keys() end local function search_update() - matches = {} - for _, v in ipairs(menus[depth-1]) do - local name - if v.type == 'category' then - name = v.category_name - else - name = v.name - end - - if string.find(name, search_text, 0, true) then + local matches = {} + for _, v in ipairs(menus[depth-1].options) do + if string.find(v.name, search_text, 0, true) then matches[#matches+1] = v end end - menus[depth] = matches - menu_titles[depth] = 'Searching: ' .. search_text + local menu = menus[depth] + menu.options = matches + menu.title = 'Searching: ' .. search_text end local function search_input(event) - if not (event.event == 'down' or event.event == 'repeat') then + if event.event ~= 'down' and event.event ~= 'repeat' then return end @@ -247,7 +245,7 @@ end local function search_finish() search_active = false - menu_titles[depth] = 'Search results: ' .. search_text + menus[depth].title = 'Search results: ' .. search_text update_osd() bind_menu_keys() end |