LUADOC - Farming Simulator 22

Script v1_7_1_0

Engine v1_7_1_0

Foundation Reference

HUDPopupMessage

Description
HUD popup message. Displays a modal popup message which requires a player input to be accepted / dismissed or expires after a given time.
Parent
HUDDisplayElement
Functions

animateHide

Description
Animate this element on showing.
Definition
animateHide()
Code
217function HUDPopupMessage:animateHide()
218 HUDPopupMessage:superClass().animateHide(self)
219
220 g_depthOfFieldManager:popArea()
221 self.blurAreaActive = false
222 self.animation:addCallback(self.finishMessage) -- call finishMessage when animation has completed
223end

assignCurrentMessage

Description
Assign a new current message and adjust display state accordingly. This also resizes the message box according to the required space.
Definition
assignCurrentMessage()
Code
148function HUDPopupMessage:assignCurrentMessage(message)
149 self.time = 0
150 self.currentMessage = message
151
152 local reqHeight = self:getTitleHeight() + self:getTextHeight() + self:getInputRowsHeight()
153 reqHeight = reqHeight + self.borderPaddingY * 2 + self.textOffsetY + self.titleTextSize + self.textSize
154 if #message.controls > 0 then
155 reqHeight = reqHeight + self.inputRowsOffsetY
156 end
157
158 if not g_isServerStreamingVersion then
159 reqHeight = reqHeight + self.skipButtonHeight
160 end
161
162 self:setDimension(self:getWidth(), math.max(self.minHeight, reqHeight))
163 self:updateButtonGlyphs()
164end

createBackground

Description
Create the background overlay.
Definition
createBackground()
Code
469function HUDPopupMessage.createBackground(hudAtlasPath)
470 local posX, posY = HUDPopupMessage.getBackgroundPosition(1)
471 local width, height = getNormalizedScreenValues(unpack(HUDPopupMessage.SIZE.SELF))
472
473 local overlay = Overlay.new(hudAtlasPath, posX - width * 0.5, posY, width, height)
474 overlay:setUVs(GuiUtils.getUVs(HUDPopupMessage.UV.BACKGROUND))
475 overlay:setColor(unpack(HUDPopupMessage.COLOR.BACKGROUND))
476 return overlay
477end

createComponents

Description
Create required display components.
Definition
createComponents()
Code
481function HUDPopupMessage:createComponents(hudAtlasPath)
482 local basePosX, basePosY = self:getPosition()
483 local baseWidth = self:getWidth()
484
485 local _, inputRowHeight = self:scalePixelToScreenVector(HUDPopupMessage.SIZE.INPUT_ROW)
486
487 local posY = basePosY + inputRowHeight -- add one row's height as spacing for the skip button
488 for i = 1, HUDPopupMessage.MAX_INPUT_ROW_COUNT do
489 local buttonRow, inputGlyph
490
491 buttonRow, inputGlyph, posY = self:createInputRow(hudAtlasPath, basePosX, posY)
492 local rowIndex = HUDPopupMessage.MAX_INPUT_ROW_COUNT - i + 1
493 self.inputRows[rowIndex] = buttonRow
494 self.inputGlyphs[rowIndex] = inputGlyph
495 self:addChild(buttonRow)
496 end
497
498 if not g_isServerStreamingVersion then
499 local offX, offY = self:scalePixelToScreenVector(HUDPopupMessage.POSITION.SKIP_BUTTON)
500 local glyphWidth, glyphHeight = self:scalePixelToScreenVector(HUDPopupMessage.SIZE.INPUT_GLYPH)
501 local skipGlyph = InputGlyphElement.new(self.inputDisplayManager, glyphWidth, glyphHeight)
502 skipGlyph:setPosition(basePosX + (baseWidth - glyphWidth) * 0.5 + offX, basePosY - offY)
503 skipGlyph:setAction(InputAction.SKIP_MESSAGE_BOX, self.l10n:getText(HUDPopupMessage.L10N_SYMBOL.BUTTON_OK), self.skipTextSize, true, false)
504
505 self.skipGlyph = skipGlyph
506 self:addChild(skipGlyph)
507 end
508end

createInputRow

