📄 q3dockwindow.cpp
字号:
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the Qt3Support 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 "q3dockwindow.h"#ifndef QT_NO_MAINWINDOW#include "qapplication.h"#include "qcursor.h"#include "qdesktopwidget.h"#include "q3dockarea.h"#include "qevent.h"#include "qlayout.h"#include "q3mainwindow.h"#include "qpainter.h"#include "qpointer.h"#include "qstyle.h"#include "qstyleoption.h"#include "qtimer.h"#include "q3toolbar.h"#include "qtoolbutton.h"#include "qtooltip.h"#include <private/q3titlebar_p.h>#include <private/qwidgetresizehandler_p.h>#include <qrubberband.h>#include <qdebug.h>#ifdef Q_WS_MACstatic bool default_opaque = true;#elsestatic bool default_opaque = false;#endifclass Q3DockWindowPrivate{};class Q3DockWindowResizeHandle : public QWidget{ Q_OBJECTpublic: Q3DockWindowResizeHandle(Qt::Orientation o, QWidget *parent, Q3DockWindow *w, const char* /*name*/=0); void setOrientation(Qt::Orientation o); Qt::Orientation orientation() const { return orient; } QSize sizeHint() const;protected: void paintEvent(QPaintEvent *); void mouseMoveEvent(QMouseEvent *); void mousePressEvent(QMouseEvent *); void mouseReleaseEvent(QMouseEvent *); bool event(QEvent *event);private: void startLineDraw(); void endLineDraw(); void drawLine(const QPoint &globalPos);private: Qt::Orientation orient; bool mousePressed; QRubberBand *rubberBand; QPoint lastPos, firstPos; Q3DockWindow *dockWindow; bool mouseOver;};Q3DockWindowResizeHandle::Q3DockWindowResizeHandle(Qt::Orientation o, QWidget *parent, Q3DockWindow *w, const char *) : QWidget(parent, "qt_dockwidget_internal"), mousePressed(false), rubberBand(0), dockWindow(w), mouseOver(false){ setOrientation(o);}QSize Q3DockWindowResizeHandle::sizeHint() const{ QStyleOptionQ3DockWindow opt; opt.init(this); if (!dockWindow->area() || dockWindow->area()->orientation() == Qt::Horizontal) opt.state |= QStyle::State_Horizontal; opt.rect = rect(); opt.docked = dockWindow->area(); opt.closeEnabled = dockWindow->isCloseEnabled(); int sw = 2 * style()->pixelMetric(QStyle::PM_SplitterWidth, &opt, this) / 3; return (style()->sizeFromContents(QStyle::CT_Q3DockWindow, &opt, QSize(sw, sw), this).expandedTo(QApplication::globalStrut()));}void Q3DockWindowResizeHandle::setOrientation(Qt::Orientation o){ orient = o; if (o == Qt::Horizontal) {#ifndef QT_NO_CURSOR setCursor(Qt::splitVCursor);#endif setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed)); } else {#ifndef QT_NO_CURSOR setCursor(Qt::splitHCursor);#endif setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding)); }}void Q3DockWindowResizeHandle::mousePressEvent(QMouseEvent *e){ e->ignore(); if (e->button() != Qt::LeftButton) return; e->accept(); mousePressed = true; if (!dockWindow->opaqueMoving()) startLineDraw(); lastPos = firstPos = e->globalPos(); if (!dockWindow->opaqueMoving()) drawLine(e->globalPos());}void Q3DockWindowResizeHandle::mouseMoveEvent(QMouseEvent *e){ if (!mousePressed) return; if (!dockWindow->opaqueMoving()) { if (orientation() != dockWindow->area()->orientation()) { if (orientation() == Qt::Horizontal) { int minpos = dockWindow->area()->mapToGlobal(QPoint(0, 0)).y(); int maxpos = dockWindow->area()->mapToGlobal(QPoint(0, 0)).y() + dockWindow->area()->height(); if (e->globalPos().y() < minpos || e->globalPos().y() > maxpos) return; } else { int minpos = dockWindow->area()->mapToGlobal(QPoint(0, 0)).x(); int maxpos = dockWindow->area()->mapToGlobal(QPoint(0, 0)).x() + dockWindow->area()->width(); if (e->globalPos().x() < minpos || e->globalPos().x() > maxpos) return; } } else { QWidget *w = dockWindow->area()->window(); if (w) { if (orientation() == Qt::Horizontal) { int minpos = w->mapToGlobal(QPoint(0, 0)).y(); int maxpos = w->mapToGlobal(QPoint(0, 0)).y() + w->height(); if (e->globalPos().y() < minpos || e->globalPos().y() > maxpos) return; } else { int minpos = w->mapToGlobal(QPoint(0, 0)).x(); int maxpos = w->mapToGlobal(QPoint(0, 0)).x() + w->width(); if (e->globalPos().x() < minpos || e->globalPos().x() > maxpos) return; } } } } if (!dockWindow->opaqueMoving()) drawLine(lastPos); lastPos = e->globalPos(); if (dockWindow->opaqueMoving()) { mouseReleaseEvent(e); mousePressed = true; firstPos = e->globalPos(); } if (!dockWindow->opaqueMoving()) drawLine(e->globalPos());}void Q3DockWindowResizeHandle::mouseReleaseEvent(QMouseEvent *e){ if (mousePressed) { if (!dockWindow->opaqueMoving()) { drawLine(lastPos); endLineDraw(); } if (orientation() != dockWindow->area()->orientation()) dockWindow->area()->invalidNextOffset(dockWindow); if (orientation() == Qt::Horizontal) { int dy; if (dockWindow->area()->handlePosition() == Q3DockArea::Normal || orientation() != dockWindow->area()->orientation()) dy = e->globalPos().y() - firstPos.y(); else dy = firstPos.y() - e->globalPos().y(); int d = dockWindow->height() + dy; if (orientation() != dockWindow->area()->orientation()) { dockWindow->setFixedExtentHeight(-1); d = qMax(d, dockWindow->minimumHeight()); int ms = dockWindow->area()->maxSpace(d, dockWindow); d = qMin(d, ms); dockWindow->setFixedExtentHeight(d); } else { dockWindow->area()->setFixedExtent(d, dockWindow); } } else { int dx; if (dockWindow->area()->handlePosition() == Q3DockArea::Normal || orientation() != dockWindow->area()->orientation()) dx = e->globalPos().x() - firstPos.x(); else dx = firstPos.x() - e->globalPos().x(); int d = dockWindow->width() + dx; if (orientation() != dockWindow->area()->orientation()) { dockWindow->setFixedExtentWidth(-1); d = qMax(d, dockWindow->minimumWidth()); int ms = dockWindow->area()->maxSpace(d, dockWindow); d = qMin(d, ms); dockWindow->setFixedExtentWidth(d); } else { dockWindow->area()->setFixedExtent(d, dockWindow); } } } QApplication::postEvent(dockWindow->area(), new QEvent(QEvent::LayoutHint)); mousePressed = false;}bool Q3DockWindowResizeHandle::event(QEvent *event){ switch (event->type()) { case QEvent::HoverEnter: if (!mouseOver) { mouseOver = true; update(); } break; case QEvent::HoverLeave: if (mouseOver) { mouseOver = false; update(); } break; default: break; } return QWidget::event(event);}void Q3DockWindowResizeHandle::paintEvent(QPaintEvent *){ QPainter p(this); QStyleOption opt(0); opt.init(this); if (orientation() == Qt::Horizontal) opt.state |= QStyle::State_Horizontal; style()->drawPrimitive(QStyle::PE_IndicatorDockWidgetResizeHandle, &opt, &p, this);}void Q3DockWindowResizeHandle::startLineDraw(){ if (rubberBand) endLineDraw(); rubberBand = new QRubberBand(QRubberBand::Line); rubberBand->setGeometry(-1, -1, 1, 1); rubberBand->show();}void Q3DockWindowResizeHandle::endLineDraw(){ delete rubberBand; rubberBand = 0;}void Q3DockWindowResizeHandle::drawLine(const QPoint &globalPos){ QPoint start = mapToGlobal(QPoint(0, 0)); QPoint starta = dockWindow->area()->mapToGlobal(QPoint(0, 0)); QPoint end = globalPos; if (orientation() == Qt::Horizontal) { if (orientation() == dockWindow->orientation()) rubberBand->setGeometry(starta.x(), end.y(), dockWindow->area()->width(), height()); else rubberBand->setGeometry(start.x(), end.y(), width(), height()); } else { if (orientation() == dockWindow->orientation()) rubberBand->setGeometry(end.x(), starta.y(), width(), dockWindow->area()->height()); else rubberBand->setGeometry(end.x(), start.y(), width(), height()); }}static QPoint realWidgetPos(Q3DockWindow *w){ if (!w->parentWidget() || w->place() == Q3DockWindow::OutsideDock) return w->pos(); return w->parentWidget()->mapToGlobal(w->geometry().topLeft());}class Q3DockWindowHandle : public QWidget{ Q_OBJECT Q_PROPERTY(QString windowTitle READ windowTitle) friend class Q3DockWindow; friend class Q3DockWindowTitleBar;public: Q3DockWindowHandle(Q3DockWindow *dw); void updateGui(); QSize minimumSizeHint() const; QSize minimumSize() const { return minimumSizeHint(); } QSize sizeHint() const { return minimumSize(); } void setOpaqueMoving(bool b) { opaque = b; } QString windowTitle() const { return dockWindow->windowTitle(); }signals: void doubleClicked();protected: void paintEvent(QPaintEvent *e); void resizeEvent(QResizeEvent *e); void mousePressEvent(QMouseEvent *e); void mouseMoveEvent(QMouseEvent *e); void mouseReleaseEvent(QMouseEvent *e); void mouseDoubleClickEvent(QMouseEvent *e); void keyPressEvent(QKeyEvent *e); void keyReleaseEvent(QKeyEvent *e); void changeEvent(QEvent *);private slots: void minimize();private: Q3DockWindow *dockWindow; QPoint offset; QToolButton *closeButton; QTimer *timer; uint opaque : 1; uint mousePressed : 1; uint hadDblClick : 1; uint ctrlDown : 1; QPointer<QWidget> oldFocus;};class Q3DockWindowTitleBar : public Q3TitleBar{ Q_OBJECT friend class Q3DockWindow; friend class Q3DockWindowHandle;public: Q3DockWindowTitleBar(Q3DockWindow *dw); void updateGui(); void setOpaqueMoving(bool b) { opaque = b; }protected: void resizeEvent(QResizeEvent *e); void mousePressEvent(QMouseEvent *e); void mouseMoveEvent(QMouseEvent *e); void mouseReleaseEvent(QMouseEvent *e); void mouseDoubleClickEvent(QMouseEvent *e); void keyPressEvent(QKeyEvent *e); void keyReleaseEvent(QKeyEvent *e);private: Q3DockWindow *dockWindow; QPoint offset; uint mousePressed : 1; uint hadDblClick : 1; uint opaque : 1; uint ctrlDown : 1; QPointer<QWidget> oldFocus;};Q3DockWindowHandle::Q3DockWindowHandle(Q3DockWindow *dw) : QWidget(dw, "qt_dockwidget_internal"), dockWindow(dw), closeButton(0), opaque(default_opaque), mousePressed(false){ ctrlDown = false; timer = new QTimer(this); connect(timer, SIGNAL(timeout()), this, SLOT(minimize()));#ifdef Q_WS_WIN setCursor(Qt::SizeAllCursor);#endif}void Q3DockWindowHandle::paintEvent(QPaintEvent *e){ if (!dockWindow->dockArea && !opaque) return; QPainter p(this); QStyleOptionQ3DockWindow opt; opt.init(this); if (!dockWindow->area() || dockWindow->area()->orientation() == Qt::Horizontal) opt.state |= QStyle::State_Horizontal; opt.rect = rect(); opt.docked = dockWindow->area(); opt.closeEnabled = dockWindow->isCloseEnabled();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -