cursor.lua (4499B)
1 -------------------------------------------------------------------------------------------------------- 2 --------------------------------Scroll/Select Implementation-------------------------------------------- 3 -------------------------------------------------------------------------------------------------------- 4 -------------------------------------------------------------------------------------------------------- 5 6 local g = require 'modules.globals' 7 local fb_utils = require 'modules.utils' 8 local ass = require 'modules.ass' 9 10 ---@class cursor 11 local cursor = {} 12 13 --disables multiselect 14 function cursor.disable_select_mode() 15 g.state.multiselect_start = nil 16 g.state.initial_selection = nil 17 end 18 19 --enables multiselect 20 function cursor.enable_select_mode() 21 g.state.multiselect_start = g.state.selected 22 g.state.initial_selection = fb_utils.copy_table(g.state.selection) 23 end 24 25 --calculates what drag behaviour is required for that specific movement 26 local function drag_select(original_pos, new_pos) 27 if original_pos == new_pos then return end 28 29 local setting = g.state.selection[g.state.multiselect_start or -1] 30 for i = original_pos, new_pos, (new_pos > original_pos and 1 or -1) do 31 --if we're moving the cursor away from the starting point then set the selection 32 --otherwise restore the original selection 33 if i > g.state.multiselect_start then 34 if new_pos > original_pos then 35 g.state.selection[i] = setting 36 elseif i ~= new_pos then 37 g.state.selection[i] = g.state.initial_selection[i] 38 end 39 elseif i < g.state.multiselect_start then 40 if new_pos < original_pos then 41 g.state.selection[i] = setting 42 elseif i ~= new_pos then 43 g.state.selection[i] = g.state.initial_selection[i] 44 end 45 end 46 end 47 end 48 49 --moves the selector up and down the list by the entered amount 50 function cursor.scroll(n, wrap) 51 local num_items = #g.state.list 52 if num_items == 0 then return end 53 54 local original_pos = g.state.selected 55 56 if original_pos + n > num_items then 57 g.state.selected = wrap and 1 or num_items 58 elseif original_pos + n < 1 then 59 g.state.selected = wrap and num_items or 1 60 else 61 g.state.selected = original_pos + n 62 end 63 64 if g.state.multiselect_start then drag_select(original_pos, g.state.selected) end 65 ass.update_ass() 66 end 67 68 --selects the first item in the list which is highlighted as playing 69 function cursor.select_playing_item() 70 for i,item in ipairs(g.state.list) do 71 if ass.highlight_entry(item) then 72 g.state.selected = i 73 return 74 end 75 end 76 end 77 78 --scans the list for which item to select by default 79 --chooses the folder that the script just moved out of 80 --or, otherwise, the item highlighted as currently playing 81 function cursor.select_prev_directory() 82 -- makes use of the directory stack to more exactly select the prev directory 83 local down_stack = g.directory_stack.stack[g.directory_stack.position + 1] 84 if down_stack then 85 for i, item in ipairs(g.state.list) do 86 if fb_utils.get_new_directory(item, g.state.directory) == down_stack then 87 g.state.selected = i 88 return 89 end 90 end 91 end 92 93 if g.state.prev_directory:find(g.state.directory, 1, true) == 1 then 94 for i, item in ipairs(g.state.list) do 95 if 96 g.state.prev_directory:find(fb_utils.get_full_path(item), 1, true) or 97 g.state.prev_directory:find(fb_utils.get_new_directory(item, g.state.directory), 1, true) 98 then 99 g.state.selected = i 100 return 101 end 102 end 103 end 104 105 cursor.select_playing_item() 106 end 107 108 --toggles the selection 109 function cursor.toggle_selection() 110 if not g.state.list[g.state.selected] then return end 111 g.state.selection[g.state.selected] = not g.state.selection[g.state.selected] or nil 112 ass.update_ass() 113 end 114 115 --select all items in the list 116 function cursor.select_all() 117 for i,_ in ipairs(g.state.list) do 118 g.state.selection[i] = true 119 end 120 ass.update_ass() 121 end 122 123 --toggles select mode 124 function cursor.toggle_select_mode() 125 if g.state.multiselect_start == nil then 126 cursor.enable_select_mode() 127 cursor.toggle_selection() 128 else 129 cursor.disable_select_mode() 130 ass.update_ass() 131 end 132 end 133 134 return cursor