LUADOC - Farming Simulator 19

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
202function HUDPopupMessage:animateHide()
203 HUDPopupMessage:superClass().animateHide(self)
204
205 self.animation:addCallback(self.finishMessage) -- call finishMessage when animation has completed
206end

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
133function HUDPopupMessage:assignCurrentMessage(message)
134 self.time = 0
135 self.currentMessage = message
136
137 local reqHeight = self:getTitleHeight() + self:getTextHeight() + self:getInputRowsHeight()
138 reqHeight = reqHeight + self.borderPaddingY * 2 + self.textOffsetY + self.titleTextSize + self.textSize
139 if #message.controls > 0 then
140 reqHeight = reqHeight + self.inputRowsOffsetY
141 end
142
143 if not g_isServerStreamingVersion then
144 reqHeight = reqHeight + self.skipButtonHeight
145 end
146
147 self:setDimension(self:getWidth(), math.max(self.minHeight, reqHeight))
148 self:updateButtonGlyphs()
149end

createBackground

Description
Create the background overlay.
Definition
createBackground()
Code
445function HUDPopupMessage.createBackground(hudAtlasPath)
446 local posX, posY = HUDPopupMessage.getBackgroundPosition(1)
447 local width, height = getNormalizedScreenValues(unpack(HUDPopupMessage.SIZE.SELF))
448
449 local overlay = Overlay:new(hudAtlasPath, posX - width * 0.5, posY, width, height)
450 overlay:setUVs(getNormalizedUVs(HUDPopupMessage.UV.BACKGROUND))
451 overlay:setColor(unpack(HUDPopupMessage.COLOR.BACKGROUND))
452 return overlay
453end

createComponents

Description
Create required display components.
Definition
createComponents()
Code
457function HUDPopupMessage:createComponents(hudAtlasPath)
458 local basePosX, basePosY = self:getPosition()
459 local baseWidth, baseHeight = self:getWidth(), self:getHeight()
460
461 local frame = HUDFrameElement:new(hudAtlasPath, basePosX, basePosY, baseWidth, baseHeight)
462 self.frameElement = frame
463 self:addChild(frame)
464
465 local _, inputRowHeight = self:scalePixelToScreenVector(HUDPopupMessage.SIZE.INPUT_ROW)
466
467 local posY = basePosY + inputRowHeight -- add one row's height as spacing for the skip button
468 local buttonRow, inputGlyph = nil, nil
469 for i = 1, HUDPopupMessage.MAX_INPUT_ROW_COUNT do
470 buttonRow, inputGlyph, posY = self:createInputRow(hudAtlasPath, basePosX, posY)
471 local rowIndex = HUDPopupMessage.MAX_INPUT_ROW_COUNT - i + 1
472 self.inputRows[rowIndex] = buttonRow
473 self.inputGlyphs[rowIndex] = inputGlyph
474 self:addChild(buttonRow)
475 end
476
477 if not g_isServerStreamingVersion then
478 local offX, offY = self:scalePixelToScreenVector(HUDPopupMessage.POSITION.SKIP_BUTTON)
479 local glyphWidth, glyphHeight = self:scalePixelToScreenVector(HUDPopupMessage.SIZE.INPUT_GLYPH)
480 local skipGlyph = InputGlyphElement:new(self.inputDisplayManager, glyphWidth, glyphHeight)
481 skipGlyph:setPosition(basePosX + (baseWidth - glyphWidth) * 0.5 + offX, basePosY - offY)
482 skipGlyph:setAction(InputAction.SKIP_MESSAGE_BOX, self.l10n:getText(HUDPopupMessage.L10N_SYMBOL.BUTTON_OK), self.skipTextSize, true, false)
483
484 self.skipGlyph = skipGlyph
485 self:addChild(skipGlyph)
486 end
487end

createInputRow

