From dd0f37d9dd0252bd101bc219eb229769c735ff22 Mon Sep 17 00:00:00 2001 From: "kepler155c@gmail.com" Date: Thu, 3 Jan 2019 05:24:16 -0500 Subject: [PATCH] milo: refactor item page --- milo/Milo.lua | 4 - milo/apps/enderchest.lua | 4 +- milo/apps/furni.lua | 2 +- milo/plugins/item.lua | 313 ++++-------------------------- milo/plugins/item/infoTab.lua | 46 +++++ milo/plugins/item/machinesTab.lua | 64 ++++++ milo/plugins/item/manageTab.lua | 103 ++++++++++ milo/plugins/item/recipeTab.lua | 65 +++++++ milo/plugins/item/resetTab.lua | 55 ++++++ 9 files changed, 373 insertions(+), 283 deletions(-) create mode 100644 milo/plugins/item/infoTab.lua create mode 100644 milo/plugins/item/machinesTab.lua create mode 100644 milo/plugins/item/manageTab.lua create mode 100644 milo/plugins/item/recipeTab.lua create mode 100644 milo/plugins/item/resetTab.lua diff --git a/milo/Milo.lua b/milo/Milo.lua index 758bc1d..58967ef 100644 --- a/milo/Milo.lua +++ b/milo/Milo.lua @@ -85,8 +85,6 @@ local context = { context.storage.nodes[localName] = context.turtleInventory context.storage.nodes[localName].adapter.name = localName -_G._p = context --debug - Milo:init(context) context.storage:initStorage() @@ -135,8 +133,6 @@ Event.on('milo_cycle', function() if not s and m then _G._debug(task.name .. ' crashed') _G._debug(m) - -- _G.printError(task.name .. ' crashed') - -- _G.printError(m) end end processing = false diff --git a/milo/apps/enderchest.lua b/milo/apps/enderchest.lua index 1e88cb8..fce6d25 100644 --- a/milo/apps/enderchest.lua +++ b/milo/apps/enderchest.lua @@ -27,7 +27,6 @@ local directions = Util.transpose { } Event.on('turtle_inventory', function() - print('processing') local s, m = pcall(function() local direction @@ -43,10 +42,11 @@ Event.on('turtle_inventory', function() end turtle.eachFilledSlot(function(s) + print('sending') enderChest().pullItems(direction, s.index) end) end) - if s and not m then + if not s and m then _G.printError(m) end print('idle') diff --git a/milo/apps/furni.lua b/milo/apps/furni.lua index 6969d3b..2cf4611 100644 --- a/milo/apps/furni.lua +++ b/milo/apps/furni.lua @@ -149,7 +149,7 @@ Event.on('turtle_inventory', function() if s and not active then break end - if s and not m then + if not s and m then _G.printError(m) end os.sleep(3) diff --git a/milo/plugins/item.lua b/milo/plugins/item.lua index 40861e1..b9a1371 100644 --- a/milo/plugins/item.lua +++ b/milo/plugins/item.lua @@ -1,262 +1,52 @@ -local Ansi = require('ansi') -local Craft = require('craft2') -local itemDB = require('itemDB') -local Milo = require('milo') local UI = require('ui') local Util = require('util') -local colors = _G.colors +local fs = _G.fs +local shell = _ENV.shell -local context = Milo:getContext() +local function loadDirectory(dir) + local tabs = { } + for _, file in pairs(fs.list(dir)) do + if not fs.isDir(fs.combine(dir, file)) then + local s, m = Util.run(_ENV, fs.combine(dir, file)) + if not s and m then + _G.printError('Error loading: ' .. file) + error(m or 'Unknown error') + end + table.insert(tabs, m) + end + end + return tabs +end -local manageTab = UI.Window { - tabTitle = 'Manage', - form = UI.Form { - x = 1, ex = -1, ey = -1, - --manualControls = true, - [1] = UI.TextEntry { - formLabel = 'Name', formKey = 'displayName', help = 'Override display name', - shadowText = 'Display name', - required = true, - limit = 120, - }, - [2] = UI.TextEntry { - width = 7, - formLabel = 'Min', formKey = 'low', help = 'Craft if below min', - validate = 'numeric', - }, - [3] = UI.TextEntry { - width = 7, - formLabel = 'Max', formKey = 'limit', help = 'Send to trash if above max', - validate = 'numeric', - }, - [4] = UI.Checkbox { - formLabel = 'Ignore Dmg', formKey = 'ignoreDamage', - help = 'Ignore damage of item', - }, - [5] = UI.Checkbox { - formLabel = 'Ignore NBT', formKey = 'ignoreNbtHash', - help = 'Ignore NBT of item', - }, - }, -} +local programDir = fs.getDir(shell.getRunningProgram()) +local tabs = loadDirectory(fs.combine(programDir, 'plugins/item')) -local machinesTab = UI.Window { - tabTitle = 'Machine', - backgroundColor = colors.cyan, - grid = UI.ScrollingGrid { - x = 2, ex = -2, y = 2, ey = -2, - disableHeader = true, - columns = { - { heading = 'Name', key = 'displayName'}, - }, - sortColumn = 'displayName', - help = 'Double-click to set machine', - }, -} - -local recipeTab = UI.Window { - tabTitle = 'Recipe', - backgroundColor = colors.cyan, - grid = UI.ScrollingGrid { - x = 2, ex = -2, y = 2, ey = -4, - disableHeader = true, - columns = { - { heading = 'Slot', key = 'slot', width = 2 }, - { heading = 'Key', key = 'key' }, - }, - sortColumn = 'slot', - }, - ignoreNBT = UI.Button { - x = -13, y = -2, - text = 'Ignore NBT', event = 'ignore_nbt', - }, -} - -local infoTab = UI.Window { - tabTitle = 'Info', - backgroundColor = colors.cyan, - textArea = UI.TextArea { - x = 2, ex = -2, y = 2, - }, -} - -local resetTab = UI.Window { - tabTitle = 'Reset', - backgroundColor = colors.cyan, - textArea = UI.TextArea { - y = 2, ey = 6, - textColor = colors.yellow, - value = [[ Warning! - - This will clear all setting, - recipe, and machine for this item.]] - }, - resetButton = UI.Button { - x = 17, y = 7, - event = 'reset', - text = 'Reset', - help = 'Clear recipe and all settings', - }, -} +table.sort(tabs, function(a, b) return a.index < b.index end) local page = UI.Page { titleBar = UI.TitleBar { title = 'Item settings', previousPage = true, }, - tabs = UI.Tabs { - y = 2, ey = -2, - [1] = manageTab, - [2] = recipeTab, - [3] = machinesTab, - [4] = infoTab, - [5] = resetTab, - }, statusBar = UI.StatusBar { }, notification = UI.Notification { }, } function page:enable(item) - self.origItem = item - self.item = Util.shallowCopy(item) - self.res = item.resource or { } - self.res.displayName = self.item.displayName - manageTab.form:setValues(self.res) - - local machine = Craft.machineLookup[self.item.key] - if machine then - self:filterMachines(machine) + for _, v in pairs(tabs) do + if v.UIElement then + v:setItem(item) + end end - self.tabs:selectTab(manageTab) - - self.tabs:setActive(machinesTab, machine) - self.tabs:setActive(recipeTab, Craft.findRecipe(item)) + self.tabs:selectTab(self.tabs[1]) UI.Page.enable(self) end -function page:filterMachines(machine) - local t = Util.filter(context.storage.nodes, function(node) - if node.category == 'machine' or node.category == 'custom' then -- TODO: - need a setting instead (ie. canCraft) - return node.adapter and node.adapter.online and node.adapter.pushItems - end - end) - machinesTab.grid:setValues(t) - machinesTab.grid:setSelected('name', machine) -end - -function machinesTab.grid:getDisplayValues(row) - row = Util.shallowCopy(row) - row.displayName = row.displayName or row.name - return row -end - -function machinesTab.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 machinesTab:eventHandler(event) - if event.type == 'grid_select' then - Craft.machineLookup[page.item.key] = event.selected.name - Util.writeTable(Craft.MACHINE_LOOKUP, Craft.machineLookup) - - self.grid:draw() - page.notification:info('Machine saved') - - return true - end -end - -function recipeTab:enable() - self.recipe = Craft.findRecipe(page.item) - - local t = { } - if self.recipe then - for k, v in pairs(self.recipe.ingredients) do - table.insert(t, { - slot = k, - key = v, - }) - end - end - self.grid:setValues(t) - UI.Window.enable(self) -end - -function recipeTab:eventHandler(event) - if event.type == 'ignore_nbt' then - local selected = self.grid:getSelected() - local item = itemDB:splitKey(selected.key) - item.nbtHash = nil - selected.key = itemDB:makeKey(item) - self.grid:draw() - - self.recipe.ingredients = { } - for _, v in pairs(self.grid.values) do - self.recipe.ingredients[v.slot] = v.key - end - - Milo:updateRecipe(self.recipe.result, self.recipe) - page.notification:info('Recipe updated') - - return true - end -end - -function infoTab:draw() - local item = page.item - local value = - string.format('%s%s%s\n%s\n', - Ansi.orange, item.displayName, Ansi.reset, - item.name) - - if item.nbtHash then - value = value .. item.nbtHash .. '\n' - end - - value = value .. string.format('\n%sDamage:%s %s', - Ansi.yellow, Ansi.reset, item.damage) - - if item.maxDamage and item.maxDamage > 0 then - value = value .. string.format(' (max: %s)', item.maxDamage) - end - - if item.maxCount then - value = value .. string.format('\n%sStack Size: %s%s', - Ansi.yellow, Ansi.reset, item.maxCount) - end - - self.textArea.value = value - UI.Window.draw(self) -end - function page:eventHandler(event) - if event.type == 'form_cancel' then - UI:setPreviousPage() - - elseif event.type == 'reset' then - if context.userRecipes[self.item.key] then - Milo:updateRecipe(self.item.key, nil) - end - - if context.resources[self.item.key] then - context.resources[self.item.key] = nil - Milo:saveResources() - end - - if Craft.machineLookup[self.item.key] then - Craft.machineLookup[self.item.key] = nil - Util.writeTable(Craft.MACHINE_LOOKUP, Craft.machineLookup) - end - - UI:setPreviousPage() - - elseif event.type == 'tab_activate' then + if event.type == 'tab_activate' then event.activated:focusFirst() elseif event.type == 'form_invalid' then @@ -266,54 +56,25 @@ function page:eventHandler(event) self.statusBar:setStatus(event.focused.help) self.statusBar:draw() - elseif event.type == 'form_complete' then - local item = self.item + elseif event.type == 'success_message' then + self.notification:success(event.message) - if manageTab.form:save() then - if self.res.displayName ~= self.origItem.displayName then - self.origItem.displayName = self.res.displayName - itemDB:add(self.origItem) - itemDB:flush() + elseif event.type == 'info_message' then + self.notification:info(event.message) - -- TODO: ugh - if context.storage.cache[self.origItem.key] then - context.storage.cache[self.origItem.key].displayName = self.res.displayName - end - end - self.res.displayName = nil - Util.prune(self.res, function(v) - if type(v) == 'boolean' then - return v - elseif type(v) == 'string' then - return #v > 0 - end - return true - end) + elseif event.type == 'error_message' then + self.notification:error(event.message) - local newKey = { - name = item.name, - damage = self.res.ignoreDamage and 0 or item.damage, - nbtHash = not self.res.ignoreNbtHash and item.nbtHash or nil, - } - - for k,v in pairs(context.resources) do - if v == self.res then - context.resources[k] = nil - break - end - end - - if not Util.empty(self.res) then - context.resources[Milo:uniqueKey(newKey)] = self.res - end - - Milo:saveResources() - UI:setPreviousPage() - end else return UI.Page.eventHandler(self, event) end return true end +local t = Util.shallowCopy(tabs) +t.y = 2 +t.ey = -2 + +page:add({ tabs = UI.Tabs(t) }) + UI:addPage('item', page) diff --git a/milo/plugins/item/infoTab.lua b/milo/plugins/item/infoTab.lua new file mode 100644 index 0000000..48decdd --- /dev/null +++ b/milo/plugins/item/infoTab.lua @@ -0,0 +1,46 @@ +local Ansi = require('ansi') +local UI = require('ui') + +local colors = _G.colors + +local infoTab = UI.Window { + tabTitle = 'Info', + index = 4, + backgroundColor = colors.cyan, + textArea = UI.TextArea { + x = 2, ex = -2, y = 2, + }, +} + +function infoTab:setItem(item) + self.item = item +end + +function infoTab:draw() + local item = self.item + local value = + string.format('%s%s%s\n%s\n', + Ansi.orange, item.displayName, Ansi.reset, + item.name) + + if item.nbtHash then + value = value .. item.nbtHash .. '\n' + end + + value = value .. string.format('\n%sDamage:%s %s', + Ansi.yellow, Ansi.reset, item.damage) + + if item.maxDamage and item.maxDamage > 0 then + value = value .. string.format(' (max: %s)', item.maxDamage) + end + + if item.maxCount then + value = value .. string.format('\n%sStack Size: %s%s', + Ansi.yellow, Ansi.reset, item.maxCount) + end + + self.textArea.value = value + UI.Window.draw(self) +end + +return infoTab diff --git a/milo/plugins/item/machinesTab.lua b/milo/plugins/item/machinesTab.lua new file mode 100644 index 0000000..f94f13a --- /dev/null +++ b/milo/plugins/item/machinesTab.lua @@ -0,0 +1,64 @@ +local Craft = require('craft2') +local Milo = require('milo') +local UI = require('ui') +local Util = require('util') + +local colors = _G.colors +local context = Milo:getContext() + +local machinesTab = UI.Window { + tabTitle = 'Machine', + index = 3, + backgroundColor = colors.cyan, + grid = UI.ScrollingGrid { + x = 2, ex = -2, y = 2, ey = -2, + disableHeader = true, + columns = { + { heading = 'Name', key = 'displayName'}, + }, + sortColumn = 'displayName', + help = 'Double-click to set machine', + }, +} + +function machinesTab:setItem(item) + self.item = item + local machine = Craft.machineLookup[self.item.key] + if machine then + local t = Util.filter(context.storage.nodes, function(node) + if node.category == 'machine' or node.category == 'custom' then -- TODO: - need a setting instead (ie. canCraft) + return node.adapter and node.adapter.online and node.adapter.pushItems + end + end) + self.grid:setValues(t) + self.grid:setSelected('name', machine) + end + self.parent:setActive(self, machine) +end + +function machinesTab.grid:getDisplayValues(row) + row = Util.shallowCopy(row) + row.displayName = row.displayName or row.name + return row +end + +function machinesTab.grid:getRowTextColor(row, selected) + if row.name == Craft.machineLookup[self.parent.item.key] then + return colors.yellow + end + return UI.Grid:getRowTextColor(row, selected) +end + +function machinesTab:eventHandler(event) + if event.type == 'grid_select' then + Craft.machineLookup[self.item.key] = event.selected.name + Util.writeTable(Craft.MACHINE_LOOKUP, Craft.machineLookup) + + self.grid:draw() + self:emit({ type = 'info_message', message = 'Machine saved' }) + + return true + end +end + +return machinesTab diff --git a/milo/plugins/item/manageTab.lua b/milo/plugins/item/manageTab.lua new file mode 100644 index 0000000..7bed3f4 --- /dev/null +++ b/milo/plugins/item/manageTab.lua @@ -0,0 +1,103 @@ +local itemDB = require('itemDB') +local Milo = require('milo') +local UI = require('ui') +local Util = require('util') + +local context = Milo:getContext() + +local manageTab = UI.Window { + tabTitle = 'Manage', + index = 1, + form = UI.Form { + x = 1, ex = -1, ey = -1, + --manualControls = true, + [1] = UI.TextEntry { + formLabel = 'Name', formKey = 'displayName', help = 'Override display name', + shadowText = 'Display name', + required = true, + limit = 120, + }, + [2] = UI.TextEntry { + width = 7, + formLabel = 'Min', formKey = 'low', help = 'Craft if below min', + validate = 'numeric', + }, + [3] = UI.TextEntry { + width = 7, + formLabel = 'Max', formKey = 'limit', help = 'Send to trash if above max', + validate = 'numeric', + }, + [4] = UI.Checkbox { + formLabel = 'Ignore Dmg', formKey = 'ignoreDamage', + help = 'Ignore damage of item', + }, + [5] = UI.Checkbox { + formLabel = 'Ignore NBT', formKey = 'ignoreNbtHash', + help = 'Ignore NBT of item', + }, + }, +} + +function manageTab:setItem(item) + self.origItem = item + self.item = Util.shallowCopy(item) + self.res = item.resource or { } + self.res.displayName = self.item.displayName + manageTab.form:setValues(self.res) +end + +function manageTab:eventHandler(event) + if event.type == 'form_cancel' then + UI:setPreviousPage() + + elseif event.type == 'form_complete' then + local item = self.item + + if self.form:save() then + if self.res.displayName ~= self.origItem.displayName then + self.origItem.displayName = self.res.displayName + itemDB:add(self.origItem) + itemDB:flush() + + -- TODO: ugh + if context.storage.cache[self.origItem.key] then + context.storage.cache[self.origItem.key].displayName = self.res.displayName + end + end + self.res.displayName = nil + Util.prune(self.res, function(v) + if type(v) == 'boolean' then + return v + elseif type(v) == 'string' then + return #v > 0 + end + return true + end) + + local newKey = { + name = item.name, + damage = self.res.ignoreDamage and 0 or item.damage, + nbtHash = not self.res.ignoreNbtHash and item.nbtHash or nil, + } + + for k,v in pairs(context.resources) do + if v == self.res then + context.resources[k] = nil + break + end + end + + if not Util.empty(self.res) then + context.resources[Milo:uniqueKey(newKey)] = self.res + end + + Milo:saveResources() + UI:setPreviousPage() + end + else + return + end + return true +end + +return manageTab diff --git a/milo/plugins/item/recipeTab.lua b/milo/plugins/item/recipeTab.lua new file mode 100644 index 0000000..e634abe --- /dev/null +++ b/milo/plugins/item/recipeTab.lua @@ -0,0 +1,65 @@ +local Craft = require('craft2') +local itemDB = require('itemDB') +local Milo = require('milo') +local UI = require('ui') + +local colors = _G.colors + +local recipeTab = UI.Window { + tabTitle = 'Recipe', + index = 2, + backgroundColor = colors.cyan, + grid = UI.ScrollingGrid { + x = 2, ex = -2, y = 2, ey = -4, + disableHeader = true, + columns = { + { heading = 'Slot', key = 'slot', width = 2 }, + { heading = 'Key', key = 'key' }, + }, + sortColumn = 'slot', + }, + ignoreNBT = UI.Button { + x = -13, y = -2, + text = 'Ignore NBT', event = 'ignore_nbt', + }, +} + +function recipeTab:setItem(item) + self.item = item + self.recipe = Craft.findRecipe(self.item) + + self.parent:setActive(self, self.recipe) + + local t = { } + if self.recipe then + for k, v in pairs(self.recipe.ingredients) do + table.insert(t, { + slot = k, + key = v, + }) + end + end + self.grid:setValues(t) +end + +function recipeTab:eventHandler(event) + if event.type == 'ignore_nbt' then + local selected = self.grid:getSelected() + local item = itemDB:splitKey(selected.key) + item.nbtHash = nil + selected.key = itemDB:makeKey(item) + self.grid:draw() + + self.recipe.ingredients = { } + for _, v in pairs(self.grid.values) do + self.recipe.ingredients[v.slot] = v.key + end + + Milo:updateRecipe(self.recipe.result, self.recipe) + self:emit({ type = 'info_message', message = 'Recipe updated' }) + + return true + end +end + +return recipeTab diff --git a/milo/plugins/item/resetTab.lua b/milo/plugins/item/resetTab.lua new file mode 100644 index 0000000..172d8a0 --- /dev/null +++ b/milo/plugins/item/resetTab.lua @@ -0,0 +1,55 @@ +local Craft = require('craft2') +local Milo = require('milo') +local UI = require('ui') +local Util = require('util') + +local colors = _G.colors +local context = Milo:getContext() + +local resetTab = UI.Window { + tabTitle = 'Reset', + index = 5, + backgroundColor = colors.cyan, + textArea = UI.TextArea { + y = 2, ey = 6, + textColor = colors.yellow, + value = [[ Warning! + + This will clear all setting, + recipe, and machine for this item.]] + }, + resetButton = UI.Button { + x = 17, y = 7, + event = 'reset', + text = 'Reset', + help = 'Clear recipe and all settings', + }, +} + +function resetTab:setItem(item) + self.item = item +end + +function resetTab:eventHandler(event) + if event.type == 'reset' then + if context.userRecipes[self.item.key] then + Milo:updateRecipe(self.item.key, nil) + end + + if context.resources[self.item.key] then + context.resources[self.item.key] = nil + Milo:saveResources() + end + + if Craft.machineLookup[self.item.key] then + Craft.machineLookup[self.item.key] = nil + Util.writeTable(Craft.MACHINE_LOOKUP, Craft.machineLookup) + end + + UI:setPreviousPage() + + return true + end +end + +return resetTab