📄 qdockwidget.cpp
字号:
int mw = q->style()->pixelMetric(QStyle::PM_DockWidgetTitleMargin, 0, q); int fw = q->style()->pixelMetric(QStyle::PM_DockWidgetFrameWidth, 0, q); return pick(verticalTitleBar, closeSize) + pick(verticalTitleBar, floatSize) + titleHeight + 2*fw + 3*mw;}int QDockWidgetLayout::titleHeight() const{ QDockWidget *q = qobject_cast<QDockWidget*>(parentWidget()); if (QWidget *title = widget(TitleBar)) return perp(verticalTitleBar, title->sizeHint()); QSize closeSize(0, 0); QSize floatSize(0, 0); if (QLayoutItem *item = item_list[CloseButton]) closeSize = item->widget()->sizeHint(); if (QLayoutItem *item = item_list[FloatButton]) floatSize = item->widget()->sizeHint(); int buttonHeight = qMax(perp(verticalTitleBar, closeSize), perp(verticalTitleBar, floatSize)); QFontMetrics titleFontMetrics = q->fontMetrics();#ifdef Q_WS_MAC if (qobject_cast<QMacStyle *>(q->style())) { extern QHash<QByteArray, QFont> *qt_app_fonts_hash(); // qapplication.cpp QFont font = qt_app_fonts_hash()->value("QToolButton", q->font()); titleFontMetrics = QFontMetrics(font); }#endif int mw = q->style()->pixelMetric(QStyle::PM_DockWidgetTitleMargin, 0, q); return qMax(buttonHeight + 2, titleFontMetrics.lineSpacing() + 2*mw);}void QDockWidgetLayout::setGeometry(const QRect &geometry){ QDockWidget *q = qobject_cast<QDockWidget*>(parentWidget()); bool nativeDeco = nativeWindowDeco(); int fw = q->isFloating() && !nativeDeco ? q->style()->pixelMetric(QStyle::PM_DockWidgetFrameWidth, 0, 0) : 0; if (nativeDeco) { if (QLayoutItem *item = item_list[Content]) item->setGeometry(geometry); } else { int titleHeight = this->titleHeight(); if (verticalTitleBar) { _titleArea = QRect(QPoint(fw, fw), QSize(titleHeight, geometry.height() - (fw * 2))); } else { _titleArea = QRect(QPoint(fw, fw), QSize(geometry.width() - (fw * 2), titleHeight)); } if (QLayoutItem *item = item_list[TitleBar]) { item->setGeometry(_titleArea); } else { QStyleOptionDockWidgetV2 opt; q->initStyleOption(&opt); if (QLayoutItem *item = item_list[CloseButton]) { if (!item->isEmpty()) { QRect r = q->style() ->subElementRect(QStyle::SE_DockWidgetCloseButton, &opt, q); if (!r.isNull()) item->setGeometry(r); } } if (QLayoutItem *item = item_list[FloatButton]) { if (!item->isEmpty()) { QRect r = q->style() ->subElementRect(QStyle::SE_DockWidgetFloatButton, &opt, q); if (!r.isNull()) item->setGeometry(r); } } } if (QLayoutItem *item = item_list[Content]) { QRect r = geometry; if (verticalTitleBar) { r.setLeft(_titleArea.right() + 1); r.adjust(0, fw, -fw, -fw); } else { r.setTop(_titleArea.bottom() + 1); r.adjust(fw, 0, -fw, -fw); } item->setGeometry(r); } } QLayoutItem *item = item_list[Content]; if (item != 0 && q->isFloating()) { QSize s = sizeFromContent(item->maximumSize(), true); q->setMaximumSize(s); } else { q->setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); }}void QDockWidgetLayout::setVerticalTitleBar(bool b){ if (b == verticalTitleBar) return; verticalTitleBar = b; invalidate(); parentWidget()->update();}/******************************************************************************** QDockWidgetItem*/QDockWidgetItem::QDockWidgetItem(QDockWidget *dockWidget) : QWidgetItem(dockWidget){}QSize QDockWidgetItem::minimumSize() const{ QSize widgetMin(0, 0); if (QLayoutItem *item = dockWidgetChildItem()) widgetMin = item->minimumSize(); return dockWidgetLayout()->sizeFromContent(widgetMin, false);}QSize QDockWidgetItem::maximumSize() const{ if (QLayoutItem *item = dockWidgetChildItem()) return dockWidgetLayout()->sizeFromContent(item->maximumSize(), false); return QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);}QSize QDockWidgetItem::sizeHint() const{ if (QLayoutItem *item = dockWidgetChildItem()) return dockWidgetLayout()->sizeFromContent(item->sizeHint(), false); return minimumSize();}/******************************************************************************** QDockWidgetPrivate*/void QDockWidgetPrivate::init(){ Q_Q(QDockWidget); QDockWidgetLayout *layout = new QDockWidgetLayout(q); QAbstractButton *button = new QDockWidgetTitleButton(q); QObject::connect(button, SIGNAL(clicked()), q, SLOT(_q_toggleTopLevel())); layout->setWidget(QDockWidgetLayout::FloatButton, button); button = new QDockWidgetTitleButton(q); QObject::connect(button, SIGNAL(clicked()), q, SLOT(close())); layout->setWidget(QDockWidgetLayout::CloseButton, button); resizer = new QWidgetResizeHandler(q); resizer->setMovingEnabled(false); resizer->setActive(false);#ifndef QT_NO_ACTION toggleViewAction = new QAction(q); toggleViewAction->setCheckable(true); fixedWindowTitle = qt_setWindowTitle_helperHelper(q->windowTitle(), q); toggleViewAction->setText(fixedWindowTitle); QObject::connect(toggleViewAction, SIGNAL(triggered(bool)), q, SLOT(_q_toggleView(bool)));#endif updateButtons();}/*! Initialize \a option with the values from this QDockWidget. This method is useful for subclasses when they need a QStyleOptionDockWidget, but don't want to fill in all the information themselves. \sa QStyleOption::initFrom()*/void QDockWidget::initStyleOption(QStyleOptionDockWidget *option) const{ Q_D(const QDockWidget); if (!option) return; QDockWidgetLayout *dwlayout = qobject_cast<QDockWidgetLayout*>(layout()); option->initFrom(this); option->rect = dwlayout->titleArea(); option->title = d->fixedWindowTitle; option->closable = hasFeature(this, QDockWidget::DockWidgetClosable); option->movable = hasFeature(this, QDockWidget::DockWidgetMovable); option->floatable = hasFeature(this, QDockWidget::DockWidgetFloatable); QDockWidgetLayout *l = qobject_cast<QDockWidgetLayout*>(layout()); QStyleOptionDockWidgetV2 *v2 = qstyleoption_cast<QStyleOptionDockWidgetV2*>(option); if (v2 != 0) v2->verticalTitleBar = l->verticalTitleBar;}void QDockWidgetPrivate::_q_toggleView(bool b){ Q_Q(QDockWidget); if (b == q->isHidden()) { if (b) q->show(); else q->close(); }}void QDockWidgetPrivate::updateButtons(){ Q_Q(QDockWidget); QDockWidgetLayout *layout = qobject_cast<QDockWidgetLayout*>(q->layout()); QStyleOptionDockWidget opt; q->initStyleOption(&opt); bool customTitleBar = layout->widget(QDockWidgetLayout::TitleBar) != 0; bool nativeDeco = layout->nativeWindowDeco(); bool hideButtons = nativeDeco || customTitleBar; bool canClose = hasFeature(q, QDockWidget::DockWidgetClosable); bool canFloat = hasFeature(q, QDockWidget::DockWidgetFloatable); QAbstractButton *button = qobject_cast<QAbstractButton*>(layout->widget(QDockWidgetLayout::FloatButton)); button->setIcon(q->style()->standardIcon(QStyle::SP_TitleBarNormalButton)); button->setVisible(canFloat && !hideButtons); button = qobject_cast <QAbstractButton*>(layout->widget(QDockWidgetLayout::CloseButton)); button->setIcon(q->style()->standardIcon(QStyle::SP_TitleBarCloseButton)); button->setVisible(canClose && !hideButtons); q->setAttribute(Qt::WA_ContentsPropagated, (canFloat || canClose) && !hideButtons); layout->invalidate();}void QDockWidgetPrivate::_q_toggleTopLevel(){ Q_Q(QDockWidget); q->setFloating(!q->isFloating());}void QDockWidgetPrivate::initDrag(const QPoint &pos, bool nca){ Q_Q(QDockWidget); if (state != 0) return; QMainWindow *win = qobject_cast<QMainWindow*>(q->parentWidget()); Q_ASSERT(win != 0); QMainWindowLayout *layout = qobject_cast<QMainWindowLayout*>(win->layout()); Q_ASSERT(layout != 0); if (layout->pluggingWidget != 0) // the main window is animating a docking operation return; state = new QDockWidgetPrivate::DragState; state->pressPos = pos; state->dragging = false; state->widgetItem = 0; state->ownWidgetItem = false; state->nca = nca; state->ctrlDrag = false;}void QDockWidgetPrivate::startDrag(){ Q_Q(QDockWidget); if (state == 0 || state->dragging) return; QMainWindowLayout *layout = qobject_cast<QMainWindowLayout *>(q->parentWidget()->layout()); Q_ASSERT(layout != 0); state->widgetItem = layout->unplug(q); if (state->widgetItem == 0) { /* I have a QMainWindow parent, but I was never inserted with QMainWindow::addDockWidget, so the QMainWindowLayout has no widget item for me. :( I have to create it myself, and then delete it if I don't get dropped into a dock area. */ state->widgetItem = new QDockWidgetItem(q); state->ownWidgetItem = true; } if (state->ctrlDrag) layout->restore(); state->dragging = true;}void QDockWidgetPrivate::endDrag(bool abort){ Q_Q(QDockWidget); Q_ASSERT(state != 0); q->releaseMouse(); if (state->dragging) { QMainWindowLayout *layout = qobject_cast<QMainWindowLayout *>(q->parentWidget()->layout()); Q_ASSERT(layout != 0); if (abort || !layout->plug(state->widgetItem)) { if (::hasFeature(q, QDockWidget::DockWidgetFloatable)) { if (state->ownWidgetItem) delete state->widgetItem; layout->restore();#ifdef Q_WS_X11 // get rid of the X11BypassWindowManager window flag and activate the resizer Qt::WindowFlags flags = q->windowFlags(); flags &= ~Qt::X11BypassWindowManagerHint; q->setWindowFlags(flags); resizer->setActive(QWidgetResizeHandler::Resize, true); q->show();#else QDockWidgetLayout *myLayout = qobject_cast<QDockWidgetLayout*>(q->layout()); resizer->setActive(QWidgetResizeHandler::Resize, myLayout->widget(QDockWidgetLayout::TitleBar) != 0);#endif undockedGeometry = q->geometry(); q->activateWindow(); } else { layout->revert(state->widgetItem); } } } delete state; state = 0;}bool QDockWidgetPrivate::isAnimating() const{ Q_Q(const QDockWidget); QMainWindow *mainWin = qobject_cast<QMainWindow*>(q->parentWidget()); if (mainWin == 0) return false; QMainWindowLayout *mainWinLayout = qobject_cast<QMainWindowLayout*>(mainWin->layout()); if (mainWinLayout == 0) return false; return (void*)mainWinLayout->pluggingWidget == (void*)q;}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))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -