diff options
Diffstat (limited to 'main.lua')
-rw-r--r-- | main.lua | 190 |
1 files changed, 104 insertions, 86 deletions
@@ -185,6 +185,10 @@ local function load_data() end end +local function asscape(str) + return mp.command_native({'escape-ass', str}) +end + local function osd_menu_lines() if depth > 1 then -- leaves an extra line for padding between titles and options @@ -194,87 +198,111 @@ local function osd_menu_lines() end end -local function update_osd() - local out = {} +local function osd_menu_title(menu) + local str = asscape(menu.title) + local col = menu.search_active and colours.selected or colours.title - if depth > 1 then - for i = 2, depth do - local col = colours.title - if menus[i].search_active then - col = colours.selected - end - out[#out+1] = col .. ' » ' .. menus[i].title + if menu.type == 'search' then + str = str:gsub('<text>', asscape(menu.search_text)) + + if str:find('<text_with_cursor>', 1, true) then + str = str:gsub('<text_with_cursor>', + asscape(menu.search_text:sub( + 1, menu.search_cursor - 1)) .. + osd_cursor_glyph .. + asscape(menu.search_text:sub( + menu.search_cursor))) end - out[#out+1] = ' ' -- space character for correct line height end - local menu = menus[depth] - for i = menu.view_top, math.min( - menu.view_top + osd_menu_lines() - 1, #menu.options) do - local opt = menu.options[i] - local str = opt.name - local col = colours.option - local icons = '' + return col .. ' » ' .. str +end - local is_empty = opt.type == 'group' and not opt.lazy and - #opt.children == 0 +local function osd_option_icons(opt, info) + local str = '' + if info.selected then + str = colours.selected .. '› ' + end + if opt.id == playing_id then + str = str .. colours.icon_playing .. '\226\143\186 ' + end + if favourites[opt.id] then + str = str .. colours.icon_favourite .. '★ ' + end + return str +end - if i == menu.cursor and not menu.search_active then - col = colours.selected - icons = col .. '› ' .. icons +local function osd_option_text(opt, info) + local str = opt.name + local col = colours.option + if info.selected then + col = info.empty and colours.selected_empty or colours.selected + elseif info.empty then + col = colours.group_empty + elseif opt.type == 'group' then + col = colours.group + end - if is_empty then - col = colours.selected_empty - end - elseif is_empty then - col = colours.group_empty - elseif opt.type == 'group' then - col = colours.group + if opt.matches then + local buf = '' + local hl_col = info.empty and colours.search_hl_empty or + colours.search_hl + local n = 0 + + for _, match in ipairs(opt.matches) do + buf = buf .. col .. + asscape(str:sub(n + 1, match.start - 1)) .. + hl_col .. + asscape(str:sub(match.start, match.stop)) + n = match.stop end + str = buf .. col .. asscape(str:sub(n + 1)) + else + str = col .. asscape(str) + end - if opt.matches then - local buf = '' - local n = 0 - local hl_col = colours.search_hl - if is_empty then - hl_col = colours.search_hl_empty - end + if opt.type == 'group' then + str = col .. '[' .. str .. ']' + end - for _, match in ipairs(opt.matches) do - buf = buf .. col .. - str:sub(n + 1, match.start - 1) .. - hl_col .. - str:sub(match.start, match.stop) - n = match.stop - end - str = buf .. col .. str:sub(n + 1) - else - str = col .. str - end + return str +end - if opt.type == 'group' then - str = col .. '[' .. str .. ']' - elseif opt.id == playing_id then - icons = icons .. colours.icon_playing .. '\226\143\186 ' - end +local function osd_option_path(opt, info) + if not opt.path or #opt.path == 0 then + return '' + end - if favourites[opt.id] then - icons = icons .. colours.icon_favourite .. '★ ' - end + local str = info.empty and colours.search_path_empty or + colours.search_path + for i = #opt.path, 1, -1 do + str = str .. ' « ' .. asscape(opt.path[i].name) + end + return str +end - if opt.path and #opt.path > 0 then - local path = colours.search_path - if is_empty then - path = colours.search_path_empty - end - for i = #opt.path, 1, -1 do - local node = opt.path[i] - path = path .. ' « ' .. node.name - end - str = str .. path +local function update_osd() + local out = {} + + if depth > 1 then + for i = 2, depth do + out[#out+1] = osd_menu_title(menus[i]) end + out[#out+1] = ' ' -- space character for correct line height + end - out[#out+1] = icons .. str + local menu = menus[depth] + for i = menu.view_top, math.min( + menu.view_top + osd_menu_lines() - 1, #menu.options) do + local opt = menu.options[i] + local info = { + selected=(i == menu.cursor and not menu.search_active), + empty=(opt.type == 'group' and not opt.lazy and + #opt.children == 0), + } + out[#out+1] = osd_option_icons(opt, info) .. + osd_option_text(opt, info) .. + osd_option_path(opt, info) end -- \q2 disables line wrapping @@ -480,18 +508,6 @@ local function favourite_option() update_osd() end -local function split_search_text() - local menu = menus[depth] - return menu.search_text:sub(1, menu.search_cursor - 1), - menu.search_text:sub(menu.search_cursor) -end - -local function update_search_osd() - local bc, ac = split_search_text() - menus[depth].title = 'Searching: ' .. bc .. osd_cursor_glyph .. ac - update_osd() -end - local function search_menu_options_build(options, t, path) local menu = menus[depth] local path = path or {} @@ -534,7 +550,7 @@ local function update_search_matches() if #menu.search_text == 0 then menu.options = menu.search_options - update_search_osd() + update_osd() return end @@ -567,7 +583,7 @@ local function update_search_matches() end menu.options = options - update_search_osd() + update_osd() end local function search_input_char(event) @@ -576,8 +592,8 @@ local function search_input_char(event) end local menu = menus[depth] - local bc, ac = split_search_text() - menu.search_text = bc .. event.key_text .. ac + menu.search_text = menu.search_text:sub(1, menu.search_cursor - 1) .. + event.key_text .. menu.search_text:sub(menu.search_cursor) menu.search_cursor = menu.search_cursor + #event.key_text update_search_matches() end @@ -615,7 +631,7 @@ local function set_search_cursor(pos) end menu.search_cursor = pos - update_search_osd() + update_osd() end local function search_cursor_left() @@ -643,13 +659,15 @@ local function start_search() local menu = menus[depth] if menu.type == 'search' then -- resume search + menu.title = 'Searching: <text_with_cursor>' menu.search_active = true menu.search_cursor = #menu.search_text + 1 menu.cursor = 1 menu.view_top = 1 - update_search_osd() + update_osd() else push_menu({ + title='Searching: <text_with_cursor>', type='search', search_active=true, search_options=search_menu_options(menu.options), @@ -665,7 +683,7 @@ end local function end_search() local menu = menus[depth] menu.search_active = false - menu.title = 'Search results: ' .. menu.search_text + menu.title = 'Search results: <text>' update_osd() bind_menu_keys() end @@ -742,7 +760,7 @@ local function toggle_menu() end mp.register_event('start-file', function() - playing_id = tonumber(mp.get_opt('iptv_menu.playing_id')) + playing_id = mp.get_opt('iptv_menu.playing_id') update_osd() end) |