diff --git a/slabos.lua b/slabos.lua new file mode 100644 index 0000000..86628d8 --- /dev/null +++ b/slabos.lua @@ -0,0 +1,289 @@ +local basalt = require("basalt") + +local main = basalt.getMainFrame() + +local FRAME_WIDTH = 26 +local FRAME_HEIGHT = 19 +local CONTROL_BUTTON_Y = 20 + +local homescreen = main:addFrame() + :setPosition(1, 1) + :setSize(FRAME_WIDTH, FRAME_HEIGHT) + :setBackground(colours.blue) + :setVisible(true) + +local active_app_frames = {} +local current_active_frame = homescreen + +local app_switcher_frame = main:addFrame() + :setPosition(1, 1) + :setSize(FRAME_WIDTH, FRAME_HEIGHT) + :setBackground(colours.brown) + :setVisible(false) + +function show_payment_confirmation(amount, purpose, callback) + + local payment_confirmation_frame = main:addFrame() + :setPosition(1, 1) + :setSize(FRAME_WIDTH, FRAME_HEIGHT / 3) + :setBackground(colours.black) + payment_confirmation_frame.z = 99 + payment_confirmation_frame.focused = true + + payment_confirmation_frame:addLabel() + :setText("Confirm Payment") + :setForeground(colours.white) + + payment_confirmation_frame:addLabel() + :setPosition(1, 3) + :setText(amount .. "G -> " .. purpose) + :setForeground(colours.white) + + payment_confirmation_frame:addButton() + :setText("Confirm") + :setPosition(1, 6) + :setSize(13, 1) + :setBackground(colours.green) + + :onClick(function() + if callback then + callback(true) + end + payment_confirmation_frame:destroy() + end) + + payment_confirmation_frame:addButton() + :setText("Deny") + :setPosition(14, 6) + :setSize(13, 1) + :setBackground(colours.red) + + :onClick(function() + + if callback then + callback(false) + end + + payment_confirmation_frame:destroy() + end) + sleep(0.01) +end + +local function payment_listener() + local modem = peripheral.find("modem") + local lchannel = tonumber(os.getComputerID() .. 43) + modem.open(lchannel) + while true do + + local event, side, channel, replyChannel, message, distance + repeat + event, side, channel, replyChannel, message, distance = os.pullEvent("modem_message") + until channel == lchannel + + local payload = textutils.unserialiseJSON(message) + if payload.type == "confirmTransaction" then + show_payment_confirmation(payload.amount, payload.vendor,function(bruh) + if bruh then + + local confirmation_payload = { + type = "transactionConfirmation", + transaction_id = payload.transaction_id, + confirmed = true + } + + modem.transmit(replyChannel,channel,textutils.serialiseJSON(confirmation_payload)) + + else + + local confirmation_payload = { + type = "transactionConfirmation", + transaction_id = payload.transaction_id, + confirmed = false + } + + modem.transmit(replyChannel,channel,textutils.serialiseJSON(confirmation_payload)) + + end + end) + + end + + end + +end + +local function populate_homescreen_buttons() + + homescreen:clear() + + local button_width = 8 + local button_height = 3 + local button_spacing_x = 3 + local button_spacing_y = 2 + local current_x = button_spacing_x + local current_y = button_spacing_y + + local app_files = fs.list("/apps/") + + for i = 1, #app_files do + local filename = app_files[i] + + local display_name = filename:gsub(".lua$", "") + + if current_x + button_width > homescreen:getWidth() then + current_x = button_spacing_x + current_y = current_y + button_height + button_spacing_y + end + + if current_y + button_height > homescreen:getHeight() then + break + end + + local app_button = homescreen:addButton() + :setText(display_name) + :setPosition(current_x, current_y) + :setSize(button_width, button_height) + :setBackground(colours.grey) + :setForeground(colours.white) + :onClick(function() + + if current_active_frame then + current_active_frame:setVisible(false) + end + + local app_frame = active_app_frames[filename] + if not app_frame then + + app_frame = main:addFrame() + :setPosition(1, 1) + :setSize(FRAME_WIDTH, FRAME_HEIGHT) + :setBackground(colours.green) + :setVisible(false) + + app_frame:addProgram() + :setSize(FRAME_WIDTH, FRAME_HEIGHT) + :execute("/apps/" .. filename) + + active_app_frames[filename] = app_frame + end + + app_frame:setVisible(true) + current_active_frame = app_frame + end) + + current_x = current_x + button_width + button_spacing_x + end +end + +local function switch_to_frame(target_frame, frame_name) + if current_active_frame then + current_active_frame:setVisible(false) + end + target_frame:setVisible(true) + current_active_frame = target_frame +end + +local function populate_app_switcher_ui() + app_switcher_frame:clear() + + app_switcher_frame:addLabel() + :setText("Active Applications") + :setPosition(5, 1) + :setSize(FRAME_WIDTH - 2, 1) + :setForeground(colours.white) + :setBackground(colours.blue) + + local current_y = 3 + + app_switcher_frame:addButton() + :setText("Home Screen") + :setPosition(2, current_y) + :setSize(FRAME_WIDTH - 3, 1) + :setBackground(homescreen == current_active_frame and colours.lightGrey or colours.grey) + :setForeground(colours.white) + :onClick(function() + switch_to_frame(homescreen, "Home Screen") + app_switcher_frame:setVisible(false) + end) + current_y = current_y + 2 + + for filename, app_frame in pairs(active_app_frames) do + + local display_name = filename:gsub(".lua$", "") + + if current_y + 1 > app_switcher_frame:getHeight() - 2 then + app_switcher_frame:addLabel() + :setText("...more apps below...") + :setPosition(1, current_y) + :setSize(FRAME_WIDTH - 2, 1) + :setForeground(colours.orange) + :setBackground(colours.black) + break + end + + app_switcher_frame:addButton() + :setText(display_name) + :setPosition(2, current_y) + :setSize(FRAME_WIDTH - 8, 1) + :setBackground(app_frame == current_active_frame and colours.lightGrey or colours.grey) + :setForeground(colours.white) + :onClick(function() + switch_to_frame(app_frame, filename) + app_switcher_frame:setVisible(false) + end) + + app_switcher_frame:addButton() + :setText("X") + :setPosition(FRAME_WIDTH - 6, current_y) + :setSize(5, 1) + :setBackground(colours.red) + :setForeground(colours.white) + :onClick(function() + + if app_frame then + app_frame:destroy() + end + active_app_frames[filename] = nil + + if current_active_frame == app_frame then + switch_to_frame(homescreen, "Home Screen (after close)") + end + + populate_app_switcher_ui() + end) + current_y = current_y + 2 + end +end + +populate_homescreen_buttons() + +main:addButton() + :setText("Home") + :setPosition(0, CONTROL_BUTTON_Y) + :setSize(14, 1) + :setBackground(colours.black) + :setForeground(colours.white) + :onClick(function() + + if current_active_frame ~= homescreen or app_switcher_frame.visible == true then + app_switcher_frame:setVisible(false) + switch_to_frame(homescreen, "Home Screen") + end + end) + +main:addButton() + :setText("Switch") + :setPosition(14, CONTROL_BUTTON_Y) + :setSize(13, 1) + :setBackground(colours.red) + :setForeground(colours.white) + :onClick(function() + + if current_active_frame then + current_active_frame:setVisible(false) + end + populate_app_switcher_ui() + app_switcher_frame:setVisible(true) + end) + +parallel.waitForAny(basalt.run,payment_listener) \ No newline at end of file