Description
Create components for an input button row.
Definition
createInputRow()
Code
491function HUDPopupMessage:createInputRow(hudAtlasPath, posX, posY)
492 local overlay = Overlay:new(hudAtlasPath, posX, posY, self.inputRowWidth, self.inputRowHeight)
493 overlay:setUVs(getNormalizedUVs(HUDPopupMessage.UV.BACKGROUND))
494 overlay:setColor(unpack(HUDPopupMessage.COLOR.INPUT_ROW))
495 local buttonPanel = HUDElement:new(overlay)
496
497 local rowHeight = buttonPanel:getHeight()
498
499 local glyphWidth, glyphHeight = self:scalePixelToScreenVector(HUDPopupMessage.SIZE.INPUT_GLYPH)
500 local inputGlyph = InputGlyphElement:new(self.inputDisplayManager, glyphWidth, glyphHeight)
501 local offX, offY = self:scalePixelToScreenVector(HUDPopupMessage.POSITION.INPUT_GLYPH)
502 local glyphX, glyphY = posX + self.borderPaddingX + offX, posY + (rowHeight - glyphHeight) * 0.5 + offY
503 inputGlyph:setPosition(glyphX, glyphY)
504 buttonPanel:addChild(inputGlyph)
505
506 local width, height = self:scalePixelToScreenVector(HUDPopupMessage.SIZE.SEPARATOR)
507 height = math.max(height, HUDPopupMessage.SIZE.SEPARATOR[2] / g_screenHeight)
508 local offX, offY = self:scalePixelToScreenVector(HUDPopupMessage.POSITION.SEPARATOR)
509 overlay = Overlay:new(hudAtlasPath, posX + offX, posY + offY, width, height)
510 overlay:setUVs(getNormalizedUVs(GameInfoDisplay.UV.SEPARATOR))
511 overlay:setColor(unpack(GameInfoDisplay.COLOR.SEPARATOR))
512 local separator = HUDElement:new(overlay)
513 buttonPanel:addChild(separator)
514
515 return buttonPanel, inputGlyph, posY + rowHeight
516end

draw

Description
Draw the message.
Definition
draw()
Code
340function HUDPopupMessage:draw()
341 if not self.isMenuVisible and self:getVisible() and self.currentMessage ~= nil then
342 HUDPopupMessage:superClass().draw(self)
343
344 local baseX, baseY = self:getPosition()
345 local width, height = self:getWidth(), self:getHeight()
346
347 -- title
348 setTextColor(unpack(HUDPopupMessage.COLOR.TITLE))
349 setTextBold(true)
350 setTextAlignment(RenderText.ALIGN_CENTER)
351 setTextWrapWidth(width - 2 * self.borderPaddingX)
352 local textPosY = baseY + height - self.borderPaddingY
353
354 if self.currentMessage.title ~= "" then
355 local title = utf8ToUpper(self.currentMessage.title)
356 textPosY = textPosY - self.titleTextSize
357 renderText(baseX + width * 0.5, textPosY, self.titleTextSize, title)
358 end
359
360 -- message
361 setTextBold(false)
362 setTextColor(unpack(HUDPopupMessage.COLOR.TEXT))
363 setTextAlignment(RenderText.ALIGN_LEFT)
364 setTextLineHeightScale(HUDPopupMessage.TEXT_LINE_HEIGHT_SCALE)
365 textPosY = textPosY - self.textSize + self.textOffsetY
366 renderText(baseX + self.borderPaddingX, textPosY, self.textSize, self.currentMessage.message)
367 textPosY = textPosY - getTextHeight(self.textSize, self.currentMessage.message)
368
369 -- input rows
370 setTextColor(unpack(HUDPopupMessage.COLOR.SKIP_TEXT))
371 setTextAlignment(RenderText.ALIGN_RIGHT)
372 local posX = baseX + width - self.borderPaddingX
373 local posY = textPosY + self.inputRowsOffsetY - self.inputRowHeight - self.textSize
374 for i = 1, #self.currentMessage.controls do
375 local inputText = self.currentMessage.controls[i].textRight
376 local offX, offY = self.inputRowTextX, self.inputRowTextY
377 renderText(posX + self.inputRowTextX, posY + self.inputRowTextY, self.textSize, inputText)
378
379 posY = posY - self.inputRowHeight
380 end
381
382 -- reset uncommon text settings:
383 setTextWrapWidth(0)
384 setTextLineHeightScale(RenderText.DEFAULT_LINE_HEIGHT_SCALE)
385 end
386end

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
223function HUDPopupMessage:finishMessage()
224 self:setInputActive(false) -- make sure we aren't blocking input anymore
225 self.ingameMap:setAllowToggle(true) -- (re-)enable toggle input on map
226
227 if self.currentMessage ~= nil and self.currentMessage.callback ~= nil then
228 if self.currentMessage.target ~= nil then
229 self.currentMessage.callback(self.currentMessage.target)
230 else
231 self.currentMessage.callback(self)
232 end
233 end
234
235 self.currentMessage = nil
236end

