add simulator mode to desktop designer for testing apps
- Add --simulator flag to launch home screen showing discovered apps - Create app discovery system to scan test-apps/ directory - Build simulator home screen with dark phone-like UI - Add Lua API: simulator.launchApp, simulator.goHome, simulator.getApps - ESC key returns to home when inside an app - Apps displayed with icons in grid layout Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
158
designer/assets/simulator/simulator.lua
Normal file
158
designer/assets/simulator/simulator.lua
Normal file
@@ -0,0 +1,158 @@
|
||||
-- Simulator Home Screen Logic
|
||||
|
||||
local apps = {}
|
||||
|
||||
-- Helper to get document (may not be available immediately)
|
||||
local function getDoc()
|
||||
if document then
|
||||
return document
|
||||
end
|
||||
if rmlui and rmlui.contexts and rmlui.contexts.main then
|
||||
local ctx = rmlui.contexts.main
|
||||
if ctx.documents then
|
||||
for i, doc in ipairs(ctx.documents) do
|
||||
if doc then
|
||||
return doc
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
-- Populate the app grid with discovered apps
|
||||
function populateAppGrid()
|
||||
local doc = getDoc()
|
||||
if not doc then
|
||||
print("[Simulator] Document not available for populateAppGrid")
|
||||
return
|
||||
end
|
||||
|
||||
local grid = doc:GetElementById("app-grid")
|
||||
if not grid then
|
||||
print("[Simulator] app-grid element not found")
|
||||
return
|
||||
end
|
||||
|
||||
-- Clear existing content
|
||||
grid.inner_rml = ""
|
||||
|
||||
if #apps == 0 then
|
||||
grid.inner_rml = [[
|
||||
<div class="no-apps">
|
||||
<p>No apps found</p>
|
||||
<p class="hint">Place apps in test-apps/ folder</p>
|
||||
</div>
|
||||
]]
|
||||
return
|
||||
end
|
||||
|
||||
-- Build app icons
|
||||
local html = ""
|
||||
for i, app in ipairs(apps) do
|
||||
local icon_html
|
||||
if app.icon and app.icon ~= "" then
|
||||
icon_html = string.format('<img src="%s"/>', app.icon)
|
||||
else
|
||||
icon_html = '<span class="app-icon-placeholder">■</span>'
|
||||
end
|
||||
|
||||
html = html .. string.format([[
|
||||
<div class="app-icon" onclick="launchApp('%s')">
|
||||
<div class="app-icon-image">%s</div>
|
||||
<span class="app-icon-label">%s</span>
|
||||
</div>
|
||||
]], app.id, icon_html, app.name)
|
||||
end
|
||||
|
||||
grid.inner_rml = html
|
||||
print("[Simulator] Populated " .. #apps .. " apps")
|
||||
end
|
||||
|
||||
-- Get apps from C++ and populate the grid
|
||||
function refreshApps()
|
||||
if simulator and simulator.getApps then
|
||||
apps = simulator.getApps()
|
||||
print("[Simulator] Got " .. #apps .. " apps from C++")
|
||||
populateAppGrid()
|
||||
else
|
||||
print("[Simulator] simulator.getApps not available")
|
||||
end
|
||||
end
|
||||
|
||||
-- Called from C++ after apps are discovered (backup method)
|
||||
function setApps(app_list)
|
||||
apps = app_list
|
||||
populateAppGrid()
|
||||
end
|
||||
|
||||
-- Launch an app by ID
|
||||
function launchApp(app_id)
|
||||
print("[Simulator] Launching app: " .. app_id)
|
||||
|
||||
-- Find the app
|
||||
for _, app in ipairs(apps) do
|
||||
if app.id == app_id then
|
||||
-- Call C++ function to launch the app
|
||||
if simulator and simulator.launchApp then
|
||||
simulator.launchApp(app.entry, app.path, app.id)
|
||||
else
|
||||
print("[Simulator] Error: simulator.launchApp not available")
|
||||
end
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
print("[Simulator] App not found: " .. app_id)
|
||||
end
|
||||
|
||||
-- Update the time display
|
||||
function updateTime()
|
||||
local doc = getDoc()
|
||||
if not doc then return end
|
||||
|
||||
local timeEl = doc:GetElementById("status-time")
|
||||
if timeEl then
|
||||
-- Use os.date if available, otherwise show static time
|
||||
local time_str = "12:00"
|
||||
if os and os.date then
|
||||
time_str = os.date("%H:%M")
|
||||
end
|
||||
timeEl.inner_rml = time_str
|
||||
end
|
||||
end
|
||||
|
||||
-- Initialize
|
||||
print("[Simulator] Home screen loaded")
|
||||
|
||||
-- Try immediate initialization first
|
||||
local doc = getDoc()
|
||||
if doc then
|
||||
print("[Simulator] Document available immediately")
|
||||
refreshApps()
|
||||
updateTime()
|
||||
elseif setInterval then
|
||||
print("[Simulator] Document not ready, setting up timer")
|
||||
-- Use a one-time timer to refresh apps after document is ready
|
||||
local initTimerId = nil
|
||||
local attempts = 0
|
||||
initTimerId = setInterval(function()
|
||||
attempts = attempts + 1
|
||||
local d = getDoc()
|
||||
if d then
|
||||
print("[Simulator] Document ready after " .. attempts .. " attempts")
|
||||
clearInterval(initTimerId)
|
||||
refreshApps()
|
||||
updateTime()
|
||||
elseif attempts > 50 then
|
||||
-- Give up after 5 seconds
|
||||
print("[Simulator] Gave up waiting for document")
|
||||
clearInterval(initTimerId)
|
||||
end
|
||||
end, 100)
|
||||
|
||||
-- Update time every minute
|
||||
setInterval(updateTime, 60000)
|
||||
else
|
||||
print("[Simulator] No setInterval and no document - cannot init")
|
||||
end
|
||||
Reference in New Issue
Block a user