📄 qdockwidget.cpp
字号:
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the QtGui module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file. Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "qdockwidget.h"#ifndef QT_NO_DOCKWIDGET#include <qaction.h>#include <qapplication.h>#include <qdesktopwidget.h>#include <qdrawutil.h>#include <qevent.h>#include <qfontmetrics.h>#include <qmainwindow.h>#include <qrubberband.h>#include <qstylepainter.h>#include <qtoolbutton.h>#include <qdebug.h>#include <private/qwidgetresizehandler_p.h>#include "qdockwidget_p.h"#include "qmainwindowlayout_p.h"#ifdef Q_WS_MAC#include <private/qt_mac_p.h>#include <qmacstyle_mac.h>#endifextern QString qt_setWindowTitle_helperHelper(const QString&, QWidget*); // qwidget.cppstatic inline bool hasFeature(const QDockWidget *dockwidget, QDockWidget::DockWidgetFeature feature){ return (dockwidget->features() & feature) == feature; }/* A Dock Window: [+] is the float button [X] is the close button +-------------------------------+ | Dock Window Title [+][X]| +-------------------------------+ | | | place to put the single | | QDockWidget child (this space | | does not yet have a name) | | | | | | | | | | | | | | | | | | | +-------------------------------+*//******************************************************************************** QDockWidgetTitleButton*/class QDockWidgetTitleButton : public QAbstractButton{ Q_OBJECTpublic: QDockWidgetTitleButton(QDockWidget *dockWidget); QSize sizeHint() const; inline QSize minimumSizeHint() const { return sizeHint(); } void enterEvent(QEvent *event); void leaveEvent(QEvent *event); void paintEvent(QPaintEvent *event);};QDockWidgetTitleButton::QDockWidgetTitleButton(QDockWidget *dockWidget) : QAbstractButton(dockWidget){ setFocusPolicy(Qt::NoFocus);}QSize QDockWidgetTitleButton::sizeHint() const{ ensurePolished(); int size = 2*style()->pixelMetric(QStyle::PM_DockWidgetTitleBarButtonMargin); if (!icon().isNull()) { int iconSize = style()->pixelMetric(QStyle::PM_SmallIconSize); const QPixmap pm = icon().pixmap(iconSize); size += qMax(pm.width(), pm.height()); } return QSize(size, size);}void QDockWidgetTitleButton::enterEvent(QEvent *event){ if (isEnabled()) update(); QAbstractButton::enterEvent(event);}void QDockWidgetTitleButton::leaveEvent(QEvent *event){ if (isEnabled()) update(); QAbstractButton::leaveEvent(event);}void QDockWidgetTitleButton::paintEvent(QPaintEvent *){ QPainter p(this); QRect r = rect(); QStyleOption opt; opt.init(this); opt.state |= QStyle::State_AutoRaise;#ifdef Q_WS_MAC if (!qobject_cast<QMacStyle *>(style()))#endif { if (isEnabled() && underMouse() && !isChecked() && !isDown()) opt.state |= QStyle::State_Raised; if (isChecked()) opt.state |= QStyle::State_On; if (isDown()) opt.state |= QStyle::State_Sunken; style()->drawPrimitive(QStyle::PE_PanelButtonTool, &opt, &p, this); } int shiftHorizontal = opt.state & QStyle::State_Sunken ? style()->pixelMetric(QStyle::PM_ButtonShiftHorizontal, &opt, this) : 0; int shiftVertical = opt.state & QStyle::State_Sunken ? style()->pixelMetric(QStyle::PM_ButtonShiftVertical, &opt, this) : 0; r.adjust(2, 2, -2, -2); r.translate(shiftHorizontal, shiftVertical); QPixmap pm = icon().pixmap(style()->pixelMetric(QStyle::PM_SmallIconSize), isEnabled() ? underMouse() ? QIcon::Active : QIcon::Normal : QIcon::Disabled, isDown() ? QIcon::On : QIcon::Off); style()->drawItemPixmap(&p, r, Qt::AlignCenter, pm);}/******************************************************************************** QDockWidgetLayout*/QDockWidgetLayout::QDockWidgetLayout(QWidget *parent) : QLayout(parent), verticalTitleBar(false), item_list(RoleCount, 0){}QDockWidgetLayout::~QDockWidgetLayout(){ qDeleteAll(item_list);}bool QDockWidgetLayout::nativeWindowDeco() const{#if defined(Q_WS_X11) || defined(Q_WS_QWS) return false;#else return parentWidget()->isWindow() && item_list[QDockWidgetLayout::TitleBar] == 0;#endif}void QDockWidgetLayout::addItem(QLayoutItem*){ qWarning() << "QDockWidgetLayout::addItem(): please use QDockWidgetLayout::setWidget()"; return;}QLayoutItem *QDockWidgetLayout::itemAt(int index) const{ int cnt = 0; foreach (QLayoutItem *item, item_list) { if (item == 0) continue; if (index == cnt++) return item; } return 0;}QLayoutItem *QDockWidgetLayout::takeAt(int index){ int j = 0; for (int i = 0; i < item_list.count(); ++i) { QLayoutItem *item = item_list.at(i); if (item == 0) continue; if (index == j) { item_list[i] = 0; invalidate(); return item; } ++j; } return 0;}int QDockWidgetLayout::count() const{ int result = 0; foreach (QLayoutItem *item, item_list) { if (item != 0) ++result; } return result;}QSize QDockWidgetLayout::sizeFromContent(const QSize &content, bool floating) const{ QSize result = content; if (verticalTitleBar) { result.setHeight(qMax(result.height(), minimumTitleWidth())); result.setWidth(qMax(content.width(), 0)); } else { result.setHeight(qMax(result.height(), 0)); result.setWidth(qMax(content.width(), minimumTitleWidth())); } QDockWidget *w = qobject_cast<QDockWidget*>(parentWidget()); bool customTitleBar = item_list[TitleBar] != 0; bool nativeDeco = floating && !customTitleBar;#if defined(Q_WS_X11) || defined(Q_WS_QWS) nativeDeco = false;#endif int fw = floating && !nativeDeco ? w->style()->pixelMetric(QStyle::PM_DockWidgetFrameWidth, 0, 0) : 0; const int th = titleHeight(); if (!nativeDeco) { if (verticalTitleBar) result += QSize(th + 2*fw, 2*fw); else result += QSize(2*fw, th + 2*fw); } result.setHeight(qMin(result.height(), (int) QWIDGETSIZE_MAX)); result.setWidth(qMin(result.width(), (int) QWIDGETSIZE_MAX)); if (content.width() < 0) result.setWidth(-1); if (content.height() < 0) result.setHeight(-1); QSize min = w->minimumSize(); /* A floating dockwidget will automatically get its minimumSize set to the layout's minimum size + deco. We're *not* interested in this, we only take minimumSize() into account if the user set it herself. Otherwise we end up expanding the result of a calculation for a non-floating dock widget to a floating dock widget's minimum size + window decorations. */ uint explicitMin = 0; if (w->d_func()->extra != 0) explicitMin = w->d_func()->extra->explicitMinSize; if (!(explicitMin & Qt::Horizontal) || min.width() == 0) min.setWidth(-1); if (!(explicitMin & Qt::Vertical) || min.height() == 0) min.setHeight(-1); return result.boundedTo(w->maximumSize()).expandedTo(min);}QSize QDockWidgetLayout::sizeHint() const{ QDockWidget *w = qobject_cast<QDockWidget*>(parentWidget()); QSize content(-1, -1); if (item_list[Content] != 0) content = item_list[Content]->sizeHint(); return sizeFromContent(content, w->isFloating());}QSize QDockWidgetLayout::minimumSize() const{ QDockWidget *w = qobject_cast<QDockWidget*>(parentWidget()); QSize content(0, 0); if (item_list[Content] != 0) content = item_list[Content]->minimumSize(); return sizeFromContent(content, w->isFloating());}QWidget *QDockWidgetLayout::widget(Role r) const{ QLayoutItem *item = item_list.at(r); return item == 0 ? 0 : item->widget();}QLayoutItem *QDockWidgetLayout::item(Role r) const{ return item_list.at(r);}void QDockWidgetLayout::setWidget(Role r, QWidget *w){ QWidget *old = widget(r); if (old != 0) { old->hide(); removeWidget(old); } if (w != 0) { addChildWidget(w); item_list[r] = new QWidgetItem(w); w->show(); } else { item_list[r] = 0; } invalidate();}static inline int pick(bool vertical, const QSize &size){ return vertical ? size.height() : size.width();}static inline int perp(bool vertical, const QSize &size){ return vertical ? size.width() : size.height();}int QDockWidgetLayout::minimumTitleWidth() const{ QDockWidget *q = qobject_cast<QDockWidget*>(parentWidget()); if (QWidget *title = widget(TitleBar)) return pick(verticalTitleBar, title->minimumSizeHint()); QSize closeSize(0, 0); QSize floatSize(0, 0); if (QLayoutItem *item = item_list[CloseButton]) closeSize = item->sizeHint(); if (QLayoutItem *item = item_list[FloatButton]) floatSize = item->sizeHint(); int titleHeight = this->titleHeight();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -