📄 qmainwindowlayout.cpp
字号:
const int snap_dist = 12; info.pos = tb_rect[line].topLeft(); set_perp(where, info.pos, cur_pt); if (pick_perp(where, info.offset) < 0) { // left/up motion int to_shave = pick_perp(where, -info.offset); int can_shave = qMin(to_shave, pick_perp(where, prev.size) - prev_min); if (can_shave > 0) { // shrink the previous one and increase size of current with same QSize real_sh = get_real_sh(prev.item->widget()->layout()); QSize sz(0, 0); set_perp(where, sz, can_shave); if ((pick_perp(where, prev.size) + pick_perp(where, sz) < pick_perp(where, real_sh) - snap_dist) || (pick_perp(where, prev.size) + pick_perp(where, sz) > pick_perp(where, real_sh) + snap_dist)) { prev.size += sz; info.size -= sz; set_perp(where, info.pos, cur_pt - can_shave); info.user_pos = info.pos; to_shave -= can_shave; } else { info.user_pos = QPoint(); info.pos = tb_rect[line].topLeft(); set_perp(where, prev.size, pick_perp(where, real_sh)); int pt = pick_perp(where, prev.pos) + pick_perp(where, prev.size); set_perp(where, info.pos, pt); // when snapping, don't push anything to_shave = 0; } } if (to_shave > 0) { // can't shrink - push the previous one if possible bool pushed = false; for (int l = i-2; to_shave > 0 && l >= 0; --l) { ToolBarLayoutInfo &t = lineInfo.list[l]; can_shave = qMin(to_shave, pick_perp(where, t.size) - pick_perp(where, get_first_item_sh(t.item->widget()->layout())) - tb_fill); if (can_shave > 0) { pushed = true; QSize sz(0, 0); set_perp(where, sz, can_shave); t.size -= sz; to_shave -= can_shave; for (int j = l+1; j < i; ++j) { set_perp(where, lineInfo.list[j].pos, pick_perp(where, lineInfo.list[j-1].pos) + pick_perp(where, lineInfo.list[j-1].size)); lineInfo.list[j].user_pos = lineInfo.list[j].pos; } } } if (!pushed) { if (to_shave > prev_min) { // this is not a ugle hack QLayoutItem *tmp = info.item; info.item = prev.item; prev.item = tmp; info.item->widget()->update(); prev.item->widget()->update(); } } } } else if (pick_perp(where, info.offset) > 0) { // right/down motion int to_shave = pick_perp(where, info.offset); int can_shave = qMin(to_shave, pick_perp(where, info.size) - pick_perp(where, min_size)); if (can_shave > 0) { QSize real_sh = get_real_sh(prev.item->widget()->layout()); QSize sz(0, 0); set_perp(where, sz, pick_perp(where, info.offset)); if ((pick_perp(where, prev.size) + pick_perp(where, sz) > pick_perp(where, real_sh) + snap_dist) || (pick_perp(where, prev.size) < pick_perp(where, real_sh) - snap_dist)) { info.size -= sz; set_perp(where, info.pos, cur_pt + can_shave); info.user_pos = info.pos; to_shave -= can_shave; } else { info.user_pos = QPoint(); info.pos = tb_rect[line].topLeft(); set_perp(where, prev.size, pick_perp(where, real_sh)); int pt = pick_perp(where, prev.pos) + pick_perp(where, prev.size); set_perp(where, info.pos, pt); // when snapping, don't push anything to_shave = 0; } } if (to_shave > 0) { bool pushed = false; for (int l = i+1; to_shave > 0 && l < num_tbs; ++l) { ToolBarLayoutInfo &t = lineInfo.list[l]; can_shave = qMin(to_shave, pick_perp(where, t.size) - pick_perp(where, get_first_item_sh(t.item->widget()->layout())) - tb_fill); if (can_shave > 0) { pushed = true; QPoint pt; set_perp(where, pt, can_shave); t.pos += pt; t.user_pos = t.pos; t.size -= QSize(pt.x(), pt.y()); to_shave -= can_shave; for (int j = l - 1; j > i; --j) { set_perp(where, lineInfo.list[j].pos, pick_perp(where, lineInfo.list[j].pos) + can_shave); lineInfo.list[j].user_pos = lineInfo.list[j].pos; } } } if (!pushed) { int nextIndex = nextVisible(i, lineInfo); if (nextIndex != -1) { ToolBarLayoutInfo &t = lineInfo.list[nextIndex]; if (pick_perp(where, info.offset) > pick_perp(where, info.size)) { // this is not a ugle hack QLayoutItem *tmp = info.item; info.item = t.item; t.item = tmp; info.item->widget()->update(); prev.item->widget()->update(); } } } } } // fix this item's position if (pick_perp(where, info.pos) < pick_perp(where, prev.pos) + prev_min) { if (info.user_pos.isNull() && prev.user_pos.isNull()) { int sz = pick_perp(where, get_real_sh(prev.item->widget()->layout())); // don't go beyond min size hint if (sz < prev_min) sz = prev_min; set_perp(where, info.pos, pick_perp(where, prev.pos) + sz); } else { set_perp(where, info.pos, pick_perp(where, prev.pos) + prev_min); } } info.offset = QPoint(); } // size if (num_tbs == 1) { set_perp(where, info.size, pick_perp(where, tb_rect[line].size())); } else { int nextIndex = nextVisible(i, lineInfo); if (nextIndex == -1) { set_perp(where, info.size, pick_perp(where, tb_rect[line].size())); if (where == LEFT || where == RIGHT) info.size.setHeight(tb_rect[line].bottom() - info.pos.y() + 1); else info.size.setWidth(tb_rect[line].right() - info.pos.x() + 1); if (pick_perp(where, info.size) < 1) set_perp(where, info.size, pick_perp(where, get_first_item_sh(info.item->widget()->layout())) + tb_fill); } } if (i > 0) { // assumes that all tbs are positioned at the correct // pos - fill in the gaps btw them int prevIndex = prevVisible(i, lineInfo); if (prevIndex != -1) { ToolBarLayoutInfo &prev = lineInfo.list[prevIndex]; set_perp(where, prev.size, pick_perp(where, info.pos) - pick_perp(where, prev.pos)); } } } if (num_tbs > 1) { const ToolBarLayoutInfo &last = lineInfo.list.last(); int target_size = pick_perp(where, tb_rect[line].size()); int shave_off = (pick_perp(where, last.pos) - pick_perp(where, tb_rect[line].topLeft())) + pick_perp(where, get_first_item_sh(last.item->widget()->layout())) + tb_fill - target_size; for (int i = num_tbs-2; shave_off > 0 && i >= 0; --i) { ToolBarLayoutInfo &info = lineInfo.list[i]; int can_shave = qMin(pick_perp(where, info.size) - (pick_perp(where, get_first_item_sh(info.item->widget()->layout())) + tb_fill), shave_off); if (can_shave > 0) { // shave size off this item QSize sz(0, 0); set_perp(where, sz, can_shave); info.size -= sz; shave_off -= can_shave; // move the next item by the amount we shaved int nextIndex = nextVisible(i, lineInfo); while (nextIndex != -1) { QPoint p(0,0); set_perp(where, p, can_shave); lineInfo.list[nextIndex].pos -= p; nextIndex = nextVisible(nextIndex, lineInfo); } } } } for (int i = 0; i < num_tbs; ++i) { ToolBarLayoutInfo &info = lineInfo.list[i]; if (info.item->isEmpty()) { info.size = QSize(); continue; } QRect tb(info.pos, info.size); tb = QStyle::visualRect(QApplication::layoutDirection(), tb_rect[line], tb); if (!tb.isEmpty() && relayout_type == QInternal::RelayoutNormal) info.item->setGeometry(tb); } }#endif // QT_NO_TOOLBAR // layout dockwidgets and center widget const int ext = parentWidget()->style()->pixelMetric(QStyle::PM_DockWidgetSeparatorExtent); if (relayout_type == QInternal::RelayoutNormal) { // hide separators for empty layouts for (int i = 0; i < 4; ++i) { if (!layout_info[i].item) continue; layout_info[i].sep->widget()->setHidden(layout_info[i].item->isEmpty()); } } { QVector<QLayoutStruct> lsH(3); for (int i = 0; i < 3; ++i) lsH[i].init(); if (layout_info[LEFT].item) init_layout_struct(this, lsH[0], LEFT, ext); if (layout_info[RIGHT].item) init_layout_struct(this, lsH[2], RIGHT, ext); lsH[1].empty = false; lsH[1].minimumSize = layout_info[CENTER].item ? layout_info[CENTER].item->minimumSize().width() : 0; lsH[1].maximumSize = layout_info[CENTER].item ? layout_info[CENTER].item->maximumSize().width() : INT_MAX; lsH[1].sizeHint = !layout_info[CENTER].size.isEmpty() ? layout_info[CENTER].size.width() : (layout_info[CENTER].item ? layout_info[CENTER].item->sizeHint().width() : 0); // fix min/max sizes fix_minmax(lsH, this, TOP); fix_minmax(lsH, this, BOTTOM); // constrain sizeHint lsH[1].sizeHint = qMin(lsH[1].maximumSize, lsH[1].sizeHint); lsH[1].sizeHint = qMax(lsH[1].minimumSize, lsH[1].sizeHint); // the center widget always gets stretch lsH[1].stretch = lsH[1].sizeHint; qGeomCalc(lsH, 0, lsH.count(), 0, r.width(), 0); if (!lsH[0].empty) layout_info[LEFT].size.setWidth(lsH[0].size); layout_info[CENTER].size.setWidth(lsH[1].size); if (!lsH[2].empty) layout_info[RIGHT].size.setWidth(lsH[2].size); } { QVector<QLayoutStruct> lsV(3); for (int i = 0; i < 3; ++i) lsV[i].init(); if (layout_info[TOP].item) init_layout_struct(this, lsV[0], TOP, ext); if (layout_info[BOTTOM].item) init_layout_struct(this, lsV[2], BOTTOM, ext); lsV[1].empty = false; lsV[1].minimumSize = layout_info[CENTER].item ? layout_info[CENTER].item->minimumSize().height() : 0; lsV[1].maximumSize = layout_info[CENTER].item ? layout_info[CENTER].item->maximumSize().height() : INT_MAX; lsV[1].sizeHint = !layout_info[CENTER].size.isEmpty() ? layout_info[CENTER].size.height() : (layout_info[CENTER].item ? layout_info[CENTER].item->sizeHint().height() : 0); // fix min/max sizes fix_minmax(lsV, this, LEFT); fix_minmax(lsV, this, RIGHT); // constrain sizeHint lsV[1].sizeHint = qMin(lsV[1].maximumSize, lsV[1].sizeHint); lsV[1].sizeHint = qMax(lsV[1].minimumSize, lsV[1].sizeHint); // the center widget always gets stretch lsV[1].stretch = lsV[1].sizeHint; qGeomCalc(lsV, 0, lsV.count(), 0, r.height(), 0); if (!lsV[0].empty) layout_info[TOP].size.setHeight(lsV[0].size); layout_info[CENTER].size.setHeight(lsV[1].size); if (!lsV[2].empty) layout_info[BOTTOM].size.setHeight(lsV[2].size); } QRect rect[4], &left = rect[LEFT], &right = rect[RIGHT], &top = rect[TOP], &bottom = rect[BOTTOM]; for (int i = 0; i < 4; ++i) { if (!layout_info[i].item || layout_info[i].item->isEmpty()) rect[i].setSize(QSize(0, 0)); else rect[i].setSize(layout_info[i].size); } left.moveLeft(r.left()); right.moveRight(r.right()); top.moveTop(r.top()); bottom.moveBottom(r.bottom()); switch (corners[Qt::TopLeftCorner]) { case Qt::TopDockWidgetArea: top.setLeft(r.left()); left.setTop(top.bottom() + 1); break; case Qt::LeftDockWidgetArea: left.setTop(r.top()); top.setLeft(left.right() + 1); break; default: Q_ASSERT(false); } switch (corners[Qt::BottomLeftCorner]) { case Qt::BottomDockWidgetArea: bottom.setLeft(r.left()); left.setBottom(bottom.top() - 1); break; case Qt::LeftDockWidgetArea: left.setBottom(r.bottom()); bottom.setLeft(left.right() + 1); break; default: Q_ASSERT(false); } switch (corners[Qt::TopRightCorner]) { case Qt::TopDockWidgetArea: top.setRight(r.right()); right.setTop(top.bottom() + 1); break; case Qt::RightDockWidgetArea: right.setTop(r.top()); top.setRight(right.left() - 1); break; default: Q_ASSERT(false); } switch (corners[Qt::BottomRightCorner]) { case Qt::BottomDockWidgetArea: bottom.setRight(r.right()); right.setBottom(bottom.top() - 1); break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -