From 37594f3a65decbff22588716948553743e1b31de Mon Sep 17 00:00:00 2001 From: Reuh Date: Tue, 28 Aug 2018 21:10:30 +0200 Subject: [PATCH] Fixed file= search, playlist clearing, some interface fixes --- daccord.can | 45 +++++++++++++++++++++++++++++----------- gui.can | 60 +++++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 78 insertions(+), 27 deletions(-) diff --git a/daccord.can b/daccord.can index 1a5cb80..00768b0 100644 --- a/daccord.can +++ b/daccord.can @@ -13,9 +13,11 @@ -- * Control+A add all the results to the playlist. -- * Enter add currently selected song to the playlist. -- * Type "TagName=" to trigger tag completion: select a tag and press Enter to select it. Or type it manually and exit tag completion by typing a space. +-- * Type "File=" to trigger filename search. -- * In current playlist: -- * Enter play currently selected song. -- * Delete remove selected song from playlist. +-- * Control+Delete clear the playlist. -- -- Most of what was initialy planned isn't implemented yet. Hopefully all will be finished before you're six feet under. -- @@ -65,7 +67,7 @@ let config = { port = 6600, password = "", -- Default behaviour - filenameSearch = false, -- instant search search also in filename (not only tags), slower + filenameSearch = false, -- instant search search also in filename (not only when using the file= syntax), slower -- Interface songDisplay = { "Track", { "Title", "file" }, "Artist", "Album" } -- list of tags or list of alternative tags (first one to exist will be used) to display for each song } @@ -89,7 +91,7 @@ end -- Connect mpc.log = () end -mpc = mpc("localhost", 6600) +mpc = mpc(config.host, config.port) if config.password ~= "" then mpc:password(config.password) end @@ -101,7 +103,6 @@ let tags = [ push t.tagtype end ] -table.insert(tags, "file") -- State let tagCompleting = { @@ -146,14 +147,17 @@ gui { start, sel, val, stop = @sub(1, @cursorPosition):match("()([A-Za-z_]+)=\"([^\"]*)()$") end + -- music tags for _, tag in ipairs(tags) do if tag:lower() == sel:lower() then let r, songs = mpc:list(tag) - if r then results = songs end - - for _, s in ipairs(results) do - if s[tag]:lower():match(val:lower()) then -- filter val - list:insert{tostring(s[tag])} + if r then + results = {} + for _, s in ipairs(songs) do + if s[tag]:lower():match(val:lower()) then -- filter val + table.insert(results, s) + list:insert{tostring(s[tag])} + end end end @@ -164,6 +168,23 @@ gui { break end end + -- file search + if sel:lower() == "file" then + let r, songs = mpc:list("file") + if r then + results = {} + for _, s in ipairs(songs) do + if s.file:lower():match(val:lower()) then -- filter val + table.insert(results, s) + list:insert{tostring(s.file)} + end + end + end + + tagCompleting.tag = "file" + tagCompleting.start = start + tagCompleting.stop = stop + end -- Song search else -- Build query @@ -285,10 +306,7 @@ gui { for i, s in ipairs(playlist) do let item = songTable(s) if @content[i] then - if @content[i] ~= item then - @remove(i) - @insert(i, item) - end + @replace(i, item) else @insert(i, item) end @@ -309,6 +327,9 @@ gui { if control == "delete" then mpc:deleteid(playlist[@selected].Id) @remove(@selected) + elseif control == "clear" then + mpc:clear() + @clear() end end } diff --git a/gui.can b/gui.can index 7ea324c..5b21c0b 100644 --- a/gui.can +++ b/gui.can @@ -126,6 +126,17 @@ let widgets = setmetatable({ @cursorPosition -= 1 @onTextInput() end + elseif control == "delete" then + screen:mvdelch(y, x) + if @cursorPosition <= utf8.len(@content) then + if @cursorPosition == 1 then -- utf8.offset(s, 0) returns the start of the last character, ie something we don't want + @content = @content:sub(utf8.offset(@content, @cursorPosition+1)) + else + @content = @content:sub(1, utf8.offset(@content, @cursorPosition)-1) + .. @content:sub(utf8.offset(@content, @cursorPosition+1)) + end + @onTextInput() + end elseif control == "right" then if @cursorPosition <= utf8.len(@content) then screen:addstr(@content:sub(utf8.offset(@content, @cursorPosition), utf8.offset(@content, @cursorPosition+1)-1)) @@ -185,18 +196,26 @@ let widgets = setmetatable({ scroll = 0, _redraw = true, _input = :(charbuffer, control) - if control == "up" and @selected > 1 then + if control == "up" then @selected -= 1 - if @selected == @scroll then - @scroll -= 1 - end @_redraw = true - elseif control == "down" and @selected < #@content then + elseif control == "down" then @selected += 1 - if @selected == @scroll + @h + 1 then - @scroll += 1 - end @_redraw = true + elseif control == "pgup" then + @selected -= 10 + @_redraw = true + elseif control == "pgdown" then + @selected += 10 + @_redraw = true + end + @selected = math.min(math.max(@selected, 1), math.max(#@content, 1)) + + while @selected <= @scroll do + @scroll -= 1 + end + while @selected >= @scroll + @h + 1 do + @scroll += 1 end if control == "enter" then @@ -218,8 +237,7 @@ let widgets = setmetatable({ end let colx = @parent.x+@x for c=1, #@columnWidth do - screen:mvaddstr(@parent.y+@y+i-1-@scroll, colx, (""):rep(@columnWidth[c])) -- FIXME: too lazy to do this the right way and extract utf8 substrings (also should probably check if the thing doesn't go too right) - screen:mvaddstr(@parent.y+@y+i-1-@scroll, colx, @content[i] and @content[i][c] or "") + screen:mvaddstr(@parent.y+@y+i-1-@scroll, colx, @content[i] and @content[i][c] or "") -- TODO: make sure it doesn't go too far right or something colx += @columnWidth[c] end if i == @selected then @@ -231,7 +249,7 @@ let widgets = setmetatable({ insert = :(pos, item) if item then table.insert(@content, pos, item) - if @selected >= pos and #@content > 1 then + if @selected > pos and @selected < #@content then @selected += 1 end else @@ -243,7 +261,8 @@ let widgets = setmetatable({ end if #item >= #@columnWidth then -- if the column fits into our dictatorship, update column width for c=1, #@columnWidth do - if utf8.len(item[c]) > @columnWidth[c] then + let l = utf8.len(item[c]) -- if it isn't valid UTF8, ignore (can happen for files in Windows-made zipfiles). Should probably raise a warning or something... TODO. + if l and l > @columnWidth[c] then @columnWidth[c] = utf8.len(item[c]) + 1 end end @@ -252,14 +271,19 @@ let widgets = setmetatable({ end, remove = :(pos=#@content) table.remove(@content, pos) - if @selected >= pos and @selected > 1 then + if @selected > pos and @selected > 1 then @selected -= 1 end + @selected = math.min(@selected, #@content) + @_redraw = true + end, + replace = :(pos, item) + @content[pos] = item @_redraw = true end, clear = :() - @.content = {} - --@.columnWidth = {} + @content = {} + @columnWidth = {} @_redraw = true @selected = 1 @scroll = 0 @@ -419,10 +443,16 @@ return (ui) control = "up" elseif k == "[B" then control = "down" + elseif k == "[5" then + control = "pgup" + elseif k == "[6" then + control = "pgdown" elseif k == "[3" then k ..= string.char(screen:getch()) if k == "[3~" then control = "delete" + elseif k == "[3;" then + control = "clear" else error("unknown control "..tostring(k)) end