feat(gui): guiden "Opsæt mark" — markfanen får oversigt med resumé (klik på en linje = ret ét trin), trin-for-trin-guide på fælles guide-ramme (ADGuide/ADFieldGuide) og egen markflåde-visning (v1.31.0.0)
This commit is contained in:
@@ -0,0 +1,229 @@
|
||||
-- Smart Pickup — fælles guide-skærm ("Opsæt mark" / "Opsæt flow")
|
||||
-- Ét trin ad gangen: overskrift, "Trin 3 af 7 — …", kort forklaring, valgene som rækker og bundknapperne
|
||||
-- Næste/Gem, Tilbage, Annullér (+ Gem uden at starte på oversigts-trinnet). Al logik ligger i ADGuide og
|
||||
-- trin-definitionerne (ADFieldGuide/ADFlowGuide); her tegnes kun rækkerne og klik routes.
|
||||
-- Hver guide registrerer sig i SmartPickupFrame.GUIDE_HOOKS[kind] = {
|
||||
-- model, tab, heading(frame, guide), context(frame, adEnv, guide) -> context|nil (nil = luk guiden),
|
||||
-- choose(frame, id, value) -> handled, save(frame, guide, start), startKey(guide), showSaveOnly(guide),
|
||||
-- canAdvance(guide), afterRows(frame, adEnv, guide) }
|
||||
-- Funktionerne lægges på SmartPickupFrame (indlæses efter SmartPickupFrame.lua).
|
||||
|
||||
SmartPickupFrame.GUIDE_HOOKS = SmartPickupFrame.GUIDE_HOOKS or {}
|
||||
|
||||
function SmartPickupFrame:initGuideButtons(i18n)
|
||||
self.guideNextButtonInfo = {inputAction = InputAction.MENU_ACTIVATE, text = i18n:getText("spu_guide_next"), callback = function() self:onClickGuideNext(true) end}
|
||||
self.guideSaveOnlyButtonInfo = {inputAction = InputAction.MENU_EXTRA_1, text = i18n:getText("spu_guide_saveOnly"), callback = function() self:onClickGuideNext(false) end}
|
||||
self.guidePrevButtonInfo = {inputAction = InputAction.MENU_EXTRA_2, text = i18n:getText("spu_guide_back"), callback = function() self:onClickGuideBack() end}
|
||||
self.guideCancelButtonInfo = {inputAction = InputAction.MENU_CANCEL, text = i18n:getText("spu_guide_cancel"), callback = function() self:onClickGuideCancel() end}
|
||||
self.guideButtons = {self.backButtonInfo, self.guideNextButtonInfo, self.guidePrevButtonInfo, self.guideCancelButtonInfo}
|
||||
self.guideSummaryButtons = {self.backButtonInfo, self.guideNextButtonInfo, self.guideSaveOnlyButtonInfo, self.guidePrevButtonInfo, self.guideCancelButtonInfo}
|
||||
end
|
||||
|
||||
function SmartPickupFrame:guideHooks()
|
||||
return self.guideKind ~= nil and SmartPickupFrame.GUIDE_HOOKS[self.guideKind] or nil
|
||||
end
|
||||
|
||||
-- Er der en åben guide på fanen?
|
||||
function SmartPickupFrame:hasGuideOn(tab)
|
||||
local hooks = self:guideHooks()
|
||||
return self.guide ~= nil and hooks ~= nil and hooks.tab == tab
|
||||
end
|
||||
|
||||
function SmartPickupFrame:openGuide(kind, guide)
|
||||
self.guideKind, self.guide = kind, guide
|
||||
self.statusOverride = nil
|
||||
self:requestRebuild()
|
||||
end
|
||||
|
||||
-- Kladden kasseres (Annullér, fanebyt, lukket menu).
|
||||
function SmartPickupFrame:closeGuide()
|
||||
self.guideKind, self.guide = nil, nil
|
||||
end
|
||||
|
||||
function SmartPickupFrame:guideText(label)
|
||||
return ADGuide.labelText(label, function(key) return self.i18n:getText(key) end)
|
||||
end
|
||||
|
||||
-- Klikbar tekstrække (ombrydes; alle linjer er klikbare). Handlingen køres fra update() (pendingClick).
|
||||
function SmartPickupFrame:addLinkRow(text, action)
|
||||
local first = nil
|
||||
for _, line in ipairs(ADFlowView.wrapText(text, SmartPickupFrame.TEXT_ROW_CHARS)) do
|
||||
local row = self:addRow(self.textPrefab, {kind = "text"})
|
||||
local title = row:getDescendantByName("title")
|
||||
title:setText(line)
|
||||
self:makeRowClickable(row, action)
|
||||
first = first or title
|
||||
end
|
||||
return first
|
||||
end
|
||||
|
||||
local function optionIndex(options, value)
|
||||
for index, option in ipairs(options) do
|
||||
if option.value == value then return index end
|
||||
end
|
||||
return 1
|
||||
end
|
||||
|
||||
function SmartPickupFrame:addGuideRow(row)
|
||||
local data = {kind = "guideRow", row = row}
|
||||
if row.type == "choice" then
|
||||
local element = self:addRow(self.productPrefab, data)
|
||||
local option = element:getDescendantByName("option")
|
||||
local texts = {}
|
||||
for _, entry in ipairs(row.options) do table.insert(texts, self:guideText(entry.label)) end
|
||||
option:setTexts(texts)
|
||||
option:setState(optionIndex(row.options, row.value), false)
|
||||
element:getDescendantByName("title"):setText(self:guideText(row.title))
|
||||
elseif row.type == "toggle" or row.type == "check" then
|
||||
local element = self:addRow(self.ingredientPrefab, data)
|
||||
local option = element:getDescendantByName("option")
|
||||
if row.type == "toggle" then option:setTexts({self:guideText(row.off), self:guideText(row.on)}) end
|
||||
option:setState(row.value and SmartPickupFrame.STATE_ON or SmartPickupFrame.STATE_OFF, false)
|
||||
element:getDescendantByName("title"):setText((row.type == "check" and " " or "") .. self:guideText(row.title))
|
||||
elseif row.type == "link" then
|
||||
local text = row.label ~= nil and self:guideText(row.label)
|
||||
or (ADGuide.lineText(row.line, function(key) return self.i18n:getText(key) end) .. self.i18n:getText("spu_guide_editSuffix"))
|
||||
self:addLinkRow(" " .. text, function(frame) frame:onGuideLink(row) end)
|
||||
else
|
||||
self:addTextRow(self:guideText(row.label))
|
||||
end
|
||||
end
|
||||
|
||||
-- Tegner den åbne guide. false = guiden er lukket (fx marken findes ikke længere) — fanen viser oversigten.
|
||||
function SmartPickupFrame:fillGuideRows(adEnv)
|
||||
local hooks = self:guideHooks()
|
||||
if hooks == nil or self.guide == nil then return false end
|
||||
local context = hooks.context(self, adEnv, self.guide)
|
||||
if context == nil then
|
||||
self:closeGuide()
|
||||
self.statusOverride = self.i18n:getText("spu_guide_closed")
|
||||
self.statusOverrideTicks = SmartPickupFrame.STATUS_OVERRIDE_TICKS
|
||||
return false
|
||||
end
|
||||
self.guide = ADGuide.withContext(self.guide, context)
|
||||
local guide, model = self.guide, hooks.model
|
||||
self:addTextRow(hooks.heading(self, guide))
|
||||
local stepTitle = self.i18n:getText(model.stepKey(guide.step))
|
||||
local index, total = ADGuide.position(guide)
|
||||
local header
|
||||
if guide.single then
|
||||
header = string.format(self.i18n:getText("spu_guide_editStep"), stepTitle)
|
||||
elseif index ~= nil and total > 1 then
|
||||
header = string.format(self.i18n:getText("spu_guide_stepOf"), index, total, stepTitle)
|
||||
else
|
||||
header = string.format(self.i18n:getText("spu_guide_stepOne"), index or 1, stepTitle)
|
||||
end
|
||||
self:addTextRow(header)
|
||||
self:addTextRow(" " .. self.i18n:getText(model.hintKey(guide.step)))
|
||||
for _, row in ipairs(model.rows(guide)) do
|
||||
self:addGuideRow(row)
|
||||
end
|
||||
if hooks.afterRows ~= nil then hooks.afterRows(self, adEnv, guide) end
|
||||
return true
|
||||
end
|
||||
|
||||
-- ---- klik ----
|
||||
|
||||
function SmartPickupFrame:applyGuideChoice(id, value)
|
||||
local hooks = self:guideHooks()
|
||||
if hooks == nil or self.guide == nil then return end
|
||||
if hooks.choose ~= nil and hooks.choose(self, id, value) then return end
|
||||
self.guide = hooks.model.choose(self.guide, id, value)
|
||||
end
|
||||
|
||||
function SmartPickupFrame:onClickGuideRow(state, data)
|
||||
self:safe(function(frame)
|
||||
local row = data ~= nil and data.row or nil
|
||||
if row == nil or frame.guide == nil then return end
|
||||
local value
|
||||
if row.type == "choice" then
|
||||
local option = row.options[state]
|
||||
if option == nil then return end
|
||||
value = option.value
|
||||
elseif row.type == "toggle" then
|
||||
value = state == SmartPickupFrame.STATE_ON
|
||||
elseif row.type == "check" then
|
||||
value = {item = row.item, on = state == SmartPickupFrame.STATE_ON}
|
||||
else
|
||||
return
|
||||
end
|
||||
frame:applyGuideChoice(row.id, value)
|
||||
frame:requestRebuild()
|
||||
end)
|
||||
end
|
||||
|
||||
-- Klikbare linjer: [Ret] på oversigts-trinnet åbner ét trin; andre links er valg (fx mark i trin 1).
|
||||
function SmartPickupFrame:onGuideLink(row)
|
||||
if self.guide == nil then return end
|
||||
if row.id == "jump" then
|
||||
self.guide = ADGuide.jump(self.guide, row.value, "summary")
|
||||
else
|
||||
self:applyGuideChoice(row.id, row.value)
|
||||
end
|
||||
self:requestRebuild()
|
||||
end
|
||||
|
||||
local function finish(frame, hooks, guide, start)
|
||||
hooks.save(frame, guide, start)
|
||||
frame:closeGuide()
|
||||
frame:requestRebuild()
|
||||
end
|
||||
|
||||
-- Næste / Gem / Kør automatisk (start = true) og Gem uden at starte (start = false).
|
||||
function SmartPickupFrame:onClickGuideNext(start)
|
||||
self:safe(function(frame)
|
||||
local hooks, guide = frame:guideHooks(), frame.guide
|
||||
if hooks == nil or guide == nil then return end
|
||||
if hooks.canAdvance ~= nil and not hooks.canAdvance(guide) then
|
||||
frame:showOverride(frame.i18n:getText(hooks.cannotAdvanceKey or "spu_guide_cannotAdvance"))
|
||||
return
|
||||
end
|
||||
if guide.single and guide.returnTo == "close" then
|
||||
if start == false then return end
|
||||
return finish(frame, hooks, guide, nil)
|
||||
end
|
||||
if guide.step == "summary" and not guide.single then
|
||||
return finish(frame, hooks, guide, start)
|
||||
end
|
||||
if start == false then return end
|
||||
local nextGuide, event = ADGuide.next(guide)
|
||||
if event == "done" then return finish(frame, hooks, guide, true) end
|
||||
frame.guide = nextGuide
|
||||
frame:requestRebuild()
|
||||
end)
|
||||
end
|
||||
|
||||
function SmartPickupFrame:onClickGuideBack()
|
||||
self:safe(function(frame)
|
||||
if frame.guide == nil then return end
|
||||
local previous, event = ADGuide.back(frame.guide)
|
||||
if event == "cancel" then frame:closeGuide() else frame.guide = previous end
|
||||
frame:requestRebuild()
|
||||
end)
|
||||
end
|
||||
|
||||
function SmartPickupFrame:onClickGuideCancel()
|
||||
self:safe(function(frame)
|
||||
frame:closeGuide()
|
||||
frame:requestRebuild()
|
||||
end)
|
||||
end
|
||||
|
||||
-- Knapperne følger trinnet: Næste / OK (tilbage til oversigten) / Gem ([Ret] fra fanen) / Kør automatisk.
|
||||
function SmartPickupFrame:getGuideButtons()
|
||||
local hooks, guide = self:guideHooks(), self.guide
|
||||
local i18n = self.i18n
|
||||
local isSummary = guide.step == "summary" and not guide.single
|
||||
local key = "spu_guide_next"
|
||||
if guide.single then
|
||||
key = guide.returnTo == "close" and "spu_guide_save" or "spu_guide_ok"
|
||||
elseif isSummary then
|
||||
key = hooks.startKey ~= nil and hooks.startKey(guide) or "spu_guide_save"
|
||||
end
|
||||
self.guideNextButtonInfo.text = i18n:getText(key)
|
||||
self.guideNextButtonInfo.disabled = hooks.canAdvance ~= nil and not hooks.canAdvance(guide)
|
||||
if isSummary and (hooks.showSaveOnly == nil or hooks.showSaveOnly(guide)) then
|
||||
return self.guideSummaryButtons
|
||||
end
|
||||
return self.guideButtons
|
||||
end
|
||||
Reference in New Issue
Block a user