50 q->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed));
51 q->setBackgroundRole(QPalette::Button);
52 q->setAttribute(Qt::WA_Hover);
53 q->setAttribute(Qt::WA_X11NetWmWindowTypeToolBar);
55 QStyle *style = q->style();
56 int e = style->pixelMetric(QStyle::PM_ToolBarIconSize,
nullptr, q);
57 iconSize = QSize(e, e);
59 layout =
new QToolBarLayout(q);
60 layout->updateMarginAndSpacing();
62 toggleViewAction =
new QAction(q);
64 q->setMovable(q->style()->styleHint(QStyle::SH_ToolBar_Movable,
nullptr, q ));
65 QObject::connect(toggleViewAction, SIGNAL(triggered(
bool)), q, SLOT(_q_toggleView(
bool)));
101 Qt::WindowFlags flags = floating ? Qt::Tool : Qt::Widget;
103 flags |= Qt::FramelessWindowHint;
105#if QT_CONFIG(draganddrop)
108 if (unplug && !QMainWindowLayout::needsPlatformDrag())
109 flags |= Qt::X11BypassWindowManagerHint;
114 q->setWindowFlags(flags);
166 Q_ASSERT(
state !=
nullptr);
171 QMainWindow *win = qobject_cast<QMainWindow*>(parent);
172 Q_ASSERT(win !=
nullptr);
173 QMainWindowLayout *layout = qt_mainwindow_layout(win);
174 Q_ASSERT(layout !=
nullptr);
176#if QT_CONFIG(draganddrop)
177 const bool wasFloating = q->isFloating();
181 state->widgetItem = layout->unplug(q, QDockWidgetPrivate::DragScope::Group);
182 Q_ASSERT(
state->widgetItem !=
nullptr);
187#if QT_CONFIG(draganddrop)
188 if (QMainWindowLayout::needsPlatformDrag() && state->dragging) {
189 auto result = layout->performPlatformWidgetDrag(state->widgetItem, state->pressPos);
190 if (result == Qt::IgnoreAction && !wasFloating) {
191 layout->revert(state->widgetItem);
231 QStyleOptionToolBar opt;
232 q->initStyleOption(&opt);
233 if (q->style()->subElementRect(QStyle::SE_ToolBarHandle, &opt, q).contains(event->position().toPoint()) ==
false) {
239 if (QMainWindow *mainWindow = qobject_cast<QMainWindow *>(parent)) {
240 if (mainWindow->toolBarArea(q) == Qt::TopToolBarArea
241 && mainWindow->unifiedTitleAndToolBarOnMac()
242 && q->childAt(event->pos()) == 0) {
243 macWindowDragging =
true;
244 macWindowDragPressPosition = event->pos();
252 if (event->button() != Qt::LeftButton)
258 initDrag(event->position().toPoint());
292 if (!macWindowDragging)
294 QWidget *w = q->window();
295 const QPoint delta = event->pos() - macWindowDragPressPosition;
296 w->move(w->pos() + delta);
302 QMainWindow *win = qobject_cast<QMainWindow*>(parent);
306 QMainWindowLayout *layout = qt_mainwindow_layout(win);
307 Q_ASSERT(layout !=
nullptr);
309 if (layout->pluggingWidget ==
nullptr
310 && (event->position().toPoint() - state->pressPos).manhattanLength() > QApplication::startDragDistance()) {
312 const auto evPos = event->position().toPoint();
313 const bool moving = !q->isWindow() && (orientation == Qt::Vertical ?
314 evPos.x() >= 0 && evPos.x() < q->width() :
315 evPos.y() >= 0 && evPos.y() < q->height());
318 if (!moving && !wasDragging)
328 QPoint pos = event->globalPosition().toPoint();
331 if (q->isLeftToRight())
332 pos -=
state->pressPos;
334 pos += QPoint(state->pressPos.x() - q->width(), -
state->pressPos.y());
337 layout->hover(
state->widgetItem, event->globalPosition().toPoint());
340 const QPoint rtl(q->width() - state->pressPos.x(), state->pressPos.y());
341 const QPoint globalPressPos = q->mapToGlobal(q->isRightToLeft() ? rtl : state->pressPos);
344 const QWindow *handle = q->window() ? q->window()->windowHandle() :
nullptr;
345 const QPoint delta = handle
346 ? QHighDpi::fromNativePixels(event->globalPosition(), handle).toPoint()
347 - QHighDpi::fromNativePixels(globalPressPos, handle)
348 : event->globalPosition().toPoint() - globalPressPos;
350 if (orientation == Qt::Vertical) {
351 pos = q->y() + delta.y();
353 if (q->isRightToLeft()) {
354 pos = win->width() - q->width() - q->x() - delta.x();
356 pos = q->x() + delta.x();
360 layout->moveToolBar(q, pos);
637void QToolBar::setOrientation(Qt::Orientation orientation)
640 if (orientation == d->orientation)
643 d->orientation = orientation;
645 if (orientation == Qt::Vertical)
646 setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred));
648 setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed));
650 d->layout->invalidate();
651 d->layout->activate();
653 emit orientationChanged(d->orientation);
672void QToolBar::setIconSize(
const QSize &iconSize)
677 QMainWindow *mw = qobject_cast<QMainWindow *>(parentWidget());
678 if (mw && mw->layout()) {
679 QLayout *layout = mw->layout();
681 QLayoutItem *item =
nullptr;
683 item = layout->itemAt(i++);
684 if (item && (item->widget() ==
this))
686 }
while (!sz.isValid() && item !=
nullptr);
690 const int metric = style()->pixelMetric(QStyle::PM_ToolBarIconSize,
nullptr,
this);
691 sz = QSize(metric, metric);
693 if (d->iconSize != sz) {
695 setMinimumSize(0, 0);
696 emit iconSizeChanged(d->iconSize);
698 d->explicitIconSize = iconSize.isValid();
700 d->layout->invalidate();
721void QToolBar::setToolButtonStyle(Qt::ToolButtonStyle toolButtonStyle)
724 d->explicitToolButtonStyle =
true;
725 if (d->toolButtonStyle == toolButtonStyle)
727 d->toolButtonStyle = toolButtonStyle;
728 setMinimumSize(0, 0);
729 emit toolButtonStyleChanged(d->toolButtonStyle);
805QAction *QToolBar::insertWidget(QAction *before, QWidget *widget)
807 QWidgetAction *action =
new QWidgetAction(
this);
808 action->setDefaultWidget(widget);
809 action->d_func()->autoCreated =
true;
810 insertAction(before, action);
836QAction *QToolBar::actionAt(
const QPoint &p)
const
839 QWidget *widget = childAt(p);
840 int index = d->layout->indexOf(widget);
843 QLayoutItem *item = d->layout->itemAt(index);
844 return static_cast<QToolBarItem*>(item)->action;
855void QToolBar::actionEvent(QActionEvent *event)
858 auto action =
static_cast<QAction *>(event->action());
859 QWidgetAction *widgetAction = qobject_cast<QWidgetAction *>(action);
861 switch (event->type()) {
862 case QEvent::ActionAdded: {
863 Q_ASSERT_X(widgetAction ==
nullptr || d->layout->indexOf(widgetAction) == -1,
864 "QToolBar",
"widgets cannot be inserted multiple times");
871 if (widgetAction !=
nullptr && widgetAction->d_func()->autoCreated)
872 widgetAction->setParent(
this);
874 int index = d->layout->count();
875 if (event->before()) {
876 index = d->layout->indexOf(event->before());
877 Q_ASSERT_X(index != -1,
"QToolBar::insertAction",
"internal error");
879 d->layout->insertAction(index, action);
883 case QEvent::ActionChanged:
884 d->layout->invalidate();
887 case QEvent::ActionRemoved: {
888 int index = d->layout->indexOf(action);
890 delete d->layout->takeAt(index);
896 Q_ASSERT_X(
false,
"QToolBar::actionEvent",
"internal error");
901void QToolBar::changeEvent(QEvent *event)
904 switch (event->type()) {
905 case QEvent::WindowTitleChange:
906 d->toggleViewAction->setText(windowTitle());
908 case QEvent::StyleChange:
909 d->layout->invalidate();
910 if (!d->explicitIconSize) {
911 QStyleOptionToolBar opt;
912 initStyleOption(&opt);
913 const int metric = style()->pixelMetric(QStyle::PM_ToolBarIconSize, &opt,
this);
914 setIconSize({metric, metric});
915 d->explicitIconSize =
false;
917 d->layout->updateMarginAndSpacing();
919 case QEvent::LayoutDirectionChange:
920 d->layout->invalidate();
925 QWidget::changeEvent(event);
929void QToolBar::paintEvent(QPaintEvent *)
934 QStyle *style =
this->style();
935 QStyleOptionToolBar opt;
936 initStyleOption(&opt);
938 if (d->layout->expanded || d->layout->animating || isWindow()) {
941 p.fillRect(opt.rect, palette().window());
942 style->drawControl(QStyle::CE_ToolBar, &opt, &p,
this);
943 style->drawPrimitive(QStyle::PE_FrameMenu, &opt, &p,
this);
945 style->drawControl(QStyle::CE_ToolBar, &opt, &p,
this);
948 opt.rect = style->subElementRect(QStyle::SE_ToolBarHandle, &opt,
this);
949 if (opt.rect.isValid())
950 style->drawPrimitive(QStyle::PE_IndicatorToolBarHandle, &opt, &p,
this);
961 if (popup ==
nullptr || popup->isHidden())
965 while (w !=
nullptr) {
968 w = w->parentWidget();
971 QMenu *menu = qobject_cast<QMenu*>(popup);
975 const QAction *action = menu->menuAction();
976 for (
auto object : action->associatedObjects()) {
977 if (QWidget *widget = qobject_cast<QWidget*>(object)) {
978 if (waitForPopup(tb, widget))
1005bool QToolBar::event(QEvent *event)
1009 switch (event->type()) {
1011 if (d->waitForPopupTimer.timerId() ==
static_cast<QTimerEvent*>(event)->timerId()) {
1012 QWidget *w = QApplication::activePopupWidget();
1013 if (!waitForPopup(
this, w)) {
1014 d->waitForPopupTimer.stop();
1015 if (!
this->underMouse())
1016 d->layout->setExpanded(
false);
1025 d->toggleViewAction->setChecked(event->type() == QEvent::Show);
1027 enableMacToolBar(
this, event->type() == QEvent::Show);
1029 emit visibilityChanged(event->type() == QEvent::Show);
1031 case QEvent::ParentChange:
1032 d->layout->checkUsePopupMenu();
1035 case QEvent::MouseButtonPress: {
1036 if (d->mousePressEvent(
static_cast<QMouseEvent*>(event)))
1040 case QEvent::MouseButtonRelease:
1041 if (d->mouseReleaseEvent(
static_cast<QMouseEvent*>(event)))
1044 case QEvent::HoverEnter:
1045 case QEvent::HoverLeave:
1048 case QEvent::HoverMove: {
1050 QHoverEvent *e =
static_cast<QHoverEvent*>(event);
1051 QStyleOptionToolBar opt;
1052 initStyleOption(&opt);
1053 if (style()->subElementRect(QStyle::SE_ToolBarHandle, &opt,
this).contains(e->position().toPoint()))
1054 setCursor(Qt::SizeAllCursor);
1060 case QEvent::MouseMove:
1061 if (d->mouseMoveEvent(
static_cast<QMouseEvent*>(event)))
1065 if (d->state !=
nullptr && d->state->dragging) {
1068 QPoint pos = QCursor::pos();
1069 QMouseEvent fake(QEvent::MouseMove, mapFromGlobal(pos), pos, Qt::NoButton,
1070 QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers());
1071 d->mouseMoveEvent(&fake);
1074 if (!d->layout->expanded)
1077 QWidget *w = QApplication::activePopupWidget();
1078 if (waitForPopup(
this, w)) {
1083 d->waitForPopupTimer.stop();
1084 d->layout->setExpanded(
false);
1091 return QWidget::event(event);
1128void QToolBar::initStyleOption(QStyleOptionToolBar *option)
const
1130 Q_D(
const QToolBar);
1135 option->initFrom(
this);
1136 if (orientation() == Qt::Horizontal)
1137 option->state |= QStyle::State_Horizontal;
1138 option->lineWidth = style()->pixelMetric(QStyle::PM_ToolBarFrameWidth,
nullptr,
this);
1139 option->features = d->layout->movable()
1140 ? QStyleOptionToolBar::Movable
1141 : QStyleOptionToolBar::None;
1143 option->toolBarArea = Qt::NoToolBarArea;
1146 QMainWindow *mainWindow = qobject_cast<QMainWindow *>(parentWidget());
1151 QMainWindowLayout *layout = qt_mainwindow_layout(mainWindow);
1152 Q_ASSERT_X(layout !=
nullptr,
"QToolBar::initStyleOption()",
1153 "QMainWindow->layout() != QMainWindowLayout");
1155 layout->getStyleOptionInfo(option,
const_cast<QToolBar *>(
this));