69 | function FillLevelsDisplay:addFillLevel(fillType, fillLevel, capacity, precision, maxReached) |
70 | local added = false |
71 | for j=1, #self.fillLevelBuffer do |
72 | local fillLevelInformation = self.fillLevelBuffer[j] |
73 | if fillLevelInformation.fillType == fillType then |
74 | fillLevelInformation.fillLevel = fillLevelInformation.fillLevel + fillLevel |
75 | fillLevelInformation.capacity = fillLevelInformation.capacity + capacity |
76 | fillLevelInformation.precision = precision |
77 | fillLevelInformation.maxReached = maxReached |
78 | |
79 | if self.addIndex ~= fillLevelInformation.addIndex then |
80 | fillLevelInformation.addIndex = self.addIndex |
81 | self.needsSorting = true |
82 | end |
83 | |
84 | added = true |
85 | break |
86 | end |
87 | end |
88 | |
89 | if not added then |
90 | table.insert(self.fillLevelBuffer, {fillType=fillType, fillLevel=fillLevel, capacity=capacity, precision=precision, addIndex=self.addIndex, maxReached=maxReached}) |
91 | self.needsSorting = true |
92 | end |
93 | |
94 | self.addIndex = self.addIndex + 1 |
95 | end |
391 | function FillLevelsDisplay:createFillTypeBar(hudAtlasPath, frame, baseX, baseY, fillType) |
392 | local width, height = getNormalizedScreenValues(unpack(FillLevelsDisplay.SIZE.BAR)) |
393 | local barX, barY = getNormalizedScreenValues(unpack(FillLevelsDisplay.POSITION.BAR)) |
394 | local posX, posY = baseX + barX, baseY + barY |
395 | |
396 | local element = HUDRoundedBarElement.new(hudAtlasPath, posX, posY, width, height, true) |
397 | element:setBarColor(unpack(FillLevelsDisplay.COLOR.BAR_FILLED)) |
398 | |
399 | frame:addChild(element) |
400 | |
401 | -- store the fill bar for scaling with fill level |
402 | self.fillTypeLevelBars[fillType.index] = element |
403 | end |
331 | function FillLevelsDisplay:createFillTypeFrame(hudAtlasPath, baseX, baseY, fillType) |
332 | local frameWidth, frameHeight = self:scalePixelToScreenVector(FillLevelsDisplay.SIZE.FILL_TYPE_FRAME) |
333 | local frameX, frameY = self:scalePixelToScreenVector(FillLevelsDisplay.POSITION.FILL_TYPE_FRAME) |
334 | |
335 | local posX, posY = baseX + frameX, baseY + frameY |
336 | |
337 | local frameOverlay = Overlay.new(nil, posX, posY, frameWidth, frameHeight) |
338 | local frame = HUDElement.new(frameOverlay) |
339 | frame:setVisible(false) |
340 | |
341 | self:createFillTypeIcon(frame, posX, posY, fillType) |
342 | self:createFillTypeBar(hudAtlasPath, frame, posX, posY, fillType) |
343 | |
344 | |
345 | -- Icon for showing max weight has been reached |
346 | local weightWidth, weightHeight = getNormalizedScreenValues(unpack(FillLevelsDisplay.SIZE.WEIGHT_LIMIT)) |
347 | local weightOffsetX, weightOffsetY = getNormalizedScreenValues(unpack(FillLevelsDisplay.POSITION.WEIGHT_LIMIT)) |
348 | local weightOverlay = Overlay.new(hudAtlasPath, posX + weightOffsetX, posY + weightOffsetY, weightWidth, weightHeight) |
349 | weightOverlay:setUVs(GuiUtils.getUVs(FillLevelsDisplay.UV.WEIGHT_LIMIT)) |
350 | |
351 | local weightFrame = HUDElement.new(weightOverlay) |
352 | frame:addChild(weightFrame) |
353 | |
354 | self.weightFrames[fillType.index] = weightFrame |
355 | |
356 | return frame |
357 | end |
361 | function FillLevelsDisplay:createFillTypeIcon(frame, baseX, baseY, fillType) |
362 | if fillType.hudOverlayFilename ~= "" then |
363 | local baseWidth = self:getWidth() |
364 | local width, height = getNormalizedScreenValues(unpack(FillLevelsDisplay.SIZE.FILL_TYPE_ICON)) |
365 | local posX, posY = getNormalizedScreenValues(unpack(FillLevelsDisplay.POSITION.FILL_TYPE_ICON)) |
366 | |
367 | |
368 | -- local backdropOverlay = Overlay.new(self.hudAtlasPath, baseX + baseWidth - width + posX , baseY + posY, width, height) |
369 | local backdropOverlay = Overlay.new(self.hudAtlasPath, baseX + posX , baseY + posY, width, height) |
370 | backdropOverlay:setColor(unpack(FillLevelsDisplay.COLOR.FILL_TYPE_BACKDROP)) |
371 | backdropOverlay:setUVs(GuiUtils.getUVs(FillLevelsDisplay.UV.FILL_ICON_BACKDROP)) |
372 | |
373 | local backdrop = HUDElement.new(backdropOverlay) |
374 | frame:addChild(backdrop) |
375 | |
376 | local iconOverlay = Overlay.new(fillType.hudOverlayFilename, baseX + posX , baseY + posY, width, height) |
377 | iconOverlay:setColor(unpack(FillLevelsDisplay.COLOR.FILL_TYPE_ICON)) |
378 | |
379 | backdrop:addChild(HUDElement.new(iconOverlay)) |
380 | end |
381 | end |
208 | function FillLevelsDisplay:draw() |
209 | FillLevelsDisplay:superClass().draw(self) |
210 | |
211 | if self:getVisible() then |
212 | local baseX, baseY = self:getPosition() |
213 | local width = self:getWidth() |
214 | |
215 | for i = 1, #self.fillLevelTextBuffer do |
216 | local fillLevelText = self.fillLevelTextBuffer[i] |
217 | |
218 | local posX = baseX + width + self.fillLevelTextOffsetX |
219 | local posY = baseY + (i - 1) * (self.frameHeight + self.frameOffsetY) |
220 | if i == 1 then |
221 | posX = posX + self.firstFillTypeOffset |
222 | end |
223 | |
224 | setTextColor(unpack(FillLevelsDisplay.COLOR.FILL_LEVEL_TEXT)) |
225 | setTextBold(false) |
226 | setTextAlignment(RenderText.ALIGN_RIGHT) |
227 | |
228 | renderText(posX, posY + self.fillLevelTextOffsetY, self.fillLevelTextSize, fillLevelText) |
229 | |
230 | -- if self.fillTypeTextBuffer[i] ~= nil then |
231 | -- renderText(posX, posY + self.fillTypeTextOffsetY, self.fillLevelTextSize, self.fillTypeTextBuffer[i]) |
232 | -- end |
233 | end |
234 | end |
235 | end |
18 | function FillLevelsDisplay.new(hudAtlasPath) |
19 | local backgroundOverlay = FillLevelsDisplay.createBackground() |
20 | local self = FillLevelsDisplay:superClass().new(backgroundOverlay, nil, FillLevelsDisplay_mt) |
21 | |
22 | self.uiScale = 1.0 |
23 | self.hudAtlasPath = hudAtlasPath |
24 | |
25 | self.vehicle = nil -- currently controlled vehicle |
26 | self.fillLevelBuffer = {} |
27 | self.fillLevelTextBuffer = {} |
28 | self.fillTypeTextBuffer = {} |
29 | |
30 | self.fillTypeFrames = {} -- fill type index -> HUDElement |
31 | self.fillTypeLevelBars = {} -- fill type index -> HUDElement |
32 | self.weightFrames = {} -- fill type index -> HUDELement |
33 | |
34 | self.frameHeight = 0 |
35 | self.fillLevelTextSize = 0 |
36 | self.fillLevelTextOffsetX = 0 |
37 | self.fillLevelTextOffsetY = 0 |
38 | |
39 | return self |
40 | end |
243 | function FillLevelsDisplay:setScale(uiScale) |
244 | FillLevelsDisplay:superClass().setScale(self, uiScale, uiScale) |
245 | |
246 | local currentVisibility = self:getVisible() |
247 | self:setVisible(true, false) |
248 | |
249 | self.uiScale = uiScale |
250 | local posX, posY = FillLevelsDisplay.getBackgroundPosition(uiScale, self:getWidth()) |
251 | self:setPosition(posX, posY) |
252 | |
253 | self:storeOriginalPosition() |
254 | self:setVisible(currentVisibility, false) |
255 | |
256 | self:storeScaledValues() |
257 | end |
278 | function FillLevelsDisplay:storeScaledValues() |
279 | self.fillLevelTextSize = self:scalePixelToScreenHeight(HUDElement.TEXT_SIZE.DEFAULT_TEXT) |
280 | self.fillLevelTextOffsetX, self.fillLevelTextOffsetY = self:scalePixelToScreenVector(FillLevelsDisplay.POSITION.FILL_LEVEL_TEXT) |
281 | |
282 | self.fillTypeTextOffsetX, self.fillTypeTextOffsetY = self:scalePixelToScreenVector(FillLevelsDisplay.POSITION.FILL_TYPE_TEXT) |
283 | |
284 | local _ |
285 | _, self.frameHeight = self:scalePixelToScreenVector(FillLevelsDisplay.SIZE.FILL_TYPE_FRAME) |
286 | _, self.frameOffsetY = self:scalePixelToScreenVector(FillLevelsDisplay.POSITION.FILL_TYPE_FRAME_MARGIN) |
287 | self.firstFillTypeOffset = self:scalePixelToScreenVector(FillLevelsDisplay.POSITION.FIRST_FILL_TYPE_OFFSET) |
288 | end |
184 | function FillLevelsDisplay:update(dt) |
185 | FillLevelsDisplay:superClass().update(self, dt) |
186 | |
187 | if self.vehicle ~= nil then |
188 | self:updateFillLevelBuffers() |
189 | |
190 | if #self.fillLevelBuffer > 0 then |
191 | if not self:getVisible() and self.animation:getFinished() then |
192 | self:setVisible(true, true) |
193 | end |
194 | |
195 | self:updateFillLevelFrames() |
196 | elseif self:getVisible() and self.animation:getFinished() then |
197 | self:setVisible(false, true) |
198 | end |
199 | end |
200 | end |
99 | function FillLevelsDisplay:updateFillLevelBuffers() |
100 | clearTable(self.fillLevelTextBuffer) |
101 | clearTable(self.fillTypeTextBuffer) |
102 | |
103 | for i=1, #self.fillLevelBuffer do |
104 | local fillLevelInformation = self.fillLevelBuffer[i] |
105 | local frame = self.fillTypeFrames[fillLevelInformation.fillType] |
106 | frame:setVisible(false) |
107 | end |
108 | |
109 | -- only empty fill level and capacity, so we won't need create the sub tables every frame |
110 | for i = 1, #self.fillLevelBuffer do |
111 | self.fillLevelBuffer[i].fillLevel = 0 |
112 | self.fillLevelBuffer[i].capacity = 0 |
113 | end |
114 | |
115 | self.addIndex = 0 |
116 | self.needsSorting = false |
117 | self.vehicle:getFillLevelInformation(self) |
118 | |
119 | if self.needsSorting then |
120 | table.sort(self.fillLevelBuffer, sortBuffer) |
121 | end |
122 | end |
126 | function FillLevelsDisplay:updateFillLevelFrames() |
127 | local _, yOffset = self:getPosition() |
128 | local isFirst = true |
129 | |
130 | for i = 1, #self.fillLevelBuffer do |
131 | local fillLevelInformation = self.fillLevelBuffer[i] |
132 | if fillLevelInformation.capacity > 0 or fillLevelInformation.fillLevel > 0 then |
133 | local value = 0 |
134 | if fillLevelInformation.capacity > 0 then |
135 | value = fillLevelInformation.fillLevel / fillLevelInformation.capacity |
136 | end |
137 | |
138 | local frame = self.fillTypeFrames[fillLevelInformation.fillType] |
139 | frame:setVisible(true) |
140 | |
141 | local fillBar = self.fillTypeLevelBars[fillLevelInformation.fillType] |
142 | fillBar:setValue(value) |
143 | |
144 | local baseX = self:getPosition() |
145 | if isFirst then |
146 | baseX = baseX + self.firstFillTypeOffset |
147 | end |
148 | frame:setPosition(baseX, yOffset) |
149 | |
150 | local precision = fillLevelInformation.precision or 0 |
151 | |
152 | local formattedNumber |
153 | if precision > 0 then |
154 | local rounded = MathUtil.round(fillLevelInformation.fillLevel, precision) |
155 | formattedNumber = string.format("%d%s%0"..precision.."d", math.floor(rounded), g_i18n.decimalSeparator, (rounded - math.floor(rounded)) * 10 ^ precision) |
156 | else |
157 | formattedNumber = string.format("%d", MathUtil.round(fillLevelInformation.fillLevel)) |
158 | end |
159 | |
160 | self.weightFrames[fillLevelInformation.fillType]:setVisible(fillLevelInformation.maxReached) |
161 | |
162 | local fillTypeName, unitShort |
163 | if fillLevelInformation.fillType ~= FillType.UNKNOWN then |
164 | local fillTypeDesc = g_fillTypeManager:getFillTypeByIndex(fillLevelInformation.fillType) |
165 | fillTypeName = fillTypeDesc.title |
166 | unitShort = fillTypeDesc.unitShort |
167 | end |
168 | |
169 | local fillText = string.format("%s%s (%d%%)", formattedNumber, unitShort or "", math.floor(100 * value)) |
170 | self.fillLevelTextBuffer[#self.fillLevelTextBuffer + 1] = fillText |
171 | |
172 | if fillTypeName ~= nil then |
173 | self.fillTypeTextBuffer[#self.fillLevelTextBuffer] = fillTypeName |
174 | end |
175 | |
176 | yOffset = yOffset + self.frameHeight + self.frameOffsetY |
177 | isFirst = false |
178 | end |
179 | end |
180 | end |