add basic bundle selecting support
This commit is contained in:
parent
56a6fb85bf
commit
3fe33524fb
36
dbg.lua
Normal file
36
dbg.lua
Normal file
@ -0,0 +1,36 @@
|
||||
|
||||
local dbg_file
|
||||
function dbg(...)
|
||||
if dbg_file then
|
||||
local out = io.open(dbg_file, "a")
|
||||
if not out then return end
|
||||
for i = 1, select("#", ...) do
|
||||
local value = select(i, ...)
|
||||
if type(value) == "table" then
|
||||
out:write(textutils.serialise(value))
|
||||
else
|
||||
out:write(tostring(value))
|
||||
out:write("\t")
|
||||
end
|
||||
end
|
||||
out:write("\n")
|
||||
out:close()
|
||||
else
|
||||
local pretty = require("cc.pretty")
|
||||
for i = 1, select("#", ...) do
|
||||
local value = select(i, ...)
|
||||
pretty.pretty_print(value)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return setmetatable({}, { __call = function(_, file)
|
||||
if dbg_file then return end
|
||||
|
||||
if file then
|
||||
dbg_file = fs.combine(shell.dir(), file)
|
||||
if dbg_file then
|
||||
fs.delete(dbg_file)
|
||||
end
|
||||
end
|
||||
end})
|
43
main.lua
43
main.lua
@ -1,33 +1,7 @@
|
||||
local ui = require("ui")
|
||||
local term_stack = require("term-stack")
|
||||
|
||||
local dbg_file = fs.combine(shell.dir(), "logs.txt")
|
||||
if dbg_file then
|
||||
fs.delete(dbg_file)
|
||||
end
|
||||
function dbg(...)
|
||||
if dbg_file then
|
||||
local out = io.open(dbg_file, "a")
|
||||
if not out then return end
|
||||
for i = 1, select("#", ...) do
|
||||
local value = select(i, ...)
|
||||
if type(value) == "table" then
|
||||
out:write(textutils.serialise(value))
|
||||
else
|
||||
out:write(tostring(value))
|
||||
out:write(" ")
|
||||
end
|
||||
end
|
||||
out:write("\n")
|
||||
out:close()
|
||||
else
|
||||
local pretty = require("cc.pretty")
|
||||
for i = 1, select("#", ...) do
|
||||
local value = select(i, ...)
|
||||
pretty.pretty_print(value)
|
||||
end
|
||||
end
|
||||
end
|
||||
require("dbg")("logs.txt")
|
||||
|
||||
local function is_inventory(peripheral_name)
|
||||
local types = {peripheral.getType(peripheral_name)}
|
||||
@ -60,8 +34,19 @@ end
|
||||
local function main()
|
||||
local main_view = require("views.main")
|
||||
|
||||
local bundles = {
|
||||
green = {
|
||||
["minecraft:kelp"] = 64,
|
||||
["minecraft:grass_block"] = 64
|
||||
},
|
||||
terraform = {
|
||||
["minecraft:grass_block"] = 64,
|
||||
["minecraft:stone"] = 64,
|
||||
["#green"] = 1
|
||||
}
|
||||
}
|
||||
local inventories = list_inventories()
|
||||
main_view:prepare(inventories, "minecraft:barrel_4")
|
||||
main_view:prepare(inventories, bundles, "minecraft:barrel_4")
|
||||
|
||||
local update_interval = 0.1
|
||||
local update_timer = os.startTimer(update_interval)
|
||||
@ -81,7 +66,7 @@ local function main()
|
||||
end
|
||||
end
|
||||
|
||||
main_view:draw()
|
||||
main_view:run()
|
||||
end
|
||||
end
|
||||
|
||||
|
540
views/main.lua
540
views/main.lua
@ -11,6 +11,14 @@ local function rect(x, y, w, h)
|
||||
return { x = x, y = y, w = w, h = h or w }
|
||||
end
|
||||
|
||||
local function copy_table(t)
|
||||
local t_copy = {}
|
||||
for k, v in pairs(t) do
|
||||
t_copy[k] = v
|
||||
end
|
||||
return t_copy
|
||||
end
|
||||
|
||||
local function list_items(inventories)
|
||||
local item_registry = {}
|
||||
for _, name in ipairs(inventories) do
|
||||
@ -69,6 +77,13 @@ local function vline(x, y, height)
|
||||
end
|
||||
end
|
||||
|
||||
local function hline(x, y, length)
|
||||
for i=1, length do
|
||||
term.setCursorPos(x+i-1, y)
|
||||
term.write("-")
|
||||
end
|
||||
end
|
||||
|
||||
local function get_item_counts(items)
|
||||
local item_counts = {}
|
||||
for name, item_collection in pairs(items) do
|
||||
@ -77,14 +92,85 @@ local function get_item_counts(items)
|
||||
return item_counts
|
||||
end
|
||||
|
||||
function main_view:prepare(inventories, result_inventory)
|
||||
self.event = {}
|
||||
local function is_bundle_name(name)
|
||||
return name:find("#") == 1
|
||||
end
|
||||
|
||||
self.is_left_active = true
|
||||
local function get_number_width(num)
|
||||
return math.floor(math.log(num, 10) + 1)
|
||||
end
|
||||
|
||||
-- TODO: improve this function
|
||||
local function resolve_bundle_items(bundles, bundle_name, seen_bundles)
|
||||
seen_bundles = seen_bundles or {}
|
||||
if seen_bundles[bundle_name] then return nil, "Circular dependency" end
|
||||
|
||||
local bundle = bundles[bundle_name]
|
||||
if not bundle then return {} end
|
||||
|
||||
local items = {}
|
||||
for dep_name, dep_count in pairs(bundle) do
|
||||
if is_bundle_name(dep_name) then
|
||||
seen_bundles[bundle_name] = true
|
||||
local dep_items, err = resolve_bundle_items(bundles, dep_name:sub(2), seen_bundles)
|
||||
if not dep_items then return nil, err end
|
||||
for item_name, item_count in pairs(dep_items) do
|
||||
items[item_name] = (items[item_name] or 0) + item_count * dep_count
|
||||
end
|
||||
seen_bundles[bundle_name] = nil
|
||||
else
|
||||
items[dep_name] = (items[dep_name] or 0) + dep_count
|
||||
end
|
||||
end
|
||||
|
||||
return items
|
||||
end
|
||||
|
||||
-- TODO: improve this function
|
||||
local function populate_bundle_details(bundle_details, bundles)
|
||||
for bundle_name in pairs(bundles) do
|
||||
local hash_name = "#"..bundle_name
|
||||
if not bundle_details[hash_name] then
|
||||
bundle_details[hash_name] = resolve_bundle_items(bundles, bundle_name)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function derive_available_bundles(available_items, bundle_details)
|
||||
local available_bundles = {}
|
||||
for bundle_name, items in pairs(bundle_details) do
|
||||
local bundle_count = math.huge
|
||||
for item_name, item_count in pairs(items) do
|
||||
local available_count = available_items[item_name] or 0
|
||||
bundle_count = math.min(bundle_count, math.max(0, available_count / item_count))
|
||||
end
|
||||
if bundle_count ~= math.huge and bundle_count > 0 then
|
||||
available_bundles[bundle_name] = math.max(bundle_count, 1)
|
||||
end
|
||||
end
|
||||
return available_bundles
|
||||
end
|
||||
|
||||
local function sort_names_by_counts(names, items, bundles)
|
||||
table.sort(names, function(a, b)
|
||||
local count_a = items[a] or bundles[a]
|
||||
local count_b = items[b] or bundles[b]
|
||||
if count_a == count_b then
|
||||
return a:gsub("^#", "") < b:gsub("^#", "")
|
||||
else
|
||||
return count_a > count_b
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function main_view:prepare(inventories, bundles, result_inventory)
|
||||
self.event = {}
|
||||
|
||||
self.main_area = rect(1, 1, term.getSize())
|
||||
self.split_x = math.floor(self.main_area.w*0.5)
|
||||
self.left_area, self.right_area = vsplit(self.main_area, self.split_x)
|
||||
self.is_left_active = true
|
||||
self.bundle_name = ""
|
||||
|
||||
self.result_inventory = result_inventory
|
||||
self.inventories = inventories
|
||||
@ -94,85 +180,239 @@ function main_view:prepare(inventories, result_inventory)
|
||||
self.item_details = {}
|
||||
populate_item_details(self.item_details, self.item_registry)
|
||||
|
||||
local all_item_counts = get_item_counts(self.item_registry)
|
||||
self.left_store = {
|
||||
all_items = all_item_counts,
|
||||
filtered_names = self:list_filtered_names(all_item_counts, ""),
|
||||
search_bar = "",
|
||||
selected_idx = 1,
|
||||
scroll = 0
|
||||
}
|
||||
self.right_store = {
|
||||
all_items = {},
|
||||
filtered_names = {},
|
||||
search_bar = "",
|
||||
selected_idx = 1,
|
||||
scroll = 0
|
||||
}
|
||||
self.bundles = bundles or {}
|
||||
self.bundle_details = {}
|
||||
populate_bundle_details(self.bundle_details, self.bundles)
|
||||
|
||||
do
|
||||
local available_items = get_item_counts(self.item_registry)
|
||||
local available_bundles = derive_available_bundles(available_items, self.bundle_details)
|
||||
|
||||
local filtered_names = {}
|
||||
do
|
||||
for name, _ in pairs(available_items) do
|
||||
table.insert(filtered_names, name)
|
||||
end
|
||||
for name, _ in pairs(available_bundles) do
|
||||
table.insert(filtered_names, name)
|
||||
end
|
||||
sort_names_by_counts(filtered_names, available_items, available_bundles)
|
||||
end
|
||||
|
||||
self.left_store = {
|
||||
items = available_items,
|
||||
bundles = available_bundles,
|
||||
|
||||
filtered_names = filtered_names,
|
||||
selected_idx = 1,
|
||||
search_bar = "",
|
||||
scroll = 0
|
||||
}
|
||||
self.right_store = {
|
||||
total_items = {},
|
||||
items = {},
|
||||
bundles = {},
|
||||
|
||||
filtered_names = {},
|
||||
selected_idx = 1,
|
||||
search_bar = "",
|
||||
scroll = 0
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
function main_view:list_filtered_names(all_items, name_filter)
|
||||
|
||||
function main_view:list_filtered_names(items, bundles, name_filter)
|
||||
name_filter = name_filter:lower()
|
||||
|
||||
local names = {}
|
||||
for name, count in pairs(all_items) do
|
||||
for name, count in pairs(items) do
|
||||
local display_name = self.item_details[name].display_name:lower()
|
||||
if display_name:find(name_filter) and count > 0 then
|
||||
table.insert(names, name)
|
||||
end
|
||||
end
|
||||
|
||||
table.sort(names, function(a, b)
|
||||
if all_items[a] == all_items[b] then
|
||||
return a < b
|
||||
else
|
||||
return all_items[a] > all_items[b]
|
||||
for name, count in pairs(bundles) do
|
||||
if name:find(name_filter) and count > 0 then
|
||||
table.insert(names, name)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
sort_names_by_counts(names, items, bundles)
|
||||
|
||||
return names
|
||||
end
|
||||
|
||||
function main_view:display_item_list(store, area, active)
|
||||
function main_view:refresh_filtered_names(store, area)
|
||||
store.filtered_names = main_view:list_filtered_names(store.items, store.bundles, store.search_bar or "")
|
||||
self:set_selected_option(store, area, store.selected_idx)
|
||||
end
|
||||
|
||||
function main_view:set_selected_option(store, area, idx)
|
||||
local filtered_count = #store.filtered_names
|
||||
store.selected_idx = clamp(idx, 1, filtered_count)
|
||||
|
||||
local item_list_height = area.h-1
|
||||
|
||||
if store.scroll+item_list_height > filtered_count and filtered_count > item_list_height then
|
||||
store.scroll = filtered_count-item_list_height
|
||||
end
|
||||
|
||||
local margin = 2
|
||||
if store.selected_idx > store.scroll+item_list_height-margin then
|
||||
local max_scroll = math.max(filtered_count - item_list_height, 0)
|
||||
store.scroll = math.min(store.selected_idx-item_list_height+margin, max_scroll)
|
||||
elseif store.selected_idx <= store.scroll+margin then
|
||||
store.scroll = math.max(store.selected_idx-1-margin, 0)
|
||||
end
|
||||
end
|
||||
|
||||
function main_view:select_option(store, area, item_name)
|
||||
for i, name in ipairs(store.filtered_names) do
|
||||
if name == item_name then
|
||||
self:set_selected_option(store, area, i)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function main_view:process_movement_keys(store, area)
|
||||
if self.down_pressed then
|
||||
self:set_selected_option(store, area, store.selected_idx + 1)
|
||||
elseif self.up_pressed then
|
||||
self:set_selected_option(store, area, store.selected_idx - 1)
|
||||
end
|
||||
|
||||
local lstore = self.left_store
|
||||
local rstore = self.right_store
|
||||
|
||||
local left_selected = lstore.filtered_names[lstore.selected_idx]
|
||||
local right_selected = rstore.filtered_names[rstore.selected_idx]
|
||||
local selected_option = self.is_left_active and left_selected or right_selected
|
||||
|
||||
if selected_option and (self.right_pressed or self.left_pressed) then
|
||||
if is_bundle_name(selected_option) then
|
||||
local bundle_name = selected_option
|
||||
local bundle = self.bundle_details[bundle_name]
|
||||
|
||||
if self.right_pressed and lstore.bundles[bundle_name] > 0 then
|
||||
for item, count in pairs(bundle) do
|
||||
lstore.items[item] = lstore.items[item] - count
|
||||
end
|
||||
rstore.bundles[bundle_name] = (rstore.bundles[bundle_name] or 0) + 1
|
||||
|
||||
elseif self.left_pressed and rstore.bundles[bundle_name] > 0 then
|
||||
for item, count in pairs(bundle) do
|
||||
lstore.items[item] = lstore.items[item] + count
|
||||
end
|
||||
rstore.bundles[bundle_name] = rstore.bundles[bundle_name] - 1
|
||||
end
|
||||
else
|
||||
local item = selected_option
|
||||
local stack_size = self.item_details[item].stack_size
|
||||
|
||||
local src_items, dest_items
|
||||
if self.right_pressed then
|
||||
src_items, dest_items = lstore.items, rstore.items
|
||||
elseif self.left_pressed then
|
||||
src_items, dest_items = rstore.items, lstore.items
|
||||
end
|
||||
|
||||
local transferred = math.min(src_items[item] or 0, stack_size)
|
||||
src_items[item] = (src_items[item] or 0) - transferred
|
||||
dest_items[item] = (dest_items[item] or 0) + transferred
|
||||
end
|
||||
|
||||
lstore.bundles = derive_available_bundles(lstore.items, self.bundle_details)
|
||||
self:refresh_filtered_names(lstore, self.left_area)
|
||||
self:refresh_filtered_names(rstore, self.right_area)
|
||||
self:select_option(store, area, selected_option)
|
||||
end
|
||||
end
|
||||
|
||||
function main_view:display_list(store, area, selected_idx)
|
||||
term_stack.push_cursor(area.x, area.y)
|
||||
|
||||
local filtered_names = store.filtered_names
|
||||
local shown_count = #filtered_names
|
||||
local filtered_count = #store.filtered_names
|
||||
|
||||
local max_count = 0
|
||||
for i=1, math.min(area.h, shown_count) do
|
||||
local name = filtered_names[i + store.scroll]
|
||||
local count = store.all_items[name]
|
||||
max_count = math.max(max_count, count)
|
||||
end
|
||||
local max_count_width = math.floor(math.log(max_count, 10) + 1)
|
||||
|
||||
for row=1, math.min(area.h, shown_count) do
|
||||
local i = row + store.scroll
|
||||
local name = filtered_names[i]
|
||||
local count = store.all_items[name]
|
||||
local item_info = self.item_details[name]
|
||||
local count_width = math.floor(math.log(count, 10) + 1)
|
||||
if i == store.selected_idx and active then
|
||||
term.setTextColor(colors.yellow)
|
||||
else
|
||||
term.setTextColor(colors.white)
|
||||
local count_collumn_width
|
||||
do -- Figure out how wide does the count column need to be
|
||||
local max_count = 0
|
||||
for row=1, math.min(area.h, filtered_count) do
|
||||
local name = store.filtered_names[row + store.scroll]
|
||||
if name then
|
||||
if is_bundle_name(name) then
|
||||
max_count = math.max(max_count, store.bundles[name])
|
||||
else
|
||||
max_count = math.max(max_count, store.items[name])
|
||||
end
|
||||
end
|
||||
end
|
||||
term.setCursorPos((max_count_width+1 - count_width), row)
|
||||
term.write(count)
|
||||
term.setCursorPos(max_count_width+2, row)
|
||||
term.write(ensure_width(item_info.display_name, area.w-max_count_width-1))
|
||||
count_collumn_width = get_number_width(max_count)
|
||||
end
|
||||
|
||||
if shown_count > area.h then
|
||||
local scroll_height = math.max(1, area.h/shown_count*area.h)
|
||||
local y = 1+store.scroll/shown_count*area.h
|
||||
paintutils.drawLine(area.w, y, area.w, y+scroll_height-1, colors.lightGray)
|
||||
do -- Display the options
|
||||
for row=1, math.min(area.h, filtered_count) do
|
||||
local i = row + store.scroll
|
||||
local name = store.filtered_names[i]
|
||||
if name then
|
||||
local count, display_name
|
||||
|
||||
if is_bundle_name(name) then
|
||||
count, display_name = store.bundles[name], name
|
||||
else
|
||||
count, display_name = store.items[name], self.item_details[name].display_name
|
||||
end
|
||||
|
||||
local count_width = math.floor(math.log(count, 10) + 1)
|
||||
if i == selected_idx then
|
||||
term.setTextColor(colors.yellow)
|
||||
else
|
||||
term.setTextColor(colors.white)
|
||||
end
|
||||
term.setCursorPos((count_collumn_width+1 - count_width), row)
|
||||
term.write(count)
|
||||
term.setCursorPos(count_collumn_width+2, row)
|
||||
term.write(ensure_width(display_name, area.w-count_collumn_width-1))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
do -- Display the scrollbar on the right
|
||||
if filtered_count > area.h then
|
||||
local total_height = math.max(filtered_count)
|
||||
local scroll_height = math.max(1, area.h/total_height*area.h)
|
||||
local y = 1+store.scroll/filtered_count*area.h
|
||||
paintutils.drawLine(area.w, y, area.w, y+scroll_height-1, colors.lightGray)
|
||||
end
|
||||
end
|
||||
|
||||
term_stack.pop_cursor()
|
||||
end
|
||||
|
||||
function main_view:display_list_with_search(store, area, active)
|
||||
term_stack.push_cursor(area.x, area.y)
|
||||
|
||||
local new_search_bar = ui:textbox(area.w, active, "Search", store.search_bar)
|
||||
if new_search_bar ~= store.search_bar then
|
||||
store.search_bar = new_search_bar
|
||||
self:refresh_filtered_names(store, area)
|
||||
end
|
||||
|
||||
if active then
|
||||
self:process_movement_keys(store, area)
|
||||
end
|
||||
|
||||
term.setBackgroundColor(colors.black)
|
||||
main_view:display_list(store, rect(1, 2, area.w, area.h-1), active and store.selected_idx)
|
||||
|
||||
term_stack.pop_cursor()
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
function main_view:move_item(item_name, amount, destination)
|
||||
local item_collection = self.item_registry[item_name]
|
||||
|
||||
@ -195,72 +435,12 @@ function main_view:move_item(item_name, amount, destination)
|
||||
return moved_amount
|
||||
end
|
||||
|
||||
function main_view:update_selected_item(store, area, idx)
|
||||
local filtered_count = #store.filtered_names
|
||||
store.selected_idx = clamp(idx, 1, filtered_count)
|
||||
|
||||
local margin = 2
|
||||
local item_list_height = area.h-1
|
||||
if store.selected_idx > store.scroll+item_list_height-margin then
|
||||
store.scroll = math.min(store.selected_idx-item_list_height+margin, filtered_count-item_list_height)
|
||||
elseif store.selected_idx <= store.scroll+margin then
|
||||
store.scroll = math.max(store.selected_idx-1-margin, 0)
|
||||
end
|
||||
end
|
||||
|
||||
function main_view:select_item(store, area, item_name)
|
||||
for i, name in ipairs(store.filtered_names) do
|
||||
if name == item_name then
|
||||
self:update_selected_item(store, area, i)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function main_view:refresh_filtered_names(store, area)
|
||||
store.filtered_names = main_view:list_filtered_names(store.all_items, store.search_bar or "")
|
||||
self:update_selected_item(store, area, store.selected_idx)
|
||||
end
|
||||
|
||||
function main_view:display_items_with_search(store, area, active)
|
||||
term_stack.push_cursor(area.x, area.y)
|
||||
|
||||
local new_search_bar = ui:textbox(area.w, active, "Search", store.search_bar)
|
||||
if new_search_bar ~= store.search_bar then
|
||||
store.search_bar = new_search_bar
|
||||
self:refresh_filtered_names(store, area)
|
||||
end
|
||||
|
||||
if active then
|
||||
if ui.event[1] == "key" then
|
||||
local key = ui.event[2]
|
||||
if key == keys.down or (main_view.ctrl_down and key == keys.j) then
|
||||
store.selected_idx = math.min(store.selected_idx + 1, #store.filtered_names)
|
||||
elseif key == keys.up or (main_view.ctrl_down and key == keys.k) then
|
||||
store.selected_idx = math.max(store.selected_idx - 1, 1)
|
||||
end
|
||||
|
||||
local margin = 2
|
||||
local item_list_height = area.h-1
|
||||
if store.selected_idx > store.scroll+item_list_height-margin then
|
||||
store.scroll = math.min(store.selected_idx-item_list_height+margin, #store.filtered_names - item_list_height)
|
||||
elseif store.selected_idx <= store.scroll+margin then
|
||||
store.scroll = math.max(store.selected_idx-1-margin, 0)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
term.setBackgroundColor(colors.black)
|
||||
main_view:display_item_list(store, rect(1, 2, area.w, area.h-1), active)
|
||||
|
||||
term_stack.pop_cursor()
|
||||
end
|
||||
|
||||
function main_view:has_selected_items()
|
||||
for _, count in pairs(main_view.right_store.all_items) do
|
||||
if count > 0 then
|
||||
return true
|
||||
end
|
||||
for _, count in pairs(main_view.right_store.items) do
|
||||
if count > 0 then return true end
|
||||
end
|
||||
for _, count in pairs(main_view.right_store.bundles) do
|
||||
if count > 0 then return true end
|
||||
end
|
||||
|
||||
return false
|
||||
@ -289,7 +469,41 @@ function main_view:deposit_items()
|
||||
self:refresh_items()
|
||||
end
|
||||
|
||||
function main_view:draw()
|
||||
function main_view:save_bundle(name, items)
|
||||
self.bundles[name] = items
|
||||
end
|
||||
|
||||
function main_view:display_bundle_popup(area)
|
||||
term_stack.push_cursor(area.x, area.y)
|
||||
-- Draw ascii box around textbox
|
||||
term.setBackgroundColor(colors.black)
|
||||
term.setTextColor(colors.lightGray)
|
||||
term.write("+")
|
||||
hline(2, 1, area.w-2)
|
||||
term.write("+")
|
||||
term.setCursorPos(1, 2)
|
||||
term.write("|")
|
||||
term.setCursorPos(area.w, 2)
|
||||
term.write("|")
|
||||
term.setCursorPos(1, 3)
|
||||
term.write("+")
|
||||
hline(2, 3, area.w-2)
|
||||
term.write("+")
|
||||
|
||||
term_stack.push_cursor(2, 2)
|
||||
self.bundle_name = ui:textbox(area.w-2, true, "Name", self.bundle_name)
|
||||
term_stack.pop_cursor()
|
||||
term_stack.pop_cursor()
|
||||
|
||||
if self.tab_pressed then
|
||||
self.bundle_popup = false
|
||||
elseif self.submit_pressed and #self.bundle_name > 0 then
|
||||
self.bundle_popup = false
|
||||
self:save_bundle(self.bundle_name, self.right_store.items)
|
||||
end
|
||||
end
|
||||
|
||||
function main_view:run()
|
||||
term.setBackgroundColor(colors.black)
|
||||
term.clear()
|
||||
|
||||
@ -298,11 +512,28 @@ function main_view:draw()
|
||||
term.setTextColor(colors.lightGray)
|
||||
vline(self.split_x, self.main_area.y, self.main_area.h)
|
||||
|
||||
main_view:display_items_with_search(self.left_store, self.left_area, self.is_left_active)
|
||||
main_view:display_items_with_search(self.right_store, self.right_area, not self.is_left_active)
|
||||
main_view:display_list_with_search(self.left_store, self.left_area, self.is_left_active and not self.bundle_popup)
|
||||
main_view:display_list_with_search(self.right_store, self.right_area, not self.is_left_active and not self.bundle_popup)
|
||||
else
|
||||
main_view:display_items_with_search(self.left_store, self.main_area, true)
|
||||
main_view:display_list_with_search(self.left_store, self.main_area, not self.bundle_popup)
|
||||
end
|
||||
|
||||
if self.bundle_popup then
|
||||
local w = self.main_area.w - 4
|
||||
local h = 3
|
||||
local area = rect(
|
||||
1+math.floor((self.main_area.w-w)/2),
|
||||
1+math.floor((self.main_area.h-h)/2),
|
||||
w, h
|
||||
)
|
||||
self:display_bundle_popup(area)
|
||||
end
|
||||
|
||||
self.up_pressed = false
|
||||
self.down_pressed = false
|
||||
self.left_pressed = false
|
||||
self.right_pressed = false
|
||||
self.tab_pressed = false
|
||||
end
|
||||
|
||||
function main_view:on_event(event, ...)
|
||||
@ -319,23 +550,32 @@ function main_view:on_event(event, ...)
|
||||
end
|
||||
|
||||
function main_view:on_key(key)
|
||||
local left_selected = self.left_store.filtered_names[self.left_store.selected_idx]
|
||||
local right_selected = self.right_store.filtered_names[self.right_store.selected_idx]
|
||||
local selected_item = self.is_left_active and left_selected or right_selected
|
||||
self.up_pressed = key == keys.up or (self.ctrl_down and key == keys.k)
|
||||
self.down_pressed = key == keys.down or (self.ctrl_down and key == keys.j)
|
||||
self.left_pressed = key == keys.left or (self.ctrl_down and key == keys.h)
|
||||
self.right_pressed = key == keys.right or (self.ctrl_down and key == keys.l)
|
||||
self.submit_pressed = key == keys.enter or (self.ctrl_down and key == keys.space)
|
||||
self.tab_pressed = key == keys.tab
|
||||
|
||||
if key == keys.rightCtrl or key == keys.leftCtrl then
|
||||
self.ctrl_down = true
|
||||
elseif key == keys.rightAlt or key == keys.leftAlt then
|
||||
self.alt_down = true
|
||||
elseif key == keys.tab then
|
||||
self.is_left_active = not self.is_left_active
|
||||
elseif key == keys.f5 then
|
||||
self:refresh_items()
|
||||
end
|
||||
|
||||
if self.ctrl_down then
|
||||
if not self.bundle_popup then
|
||||
local has_selected_items = self:has_selected_items()
|
||||
if key == keys.space then
|
||||
|
||||
if key == keys.n and has_selected_items then
|
||||
self.bundle_popup = true
|
||||
|
||||
elseif key == keys.tab then
|
||||
self.is_left_active = not self.is_left_active
|
||||
|
||||
elseif key == keys.f5 then
|
||||
self:refresh_items()
|
||||
|
||||
elseif self.submit_pressed then
|
||||
if has_selected_items then
|
||||
for name, count in pairs(self.right_store.all_items) do
|
||||
local transferred = self:move_item(name, count, self.result_inventory)
|
||||
@ -345,42 +585,20 @@ function main_view:on_key(key)
|
||||
self:refresh_filtered_names(self.left_store, self.left_area)
|
||||
self:refresh_filtered_names(self.right_store, self.right_area)
|
||||
else
|
||||
if left_selected then
|
||||
local item = left_selected
|
||||
local selected_item = self.left_store.filtered_names[self.left_store.selected_idx]
|
||||
if selected_item then
|
||||
local item = selected_item
|
||||
local stack_size = self.item_details[item].stack_size
|
||||
local transferred_count = self:move_item(item, stack_size, self.result_inventory)
|
||||
self.left_store.all_items[item] = self.left_store.all_items[item] - transferred_count
|
||||
self:refresh_filtered_names(self.left_store, self.left_area)
|
||||
self:select_item(self.left_store, self.left_area, item)
|
||||
self:select_option(self.left_store, self.left_area, item)
|
||||
end
|
||||
end
|
||||
elseif key == keys.d then
|
||||
|
||||
elseif self.ctrl_down and key == keys.d then
|
||||
self:deposit_items()
|
||||
end
|
||||
|
||||
if selected_item and (key == keys.l or key == keys.h) then
|
||||
local item = selected_item
|
||||
local stack_size = self.item_details[item].stack_size
|
||||
local right_items = self.right_store.all_items
|
||||
local left_items = self.left_store.all_items
|
||||
|
||||
if key == keys.l then
|
||||
local transferred = math.min(left_items[item], stack_size)
|
||||
left_items[item] = left_items[item] - transferred
|
||||
right_items[item] = (right_items[item] or 0) + transferred
|
||||
elseif key == keys.h then
|
||||
local transferred = math.min(right_items[item] or 0, stack_size)
|
||||
left_items[item] = left_items[item] + transferred
|
||||
right_items[item] = (right_items[item] or 0) - transferred
|
||||
end
|
||||
|
||||
self:refresh_filtered_names(self.left_store, self.left_area)
|
||||
self:refresh_filtered_names(self.right_store, self.right_area)
|
||||
if self.is_left_active then
|
||||
self:select_item(self.left_store, self.left_area, item)
|
||||
else
|
||||
self:select_item(self.right_store, self.right_area, item)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user