diff options
author | Lorn Potter <lorn.potter@gmail.com> | 2017-11-11 05:38:50 +1000 |
---|---|---|
committer | Lorn Potter <lorn.potter@gmail.com> | 2017-11-10 19:56:10 +0000 |
commit | 41ca0d5038318deeaae3a5a56a3359bf13add2f2 (patch) | |
tree | 73c415125330d2182c2c16e5c4441a32962e7db6 | |
parent | a8849578b712cc088ebf5d731cab710dde26f55e (diff) |
webassembly: remove platform plugin dependency on QWidgets
Change-Id: Ic66de97373294bba60ac9c3d5c12d9e68d3721a7
Reviewed-by: Lorn Potter <lorn.potter@gmail.com>
-rw-r--r-- | src/plugins/platforms/html5/html5.pro | 3 | ||||
-rw-r--r-- | src/plugins/platforms/html5/qhtml5backingstore.cpp | 41 | ||||
-rw-r--r-- | src/plugins/platforms/html5/qhtml5compositor.cpp | 507 | ||||
-rw-r--r-- | src/plugins/platforms/html5/qhtml5compositor.h | 79 | ||||
-rw-r--r-- | src/plugins/platforms/html5/qhtml5eventdispatcher.cpp | 52 | ||||
-rw-r--r-- | src/plugins/platforms/html5/qhtml5eventtranslator.cpp | 3 | ||||
-rw-r--r-- | src/plugins/platforms/html5/qhtml5integration.cpp | 23 | ||||
-rw-r--r-- | src/plugins/platforms/html5/qhtml5integration.h | 3 | ||||
-rw-r--r-- | src/plugins/platforms/html5/qhtml5screen.cpp | 39 | ||||
-rw-r--r-- | src/plugins/platforms/html5/qhtml5screen.h | 2 | ||||
-rw-r--r-- | src/plugins/platforms/html5/qhtml5stylepixmaps_p.h | 193 | ||||
-rw-r--r-- | src/plugins/platforms/html5/qhtml5window.cpp | 96 | ||||
-rw-r--r-- | src/plugins/platforms/html5/qhtml5window.h | 11 |
13 files changed, 919 insertions, 133 deletions
diff --git a/src/plugins/platforms/html5/html5.pro b/src/plugins/platforms/html5/html5.pro index 30ea6cf398..efb7b28fe5 100644 --- a/src/plugins/platforms/html5/html5.pro +++ b/src/plugins/platforms/html5/html5.pro @@ -26,7 +26,8 @@ HEADERS = qhtml5integration.h \ qhtml5fontdatabase.h \ qhtml5eventtranslator.h \ qhtml5eventdispatcher.h \ - qhtml5compositor.h + qhtml5compositor.h \ + qhtml5stylepixmaps_p.h RESOURCES += fonts/html5fonts.qrc diff --git a/src/plugins/platforms/html5/qhtml5backingstore.cpp b/src/plugins/platforms/html5/qhtml5backingstore.cpp index 1eb17811cb..013b5973bd 100644 --- a/src/plugins/platforms/html5/qhtml5backingstore.cpp +++ b/src/plugins/platforms/html5/qhtml5backingstore.cpp @@ -80,6 +80,41 @@ void QHTML5BackingStore::flush(QWindow *window, const QRegion ®ion, const QPo Q_UNUSED(offset); mCompositor->requestRedraw(); + + /* + auto* screen = static_cast<QHTML5Screen *>(window->screen()->handle()); + + mContext->makeCurrent(window); + + int dx = window->handle()->winId() == 1 ? 100 : 0; + int dy = window->handle()->winId() == 1 ? 100 : 0; + + //glViewport(0, 0, screen->geometry().width(), screen->geometry().height()); + glViewport(offset.x() + dx, window->screen()->geometry().height() - offset.y() - window->height() - dy, window->width(), window->height()); + + + updateTexture(); + + if (!mBlitter->isCreated()) + mBlitter->create(); + + float x = (float)window->x() / (float)screen->geometry().width(); + float y = 1.0f - (float)window->y() / (float)screen->geometry().height(); + + QMatrix4x4 m; + //m.translate(offset.x(), offset.y()); + //m.translate(-0.5f + 1.0f * (float)(window->handle()->winId() - 1), 0.0f); + //m.translate(x, y); + //m.translate(0, y); + //m.scale(0.5f, 0.5f); + + mBlitter->bind(); + mBlitter->setRedBlueSwizzle(true); + mBlitter->blit(mTexture->textureId(), m, QOpenGLTextureBlitter::OriginTopLeft); + mBlitter->release(); + + mContext->swapBuffers(window); + */ } void QHTML5BackingStore::updateTexture() @@ -148,8 +183,14 @@ void QHTML5BackingStore::resize(const QSize &size, const QRegion &staticContents mImage = QImage(size, QImage::Format_RGB32); + //mContext->makeCurrent(window()); + if (mTexture->isCreated()) mTexture->destroy(); + + /* + updateTexture(); + */ } QImage QHTML5BackingStore::toImage() const diff --git a/src/plugins/platforms/html5/qhtml5compositor.cpp b/src/plugins/platforms/html5/qhtml5compositor.cpp index 76fe3beef8..e7e8fc1f37 100644 --- a/src/plugins/platforms/html5/qhtml5compositor.cpp +++ b/src/plugins/platforms/html5/qhtml5compositor.cpp @@ -35,24 +35,27 @@ #include "qhtml5compositor.h" #include "qhtml5window.h" +#include "qhtml5stylepixmaps_p.h" #include <QOpenGLTexture> -#include <QtWidgets/QStyle> -#include <QtWidgets/QStyleOptionTitleBar> + #include <QtGui/private/qwindow_p.h> #include <QtGui/QOpenGLContext> #include <QtGui/QOpenGLFunctions> #include <QtGui/qopengltextureblitter.h> #include <QtGui/QPainter> +#include <private/qpixmapcache_p.h> +#include <QFontMetrics> #include <private/qguiapplication_p.h> #include <qpa/qwindowsysteminterface.h> -#include <QtWidgets/QApplication> #include <QCoreApplication> #include <QGuiApplication> #include <QDebug> +Q_GUI_EXPORT int qt_defaultDpiX(); + QHtml5CompositedWindow::QHtml5CompositedWindow() : window(0) , parentWindow(0) @@ -70,8 +73,6 @@ QHtml5Compositor::QHtml5Compositor() , m_isEnabled(true) , m_targetDevicePixelRatio(1) { - qDebug() << Q_FUNC_INFO; - } QHtml5Compositor::~QHtml5Compositor() @@ -86,8 +87,6 @@ void QHtml5Compositor::setEnabled(bool enabled) void QHtml5Compositor::addWindow(QHtml5Window *window, QHtml5Window *parentWindow) { - qDebug() << "window: " << window->window()->flags(); - QHtml5CompositedWindow compositedWindow; compositedWindow.window = window; compositedWindow.parentWindow = parentWindow; @@ -104,8 +103,6 @@ void QHtml5Compositor::addWindow(QHtml5Window *window, QHtml5Window *parentWindo void QHtml5Compositor::removeWindow(QHtml5Window *window) { - qDebug() << Q_FUNC_INFO; - QHtml5Window *platformWindow = m_compositedWindows[window].parentWindow; if (platformWindow) { @@ -126,7 +123,6 @@ void QHtml5Compositor::setScreen(QHTML5Screen *screen) void QHtml5Compositor::setVisible(QHtml5Window *window, bool visible) { - qDebug() << Q_FUNC_INFO; QHtml5CompositedWindow &compositedWindow = m_compositedWindows[window]; if (compositedWindow.visible == visible) return; @@ -143,8 +139,6 @@ void QHtml5Compositor::setVisible(QHtml5Window *window, bool visible) void QHtml5Compositor::raise(QHtml5Window *window) { - qDebug() << Q_FUNC_INFO; - if (m_compositedWindows.size() <= 1) return; @@ -158,8 +152,6 @@ void QHtml5Compositor::raise(QHtml5Window *window) void QHtml5Compositor::lower(QHtml5Window *window) { - qDebug() << Q_FUNC_INFO; - if (m_compositedWindows.size() <= 1) return; @@ -173,7 +165,6 @@ void QHtml5Compositor::lower(QHtml5Window *window) void QHtml5Compositor::setParent(QHtml5Window *window, QHtml5Window *parent) { - qDebug() << Q_FUNC_INFO; m_compositedWindows[window].parentWindow = parent; requestRedraw(); @@ -181,7 +172,6 @@ void QHtml5Compositor::setParent(QHtml5Window *window, QHtml5Window *parent) void QHtml5Compositor::flush(QHtml5Window *window, const QRegion ®ion) { - QHtml5CompositedWindow &compositedWindow = m_compositedWindows[window]; compositedWindow.flushPending = true; compositedWindow.damage = region; @@ -211,8 +201,6 @@ QWindow *QHtml5Compositor::windowAt(QPoint p, int padding) const while (index >= 0) { const QHtml5CompositedWindow &compositedWindow = m_compositedWindows[m_windowStack.at(index)]; //qDebug() << "windwAt testing" << compositedWindow.window << - //compositedWindow.window->geometry(); - QRect geometry = compositedWindow.window->windowFrameGeometry() .adjusted(-padding, -padding, padding, padding); @@ -241,7 +229,7 @@ bool QHtml5Compositor::event(QEvent *ev) return QObject::event(ev); } -void blit(QOpenGLTextureBlitter *blitter, QHTML5Screen *screen, const QOpenGLTexture *texture, QRect targetGeometry) +void QHtml5Compositor::blit(QOpenGLTextureBlitter *blitter, QHTML5Screen *screen, const QOpenGLTexture *texture, QRect targetGeometry) { QMatrix4x4 m; m.translate(-1.0f, -1.0f); @@ -260,7 +248,7 @@ void blit(QOpenGLTextureBlitter *blitter, QHTML5Screen *screen, const QOpenGLTex blitter->blit(texture->textureId(), m, QOpenGLTextureBlitter::OriginTopLeft); } -void drawWindowContent(QOpenGLTextureBlitter *blitter, QHTML5Screen *screen, QHtml5Window *window) +void QHtml5Compositor::drawWindowContent(QOpenGLTextureBlitter *blitter, QHTML5Screen *screen, QHtml5Window *window) { QHTML5BackingStore* backingStore = window->backingStore(); @@ -269,7 +257,7 @@ void drawWindowContent(QOpenGLTextureBlitter *blitter, QHTML5Screen *screen, QHt blit(blitter, screen, texture, window->geometry()); } -QPalette makeWindowPalette() +QPalette QHtml5Compositor::makeWindowPalette() { QPalette palette; palette.setColor(QPalette::Active, QPalette::Highlight, @@ -286,55 +274,135 @@ QPalette makeWindowPalette() return palette; } -QStyleOptionTitleBar makeTitleBarOptions(const QHtml5Window *window) +QRect QHtml5Compositor::titlebarRect(QHtml5TitleBarOptions tb, QHtml5Compositor::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); +// offset += 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; +} + +int dpiScaled(qreal value) +{ + return value * (qreal(qt_defaultDpiX()) / 96.0); +} + +QHtml5Compositor::QHtml5TitleBarOptions QHtml5Compositor::makeTitleBarOptions(const QHtml5Window *window) { int width = window->windowFrameGeometry().width(); + int border = window->borderWidth(); - QApplication *app = static_cast<QApplication*>(QApplication::instance()); - QStyle *style = app->style(); + QHtml5TitleBarOptions titleBarOptions; - int border = style->pixelMetric(QStyle::PM_MDIFrameWidth); + titleBarOptions.rect = QRect(border, border, width - 2 * border, window->titleHeight()); + titleBarOptions.flags = window->window()->flags(); + titleBarOptions.state = window->window()->windowState(); - QStyleOptionTitleBar titleBarOptions; - int titleHeight = style->pixelMetric(QStyle::PM_TitleBarHeight, &titleBarOptions, nullptr); - titleBarOptions.rect = QRect(border, border, width - 2*border, titleHeight); - titleBarOptions.titleBarFlags = window->window()->flags(); - titleBarOptions.titleBarState = window->window()->windowState(); + // bool isMinimized = titleBarOptions.flags & Qt::WindowMinimized; + 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; + } // Disable minimize button - titleBarOptions.titleBarFlags.setFlag(Qt::WindowMinimizeButtonHint, false); + // titleBarOptions.flags.setFlag(Qt::WindowMinimizeButtonHint, false); - titleBarOptions.palette = makeWindowPalette(); + titleBarOptions.palette = QHtml5Compositor::makeWindowPalette(); if (window->window()->isActive()) { - titleBarOptions.state |= QStyle::State_Active; - titleBarOptions.titleBarState |= QStyle::State_Active; + // titleBarOptions.state |= QHtml5Compositor::State_Active; + // titleBarOptions.state |= QHtml5Compositor::State_Active; titleBarOptions.palette.setCurrentColorGroup(QPalette::Active); } else { - titleBarOptions.state &= ~QStyle::State_Active; + // titleBarOptions.state &= ~QHtml5Compositor::State_Active; titleBarOptions.palette.setCurrentColorGroup(QPalette::Inactive); } - if (window->activeSubControl() != QStyle::SC_None) { - titleBarOptions.activeSubControls = window->activeSubControl(); - titleBarOptions.state |= QStyle::State_Sunken; - } + if (window->activeSubControl() != QHtml5Compositor::SC_None) { + titleBarOptions.subControls = window->activeSubControl(); + // titleBarOptions.state |= QHtml5Compositor::State_Sunken; + } if (!window->window()->title().isEmpty()) { - int titleWidth = style->subControlRect(QStyle::CC_TitleBar, &titleBarOptions, - QStyle::SC_TitleBarLabel, nullptr).width(); - titleBarOptions.text = titleBarOptions.fontMetrics - .elidedText(window->window()->title(), Qt::ElideRight, titleWidth); + + titleBarOptions.titleBarOptionsString = window->window()->title(); + +#warning FIXME QFontMetrics +// QFont font = QApplication::font("QMdiSubWindowTitleBar"); +// QFontMetrics fontMetrics = QFontMetrics(font); +// fontMetrics.elidedText(window->window()->title(), Qt::ElideRight, titleWidth); } return titleBarOptions; } -void drawWindowDecorations(QOpenGLTextureBlitter *blitter, QHTML5Screen *screen, QHtml5Window *window) +void QHtml5Compositor::drawWindowDecorations(QOpenGLTextureBlitter *blitter, QHTML5Screen *screen, QHtml5Window *window) { - QApplication *app = static_cast<QApplication*>(QApplication::instance()); - QStyle *style = app->style(); - int width = window->windowFrameGeometry().width(); int height = window->windowFrameGeometry().height(); @@ -342,16 +410,15 @@ void drawWindowDecorations(QOpenGLTextureBlitter *blitter, QHTML5Screen *screen, QPainter painter(&image); painter.fillRect(QRect(0, 0, width, height), painter.background()); - QStyleOptionTitleBar titleBarOptions = makeTitleBarOptions(window); + QHtml5TitleBarOptions titleBarOptions = makeTitleBarOptions(window); - style->drawComplexControl(QStyle::CC_TitleBar, &titleBarOptions, &painter); + drawTitlebarWindow(titleBarOptions, &painter); - QStyleOptionFrame frameOptions; + QHtml5FrameOptions frameOptions; frameOptions.rect = QRect(0, 0, width, height); - frameOptions.lineWidth = style->pixelMetric(QStyle::PM_MdiSubWindowFrameWidth, 0, nullptr); - frameOptions.state.setFlag(QStyle::State_Active, window->window()->isActive()); + frameOptions.lineWidth = dpiScaled(4.); - style->drawPrimitive(QStyle::PE_FrameWindow, &frameOptions, &painter, nullptr); + drawFrameWindow(frameOptions, &painter); painter.end(); @@ -369,7 +436,334 @@ void drawWindowDecorations(QOpenGLTextureBlitter *blitter, QHTML5Screen *screen, blit(blitter, screen, &texture, QRect(window->windowFrameGeometry().topLeft(), QSize(width, height))); } -void drawWindow(QOpenGLTextureBlitter *blitter, QHTML5Screen *screen, QHtml5Window *window) +void QHtml5Compositor::drawFrameWindow(QHtml5FrameOptions options, QPainter *painter) +{ + int x = options.rect.x(); + int y = options.rect.y(); + int w = options.rect.width(); + int h = options.rect.height(); + const QColor &c1 = options.palette.light().color(); + const QColor &c2 = options.palette.shadow().color(); + const QColor &c3 = options.palette.midlight().color(); + const QColor &c4 = options.palette.dark().color(); + const QBrush *fill = 0; + + const qreal devicePixelRatio = painter->device()->devicePixelRatioF(); + if (!qFuzzyCompare(devicePixelRatio, qreal(1))) { + painter->save(); + const qreal inverseScale = qreal(1) / devicePixelRatio; + painter->scale(inverseScale, inverseScale); + x = qRound(devicePixelRatio * x); + y = qRound(devicePixelRatio * y); + w = qRound(devicePixelRatio * w); + h = qRound(devicePixelRatio * h); + } + + QPen oldPen = painter->pen(); + QPoint a[3] = { QPoint(x, y+h-2), QPoint(x, y), QPoint(x+w-2, y) }; + painter->setPen(c1); + painter->drawPolyline(a, 3); + QPoint b[3] = { QPoint(x, y+h-1), QPoint(x+w-1, y+h-1), QPoint(x+w-1, y) }; + painter->setPen(c2); + painter->drawPolyline(b, 3); + if (w > 4 && h > 4) { + QPoint c[3] = { QPoint(x+1, y+h-3), QPoint(x+1, y+1), QPoint(x+w-3, y+1) }; + painter->setPen(c3); + painter->drawPolyline(c, 3); + QPoint d[3] = { QPoint(x+1, y+h-2), QPoint(x+w-2, y+h-2), QPoint(x+w-2, y+1) }; + painter->setPen(c4); + painter->drawPolyline(d, 3); + if (fill) + painter->fillRect(QRect(x+2, y+2, w-4, h-4), *fill); + } + 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<const void*>(xpm)); + if (!QPixmapCache::find(tag, &result)) { + result = QPixmap(xpm); + QPixmapCache::insert(tag, result); + } + return result; +} + +void QHtml5Compositor::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 QHtml5Compositor::drawTitlebarWindow(QHtml5TitleBarOptions 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 + + bool down = false; + QPixmap pixmap; + + if (tb.subControls.testFlag(SC_TitleBarCloseButton) + && tb.flags & Qt::WindowSystemMenuHint) { + ir = titlebarRect(tb, SC_TitleBarCloseButton); + down = tb.subControls & SC_TitleBarCloseButton && (tb.state & State_Sunken); + 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); + down = tb.subControls & SC_TitleBarMaxButton && (tb.state & State_Sunken); + pixmap = cachedPixmapFromXPM(qt_maximize_xpm).scaled(QSize(10, 10)); + drawItemPixmap(painter, ir, Qt::AlignCenter, pixmap); + } //SC_TitleBarMaxButton + +// QHtml5TitleBarOptions tool = tb; +// tool.rect = ir; +// tool.state = down ? State_Sunken : State_Raised; + + // FIXME + + // painter->save(); + // if (down) + // painter->translate(proxy()->pixelMetric(PM_ButtonShiftHorizontal, tb, widget), + // proxy()->pixelMetric(PM_ButtonShiftVertical, tb, widget)); + + // painter->restore(); + // } + + // if (tb->subControls & SC_TitleBarMinButton + // && tb->titleBarFlags & Qt::WindowMinimizeButtonHint + // && !(tb->titleBarState & Qt::WindowMinimized)) { + // ir = proxy()->subControlRect(CC_TitleBar, tb, SC_TitleBarMinButton, widget); + // down = tb->activeSubControls & SC_TitleBarMinButton && (opt->state & State_Sunken); + // pm = proxy()->standardIcon(SP_TitleBarMinButton, &tool, widget).pixmap(qt_getWindow(widget), QSize(10, 10)); + // tool.rect = ir; + // tool.state = down ? State_Sunken : State_Raised; + // proxy()->drawPrimitive(PE_PanelButtonTool, &tool, p, widget); + + // painter->save(); + // if (down) + // painter->translate(proxy()->pixelMetric(PM_ButtonShiftHorizontal, tb, widget), + // proxy()->pixelMetric(PM_ButtonShiftVertical, tb, widget)); + // proxy()->drawItemPixmap(p, ir, Qt::AlignCenter, pm); + // painter->restore(); + // } + + 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); + down = tb.subControls & SC_TitleBarNormalButton && (tb.state & State_Sunken); + pixmap = cachedPixmapFromXPM(qt_normalizeup_xpm).scaled( QSize(10, 10)); + +// tool.rect = ir; +// tool.state = down ? State_Sunken : State_Raised; + drawItemPixmap(painter, ir, Qt::AlignCenter, pixmap); + + // painter->save(); + // if (down) + // painter->translate(proxy()->pixelMetric(PM_ButtonShiftHorizontal, tb, widget), + // proxy()->pixelMetric(PM_ButtonShiftVertical, tb, widget)); + + // painter->restore(); + } // SC_TitleBarNormalButton + + // if (tb->subControls & SC_TitleBarShadeButton + // && tb->titleBarFlags & Qt::WindowShadeButtonHint + // && !(tb->titleBarState & Qt::WindowMinimized)) { + // ir = proxy()->subControlRect(CC_TitleBar, tb, SC_TitleBarShadeButton, widget); + // down = (tb->activeSubControls & SC_TitleBarShadeButton && (opt->state & State_Sunken)); + // pm = proxy()->standardIcon(SP_TitleBarShadeButton, &tool, widget).pixmap(qt_getWindow(widget), QSize(10, 10)); + // tool.rect = ir; + // tool.state = down ? State_Sunken : State_Raised; + // proxy()->drawPrimitive(PE_PanelButtonTool, &tool, p, widget); + // painter->save(); + // if (down) + // painter->translate(proxy()->pixelMetric(PM_ButtonShiftHorizontal, tb, widget), + // proxy()->pixelMetric(PM_ButtonShiftVertical, tb, widget)); + // proxy()->drawItemPixmap(p, ir, Qt::AlignCenter, pm); + // painter->restore(); + // } + + // if (tb->subControls & SC_TitleBarUnshadeButton + // && tb->titleBarFlags & Qt::WindowShadeButtonHint + // && tb->titleBarState & Qt::WindowMinimized) { + // ir = proxy()->subControlRect(CC_TitleBar, tb, SC_TitleBarUnshadeButton, widget); + + // down = tb->activeSubControls & SC_TitleBarUnshadeButton && (opt->state & State_Sunken); + // pm = proxy()->standardIcon(SP_TitleBarUnshadeButton, &tool, widget).pixmap(qt_getWindow(widget), QSize(10, 10)); + // tool.rect = ir; + // tool.state = down ? State_Sunken : State_Raised; + // proxy()->drawPrimitive(PE_PanelButtonTool, &tool, p, widget); + // painter->save(); + // if (down) + // painter->translate(proxy()->pixelMetric(PM_ButtonShiftHorizontal, tb, widget), + // proxy()->pixelMetric(PM_ButtonShiftVertical, tb, widget)); + // proxy()->drawItemPixmap(p, ir, Qt::AlignCenter, pm); + // painter->restore(); + // } + + + // if (tb->subControls & SC_TitleBarContextHelpButton + // && tb->titleBarFlags & Qt::WindowContextHelpButtonHint) { + // ir = proxy()->subControlRect(CC_TitleBar, tb, SC_TitleBarContextHelpButton, widget); + + // down = tb->activeSubControls & SC_TitleBarContextHelpButton && (opt->state & State_Sunken); + // pm = proxy()->standardIcon(SP_TitleBarContextHelpButton, &tool, widget).pixmap(qt_getWindow(widget), QSize(10, 10)); + // tool.rect = ir; + // tool.state = down ? State_Sunken : State_Raised; + // proxy()->drawPrimitive(PE_PanelButtonTool, &tool, p, widget); + // painter->save(); + // if (down) + // painter->translate(proxy()->pixelMetric(PM_ButtonShiftHorizontal, tb, widget), + // proxy()->pixelMetric(PM_ButtonShiftVertical, tb, widget)); + // proxy()->drawItemPixmap(p, ir, Qt::AlignCenter, pm); + // painter->restore(); + // } + + if (tb.subControls & SC_TitleBarSysMenu && tb.flags & Qt::WindowSystemMenuHint) { + ir = titlebarRect(tb, SC_TitleBarSysMenu); +// if (!tb.icon.isNull()) { +// tb.icon.paint(p, ir); +// } else { + // int iconSize = proxy()->pixelMetric(PM_SmallIconSize, tb, widget); + pixmap = cachedPixmapFromXPM(qt_menu_xpm).scaled(QSize(10, 10)); + // tool.rect = ir; + // painter->save(); + drawItemPixmap(painter, ir, Qt::AlignCenter, pixmap); + // painter->restore(); +// } + } + //} +} + +void QHtml5Compositor::drawShadePanel(QHtml5TitleBarOptions options, QPainter *painter) +{ + int lineWidth = 1; + QPalette palette = options.palette; + const QBrush *fill = &options.palette.brush(QPalette::Button); + + int x = options.rect.x(); + int y = options.rect.y(); + int w = options.rect.width(); + int h = options.rect.height(); + + const qreal devicePixelRatio = painter->device()->devicePixelRatioF(); + if (!qFuzzyCompare(devicePixelRatio, qreal(1))) { + // painter->save(); + const qreal inverseScale = qreal(1) / devicePixelRatio; + painter->scale(inverseScale, inverseScale); + + x = qRound(devicePixelRatio * x); + y = qRound(devicePixelRatio * y); + w = qRound(devicePixelRatio * w); + h = qRound(devicePixelRatio * h); + lineWidth = qRound(devicePixelRatio * lineWidth); + } + + QColor shade = palette.dark().color(); + QColor light = palette.light().color(); + + if (fill) { + if (fill->color() == shade) + shade = palette.shadow().color(); + if (fill->color() == light) + light = palette.midlight().color(); + } + QPen oldPen = painter->pen(); // save pen + QVector<QLineF> lines; + lines.reserve(2*lineWidth); + + // if (sunken) + // painter->setPen(shade); + // else + painter->setPen(light); + int x1, y1, x2, y2; + int i; + x1 = x; + y1 = y2 = y; + x2 = x+w-2; + for (i=0; i<lineWidth; i++) { // top shadow + lines << QLineF(x1, y1++, x2--, y2++); + } + x2 = x1; + y1 = y+h-2; + for (i=0; i<lineWidth; i++) { // left shado + lines << QLineF(x1++, y1, x2++, y2--); + } + painter->drawLines(lines); + lines.clear(); + // if (sunken) + // painter->setPen(light); + // else + painter->setPen(shade); + x1 = x; + y1 = y2 = y+h-1; + x2 = x+w-1; + for (i=0; i<lineWidth; i++) { // bottom shadow + lines << QLineF(x1++, y1--, x2, y2--); + } + x1 = x2; + y1 = y; + y2 = y+h-lineWidth-1; + for (i=0; i<lineWidth; i++) { // right shadow + lines << QLineF(x1--, y1++, x2--, y2); + } + painter->drawLines(lines); + if (fill) // fill with fill color + painter->fillRect(x+lineWidth, y+lineWidth, w-lineWidth*2, h-lineWidth*2, *fill); + painter->setPen(oldPen); // restore pen + +} + +void QHtml5Compositor::drawWindow(QOpenGLTextureBlitter *blitter, QHTML5Screen *screen, QHtml5Window *window) { drawWindowDecorations(blitter, screen, window); drawWindowContent(blitter, screen, window); @@ -389,7 +783,7 @@ void QHtml5Compositor::frame() foreach (QHtml5Window *window, m_windowStack) { if (window->window()->surfaceClass() == QSurface::Window - && qt_window_private(static_cast<QWindow *>(window->window()))->receivedExpose) { + && qt_window_private(static_cast<QWindow *>(window->window()))->receivedExpose) { someWindow = window; break; } @@ -443,9 +837,8 @@ void QHtml5Compositor::notifyTopWindowChanged(QHtml5Window* window) } //if (keyWindow()->handle() == window) - //return; + //return; requestRedraw(); QWindowSystemInterface::handleWindowActivated(window->window()); } - diff --git a/src/plugins/platforms/html5/qhtml5compositor.h b/src/plugins/platforms/html5/qhtml5compositor.h index 97ae722fed..117a566ee4 100644 --- a/src/plugins/platforms/html5/qhtml5compositor.h +++ b/src/plugins/platforms/html5/qhtml5compositor.h @@ -38,7 +38,12 @@ #include <QtGui/QRegion> #include <qpa/qplatformwindow.h> -#include <QtWidgets/QStyleOptionTitleBar> + +#include <QOpenGLTextureBlitter> +#include <QOpenGLTexture> +#include <QPalette> +#include <QRect> +#include <QFontMetrics> QT_BEGIN_NAMESPACE @@ -47,8 +52,7 @@ class QHTML5Screen; class QOpenGLContext; class QOpenGLTextureBlitter; -QStyleOptionTitleBar makeTitleBarOptions(const QHtml5Window *window); - +// class QHtml5CompositedWindow { public: @@ -69,6 +73,42 @@ public: QHtml5Compositor(); ~QHtml5Compositor(); + enum QHtml5SubControl { + 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, QHtml5SubControl) + + enum QHtml5StateFlag { + State_None = 0x00000000, + State_Enabled = 0x00000001, + State_Raised = 0x00000002, + State_Sunken = 0x00000004 + }; + Q_DECLARE_FLAGS(StateFlags, QHtml5StateFlag) + + struct QHtml5TitleBarOptions { + QRect rect; + Qt::WindowFlags flags; + int state; + QPalette palette; + QString titleBarOptionsString; + QHtml5Compositor::SubControls subControls; + // QFontMetrics fontMetrics; + // Qt::LayoutDirection direction; ?? + }; + + struct QHtml5FrameOptions { + QRect rect; + int lineWidth; + QPalette palette; + }; + void setEnabled(bool enabled); void addWindow(QHtml5Window *window, QHtml5Window *parentWindow = 0); @@ -80,35 +120,33 @@ public: void lower(QHtml5Window *window); void setParent(QHtml5Window *window, QHtml5Window *parent); - //void setFrameBuffer(QWindow *window, QImage *frameBuffer); void flush(QHtml5Window *surface, const QRegion ®ion); - //void waitForFlushed(QWindow *surface); - - /* - void beginResize(QSize newSize, - qreal newDevicePixelRatio); // call when the frame buffer geometry changes - void endResize(); - */ int windowCount() const; void requestRedraw(); QWindow *windowAt(QPoint p, int padding = 0) const; QWindow *keyWindow() const; - //void maybeComposit(); - //void composit(); bool event(QEvent *event); + static QHtml5TitleBarOptions makeTitleBarOptions(const QHtml5Window *window); + static QRect titlebarRect(QHtml5TitleBarOptions tb, QHtml5Compositor::SubControls subcontrol); + private slots: void frame(); private: - //void createFrameBuffer(); + void createFrameBuffer(); void flush2(const QRegion ®ion); void flushCompletedCallback(int32_t); void notifyTopWindowChanged(QHtml5Window* window); + void drawWindow(QOpenGLTextureBlitter *blitter, QHTML5Screen *screen, QHtml5Window *window); + void drawWindowContent(QOpenGLTextureBlitter *blitter, QHTML5Screen *screen, QHtml5Window *window); + void blit(QOpenGLTextureBlitter *blitter, QHTML5Screen *screen, const QOpenGLTexture *texture, QRect targetGeometry); + void drawWindowDecorations(QOpenGLTextureBlitter *blitter, QHTML5Screen *screen, QHtml5Window *window); + void drwPanelButton(); private: QImage *m_frameBuffer; QScopedPointer<QOpenGLContext> mContext; @@ -117,8 +155,6 @@ private: QHash<QHtml5Window *, QHtml5CompositedWindow> m_compositedWindows; QList<QHtml5Window *> m_windowStack; -// pp::Graphics2D *m_context2D; -// pp::ImageData *m_imageData2D; QRegion globalDamage; // damage caused by expose, window close, etc. bool m_needComposit; bool m_inFlush; @@ -127,8 +163,17 @@ private: QSize m_targetSize; qreal m_targetDevicePixelRatio; -// pp::CompletionCallbackFactory<QPepperCompositor> m_callbackFactory; +//////////////////////// + + static QPalette makeWindowPalette(); + + void drawFrameWindow(QHtml5FrameOptions options, QPainter *painter); + void drawTitlebarWindow(QHtml5TitleBarOptions options, QPainter *painter); + void drawShadePanel(QHtml5TitleBarOptions options, QPainter *painter); + void drawItemPixmap(QPainter *painter, const QRect &rect, + int alignment, const QPixmap &pixmap) const; }; +Q_DECLARE_OPERATORS_FOR_FLAGS(QHtml5Compositor::SubControls) QT_END_NAMESPACE diff --git a/src/plugins/platforms/html5/qhtml5eventdispatcher.cpp b/src/plugins/platforms/html5/qhtml5eventdispatcher.cpp index e0019b11e2..7edfd43cac 100644 --- a/src/plugins/platforms/html5/qhtml5eventdispatcher.cpp +++ b/src/plugins/platforms/html5/qhtml5eventdispatcher.cpp @@ -72,3 +72,55 @@ bool QHtml5EventDispatcher::hasPendingEvents() { return QUnixEventDispatcherQPA::hasPendingEvents(); } + +//void QHtml5EventDispatcher::timerCallback(int32_t result, int32_t timerSerial) +//{ +// Q_UNUSED(result); +// qCDebug(QT_PLATFORM_PEPPER_EVENTDISPATHCER) << "timerCallback" << timerSerial; + +// // The timer might have been unregistered. In that case don't fire. +// if (!m_activeTimerIds.contains(timerSerial)) +// return; + +// // Get the timer info for the timerSerial/timerID. +// int timerId = m_activeTimerIds.value(timerSerial); +// const PepperTimerInfo &info = m_timerDetails.value(timerId); + +// // Send the timer event +// QTimerEvent e(info.timerId); +// QCoreApplication::sendEvent(info.object, &e); +// processEvents(); + +// // After running Qt and application code the timer may have been unregistered, +// // and the timer id may have been reused. The timerSerial will hower not +// // be reused; use that to determine if the timer is active. +// if (m_activeTimerIds.contains(timerSerial)) +// startTimer(info); + +// // one serial number per callback, we are done with this one. +// m_activeTimerIds.remove(timerSerial); +//} + +//void QHtml5EventDispatcher::scheduleProcessEvents() +//{ +// qDebug() << "scheduleProcessEvents" << m_hasPendingProcessEvents; +// if (!m_hasPendingProcessEvents) { +// m_hasPendingProcessEvents = true; +// pp::CompletionCallback processEvents +// = m_completionCallbackFactory.NewCallback(&QHtml5EventDispatcher::processEventsCallback); +// int32_t result = m_messageLoop.PostWork(processEvents); +// if (result != PP_OK) +// qDebug() << "scheduleProcessEvents PostWork error" +// << result; +// } +//} + +//void QHtml5EventDispatcher::processEventsCallback(int32_t status) +//{ +// Q_UNUSED(status); +// qDebug() << "processEvents"; +// m_hasPendingProcessEvents = false; + +// processEvents(); +//} + diff --git a/src/plugins/platforms/html5/qhtml5eventtranslator.cpp b/src/plugins/platforms/html5/qhtml5eventtranslator.cpp index eb82eeff78..64bff8cf8f 100644 --- a/src/plugins/platforms/html5/qhtml5eventtranslator.cpp +++ b/src/plugins/platforms/html5/qhtml5eventtranslator.cpp @@ -39,12 +39,11 @@ #include "qhtml5eventtranslator.h" #include "qhtml5compositor.h" #include "qhtml5integration.h" + #include <QDebug> #include <QEvent> #include <qpa/qwindowsysteminterface.h> #include <QCoreApplication> -#include <QtWidgets/QApplication> -#include <QtWidgets/QStyle> #include <QtGlobal> #include <iostream> diff --git a/src/plugins/platforms/html5/qhtml5integration.cpp b/src/plugins/platforms/html5/qhtml5integration.cpp index e5c4789424..fb69cd854b 100644 --- a/src/plugins/platforms/html5/qhtml5integration.cpp +++ b/src/plugins/platforms/html5/qhtml5integration.cpp @@ -110,6 +110,7 @@ QHTML5Integration::QHTML5Integration() QHTML5Integration::~QHTML5Integration() { + qDebug() << Q_FUNC_INFO; delete mCompositor; destroyScreen(mScreen); delete mFontDb; @@ -174,26 +175,24 @@ QAbstractEventDispatcher *QHTML5Integration::createEventDispatcher() const QVariant QHTML5Integration::styleHint(QPlatformIntegration::StyleHint hint) const { - if (hint == QPlatformIntegration::ShowIsFullScreen) - return true; - return QPlatformIntegration::styleHint(hint); } int QHTML5Integration::uiEvent_cb(int eventType, const EmscriptenUiEvent *e, void */*userData*/) { - Q_UNUSED(eventType) Q_UNUSED(e) - - //QSize windowSize(e->documentBodyClientWidth, e->documentBodyClientHeight); - //QRect windowRect(QPoint(0, 0), windowSize); - - QHTML5Integration::get()->mScreen->invalidateSize(); - //QHTML5Integration::get()->mScreen->resizeMaximizedWindows(); - QHTML5Integration::get()->mCompositor->requestRedraw(); +// qDebug() << __FUNCTION__ << eventType << e; +// qDebug() << e->documentBodyClientWidth +// << e->documentBodyClientHeight; + + if (eventType == EMSCRIPTEN_EVENT_RESIZE) { + QHTML5Integration::get()->mScreen->invalidateSize(); +// QRect newRect(0,0,e->documentBodyClientWidth,e->documentBodyClientHeight); +// QHTML5Integration::get()->mScreen->setGeometry(newRect); + QHTML5Integration::get()->mCompositor->requestRedraw(); + } return 0; } - QT_END_NAMESPACE diff --git a/src/plugins/platforms/html5/qhtml5integration.h b/src/plugins/platforms/html5/qhtml5integration.h index 9ea2596eb6..81d93b30b9 100644 --- a/src/plugins/platforms/html5/qhtml5integration.h +++ b/src/plugins/platforms/html5/qhtml5integration.h @@ -76,7 +76,6 @@ public: QVariant styleHint(QPlatformIntegration::StyleHint hint) const Q_DECL_OVERRIDE; static QHTML5Integration *get(); - //QHTML5Window *topLevelWindow(); QHTML5Screen *screen() { return mScreen; } QHtml5Compositor *compositor() { return mCompositor; } @@ -87,8 +86,6 @@ private: mutable QHTML5EventTranslator *m_eventTranslator; mutable QHtml5EventDispatcher *m_eventDispatcher; static int uiEvent_cb(int eventType, const EmscriptenUiEvent *e, void *userData); - - //mutable QHTML5Window *m_topLevelWindow; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/html5/qhtml5screen.cpp b/src/plugins/platforms/html5/qhtml5screen.cpp index 346815438d..45b1c2a5f2 100644 --- a/src/plugins/platforms/html5/qhtml5screen.cpp +++ b/src/plugins/platforms/html5/qhtml5screen.cpp @@ -48,6 +48,8 @@ #include <qpa/qwindowsysteminterface.h> #include <QtCore/QCoreApplication> #include <QDebug> +#include <QGuiApplication> +#include <private/qhighdpiscaling_p.h> #ifdef Q_OPENKODE #include <KD/kd.h> @@ -174,6 +176,11 @@ void QHTML5Screen::createAndSetPlatformContext() eglQuerySurface(m_dpy, m_surface, EGL_HEIGHT, &h); m_geometry = QRect(0,0,w,h); + + //m_context.reset(new QOpenGLContext); + //m_context->setFormat(platformFormat); + //m_context->setScreen(screen); + //m_context->create(); } QRect QHTML5Screen::geometry() const @@ -209,7 +216,31 @@ QPlatformOpenGLContext *QHTML5Screen::platformContext() const void QHTML5Screen::resizeMaximizedWindows() { - QPlatformScreen::resizeMaximizedWindows(); + QList<QWindow*> windows = QGuiApplication::allWindows(); + // 'screen()' still has the old geometry info while 'this' has the new geometry info + const QRect oldGeometry = screen()->geometry(); + const QRect oldAvailableGeometry = screen()->availableGeometry(); + + const QRect newGeometry = deviceIndependentGeometry(); + const QRect newAvailableGeometry = QHighDpi::fromNative(availableGeometry(), QHighDpiScaling::factor(this), newGeometry.topLeft()); + + // make sure maximized and fullscreen windows are updated + for (int i = 0; i < windows.size(); ++i) { + QWindow *w = windows.at(i); + + // Skip non-platform windows, e.g., offscreen windows. + if (!w->handle()) + continue; + + if (platformScreenForWindow(w) != this) + continue; + + if (w->windowState() & Qt::WindowMaximized || w->geometry() == oldAvailableGeometry) + w->setGeometry(newAvailableGeometry); + + else if (w->windowState() & Qt::WindowFullScreen || w->geometry() == oldGeometry) + w->setGeometry(newGeometry); + } } QWindow *QHTML5Screen::topWindow() const @@ -227,5 +258,11 @@ void QHTML5Screen::invalidateSize() m_geometry = QRect(); } +void QHTML5Screen::setGeometry(const QRect &rect) +{ + m_geometry = rect; + QWindowSystemInterface::handleScreenGeometryChange(QPlatformScreen::screen(), geometry(), availableGeometry()); + resizeMaximizedWindows(); +} QT_END_NAMESPACE diff --git a/src/plugins/platforms/html5/qhtml5screen.h b/src/plugins/platforms/html5/qhtml5screen.h index 6a09a3f6b3..88e8aad237 100644 --- a/src/plugins/platforms/html5/qhtml5screen.h +++ b/src/plugins/platforms/html5/qhtml5screen.h @@ -88,7 +88,7 @@ public: public slots: //virtual void setDirty(const QRect &rect); - + void setGeometry(const QRect &rect); protected: //QList<QHtml5Window *> mWindowStack; //QRegion mRepaintRegion; diff --git a/src/plugins/platforms/html5/qhtml5stylepixmaps_p.h b/src/plugins/platforms/html5/qhtml5stylepixmaps_p.h new file mode 100644 index 0000000000..f3d514bb80 --- /dev/null +++ b/src/plugins/platforms/html5/qhtml5stylepixmaps_p.h @@ -0,0 +1,193 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QHTML5STYLEPIXMAPS_P_H +#define QHTML5STYLEPIXMAPS_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +/* XPM */ +static const char * const qt_menu_xpm[] = { +"16 16 72 1", +" c None", +". c #65AF36", +"+ c #66B036", +"@ c #77B94C", +"# c #A7D28C", +"$ c #BADBA4", +"% c #A4D088", +"& c #72B646", +"* c #9ACB7A", +"= c #7FBD56", +"- c #85C05F", +"; c #F4F9F0", +"> c #FFFFFF", +", c #E5F1DC", +"' c #ECF5E7", +") c #7ABA50", +"! c #83BF5C", +"~ c #AED595", +"{ c #D7EACA", +"] c #A9D28D", +"^ c #BCDDA8", +"/ c #C4E0B1", +"( c #81BE59", +"_ c #D0E7C2", +": c #D4E9C6", +"< c #6FB542", +"[ c #6EB440", +"} c #88C162", +"| c #98CA78", +"1 c #F4F9F1", +"2 c #8FC56C", +"3 c #F1F8EC", +"4 c #E8F3E1", +"5 c #D4E9C7", +"6 c #74B748", +"7 c #80BE59", +"8 c #73B747", +"9 c #6DB43F", +"0 c #CBE4BA", +"a c #80BD58", +"b c #6DB33F", +"c c #FEFFFE", +"d c #68B138", +"e c #F9FCF7", +"f c #91C66F", +"g c #E8F3E0", +"h c #DCEDD0", +"i c #91C66E", +"j c #A3CF86", +"k c #C9E3B8", +"l c #B0D697", +"m c #E3F0DA", +"n c #95C873", +"o c #E6F2DE", +"p c #9ECD80", +"q c #BEDEAA", +"r c #C7E2B6", +"s c #79BA4F", +"t c #6EB441", +"u c #BCDCA7", +"v c #FAFCF8", +"w c #F6FAF3", +"x c #84BF5D", +"y c #EDF6E7", +"z c #FAFDF9", +"A c #88C263", +"B c #98CA77", +"C c #CDE5BE", +"D c #67B037", +"E c #D9EBCD", +"F c #6AB23C", +"G c #77B94D", +" .++++++++++++++", +".+++++++++++++++", +"+++@#$%&+++*=+++", +"++-;>,>')+!>~+++", +"++{>]+^>/(_>:~<+", +"+[>>}+|>123>456+", +"+7>>8+->>90>~+++", +"+a>>b+a>c[0>~+++", +"+de>=+f>g+0>~+++", +"++h>i+j>k+0>~+++", +"++l>mno>p+q>rst+", +"++duv>wl++xy>zA+", +"++++B>Cb++++&D++", +"+++++0zE++++++++", +"++++++FG+++++++.", +"++++++++++++++. "}; + +static const char * const qt_close_xpm[] = { +"10 10 2 1", +"# c #000000", +". c None", +"..........", +".##....##.", +"..##..##..", +"...####...", +"....##....", +"...####...", +"..##..##..", +".##....##.", +"..........", +".........."}; + +static const char * const qt_maximize_xpm[]={ +"10 10 2 1", +"# c #000000", +". c None", +"#########.", +"#########.", +"#.......#.", +"#.......#.", +"#.......#.", +"#.......#.", +"#.......#.", +"#.......#.", +"#########.", +".........."}; + + +static const char * const qt_normalizeup_xpm[] = { +"10 10 2 1", +"# c #000000", +". c None", +"...######.", +"...######.", +"...#....#.", +".######.#.", +".######.#.", +".#....###.", +".#....#...", +".#....#...", +".######...", +".........."}; + + +#endif // QHTML5STYLEPIXMAPS_P_H diff --git a/src/plugins/platforms/html5/qhtml5window.cpp b/src/plugins/platforms/html5/qhtml5window.cpp index 398937f853..c130d31b23 100644 --- a/src/plugins/platforms/html5/qhtml5window.cpp +++ b/src/plugins/platforms/html5/qhtml5window.cpp @@ -39,8 +39,6 @@ #include <qpa/qwindowsysteminterface.h> #include <private/qguiapplication_p.h> -#include <QtWidgets/QApplication> -#include <QtWidgets/QStyle> #include <QtGui/private/qopenglcontext_p.h> #include <QtGui/QOpenGLContext> @@ -53,25 +51,21 @@ #include <iostream> //#include "qhtml5compositor.h" +Q_GUI_EXPORT int qt_defaultDpiX(); QT_BEGIN_NAMESPACE //static QHtml5Window *globalHtml5Window; //QHtml5Window *QHtml5Window::get() { return globalHtml5Window; } -QStyle *getAppStyle() -{ - QApplication *app = static_cast<QApplication*>(QApplication::instance()); - return app->style(); -} - QHtml5Window::QHtml5Window(QWindow *w, QHtml5Compositor* compositor) : QPlatformWindow(w), mWindow(w), mWindowState(Qt::WindowNoState), mCompositor(compositor), m_raster(false), - mActiveControl(QStyle::SC_None) + mActiveControl(QHtml5Compositor::SC_None), + mNormalGeometry(0,0,0,0) { //globalHtml5Window = this; static int serialNo = 0; @@ -116,6 +110,7 @@ void QHtml5Window::create() if (window()->isTopLevel()) setWindowIcon(window()->icon()); + mNormalGeometry = rect; } QHTML5Screen *QHtml5Window::platformScreen() const @@ -154,7 +149,6 @@ void QHtml5Window::setVisible(bool visible) else if (mWindowState & Qt::WindowMaximized) newGeom = platformScreen()->availableGeometry(); } - QPlatformWindow::setVisible(visible); mCompositor->setVisible(this, visible); @@ -169,18 +163,15 @@ void QHtml5Window::setVisible(bool visible) QMargins QHtml5Window::frameMargins() const { - QApplication *app = static_cast<QApplication*>(QApplication::instance()); - QStyle *style = app->style(); - bool hasTitle = window()->flags().testFlag(Qt::WindowTitleHint); - int border = hasTitle ? style->pixelMetric(QStyle::PM_MDIFrameWidth) : 0; - int titleHeight = hasTitle ? style->pixelMetric(QStyle::PM_TitleBarHeight, nullptr, nullptr) : 0; + int border = hasTitle ? 4. * (qreal(qt_defaultDpiX()) / 96.0) : 0; + int titleBarHeight = hasTitle ? titleHeight() : 0; QMargins margins; margins.setLeft(border); margins.setRight(border); - margins.setTop(2*border + titleHeight); + margins.setTop(2*border + titleBarHeight); margins.setBottom(border); return margins; @@ -220,11 +211,13 @@ void QHtml5Window::injectMousePressed(const QPoint &local, const QPoint &global, return; if (maxButtonRect().contains(global)) - mActiveControl = QStyle::SC_TitleBarMaxButton; + mActiveControl = QHtml5Compositor::SC_TitleBarMaxButton; else if (minButtonRect().contains(global)) - mActiveControl = QStyle::SC_TitleBarMinButton; + mActiveControl = QHtml5Compositor::SC_TitleBarMinButton; else if (closeButtonRect().contains(global)) - mActiveControl = QStyle::SC_TitleBarCloseButton; + mActiveControl = QHtml5Compositor::SC_TitleBarCloseButton; + else if (normButtonRect().contains(global)) + mActiveControl = QHtml5Compositor::SC_TitleBarNormalButton; invalidate(); } @@ -233,28 +226,37 @@ void QHtml5Window::injectMouseReleased(const QPoint &local, const QPoint &global Qt::MouseButton button, Qt::KeyboardModifiers mods) { Q_UNUSED(local); - Q_UNUSED(global); Q_UNUSED(mods); if (button != Qt::LeftButton) return; - if (closeButtonRect().contains(global) && mActiveControl == QStyle::SC_TitleBarCloseButton) + if (closeButtonRect().contains(global) && mActiveControl == QHtml5Compositor::SC_TitleBarCloseButton) window()->close(); - mActiveControl = QStyle::SC_None; + if (maxButtonRect().contains(global) && mActiveControl == QHtml5Compositor::SC_TitleBarMaxButton) { + window()->setWindowState(Qt::WindowMaximized); + platformScreen()->resizeMaximizedWindows(); + } + + if (normButtonRect().contains(global) && mActiveControl == QHtml5Compositor::SC_TitleBarNormalButton) { + window()->setWindowState(Qt::WindowNoState); + setGeometry(normalGeometry()); + } + + mActiveControl = QHtml5Compositor::SC_None; invalidate(); } int QHtml5Window::titleHeight() const { - return getAppStyle()->pixelMetric(QStyle::PM_TitleBarHeight, nullptr, nullptr); + return 18. * (qreal(qt_defaultDpiX()) / 96.0);//dpiScaled(18.); } int QHtml5Window::borderWidth() const { - return getAppStyle()->pixelMetric(QStyle::PM_MDIFrameWidth, nullptr, nullptr); + return 4. * (qreal(qt_defaultDpiX()) / 96.0);// dpiScaled(4.); } QRegion QHtml5Window::titleGeometry() const @@ -282,7 +284,8 @@ QRegion QHtml5Window::resizeRegion() const bool QHtml5Window::isPointOnTitle(QPoint point) const { - return titleGeometry().contains(point); + bool ok = titleGeometry().contains(point); + return ok; } bool QHtml5Window::isPointOnResizeRegion(QPoint point) const @@ -331,35 +334,39 @@ QHtml5Window::ResizeMode QHtml5Window::resizeModeAtPoint(QPoint point) const return ResizeNone; } -QRect getSubControlRect(const QHtml5Window *window, QStyle::ComplexControl control, QStyle::SubControl subControl) +QRect getSubControlRect(const QHtml5Window *window, QHtml5Compositor::SubControls subControl) { - QStyle *style = getAppStyle(); - QStyleOptionTitleBar options = makeTitleBarOptions(window); + QHtml5Compositor::QHtml5TitleBarOptions options = QHtml5Compositor::makeTitleBarOptions(window); - QRect r = style->subControlRect(control, &options, subControl, nullptr); - r.translate(window->window()->frameGeometry().x(), window->window()->frameGeometry().y());; + QRect r = QHtml5Compositor::titlebarRect(options, subControl); + r.translate(window->window()->frameGeometry().x(), window->window()->frameGeometry().y()); - return r; + return r; } QRect QHtml5Window::maxButtonRect() const { - return getSubControlRect(this, QStyle::CC_TitleBar, QStyle::SC_TitleBarMaxButton); + return getSubControlRect(this, QHtml5Compositor::SC_TitleBarMaxButton); } QRect QHtml5Window::minButtonRect() const { - return getSubControlRect(this, QStyle::CC_TitleBar, QStyle::SC_TitleBarMinButton); + return getSubControlRect(this, QHtml5Compositor::SC_TitleBarMinButton); } QRect QHtml5Window::closeButtonRect() const { - return getSubControlRect(this, QStyle::CC_TitleBar, QStyle::SC_TitleBarCloseButton); + return getSubControlRect(this, QHtml5Compositor::SC_TitleBarCloseButton); +} + +QRect QHtml5Window::normButtonRect() const +{ + return getSubControlRect(this, QHtml5Compositor::SC_TitleBarNormalButton); } QRect QHtml5Window::sysMenuRect() const { - return getSubControlRect(this, QStyle::CC_TitleBar, QStyle::SC_TitleBarSysMenu); + return getSubControlRect(this, QHtml5Compositor::SC_TitleBarSysMenu); } QRegion QHtml5Window::titleControlRegion() const @@ -378,9 +385,26 @@ void QHtml5Window::invalidate() mCompositor->requestRedraw(); } -QStyle::SubControl QHtml5Window::activeSubControl() const +QHtml5Compositor::SubControls QHtml5Window::activeSubControl() const { return mActiveControl; } +void QHtml5Window::setWindowState(Qt::WindowStates states) +{ + mWindowState = Qt::WindowNoState; + if (states & Qt::WindowMinimized) + mWindowState = Qt::WindowMinimized; +#warning FIXME ShowFullScreen + else if (states & Qt::WindowFullScreen) // someone sets this initially as default + mWindowState = Qt::WindowFullScreen; + else if (states & Qt::WindowMaximized) + mWindowState = Qt::WindowMaximized; +// update? +} + +QRect QHtml5Window::normalGeometry() const +{ + return mNormalGeometry; +} QT_END_NAMESPACE diff --git a/src/plugins/platforms/html5/qhtml5window.h b/src/plugins/platforms/html5/qhtml5window.h index 4e77f75e62..24cde71e77 100644 --- a/src/plugins/platforms/html5/qhtml5window.h +++ b/src/plugins/platforms/html5/qhtml5window.h @@ -45,7 +45,7 @@ #include <emscripten/html5.h> #include "qhtml5backingstore.h" #include "qhtml5screen.h" -#include <QtWidgets/QStyle> +#include "qhtml5compositor.h" QT_BEGIN_NAMESPACE @@ -80,6 +80,7 @@ public: void propagateSizeHints() Q_DECL_OVERRIDE; void raise() Q_DECL_OVERRIDE; void lower() Q_DECL_OVERRIDE; + QRect normalGeometry() const override; QHTML5Screen *platformScreen() const; void setBackingStore(QHTML5BackingStore *store) { mBackingStore = store; } @@ -102,8 +103,11 @@ public: QRect minButtonRect() const; QRect closeButtonRect() const; QRect sysMenuRect() const; + QRect normButtonRect() const; QRegion titleControlRegion() const; - QStyle::SubControl activeSubControl() const; + QHtml5Compositor::SubControls activeSubControl() const; + + void setWindowState(Qt::WindowStates state); protected: void invalidate(); @@ -122,7 +126,8 @@ protected: QHtml5Compositor *mCompositor; bool m_raster; - QStyle::SubControl mActiveControl; + QHtml5Compositor::SubControls mActiveControl; + QRect mNormalGeometry; }; QT_END_NAMESPACE #endif // QHTML5WINDOW_H |