diff --git a/milo/plugins/item/manageTab.lua b/milo/plugins/item/manageTab.lua index 7bed3f4..98407eb 100644 --- a/milo/plugins/item/manageTab.lua +++ b/milo/plugins/item/manageTab.lua @@ -43,7 +43,7 @@ function manageTab:setItem(item) self.item = Util.shallowCopy(item) self.res = item.resource or { } self.res.displayName = self.item.displayName - manageTab.form:setValues(self.res) + self.form:setValues(self.res) end function manageTab:eventHandler(event) diff --git a/milo/plugins/item/storeTab.lua b/milo/plugins/item/storeTab.lua new file mode 100644 index 0000000..e11f225 --- /dev/null +++ b/milo/plugins/item/storeTab.lua @@ -0,0 +1,65 @@ +local Config = require('config') +local UI = require('ui') + +local os = _G.os + +local config = Config.load('store') + +local storeTab = UI.Window { + tabTitle = 'Store', + index = 1, + form = UI.Form { + x = 1, ex = -1, ey = -1, + manualControls = true, + [1] = UI.TextEntry { + formLabel = 'Name', formKey = 'name', + help = 'Unique name used when paying for an item', + required = true, + limit = 64, + }, + [2] = UI.TextEntry { + formLabel = 'Price', formKey = 'price', + help = 'Per item cost', + required = true, + validate = 'numeric', + }, + clearButton = UI.Button { + x = 2, y = -2, + event = 'clear', + text = 'Remove', + }, + updateButton = UI.Button { + x = -12, y = -2, + event = 'update', + text = 'Update', + }, + }, +} + +function storeTab:setItem(item) + self.item = item + self.form:setValues(config[item.key] or { }) +end + +function storeTab:eventHandler(event) + if event.type == 'clear' then + self.form:setValues({ }) + config[self.item.key] = nil + Config.update('store', config) + os.queueEvent('store_refresh') + self.form:draw() + + elseif event.type == 'update' then + if self.form:save() then + config[self.item.key] = self.form.values + Config.update('store', config) + os.queueEvent('store_refresh') + self:emit({ type = 'success_message', message = 'Updated' }) + end + else + return + end + return true +end + +return storeTab diff --git a/milo/plugins/storeConfig.lua b/milo/plugins/storeConfig.lua new file mode 100644 index 0000000..8d27e60 --- /dev/null +++ b/milo/plugins/storeConfig.lua @@ -0,0 +1,67 @@ +local UI = require('ui') + +local colors = _G.colors +local device = _G.device + +--[[ Configuration Page ]]-- +local wizardPage = UI.Window { + title = 'Store Front', + index = 2, + backgroundColor = colors.cyan, + form = UI.Form { + x = 2, ex = -2, y = 2, ey = -4, + manualControls = true, + [1] = UI.TextEntry { + formLabel = 'Domain', formKey = 'domain', + help = 'Krist wallet address', + limit = 64, + shadowText = 'example.kst', + required = true, + }, + [2] = UI.TextEntry { + formLabel = 'Password', formKey = 'password', + shadowText = 'password', + limit = 64, + required = true, + help = 'Krist wallet password', + }, + [3] = UI.Chooser { + width = 9, + formLabel = 'Font Size', formKey = 'textScale', + nochoice = 'Small', + choices = { + { name = 'Small', value = .5 }, + { name = 'Large', value = 1 }, + }, + help = 'Adjust text scaling', + }, + }, +} + +function wizardPage:setNode(node) + self.form:setValues(node) +end + +function wizardPage:validate() + return self.form:save() +end + +function wizardPage:saveNode(node) +-- queue event ?? +end + +function wizardPage:isValidType(node) + local m = device[node.name] + return m and m.type == 'monitor' and { + name = 'Store Front', + value = 'store', + category = 'display', + help = 'Add a store front display' + } +end + +function wizardPage:isValidFor(node) + return node.mtype == 'store' +end + +UI:getPage('nodeWizard').wizard:add({ storeFront = wizardPage }) diff --git a/milo/plugins/storeView.lua b/milo/plugins/storeView.lua new file mode 100644 index 0000000..35a6b76 --- /dev/null +++ b/milo/plugins/storeView.lua @@ -0,0 +1,146 @@ +local Config = require('config') +local Event = require('event') +local itemDB = require('itemDB') +local Milo = require('milo') +local UI = require('ui') +local Util = require('util') + +local colors = _G.colors +local context = Milo:getContext() +local os = _G.os + +local config = Config.load('store') + +--[[ Display ]]-- +local function createPage(node) + local monitor = UI.Device { + device = node.adapter, + textScale = node.textScale or .5, + } + + function monitor:resize() + self.textScale = node.textScale or .5 + UI.Device.resize(self) + end + + local page = UI.Page { + parent = monitor, + grid = UI.Grid { + ey = -6, + columns = { + { heading = 'Qty', key = 'count', width = 5 }, + { heading = 'Price', key = 'price', width = 5 }, + { heading = 'Name', key = 'displayName' }, + { heading = 'Address', key = 'address', width = 20 }, + }, + sortColumn = 'displayName', + }, + buttons = UI.Window { + y = -5, height = 5, + backgroundColor = colors.gray, + prevButton = UI.Button { + x = 2, y = 2, height = 3, width = 5, + event = 'previous', + backgroundColor = colors.lightGray, + text = ' < ' + }, + nextButton = UI.Button { + x = -6, y = 2, height = 3, width = 5, + event = 'next', + backgroundColor = colors.lightGray, + text = ' > ' + }, + }, + timestamp = os.clock(), + } + + function page.grid:getRowTextColor(row, selected) + if row.count == 0 then + return colors.gray + end + return UI.Grid:getRowTextColor(row, selected) + end + + function page.grid:getDisplayValues(row) + row = Util.shallowCopy(row) + row.count = Util.toBytes(row.count) + row.address = row.name .. '@' .. node.domain + return row + end + + function page:eventHandler(event) + if event.type == 'next' then + self.grid:nextPage() + + elseif event.type == 'previous' then + self.grid:previousPage() + + else + return UI.Page.eventHandler(self, event) + end + + Event.onTimeout(.1, function() + self:setFocus(self.grid) + self:sync() + end) + return true + end + + function page:refresh() + local list = Milo:listItems() + self.grid.values = { } + for k,v in pairs(config) do + local item = list[k] + if item then + table.insert(self.grid.values, { + displayName = item.displayName, + count = item.count, + name = v.name, + price = v.price, + }) + else + table.insert(self.grid.values, { + displayName = itemDB:getName(k), + count = 0, + name = v.name, + price = v.price, + }) + end + end + self.grid:update() + self.grid:draw() + end + + function page:update() + page:refresh() + page:sync() + end + + UI:setPage(page) + return page +end + +local pages = { } + +-- called when an item to sell has been changed +Event.on('store_refresh', function() + config = Config.load('store') +end) + +--[[ Task ]]-- +local StoreTask = { + name = 'store', + priority = 30, +} + +function StoreTask:cycle() + for node in context.storage:filterActive('store') do + if not pages[node.name] then + pages[node.name] = createPage(node) + end + -- update the display + pages[node.name]:update() + end +end + +Milo:registerTask(StoreTask)