diff --git a/main.lua b/main.lua index eb3f562..be3d7e6 100644 --- a/main.lua +++ b/main.lua @@ -75,13 +75,14 @@ local function onDataComplete(deviceName, success, dataSet, response) loadingText:removeSelf() background:removeSelf() - -- Wechsle zur Datenansicht-Scene und übergebe die Daten + -- Wechsle zur Datenansicht-Scene und übergebe die Daten + Cookie composer.gotoScene("scenen.scene01", { effect = "fade", time = 500, params = { deviceDataSets = deviceDataSets, - devices = devices + devices = devices, + cookie = cookie } }) end diff --git a/scene-template.lua b/scene-template.lua new file mode 100644 index 0000000..70a0379 --- /dev/null +++ b/scene-template.lua @@ -0,0 +1,77 @@ + +local composer = require( "composer" ) + +local scene = composer.newScene() + +-- ----------------------------------------------------------------------------------- +-- Code outside of the scene event functions below will only be executed ONCE unless +-- the scene is removed entirely (not recycled) via "composer.removeScene()" +-- ----------------------------------------------------------------------------------- + + + + +-- ----------------------------------------------------------------------------------- +-- Scene event functions +-- ----------------------------------------------------------------------------------- + +-- create() +function scene:create( event ) + + local sceneGroup = self.view + -- Code here runs when the scene is first created but has not yet appeared on screen + +end + + +-- show() +function scene:show( event ) + + local sceneGroup = self.view + local phase = event.phase + + if ( phase == "will" ) then + -- Code here runs when the scene is still off screen (but is about to come on screen) + + elseif ( phase == "did" ) then + -- Code here runs when the scene is entirely on screen + + end +end + + +-- hide() +function scene:hide( event ) + + local sceneGroup = self.view + local phase = event.phase + + if ( phase == "will" ) then + -- Code here runs when the scene is on screen (but is about to go off screen) + + elseif ( phase == "did" ) then + -- Code here runs immediately after the scene goes entirely off screen + + end +end + + +-- destroy() +function scene:destroy( event ) + + local sceneGroup = self.view + -- Code here runs prior to the removal of scene's view + +end + + +-- ----------------------------------------------------------------------------------- +-- Scene event function listeners +-- ----------------------------------------------------------------------------------- +scene:addEventListener( "create", scene ) +scene:addEventListener( "show", scene ) +scene:addEventListener( "hide", scene ) +scene:addEventListener( "destroy", scene ) +-- ----------------------------------------------------------------------------------- + +return scene diff --git a/scenen/scene01.lua b/scenen/scene01.lua index 4ba2335..1681395 100644 --- a/scenen/scene01.lua +++ b/scenen/scene01.lua @@ -6,18 +6,63 @@ ----------------------------------------------------------------------------------------- local composer = require("composer") -local json = require("json") +local widget = require("widget") +local AskiRepository = require("askirepository") local scene = composer.newScene() +-- Globale Variablen für Datenabruf +local selectedDate = nil +local devices = nil +local currentCookie = nil + -- ----------------------------------------------------------------------------------- -- Scene event functions -- ----------------------------------------------------------------------------------- +-- Hilfsfunktion: Hole Gestern als Datum +local function getYesterdayDate() + local currentTime = os.time() + print("Aktuelle Zeit (Timestamp): " .. currentTime) + local yesterdayTime = currentTime - (24 * 60 * 60) -- 1 Tag zurück + print("Gestern Zeit (Timestamp): " .. yesterdayTime) + return os.date("*t", yesterdayTime) +end + +-- Hilfsfunktion: Formatiere Datum für API +local function formatDateForAPI(dateTable, isEndOfDay) + if isEndOfDay then + return string.format("%04d-%02d-%02dT23:59:59.999Z", + dateTable.year, dateTable.month, dateTable.day) + else + return string.format("%04d-%02d-%02dT00:00:00.000Z", + dateTable.year, dateTable.month, dateTable.day) + end +end + +-- Go to Week scene02 +local function gotoWeek() + composer.gotoScene("scenen.scene02", { + effect = "fade", + time = 500, + params = { + devices = devices, + cookie = currentCookie + } + }) +end + -- create() function scene:create(event) local sceneGroup = self.view - -- Kein Hintergrund, keine UI-Elemente + + -- Hintergrund + local bg = display.newRect(sceneGroup, display.contentCenterX, display.contentCenterY, + display.contentWidth, display.contentHeight) + bg:setFillColor(0.95, 0.95, 0.95) + + -- Setze Standard-Datum auf gestern + selectedDate = getYesterdayDate() end -- show() @@ -31,97 +76,323 @@ function scene:show(event) elseif phase == "did" then -- Code hier wird ausgeführt, wenn die Scene komplett on-screen ist - -- Hole die übergebenen Daten - local deviceDataSets = event.params.deviceDataSets - local devices = event.params.devices + -- Hole die übergebenen Daten (falls neu übermittelt) + local deviceDataSets = event.params and event.params.deviceDataSets or nil + if event.params then + if event.params.devices then + devices = event.params.devices + end + if event.params.cookie then + currentCookie = event.params.cookie + end + end - if deviceDataSets and devices then - -- Berechne Layout - local itemHeight = 90 - local cardWidth = display.contentWidth - 60 - local totalHeight = #devices * itemHeight - local startY = (display.contentHeight - totalHeight) / 2 + (itemHeight / 2) - - for i, device in ipairs(devices) do - local yPos = startY + ((i - 1) * itemHeight) - - -- Container für jedes Device (zentral) - local itemBg = display.newRoundedRect(sceneGroup, display.contentCenterX, yPos, cardWidth, itemHeight - 10, 8) - itemBg:setFillColor(1, 1, 1) - itemBg.strokeWidth = 2 - itemBg:setStrokeColor(0.85, 0.85, 0.85) - - -- Device Name (Titel) - local nameText = display.newText({ - parent = sceneGroup, - text = device.name, - x = display.contentCenterX, - y = yPos - 25, - fontSize = 18, - font = native.systemFontBold, - align = "center" - }) - nameText:setFillColor(0.2, 0.2, 0.2) - - -- Daten extrahieren - local dataSet = deviceDataSets[device.name] - local valueText = "Keine Daten" - local dateText = "" - - if dataSet and not dataSet.error then - if type(dataSet) == "table" and #dataSet > 0 then - local meterData = nil - for _, meter in ipairs(dataSet) do - if meter.deviceId == device.deviceId then - meterData = meter - break - end - end - - if meterData and meterData.values and #meterData.values > 0 then - local firstValue = meterData.values[1] - if firstValue.value then - valueText = string.format("%.2f kW", firstValue.value) - end - if firstValue.datetime then - dateText = firstValue.datetime - end - end - end - elseif dataSet and dataSet.error then - valueText = "Fehler: " .. dataSet.error - end - - -- Wert anzeigen - local valueLabel = display.newText({ - parent = sceneGroup, - text = valueText, - x = display.contentCenterX, - y = yPos, - fontSize = 16, - align = "center" - }) - valueLabel:setFillColor(0.3, 0.6, 0.3) - - -- Datum anzeigen (falls vorhanden) - if dateText ~= "" then - local formattedDate = dateText:match("(%d%d%d%d%-%d%d%-%d%d)") - if formattedDate then - local dateLabel = display.newText({ - parent = sceneGroup, - text = "📅 " .. formattedDate, - x = display.contentCenterX, - y = yPos + 25, - fontSize = 12, - align = "center" - }) - dateLabel:setFillColor(0.5, 0.5, 0.5) - end + -- Funktion zum Anzeigen der Daten + local function displayData(dataSets) + -- Entferne alte Daten-Anzeigen (aber nicht Datepicker und Button) + for i = sceneGroup.numChildren, 1, -1 do + local child = sceneGroup[i] + if child._isDataDisplay then + child:removeSelf() end end - print("✓ Scene01 geladen mit zentral angeordneten Datenboxen") + if dataSets and devices then + -- Kompaktes Layout + local itemHeight = 60 + local cardWidth = display.contentWidth - 40 + local startY = 190 -- Start nach Datepicker und Button + + for i, device in ipairs(devices) do + local yPos = startY + ((i - 1) * itemHeight) + + -- Container für jedes Device + local itemBg = display.newRoundedRect(sceneGroup, display.contentCenterX, yPos, cardWidth, itemHeight - 8, 6) + itemBg:setFillColor(1, 1, 1) + itemBg.strokeWidth = 1 + itemBg:setStrokeColor(0.85, 0.85, 0.85) + itemBg._isDataDisplay = true + + -- Device Name + local nameText = display.newText({ + parent = sceneGroup, + text = device.name, + x = display.contentCenterX - cardWidth/2 + 80, + y = yPos - 5, + fontSize = 14, + font = native.systemFontBold, + align = "left" + }) + nameText:setFillColor(0.2, 0.2, 0.2) + nameText._isDataDisplay = true + + -- Daten extrahieren + local dataSet = dataSets[device.name] + local valueText = "Keine Daten" + local dateText = "" + + if dataSet and not dataSet.error then + if type(dataSet) == "table" and #dataSet > 0 then + local meterData = nil + for _, meter in ipairs(dataSet) do + if meter.deviceId == device.deviceId then + meterData = meter + break + end + end + + if meterData and meterData.values and #meterData.values > 0 then + local firstValue = meterData.values[1] + if firstValue.value then + valueText = string.format("%.2f kW", firstValue.value) + end + if firstValue.datetime then + dateText = firstValue.datetime:match("(%d%d%d%d%-%d%d%-%d%d)") or "" + end + end + end + elseif dataSet and dataSet.error then + valueText = "Fehler" + end + + -- Wert anzeigen + local valueLabel = display.newText({ + parent = sceneGroup, + text = valueText, + x = display.contentCenterX - cardWidth/2 + 80, + y = yPos + 12, + fontSize = 13, + align = "left" + }) + valueLabel:setFillColor(0.3, 0.6, 0.3) + valueLabel._isDataDisplay = true + + -- Datum (rechts) + if dateText ~= "" then + local dateLabel = display.newText({ + parent = sceneGroup, + text = dateText, + x = display.contentCenterX + cardWidth/2 - 60, + y = yPos, + fontSize = 11, + align = "right" + }) + dateLabel:setFillColor(0.5, 0.5, 0.5) + dateLabel._isDataDisplay = true + end + end + end end + + -- Funktion zum Neuladen der Daten + local function reloadData() + if not currentCookie or not devices or not selectedDate then + print("Fehler: Cookie, Devices oder Datum fehlt") + return + end + + print("Lade Daten für " .. string.format("%04d-%02d-%02d", selectedDate.year, selectedDate.month, selectedDate.day)) + + local fromDate = formatDateForAPI(selectedDate, false) + local toDate = formatDateForAPI(selectedDate, true) + local newDeviceDataSets = {} + local completedRequests = 0 + local totalRequests = #devices + + -- Lade-Anzeige + local loadingOverlay = display.newRect(sceneGroup, display.contentCenterX, display.contentCenterY, + display.contentWidth, display.contentHeight) + loadingOverlay:setFillColor(0, 0, 0, 0.5) + loadingOverlay._isDataDisplay = true + + local loadingText = display.newText({ + parent = sceneGroup, + text = "Lade Daten...", + x = display.contentCenterX, + y = display.contentCenterY, + fontSize = 20, + font = native.systemFontBold + }) + loadingText:setFillColor(1, 1, 1) + loadingText._isDataDisplay = true + + -- Callback für jeden Device + local function onDataComplete(deviceName, success, dataSet, response) + completedRequests = completedRequests + 1 + + if success then + newDeviceDataSets[deviceName] = dataSet + print("✓ Daten empfangen für: " .. deviceName) + print(" Typ: " .. type(dataSet)) + if type(dataSet) == "table" then + print(" Anzahl Einträge: " .. #dataSet) + end + else + newDeviceDataSets[deviceName] = { error = tostring(response) } + print("✗ Fehler für " .. deviceName .. ": " .. tostring(response)) + end + + if completedRequests >= totalRequests then + -- Entferne Lade-Anzeige + loadingOverlay:removeSelf() + loadingText:removeSelf() + + + -- Zeige neue Daten + displayData(newDeviceDataSets) + print("✓ Daten erfolgreich geladen") + end + end + + -- Lade Daten für alle Devices + for i, device in ipairs(devices) do + local function deviceCallback(success, dataSet, response) + onDataComplete(device.name, success, dataSet, response) + end + + AskiRepository.getPostHistoricData( + "https://api.portal.aski.at/historical_values/power", + device.deviceId, + fromDate, + toDate, + currentCookie, + deviceCallback + ) + end + end + + -- Datepicker-Bereich (oben) + local datePickerBg = display.newRoundedRect(sceneGroup, display.contentCenterX, 50, + display.contentWidth - 40, 60, 8) + datePickerBg:setFillColor(1, 1, 1) + datePickerBg.strokeWidth = 2 + datePickerBg:setStrokeColor(0.3, 0.5, 0.8) + + local dateLabel = display.newText({ + parent = sceneGroup, + text = "Datum Auswahl:", + x = display.contentCenterX - 80, + y = 40, + fontSize = 14, + font = native.systemFontBold + }) + dateLabel:setFillColor(0.2, 0.2, 0.2) + + -- Datum-Anzeige (klickbar) + local dateDisplay = display.newText({ + parent = sceneGroup, + text = string.format("%04d-%02d-%02d", selectedDate.year, selectedDate.month, selectedDate.day), + x = display.contentCenterX - 80, + y = 60, + fontSize = 16, + font = native.systemFont + }) + dateDisplay:setFillColor(0.3, 0.5, 0.8) + + -- Pfeile zum Datum ändern + local prevDayBtn = display.newText({ + parent = sceneGroup, + text = "◀", + x = display.contentCenterX + 30, + y = 50, + fontSize = 24 + }) + prevDayBtn:setFillColor(0.3, 0.5, 0.8) + + local nextDayBtn = display.newText({ + parent = sceneGroup, + text = "▶", + x = display.contentCenterX + 90, + y = 50, + fontSize = 24 + }) + nextDayBtn:setFillColor(0.5, 0.5, 0.5) -- Ausgegraut, falls am Maximum + + -- Funktion zum Aktualisieren der Datumsanzeige + local function updateDateDisplay() + dateDisplay.text = string.format("%04d-%02d-%02d", selectedDate.year, selectedDate.month, selectedDate.day) + + -- Prüfe ob "nächster Tag" erlaubt ist + local yesterday = getYesterdayDate() + local yesterdayTimestamp = os.time(yesterday) + local selectedTimestamp = os.time(selectedDate) + + if selectedTimestamp >= yesterdayTimestamp then + nextDayBtn:setFillColor(0.5, 0.5, 0.5) -- Ausgegraut + else + nextDayBtn:setFillColor(0.3, 0.5, 0.8) -- Aktiv + end + end + + -- Event-Handler für Datum-Änderung + prevDayBtn:addEventListener("tap", function() + local currentTimestamp = os.time(selectedDate) + local newTimestamp = currentTimestamp - (24 * 60 * 60) + selectedDate = os.date("*t", newTimestamp) + updateDateDisplay() + end) + + nextDayBtn:addEventListener("tap", function() + local yesterday = getYesterdayDate() + local yesterdayTimestamp = os.time(yesterday) + local currentTimestamp = os.time(selectedDate) + + if currentTimestamp < yesterdayTimestamp then + local newTimestamp = currentTimestamp + (24 * 60 * 60) + selectedDate = os.date("*t", newTimestamp) + updateDateDisplay() + end + end) + + -- Reload-Button + local reloadBtn = widget.newButton({ + label = "Daten laden", + onRelease = reloadData, + emboss = false, + shape = "roundedRect", + width = 200, + height = 40, + cornerRadius = 8, + fillColor = { default={0.3, 0.6, 0.3, 1}, over={0.2, 0.5, 0.2, 1} }, + strokeColor = { default={0.2, 0.4, 0.2, 1}, over={0.1, 0.3, 0.1, 1} }, + strokeWidth = 2, + labelColor = { default={1, 1, 1}, over={1, 1, 1} }, + fontSize = 16, + x = display.contentCenterX, + y = 120 + }) + sceneGroup:insert(reloadBtn) + + -- Zeige initiale Daten oder lade sie neu + if deviceDataSets and devices then + displayData(deviceDataSets) + print("✓ Scene01 geladen mit Datepicker und kompakter Ansicht") + elseif devices and currentCookie then + -- Wenn wir von einer anderen Scene zurückkommen (z.B. Scene02), + -- aber keine neuen Daten mitgebracht haben, lade die Daten neu + print("✓ Zurück zu Scene01 - Lade Daten neu...") + reloadData() + end + + -- Design für Wochenübersicht Button + local weekBtn = widget.newButton({ + label = "Zu den letzten 7 Tagen", + emboss = false, + shape = "roundedRect", + width = 200, + height = 40, + cornerRadius = 8, + fillColor = { default = { 0.3, 0.5, 0.8, 1 }, over = { 0.2, 0.4, 0.7, 1 } }, + strokeColor = { default = { 0.2, 0.4, 0.2, 1 }, over = { 0.1, 0.3, 0.1, 1 } }, + strokeWidth = 2, + labelColor = { default = { 1, 1, 1 }, over = { 1, 1, 1 } }, + fontSize = 16, + x = display.contentCenterX, + y = 380 + }) + -- Event-Listener für Wochenübersicht Button + sceneGroup:insert(weekBtn) + weekBtn:addEventListener("tap", gotoWeek) end end diff --git a/scenen/scene02.lua b/scenen/scene02.lua new file mode 100644 index 0000000..c8e4ab2 --- /dev/null +++ b/scenen/scene02.lua @@ -0,0 +1,238 @@ + +local composer = require( "composer" ) + +local json = require("json") +local widget = require("widget") +local AskiRepository = require("askirepository") + +local scene = composer.newScene() + +-- Globale Variablen für Datenabruf +local yesterdayDate = nil +local selectedDate = nil + +-- ----------------------------------------------------------------------------------- +-- Code outside of the scene event functions below will only be executed ONCE unless +-- the scene is removed entirely (not recycled) via "composer.removeScene()" +-- ----------------------------------------------------------------------------------- +-- Hilfsfunktion: Hole Datum minus 7 Tage Datum +local function getCurrentAndLastDate(isCurrentDate) + local currentTime = os.time() + --print("Aktuelle Zeit (Timestamp): " .. currentTime) + local lastSevenDayTime = currentTime - (24 * 60 * 60 * 7) -- 7 Tage zurück + --print("Vor 7 Tagen Zeit (Timestamp): " .. lastSevenDayTime) + if isCurrentDate then + return os.date("*t", currentTime - (24 * 60 * 60)) -- minus 1 Tag für gestern + else + return os.date("*t", lastSevenDayTime - (24 * 60 * 60)) -- nochmal minus 1 Tag für vor 7 Tage + end +end + +-- Hilfsfunktion: Formatiere Datum für API +local function formatDateForAPI(dateTable, isEndOfDay) + if isEndOfDay then + return string.format("%04d-%02d-%02dT23:59:59.999Z", + dateTable.year, dateTable.month, dateTable.day) + else + return string.format("%04d-%02d-%02dT00:00:00.000Z", + dateTable.year, dateTable.month, dateTable.day) + end +end + +-- Go to Day scene02 +local function gotoDay() + composer.gotoScene("scenen.scene01", { + effect = "fade", + time = 500 + }) +end + + +-- ----------------------------------------------------------------------------------- +-- Scene event functions +-- ----------------------------------------------------------------------------------- + +-- create() +function scene:create( event ) + + local sceneGroup = self.view + -- Code here runs when the scene is first created but has not yet appeared on screen + -- Hintergrund + local bg = display.newRect(sceneGroup, display.contentCenterX, display.contentCenterY, + display.contentWidth, display.contentHeight) + bg:setFillColor(0.95, 0.95, 0.95) + + -- aktuelles Tagesdatum -1 Tag für gestern + yesterdayDate = getCurrentAndLastDate(true) + -- Setze Standard-Datum auf vor 8 Tagen + selectedDate = getCurrentAndLastDate(false) + +end + + +-- show() +function scene:show( event ) + + local sceneGroup = self.view + local phase = event.phase + + if ( phase == "will" ) then + -- Code here runs when the scene is still off screen (but is about to come on screen) + + elseif ( phase == "did" ) then + -- Hole die übergebenen Daten + local devices = event.params.devices + local currentCookie = event.params.cookie + -- Formatiere die Daten für die API + local fromDate = formatDateForAPI(selectedDate, false) + local toDate = formatDateForAPI(yesterdayDate, true) + local completedRequests = 0 + local totalRequests = #devices + local currentDataSets = {} + + -- Ausgabe der übergebenen Daten für Debugging + print("Scene02 ist jetzt sichtbar - Zeige Daten an") + print("Entspricht einer Woche von Gestern 7 Tage zurück") + print("Formatiertes Start-Datum für API: " .. fromDate) + print("Formatiertes End-Datum für API: " .. toDate) + print("Übergebene Geräte: " .. (devices and #devices or "Keine")) + print("Cookie:" .. tostring(currentCookie)) + + + -- Funktion zum Neuladen der Daten + local function reloadDataFromSevenDays() + if not currentCookie or not devices or not selectedDate then + print("Fehler: Cookie, Devices oder Datum fehlt") + return + end + + print("Lade Daten von " .. + string.format("%04d-%02d-%02d", selectedDate.year, selectedDate.month, selectedDate.day) .. + " bis " .. + string.format("%04d-%02d-%02d", yesterdayDate.year, yesterdayDate.month, yesterdayDate.day) .. + " für " .. #devices .. " Geräte") + + + -- Lade-Anzeige + local loadingOverlay = display.newRect(sceneGroup, display.contentCenterX, display.contentCenterY, + display.contentWidth, display.contentHeight) + loadingOverlay:setFillColor(0, 0, 0, 0.5) + loadingOverlay._isDataDisplay = true + + local loadingText = display.newText({ + parent = sceneGroup, + text = "Lade Daten...", + x = display.contentCenterX, + y = display.contentCenterY, + fontSize = 20, + font = native.systemFontBold + }) + loadingText:setFillColor(1, 1, 1) + loadingText._isDataDisplay = true + + -- Callback für jeden Device + local function onDataComplete(deviceName, success, dataSet, response) + completedRequests = completedRequests + 1 + + if success then + currentDataSets[deviceName] = dataSet + else + currentDataSets[deviceName] = { error = tostring(response) } + end + + if completedRequests >= totalRequests then + -- Entferne Lade-Anzeige + loadingOverlay:removeSelf() + loadingText:removeSelf() + + -- Ausgabe der kompletten newDeviceDataSets Table + print("\n========== ALLE GELADENEN DATEN (newDeviceDataSets) ==========") + print("JSON-Format:") + print(json.prettify(currentDataSets)) + print("===============================================================\n") + -- Zeige neue Daten + print("✓ Daten erfolgreich geladen") + end + end + + -- Lade Daten für alle Devices + for i, device in ipairs(devices) do + local function deviceCallback(success, dataSet, response) + onDataComplete(device.name, success, dataSet, response) + end + + AskiRepository.getPostHistoricData( + "https://api.portal.aski.at/historical_values/power", + device.deviceId, + fromDate, + toDate, + currentCookie, + deviceCallback + ) + end + end + + -- Code here runs when the scene is entirely on screen + reloadDataFromSevenDays() -- Lade die Daten direkt beim Anzeigen der Scene02 + -- Inhalt Diagramm anzeigen + + + -- Button für zurück zu Scene01 + -- Design für Tagesansicht Button + local dayBtn = widget.newButton({ + label = "Vortagesansicht", + emboss = false, + shape = "roundedRect", + width = 200, + height = 40, + cornerRadius = 8, + fillColor = { default = { 0.3, 0.5, 0.8, 1 }, over = { 0.2, 0.4, 0.7, 1 } }, + strokeColor = { default = { 0.2, 0.4, 0.2, 1 }, over = { 0.1, 0.3, 0.1, 1 } }, + strokeWidth = 2, + labelColor = { default = { 1, 1, 1 }, over = { 1, 1, 1 } }, + fontSize = 16, + x = display.contentCenterX, + y = 380 + }) + -- Event-Listener für Tagesansicht Button + sceneGroup:insert(dayBtn) + dayBtn:addEventListener("tap", gotoDay) + end +end + + +-- hide() +function scene:hide( event ) + + local sceneGroup = self.view + local phase = event.phase + + if ( phase == "will" ) then + -- Code here runs when the scene is on screen (but is about to go off screen) + + elseif ( phase == "did" ) then + -- Code here runs immediately after the scene goes entirely off screen + + end +end + + +-- destroy() +function scene:destroy( event ) + + local sceneGroup = self.view + -- Code here runs prior to the removal of scene's view + print("Scene02 zerstört") +end + + +-- ----------------------------------------------------------------------------------- +-- Scene event function listeners +-- ----------------------------------------------------------------------------------- +scene:addEventListener( "create", scene ) +scene:addEventListener( "show", scene ) +scene:addEventListener( "hide", scene ) +scene:addEventListener( "destroy", scene ) +-- ----------------------------------------------------------------------------------- + +return scene