save state

This commit is contained in:
2026-01-15 17:57:24 +01:00
parent 1f8f06de2a
commit 6ad11773dd
8 changed files with 320 additions and 58 deletions

6
.gitignore vendored
View File

@@ -1 +1,7 @@
/build /build
/.idea
/.vs
/build
/build_test
/cmake-build*
/out

73
AGENTS.md Normal file
View File

@@ -0,0 +1,73 @@
# Mosis Designer Agent Guidelines
## Build, Lint, and Test Commands
### Build Commands
- `cmake --build build --config Debug` - Build the project in debug mode
- `cmake --build build --config Release` - Build the project in release mode
- `cmake -B build` - Configure the build system
- `cmake --build build --parallel 4` - Build with 4 parallel jobs
### Lint Commands
- No specific linting tools configured
- Uses C++23 standard with clang-tidy if available
### Test Commands
- No unit tests configured
- Manual testing required for functionality verification
## Code Style Guidelines
### General
- Follow C++23 standard with modern C++ features
- Use snake_case for variable and function names
- Use camelCase for class and struct names
- Use uppercase for constants and enum values
### Naming Conventions
- Functions: camelCase
- Variables: snake_case
- Classes/Structs: camelCase
- Constants: UPPER_CASE
- Enums: UPPER_CASE with prefix (e.g., `enum class FileType { XML, RML };`)
### Includes and Imports
- Use angle brackets for system headers: `#include <iostream>`
- Use quotes for local headers: `#include "header.h"`
- Group includes: system headers, then local headers
- Sort includes alphabetically within groups
### Formatting
- 4 spaces for indentation (no tabs)
- No trailing whitespace
- Unix line endings (\n)
- One statement per line
- Function definitions: space after function name, no space before opening parenthesis
- If statements: space after keyword, no space before opening parenthesis
### Error Handling
- Use exceptions for error conditions
- Check return values of system calls
- Prefer early returns over nested conditionals
- Use constexpr for compile-time constants
### Memory Management
- Prefer stack allocation over heap
- Use smart pointers (std::unique_ptr, std::shared_ptr)
- Avoid raw pointers when possible
- Use RAII principles
### Documentation
- Document public APIs with comments
- Use Doxygen-style comments for functions and classes
- Keep comments concise and clear
## Special Rules
### Cursor Rules
- No cursor rules configured
- No .cursorrules file found
### Copilot Rules
- No copilot instructions configured
- No .github/copilot-instructions.md file found

55
CLAUDE.md Normal file
View File

@@ -0,0 +1,55 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
Mosis Designer is a Windows desktop application for previewing RML/RCSS files using the RmlUi library. It provides live reloading when files change in the assets directory.
## Build Commands
```bash
# Configure the build (requires vcpkg for glfw3 and freetype)
cmake -B build
# Build debug
cmake --build build --config Debug
# Build release
cmake --build build --config Release
# Build with parallel jobs
cmake --build build --parallel 4
```
## Running the Application
```bash
# Run with an RML file
./build/Debug/mosis-designer.exe assets/demo.rml
```
The application watches the parent directory of the loaded file for changes and automatically reloads.
## Architecture
Single-file C++23 application (`main.cpp`) that:
- Uses RmlUi for rendering HTML/CSS-like markup (RML/RCSS)
- Uses GLFW + OpenGL 3 backend from RmlUi
- Windows-specific file watching via `FindFirstChangeNotification`
- Automatically loads all `.ttf` fonts from the RML file's directory
## Dependencies
- **RmlUi**: Fetched via CMake FetchContent from GitHub
- **GLFW3**: Via vcpkg
- **FreeType**: Via vcpkg
## Code Style
- C++23 standard
- 4 spaces indentation
- snake_case for variables, camelCase for functions/classes
- UPPER_CASE for constants and enums
- Early returns preferred over nested conditionals
- Smart pointers over raw pointers

View File

