diff options
Diffstat (limited to 'src/plugins/platforms/wasm/qwasmwindow.cpp')
| -rw-r--r-- | src/plugins/platforms/wasm/qwasmwindow.cpp | 293 |
1 files changed, 246 insertions, 47 deletions
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 <QtGui/private/qopenglcontext_p.h> #include <QtGui/private/qwindow_p.h> #include <QtGui/qopenglcontext.h> +#include <private/qpixmapcache_p.h> #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<const void *>(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) -{ - QWasmCompositor::QWasmTitleBarOptions options = QWasmCompositor::makeTitleBarOptions(window); +QRect QWasmWindow::getTitleBarControlRect(const TitleBarOptions &tb, TitleBarControl control) const +{ + 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 (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; + }; + + if (control != SC_TitleBarLabel && control != SC_TitleBarSysMenu) { + ret.setRect(tb.rect.right() - offset, tb.rect.top() + controlMargin, controlHeight, + controlHeight); + } - QRect r = QWasmCompositor::titlebarRect(options, subControl); - r.translate(window->window()->frameGeometry().x(), window->window()->frameGeometry().y()); + if (qApp->layoutDirection() == Qt::LeftToRight) + return ret; - return r; -} + QRect rect = ret; + rect.translate(2 * (tb.rect.right() - ret.right()) + ret.width() - tb.rect.width(), 0); -QRect QWasmWindow::maxButtonRect() const -{ - return getSubControlRect(this, QWasmCompositor::SC_TitleBarMaxButton); -} - -QRect QWasmWindow::minButtonRect() const -{ - return getSubControlRect(this, QWasmCompositor::SC_TitleBarMinButton); -} - -QRect QWasmWindow::closeButtonRect() const -{ - return getSubControlRect(this, QWasmCompositor::SC_TitleBarCloseButton); -} - -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; |
