diff --git a/FS25_ADSmartPickup/gui/SmartPickupFlowGuide.lua b/FS25_ADSmartPickup/gui/SmartPickupFlowGuide.lua
index 9348083..7e92103 100644
--- a/FS25_ADSmartPickup/gui/SmartPickupFlowGuide.lua
+++ b/FS25_ADSmartPickup/gui/SmartPickupFlowGuide.lua
@@ -8,7 +8,8 @@ function SmartPickupFrame:initFlowButtons(i18n)
self.flowSetupButtonInfo = {inputAction = InputAction.MENU_EXTRA_1, text = i18n:getText("spu_guide_flow_open"), callback = function() self:onClickFlowSetup() end}
self.flowNewButtonInfo = {inputAction = InputAction.MENU_EXTRA_2, text = i18n:getText("spu_button_new"), callback = function() self:onClickFlowNew() end}
-- Flows-fanen: [Start/Stop] [Opsæt flow] [Nyt flow] [Slet]; omdøb ligger på resuméets Navn-linje
- self.flowButtons = {self.backButtonInfo, self.startButtonInfo, self.flowSetupButtonInfo, self.flowNewButtonInfo, self.deleteButtonInfo}
+ -- v1.58: listen har Start/Stop pr. række; Opsæt/Slet ligger i redigeringsvinduet
+ self.flowButtons = {self.backButtonInfo, self.flowNewButtonInfo}
end
-- ---- traktor-tekst (også til guidens traktorliste) ----
@@ -160,33 +161,94 @@ end
-- Flows: det valgte flow øverst (indstillinger som "ret"-linjer + status), derunder en kort liste til at vælge
-- et andet flow. Tavlen med alle flows står i Oversigt (in-game 27/9: de to faner så ens ud).
function SmartPickupFrame:fillFlowTabRows(adEnv)
- if self:hasGuideOn(SmartPickupFrame.TAB_FLOWS) and self:fillGuideRows(adEnv) then return end
- self.overviewRows = {}
- local run = self:getRun()
- if run == nil then
- self:addTextRow(self.i18n:getText("spu_noRuns"))
+ if not self.editPanelOpen and self:hasGuideOn(SmartPickupFrame.TAB_FLOWS) and self:fillGuideRows(adEnv) then return end
+ self.flowListRows = {}
+ local i18n = self.i18n
+ if #ADRunsController.store.runs == 0 then
+ self:addTextRow(i18n:getText("spu_noRuns"))
return
end
- self:fillFlowSummary(adEnv, run)
- self:addTextRow(self.i18n:getText("spu_flow_pickOther"))
+ self:addTextRow(i18n:getText("spu_flowList_hint"))
for _, group in ipairs(ADFlowView.boardGroups(ADRunsController.store.runs)) do
- for _, other in ipairs(group.runs) do
- if other.id ~= run.id then
- local cells = self:flowCells(adEnv, other)
- local otherId = other.id
- self:addLinkRow(string.format(" %s — %s", tostring(other.name), tostring(cells[6] or "")), function(frame)
- frame.selectedRunId = otherId
- frame.statusOverride = nil
+ self:addTextRow(i18n:getText(group.kind == "outbound" and "spu_board_outbound" or "spu_board_supply"))
+ for _, run in ipairs(group.runs) do
+ local row = self:addRow(self.flowListPrefab, {kind = "flowList"})
+ local entry = {runId = run.id, row = row, dot = row:getDescendantByName("dot"),
+ cells = {row:getDescendantByName("c1"), row:getDescendantByName("c2"), row:getDescendantByName("c3"),
+ row:getDescendantByName("c4"), row:getDescendantByName("c5")}}
+ local runId = run.id
+ local actionCell = entry.cells[5]
+ self:makeRowClickable(row, function(frame)
+ -- klik på [Start]/[Stop]-feltet = handling (kun dette flow); ellers åbn redigeringsvinduet
+ if frame.lastClickX ~= nil and actionCell.absPosition ~= nil and frame.lastClickX >= actionCell.absPosition[1] then
+ frame:toggleRun(frame.getAdEnv(), runId)
frame:requestRebuild()
- end)
- end
+ else
+ frame.selectedRunId = runId
+ frame:openEditPanel("flow", runId)
+ end
+ end)
+ table.insert(self.flowListRows, entry)
+ end
+ end
+ self:refreshFlowListRows(adEnv)
+end
+
+-- Listens celler, prik og statusfarve (hvert sekund og efter opbygning).
+function SmartPickupFrame:refreshFlowListRows(adEnv)
+ local unpackFn = table.unpack or unpack
+ for _, entry in ipairs(self.flowListRows or {}) do
+ local run = ADRuns.getRun(ADRunsController.store, entry.runId)
+ if run ~= nil then
+ local cells = self:flowCells(adEnv, run)
+ local color = ADFlowView.LEVEL_COLORS[self:flowLevel(adEnv, run)]
+ local canStop = ADRunsController.getRunStatus(adEnv, run).canStop
+ entry.cells[1]:setText(tostring(run.name))
+ entry.cells[2]:setText(tostring(cells[2]))
+ entry.cells[3]:setText(tostring(cells[5]))
+ entry.cells[4]:setText(tostring(cells[6]))
+ entry.cells[5]:setText(self.i18n:getText(canStop and "spu_flowList_stop" or "spu_flowList_start"))
+ if entry.dot ~= nil and entry.dot.setImageColor ~= nil then entry.dot:setImageColor(nil, unpackFn(color)) end
+ if entry.cells[4].setTextColor ~= nil then entry.cells[4]:setTextColor(unpackFn(color)) end
end
end
end
+-- Start/Stop for ét flow (rækkens felt og vinduets knap). Husker om sidste start blev helt afvist (rød).
+function SmartPickupFrame:toggleRun(adEnv, runId)
+ local run = ADRuns.getRun(ADRunsController.store, runId)
+ if adEnv == nil or run == nil then return end
+ self.lastStartFailed = self.lastStartFailed or {}
+ if ADRunsController.getRunStatus(adEnv, run).canStop then
+ ADRunsController.stopRun(adEnv, run.id)
+ self.lastStartFailed[run.id] = nil
+ self.statusOverride = nil
+ else
+ local started, skipped, reasons = self:summarizeStartResults(ADRunsController.startRun(adEnv, run.id))
+ self.lastStartFailed[run.id] = started == 0 and skipped > 0
+ local text = string.format(self.i18n:getText("spu_status_started"), started, skipped)
+ self:showOverride(text, reasons)
+ -- statuslinjen kan ligge uden for skærmen: sprunget over vises også som besked i højre side
+ if skipped > 0 and ADFieldJobs ~= nil and ADFieldJobs.notify ~= nil then
+ ADFieldJobs.notify(string.format("%s: %s — %s", tostring(run.name), text, table.concat(reasons, "; ")), started == 0)
+ end
+ end
+ ADRunsController.save()
+end
+
+function SmartPickupFrame:flowLevel(adEnv, run)
+ local row = ADRunsController.getFlowRow(adEnv, run)
+ local status = ADRunsController.getRunStatus(adEnv, run)
+ return ADFlowView.flowStatus({running = row.running, total = row.total, stopped = run.stopped == true,
+ canStop = status.canStop == true, warning = row.warning, reason = row.reason,
+ lastStartFailed = (self.lastStartFailed or {})[run.id] == true})
+end
+
function SmartPickupFrame:fillFlowSummary(adEnv, run)
local i18n = self.i18n
- self:addTextRow(string.format(i18n:getText("spu_guide_flow_section"), tostring(run.name)))
+ if not self.editPanelOpen then
+ self:addTextRow(string.format(i18n:getText("spu_guide_flow_section"), tostring(run.name)))
+ end
self:addTextRow(" " .. i18n:getText("spu_guide_sum_hint"))
local guide = ADFlowGuide.open(run, self:flowGuideContext(adEnv, run))
local getText = function(key) return i18n:getText(key) end
@@ -199,31 +261,53 @@ function SmartPickupFrame:fillFlowSummary(adEnv, run)
end
local cells = self:flowCells(adEnv, run)
self:addTextRow(" " .. string.format(i18n:getText("spu_field_statusFull"), tostring(cells[6])))
+ self:addLinkRow(" " .. i18n:getText("spu_guide_flow_open"), function(frame)
+ frame.selectedRunId = runId
+ frame:onClickFlowSetup()
+ end)
end
+-- Redigeringsvinduet for et flow (gui/SmartPickupEditPanel.lua).
+SmartPickupFrame.EDIT_PANEL_KINDS = SmartPickupFrame.EDIT_PANEL_KINDS or {}
+SmartPickupFrame.EDIT_PANEL_KINDS.flow = {
+ canDelete = true,
+ exists = function(frame, id) return ADRuns.getRun(ADRunsController.store, id) ~= nil end,
+ title = function(frame, id)
+ local run = ADRuns.getRun(ADRunsController.store, id)
+ return string.format(frame.i18n:getText("spu_panel_flowTitle"), tostring(run ~= nil and run.name or "?"))
+ end,
+ fill = function(frame, adEnv, id)
+ local run = ADRuns.getRun(ADRunsController.store, id)
+ if run ~= nil then frame:fillFlowSummary(adEnv, run) end
+ end,
+ status = function(frame, adEnv, id)
+ local run = ADRuns.getRun(ADRunsController.store, id)
+ return {text = tostring(frame:flowCells(adEnv, run)[6]), level = frame:flowLevel(adEnv, run)}
+ end,
+ startStopText = function(frame, adEnv, id)
+ local run = ADRuns.getRun(ADRunsController.store, id)
+ return frame.i18n:getText(ADRunsController.getRunStatus(adEnv, run).canStop and "spu_button_stop" or "spu_button_start")
+ end,
+ startStop = function(frame, id) frame:toggleRun(frame.getAdEnv(), id) end,
+ delete = function(frame, id)
+ frame.selectedRunId = id
+ frame:onClickDelete()
+ end,
+}
+
-- Hvert sekund: tavlens celler, statuslinje og knapper.
function SmartPickupFrame:refreshFlowTab(adEnv)
- local run = self:getRun()
- local isRunning = false
- if self:hasGuideOn(SmartPickupFrame.TAB_FLOWS) then
+ if not self.editPanelOpen and self:hasGuideOn(SmartPickupFrame.TAB_FLOWS) then
self:setStatusText(self.statusOverride or "")
- else
- self:refreshOverview(adEnv)
- if run ~= nil then
- local status = ADRunsController.getRunStatus(adEnv, run)
- isRunning = status.canStop == true
- local text = status.running > 0 and string.format(self.i18n:getText("spu_status_running"), status.running, status.total)
- or string.format(self.i18n:getText("spu_status_stopped"), status.total)
- self:setStatusText(self.statusOverride or text)
- else
- -- tavlen siger allerede "Ingen flows"
- self:setStatusText(self.statusOverride or "")
- end
+ return
end
- self.startButtonInfo.text = self.i18n:getText(isRunning and "spu_button_stop" or "spu_button_start")
- self.startButtonInfo.disabled = run == nil
- self.flowSetupButtonInfo.disabled = run == nil
- self.deleteButtonInfo.disabled = run == nil
+ self:refreshFlowListRows(adEnv)
+ local running, total = 0, 0
+ for _, run in ipairs(ADRunsController.store.runs) do
+ total = total + 1
+ if ADRunsController.getRunStatus(adEnv, run).running > 0 then running = running + 1 end
+ end
+ self:setStatusText(self.statusOverride or string.format(self.i18n:getText("spu_flowList_status"), running, total))
end
-- ---- hooks til den fælles guide-skærm ----
diff --git a/FS25_ADSmartPickup/gui/SmartPickupFlowTab.lua b/FS25_ADSmartPickup/gui/SmartPickupFlowTab.lua
index 112a807..a663e5f 100644
--- a/FS25_ADSmartPickup/gui/SmartPickupFlowTab.lua
+++ b/FS25_ADSmartPickup/gui/SmartPickupFlowTab.lua
@@ -85,6 +85,7 @@ function SmartPickupFrame:makeRowClickable(row, action)
local blockedByPanel = frame.editPanelOpen and layout == frame.boxLayout
if not used and not eventUsed and not blockedByPanel and isUp and button == MOUSE_LEFT and (element.getIsVisible == nil or element:getIsVisible())
and isInside(element, posX, posY) and isInside(layout, posX, posY) then
+ frame.lastClickX = posX
frame.pendingClick = action
return true
end
diff --git a/FS25_ADSmartPickup/gui/SmartPickupFrame.lua b/FS25_ADSmartPickup/gui/SmartPickupFrame.lua
index 52ca61c..d17f4fa 100644
--- a/FS25_ADSmartPickup/gui/SmartPickupFrame.lua
+++ b/FS25_ADSmartPickup/gui/SmartPickupFrame.lua
@@ -86,7 +86,7 @@ end
-- Prefabs skal ud af layoutet før de klones, ellers vises de selv som rækker.
function SmartPickupFrame:initialize()
- for _, name in ipairs({"ingredientPrefab", "vehiclePrefab", "textPrefab", "productPrefab", "statPrefab", "gridPrefab", "flowPrefab", "fieldPrefab", "kpiPrefab", "alertPrefab", "itemPrefab", "subPrefab"}) do
+ for _, name in ipairs({"ingredientPrefab", "vehiclePrefab", "textPrefab", "productPrefab", "statPrefab", "gridPrefab", "flowPrefab", "flowListPrefab", "fieldPrefab", "kpiPrefab", "alertPrefab", "itemPrefab", "subPrefab"}) do
local prefab = self[name]
if prefab ~= nil then
prefab:unlinkElement()
@@ -785,20 +785,7 @@ function SmartPickupFrame:onClickStartStop()
self:safe(function(frame)
local adEnv, run = frame.getAdEnv(), frame:getRun()
if adEnv == nil or run == nil then return end
- if ADRunsController.getRunStatus(adEnv, run).canStop then
- ADRunsController.stopRun(adEnv, run.id)
- frame.statusOverride = nil
- else
- local started, skipped, reasons = frame:summarizeStartResults(ADRunsController.startRun(adEnv, run.id))
- local text = string.format(frame.i18n:getText("spu_status_started"), started, skipped)
- frame:showOverride(text, reasons)
- -- statuslinjen ligger nederst i den rullende liste: sprunget over vises også som besked i højre side
- -- (in-game 29/9: Start på Milk Store 'gjorde ingenting' — begge traktorer afvist, grunden sås ikke)
- if skipped > 0 and ADFieldJobs ~= nil and ADFieldJobs.notify ~= nil then
- ADFieldJobs.notify(string.format("%s: %s — %s", tostring(run.name), text, table.concat(reasons, "; ")), started == 0)
- end
- end
- ADRunsController.save()
+ frame:toggleRun(adEnv, run.id)
frame:requestRebuild()
end)
end
diff --git a/FS25_ADSmartPickup/gui/SmartPickupFrame.xml b/FS25_ADSmartPickup/gui/SmartPickupFrame.xml
index d2bcf9c..5ee6a65 100644
--- a/FS25_ADSmartPickup/gui/SmartPickupFrame.xml
+++ b/FS25_ADSmartPickup/gui/SmartPickupFrame.xml
@@ -89,6 +89,15 @@
+
+
+
+
+
+
+
+
+
diff --git a/FS25_ADSmartPickup/l10n/l10n_da.xml b/FS25_ADSmartPickup/l10n/l10n_da.xml
index 0e71106..77c7bef 100644
--- a/FS25_ADSmartPickup/l10n/l10n_da.xml
+++ b/FS25_ADSmartPickup/l10n/l10n_da.xml
@@ -254,6 +254,11 @@
+
+
+
+
+
diff --git a/FS25_ADSmartPickup/l10n/l10n_en.xml b/FS25_ADSmartPickup/l10n/l10n_en.xml
index d492ba8..a0f8ac0 100644
--- a/FS25_ADSmartPickup/l10n/l10n_en.xml
+++ b/FS25_ADSmartPickup/l10n/l10n_en.xml
@@ -254,6 +254,11 @@
+
+
+
+
+