diff --git a/manager/display.lua b/manager/display.lua index a18ead3..10f45fe 100644 --- a/manager/display.lua +++ b/manager/display.lua @@ -40,6 +40,7 @@ local smelterPage = nil local selectedAmount = 1 local amountOptions = {1, 4, 8, 16, 32, 64} local searchQuery = "" +local showKeyboard = false local smelterView = "status" ------------------------------------------------- @@ -263,17 +264,45 @@ local function buildMainPage() searchRow = UI.Window { x = 1, y = 6, ex = -1, height = 1, backgroundColor = colors.black, - }, - - searchEntry = UI.TextEntry { - x = 3, y = 6, - ex = '45%', - shadowText = "search...", - backgroundColor = colors.black, - backgroundFocusColor = colors.gray, - textColor = colors.white, - shadowTextColor = colors.gray, - limit = 30, + draw = function(self) + self:clear(colors.black) + -- Keyboard toggle button + local kbLabel = showKeyboard and " X " or " ? " + local kbBg = showKeyboard and colors.red or colors.purple + self:write(1, 1, kbLabel, kbBg, colors.white) + -- Search query display + local fieldW = math.floor(self.width * 0.4) + if fieldW < 10 then fieldW = 10 end + local queryDisplay = searchQuery + if showKeyboard then + queryDisplay = queryDisplay .. "|" + elseif queryDisplay == "" then + queryDisplay = "search..." + end + local displayText = queryDisplay:sub(1, fieldW) + displayText = displayText .. string.rep("_", math.max(0, fieldW - #displayText)) + local tc = (searchQuery == "" and not showKeyboard) and colors.gray or colors.white + self:write(5, 1, displayText, colors.black, tc) + end, + eventHandler = function(self, event) + if event.type == 'mouse_click' then + showKeyboard = not showKeyboard + local page = self:getPage() + if showKeyboard then + UI.Window.enable(page.keyboard) + page.keyboard:draw() + else + page.keyboard:disable() + page.alertBar:draw() + page.footerBar:draw() + page.bottomBar:draw() + end + self:draw() + page:sync() + return true + end + return UI.Window.eventHandler(self, event) + end, }, refreshBtn = UI.Button { @@ -383,15 +412,118 @@ local function buildMainPage() end, }, + -- On-screen keyboard overlay (bottom 3 rows; starts disabled) + keyboard = UI.Window { + x = 1, ex = -1, ey = -1, height = 3, + backgroundColor = colors.black, + enable = function() end, -- prevent auto-enable; toggled manually + draw = function(self) + self:clear(colors.black) + local kbDefs = { + { keys = {"Q","W","E","R","T","Y","U","I","O","P"}, specials = {{ label = " Bksp ", bg = colors.red, action = "kb_bksp" }} }, + { keys = {"A","S","D","F","G","H","J","K","L"}, specials = {{ label = " Done ", bg = colors.green, action = "kb_done" }} }, + { keys = {"Z","X","C","V","B","N","M"}, specials = { + { label = " Space ", bg = colors.lightGray, action = "kb_space" }, + { label = " Clr ", bg = colors.orange, action = "kb_clear" }, + }}, + } + self._zones = {} + local keyW = 3 + local keyGap = 1 + for rowIdx, def in ipairs(kbDefs) do + local y = rowIdx + local keysW = #def.keys * keyW + math.max(0, #def.keys - 1) * keyGap + local specialsW = 0 + for _, sp in ipairs(def.specials) do + specialsW = specialsW + keyGap + #sp.label + end + local rowW = keysW + specialsW + local x = math.floor((self.width - rowW) / 2) + 1 + -- Draw letter keys + for ki, key in ipairs(def.keys) do + self:write(x, y, " " .. key .. " ", colors.gray, colors.white) + table.insert(self._zones, { x1 = x, y1 = y, x2 = x + keyW - 1, y2 = y, action = "kb_key", data = key:lower() }) + x = x + keyW + if ki < #def.keys then x = x + keyGap end + end + -- Draw special keys + for _, sp in ipairs(def.specials) do + x = x + keyGap + self:write(x, y, sp.label, sp.bg, colors.white) + table.insert(self._zones, { x1 = x, y1 = y, x2 = x + #sp.label - 1, y2 = y, action = sp.action }) + x = x + #sp.label + end + end + end, + eventHandler = function(self, event) + if event.type == 'mouse_click' then + if self._zones then + for _, zone in ipairs(self._zones) do + if event.x >= zone.x1 and event.x <= zone.x2 + and event.y >= zone.y1 and event.y <= zone.y2 then + self:emit({ type = zone.action, data = zone.data, element = self }) + return true + end + end + end + return true -- consume click even if no zone hit + end + return UI.Window.eventHandler(self, event) + end, + }, + -- Notification overlay notification = UI.Notification { anchor = 'bottom', }, eventHandler = function(self, event) - if event.type == 'text_change' then - searchQuery = event.text or "" + if event.type == 'kb_key' then + if #searchQuery < 30 then + searchQuery = searchQuery .. event.data + end D.refreshItemGrid() + self.searchRow:draw() + self.footerBar:draw() + self:sync() + return true + + elseif event.type == 'kb_bksp' then + if #searchQuery > 0 then + searchQuery = searchQuery:sub(1, -2) + end + D.refreshItemGrid() + self.searchRow:draw() + self.footerBar:draw() + self:sync() + return true + + elseif event.type == 'kb_space' then + if #searchQuery < 30 then + searchQuery = searchQuery .. " " + end + D.refreshItemGrid() + self.searchRow:draw() + self.footerBar:draw() + self:sync() + return true + + elseif event.type == 'kb_done' then + showKeyboard = false + self.keyboard:disable() + self.searchRow:draw() + self.alertBar:draw() + self.footerBar:draw() + self.bottomBar:draw() + self:sync() + return true + + elseif event.type == 'kb_clear' then + searchQuery = "" + showKeyboard = false + self.keyboard:disable() + D.refreshItemGrid() + self.searchRow:draw() self.alertBar:draw() self.footerBar:draw() self.bottomBar:draw()