bool QDockWidgetPrivate::mousePressEvent(QMouseEvent *event) { #if !defined(QT_NO_MAINWINDOW) Q_Q(QDockWidget); QDockWidgetLayout *dwLayout = qobject_cast<QDockWidgetLayout*>(layout); if (!dwLayout->nativeWindowDeco()) { QRect titleArea = dwLayout->titleArea(); if (event->button() != Qt::LeftButton || !titleArea.contains(event->pos()) || // check if the tool window is movable... do nothing if it // is not (but allow moving if the window is floating) (!hasFeature(this, QDockWidget::DockWidgetMovable) && !q->isFloating()) || qobject_cast<QMainWindow*>(parent) == 0 || isAnimating() || state != 0) { return false; } initDrag(event->pos(), false); if (state) state->ctrlDrag = hasFeature(this, QDockWidget::DockWidgetFloatable) && event->modifiers() & Qt::ControlModifier; return true; } #endif // !defined(QT_NO_MAINWINDOW) return false; }
/*! \reimp */ void QDockWidget::paintEvent(QPaintEvent *event) { Q_UNUSED(event) QDockWidgetLayout *layout = qobject_cast<QDockWidgetLayout*>(this->layout()); bool customTitleBar = layout->widgetForRole(QDockWidgetLayout::TitleBar) != 0; bool nativeDeco = layout->nativeWindowDeco(); if (!nativeDeco && !customTitleBar) { QStylePainter p(this); // ### Add PixelMetric to change spacers, so style may show border // when not floating. if (isFloating()) { QStyleOptionFrame framOpt; framOpt.init(this); p.drawPrimitive(QStyle::PE_FrameDockWidget, framOpt); } // Title must be painted after the frame, since the areas overlap, and // the title may wish to extend out to all sides (eg. XP style) QStyleOptionDockWidgetV2 titleOpt; initStyleOption(&titleOpt); p.drawControl(QStyle::CE_DockWidgetTitle, titleOpt); } }
void QDockWidgetPrivate::updateButtons() { Q_Q(QDockWidget); QDockWidgetLayout *dwLayout = qobject_cast<QDockWidgetLayout*>(layout); QStyleOptionDockWidget opt; q->initStyleOption(&opt); bool customTitleBar = dwLayout->widgetForRole(QDockWidgetLayout::TitleBar) != 0; bool nativeDeco = dwLayout->nativeWindowDeco(); bool hideButtons = nativeDeco || customTitleBar; bool canClose = hasFeature(this, QDockWidget::DockWidgetClosable); bool canFloat = hasFeature(this, QDockWidget::DockWidgetFloatable); QAbstractButton *button = qobject_cast<QAbstractButton*>(dwLayout->widgetForRole(QDockWidgetLayout::FloatButton)); button->setIcon(q->style()->standardIcon(QStyle::SP_TitleBarNormalButton, &opt, q)); button->setVisible(canFloat && !hideButtons); button = qobject_cast <QAbstractButton*>(dwLayout->widgetForRole(QDockWidgetLayout::CloseButton)); button->setIcon(q->style()->standardIcon(QStyle::SP_TitleBarCloseButton, &opt, q)); button->setVisible(canClose && !hideButtons); q->setAttribute(Qt::WA_ContentsPropagated, (canFloat || canClose) && !hideButtons); layout->invalidate(); }
void QDockWidgetPrivate::setWindowState(bool floating, bool unplug, const QRect &rect) { Q_Q(QDockWidget); if (!floating && parent) { QMainWindowLayout *mwlayout = qt_mainwindow_layout(qobject_cast<QMainWindow *>(q->parentWidget())); if (mwlayout && mwlayout->dockWidgetArea(q) == Qt::NoDockWidgetArea) return; // this dockwidget can't be redocked } bool wasFloating = q->isFloating(); bool hidden = q->isHidden(); if (q->isVisible()) q->hide(); Qt::WindowFlags flags = floating ? Qt::Tool : Qt::Widget; QDockWidgetLayout *dwLayout = qobject_cast<QDockWidgetLayout*>(layout); const bool nativeDeco = dwLayout->nativeWindowDeco(floating); if (nativeDeco) { flags |= Qt::CustomizeWindowHint | Qt::WindowTitleHint; if (hasFeature(this, QDockWidget::DockWidgetClosable)) flags |= Qt::WindowCloseButtonHint; } else { flags |= Qt::FramelessWindowHint; } if (unplug) flags |= Qt::X11BypassWindowManagerHint; q->setWindowFlags(flags); #if defined(Q_WS_MAC) && !defined(QT_MAC_USE_COCOA) if (floating && nativeDeco && (q->features() & QDockWidget::DockWidgetVerticalTitleBar)) { ChangeWindowAttributes(HIViewGetWindow(HIViewRef(q->winId())), kWindowSideTitlebarAttribute, 0); } #endif if (!rect.isNull()) q->setGeometry(rect); updateButtons(); if (!hidden) q->show(); if (floating != wasFloating) { emit q->topLevelChanged(floating); if (!floating && parent) { QMainWindowLayout *mwlayout = qt_mainwindow_layout(qobject_cast<QMainWindow *>(q->parentWidget())); if (mwlayout) emit q->dockLocationChanged(mwlayout->dockWidgetArea(q)); } } resizer->setActive(QWidgetResizeHandler::Resize, !unplug && floating && !nativeDeco); }
void QDockWidgetPrivate::setWindowState(bool floating, bool unplug, const QRect &rect) { Q_Q(QDockWidget); if (!floating && parent) { QMainWindowLayout *mwlayout = qt_mainwindow_layout(qobject_cast<QMainWindow *>(q->parentWidget())); if (mwlayout && mwlayout->dockWidgetArea(q) == Qt::NoDockWidgetArea) return; // this dockwidget can't be redocked } bool wasFloating = q->isFloating(); bool hidden = q->isHidden(); if (q->isVisible()) q->hide(); Qt::WindowFlags flags = floating ? Qt::Tool : Qt::Widget; QDockWidgetLayout *dwLayout = qobject_cast<QDockWidgetLayout*>(layout); const bool nativeDeco = dwLayout->nativeWindowDeco(floating); if (nativeDeco) { flags |= Qt::CustomizeWindowHint | Qt::WindowTitleHint; if (hasFeature(this, QDockWidget::DockWidgetClosable)) flags |= Qt::WindowCloseButtonHint; } else { flags |= Qt::FramelessWindowHint; } if (unplug) flags |= Qt::X11BypassWindowManagerHint; q->setWindowFlags(flags); if (!rect.isNull()) q->setGeometry(rect); updateButtons(); if (!hidden) q->show(); if (floating != wasFloating) { emit q->topLevelChanged(floating); if (!floating && parent) { QMainWindowLayout *mwlayout = qt_mainwindow_layout(qobject_cast<QMainWindow *>(q->parentWidget())); if (mwlayout) emit q->dockLocationChanged(mwlayout->dockWidgetArea(q)); } } if (floating && nativeDeco) if (const QWindow *window = q->windowHandle()) if (QPlatformWindow *platformWindow = window->handle()) platformWindow->setFrameStrutEventsEnabled(true); resizer->setActive(QWidgetResizeHandler::Resize, !unplug && floating && !nativeDeco); }
void QDockWidgetPrivate::unplug(const QRect &rect) { Q_Q(QDockWidget); QRect r = rect; r.moveTopLeft(q->mapToGlobal(QPoint(0, 0))); QDockWidgetLayout *dwLayout = qobject_cast<QDockWidgetLayout*>(layout); if (dwLayout->nativeWindowDeco(true)) r.adjust(0, dwLayout->titleHeight(), 0, 0); setWindowState(true, true, r); }
bool QDockWidgetPrivate::mouseDoubleClickEvent(QMouseEvent *event) { QDockWidgetLayout *dwLayout = qobject_cast<QDockWidgetLayout*>(layout); if (!dwLayout->nativeWindowDeco()) { QRect titleArea = dwLayout->titleArea(); if (event->button() == Qt::LeftButton && titleArea.contains(event->pos()) && hasFeature(this, QDockWidget::DockWidgetFloatable)) { _q_toggleTopLevel(); return true; } } return false; }
void tst_QDockWidget::taskQTBUG_1665_closableChanged() { QDockWidget dock; dock.show(); QVERIFY(QTest::qWaitForWindowExposed(&dock)); QDockWidgetLayout *l = qobject_cast<QDockWidgetLayout*>(dock.layout()); if (l && !l->nativeWindowDeco()) QSKIP("this machine doesn't support native dock widget"); QVERIFY(dock.windowFlags() & Qt::WindowCloseButtonHint); //now let's remove the closable attribute dock.setFeatures(dock.features() ^ QDockWidget::DockWidgetClosable); QVERIFY(!(dock.windowFlags() & Qt::WindowCloseButtonHint)); }
void QDockWidgetPrivate::mouseDoubleClickEvent(QMouseEvent *event) { Q_Q(QDockWidget); QDockWidgetLayout *layout = qobject_cast<QDockWidgetLayout*>(q->layout()); if (!layout->nativeWindowDeco()) { QRect titleArea = layout->titleArea(); if (event->button() != Qt::LeftButton) return; if (!titleArea.contains(event->pos())) return; if (!::hasFeature(q, QDockWidget::DockWidgetFloatable)) return; _q_toggleTopLevel(); } }
void QDockWidget::setFeatures(QDockWidget::DockWidgetFeatures features) { Q_D(QDockWidget); features &= DockWidgetFeatureMask; if (d->features == features) return; const bool closableChanged = (d->features ^ features) & DockWidgetClosable; d->features = features; QDockWidgetLayout *layout = qobject_cast<QDockWidgetLayout*>(this->layout()); layout->setVerticalTitleBar(features & DockWidgetVerticalTitleBar); d->updateButtons(); d->toggleViewAction->setEnabled((d->features & DockWidgetClosable) == DockWidgetClosable); emit featuresChanged(d->features); update(); if (closableChanged && layout->nativeWindowDeco()) { //this ensures the native decoration is drawn d->setWindowState(true /*floating*/, true /*unplug*/); } }
bool QDockWidgetPrivate::mouseMoveEvent(QMouseEvent *event) { bool ret = false; #if !defined(QT_NO_MAINWINDOW) Q_Q(QDockWidget); if (!state) return ret; QDockWidgetLayout *dwlayout = qobject_cast<QDockWidgetLayout*>(layout); QMainWindowLayout *mwlayout = qobject_cast<QMainWindowLayout*>(q->parentWidget()->layout()); if (!dwlayout->nativeWindowDeco()) { if (!state->dragging && mwlayout->pluggingWidget == 0 && (event->pos() - state->pressPos).manhattanLength() > QApplication::startDragDistance()) { startDrag(); #ifdef Q_OS_WIN grabMouseWhileInWindow(); #else q->grabMouse(); #endif ret = true; } } if (state->dragging && !state->nca) { QPoint pos = event->globalPos() - state->pressPos; q->move(pos); if (!state->ctrlDrag) mwlayout->hover(state->widgetItem, event->globalPos()); ret = true; } #endif // !defined(QT_NO_MAINWINDOW) return ret; }
void QDockWidgetPrivate::mousePressEvent(QMouseEvent *event) { #if !defined(QT_NO_MAINWINDOW) Q_Q(QDockWidget); QDockWidgetLayout *layout = qobject_cast<QDockWidgetLayout*>(q->layout()); if (!layout->nativeWindowDeco()) { QRect titleArea = layout->titleArea(); if (event->button() != Qt::LeftButton) return; if (!titleArea.contains(event->pos())) return; // check if the tool window is movable... do nothing if it is not if (!::hasFeature(q, QDockWidget::DockWidgetMovable)) return; if (qobject_cast<QMainWindow*>(q->parentWidget()) == 0) return; if (isAnimating()) return; if (state != 0) return; initDrag(event->pos(), false); if (state == 0) return; state->ctrlDrag = event->modifiers() & Qt::ControlModifier; } #endif // !defined(QT_NO_MAINWINDOW) }