actually sensible classes

This commit is contained in:
Jorijn van der Graaf 2025-11-25 20:30:54 +01:00
commit c3b8761102
13 changed files with 128 additions and 152 deletions

View file

@ -39,7 +39,8 @@ module;
module Crafter.Graphics:Window_wayland_impl;
import :Window;
import :UiElement;
import :RenderingElement;
import :MouseElement;
import std;
import :Types;
import :Shm;
@ -135,36 +136,40 @@ void WindowWayland::StartSync() {
void RenderElement(RenderingElement* element, WindowWayland* window) {
for (std::int_fast32_t x = element->transform.scaled.x; x - element->transform.scaled.x < element->transform.scaled.width; x++) {
for (std::int_fast32_t y = element->transform.scaled.y; y - element->transform.scaled.y < element->transform.scaled.height; y++) {
if (x >= 0 && x < window->width && y >= 0 && y < window->height) {
Pixel_BU8_GU8_RU8_AU8& dst = window->framebuffer[y * window->width + x];
const Pixel_BU8_GU8_RU8_AU8& src = element->scaled[(y - element->transform.scaled.y) * element->transform.scaled.width + (x - element->transform.scaled.x)];
void RenderElement(Transform* transform, WindowWayland* window) {
RenderingElement* element = dynamic_cast<RenderingElement*>(transform);
if(element) {
for (std::int_fast32_t x = element->scaled.x; x - element->scaled.x < element->scaled.width; x++) {
for (std::int_fast32_t y = element->scaled.y; y - element->scaled.y < element->scaled.height; y++) {
if (x >= 0 && x < window->width && y >= 0 && y < window->height) {
Pixel_BU8_GU8_RU8_AU8& dst = window->framebuffer[y * window->width + x];
const Pixel_BU8_GU8_RU8_AU8& src = element->bufferScaled[(y - element->scaled.y) * element->scaled.width + (x - element->scaled.x)];
float srcA = src.a / 255.0f;
float dstA = dst.a / 255.0f;
float srcA = src.a / 255.0f;
float dstA = dst.a / 255.0f;
float outA = srcA + dstA * (1.0f - srcA);
if (outA > 0.0f) {
dst = {
static_cast<uint8_t>((src.b * srcA + dst.b * dstA * (1.0f - srcA)) / outA),
static_cast<uint8_t>((src.g * srcA + dst.g * dstA * (1.0f - srcA)) / outA),
static_cast<uint8_t>((src.r * srcA + dst.r * dstA * (1.0f - srcA)) / outA),
static_cast<uint8_t>(outA * 255)
};
}
}
}
}
std::sort(element->transform.children.begin(), element->transform.children.end(), [](Transform* a, Transform* b){ return a->z < b->z; });
for(Transform* child : element->transform.children) {
RenderElement(reinterpret_cast<RenderingElement*>(child->element), window);
float outA = srcA + dstA * (1.0f - srcA);
if (outA > 0.0f) {
dst = {
static_cast<uint8_t>((src.b * srcA + dst.b * dstA * (1.0f - srcA)) / outA),
static_cast<uint8_t>((src.g * srcA + dst.g * dstA * (1.0f - srcA)) / outA),
static_cast<uint8_t>((src.r * srcA + dst.r * dstA * (1.0f - srcA)) / outA),
static_cast<uint8_t>(outA * 255)
};
}
}
}
}
}
std::sort(transform->children.begin(), transform->children.end(), [](Transform* a, Transform* b){ return a->z < b->z; });
for(Transform* child : transform->children) {
RenderElement(child, window);
}
}
void WindowWayland::Render() {
std::sort(elements.begin(), elements.end(), [](RenderingElement* a, RenderingElement* b){ return a->transform.z < b->transform.z; });
std::sort(elements.begin(), elements.end(), [](Transform* a, Transform* b){ return a->z < b->z; });
for (std::uint_fast32_t x = 0; x < width; x++) {
for (std::uint_fast32_t y = 0; y - height; y++) {
@ -172,8 +177,8 @@ void WindowWayland::Render() {
}
}
for(RenderingElement* element : elements) {
RenderElement(element, this);
for(Transform* child : elements) {
RenderElement(child, this);
}
wl_surface_attach(surface, buffer, 0, 0);
@ -261,16 +266,16 @@ void WindowWayland::pointer_handle_button(void* data, wl_pointer* pointer, std::
window->mouseLeftHeld = true;
window->onMouseLeftClick.Invoke(window->currentMousePos);
for(MouseElement* element : window->mouseElements) {
if(window->currentMousePos.x >= element->transform.scaled.x && window->currentMousePos.x <= element->transform.scaled.x+element->transform.scaled.width && window->currentMousePos.y > element->transform.scaled.y && window->currentMousePos.y < element->transform.scaled.y+element->transform.scaled.height) {
element->onMouseLeftClick.Invoke({FractionalToMappedBoundless(static_cast<double>(window->currentMousePos.x - element->transform.scaled.x) / element->transform.scaled.width), FractionalToMappedBoundless(static_cast<double>(window->currentMousePos.y - element->transform.scaled.y) / element->transform.scaled.height)});
if(window->currentMousePos.x >= element->scaled.x && window->currentMousePos.x <= element->scaled.x+element->scaled.width && window->currentMousePos.y > element->scaled.y && window->currentMousePos.y < element->scaled.y+element->scaled.height) {
element->onMouseLeftClick.Invoke({FractionalToMappedBoundless(static_cast<double>(window->currentMousePos.x - element->scaled.x) / element->scaled.width), FractionalToMappedBoundless(static_cast<double>(window->currentMousePos.y - element->scaled.y) / element->scaled.height)});
}
}
} else {
window->mouseLeftHeld = false;
window->onMouseLeftRelease.Invoke(window->currentMousePos);
for(MouseElement* element : window->mouseElements) {
if(window->currentMousePos.x >= element->transform.scaled.x && window->currentMousePos.x <= element->transform.scaled.x+element->transform.scaled.width && window->currentMousePos.y > element->transform.scaled.y && window->currentMousePos.y < element->transform.scaled.y+element->transform.scaled.height) {
element->onMouseLeftRelease.Invoke({FractionalToMappedBoundless(static_cast<double>(window->currentMousePos.x - element->transform.scaled.x) / element->transform.scaled.width), FractionalToMappedBoundless(static_cast<double>(window->currentMousePos.y - element->transform.scaled.y) / element->transform.scaled.height)});
if(window->currentMousePos.x >= element->scaled.x && window->currentMousePos.x <= element->scaled.x+element->scaled.width && window->currentMousePos.y > element->scaled.y && window->currentMousePos.y < element->scaled.y+element->scaled.height) {
element->onMouseLeftRelease.Invoke({FractionalToMappedBoundless(static_cast<double>(window->currentMousePos.x - element->scaled.x) / element->scaled.width), FractionalToMappedBoundless(static_cast<double>(window->currentMousePos.y - element->scaled.y) / element->scaled.height)});
}
}
}
@ -279,16 +284,16 @@ void WindowWayland::pointer_handle_button(void* data, wl_pointer* pointer, std::
window->mouseRightHeld = true;
window->onMouseRightClick.Invoke(window->currentMousePos);
for(MouseElement* element : window->mouseElements) {
if(window->currentMousePos.x >= element->transform.scaled.x && window->currentMousePos.x <= element->transform.scaled.x+element->transform.scaled.width && window->currentMousePos.y > element->transform.scaled.y && window->currentMousePos.y < element->transform.scaled.y+element->transform.scaled.height) {
element->onMouseRightClick.Invoke({FractionalToMappedBoundless(static_cast<double>(window->currentMousePos.x - element->transform.scaled.x) / element->transform.scaled.width), FractionalToMappedBoundless(static_cast<double>(window->currentMousePos.y - element->transform.scaled.y) / element->transform.scaled.height)});
if(window->currentMousePos.x >= element->scaled.x && window->currentMousePos.x <= element->scaled.x+element->scaled.width && window->currentMousePos.y > element->scaled.y && window->currentMousePos.y < element->scaled.y+element->scaled.height) {
element->onMouseRightClick.Invoke({FractionalToMappedBoundless(static_cast<double>(window->currentMousePos.x - element->scaled.x) / element->scaled.width), FractionalToMappedBoundless(static_cast<double>(window->currentMousePos.y - element->scaled.y) / element->scaled.height)});
}
}
} else {
window->mouseRightHeld = true;
window->onMouseRightRelease.Invoke(window->currentMousePos);
for(MouseElement* element : window->mouseElements) {
if(window->currentMousePos.x >= element->transform.scaled.x && window->currentMousePos.x <= element->transform.scaled.x+element->transform.scaled.width && window->currentMousePos.y > element->transform.scaled.y && window->currentMousePos.y < element->transform.scaled.y+element->transform.scaled.height) {
element->onMouseRightRelease.Invoke({FractionalToMappedBoundless(static_cast<double>(window->currentMousePos.x - element->transform.scaled.x) / element->transform.scaled.width), FractionalToMappedBoundless(static_cast<double>(window->currentMousePos.y - element->transform.scaled.y) / element->transform.scaled.height)});
if(window->currentMousePos.x >= element->scaled.x && window->currentMousePos.x <= element->scaled.x+element->scaled.width && window->currentMousePos.y > element->scaled.y && window->currentMousePos.y < element->scaled.y+element->scaled.height) {
element->onMouseRightRelease.Invoke({FractionalToMappedBoundless(static_cast<double>(window->currentMousePos.x - element->scaled.x) / element->scaled.width), FractionalToMappedBoundless(static_cast<double>(window->currentMousePos.y - element->scaled.y) / element->scaled.height)});
}
}
}
@ -303,13 +308,13 @@ void WindowWayland::PointerListenerHandleMotion(void* data, wl_pointer* wl_point
window->mouseDelta = {window->currentMousePos.x-window->lastMousePos.x, window->currentMousePos.y-window->lastMousePos.y};
window->onMouseMove.Invoke({window->lastMousePos, window->currentMousePos, window->mouseDelta});
for(MouseElement* element : window->mouseElements) {
if(window->currentMousePos.x >= element->transform.scaled.x && window->currentMousePos.x <= element->transform.scaled.x+element->transform.scaled.width && window->currentMousePos.y > element->transform.scaled.y && window->currentMousePos.y < element->transform.scaled.y+element->transform.scaled.height) {
element->onMouseMove.Invoke({FractionalToMappedBoundless(static_cast<double>(window->currentMousePos.x - element->transform.scaled.x) / element->transform.scaled.width), FractionalToMappedBoundless(static_cast<double>(window->currentMousePos.y - element->transform.scaled.y) / element->transform.scaled.height)});
if(!(window->lastMousePos.x >= element->transform.scaled.x && window->lastMousePos.x <= element->transform.scaled.x+element->transform.scaled.width && window->lastMousePos.y > element->transform.scaled.y && window->lastMousePos.y < element->transform.scaled.y+element->transform.scaled.height)) {
element->onMouseEnter.Invoke({FractionalToMappedBoundless(static_cast<double>(window->currentMousePos.x - element->transform.scaled.x) / element->transform.scaled.width), FractionalToMappedBoundless(static_cast<double>(window->currentMousePos.y - element->transform.scaled.y) / element->transform.scaled.height)});
if(window->currentMousePos.x >= element->scaled.x && window->currentMousePos.x <= element->scaled.x+element->scaled.width && window->currentMousePos.y > element->scaled.y && window->currentMousePos.y < element->scaled.y+element->scaled.height) {
element->onMouseMove.Invoke({FractionalToMappedBoundless(static_cast<double>(window->currentMousePos.x - element->scaled.x) / element->scaled.width), FractionalToMappedBoundless(static_cast<double>(window->currentMousePos.y - element->scaled.y) / element->scaled.height)});
if(!(window->lastMousePos.x >= element->scaled.x && window->lastMousePos.x <= element->scaled.x+element->scaled.width && window->lastMousePos.y > element->scaled.y && window->lastMousePos.y < element->scaled.y+element->scaled.height)) {
element->onMouseEnter.Invoke({FractionalToMappedBoundless(static_cast<double>(window->currentMousePos.x - element->scaled.x) / element->scaled.width), FractionalToMappedBoundless(static_cast<double>(window->currentMousePos.y - element->scaled.y) / element->scaled.height)});
}
} else if(window->lastMousePos.x >= element->transform.scaled.x && window->lastMousePos.x <= element->transform.scaled.x+element->transform.scaled.width && window->lastMousePos.y > element->transform.scaled.y && window->lastMousePos.y < element->transform.scaled.y+element->transform.scaled.height) {
element->onMouseLeave.Invoke({FractionalToMappedBoundless(static_cast<double>(window->currentMousePos.x - element->transform.scaled.x) / element->transform.scaled.width), FractionalToMappedBoundless(static_cast<double>(window->currentMousePos.y - element->transform.scaled.y) / element->transform.scaled.height)});
} else if(window->lastMousePos.x >= element->scaled.x && window->lastMousePos.x <= element->scaled.x+element->scaled.width && window->lastMousePos.y > element->scaled.y && window->lastMousePos.y < element->scaled.y+element->scaled.height) {
element->onMouseLeave.Invoke({FractionalToMappedBoundless(static_cast<double>(window->currentMousePos.x - element->scaled.x) / element->scaled.width), FractionalToMappedBoundless(static_cast<double>(window->currentMousePos.y - element->scaled.y) / element->scaled.height)});
}
}
}