Description
Create components for an input button row.
Definition
createInputRow()
Code
512function HUDPopupMessage:createInputRow(hudAtlasPath, posX, posY)
513 local overlay = Overlay.new(hudAtlasPath, posX, posY, self.inputRowWidth, self.inputRowHeight)
514 overlay:setUVs(GuiUtils.getUVs(HUDPopupMessage.UV.BACKGROUND))
515 overlay:setColor(unpack(HUDPopupMessage.COLOR.INPUT_ROW))
516 local buttonPanel = HUDElement.new(overlay)
517
518 local rowHeight = buttonPanel:getHeight()
519
520 local glyphWidth, glyphHeight = self:scalePixelToScreenVector(HUDPopupMessage.SIZE.INPUT_GLYPH)
521 local inputGlyph = InputGlyphElement.new(self.inputDisplayManager, glyphWidth, glyphHeight)
522 local offX, offY = self:scalePixelToScreenVector(HUDPopupMessage.POSITION.INPUT_GLYPH)
523 local glyphX, glyphY = posX + self.borderPaddingX + offX, posY + (rowHeight - glyphHeight) * 0.5 + offY
524 inputGlyph:setPosition(glyphX, glyphY)
525 buttonPanel:addChild(inputGlyph)
526
527 local width, height = self:scalePixelToScreenVector(HUDPopupMessage.SIZE.SEPARATOR)
528 height = math.max(height, HUDPopupMessage.SIZE.SEPARATOR[2] / g_screenHeight)
529 offX, offY = self:scalePixelToScreenVector(HUDPopupMessage.POSITION.SEPARATOR)
530 overlay = Overlay.new(hudAtlasPath, posX + offX, posY + offY, width, height)
531 overlay:setUVs(GuiUtils.getUVs(GameInfoDisplay.UV.SEPARATOR))
532 overlay:setColor(unpack(GameInfoDisplay.COLOR.SEPARATOR))
533 local separator = HUDElement.new(overlay)
534 buttonPanel:addChild(separator)
535
536 return buttonPanel, inputGlyph, posY + rowHeight
537end

draw

Description
Draw the message.
Definition
draw()
Code
366function HUDPopupMessage:draw()
367 if not self.isMenuVisible and self:getVisible() and self.currentMessage ~= nil then
368 HUDPopupMessage:superClass().draw(self)
369
370 local baseX, baseY = self:getPosition()
371 local width, height = self:getWidth(), self:getHeight()
372
373 -- title
374 setTextColor(unpack(HUDPopupMessage.COLOR.TITLE))
375 setTextBold(true)
376 setTextAlignment(RenderText.ALIGN_CENTER)
377 setTextWrapWidth(width - 2 * self.borderPaddingX)
378 local textPosY = baseY + height - self.borderPaddingY
379
380 if self.currentMessage.title ~= "" then
381 local title = utf8ToUpper(self.currentMessage.title)
382 textPosY = textPosY - self.titleTextSize
383 renderText(baseX + width * 0.5, textPosY, self.titleTextSize, title)
384 end
385
386 -- message
387 setTextBold(false)
388 setTextColor(unpack(HUDPopupMessage.COLOR.TEXT))
389 setTextAlignment(RenderText.ALIGN_LEFT)
390 setTextLineHeightScale(HUDPopupMessage.TEXT_LINE_HEIGHT_SCALE)
391 textPosY = textPosY - self.textSize + self.textOffsetY
392 renderText(baseX + self.borderPaddingX, textPosY, self.textSize, self.currentMessage.message)
393 textPosY = textPosY - getTextHeight(self.textSize, self.currentMessage.message)
394
395 -- input rows
396 setTextColor(unpack(HUDPopupMessage.COLOR.SKIP_TEXT))
397 setTextAlignment(RenderText.ALIGN_RIGHT)
398 local posX = baseX + width - self.borderPaddingX
399 local posY = textPosY + self.inputRowsOffsetY - self.inputRowHeight - self.textSize
400 for i = 1, #self.currentMessage.controls do
401 local inputText = self.currentMessage.controls[i].textRight
402 renderText(posX + self.inputRowTextX, posY + self.inputRowTextY, self.textSize, inputText)
403
404 posY = posY - self.inputRowHeight
405 end
406
407 -- reset uncommon text settings:
408 setTextWrapWidth(0)
409 setTextLineHeightScale(RenderText.DEFAULT_LINE_HEIGHT_SCALE)
410 end
411end

finishMessage

Description
Finish displaying a message after it has either elapsed or been acknowledged by the player. Resets display and input state and triggers any provided message callback.
Definition
finishMessage()
Code
239function HUDPopupMessage:finishMessage()
240 self.ingameMap:setAllowToggle(true) -- (re-)enable toggle input on map
241
242 if self.currentMessage ~= nil and self.currentMessage.callback ~= nil then
243 if self.currentMessage.target ~= nil then
244 self.currentMessage.callback(self.currentMessage.target)
245 else
246 self.currentMessage.callback(self)
247 end
248 end
249
250 self.currentMessage = nil
251end

