711 lines
28 KiB
QML
711 lines
28 KiB
QML
import QtQuick 2.15
|
|
import QtQuick.Layouts 1.15
|
|
import QtQuick.Templates 2.15 as T
|
|
import DelegateUI 1.0
|
|
|
|
Item {
|
|
id: control
|
|
clip: true
|
|
|
|
enum TabPosition
|
|
{
|
|
Position_Top = 0,
|
|
Position_Bottom = 1,
|
|
Position_Left = 2,
|
|
Position_Right = 3
|
|
}
|
|
|
|
enum TabType
|
|
{
|
|
Type_Default = 0,
|
|
Type_Card = 1,
|
|
Type_CardEditable = 2
|
|
}
|
|
|
|
enum TabSize
|
|
{
|
|
Size_Auto = 0,
|
|
Size_Fixed = 1
|
|
}
|
|
|
|
property bool animationEnabled: DelTheme.animationEnabled
|
|
property var initModel: []
|
|
property alias count: __tabModel.count
|
|
property alias currentIndex: __tabView.currentIndex
|
|
property int tabType: DelTabView.Type_Default
|
|
property int tabSize: DelTabView.Size_Auto
|
|
property int tabPosition: DelTabView.Position_Top
|
|
property bool tabCentered: false
|
|
property bool tabCardMovable: true
|
|
property int defaultTabWidth: 80
|
|
property int defaultTabHeight: DelTheme.DelTabView.fontSize + 16
|
|
property int defaultTabSpacing: 2
|
|
property int defaultTabBgRadius: DelTheme.DelTabView.radiusTabBg
|
|
property int defaultHighlightWidth: __private.isHorizontal ? 30 : 20
|
|
property var addTabCallback:
|
|
() => {
|
|
append({ title: `New Tab ${__tabView.count + 1}` });
|
|
positionViewAtEnd();
|
|
}
|
|
property Component addButtonDelegate: DelCaptionButton {
|
|
id: __addButton
|
|
iconSize: DelTheme.DelTabView.fontSize
|
|
iconSource: DelIcon.PlusOutlined
|
|
colorIcon: DelTheme.DelTabView.colorTabCloseHover
|
|
background: Rectangle {
|
|
radius: DelTheme.DelTabView.radiusButton
|
|
color: __addButton.colorBg
|
|
}
|
|
onClicked: addTabCallback();
|
|
}
|
|
property Component tabDelegate: tabType == DelTabView.Type_Default ? __defaultTabDelegate : __cardTabDelegate
|
|
property Component contentDelegate: Item { }
|
|
property Component highlightDelegate: Item {
|
|
Loader {
|
|
id: __highlight
|
|
width: __private.isHorizontal ? defaultHighlightWidth : 2
|
|
height: __private.isHorizontal ? 2 : defaultHighlightWidth
|
|
anchors {
|
|
bottom: control.tabPosition == DelTabView.Position_Top ? parent.bottom : undefined
|
|
right: control.tabPosition == DelTabView.Position_Left ? parent.right : undefined
|
|
}
|
|
state: __content.state
|
|
states: [
|
|
State {
|
|
name: "top"
|
|
AnchorChanges {
|
|
target: __highlight
|
|
anchors.top: undefined
|
|
anchors.bottom: parent.bottom
|
|
anchors.left: undefined
|
|
anchors.right: undefined
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
anchors.verticalCenter: undefined
|
|
}
|
|
},
|
|
State {
|
|
name: "bottom"
|
|
AnchorChanges {
|
|
target: __highlight
|
|
anchors.top: parent.top
|
|
anchors.bottom: undefined
|
|
anchors.left: undefined
|
|
anchors.right: undefined
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
anchors.verticalCenter: undefined
|
|
}
|
|
},
|
|
State {
|
|
name: "left"
|
|
AnchorChanges {
|
|
target: __highlight
|
|
anchors.top: undefined
|
|
anchors.bottom: undefined
|
|
anchors.left: undefined
|
|
anchors.right: parent.right
|
|
anchors.horizontalCenter: undefined
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
}
|
|
},
|
|
State {
|
|
name: "right"
|
|
AnchorChanges {
|
|
target: __highlight
|
|
anchors.top: undefined
|
|
anchors.bottom: undefined
|
|
anchors.left: parent.left
|
|
anchors.right: undefined
|
|
anchors.horizontalCenter: undefined
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
}
|
|
}
|
|
]
|
|
active: control.tabType === DelTabView.Type_Default
|
|
sourceComponent: Rectangle {
|
|
color: DelTheme.isDark ? DelTheme.DelTabView.colorHightlightDark : DelTheme.DelTabView.colorHightlight
|
|
}
|
|
}
|
|
}
|
|
|
|
onInitModelChanged: {
|
|
clear();
|
|
for (const object of initModel) {
|
|
append(object);
|
|
}
|
|
}
|
|
|
|
function flick(xVelocity: real, yVelocity: real) {
|
|
__tabView.flick(xVelocity, yVelocity);
|
|
}
|
|
|
|
function positionViewAtBeginning() {
|
|
__tabView.positionViewAtBeginning();
|
|
}
|
|
|
|
function positionViewAtIndex(index, mode) {
|
|
__tabView.positionViewAtIndex(index, mode);
|
|
}
|
|
|
|
function positionViewAtEnd() {
|
|
__tabView.positionViewAtEnd();
|
|
}
|
|
|
|
function get(index) {
|
|
return __tabModel.get(index);
|
|
}
|
|
|
|
function set(index, object) {
|
|
//默认为true
|
|
if (object.editable === undefined)
|
|
object.editable = true;
|
|
__tabModel.set(index, object);
|
|
}
|
|
|
|
function setProperty(index, propertyName, value) {
|
|
__tabModel.setProperty(index, propertyName, value);
|
|
}
|
|
|
|
function move(from, to, count = 1) {
|
|
__tabModel.move(from, to, count);
|
|
}
|
|
|
|
function insert(index, object) {
|
|
//默认为true
|
|
if (object.editable === undefined)
|
|
object.editable = true;
|
|
__tabModel.insert(index, object);
|
|
}
|
|
|
|
function append(object) {
|
|
//默认为true
|
|
if (object.editable === undefined)
|
|
object.editable = true;
|
|
__tabModel.append(object);
|
|
}
|
|
|
|
function remove(index, count = 1) {
|
|
__tabModel.remove(index, count);
|
|
}
|
|
|
|
function clear() {
|
|
__tabModel.clear();
|
|
}
|
|
|
|
Component {
|
|
id: __defaultTabDelegate
|
|
|
|
DelIconButton {
|
|
id: __tabItem
|
|
width: (!__private.isHorizontal && control.tabSize == DelTabView.Size_Auto) ? Math.max(__private.tabMaxWidth, tabWidth) : tabWidth
|
|
height: tabHeight
|
|
leftPadding: 5
|
|
rightPadding: 5
|
|
iconSize: tabIconSize
|
|
iconSource: tabIcon
|
|
text: tabTitle
|
|
effectEnabled: false
|
|
colorBg: "transparent"
|
|
colorBorder: "transparent"
|
|
colorText: {
|
|
if (isCurrent) {
|
|
return DelTheme.isDark ? DelTheme.DelTabView.colorHightlightDark : DelTheme.DelTabView.colorHightlight;
|
|
} else {
|
|
return down ? DelTheme.DelTabView.colorTabActive :
|
|
hovered ? DelTheme.DelTabView.colorTabHover :
|
|
DelTheme.DelTabView.colorTab;
|
|
}
|
|
}
|
|
font {
|
|
family: DelTheme.DelTabView.fontFamily
|
|
pixelSize: DelTheme.DelTabView.fontSize
|
|
}
|
|
contentItem: Item {
|
|
implicitWidth: control.tabSize == DelTabView.Size_Auto ? (__text.width + calcIconWidth) : __tabItem.tabFixedWidth
|
|
implicitHeight: Math.max(__icon.implicitHeight, __text.implicitHeight)
|
|
|
|
property int calcIconWidth: iconSource == 0 ? 0 : (__icon.implicitWidth + __tabItem.tabIconSpacing)
|
|
|
|
DelIconText {
|
|
id: __icon
|
|
width: iconSource == 0 ? 0 : implicitWidth
|
|
anchors.left: parent.left
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
color: __tabItem.colorIcon
|
|
iconSize: __tabItem.iconSize
|
|
iconSource: __tabItem.iconSource
|
|
verticalAlignment: Text.AlignVCenter
|
|
|
|
Behavior on color { enabled: control.animationEnabled; ColorAnimation { duration: DelTheme.Primary.durationFast } }
|
|
}
|
|
|
|
Text {
|
|
id: __text
|
|
width: control.tabSize == DelTabView.Size_Auto ? implicitWidth :
|
|
Math.max(0, __tabItem.tabFixedWidth - 5 - parent.calcIconWidth)
|
|
anchors.left: __icon.right
|
|
anchors.leftMargin: __icon.iconSource == 0 ? 0 : __tabItem.tabIconSpacing
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
text: __tabItem.text
|
|
font: __tabItem.font
|
|
color: __tabItem.colorText
|
|
elide: Text.ElideRight
|
|
|
|
Behavior on color { enabled: control.animationEnabled; ColorAnimation { duration: DelTheme.Primary.durationFast } }
|
|
}
|
|
}
|
|
onTabWidthChanged: {
|
|
if (index == 0)
|
|
__private.tabMaxWidth = 0;
|
|
__private.tabMaxWidth = Math.max(__private.tabMaxWidth, __tabItem.tabWidth);
|
|
}
|
|
onClicked: __tabView.currentIndex = index;
|
|
|
|
required property int index
|
|
required property var model
|
|
property alias modelData: __tabItem.model
|
|
property bool isCurrent: __tabView.currentIndex === index
|
|
property string tabKey: modelData.key || ""
|
|
property int tabIcon: modelData.icon || 0
|
|
property int tabIconSize: modelData.iconSize || DelTheme.DelTabView.fontSize
|
|
property int tabIconSpacing: modelData.iconSpacing || 5
|
|
property string tabTitle: modelData.title || ""
|
|
property int tabFixedWidth: modelData.tabWidth || defaultTabWidth
|
|
property int tabWidth: control.tabSize == DelTabView.Size_Auto ? (implicitContentWidth + leftPadding + rightPadding) :
|
|
implicitContentWidth
|
|
property int tabHeight: modelData.tabHeight || defaultTabHeight
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: __cardTabDelegate
|
|
|
|
Item {
|
|
id: __tabContainer
|
|
width: __tabItem.width
|
|
height: __tabItem.height
|
|
|
|
required property int index
|
|
required property var model
|
|
property alias modelData: __tabContainer.model
|
|
property alias tabItem: __tabItem
|
|
property bool isCurrent: __tabView.currentIndex === index
|
|
property string tabKey: modelData.key || ""
|
|
property int tabIcon: modelData.icon || 0
|
|
property int tabIconSize: modelData.iconSize || DelTheme.DelTabView.fontSize
|
|
property int tabIconSpacing: modelData.iconSpacing || 5
|
|
property string tabTitle: modelData.title || ""
|
|
property int tabFixedWidth: modelData.tabWidth || defaultTabWidth
|
|
property int tabWidth: __tabItem.calcWidth
|
|
property int tabHeight: modelData.tabHeight || defaultTabHeight
|
|
|
|
property bool tabEditable: modelData.editable && control.tabType == DelTabView.Type_CardEditable
|
|
|
|
onTabWidthChanged: {
|
|
if (__private.needResetTabMaxWidth) {
|
|
__private.needResetTabMaxWidth = false;
|
|
__private.tabMaxWidth = 0;
|
|
}
|
|
__private.tabMaxWidth = Math.max(__private.tabMaxWidth, __tabItem.calcWidth);
|
|
}
|
|
|
|
DelRectangle {
|
|
id: __tabItem
|
|
width: (!__private.isHorizontal && control.tabSize == DelTabView.Size_Auto) ? Math.max(__private.tabMaxWidth, tabWidth) : tabWidth
|
|
height: tabHeight
|
|
z: __dragHandler.drag.active ? 1 : 0
|
|
color: {
|
|
if (DelTheme.isDark)
|
|
return isCurrent ? DelTheme.DelTabView.colorTabCardBgCheckedDark : DelTheme.DelTabView.colorTabCardBgDark;
|
|
else
|
|
return isCurrent ? DelTheme.DelTabView.colorTabCardBgChecked : DelTheme.DelTabView.colorTabCardBg;
|
|
}
|
|
border.color: DelTheme.DelTabView.colorTabCardBorder
|
|
topLeftRadius: control.tabPosition == DelTabView.Position_Top || control.tabPosition == DelTabView.Position_Left ? defaultTabBgRadius : 0
|
|
topRightRadius: control.tabPosition == DelTabView.Position_Top || control.tabPosition == DelTabView.Position_Right ? defaultTabBgRadius : 0
|
|
bottomLeftRadius: control.tabPosition == DelTabView.Position_Bottom || control.tabPosition == DelTabView.Position_Left ? defaultTabBgRadius : 0
|
|
bottomRightRadius: control.tabPosition == DelTabView.Position_Bottom || control.tabPosition == DelTabView.Position_Right ? defaultTabBgRadius : 0
|
|
|
|
property int calcIconWidth: __icon.iconSource == 0 ? 0 : (__icon.implicitWidth + __tabContainer.tabIconSpacing)
|
|
property int calcCloseWidth: __close.visible ? (__close.implicitWidth + 5) : 0
|
|
property real calcWidth: control.tabSize == DelTabView.Size_Auto ? (__text.width + calcIconWidth + calcCloseWidth + 10)
|
|
: __tabContainer.tabFixedWidth
|
|
property real calcHeight: Math.max(__icon.implicitHeight, __text.implicitHeight, __close.height)
|
|
property color colorText: {
|
|
if (isCurrent) {
|
|
return DelTheme.isDark ? DelTheme.DelTabView.colorHightlightDark : DelTheme.DelTabView.colorHightlight;
|
|
} else {
|
|
return down ? DelTheme.DelTabView.colorTabActive :
|
|
hovered ? DelTheme.DelTabView.colorTabHover :
|
|
DelTheme.DelTabView.colorTab;
|
|
}
|
|
}
|
|
property bool down: false
|
|
property bool hovered: false
|
|
|
|
Behavior on color { enabled: control.animationEnabled; ColorAnimation { duration: DelTheme.Primary.durationMid } }
|
|
|
|
MouseArea {
|
|
id: __dragHandler
|
|
anchors.fill: parent
|
|
hoverEnabled: true
|
|
drag.target: control.tabCardMovable ? __tabItem : null
|
|
drag.axis: __private.isHorizontal ? Drag.XAxis : Drag.YAxis
|
|
onEntered: __tabItem.hovered = true;
|
|
onExited: __tabItem.hovered = false;
|
|
onClicked: __tabView.currentIndex = index;
|
|
onPressed:
|
|
(mouse) => {
|
|
__tabView.currentIndex = index;
|
|
__tabItem.down = true;
|
|
|
|
if (control.tabCardMovable) {
|
|
const pos = __tabView.mapFromItem(__tabContainer, 0, 0);
|
|
__tabItem.parent = __tabView;
|
|
__tabItem.x = pos.x;
|
|
__tabItem.y = pos.y;
|
|
}
|
|
}
|
|
onPositionChanged: move();
|
|
onReleased: {
|
|
__keepMovingTimer.stop();
|
|
__tabItem.down = false;
|
|
__tabItem.parent = __tabContainer;
|
|
__tabItem.x = __tabItem.y = 0;
|
|
__tabView.forceLayout();
|
|
}
|
|
|
|
function move() {
|
|
if (pressed && control.tabCardMovable) {
|
|
if (!__keepMovingTimer.running)
|
|
__keepMovingTimer.restart();
|
|
const pos = __tabView.mapFromItem(__tabItem, width * 0.5, height * 0.5);
|
|
const item = __tabView.itemAt(pos.x + __tabView.contentX + 1, pos.y + __tabView.contentY + 1);
|
|
if (item) {
|
|
if (item.index !== __tabContainer.index) {
|
|
__tabModel.move(item.index, __tabContainer.index, 1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Timer {
|
|
id: __keepMovingTimer
|
|
repeat: true
|
|
interval: 100
|
|
onTriggered: __dragHandler.move();
|
|
}
|
|
}
|
|
|
|
DelIconText {
|
|
id: __icon
|
|
anchors.left: parent.left
|
|
anchors.leftMargin: 5
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
color: __tabItem.colorText
|
|
iconSize: tabIconSize
|
|
iconSource: tabIcon
|
|
verticalAlignment: Text.AlignVCenter
|
|
|
|
Behavior on color { enabled: control.animationEnabled; ColorAnimation { duration: DelTheme.Primary.durationFast } }
|
|
}
|
|
|
|
Text {
|
|
id: __text
|
|
width: control.tabSize == DelTabView.Size_Auto ? implicitWidth :
|
|
Math.max(0, __tabContainer.tabFixedWidth - 5 - __tabItem.calcIconWidth - __tabItem.calcCloseWidth)
|
|
anchors.left: __icon.right
|
|
anchors.leftMargin: __icon.iconSource == 0 ? 0 : __tabContainer.tabIconSpacing
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
text: tabTitle
|
|
font {
|
|
family: DelTheme.DelTabView.fontFamily
|
|
pixelSize: DelTheme.DelTabView.fontSize
|
|
}
|
|
color: __tabItem.colorText
|
|
elide: Text.ElideRight
|
|
|
|
Behavior on color { enabled: control.animationEnabled; ColorAnimation { duration: DelTheme.Primary.durationFast } }
|
|
}
|
|
|
|
DelCaptionButton {
|
|
id: __close
|
|
visible: __tabContainer.tabEditable
|
|
enabled: visible
|
|
implicitWidth: visible ? (implicitContentWidth + leftPadding + rightPadding) : 0
|
|
topPadding: 0
|
|
bottomPadding: 0
|
|
leftPadding: 2
|
|
rightPadding: 2
|
|
anchors.right: parent.right
|
|
anchors.rightMargin: 5
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
iconSize: tabIconSize
|
|
iconSource: DelIcon.CloseOutlined
|
|
colorIcon: hovered ? DelTheme.DelTabView.colorTabCloseHover : DelTheme.DelTabView.colorTabClose
|
|
onClicked: {
|
|
control.remove(index);
|
|
}
|
|
|
|
HoverHandler {
|
|
cursorShape: Qt.PointingHandCursor
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Connections {
|
|
target: control
|
|
function onTabTypeChanged() {
|
|
__private.needResetTabMaxWidth = true;
|
|
}
|
|
function onTabSizeChanged() {
|
|
__private.needResetTabMaxWidth = true;
|
|
}
|
|
}
|
|
|
|
QtObject {
|
|
id: __private
|
|
property bool isHorizontal: control.tabPosition == DelTabView.Position_Top || control.tabPosition == DelTabView.Position_Bottom
|
|
property int tabMaxWidth: 0
|
|
property bool needResetTabMaxWidth: false
|
|
}
|
|
|
|
MouseArea {
|
|
anchors.fill: __tabView
|
|
onWheel:
|
|
(wheel) => {
|
|
if (__private.isHorizontal)
|
|
__tabView.flick(wheel.angleDelta.y * 6.5, 0);
|
|
else
|
|
__tabView.flick(0, wheel.angleDelta.y * 6.5);
|
|
}
|
|
}
|
|
|
|
ListView {
|
|
id: __tabView
|
|
width: {
|
|
if (__private.isHorizontal) {
|
|
const maxWidth = control.width - (__addButtonLoader.width + 5) * (control.tabCentered ? 2 : 1);
|
|
return (control.tabCentered ? Math.min(contentWidth, maxWidth) : maxWidth);
|
|
} else {
|
|
return __private.tabMaxWidth;
|
|
}
|
|
}
|
|
height: {
|
|
if (__private.isHorizontal) {
|
|
return defaultTabHeight;
|
|
} else {
|
|
const maxHeight = control.height - (__addButtonLoader.height + 5) * (control.tabCentered ? 2 : 1);
|
|
return (control.tabCentered ? Math.min(contentHeight, maxHeight) : maxHeight)
|
|
}
|
|
}
|
|
clip: true
|
|
onContentWidthChanged: if (__private.isHorizontal) cacheBuffer = contentWidth;
|
|
onContentHeightChanged: if (!__private.isHorizontal) cacheBuffer = contentHeight;
|
|
spacing: defaultTabSpacing
|
|
move: Transition {
|
|
NumberAnimation { properties: "x,y"; duration: control.animationEnabled ? DelTheme.Primary.durationMid : 0 }
|
|
}
|
|
model: ListModel { id: __tabModel }
|
|
delegate: tabDelegate
|
|
highlight: highlightDelegate
|
|
highlightMoveDuration: control.animationEnabled ? DelTheme.Primary.durationMid : 0
|
|
orientation: __private.isHorizontal ? Qt.Horizontal : Qt.Vertical
|
|
boundsBehavior: Flickable.StopAtBounds
|
|
state: control.tabCentered ? (__content.state + "Center") : __content.state
|
|
states: [
|
|
State {
|
|
name: "top"
|
|
AnchorChanges {
|
|
target: __tabView
|
|
anchors.top: control.top
|
|
anchors.bottom: undefined
|
|
anchors.left: control.left
|
|
anchors.right: undefined
|
|
anchors.horizontalCenter: undefined
|
|
anchors.verticalCenter: undefined
|
|
}
|
|
},
|
|
State {
|
|
name: "topCenter"
|
|
AnchorChanges {
|
|
target: __tabView
|
|
anchors.top: control.top
|
|
anchors.bottom: undefined
|
|
anchors.left: undefined
|
|
anchors.right: undefined
|
|
anchors.horizontalCenter: control.horizontalCenter
|
|
anchors.verticalCenter: undefined
|
|
}
|
|
},
|
|
State {
|
|
name: "bottom"
|
|
AnchorChanges {
|
|
target: __tabView
|
|
anchors.top: undefined
|
|
anchors.bottom: control.bottom
|
|
anchors.left: control.left
|
|
anchors.right: undefined
|
|
anchors.horizontalCenter: undefined
|
|
anchors.verticalCenter: undefined
|
|
}
|
|
},
|
|
State {
|
|
name: "bottomCenter"
|
|
AnchorChanges {
|
|
target: __tabView
|
|
anchors.top: undefined
|
|
anchors.bottom: control.bottom
|
|
anchors.left: undefined
|
|
anchors.right: undefined
|
|
anchors.horizontalCenter: control.horizontalCenter
|
|
anchors.verticalCenter: undefined
|
|
}
|
|
},
|
|
State {
|
|
name: "left"
|
|
AnchorChanges {
|
|
target: __tabView
|
|
anchors.top: control.top
|
|
anchors.bottom: undefined
|
|
anchors.left: control.left
|
|
anchors.right: undefined
|
|
anchors.horizontalCenter: undefined
|
|
anchors.verticalCenter: undefined
|
|
}
|
|
},
|
|
State {
|
|
name: "leftCenter"
|
|
AnchorChanges {
|
|
target: __tabView
|
|
anchors.top: undefined
|
|
anchors.bottom: undefined
|
|
anchors.left: control.left
|
|
anchors.right: undefined
|
|
anchors.horizontalCenter: undefined
|
|
anchors.verticalCenter: control.verticalCenter
|
|
}
|
|
},
|
|
State {
|
|
name: "right"
|
|
AnchorChanges {
|
|
target: __tabView
|
|
anchors.top: control.top
|
|
anchors.bottom: undefined
|
|
anchors.left: undefined
|
|
anchors.right: control.right
|
|
anchors.horizontalCenter: undefined
|
|
anchors.verticalCenter: undefined
|
|
}
|
|
},
|
|
State {
|
|
name: "rightCenter"
|
|
AnchorChanges {
|
|
target: __tabView
|
|
anchors.top: undefined
|
|
anchors.bottom: undefined
|
|
anchors.left: undefined
|
|
anchors.right: control.right
|
|
anchors.horizontalCenter: undefined
|
|
anchors.verticalCenter: control.verticalCenter
|
|
}
|
|
}
|
|
]
|
|
}
|
|
|
|
Loader {
|
|
id: __addButtonLoader
|
|
x: {
|
|
switch (tabPosition) {
|
|
case DelTabView.Position_Top:
|
|
case DelTabView.Position_Bottom:
|
|
return Math.min(__tabView.x + __tabView.contentWidth + 5, control.width - width);
|
|
case DelTabView.Position_Left:
|
|
return Math.max(0, __tabView.width - width);
|
|
case DelTabView.Position_Right:
|
|
return Math.max(0, __tabView.x);
|
|
}
|
|
}
|
|
y: {
|
|
switch (tabPosition) {
|
|
case DelTabView.Position_Top:
|
|
return Math.max(0, __tabView.y + __tabView.height - height);
|
|
case DelTabView.Position_Bottom:
|
|
return __tabView.y;
|
|
case DelTabView.Position_Left:
|
|
case DelTabView.Position_Right:
|
|
return Math.min(__tabView.y + __tabView.contentHeight + 5, control.height - height);
|
|
}
|
|
}
|
|
z: 10
|
|
sourceComponent: addButtonDelegate
|
|
}
|
|
|
|
Item {
|
|
id: __content
|
|
state: {
|
|
switch (tabPosition) {
|
|
case DelTabView.Position_Top: return "top";
|
|
case DelTabView.Position_Bottom: return "bottom";
|
|
case DelTabView.Position_Left: return "left";
|
|
case DelTabView.Position_Right: return "right";
|
|
}
|
|
}
|
|
states: [
|
|
State {
|
|
name: "top"
|
|
AnchorChanges {
|
|
target: __content
|
|
anchors.top: __tabView.bottom
|
|
anchors.bottom: control.bottom
|
|
anchors.left: control.left
|
|
anchors.right: control.right
|
|
}
|
|
},
|
|
State {
|
|
name: "bottom"
|
|
AnchorChanges {
|
|
target: __content
|
|
anchors.top: control.top
|
|
anchors.bottom: __tabView.top
|
|
anchors.left: control.left
|
|
anchors.right: control.right
|
|
}
|
|
},
|
|
State {
|
|
name: "left"
|
|
AnchorChanges {
|
|
target: __content
|
|
anchors.top: control.top
|
|
anchors.bottom: control.bottom
|
|
anchors.left: __tabView.right
|
|
anchors.right: control.right
|
|
}
|
|
},
|
|
State {
|
|
name: "right"
|
|
AnchorChanges {
|
|
target: __content
|
|
anchors.top: control.top
|
|
anchors.bottom: control.bottom
|
|
anchors.left: control.left
|
|
anchors.right: __tabView.left
|
|
}
|
|
}
|
|
]
|
|
|
|
Repeater {
|
|
model: __tabModel
|
|
delegate: Loader {
|
|
id: __contentLoader
|
|
anchors.fill: parent
|
|
sourceComponent: contentDelegate
|
|
visible: __tabView.currentIndex === index
|
|
required property int index
|
|
required property var model
|
|
}
|
|
}
|
|
}
|
|
}
|