nirish

config files for niri window manager
Log | Files | Refs | README | LICENSE

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