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 bool moving = !q->isWindow() && (orientation == Qt::Vertical ?
313 event->position().toPoint().x() >= 0 && event->position().toPoint().x() < q->width() :
314 event->position().toPoint().y() >= 0 && event->position().toPoint().y() < q->height());
317 if (!moving && !wasDragging)
327 QPoint pos = event->globalPosition().toPoint();
330 if (q->isLeftToRight())
331 pos -=
state->pressPos;
333 pos += QPoint(state->pressPos.x() - q->width(), -state->pressPos.y());
336 layout->hover(
state->widgetItem, event->globalPosition().toPoint());
339 const QPoint rtl(q->width() - state->pressPos.x(), state->pressPos.y());
340 const QPoint globalPressPos = q->mapToGlobal(q->isRightToLeft() ? rtl : state->pressPos);
343 const QWindow *handle = q->window() ? q->window()->windowHandle() :
nullptr;
344 const QPoint delta = handle
345 ? QHighDpi::fromNativePixels(event->globalPosition(), handle).toPoint()
346 - QHighDpi::fromNativePixels(globalPressPos, handle)
347 : event->globalPosition().toPoint() - globalPressPos;
349 if (orientation == Qt::Vertical) {
350 pos = q->y() + delta.y();
352 if (q->isRightToLeft()) {
353 pos = win->width() - q->width() - q->x() - delta.x();
355 pos = q->x() + delta.x();
359 layout->moveToolBar(q, pos);
636void QToolBar::setOrientation(Qt::Orientation orientation)
639 if (orientation == d->orientation)
642 d->orientation = orientation;
644 if (orientation == Qt::Vertical)
645 setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred));
647 setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed));
649 d->layout->invalidate();
650 d->layout->activate();
652 emit orientationChanged(d->orientation);
671void QToolBar::setIconSize(
const QSize &iconSize)
676 QMainWindow *mw = qobject_cast<QMainWindow *>(parentWidget());
677 if (mw && mw->layout()) {
678 QLayout *layout = mw->layout();
680 QLayoutItem *item =
nullptr;
682 item = layout->itemAt(i++);
683 if (item && (item->widget() ==
this))
685 }
while (!sz.isValid() && item !=
nullptr);
689 const int metric = style()->pixelMetric(QStyle::PM_ToolBarIconSize,
nullptr,
this);
690 sz = QSize(metric, metric);
692 if (d->iconSize != sz) {
694 setMinimumSize(0, 0);
695 emit iconSizeChanged(d->iconSize);
697 d->explicitIconSize = iconSize.isValid();
699 d->layout->invalidate();
720void QToolBar::setToolButtonStyle(Qt::ToolButtonStyle toolButtonStyle)
723 d->explicitToolButtonStyle =
true;
724 if (d->toolButtonStyle == toolButtonStyle)
726 d->toolButtonStyle = toolButtonStyle;
727 setMinimumSize(0, 0);
728 emit toolButtonStyleChanged(d->toolButtonStyle);
804QAction *QToolBar::insertWidget(QAction *before, QWidget *widget)
806 QWidgetAction *action =
new QWidgetAction(
this);
807 action->setDefaultWidget(widget);
808 action->d_func()->autoCreated =
true;
809 insertAction(before, action);
835QAction *QToolBar::actionAt(
const QPoint &p)
const
838 QWidget *widget = childAt(p);
839 int index = d->layout->indexOf(widget);
842 QLayoutItem *item = d->layout->itemAt(index);
843 return static_cast<QToolBarItem*>(item)->action;
854void QToolBar::actionEvent(QActionEvent *event)
857 auto action =
static_cast<QAction *>(event->action());
858 QWidgetAction *widgetAction = qobject_cast<QWidgetAction *>(action);
860 switch (event->type()) {
861 case QEvent::ActionAdded: {
862 Q_ASSERT_X(widgetAction ==
nullptr || d->layout->indexOf(widgetAction) == -1,
863 "QToolBar",
"widgets cannot be inserted multiple times");
870 if (widgetAction !=
nullptr && widgetAction->d_func()->autoCreated)
871 widgetAction->setParent(
this);
873 int index = d->layout->count();
874 if (event->before()) {
875 index = d->layout->indexOf(event->before());
876 Q_ASSERT_X(index != -1,
"QToolBar::insertAction",
"internal error");
878 d->layout->insertAction(index, action);
882 case QEvent::ActionChanged:
883 d->layout->invalidate();
886 case QEvent::ActionRemoved: {
887 int index = d->layout->indexOf(action);
889 delete d->layout->takeAt(index);
895 Q_ASSERT_X(
false,
"QToolBar::actionEvent",
"internal error");
900void QToolBar::changeEvent(QEvent *event)
903 switch (event->type()) {
904 case QEvent::WindowTitleChange:
905 d->toggleViewAction->setText(windowTitle());
907 case QEvent::StyleChange:
908 d->layout->invalidate();
909 if (!d->explicitIconSize) {
910 QStyleOptionToolBar opt;
911 initStyleOption(&opt);
912 const int metric = style()->pixelMetric(QStyle::PM_ToolBarIconSize, &opt,
this);
913 setIconSize({metric, metric});
914 d->explicitIconSize =
false;
916 d->layout->updateMarginAndSpacing();
918 case QEvent::LayoutDirectionChange:
919 d->layout->invalidate();
924 QWidget::changeEvent(event);
928void QToolBar::paintEvent(QPaintEvent *)
933 QStyle *style =
this->style();
934 QStyleOptionToolBar opt;
935 initStyleOption(&opt);
937 if (d->layout->expanded || d->layout->animating || isWindow()) {
940 p.fillRect(opt.rect, palette().window());
941 style->drawControl(QStyle::CE_ToolBar, &opt, &p,
this);
942 style->drawPrimitive(QStyle::PE_FrameMenu, &opt, &p,
this);
944 style->drawControl(QStyle::CE_ToolBar, &opt, &p,
this);
947 opt.rect = style->subElementRect(QStyle::SE_ToolBarHandle, &opt,
this);
948 if (opt.rect.isValid())
949 style->drawPrimitive(QStyle::PE_IndicatorToolBarHandle, &opt, &p,
this);
960 if (popup ==
nullptr || popup->isHidden())
964 while (w !=
nullptr) {
967 w = w->parentWidget();
970 QMenu *menu = qobject_cast<QMenu*>(popup);
974 const QAction *action = menu->menuAction();
975 for (
auto object : action->associatedObjects()) {
976 if (QWidget *widget = qobject_cast<QWidget*>(object)) {
977 if (waitForPopup(tb, widget))
1004bool QToolBar::event(QEvent *event)
1008 switch (event->type()) {
1010 if (d->waitForPopupTimer.timerId() ==
static_cast<QTimerEvent*>(event)->timerId()) {
1011 QWidget *w = QApplication::activePopupWidget();
1012 if (!waitForPopup(
this, w)) {
1013 d->waitForPopupTimer.stop();
1014 if (!
this->underMouse())
1015 d->layout->setExpanded(
false);
1024 d->toggleViewAction->setChecked(event->type() == QEvent::Show);
1026 enableMacToolBar(
this, event->type() == QEvent::Show);
1028 emit visibilityChanged(event->type() == QEvent::Show);
1030 case QEvent::ParentChange:
1031 d->layout->checkUsePopupMenu();
1034 case QEvent::MouseButtonPress: {
1035 if (d->mousePressEvent(
static_cast<QMouseEvent*>(event)))
1039 case QEvent::MouseButtonRelease:
1040 if (d->mouseReleaseEvent(
static_cast<QMouseEvent*>(event)))
1043 case QEvent::HoverEnter:
1044 case QEvent::HoverLeave:
1047 case QEvent::HoverMove: {
1049 QHoverEvent *e =
static_cast<QHoverEvent*>(event);
1050 QStyleOptionToolBar opt;
1051 initStyleOption(&opt);
1052 if (style()->subElementRect(QStyle::SE_ToolBarHandle, &opt,
this).contains(e->position().toPoint()))
1053 setCursor(Qt::SizeAllCursor);
1059 case QEvent::MouseMove:
1060 if (d->mouseMoveEvent(
static_cast<QMouseEvent*>(event)))
1064 if (d->state !=
nullptr && d->state->dragging) {
1067 QPoint pos = QCursor::pos();
1068 QMouseEvent fake(QEvent::MouseMove, mapFromGlobal(pos), pos, Qt::NoButton,
1069 QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers());
1070 d->mouseMoveEvent(&fake);
1073 if (!d->layout->expanded)
1076 QWidget *w = QApplication::activePopupWidget();
1077 if (waitForPopup(
this, w)) {
1082 d->waitForPopupTimer.stop();
1083 d->layout->setExpanded(
false);
1090 return QWidget::event(event);
1127void QToolBar::initStyleOption(QStyleOptionToolBar *option)
const
1129 Q_D(
const QToolBar);
1134 option->initFrom(
this);
1135 if (orientation() == Qt::Horizontal)
1136 option->state |= QStyle::State_Horizontal;
1137 option->lineWidth = style()->pixelMetric(QStyle::PM_ToolBarFrameWidth,
nullptr,
this);
1138 option->features = d->layout->movable()
1139 ? QStyleOptionToolBar::Movable
1140 : QStyleOptionToolBar::None;
1142 option->toolBarArea = Qt::NoToolBarArea;
1145 QMainWindow *mainWindow = qobject_cast<QMainWindow *>(parentWidget());
1150 QMainWindowLayout *layout = qt_mainwindow_layout(mainWindow);
1151 Q_ASSERT_X(layout !=
nullptr,
"QToolBar::initStyleOption()",
1152 "QMainWindow->layout() != QMainWindowLayout");
1154 layout->getStyleOptionInfo(option,
const_cast<QToolBar *>(
this));