Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --backup color
- local fg,bg=term.getTextColor(),term.getBackgroundColor()
- --init file locals
- local file1,st_file
- local lzssepm_code=[===[-- LZSS SEP-Maker
- --
- -- This program was made to create self-extracting archives.
- --
- -- That kind of self-extracting programs(SEP) has built-in LZSS
- -- unpack function, so they can be launched without LZSS installed.
- -- You can run them with pastebin or wget or directly from
- -- shell (or.run is posible but unrecomended)
- -- Help message
- local tArgs={...}
- if not ... then print"Usage: <src> [dest] [wget] [uneffective] [rewrite]"return end
- --main part (part that will be inserted at the start of file)
- local extractor_base=[==[P=P:sub(SiZ,ZiS)while#P>=o do f=P:byte(o)o=o+1
- for _=0,7 do s=nil
- if 0<A(f,1)then
- if#P>=o then s=S(P,o,o)o=o+1
- end
- elseif#P>=o+1 then
- t=('>I2'):unpack(P,o)p=1+R(t,4)s=S(w,p,p+A(t,15)+2)o=o+2
- end
- f=R(f,1)if s then w=S(w..s,-4096)r=r..s end
- end
- end
- return load(r,O,nil,_ENV)(...)--[]==]
- --advanced extractor (biger then default, but can be launched directly from wget/pastebin)
- local extractor_wget=[==[local D,A,R,o,r,w,f,t,p,s,S,O,G,L,P=debug or{},bit32.band,bit32.rshift,1,'',''G=D.getinfo or r.char
- L=D.getlocal
- O=(G(3)or{}).source or""P=O:find"wget.lua$"and 4 or O:find"pastebin.lua$"and 6 or P
- S=O.sub
- if P then D,O=L(3,P)D,P=L(3,7)else L=shell O=L and"@/"..L.resolveProgram(arg[0])or(G(1)or{}).source or""D,L=io.open(S(O,2),'rb')L=L and error(L)P=D:read"*a"D:close()end
- ]==]
- --default extractor (can start from file only, but smaller)
- local extractor_def =[==[local D,A,R,L,o,r,w,f,t,p,s,S,O,P=debug or{},bit32.band,bit32.rshift,shell,1,'',''S=r.sub
- O=L and"@/"..L.resolveProgram(arg[0])or(D.getinfo or r.char)(1).source or""D,L=io.open(S(O,2),'rb')L=L and error(L)P=D:read"*a"D:close()]==]
- -- "@/" - needed to make chunknames of packed programs similar to unpacked ones
- -- read source
- local eq_count=0
- local file=fs.open(...or"",'r') or error"LZSS> Can't open source file..."
- local before=file.readAll()
- local prog=lzss.pack(before)
- file.close()
- -- choose/print extractor
- local wget
- write"LZSSEPM> Add wget/pastebin support? [Y/n]: "
- if tArgs[3]=="true"or tArgs[3]=="Y"or tArgs[3]=="y"then print(tArgs[3]) wget=1
- elseif tArgs[3]=="false" or tArgs[3]=="N"or tArgs[3]=="n" then print(tArgs[3])
- else
- wget = read():find"^[Yy]"
- end
- print("LZSSEPM> Extractor type :",wget and"WGET/PASTEBIN Support"or"Default")
- local extractor = (wget and extractor_wget or extractor_def)..extractor_base
- print(("LZSSEPM> Extractor size : %.2f"):format(#extractor/1024),"Kb's\n")
- -- make container for compressed code
- k=false
- repeat
- if prog:find('([%[%]])'..("="):rep(eq_count)..'%1') then
- eq_count=eq_count+1
- else
- k=true
- end
- until k
- --print stats
- print(("LZSSEPM> Default size : %.2f"):format(#before/1024),"Kb's")
- print(("LZSSEPM> After LZSS size: %.2f"):format(#prog/1024),"Kb's")
- print(("LZSSEPM> Final size : %.2f"):format((#prog+#extractor+3+eq_count*2)/1024),"Kb's\n")
- --Warning if compression is bad
- if #before <= #prog+#extractor+3+eq_count*2 then
- print"LZSSEPM> Ineffective compression!"
- write"LZSSEPM> Continue? [Y/n]: "
- if tArgs[4]=="false"or tArgs[4]=="N" or tArgs[4]=="n"then print(tArgs[4])return
- elseif tArgs[4]=="true"or tArgs[4]=="Y" or tArgs[4]=="y"then print(tArgs[4])
- elseif read():find"^[^Yy]" then return
- end
- print()
- end
- -- set dest file
- local dest = tArgs[2] or ... .. ".sep"
- if fs.exists(dest) then
- print"LZSSEPM> Destination already exists!"
- write"LZSSEPM> Continue? [Y/n]: "
- if tArgs[5]=="true"or tArgs[5]=="Y"or tArgs[5]=="y"then print(tArgs[5])
- elseif tArgs[5]=="false"or tArgs[5]=="N"or tArgs[5]=="n"then print(tArgs[5])return
- elseif read():find"^[^Yy]"then return
- end
- end
- -- write dest file
- file=fs.open(dest,'wb')
- file.write(extractor:gsub("SiZ",#extractor+2+eq_count):gsub("ZiS",("%.2d"):format(-3-eq_count)))--extractior
- file.write(("="):rep(eq_count).."["..prog.."]"..("="):rep(eq_count).."]")--code
- file.close()
- print("LZSSEPM> Packing complete:",dest)]===]
- local startup_code=[===[local path,comp,fl,ch="PATH_R",require"cc.shell.completion"
- fl={comp.file,true}
- ch={comp.choice,{"true ","false "}}
- shell.setAlias("lzssepm",path)
- shell.setCompletionFunction(path,comp.build(fl,fl,ch,ch,ch))]===]
- --Install function
- local install = function(lzssepm_path,lzssepm,startup)
- startup_code=startup_code:gsub("PATH_R",fs.combine(lzssepm_path))
- lzssepm.write(lzssepm_code)--make prog
- startup.write(startup_code)--make startup
- end
- --QUITE RUN
- --Args: -lzss=*path_to_lzssepm_path* --startup=*startup_file* --func
- if #{...}>0 then --quite run
- local type_api="Minified LZSS"
- local path_to_lzssepm
- local path_to_startup
- local install_prog=false
- for _,k in pairs{...}do --for all args
- if k:find"^%-S=" or k:find"^%-%-startup=" then --install startup (path to startup)
- path_to_startup=k:match"=(.+)$"
- print("LZSSEPM> startup:",path_to_startup)
- elseif k:find"^%-P" or k:find"^%-%-program" then --install the LZSS shell Launcher (simple archiver with size of 598 bytes
- install_prog=true
- print("LZSSEPM> prog:",path_to_lzssepm)
- elseif k:find"^%-H" or k:find"^%-%-help" then
- print("Usage:\n"..
- " lzssepm_install *no_args* --launch UI\n"..
- "\n"..
- " -H --help --Show this message and exit\n"..
- " -S=*path* --startup=*path*\n"..
- " --Set the path to startup file\n"..
- " -P --program=*path*\n"..
- " --Set the path to program file")
- return
- else
- error("Unexpected argument: "..k)
- end
- end
- if not path_to_lzssepm then error"Path to instalation file not set! Use <-P=*path_to_file*> or <--prog=*path_to_file*>.\nP.S:(You can launch lzssepm_install with no args to use GUI)"end
- local tmp1,err1=fs.open(fs.combine(path_to_lzssepm),"w")
- file1=tmp1 or error(err1)
- if not path_to_lzssepm then error"Path to startup file not set! Use <-S=*path_to_file*> or <--startup=*path_to_file*>.\nP.S:(You can launch lzssepm_install with no args to use GUI)"end
- local tmp3,err3=fs.open(path_to_startup,"w")
- st_file=tmp3 or error(err3)
- install(path_to_lzssepm,file1,st_file)
- print("LZSSEPM> Instalation complete...")
- print("LZSSEPM> Please reload OS...")
- else --no args - interface launch required
- ------------------------------------------------------------------------------------
- ------------------------------------------------------------------------------------
- ------------------------------------------------------------------------------------
- --PrimeUI INIT SECTION (This part of code was created by JackMacWindows)
- local expect = require "cc.expect".expect
- -- Initialization code
- local PrimeUI = {}
- do
- local coros = {}
- local restoreCursor
- --- Adds a task to run in the main loop.
- ---@param func function The function to run, usually an `os.pullEvent` loop
- function PrimeUI.addTask(func)
- expect(1, func, "function")
- local t = {coro = coroutine.create(func)}
- coros[#coros+1] = t
- _, t.filter = coroutine.resume(t.coro)
- end
- --- Sends the provided arguments to the run loop, where they will be returned.
- ---@param ... any The parameters to send
- function PrimeUI.resolve(...)
- coroutine.yield(coros, ...)
- end
- --- Clears the screen and resets all components. Do not use any previously
- --- created components after calling this function.
- function PrimeUI.clear()
- -- Reset the screen.
- term.setCursorPos(1, 1)
- term.setCursorBlink(false)
- term.setBackgroundColor(colors.black)
- term.setTextColor(colors.white)
- term.clear()
- -- Reset the task list and cursor restore function.
- coros = {}
- restoreCursor = nil
- end
- --- Sets or clears the window that holds where the cursor should be.
- ---@param win window|nil The window to set as the active window
- function PrimeUI.setCursorWindow(win)
- expect(1, win, "table", "nil")
- restoreCursor = win and win.restoreCursor
- end
- --- Gets the absolute position of a coordinate relative to a window.
- ---@param win window The window to check
- ---@param x number The relative X position of the point
- ---@param y number The relative Y position of the point
- ---@return number x The absolute X position of the window
- ---@return number y The absolute Y position of the window
- function PrimeUI.getWindowPos(win, x, y)
- if win == term then return x, y end
- while win ~= term.native() and win ~= term.current() do
- if not win.getPosition then return x, y end
- local wx, wy = win.getPosition()
- x, y = x + wx - 1, y + wy - 1
- _, win = debug.getupvalue(select(2, debug.getupvalue(win.isColor, 1)), 1) -- gets the parent window through an upvalue
- end
- return x, y
- end
- --- Runs the main loop, returning information on an action.
- ---@return any ... The result of the coroutine that exited
- function PrimeUI.run()
- while true do
- -- Restore the cursor and wait for the next event.
- if restoreCursor then restoreCursor() end
- local ev = table.pack(os.pullEvent())
- -- Run all coroutines.
- for _, v in ipairs(coros) do
- if v.filter == nil or v.filter == ev[1] then
- -- Resume the coroutine, passing the current event.
- local res = table.pack(coroutine.resume(v.coro, table.unpack(ev, 1, ev.n)))
- -- If the call failed, bail out. Coroutines should never exit.
- if not res[1] then error(res[2], 2) end
- -- If the coroutine resolved, return its values.
- if res[2] == coros then return table.unpack(res, 3, res.n) end
- -- Set the next event filter.
- v.filter = res[2]
- end
- end
- end
- end
- end
- --- Draws a line of text at a position.
- ---@param win window The window to draw on
- ---@param x number The X position of the left side of the text
- ---@param y number The Y position of the text
- ---@param text string The text to draw
- ---@param fgColor color|nil The color of the text (defaults to white)
- ---@param bgColor color|nil The color of the background (defaults to black)
- function PrimeUI.label(win, x, y, text, fgColor, bgColor)
- expect(1, win, "table")
- expect(2, x, "number")
- expect(3, y, "number")
- expect(4, text, "string")
- fgColor = expect(5, fgColor, "number", "nil") or colors.white
- bgColor = expect(6, bgColor, "number", "nil") or colors.black
- win.setCursorPos(x, y)
- win.setTextColor(fgColor)
- win.setBackgroundColor(bgColor)
- win.write(text)
- end
- --- Draws a horizontal line at a position with the specified width.
- ---@param win window The window to draw on
- ---@param x number The X position of the left side of the line
- ---@param y number The Y position of the line
- ---@param width number The width/length of the line
- ---@param fgColor color|nil The color of the line (defaults to white)
- ---@param bgColor color|nil The color of the background (defaults to black)
- function PrimeUI.horizontalLine(win, x, y, width, fgColor, bgColor)
- expect(1, win, "table")
- expect(2, x, "number")
- expect(3, y, "number")
- expect(4, width, "number")
- fgColor = expect(5, fgColor, "number", "nil") or colors.white
- bgColor = expect(6, bgColor, "number", "nil") or colors.black
- -- Use drawing characters to draw a thin line.
- win.setCursorPos(x, y)
- win.setTextColor(fgColor)
- win.setBackgroundColor(bgColor)
- win.write(("\x8C"):rep(width))
- end
- --- Creates a clickable button on screen with text.
- ---@param win window The window to draw on
- ---@param x number The X position of the button
- ---@param y number The Y position of the button
- ---@param text string The text to draw on the button
- ---@param action function|string A function to call when clicked, or a string to send with a `run` event
- ---@param fgColor color|nil The color of the button text (defaults to white)
- ---@param bgColor color|nil The color of the button (defaults to light gray)
- ---@param clickedColor color|nil The color of the button when clicked (defaults to gray)
- function PrimeUI.button(win, x, y, text, action, fgColor, bgColor, clickedColor)
- expect(1, win, "table")
- expect(2, x, "number")
- expect(3, y, "number")
- expect(4, text, "string")
- expect(5, action, "function", "string")
- fgColor = expect(6, fgColor, "number", "nil") or colors.white
- bgColor = expect(7, bgColor, "number", "nil") or colors.gray
- clickedColor = expect(8, clickedColor, "number", "nil") or colors.lightGray
- -- Draw the initial button.
- win.setCursorPos(x, y)
- win.setBackgroundColor(bgColor)
- win.setTextColor(fgColor)
- win.write(" " .. text .. " ")
- -- Get the screen position and add a click handler.
- PrimeUI.addTask(function()
- local buttonDown = false
- while true do
- local event, button, clickX, clickY = os.pullEvent()
- local screenX, screenY = PrimeUI.getWindowPos(win, x, y)
- if event == "mouse_click" and button == 1 and clickX >= screenX and clickX < screenX + #text + 2 and clickY == screenY then
- -- Initiate a click action (but don't trigger until mouse up).
- buttonDown = true
- -- Redraw the button with the clicked background color.
- win.setCursorPos(x, y)
- win.setBackgroundColor(clickedColor)
- win.setTextColor(fgColor)
- win.write(" " .. text .. " ")
- elseif event == "mouse_up" and button == 1 and buttonDown then
- -- Finish a click event.
- if clickX >= screenX and clickX < screenX + #text + 2 and clickY == screenY then
- -- Trigger the action.
- if type(action) == "string" then PrimeUI.resolve("button", action)
- else action() end
- end
- -- Redraw the original button state.
- win.setCursorPos(x, y)
- win.setBackgroundColor(bgColor)
- win.setTextColor(fgColor)
- win.write(" " .. text .. " ")
- end
- end
- end)
- end
- --- Adds an action to trigger when a key is pressed.
- ---@param key key The key to trigger on, from `keys.*`
- ---@param action function|string A function to call when clicked, or a string to use as a key for a `run` return event
- function PrimeUI.keyAction(key, action)
- expect(1, key, "number")
- expect(2, action, "function", "string")
- PrimeUI.addTask(function()
- while true do
- local _, param1 = os.pullEvent("key") -- wait for key
- if param1 == key then
- if type(action) == "string" then PrimeUI.resolve("keyAction", action)
- else action() end
- end
- end
- end)
- end
- --- Adds an action to trigger when a key is pressed with modifier keys.
- ---@param key key The key to trigger on, from `keys.*`
- ---@param withCtrl boolean Whether Ctrl is required
- ---@param withAlt boolean Whether Alt is required
- ---@param withShift boolean Whether Shift is required
- ---@param action function|string A function to call when clicked, or a string to use as a key for a `run` return event
- function PrimeUI.keyCombo(key, withCtrl, withAlt, withShift, action)
- expect(1, key, "number")
- expect(2, withCtrl, "boolean")
- expect(3, withAlt, "boolean")
- expect(4, withShift, "boolean")
- expect(5, action, "function", "string")
- PrimeUI.addTask(function()
- local heldCtrl, heldAlt, heldShift = false, false, false
- while true do
- local event, param1, param2 = os.pullEvent() -- wait for key
- if event == "key" then
- -- check if key is down, all modifiers are correct, and that it's not held
- if param1 == key and heldCtrl == withCtrl and heldAlt == withAlt and heldShift == withShift and not param2 then
- if type(action) == "string" then PrimeUI.resolve("keyCombo", action)
- else action() end
- -- activate modifier keys
- elseif param1 == keys.leftCtrl or param1 == keys.rightCtrl then heldCtrl = true
- elseif param1 == keys.leftAlt or param1 == keys.rightAlt then heldAlt = true
- elseif param1 == keys.leftShift or param1 == keys.rightShift then heldShift = true end
- elseif event == "key_up" then
- -- deactivate modifier keys
- if param1 == keys.leftCtrl or param1 == keys.rightCtrl then heldCtrl = false
- elseif param1 == keys.leftAlt or param1 == keys.rightAlt then heldAlt = false
- elseif param1 == keys.leftShift or param1 == keys.rightShift then heldShift = false end
- end
- end
- end)
- end
- --- Creates a scrollable window, which allows drawing large content in a small area.
- ---@param win window The parent window of the scroll box
- ---@param x number The X position of the box
- ---@param y number The Y position of the box
- ---@param width number The width of the box
- ---@param height number The height of the outer box
- ---@param innerHeight number The height of the inner scroll area
- ---@param allowArrowKeys boolean|nil Whether to allow arrow keys to scroll the box (defaults to true)
- ---@param showScrollIndicators boolean|nil Whether to show arrow indicators on the right side when scrolling is available, which reduces the inner width by 1 (defaults to false)
- ---@param fgColor number|nil The color of scroll indicators (defaults to white)
- ---@param bgColor color|nil The color of the background (defaults to black)
- ---@return window inner The inner window to draw inside
- function PrimeUI.scrollBox(win, x, y, width, height, innerHeight, allowArrowKeys, showScrollIndicators, fgColor, bgColor)
- expect(1, win, "table")
- expect(2, x, "number")
- expect(3, y, "number")
- expect(4, width, "number")
- expect(5, height, "number")
- expect(6, innerHeight, "number")
- expect(7, allowArrowKeys, "boolean", "nil")
- expect(8, showScrollIndicators, "boolean", "nil")
- fgColor = expect(9, fgColor, "number", "nil") or colors.white
- bgColor = expect(10, bgColor, "number", "nil") or colors.black
- if allowArrowKeys == nil then allowArrowKeys = true end
- -- Create the outer container box.
- local outer = window.create(win == term and term.current() or win, x, y, width, height)
- outer.setBackgroundColor(bgColor)
- outer.clear()
- -- Create the inner scrolling box.
- local inner = window.create(outer, 1, 1, width - (showScrollIndicators and 1 or 0), innerHeight)
- inner.setBackgroundColor(bgColor)
- inner.clear()
- -- Draw scroll indicators if desired.
- if showScrollIndicators then
- outer.setBackgroundColor(bgColor)
- outer.setTextColor(fgColor)
- outer.setCursorPos(width, height)
- outer.write(innerHeight > height and "\31" or " ")
- end
- -- Get the absolute position of the window.
- x, y = PrimeUI.getWindowPos(win, x, y)
- -- Add the scroll handler.
- PrimeUI.addTask(function()
- local scrollPos = 1
- while true do
- -- Wait for next event.
- local ev = table.pack(os.pullEvent())
- -- Update inner height in case it changed.
- innerHeight = select(2, inner.getSize())
- -- Check for scroll events and set direction.
- local dir
- if ev[1] == "key" and allowArrowKeys then
- if ev[2] == keys.up then dir = -1
- elseif ev[2] == keys.down then dir = 1 end
- elseif ev[1] == "mouse_scroll" and ev[3] >= x and ev[3] < x + width and ev[4] >= y and ev[4] < y + height then
- dir = ev[2]
- end
- -- If there's a scroll event, move the window vertically.
- if dir and (scrollPos + dir >= 1 and scrollPos + dir <= innerHeight - height) then
- scrollPos = scrollPos + dir
- inner.reposition(1, 2 - scrollPos)
- end
- -- Redraw scroll indicators if desired.
- if showScrollIndicators then
- outer.setBackgroundColor(bgColor)
- outer.setTextColor(fgColor)
- outer.setCursorPos(width, 1)
- outer.write(scrollPos > 1 and "\30" or " ")
- outer.setCursorPos(width, height)
- outer.write(scrollPos < innerHeight - height and "\31" or " ")
- end
- end
- end)
- return inner
- end
- --- Creates a text input box.
- ---@param win window The window to draw on
- ---@param x number The X position of the left side of the box
- ---@param y number The Y position of the box
- ---@param width number The width/length of the box
- ---@param action function|string A function or `run` event to call when the enter key is pressed
- ---@param fgColor color|nil The color of the text (defaults to white)
- ---@param bgColor color|nil The color of the background (defaults to black)
- ---@param replacement string|nil A character to replace typed characters with
- ---@param history string[]|nil A list of previous entries to provide
- ---@param completion function|nil A function to call to provide completion
- ---@param default string|nil A string to return if the box is empty
- function PrimeUI.inputBox(win, x, y, width, action, fgColor, bgColor, replacement, history, completion, default)
- expect(1, win, "table")
- expect(2, x, "number")
- expect(3, y, "number")
- expect(4, width, "number")
- expect(5, action, "function", "string")
- fgColor = expect(6, fgColor, "number", "nil") or colors.white
- bgColor = expect(7, bgColor, "number", "nil") or colors.black
- expect(8, replacement, "string", "nil")
- expect(9, history, "table", "nil")
- expect(10, completion, "function", "nil")
- expect(11, default, "string", "nil")
- -- Create a window to draw the input in.
- local box = window.create(win, x, y, width, 1)
- box.setTextColor(fgColor)
- box.setBackgroundColor(bgColor)
- box.clear()
- -- Call read() in a new coroutine.
- PrimeUI.addTask(function()
- -- We need a child coroutine to be able to redirect back to the window.
- local coro = coroutine.create(read)
- -- Run the function for the first time, redirecting to the window.
- local old = term.redirect(box)
- local ok, res = coroutine.resume(coro, replacement, history, completion, default)
- term.redirect(old)
- -- Run the coroutine until it finishes.
- while coroutine.status(coro) ~= "dead" do
- -- Get the next event.
- local ev = table.pack(os.pullEvent())
- -- Redirect and resume.
- old = term.redirect(box)
- ok, res = coroutine.resume(coro, table.unpack(ev, 1, ev.n))
- term.redirect(old)
- -- Pass any errors along.
- if not ok then error(res) end
- end
- -- Send the result to the receiver.
- if type(action) == "string" then PrimeUI.resolve("inputBox", action, res)
- else action(res) end
- -- Spin forever, because tasks cannot exit.
- while true do os.pullEvent() end
- end)
- end
- --- Creates a list of entries with toggleable check boxes.
- ---@param win window The window to draw on
- ---@param x number The X coordinate of the inside of the box
- ---@param y number The Y coordinate of the inside of the box
- ---@param width number The width of the inner box
- ---@param height number The height of the inner box
- ---@param selections {string: string|boolean} A list of entries to show, where the value is whether the item is pre-selected (or `"R"` for required/forced selected)
- ---@param action function|string|nil A function or `run` event that's called when a selection is made
- ---@param fgColor color|nil The color of the text (defaults to white)
- ---@param bgColor color|nil The color of the background (defaults to black)
- function PrimeUI.checkSelectionBox(win, x, y, width, height, selections, action, fgColor, bgColor)
- expect(1, win, "table")
- expect(2, x, "number")
- expect(3, y, "number")
- expect(4, width, "number")
- expect(5, height, "number")
- expect(6, selections, "table")
- expect(7, action, "function", "string", "nil")
- fgColor = expect(8, fgColor, "number", "nil") or colors.white
- bgColor = expect(9, bgColor, "number", "nil") or colors.black
- -- Calculate how many selections there are.
- local nsel = 0
- for _ in pairs(selections) do nsel = nsel + 1 end
- -- Create the outer display box.
- local outer = window.create(win, x, y, width, height)
- outer.setBackgroundColor(bgColor)
- outer.clear()
- -- Create the inner scroll box.
- local inner = window.create(outer, 1, 1, width - 1, nsel)
- inner.setBackgroundColor(bgColor)
- inner.setTextColor(fgColor)
- inner.clear()
- -- Draw each line in the window.
- local lines = {}
- local nl, selected = 1, 1
- for k, v in pairs(selections) do
- inner.setCursorPos(1, nl)
- inner.write((v and (v == "R" and "[-] " or "[\xD7] ") or "[ ] ") .. k)
- lines[nl] = {k, not not v}
- nl = nl + 1
- end
- -- Draw a scroll arrow if there is scrolling.
- if nsel > height then
- outer.setCursorPos(width, height)
- outer.setBackgroundColor(bgColor)
- outer.setTextColor(fgColor)
- outer.write("\31")
- end
- -- Set cursor blink status.
- inner.setCursorPos(2, selected)
- inner.setCursorBlink(true)
- PrimeUI.setCursorWindow(inner)
- -- Get screen coordinates & add run task.
- local screenX, screenY = PrimeUI.getWindowPos(win, x, y)
- PrimeUI.addTask(function()
- local scrollPos = 1
- while true do
- -- Wait for an event.
- local ev = table.pack(os.pullEvent())
- -- Look for a scroll event or a selection event.
- local dir
- if ev[1] == "key" then
- if ev[2] == keys.up then dir = -1
- elseif ev[2] == keys.down then dir = 1
- elseif ev[2] == keys.space and selections[lines[selected][1]] ~= "R" then
- -- (Un)select the item.
- lines[selected][2] = not lines[selected][2]
- inner.setCursorPos(2, selected)
- inner.write(lines[selected][2] and "\xD7" or " ")
- -- Call the action if passed; otherwise, set the original table.
- if type(action) == "string" then PrimeUI.resolve("checkSelectionBox", action, lines[selected][1], lines[selected][2])
- elseif action then action(lines[selected][1], lines[selected][2])
- else selections[lines[selected][1]] = lines[selected][2] end
- -- Redraw all lines in case of changes.
- for i, v in ipairs(lines) do
- local vv = selections[v[1]] == "R" and "R" or v[2]
- inner.setCursorPos(2, i)
- inner.write((vv and (vv == "R" and "-" or "\xD7") or " "))
- end
- inner.setCursorPos(2, selected)
- end
- elseif ev[1] == "mouse_scroll" and ev[3] >= screenX and ev[3] < screenX + width and ev[4] >= screenY and ev[4] < screenY + height then
- dir = ev[2]
- end
- -- Scroll the screen if required.
- if dir and (selected + dir >= 1 and selected + dir <= nsel) then
- selected = selected + dir
- if selected - scrollPos < 0 or selected - scrollPos >= height then
- scrollPos = scrollPos + dir
- inner.reposition(1, 2 - scrollPos)
- end
- inner.setCursorPos(2, selected)
- end
- -- Redraw scroll arrows and reset cursor.
- outer.setCursorPos(width, 1)
- outer.write(scrollPos > 1 and "\30" or " ")
- outer.setCursorPos(width, height)
- outer.write(scrollPos < nsel - height + 1 and "\31" or " ")
- inner.restoreCursor()
- end
- end)
- end
- --- Creates a text box that wraps text and can have its text modified later.
- ---@param win window The parent window of the text box
- ---@param x number The X position of the box
- ---@param y number The Y position of the box
- ---@param width number The width of the box
- ---@param height number The height of the box
- ---@param text string The initial text to draw
- ---@param fgColor color|nil The color of the text (defaults to white)
- ---@param bgColor color|nil The color of the background (defaults to black)
- ---@return function redraw A function to redraw the window with new contents
- function PrimeUI.textBox(win, x, y, width, height, text, fgColor, bgColor)
- expect(1, win, "table")
- expect(2, x, "number")
- expect(3, y, "number")
- expect(4, width, "number")
- expect(5, height, "number")
- expect(6, text, "string")
- fgColor = expect(7, fgColor, "number", "nil") or colors.white
- bgColor = expect(8, bgColor, "number", "nil") or colors.black
- -- Create the box window.
- local box = window.create(win, x, y, width, height)
- -- Override box.getSize to make print not scroll.
- function box.getSize()
- return width, math.huge
- end
- -- Define a function to redraw with.
- local function redraw(_text)
- expect(1, _text, "string")
- -- Set window parameters.
- box.setBackgroundColor(bgColor)
- box.setTextColor(fgColor)
- box.clear()
- box.setCursorPos(1, 1)
- -- Redirect and draw with `print`.
- local old = term.redirect(box)
- print(_text)
- term.redirect(old)
- end
- redraw(text)
- return redraw
- end
- --- Draws a thin border around a screen region.
- ---@param win window The window to draw on
- ---@param x number The X coordinate of the inside of the box
- ---@param y number The Y coordinate of the inside of the box
- ---@param width number The width of the inner box
- ---@param height number The height of the inner box
- ---@param fgColor color|nil The color of the border (defaults to white)
- ---@param bgColor color|nil The color of the background (defaults to black)
- function PrimeUI.borderBox(win, x, y, width, height, fgColor, bgColor)
- expect(1, win, "table")
- expect(2, x, "number")
- expect(3, y, "number")
- expect(4, width, "number")
- expect(5, height, "number")
- fgColor = expect(6, fgColor, "number", "nil") or colors.white
- bgColor = expect(7, bgColor, "number", "nil") or colors.black
- -- Draw the top-left corner & top border.
- win.setBackgroundColor(bgColor)
- win.setTextColor(fgColor)
- win.setCursorPos(x - 1, y - 1)
- win.write("\x9C" .. ("\x8C"):rep(width))
- -- Draw the top-right corner.
- win.setBackgroundColor(fgColor)
- win.setTextColor(bgColor)
- win.write("\x93")
- -- Draw the right border.
- for i = 1, height do
- win.setCursorPos(win.getCursorPos() - 1, y + i - 1)
- win.write("\x95")
- end
- -- Draw the left border.
- win.setBackgroundColor(bgColor)
- win.setTextColor(fgColor)
- for i = 1, height do
- win.setCursorPos(x - 1, y + i - 1)
- win.write("\x95")
- end
- -- Draw the bottom border and corners.
- win.setCursorPos(x - 1, y + height)
- win.write("\x8D" .. ("\x8C"):rep(width) .. "\x8E")
- end
- --- Draws a block of text inside a window with word wrapping, optionally resizing the window to fit.
- ---@param win window The window to draw in
- ---@param text string The text to draw
- ---@param resizeToFit boolean|nil Whether to resize the window to fit the text (defaults to false). This is useful for scroll boxes.
- ---@param fgColor color|nil The color of the text (defaults to white)
- ---@param bgColor color|nil The color of the background (defaults to black)
- ---@return number lines The total number of lines drawn
- function PrimeUI.drawText(win, text, resizeToFit, fgColor, bgColor)
- expect(1, win, "table")
- expect(2, text, "string")
- expect(3, resizeToFit, "boolean", "nil")
- fgColor = expect(4, fgColor, "number", "nil") or colors.white
- bgColor = expect(5, bgColor, "number", "nil") or colors.black
- -- Set colors.
- win.setBackgroundColor(bgColor)
- win.setTextColor(fgColor)
- -- Redirect to the window to use print on it.
- local old = term.redirect(win)
- -- Draw the text using print().
- local lines = print(text)
- -- Redirect back to the original terminal.
- term.redirect(old)
- -- Resize the window if desired.
- if resizeToFit then
- -- Get original parameters.
- local x, y = win.getPosition()
- local w = win.getSize()
- -- Resize the window.
- win.reposition(x, y, w, lines)
- end
- return lines
- end
- --- Runs a function or action after the specified time period, with optional canceling.
- ---@param time number The amount of time to wait for, in seconds
- ---@param action function|string The function to call when the timer completes, or a `run` event to send
- ---@return function cancel A function to cancel the timer
- function PrimeUI.timeout(time, action)
- expect(1, time, "number")
- expect(2, action, "function", "string")
- -- Start the timer.
- local timer = os.startTimer(time)
- -- Add a task to wait for the timer.
- PrimeUI.addTask(function()
- while true do
- -- Wait for a timer event.
- local _, tm = os.pullEvent("timer")
- if tm == timer then
- -- Fire the timer action.
- if type(action) == "string" then PrimeUI.resolve("timeout", action)
- else action() end
- end
- end
- end)
- -- Return a function to cancel the timer.
- return function() os.cancelTimer(timer) end
- end
- --PrimeUI INIT END
- ------------------------------------------------------------------------------------
- ------------------------------------------------------------------------------------
- ------------------------------------------------------------------------------------
- local comp=require"cc.shell.completion"
- local main=term.current()
- x,y=6,10
- max_x,max_y=term.getSize()
- local desc1=[[--PACKAGE DESCRIPTION--
- This package has quiet install mode.
- Use `-H` or `--help` option for more information.
- Controls:
- Enter == Continue
- Ctrl+c == Exit / Cancel
- Space == Select option
- Package version: 1.0
- Package creator: M.A.G.Gen.
- Git: https://github.com/MAGGen-hub
- PrimeUI creator: JackMacWindows
- Git: https://github.com/MCJack123/PrimeUI
- ALL LICENCES ARE PUBLIC:
- For a more detailed acquaintance visit previously mentioned links.
- WARNING!
- This package require default LZSS package!
- To install it run `pastebin run MxnRb6E8`
- Required modules: Minified API; startup module.
- WARNING!
- This package has no minified version.
- If you have size issues and can't install it
- Use LZSSEPM-Online:
- `pastebin run 35C8TNCZ`
- What is lzssepm.lua?
- lzssepm.lua - program for making self-extracting programs (SEP).
- SEP usualy have smaller size than default program.
- SEP's has built-in unpack function from LZSS archiver.
- Lzssepm was created to provide transparent compression to your programs, so user of SEP's can launch them without LZSS package instalation.
- WARNING!
- It's nice if you have only one or two SEP's on your system, but if you have a lot of them - installing LZSS will be much more efficient solution!
- --END OF PACKAGE DESCRIPTION--
- ]]
- mkgui=function(nobtn)
- local lab="LZSSEPM Installer V1.0"
- PrimeUI.label(main,3,2,lab,colors.yellow)
- PrimeUI.horizontalLine(main,3,3,#lab + 2,colors.yellow)
- PrimeUI.borderBox(main,4,6,max_x-x,max_y-y,colors.yellow)
- PrimeUI.keyCombo(keys.c,true,false,false,"exit")
- if not nobtn then
- PrimeUI.keyAction(keys.enter,"done")
- PrimeUI.button(main,3,max_y-2,"Continue","done",colors.yellow,nil,colors.lightGray)
- PrimeUI.button(main,14,max_y-2,"Cancel","exit",colors.yellow,nil,colors.lightGray)
- else
- PrimeUI.label(main,3,max_y-2," Continue ",colors.lightGray,colors.gray)
- PrimeUI.button(main,14,max_y-2,"Cancel","exit",colors.yellow,nil,colors.lightGray)
- end
- end
- --DESCRIPTION SHOW--
- PrimeUI.clear()
- mkgui()
- local scroll_box=PrimeUI.scrollBox(main,4,6,max_x-x, max_y-y,999,true,true)
- PrimeUI.drawText(scroll_box,desc1,true)
- local _,act = PrimeUI.run()
- local lzssepm_path,prev,err
- --SELECT LZSSEPM FOLDER
- if act=="done" then
- local histor={"/lzssepm.lua","/progs/lzssepm.lua","/programs/lzssepm.lua","/disk/lzssepm.lua","/lib/lzssepm.lua","/apis/lzssepm.lua","/lzss/lzssepm.lua"}-- posible names for directory
- --wnd.reposition(4,9)
- --wnd.clear()
- repeat
- lzssepm_path=nil
- PrimeUI.clear()
- mkgui(true)
- PrimeUI.label(main,4,6,"Choose instalation file (use \x12):",colors.yellow)
- paintutils.drawLine(4,8,max_x-x+3,8,colors.gray)
- PrimeUI.inputBox(main,5,8,max_x-x-2,"done",colors.yellow,colors.gray,nil,histor,
- function(sLine) if #sLine>0 then return comp.dir(shell,sLine)end end,histor[#histor])
- PrimeUI.textBox(main,4,9,max_x-x,3,err or"",colors.red)
- _,act,lzssepm_path=PrimeUI.run()--attempt to get the way
- _,err=pcall(function()
- if lzssepm_path then --create files if posible
- if prev~=lzssepm_path and fs.exists(lzssepm_path) then
- prev=lzssepm_path
- error("Warning! File 'lzssepm.lua' will be rewriten! Are you sure? [Enter]"..prev..tostring(prev~=lzssepm_path))
- end
- local tmp1,err1=fs.open(fs.combine(lzssepm_path),"w")
- err1=tmp1 or error(err1)
- file1=tmp1
- end
- end)
- histor[#histor+1]=lzssepm_path~=histor[#histor] and lzssepm_path or nil
- until file1 or act=="exit"
- end
- err=nil
- local st_path
- --SELECT STARTUP
- if act=="done" then
- local histor={"/startup.lua","/disk/startup.lua","/disk/startup/01_lzssepm.lua","/startup/lzssepm.lua","/startup/02_lzssepm.lua","/startup/01_lzssepm.lua"}
- repeat
- PrimeUI.clear()
- mkgui(true)
- PrimeUI.label(main,4,6,"Enter startup (use \x12):",colors.yellow)
- paintutils.drawLine(4,8,max_x-x+3,8,colors.gray)
- PrimeUI.inputBox(main,5,8,max_x-x-2,"done",colors.yellow,colors.gray,nil,histor,
- function(sLine) if #sLine>0 then return comp.dirOrFile(shell,sLine)end end, histor[#histor])
- PrimeUI.textBox(main,4,9,max_x-x,3,err or"",colors.red)
- _,act,st_path=PrimeUI.run()
- _,err=pcall(function()
- if st_path then
- local tmp,err1=fs.open(st_path,"w")
- st_file=tmp or error(err1)
- end
- end)
- histor[#histor+1]=st_path~=histor[#histor] and st_path or nil
- until st_file or act=="exit"
- end
- --SIZE DEMO PART
- if act=="done" then
- local s_prog = #lzssepm_code/1024 or 0
- local s_stp =(#startup_code - 6 + #lzssepm_path)/1024
- PrimeUI.clear()
- mkgui()
- PrimeUI.label(main ,4,6,("Startup: %6.2fKb's"):format(s_stp),colors.yellow)
- PrimeUI.label(main ,4,7,(" Prog: %6.2fKb's"):format(s_prog),colors.yellow)
- PrimeUI.label(main ,4,8,("Total Size:%6.2fKb's"):format(s_prog+s_stp),colors.yellow)
- PrimeUI.label(main ,4,9,"Continue instalation?",colors.yellow)
- _,act=PrimeUI.run()
- end
- --INSTALL PART
- if act=="done" then
- install(lzssepm_path,file1,st_file)
- PrimeUI.clear()
- mkgui()
- PrimeUI.label(main ,4,6,"Instalation completed...",colors.yellow)
- PrimeUI.label(main ,4,7,"Please reload OS...",colors.yellow)
- PrimeUI.label(main ,4,8,"Press any key to continue...",colors.yellow)
- PrimeUI.label(main ,4,9,"Program will exit automaticly after 5 seconds.",colors.yellow)
- PrimeUI.addTask(function()while true do
- local ev=os.pullEvent"key"
- ev=ev and PrimeUI.resolve()
- end
- end)
- PrimeUI.timeout(5,"done")
- PrimeUI.run()
- end
- --IF CANCELED
- if act=="exit" then
- PrimeUI.clear()
- mkgui()
- PrimeUI.label(main ,4,6,"Instalation canceled. Press any key to exit.",colors.red)
- PrimeUI.label(main ,4,7,"Program will exit automaticly after 3 seconds.",colors.yellow)
- PrimeUI.addTask(function()while true do
- local ev=os.pullEvent"key"
- ev=ev and PrimeUI.resolve()
- end
- end)
- PrimeUI.timeout(3,"done")
- PrimeUI.run()
- end
- end
- --close all files
- _=file1 and pcall(file1.close)
- _=st_file and pcall(st_file.close)
- if #{...}<1 then
- --restore color after UI and clear shell
- term.setTextColor(fg) term.setBackgroundColor(bg)
- shell.run"clear"
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement