This commit is contained in:
Jorijn van der Graaf 2025-11-12 20:45:35 +01:00
commit 9651d84dc4
8 changed files with 239 additions and 207 deletions

View file

@ -1,193 +1,26 @@
import Crafter.CppDOM;
using namespace Crafter;
using namespace Crafter::CppDOM;
using namespace Crafter::CppDOMBindings;
import std;
// Create the main container element
HtmlElementView* body = new HtmlElementView("body", "<div id='container'>"
"<h1>Enhanced Event Handling Demo</h1>"
"<div id='events-container'>"
"<div class='event-section'>"
"<h2>Mouse Events</h2>"
"<button id='mouseButton'>Click Me!</button>"
"<div id='mouseOutput'></div>"
"</div>"
"<div class='event-section'>"
"<h2>Keyboard Events</h2>"
"<input type='text' id='keyInput' placeholder='Press keys here'>"
"<div id='keyOutput'></div>"
"</div>"
"<div class='event-section'>"
"<h2>Focus Events</h2>"
"<input type='text' id='focusInput' placeholder='Focus me!'>"
"<div id='focusOutput'></div>"
"</div>"
"<div class='event-section'>"
"<h2>Form Events</h2>"
"<form id='formElement'>"
"<input type='text' id='formInput' placeholder='Type something'>"
"<select id='formSelect'>"
"<option value='option1'>Option 1</option>"
"<option value='option2'>Option 2</option>"
"<option value='option3'>Option 3</option>"
"</select>"
"<button type='submit'>Submit Form</button>"
"</form>"
"<div id='formOutput'></div>"
"</div>"
"<div class='event-section'>"
"<h2>Window Events</h2>"
"<div id='windowOutput'></div>"
"</div>"
"<div class='event-section'>"
"<h2>Drag & Drop Events</h2>"
"<div id='dragSource' draggable='true'>Drag Me!</div>"
"<div id='dropTarget'>Drop Here</div>"
"<div id='dragOutput'></div>"
"</div>"
"<div class='event-section'>"
"<h2>Wheel Events</h2>"
"<div id='wheelContainer'>Scroll here</div>"
"<div id='wheelOutput'></div>"
"</div>"
"</div>"
"</div>");
// Get references to elements
HtmlElementView* mouseButton = new HtmlElementView("mouseButton");
HtmlElementView* mouseOutput = new HtmlElementView("mouseOutput");
HtmlElementView* keyInput = new HtmlElementView("keyInput");
HtmlElementView* keyOutput = new HtmlElementView("keyOutput");
HtmlElementView* focusInput = new HtmlElementView("focusInput");
HtmlElementView* focusOutput = new HtmlElementView("focusOutput");
HtmlElementView* formInput = new HtmlElementView("formInput");
HtmlElementView* formSelect = new HtmlElementView("formSelect");
HtmlElementView* formElement = new HtmlElementView("formElement");
HtmlElementView* formOutput = new HtmlElementView("formOutput");
HtmlElementView* windowOutput = new HtmlElementView("windowOutput");
HtmlElementView* dragSource = new HtmlElementView("dragSource");
HtmlElementView* dropTarget = new HtmlElementView("dropTarget");
HtmlElementView* dragOutput = new HtmlElementView("dragOutput");
HtmlElementView* wheelContainer = new HtmlElementView("wheelContainer");
HtmlElementView* wheelOutput = new HtmlElementView("wheelOutput");
int main() {
// Mouse Events
mouseButton->AddClickListener([&](MouseEvent event) {
mouseOutput->SetInnerHTML(std::format("<p><strong>Click:</strong> X={}, Y={}</p>", event.clientX, event.clientY));
HtmlElementView body("body");
body.SetInnerHTML("<h1>All Event Handling</h1>");
HtmlElementView div("div");
div.SetInnerHTML("<p>Click me!</p>");
div.SetStyle("padding: 20px; background-color: lightblue; cursor: pointer;");
// Add click handler
div.AddClickListener([](Crafter::MouseEvent e) {
std::cout << "Clicked!" << std::endl;
});
mouseButton->AddMouseOverListener([&](MouseEvent event) {
mouseOutput->SetInnerHTML(std::format("<p><strong>Mouse Over:</strong> X={}, Y={}</p>", event.clientX, event.clientY));
});
mouseButton->AddMouseOutListener([&](MouseEvent event) {
mouseOutput->SetInnerHTML(std::format("<p><strong>Mouse Out:</strong> X={}, Y={}</p>", event.clientX, event.clientY));
});
mouseButton->AddMouseMoveListener([&](MouseEvent event) {
mouseOutput->SetInnerHTML(std::format("<p><strong>Mouse Move:</strong> X={}, Y={}</p>", event.clientX, event.clientY));
});
mouseButton->AddMouseDownListener([&](MouseEvent event) {
mouseOutput->SetInnerHTML(std::format("<p><strong>Mouse Down:</strong> Button={}, X={}, Y={}</p>", event.button, event.clientX, event.clientY));
});
mouseButton->AddMouseUpListener([&](MouseEvent event) {
mouseOutput->SetInnerHTML(std::format("<p><strong>Mouse Up:</strong> Button={}, X={}, Y={}</p>", event.button, event.clientX, event.clientY));
});
// Keyboard Events
keyInput->AddKeyDownListener([&](KeyboardEvent event) {
std::string keyInfo = std::format("<p><strong>Key Down:</strong> Key='{}', Code={}, Ctrl={}, Shift={}, Alt={}</p>",
event.key, event.keyCode, event.ctrlKey, event.shiftKey, event.altKey);
keyOutput->SetInnerHTML(keyInfo);
});
keyInput->AddKeyUpListener([&](KeyboardEvent event) {
std::string keyInfo = std::format("<p><strong>Key Up:</strong> Key='{}', Code={}, Ctrl={}, Shift={}, Alt={}</p>",
event.key, event.keyCode, event.ctrlKey, event.shiftKey, event.altKey);
keyOutput->SetInnerHTML(keyInfo);
});
keyInput->AddKeyPressListener([&](KeyboardEvent event) {
std::string keyInfo = std::format("<p><strong>Key Press:</strong> Key='{}', Code={}, Ctrl={}, Shift={}, Alt={}</p>",
event.key, event.keyCode, event.ctrlKey, event.shiftKey, event.altKey);
keyOutput->SetInnerHTML(keyInfo);
});
// Focus Events
focusInput->AddFocusListener([&](FocusEvent event) {
focusOutput->SetInnerHTML("<p><strong>Focus:</strong> Element gained focus</p>");
});
focusInput->AddBlurListener([&](FocusEvent event) {
focusOutput->SetInnerHTML("<p><strong>Blur:</strong> Element lost focus</p>");
});
// Form Events
formInput->AddInputListener([&](InputEvent event) {
formOutput->SetInnerHTML(std::format("<p><strong>Input:</strong> Value='{}'</p>", event.data));
});
formInput->AddChangeListener([&](ChangeEvent event) {
formOutput->SetInnerHTML(std::format("<p><strong>Change:</strong> Value='{}'</p>", event.value));
});
formSelect->AddChangeListener([&](ChangeEvent event) {
formOutput->SetInnerHTML(std::format("<p><strong>Select Change:</strong> Value='{}'</p>", event.value));
});
// Submit Event
formElement->AddSubmitListener([&]() {
formOutput->SetInnerHTML("<p><strong>Submit:</strong> Form submitted successfully!</p>");
});
// Window Events
// Resize event
body->AddResizeListener([&](ResizeEvent event) {
windowOutput->SetInnerHTML(std::format("<p><strong>Resize:</strong> Width={}, Height={}</p>", event.width, event.height));
});
// Scroll event
body->AddScrollListener([&](ScrollEvent event) {
windowOutput->SetInnerHTML(std::format("<p><strong>Scroll:</strong> X={}, Y={}</p>", event.scrollX, event.scrollY));
});
// Context Menu Event
body->AddContextMenuListener([&](MouseEvent event) {
windowOutput->SetInnerHTML(std::format("<p><strong>Context Menu:</strong> X={}, Y={}</p>", event.clientX, event.clientY));
});
// Drag and Drop Events
dragSource->AddDragStartListener([&](MouseEvent event) {
dragOutput->SetInnerHTML("<p><strong>Drag Start:</strong> Dragging started</p>");
});
dragSource->AddDragEndListener([&](MouseEvent event) {
dragOutput->SetInnerHTML("<p><strong>Drag End:</strong> Dragging ended</p>");
});
dropTarget->AddDragOverListener([&](MouseEvent event) {
dragOutput->SetInnerHTML("<p><strong>Drag Over:</strong> Dragging over drop target</p>");
});
dropTarget->AddDragEnterListener([&](MouseEvent event) {
dragOutput->SetInnerHTML("<p><strong>Drag Enter:</strong> Drag entered drop target</p>");
});
dropTarget->AddDragLeaveListener([&](MouseEvent event) {
dragOutput->SetInnerHTML("<p><strong>Drag Leave:</strong> Drag left drop target</p>");
});
dropTarget->AddDropListener([&](MouseEvent event) {
dragOutput->SetInnerHTML("<p><strong>Drop:</strong> Item dropped</p>");
});
// Wheel Event
wheelContainer->AddWheelListener([&](WheelEvent event) {
wheelOutput->SetInnerHTML(std::format("<p><strong>Wheel:</strong> DeltaX={}, DeltaY={}, DeltaZ={}</p>",
event.deltaX, event.deltaY, event.deltaZ));
});
body.AddChild(div);
// Demonstrate new bindings
std::string path = GetPathNameString();
std::cout << "Current path: " << path << std::endl;
return 0;
}

View file

@ -0,0 +1,67 @@
import Crafter.CppDOM;
import std;
using namespace Crafter;
using namespace Crafter::CppDOMBindings;
HtmlElementView* body = new HtmlElementView("body", R"(
<nav>
<h2 style="margin-bottom: 20px; padding: 10px; background-color: #f0f0f0;">SPA Navigation Demo</h2>
<a id="home" style="margin-right: 15px; text-decoration: none; color: blue; cursor: pointer;">Home</a>
<a id="about" style="margin-right: 15px; text-decoration: none; color: blue; cursor: pointer;">About</a>
<a id="contact" style="margin-right: 15px; text-decoration: none; color: blue; cursor: pointer;">Contact</a>
</nav>
<div id="content" style="min-height: 200px; padding: 15px; border: 1px solid #ccc;"></div>
)");
HtmlElementView* home = new HtmlElementView("home");
HtmlElementView* about = new HtmlElementView("about");
HtmlElementView* contact = new HtmlElementView("contact");
HtmlElementView* content = new HtmlElementView("content");
void UpdateContent(const std::string_view page) {
if (page == "home") {
content->SetInnerHTML("<h3>Home Page</h3><p>Welcome to the Home page of our Single Page Application!</p><p>This demo shows how to use the new history.pushState and popstate event handling features.</p>");
} else if (page == "about") {
content->SetInnerHTML("<h3>About Page</h3><p>This is the About page.</p><p>Notice how the URL changes without reloading the page.</p>");
} else if (page == "contact") {
content->SetInnerHTML("<h3>Contact Page</h3><p>This is the Contact page.</p><p>You can navigate back and forth using the browser's back/forward buttons.</p>");
}
}
int main() {
body->SetStyle("font-family: Arial, sans-serif; margin: 0; padding: 20px;");
// Add click handlers for navigation
home->AddClickListener([](Crafter::MouseEvent e) {
PushState("{\"page\": \"home\"}", "Home", "/");
UpdateContent("home");
});
about->AddClickListener([](Crafter::MouseEvent e) {
PushState("{\"page\": \"about\"}", "About", "/about");
UpdateContent("about");
});
contact->AddClickListener([](Crafter::MouseEvent e) {
PushState("{\"page\": \"contact\"}", "Contact", "/contact");
UpdateContent("contact");
});
// Add popstate listener to handle browser back/forward buttons
auto popStateId = AddPopStateListener([]() {
std::string path = GetPathNameString();
if (path == "/") {
UpdateContent("home");
} else if (path == "/about") {
UpdateContent("about");
} else if (path == "/contact") {
UpdateContent("contact");
} else {
UpdateContent("home");
}
});
// Initialize with home page
UpdateContent("home");
return 0;
}

View file

@ -0,0 +1,17 @@
{
"name": "main",
"configurations": [
{
"name": "executable",
"implementations": ["main"],
"target": "wasm32-wasi",
"debug" : true,
"dependencies": [
{
"path":"../../project.json",
"configuration":"lib-debug"
}
]
}
]
}

1
examples/SPAExample/run.sh Executable file
View file

@ -0,0 +1 @@
caddy file-server --listen :8080 --root bin/executable