📄 qmainwindowlayout.cpp
字号:
const ToolBarLayoutInfo &info = lineInfo.list.at(i); return info.item; } } }#endif for (int i = 0; i < NPOSITIONS; ++i) { if (!layout_info[i].item) continue; if (x++ == index) return layout_info[i].item; } if (x++ == index) return statusbar; return 0;}QLayoutItem *QMainWindowLayout::takeAt(int index){ DEBUG("QMainWindowLayout::takeAt: index %d", index); int x = 0;#ifndef QT_NO_TOOLBAR for (int line = 0; line < tb_layout_info.size(); ++line) { ToolBarLineInfo &lineInfo = tb_layout_info[line]; for (int i = 0; i < lineInfo.list.size(); ++i) { if (x++ == index) { QLayoutItem *ret = lineInfo.list.at(i).item; lineInfo.list.removeAt(i); if (lineInfo.list.size() == 0) tb_layout_info.removeAt(line); return ret; } } }#endif for (int i = 0; i < NPOSITIONS; ++i) { if (!layout_info[i].item) continue; if (x++ == index) { VDEBUG() << " where" << i; QLayoutItem *ret = layout_info[i].item; if (!save_layout_info) { layout_info[i].size = QSize(); if (layout_info[i].sep) { delete layout_info[i].sep->widget(); delete layout_info[i].sep; } } layout_info[i].item = 0; layout_info[i].sep = 0; VDEBUG() << "END of QMainWindowLayout::takeAt (removed" << i << ")"; return ret; } } if (x++ == index) { QLayoutItem *ret = statusbar; statusbar = 0; return ret; } VDEBUG() << "END of QMainWindowLayout::takeAt (not found)"; return 0;}/* Fixes the mininum and maximum sizes depending on the current corner configuration.*/static void fix_minmax(QVector<QLayoutStruct> &ls, const QMainWindowLayout * const layout, POSITION pos){#ifdef QT_NO_DOCKWIDGET Q_UNUSED(ls); Q_UNUSED(layout); Q_UNUSED(pos);#else const Qt::DockWidgetArea area = static_cast<Qt::DockWidgetArea>(areaForPosition(pos)); const struct { Qt::Corner corner1, corner2; POSITION perp1, perp2; } order[] = { // LEFT { Qt::TopLeftCorner, Qt::BottomLeftCorner, TOP, BOTTOM }, // RIGHT { Qt::TopRightCorner, Qt::BottomRightCorner, TOP, BOTTOM }, // TOP { Qt::TopLeftCorner, Qt::TopRightCorner, LEFT, RIGHT }, // BOTTOM { Qt::BottomLeftCorner, Qt::BottomRightCorner, LEFT, RIGHT } }; if (!layout->layout_info[pos].item) return; if ((layout->corners[order[pos].corner1] != area || !layout->layout_info[order[pos].perp1].item) && (layout->corners[order[pos].corner2] != area || !layout->layout_info[order[pos].perp2].item)) { // if the area does not occupy any corner, we constrain the // minimum size of the center to the minimum size of the area ls[1].minimumSize = qMax(pick_perp(pos, layout->layout_info[pos].item->minimumSize()), ls[1].minimumSize); ls[1].maximumSize = qMin(pick_perp(pos, layout->layout_info[pos].item->maximumSize()), ls[1].maximumSize); } else { // if the area occupies only a single corner, then we // distribute the minimum size of the area across the center // and opposite side equally const int min = pick_perp(pos, layout->layout_info[pos].item->minimumSize()); if (layout->layout_info[order[pos].perp1].item && layout->corners[order[pos].corner1] == area && layout->corners[order[pos].corner2] != area) { ls[1].minimumSize = qMax(ls[1].minimumSize, min - ls[0].minimumSize); } else if (layout->layout_info[order[pos].perp2].item && layout->corners[order[pos].corner2] == area && layout->corners[order[pos].corner1] != area) { ls[1].minimumSize = qMax(ls[1].minimumSize, min - ls[2].minimumSize); } }#endif // QT_NO_DOCKWIDGET}/* Initializes the layout struct with information from the specified dock window area.*/static void init_layout_struct(const QMainWindowLayout * const layout, QLayoutStruct &ls, const POSITION pos, const int ext){ const QMainWindowLayout::QMainWindowLayoutInfo &info = layout->layout_info[pos]; ls.empty = info.item->isEmpty(); if (!ls.empty) { ls.minimumSize = pick(pos, info.item->minimumSize()) + ext; ls.maximumSize = pick(pos, info.item->maximumSize()) + ext; ls.sizeHint = !info.size.isEmpty() ? pick(pos, info.size) : pick(pos, info.item->sizeHint()) + ext; // constrain sizeHint ls.sizeHint = qMin(ls.maximumSize, ls.sizeHint); ls.sizeHint = qMax(ls.minimumSize, ls.sizeHint); }}#ifndef QT_NO_TOOLBAR/* Returns the size hint for the first user item in a tb layout. This is used to contrain the minimum size a tb can have.*/static QSize get_first_item_sh(QLayout *layout){ QLayoutItem *item = layout->itemAt(1); if (item && item->widget()) return item->widget()->sizeHint(); else return QSize(0, 0);}/* Returns the real size hint for items in a layout - including sizes for hidden items.*/static QSize get_real_sh(QLayout *layout){ QSize real_sh(0, 0); int i = 0; while (layout && layout->itemAt(i)) real_sh += layout->itemAt(i++)->widget()->sizeHint(); --i; int spacing = layout->spacing(); int margin = layout->margin(); real_sh += QSize(spacing*i + margin*2, spacing*i + margin*2); return real_sh;}#endif // QT_NO_TOOLBARvoid QMainWindowLayout::setGeometry(const QRect &_r){ QLayout::setGeometry(_r); QRect r = _r; if (statusbar) { QRect sbr(QPoint(0, 0), QSize(r.width(), statusbar->heightForWidth(r.width())) .expandedTo(statusbar->minimumSize())); sbr.moveBottom(r.bottom()); QRect vr = QStyle::visualRect(QApplication::layoutDirection(), _r, sbr); statusbar->setGeometry(vr); r.setBottom(sbr.top() - 1); }#ifndef QT_NO_TOOLBAR // layout toolbars // calculate the respective tool bar rectangles and store the // width/height of the largest tb on each line QVarLengthArray<QRect> tb_rect(tb_layout_info.size()); QMap<int, QSize> rest_sz; QStack<QSize> bottom_sz; QStack<QSize> right_sz; QStack<QRect> bottom_rect; QStack<QRect> right_rect; // calculate the width/height of the different tool bar lines - // the order of the bottom and right tool bars needs to reversed for (int line = 0; line < tb_layout_info.size(); ++line) { const ToolBarLineInfo &lineInfo = tb_layout_info.at(line); QSize tb_sz; for (int i = 0; i < lineInfo.list.size(); ++i) { const ToolBarLayoutInfo &info = lineInfo.list.at(i); if (info.item->isEmpty()) continue; QSize sh = info.item->sizeHint(); if (tb_sz.width() < sh.width()) tb_sz.setWidth(sh.width()); if (tb_sz.height() < sh.height()) tb_sz.setHeight(sh.height()); } switch(lineInfo.pos) { case TOP: case LEFT: rest_sz[line] = tb_sz; break; case BOTTOM: bottom_sz.push(tb_sz); break; case RIGHT: right_sz.push(tb_sz); break; default: Q_ASSERT_X(false, "QMainWindowLayout", "internal error"); } } // calculate the rect for each tool bar line for (int line = 0; line < tb_layout_info.size(); ++line) { const ToolBarLineInfo &lineInfo = tb_layout_info.at(line); QSize tb_sz; tb_rect[line] = r; bool lineHidden = true; for (int i = 0; i < lineInfo.list.size(); ++i) lineHidden &= lineInfo.list.at(i).item->isEmpty(); if (lineHidden) continue; switch (lineInfo.pos) { case TOP: tb_sz = rest_sz[line]; tb_rect[line].setBottom(tb_rect[line].top() + tb_sz.height() - 1); r.setTop(tb_rect[line].bottom() + 1); break; case LEFT: tb_sz = rest_sz[line]; tb_rect[line].setRight(tb_rect[line].x() + tb_sz.width() - 1); r.setLeft(tb_rect[line].right() + 1); break; case BOTTOM: tb_sz = bottom_sz.pop(); tb_rect[line].setTop(tb_rect[line].bottom() - tb_sz.height() + 1); bottom_rect.push(tb_rect[line]); r.setBottom(tb_rect[line].top() - 1); break; case RIGHT: tb_sz = right_sz.pop(); tb_rect[line].setLeft(tb_rect[line].right() - tb_sz.width() + 1); right_rect.push(tb_rect[line]); r.setRight(tb_rect[line].left() - 1); break; default: Q_ASSERT_X(false, "QMainWindowLayout", "internal error"); } } // put the right and bottom rects back in correct order for (int line = 0; line < tb_layout_info.size(); ++line) { const ToolBarLineInfo &lineInfo = tb_layout_info.at(line); bool lineHidden = true; for (int i = 0; i < lineInfo.list.size(); ++i) lineHidden &= lineInfo.list.at(i).item->isEmpty(); if (lineHidden) continue; if (lineInfo.pos == BOTTOM) tb_rect[line] = bottom_rect.pop(); else if (lineInfo.pos == RIGHT) tb_rect[line] = right_rect.pop(); } // at this point the space for the tool bars have been shaved off // the main rect, continue laying out each tool bar line int tb_fill = 0; if (!tb_layout_info.isEmpty() && !tb_layout_info.at(0).list.isEmpty()) { tb_fill = tb_layout_info.at(0).list.at(0).item->widget()->layout()->margin() * 2 + parentWidget()->style()->pixelMetric(QStyle::PM_ToolBarHandleExtent) + parentWidget()->style()->pixelMetric(QStyle::PM_ToolBarItemSpacing) * 2 + parentWidget()->style()->pixelMetric(QStyle::PM_ToolBarExtensionExtent); } for (int line = 0; line < tb_layout_info.size(); ++line) { ToolBarLineInfo &lineInfo = tb_layout_info[line]; int num_tbs = lineInfo.list.size(); POSITION where = static_cast<POSITION>(lineInfo.pos); bool first = true; for (int i = 0; i < num_tbs; ++i) { ToolBarLayoutInfo &info = lineInfo.list[i]; if (info.item->isEmpty()) continue; set(where, info.size, pick(where, tb_rect[line].size())); // position if (first) { // first tool bar can't have an offset first = false; int nextIndex = nextVisible(i, lineInfo); if (nextIndex != -1 && !info.size.isEmpty() && pick_perp(where, info.offset) > pick_perp(where, info.size)) { // swap if dragging it past the next one ToolBarLayoutInfo &next = lineInfo.list[nextIndex]; next.pos = tb_rect[line].topLeft(); next.size.setHeight(pick_perp(where, get_first_item_sh(next.item->widget()->layout())) + tb_fill); next.offset = QPoint(); if (where == LEFT || where == RIGHT) info.pos = QPoint(tb_rect[line].left(), next.pos.y() + next.size.height()); else info.pos = QPoint(next.pos.x() + next.size.width(), tb_rect[line].top()); info.offset = QPoint(); // has to be done before swapping lineInfo.list.swap(i, nextIndex); } else { info.pos = tb_rect[line].topLeft(); info.offset = QPoint(); } } else { int prevIndex = prevVisible(i, lineInfo); Q_ASSERT_X(prevIndex != -1, "QMainWindowLayout", "internal error"); ToolBarLayoutInfo &prev = lineInfo.list[prevIndex]; QSize min_size = info.item->widget()->minimumSize(); int cur_pt = info.size.isEmpty() ? (pick_perp(where, prev.pos) + pick_perp(where, get_real_sh(prev.item->widget()->layout()))) : (info.user_pos.isNull() ? (pick_perp(where, prev.pos) + pick_perp(where, get_real_sh(prev.item->widget()->layout()))) : pick_perp(where, info.user_pos)); cur_pt = qMax(cur_pt, 0); const int prev_min = pick_perp(where, prev.item->widget()->minimumSize());
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -