318 | function ContextActionDisplay:createActionIcons(hudAtlasPath, baseX, baseY) |
319 | local posX, posY = getNormalizedScreenValues(unpack(ContextActionDisplay.POSITION.CONTEXT_ICON)) |
320 | local width, height = getNormalizedScreenValues(unpack(ContextActionDisplay.SIZE.CONTEXT_ICON)) |
321 | |
322 | local centerY = baseY + (self:getHeight() - height) * 0.5 + posY |
323 | |
324 | for _, iconName in pairs(ContextActionDisplay.CONTEXT_ICON) do |
325 | local iconOverlay = Overlay.new(hudAtlasPath, baseX + posX, centerY, width, height) |
326 | local uvs = ContextActionDisplay.UV[iconName] |
327 | iconOverlay:setUVs(GuiUtils.getUVs(uvs)) |
328 | iconOverlay:setColor(unpack(ContextActionDisplay.COLOR.CONTEXT_ICON)) |
329 | |
330 | local iconElement = HUDElement.new(iconOverlay) |
331 | iconElement:setVisible(false) |
332 | |
333 | self.contextIconElements[iconName] = iconElement |
334 | self:addChild(iconElement) |
335 | end |
336 | end |
279 | function ContextActionDisplay:createComponents(hudAtlasPath, inputDisplayManager) |
280 | local baseX, baseY = self:getPosition() |
281 | self:createFrame(hudAtlasPath, baseX, baseY) |
282 | self:createInputGlyph(hudAtlasPath, baseX, baseY, inputDisplayManager) |
283 | self:createActionIcons(hudAtlasPath, baseX, baseY) |
284 | |
285 | self:createFadeBackground(hudAtlasPath) |
286 | |
287 | |
288 | self:storeOriginalPosition() |
289 | end |
293 | function ContextActionDisplay:createInputGlyph(hudAtlasPath, baseX, baseY, inputDisplayManager) |
294 | local width, height = getNormalizedScreenValues(unpack(ContextActionDisplay.SIZE.INPUT_ICON)) |
295 | local offX, offY = getNormalizedScreenValues(unpack(ContextActionDisplay.POSITION.INPUT_ICON)) |
296 | local element = InputGlyphElement.new(inputDisplayManager, width, height) |
297 | |
298 | local posX, posY = baseX + offX, baseY + offY + (self:getHeight() - height) * 0.5 |
299 | |
300 | element:setPosition(posX, posY) |
301 | element:setKeyboardGlyphColor(ContextActionDisplay.COLOR.INPUT_ICON) |
302 | |
303 | self.inputGlyphElement = element |
304 | self:addChild(element) |
305 | end |
165 | function ContextActionDisplay:draw() |
166 | if self.contextAction ~= "" and self.contextEventHelpElement ~= nil then |
167 | self.inputGlyphElement:setAction(self.contextAction) -- updates input mode and glyphs if necessary |
168 | |
169 | ContextActionDisplay:superClass().draw(self) |
170 | local _, baseY = self:getPosition() |
171 | |
172 | setTextColor(unpack(ContextActionDisplay.COLOR.ACTION_TEXT)) |
173 | setTextBold(true) |
174 | setTextAlignment(RenderText.ALIGN_LEFT) |
175 | |
176 | local height = self:getHeight() |
177 | |
178 | local posX, posY = self.rightSideX, baseY + height * 0.5 + self.targetTextSize * 0.5 + self.actionTextOffsetY |
179 | renderText(posX, posY, self.actionTextSize, self.actionText) |
180 | |
181 | posY = baseY + height * 0.5 |
182 | |
183 | setTextColor(unpack(ContextActionDisplay.COLOR.TARGET_TEXT)) |
184 | setTextBold(false) |
185 | |
186 | local width = self:getWidth() |
187 | local textWrapWidth = width - self.targetTextOffsetX - self.contextIconSizeX - self.inputGlyphElement:getWidth() * 2 - self.contextIconOffsetX |
188 | |
189 | setTextVerticalAlignment(RenderText.VERTICAL_ALIGN_MIDDLE) |
190 | setTextAlignment(RenderText.ALIGN_CENTER) |
191 | renderText(0.5, posY, self.targetTextSize, self.targetText) |
192 | |
193 | setTextVerticalAlignment(RenderText.VERTICAL_ALIGN_BASELINE) |
194 | |
195 | if g_uiDebugEnabled then |
196 | local yPixel = 1 / g_screenHeight |
197 | setOverlayColor(GuiElement.debugOverlay, 0, 1, 1, 1) |
198 | renderOverlay(GuiElement.debugOverlay, posX, posY, textWrapWidth, yPixel) |
199 | end |
200 | end |
201 | end |
31 | function ContextActionDisplay.new(hudAtlasPath, inputDisplayManager) |
32 | local backgroundOverlay = ContextActionDisplay.createBackground() |
33 | local self = ContextActionDisplay:superClass().new(backgroundOverlay, nil, ContextActionDisplay_mt) |
34 | |
35 | self.uiScale = 1.0 |
36 | self.inputDisplayManager = inputDisplayManager |
37 | |
38 | self.inputGlyphElement = nil |
39 | |
40 | self.contextIconElements = {} |
41 | self.contextAction = "" |
42 | self.contextIconName = "" |
43 | self.targetText = "" |
44 | self.actionText = "" |
45 | self.contextPriority = -math.huge |
46 | |
47 | self.contextIconElementRightX = 0 |
48 | self.contextIconOffsetX, self.contextIconOffsetY = 0, 0 |
49 | self.contextIconSizeX = 0 |
50 | self.actionTextOffsetX, self.actionTextOffsetY = 0, 0 |
51 | self.actionTextSize = 0 |
52 | self.targetTextOffsetX, self.targetTextOffsetY = 0, 0 |
53 | self.targetTextSize = 0 |
54 | self.borderOffsetX = 0 |
55 | |
56 | self.displayTime = 0 |
57 | |
58 | self:createComponents(hudAtlasPath, inputDisplayManager) |
59 | |
60 | return self |
61 | end |
72 | function ContextActionDisplay:setContext(contextAction, contextIconName, targetText, priority, actionText) |
73 | if priority == nil then |
74 | priority = 0 |
75 | end |
76 | |
77 | if priority >= self.contextPriority and self.contextIconElements[contextIconName] ~= nil then |
78 | self.contextAction = contextAction |
79 | self.contextIconName = contextIconName |
80 | self.targetText = targetText |
81 | self.contextPriority = priority |
82 | |
83 | local eventHelpElement = self.inputDisplayManager:getEventHelpElementForAction(self.contextAction) |
84 | self.contextEventHelpElement = eventHelpElement |
85 | |
86 | if eventHelpElement ~= nil then |
87 | self.inputGlyphElement:setAction(contextAction) |
88 | self.actionText = utf8ToUpper(actionText or eventHelpElement.textRight or eventHelpElement.textLeft) |
89 | |
90 | |
91 | -- Position directly left of the target text. We center this text so we use the position |
92 | -- to determine icon position |
93 | local targetTextWidth = getTextWidth(self.targetTextSize, self.targetText) |
94 | self.rightSideX = 0.5 - targetTextWidth * 0.5 |
95 | |
96 | |
97 | local contextIconWidth = 0 |
98 | |
99 | local posX = self.rightSideX + self.contextIconOffsetX |
100 | for name, element in pairs(self.contextIconElements) do |
101 | element:setPosition(posX - element:getWidth(), nil) -- no change to Y position |
102 | |
103 | if name == self.contextIconName then |
104 | contextIconWidth = element:getWidth() |
105 | end |
106 | end |
107 | |
108 | posX = posX - self.inputGlyphElement:getWidth() + self.inputIconOffsetX - contextIconWidth |
109 | self.inputGlyphElement:setPosition(posX, nil) |
110 | end |
111 | |
112 | if not self:getVisible() then |
113 | self:setVisible(true, true) |
114 | end |
115 | end |
116 | |
117 | for name, element in pairs(self.contextIconElements) do |
118 | element:setVisible(name == self.contextIconName) |
119 | end |
120 | |
121 | -- always refresh display time: |
122 | self.displayTime = ContextActionDisplay.MIN_DISPLAY_DURATION |
123 | end |
213 | function ContextActionDisplay:setScale(uiScale) |
214 | ContextActionDisplay:superClass().setScale(self, uiScale, uiScale) |
215 | |
216 | local currentVisibility = self:getVisible() |
217 | self:setVisible(true, false) |
218 | |
219 | self.uiScale = uiScale |
220 | local posX, posY = ContextActionDisplay.getBackgroundPosition(uiScale, self:getWidth()) |
221 | self:setPosition(posX, posY) |
222 | |
223 | self:storeOriginalPosition() |
224 | self:setVisible(currentVisibility, false) |
225 | |
226 | self:storeScaledValues() |
227 | |
228 | -- Special case because this display needs to cover the whole width at all times |
229 | self.fadeBackgroundElement:setDimension(1) |
230 | self.fadeBackgroundElement:setPosition(0, 0) |
231 | end |
235 | function ContextActionDisplay:storeScaledValues() |
236 | self.contextIconOffsetX, self.contextIconOffsetY = self:scalePixelToScreenVector(ContextActionDisplay.POSITION.CONTEXT_ICON) |
237 | self.contextIconSizeX = self:scalePixelToScreenWidth(ContextActionDisplay.SIZE.CONTEXT_ICON[1]) |
238 | self.borderOffsetX = self:scalePixelToScreenWidth(ContextActionDisplay.OFFSET.X) |
239 | |
240 | self.inputIconOffsetX, self.inputIconOffsetX = self:scalePixelToScreenVector(ContextActionDisplay.POSITION.INPUT_ICON) |
241 | |
242 | self.actionTextOffsetX, self.actionTextOffsetY = self:scalePixelToScreenVector(ContextActionDisplay.POSITION.ACTION_TEXT) |
243 | self.actionTextSize = self:scalePixelToScreenHeight(ContextActionDisplay.TEXT_SIZE.ACTION_TEXT) |
244 | |
245 | self.targetTextOffsetX, self.targetTextOffsetY = self:scalePixelToScreenVector(ContextActionDisplay.POSITION.TARGET_TEXT) |
246 | self.targetTextSize = self:scalePixelToScreenHeight(ContextActionDisplay.TEXT_SIZE.TARGET_TEXT) |
247 | end |
131 | function ContextActionDisplay:update(dt) |
132 | ContextActionDisplay:superClass().update(self, dt) |
133 | |
134 | self.displayTime = self.displayTime - dt |
135 | local isVisible = self:getVisible() |
136 | |
137 | if self.displayTime <= 0 and isVisible and self.animation:getFinished() then |
138 | self:setVisible(false, true) |
139 | end |
140 | |
141 | if not self.animation:getFinished() then |
142 | self:storeScaledValues() |
143 | elseif self.contextAction ~= "" and not isVisible then |
144 | self:resetContext() -- reset context data when move-out animation has finished |
145 | end |
146 | end |