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);
638void QToolBar::setOrientation(Qt::Orientation orientation)
641 if (orientation == d->orientation)
644 d->orientation = orientation;
646 if (orientation == Qt::Vertical)
647 setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred));
649 setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed));
651 d->layout->invalidate();
652 d->layout->activate();
654 emit orientationChanged(d->orientation);
673void QToolBar::setIconSize(
const QSize &iconSize)
678 QMainWindow *mw = qobject_cast<QMainWindow *>(parentWidget());
679 if (mw && mw->layout()) {
680 QLayout *layout = mw->layout();
682 QLayoutItem *item =
nullptr;
684 item = layout->itemAt(i++);
685 if (item && (item->widget() ==
this))
687 }
while (!sz.isValid() && item !=
nullptr);
691 const int metric = style()->pixelMetric(QStyle::PM_ToolBarIconSize,
nullptr,
this);
692 sz = QSize(metric, metric);
694 if (d->iconSize != sz) {
696 setMinimumSize(0, 0);
697 emit iconSizeChanged(d->iconSize);
699 d->explicitIconSize = iconSize.isValid();
701 d->layout->invalidate();
722void QToolBar::setToolButtonStyle(Qt::ToolButtonStyle toolButtonStyle)
725 d->explicitToolButtonStyle =
true;
726 if (d->toolButtonStyle == toolButtonStyle)
728 d->toolButtonStyle = toolButtonStyle;
729 setMinimumSize(0, 0);
730 emit toolButtonStyleChanged(d->toolButtonStyle);
806QAction *QToolBar::insertWidget(QAction *before, QWidget *widget)
808 QWidgetAction *action =
new QWidgetAction(
this);
809 action->setDefaultWidget(widget);
810 action->d_func()->autoCreated =
true;
811 insertAction(before, action);
837QAction *QToolBar::actionAt(
const QPoint &p)
const
840 QWidget *widget = childAt(p);
841 int index = d->layout->indexOf(widget);
844 QLayoutItem *item = d->layout->itemAt(index);
845 return static_cast<QToolBarItem*>(item)->action;
856void QToolBar::actionEvent(QActionEvent *event)
859 auto action =
static_cast<QAction *>(event->action());
860 QWidgetAction *widgetAction = qobject_cast<QWidgetAction *>(action);
862 switch (event->type()) {
863 case QEvent::ActionAdded: {
864 Q_ASSERT_X(widgetAction ==
nullptr || d->layout->indexOf(widgetAction) == -1,
865 "QToolBar",
"widgets cannot be inserted multiple times");
872 if (widgetAction !=
nullptr && widgetAction->d_func()->autoCreated)
873 widgetAction->setParent(
this);
875 int index = d->layout->count();
876 if (event->before()) {
877 index = d->layout->indexOf(event->before());
878 Q_ASSERT_X(index != -1,
"QToolBar::insertAction",
"internal error");
880 d->layout->insertAction(index, action);
884 case QEvent::ActionChanged:
885 d->layout->invalidate();
888 case QEvent::ActionRemoved: {
889 int index = d->layout->indexOf(action);
891 delete d->layout->takeAt(index);
897 Q_ASSERT_X(
false,
"QToolBar::actionEvent",
"internal error");
902void QToolBar::changeEvent(QEvent *event)
905 switch (event->type()) {
906 case QEvent::WindowTitleChange:
907 d->toggleViewAction->setText(windowTitle());
909 case QEvent::StyleChange:
910 d->layout->invalidate();
911 if (!d->explicitIconSize) {
912 QStyleOptionToolBar opt;
913 initStyleOption(&opt);
914 const int metric = style()->pixelMetric(QStyle::PM_ToolBarIconSize, &opt,
this);
915 setIconSize({metric, metric});
916 d->explicitIconSize =
false;
918 d->layout->updateMarginAndSpacing();
920 case QEvent::LayoutDirectionChange:
921 d->layout->invalidate();
926 QWidget::changeEvent(event);
930void QToolBar::paintEvent(QPaintEvent *)
935 QStyle *style =
this->style();
936 QStyleOptionToolBar opt;
937 initStyleOption(&opt);
939 if (d->layout->expanded || d->layout->animating || isWindow()) {
942 p.fillRect(opt.rect, palette().window());
943 style->drawControl(QStyle::CE_ToolBar, &opt, &p,
this);
944 style->drawPrimitive(QStyle::PE_FrameMenu, &opt, &p,
this);
946 style->drawControl(QStyle::CE_ToolBar, &opt, &p,
this);
949 opt.rect = style->subElementRect(QStyle::SE_ToolBarHandle, &opt,
this);
950 if (opt.rect.isValid())
951 style->drawPrimitive(QStyle::PE_IndicatorToolBarHandle, &opt, &p,
this);
962 if (popup ==
nullptr || popup->isHidden())
966 while (w !=
nullptr) {
969 w = w->parentWidget();
972 QMenu *menu = qobject_cast<QMenu*>(popup);
976 const QAction *action = menu->menuAction();
977 for (
auto object : action->associatedObjects()) {
978 if (QWidget *widget = qobject_cast<QWidget*>(object)) {
979 if (waitForPopup(tb, widget))
1001bool QToolBar::event(QEvent *event)
1005 switch (event->type()) {
1007 if (d->waitForPopupTimer.timerId() ==
static_cast<QTimerEvent*>(event)->timerId()) {
1008 QWidget *w = QApplication::activePopupWidget();
1009 if (!waitForPopup(
this, w)) {
1010 d->waitForPopupTimer.stop();
1011 if (!
this->underMouse())
1012 d->layout->setExpanded(
false);
1021 d->toggleViewAction->setChecked(event->type() == QEvent::Show);
1023 enableMacToolBar(
this, event->type() == QEvent::Show);
1025 emit visibilityChanged(event->type() == QEvent::Show);
1027 case QEvent::ParentChange:
1028 d->layout->checkUsePopupMenu();
1031 case QEvent::MouseButtonPress: {
1032 if (d->mousePressEvent(
static_cast<QMouseEvent*>(event)))
1036 case QEvent::MouseButtonRelease:
1037 if (d->mouseReleaseEvent(
static_cast<QMouseEvent*>(event)))
1040 case QEvent::HoverEnter:
1041 case QEvent::HoverLeave:
1044 case QEvent::HoverMove: {
1046 QHoverEvent *e =
static_cast<QHoverEvent*>(event);
1047 QStyleOptionToolBar opt;
1048 initStyleOption(&opt);
1049 if (style()->subElementRect(QStyle::SE_ToolBarHandle, &opt,
this).contains(e->position().toPoint()))
1050 setCursor(Qt::SizeAllCursor);
1056 case QEvent::MouseMove:
1057 if (d->mouseMoveEvent(
static_cast<QMouseEvent*>(event)))
1061 if (d->state !=
nullptr && d->state->dragging) {
1064 QPoint pos = QCursor::pos();
1065 QMouseEvent fake(QEvent::MouseMove, mapFromGlobal(pos), pos, Qt::NoButton,
1066 QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers());
1067 d->mouseMoveEvent(&fake);
1070 if (!d->layout->expanded)
1073 QWidget *w = QApplication::activePopupWidget();
1074 if (waitForPopup(
this, w)) {
1079 d->waitForPopupTimer.stop();
1080 d->layout->setExpanded(
false);
1087 return QWidget::event(event);
1124void QToolBar::initStyleOption(QStyleOptionToolBar *option)
const
1126 Q_D(
const QToolBar);
1131 option->initFrom(
this);
1132 if (orientation() == Qt::Horizontal)
1133 option->state |= QStyle::State_Horizontal;
1134 option->lineWidth = style()->pixelMetric(QStyle::PM_ToolBarFrameWidth,
nullptr,
this);
1135 option->features = d->layout->movable()
1136 ? QStyleOptionToolBar::Movable
1137 : QStyleOptionToolBar::None;
1139 option->toolBarArea = Qt::NoToolBarArea;
1142 QMainWindow *mainWindow = qobject_cast<QMainWindow *>(parentWidget());
1147 QMainWindowLayout *layout = qt_mainwindow_layout(mainWindow);
1148 Q_ASSERT_X(layout !=
nullptr,
"QToolBar::initStyleOption()",
1149 "QMainWindow->layout() != QMainWindowLayout");
1151 layout->getStyleOptionInfo(option,
const_cast<QToolBar *>(
this));