import QtQuick import QtQuick.Templates as QQCT import QtQuick.Window import Weave.Controls import Weave.Templates as T T.TabButton { id: root spacing: style === TabBar.Underline ? Theme.component.tab.underline.marginRight : Theme.component.tab.box.paddingRight // TODO: Theme.component.tab.box.marginRight ? leftPadding: style === TabBar.Underline ? mirrored ? Theme.component.tab.underline.paddingRight : Theme.component.tab.underline.paddingLeft : mirrored ? (Theme.component.tab.box.paddingRight + (style === TabBar.Box && dividerVisible ? Theme.component.divider.borderWidth : _triangleWidth)) : Theme.component.tab.box.paddingLeft rightPadding: style === TabBar.Underline ? mirrored ? Theme.component.tab.underline.paddingLeft : Theme.component.tab.underline.paddingRight : mirrored ? Theme.component.tab.box.paddingLeft : (Theme.component.tab.box.paddingRight + (style === TabBar.Box && dividerVisible ? Theme.component.divider.borderWidth : _triangleWidth)) leftInset: mirrored && style === TabBar.Canvas ? _triangleWidth : mirrored && style === TabBar.Box && dividerVisible ? Theme.component.divider.borderWidth : 0 rightInset: !mirrored && style === TabBar.Canvas ? _triangleWidth : !mirrored && style === TabBar.Box && dividerVisible ? Theme.component.divider.borderWidth : 0 bottomPadding: style === TabBar.Underline ? Theme.component.tab.underline.paddingBottom : Theme.component.tab.box.paddingBottom topPadding: style === TabBar.Underline ? Theme.component.tab.underline.paddingTop : Theme.component.tab.box.paddingTop width: (_weave_tabbar && (_weave_tabbar.accentEdge === TabBar.LeftEdge || _weave_tabbar.accentEdge === TabBar.RightEdge)) ? _weave_tabbar.width : (_weave_tabbar && _weave_tabbar.fullWidth) ? _weave_tabbar.width / _weave_tabbar.count : implicitWidth implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, implicitContentWidth + leftPadding + rightPadding) implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, implicitContentHeight + topPadding + bottomPadding) font.family: Theme.component.tab.fontFamily font.pixelSize: Theme.component.tab.fontSize font.weight: _isSelectedDelegate ? Theme.component.tab.fontWeight.selected : Theme.component.tab.fontWeight.default icon.color: style === TabBar.Canvas ? root.hovered ? Theme.component.tablist.canvas.icon.fillColor.hover : Theme.component.tablist.canvas.icon.fillColor.default : Theme.component.tab.icon.fill icon.width: Theme.component.tab.icon.width icon.height: Theme.component.tab.icon.height style: _weave_tabbar ? _weave_tabbar.style : TabBar.Underline accentEdge: _weave_tabbar ? _weave_tabbar.accentEdge : style === TabBar.Underline ? TabBar.BottomEdge : TabBar.TopEdge dividerVisible: _weave_tabbar && _weave_tabbar.dividerVisible && ((QQCT.TabBar.index < _weave_tabbar.count - 1) || (root.style === TabBar.Canvas && _weave_tabbar.addTabButtonVisible)) property bool _hideDivider: !dividerVisible || (_weave_tabbar && (_weave_tabbar.currentIndex === QQCT.TabBar.index || _weave_tabbar.currentIndex === (QQCT.TabBar.index + 1))) property QQCT.TabBar _weave_tabbar: QQCT.TabBar.tabBar property bool _isFirstDelegate: QQCT.TabBar.index === 0 property bool _isSelectedDelegate: _weave_tabbar && _weave_tabbar.currentIndex === QQCT.TabBar.index property real _triangleWidth: style === TabBar.Canvas && background ? Math.round(background.height * Theme.autodeskAngleTan) : 0 hoverEnabled: root.enabled onHoveredChanged: { if (_weave_tabbar) { if (hovered) { _weave_tabbar.hoveredIndex = QQCT.TabBar.index } else if (_weave_tabbar.hoveredIndex === QQCT.TabBar.index) { _weave_tabbar.hoveredIndex = -1 } } } contentItem: Item { id: content readonly property real iconPadding: iconImage.visible && iconImage.status === Image.Ready ? iconImage.width + (root.text.length ? root.spacing : 0) : 0 readonly property real closePadding: root.closeButton.visible ? root.closeButton.implicitContentWidth + root.spacing : 0 implicitWidth: iconPadding + selectedText.implicitWidth + closePadding implicitHeight: Math.max(selectedText.implicitHeight, iconImage.visible ? iconImage.implicitHeight : 0) opacity: root.enabled ? 1.0 : Theme.component.tab.opacity.disabled Text { id: label x: (content.mirrored ? content.closePadding : content.iconPadding) + Math.max(0, (content.width - width - content.iconPadding - content.closePadding) / 2) width: Math.min(selectedText.implicitWidth, content.width - content.iconPadding - content.closePadding) height: parent.height text: root.text font: root.checked ? selectedText.font : root.font color: Theme.component.tab.textColor elide: Text.ElideRight horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter } Text { // Used for implicit size calculation only. Selected text is bolder and therefore // potentially wider and we don't want the buttons to resize when you change tabs. id: selectedText text: root.text font.family: root.font.family font.pixelSize: root.font.pixelSize font.weight: Theme.component.tab.fontWeight.selected visible: false } T.IconImage { id: iconImage visible: style !== TabBar.Underline anchors.verticalCenter: label.verticalCenter x: root.text.length ? root.mirrored ? label.x + label.width + root.spacing : label.x - width - root.spacing : (content.width - width - content.closePadding)/2 color: root.icon.color name: root.icon.name url: root.icon.source sourceSize: Qt.size(root.icon.width, root.icon.height) } } background: Item { id: bgItem opacity: root.enabled ? 1.0 : Theme.component.tab.opacity.disabled Item { id: canvasClip clip: root.style === TabBar.Canvas && root._isFirstDelegate anchors { fill: parent leftMargin: root._isFirstDelegate ? 0 : -root._triangleWidth rightMargin: -root._triangleWidth } Rectangle { id: canvasRect visible: root.style === TabBar.Canvas x: root._isFirstDelegate ? -root._triangleWidth : 0 width: bgItem.width + root._triangleWidth height: bgItem.height color: (root.enabled && root.hovered) ? Theme.component.tablist.canvas.backgroundColor.hover : (root._isSelectedDelegate || root.pressed) ? Theme.component.tablist.canvas.backgroundColor.selected : Theme.component.tab.box.backgroundColor.default // TODO: Theme.component.tablist.canvas.backgroundColor.default transform: Matrix4x4 { matrix: Qt.matrix4x4( 1, root.style === TabBar.Canvas ? -Theme.autodeskAngleTan : 0, 0, root._triangleWidth, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) } } Rectangle { id: bgRect visible: !canvasRect.visible width: bgItem.width height: bgItem.height color: root.style === TabBar.Box ? (root.enabled && root.hovered) ? Theme.component.tab.box.backgroundColor.hover : (root._isSelectedDelegate || root.pressed) ? Theme.component.tab.box.backgroundColor.selected : (root.visualFocus || root.closeButton.visualFocus) ? Theme.component.tab.box.backgroundColor.focus : Theme.component.tab.box.backgroundColor.default : Theme.component.tab.underline.backgroundColor } } Rectangle { id: focusRect visible: root.style !== TabBar.Canvas && (root.visualFocus || root.closeButton.visualFocus) width: root.style === TabBar.Underline || (root.accentEdge === TabBar.TopEdge || root.accentEdge === TabBar.BottomEdge) ? parent.width : Theme.component.tab.box.orientationVertical.borderLeftWidth.focus height: root.style === TabBar.Underline ? Theme.component.tab.underline.boxShadowY.focus : (root.accentEdge === TabBar.TopEdge || root.accentEdge === TabBar.BottomEdge) ? Theme.component.tab.box.orientationHorizontal.borderTopWidth.focus : parent.height y: (root.style === TabBar.Underline || root.accentEdge === TabBar.BottomEdge) ? parent.height - height : 0 x: (root.style === TabBar.Underline || root.accentEdge !== TabBar.RightEdge) ? 0 : (parent.width - width) color: root.style === TabBar.Underline ? Theme.component.tab.underline.boxShadowColor.focus : (root.accentEdge === TabBar.TopEdge || root.accentEdge === TabBar.BottomEdge) ? Theme.component.tab.box.orientationHorizontal.borderTopColor.focus : Theme.component.tab.box.orientationVertical.borderLeftColor.focus } Rectangle { id: indicatorRect readonly property bool hovered: root.enabled && (root.hovered || root.closeButton.hovered || root.pressed || root.closeButton.pressed) visible: root.style === TabBar.Underline && (hovered || root.checked) width: parent.width height: hovered ? Theme.component.tab.underline.borderWidth.hover : Theme.component.tab.underline.borderWidth.selected y: parent.height - focusRect.height - height color: hovered ? Theme.component.tab.underline.borderColor.hover : Theme.component.tab.underline.borderColor.selected } Rectangle { id: boxDividerRect anchors.verticalCenter: parent.verticalCenter x: parent.width visible: root.style === TabBar.Box && !root._hideDivider height: Theme.component.tab.box.divider.height width: Theme.component.divider.borderWidth color: Theme.component.tab.box.divider.backgroundColor } Image { id: boxAngledDividerRect x: parent.width + Math.floor(width/2) // Align to pixel boundary anchors.verticalCenter: parent.verticalCenter visible: root.style === TabBar.Canvas && !root._hideDivider // Because the image provider returns a texture which is scaled properly // for the device pixel ratio (in order to ensure smooth rendering), // we CANNOT use the implicit width and height (because it won't be // in device-independent-pixels but rather in device-dependent-pixels). // Thus, specify width and height in device-independent-pixels directly. // TODO: remove these three lines for Qt 6.5 - see QTBUG-100355. height: sourceSize.height width: sourceSize.width fillMode: Image.PreserveAspectFit // Add one stroke-width of padding on each edge of the texture for antialiasing. // Specify all of these values in device independent pixels. property real strokeWidth: Theme.component.divider.borderWidth sourceSize.height: (Theme.autodeskAngleCos * Theme.component.tab.box.divider.height) + 2*strokeWidth sourceSize.width: (Theme.autodeskAngleTan * Theme.autodeskAngleCos * Theme.component.tab.box.divider.height) + 2*strokeWidth source: "image://weave-angledivider/slash?color=" + Theme.component.tablist.canvas.divider.backgroundColor + "&strokeWidth=" + strokeWidth * Screen.devicePixelRatio // Provide the prescaled device dependent value + "&scale=" + Screen.devicePixelRatio } } closeButton { x: mirrored ? leftPadding : (width - closeButton.width - rightPadding) y: topPadding + ((availableHeight - closeButton.height) / 2) implicitWidth: Theme.component.tab.closeButton.icon.width implicitHeight: Theme.component.tab.closeButton.icon.height contentItem: T.IconImage { name: Theme.icon.small("close") color: root.closeButton.pressed ? Theme.component.iconbutton.icon.fill.pressed : ((root.closeButton.enabled && root.closeButton.hovered) || root.closeButton.visualFocus) ? Theme.component.iconbutton.icon.fill.hover : Theme.component.iconbutton.icon.fill.default horizontalAlignment: Image.AlignHCenter verticalAlignment: Image.AlignVCenter } } }