📄 qdockwidgetlayout.cpp
字号:
if (info.item->layout()) { // forward the place to the nested layout QDockWidgetLayout *l = qobject_cast<QDockWidgetLayout *>(info.item->layout()); Q_ASSERT(l != 0); DEBUG(" forwarding..."); target = l->place(dockwidget, _r, mouse); DEBUG("END of QDockWidgetLayout::place (forwarded)"); return target; } const QSize sz1 = dockwidget->minimumSizeHint(), sz2 = info.item->minimumSize(); const int separatorExtent = parentWidget()->style()->pixelMetric(QStyle::PM_DockWidgetSeparatorExtent); Qt::DockWidgetAreas allowedAreas = getAllowedAreas(QStyle::visualRect(QApplication::layoutDirection(), parentWidget()->rect(), info.item->geometry()), sz1, sz2, separatorExtent); /* we do in-place reordering if the dock widget is in this layout. we allow splitting into adjacent items by delaying the reordering until the mouse is closer to the center of the adjacent item then the current one */ int which = -1; for (int i = 0; which == -1 && i < layout_info.count(); ++i) { const QDockWidgetLayoutInfo &info = layout_info.at(i); if (info.is_sep) continue; if (info.item->isEmpty()) continue; if (dockwidget == info.item->widget()) which = i; } if (which != -1) { if (which == location.index) { target = info.item->geometry(); target.moveTopLeft(parentWidget()->mapToGlobal(target.topLeft())); DEBUG() << "END of place (placed back at original position" << target << ")"; return target; } const int center = pick(orientation, QStyle::visualRect(QApplication::layoutDirection(), parentWidget()->rect(), layout_info.at(location.index).item->geometry()).center()); const int pos = pick(orientation, p); if ((which > location.index && pos < center) || (which < location.index && pos > center)) { DEBUG() << " swapping" << which << "with" << location.index; layout_info.swap(which, location.index); relayout(); target = layout_info.at(location.index).item->geometry(); target.moveTopLeft(parentWidget()->mapToGlobal(target.topLeft())); // make sure we don't discard the new layout information! *save_layout_info = layout_info; DEBUG() << "END of place, in-place reorder, target is" << target; return target; } else { DEBUG() << " cannot swap"; if (horizontal) allowedAreas &= ~(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); else allowedAreas &= ~(Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea); } } DEBUG() << " trySplit:" << orientation << location.area << QStyle::visualRect(QApplication::layoutDirection(), parentWidget()->rect(), info.item->geometry()) << p << sz1 << sz2 << separatorExtent; target = ::trySplit(orientation, location.area, allowedAreas, QStyle::visualRect(QApplication::layoutDirection(), parentWidget()->rect(), info.item->geometry()), p, separatorExtent); DEBUG() << " got" << target; if (!target.isEmpty()) { target = QStyle::visualRect(QApplication::layoutDirection(), parentWidget()->rect(), target); target.setSize(target.size().expandedTo(sz1)); target.moveTopLeft(parentWidget()->mapToGlobal(target.topLeft())); } DEBUG() << "END of place, target is" << target; return target;}/*! */void QDockWidgetLayout::drop(QDockWidget *dockwidget, const QRect &_r, const QPoint &mouse){ DEBUG("QDockWidgetLayout::drop"); // screen -> logical coordinates QPoint p = parentWidget()->mapFromGlobal(mouse); if (QApplication::layoutDirection() == Qt::RightToLeft) p = QPoint(parentWidget()->rect().right() - p.x(), p.y()); QRect r = QStyle::visualRect(QApplication::layoutDirection(), parentWidget()->rect(), _r); Location location = locate(p - QStyle::visualRect(QApplication::layoutDirection(), parentWidget()->rect(), geometry()).topLeft()); const QDockWidgetLayoutInfo &info = layout_info.at(location.index); const bool horizontal = orientation == Qt::Horizontal; if (info.item->layout()) { // forward the drop to the nested layout QDockWidgetLayout *l = qobject_cast<QDockWidgetLayout *>(info.item->layout()); Q_ASSERT(l != 0); DEBUG(" forwarding..."); l->drop(dockwidget, _r, mouse); DEBUG("END of QDockWidgetLayout::drop (forwarded)"); return; } if (dockwidget == info.item->widget()) { // placed back at original position if (dockwidget->isFloating()) { dockwidget->setFloating(false); dockwidget->show(); } DEBUG("END of drop (shortcut - dropped at original position)"); return; } const QSize sz1 = dockwidget->minimumSizeHint(), sz2 = info.item->minimumSize(); const int separatorExtent = parentWidget()->style()->pixelMetric(QStyle::PM_DockWidgetSeparatorExtent); Qt::DockWidgetAreas allowedAreas = getAllowedAreas(QStyle::visualRect(QApplication::layoutDirection(), parentWidget()->rect(), info.item->geometry()), sz1, sz2, separatorExtent); /* we do in-place reordering if the dock widget is in this layout. we allow splitting into adjacent items by delaying the reordering until the mouse is closer to the center of the adjacent item then the current one */ int found = -1; int which = -1; for (int i = 0; which == -1 && i < layout_info.count(); ++i) { const QDockWidgetLayoutInfo &info = layout_info.at(i); if (info.is_sep) continue; if (dockwidget == info.item->widget()) { found = i; if (!info.item->isEmpty()) which = i; } } if (which != -1) { DEBUG() << " drop after in-place reorder, only allowing perpendicular splits"; if (horizontal) allowedAreas &= ~(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); else allowedAreas &= ~(Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea); }#ifndef QT_NO_MAINWINDOW DEBUG() << " trySplit:" << orientation << location.area << QStyle::visualRect(QApplication::layoutDirection(), parentWidget()->rect(), info.item->geometry()) << p << sz1 << sz2 << separatorExtent; QRect target = ::trySplit(orientation, location.area, allowedAreas, QStyle::visualRect(QApplication::layoutDirection(), parentWidget()->rect(), info.item->geometry()), p, separatorExtent); DEBUG() << " got" << target; if (!target.isEmpty()) { target = QStyle::visualRect(QApplication::layoutDirection(), parentWidget()->rect(), target); QMainWindowLayout *layout = qobject_cast<QMainWindowLayout *>(parentWidget()->layout()); Q_ASSERT(layout != 0); layout->removeRecursive(dockwidget); // if we removed a dock widget in this layout, adjust the // insertion index if (found != -1 && found < location.index) location.index -= 2; bool nested = false; switch (orientation) { case Qt::Horizontal: switch (location.area) { case Qt::TopDockWidgetArea: case Qt::BottomDockWidgetArea: nested = true; default: break; } break; case Qt::Vertical: switch (location.area) { case Qt::LeftDockWidgetArea: case Qt::RightDockWidgetArea: nested = true; default: break; } break; default: Q_ASSERT_X(false, "QDockWidgetLayout", "internal error"); } if (nested) { DEBUG() << " splitting"; split(this, qobject_cast<QDockWidget *>(info.item->widget()), dockwidget, location.area); } else { DEBUG() << " extending"; int at = location.index / 2; if (location.area == Qt::RightDockWidgetArea || location.area == Qt::BottomDockWidgetArea) ++at; const int sz = pick(orientation, target.size()); const_cast<QDockWidgetLayoutInfo &>(info).cur_size -= sz + separatorExtent; QDockWidgetLayoutInfo &newInfo = insert(at, new QWidgetItem(dockwidget)); newInfo.cur_size = sz; newInfo.is_dropped = true; relayout(QInternal::RelayoutDropped); newInfo.is_dropped = false; } if (dockwidget->isFloating()) { // reparent the dock window into the main window dockwidget->setFloating(false); dockwidget->show(); } } DEBUG("END of drop");#endif // QT_NO_MAINWINDOW}void QDockWidgetLayout::extend(QDockWidget *dockwidget, Qt::Orientation direction){ if (direction == orientation) { addWidget(dockwidget); } else { Q_ASSERT(relayout_type == QInternal::RelayoutNormal); relayout_type = QInternal::RelayoutDropped; QDockWidgetLayout *nestedLayout = new QDockWidgetLayout(area, orientation); nestedLayout->setParent(this); nestedLayout->setObjectName(objectName() + QLatin1String("_nestedCopy")); for (int i = 0; i < layout_info.count(); ++i) { const QDockWidgetLayoutInfo &info = layout_info.at(i); if (info.is_sep) { delete info.item->widget(); delete info.item; } else { nestedLayout->addItem(info.item); } } relayout_type = QInternal::RelayoutNormal; layout_info.clear(); setOrientation(direction); addItem(nestedLayout); addWidget(dockwidget); }}static void locateDockWidget(QDockWidget *w, QDockWidgetLayout **layout, int *where){ QDockWidgetLayout *l = *layout; *where = -1; for (int i = 0; i < l->layout_info.count(); ++i) { const QDockWidgetLayoutInfo &info = l->layout_info.at(i); if (info.is_sep) continue; if (w == info.item->widget()) { *where = i; *layout = l; } else if (QLayout *lout = info.item->layout()) { *layout = qobject_cast<QDockWidgetLayout *>(lout); locateDockWidget(w, layout, where); } if (*where != -1) return; }}void QDockWidgetLayout::split(QDockWidgetLayout *layout, QDockWidget *existing, QDockWidget *with, Qt::DockWidgetArea area){ int which = -1; locateDockWidget(existing, &layout, &which); Q_ASSERT(which != -1); const QDockWidgetLayoutInfo &info = layout->layout_info.at(which); Q_ASSERT(layout->relayout_type == QInternal::RelayoutNormal); layout->relayout_type = QInternal::RelayoutDropped; const Qt::Orientation howToSplit = ((area == Qt::LeftDockWidgetArea || area == Qt::RightDockWidgetArea) ? Qt::Horizontal : Qt::Vertical); if (layout->orientation == howToSplit) { // don't nest, just split save_size between the 2 dock widgets const int separator_extent = layout->parentWidget()->style()->pixelMetric(QStyle::PM_DockWidgetSeparatorExtent); int each_size = qMax(info.cur_size - separator_extent, 0) / 2; int at = which; if (area == Qt::RightDockWidgetArea || area == Qt::BottomDockWidgetArea) at += 2; layout->addChildWidget(with); layout->insert(at, new QWidgetItem(with)).cur_size = const_cast<QDockWidgetLayoutInfo &>(info).cur_size = each_size; } else { // create a nested window dock in place of the current widget QDockWidgetLayout *nestedLayout = new QDockWidgetLayout(area, (layout->orientation == Qt::Horizontal ? Qt::Vertical : Qt::Horizontal)); nestedLayout->setParent(layout); nestedLayout->setObjectName(layout->objectName() + "_nestedLayout"); int save_size = info.cur_size; layout->removeWidget(existing); // note: info is invalid from now on layout->insert(which / 2, nestedLayout).cur_size = save_size; layout->invalidate(); switch (area) { case Qt::LeftDockWidgetArea: case Qt::TopDockWidgetArea: nestedLayout->addWidget(with); nestedLayout->addWidget(existing); break; case Qt::RightDockWidgetArea: case Qt::BottomDockWidgetArea: nestedLayout->addWidget(existing); nestedLayout->addWidget(with); break; default: Q_ASSERT_X(false, "QDockWidgetLayout", "internal error"); break; } } layout->relayout_type = QInternal::RelayoutNormal;}void QDockWidgetLayout::maybeDelete(){ if (layout_info.isEmpty()) delete this;}#endif // QT_NO_DOCKWIDGET
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -