feat(fields): Fields-fanen som farvet liste med Start/Stop pr. række; klik åbner redigeringsvinduet

This commit is contained in:
2026-09-29 17:45:47 +02:00
parent 44f1204be9
commit 19ed87ce0f
6 changed files with 90 additions and 13 deletions
@@ -11,7 +11,8 @@ function SmartPickupFrame:initFieldButtons(i18n)
self.fieldSetupButtonInfo = {inputAction = InputAction.MENU_EXTRA_1, text = i18n:getText("spu_guide_field_open"), callback = function() self:onClickFieldSetup() end} self.fieldSetupButtonInfo = {inputAction = InputAction.MENU_EXTRA_1, text = i18n:getText("spu_guide_field_open"), callback = function() self:onClickFieldSetup() end}
self.fieldFleetButtonInfo = {inputAction = InputAction.MENU_EXTRA_2, text = i18n:getText("spu_guide_fleet_open"), callback = function() self:onClickFieldFleet(true) end} self.fieldFleetButtonInfo = {inputAction = InputAction.MENU_EXTRA_2, text = i18n:getText("spu_guide_fleet_open"), callback = function() self:onClickFieldFleet(true) end}
self.fieldFleetCloseButtonInfo = {inputAction = InputAction.MENU_EXTRA_2, text = i18n:getText("spu_guide_fleet_close"), callback = function() self:onClickFieldFleet(false) end} self.fieldFleetCloseButtonInfo = {inputAction = InputAction.MENU_EXTRA_2, text = i18n:getText("spu_guide_fleet_close"), callback = function() self:onClickFieldFleet(false) end}
self.fieldButtons = {self.backButtonInfo, self.fieldStartButtonInfo, self.fieldSetupButtonInfo, self.fieldFleetButtonInfo} -- v1.59: listen har Start/Stop pr. række; Opsæt mark ligger i redigeringsvinduet
self.fieldButtons = {self.backButtonInfo, self.fieldFleetButtonInfo}
self.fieldFleetButtons = {self.backButtonInfo, self.fieldFleetCloseButtonInfo} self.fieldFleetButtons = {self.backButtonInfo, self.fieldFleetCloseButtonInfo}
end end
+74 -11
View File
@@ -104,13 +104,14 @@ function SmartPickupFrame:fieldCells(row)
for _, assignment in ipairs(ADFieldJobs.assignmentsFor(info.id)) do for _, assignment in ipairs(ADFieldJobs.assignmentsFor(info.id)) do
table.insert(names, ADRuns.vehicleLabel(assignment.vehicle)) table.insert(names, ADRuns.vehicleLabel(assignment.vehicle))
end end
local name = string.format("%s%sF%d", info.id == self.selectedFieldId and "> " or "", info.markerId == nil and "! " or "", info.id) local name = string.format("%sF%d", info.markerId == nil and "! " or "", info.id)
local crop = ADFieldView.cropText(info, function(key) return self.i18n:getText(key) end) local crop = ADFieldView.cropText(info, function(key) return self.i18n:getText(key) end)
return { return {
name, crop, self:fieldPlanText(field, info), name, crop, self:fieldPlanText(field, info),
self.i18n:getText(field.plan.mode == "auto" and "spu_field_mode_auto" or "spu_field_mode_manual"), self.i18n:getText(field.plan.mode == "auto" and "spu_field_mode_auto" or "spu_field_mode_manual"),
self:fieldStatusText(field, info, true), self:fieldStatusText(field, info, true),
ADFlowView.joinCounted(names, ", ", "-"), ADFlowView.joinCounted(names, ", ", "-"),
self:fieldActionText(info.id),
} }
end end
@@ -133,32 +134,68 @@ function SmartPickupFrame:fillFieldRows(adEnv)
if ADFieldJobs.state.fleetMode == "ticked" and next(ADFieldJobs.state.fleet or {}) == nil then if ADFieldJobs.state.fleetMode == "ticked" and next(ADFieldJobs.state.fleet or {}) == nil then
self:addTextRow(i18n:getText("spu_field_fleetEmpty")) self:addTextRow(i18n:getText("spu_field_fleetEmpty"))
end end
self:addCellRow(self.fieldPrefab, {i18n:getText("spu_col_field"), i18n:getText("spu_col_crop"), i18n:getText("spu_col_plan"), i18n:getText("spu_col_mode"), i18n:getText("spu_col_status"), i18n:getText("spu_col_tractors")}) self:addCellRow(self.fieldListPrefab, {i18n:getText("spu_col_field"), i18n:getText("spu_col_crop"), i18n:getText("spu_col_plan"), i18n:getText("spu_col_mode"), i18n:getText("spu_col_status"), i18n:getText("spu_col_tractors"), ""})
for _, row in ipairs(ADFieldView.rows(infos, ADFieldJobs.state.fields)) do for _, row in ipairs(ADFieldView.rows(infos, ADFieldJobs.state.fields)) do
local cells = self:addCellRow(self.fieldPrefab, self:fieldCells(row)) local cells = self:addCellRow(self.fieldListPrefab, self:fieldCells(row))
local fieldId = row.info.id local fieldId = row.info.id
if cells[1] ~= nil and cells[1].parent ~= nil then if cells[1] ~= nil and cells[1].parent ~= nil then
local actionCell = cells[7]
self:makeRowClickable(cells[1].parent, function(frame) self:makeRowClickable(cells[1].parent, function(frame)
frame.selectedFieldId = fieldId -- klik på [Start]/[Stop]-feltet = handling (kun denne mark); ellers åbn redigeringsvinduet
frame:requestRebuild() if frame.lastClickX ~= nil and actionCell ~= nil and actionCell.absPosition ~= nil and frame.lastClickX >= actionCell.absPosition[1] then
frame:toggleField(fieldId)
else
frame.selectedFieldId = fieldId
frame:openEditPanel("field", fieldId)
end
end) end)
end end
table.insert(self.fieldRows, {id = fieldId, cells = cells}) table.insert(self.fieldRows, {id = fieldId, cells = cells})
end end
end end
local selected = self.selectedFieldId ~= nil and ADFields.getInfo(self.selectedFieldId) or nil self:refreshFieldLevels()
if selected ~= nil then end
self:fillFieldOverview(adEnv, selected)
-- Prik og statusfarve pr. mark i listen.
function SmartPickupFrame:refreshFieldLevels()
local unpackFn = table.unpack or unpack
for _, entry in ipairs(self.fieldRows or {}) do
local color = ADFlowView.LEVEL_COLORS[self:fieldLevel(entry.id)]
local row = entry.cells[1] ~= nil and entry.cells[1].parent or nil
local dot = row ~= nil and row:getDescendantByName("dot") or nil
if dot ~= nil and dot.setImageColor ~= nil then dot:setImageColor(nil, unpackFn(color)) end
if entry.cells[5] ~= nil and entry.cells[5].setTextColor ~= nil then entry.cells[5]:setTextColor(unpackFn(color)) end
end end
end end
function SmartPickupFrame:fieldLevel(id)
local field, info = ADFieldJobs.getField(id), ADFields.getInfo(id)
if field == nil or info == nil then return "stopped" end
local reason = type(field.reason) == "table" and field.reason.key or nil
return ADFieldView.fieldStatus({hasMarker = info.markerId ~= nil, working = ADFieldModel.isWorking(field),
awaiting = ADFieldJobs.awaitingPlayer(id) ~= nil,
startRequested = ADFieldJobs.isStartRequested ~= nil and ADFieldJobs.isStartRequested(id) or false,
reasonKey = reason})
end
-- forButton: knaplinjens tekst (Start/Stop) i stedet for listens [Start]/[Stop].
function SmartPickupFrame:fieldActionText(id, forButton)
local field = ADFieldJobs.getField(id)
if ADFieldJobs.awaitingPlayer(id) ~= nil then return self.i18n:getText("spu_field_button_takeover") end
local isWorking = field ~= nil and ADFieldModel.isWorking(field)
if forButton then return self.i18n:getText(isWorking and "spu_field_button_stop" or "spu_field_button_start") end
return self.i18n:getText(isWorking and "spu_flowList_stop" or "spu_flowList_start")
end
-- Den valgte marks resumé: én klikbar linje pr. emne ([Ret] åbner kun det trin), hele status, markør og -- Den valgte marks resumé: én klikbar linje pr. emne ([Ret] åbner kun det trin), hele status, markør og
-- advarsel om marksilo der ikke tømmes hjem. -- advarsel om marksilo der ikke tømmes hjem.
function SmartPickupFrame:fillFieldOverview(adEnv, info) function SmartPickupFrame:fillFieldOverview(adEnv, info)
local i18n = self.i18n local i18n = self.i18n
local field = ADFieldJobs.getField(info.id) local field = ADFieldJobs.getField(info.id)
local crop = ADFieldView.cropText(info, function(key) return i18n:getText(key) end) local crop = ADFieldView.cropText(info, function(key) return i18n:getText(key) end)
self:addTextRow(string.format(i18n:getText("spu_field_section"), info.id, crop)) if not self.editPanelOpen then
self:addTextRow(string.format(i18n:getText("spu_field_section"), info.id, crop))
end
self:addTextRow(" " .. i18n:getText("spu_guide_sum_hint")) self:addTextRow(" " .. i18n:getText("spu_guide_sum_hint"))
local context = self:fieldGuideContext(adEnv, info, field.plan, field.plan.storeBuildingIds) local context = self:fieldGuideContext(adEnv, info, field.plan, field.plan.storeBuildingIds)
local guide = ADFieldGuide.open(field, context) local guide = ADFieldGuide.open(field, context)
@@ -283,7 +320,7 @@ end
-- ---- live ---- -- ---- live ----
function SmartPickupFrame:refreshFieldRows(adEnv) function SmartPickupFrame:refreshFieldRows(adEnv)
if self:hasGuideOn(SmartPickupFrame.TAB_FIELDS) or self.fieldView == "fleet" then if (not self.editPanelOpen and self:hasGuideOn(SmartPickupFrame.TAB_FIELDS)) or self.fieldView == "fleet" then
self:setStatusText(self.statusOverride or "") self:setStatusText(self.statusOverride or "")
return return
end end
@@ -298,6 +335,7 @@ function SmartPickupFrame:refreshFieldRows(adEnv)
if ADFieldModel.isWorking(row.field) then working = working + 1 end if ADFieldModel.isWorking(row.field) then working = working + 1 end
end end
end end
self:refreshFieldLevels()
self:setStatusText(self.statusOverride or string.format(self.i18n:getText("spu_field_status"), working, total)) self:setStatusText(self.statusOverride or string.format(self.i18n:getText("spu_field_status"), working, total))
local selected = self.selectedFieldId ~= nil and ADFieldJobs.getField(self.selectedFieldId) or nil local selected = self.selectedFieldId ~= nil and ADFieldJobs.getField(self.selectedFieldId) or nil
local info = self.selectedFieldId ~= nil and ADFields.getInfo(self.selectedFieldId) or nil local info = self.selectedFieldId ~= nil and ADFields.getInfo(self.selectedFieldId) or nil
@@ -327,8 +365,12 @@ end
-- Start nu: pleje hvis marken trænger (og vokser), ellers hele kæden (høst/slå, eller klargøring på bar mark). -- Start nu: pleje hvis marken trænger (og vokser), ellers hele kæden (høst/slå, eller klargøring på bar mark).
function SmartPickupFrame:onClickFieldStartStop() function SmartPickupFrame:onClickFieldStartStop()
self:toggleField(self.selectedFieldId)
end
-- Start/Stop/Overtag for én mark (rækkens felt, vinduets knap og knaplinjen).
function SmartPickupFrame:toggleField(id)
self:safe(function(frame) self:safe(function(frame)
local id = frame.selectedFieldId
if id == nil then return end if id == nil then return end
local field = ADFieldJobs.getField(id) local field = ADFieldJobs.getField(id)
if ADFieldJobs.awaitingPlayer(id) ~= nil then if ADFieldJobs.awaitingPlayer(id) ~= nil then
@@ -350,3 +392,24 @@ function SmartPickupFrame:onClickFieldStartStop()
frame:requestRebuild() frame:requestRebuild()
end) end)
end end
-- Redigeringsvinduet for en mark (gui/SmartPickupEditPanel.lua).
SmartPickupFrame.EDIT_PANEL_KINDS = SmartPickupFrame.EDIT_PANEL_KINDS or {}
SmartPickupFrame.EDIT_PANEL_KINDS.field = {
canDelete = false,
exists = function(frame, id) return ADFields.getInfo(id) ~= nil and ADFieldJobs.getField(id) ~= nil end,
title = function(frame, id) return string.format(frame.i18n:getText("spu_panel_fieldTitle"), id) end,
fill = function(frame, adEnv, id)
frame:fillFieldOverview(adEnv, ADFields.getInfo(id))
frame:addLinkRow(" " .. frame.i18n:getText("spu_guide_field_open"), function(f)
f.selectedFieldId = id
f:onClickFieldSetup()
end)
end,
status = function(frame, adEnv, id)
return {text = frame:fieldStatusText(ADFieldJobs.getField(id), ADFields.getInfo(id), true), level = frame:fieldLevel(id)}
end,
startStopText = function(frame, adEnv, id) return frame:fieldActionText(id, true) end,
startStop = function(frame, id) frame:toggleField(id) end,
delete = function() end,
}
+1 -1
View File
@@ -86,7 +86,7 @@ end
-- Prefabs skal ud af layoutet før de klones, ellers vises de selv som rækker. -- Prefabs skal ud af layoutet før de klones, ellers vises de selv som rækker.
function SmartPickupFrame:initialize() function SmartPickupFrame:initialize()
for _, name in ipairs({"ingredientPrefab", "vehiclePrefab", "textPrefab", "productPrefab", "statPrefab", "gridPrefab", "flowPrefab", "flowListPrefab", "fieldPrefab", "kpiPrefab", "alertPrefab", "itemPrefab", "subPrefab"}) do for _, name in ipairs({"ingredientPrefab", "vehiclePrefab", "textPrefab", "productPrefab", "statPrefab", "gridPrefab", "flowPrefab", "flowListPrefab", "fieldPrefab", "fieldListPrefab", "kpiPrefab", "alertPrefab", "itemPrefab", "subPrefab"}) do
local prefab = self[name] local prefab = self[name]
if prefab ~= nil then if prefab ~= nil then
prefab:unlinkElement() prefab:unlinkElement()
@@ -107,6 +107,17 @@
<Text profile="spuCell" name="c5" position="440px 0px" size="230px 40px" textMaxWidth="222px"/> <Text profile="spuCell" name="c5" position="440px 0px" size="230px 40px" textMaxWidth="222px"/>
<Text profile="spuCell" name="c6" position="670px 0px" size="140px 40px" textMaxWidth="132px"/> <Text profile="spuCell" name="c6" position="670px 0px" size="140px 40px" textMaxWidth="132px"/>
</Bitmap> </Bitmap>
<!-- Fields-listen (v1.59): ● · mark · afgrøde · plan · kørsel · status · maskiner · [Start]/[Stop]. ~835 px. -->
<Bitmap profile="fs25_multiTextOptionContainer" id="fieldListPrefab">
<Bitmap profile="spuDot" name="dot" position="20px 0px"/>
<Text profile="spuCellBold" name="c1" position="38px 0px" size="82px 40px" textMaxWidth="76px"/>
<Text profile="spuCell" name="c2" position="120px 0px" size="120px 40px" textMaxWidth="112px"/>
<Text profile="spuCell" name="c3" position="240px 0px" size="100px 40px" textMaxWidth="92px"/>
<Text profile="spuCell" name="c4" position="340px 0px" size="70px 40px" textMaxWidth="62px"/>
<Text profile="spuCell" name="c5" position="410px 0px" size="200px 40px" textMaxWidth="192px"/>
<Text profile="spuCell" name="c6" position="610px 0px" size="120px 40px" textMaxWidth="112px"/>
<Text profile="spuCellBold" name="c7" position="730px 0px" size="100px 40px" textMaxWidth="92px"/>
</Bitmap>
<!-- Lagre: statistik-tabel (vare · i bygningen · værdi nu · ved toppris · gården · rækker til · forbrug/prod.) --> <!-- Lagre: statistik-tabel (vare · i bygningen · værdi nu · ved toppris · gården · rækker til · forbrug/prod.) -->
<Bitmap profile="fs25_multiTextOptionContainer" id="statPrefab"> <Bitmap profile="fs25_multiTextOptionContainer" id="statPrefab">
<Text profile="spuCellBold" name="c1" position="20px 0px" size="140px 40px" textMaxWidth="132px"/> <Text profile="spuCellBold" name="c1" position="20px 0px" size="140px 40px" textMaxWidth="132px"/>
+1
View File
@@ -259,6 +259,7 @@
<text name="spu_flowList_stop" text="[Stop]"/> <text name="spu_flowList_stop" text="[Stop]"/>
<text name="spu_flowList_status" text="Flows i gang: %d af %d"/> <text name="spu_flowList_status" text="Flows i gang: %d af %d"/>
<text name="spu_panel_flowTitle" text="Rediger flow: %s"/> <text name="spu_panel_flowTitle" text="Rediger flow: %s"/>
<text name="spu_panel_fieldTitle" text="Mark F%d"/>
<text name="spu_newRunName" text="Flow %d"/> <text name="spu_newRunName" text="Flow %d"/>
<text name="spu_renameTitle" text="Navn på flow"/> <text name="spu_renameTitle" text="Navn på flow"/>
<text name="spu_deleteConfirm" text="Slet run '%s'? Dets kørende traktorer stoppes. Kan ikke fortrydes."/> <text name="spu_deleteConfirm" text="Slet run '%s'? Dets kørende traktorer stoppes. Kan ikke fortrydes."/>
+1
View File
@@ -259,6 +259,7 @@
<text name="spu_flowList_stop" text="[Stop]"/> <text name="spu_flowList_stop" text="[Stop]"/>
<text name="spu_flowList_status" text="Flows running: %d of %d"/> <text name="spu_flowList_status" text="Flows running: %d of %d"/>
<text name="spu_panel_flowTitle" text="Edit flow: %s"/> <text name="spu_panel_flowTitle" text="Edit flow: %s"/>
<text name="spu_panel_fieldTitle" text="Field F%d"/>
<text name="spu_newRunName" text="Flow %d"/> <text name="spu_newRunName" text="Flow %d"/>
<text name="spu_renameTitle" text="Flow name"/> <text name="spu_renameTitle" text="Flow name"/>
<text name="spu_deleteConfirm" text="Delete run '%s'? Its running tractors will be stopped. This cannot be undone."/> <text name="spu_deleteConfirm" text="Delete run '%s'? Its running tractors will be stopped. This cannot be undone."/>