save state
This commit is contained in:
6
.gitignore
vendored
6
.gitignore
vendored
@@ -1 +1,7 @@
|
|||||||
/build
|
/build
|
||||||
|
/.idea
|
||||||
|
/.vs
|
||||||
|
/build
|
||||||
|
/build_test
|
||||||
|
/cmake-build*
|
||||||
|
/out
|
||||||
|
|||||||
73
AGENTS.md
Normal file
73
AGENTS.md
Normal 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
55
CLAUDE.md
Normal 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
|
||||||
@@ -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
|
||||||
)
|
)
|
||||||
@@ -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
93
assets/html.rcss
Normal 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;
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
}
|
}
|
||||||
61
main.cpp
61
main.cpp
@@ -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();
|
||||||
|
|||||||
Reference in New Issue
Block a user