mirror of
https://github.com/zhuzichu520/FluentUI.git
synced 2025-03-31 03:08:37 +08:00
feat: FluCarousel支持纵向轮播
This commit is contained in:
parent
9ac58a8ca7
commit
8377fb5227
@ -1123,6 +1123,11 @@ Updated content:
|
||||
<source>Carousel map, support infinite carousel, infinite swipe, and components implemented with ListView</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_Carousel.qml" line="203"/>
|
||||
<source>Auto play</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>T_CheckBox</name>
|
||||
|
@ -1142,12 +1142,17 @@ Updated content:
|
||||
<message>
|
||||
<location filename="qml/page/T_Carousel.qml" line="10"/>
|
||||
<source>Carousel</source>
|
||||
<translation type="unfinished">轮播图</translation>
|
||||
<translation>轮播图</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_Carousel.qml" line="36"/>
|
||||
<source>Carousel map, support infinite carousel, infinite swipe, and components implemented with ListView</source>
|
||||
<translation type="unfinished">轮播图,支持无限轮播,无限滑动,用ListView实现的组件</translation>
|
||||
<translation>轮播图,支持无限轮播,无限滑动,用ListView实现的组件</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_Carousel.qml" line="203"/>
|
||||
<source>Auto play</source>
|
||||
<translation>自动轮播</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
@ -121,7 +121,6 @@ FluScrollablePage{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
CodeExpander{
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: -6
|
||||
@ -140,6 +139,90 @@ FluScrollablePage{
|
||||
Component.onCompleted: {
|
||||
carousel.model = [{url:"qrc:/example/res/image/banner_1.jpg"},{url:"qrc:/example/res/image/banner_2.jpg"},{url:"qrc:/example/res/image/banner_3.jpg"}]
|
||||
}
|
||||
}'
|
||||
}
|
||||
|
||||
FluFrame{
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 300 + topPadding + bottomPadding
|
||||
padding: 10
|
||||
Layout.topMargin: 10
|
||||
RowLayout{
|
||||
anchors.fill: parent
|
||||
Item{
|
||||
Layout.preferredWidth: 400
|
||||
Layout.fillHeight: true
|
||||
FluShadow{
|
||||
radius: 8
|
||||
}
|
||||
FluCarousel{
|
||||
anchors.fill: parent
|
||||
orientation: Qt.Vertical
|
||||
autoPlay: auto_play_switch.checked
|
||||
loopTime:1500
|
||||
indicatorGravity: Qt.AlignVCenter | Qt.AlignRight
|
||||
indicatorMarginTop:15
|
||||
delegate: Component{
|
||||
Item{
|
||||
anchors.fill: parent
|
||||
Image {
|
||||
anchors.fill: parent
|
||||
source: model.url
|
||||
asynchronous: true
|
||||
fillMode:Image.PreserveAspectCrop
|
||||
}
|
||||
Rectangle{
|
||||
height: 40
|
||||
width: parent.width
|
||||
anchors.bottom: parent.bottom
|
||||
color: "#33000000"
|
||||
FluText{
|
||||
anchors.fill: parent
|
||||
verticalAlignment: Qt.AlignVCenter
|
||||
horizontalAlignment: Qt.AlignHCenter
|
||||
text:model.title
|
||||
color: FluColors.Grey10
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Layout.topMargin: 20
|
||||
Layout.leftMargin: 5
|
||||
Component.onCompleted: {
|
||||
var arr = []
|
||||
arr.push({url:"qrc:/example/res/image/banner_1.jpg",title:"共同应对全球性问题"})
|
||||
arr.push({url:"qrc:/example/res/image/banner_2.jpg",title:"三小只全程没互动"})
|
||||
arr.push({url:"qrc:/example/res/image/banner_3.jpg",title:"有效投资扩大 激发增长动能"})
|
||||
model = arr
|
||||
}
|
||||
}
|
||||
}
|
||||
FluToggleSwitch{
|
||||
id: auto_play_switch
|
||||
Layout.alignment: Qt.AlignRight
|
||||
text: qsTr("Auto play")
|
||||
}
|
||||
}
|
||||
}
|
||||
CodeExpander{
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: -6
|
||||
code:'FluCarousel{
|
||||
id:carousel
|
||||
width: 400
|
||||
height: 300
|
||||
orientation: Qt.Vertical
|
||||
delegate: Component{
|
||||
Image {
|
||||
anchors.fill: parent
|
||||
source: model.url
|
||||
asynchronous: true
|
||||
fillMode:Image.PreserveAspectCrop
|
||||
}
|
||||
}
|
||||
Component.onCompleted: {
|
||||
carousel.model = [{url:"qrc:/example/res/image/banner_1.jpg"},{url:"qrc:/example/res/image/banner_2.jpg"},{url:"qrc:/example/res/image/banner_3.jpg"}]
|
||||
}
|
||||
}'
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import FluentUI 1.0
|
||||
|
||||
Item {
|
||||
property bool autoPlay: true
|
||||
property int orientation: Qt.Horizontal
|
||||
property int loopTime: 2000
|
||||
property var model
|
||||
property Component delegate
|
||||
@ -14,7 +15,7 @@ Item {
|
||||
property int indicatorMarginTop: 0
|
||||
property int indicatorMarginBottom: 20
|
||||
property int indicatorSpacing: 10
|
||||
property alias indicatorAnchors: layout_indicator.anchors
|
||||
property alias indicatorAnchors: indicator_loader.anchors
|
||||
property Component indicatorDelegate : com_indicator
|
||||
id:control
|
||||
width: 400
|
||||
@ -24,13 +25,24 @@ Item {
|
||||
}
|
||||
QtObject{
|
||||
id:d
|
||||
property bool flagXChanged: false
|
||||
property bool isManualMoving: false
|
||||
property bool isAnimEnable: control.autoPlay && list_view.count>3
|
||||
onIsAnimEnableChanged: {
|
||||
if(isAnimEnable){
|
||||
timer_run.restart()
|
||||
}else{
|
||||
timer_run.stop()
|
||||
}
|
||||
}
|
||||
function setData(data){
|
||||
if(!data){
|
||||
if(!data || !Array.isArray(data)){
|
||||
return
|
||||
}
|
||||
content_model.clear()
|
||||
list_view.resetPos()
|
||||
if(data.length === 0){
|
||||
return
|
||||
}
|
||||
content_model.append(data[data.length-1])
|
||||
content_model.append(data)
|
||||
content_model.append(data[0])
|
||||
@ -49,7 +61,7 @@ Item {
|
||||
clip: true
|
||||
boundsBehavior: ListView.StopAtBounds
|
||||
model:content_model
|
||||
maximumFlickVelocity: 4 * (list_view.orientation === Qt.Horizontal ? width : height)
|
||||
maximumFlickVelocity: 4 * (control.orientation === Qt.Vertical ? height : width)
|
||||
preferredHighlightBegin: 0
|
||||
preferredHighlightEnd: 0
|
||||
highlightMoveDuration: 0
|
||||
@ -63,7 +75,7 @@ Item {
|
||||
d.setData(control.model)
|
||||
}
|
||||
}
|
||||
orientation : ListView.Horizontal
|
||||
orientation : control.orientation
|
||||
delegate: Item{
|
||||
id:item_control
|
||||
width: ListView.view.width
|
||||
@ -88,34 +100,63 @@ Item {
|
||||
}
|
||||
}
|
||||
onMovementEnded:{
|
||||
d.flagXChanged = false
|
||||
d.isManualMoving = false
|
||||
list_view.highlightMoveDuration = 0
|
||||
currentIndex = list_view.contentX/list_view.width
|
||||
if(currentIndex === 0){
|
||||
currentIndex = list_view.count-2
|
||||
}else if(currentIndex === list_view.count-1){
|
||||
currentIndex = 1
|
||||
if(control.orientation === Qt.Vertical){
|
||||
currentIndex = (list_view.contentY - list_view.originY) / list_view.height
|
||||
if(currentIndex === 0){
|
||||
currentIndex = list_view.count - 2
|
||||
}else if(currentIndex === list_view.count - 1) {
|
||||
currentIndex = 1
|
||||
}
|
||||
} else {
|
||||
currentIndex = (list_view.contentX - list_view.originX) / list_view.width
|
||||
if(currentIndex === 0){
|
||||
currentIndex = list_view.count - 2
|
||||
}else if(currentIndex === list_view.count - 1){
|
||||
currentIndex = 1
|
||||
}
|
||||
}
|
||||
if(d.isAnimEnable){
|
||||
timer_run.restart()
|
||||
}
|
||||
}
|
||||
onMovementStarted: {
|
||||
d.flagXChanged = true
|
||||
d.isManualMoving = true
|
||||
timer_run.stop()
|
||||
}
|
||||
onContentXChanged: {
|
||||
if(d.flagXChanged){
|
||||
var maxX = Math.min(list_view.width*(currentIndex+1),list_view.count*list_view.width)
|
||||
var minX = Math.max(0,(list_view.width*(currentIndex-1)))
|
||||
if(contentX>=maxX){
|
||||
contentX = maxX
|
||||
if(d.isManualMoving && control.orientation === Qt.Horizontal){
|
||||
const range = getPosRange(list_view.width, currentIndex)
|
||||
if(contentX >= range.max){
|
||||
contentX = range.max
|
||||
}
|
||||
if(contentX<=minX){
|
||||
contentX = minX
|
||||
if(contentX <= range.min){
|
||||
contentX = range.min
|
||||
}
|
||||
}
|
||||
}
|
||||
onContentYChanged: {
|
||||
if(d.isManualMoving && control.orientation === Qt.Vertical){
|
||||
const range = getPosRange(list_view.height, currentIndex)
|
||||
if(contentY >= range.max){
|
||||
contentY = range.max
|
||||
}
|
||||
if(contentY <= range.min){
|
||||
contentY = range.min
|
||||
}
|
||||
}
|
||||
}
|
||||
function resetPos() {
|
||||
contentX = 0
|
||||
contentY = 0
|
||||
}
|
||||
function getPosRange(size, index) {
|
||||
return {
|
||||
"min": Math.max(0, size * (index - 1)),
|
||||
"max": Math.min(size * (index + 1), list_view.count * size)
|
||||
}
|
||||
}
|
||||
}
|
||||
Component{
|
||||
id:com_indicator
|
||||
@ -140,9 +181,9 @@ Item {
|
||||
}
|
||||
}
|
||||
}
|
||||
Row{
|
||||
id:layout_indicator
|
||||
spacing: control.indicatorSpacing
|
||||
|
||||
Loader{
|
||||
id: indicator_loader
|
||||
anchors{
|
||||
horizontalCenter:(indicatorGravity & Qt.AlignHCenter) ? parent.horizontalCenter : undefined
|
||||
verticalCenter: (indicatorGravity & Qt.AlignVCenter) ? parent.verticalCenter : undefined
|
||||
@ -155,28 +196,66 @@ Item {
|
||||
rightMargin: control.indicatorMarginBottom
|
||||
topMargin: control.indicatorMarginBottom
|
||||
}
|
||||
visible: showIndicator
|
||||
Repeater{
|
||||
id:repeater_indicator
|
||||
model: list_view.count
|
||||
FluLoader{
|
||||
property int displayIndex: {
|
||||
if(index === 0)
|
||||
return list_view.count-3
|
||||
if(index === list_view.count-1)
|
||||
return 0
|
||||
return index-1
|
||||
}
|
||||
property int realIndex: index
|
||||
property bool checked: list_view.currentIndex === index
|
||||
sourceComponent: {
|
||||
if(index===0 || index===list_view.count-1)
|
||||
return undefined
|
||||
return control.indicatorDelegate
|
||||
active: showIndicator
|
||||
sourceComponent: control.orientation === Qt.Vertical ? column_indicator : row_indicator
|
||||
}
|
||||
|
||||
Component{
|
||||
id: row_indicator
|
||||
Row{
|
||||
id:layout_indicator
|
||||
spacing: control.indicatorSpacing
|
||||
Repeater{
|
||||
id:repeater_indicator
|
||||
model: list_view.count
|
||||
FluLoader{
|
||||
property int displayIndex: {
|
||||
if(index === 0)
|
||||
return list_view.count-3
|
||||
if(index === list_view.count-1)
|
||||
return 0
|
||||
return index-1
|
||||
}
|
||||
property int realIndex: index
|
||||
property bool checked: list_view.currentIndex === index
|
||||
sourceComponent: {
|
||||
if(index===0 || index===list_view.count-1)
|
||||
return undefined
|
||||
return control.indicatorDelegate
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component{
|
||||
id: column_indicator
|
||||
Column{
|
||||
id:layout_indicator
|
||||
spacing: control.indicatorSpacing
|
||||
Repeater{
|
||||
id:repeater_indicator
|
||||
model: list_view.count
|
||||
FluLoader{
|
||||
property int displayIndex: {
|
||||
if(index === 0)
|
||||
return list_view.count-3
|
||||
if(index === list_view.count-1)
|
||||
return 0
|
||||
return index-1
|
||||
}
|
||||
property int realIndex: index
|
||||
property bool checked: list_view.currentIndex === index
|
||||
sourceComponent: {
|
||||
if(index===0 || index===list_view.count-1)
|
||||
return undefined
|
||||
return control.indicatorDelegate
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Timer{
|
||||
id:timer_anim
|
||||
interval: 250
|
||||
@ -198,10 +277,10 @@ Item {
|
||||
}
|
||||
}
|
||||
function changedIndex(index){
|
||||
d.flagXChanged = true
|
||||
d.isManualMoving = true
|
||||
timer_run.stop()
|
||||
list_view.currentIndex = index
|
||||
d.flagXChanged = false
|
||||
d.isManualMoving = false
|
||||
if(d.isAnimEnable){
|
||||
timer_run.restart()
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import QtQuick.tooling 1.2
|
||||
// It is used for QML tooling purposes only.
|
||||
//
|
||||
// This file was auto-generated by:
|
||||
// 'qmlplugindump -nonrelocatable -noinstantiate FluentUI 1.0 F:/FluentUI/build/Desktop_Qt_5_15_2_MSVC2019_32bit-Release/src'
|
||||
// 'qmlplugindump -nonrelocatable -noinstantiate FluentUI 1.0 E:/develop/QtCode/opensource/FluentUI/build/Desktop_Qt_5_15_2_MinGW_64_bit-Release/src'
|
||||
|
||||
Module {
|
||||
dependencies: ["QtQuick 2.0"]
|
||||
@ -2776,7 +2776,7 @@ Module {
|
||||
}
|
||||
Property {
|
||||
name: "layoutMacosButtons"
|
||||
type: "FluLoader_QMLTYPE_11"
|
||||
type: "FluLoader_QMLTYPE_14"
|
||||
isReadonly: true
|
||||
isPointer: true
|
||||
}
|
||||
@ -2898,6 +2898,7 @@ Module {
|
||||
isComposite: true
|
||||
defaultProperty: "data"
|
||||
Property { name: "autoPlay"; type: "bool" }
|
||||
Property { name: "orientation"; type: "int" }
|
||||
Property { name: "loopTime"; type: "int" }
|
||||
Property { name: "model"; type: "QVariant" }
|
||||
Property { name: "delegate"; type: "QQmlComponent"; isPointer: true }
|
||||
@ -2955,12 +2956,12 @@ Module {
|
||||
Property { name: "checkedDisableColor"; type: "QColor" }
|
||||
Property { name: "disableColor"; type: "QColor" }
|
||||
Property { name: "size"; type: "double" }
|
||||
Property { name: "textColor"; type: "QColor" }
|
||||
Property { name: "textRight"; type: "bool" }
|
||||
Property { name: "textSpacing"; type: "double" }
|
||||
Property { name: "animationEnabled"; type: "bool" }
|
||||
Property { name: "clickListener"; type: "QVariant" }
|
||||
Property { name: "indeterminate"; type: "bool" }
|
||||
Property { name: "textColor"; type: "QColor" }
|
||||
}
|
||||
Component {
|
||||
prototype: "FluRectangle"
|
||||
@ -3189,6 +3190,8 @@ Module {
|
||||
isComposite: true
|
||||
defaultProperty: "content"
|
||||
Property { name: "headerText"; type: "string" }
|
||||
Property { name: "headerHeight"; type: "int" }
|
||||
Property { name: "headerDelegate"; type: "QQmlComponent"; isPointer: true }
|
||||
Property { name: "expand"; type: "bool" }
|
||||
Property { name: "contentHeight"; type: "int" }
|
||||
Property { name: "content"; type: "QObject"; isList: true; isReadonly: true }
|
||||
@ -3469,15 +3472,15 @@ Module {
|
||||
defaultProperty: "data"
|
||||
Property { name: "logo"; type: "QUrl" }
|
||||
Property { name: "title"; type: "string" }
|
||||
Property { name: "items"; type: "FluObject_QMLTYPE_176"; isPointer: true }
|
||||
Property { name: "footerItems"; type: "FluObject_QMLTYPE_176"; isPointer: true }
|
||||
Property { name: "items"; type: "FluObject_QMLTYPE_182"; isPointer: true }
|
||||
Property { name: "footerItems"; type: "FluObject_QMLTYPE_182"; isPointer: true }
|
||||
Property { name: "displayMode"; type: "int" }
|
||||
Property { name: "autoSuggestBox"; type: "QQmlComponent"; isPointer: true }
|
||||
Property { name: "actionItem"; type: "QQmlComponent"; isPointer: true }
|
||||
Property { name: "topPadding"; type: "int" }
|
||||
Property { name: "pageMode"; type: "int" }
|
||||
Property { name: "navItemRightMenu"; type: "FluMenu_QMLTYPE_48"; isPointer: true }
|
||||
Property { name: "navItemExpanderRightMenu"; type: "FluMenu_QMLTYPE_48"; isPointer: true }
|
||||
Property { name: "navItemRightMenu"; type: "FluMenu_QMLTYPE_47"; isPointer: true }
|
||||
Property { name: "navItemExpanderRightMenu"; type: "FluMenu_QMLTYPE_47"; isPointer: true }
|
||||
Property { name: "navCompactWidth"; type: "int" }
|
||||
Property { name: "navTopMargin"; type: "int" }
|
||||
Property { name: "cellHeight"; type: "int" }
|
||||
@ -3676,6 +3679,7 @@ Module {
|
||||
exportMetaObjectRevisions: [0]
|
||||
isComposite: true
|
||||
defaultProperty: "content"
|
||||
Property { name: "textHighlightColor"; type: "QColor" }
|
||||
Property { name: "textNormalColor"; type: "QColor" }
|
||||
Property { name: "textHoverColor"; type: "QColor" }
|
||||
Property { name: "textSpacing"; type: "int" }
|
||||
@ -3772,11 +3776,11 @@ Module {
|
||||
Property { name: "normalColor"; type: "QColor" }
|
||||
Property { name: "hoverColor"; type: "QColor" }
|
||||
Property { name: "disableColor"; type: "QColor" }
|
||||
Property { name: "textColor"; type: "QColor" }
|
||||
Property { name: "size"; type: "double" }
|
||||
Property { name: "textRight"; type: "bool" }
|
||||
Property { name: "textSpacing"; type: "double" }
|
||||
Property { name: "clickListener"; type: "QVariant" }
|
||||
Property { name: "textColor"; type: "QColor" }
|
||||
}
|
||||
Component {
|
||||
prototype: "QQuickItem"
|
||||
@ -3899,7 +3903,9 @@ Module {
|
||||
exportMetaObjectRevisions: [0]
|
||||
isComposite: true
|
||||
defaultProperty: "content"
|
||||
Property { name: "autoResetScroll"; type: "bool" }
|
||||
Property { name: "content"; type: "QObject"; isList: true; isReadonly: true }
|
||||
Method { name: "resetScroll"; type: "QVariant" }
|
||||
Property { name: "launchMode"; type: "int" }
|
||||
Property { name: "animationEnabled"; type: "bool" }
|
||||
Property { name: "url"; type: "string" }
|
||||
@ -4294,8 +4300,8 @@ Module {
|
||||
Property { name: "dotDisableColor"; type: "QColor" }
|
||||
Property { name: "textSpacing"; type: "double" }
|
||||
Property { name: "textRight"; type: "bool" }
|
||||
Property { name: "clickListener"; type: "QVariant" }
|
||||
Property { name: "textColor"; type: "QColor" }
|
||||
Property { name: "clickListener"; type: "QVariant" }
|
||||
}
|
||||
Component {
|
||||
prototype: "QQuickToolTip"
|
||||
@ -4379,7 +4385,6 @@ Module {
|
||||
Property { name: "fitsAppBarWindows"; type: "bool" }
|
||||
Property { name: "tintOpacity"; type: "QVariant" }
|
||||
Property { name: "blurRadius"; type: "int" }
|
||||
Property { name: "availableEffects"; type: "QVariant"; isReadonly: true }
|
||||
Property { name: "appBar"; type: "QQuickItem"; isPointer: true }
|
||||
Property { name: "backgroundColor"; type: "QColor" }
|
||||
Property { name: "stayTop"; type: "bool" }
|
||||
@ -4403,6 +4408,7 @@ Module {
|
||||
Property { name: "contentData"; type: "QObject"; isList: true; isReadonly: true }
|
||||
Property { name: "effect"; type: "string" }
|
||||
Property { name: "effective"; type: "bool"; isReadonly: true }
|
||||
Property { name: "availableEffects"; type: "QStringList"; isReadonly: true }
|
||||
Signal {
|
||||
name: "initArgument"
|
||||
Parameter { name: "argument"; type: "QVariant" }
|
||||
@ -4485,7 +4491,6 @@ Module {
|
||||
Property { name: "fitsAppBarWindows"; type: "bool" }
|
||||
Property { name: "tintOpacity"; type: "QVariant" }
|
||||
Property { name: "blurRadius"; type: "int" }
|
||||
Property { name: "availableEffects"; type: "QVariant"; isReadonly: true }
|
||||
Property { name: "appBar"; type: "QQuickItem"; isPointer: true }
|
||||
Property { name: "backgroundColor"; type: "QColor" }
|
||||
Property { name: "stayTop"; type: "bool" }
|
||||
@ -4509,6 +4514,7 @@ Module {
|
||||
Property { name: "contentData"; type: "QObject"; isList: true; isReadonly: true }
|
||||
Property { name: "effect"; type: "string" }
|
||||
Property { name: "effective"; type: "bool"; isReadonly: true }
|
||||
Property { name: "availableEffects"; type: "QStringList"; isReadonly: true }
|
||||
Signal {
|
||||
name: "initArgument"
|
||||
Parameter { name: "argument"; type: "QVariant" }
|
||||
|
@ -4,6 +4,7 @@ import FluentUI
|
||||
|
||||
Item {
|
||||
property bool autoPlay: true
|
||||
property int orientation: Qt.Horizontal
|
||||
property int loopTime: 2000
|
||||
property var model
|
||||
property Component delegate
|
||||
@ -14,7 +15,7 @@ Item {
|
||||
property int indicatorMarginTop: 0
|
||||
property int indicatorMarginBottom: 20
|
||||
property int indicatorSpacing: 10
|
||||
property alias indicatorAnchors: layout_indicator.anchors
|
||||
property alias indicatorAnchors: indicator_loader.anchors
|
||||
property Component indicatorDelegate : com_indicator
|
||||
id:control
|
||||
width: 400
|
||||
@ -24,13 +25,24 @@ Item {
|
||||
}
|
||||
QtObject{
|
||||
id:d
|
||||
property bool flagXChanged: false
|
||||
property bool isManualMoving: false
|
||||
property bool isAnimEnable: control.autoPlay && list_view.count>3
|
||||
onIsAnimEnableChanged: {
|
||||
if(isAnimEnable){
|
||||
timer_run.restart()
|
||||
}else{
|
||||
timer_run.stop()
|
||||
}
|
||||
}
|
||||
function setData(data){
|
||||
if(!data){
|
||||
if(!data || !Array.isArray(data)){
|
||||
return
|
||||
}
|
||||
content_model.clear()
|
||||
list_view.resetPos()
|
||||
if(data.length === 0){
|
||||
return
|
||||
}
|
||||
content_model.append(data[data.length-1])
|
||||
content_model.append(data)
|
||||
content_model.append(data[0])
|
||||
@ -49,7 +61,7 @@ Item {
|
||||
clip: true
|
||||
boundsBehavior: ListView.StopAtBounds
|
||||
model:content_model
|
||||
maximumFlickVelocity: 4 * (list_view.orientation === Qt.Horizontal ? width : height)
|
||||
maximumFlickVelocity: 4 * (control.orientation === Qt.Vertical ? height : width)
|
||||
preferredHighlightBegin: 0
|
||||
preferredHighlightEnd: 0
|
||||
highlightMoveDuration: 0
|
||||
@ -63,7 +75,7 @@ Item {
|
||||
d.setData(control.model)
|
||||
}
|
||||
}
|
||||
orientation : ListView.Horizontal
|
||||
orientation : control.orientation
|
||||
delegate: Item{
|
||||
id:item_control
|
||||
width: ListView.view.width
|
||||
@ -88,34 +100,63 @@ Item {
|
||||
}
|
||||
}
|
||||
onMovementEnded:{
|
||||
d.flagXChanged = false
|
||||
d.isManualMoving = false
|
||||
list_view.highlightMoveDuration = 0
|
||||
currentIndex = list_view.contentX/list_view.width
|
||||
if(currentIndex === 0){
|
||||
currentIndex = list_view.count-2
|
||||
}else if(currentIndex === list_view.count-1){
|
||||
currentIndex = 1
|
||||
if(control.orientation === Qt.Vertical){
|
||||
currentIndex = (list_view.contentY - list_view.originY) / list_view.height
|
||||
if(currentIndex === 0){
|
||||
currentIndex = list_view.count - 2
|
||||
}else if(currentIndex === list_view.count - 1) {
|
||||
currentIndex = 1
|
||||
}
|
||||
} else {
|
||||
currentIndex = (list_view.contentX - list_view.originX) / list_view.width
|
||||
if(currentIndex === 0){
|
||||
currentIndex = list_view.count - 2
|
||||
}else if(currentIndex === list_view.count - 1){
|
||||
currentIndex = 1
|
||||
}
|
||||
}
|
||||
if(d.isAnimEnable){
|
||||
timer_run.restart()
|
||||
}
|
||||
}
|
||||
onMovementStarted: {
|
||||
d.flagXChanged = true
|
||||
d.isManualMoving = true
|
||||
timer_run.stop()
|
||||
}
|
||||
onContentXChanged: {
|
||||
if(d.flagXChanged){
|
||||
var maxX = Math.min(list_view.width*(currentIndex+1),list_view.count*list_view.width)
|
||||
var minX = Math.max(0,(list_view.width*(currentIndex-1)))
|
||||
if(contentX>=maxX){
|
||||
contentX = maxX
|
||||
if(d.isManualMoving && control.orientation === Qt.Horizontal){
|
||||
const range = getPosRange(list_view.width, currentIndex)
|
||||
if(contentX >= range.max){
|
||||
contentX = range.max
|
||||
}
|
||||
if(contentX<=minX){
|
||||
contentX = minX
|
||||
if(contentX <= range.min){
|
||||
contentX = range.min
|
||||
}
|
||||
}
|
||||
}
|
||||
onContentYChanged: {
|
||||
if(d.isManualMoving && control.orientation === Qt.Vertical){
|
||||
const range = getPosRange(list_view.height, currentIndex)
|
||||
if(contentY >= range.max){
|
||||
contentY = range.max
|
||||
}
|
||||
if(contentY <= range.min){
|
||||
contentY = range.min
|
||||
}
|
||||
}
|
||||
}
|
||||
function resetPos() {
|
||||
contentX = 0
|
||||
contentY = 0
|
||||
}
|
||||
function getPosRange(size, index) {
|
||||
return {
|
||||
"min": Math.max(0, size * (index - 1)),
|
||||
"max": Math.min(size * (index + 1), list_view.count * size)
|
||||
}
|
||||
}
|
||||
}
|
||||
Component{
|
||||
id:com_indicator
|
||||
@ -140,9 +181,9 @@ Item {
|
||||
}
|
||||
}
|
||||
}
|
||||
Row{
|
||||
id:layout_indicator
|
||||
spacing: control.indicatorSpacing
|
||||
|
||||
Loader{
|
||||
id: indicator_loader
|
||||
anchors{
|
||||
horizontalCenter:(indicatorGravity & Qt.AlignHCenter) ? parent.horizontalCenter : undefined
|
||||
verticalCenter: (indicatorGravity & Qt.AlignVCenter) ? parent.verticalCenter : undefined
|
||||
@ -155,28 +196,66 @@ Item {
|
||||
rightMargin: control.indicatorMarginBottom
|
||||
topMargin: control.indicatorMarginBottom
|
||||
}
|
||||
visible: showIndicator
|
||||
Repeater{
|
||||
id:repeater_indicator
|
||||
model: list_view.count
|
||||
FluLoader{
|
||||
property int displayIndex: {
|
||||
if(index === 0)
|
||||
return list_view.count-3
|
||||
if(index === list_view.count-1)
|
||||
return 0
|
||||
return index-1
|
||||
}
|
||||
property int realIndex: index
|
||||
property bool checked: list_view.currentIndex === index
|
||||
sourceComponent: {
|
||||
if(index===0 || index===list_view.count-1)
|
||||
return undefined
|
||||
return control.indicatorDelegate
|
||||
active: showIndicator
|
||||
sourceComponent: control.orientation === Qt.Vertical ? column_indicator : row_indicator
|
||||
}
|
||||
|
||||
Component{
|
||||
id: row_indicator
|
||||
Row{
|
||||
id:layout_indicator
|
||||
spacing: control.indicatorSpacing
|
||||
Repeater{
|
||||
id:repeater_indicator
|
||||
model: list_view.count
|
||||
FluLoader{
|
||||
property int displayIndex: {
|
||||
if(index === 0)
|
||||
return list_view.count-3
|
||||
if(index === list_view.count-1)
|
||||
return 0
|
||||
return index-1
|
||||
}
|
||||
property int realIndex: index
|
||||
property bool checked: list_view.currentIndex === index
|
||||
sourceComponent: {
|
||||
if(index===0 || index===list_view.count-1)
|
||||
return undefined
|
||||
return control.indicatorDelegate
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component{
|
||||
id: column_indicator
|
||||
Column{
|
||||
id:layout_indicator
|
||||
spacing: control.indicatorSpacing
|
||||
Repeater{
|
||||
id:repeater_indicator
|
||||
model: list_view.count
|
||||
FluLoader{
|
||||
property int displayIndex: {
|
||||
if(index === 0)
|
||||
return list_view.count-3
|
||||
if(index === list_view.count-1)
|
||||
return 0
|
||||
return index-1
|
||||
}
|
||||
property int realIndex: index
|
||||
property bool checked: list_view.currentIndex === index
|
||||
sourceComponent: {
|
||||
if(index===0 || index===list_view.count-1)
|
||||
return undefined
|
||||
return control.indicatorDelegate
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Timer{
|
||||
id:timer_anim
|
||||
interval: 250
|
||||
@ -198,10 +277,10 @@ Item {
|
||||
}
|
||||
}
|
||||
function changedIndex(index){
|
||||
d.flagXChanged = true
|
||||
d.isManualMoving = true
|
||||
timer_run.stop()
|
||||
list_view.currentIndex = index
|
||||
d.flagXChanged = false
|
||||
d.isManualMoving = false
|
||||
if(d.isAnimEnable){
|
||||
timer_run.restart()
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user