diff --git a/mtmenu/mtmenu.lua b/mtmenu/mtmenu.lua new file mode 100644 index 0000000..c76f3e6 --- /dev/null +++ b/mtmenu/mtmenu.lua @@ -0,0 +1,85 @@ +local event = require "event" +local mtmenu = {} +local mx, my + +local ssub = (unicode or {}).sub or string.sub + +function mtmenu.getScreenSize() + if mx and my then return mx, my end + io.write("\27[999;999H") + mx, my = mtmenu.getCursor() + return mx, my +end + +function mtmenu.getCursor() + io.write("\27[6n") + local b = "" + repeat + b = b .. io.read(1) + until b:match("\27%[%d+;%d+R") + local y,x = b:match("\27%[(%d+);(%d+)R") + return tonumber(x), tonumber(y) +end + +function mtmenu.setStatus(str) + local ox, oy = mtmenu.getCursor() + status = str + io.write(string.format("\27[%d;1H\27[0m\27[7m\27[2K%s\27[0m\27[%i;%iH", my, status, oy, ox)) +end + +function mtmenu.menu(items, state) + local mx, my = mtmenu.getScreenSize() + local state = state or {1,1} + local i, si = state[1], state[2] + while true do + if si > i - 3 then + si = math.max(1, i-5) + elseif i > (si+my) - 6 then + si = math.min(i - (my-3) + 5, #items - (my - 3)) + end + i = math.max(1,math.min(#items, i)) + print(string.format("\27[H\27[0m\27[7m\27[2K%s\27[0m", items.header or "")) + for j = si, (si+my)-3 do + print((i==j and "\27[7m" or "\27[0m") .. "\27[2K" .. (items[j] or ""):sub(1,mx)) + end + mtmenu.setStatus(items.status) + local _,_,ch,co = event.pull(60,"key_down") + ch=string.char(ch or 0) + if co == 208 then -- down + i = i + 1 + elseif co == 200 then -- up + i = i - 1 + elseif co == 201 then -- pgdn + i = i - (my - 2) + elseif co == 209 then -- pgdn + i = i + my - 2 + else + return i, ch, co, {i, si} + end + end +end + +function mtmenu.popup(str,title,state) + local mx, my = mtmenu.getScreenSize() + local len = (unicode or {}).len or string.len + if title then + title=string.format("[%s]",title or "") + else + title = "" + end + local width, height, content = 0, 0, {} + for line in str:gmatch("[^\n]*") do + height = height + 1 + width = math.max(width,len(line)) + content[#content+1] = line + end + if width < 1 or height < 1 then return false end + local startx,starty = ((mx//2)-(width//2))-2, ((my//2)-(height//2))-2 + io.write(string.format("\27[%d;%dH╒═%s%s╕",starty,startx,title,("═"):rep((width+1)-len(title)))) + for k,v in pairs(content) do + io.write(string.format("\27[%d;%dH│ %s%s │",starty+k,startx,v,(" "):rep(width-len(v)))) + end + io.write(string.format("\27[%d;%dH┕%s┙",starty+1+#content,startx,("━"):rep(width+2))) +end + +return mtmenu