54 Q_DECLARE_PUBLIC(QTabBar)
57 : layoutDirty(
false), drawBase(
true), elideModeSetByUser(
false), useScrollButtons(
false),
58 useScrollButtonsSetByUser(
false), expanding(
true), closeButtonOnTabs(
false),
59 paintWithOffsets(
true), movable(
false), dragInProgress(
false), documentMode(
false),
60 autoHide(
false), changeCurrentOnDrag(
false)
68 QPoint dragStartPosition;
69 QPoint mousePosition = {-1, -1};
70#if QT_CONFIG(wheelevent)
71 QPoint accumulatedAngleDelta;
74 QToolButton* rightB =
nullptr;
75 QToolButton* leftB =
nullptr;
76 QMovableTabWidget *movingTab =
nullptr;
78 int switchTabCurrentIndex = -1;
79 QBasicTimer switchTabTimer;
80 Qt::TextElideMode elideMode = Qt::ElideNone;
81 QTabBar::SelectionBehavior selectionBehaviorOnRemove = QTabBar::SelectRightTab;
82 QTabBar::Shape shape = QTabBar::RoundedNorth;
83 Qt::MouseButtons mouseButtons = Qt::NoButton;
85 int currentIndex = -1;
86 int pressedIndex = -1;
93 bool elideModeSetByUser : 1;
94 bool useScrollButtons : 1;
95 bool useScrollButtonsSetByUser : 1;
97 bool closeButtonOnTabs : 1;
98 bool paintWithOffsets : 1;
100 bool dragInProgress : 1;
101 bool documentMode : 1;
103 bool changeCurrentOnDrag : 1;
106 inline Tab(
const QIcon &ico,
const QString &txt)
107 : text(txt), icon(ico), enabled(
true), visible(
true), measuringMinimum(
false)
111
112
113
114 Q_DISABLE_COPY_MOVE(Tab);
117#if QT_CONFIG(tooltip)
120#if QT_CONFIG(whatsthis)
123#if QT_CONFIG(accessibility)
124 QString accessibleName;
133 QWidget *leftWidget =
nullptr;
134 QWidget *rightWidget =
nullptr;
140 uint measuringMinimum : 1;
142#if QT_CONFIG(animation)
143 struct TabBarAnimation :
public QVariantAnimation {
144 TabBarAnimation(Tab *t, QTabBarPrivate *_priv) : tab(t), priv(_priv)
145 { setEasingCurve(QEasingCurve::InOutQuad); }
147 void updateCurrentValue(
const QVariant ¤t) override;
149 void updateState(State newState, State) override;
153 QTabBarPrivate *priv;
155 std::unique_ptr<TabBarAnimation> animation;
157 void startAnimation(QTabBarPrivate *priv,
int duration) {
158 if (!priv->isAnimated()) {
159 priv->moveTabFinished(priv->tabList.indexOf(
this));
163 animation = std::make_unique<TabBarAnimation>(
this, priv);
164 animation->setStartValue(dragOffset);
165 animation->setEndValue(0);
166 animation->setDuration(duration);
170 void startAnimation(QTabBarPrivate *priv,
int duration)
171 { Q_UNUSED(duration); priv->moveTabFinished(priv->tabList.indexOf(
this)); }
175 mutable QHash<QString, QSize> textSizes;
177 void calculateFirstLastVisible(
int index,
bool visible,
bool remove);
178 int selectNewCurrentIndexFrom(
int currentIndex);
179 int calculateNewPosition(
int from,
int to,
int index)
const;
180 void slide(
int from,
int to);
183 inline Tab *at(
int index) {
return tabList.value(index,
nullptr); }
184 inline const Tab *at(
int index)
const {
return tabList.value(index,
nullptr); }
186 int indexAtPos(
const QPoint &p)
const;
188 inline bool isAnimated()
const { Q_Q(
const QTabBar);
return q->style()->styleHint(QStyle::SH_Widget_Animation_Duration,
nullptr, q) > 0; }
189 inline bool validIndex(
int index)
const {
return index >= 0 && index < tabList.size(); }
190 void setCurrentNextEnabledIndex(
int offset);
194 void moveTab(
int index,
int offset);
195 void moveTabFinished(
int index);
199 void layoutWidgets(
int start = 0);
200 void layoutTab(
int index);
201 void updateMacBorderMetrics();
202 bool isTabInMacUnifiedToolbarArea()
const;
203 void setupMovableTab();
205 QRect normalizedScrollRect(
int index = -1);
206 int hoveredTabIndex()
const;
208 void initBasicStyleOption(QStyleOptionTab *option,
int tabIndex)
const;
210 void makeVisible(
int index);
211 const Tab *lastVisibleTab()
const
213 auto it = std::find_if(tabList.rbegin(), tabList.rend(),
214 [](
const Tab *tab) {
return tab->visible; });
215 return it == tabList.rend() ?
nullptr : *it;
219 static void initStyleBaseOption(QStyleOptionTabBarBase *optTabBase, QTabBar *tabbar, QSize size)
221 QStyleOptionTab tabOverlap;
222 tabOverlap.shape = tabbar->shape();
223 int overlap = tabbar->style()->pixelMetric(QStyle::PM_TabBarBaseOverlap, &tabOverlap, tabbar);
224 QWidget *theParent = tabbar->parentWidget();
225 optTabBase->initFrom(tabbar);
226 optTabBase->shape = tabbar->shape();
227 optTabBase->documentMode = tabbar->documentMode();
228 if (theParent && overlap > 0) {
230 switch (tabOverlap.shape) {
231 case QTabBar::RoundedNorth:
232 case QTabBar::TriangularNorth:
233 rect.setRect(0, size.height()-overlap, size.width(), overlap);
235 case QTabBar::RoundedSouth:
236 case QTabBar::TriangularSouth:
237 rect.setRect(0, 0, size.width(), overlap);
239 case QTabBar::RoundedEast:
240 case QTabBar::TriangularEast:
241 rect.setRect(0, 0, overlap, size.height());
243 case QTabBar::RoundedWest:
244 case QTabBar::TriangularWest:
245 rect.setRect(size.width() - overlap, 0, overlap, size.height());
248 optTabBase->rect = rect;
252 void killSwitchTabTimer();