getBackgroundPosition

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

getInputRowsHeight

Description
Get the display height of the current message's input rows.
Definition
getInputRowsHeight()
Code
190function HUDPopupMessage:getInputRowsHeight()
191 local height = 0
192 if self.currentMessage ~= nil then
193 -- add one to row count for the skip button
194 height = (#self.currentMessage.controls + 1) * self.inputRowHeight
195 end
196
197 return height
198end

getTextHeight

Description
Get the display height of the current message's text.
Definition
getTextHeight()
Code
172function HUDPopupMessage:getTextHeight()
173 local height = 0
174 if self.currentMessage ~= nil then
175 setTextAlignment(RenderText.ALIGN_LEFT)
176 setTextBold(false)
177 setTextWrapWidth(self:getWidth() - 2 * self.borderPaddingX)
178 setTextLineHeightScale(HUDPopupMessage.TEXT_LINE_HEIGHT_SCALE)
179 height = getTextHeight(self.textSize, self.currentMessage.message)
180
181 setTextWrapWidth(0)
182 setTextLineHeightScale(RenderText.DEFAULT_LINE_HEIGHT_SCALE)
183 end
184
185 return height
186end

getTitleHeight

Description
Get the display height of the current message's title.
Definition
getTitleHeight()
Code
153function HUDPopupMessage:getTitleHeight()
154 local height = 0
155 if self.currentMessage ~= nil then
156 setTextAlignment(RenderText.ALIGN_CENTER)
157 setTextBold(false)
158 setTextWrapWidth(self:getWidth() - 2 * self.borderPaddingX)
159 local title = utf8ToUpper(self.currentMessage.title)
160 local lineHeight, numTitleRows = getTextHeight(self.titleTextSize, title)
161
162 height = numTitleRows * lineHeight
163
164 setTextWrapWidth(0)
165 end
166
167 return height
168end

getVisible

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

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(HUDPopupMessage_mt, backgroundOverlay, nil)
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 self.frameElement = nil -- FrameElement
59
60 self.isMenuVisible = false
61 self.time = 0 -- accumulated message display time
62 self.isGamePaused = false -- game paused state
63
64 self:storeScaledValues()
65 self:createComponents(hudAtlasPath)
66
67 return self
68end

onConfirmMessage

Description
Event function for either InputAction.SKIP_MESSAGE_BOX or InputAction.MENU_ACCEPT.
Definition
onConfirmMessage()
Code
328function HUDPopupMessage:onConfirmMessage(actionName, inputValue)
329 if self.animation:getFinished() then -- callbacks are tied to animation, make sure animation is not active
330 self:setVisible(false, true)
331 end
332end

onMenuVisibilityChange

Description
Handle menu visibility changes.
Definition
onMenuVisibilityChange()
Code
126function HUDPopupMessage:onMenuVisibilityChange(isMenuVisible)
127 self.isMenuVisible = isMenuVisible
128end

setDimension

Description
Set this HUD element's width and height.
Definition
setDimension()
Code
414function HUDPopupMessage:setDimension(width, height)
415 HUDPopupMessage:superClass().setDimension(self, width, height)
416 self.frameElement:setDimension(width, height)
417end

setInputActive

Description
Enable / disable input events for message confirmation / skipping.
Definition
setInputActive()
Code
308function HUDPopupMessage:setInputActive(isActive)
309 if not self.isCustomInputActive and isActive then
310 self.inputManager:setContext(HUDPopupMessage.INPUT_CONTEXT_NAME, true, false)
311
312 local _, eventId = self.inputManager:registerActionEvent(InputAction.MENU_ACCEPT, self, self.onConfirmMessage, false, true, false, true)
313 self.inputManager:setActionEventTextVisibility(eventId, false)
314
315 _, eventId = self.inputManager:registerActionEvent(InputAction.SKIP_MESSAGE_BOX, self, self.onConfirmMessage, false, true, false, true)
316 self.inputManager:setActionEventTextVisibility(eventId, false)
317
318 self.isCustomInputActive = true
319 elseif self.isCustomInputActive and not isActive then
320 self.inputManager:removeActionEventsByTarget(self)
321 self.inputManager:revertContext(true) -- revert and clear message context
322 self.isCustomInputActive = false
323 end
324end

setScale

Description
Set uniform UI scale.
Definition
setScale()
Code
402function HUDPopupMessage:setScale(uiScale)
403 HUDPopupMessage:superClass().setScale(self, uiScale)
404 self:storeScaledValues()
405
406 -- reposition to middle of the screen, because the scale affects the position from bottom left corner
407 local posX, posY = HUDPopupMessage.getBackgroundPosition(uiScale)
408 local width = self:getWidth()
409 self:setPosition(posX - width * 0.5, posY)
410end

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
80function HUDPopupMessage:showMessage(title, message, duration, controls, callback, target)
81 if duration == 0 then -- if no duration indicated, adjust duration according to message length
82 duration = HUDPopupMessage.MIN_DURATION + string.len(message) * HUDPopupMessage.DURATION_PER_CHARACTER
83 elseif duration < 0 then -- a negative duration is adjusted to five minutes ("almost" indefinite)
84 duration = HUDPopupMessage.MAX_DURATION
85 end
86
87 while #self.pendingMessages > HUDPopupMessage.MAX_PENDING_MESSAGE_COUNT do
88 table.remove(self.pendingMessages, 1)
89 end
90
91 local message = {isDialog=false, title=title, message=message, duration=duration,
92 controls=Utils.getNoNil(controls, {}), callback=callback, target=target}
93
94 if #message.controls > HUDPopupMessage.MAX_INPUT_ROW_COUNT then -- truncate
95 for i = #message.controls, HUDPopupMessage.MAX_INPUT_ROW_COUNT + 1, -1 do
96 table.remove(message.controls, i)
97 end
98 end
99
100 table.insert(self.pendingMessages, message)
101end

startMessage

Description
Start displaying a message dequeued from the currently pending messages. Sets all required display and input state.
Definition
startMessage()
Code
211function HUDPopupMessage:startMessage()
212 self.ingameMap:setAllowToggle(false) -- disable toggle input on map
213 self.ingameMap:toggleSize(IngameMap.STATE_MINIMAP, true) -- force map size to minimap state
214
215 self:assignCurrentMessage(self.pendingMessages[1])
216 table.remove(self.pendingMessages, 1)
217 self:setInputActive(true)
218end

storeScaledValues

Description
Store scaled positioning, size and offset values.
Definition
storeScaledValues()
Code
421function HUDPopupMessage:storeScaledValues()
422 self.minWidth, self.minHeight = self:scalePixelToScreenVector(HUDPopupMessage.SIZE.SELF)
423
424 self.textOffsetX, self.textOffsetY = self:scalePixelToScreenVector(HUDPopupMessage.POSITION.MESSAGE_TEXT)
425 self.inputRowsOffsetX, self.inputRowsOffsetY = self:scalePixelToScreenVector(HUDPopupMessage.POSITION.INPUT_ROWS)
426 self.skipButtonOffsetX, self.skipButtonOffsetY = self:scalePixelToScreenVector(HUDPopupMessage.POSITION.SKIP_BUTTON)
427 self.skipButtonWidth, self.skipButtonHeight = self:scalePixelToScreenVector(HUDPopupMessage.SIZE.SKIP_BUTTON)
428
429 self.inputRowWidth, self.inputRowHeight = self:scalePixelToScreenVector(HUDPopupMessage.SIZE.INPUT_ROW)
430 self.borderPaddingX, self.borderPaddingY = self:scalePixelToScreenVector(HUDPopupMessage.SIZE.BORDER_PADDING)
431
432 self.inputRowTextX, self.inputRowTextY = self:scalePixelToScreenVector(HUDPopupMessage.POSITION.INPUT_TEXT)
433
434 self.titleTextSize = self:scalePixelToScreenHeight(HUDPopupMessage.TEXT_SIZE.TITLE)
435 self.textSize = self:scalePixelToScreenHeight(HUDPopupMessage.TEXT_SIZE.TEXT)
436 self.skipTextSize = self:scalePixelToScreenHeight(HUDPopupMessage.TEXT_SIZE.SKIP_TEXT)
437end

update

Description
Update this element's state.
Definition
update()
Code
244function HUDPopupMessage:update(dt)
245 if not self.isMenuVisible then
246 HUDPopupMessage:superClass().update(self, dt)
247
248 if not self.isGamePaused then
249 self.time = self.time + dt
250 self:updateCurrentMessage()
251 end
252
253 if self:getVisible() then
254 local inputMode = self.inputManager:getInputHelpMode()
255 if inputMode ~= self.lastInputMode then
256 self.lastInputMode = inputMode
257 self:updateButtonGlyphs()
258 end
259 end
260 end
261end

updateButtonGlyphs

Description
Update button glyphs when the player input mode has changed.
Definition
updateButtonGlyphs()
Code
280function HUDPopupMessage:updateButtonGlyphs()
281 if self.skipGlyph ~= nil then
282 self.skipGlyph:setAction(InputAction.SKIP_MESSAGE_BOX, self.l10n:getText(HUDPopupMessage.L10N_SYMBOL.BUTTON_OK), self.skipTextSize, true, false)
283 end
284
285 if self.currentMessage ~= nil then
286 local controlIndex = 1
287 for i = 1, HUDPopupMessage.MAX_INPUT_ROW_COUNT do
288 local rowIndex = HUDPopupMessage.MAX_INPUT_ROW_COUNT - i + 1
289 local inputRowVisible = rowIndex <= #self.currentMessage.controls
290 self.inputRows[i]:setVisible(inputRowVisible)
291
292 if inputRowVisible then
293 local control = self.currentMessage.controls[controlIndex]
294 self.inputGlyphs[i]:setActions(control:getActionNames(), "", self.textSize, false, false)
295 self.inputGlyphs[i]:setKeyboardGlyphColor(HUDPopupMessage.COLOR.INPUT_GLYPH)
296 controlIndex = controlIndex + 1
297 end
298 end
299 end
300end

updateCurrentMessage

Description
Update the current message. Disables this popup when time runs out and dequeues a pending messages for displaying.
Definition
updateCurrentMessage()
Code
266function HUDPopupMessage:updateCurrentMessage()
267 if self.currentMessage ~= nil then
268 if self.time > self.currentMessage.duration then
269 self.time = -math.huge -- clear time to avoid double triggers
270 self:setVisible(false, true) -- animate out
271 end
272 elseif #self.pendingMessages > 0 then
273 self:startMessage()
274 self:setVisible(true, true) -- animate in
275 end
276end