feat: add Opus autorun script and grid single-click for touch
- Add autorun/startup.lua for Opus package integration: - Detects role from config files (.manager_config, .client_config, etc.) - Registers reboot listener as kernel hook - Launches program via shell.openForegroundTab() - Client role also opens dropperController in separate tab - Override grid eventHandler on actionable grids (itemGrid, smeltTab, craftTab) to emit grid_select on single mouse_click, enabling monitor touch to trigger actions immediately instead of requiring double-click
This commit is contained in:
83
autorun/startup.lua
Normal file
83
autorun/startup.lua
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
-- Inventory Manager - Opus autorun script
|
||||||
|
-- Detects configured role and launches the appropriate program at boot
|
||||||
|
|
||||||
|
local fs = _G.fs
|
||||||
|
local kernel = _G.kernel
|
||||||
|
local os = _G.os
|
||||||
|
local peripheral = _G.peripheral
|
||||||
|
local shell = _ENV.shell
|
||||||
|
|
||||||
|
local BASE = 'packages/inventory-manager'
|
||||||
|
|
||||||
|
-------------------------------------------------
|
||||||
|
-- Determine role from config files written during install
|
||||||
|
-------------------------------------------------
|
||||||
|
|
||||||
|
local role
|
||||||
|
if fs.exists(fs.combine(BASE, '.manager_config')) then
|
||||||
|
role = 'manager'
|
||||||
|
elseif fs.exists(fs.combine(BASE, '.client_config')) then
|
||||||
|
role = 'client'
|
||||||
|
elseif fs.exists(fs.combine(BASE, '.webbridge_config')) then
|
||||||
|
role = 'bridge'
|
||||||
|
elseif _G.turtle then
|
||||||
|
role = 'turtle'
|
||||||
|
end
|
||||||
|
|
||||||
|
if not role then return end
|
||||||
|
|
||||||
|
-------------------------------------------------
|
||||||
|
-- Register reboot listener as a kernel hook
|
||||||
|
-- Allows remote reboot via modem (channel 4205)
|
||||||
|
-------------------------------------------------
|
||||||
|
|
||||||
|
local SYSTEM_CHANNEL = 4205
|
||||||
|
|
||||||
|
local modem = peripheral.find('modem')
|
||||||
|
if modem then
|
||||||
|
modem.open(SYSTEM_CHANNEL)
|
||||||
|
|
||||||
|
kernel.hook('modem_message', function(_, data)
|
||||||
|
-- data = { side, channel, replyChannel, message, distance }
|
||||||
|
if data[2] == SYSTEM_CHANNEL
|
||||||
|
and type(data[4]) == 'table'
|
||||||
|
and data[4].type == 'reboot'
|
||||||
|
then
|
||||||
|
local target = data[4].target or 'all'
|
||||||
|
if target == 'all'
|
||||||
|
or target == role
|
||||||
|
or target == tostring(os.getComputerID())
|
||||||
|
then
|
||||||
|
os.reboot()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
-------------------------------------------------
|
||||||
|
-- Launch the program for this role
|
||||||
|
-------------------------------------------------
|
||||||
|
|
||||||
|
local programs = {
|
||||||
|
manager = 'inventoryManager.lua',
|
||||||
|
client = 'inventoryClient.lua',
|
||||||
|
bridge = 'inventoryWebBridge.lua',
|
||||||
|
turtle = 'craftingTurtle.lua',
|
||||||
|
}
|
||||||
|
|
||||||
|
local program = fs.combine(BASE, programs[role])
|
||||||
|
|
||||||
|
if shell.openForegroundTab then
|
||||||
|
shell.openForegroundTab(program)
|
||||||
|
|
||||||
|
-- Client role also runs the dropper controller
|
||||||
|
if role == 'client' then
|
||||||
|
local dropper = fs.combine(BASE, 'dropperController.lua')
|
||||||
|
if fs.exists(dropper) then
|
||||||
|
shell.openTab(dropper)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
-- No multishell — run directly (blocks boot)
|
||||||
|
shell.run(program)
|
||||||
|
end
|
||||||
@@ -320,6 +320,18 @@ local function buildMainPage()
|
|||||||
ratio = row.ratio or 0,
|
ratio = row.ratio or 0,
|
||||||
}
|
}
|
||||||
end,
|
end,
|
||||||
|
|
||||||
|
-- Single-click triggers grid_select (for monitor touch)
|
||||||
|
eventHandler = function(self, event)
|
||||||
|
if event.type == 'mouse_click' then
|
||||||
|
local handled = UI.Grid.eventHandler(self, event)
|
||||||
|
if handled and self.selected then
|
||||||
|
self:emit({ type = 'grid_select', selected = self.selected, element = self })
|
||||||
|
end
|
||||||
|
return handled
|
||||||
|
end
|
||||||
|
return UI.Grid.eventHandler(self, event)
|
||||||
|
end,
|
||||||
},
|
},
|
||||||
|
|
||||||
-- Alert / status area
|
-- Alert / status area
|
||||||
@@ -628,9 +640,20 @@ local function buildSmelterPage()
|
|||||||
|
|
||||||
getRowTextColor = function(self, row, selected)
|
getRowTextColor = function(self, row, selected)
|
||||||
if selected then return colors.white end
|
if selected then return colors.white end
|
||||||
-- Color the toggle column indicator
|
|
||||||
return colors.white
|
return colors.white
|
||||||
end,
|
end,
|
||||||
|
|
||||||
|
-- Single-click triggers grid_select (for monitor touch)
|
||||||
|
eventHandler = function(self, event)
|
||||||
|
if event.type == 'mouse_click' then
|
||||||
|
local handled = UI.Grid.eventHandler(self, event)
|
||||||
|
if handled and self.selected then
|
||||||
|
self:emit({ type = 'grid_select', selected = self.selected, element = self })
|
||||||
|
end
|
||||||
|
return handled
|
||||||
|
end
|
||||||
|
return UI.Grid.eventHandler(self, event)
|
||||||
|
end,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -671,6 +694,18 @@ local function buildSmelterPage()
|
|||||||
{ heading = 'Go', key = 'goLabel', width = 6 },
|
{ heading = 'Go', key = 'goLabel', width = 6 },
|
||||||
},
|
},
|
||||||
values = {},
|
values = {},
|
||||||
|
|
||||||
|
-- Single-click triggers grid_select (for monitor touch)
|
||||||
|
eventHandler = function(self, event)
|
||||||
|
if event.type == 'mouse_click' then
|
||||||
|
local handled = UI.Grid.eventHandler(self, event)
|
||||||
|
if handled and self.selected then
|
||||||
|
self:emit({ type = 'grid_select', selected = self.selected, element = self })
|
||||||
|
end
|
||||||
|
return handled
|
||||||
|
end
|
||||||
|
return UI.Grid.eventHandler(self, event)
|
||||||
|
end,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user