@@ -4,20 +4,36 @@ project("mosis-designer")
set(CMAKE_CXX_STANDARD 23) set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(RmlUi CONFIG REQUIRED) # Use FetchContent for RmlUi
find_package(glfw3 CONFIG REQUIRED) include(FetchContent)
set(RMLUI_BACKEND "D:/vcpkg/buildtrees/rmlui/src/6.1-fbf6dfc3b5.clean/Backends") # Fetch RmlUi from GitHub
FetchContent_Declare(
rmlui
GIT_REPOSITORY https://github.com/mikke89/RmlUi.git
GIT_TAG master
)
FetchContent_MakeAvailable(rmlui)
# Find other dependencies via vcpkg
find_package(glfw3 CONFIG REQUIRED)
find_package(freetype CONFIG REQUIRED)
# Get the RmlUi source directory for include paths
FetchContent_GetProperties(rmlui)
set(RMLUI_SOURCE_DIR ${rmlui_SOURCE_DIR})
add_executable(mosis-designer add_executable(mosis-designer
main.cpp main.cpp
${RMLUI_BACKEND}/RmlUi_Backend_GLFW_GL3.cpp ${rmlui_SOURCE_DIR}/Backends/RmlUi_Backend_GLFW_GL3.cpp
${RMLUI_BACKEND}/RmlUi_Platform_GLFW.cpp ${rmlui_SOURCE_DIR}/Backends/RmlUi_Platform_GLFW.cpp
${RMLUI_BACKEND}/RmlUi_Renderer_GL3.cpp ${rmlui_SOURCE_DIR}/Backends/RmlUi_Renderer_GL3.cpp
) )
target_link_libraries(mosis-designer PUBLIC target_link_libraries(mosis-designer PUBLIC
RmlUi::RmlUi glfw RmlUi::RmlUi glfw freetype
) )
target_include_directories(mosis-designer PUBLIC target_include_directories(mosis-designer PUBLIC
${RMLUI_BACKEND} ${RMLUI_SOURCE_DIR}
${RMLUI_SOURCE_DIR}/Backends
) )

View File

@@ -1,5 +1,6 @@
<rml> <rml>
<head> <head>
<link type="text/rcss" href="html.rcss"/>
<link type="text/rcss" href="phone.rcss"/> <link type="text/rcss" href="phone.rcss"/>
<title>Fullscreen Mobile UI</title> <title>Fullscreen Mobile UI</title>
</head> </head>
@@ -9,13 +10,16 @@
<div class="status-icons"> <div class="status-icons">
<span class="icon">📶</span> <span class="icon">📶</span>
<span class="icon">🔋</span> <span class="icon">🔋</span>
<span class="icon">📶</span>
<span class="icon">🔋</span>
<span class="icon">📶</span>
<span class="icon">🔋</span>
</div> </div>
</div> </div>
<div id="content"> <div id="content">
<div class="header-section"> <div class="header-section">
<h1>Activity</h1> <h1>Hello omar 3 hello! and hello LEO 2 Hello!</h1>
<p>Monday, January 5</p>
</div> </div>
</div> </div>
@@ -23,6 +27,9 @@
<div class="nav-item">Home</div> <div class="nav-item">Home</div>
<div class="nav-item">Apps</div> <div class="nav-item">Apps</div>
<div class="nav-item">Settings</div> <div class="nav-item">Settings</div>
<div class="nav-item">Home</div>
<div class="nav-item">Apps</div>
<div class="nav-item">Settings</div>
</div> </div>
</body> </body>
</rml> </rml>

93
assets/html.rcss Normal file
View File

@@ -0,0 +1,93 @@
body, div,
h1, h2, h3, h4,
h5, h6, p,
hr, pre,
tabset tabs
{
display: block;
}
h1
{
font-size: 2em;
margin: .67em 0;
}
h2
{
font-size: 1.5em;
margin: .75em 0;
}
h3
{
font-size: 1.17em;
margin: .83em 0;
}
h4, p
{
margin: 1.12em 0;
}
h5
{
font-size: .83em;
margin: 1.5em 0;
}
h6
{
font-size: .75em;
margin: 1.67em 0;
}
h1, h2, h3, h4,
h5, h6, strong
{
font-weight: bold;
}
em
{
font-style: italic;
}
pre
{
white-space: pre;
}
hr
{
border-width: 1px;
}
table
{
box-sizing: border-box;
display: table;
}
tr
{
box-sizing: border-box;
display: table-row;
}
td
{
box-sizing: border-box;
display: table-cell;
}
col
{
box-sizing: border-box;
display: table-column;
}
colgroup
{
display: table-column-group;
}
thead, tbody, tfoot
{
display: table-row-group;
}

View File

