diff --git a/src/plugins/platforms/wasm/qwasmcompositor.cpp b/src/plugins/platforms/wasm/qwasmcompositor.cpp index 9289b0fbc83..8f9a6bb72b3 100644 --- a/src/plugins/platforms/wasm/qwasmcompositor.cpp +++ b/src/plugins/platforms/wasm/qwasmcompositor.cpp @@ -2,7 +2,6 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include "qwasmcompositor.h" -#include "qwasmstylepixmaps_p.h" #include "qwasmwindow.h" #include "qwasmeventtranslator.h" #include "qwasmeventdispatcher.h" @@ -16,7 +15,6 @@ #include #include #include -#include #include @@ -264,85 +262,6 @@ void QWasmCompositor::drawWindowContent(QOpenGLTextureBlitter *blitter, QWasmScr blit(blitter, screen, texture, windowCanvasGeometry); } -QPalette QWasmCompositor::makeWindowPalette() -{ - QPalette palette; - palette.setColor(QPalette::Active, QPalette::Highlight, - palette.color(QPalette::Active, QPalette::Highlight)); - palette.setColor(QPalette::Active, QPalette::Base, - palette.color(QPalette::Active, QPalette::Highlight)); - palette.setColor(QPalette::Inactive, QPalette::Highlight, - palette.color(QPalette::Inactive, QPalette::Dark)); - palette.setColor(QPalette::Inactive, QPalette::Base, - palette.color(QPalette::Inactive, QPalette::Dark)); - palette.setColor(QPalette::Inactive, QPalette::HighlightedText, - palette.color(QPalette::Inactive, QPalette::Window)); - - return palette; -} - -QRect QWasmCompositor::titlebarRect(QWasmTitleBarOptions tb, QWasmCompositor::SubControls subcontrol) -{ - QRect ret; - const int controlMargin = 2; - const int controlHeight = tb.rect.height() - controlMargin *2; - const int delta = controlHeight + controlMargin; - int offset = 0; - - bool isMinimized = tb.state & Qt::WindowMinimized; - bool isMaximized = tb.state & Qt::WindowMaximized; - - ret = tb.rect; - switch (subcontrol) { - case SC_TitleBarLabel: - if (tb.flags & Qt::WindowSystemMenuHint) - ret.adjust(delta, 0, -delta, 0); - break; - case SC_TitleBarCloseButton: - if (tb.flags & Qt::WindowSystemMenuHint) { - ret.adjust(0, 0, -delta, 0); - offset += delta; - } - break; - case SC_TitleBarMaxButton: - if (!isMaximized && tb.flags & Qt::WindowMaximizeButtonHint) { - ret.adjust(0, 0, -delta*2, 0); - offset += (delta +delta); - } - break; - case SC_TitleBarNormalButton: - if (isMinimized && (tb.flags & Qt::WindowMinimizeButtonHint)) { - offset += delta; - } else if (isMaximized && (tb.flags & Qt::WindowMaximizeButtonHint)) { - ret.adjust(0, 0, -delta*2, 0); - offset += (delta +delta); - } - break; - case SC_TitleBarSysMenu: - if (tb.flags & Qt::WindowSystemMenuHint) { - ret.setRect(tb.rect.left() + controlMargin, tb.rect.top() + controlMargin, - controlHeight, controlHeight); - } - break; - default: - break; - }; - - if (subcontrol != SC_TitleBarLabel && subcontrol != SC_TitleBarSysMenu) { - ret.setRect(tb.rect.right() - offset, tb.rect.top() + controlMargin, - controlHeight, controlHeight); - } - - if (qApp->layoutDirection() == Qt::LeftToRight) - return ret; - - QRect rect = ret; - rect.translate(2 * (tb.rect.right() - ret.right()) + - ret.width() - tb.rect.width(), 0); - - return rect; -} - void QWasmCompositor::requestUpdateAllWindows() { m_requestUpdateAllWindows = true; @@ -439,51 +358,6 @@ int dpiScaled(qreal value) return value * (qreal(qt_defaultDpiX()) / 96.0); } -QWasmCompositor::QWasmTitleBarOptions QWasmCompositor::makeTitleBarOptions(const QWasmWindow *window) -{ - int width = window->windowFrameGeometry().width(); - int border = window->borderWidth(); - - QWasmTitleBarOptions titleBarOptions; - - titleBarOptions.rect = QRect(border, border, width - 2 * border, window->titleHeight()); - titleBarOptions.flags = window->window()->flags(); - titleBarOptions.state = window->window()->windowState(); - - bool isMaximized = titleBarOptions.state & Qt::WindowMaximized; // this gets reset when maximized - - if (titleBarOptions.flags & (Qt::WindowTitleHint)) - titleBarOptions.subControls |= SC_TitleBarLabel; - if (titleBarOptions.flags & Qt::WindowMaximizeButtonHint) { - if (isMaximized) - titleBarOptions.subControls |= SC_TitleBarNormalButton; - else - titleBarOptions.subControls |= SC_TitleBarMaxButton; - } - if (titleBarOptions.flags & Qt::WindowSystemMenuHint) { - titleBarOptions.subControls |= SC_TitleBarCloseButton; - titleBarOptions.subControls |= SC_TitleBarSysMenu; - } - - - titleBarOptions.palette = QWasmCompositor::makeWindowPalette(); - - if (window->window()->isActive()) - titleBarOptions.palette.setCurrentColorGroup(QPalette::Active); - else - titleBarOptions.palette.setCurrentColorGroup(QPalette::Inactive); - - if (window->activeSubControl() != QWasmCompositor::SC_None) - titleBarOptions.subControls = window->activeSubControl(); - - if (!window->window()->title().isEmpty()) - titleBarOptions.titleBarOptionsString = window->window()->title(); - - titleBarOptions.windowIcon = window->window()->icon(); - - return titleBarOptions; -} - void QWasmCompositor::drawWindowDecorations(QOpenGLTextureBlitter *blitter, QWasmScreen *screen, const QWasmWindow *window) { @@ -496,9 +370,7 @@ void QWasmCompositor::drawWindowDecorations(QOpenGLTextureBlitter *blitter, QWas QPainter painter(&image); painter.fillRect(QRect(0, 0, width, height), painter.background()); - QWasmTitleBarOptions titleBarOptions = makeTitleBarOptions(window); - - drawTitlebarWindow(titleBarOptions, &painter); + window->drawTitleBar(&painter); QWasmFrameOptions frameOptions; frameOptions.rect = QRect(0, 0, width, height); @@ -572,109 +444,6 @@ void QWasmCompositor::drawFrameWindow(QWasmFrameOptions options, QPainter *paint painter->setPen(oldPen); } -//from commonstyle.cpp -static QPixmap cachedPixmapFromXPM(const char * const *xpm) -{ - QPixmap result; - const QString tag = QString::asprintf("xpm:0x%p", static_cast(xpm)); - if (!QPixmapCache::find(tag, &result)) { - result = QPixmap(xpm); - QPixmapCache::insert(tag, result); - } - return result; -} - -void QWasmCompositor::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment, - const QPixmap &pixmap) const -{ - qreal scale = pixmap.devicePixelRatio(); - QSize size = pixmap.size() / scale; - int x = rect.x(); - int y = rect.y(); - int w = size.width(); - int h = size.height(); - if ((alignment & Qt::AlignVCenter) == Qt::AlignVCenter) - y += rect.size().height()/2 - h/2; - else if ((alignment & Qt::AlignBottom) == Qt::AlignBottom) - y += rect.size().height() - h; - if ((alignment & Qt::AlignRight) == Qt::AlignRight) - x += rect.size().width() - w; - else if ((alignment & Qt::AlignHCenter) == Qt::AlignHCenter) - x += rect.size().width()/2 - w/2; - - QRect aligned = QRect(x, y, w, h); - QRect inter = aligned.intersected(rect); - - painter->drawPixmap(inter.x(), inter.y(), pixmap, inter.x() - aligned.x(), - inter.y() - aligned.y(), inter.width() * scale, inter.height() *scale); -} - - -void QWasmCompositor::drawTitlebarWindow(QWasmTitleBarOptions tb, QPainter *painter) -{ - QRect ir; - if (tb.subControls.testFlag(SC_TitleBarLabel)) { - QColor left = tb.palette.highlight().color(); - QColor right = tb.palette.base().color(); - - QBrush fillBrush(left); - if (left != right) { - QPoint p1(tb.rect.x(), tb.rect.top() + tb.rect.height()/2); - QPoint p2(tb.rect.right(), tb.rect.top() + tb.rect.height()/2); - QLinearGradient lg(p1, p2); - lg.setColorAt(0, left); - lg.setColorAt(1, right); - fillBrush = lg; - } - - painter->fillRect(tb.rect, fillBrush); - ir = titlebarRect(tb, SC_TitleBarLabel); - painter->setPen(tb.palette.highlightedText().color()); - painter->drawText(ir.x() + 2, ir.y(), ir.width() - 2, ir.height(), - Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine, tb.titleBarOptionsString); - } // SC_TitleBarLabel - - QPixmap pixmap; - - if (tb.subControls.testFlag(SC_TitleBarCloseButton) - && tb.flags & Qt::WindowSystemMenuHint) { - ir = titlebarRect(tb, SC_TitleBarCloseButton); - pixmap = cachedPixmapFromXPM(qt_close_xpm).scaled(QSize(10, 10)); - drawItemPixmap(painter, ir, Qt::AlignCenter, pixmap); - } //SC_TitleBarCloseButton - - if (tb.subControls.testFlag(SC_TitleBarMaxButton) - && tb.flags & Qt::WindowMaximizeButtonHint - && !(tb.state & Qt::WindowMaximized)) { - ir = titlebarRect(tb, SC_TitleBarMaxButton); - pixmap = cachedPixmapFromXPM(qt_maximize_xpm).scaled(QSize(10, 10)); - drawItemPixmap(painter, ir, Qt::AlignCenter, pixmap); - } //SC_TitleBarMaxButton - - bool drawNormalButton = (tb.subControls & SC_TitleBarNormalButton) - && (((tb.flags & Qt::WindowMinimizeButtonHint) - && (tb.flags & Qt::WindowMinimized)) - || ((tb.flags & Qt::WindowMaximizeButtonHint) - && (tb.flags & Qt::WindowMaximized))); - - if (drawNormalButton) { - ir = titlebarRect(tb, SC_TitleBarNormalButton); - pixmap = cachedPixmapFromXPM(qt_normalizeup_xpm).scaled( QSize(10, 10)); - - drawItemPixmap(painter, ir, Qt::AlignCenter, pixmap); - } // SC_TitleBarNormalButton - - if (tb.subControls & SC_TitleBarSysMenu && tb.flags & Qt::WindowSystemMenuHint) { - ir = titlebarRect(tb, SC_TitleBarSysMenu); - if (!tb.windowIcon.isNull()) { - tb.windowIcon.paint(painter, ir, Qt::AlignCenter); - } else { - pixmap = cachedPixmapFromXPM(qt_menu_xpm).scaled(QSize(10, 10)); - drawItemPixmap(painter, ir, Qt::AlignCenter, pixmap); - } - } -} - void QWasmCompositor::drawWindow(QOpenGLTextureBlitter *blitter, QWasmScreen *screen, const QWasmWindow *window) { diff --git a/src/plugins/platforms/wasm/qwasmcompositor.h b/src/plugins/platforms/wasm/qwasmcompositor.h index 2af0cbd4499..09879d52d2f 100644 --- a/src/plugins/platforms/wasm/qwasmcompositor.h +++ b/src/plugins/platforms/wasm/qwasmcompositor.h @@ -41,17 +41,6 @@ public: void deregisterEventHandlers(); void destroy(); - enum QWasmSubControl { - SC_None = 0x00000000, - SC_TitleBarSysMenu = 0x00000001, - SC_TitleBarMinButton = 0x00000002, - SC_TitleBarMaxButton = 0x00000004, - SC_TitleBarCloseButton = 0x00000008, - SC_TitleBarNormalButton = 0x00000010, - SC_TitleBarLabel = 0x00000100 - }; - Q_DECLARE_FLAGS(SubControls, QWasmSubControl) - enum QWasmStateFlag { State_None = 0x00000000, State_Enabled = 0x00000001, @@ -60,16 +49,6 @@ public: }; Q_DECLARE_FLAGS(StateFlags, QWasmStateFlag) - struct QWasmTitleBarOptions { - QRect rect; - Qt::WindowFlags flags; - int state; - QPalette palette; - QString titleBarOptionsString; - QWasmCompositor::SubControls subControls; - QIcon windowIcon; - }; - struct QWasmFrameOptions { QRect rect; int lineWidth; @@ -90,9 +69,6 @@ public: QWindow *windowAt(QPoint globalPoint, int padding = 0) const; QWindow *keyWindow() const; - static QWasmTitleBarOptions makeTitleBarOptions(const QWasmWindow *window); - static QRect titlebarRect(QWasmTitleBarOptions tb, QWasmCompositor::SubControls subcontrol); - QWasmScreen *screen(); QOpenGLContext *context(); @@ -166,12 +142,7 @@ private: void drawWindowDecorations(QOpenGLTextureBlitter *blitter, QWasmScreen *screen, const QWasmWindow *window); - static QPalette makeWindowPalette(); - void drawFrameWindow(QWasmFrameOptions options, QPainter *painter); - void drawTitlebarWindow(QWasmTitleBarOptions options, QPainter *painter); - void drawItemPixmap(QPainter *painter, const QRect &rect, - int alignment, const QPixmap &pixmap) const; static int keyboard_cb(int eventType, const EmscriptenKeyboardEvent *keyEvent, void *userData); static int focus_cb(int eventType, const EmscriptenFocusEvent *focusEvent, void *userData); @@ -220,7 +191,6 @@ private: bool m_mouseInCanvas = false; QPointer m_windowUnderMouse; }; -Q_DECLARE_OPERATORS_FOR_FLAGS(QWasmCompositor::SubControls) QT_END_NAMESPACE diff --git a/src/plugins/platforms/wasm/qwasmwindow.cpp b/src/plugins/platforms/wasm/qwasmwindow.cpp index 4fc9af4b5ce..54c174e9742 100644 --- a/src/plugins/platforms/wasm/qwasmwindow.cpp +++ b/src/plugins/platforms/wasm/qwasmwindow.cpp @@ -6,9 +6,11 @@ #include #include #include +#include #include "qwasmwindow.h" #include "qwasmscreen.h" +#include "qwasmstylepixmaps_p.h" #include "qwasmcompositor.h" #include "qwasmeventdispatcher.h" @@ -19,6 +21,61 @@ QT_BEGIN_NAMESPACE Q_GUI_EXPORT int qt_defaultDpiX(); +namespace { +// from commonstyle.cpp +static QPixmap cachedPixmapFromXPM(const char *const *xpm) +{ + QPixmap result; + const QString tag = QString::asprintf("xpm:0x%p", static_cast(xpm)); + if (!QPixmapCache::find(tag, &result)) { + result = QPixmap(xpm); + QPixmapCache::insert(tag, result); + } + return result; +} + +QPalette makePalette() +{ + QPalette palette; + palette.setColor(QPalette::Active, QPalette::Highlight, + palette.color(QPalette::Active, QPalette::Highlight)); + palette.setColor(QPalette::Active, QPalette::Base, + palette.color(QPalette::Active, QPalette::Highlight)); + palette.setColor(QPalette::Inactive, QPalette::Highlight, + palette.color(QPalette::Inactive, QPalette::Dark)); + palette.setColor(QPalette::Inactive, QPalette::Base, + palette.color(QPalette::Inactive, QPalette::Dark)); + palette.setColor(QPalette::Inactive, QPalette::HighlightedText, + palette.color(QPalette::Inactive, QPalette::Window)); + + return palette; +} + +void drawItemPixmap(QPainter *painter, const QRect &rect, int alignment, const QPixmap &pixmap) +{ + qreal scale = pixmap.devicePixelRatio(); + QSize size = pixmap.size() / scale; + int x = rect.x(); + int y = rect.y(); + int w = size.width(); + int h = size.height(); + if ((alignment & Qt::AlignVCenter) == Qt::AlignVCenter) + y += rect.size().height() / 2 - h / 2; + else if ((alignment & Qt::AlignBottom) == Qt::AlignBottom) + y += rect.size().height() - h; + if ((alignment & Qt::AlignRight) == Qt::AlignRight) + x += rect.size().width() - w; + else if ((alignment & Qt::AlignHCenter) == Qt::AlignHCenter) + x += rect.size().width() / 2 - w / 2; + + QRect aligned = QRect(x, y, w, h); + QRect inter = aligned.intersected(rect); + + painter->drawPixmap(inter.x(), inter.y(), pixmap, inter.x() - aligned.x(), + inter.y() - aligned.y(), inter.width() * scale, inter.height() * scale); +} +} + QWasmWindow::QWasmWindow(QWindow *w, QWasmCompositor *compositor, QWasmBackingStore *backingStore) : QPlatformWindow(w), m_window(w), @@ -162,14 +219,16 @@ void QWasmWindow::injectMousePressed(const QPoint &local, const QPoint &global, if (!hasTitleBar() || button != Qt::LeftButton) return; - if (maxButtonRect().contains(global)) - m_activeControl = QWasmCompositor::SC_TitleBarMaxButton; - else if (minButtonRect().contains(global)) - m_activeControl = QWasmCompositor::SC_TitleBarMinButton; - else if (closeButtonRect().contains(global)) - m_activeControl = QWasmCompositor::SC_TitleBarCloseButton; - else if (normButtonRect().contains(global)) - m_activeControl = QWasmCompositor::SC_TitleBarNormalButton; + const auto pointInFrameCoords = global - windowFrameGeometry().topLeft(); + const auto options = makeTitleBarOptions(); + if (getTitleBarControlRect(options, SC_TitleBarMaxButton).contains(pointInFrameCoords)) + m_activeControl = SC_TitleBarMaxButton; + else if (getTitleBarControlRect(options, SC_TitleBarMinButton).contains(pointInFrameCoords)) + m_activeControl = SC_TitleBarMinButton; + else if (getTitleBarControlRect(options, SC_TitleBarCloseButton).contains(pointInFrameCoords)) + m_activeControl = SC_TitleBarCloseButton; + else if (getTitleBarControlRect(options, SC_TitleBarNormalButton).contains(pointInFrameCoords)) + m_activeControl = SC_TitleBarNormalButton; invalidate(); } @@ -183,20 +242,25 @@ void QWasmWindow::injectMouseReleased(const QPoint &local, const QPoint &global, if (!hasTitleBar() || button != Qt::LeftButton) return; - if (closeButtonRect().contains(global) && m_activeControl == QWasmCompositor::SC_TitleBarCloseButton) { + const auto pointInFrameCoords = global - windowFrameGeometry().topLeft(); + const auto options = makeTitleBarOptions(); + if (getTitleBarControlRect(options, SC_TitleBarCloseButton).contains(pointInFrameCoords) + && m_activeControl == SC_TitleBarCloseButton) { window()->close(); return; } - if (maxButtonRect().contains(global) && m_activeControl == QWasmCompositor::SC_TitleBarMaxButton) { + if (getTitleBarControlRect(options, SC_TitleBarMaxButton).contains(pointInFrameCoords) + && m_activeControl == SC_TitleBarMaxButton) { window()->setWindowState(Qt::WindowMaximized); } - if (normButtonRect().contains(global) && m_activeControl == QWasmCompositor::SC_TitleBarNormalButton) { + if (getTitleBarControlRect(options, SC_TitleBarNormalButton).contains(pointInFrameCoords) + && m_activeControl == SC_TitleBarNormalButton) { window()->setWindowState(Qt::WindowNoState); } - m_activeControl = QWasmCompositor::SC_None; + m_activeControl = SC_None; invalidate(); } @@ -265,48 +329,75 @@ Qt::Edges QWasmWindow::resizeEdgesAtPoint(QPoint point) const return edges | (right.contains(point) ? Qt::Edge::RightEdge : Qt::Edge(0)); } -QRect getSubControlRect(const QWasmWindow *window, QWasmCompositor::SubControls subControl) +QRect QWasmWindow::getTitleBarControlRect(const TitleBarOptions &tb, TitleBarControl control) const { - QWasmCompositor::QWasmTitleBarOptions options = QWasmCompositor::makeTitleBarOptions(window); + QRect ret; + const int controlMargin = 2; + const int controlHeight = tb.rect.height() - controlMargin * 2; + const int delta = controlHeight + controlMargin; + int offset = 0; - QRect r = QWasmCompositor::titlebarRect(options, subControl); - r.translate(window->window()->frameGeometry().x(), window->window()->frameGeometry().y()); + bool isMinimized = tb.state & Qt::WindowMinimized; + bool isMaximized = tb.state & Qt::WindowMaximized; - return r; -} + ret = tb.rect; + switch (control) { + case SC_TitleBarLabel: + if (tb.flags & Qt::WindowSystemMenuHint) + ret.adjust(delta, 0, -delta, 0); + break; + case SC_TitleBarCloseButton: + if (tb.flags & Qt::WindowSystemMenuHint) { + ret.adjust(0, 0, -delta, 0); + offset += delta; + } + break; + case SC_TitleBarMaxButton: + if (!isMaximized && tb.flags & Qt::WindowMaximizeButtonHint) { + ret.adjust(0, 0, -delta * 2, 0); + offset += (delta + delta); + } + break; + case SC_TitleBarNormalButton: + if (isMinimized && (tb.flags & Qt::WindowMinimizeButtonHint)) { + offset += delta; + } else if (isMaximized && (tb.flags & Qt::WindowMaximizeButtonHint)) { + ret.adjust(0, 0, -delta * 2, 0); + offset += (delta + delta); + } + break; + case SC_TitleBarSysMenu: + if (tb.flags & Qt::WindowSystemMenuHint) { + ret.setRect(tb.rect.left() + controlMargin, tb.rect.top() + controlMargin, + controlHeight, controlHeight); + } + break; + default: + break; + }; -QRect QWasmWindow::maxButtonRect() const -{ - return getSubControlRect(this, QWasmCompositor::SC_TitleBarMaxButton); -} + if (control != SC_TitleBarLabel && control != SC_TitleBarSysMenu) { + ret.setRect(tb.rect.right() - offset, tb.rect.top() + controlMargin, controlHeight, + controlHeight); + } -QRect QWasmWindow::minButtonRect() const -{ - return getSubControlRect(this, QWasmCompositor::SC_TitleBarMinButton); -} + if (qApp->layoutDirection() == Qt::LeftToRight) + return ret; -QRect QWasmWindow::closeButtonRect() const -{ - return getSubControlRect(this, QWasmCompositor::SC_TitleBarCloseButton); -} + QRect rect = ret; + rect.translate(2 * (tb.rect.right() - ret.right()) + ret.width() - tb.rect.width(), 0); -QRect QWasmWindow::normButtonRect() const -{ - return getSubControlRect(this, QWasmCompositor::SC_TitleBarNormalButton); -} - -QRect QWasmWindow::sysMenuRect() const -{ - return getSubControlRect(this, QWasmCompositor::SC_TitleBarSysMenu); + return rect; } QRegion QWasmWindow::titleControlRegion() const { QRegion result; - result += closeButtonRect(); - result += minButtonRect(); - result += maxButtonRect(); - result += sysMenuRect(); + const auto options = makeTitleBarOptions(); + result += getTitleBarControlRect(options, SC_TitleBarCloseButton); + result += getTitleBarControlRect(options, SC_TitleBarMinButton); + result += getTitleBarControlRect(options, SC_TitleBarMaxButton); + result += getTitleBarControlRect(options, SC_TitleBarSysMenu); return result; } @@ -316,7 +407,7 @@ void QWasmWindow::invalidate() m_compositor->requestUpdateWindow(this); } -QWasmCompositor::SubControls QWasmWindow::activeSubControl() const +QWasmWindow::TitleBarControl QWasmWindow::activeTitleBarControl() const { return m_activeControl; } @@ -366,6 +457,114 @@ void QWasmWindow::applyWindowState() setGeometry(newGeom); } +void QWasmWindow::drawTitleBar(QPainter *painter) const +{ + const auto tb = makeTitleBarOptions(); + QRect ir; + if (tb.subControls.testFlag(SC_TitleBarLabel)) { + QColor left = tb.palette.highlight().color(); + QColor right = tb.palette.base().color(); + + QBrush fillBrush(left); + if (left != right) { + QPoint p1(tb.rect.x(), tb.rect.top() + tb.rect.height() / 2); + QPoint p2(tb.rect.right(), tb.rect.top() + tb.rect.height() / 2); + QLinearGradient lg(p1, p2); + lg.setColorAt(0, left); + lg.setColorAt(1, right); + fillBrush = lg; + } + + painter->fillRect(tb.rect, fillBrush); + ir = getTitleBarControlRect(tb, SC_TitleBarLabel); + painter->setPen(tb.palette.highlightedText().color()); + painter->drawText(ir.x() + 2, ir.y(), ir.width() - 2, ir.height(), + Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine, + tb.titleBarOptionsString); + } // SC_TitleBarLabel + + QPixmap pixmap; + + if (tb.subControls.testFlag(SC_TitleBarCloseButton) && tb.flags & Qt::WindowSystemMenuHint) { + ir = getTitleBarControlRect(tb, SC_TitleBarCloseButton); + pixmap = cachedPixmapFromXPM(qt_close_xpm).scaled(QSize(10, 10)); + drawItemPixmap(painter, ir, Qt::AlignCenter, pixmap); + } // SC_TitleBarCloseButton + + if (tb.subControls.testFlag(SC_TitleBarMaxButton) && tb.flags & Qt::WindowMaximizeButtonHint + && !(tb.state & Qt::WindowMaximized)) { + ir = getTitleBarControlRect(tb, SC_TitleBarMaxButton); + pixmap = cachedPixmapFromXPM(qt_maximize_xpm).scaled(QSize(10, 10)); + drawItemPixmap(painter, ir, Qt::AlignCenter, pixmap); + } // SC_TitleBarMaxButton + + bool drawNormalButton = (tb.subControls & SC_TitleBarNormalButton) + && (((tb.flags & Qt::WindowMinimizeButtonHint) && (tb.flags & Qt::WindowMinimized)) + || ((tb.flags & Qt::WindowMaximizeButtonHint) && (tb.flags & Qt::WindowMaximized))); + + if (drawNormalButton) { + ir = getTitleBarControlRect(tb, SC_TitleBarNormalButton); + pixmap = cachedPixmapFromXPM(qt_normalizeup_xpm).scaled(QSize(10, 10)); + + drawItemPixmap(painter, ir, Qt::AlignCenter, pixmap); + } // SC_TitleBarNormalButton + + if (tb.subControls & SC_TitleBarSysMenu && tb.flags & Qt::WindowSystemMenuHint) { + ir = getTitleBarControlRect(tb, SC_TitleBarSysMenu); + if (!tb.windowIcon.isNull()) { + tb.windowIcon.paint(painter, ir, Qt::AlignCenter); + } else { + pixmap = cachedPixmapFromXPM(qt_menu_xpm).scaled(QSize(10, 10)); + drawItemPixmap(painter, ir, Qt::AlignCenter, pixmap); + } + } +} + +QWasmWindow::TitleBarOptions QWasmWindow::makeTitleBarOptions() const +{ + int width = windowFrameGeometry().width(); + int border = borderWidth(); + + TitleBarOptions titleBarOptions; + + titleBarOptions.rect = QRect(border, border, width - 2 * border, titleHeight()); + titleBarOptions.flags = window()->flags(); + titleBarOptions.state = window()->windowState(); + + bool isMaximized = + titleBarOptions.state & Qt::WindowMaximized; // this gets reset when maximized + + if (titleBarOptions.flags & (Qt::WindowTitleHint)) + titleBarOptions.subControls |= SC_TitleBarLabel; + if (titleBarOptions.flags & Qt::WindowMaximizeButtonHint) { + if (isMaximized) + titleBarOptions.subControls |= SC_TitleBarNormalButton; + else + titleBarOptions.subControls |= SC_TitleBarMaxButton; + } + if (titleBarOptions.flags & Qt::WindowSystemMenuHint) { + titleBarOptions.subControls |= SC_TitleBarCloseButton; + titleBarOptions.subControls |= SC_TitleBarSysMenu; + } + + titleBarOptions.palette = makePalette(); + + if (window()->isActive()) + titleBarOptions.palette.setCurrentColorGroup(QPalette::Active); + else + titleBarOptions.palette.setCurrentColorGroup(QPalette::Inactive); + + if (activeTitleBarControl() != SC_None) + titleBarOptions.subControls = activeTitleBarControl(); + + if (!window()->title().isEmpty()) + titleBarOptions.titleBarOptionsString = window()->title(); + + titleBarOptions.windowIcon = window()->icon(); + + return titleBarOptions; +} + QRect QWasmWindow::normalGeometry() const { return m_normalGeometry; diff --git a/src/plugins/platforms/wasm/qwasmwindow.h b/src/plugins/platforms/wasm/qwasmwindow.h index 650e34ce5c0..7dd0a0d1024 100644 --- a/src/plugins/platforms/wasm/qwasmwindow.h +++ b/src/plugins/platforms/wasm/qwasmwindow.h @@ -16,6 +16,17 @@ QT_BEGIN_NAMESPACE class QWasmWindow : public QPlatformWindow { public: + enum TitleBarControl { + SC_None = 0x00000000, + SC_TitleBarSysMenu = 0x00000001, + SC_TitleBarMinButton = 0x00000002, + SC_TitleBarMaxButton = 0x00000004, + SC_TitleBarCloseButton = 0x00000008, + SC_TitleBarNormalButton = 0x00000010, + SC_TitleBarLabel = 0x00000100 + }; + Q_DECLARE_FLAGS(TitleBarControls, TitleBarControl); + QWasmWindow(QWindow *w, QWasmCompositor *compositor, QWasmBackingStore *backingStore); ~QWasmWindow(); void destroy(); @@ -47,41 +58,53 @@ public: void injectMouseReleased(const QPoint &local, const QPoint &global, Qt::MouseButton button, Qt::KeyboardModifiers mods); - int titleHeight() const; - int borderWidth() const; - QRegion titleGeometry() const; - QRegion resizeRegion() const; bool isPointOnTitle(QPoint point) const; bool isPointOnResizeRegion(QPoint point) const; + Qt::Edges resizeEdgesAtPoint(QPoint point) const; - QRect maxButtonRect() const; - QRect minButtonRect() const; - QRect closeButtonRect() const; - QRect sysMenuRect() const; - QRect normButtonRect() const; - QRegion titleControlRegion() const; - QWasmCompositor::SubControls activeSubControl() const; void setWindowState(Qt::WindowStates state) override; void applyWindowState(); bool setKeyboardGrabEnabled(bool) override { return false; } bool setMouseGrabEnabled(bool) override { return false; } + void drawTitleBar(QPainter *painter) const; + protected: void invalidate(); bool hasTitleBar() const; -protected: +private: friend class QWasmScreen; - QWindow* m_window = nullptr; + struct TitleBarOptions + { + QRect rect; + Qt::WindowFlags flags; + int state; + QPalette palette; + QString titleBarOptionsString; + TitleBarControls subControls; + QIcon windowIcon; + }; + + TitleBarOptions makeTitleBarOptions() const; + QRect getTitleBarControlRect(const TitleBarOptions &tb, TitleBarControl control) const; + QRegion titleControlRegion() const; + QRegion titleGeometry() const; + int borderWidth() const; + int titleHeight() const; + QRegion resizeRegion() const; + TitleBarControl activeTitleBarControl() const; + + QWindow *m_window = nullptr; QWasmCompositor *m_compositor = nullptr; QWasmBackingStore *m_backingStore = nullptr; QRect m_normalGeometry {0, 0, 0 ,0}; Qt::WindowStates m_windowState = Qt::WindowNoState; Qt::WindowStates m_previousWindowState = Qt::WindowNoState; - QWasmCompositor::SubControls m_activeControl = QWasmCompositor::SC_None; + TitleBarControl m_activeControl = SC_None; WId m_winid = 0; bool m_hasTitle = false; bool m_needsCompositor = false; @@ -90,5 +113,7 @@ protected: friend class QWasmEventTranslator; bool windowIsPopupType(Qt::WindowFlags flags) const; }; + +Q_DECLARE_OPERATORS_FOR_FLAGS(QWasmWindow::TitleBarControls); QT_END_NAMESPACE #endif // QWASMWINDOW_H