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