From e1084422e526796198d72812405f710d9c72e200 Mon Sep 17 00:00:00 2001 From: "kepler155c@gmail.com" Date: Sat, 1 Dec 2018 00:52:39 -0500 Subject: [PATCH] milo: categories, better listing page separation --- milo/Milo.lua | 47 +++++++++++++++++++--------- milo/apis/storage.lua | 5 ++- milo/core/listing.lua | 11 ++++++- milo/core/machines.lua | 50 +++++++++++++++++++----------- milo/plugins/activityView.lua | 1 + milo/plugins/brewingStandView.lua | 1 + milo/plugins/exportView.lua | 1 + milo/plugins/importView.lua | 1 + milo/plugins/inputChestView.lua | 1 + milo/plugins/item.lua | 51 ++++++++++++++++--------------- milo/plugins/jobMonitor.lua | 1 + milo/plugins/learn.lua | 27 ++++++++-------- milo/plugins/machineLearn.lua | 27 ++++++++-------- milo/plugins/manipulatorView.lua | 1 + milo/plugins/storageView.lua | 2 ++ milo/plugins/trashcanView.lua | 1 + milo/plugins/turtleLearn.lua | 14 ++++----- 17 files changed, 146 insertions(+), 96 deletions(-) diff --git a/milo/Milo.lua b/milo/Milo.lua index ac734fd..5d2a05a 100644 --- a/milo/Milo.lua +++ b/milo/Milo.lua @@ -33,24 +33,43 @@ if multishell then multishell.setTitle(multishell.getCurrent(), 'Milo') end -local config = { - nodes = { }, -} -Config.load('milo', config) +local nodes = Config.load('milo', { }) -- TODO: remove - temporary -if config.remoteDefaults then - config.nodes = config.remoteDefaults - config.remoteDefaults = nil +if nodes.remoteDefaults then + nodes.nodes = nodes.remoteDefaults + nodes.remoteDefaults = nil end -- TODO: remove - temporary -for _, node in pairs(config.nodes) do - if node.lock and type(node.lock) == 'string' then - node.lock = { - [ node.lock ] = true, - } +if nodes.nodes then + local categories = { + input = 'custom', + trash = 'custom', + machine = 'machine', + brewingStand = 'custom', + activity = 'display', + jobs = 'display', + ignore = 'ignore', + hidden = 'ignore', + manipulator = 'custom', + storage = 'storage', + } + for _, node in pairs(nodes.nodes) do + if node.lock and type(node.lock) == 'string' then + node.lock = { + [ node.lock ] = true, + } + end + if not node.category then + node.category = categories[node.mtype] + if not node.category then + Util.print(node) + error('invalid node') + end + end end + nodes = nodes.nodes end local function Syntax(msg) @@ -87,7 +106,7 @@ if not device.workbench then end local context = { - config = config, + nodes = nodes, resources = Util.readTable(Milo.RESOURCE_FILE) or { }, state = { }, @@ -97,7 +116,7 @@ local context = { queue = { }, localName = modem.getNameLocal(), - storage = Storage(config), + storage = Storage(nodes), turtleInventory = introspection.getInventory(), } diff --git a/milo/apis/storage.lua b/milo/apis/storage.lua index 50003f0..962e3a7 100644 --- a/milo/apis/storage.lua +++ b/milo/apis/storage.lua @@ -10,16 +10,15 @@ local os = _G.os local Storage = class() -function Storage:init(args) +function Storage:init(nodes) local defaults = { - nodes = { }, + nodes = nodes or { }, dirty = true, activity = { }, storageOnline = true, lastRefresh = os.clock(), } Util.merge(self, defaults) - Util.merge(self, args) local modem = Peripheral.get('wired_modem') or error('Wired modem not attached') self.localName = modem.getNameLocal() diff --git a/milo/core/listing.lua b/milo/core/listing.lua index 0123e36..3e22299 100644 --- a/milo/core/listing.lua +++ b/milo/core/listing.lua @@ -262,7 +262,7 @@ function page:eventHandler(event) return true end -function page:enable() +function page:enable(args) local function updateStatus() self.statusBar.storageStatus.value = context.storage:isOnline() and '' or 'offline' @@ -292,6 +292,15 @@ function page:enable() end) end) + if args and args.filter then + self.filter = args.filter + self.statusBar.filter.value = args.filter + end + + if args and args.message then + self.notification:success(args.message) + end + self:setFocus(self.statusBar.filter) UI.Page.enable(self) end diff --git a/milo/core/machines.lua b/milo/core/machines.lua index 68ce4f7..9856e98 100644 --- a/milo/core/machines.lua +++ b/milo/core/machines.lua @@ -16,15 +16,15 @@ local nodeWizard local function saveConfig() local t = { } - for k,v in pairs(context.config.nodes) do + for k,v in pairs(context.nodes) do t[k] = v.adapter v.adapter = nil end - Config.update('milo', context.config) + Config.update('milo', context.nodes) for k,v in pairs(t) do - context.config.nodes[k].adapter = v + context.nodes[k].adapter = v end context.storage:initStorage() end @@ -43,12 +43,13 @@ local networkPage = UI.Page { }, grid = UI.ScrollingGrid { y = 2, ey = -3, - values = context.config.nodes, + values = context.nodes, columns = { { key = 'suffix', width = 4, justify = 'right' }, { heading = 'Name', key = 'displayName' }, { heading = 'Type', key = 'mtype', width = 4 }, - { heading = 'Pri', key = 'priority', width = 3 }, + { heading = 'Cat', key = 'category', width = 3 }, + --{ heading = 'Pri', key = 'priority', width = 3 }, }, sortColumn = 'displayName', help = 'Select Node', @@ -96,16 +97,26 @@ function networkPage.grid:getRowTextColor(row, selected) return UI.Grid:getRowTextColor(row, selected) end +function networkPage.grid:sortCompare(a, b) + if self.sortColumn == 'displayName' then + local an = a.displayName or a.name + local bn = b.displayName or b.name + return an:lower() < bn:lower() + end + return UI.Grid.sortCompare(self, a, b) +end + function networkPage:getList() for _, v in pairs(device) do - if not context.config.nodes[v.name] then + if not context.nodes[v.name] then local node = { name = v.name, mtype = 'ignore', + category = 'ignore', } for _, page in pairs(nodeWizard.wizard.pages) do if page.isValidType and page:isValidType(node) then - context.config.nodes[v.name] = node + context.nodes[v.name] = node break end end @@ -146,7 +157,7 @@ function networkPage:disable() end function networkPage:applyFilter() - local t = Util.filter(context.config.nodes, function(v) + local t = Util.filter(context.nodes, function(v) return v.mtype ~= 'hidden' end) @@ -173,7 +184,7 @@ function networkPage:eventHandler(event) elseif event.type == 'remove_node' then local node = self.grid:getSelected() if node then - context.config.nodes[node.name] = nil + context.nodes[node.name] = nil saveConfig() end self:applyFilter() @@ -412,6 +423,9 @@ end function nodeWizard.wizard.pages.general:validate() if self.form:save() then + _G._p3 = nodeWizard.choices + _G._p4 = nodeWizard.node + nodeWizard.node.category = Util.find(nodeWizard.choices, 'value', nodeWizard.node.mtype).category for _, page in pairs(nodeWizard.wizard.pages) do page.index = nil end @@ -442,20 +456,20 @@ function nodeWizard:enable(node) self.node.adapter = adapter node.adapter = adapter - local choices = { - { name = 'Ignore', value = 'ignore', '' }, - { name = 'Hidden', value = 'hidden', help = 'Do not show in list' }, + self.choices = { + { name = 'Ignore', value = 'ignore', category = 'ignore' }, + { name = 'Hidden', value = 'hidden', category = 'ignore', help = 'Do not show in list' }, } for _, page in pairs(self.wizard.pages) do if page.isValidType then local choice = page:isValidType(self.node) - if choice and not Util.find(choices, 'value', choice.value) then - table.insert(choices, 2, choice) + if choice and not Util.find(self.choices, 'value', choice.value) then + table.insert(self.choices, 2, choice) end end end self.wizard.pages.general.form[1].shadowText = self.node.name - self.wizard.pages.general.form[2].choices = choices + self.wizard.pages.general.form[2].choices = self.choices self.wizard.pages.general.form:setValues(self.node) self.wizard.pages.general:showInventory(self.node) @@ -491,9 +505,9 @@ function nodeWizard:eventHandler(event) return true end) - Util.clear(context.config.nodes[self.node.name]) - Util.merge(context.config.nodes[self.node.name], self.node) - context.config.nodes[self.node.name].adapter = adapter + Util.clear(context.nodes[self.node.name]) + Util.merge(context.nodes[self.node.name], self.node) + context.nodes[self.node.name].adapter = adapter saveConfig() diff --git a/milo/plugins/activityView.lua b/milo/plugins/activityView.lua index f5937a6..50e6341 100644 --- a/milo/plugins/activityView.lua +++ b/milo/plugins/activityView.lua @@ -31,6 +31,7 @@ function activityWizardPage:isValidType(node) return m and m.type == 'monitor' and { name = 'Activity Monitor', value = 'activity', + category = 'display', help = 'Display storage activity' } end diff --git a/milo/plugins/brewingStandView.lua b/milo/plugins/brewingStandView.lua index d67a74e..ec7aba4 100644 --- a/milo/plugins/brewingStandView.lua +++ b/milo/plugins/brewingStandView.lua @@ -30,6 +30,7 @@ function brewingStandView:isValidType(node) return m and m.type == 'minecraft:brewing_stand'and { name = 'Brewing Stand', value = 'brewingStand', + category = 'custom', help = 'Auto-learning brewing stand', } end diff --git a/milo/plugins/exportView.lua b/milo/plugins/exportView.lua index 80821a0..192ab4d 100644 --- a/milo/plugins/exportView.lua +++ b/milo/plugins/exportView.lua @@ -46,6 +46,7 @@ function exportView:isValidType(node) return m and m.pullItems and { name = 'Generic Inventory', value = 'machine', + category = 'machine', help = 'Chest, furnace... (has an inventory)' } end diff --git a/milo/plugins/importView.lua b/milo/plugins/importView.lua index b27e8e4..80131dd 100644 --- a/milo/plugins/importView.lua +++ b/milo/plugins/importView.lua @@ -46,6 +46,7 @@ function importView:isValidType(node) return m and m.pullItems and { name = 'Generic Inventory', value = 'machine', + category = 'machine', help = 'Chest, furnace... (has an inventory)', } end diff --git a/milo/plugins/inputChestView.lua b/milo/plugins/inputChestView.lua index 59d48fe..8a7d752 100644 --- a/milo/plugins/inputChestView.lua +++ b/milo/plugins/inputChestView.lua @@ -26,6 +26,7 @@ function inputChestWizardPage:isValidType(node) return m and m.pullItems and { name = 'Input Chest', value = 'input', + category = 'custom', help = 'Sends all items to storage', } end diff --git a/milo/plugins/item.lua b/milo/plugins/item.lua index 09850a5..e494f3a 100644 --- a/milo/plugins/item.lua +++ b/milo/plugins/item.lua @@ -10,7 +10,7 @@ local device = _G.device local context = Milo:getContext() -local itemPage = UI.Page { +local page = UI.Page { titleBar = UI.TitleBar { title = 'Limit Resource', previousPage = true, @@ -46,7 +46,7 @@ local itemPage = UI.Page { x = 2, y = -2, width = 10, formLabel = 'Machine', event = 'select_machine', - text = 'Configure', + text = 'Assign', }, infoButton = UI.Button { x = 2, y = -2, @@ -108,7 +108,6 @@ local itemPage = UI.Page { grid = UI.ScrollingGrid { y = 2, ey = -5, disableHeader = true, - values = context.config.nodes, columns = { { heading = 'Name', key = 'displayName'}, }, @@ -142,42 +141,48 @@ local itemPage = UI.Page { notification = UI.Notification { }, } -function itemPage:enable(item) +function page:enable(item) self.origItem = item self.item = Util.shallowCopy(item) self.res = item.resource or { } self.res.displayName = self.item.displayName self.form:setValues(self.res) - self.titleBar.title = item.displayName or item.name - self.form.machineButton.inactive = not Craft.machineLookup[self.item.key] + + local machine = Craft.machineLookup[self.item.key] + self.form.machineButton.inactive = not machine + if machine then + self:filterMachines(machine) + end UI.Page.enable(self) self:focusFirst() end -function itemPage.machines.grid:isRowValid(_, value) - local ignores = Util.transpose({ 'storage', 'ignore', 'hidden' }) - if not ignores[value.mtype] then - local node = context.storage.nodes[value.name] - return node and node.adapter and node.adapter.online and node.adapter.pushItems - end +function page:filterMachines(machine) + local t = Util.filter(context.storage.nodes, function(node) + if node.category == 'machine' then + return node.adapter and node.adapter.online and node.adapter.pushItems + end + end) + self.machines.grid:setValues(t) + self.machines.grid:setSelected('name', machine) end -function itemPage.machines.grid:getDisplayValues(row) +function page.machines.grid:getDisplayValues(row) row = Util.shallowCopy(row) row.displayName = row.displayName or row.name return row end - function itemPage.machines.grid:getRowTextColor(row, selected) - if row.name == Craft.machineLookup[itemPage.item.key] then - return colors.yellow - end - return UI.Grid:getRowTextColor(row, selected) +function page.machines.grid:getRowTextColor(row, selected) + if row.name == Craft.machineLookup[page.item.key] then + return colors.yellow end + return UI.Grid:getRowTextColor(row, selected) +end -function itemPage.rsControl:enable() +function page.rsControl:enable() local devices = self.form[2].choices Util.clear(devices) for _,dev in pairs(device) do @@ -193,7 +198,7 @@ function itemPage.rsControl:enable() UI.SlideOut.enable(self) end -function itemPage.rsControl:eventHandler(event) +function page.rsControl:eventHandler(event) if event.type == 'form_cancel' then self:hide() elseif event.type == 'form_complete' then @@ -204,7 +209,7 @@ function itemPage.rsControl:eventHandler(event) return true end -function itemPage:eventHandler(event) +function page:eventHandler(event) if event.type == 'form_cancel' then UI:setPreviousPage() @@ -212,8 +217,6 @@ function itemPage:eventHandler(event) self.rsControl:show() elseif event.type == 'select_machine' then - self.machines.grid:update() - self.machines.grid:setIndex(1) self.machines:show() elseif event.type == 'reset' then @@ -334,4 +337,4 @@ function itemPage:eventHandler(event) return true end -UI:addPage('item', itemPage) +UI:addPage('item', page) diff --git a/milo/plugins/jobMonitor.lua b/milo/plugins/jobMonitor.lua index e555754..378102a 100644 --- a/milo/plugins/jobMonitor.lua +++ b/milo/plugins/jobMonitor.lua @@ -27,6 +27,7 @@ function wizardPage:isValidType(node) return m and m.type == 'monitor' and { name = 'Crafting Monitor', value = 'jobs', + category = 'display', help = 'Display crafting progress / jobs' } end diff --git a/milo/plugins/learn.lua b/milo/plugins/learn.lua index 7172c17..0c9460e 100644 --- a/milo/plugins/learn.lua +++ b/milo/plugins/learn.lua @@ -6,11 +6,15 @@ local context = Milo:getContext() local turtle = _G.turtle local learnPage = UI.Dialog { - height = 6, width = UI.term.width - 6, + height = 9, width = UI.term.width - 6, title = 'Learn Recipe', - chooser = UI.Chooser { - x = 8, y = 3, - width = 20, + grid = UI.ScrollingGrid { + x = 2, ex = -2, y = 3, height = 4, + disableHeader = true, + columns = { + { heading = 'Name', key = 'name'}, + }, + sortColumn = 'name', }, cancel = UI.Button { x = 3, y = -2, @@ -24,17 +28,15 @@ local learnPage = UI.Dialog { } function learnPage:enable() - self.chooser.choices = { } - + local t = { } for k in pairs(context.learnTypes) do - table.insert(self.chooser.choices, { + table.insert(t, { name = k, value = k, }) end - self.chooser.value = - Milo:getState('learnType') or - self.chooser.choices[1].value + self.grid:setValues(t) + self.grid:setSelected('name', Milo:getState('learnType') or '') Milo:pauseCrafting({ key = 'gridInUse', msg = 'Crafting paused' }) sync.lock(turtle) @@ -53,12 +55,11 @@ function learnPage:eventHandler(event) Milo:resumeCrafting({ key = 'gridInUse' }) UI:setPreviousPage() - elseif event.type == 'accept' then - local choice = self.chooser.value + elseif event.type == 'accept' or event.type == 'grid_select' then + local choice = self.grid:getSelected().value Milo:setState('learnType', choice) UI:setPage(context.learnTypes[choice]) - else return UI.Dialog.eventHandler(self, event) end diff --git a/milo/plugins/machineLearn.lua b/milo/plugins/machineLearn.lua index 4f1afc6..b729ce5 100644 --- a/milo/plugins/machineLearn.lua +++ b/milo/plugins/machineLearn.lua @@ -11,7 +11,7 @@ local turtle = _G.turtle local context = Milo:getContext() local machineLearnWizard = UI.Page { - titleBar = UI.TitleBar { title = 'Learn a crafting recipe' }, + titleBar = UI.TitleBar { title = 'Select machine' }, wizard = UI.Wizard { y = 2, ey = -2, pages = { @@ -19,7 +19,6 @@ local machineLearnWizard = UI.Page { index = 1, grid = UI.ScrollingGrid { y = 2, ey = -2, - values = context.config.nodes, columns = { { heading = 'Name', key = 'displayName' }, }, @@ -47,10 +46,6 @@ Example: Slot 1 is the top slot in a furnace.]], local pages = machineLearnWizard.wizard.pages local machine -function pages.machines.grid:isRowValid(_, value) - return value.mtype == 'machine' and value.adapter and value.adapter.online -end - function pages.machines.grid:getDisplayValues(row) row = Util.shallowCopy(row) row.displayName = row.displayName or row.name @@ -58,7 +53,12 @@ function pages.machines.grid:getDisplayValues(row) end function pages.machines:enable() - self.grid:update() + local t = Util.filter(context.storage.nodes, function(node) + if node.category == 'machine' then + return node.adapter and node.adapter.online and node.adapter.pushItems + end + end) + self.grid:setValues(t) UI.Window.enable(self) end @@ -122,15 +122,12 @@ function pages.confirmation:validate() Milo:saveMachineRecipe(recipe, result, machine.name) - local listingPage = UI:getPage('listing') local displayName = itemDB:getName(result) - listingPage.statusBar.filter:setValue(displayName) - listingPage.notification:success('Learned: ' .. displayName) - listingPage.filter = displayName - listingPage:refresh() - listingPage.grid:draw() - + UI:setPage('listing', { + filter = displayName, + message = 'Learned: ' .. displayName, + }) return true end @@ -141,7 +138,7 @@ function machineLearnWizard:disable() end function machineLearnWizard:eventHandler(event) - if event.type == 'cancel' or event.type == 'accept' then + if event.type == 'cancel' then turtle.emptyInventory() UI:setPage('listing') else diff --git a/milo/plugins/manipulatorView.lua b/milo/plugins/manipulatorView.lua index 84d9107..87b2335 100644 --- a/milo/plugins/manipulatorView.lua +++ b/milo/plugins/manipulatorView.lua @@ -38,6 +38,7 @@ function wizardPage:isValidType(node) { name = 'Manipulator', value = 'manipulator', + category = 'custom', help = 'Manipulator w/bound introspection mod' } end diff --git a/milo/plugins/storageView.lua b/milo/plugins/storageView.lua index acacc0f..bbb7c9a 100644 --- a/milo/plugins/storageView.lua +++ b/milo/plugins/storageView.lua @@ -48,6 +48,7 @@ function storageView:isValidType(node) return m and m.pullItems and { name = 'Storage', value = 'storage', + category = 'storage', help = 'Use for item storage', } end @@ -117,6 +118,7 @@ function lockView:isValidType(node) return m and m.pullItems and { name = 'Storage', value = 'storage', + category = 'storage', help = 'Use for item storage', } end diff --git a/milo/plugins/trashcanView.lua b/milo/plugins/trashcanView.lua index e305251..a5df858 100644 --- a/milo/plugins/trashcanView.lua +++ b/milo/plugins/trashcanView.lua @@ -58,6 +58,7 @@ function wizardPage:isValidType(node) return m and m.pullItems and { name = 'Trashcan', value = 'trashcan', + category = 'custom', help = 'An inventory to send unwanted items', } end diff --git a/milo/plugins/turtleLearn.lua b/milo/plugins/turtleLearn.lua index 23d7743..10948c7 100644 --- a/milo/plugins/turtleLearn.lua +++ b/milo/plugins/turtleLearn.lua @@ -133,15 +133,12 @@ function turtleLearnWizard.wizard.pages.confirmation:validate() local recipe, msg = learnRecipe(self) if recipe then - local listingPage = UI:getPage('listing') local displayName = itemDB:getName(recipe) - listingPage.statusBar.filter:setValue(displayName) - listingPage.notification:success('Learned: ' .. displayName) - listingPage.filter = displayName - listingPage:refresh() - listingPage.grid:draw() - + UI:setPage('listing', { + filter = displayName, + message = 'Learned: ' .. displayName, + }) return true else turtleLearnWizard.notification:error(msg) @@ -149,7 +146,8 @@ function turtleLearnWizard.wizard.pages.confirmation:validate() end function turtleLearnWizard:eventHandler(event) - if event.type == 'cancel' or event.type == 'accept' then + if event.type == 'cancel' then + turtle.emptyInventory() UI:setPage('listing') else return UI.Page.eventHandler(self, event)