fix(gui): review — vinduets placering (størrelse før position, genanvendes hvert sekund, profil uden midt-anker), fokus ved sletning af vinduets rækker, ESC via requestClose, [Start] kræver markør, forældet rød status, markvindue uden Slet
This commit is contained in:
@@ -97,3 +97,8 @@ function ADFieldView.fieldStatus(s)
|
|||||||
if s.reasonKey ~= nil then return "waiting" end
|
if s.reasonKey ~= nil then return "waiting" end
|
||||||
return "stopped"
|
return "stopped"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Må [Start]/[Stop] trykkes? Stop altid når marken arbejder; Start kræver en markør.
|
||||||
|
function ADFieldView.canStart(s)
|
||||||
|
return s.working == true or s.hasMarker == true
|
||||||
|
end
|
||||||
|
|||||||
@@ -14,9 +14,16 @@ function SmartPickupFrame:initEditPanelButtons(i18n)
|
|||||||
self.panelStartButtonInfo = {inputAction = InputAction.MENU_ACTIVATE, text = i18n:getText("spu_button_start"), callback = function() self:onClickPanelStartStop() end}
|
self.panelStartButtonInfo = {inputAction = InputAction.MENU_ACTIVATE, text = i18n:getText("spu_button_start"), callback = function() self:onClickPanelStartStop() end}
|
||||||
self.panelDeleteButtonInfo = {inputAction = InputAction.MENU_CANCEL, text = i18n:getText("spu_button_delete"), callback = function() self:onClickPanelDelete() end}
|
self.panelDeleteButtonInfo = {inputAction = InputAction.MENU_CANCEL, text = i18n:getText("spu_button_delete"), callback = function() self:onClickPanelDelete() end}
|
||||||
self.panelButtons = {self.panelCloseButtonInfo, self.panelStartButtonInfo, self.panelDeleteButtonInfo}
|
self.panelButtons = {self.panelCloseButtonInfo, self.panelStartButtonInfo, self.panelDeleteButtonInfo}
|
||||||
|
self.panelButtonsNoDelete = {self.panelCloseButtonInfo, self.panelStartButtonInfo}
|
||||||
self.panelGuideButtonCache = setmetatable({}, {__mode = "k"})
|
self.panelGuideButtonCache = setmetatable({}, {__mode = "k"})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Vinduets knaplinje (uden Slet for arter der ikke kan slettes).
|
||||||
|
function SmartPickupFrame:getPanelButtons()
|
||||||
|
local hooks = self:editPanelHooks()
|
||||||
|
return (hooks ~= nil and hooks.canDelete) and self.panelButtons or self.panelButtonsNoDelete
|
||||||
|
end
|
||||||
|
|
||||||
function SmartPickupFrame:editPanelHooks()
|
function SmartPickupFrame:editPanelHooks()
|
||||||
return self.editPanelOpen and SmartPickupFrame.EDIT_PANEL_KINDS[self.editPanelKind] or nil
|
return self.editPanelOpen and SmartPickupFrame.EDIT_PANEL_KINDS[self.editPanelKind] or nil
|
||||||
end
|
end
|
||||||
@@ -35,23 +42,33 @@ function SmartPickupFrame:panelGuideButtons()
|
|||||||
return cached
|
return cached
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Vinduet dækker listens flade; panelet er centreret i den (absolutte koordinater, y opad).
|
-- Sæt størrelse FØR position: setSize kan genberegne den absolutte position ud fra forælderen (review 29/9).
|
||||||
|
-- -> true hvis elementet flyttede sig.
|
||||||
|
local function place(element, x, y, w, h)
|
||||||
|
if w ~= nil then element:setSize(w, h) end
|
||||||
|
local pos = element.absPosition
|
||||||
|
local moved = pos == nil or math.abs(pos[1] - x) > 1e-6 or math.abs(pos[2] - y) > 1e-6
|
||||||
|
element:setAbsolutePosition(x, y)
|
||||||
|
return moved
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Vinduet dækker listens flade; panelet er centreret i den (absolutte koordinater, y opad). Kaldes ved åbning,
|
||||||
|
-- ved hver opbygning og hvert sekund, så en layout-gennemgang i menuen ikke flytter det væk.
|
||||||
function SmartPickupFrame:layoutEditPanel()
|
function SmartPickupFrame:layoutEditPanel()
|
||||||
local box = self.boxLayout
|
local box = self.boxLayout
|
||||||
if box == nil or box.absPosition == nil or box.absSize == nil then return end
|
if box == nil or box.absPosition == nil or box.absSize == nil then return end
|
||||||
local x, y, w, h = box.absPosition[1], box.absPosition[2], box.absSize[1], box.absSize[2]
|
local x, y, w, h = box.absPosition[1], box.absPosition[2], box.absSize[1], box.absSize[2]
|
||||||
self.editBackdrop:setAbsolutePosition(x, y)
|
place(self.editBackdrop, x, y, w, h)
|
||||||
self.editBackdrop:setSize(w, h)
|
|
||||||
local pw, ph = w * SmartPickupFrame.EDIT_PANEL_WIDTH, h * SmartPickupFrame.EDIT_PANEL_HEIGHT
|
local pw, ph = w * SmartPickupFrame.EDIT_PANEL_WIDTH, h * SmartPickupFrame.EDIT_PANEL_HEIGHT
|
||||||
local px, py = x + (w - pw) / 2, y + (h - ph) / 2
|
local px, py = x + (w - pw) / 2, y + (h - ph) / 2
|
||||||
self.editPanel:setAbsolutePosition(px, py)
|
place(self.editPanel, px, py, pw, ph)
|
||||||
self.editPanel:setSize(pw, ph)
|
|
||||||
local header = SmartPickupFrame.EDIT_PANEL_HEADER_PX * g_pixelSizeScaledY
|
local header = SmartPickupFrame.EDIT_PANEL_HEADER_PX * g_pixelSizeScaledY
|
||||||
local margin = 20 * g_pixelSizeScaledX
|
local margin = 20 * g_pixelSizeScaledX
|
||||||
self.editTitle:setAbsolutePosition(px + margin, py + ph - header * 0.45)
|
place(self.editTitle, px + margin, py + ph - header * 0.45)
|
||||||
self.editStatus:setAbsolutePosition(px + margin, py + ph - header * 0.85)
|
place(self.editStatus, px + margin, py + ph - header * 0.85)
|
||||||
self.editLayout:setAbsolutePosition(px, py)
|
if place(self.editLayout, px, py, pw, ph - header) then
|
||||||
self.editLayout:setSize(pw, ph - header)
|
self.editLayout:invalidateLayout()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function SmartPickupFrame:openEditPanel(kind, id)
|
function SmartPickupFrame:openEditPanel(kind, id)
|
||||||
@@ -108,9 +125,12 @@ function SmartPickupFrame:refreshEditPanel(adEnv)
|
|||||||
local hooks = self:editPanelHooks()
|
local hooks = self:editPanelHooks()
|
||||||
if hooks == nil or adEnv == nil then return end
|
if hooks == nil or adEnv == nil then return end
|
||||||
if not hooks.exists(self, self.editPanelId) then
|
if not hooks.exists(self, self.editPanelId) then
|
||||||
|
self.statusOverride = self.i18n:getText("spu_panel_gone")
|
||||||
|
self.statusOverrideTicks = SmartPickupFrame.STATUS_OVERRIDE_TICKS
|
||||||
self:closeEditPanel()
|
self:closeEditPanel()
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
self:layoutEditPanel()
|
||||||
local status = hooks.status(self, adEnv, self.editPanelId)
|
local status = hooks.status(self, adEnv, self.editPanelId)
|
||||||
self.editStatus:setText(tostring(status.text or ""))
|
self.editStatus:setText(tostring(status.text or ""))
|
||||||
local color = ADFlowView.LEVEL_COLORS[status.level] or ADFlowView.LEVEL_COLORS.stopped
|
local color = ADFlowView.LEVEL_COLORS[status.level] or ADFlowView.LEVEL_COLORS.stopped
|
||||||
@@ -118,10 +138,29 @@ function SmartPickupFrame:refreshEditPanel(adEnv)
|
|||||||
self.editStatus:setTextColor(color[1], color[2], color[3], color[4])
|
self.editStatus:setTextColor(color[1], color[2], color[3], color[4])
|
||||||
end
|
end
|
||||||
self.panelStartButtonInfo.text = hooks.startStopText(self, adEnv, self.editPanelId)
|
self.panelStartButtonInfo.text = hooks.startStopText(self, adEnv, self.editPanelId)
|
||||||
self.panelDeleteButtonInfo.disabled = not hooks.canDelete
|
self.panelStartButtonInfo.disabled = hooks.canStart ~= nil and not hooks.canStart(self, self.editPanelId)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- ESC mens vinduet er åbent: menuen spørger requestClose; vinduet lukkes (trin først), menuen bliver.
|
||||||
|
-- Kalder spillet OGSÅ knappens callback for samme tryk, må det ikke lukke to trin (panelClosedAt).
|
||||||
|
SmartPickupFrame.PANEL_ESC_DEBOUNCE_MS = 250
|
||||||
|
|
||||||
|
function SmartPickupFrame:requestClose(callback)
|
||||||
|
if self.editPanelOpen then
|
||||||
|
self:onClickPanelClose()
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
if g_time ~= nil and self.panelClosedAt ~= nil and g_time - self.panelClosedAt < SmartPickupFrame.PANEL_ESC_DEBOUNCE_MS then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
return SmartPickupFrame:superClass().requestClose(self, callback)
|
||||||
end
|
end
|
||||||
|
|
||||||
function SmartPickupFrame:onClickPanelClose()
|
function SmartPickupFrame:onClickPanelClose()
|
||||||
|
if g_time ~= nil and self.panelClosedAt ~= nil and g_time - self.panelClosedAt < SmartPickupFrame.PANEL_ESC_DEBOUNCE_MS then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
self.panelClosedAt = g_time
|
||||||
self:safe(function(frame)
|
self:safe(function(frame)
|
||||||
-- et åbent [Edit]-trin lukkes først (kladden kasseres som ved Annullér)
|
-- et åbent [Edit]-trin lukkes først (kladden kasseres som ved Annullér)
|
||||||
if frame.guide ~= nil then
|
if frame.guide ~= nil then
|
||||||
|
|||||||
@@ -168,6 +168,14 @@ function SmartPickupFrame:refreshFieldLevels()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- [Start] kræver en markør (Stop/Overtag altid muligt når marken arbejder).
|
||||||
|
function SmartPickupFrame:fieldCanStart(id)
|
||||||
|
local field, info = ADFieldJobs.getField(id), ADFields.getInfo(id)
|
||||||
|
if field == nil or info == nil then return false end
|
||||||
|
return ADFieldView.canStart({hasMarker = info.markerId ~= nil,
|
||||||
|
working = ADFieldModel.isWorking(field) or ADFieldJobs.awaitingPlayer(id) ~= nil})
|
||||||
|
end
|
||||||
|
|
||||||
function SmartPickupFrame:fieldLevel(id)
|
function SmartPickupFrame:fieldLevel(id)
|
||||||
local field, info = ADFieldJobs.getField(id), ADFields.getInfo(id)
|
local field, info = ADFieldJobs.getField(id), ADFields.getInfo(id)
|
||||||
if field == nil or info == nil then return "stopped" end
|
if field == nil or info == nil then return "stopped" end
|
||||||
@@ -371,7 +379,7 @@ end
|
|||||||
-- Start/Stop/Overtag for én mark (rækkens felt, vinduets knap og knaplinjen).
|
-- Start/Stop/Overtag for én mark (rækkens felt, vinduets knap og knaplinjen).
|
||||||
function SmartPickupFrame:toggleField(id)
|
function SmartPickupFrame:toggleField(id)
|
||||||
self:safe(function(frame)
|
self:safe(function(frame)
|
||||||
if id == nil then return end
|
if id == nil or not frame:fieldCanStart(id) 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
|
||||||
-- manuel transport: overtag nu (skærebordet tjekkes stadig)
|
-- manuel transport: overtag nu (skærebordet tjekkes stadig)
|
||||||
@@ -411,5 +419,6 @@ SmartPickupFrame.EDIT_PANEL_KINDS.field = {
|
|||||||
end,
|
end,
|
||||||
startStopText = function(frame, adEnv, id) return frame:fieldActionText(id, true) end,
|
startStopText = function(frame, adEnv, id) return frame:fieldActionText(id, true) end,
|
||||||
startStop = function(frame, id) frame:toggleField(id) end,
|
startStop = function(frame, id) frame:toggleField(id) end,
|
||||||
|
canStart = function(frame, id) return frame:fieldCanStart(id) end,
|
||||||
delete = function() end,
|
delete = function() end,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -239,6 +239,8 @@ end
|
|||||||
function SmartPickupFrame:flowLevel(adEnv, run)
|
function SmartPickupFrame:flowLevel(adEnv, run)
|
||||||
local row = ADRunsController.getFlowRow(adEnv, run)
|
local row = ADRunsController.getFlowRow(adEnv, run)
|
||||||
local status = ADRunsController.getRunStatus(adEnv, run)
|
local status = ADRunsController.getRunStatus(adEnv, run)
|
||||||
|
-- en gammel afvisning gælder ikke længere når flowet kører (fx startet fra Oversigt bagefter)
|
||||||
|
if row.running > 0 and self.lastStartFailed ~= nil then self.lastStartFailed[run.id] = nil end
|
||||||
return ADFlowView.flowStatus({running = row.running, total = row.total, stopped = run.stopped == true,
|
return ADFlowView.flowStatus({running = row.running, total = row.total, stopped = run.stopped == true,
|
||||||
canStop = status.canStop == true, warning = row.warning, reason = row.reason,
|
canStop = status.canStop == true, warning = row.warning, reason = row.reason,
|
||||||
lastStartFailed = (self.lastStartFailed or {})[run.id] == true})
|
lastStartFailed = (self.lastStartFailed or {})[run.id] == true})
|
||||||
|
|||||||
@@ -376,7 +376,11 @@ function SmartPickupFrame:withRowTarget(layout, fn)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function SmartPickupFrame:clearPanelRows()
|
function SmartPickupFrame:clearPanelRows()
|
||||||
|
local focused = SmartPickupFrame.getFocusedElement()
|
||||||
for _, row in ipairs(self.panelRows or {}) do
|
for _, row in ipairs(self.panelRows or {}) do
|
||||||
|
if focused ~= nil and SmartPickupFrame.isDescendantOf(focused, row) then
|
||||||
|
self.focusLost = true
|
||||||
|
end
|
||||||
FocusManager:removeElement(row)
|
FocusManager:removeElement(row)
|
||||||
row:delete()
|
row:delete()
|
||||||
end
|
end
|
||||||
@@ -600,7 +604,7 @@ end
|
|||||||
function SmartPickupFrame:refreshButtons()
|
function SmartPickupFrame:refreshButtons()
|
||||||
local wanted = self.flowButtons
|
local wanted = self.flowButtons
|
||||||
if self.editPanelOpen then
|
if self.editPanelOpen then
|
||||||
wanted = self.guide ~= nil and self:panelGuideButtons() or self.panelButtons
|
wanted = self.guide ~= nil and self:panelGuideButtons() or self:getPanelButtons()
|
||||||
elseif self:hasGuideOn(self.currentTab) then
|
elseif self:hasGuideOn(self.currentTab) then
|
||||||
wanted = self:getGuideButtons()
|
wanted = self:getGuideButtons()
|
||||||
elseif self.currentTab == SmartPickupFrame.TAB_OVERVIEW then
|
elseif self.currentTab == SmartPickupFrame.TAB_OVERVIEW then
|
||||||
|
|||||||
@@ -54,13 +54,14 @@
|
|||||||
<textColor value="0.75 0.75 0.75 1"/>
|
<textColor value="0.75 0.75 0.75 1"/>
|
||||||
</Profile>
|
</Profile>
|
||||||
<!-- redigeringsvindue (v1.58): mørk flade + panel; størrelser/placering sættes i Lua ud fra boxLayout -->
|
<!-- redigeringsvindue (v1.58): mørk flade + panel; størrelser/placering sættes i Lua ud fra boxLayout -->
|
||||||
<Profile name="spuOverlayBackdrop" extends="spuBar">
|
<Profile name="spuOverlayBackdrop" extends="baseReference" with="anchorTopLeft">
|
||||||
|
<imageUVs value="10px 1010px 4px 4px"/>
|
||||||
|
<positionOrigin value="bottomLeft"/>
|
||||||
<imageColor value="0 0 0 0.65"/>
|
<imageColor value="0 0 0 0.65"/>
|
||||||
<size value="100px 100px"/>
|
<size value="100px 100px"/>
|
||||||
</Profile>
|
</Profile>
|
||||||
<Profile name="spuOverlayPanel" extends="spuBar">
|
<Profile name="spuOverlayPanel" extends="spuOverlayBackdrop">
|
||||||
<imageColor value="0.09 0.09 0.09 0.97"/>
|
<imageColor value="0.09 0.09 0.09 0.97"/>
|
||||||
<size value="100px 100px"/>
|
|
||||||
</Profile>
|
</Profile>
|
||||||
<Profile name="spuPanelTitle" extends="spuCellBold">
|
<Profile name="spuPanelTitle" extends="spuCellBold">
|
||||||
<textSize value="20px"/>
|
<textSize value="20px"/>
|
||||||
|
|||||||
@@ -18,5 +18,9 @@ check("regn", V.fieldStatus({hasMarker = true, working = true, reasonKey = "spu_
|
|||||||
check("venter på spilleren (høster)", V.fieldStatus({hasMarker = true, awaiting = true}), "waiting")
|
check("venter på spilleren (høster)", V.fieldStatus({hasMarker = true, awaiting = true}), "waiting")
|
||||||
check("start bestilt", V.fieldStatus({hasMarker = true, startRequested = true}), "waiting")
|
check("start bestilt", V.fieldStatus({hasMarker = true, startRequested = true}), "waiting")
|
||||||
check("i ro", V.fieldStatus({hasMarker = true}), "stopped")
|
check("i ro", V.fieldStatus({hasMarker = true}), "stopped")
|
||||||
|
-- Start må ikke bestilles på en mark uden markør (knappen var før deaktiveret; review 29/9)
|
||||||
|
check("kan starte: med markør", V.canStart({hasMarker = true, working = false}), true)
|
||||||
|
check("kan starte: uden markør -> nej", V.canStart({hasMarker = false, working = false}), false)
|
||||||
|
check("kan stoppe: uden markør men i gang", V.canStart({hasMarker = false, working = true}), true)
|
||||||
print(failures == 0 and "\nALLE TESTS OK" or ("\n" .. failures .. " FEJL"))
|
print(failures == 0 and "\nALLE TESTS OK" or ("\n" .. failures .. " FEJL"))
|
||||||
os.exit(failures == 0 and 0 or 1)
|
os.exit(failures == 0 and 0 or 1)
|
||||||
|
|||||||
Reference in New Issue
Block a user