4#include "private/qlayoutengine_p.h"
5#if QT_CONFIG(itemviews)
14#if QT_CONFIG(tabwidget)
20#if QT_CONFIG(whatsthis)
23#include "private/qtextengine_p.h"
24#if QT_CONFIG(accessibility)
28#include <qpa/qplatformnativeinterface.h>
32#include "private/qapplication_p.h"
33#include "private/qtabbar_p.h"
71 p.drawPixmap(0, 0, m_pixmap);
76#if defined(Q_OS_MACOS)
88 upper = windowPos.
y();
89 int tabStripHeight =
q->tabSizeHint(0).height();
91 lower = upper + tabStripHeight + pixelTweak;
108 (
reinterpret_cast<RegisterContentBorderAreaFunction
>(
function))(
q->window()->windowHandle(), identifier, upper, lower);
115 (
reinterpret_cast<SetContentBorderAreaEnabledFunction
>(
function))(
q->window()->windowHandle(), identifier,
q->isVisible());
128 const int totalTabs =
tabList.size();
130 if (!
option || (tabIndex < 0 || tabIndex >= totalTabs))
136 option->rect =
q->tabRect(tabIndex);
143 if (isCurrent &&
q->hasFocus())
147 if (
q->isActiveWindow())
157 option->iconSize =
q->iconSize();
164 option->selectedPosition = QStyleOptionTab::PreviousIsSelected;
165 else if (tabIndex + 1 < totalTabs && tabIndex + 1 ==
currentIndex)
166 option->selectedPosition = QStyleOptionTab::NextIsSelected;
168 option->selectedPosition = QStyleOptionTab::NotAdjacent;
172 if (paintBeginning) {
174 option->position = QStyleOptionTab::OnlyOneTab;
176 option->position = QStyleOptionTab::Beginning;
177 }
else if (paintEnd) {
178 option->position = QStyleOptionTab::End;
180 option->position = QStyleOptionTab::Middle;
183#if QT_CONFIG(tabwidget)
184 if (
const QTabWidget *tw = qobject_cast<const QTabWidget *>(
q->parentWidget())) {
185 option->features |= QStyleOptionTab::HasFrame;
187 option->cornerWidgets |= QStyleOptionTab::LeftCornerWidget;
189 option->cornerWidgets |= QStyleOptionTab::RightCornerWidget;
192 option->tabIndex = tabIndex;
205 d->initBasicStyleOption(
option, tabIndex);
376#ifdef QT_KEYPAD_NAVIGATION
377 if (QApplicationPrivate::keypadNavigationEnabled()) {
385#if QT_CONFIG(accessibility)
386 leftB->setAccessibleName(QTabBar::tr(
"Scroll Left"));
387 rightB->setAccessibleName(QTabBar::tr(
"Scroll Right"));
400 if (
tabList.at(
i)->enabled &&
q->tabRect(
i).contains(
p))
413 int tabChainIndex = 0;
421 tabChain[tabChainIndex].init();
422 tabChain[tabChainIndex].expansive = (!
expanding)
425 tabChain[tabChainIndex].
empty =
true;
450 sz =
q->minimumTabSizeHint(
i);
453 tabChain[tabChainIndex].init();
454 tabChain[tabChainIndex].sizeHint = tab->maxRect.width();
455 tabChain[tabChainIndex].minimumSize = sz.
width();
456 tabChain[tabChainIndex].
empty =
false;
457 tabChain[tabChainIndex].expansive =
true;
460 tabChain[tabChainIndex].maximumSize = tabChain[tabChainIndex].sizeHint;
465 available =
size.width();
466 maxExtent = maxHeight;
481 sz =
q->minimumTabSizeHint(
i);
484 tabChain[tabChainIndex].init();
485 tabChain[tabChainIndex].sizeHint = tab->maxRect.height();
486 tabChain[tabChainIndex].minimumSize = sz.
height();
487 tabChain[tabChainIndex].
empty =
false;
488 tabChain[tabChainIndex].expansive =
true;
491 tabChain[tabChainIndex].maximumSize = tabChain[tabChainIndex].sizeHint;
496 available =
size.height();
497 maxExtent = maxWidth;
501 tabChain[tabChainIndex].init();
502 tabChain[tabChainIndex].expansive = (!
expanding)
505 tabChain[tabChainIndex].
empty =
true;
506 Q_ASSERT(tabChainIndex == tabChain.
size() - 1 - hiddenTabs);
522 tab->rect.setRect(lstruct.
pos, 0, lstruct.
size, maxExtent);
524 tab->rect.setRect(0, lstruct.
pos, maxExtent, lstruct.
size);
541 scrollButtonLeftRect.
setHeight(scrollButtonWidth);
542 scrollButtonRightRect.
setY(scrollButtonRightRect.
bottom() + 1 - scrollButtonWidth);
543 scrollButtonRightRect.
setHeight(scrollButtonWidth);
547 scrollButtonRightRect.
setWidth(scrollButtonWidth);
548 scrollButtonLeftRect.
setX(scrollButtonLeftRect.
right() + 1 - scrollButtonWidth);
549 scrollButtonLeftRect.
setWidth(scrollButtonWidth);
553 scrollButtonLeftRect.
setWidth(scrollButtonWidth);
554 scrollButtonRightRect.
setX(scrollButtonRightRect.
right() + 1 - scrollButtonWidth);
555 scrollButtonRightRect.
setWidth(scrollButtonWidth);
573 q->tabLayoutChange();
599 int topEdge, bottomEdge;
600 bool leftButtonIsOnTop = scrollButtonLeftRect.
y() <
q->height() / 2;
601 bool rightButtonIsOnTop = scrollButtonRightRect.
y() <
q->height() / 2;
603 if (leftButtonIsOnTop && rightButtonIsOnTop) {
604 topEdge = scrollButtonRightRect.
bottom() + 1;
605 bottomEdge =
q->height();
606 }
else if (!leftButtonIsOnTop && !rightButtonIsOnTop) {
608 bottomEdge = scrollButtonLeftRect.
top();
610 topEdge = scrollButtonLeftRect.
bottom() + 1;
611 bottomEdge = scrollButtonRightRect.
top();
616 if (tearTopVisible && !tearLeftRect.
isNull())
617 topEdge = tearLeftRect.
bottom() + 1;
618 if (tearBottomVisible && !tearRightRect.
isNull())
619 bottomEdge = tearRightRect.
top();
621 return QRect(topEdge, 0, bottomEdge - topEdge,
q->height());
630 int leftEdge, rightEdge;
631 bool leftButtonIsOnLeftSide = scrollButtonLeftRect.
x() <
q->width() / 2;
632 bool rightButtonIsOnLeftSide = scrollButtonRightRect.
x() <
q->width() / 2;
634 if (leftButtonIsOnLeftSide && rightButtonIsOnLeftSide) {
635 leftEdge = scrollButtonRightRect.
right() + 1;
636 rightEdge =
q->width();
637 }
else if (!leftButtonIsOnLeftSide && !rightButtonIsOnLeftSide) {
639 rightEdge = scrollButtonLeftRect.
left();
641 leftEdge = scrollButtonLeftRect.
right() + 1;
642 rightEdge = scrollButtonRightRect.
left();
647 if (tearLeftVisible && !tearLeftRect.
isNull())
648 leftEdge = tearLeftRect.
right() + 1;
649 if (tearRightVisible && !tearRightRect.
isNull())
650 rightEdge = tearRightRect.
left();
652 return QRect(leftEdge, 0, rightEdge - leftEdge,
q->height());
674 const int available = horiz ?
q->width() :
q->height();
675 const int tabStart = horiz ? tabRect.
left() : tabRect.
top();
676 const int tabEnd = horiz ? tabRect.
right() : tabRect.
bottom();
677 const int lastTabEnd = horiz ?
tabList.constLast()->rect.right() :
tabList.constLast()->rect.bottom();
683 if (tabStart < scrolledTabBarStart) {
686 }
else if (tabEnd > scrolledTabBarEnd) {
692 }
else if (available >= lastTabEnd) {
755 for (
int i =
start;
i <
q->count(); ++
i) {
765 q->setVisible(
q->count() > 1);
787 if (tabToClose != -1)
788 emit q->tabCloseRequested(tabToClose);
800 if (sender ==
leftB) {
808 }
else if (sender ==
rightB) {
810 const auto tabRect =
tabList.at(
i)->rect;
811 int start = horizontal ? tabRect.left() : tabRect.top();
812 int end = horizontal ? tabRect.right() : tabRect.bottom();
834 if (!
q->isVisible()) {
955 if (!
d->validIndex(
index)) {
956 index =
d->tabList.size();
961#ifndef QT_NO_SHORTCUT
966 if (
d->tabList.size() == 1)
971 if (index <= d->lastVisible)
976 if (
d->closeButtonOnTabs) {
985 for (
const auto tab : std::as_const(
d->tabList)) {
986 if (tab->lastTab >=
index)
1009 if (
d->validIndex(
index)) {
1010 auto removedTab =
d->tabList.at(
index);
1011 if (
d->dragInProgress)
1012 d->moveTabFinished(
d->pressedIndex);
1014#ifndef QT_NO_SHORTCUT
1017 if (removedTab->leftWidget) {
1018 removedTab->leftWidget->hide();
1019 removedTab->leftWidget->deleteLater();
1020 removedTab->leftWidget =
nullptr;
1022 if (removedTab->rightWidget) {
1023 removedTab->rightWidget->hide();
1024 removedTab->rightWidget->deleteLater();
1025 removedTab->rightWidget =
nullptr;
1028 int newIndex = removedTab->lastTab;
1029 d->tabList.removeAt(
index);
1031 for (
auto tab : std::as_const(
d->tabList)) {
1032 if (tab->lastTab ==
index)
1034 if (tab->lastTab >
index)
1038 d->calculateFirstLastVisible(
index,
false,
true);
1040 if (
index ==
d->currentIndex) {
1044 d->currentIndex = -1;
1045 if (
d->tabList.size() > 0) {
1046 switch(
d->selectionBehaviorOnRemove) {
1048 if (newIndex >
index)
1050 if (
d->validIndex(newIndex) &&
d->tabList.at(newIndex)->visible)
1057 newIndex =
qBound(
d->firstVisible,
index-1,
d->lastVisible);
1063 if (
d->validIndex(newIndex)) {
1065 int bump =
d->tabList.at(newIndex)->lastTab;
1067 d->tabList.at(newIndex)->lastTab = bump;
1080 if (
d->hoverRect.isValid()) {
1082 d->hoverIndex =
tabAt(
d->mousePosition);
1083 if (
d->validIndex(
d->hoverIndex)) {
1103 return tab->enabled;
1116#ifndef QT_NO_SHORTCUT
1136 if (
d->validIndex(
index))
1137 return d->tabList.at(
index)->visible;
1150 d->layoutDirty = (
visible != tab->visible);
1151 if (!
d->layoutDirty)
1154 if (tab->leftWidget)
1155 tab->leftWidget->setVisible(
visible);
1156 if (tab->rightWidget)
1157 tab->rightWidget->setVisible(
visible);
1158#ifndef QT_NO_SHORTCUT
1163 const int newindex =
d->selectNewCurrentIndexFrom(
index+1);
1190 d->textSizes.remove(tab->text);
1192#ifndef QT_NO_SHORTCUT
1211 return tab->textColor;
1226 tab->textColor =
color;
1250 bool simpleIconChange = (!
icon.
isNull() && !tab->icon.isNull());
1252 if (simpleIconChange)
1259#if QT_CONFIG(tooltip)
1263void QTabBar::setTabToolTip(
int index,
const QString & tip)
1278 return tab->toolTip;
1283#if QT_CONFIG(whatsthis)
1294 tab->whatsThis =
text;
1307 return tab->whatsThis;
1351 r.translate(-
d->scrollOffset, 0);
1368 if (
d->validIndex(
d->currentIndex)
1370 return d->currentIndex;
1372 const int max =
d->tabList.size();
1373 for (
int i = 0;
i < max; ++
i) {
1391 if (
d->validIndex(
d->currentIndex))
1392 return d->currentIndex;
1400 if (
d->dragInProgress &&
d->pressedIndex != -1)
1402 if (
d->currentIndex ==
index)
1405 int oldIndex =
d->currentIndex;
1406 if (
auto tab =
d->at(
index)) {
1417 if (
d->validIndex(oldIndex)) {
1418 tab->lastTab = oldIndex;
1419 d->layoutTab(oldIndex);
1422#if QT_CONFIG(accessibility)
1423 if (QAccessible::isActive()) {
1425 QAccessibleEvent focusEvent(
this, QAccessible::Focus);
1426 focusEvent.setChild(
index);
1427 QAccessible::updateAccessibility(&focusEvent);
1429 QAccessibleEvent selectionEvent(
this, QAccessible::Selection);
1430 selectionEvent.setChild(
index);
1431 QAccessible::updateAccessibility(&selectionEvent);
1451 if (
d->iconSize.isValid())
1454 return QSize(iconExtent, iconExtent);
1462 d->layoutDirty =
true;
1475 return d->tabList.size();
1487 for (
const auto tab :
d->tabList) {
1489 r =
r.united(tab->maxRect);
1501 if (!
d->useScrollButtons) {
1503 for (
const auto tab :
d->tabList) {
1505 r =
r.united(tab->minRect);
1521 static const auto Ellipses =
"..."_L1;
1552 tab->
text = oldText;
1564 QStyleOptionTab
opt;
1572 int maxWidgetHeight =
qMax(
opt.leftButtonSize.height(),
opt.rightButtonSize.height());
1573 int maxWidgetWidth =
qMax(
opt.leftButtonSize.width(),
opt.rightButtonSize.width());
1575 int widgetWidth = 0;
1576 int widgetHeight = 0;
1578 if (!
opt.leftButtonSize.isEmpty()) {
1580 widgetWidth +=
opt.leftButtonSize.width();
1581 widgetHeight +=
opt.leftButtonSize.height();
1583 if (!
opt.rightButtonSize.isEmpty()) {
1585 widgetWidth +=
opt.rightButtonSize.width();
1586 widgetHeight +=
opt.rightButtonSize.height();
1592 if (
it ==
d->textSizes.end())
1594 const int textWidth =
it.value().width();
1598 textWidth +
iconSize.
width() + hframe + widgetHeight + padding);
1649 if (!
d->validIndex(
d->currentIndex))
1652 d->makeVisible(
d->currentIndex);
1653 d->updateMacBorderMetrics();
1661 d->updateMacBorderMetrics();
1669 switch (
event->type()) {
1674 if (!
d->hoverRect.contains(
d->mousePosition)) {
1675 if (
d->hoverRect.isValid())
1677 d->hoverIndex =
tabAt(
d->mousePosition);
1678 if (
d->validIndex(
d->hoverIndex)) {
1688 d->mousePosition = {-1, -1};
1689 if (
d->hoverRect.isValid())
1693#if QT_CONFIG(wheelevent)
1694 d->accumulatedAngleDelta =
QPoint();
1698#if QT_CONFIG(tooltip)
1701 if (!tab->toolTip.isEmpty()) {
1708#if QT_CONFIG(whatsthis)
1709 case QEvent::QEvent::QueryWhatsThis: {
1711 if (!tab || tab->whatsThis.isEmpty())
1717 if (!tab->whatsThis.isEmpty()) {
1719 tab->whatsThis,
this);
1725#ifndef QT_NO_SHORTCUT
1729 for (
int i = 0;
i <
d->tabList.size(); ++
i) {
1740 d->updateMacBorderMetrics();
1742#if QT_CONFIG(draganddrop)
1745 if (
d->changeCurrentOnDrag)
1749 if (
d->changeCurrentOnDrag) {
1750 const int tabIndex =
tabAt(
static_cast<QDragMoveEvent *
>(
event)->
position().toPoint());
1751 if (
isTabEnabled(tabIndex) &&
d->switchTabCurrentIndex != tabIndex) {
1752 d->switchTabCurrentIndex = tabIndex;
1753 if (
d->switchTabTimerId)
1762 d->killSwitchTabTimer();
1790 d->makeVisible(
d->currentIndex);
1799 QStyleOptionTabBarBase optTabBase;
1807 QStyleOptionTab cutTabLeft;
1808 QStyleOptionTab cutTabRight;
1809 selected =
d->currentIndex;
1810 if (
d->dragInProgress)
1811 selected =
d->pressedIndex;
1812 const QRect scrollRect =
d->normalizedScrollRect();
1814 for (
int i = 0;
i <
d->tabList.size(); ++
i)
1815 optTabBase.tabBarRect |=
tabRect(
i);
1817 optTabBase.selectedTabRect =
tabRect(selected);
1824 if (
d->leftB->isVisible() ||
d->rightB->isVisible()) {
1828 if (
d->leftB->isVisible())
1830 if (
d->rightB->isVisible())
1836 for (
int i = 0;
i <
d->tabList.size(); ++
i) {
1837 const auto tab =
d->tabList.at(
i);
1840 QStyleOptionTab tabOption;
1842 if (
d->paintWithOffsets && tab->dragOffset != 0) {
1844 tabOption.rect.moveTop(tabOption.rect.y() + tab->dragOffset);
1846 tabOption.rect.moveLeft(tabOption.rect.x() + tab->dragOffset);
1858 if (tabStart < scrollRect.
left() +
d->scrollOffset) {
1860 cutTabLeft = tabOption;
1861 }
else if (tabEnd > scrollRect.
right() +
d->scrollOffset) {
1863 cutTabRight = tabOption;
1867 if ((!vertical && (tabOption.rect.right() < 0 || tabOption.rect.left() >
width()))
1868 || (vertical && (tabOption.rect.bottom() < 0 || tabOption.rect.top() >
height())))
1871 optTabBase.tabBarRect |= tabOption.rect;
1879 if (selected >= 0) {
1880 QStyleOptionTab tabOption;
1881 const auto tab =
d->tabList.at(selected);
1884 if (
d->paintWithOffsets && tab->dragOffset != 0) {
1887 tabOption.position = QStyleOptionTab::TabPosition::Moving;
1890 tabOption.rect.moveTop(tabOption.rect.y() + tab->dragOffset);
1892 tabOption.rect.moveLeft(tabOption.rect.x() + tab->dragOffset);
1898 ? tabOption.rect.adjusted(0, -taboverlap, 0, taboverlap)
1899 : tabOption.rect.adjusted(-taboverlap, 0, taboverlap, 0);
1903 if (
d->dragInProgress)
1904 d->movingTab->setGeometry(movingRect);
1910 if (
d->leftB->isVisible() && cutLeft >= 0) {
1911 cutTabLeft.rect =
rect();
1916 if (
d->rightB->isVisible() && cutRight >= 0) {
1917 cutTabRight.rect =
rect();
1944 for (
int i =
tabList.size() - 1;
i >= 0; --
i) {
1962 for (
int i = fromIndex;
i <
tabList.size(); ++
i) {
1969 for (
int i = fromIndex-1;
i > -1; --
i) {
1991 index += (from < to) ? -1 : 1;
2005 || !
d->validIndex(from)
2006 || !
d->validIndex(to))
2009 auto &fromTab = *
d->tabList.at(from);
2010 auto &toTab = *
d->tabList.at(to);
2013 int oldPressedPosition = 0;
2014 if (
d->pressedIndex != -1) {
2016 oldPressedPosition = vertical ?
d->tabList.at(
d->pressedIndex)->rect.y()
2017 :
d->tabList.at(
d->pressedIndex)->rect.x();
2023 int width = vertical ? fromTab.rect.height() : fromTab.rect.width();
2030 auto &tab = *
d->tabList.at(
i);
2032 tab.rect.moveTop(tab.rect.y() +
width);
2034 tab.rect.moveLeft(tab.rect.x() +
width);
2036 if (rtl && !vertical)
2038 if (tab.dragOffset != 0)
2044 fromTab.rect.moveTop(toTab.rect.bottom() + 1);
2046 fromTab.rect.moveTop(toTab.rect.top() -
width);
2049 fromTab.rect.moveLeft(toTab.rect.right() + 1);
2051 fromTab.rect.moveLeft(toTab.rect.left() -
width);
2055 d->tabList.move(from, to);
2058 for (
const auto tab : std::as_const(
d->tabList))
2059 tab->lastTab =
d->calculateNewPosition(from, to, tab->lastTab);
2062 int previousIndex =
d->currentIndex;
2063 d->currentIndex =
d->calculateNewPosition(from, to,
d->currentIndex);
2066 if (
d->pressedIndex != -1) {
2067 d->pressedIndex =
d->calculateNewPosition(from, to,
d->pressedIndex);
2068 const auto pressedTab =
d->tabList.at(
d->pressedIndex);
2069 int newPressedPosition = vertical ? pressedTab->rect.top() : pressedTab->rect.left();
2070 int diff = oldPressedPosition - newPressedPosition;
2074 d->dragStartPosition.setY(
d->dragStartPosition.y() - diff);
2076 d->dragStartPosition.setX(
d->dragStartPosition.x() - diff);
2082 if (previousIndex !=
d->currentIndex)
2095 int preLocation = vertical ?
q->tabRect(from).y() :
q->tabRect(from).x();
2096 q->setUpdatesEnabled(
false);
2097 q->moveTab(from, to);
2098 q->setUpdatesEnabled(
true);
2099 int postLocation = vertical ?
q->tabRect(to).y() :
q->tabRect(to).x();
2100 int length = postLocation - preLocation;
2120 const QPoint pos =
event->position().toPoint();
2121 const bool isEventInCornerButtons = (!
d->leftB->isHidden() &&
d->leftB->geometry().contains(
pos))
2122 || (!
d->rightB->isHidden() &&
d->rightB->geometry().contains(
pos));
2123 if (!isEventInCornerButtons) {
2133 if (
d->pressedIndex != -1 &&
d->movable)
2134 d->moveTabFinished(
d->pressedIndex);
2136 d->pressedIndex =
d->indexAtPos(
event->position().toPoint());
2138 if (
d->validIndex(
d->pressedIndex)) {
2139 QStyleOptionTabBarBase optTabBase;
2140 optTabBase.initFrom(
this);
2141 optTabBase.documentMode =
d->documentMode;
2147 d->dragStartPosition =
event->position().toPoint();
2159 if (
d->pressedIndex != -1
2161 d->moveTabFinished(
d->pressedIndex);
2164 if (!
d->dragInProgress &&
d->pressedIndex != -1) {
2166 d->dragInProgress =
true;
2167 d->setupMovableTab();
2172 &&
d->dragInProgress
2173 &&
d->validIndex(
d->pressedIndex)) {
2177 dragDistance = (
event->position().toPoint().y() -
d->dragStartPosition.y());
2179 dragDistance = (
event->position().toPoint().x() -
d->dragStartPosition.x());
2181 d->tabList.at(
d->pressedIndex)->dragOffset = dragDistance;
2185 startingRect.
moveTop(startingRect.
y() + dragDistance);
2187 startingRect.
moveLeft(startingRect.
x() + dragDistance);
2190 if (dragDistance < 0)
2195 if (overIndex !=
d->pressedIndex && overIndex != -1) {
2199 if (dragDistance < 0) {
2203 for (
int i =
d->pressedIndex;
2204 offset > 0 ? i < overIndex : i > overIndex;
2207 int needsToBeOver = (vertical ? overIndexRect.
height() : overIndexRect.
width()) / 2;
2208 if (dragDistance > needsToBeOver)
2213 if (
d->pressedIndex != -1)
2214 d->layoutTab(
d->pressedIndex);
2235 grabRect.
adjust(0, -taboverlap, 0, taboverlap);
2237 grabRect.
adjust(-taboverlap, 0, taboverlap, 0);
2239 QPixmap grabImage(grabRect.
size() *
q->devicePixelRatio());
2244 QStyleOptionTab tab;
2246 tab.position = QStyleOptionTab::OnlyOneTab;
2248 tab.rect.moveTopLeft(
QPoint(0, taboverlap));
2250 tab.rect.moveTopLeft(
QPoint(taboverlap, 0));
2260 if (pressedTab.leftWidget)
2261 pressedTab.leftWidget->raise();
2262 if (pressedTab.rightWidget)
2263 pressedTab.rightWidget->raise();
2275 bool allAnimationsFinished =
true;
2276#if QT_CONFIG(animation)
2277 for (
const auto tab : std::as_const(
tabList)) {
2279 allAnimationsFinished =
false;
2284 if (allAnimationsFinished && cleanup) {
2287 for (
auto tab : std::as_const(
tabList)) {
2288 tab->dragOffset = 0;
2314 if (
d->movable &&
d->dragInProgress &&
d->validIndex(
d->pressedIndex)) {
2315 int length =
d->tabList.at(
d->pressedIndex)->dragOffset;
2321 d->tabList.at(
d->pressedIndex)->startAnimation(
d, duration);
2322 d->dragInProgress =
false;
2323 d->movingTab->setVisible(
false);
2324 d->dragStartPosition =
QPoint();
2328 int oldPressedIndex =
d->pressedIndex;
2329 int i =
d->indexAtPos(
event->position().toPoint()) ==
d->pressedIndex ?
d->pressedIndex : -1;
2330 d->pressedIndex = -1;
2331 QStyleOptionTabBarBase optTabBase;
2332 optTabBase.initFrom(
this);
2333 optTabBase.documentMode =
d->documentMode;
2334 const bool selectOnRelease =
2336 if (selectOnRelease)
2338 if (
d->validIndex(oldPressedIndex))
2347 const QPoint pos =
event->position().toPoint();
2348 const bool isEventInCornerButtons = (!
d->leftB->isHidden() &&
d->leftB->geometry().contains(
pos))
2349 || (!
d->rightB->isHidden() &&
d->rightB->geometry().contains(
pos));
2350 if (!isEventInCornerButtons)
2366 d->setCurrentNextEnabledIndex(
offset);
2371#if QT_CONFIG(wheelevent)
2372void QTabBar::wheelEvent(QWheelEvent *
event)
2376 const bool wheelVertical =
qAbs(
event->angleDelta().y()) >
qAbs(
event->angleDelta().x());
2382 if (tabsVertical == wheelVertical)
2383 delta = wheelVertical ?
event->pixelDelta().y() :
event->pixelDelta().x();
2386 if (delta &&
d->validIndex(
d->lastVisible)) {
2387 const int oldScrollOffset =
d->scrollOffset;
2388 const QRect lastTabRect =
d->tabList.at(
d->lastVisible)->rect;
2389 const QRect scrollRect =
d->normalizedScrollRect(
d->lastVisible);
2390 int scrollRectExtent = scrollRect.
right();
2391 if (!
d->leftB->isVisible())
2392 scrollRectExtent += tabsVertical ?
d->leftB->height() :
d->leftB->width();
2393 if (!
d->rightB->isVisible())
2394 scrollRectExtent += tabsVertical ?
d->rightB->height() :
d->rightB->width();
2396 const int maxScrollOffset =
qMax((tabsVertical ?
2398 lastTabRect.
right()) - scrollRectExtent, 0);
2399 d->scrollOffset =
qBound(0,
d->scrollOffset - delta, maxScrollOffset);
2400 d->leftB->setEnabled(
d->scrollOffset > -scrollRect.
left());
2401 d->rightB->setEnabled(maxScrollOffset >
d->scrollOffset);
2402 if (oldScrollOffset !=
d->scrollOffset) {
2409 d->accumulatedAngleDelta +=
event->angleDelta();
2410 const int xSteps =
d->accumulatedAngleDelta.x() / QWheelEvent::DefaultDeltasPerStep;
2411 const int ySteps =
d->accumulatedAngleDelta.y() / QWheelEvent::DefaultDeltasPerStep;
2413 if (xSteps > 0 || ySteps > 0) {
2415 d->accumulatedAngleDelta =
QPoint();
2416 }
else if (xSteps < 0 || ySteps < 0) {
2418 d->accumulatedAngleDelta =
QPoint();
2420 const int oldCurrentIndex =
d->currentIndex;
2421 d->setCurrentNextEnabledIndex(
offset);
2422 if (oldCurrentIndex !=
d->currentIndex) {
2427 QWidget::wheelEvent(
event);
2437 q->setCurrentIndex(
index);
2448 switch (
event->type()) {
2450 if (!
d->elideModeSetByUser)
2452 if (!
d->useScrollButtonsSetByUser)
2456 d->textSizes.clear();
2472 if (
event->timerId() ==
d->switchTabTimerId) {
2474 d->switchTabTimerId = 0;
2476 d->switchTabCurrentIndex = -1;
2497 return d->elideMode;
2503 d->elideMode =
mode;
2504 d->elideModeSetByUser =
true;
2505 d->textSizes.clear();
2524 return d_func()->useScrollButtons;
2530 d->useScrollButtonsSetByUser =
true;
2531 if (
d->useScrollButtons == useButtons)
2533 d->useScrollButtons = useButtons;
2554 return d->closeButtonOnTabs;
2560 if (
d->closeButtonOnTabs == closable)
2562 d->closeButtonOnTabs = closable;
2565 for (
auto tab : std::as_const(
d->tabList)) {
2566 if (closeSide ==
LeftSide && tab->leftWidget) {
2567 tab->leftWidget->deleteLater();
2568 tab->leftWidget =
nullptr;
2570 if (closeSide ==
RightSide && tab->rightWidget) {
2571 tab->rightWidget->deleteLater();
2572 tab->rightWidget =
nullptr;
2576 bool newButtons =
false;
2577 for (
int i = 0;
i <
d->tabList.size(); ++
i) {
2633 return d->selectionBehaviorOnRemove;
2639 d->selectionBehaviorOnRemove = behavior;
2655 return d->expanding;
2703 return d_func()->documentMode;
2711 d->updateMacBorderMetrics();
2734 if (
d->autoHide ==
hide)
2759 return d->changeCurrentOnDrag;
2765 d->changeCurrentOnDrag = change;
2767 d->killSwitchTabTimer();
2787 if (index < 0 || index >=
d->tabList.size())
2795 auto &tab = *
d->tabList.at(
index);
2798 tab.leftWidget->hide();
2801 if (tab.rightWidget)
2802 tab.rightWidget->
hide();
2803 tab.rightWidget =
widget;
2817 if (
const auto tab =
d->at(
index)) {
2824#if QT_CONFIG(accessibility)
2832 tab->accessibleName =
name;
2833 QAccessibleEvent
event(
this, QAccessible::NameChanged);
2834 event.setChild(
index);
2835 QAccessible::updateAccessibility(&
event);
2847 return tab->accessibleName;
2859#if QT_CONFIG(tooltip)
2865QSize CloseButton::sizeHint()
const
2893 if (
isEnabled() && underMouse() && !isChecked() && !isDown())
2900 if (
const QTabBar *tb = qobject_cast<const QTabBar *>(
parent())) {
2901 int index = tb->currentIndex();
2910#if QT_CONFIG(animation)
2911void QTabBarPrivate::Tab::TabBarAnimation::updateCurrentValue(
const QVariant ¤t)
2918 if (
newState == Stopped)
priv->moveTabFinished(
priv->tabList.indexOf(tab));
2924#include "moc_qtabbar.cpp"
2925#include "qtabbar.moc"
State
This enum describes the state of the animation.
int startDragDistance
the minimum distance required for a drag and drop operation to start.
The QColor class provides colors based on RGB, HSV or CMYK values.
bool isValid() const noexcept
Returns true if the color is valid; otherwise returns false.
\reentrant \inmodule QtGui
int height() const
Returns the height of the font.
QSize size(int flags, const QString &str, int tabstops=0, int *tabarray=nullptr) const
Returns the size in pixels of text.
QString elidedText(const QString &text, Qt::TextElideMode mode, int width, int flags=0) const
static QPlatformNativeInterface * platformNativeInterface()
The QHelpEvent class provides an event that is used to request helpful information about a particular...
const QPoint & pos() const
Returns the mouse cursor position when the event was generated, relative to the widget to which the e...
The QHideEvent class provides an event which is sent after a widget is hidden.
The QIcon class provides scalable icons in different modes and states.
bool isNull() const
Returns true if the icon is empty; otherwise returns false.
The QKeyEvent class describes a key event.
static QKeySequence mnemonic(const QString &text)
Returns the shortcut key sequence for the mnemonic in text, or an empty key sequence if no mnemonics ...
qsizetype size() const noexcept
bool empty() const noexcept
const_reference at(qsizetype i) const noexcept
int startTimer(int interval, Qt::TimerType timerType=Qt::CoarseTimer)
This is an overloaded function that will start a timer of type timerType and a timeout of interval mi...
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
QObject * sender() const
Returns a pointer to the object that sent the signal, if called in a slot activated by a signal; othe...
virtual void timerEvent(QTimerEvent *event)
This event handler can be reimplemented in a subclass to receive timer events for the object.
Q_WEAK_OVERLOAD void setObjectName(const QString &name)
Sets the object's name to name.
void killTimer(int id)
Kills the timer with timer identifier, id.
The QPaintEvent class contains event parameters for paint events.
The QPainter class performs low-level painting on widgets and other paint devices.
Returns a copy of the pixmap that is transformed using the given transformation transform and transfo...
void setDevicePixelRatio(qreal scaleFactor)
Sets the device pixel ratio for the pixmap.
void fill(const QColor &fillColor=Qt::white)
Fills the pixmap with the given color.
constexpr QPoint toPoint() const
Rounds the coordinates of this point to the nearest integer, and returns a QPoint object with the rou...
\inmodule QtCore\reentrant
constexpr int y() const noexcept
Returns the y coordinate of this point.
\inmodule QtCore\reentrant
constexpr void adjust(int x1, int y1, int x2, int y2) noexcept
Adds dx1, dy1, dx2 and dy2 respectively to the existing coordinates of the rectangle.
constexpr int height() const noexcept
Returns the height of the rectangle.
constexpr bool isNull() const noexcept
Returns true if the rectangle is a null rectangle, otherwise returns false.
constexpr int bottom() const noexcept
Returns the y-coordinate of the rectangle's bottom edge.
constexpr QPoint topLeft() const noexcept
Returns the position of the rectangle's top-left corner.
constexpr int top() const noexcept
Returns the y-coordinate of the rectangle's top edge.
constexpr QPoint topRight() const noexcept
Returns the position of the rectangle's top-right corner.
constexpr void moveLeft(int pos) noexcept
Moves the rectangle horizontally, leaving the rectangle's left edge at the given x coordinate.
bool contains(const QRect &r, bool proper=false) const noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
constexpr int left() const noexcept
Returns the x-coordinate of the rectangle's left edge.
constexpr int x() const noexcept
Returns the x-coordinate of the rectangle's left edge.
constexpr void setWidth(int w) noexcept
Sets the width of the rectangle to the given width.
constexpr void setX(int x) noexcept
Sets the left edge of the rectangle to the given x coordinate.
constexpr QSize size() const noexcept
Returns the size of the rectangle.
constexpr void translate(int dx, int dy) noexcept
Moves the rectangle dx along the x axis and dy along the y axis, relative to the current position.
constexpr int width() const noexcept
Returns the width of the rectangle.
constexpr QRect translated(int dx, int dy) const noexcept
Returns a copy of the rectangle that is translated dx along the x axis and dy along the y axis,...
constexpr int y() const noexcept
Returns the y-coordinate of the rectangle's top edge.
constexpr void setHeight(int h) noexcept
Sets the height of the rectangle to the given height.
constexpr void moveTop(int pos) noexcept
Moves the rectangle vertically, leaving the rectangle's top edge at the given y coordinate.
constexpr void setY(int y) noexcept
Sets the top edge of the rectangle to the given y coordinate.
constexpr int right() const noexcept
Returns the x-coordinate of the rectangle's right edge.
The QRegion class specifies a clip region for a painter.
bool isEmpty() const
Returns true if the region is empty; otherwise returns false.
The QResizeEvent class contains event parameters for resize events.
The QShortcutEvent class provides an event which is generated when the user presses a key combination...
The QShowEvent class provides an event that is sent when a widget is shown.
QPointF position() const
Returns the position of the point in this event, relative to the widget or item that received the eve...
constexpr int height() const noexcept
Returns the height.
constexpr int width() const noexcept
Returns the width.
constexpr bool isNull() const noexcept
Returns true if both the width and height is 0; otherwise returns false.
\macro QT_RESTRICTED_CAST_FROM_ASCII
QString right(qsizetype n) const
Returns a substring that contains the n rightmost characters of the string.
qsizetype size() const
Returns the number of characters in this string.
QString left(qsizetype n) const
Returns a substring that contains the n leftmost characters of the string.
The QStyleOption class stores the parameters used by QStyle functions.
void initFrom(const QWidget *w)
The QStylePainter class is a convenience class for drawing QStyle elements inside a widget.
The QStyle class is an abstract base class that encapsulates the look and feel of a GUI.
virtual QSize sizeFromContents(ContentsType ct, const QStyleOption *opt, const QSize &contentsSize, const QWidget *w=nullptr) const =0
Returns the size of the element described by the specified option and type, based on the provided con...
@ SH_TabBar_CloseButtonPosition
@ SH_TabBar_AllowWheelScrolling
@ SH_TabBar_ChangeCurrentDelay
@ SH_TabBar_PreferNoArrows
@ SH_TabBar_SelectMouseType
virtual int styleHint(StyleHint stylehint, const QStyleOption *opt=nullptr, const QWidget *widget=nullptr, QStyleHintReturn *returnData=nullptr) const =0
Returns an integer representing the specified style hint for the given widget described by the provid...
virtual QRect subElementRect(SubElement subElement, const QStyleOption *option, const QWidget *widget=nullptr) const =0
Returns the sub-area for the given element as described in the provided style option.
static QRect visualRect(Qt::LayoutDirection direction, const QRect &boundingRect, const QRect &logicalRect)
Returns the given logicalRectangle converted to screen coordinates based on the specified direction.
@ PM_TabCloseIndicatorWidth
@ PM_TabBarScrollButtonWidth
@ PM_TabCloseIndicatorHeight
@ PE_IndicatorTabTearRight
@ PE_IndicatorTabTearLeft
virtual int pixelMetric(PixelMetric metric, const QStyleOption *option=nullptr, const QWidget *widget=nullptr) const =0
Returns the value of the given pixel metric.
@ SE_TabBarTearIndicatorLeft
@ SE_TabBarTabRightButton
@ SE_TabBarTearIndicatorRight
@ SE_TabBarScrollRightButton
@ SE_TabBarScrollLeftButton
void initBasicStyleOption(QStyleOptionTab *option, int tabIndex) const
int calculateNewPosition(int from, int to, int index) const
bool validIndex(int index) const
int hoveredTabIndex() const
void killSwitchTabTimer()
int selectNewCurrentIndexFrom(int currentIndex)
void moveTab(int index, int offset)
QRect normalizedScrollRect(int index=-1)
void updateMacBorderMetrics()
Qt::TextElideMode elideMode
int switchTabCurrentIndex
Qt::MouseButtons mouseButtons
void layoutWidgets(int start=0)
void layoutTab(int index)
void setCurrentNextEnabledIndex(int offset)
\reimp
void makeVisible(int index)
void calculateFirstLastVisible(int index, bool visible, bool remove)
void moveTabFinished(int index)
QMovableTabWidget * movingTab
static void initStyleBaseOption(QStyleOptionTabBarBase *optTabBase, QTabBar *tabbar, QSize size)
void slide(int from, int to)
int indexAtPos(const QPoint &p) const
The QTabBar class provides a tab bar, e.g.
Qt::TextElideMode elideMode
how to elide text in the tab bar
void setUsesScrollButtons(bool useButtons)
void setTabsClosable(bool closable)
virtual QSize minimumTabSizeHint(int index) const
Returns the minimum tab size hint for the tab at position index.
void setTabButton(int index, ButtonPosition position, QWidget *widget)
Sets widget on the tab index.
bool movable
This property holds whether the user can move the tabs within the tabbar area.
void paintEvent(QPaintEvent *) override
\reimp
void setSelectionBehaviorOnRemove(SelectionBehavior behavior)
int count
the number of tabs in the tab bar
int currentIndex
the index of the tab bar's visible tab
bool event(QEvent *) override
\reimp
void setShape(Shape shape)
QSize sizeHint() const override
\reimp
QString tabText(int index) const
Returns the text of the tab at position index, or an empty string if index is out of range.
void setTabData(int index, const QVariant &data)
Sets the data of the tab at position index to data.
void mousePressEvent(QMouseEvent *) override
\reimp
bool drawBase
defines whether or not tab bar should draw its base.
virtual void tabRemoved(int index)
This virtual handler is called after a tab was removed from position index.
void setCurrentIndex(int index)
void setTabText(int index, const QString &text)
Sets the text of the tab at position index to text.
void currentChanged(int index)
This signal is emitted when the tab bar's current tab changes.
virtual void initStyleOption(QStyleOptionTab *option, int tabIndex) const
Initialize option with the values from the tab at tabIndex.
bool expanding
When expanding is true QTabBar will expand the tabs to use the empty space.
void removeTab(int index)
Removes the tab at position index.
void tabBarDoubleClicked(int index)
This signal is emitted when the user double clicks on a tab at index.
void setDocumentMode(bool set)
bool usesScrollButtons
Whether or not a tab bar should use buttons to scroll tabs when it has many tabs.
QIcon tabIcon(int index) const
Returns the icon of the tab at position index, or a null icon if index is out of range.
void setIconSize(const QSize &size)
QVariant tabData(int index) const
Returns the data of the tab at position index, or a null variant if index is out of range.
void setAutoHide(bool hide)
void showEvent(QShowEvent *) override
\reimp
void mouseReleaseEvent(QMouseEvent *) override
\reimp
void mouseDoubleClickEvent(QMouseEvent *) override
\reimp
void hideEvent(QHideEvent *) override
\reimp
void resizeEvent(QResizeEvent *) override
\reimp
void setTabVisible(int index, bool visible)
If visible is true, make the tab at position index visible, otherwise make it hidden.
bool isTabEnabled(int index) const
Returns true if the tab at position index is enabled; otherwise returns false.
~QTabBar()
Destroys the tab bar.
void timerEvent(QTimerEvent *event) override
\reimp
QColor tabTextColor(int index) const
Returns the text color of the tab with the given index, or a invalid color if index is out of range.
void mouseMoveEvent(QMouseEvent *) override
\reimp
void setTabIcon(int index, const QIcon &icon)
Sets the icon of the tab at position index to icon.
virtual void tabInserted(int index)
This virtual handler is called after a new tab was added or inserted at position index.
void setTabEnabled(int index, bool enabled)
If enabled is true then the tab at position index is enabled; otherwise the item at position index is...
void tabMoved(int from, int to)
void keyPressEvent(QKeyEvent *) override
\reimp
void setDrawBase(bool drawTheBase)
QSize iconSize
The size for icons in the tab bar.
QRect tabRect(int index) const
Returns the visual rectangle of the tab at position index, or a null rectangle if index is hidden,...
Shape shape
the shape of the tabs in the tab bar
void moveTab(int from, int to)
Moves the item at index position from to index position to.
SelectionBehavior selectionBehaviorOnRemove
What tab should be set as current when removeTab is called if the removed tab is also the current tab...
bool autoHide
If true, the tab bar is automatically hidden when it contains less than 2 tabs.
void setMovable(bool movable)
int insertTab(int index, const QString &text)
Inserts a new tab with text text at position index.
void setTabTextColor(int index, const QColor &color)
Sets the color of the text in the tab with the given index to the specified color.
int tabAt(const QPoint &pos) const
bool changeCurrentOnDrag
If true, then the current tab is automatically changed when dragging over the tabbar.
int addTab(const QString &text)
Adds a new tab with text text.
QTabBar(QWidget *parent=nullptr)
Creates a new tab bar with the given parent.
void setElideMode(Qt::TextElideMode mode)
QWidget * tabButton(int index, ButtonPosition position) const
Returns the widget set a tab index and position or \nullptr if one is not set.
void tabBarClicked(int index)
This signal is emitted when user clicks on a tab at an index.
bool documentMode
Whether or not the tab bar is rendered in a mode suitable for the main window.
void changeEvent(QEvent *) override
\reimp
Shape
This enum type lists the built-in shapes supported by QTabBar.
bool isTabVisible(int index) const
Returns true if the tab at position index is visible; otherwise returns false.
void setExpanding(bool enabled)
virtual void tabLayoutChange()
This virtual handler is called whenever the tab layout changes.
QSize minimumSizeHint() const override
\reimp
virtual QSize tabSizeHint(int index) const
Returns the size hint for the tab at position index.
void setChangeCurrentOnDrag(bool change)
bool tabsClosable
Whether or not a tab bar should place close buttons on each tab.
int toInt(bool *ok=nullptr) const
Returns the variant as an int if the variant has userType() \l QMetaType::Int, \l QMetaType::Bool,...
static void showText(const QPoint &pos, const QString &text, QWidget *w=nullptr)
Shows text as a "What's This?" window, at global position pos.
QSet< QString >::iterator it
void newState(QList< State > &states, const char *token, const char *lexem, bool pre)
Combined button and popup list for selecting options.
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return DBusMessage void
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction function
void qGeomCalc(QList< QLayoutStruct > &chain, int start, int count, int pos, int space, int spacer)
constexpr const T & qMin(const T &a, const T &b)
constexpr const T & qBound(const T &min, const T &val, const T &max)
constexpr const T & qMax(const T &a, const T &b)
constexpr T qAbs(const T &t)
static bool contains(const QJsonArray &haystack, unsigned needle)
GLint GLint GLint GLint GLint x
[0]
GLint GLsizei GLsizei height
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum GLuint GLenum GLsizei length
GLenum GLenum GLsizei const GLuint GLboolean enabled
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum GLuint GLintptr offset
GLdouble GLdouble GLdouble GLdouble q
decorationRoleName setToolTip
static qreal position(const QQuickItem *item, QQuickAnchors::Anchor anchorLine)
static QString computeElidedText(Qt::TextElideMode mode, const QString &text)
#define ANIMATION_DURATION
constexpr bool verticalTabs(QTabBar::Shape shape) noexcept
settings remove("monkey")
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent