add icons and navigation
@@ -1,9 +0,0 @@
|
||||
-- Simple button click handler
|
||||
click_count = 0
|
||||
|
||||
function onButtonClick(event)
|
||||
click_count = click_count + 1
|
||||
local button = event.current_element
|
||||
button.inner_rml = "Clicked " .. click_count .. " times!"
|
||||
print("Button clicked! Count: " .. click_count)
|
||||
end
|
||||
119
assets/demo.rml
@@ -1,119 +0,0 @@
|
||||
<rml>
|
||||
<head>
|
||||
<link type="text/rcss" href="ui/theme.rcss"/>
|
||||
<link type="text/rcss" href="ui/components.rcss"/>
|
||||
<script src="scripts/navigation.lua"></script>
|
||||
<script src="scripts/phone.lua"></script>
|
||||
<title>Virtual Smartphone - Home</title>
|
||||
<style>
|
||||
.home-screen {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #121212;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.home-content {
|
||||
flex: 1;
|
||||
padding-bottom: 80px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="home-screen">
|
||||
<!-- Status Bar -->
|
||||
<div class="status-bar">
|
||||
<span class="status-bar-time">12:30</span>
|
||||
<div class="status-bar-icons">
|
||||
<span>*</span>
|
||||
<span>+</span>
|
||||
<span>|</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- App Grid -->
|
||||
<div class="home-content">
|
||||
<div class="app-grid">
|
||||
<!-- Row 1 -->
|
||||
<div class="app-icon" onclick="navigateTo('dialer')">
|
||||
<div class="app-icon-image" style="background-color: #4CAF50;">P</div>
|
||||
<span class="app-icon-label">Phone</span>
|
||||
</div>
|
||||
<div class="app-icon" onclick="navigateTo('messages')">
|
||||
<div class="app-icon-image" style="background-color: #2196F3;">M</div>
|
||||
<span class="app-icon-label">Messages</span>
|
||||
</div>
|
||||
<div class="app-icon" onclick="navigateTo('contacts')">
|
||||
<div class="app-icon-image" style="background-color: #FF9800;">C</div>
|
||||
<span class="app-icon-label">Contacts</span>
|
||||
</div>
|
||||
<div class="app-icon" onclick="navigateTo('browser')">
|
||||
<div class="app-icon-image" style="background-color: #F44336;">B</div>
|
||||
<span class="app-icon-label">Browser</span>
|
||||
</div>
|
||||
|
||||
<!-- Row 2 -->
|
||||
<div class="app-icon">
|
||||
<div class="app-icon-image" style="background-color: #9C27B0;">G</div>
|
||||
<span class="app-icon-label">Gallery</span>
|
||||
</div>
|
||||
<div class="app-icon">
|
||||
<div class="app-icon-image" style="background-color: #00BCD4;">C</div>
|
||||
<span class="app-icon-label">Camera</span>
|
||||
</div>
|
||||
<div class="app-icon" onclick="navigateTo('settings')">
|
||||
<div class="app-icon-image" style="background-color: #607D8B;">S</div>
|
||||
<span class="app-icon-label">Settings</span>
|
||||
</div>
|
||||
<div class="app-icon">
|
||||
<div class="app-icon-image" style="background-color: #E91E63;">M</div>
|
||||
<span class="app-icon-label">Music</span>
|
||||
</div>
|
||||
|
||||
<!-- Row 3 -->
|
||||
<div class="app-icon">
|
||||
<div class="app-icon-image" style="background-color: #3F51B5;">C</div>
|
||||
<span class="app-icon-label">Calendar</span>
|
||||
</div>
|
||||
<div class="app-icon">
|
||||
<div class="app-icon-image" style="background-color: #009688;">C</div>
|
||||
<span class="app-icon-label">Clock</span>
|
||||
</div>
|
||||
<div class="app-icon">
|
||||
<div class="app-icon-image" style="background-color: #795548;">N</div>
|
||||
<span class="app-icon-label">Notes</span>
|
||||
</div>
|
||||
<div class="app-icon">
|
||||
<div class="app-icon-image" style="background-color: #FF5722;">M</div>
|
||||
<span class="app-icon-label">Maps</span>
|
||||
</div>
|
||||
|
||||
<!-- Row 4 -->
|
||||
<div class="app-icon">
|
||||
<div class="app-icon-image" style="background-color: #8BC34A;">S</div>
|
||||
<span class="app-icon-label">Store</span>
|
||||
</div>
|
||||
<div class="app-icon">
|
||||
<div class="app-icon-image" style="background-color: #CDDC39;">F</div>
|
||||
<span class="app-icon-label">Files</span>
|
||||
</div>
|
||||
<div class="app-icon">
|
||||
<div class="app-icon-image" style="background-color: #FFC107;">C</div>
|
||||
<span class="app-icon-label">Calculator</span>
|
||||
</div>
|
||||
<div class="app-icon">
|
||||
<div class="app-icon-image" style="background-color: #673AB7;">W</div>
|
||||
<span class="app-icon-label">Weather</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Dock -->
|
||||
<div class="dock">
|
||||
<div class="dock-item" style="background-color: #4CAF50;" onclick="navigateTo('dialer')">P</div>
|
||||
<div class="dock-item" style="background-color: #2196F3;" onclick="navigateTo('messages')">M</div>
|
||||
<div class="dock-item" style="background-color: #FF9800;" onclick="navigateTo('contacts')">C</div>
|
||||
<div class="dock-item" style="background-color: #F44336;" onclick="navigateTo('browser')">B</div>
|
||||
</div>
|
||||
</body>
|
||||
</rml>
|
||||
BIN
assets/icons/add.tga
Normal file
|
After Width: | Height: | Size: 9.0 KiB |
BIN
assets/icons/back.tga
Normal file
|
After Width: | Height: | Size: 9.0 KiB |
BIN
assets/icons/backspace.tga
Normal file
|
After Width: | Height: | Size: 9.0 KiB |
BIN
assets/icons/battery.tga
Normal file
|
After Width: | Height: | Size: 9.0 KiB |
BIN
assets/icons/browser.tga
Normal file
|
After Width: | Height: | Size: 36 KiB |
BIN
assets/icons/calculator.tga
Normal file
|
After Width: | Height: | Size: 36 KiB |
BIN
assets/icons/calendar.tga
Normal file
|
After Width: | Height: | Size: 36 KiB |
BIN
assets/icons/call_small.tga
Normal file
|
After Width: | Height: | Size: 9.0 KiB |
BIN
assets/icons/camera.tga
Normal file
|
After Width: | Height: | Size: 36 KiB |
BIN
assets/icons/clock.tga
Normal file
|
After Width: | Height: | Size: 36 KiB |
BIN
assets/icons/close.tga
Normal file
|
After Width: | Height: | Size: 9.0 KiB |
BIN
assets/icons/contact_phone.tga
Normal file
|
After Width: | Height: | Size: 9.0 KiB |
BIN
assets/icons/contacts.tga
Normal file
|
After Width: | Height: | Size: 36 KiB |
BIN
assets/icons/dialpad.tga
Normal file
|
After Width: | Height: | Size: 9.0 KiB |
BIN
assets/icons/files.tga
Normal file
|
After Width: | Height: | Size: 36 KiB |
BIN
assets/icons/forward.tga
Normal file
|
After Width: | Height: | Size: 9.0 KiB |
BIN
assets/icons/gallery.tga
Normal file
|
After Width: | Height: | Size: 36 KiB |
BIN
assets/icons/history.tga
Normal file
|
After Width: | Height: | Size: 9.0 KiB |
BIN
assets/icons/home.tga
Normal file
|
After Width: | Height: | Size: 9.0 KiB |
BIN
assets/icons/maps.tga
Normal file
|
After Width: | Height: | Size: 36 KiB |
BIN
assets/icons/menu.tga
Normal file
|
After Width: | Height: | Size: 9.0 KiB |
BIN
assets/icons/message.tga
Normal file
|
After Width: | Height: | Size: 36 KiB |
BIN
assets/icons/more.tga
Normal file
|
After Width: | Height: | Size: 9.0 KiB |
BIN
assets/icons/music.tga
Normal file
|
After Width: | Height: | Size: 36 KiB |
BIN
assets/icons/notes.tga
Normal file
|
After Width: | Height: | Size: 36 KiB |
BIN
assets/icons/phone.tga
Normal file
|
After Width: | Height: | Size: 36 KiB |
BIN
assets/icons/refresh.tga
Normal file
|
After Width: | Height: | Size: 9.0 KiB |
BIN
assets/icons/search.tga
Normal file
|
After Width: | Height: | Size: 9.0 KiB |
BIN
assets/icons/send.tga
Normal file
|
After Width: | Height: | Size: 9.0 KiB |
BIN
assets/icons/settings.tga
Normal file
|
After Width: | Height: | Size: 36 KiB |
BIN
assets/icons/signal.tga
Normal file
|
After Width: | Height: | Size: 9.0 KiB |
BIN
assets/icons/store.tga
Normal file
|
After Width: | Height: | Size: 36 KiB |
BIN
assets/icons/weather.tga
Normal file
|
After Width: | Height: | Size: 36 KiB |
BIN
assets/icons/wifi.tga
Normal file
|
After Width: | Height: | Size: 9.0 KiB |
@@ -1,137 +0,0 @@
|
||||
/* Ensure the body fills the entire window */
|
||||
body {
|
||||
font-family: LatoLatin;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background: #0f0f12;
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* Status Bar pinned to top */
|
||||
#status-bar {
|
||||
display: block;
|
||||
height: 140px;
|
||||
padding: 10px 20px 0;
|
||||
background-color: rgba(255, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.time {
|
||||
float: left;
|
||||
font-weight: bold;
|
||||
font-size: 2em;
|
||||
}
|
||||
|
||||
.status-icons {
|
||||
float: right;
|
||||
font-size: 2em;
|
||||
}
|
||||
|
||||
.icon {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
/* Content area grows to fill space */
|
||||
#content {
|
||||
padding: 20px;
|
||||
/* Leaves room for status and nav bars */
|
||||
height: 80%;
|
||||
align: center;
|
||||
}
|
||||
|
||||
.header-section {
|
||||
margin-bottom: 30px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2.5em;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* Mobile-style cards */
|
||||
.card {
|
||||
background: #1e1e24;
|
||||
border-radius: 20px;
|
||||
padding: 20px;
|
||||
margin-bottom: 15px;
|
||||
border: 1px solid #333;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
font-size: 1.2em;
|
||||
margin-bottom: 10px;
|
||||
color: #3498db;
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
height: 8px;
|
||||
background: #333;
|
||||
border-radius: 4px;
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.progress-fill {
|
||||
width: 84%;
|
||||
height: 100%;
|
||||
background: #3498db;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
/* Navigation Bar pinned to bottom */
|
||||
#nav-bar {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
height: 65px;
|
||||
background-color: #16161a;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
border-top: 1px solid #333;
|
||||
}
|
||||
|
||||
.nav-item {
|
||||
font-size: 1.9em;
|
||||
color: #888;
|
||||
background-color: red;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
line-height: 90px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.nav-item:hover {
|
||||
color: #3498db;
|
||||
background-color: blue;
|
||||
}
|
||||
|
||||
/* Button container for centering */
|
||||
.button-container {
|
||||
display: block;
|
||||
text-align: center;
|
||||
margin-top: 50px;
|
||||
}
|
||||
|
||||
/* Styled button */
|
||||
button {
|
||||
padding: 20px 60px;
|
||||
font-size: 1.5em;
|
||||
font-family: LatoLatin;
|
||||
font-weight: bold;
|
||||
color: white;
|
||||
background-color: #3498db;
|
||||
border-radius: 12px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background-color: #2980b9;
|
||||
}
|
||||
|
||||
button:active {
|
||||
background-color: #1c5a85;
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
<rml>
|
||||
<head>
|
||||
<link type="text/rcss" href="../ui/html.rcss"/>
|
||||
<link type="text/rcss" href="../ui/theme.rcss"/>
|
||||
<link type="text/rcss" href="../ui/components.rcss"/>
|
||||
<script src="../scripts/navigation.lua"></script>
|
||||
@@ -173,14 +174,13 @@
|
||||
|
||||
<!-- Browser Toolbar -->
|
||||
<div class="browser-toolbar">
|
||||
<div class="browser-nav-btn" onclick="goBack()">←</div>
|
||||
<div class="browser-nav-btn disabled">→</div>
|
||||
<div class="browser-nav-btn" onclick="goBack()"><img src="../icons/back.tga" style="width: 24px; height: 24px;"/></div>
|
||||
<div class="browser-nav-btn disabled"><img src="../icons/forward.tga" style="width: 24px; height: 24px; opacity: 0.3;"/></div>
|
||||
<div class="browser-url-bar">
|
||||
<span class="browser-secure-icon">L</span>
|
||||
<input class="browser-url" type="text" value="example.com"/>
|
||||
</div>
|
||||
<div class="browser-nav-btn">R</div>
|
||||
<div class="browser-nav-btn">:</div>
|
||||
<div class="browser-nav-btn"><img src="../icons/refresh.tga" style="width: 24px; height: 24px;"/></div>
|
||||
<div class="browser-nav-btn"><img src="../icons/more.tga" style="width: 24px; height: 24px;"/></div>
|
||||
</div>
|
||||
|
||||
<!-- Browser Content -->
|
||||
@@ -213,7 +213,7 @@
|
||||
<!-- Bottom Bar -->
|
||||
<div class="browser-bottom-bar">
|
||||
<div class="browser-tab-btn" onclick="goHome()">
|
||||
<span class="browser-tab-icon">H</span>
|
||||
<img src="../icons/home.tga" class="browser-tab-icon" style="width: 24px; height: 24px;"/>
|
||||
<span class="browser-tab-label">Home</span>
|
||||
</div>
|
||||
<div class="browser-tab-btn">
|
||||
@@ -221,11 +221,11 @@
|
||||
<span class="browser-tab-label">Tabs</span>
|
||||
</div>
|
||||
<div class="browser-tab-btn">
|
||||
<span class="browser-tab-icon">+</span>
|
||||
<img src="../icons/add.tga" class="browser-tab-icon" style="width: 24px; height: 24px;"/>
|
||||
<span class="browser-tab-label">New Tab</span>
|
||||
</div>
|
||||
<div class="browser-tab-btn">
|
||||
<span class="browser-tab-icon">:</span>
|
||||
<img src="../icons/menu.tga" class="browser-tab-icon" style="width: 24px; height: 24px;"/>
|
||||
<span class="browser-tab-label">Menu</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<rml>
|
||||
<head>
|
||||
<link type="text/rcss" href="../ui/html.rcss"/>
|
||||
<link type="text/rcss" href="../ui/theme.rcss"/>
|
||||
<link type="text/rcss" href="../ui/components.rcss"/>
|
||||
<script src="../scripts/navigation.lua"></script>
|
||||
@@ -71,14 +72,14 @@
|
||||
<body class="contacts-screen">
|
||||
<!-- App Bar -->
|
||||
<div class="app-bar">
|
||||
<div class="btn-icon" onclick="goBack()">←</div>
|
||||
<div class="btn-icon" onclick="goBack()"><img src="../icons/back.tga" style="width: 24px; height: 24px;"/></div>
|
||||
<span class="app-bar-title">Contacts</span>
|
||||
<div class="btn-icon">+</div>
|
||||
<div class="btn-icon"><img src="../icons/add.tga" style="width: 24px; height: 24px;"/></div>
|
||||
</div>
|
||||
|
||||
<!-- Search Bar -->
|
||||
<div class="search-bar">
|
||||
<span class="search-icon">Q</span>
|
||||
<img src="../icons/search.tga" class="search-icon" style="width: 20px; height: 20px;"/>
|
||||
<input class="search-input" type="text" placeholder="Search contacts"/>
|
||||
</div>
|
||||
|
||||
@@ -177,20 +178,20 @@
|
||||
</div>
|
||||
|
||||
<!-- FAB -->
|
||||
<div class="btn-fab">+</div>
|
||||
<div class="btn-fab"><img src="../icons/add.tga" style="width: 24px; height: 24px;"/></div>
|
||||
|
||||
<!-- Bottom Navigation -->
|
||||
<div class="bottom-nav">
|
||||
<div class="bottom-nav-item" onclick="navigateTo('dialer')">
|
||||
<span class="bottom-nav-icon">*</span>
|
||||
<img src="../icons/dialpad.tga" class="bottom-nav-icon" style="width: 24px; height: 24px;"/>
|
||||
<span class="bottom-nav-label">Keypad</span>
|
||||
</div>
|
||||
<div class="bottom-nav-item">
|
||||
<span class="bottom-nav-icon">O</span>
|
||||
<img src="../icons/history.tga" class="bottom-nav-icon" style="width: 24px; height: 24px;"/>
|
||||
<span class="bottom-nav-label">Recent</span>
|
||||
</div>
|
||||
<div class="bottom-nav-item active">
|
||||
<span class="bottom-nav-icon">@</span>
|
||||
<img src="../icons/contacts.tga" class="bottom-nav-icon" style="width: 24px; height: 24px;"/>
|
||||
<span class="bottom-nav-label">Contacts</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<rml>
|
||||
<head>
|
||||
<link type="text/rcss" href="../ui/html.rcss"/>
|
||||
<link type="text/rcss" href="../ui/theme.rcss"/>
|
||||
<link type="text/rcss" href="../ui/components.rcss"/>
|
||||
<script src="../scripts/navigation.lua"></script>
|
||||
@@ -107,7 +108,7 @@
|
||||
<body class="dialer-screen">
|
||||
<!-- App Bar -->
|
||||
<div class="app-bar">
|
||||
<div class="btn-icon" onclick="goBack()">←</div>
|
||||
<div class="btn-icon" onclick="goBack()"><img src="../icons/back.tga" style="width: 24px; height: 24px;"/></div>
|
||||
<span class="app-bar-title">Phone</span>
|
||||
</div>
|
||||
|
||||
@@ -175,21 +176,21 @@
|
||||
|
||||
<!-- Call Button -->
|
||||
<div class="dial-actions">
|
||||
<div class="dial-call-btn" onclick="makeCall()">C</div>
|
||||
<div class="dial-call-btn" onclick="makeCall()"><img src="../icons/call_small.tga" style="width: 32px; height: 32px;"/></div>
|
||||
</div>
|
||||
|
||||
<!-- Bottom Navigation -->
|
||||
<div class="bottom-nav">
|
||||
<div class="bottom-nav-item active">
|
||||
<span class="bottom-nav-icon">*</span>
|
||||
<img src="../icons/dialpad.tga" class="bottom-nav-icon" style="width: 24px; height: 24px;"/>
|
||||
<span class="bottom-nav-label">Keypad</span>
|
||||
</div>
|
||||
<div class="bottom-nav-item">
|
||||
<span class="bottom-nav-icon">O</span>
|
||||
<img src="../icons/history.tga" class="bottom-nav-icon" style="width: 24px; height: 24px;"/>
|
||||
<span class="bottom-nav-label">Recent</span>
|
||||
</div>
|
||||
<div class="bottom-nav-item" onclick="navigateTo('contacts')">
|
||||
<span class="bottom-nav-icon">@</span>
|
||||
<img src="../icons/contacts.tga" class="bottom-nav-icon" style="width: 24px; height: 24px;"/>
|
||||
<span class="bottom-nav-label">Contacts</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
<rml>
|
||||
<head>
|
||||
<link type="text/rcss" href="../ui/html.rcss"/>
|
||||
<link type="text/rcss" href="../ui/theme.rcss"/>
|
||||
<link type="text/rcss" href="../ui/components.rcss"/>
|
||||
<title>Home</title>
|
||||
<script src="../scripts/navigation.lua"></script>
|
||||
<title>Virtual Smartphone - Home</title>
|
||||
<style>
|
||||
.home-screen {
|
||||
width: 100%;
|
||||
@@ -17,13 +19,20 @@
|
||||
padding-bottom: 80px;
|
||||
}
|
||||
|
||||
.wallpaper-overlay {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: linear-gradient(180deg, rgba(18,18,18,0.3) 0%, rgba(18,18,18,0.8) 100%);
|
||||
.app-icon-image img {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.dock-item img {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.status-bar-icons img {
|
||||
pointer-events: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
@@ -32,9 +41,9 @@
|
||||
<div class="status-bar">
|
||||
<span class="status-bar-time">12:30</span>
|
||||
<div class="status-bar-icons">
|
||||
<span>*</span>
|
||||
<span>+</span>
|
||||
<span>|</span>
|
||||
<img src="../icons/wifi.tga" style="width: 16px; height: 16px;"/>
|
||||
<img src="../icons/signal.tga" style="width: 16px; height: 16px;"/>
|
||||
<img src="../icons/battery.tga" style="width: 16px; height: 16px;"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -42,74 +51,74 @@
|
||||
<div class="home-content">
|
||||
<div class="app-grid">
|
||||
<!-- Row 1 -->
|
||||
<div class="app-icon" onclick="navigateTo('dialer')">
|
||||
<div class="app-icon-image" style="background-color: #4CAF50;">P</div>
|
||||
<div class="app-icon">
|
||||
<div class="app-icon-image" style="background-color: #4CAF50;" onclick="navigateTo('dialer')"><img src="../icons/phone.tga"/></div>
|
||||
<span class="app-icon-label">Phone</span>
|
||||
</div>
|
||||
<div class="app-icon" onclick="navigateTo('messages')">
|
||||
<div class="app-icon-image" style="background-color: #2196F3;">M</div>
|
||||
<div class="app-icon">
|
||||
<div class="app-icon-image" style="background-color: #2196F3;" onclick="navigateTo('messages')"><img src="../icons/message.tga"/></div>
|
||||
<span class="app-icon-label">Messages</span>
|
||||
</div>
|
||||
<div class="app-icon" onclick="navigateTo('contacts')">
|
||||
<div class="app-icon-image" style="background-color: #FF9800;">C</div>
|
||||
<div class="app-icon">
|
||||
<div class="app-icon-image" style="background-color: #FF9800;" onclick="navigateTo('contacts')"><img src="../icons/contacts.tga"/></div>
|
||||
<span class="app-icon-label">Contacts</span>
|
||||
</div>
|
||||
<div class="app-icon" onclick="navigateTo('browser')">
|
||||
<div class="app-icon-image" style="background-color: #F44336;">B</div>
|
||||
<div class="app-icon">
|
||||
<div class="app-icon-image" style="background-color: #F44336;" onclick="navigateTo('browser')"><img src="../icons/browser.tga"/></div>
|
||||
<span class="app-icon-label">Browser</span>
|
||||
</div>
|
||||
|
||||
<!-- Row 2 -->
|
||||
<div class="app-icon">
|
||||
<div class="app-icon-image" style="background-color: #9C27B0;">G</div>
|
||||
<div class="app-icon-image" style="background-color: #9C27B0;"><img src="../icons/gallery.tga"/></div>
|
||||
<span class="app-icon-label">Gallery</span>
|
||||
</div>
|
||||
<div class="app-icon">
|
||||
<div class="app-icon-image" style="background-color: #00BCD4;">C</div>
|
||||
<div class="app-icon-image" style="background-color: #00BCD4;"><img src="../icons/camera.tga"/></div>
|
||||
<span class="app-icon-label">Camera</span>
|
||||
</div>
|
||||
<div class="app-icon" onclick="navigateTo('settings')">
|
||||
<div class="app-icon-image" style="background-color: #607D8B;">S</div>
|
||||
<div class="app-icon">
|
||||
<div class="app-icon-image" style="background-color: #607D8B;" onclick="navigateTo('settings')"><img src="../icons/settings.tga"/></div>
|
||||
<span class="app-icon-label">Settings</span>
|
||||
</div>
|
||||
<div class="app-icon">
|
||||
<div class="app-icon-image" style="background-color: #E91E63;">M</div>
|
||||
<div class="app-icon-image" style="background-color: #E91E63;"><img src="../icons/music.tga"/></div>
|
||||
<span class="app-icon-label">Music</span>
|
||||
</div>
|
||||
|
||||
<!-- Row 3 -->
|
||||
<div class="app-icon">
|
||||
<div class="app-icon-image" style="background-color: #3F51B5;">C</div>
|
||||
<div class="app-icon-image" style="background-color: #3F51B5;"><img src="../icons/calendar.tga"/></div>
|
||||
<span class="app-icon-label">Calendar</span>
|
||||
</div>
|
||||
<div class="app-icon">
|
||||
<div class="app-icon-image" style="background-color: #009688;">C</div>
|
||||
<div class="app-icon-image" style="background-color: #009688;"><img src="../icons/clock.tga"/></div>
|
||||
<span class="app-icon-label">Clock</span>
|
||||
</div>
|
||||
<div class="app-icon">
|
||||
<div class="app-icon-image" style="background-color: #795548;">N</div>
|
||||
<div class="app-icon-image" style="background-color: #795548;"><img src="../icons/notes.tga"/></div>
|
||||
<span class="app-icon-label">Notes</span>
|
||||
</div>
|
||||
<div class="app-icon">
|
||||
<div class="app-icon-image" style="background-color: #FF5722;">M</div>
|
||||
<div class="app-icon-image" style="background-color: #FF5722;"><img src="../icons/maps.tga"/></div>
|
||||
<span class="app-icon-label">Maps</span>
|
||||
</div>
|
||||
|
||||
<!-- Row 4 -->
|
||||
<div class="app-icon">
|
||||
<div class="app-icon-image" style="background-color: #8BC34A;">S</div>
|
||||
<div class="app-icon-image" style="background-color: #8BC34A;"><img src="../icons/store.tga"/></div>
|
||||
<span class="app-icon-label">Store</span>
|
||||
</div>
|
||||
<div class="app-icon">
|
||||
<div class="app-icon-image" style="background-color: #CDDC39;">F</div>
|
||||
<div class="app-icon-image" style="background-color: #CDDC39;"><img src="../icons/files.tga"/></div>
|
||||
<span class="app-icon-label">Files</span>
|
||||
</div>
|
||||
<div class="app-icon">
|
||||
<div class="app-icon-image" style="background-color: #FFC107;">C</div>
|
||||
<div class="app-icon-image" style="background-color: #FFC107;"><img src="../icons/calculator.tga"/></div>
|
||||
<span class="app-icon-label">Calculator</span>
|
||||
</div>
|
||||
<div class="app-icon">
|
||||
<div class="app-icon-image" style="background-color: #673AB7;">W</div>
|
||||
<div class="app-icon-image" style="background-color: #673AB7;"><img src="../icons/weather.tga"/></div>
|
||||
<span class="app-icon-label">Weather</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -117,10 +126,10 @@
|
||||
|
||||
<!-- Dock -->
|
||||
<div class="dock">
|
||||
<div class="dock-item" style="background-color: #4CAF50;" onclick="navigateTo('dialer')">P</div>
|
||||
<div class="dock-item" style="background-color: #2196F3;" onclick="navigateTo('messages')">M</div>
|
||||
<div class="dock-item" style="background-color: #FF9800;" onclick="navigateTo('contacts')">C</div>
|
||||
<div class="dock-item" style="background-color: #F44336;" onclick="navigateTo('browser')">B</div>
|
||||
<div class="dock-item" style="background-color: #4CAF50;" onclick="navigateTo('dialer')"><img src="../icons/phone.tga"/></div>
|
||||
<div class="dock-item" style="background-color: #2196F3;" onclick="navigateTo('messages')"><img src="../icons/message.tga"/></div>
|
||||
<div class="dock-item" style="background-color: #FF9800;" onclick="navigateTo('contacts')"><img src="../icons/contacts.tga"/></div>
|
||||
<div class="dock-item" style="background-color: #F44336;" onclick="navigateTo('browser')"><img src="../icons/browser.tga"/></div>
|
||||
</div>
|
||||
</body>
|
||||
</rml>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<rml>
|
||||
<head>
|
||||
<link type="text/rcss" href="../ui/html.rcss"/>
|
||||
<link type="text/rcss" href="../ui/theme.rcss"/>
|
||||
<link type="text/rcss" href="../ui/components.rcss"/>
|
||||
<script src="../scripts/navigation.lua"></script>
|
||||
@@ -168,8 +169,8 @@
|
||||
|
||||
<!-- Shortcuts -->
|
||||
<div class="lock-shortcuts">
|
||||
<div class="lock-shortcut" onclick="navigateTo('dialer')">P</div>
|
||||
<div class="lock-shortcut">C</div>
|
||||
<div class="lock-shortcut" onclick="navigateTo('dialer')"><img src="../icons/phone.tga" style="width: 32px; height: 32px;"/></div>
|
||||
<div class="lock-shortcut"><img src="../icons/camera.tga" style="width: 32px; height: 32px;"/></div>
|
||||
</div>
|
||||
</body>
|
||||
</rml>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<rml>
|
||||
<head>
|
||||
<link type="text/rcss" href="../ui/html.rcss"/>
|
||||
<link type="text/rcss" href="../ui/theme.rcss"/>
|
||||
<link type="text/rcss" href="../ui/components.rcss"/>
|
||||
<script src="../scripts/navigation.lua"></script>
|
||||
@@ -131,9 +132,9 @@
|
||||
<body class="messages-screen">
|
||||
<!-- App Bar -->
|
||||
<div class="app-bar">
|
||||
<div class="btn-icon" onclick="goBack()">←</div>
|
||||
<div class="btn-icon" onclick="goBack()"><img src="../icons/back.tga" style="width: 24px; height: 24px;"/></div>
|
||||
<span class="app-bar-title">Messages</span>
|
||||
<div class="btn-icon">Q</div>
|
||||
<div class="btn-icon"><img src="../icons/search.tga" style="width: 24px; height: 24px;"/></div>
|
||||
</div>
|
||||
|
||||
<!-- Conversations List -->
|
||||
@@ -218,6 +219,6 @@
|
||||
</div>
|
||||
|
||||
<!-- FAB -->
|
||||
<div class="btn-fab">+</div>
|
||||
<div class="btn-fab"><img src="../icons/add.tga" style="width: 24px; height: 24px;"/></div>
|
||||
</body>
|
||||
</rml>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<rml>
|
||||
<head>
|
||||
<link type="text/rcss" href="../ui/html.rcss"/>
|
||||
<link type="text/rcss" href="../ui/theme.rcss"/>
|
||||
<link type="text/rcss" href="../ui/components.rcss"/>
|
||||
<script src="../scripts/navigation.lua"></script>
|
||||
@@ -149,9 +150,9 @@
|
||||
<body class="settings-screen">
|
||||
<!-- App Bar -->
|
||||
<div class="app-bar">
|
||||
<div class="btn-icon" onclick="goBack()">←</div>
|
||||
<div class="btn-icon" onclick="goBack()"><img src="../icons/back.tga" style="width: 24px; height: 24px;"/></div>
|
||||
<span class="app-bar-title">Settings</span>
|
||||
<div class="btn-icon">Q</div>
|
||||
<div class="btn-icon"><img src="../icons/search.tga" style="width: 24px; height: 24px;"/></div>
|
||||
</div>
|
||||
|
||||
<!-- Settings List -->
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
-- Screen registry - maps screen names to RML file paths
|
||||
local screens = {
|
||||
home = "demo.rml",
|
||||
home = "screens/home.rml",
|
||||
lock = "screens/lock.rml",
|
||||
dialer = "screens/dialer.rml",
|
||||
contacts = "screens/contacts.rml",
|
||||
@@ -12,27 +12,36 @@ local screens = {
|
||||
browser = "screens/browser.rml"
|
||||
}
|
||||
|
||||
-- Navigation history stack
|
||||
local history = {}
|
||||
-- Use global state to persist across document loads
|
||||
-- Initialize only if not already set
|
||||
if not _G.nav_state then
|
||||
_G.nav_state = {
|
||||
history = {},
|
||||
current_screen = "home"
|
||||
}
|
||||
end
|
||||
|
||||
-- Current screen name
|
||||
local current_screen = "home"
|
||||
-- Local references for convenience
|
||||
local history = _G.nav_state.history
|
||||
local function get_current() return _G.nav_state.current_screen end
|
||||
local function set_current(s) _G.nav_state.current_screen = s end
|
||||
|
||||
-- Navigate to a screen by name
|
||||
function navigateTo(screen_name)
|
||||
print("navigateTo called with: " .. tostring(screen_name))
|
||||
local path = screens[screen_name]
|
||||
if path then
|
||||
-- Push current screen to history before navigating
|
||||
table.insert(history, current_screen)
|
||||
current_screen = screen_name
|
||||
table.insert(history, get_current())
|
||||
set_current(screen_name)
|
||||
|
||||
-- Load the new screen using C++ function
|
||||
local success = loadScreen(path)
|
||||
if success then
|
||||
print("Navigated to: " .. screen_name)
|
||||
print("Navigated to: " .. screen_name .. " (history depth: " .. #history .. ")")
|
||||
else
|
||||
-- Restore previous state on failure
|
||||
current_screen = table.remove(history)
|
||||
set_current(table.remove(history))
|
||||
print("Failed to navigate to: " .. screen_name)
|
||||
end
|
||||
return success
|
||||
@@ -44,11 +53,12 @@ end
|
||||
|
||||
-- Go back to previous screen
|
||||
function goBack()
|
||||
print("goBack called (history depth: " .. #history .. ")")
|
||||
if #history > 0 then
|
||||
local previous = table.remove(history)
|
||||
local path = screens[previous]
|
||||
if path then
|
||||
current_screen = previous
|
||||
set_current(previous)
|
||||
loadScreen(path)
|
||||
print("Back to: " .. previous)
|
||||
return true
|
||||
@@ -61,15 +71,18 @@ end
|
||||
|
||||
-- Go to home screen (clear history)
|
||||
function goHome()
|
||||
history = {}
|
||||
current_screen = "home"
|
||||
-- Clear the history table
|
||||
for i = #history, 1, -1 do
|
||||
history[i] = nil
|
||||
end
|
||||
set_current("home")
|
||||
loadScreen(screens.home)
|
||||
print("Navigated to home")
|
||||
end
|
||||
|
||||
-- Get current screen name
|
||||
function getCurrentScreen()
|
||||
return current_screen
|
||||
return get_current()
|
||||
end
|
||||
|
||||
-- Check if we can go back
|
||||
@@ -79,7 +92,9 @@ end
|
||||
|
||||
-- Clear navigation history
|
||||
function clearHistory()
|
||||
history = {}
|
||||
for i = #history, 1, -1 do
|
||||
history[i] = nil
|
||||
end
|
||||
end
|
||||
|
||||
-- Get history depth
|
||||
@@ -87,4 +102,4 @@ function getHistoryDepth()
|
||||
return #history
|
||||
end
|
||||
|
||||
print("Navigation system initialized")
|
||||
print("Navigation system initialized (current: " .. get_current() .. ", history: " .. #history .. ")")
|
||||
|
||||
124
main.cpp
@@ -29,6 +29,86 @@ struct AppState {
|
||||
std::filesystem::path assets_path;
|
||||
} g_app;
|
||||
|
||||
// Custom system interface to enable logging
|
||||
class LoggingSystemInterface : public Rml::SystemInterface {
|
||||
public:
|
||||
LoggingSystemInterface(Rml::SystemInterface* backend) : backend_(backend) {}
|
||||
|
||||
double GetElapsedTime() override { return backend_->GetElapsedTime(); }
|
||||
|
||||
bool LogMessage(Rml::Log::Type type, const Rml::String& message) override {
|
||||
const char* type_str = "";
|
||||
switch (type) {
|
||||
case Rml::Log::LT_ERROR: type_str = "ERROR"; break;
|
||||
case Rml::Log::LT_WARNING: type_str = "WARNING"; break;
|
||||
case Rml::Log::LT_INFO: type_str = "INFO"; break;
|
||||
case Rml::Log::LT_DEBUG: type_str = "DEBUG"; break;
|
||||
default: type_str = "LOG"; break;
|
||||
}
|
||||
std::println("[RmlUi {}] {}", type_str, message);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Forward JoinPath to fix Windows path issues
|
||||
void JoinPath(Rml::String& translated_path, const Rml::String& document_path, const Rml::String& path) override {
|
||||
// Fix paths where colon was converted to pipe (D| -> D:)
|
||||
std::string fixed_path = path;
|
||||
if (fixed_path.length() >= 2 && fixed_path[1] == '|') {
|
||||
fixed_path[1] = ':';
|
||||
}
|
||||
|
||||
std::string fixed_doc = document_path;
|
||||
if (fixed_doc.length() >= 2 && fixed_doc[1] == '|') {
|
||||
fixed_doc[1] = ':';
|
||||
}
|
||||
|
||||
// Use std::filesystem to join paths properly and normalize (resolve ..)
|
||||
std::filesystem::path doc_dir = std::filesystem::path(fixed_doc).parent_path();
|
||||
std::filesystem::path result = (doc_dir / fixed_path).lexically_normal();
|
||||
translated_path = result.generic_string();
|
||||
std::println("JoinPath: {} + {} -> {}", fixed_doc, fixed_path, translated_path);
|
||||
}
|
||||
|
||||
private:
|
||||
Rml::SystemInterface* backend_;
|
||||
};
|
||||
|
||||
static LoggingSystemInterface* g_logging_interface = nullptr;
|
||||
|
||||
// Custom file interface to fix Windows path issues (D| -> D:)
|
||||
class WindowsFileInterface : public Rml::FileInterface {
|
||||
public:
|
||||
Rml::FileHandle Open(const Rml::String& path) override {
|
||||
// Fix paths where colon was converted to pipe (D| -> D:)
|
||||
std::string fixed_path = path;
|
||||
if (fixed_path.length() >= 2 && fixed_path[1] == '|') {
|
||||
fixed_path[1] = ':';
|
||||
}
|
||||
std::println("FileInterface::Open: {} -> {}", path, fixed_path);
|
||||
|
||||
FILE* fp = fopen(fixed_path.c_str(), "rb");
|
||||
return reinterpret_cast<Rml::FileHandle>(fp);
|
||||
}
|
||||
|
||||
void Close(Rml::FileHandle file) override {
|
||||
fclose(reinterpret_cast<FILE*>(file));
|
||||
}
|
||||
|
||||
size_t Read(void* buffer, size_t size, Rml::FileHandle file) override {
|
||||
return fread(buffer, 1, size, reinterpret_cast<FILE*>(file));
|
||||
}
|
||||
|
||||
bool Seek(Rml::FileHandle file, long offset, int origin) override {
|
||||
return fseek(reinterpret_cast<FILE*>(file), offset, origin) == 0;
|
||||
}
|
||||
|
||||
size_t Tell(Rml::FileHandle file) override {
|
||||
return ftell(reinterpret_cast<FILE*>(file));
|
||||
}
|
||||
};
|
||||
|
||||
static WindowsFileInterface* g_file_interface = nullptr;
|
||||
|
||||
void load_fonts(const std::filesystem::path& dir)
|
||||
{
|
||||
for (const auto& file : std::filesystem::directory_iterator(dir))
|
||||
@@ -44,13 +124,15 @@ void load_fonts(const std::filesystem::path& dir)
|
||||
// Path is relative to assets folder
|
||||
int lua_loadScreen(lua_State* L)
|
||||
{
|
||||
std::println("lua_loadScreen called!");
|
||||
const char* path = luaL_checkstring(L, 1);
|
||||
std::println("Loading: {}", path);
|
||||
|
||||
std::filesystem::path full_path = g_app.assets_path / path;
|
||||
|
||||
if (!std::filesystem::exists(full_path))
|
||||
{
|
||||
std::println("Screen not found: {}", full_path.string());
|
||||
std::println("Screen not found: {}", full_path.generic_string());
|
||||
lua_pushboolean(L, false);
|
||||
return 1;
|
||||
}
|
||||
@@ -62,8 +144,10 @@ int lua_loadScreen(lua_State* L)
|
||||
g_app.document = nullptr;
|
||||
}
|
||||
|
||||
// Load new document
|
||||
g_app.document = g_app.context->LoadDocument(full_path.string());
|
||||
// Load new document with absolute path
|
||||
std::string full_path_str = full_path.generic_string();
|
||||
std::println("Full path: {}", full_path_str);
|
||||
g_app.document = g_app.context->LoadDocument(full_path_str);
|
||||
if (g_app.document)
|
||||
{
|
||||
g_app.document->Show();
|
||||
@@ -233,10 +317,15 @@ int main(const int argc, const char* argv[])
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
Rml::SetSystemInterface(Backend::GetSystemInterface());
|
||||
// Use custom interfaces
|
||||
g_logging_interface = new LoggingSystemInterface(Backend::GetSystemInterface());
|
||||
g_file_interface = new WindowsFileInterface();
|
||||
Rml::SetSystemInterface(g_logging_interface);
|
||||
Rml::SetFileInterface(g_file_interface);
|
||||
Rml::SetRenderInterface(Backend::GetRenderInterface());
|
||||
Rml::Initialise();
|
||||
Rml::Lua::Initialise();
|
||||
std::println("RmlUi and Lua initialized");
|
||||
|
||||
g_app.context = Rml::CreateContext("main", Rml::Vector2i(window_width, window_height));
|
||||
if (!g_app.context)
|
||||
@@ -249,14 +338,18 @@ int main(const int argc, const char* argv[])
|
||||
// Register custom Lua functions
|
||||
registerLuaFunctions();
|
||||
|
||||
// Find the assets folder by checking for fonts
|
||||
// Find the assets folder by checking for fonts/ subdirectory
|
||||
g_app.assets_path = std::filesystem::absolute(file.parent_path());
|
||||
|
||||
// Walk up the directory tree to find a folder containing .ttf fonts
|
||||
// Walk up the directory tree to find a folder containing a fonts/ subdirectory with .ttf files
|
||||
std::filesystem::path fonts_path;
|
||||
while (!g_app.assets_path.empty() && g_app.assets_path.has_parent_path())
|
||||
{
|
||||
fonts_path = g_app.assets_path / "fonts";
|
||||
if (std::filesystem::exists(fonts_path) && std::filesystem::is_directory(fonts_path))
|
||||
{
|
||||
bool has_fonts = false;
|
||||
for (const auto& entry : std::filesystem::directory_iterator(g_app.assets_path))
|
||||
for (const auto& entry : std::filesystem::directory_iterator(fonts_path))
|
||||
{
|
||||
if (entry.path().extension() == ".ttf")
|
||||
{
|
||||
@@ -265,15 +358,26 @@ int main(const int argc, const char* argv[])
|
||||
}
|
||||
}
|
||||
if (has_fonts) break;
|
||||
}
|
||||
g_app.assets_path = g_app.assets_path.parent_path();
|
||||
}
|
||||
|
||||
load_fonts(g_app.assets_path);
|
||||
load_fonts(fonts_path);
|
||||
|
||||
g_app.document = g_app.context->LoadDocument(file.string());
|
||||
// Load document with absolute path
|
||||
std::filesystem::path abs_file = std::filesystem::absolute(file);
|
||||
std::string abs_file_str = abs_file.generic_string();
|
||||
std::println("Loading document: {}", abs_file_str);
|
||||
std::println("Assets path: {}", g_app.assets_path.generic_string());
|
||||
g_app.document = g_app.context->LoadDocument(abs_file_str);
|
||||
if (g_app.document)
|
||||
{
|
||||
g_app.document->Show();
|
||||
std::println("Document loaded successfully");
|
||||
}
|
||||
else
|
||||
{
|
||||
std::println("Failed to load document!");
|
||||
}
|
||||
|
||||
// Dump mode: render and capture screenshot
|
||||
@@ -350,7 +454,7 @@ int main(const int argc, const char* argv[])
|
||||
g_app.context->UnloadDocument(g_app.document);
|
||||
g_app.context->Update();
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
g_app.document = g_app.context->LoadDocument(file.string());
|
||||
g_app.document = g_app.context->LoadDocument(abs_file_str);
|
||||
if (g_app.document)
|
||||
{
|
||||
g_app.document->ReloadStyleSheet();
|
||||
|
||||