11#include <qpa/qwindowsysteminterface.h>
13#include <QtCore/qassert.h>
19 std::function<
void()> onClick)
20 : m_onInteraction(
std::move(onInteraction)), m_onClick(
std::move(onClick))
23 "Both callbacks need to be either null or non-null");
32 return m_onInteraction();
45 m_imgElement.set(
"draggable",
false);
47 m_containerElement[
"classList"].call<
void>(
"add", emscripten::val(
"image-button"));
48 m_containerElement.call<
void>(
"appendChild", m_imgElement);
56 if (!m_webClickEventCallback) {
57 m_webMouseDownEventCallback = std::make_unique<qstdweb::EventCallback>(
58 m_containerElement,
"pointerdown", [
this](emscripten::val
event) {
59 event.call<
void>(
"preventDefault");
60 event.call<
void>(
"stopPropagation");
63 m_webClickEventCallback = std::make_unique<qstdweb::EventCallback>(
64 m_containerElement,
"click", [
this](emscripten::val
event) {
66 event.call<
void>(
"stopPropagation");
70 m_webMouseDownEventCallback.reset();
71 m_webClickEventCallback.reset();
79 m_imgElement.set(
"src",
80 "data:image/" + std::string(
format) +
";base64," + std::string(
imageData));
85 m_containerElement[
"style"].set(
"display", visible ?
"flex" :
"none");
96 m_element[
"classList"].call<
void>(
"add", emscripten::val(
"resize-outline"));
99 parentElement.call<
void>(
"appendChild", m_element);
101 m_mouseDownEvent = std::make_unique<qstdweb::EventCallback>(
102 m_element,
"pointerdown", [
this](emscripten::val
event) {
105 m_resizer->onInteraction();
106 event.call<
void>(
"preventDefault");
107 event.call<
void>(
"stopPropagation");
109 m_mouseMoveEvent = std::make_unique<qstdweb::EventCallback>(
110 m_element,
"pointermove", [
this](emscripten::val
event) {
112 event.call<
void>(
"preventDefault");
114 m_mouseUpEvent = std::make_unique<qstdweb::EventCallback>(
115 m_element,
"pointerup", [
this](emscripten::val
event) {
117 event.call<
void>(
"preventDefault");
118 event.call<
void>(
"stopPropagation");
125 m_element[
"parentElement"].call<emscripten::val>(
"removeChild", m_element);
132 m_element.call<
void>(
"setPointerCapture",
event.pointerId);
133 m_capturedPointerId =
event.pointerId;
135 m_resizer->startResize(m_edges,
event);
141 if (m_capturedPointerId !=
event.pointerId)
144 m_resizer->continueResize(
event);
150 if (m_capturedPointerId !=
event.pointerId)
153 m_resizer->finishResize();
154 m_element.call<
void>(
"releasePointerCapture",
event.pointerId);
155 m_capturedPointerId = -1;
160 : m_window(
window), m_windowElement(parentElement)
172 std::transform(std::begin(ResizeEdges), std::end(ResizeEdges), std::back_inserter(m_elements),
173 [parentElement,
this](
int edges) {
174 return std::make_unique<ResizerElement>(parentElement,
175 Qt::Edges::fromInt(edges),
this);
188 const auto frameRect =
189 QRectF::fromDOMRect(m_windowElement.call<emscripten::val>(
"getBoundingClientRect"));
190 auto containerGeometry =
192 "getBoundingClientRect"));
194 const int maxGrowTop = frameRect.top() - containerGeometry.top();
199void Resizer::onInteraction()
208 m_currentResizeData.reset(
new ResizeData{
209 .edges = resizeEdges,
215 m_currentResizeData->minShrink = resizeConstraints.minShrink;
217 m_currentResizeData->maxGrow =
218 QPoint(resizeConstraints.maxGrow.x(),
219 std::min(resizeEdges &
Qt::Edge::TopEdge ? resizeConstraints.maxGrowTop : INT_MAX,
220 resizeConstraints.maxGrow.
y()));
222 m_currentResizeData->initialBounds = m_window->
window()->geometry();
227 const auto pointInScreen =
229 const auto amount = (pointInScreen - m_currentResizeData->originInScreenCoords).toPoint();
230 const QPoint cappedGrowVector(
231 std::min(m_currentResizeData->maxGrow.x(),
232 std::max(m_currentResizeData->minShrink.x(),
234 : (m_currentResizeData->edges &
Qt::Edge::
RightEdge)
237 std::
min(m_currentResizeData->maxGrow.
y(),
238 std::max(m_currentResizeData->minShrink.
y(),
239 (m_currentResizeData->edges &
Qt::Edge::
TopEdge) ? -amount.
y()
244 auto bounds = m_currentResizeData->initialBounds.adjusted(
246 (m_currentResizeData->edges &
Qt::Edge::
TopEdge) ? -cappedGrowVector.
y() : 0,
247 (m_currentResizeData->edges &
Qt::Edge::
RightEdge) ? cappedGrowVector.
x() : 0,
248 (m_currentResizeData->edges &
Qt::Edge::
BottomEdge) ? cappedGrowVector.
y() : 0);
253void Resizer::finishResize()
256 m_currentResizeData.reset();
264 m_icon = std::make_unique<WebImageButton>();
266 m_element.call<
void>(
"appendChild", m_icon->htmlElement());
267 m_element.set(
"className",
"title-bar");
269 auto spacer =
dom::document().call<emscripten::val>(
"createElement", emscripten::val(
"div"));
270 spacer[
"style"].set(
"width",
"4px");
271 m_element.call<
void>(
"appendChild", spacer);
273 m_label.set(
"className",
"window-name");
275 m_element.call<
void>(
"appendChild", m_label);
277 spacer =
dom::document().call<emscripten::val>(
"createElement", emscripten::val(
"div"));
278 spacer.set(
"className",
"spacer");
279 m_element.call<
void>(
"appendChild", spacer);
281 m_restore = std::make_unique<WebImageButton>();
284 m_restore->setCallbacks(
288 m_element.call<
void>(
"appendChild", m_restore->htmlElement());
290 m_maximize = std::make_unique<WebImageButton>();
293 m_maximize->setCallbacks(
297 m_element.call<
void>(
"appendChild", m_maximize->htmlElement());
299 m_close = std::make_unique<WebImageButton>();
301 m_close->setCallbacks(
305 m_element.call<
void>(
"appendChild", m_close->htmlElement());
307 parentElement.call<
void>(
"appendChild", m_element);
309 m_mouseDownEvent = std::make_unique<qstdweb::EventCallback>(
310 m_element,
"pointerdown", [
this](emscripten::val
event) {
314 event.call<
void>(
"preventDefault");
315 event.call<
void>(
"stopPropagation");
317 m_mouseMoveEvent = std::make_unique<qstdweb::EventCallback>(
318 m_element,
"pointermove", [
this](emscripten::val
event) {
320 event.call<
void>(
"preventDefault");
323 m_mouseUpEvent = std::make_unique<qstdweb::EventCallback>(
324 m_element,
"pointerup", [
this](emscripten::val
event) {
326 event.call<
void>(
"preventDefault");
327 event.call<
void>(
"stopPropagation");
330 m_doubleClickEvent = std::make_unique<qstdweb::EventCallback>(
331 m_element,
"dblclick", [
this](emscripten::val
event) {
332 if (onDoubleClick()) {
333 event.call<
void>(
"preventDefault");
334 event.call<
void>(
"stopPropagation");
341 m_element[
"parentElement"].call<emscripten::val>(
"removeChild", m_element);
351 m_restore->setVisible(visible);
356 m_maximize->setVisible(visible);
361 m_close->setVisible(visible);
371 m_element[
"style"].set(
"width", std::to_string(
width) +
"px");
376 return QRectF::fromDOMRect(m_element.call<emscripten::val>(
"getBoundingClientRect"));
381 m_element.call<
void>(
"setPointerCapture",
event.pointerId);
382 m_capturedPointerId =
event.pointerId;
384 m_moveStartWindowPosition = m_window->
window()->position();
385 m_moveStartPoint = clipPointWithScreen(
event.localPoint);
392 if (m_capturedPointerId !=
event.pointerId)
395 const QPoint delta = (clipPointWithScreen(
event.localPoint) - m_moveStartPoint).toPoint();
397 m_window->
window()->setPosition(m_moveStartWindowPosition + delta);
404 if (m_capturedPointerId !=
event.pointerId)
407 m_element.call<
void>(
"releasePointerCapture",
event.pointerId);
408 m_capturedPointerId = -1;
413bool TitleBar::onDoubleClick()
419QPointF TitleBar::clipPointWithScreen(
const QPointF &pointInTitleBarCoords)
const
423 "getBoundingClientRect"));
425 pointInTitleBarCoords);
433 : m_qtWindowElement(qtWindowElement),
437 updateResizability();
444 m_titleBar->setWidth(
width);
449 updateResizability();
452void NonClientArea::updateResizability()
454 const auto resizeConstraints = m_resizer->getResizeConstraints();
455 const bool nonResizable = resizeConstraints.minShrink.isNull()
456 && resizeConstraints.maxGrow.isNull() && resizeConstraints.maxGrowTop == 0;
static Base64IconStore * get()
void onClientAreaWidthChange(int width)
void propagateSizeHints()
NonClientArea(QWasmWindow *window, emscripten::val containerElement)
\inmodule QtCore\reentrant
constexpr QPoint toPoint() const
Rounds the coordinates of this point to the nearest integer, and returns a QPoint object with the rou...
\inmodule QtCore\reentrant
\inmodule QtCore\reentrant
\macro QT_RESTRICTED_CAST_FROM_ASCII
std::string toStdString() const
Returns a std::string object with the data contained in this QString.
emscripten::val element() const
QPointF mapFromLocal(const QPointF &p) const
virtual emscripten::val containerElement()=0
void onNonClientAreaInteraction()
bool onNonClientEvent(const PointerEvent &event)
QWasmWindowTreeNode * parentNode() final
QWasmScreen * platformScreen() const
void setGeometry(int posx, int posy, int w, int h)
Sets the geometry of the window, excluding its window frame, to a rectangle constructed from posx,...
bool onPointerUp(const PointerEvent &event)
static constexpr const char * cssClassNameForEdges(Qt::Edges edges)
ResizerElement(emscripten::val parentElement, Qt::Edges edges, Resizer *resizer)
bool onPointerDown(const PointerEvent &event)
bool onPointerMove(const PointerEvent &event)
Resizer(QWasmWindow *window, emscripten::val parentElement)
ResizeConstraints getResizeConstraints()
void setTitle(const QString &title)
void setMaximizeVisible(bool visible)
TitleBar(QWasmWindow *window, emscripten::val parentElement)
void setIcon(std::string_view imageData, std::string_view format)
void setCloseVisible(bool visible)
void setRestoreVisible(bool visible)
Combined button and popup list for selecting options.
constexpr const T & min(const T &a, const T &b)
void syncCSSClassWith(emscripten::val element, std::string cssClassName, bool flag)
QPointF mapPoint(emscripten::val source, emscripten::val target, const QPointF &point)
emscripten::val document()
constexpr const T & qBound(const T &min, const T &val, const T &max)
GLint GLint GLint GLint GLint x
[0]
GLint GLsizei GLsizei GLenum format
#define Q_ASSERT_X(cond, x, msg)
PromiseCallbacks callbacks
static std::optional< PointerEvent > fromWeb(emscripten::val webEvent)