getBackgroundPosition

Description
Get this element's base background position.
Definition
getBackgroundPosition(float uiScale)
Arguments
floatuiScaleCurrent UI scale factor
Code
420function HUDPopupMessage.getBackgroundPosition(uiScale)
421 local offX, offY = getNormalizedScreenValues(unpack(HUDPopupMessage.POSITION.SELF))
422 return 0.5 + offX * uiScale, g_safeFrameOffsetY + offY * uiScale -- bottom center plus offset
423end

getInputRowsHeight

Description
Get the display height of the current message's input rows.
Definition
getInputRowsHeight()
Code
205function HUDPopupMessage:getInputRowsHeight()
206 local height = 0
207 if self.currentMessage ~= nil then
208 -- add one to row count for the skip button
209 height = (#self.currentMessage.controls + 1) * self.inputRowHeight
210 end
211
212 return height
213end

getTextHeight

Description
Get the display height of the current message's text.
Definition
getTextHeight()
Code
187function HUDPopupMessage:getTextHeight()
188 local height = 0
189 if self.currentMessage ~= nil then
190 setTextAlignment(RenderText.ALIGN_LEFT)
191 setTextBold(false)
192 setTextWrapWidth(self:getWidth() - 2 * self.borderPaddingX)
193 setTextLineHeightScale(HUDPopupMessage.TEXT_LINE_HEIGHT_SCALE)
194 height = getTextHeight(self.textSize, self.currentMessage.message)
195
196 setTextWrapWidth(0)
197 setTextLineHeightScale(RenderText.DEFAULT_LINE_HEIGHT_SCALE)
198 end
199
200 return height
201end

getTitleHeight

Description
Get the display height of the current message's title.
Definition
getTitleHeight()
Code
168function HUDPopupMessage:getTitleHeight()
169 local height = 0
170 if self.currentMessage ~= nil then
171 setTextAlignment(RenderText.ALIGN_CENTER)
172 setTextBold(false)
173 setTextWrapWidth(self:getWidth() - 2 * self.borderPaddingX)
174 local title = utf8ToUpper(self.currentMessage.title)
175 local lineHeight, numTitleRows = getTextHeight(self.titleTextSize, title)
176
177 height = numTitleRows * lineHeight
178
179 setTextWrapWidth(0)
180 end
181
182 return height
183end

getVisible

Description
Get this HUD element's visibility.
Definition
getVisible()
Code
126function HUDPopupMessage:getVisible()
127 return HUDPopupMessage:superClass().getVisible(self) and self.currentMessage ~= nil
128end

new

Description
Create a new instance of HUDPopupMessage.
Definition
new(string hudAtlasPath, l10n I18N, inputManager InputBinding, inputDisplayManager InputDisplayManager, ingameMap IngameMap)
Arguments
stringhudAtlasPathPath to the HUD texture atlas
l10nI18Nreference for text localization
inputManagerInputBindingreference for custom input context handling
inputDisplayManagerInputDisplayManagerfor input glyph display
ingameMapIngameMapreference used to notify the map when a message is shown
Return Values
tableHUDPopupMessageinstance
Code
41function HUDPopupMessage.new(hudAtlasPath, l10n, inputManager, inputDisplayManager, ingameMap, guiSoundPlayer)
42 local backgroundOverlay = HUDPopupMessage.createBackground(hudAtlasPath)
43 local self = HUDPopupMessage:superClass().new(backgroundOverlay, nil, HUDPopupMessage_mt)
44
45 self.l10n = l10n
46 self.inputManager = inputManager
47 self.inputDisplayManager = inputDisplayManager
48 self.ingameMap = ingameMap -- in game map reference required to hide the map when showing a message
49 self.guiSoundPlayer = guiSoundPlayer
50
51 self.pendingMessages = {} -- {i={<message as defined in showMessage()>}}, ordered as a queue
52 self.isCustomInputActive = false -- input state flag
53 self.lastInputMode = self.inputManager:getInputHelpMode()
54
55 self.inputRows = {} -- {i=HUDElement}
56 self.inputGlyphs = {} -- {i=InputGlyphElement}, synchronous with self.inputRows
57 self.skipGlyph = nil -- InputGlyphElement
58
59 self.isMenuVisible = false
60 self.time = 0 -- accumulated message display time
61 self.isGamePaused = false -- game paused state
62
63 self:storeScaledValues()
64 self:createComponents(hudAtlasPath)
65
66 return self
67end

onConfirmMessage

Description
Event function for either InputAction.SKIP_MESSAGE_BOX or InputAction.MENU_ACCEPT.
Definition
onConfirmMessage()
Code
349function HUDPopupMessage:onConfirmMessage(actionName, inputValue)
350 if self.animation:getFinished() then -- callbacks are tied to animation, make sure animation is not active
351 self:setVisible(false, true)
352 end
353end

onMenuVisibilityChange

Description
Handle menu visibility changes.
Definition
onMenuVisibilityChange()
Code
141function HUDPopupMessage:onMenuVisibilityChange(isMenuVisible)
142 self.isMenuVisible = isMenuVisible
143end

setDimension

Description
Set this HUD element's width and height.
Definition
setDimension()
Code
439function HUDPopupMessage:setDimension(width, height)
440 HUDPopupMessage:superClass().setDimension(self, width, height)
441end

setInputActive

Description
Enable / disable input events for message confirmation / skipping.
Definition
setInputActive()
Code
329function HUDPopupMessage:setInputActive(isActive)
330 if not self.isCustomInputActive and isActive then
331 self.inputManager:setContext(HUDPopupMessage.INPUT_CONTEXT_NAME, true, false)
332
333 local _, eventId = self.inputManager:registerActionEvent(InputAction.MENU_ACCEPT, self, self.onConfirmMessage, false, true, false, true)
334 self.inputManager:setActionEventTextVisibility(eventId, false)
335
336 _, eventId = self.inputManager:registerActionEvent(InputAction.SKIP_MESSAGE_BOX, self, self.onConfirmMessage, false, true, false, true)
337 self.inputManager:setActionEventTextVisibility(eventId, false)
338
339 self.isCustomInputActive = true
340 elseif self.isCustomInputActive and not isActive then
341 self.inputManager:removeActionEventsByTarget(self)
342 self.inputManager:revertContext(true) -- revert and clear message context
343 self.isCustomInputActive = false
344 end
345end

setScale

Description
Set uniform UI scale.
Definition
setScale()
Code
427function HUDPopupMessage:setScale(uiScale)
428 HUDPopupMessage:superClass().setScale(self, uiScale)
429 self:storeScaledValues()
430
431 -- reposition to middle of the screen, because the scale affects the position from bottom left corner
432 local posX, posY = HUDPopupMessage.getBackgroundPosition(uiScale)
433 local width = self:getWidth()
434 self:setPosition(posX - width * 0.5, posY)
435end

showMessage

Description
Show a new message.
Definition
showMessage(string title, string message, int duration, table controls, function callback, table target)
Arguments
stringtitleTitle text
stringmessageMain message text
intdurationMessage display duration in milliseconds. If set to 0, will cause the message to be displayed for a duration derived from the message length. If set to <0, will cause the message to be displayed for a very long time.
tablecontrols[optional] Array of InputHelpElement instance for input hint row display
functioncallback[optional] Function to be called when the message is acknowledged or expires
tabletarget[optional] Callback target which is passed as the first argument to the given callback function
Code
88function HUDPopupMessage:showMessage(title, text, duration, controls, callback, target)
89 if duration == 0 then -- if no duration indicated, adjust duration according to message length
90 duration = HUDPopupMessage.MIN_DURATION + string.len(text) * HUDPopupMessage.DURATION_PER_CHARACTER
91 elseif duration < 0 then -- a negative duration is adjusted to five minutes ("almost" indefinite)
92 duration = HUDPopupMessage.MAX_DURATION
93 end
94
95 while #self.pendingMessages > HUDPopupMessage.MAX_PENDING_MESSAGE_COUNT do
96 table.remove(self.pendingMessages, 1)
97 end
98
99 local message = {
100 isDialog=false,
101 title=title,
102 message=text,
103 duration=duration,
104 controls=Utils.getNoNil(controls, {}),
105 callback=callback,
106 target=target
107 }
108
109 if #message.controls > HUDPopupMessage.MAX_INPUT_ROW_COUNT then -- truncate
110 for i = #message.controls, HUDPopupMessage.MAX_INPUT_ROW_COUNT + 1, -1 do
111 table.remove(message.controls, i)
112 end
113 end
114
115 table.insert(self.pendingMessages, message)
116end

startMessage

Description
Start displaying a message dequeued from the currently pending messages. Sets all required display and input state.
Definition
startMessage()
Code
228function HUDPopupMessage:startMessage()
229 self.ingameMap:setAllowToggle(false) -- disable toggle input on map
230 self.ingameMap:turnSmall() -- force map size to minimap state
231
232 self:assignCurrentMessage(self.pendingMessages[1])
233 table.remove(self.pendingMessages, 1)
234end

storeScaledValues

Description
Store scaled positioning, size and offset values.
Definition
storeScaledValues()
Code
445function HUDPopupMessage:storeScaledValues()
446 self.minWidth, self.minHeight = self:scalePixelToScreenVector(HUDPopupMessage.SIZE.SELF)
447
448 self.textOffsetX, self.textOffsetY = self:scalePixelToScreenVector(HUDPopupMessage.POSITION.MESSAGE_TEXT)
449 self.inputRowsOffsetX, self.inputRowsOffsetY = self:scalePixelToScreenVector(HUDPopupMessage.POSITION.INPUT_ROWS)
450 self.skipButtonOffsetX, self.skipButtonOffsetY = self:scalePixelToScreenVector(HUDPopupMessage.POSITION.SKIP_BUTTON)
451 self.skipButtonWidth, self.skipButtonHeight = self:scalePixelToScreenVector(HUDPopupMessage.SIZE.SKIP_BUTTON)
452
453 self.inputRowWidth, self.inputRowHeight = self:scalePixelToScreenVector(HUDPopupMessage.SIZE.INPUT_ROW)
454 self.borderPaddingX, self.borderPaddingY = self:scalePixelToScreenVector(HUDPopupMessage.SIZE.BORDER_PADDING)
455
456 self.inputRowTextX, self.inputRowTextY = self:scalePixelToScreenVector(HUDPopupMessage.POSITION.INPUT_TEXT)
457
458 self.titleTextSize = self:scalePixelToScreenHeight(HUDPopupMessage.TEXT_SIZE.TITLE)
459 self.textSize = self:scalePixelToScreenHeight(HUDPopupMessage.TEXT_SIZE.TEXT)
460 self.skipTextSize = self:scalePixelToScreenHeight(HUDPopupMessage.TEXT_SIZE.SKIP_TEXT)
461end

update

Description
Update this element's state.
Definition
update()
Code
259function HUDPopupMessage:update(dt)
260 if not self.isMenuVisible then
261 HUDPopupMessage:superClass().update(self, dt)
262
263 if not self.isGamePaused and not g_sleepManager:getIsSleeping() then
264 self.time = self.time + dt
265 self:updateCurrentMessage()
266 end
267
268 if self:getVisible() then
269 local inputMode = self.inputManager:getInputHelpMode()
270 if inputMode ~= self.lastInputMode then
271 self.lastInputMode = inputMode
272 self:updateButtonGlyphs()
273 end
274 end
275 end
276end

updateButtonGlyphs

Description
Update button glyphs when the player input mode has changed.
Definition
updateButtonGlyphs()
Code
301function HUDPopupMessage:updateButtonGlyphs()
302 if self.skipGlyph ~= nil then
303 self.skipGlyph:setAction(InputAction.SKIP_MESSAGE_BOX, self.l10n:getText(HUDPopupMessage.L10N_SYMBOL.BUTTON_OK), self.skipTextSize, true, false)
304 end
305
306 if self.currentMessage ~= nil then
307 local controlIndex = 1
308 for i = 1, HUDPopupMessage.MAX_INPUT_ROW_COUNT do
309 local rowIndex = HUDPopupMessage.MAX_INPUT_ROW_COUNT - i + 1
310 local inputRowVisible = rowIndex <= #self.currentMessage.controls
311 self.inputRows[i]:setVisible(inputRowVisible)
312
313 if inputRowVisible then
314 local control = self.currentMessage.controls[controlIndex]
315 self.inputGlyphs[i]:setActions(control:getActionNames(), "", self.textSize, false, false)
316 self.inputGlyphs[i]:setKeyboardGlyphColor(HUDPopupMessage.COLOR.INPUT_GLYPH)
317 controlIndex = controlIndex + 1
318 end
319 end
320 end
321end

updateCurrentMessage

Description
Update the current message. Disables this popup when time runs out and dequeues a pending messages for displaying.
Definition
updateCurrentMessage()
Code
281function HUDPopupMessage:updateCurrentMessage()
282 if self.currentMessage ~= nil then
283 if self.time > self.currentMessage.duration then
284 self.time = -math.huge -- clear time to avoid double triggers
285 self:setVisible(false, true) -- animate out
286 end
287 elseif #self.pendingMessages > 0 then
288 self:startMessage()
289 self:setVisible(true, true) -- animate in
290
291 self.animation:addCallback(function()
292 local x, y = self:getPosition()
293 g_depthOfFieldManager:pushArea(x, y, self:getWidth(), self:getHeight())
294 self.blurAreaActive = true
295 end)
296 end
297end