fix: Smart Pickup-fane — ingen callbacks under opbygning, fokus-oprydning, pcall på alle klik, navn/ikon/status
This commit is contained in:
@@ -677,7 +677,7 @@ local function restoreStoppedVehicles()
|
||||
end
|
||||
|
||||
-- Indsætter fanen i ESC-menuen foran Statistik/Priser (mønster fra FS25_FarmOperationsDashboard).
|
||||
local function insertInGameMenuPage(frame, pageName, iconFile, uvs, position, predicate)
|
||||
local function insertInGameMenuPage(frame, pageName, iconFile, iconUVs, position, predicate)
|
||||
local inGameMenu = g_gui ~= nil and g_gui.screenControllers ~= nil and g_gui.screenControllers[InGameMenu] or nil
|
||||
if inGameMenu == nil or inGameMenu.pagingElement == nil then
|
||||
return false
|
||||
@@ -717,7 +717,7 @@ local function insertInGameMenuPage(frame, pageName, iconFile, uvs, position, pr
|
||||
inGameMenu.pagingElement:updateAbsolutePosition()
|
||||
inGameMenu.pagingElement:updatePageMapping()
|
||||
inGameMenu:registerPage(frame, position, predicate)
|
||||
inGameMenu:addPageTab(frame, iconFile, GuiUtils.getUVs(uvs))
|
||||
inGameMenu:addPageTab(frame, iconFile, iconUVs)
|
||||
inGameMenu:rebuildTabList()
|
||||
return true
|
||||
end
|
||||
@@ -730,7 +730,10 @@ local function loadGui()
|
||||
local frame = SmartPickupFrame.new(g_i18n, getAutoDriveEnv)
|
||||
g_gui:loadGui(ADSmartPickup.dir .. "gui/SmartPickupFrame.xml", "smartPickupFrame", frame, true)
|
||||
local iconFile = Utils.getFilename("icon.dds", ADSmartPickup.dir)
|
||||
if not insertInGameMenuPage(frame, "smartPickupFrame", iconFile, {0, 0, 512, 512}, 2, function() return g_currentMission ~= nil end) then
|
||||
-- icon.dds er 512×512. Uden referencestørrelsen normaliserer getUVs mod 1024×1024,
|
||||
-- og fanen ville kun vise ikonets øverste venstre fjerdedel.
|
||||
local iconUVs = GuiUtils.getUVs({0, 0, 512, 512}, {512, 512})
|
||||
if not insertInGameMenuPage(frame, "smartPickupFrame", iconFile, iconUVs, 2, function() return g_currentMission ~= nil end) then
|
||||
Logging.warning(ADSmartPickup.LOG_PREFIX .. "kunne ikke indsætte fanen i ESC-menuen")
|
||||
return
|
||||
end
|
||||
|
||||
@@ -26,7 +26,9 @@ function SmartPickupFrame.new(i18n, getAdEnv)
|
||||
self.newButtonInfo = {inputAction = InputAction.MENU_EXTRA_1, text = i18n:getText("spu_button_new"), callback = function() self:onClickNew() end}
|
||||
self.renameButtonInfo = {inputAction = InputAction.MENU_EXTRA_2, text = i18n:getText("spu_button_rename"), callback = function() self:onClickRename() end}
|
||||
self.deleteButtonInfo = {inputAction = InputAction.MENU_CANCEL, text = i18n:getText("spu_button_delete"), callback = function() self:onClickDelete() end}
|
||||
self:setMenuButtonInfo({self.backButtonInfo, self.startButtonInfo, self.newButtonInfo, self.renameButtonInfo, self.deleteButtonInfo})
|
||||
-- Egen reference til listen: fallback'en i refreshButtons skal kunne sende den igen.
|
||||
self.menuButtonInfo = {self.backButtonInfo, self.startButtonInfo, self.newButtonInfo, self.renameButtonInfo, self.deleteButtonInfo}
|
||||
self:setMenuButtonInfo(self.menuButtonInfo)
|
||||
return self
|
||||
end
|
||||
|
||||
@@ -56,11 +58,20 @@ function SmartPickupFrame:initialize()
|
||||
self.loopsOption:setTexts(loopTexts)
|
||||
end
|
||||
|
||||
-- rebuild sletter de rækker der kan have fokus (fx vare-rækkerne når Varer skifter til
|
||||
-- Auto); uden dette står fokus på et slettet element og tastatur/controller er død.
|
||||
function SmartPickupFrame:focusRunOption()
|
||||
self:safe(function(frame)
|
||||
if frame.runOption ~= nil then
|
||||
FocusManager:setFocus(frame.runOption)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function SmartPickupFrame:onFrameOpen()
|
||||
SmartPickupFrame:superClass().onFrameOpen(self)
|
||||
self.statusOverride = nil
|
||||
self:safe(self.rebuild)
|
||||
FocusManager:setFocus(self.runOption)
|
||||
end
|
||||
|
||||
function SmartPickupFrame:onFrameClose()
|
||||
@@ -94,8 +105,11 @@ end
|
||||
|
||||
-- ---- opbygning ----
|
||||
|
||||
-- addRow melder hver klonet række ind i FocusManager; uden afmelding her ville
|
||||
-- FocusManager beholde slettede rækker og fokus-navigationen gå i stå.
|
||||
function SmartPickupFrame:clearRows()
|
||||
for _, row in ipairs(self.clonedRows) do
|
||||
FocusManager:removeElement(row)
|
||||
row:delete()
|
||||
end
|
||||
self.clonedRows, self.rowData = {}, {}
|
||||
@@ -128,10 +142,10 @@ function SmartPickupFrame:rebuild()
|
||||
end
|
||||
if hasRun then
|
||||
self:fillTargetOption(adEnv, run)
|
||||
self.ingredientModeOption:setState(run.ingredientMode == "manual" and SmartPickupFrame.STATE_ON or SmartPickupFrame.STATE_OFF, true)
|
||||
self.ingredientModeOption:setState(run.ingredientMode == "manual" and SmartPickupFrame.STATE_ON or SmartPickupFrame.STATE_OFF, false)
|
||||
self:fillIngredientRows(adEnv, run)
|
||||
self:fillWaitPoolOption(adEnv, run)
|
||||
self.loopsOption:setState(run.loops + 1, true)
|
||||
self.loopsOption:setState(run.loops + 1, false)
|
||||
self:fillVehicleRows(adEnv, run)
|
||||
end
|
||||
self:fillPoolRows(adEnv)
|
||||
@@ -139,6 +153,7 @@ function SmartPickupFrame:rebuild()
|
||||
box:invalidateLayout()
|
||||
end
|
||||
self:refreshLive()
|
||||
self:focusRunOption()
|
||||
end
|
||||
|
||||
function SmartPickupFrame:fillRunOption(adEnv)
|
||||
@@ -156,7 +171,7 @@ function SmartPickupFrame:fillRunOption(adEnv)
|
||||
texts = {self.i18n:getText("spu_noRuns")}
|
||||
end
|
||||
self.runOption:setTexts(texts)
|
||||
self.runOption:setState(index, true)
|
||||
self.runOption:setState(index, false)
|
||||
self.runOption:setDisabled(#self.runIds == 0)
|
||||
end
|
||||
|
||||
@@ -171,7 +186,7 @@ function SmartPickupFrame:fillTargetOption(adEnv, run)
|
||||
end
|
||||
end
|
||||
self.targetOption:setTexts(texts)
|
||||
self.targetOption:setState(index, true)
|
||||
self.targetOption:setState(index, false)
|
||||
end
|
||||
|
||||
function SmartPickupFrame:fillIngredientRows(adEnv, run)
|
||||
@@ -185,7 +200,7 @@ function SmartPickupFrame:fillIngredientRows(adEnv, run)
|
||||
for _, fillType in ipairs(ADRunsController.getTargetAcceptedFillTypes(adEnv, run)) do
|
||||
local row = self:addRow(self.ingredientPrefab, self.ingredientBox, {kind = "ingredient", name = fillType.name})
|
||||
row:getDescendantByName("title"):setText(tostring(fillType.title))
|
||||
row:getDescendantByName("option"):setState(chosen[fillType.name] and SmartPickupFrame.STATE_ON or SmartPickupFrame.STATE_OFF, true)
|
||||
row:getDescendantByName("option"):setState(chosen[fillType.name] and SmartPickupFrame.STATE_ON or SmartPickupFrame.STATE_OFF, false)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -200,7 +215,7 @@ function SmartPickupFrame:fillWaitPoolOption(adEnv, run)
|
||||
end
|
||||
end
|
||||
self.waitPoolOption:setTexts(texts)
|
||||
self.waitPoolOption:setState(index, true)
|
||||
self.waitPoolOption:setState(index, false)
|
||||
end
|
||||
|
||||
function SmartPickupFrame:fillVehicleRows(adEnv, run)
|
||||
@@ -212,7 +227,7 @@ function SmartPickupFrame:fillVehicleRows(adEnv, run)
|
||||
local id = ADRunsController.getVehicleId(vehicle)
|
||||
local row = self:addRow(self.vehiclePrefab, self.vehicleBox, {kind = "vehicle", vehicle = vehicle, row = nil})
|
||||
self.rowData[row:getDescendantByName("option")].row = row
|
||||
row:getDescendantByName("option"):setState(inRun[id] and SmartPickupFrame.STATE_ON or SmartPickupFrame.STATE_OFF, true)
|
||||
row:getDescendantByName("option"):setState(inRun[id] and SmartPickupFrame.STATE_ON or SmartPickupFrame.STATE_OFF, false)
|
||||
row:getDescendantByName("title"):setText(self:describeVehicle(adEnv, run, vehicle, inRun[id]))
|
||||
end
|
||||
end
|
||||
@@ -254,6 +269,21 @@ function SmartPickupFrame:fillPoolRows(adEnv)
|
||||
end
|
||||
end
|
||||
|
||||
-- BinaryOption har :getState() i FS25, men feltet .state i ældre GUI-versioner.
|
||||
function SmartPickupFrame.getOptionState(option)
|
||||
return option.getState ~= nil and option:getState() or option.state
|
||||
end
|
||||
|
||||
-- setMenuButtonInfoDirty findes i FS22/25's TabbedMenuFrameElement; mangler den,
|
||||
-- sendes listen igen. Kaldes hvert sekund, så den må aldrig kaste.
|
||||
function SmartPickupFrame:refreshButtons()
|
||||
if self.setMenuButtonInfoDirty ~= nil then
|
||||
self:setMenuButtonInfoDirty()
|
||||
else
|
||||
self:setMenuButtonInfo(self.menuButtonInfo)
|
||||
end
|
||||
end
|
||||
|
||||
-- Status + Start/Stop-knappens tekst, kaldes hvert sekund.
|
||||
function SmartPickupFrame:refreshLive()
|
||||
local adEnv = self.getAdEnv()
|
||||
@@ -271,17 +301,20 @@ function SmartPickupFrame:refreshLive()
|
||||
self.statusText:setText(self.statusOverride or text)
|
||||
for option, data in pairs(self.rowData) do
|
||||
if data.kind == "vehicle" and data.row ~= nil then
|
||||
data.row:getDescendantByName("title"):setText(self:describeVehicle(adEnv, run, data.vehicle, option:getState() == SmartPickupFrame.STATE_ON))
|
||||
data.row:getDescendantByName("title"):setText(self:describeVehicle(adEnv, run, data.vehicle, SmartPickupFrame.getOptionState(option) == SmartPickupFrame.STATE_ON))
|
||||
end
|
||||
end
|
||||
else
|
||||
self.statusText:setText(self.statusOverride or self.i18n:getText("spu_noRuns"))
|
||||
end
|
||||
-- Engangsbesked ("Startet 2, sprunget over 1", "flyttet fra ..."): vist nu, ryddet her,
|
||||
-- så næste opdatering om et sekund viser den levende status igen.
|
||||
self.statusOverride = nil
|
||||
self.startButtonInfo.text = self.i18n:getText(isRunning and "spu_button_stop" or "spu_button_start")
|
||||
self.startButtonInfo.disabled = run == nil
|
||||
self.renameButtonInfo.disabled = run == nil
|
||||
self.deleteButtonInfo.disabled = run == nil
|
||||
self:setMenuButtonInfoDirty()
|
||||
self:refreshButtons()
|
||||
end
|
||||
|
||||
-- ---- callbacks fra XML (state = 1-baseret indeks; element = det klikkede element) ----
|
||||
@@ -293,22 +326,27 @@ function SmartPickupFrame:onClickRun(state)
|
||||
end
|
||||
|
||||
function SmartPickupFrame:onClickTarget(state)
|
||||
local run = self:getRun()
|
||||
self:safe(function(frame)
|
||||
local run = frame:getRun()
|
||||
if run == nil then return end
|
||||
-- targetIds[1] er false = "(vælg mål)"; modellen tolker false som "ryd målet"
|
||||
ADRunsController.updateRun(run.id, {targetWayPointId = self.targetIds[state] or false})
|
||||
self:safe(self.rebuild)
|
||||
ADRunsController.updateRun(run.id, {targetWayPointId = frame.targetIds[state] or false})
|
||||
frame:rebuild()
|
||||
end)
|
||||
end
|
||||
|
||||
function SmartPickupFrame:onClickIngredientMode(state)
|
||||
local run = self:getRun()
|
||||
self:safe(function(frame)
|
||||
local run = frame:getRun()
|
||||
if run == nil then return end
|
||||
ADRunsController.updateRun(run.id, {ingredientMode = state == SmartPickupFrame.STATE_ON and "manual" or "auto"})
|
||||
self:safe(self.rebuild)
|
||||
frame:rebuild()
|
||||
end)
|
||||
end
|
||||
|
||||
function SmartPickupFrame:onClickIngredient(state, element)
|
||||
local run, data = self:getRun(), self.rowData[element]
|
||||
self:safe(function(frame)
|
||||
local run, data = frame:getRun(), frame.rowData[element]
|
||||
if run == nil or data == nil then return end
|
||||
local names = {}
|
||||
for _, name in ipairs(run.ingredients) do
|
||||
@@ -318,33 +356,40 @@ function SmartPickupFrame:onClickIngredient(state, element)
|
||||
table.insert(names, data.name)
|
||||
end
|
||||
ADRunsController.updateRun(run.id, {ingredients = names})
|
||||
end)
|
||||
end
|
||||
|
||||
function SmartPickupFrame:onClickWaitPool(state)
|
||||
local run = self:getRun()
|
||||
self:safe(function(frame)
|
||||
local run = frame:getRun()
|
||||
if run == nil then return end
|
||||
ADRunsController.updateRun(run.id, {waitPoolGroup = self.poolGroups[state] or ""})
|
||||
ADRunsController.updateRun(run.id, {waitPoolGroup = frame.poolGroups[state] or ""})
|
||||
end)
|
||||
end
|
||||
|
||||
function SmartPickupFrame:onClickLoops(state)
|
||||
local run = self:getRun()
|
||||
self:safe(function(frame)
|
||||
local run = frame:getRun()
|
||||
if run == nil then return end
|
||||
ADRunsController.updateRun(run.id, {loops = state - 1})
|
||||
end)
|
||||
end
|
||||
|
||||
function SmartPickupFrame:onClickVehicle(state, element)
|
||||
local run, data = self:getRun(), self.rowData[element]
|
||||
self:safe(function(frame)
|
||||
local run, data = frame:getRun(), frame.rowData[element]
|
||||
if run == nil or data == nil then return end
|
||||
if state == SmartPickupFrame.STATE_ON then
|
||||
local previousRunId = ADRunsController.assignVehicle(run.id, data.vehicle)
|
||||
if previousRunId ~= nil then
|
||||
local previous = ADRuns.getRun(ADRunsController.store, previousRunId)
|
||||
self.statusOverride = string.format(self.i18n:getText("spu_movedFrom"), previous ~= nil and previous.name or tostring(previousRunId))
|
||||
frame.statusOverride = string.format(frame.i18n:getText("spu_movedFrom"), previous ~= nil and previous.name or tostring(previousRunId))
|
||||
end
|
||||
else
|
||||
ADRunsController.unassignVehicle(data.vehicle)
|
||||
end
|
||||
self:safe(self.refreshLive)
|
||||
frame:refreshLive()
|
||||
end)
|
||||
end
|
||||
|
||||
-- ---- knapper i bundlinjen ----
|
||||
@@ -370,7 +415,8 @@ end
|
||||
|
||||
function SmartPickupFrame:onClickNew()
|
||||
self:safe(function(frame)
|
||||
local run = ADRunsController.createRun(string.format(frame.i18n:getText("spu_newRunName"), ADRunsController.store.nextId - 1))
|
||||
-- nextId er id'et det NYE run får; navnet skal matche det, ikke det forrige.
|
||||
local run = ADRunsController.createRun(string.format(frame.i18n:getText("spu_newRunName"), ADRunsController.store.nextId))
|
||||
frame.selectedRunId = run.id
|
||||
frame.statusOverride = nil
|
||||
frame:rebuild()
|
||||
@@ -384,11 +430,13 @@ function SmartPickupFrame:onClickRename()
|
||||
end
|
||||
|
||||
function SmartPickupFrame:onRenameResult(value, clickOk)
|
||||
local run = self:getRun()
|
||||
self:safe(function(frame)
|
||||
local run = frame:getRun()
|
||||
if clickOk and run ~= nil and value ~= nil and value:match("%S") then
|
||||
ADRunsController.updateRun(run.id, {name = value})
|
||||
self:safe(self.rebuild)
|
||||
frame:rebuild()
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function SmartPickupFrame:onClickDelete()
|
||||
@@ -398,10 +446,12 @@ function SmartPickupFrame:onClickDelete()
|
||||
end
|
||||
|
||||
function SmartPickupFrame:onDeleteResult(yes)
|
||||
local run = self:getRun()
|
||||
self:safe(function(frame)
|
||||
local run = frame:getRun()
|
||||
if yes and run ~= nil then
|
||||
ADRunsController.deleteRun(run.id)
|
||||
self.selectedRunId = nil
|
||||
self:safe(self.rebuild)
|
||||
frame.selectedRunId = nil
|
||||
frame:rebuild()
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user