@@ -12,19 +12,20 @@ body {
/* Status Bar pinned to top */ /* Status Bar pinned to top */
#status-bar { #status-bar {
display: block; display: block;
height: 40px; height: 140px;
padding: 10px 20px 0; padding: 10px 20px 0;
background-color: rgba(0, 0, 0, 0.2); background-color: rgba(255, 0, 0, 0.2);
} }
.time { .time {
float: left; float: left;
font-weight: bold; font-weight: bold;
font-size: 1.1em; font-size: 2em;
} }
.status-icons { .status-icons {
float: right; float: right;
font-size: 2em;
} }
.icon { .icon {
@@ -94,8 +95,16 @@ h1 {
.nav-item { .nav-item {
font-size: 1.9em; font-size: 1.9em;
color: #888; color: #888;
background-color: red;
width: 100px;
height: 100px;
text-align: center;
vertical-align: middle;
line-height: 90px;
border-radius: 10px;
} }
.nav-item:hover { .nav-item:hover {
color: #3498db; color: #3498db;
background-color: blue;
} }

View File

@@ -2,39 +2,44 @@
#include <thread> #include <thread>
#include <chrono> #include <chrono>
#include <filesystem> #include <filesystem>
#include <iostream>
#include <RmlUi/Core.h> #include <RmlUi/Core.h>
#include <RmlUi/Debugger.h> #include <RmlUi/Debugger.h>
#include <RmlUi_Backend.h> #include <RmlUi_Backend.h>
#include <RmlUi_Include_Windows.h> #include <RmlUi_Include_Windows.h>
void load_fonts() void load_fonts(const std::filesystem::path& dir)
{ {
const Rml::String directory = "assets/"; for (const auto& file : std::filesystem::directory_iterator(dir))
{
struct FontFace { if (file.path().extension() == ".ttf")
const char* filename; {
bool fallback_face; Rml::LoadFontFace(file.path().string());
}; }
FontFace font_faces[] = { }
{"LatoLatin-Regular.ttf", false},
{"LatoLatin-Italic.ttf", false},
{"LatoLatin-Bold.ttf", false},
{"LatoLatin-BoldItalic.ttf", false},
{"NotoEmoji-Regular.ttf", true},
};
for (const FontFace& face : font_faces)
Rml::LoadFontFace(directory + face.filename, face.fallback_face);
} }
int main() int main(const int argc, const char* argv[])
{ {
const int window_width = 1024; constexpr int window_width = 540;
const int window_height = 768; constexpr int window_height = 960;
if (argc < 2)
{
std::println("Usage: mosis-designer file.rml");
return EXIT_FAILURE;
}
const std::filesystem::path file = argv[1];
if (!std::filesystem::exists(file))
{
std::println("File does not exist");
return EXIT_FAILURE;
}
if (!Backend::Initialize("Load Document Sample", window_width, window_height, true)) if (!Backend::Initialize("Load Document Sample", window_width, window_height, true))
{ {
return -1; return EXIT_FAILURE;
} }
Rml::SetSystemInterface(Backend::GetSystemInterface()); Rml::SetSystemInterface(Backend::GetSystemInterface());
@@ -46,21 +51,19 @@ int main()
{ {
Rml::Shutdown(); Rml::Shutdown();
Backend::Shutdown(); Backend::Shutdown();
return -1; return EXIT_FAILURE;
} }
load_fonts(); const std::filesystem::path assets_path = std::filesystem::absolute(file.parent_path());
load_fonts(assets_path);
Rml::ElementDocument* document = context->LoadDocument("assets/demo.rml"); Rml::ElementDocument* document = context->LoadDocument(file.string());
if (document) if (document)
{ {
document->Show(); document->Show();
} }
const std::wstring assets_path = std::filesystem::absolute( const HANDLE hNotif = FindFirstChangeNotification(assets_path.c_str(),
std::filesystem::current_path() / "assets").wstring();
HANDLE hNotif = FindFirstChangeNotification(assets_path.c_str(),
TRUE, FILE_NOTIFY_CHANGE_LAST_WRITE); TRUE, FILE_NOTIFY_CHANGE_LAST_WRITE);
bool running = true; bool running = true;
@@ -73,7 +76,7 @@ int main()
context->UnloadDocument(document); context->UnloadDocument(document);
context->Update(); context->Update();
std::this_thread::sleep_for(std::chrono::milliseconds(100)); std::this_thread::sleep_for(std::chrono::milliseconds(100));
document = context->LoadDocument("assets/demo.rml"); document = context->LoadDocument(file.string());
if (document) if (document)
{ {
document->ReloadStyleSheet(); document->ReloadStyleSheet();