summaryrefslogtreecommitdiffstats
path: root/src/widgets
diff options
context:
space:
mode:
authorAxel Spoerl <axel.spoerl@qt.io>2023-04-18 10:02:33 +0200
committerAxel Spoerl <axel.spoerl@qt.io>2023-04-20 16:02:42 +0200
commitd4b40fa96bcb83eb8948c381bdae9c1ed0f223d0 (patch)
tree4fa339c0de03911085fc2aba97131074543866e3 /src/widgets
parent3d0fb2cea9c4e392497f9067d21b194124de9333 (diff)
QTabBar: draw text within moving tab
When a tab was moved by dragging, the tab's rectangle was drawn empty, without the tab text. When a tab was moved by animated snap back to its original position, the tab text was already drawn on the original position, while the rectangle was still moving due to animation. Adds the enum value QStyleOptionTab::TabPosition::Moving When this option is set, QCommonStyle draws the tab text at the current position instead of the original home position of the tab. The QMacStyle switches over the TabPosition enum. As a moving tab is laid out like the last tab in the given orientation, the enum value Moving is treated like End. Fixes: QTBUG-112277 Change-Id: I42a2d9c269dadfe9819c12dbc69e3ae995a45b09 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Diffstat (limited to 'src/widgets')
-rw-r--r--src/widgets/styles/qcommonstyle.cpp5
-rw-r--r--src/widgets/styles/qstyleoption.cpp2
-rw-r--r--src/widgets/styles/qstyleoption.h2
-rw-r--r--src/widgets/widgets/qtabbar.cpp27
4 files changed, 25 insertions, 11 deletions
diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp
index 5736538443..08c2224092 100644
--- a/src/widgets/styles/qcommonstyle.cpp
+++ b/src/widgets/styles/qcommonstyle.cpp
@@ -2009,7 +2009,10 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt,
}
QRect iconRect;
d->tabLayout(tab, widget, &tr, &iconRect);
- tr = proxy()->subElementRect(SE_TabBarTabText, opt, widget); //we compute tr twice because the style may override subElementRect
+
+ // compute tr again, unless tab is moving, because the style may override subElementRect
+ if (tab->position != QStyleOptionTab::TabPosition::Moving)
+ tr = proxy()->subElementRect(SE_TabBarTabText, opt, widget);
if (!tab->icon.isNull()) {
QPixmap tabIcon = tab->icon.pixmap(tab->iconSize, p->device()->devicePixelRatio(),
diff --git a/src/widgets/styles/qstyleoption.cpp b/src/widgets/styles/qstyleoption.cpp
index de7cd482a3..73164918bb 100644
--- a/src/widgets/styles/qstyleoption.cpp
+++ b/src/widgets/styles/qstyleoption.cpp
@@ -1314,6 +1314,8 @@ QStyleOptionTab::QStyleOptionTab(int version)
\value Middle The tab is neither the first nor the last tab in the tab bar.
\value End The tab is the last tab in the tab bar.
\value OnlyOneTab The tab is both the first and the last tab in the tab bar.
+ \value Moving The tab is moving by mouse drag or animation.
+ This enum value was added in Qt 6.6.
\sa position
*/
diff --git a/src/widgets/styles/qstyleoption.h b/src/widgets/styles/qstyleoption.h
index 6841a81b84..0e0118f6e9 100644
--- a/src/widgets/styles/qstyleoption.h
+++ b/src/widgets/styles/qstyleoption.h
@@ -244,7 +244,7 @@ public:
enum StyleOptionType { Type = SO_Tab };
enum StyleOptionVersion { Version = 1 };
- enum TabPosition { Beginning, Middle, End, OnlyOneTab };
+ enum TabPosition { Beginning, Middle, End, OnlyOneTab, Moving };
enum SelectedPosition { NotAdjacent, NextIsSelected, PreviousIsSelected };
enum CornerWidget { NoCornerWidgets = 0x00, LeftCornerWidget = 0x01,
RightCornerWidget = 0x02 };
diff --git a/src/widgets/widgets/qtabbar.cpp b/src/widgets/widgets/qtabbar.cpp
index 1b64301fa6..74e94cac4a 100644
--- a/src/widgets/widgets/qtabbar.cpp
+++ b/src/widgets/widgets/qtabbar.cpp
@@ -1873,21 +1873,30 @@ void QTabBar::paintEvent(QPaintEvent *)
QStyleOptionTab tabOption;
const auto tab = d->tabList.at(selected);
initStyleOption(&tabOption, selected);
+
if (d->paintWithOffsets && tab->dragOffset != 0) {
+ // if the drag offset is != 0, a move is in progress (drag or animation)
+ // => set the tab position to Moving to preserve the rect
+ tabOption.position = QStyleOptionTab::TabPosition::Moving;
+
if (vertical)
tabOption.rect.moveTop(tabOption.rect.y() + tab->dragOffset);
else
tabOption.rect.moveLeft(tabOption.rect.x() + tab->dragOffset);
}
- if (!d->dragInProgress)
- p.drawControl(QStyle::CE_TabBarTab, tabOption);
- else {
- int taboverlap = style()->pixelMetric(QStyle::PM_TabBarTabOverlap, nullptr, this);
- if (verticalTabs(d->shape))
- d->movingTab->setGeometry(tabOption.rect.adjusted(0, -taboverlap, 0, taboverlap));
- else
- d->movingTab->setGeometry(tabOption.rect.adjusted(-taboverlap, 0, taboverlap, 0));
- }
+
+ // Calculate the rect of a moving tab
+ const int taboverlap = style()->pixelMetric(QStyle::PM_TabBarTabOverlap, nullptr, this);
+ const QRect &movingRect = verticalTabs(d->shape)
+ ? tabOption.rect.adjusted(0, -taboverlap, 0, taboverlap)
+ : tabOption.rect.adjusted(-taboverlap, 0, taboverlap, 0);
+
+ // If a drag is in process, set the moving tab's geometry here
+ // (in an animation, it is already set)
+ if (d->dragInProgress)
+ d->movingTab->setGeometry(movingRect);
+
+ p.drawControl(QStyle::CE_TabBarTab, tabOption);
}
// Only draw the tear indicator if necessary. Most of the time we don't need too.