mirror of
https://github.com/zhuzichu520/FluentUI.git
synced 2025-04-01 20:28:38 +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>
|
<source>Carousel map, support infinite carousel, infinite swipe, and components implemented with ListView</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="qml/page/T_Carousel.qml" line="203"/>
|
||||||
|
<source>Auto play</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>T_CheckBox</name>
|
<name>T_CheckBox</name>
|
||||||
|
@ -1142,12 +1142,17 @@ Updated content:
|
|||||||
<message>
|
<message>
|
||||||
<location filename="qml/page/T_Carousel.qml" line="10"/>
|
<location filename="qml/page/T_Carousel.qml" line="10"/>
|
||||||
<source>Carousel</source>
|
<source>Carousel</source>
|
||||||
<translation type="unfinished">轮播图</translation>
|
<translation>轮播图</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="qml/page/T_Carousel.qml" line="36"/>
|
<location filename="qml/page/T_Carousel.qml" line="36"/>
|
||||||
<source>Carousel map, support infinite carousel, infinite swipe, and components implemented with ListView</source>
|
<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>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
|
@ -121,7 +121,6 @@ FluScrollablePage{
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeExpander{
|
CodeExpander{
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: -6
|
Layout.topMargin: -6
|
||||||
@ -140,6 +139,90 @@ FluScrollablePage{
|
|||||||
Component.onCompleted: {
|
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"}]
|
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 {
|
Item {
|
||||||
property bool autoPlay: true
|
property bool autoPlay: true
|
||||||
|
property int orientation: Qt.Horizontal
|
||||||
property int loopTime: 2000
|
property int loopTime: 2000
|
||||||
property var model
|
property var model
|
||||||
property Component delegate
|
property Component delegate
|
||||||
@ -14,7 +15,7 @@ Item {
|
|||||||
property int indicatorMarginTop: 0
|
property int indicatorMarginTop: 0
|
||||||
property int indicatorMarginBottom: 20
|
property int indicatorMarginBottom: 20
|
||||||
property int indicatorSpacing: 10
|
property int indicatorSpacing: 10
|
||||||
property alias indicatorAnchors: layout_indicator.anchors
|
property alias indicatorAnchors: indicator_loader.anchors
|
||||||
property Component indicatorDelegate : com_indicator
|
property Component indicatorDelegate : com_indicator
|
||||||
id:control
|
id:control
|
||||||
width: 400
|
width: 400
|
||||||
@ -24,13 +25,24 @@ Item {
|
|||||||
}
|
}
|
||||||
QtObject{
|
QtObject{
|
||||||
id:d
|
id:d
|
||||||
property bool flagXChanged: false
|
property bool isManualMoving: false
|
||||||
property bool isAnimEnable: control.autoPlay && list_view.count>3
|
property bool isAnimEnable: control.autoPlay && list_view.count>3
|
||||||
|
onIsAnimEnableChanged: {
|
||||||
|
if(isAnimEnable){
|
||||||
|
timer_run.restart()
|
||||||
|
}else{
|
||||||
|
timer_run.stop()
|
||||||
|
}
|
||||||
|
}
|
||||||
function setData(data){
|
function setData(data){
|
||||||
if(!data){
|
if(!data || !Array.isArray(data)){
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
content_model.clear()
|
content_model.clear()
|
||||||
|
list_view.resetPos()
|
||||||
|
if(data.length === 0){
|
||||||
|
return
|
||||||
|
}
|
||||||
content_model.append(data[data.length-1])
|
content_model.append(data[data.length-1])
|
||||||
content_model.append(data)
|
content_model.append(data)
|
||||||
content_model.append(data[0])
|
content_model.append(data[0])
|
||||||
@ -49,7 +61,7 @@ Item {
|
|||||||
clip: true
|
clip: true
|
||||||
boundsBehavior: ListView.StopAtBounds
|
boundsBehavior: ListView.StopAtBounds
|
||||||
model:content_model
|
model:content_model
|
||||||
maximumFlickVelocity: 4 * (list_view.orientation === Qt.Horizontal ? width : height)
|
maximumFlickVelocity: 4 * (control.orientation === Qt.Vertical ? height : width)
|
||||||
preferredHighlightBegin: 0
|
preferredHighlightBegin: 0
|
||||||
preferredHighlightEnd: 0
|
preferredHighlightEnd: 0
|
||||||
highlightMoveDuration: 0
|
highlightMoveDuration: 0
|
||||||
@ -63,7 +75,7 @@ Item {
|
|||||||
d.setData(control.model)
|
d.setData(control.model)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
orientation : ListView.Horizontal
|
orientation : control.orientation
|
||||||
delegate: Item{
|
delegate: Item{
|
||||||
id:item_control
|
id:item_control
|
||||||
width: ListView.view.width
|
width: ListView.view.width
|
||||||
@ -88,34 +100,63 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
onMovementEnded:{
|
onMovementEnded:{
|
||||||
d.flagXChanged = false
|
d.isManualMoving = false
|
||||||
list_view.highlightMoveDuration = 0
|
list_view.highlightMoveDuration = 0
|
||||||
currentIndex = list_view.contentX/list_view.width
|
if(control.orientation === Qt.Vertical){
|
||||||
if(currentIndex === 0){
|
currentIndex = (list_view.contentY - list_view.originY) / list_view.height
|
||||||
currentIndex = list_view.count-2
|
if(currentIndex === 0){
|
||||||
}else if(currentIndex === list_view.count-1){
|
currentIndex = list_view.count - 2
|
||||||
currentIndex = 1
|
}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){
|
if(d.isAnimEnable){
|
||||||
timer_run.restart()
|
timer_run.restart()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onMovementStarted: {
|
onMovementStarted: {
|
||||||
d.flagXChanged = true
|
d.isManualMoving = true
|
||||||
timer_run.stop()
|
timer_run.stop()
|
||||||
}
|
}
|
||||||
onContentXChanged: {
|
onContentXChanged: {
|
||||||
if(d.flagXChanged){
|
if(d.isManualMoving && control.orientation === Qt.Horizontal){
|
||||||
var maxX = Math.min(list_view.width*(currentIndex+1),list_view.count*list_view.width)
|
const range = getPosRange(list_view.width, currentIndex)
|
||||||
var minX = Math.max(0,(list_view.width*(currentIndex-1)))
|
if(contentX >= range.max){
|
||||||
if(contentX>=maxX){
|
contentX = range.max
|
||||||
contentX = maxX
|
|
||||||
}
|
}
|
||||||
if(contentX<=minX){
|
if(contentX <= range.min){
|
||||||
contentX = minX
|
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{
|
Component{
|
||||||
id:com_indicator
|
id:com_indicator
|
||||||
@ -140,9 +181,9 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Row{
|
|
||||||
id:layout_indicator
|
Loader{
|
||||||
spacing: control.indicatorSpacing
|
id: indicator_loader
|
||||||
anchors{
|
anchors{
|
||||||
horizontalCenter:(indicatorGravity & Qt.AlignHCenter) ? parent.horizontalCenter : undefined
|
horizontalCenter:(indicatorGravity & Qt.AlignHCenter) ? parent.horizontalCenter : undefined
|
||||||
verticalCenter: (indicatorGravity & Qt.AlignVCenter) ? parent.verticalCenter : undefined
|
verticalCenter: (indicatorGravity & Qt.AlignVCenter) ? parent.verticalCenter : undefined
|
||||||
@ -155,28 +196,66 @@ Item {
|
|||||||
rightMargin: control.indicatorMarginBottom
|
rightMargin: control.indicatorMarginBottom
|
||||||
topMargin: control.indicatorMarginBottom
|
topMargin: control.indicatorMarginBottom
|
||||||
}
|
}
|
||||||
visible: showIndicator
|
active: showIndicator
|
||||||
Repeater{
|
sourceComponent: control.orientation === Qt.Vertical ? column_indicator : row_indicator
|
||||||
id:repeater_indicator
|
}
|
||||||
model: list_view.count
|
|
||||||
FluLoader{
|
Component{
|
||||||
property int displayIndex: {
|
id: row_indicator
|
||||||
if(index === 0)
|
Row{
|
||||||
return list_view.count-3
|
id:layout_indicator
|
||||||
if(index === list_view.count-1)
|
spacing: control.indicatorSpacing
|
||||||
return 0
|
Repeater{
|
||||||
return index-1
|
id:repeater_indicator
|
||||||
}
|
model: list_view.count
|
||||||
property int realIndex: index
|
FluLoader{
|
||||||
property bool checked: list_view.currentIndex === index
|
property int displayIndex: {
|
||||||
sourceComponent: {
|
if(index === 0)
|
||||||
if(index===0 || index===list_view.count-1)
|
return list_view.count-3
|
||||||
return undefined
|
if(index === list_view.count-1)
|
||||||
return control.indicatorDelegate
|
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{
|
Timer{
|
||||||
id:timer_anim
|
id:timer_anim
|
||||||
interval: 250
|
interval: 250
|
||||||
@ -198,10 +277,10 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
function changedIndex(index){
|
function changedIndex(index){
|
||||||
d.flagXChanged = true
|
d.isManualMoving = true
|
||||||
timer_run.stop()
|
timer_run.stop()
|
||||||
list_view.currentIndex = index
|
list_view.currentIndex = index
|
||||||
d.flagXChanged = false
|
d.isManualMoving = false
|
||||||
if(d.isAnimEnable){
|
if(d.isAnimEnable){
|
||||||
timer_run.restart()
|
timer_run.restart()
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ import QtQuick.tooling 1.2
|
|||||||
// It is used for QML tooling purposes only.
|
// It is used for QML tooling purposes only.
|
||||||
//
|
//
|
||||||
// This file was auto-generated by:
|
// 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 {
|
Module {
|
||||||
dependencies: ["QtQuick 2.0"]
|
dependencies: ["QtQuick 2.0"]
|
||||||
@ -2776,7 +2776,7 @@ Module {
|
|||||||
}
|
}
|
||||||
Property {
|
Property {
|
||||||
name: "layoutMacosButtons"
|
name: "layoutMacosButtons"
|
||||||
type: "FluLoader_QMLTYPE_11"
|
type: "FluLoader_QMLTYPE_14"
|
||||||
isReadonly: true
|
isReadonly: true
|
||||||
isPointer: true
|
isPointer: true
|
||||||
}
|
}
|
||||||
@ -2898,6 +2898,7 @@ Module {
|
|||||||
isComposite: true
|
isComposite: true
|
||||||
defaultProperty: "data"
|
defaultProperty: "data"
|
||||||
Property { name: "autoPlay"; type: "bool" }
|
Property { name: "autoPlay"; type: "bool" }
|
||||||
|
Property { name: "orientation"; type: "int" }
|
||||||
Property { name: "loopTime"; type: "int" }
|
Property { name: "loopTime"; type: "int" }
|
||||||
Property { name: "model"; type: "QVariant" }
|
Property { name: "model"; type: "QVariant" }
|
||||||
Property { name: "delegate"; type: "QQmlComponent"; isPointer: true }
|
Property { name: "delegate"; type: "QQmlComponent"; isPointer: true }
|
||||||
@ -2955,12 +2956,12 @@ Module {
|
|||||||
Property { name: "checkedDisableColor"; type: "QColor" }
|
Property { name: "checkedDisableColor"; type: "QColor" }
|
||||||
Property { name: "disableColor"; type: "QColor" }
|
Property { name: "disableColor"; type: "QColor" }
|
||||||
Property { name: "size"; type: "double" }
|
Property { name: "size"; type: "double" }
|
||||||
|
Property { name: "textColor"; type: "QColor" }
|
||||||
Property { name: "textRight"; type: "bool" }
|
Property { name: "textRight"; type: "bool" }
|
||||||
Property { name: "textSpacing"; type: "double" }
|
Property { name: "textSpacing"; type: "double" }
|
||||||
Property { name: "animationEnabled"; type: "bool" }
|
Property { name: "animationEnabled"; type: "bool" }
|
||||||
Property { name: "clickListener"; type: "QVariant" }
|
Property { name: "clickListener"; type: "QVariant" }
|
||||||
Property { name: "indeterminate"; type: "bool" }
|
Property { name: "indeterminate"; type: "bool" }
|
||||||
Property { name: "textColor"; type: "QColor" }
|
|
||||||
}
|
}
|
||||||
Component {
|
Component {
|
||||||
prototype: "FluRectangle"
|
prototype: "FluRectangle"
|
||||||
@ -3189,6 +3190,8 @@ Module {
|
|||||||
isComposite: true
|
isComposite: true
|
||||||
defaultProperty: "content"
|
defaultProperty: "content"
|
||||||
Property { name: "headerText"; type: "string" }
|
Property { name: "headerText"; type: "string" }
|
||||||
|
Property { name: "headerHeight"; type: "int" }
|
||||||
|
Property { name: "headerDelegate"; type: "QQmlComponent"; isPointer: true }
|
||||||
Property { name: "expand"; type: "bool" }
|
Property { name: "expand"; type: "bool" }
|
||||||
Property { name: "contentHeight"; type: "int" }
|
Property { name: "contentHeight"; type: "int" }
|
||||||
Property { name: "content"; type: "QObject"; isList: true; isReadonly: true }
|
Property { name: "content"; type: "QObject"; isList: true; isReadonly: true }
|
||||||
@ -3469,15 +3472,15 @@ Module {
|
|||||||
defaultProperty: "data"
|
defaultProperty: "data"
|
||||||
Property { name: "logo"; type: "QUrl" }
|
Property { name: "logo"; type: "QUrl" }
|
||||||
Property { name: "title"; type: "string" }
|
Property { name: "title"; type: "string" }
|
||||||
Property { name: "items"; type: "FluObject_QMLTYPE_176"; isPointer: true }
|
Property { name: "items"; type: "FluObject_QMLTYPE_182"; isPointer: true }
|
||||||
Property { name: "footerItems"; type: "FluObject_QMLTYPE_176"; isPointer: true }
|
Property { name: "footerItems"; type: "FluObject_QMLTYPE_182"; isPointer: true }
|
||||||
Property { name: "displayMode"; type: "int" }
|
Property { name: "displayMode"; type: "int" }
|
||||||
Property { name: "autoSuggestBox"; type: "QQmlComponent"; isPointer: true }
|
Property { name: "autoSuggestBox"; type: "QQmlComponent"; isPointer: true }
|
||||||
Property { name: "actionItem"; type: "QQmlComponent"; isPointer: true }
|
Property { name: "actionItem"; type: "QQmlComponent"; isPointer: true }
|
||||||
Property { name: "topPadding"; type: "int" }
|
Property { name: "topPadding"; type: "int" }
|
||||||
Property { name: "pageMode"; type: "int" }
|
Property { name: "pageMode"; type: "int" }
|
||||||
Property { name: "navItemRightMenu"; type: "FluMenu_QMLTYPE_48"; isPointer: true }
|
Property { name: "navItemRightMenu"; type: "FluMenu_QMLTYPE_47"; isPointer: true }
|
||||||
Property { name: "navItemExpanderRightMenu"; type: "FluMenu_QMLTYPE_48"; isPointer: true }
|
Property { name: "navItemExpanderRightMenu"; type: "FluMenu_QMLTYPE_47"; isPointer: true }
|
||||||
Property { name: "navCompactWidth"; type: "int" }
|
Property { name: "navCompactWidth"; type: "int" }
|
||||||
Property { name: "navTopMargin"; type: "int" }
|
Property { name: "navTopMargin"; type: "int" }
|
||||||
Property { name: "cellHeight"; type: "int" }
|
Property { name: "cellHeight"; type: "int" }
|
||||||
@ -3676,6 +3679,7 @@ Module {
|
|||||||
exportMetaObjectRevisions: [0]
|
exportMetaObjectRevisions: [0]
|
||||||
isComposite: true
|
isComposite: true
|
||||||
defaultProperty: "content"
|
defaultProperty: "content"
|
||||||
|
Property { name: "textHighlightColor"; type: "QColor" }
|
||||||
Property { name: "textNormalColor"; type: "QColor" }
|
Property { name: "textNormalColor"; type: "QColor" }
|
||||||
Property { name: "textHoverColor"; type: "QColor" }
|
Property { name: "textHoverColor"; type: "QColor" }
|
||||||
Property { name: "textSpacing"; type: "int" }
|
Property { name: "textSpacing"; type: "int" }
|
||||||
@ -3772,11 +3776,11 @@ Module {
|
|||||||
Property { name: "normalColor"; type: "QColor" }
|
Property { name: "normalColor"; type: "QColor" }
|
||||||
Property { name: "hoverColor"; type: "QColor" }
|
Property { name: "hoverColor"; type: "QColor" }
|
||||||
Property { name: "disableColor"; type: "QColor" }
|
Property { name: "disableColor"; type: "QColor" }
|
||||||
|
Property { name: "textColor"; type: "QColor" }
|
||||||
Property { name: "size"; type: "double" }
|
Property { name: "size"; type: "double" }
|
||||||
Property { name: "textRight"; type: "bool" }
|
Property { name: "textRight"; type: "bool" }
|
||||||
Property { name: "textSpacing"; type: "double" }
|
Property { name: "textSpacing"; type: "double" }
|
||||||
Property { name: "clickListener"; type: "QVariant" }
|
Property { name: "clickListener"; type: "QVariant" }
|
||||||
Property { name: "textColor"; type: "QColor" }
|
|
||||||
}
|
}
|
||||||
Component {
|
Component {
|
||||||
prototype: "QQuickItem"
|
prototype: "QQuickItem"
|
||||||
@ -3899,7 +3903,9 @@ Module {
|
|||||||
exportMetaObjectRevisions: [0]
|
exportMetaObjectRevisions: [0]
|
||||||
isComposite: true
|
isComposite: true
|
||||||
defaultProperty: "content"
|
defaultProperty: "content"
|
||||||
|
Property { name: "autoResetScroll"; type: "bool" }
|
||||||
Property { name: "content"; type: "QObject"; isList: true; isReadonly: true }
|
Property { name: "content"; type: "QObject"; isList: true; isReadonly: true }
|
||||||
|
Method { name: "resetScroll"; type: "QVariant" }
|
||||||
Property { name: "launchMode"; type: "int" }
|
Property { name: "launchMode"; type: "int" }
|
||||||
Property { name: "animationEnabled"; type: "bool" }
|
Property { name: "animationEnabled"; type: "bool" }
|
||||||
Property { name: "url"; type: "string" }
|
Property { name: "url"; type: "string" }
|
||||||
@ -4294,8 +4300,8 @@ Module {
|
|||||||
Property { name: "dotDisableColor"; type: "QColor" }
|
Property { name: "dotDisableColor"; type: "QColor" }
|
||||||
Property { name: "textSpacing"; type: "double" }
|
Property { name: "textSpacing"; type: "double" }
|
||||||
Property { name: "textRight"; type: "bool" }
|
Property { name: "textRight"; type: "bool" }
|
||||||
Property { name: "clickListener"; type: "QVariant" }
|
|
||||||
Property { name: "textColor"; type: "QColor" }
|
Property { name: "textColor"; type: "QColor" }
|
||||||
|
Property { name: "clickListener"; type: "QVariant" }
|
||||||
}
|
}
|
||||||
Component {
|
Component {
|
||||||
prototype: "QQuickToolTip"
|
prototype: "QQuickToolTip"
|
||||||
@ -4379,7 +4385,6 @@ Module {
|
|||||||
Property { name: "fitsAppBarWindows"; type: "bool" }
|
Property { name: "fitsAppBarWindows"; type: "bool" }
|
||||||
Property { name: "tintOpacity"; type: "QVariant" }
|
Property { name: "tintOpacity"; type: "QVariant" }
|
||||||
Property { name: "blurRadius"; type: "int" }
|
Property { name: "blurRadius"; type: "int" }
|
||||||
Property { name: "availableEffects"; type: "QVariant"; isReadonly: true }
|
|
||||||
Property { name: "appBar"; type: "QQuickItem"; isPointer: true }
|
Property { name: "appBar"; type: "QQuickItem"; isPointer: true }
|
||||||
Property { name: "backgroundColor"; type: "QColor" }
|
Property { name: "backgroundColor"; type: "QColor" }
|
||||||
Property { name: "stayTop"; type: "bool" }
|
Property { name: "stayTop"; type: "bool" }
|
||||||
@ -4403,6 +4408,7 @@ Module {
|
|||||||
Property { name: "contentData"; type: "QObject"; isList: true; isReadonly: true }
|
Property { name: "contentData"; type: "QObject"; isList: true; isReadonly: true }
|
||||||
Property { name: "effect"; type: "string" }
|
Property { name: "effect"; type: "string" }
|
||||||
Property { name: "effective"; type: "bool"; isReadonly: true }
|
Property { name: "effective"; type: "bool"; isReadonly: true }
|
||||||
|
Property { name: "availableEffects"; type: "QStringList"; isReadonly: true }
|
||||||
Signal {
|
Signal {
|
||||||
name: "initArgument"
|
name: "initArgument"
|
||||||
Parameter { name: "argument"; type: "QVariant" }
|
Parameter { name: "argument"; type: "QVariant" }
|
||||||
@ -4485,7 +4491,6 @@ Module {
|
|||||||
Property { name: "fitsAppBarWindows"; type: "bool" }
|
Property { name: "fitsAppBarWindows"; type: "bool" }
|
||||||
Property { name: "tintOpacity"; type: "QVariant" }
|
Property { name: "tintOpacity"; type: "QVariant" }
|
||||||
Property { name: "blurRadius"; type: "int" }
|
Property { name: "blurRadius"; type: "int" }
|
||||||
Property { name: "availableEffects"; type: "QVariant"; isReadonly: true }
|
|
||||||
Property { name: "appBar"; type: "QQuickItem"; isPointer: true }
|
Property { name: "appBar"; type: "QQuickItem"; isPointer: true }
|
||||||
Property { name: "backgroundColor"; type: "QColor" }
|
Property { name: "backgroundColor"; type: "QColor" }
|
||||||
Property { name: "stayTop"; type: "bool" }
|
Property { name: "stayTop"; type: "bool" }
|
||||||
@ -4509,6 +4514,7 @@ Module {
|
|||||||
Property { name: "contentData"; type: "QObject"; isList: true; isReadonly: true }
|
Property { name: "contentData"; type: "QObject"; isList: true; isReadonly: true }
|
||||||
Property { name: "effect"; type: "string" }
|
Property { name: "effect"; type: "string" }
|
||||||
Property { name: "effective"; type: "bool"; isReadonly: true }
|
Property { name: "effective"; type: "bool"; isReadonly: true }
|
||||||
|
Property { name: "availableEffects"; type: "QStringList"; isReadonly: true }
|
||||||
Signal {
|
Signal {
|
||||||
name: "initArgument"
|
name: "initArgument"
|
||||||
Parameter { name: "argument"; type: "QVariant" }
|
Parameter { name: "argument"; type: "QVariant" }
|
||||||
|
@ -4,6 +4,7 @@ import FluentUI
|
|||||||
|
|
||||||
Item {
|
Item {
|
||||||
property bool autoPlay: true
|
property bool autoPlay: true
|
||||||
|
property int orientation: Qt.Horizontal
|
||||||
property int loopTime: 2000
|
property int loopTime: 2000
|
||||||
property var model
|
property var model
|
||||||
property Component delegate
|
property Component delegate
|
||||||
@ -14,7 +15,7 @@ Item {
|
|||||||
property int indicatorMarginTop: 0
|
property int indicatorMarginTop: 0
|
||||||
property int indicatorMarginBottom: 20
|
property int indicatorMarginBottom: 20
|
||||||
property int indicatorSpacing: 10
|
property int indicatorSpacing: 10
|
||||||
property alias indicatorAnchors: layout_indicator.anchors
|
property alias indicatorAnchors: indicator_loader.anchors
|
||||||
property Component indicatorDelegate : com_indicator
|
property Component indicatorDelegate : com_indicator
|
||||||
id:control
|
id:control
|
||||||
width: 400
|
width: 400
|
||||||
@ -24,13 +25,24 @@ Item {
|
|||||||
}
|
}
|
||||||
QtObject{
|
QtObject{
|
||||||
id:d
|
id:d
|
||||||
property bool flagXChanged: false
|
property bool isManualMoving: false
|
||||||
property bool isAnimEnable: control.autoPlay && list_view.count>3
|
property bool isAnimEnable: control.autoPlay && list_view.count>3
|
||||||
|
onIsAnimEnableChanged: {
|
||||||
|
if(isAnimEnable){
|
||||||
|
timer_run.restart()
|
||||||
|
}else{
|
||||||
|
timer_run.stop()
|
||||||
|
}
|
||||||
|
}
|
||||||
function setData(data){
|
function setData(data){
|
||||||
if(!data){
|
if(!data || !Array.isArray(data)){
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
content_model.clear()
|
content_model.clear()
|
||||||
|
list_view.resetPos()
|
||||||
|
if(data.length === 0){
|
||||||
|
return
|
||||||
|
}
|
||||||
content_model.append(data[data.length-1])
|
content_model.append(data[data.length-1])
|
||||||
content_model.append(data)
|
content_model.append(data)
|
||||||
content_model.append(data[0])
|
content_model.append(data[0])
|
||||||
@ -49,7 +61,7 @@ Item {
|
|||||||
clip: true
|
clip: true
|
||||||
boundsBehavior: ListView.StopAtBounds
|
boundsBehavior: ListView.StopAtBounds
|
||||||
model:content_model
|
model:content_model
|
||||||
maximumFlickVelocity: 4 * (list_view.orientation === Qt.Horizontal ? width : height)
|
maximumFlickVelocity: 4 * (control.orientation === Qt.Vertical ? height : width)
|
||||||
preferredHighlightBegin: 0
|
preferredHighlightBegin: 0
|
||||||
preferredHighlightEnd: 0
|
preferredHighlightEnd: 0
|
||||||
highlightMoveDuration: 0
|
highlightMoveDuration: 0
|
||||||
@ -63,7 +75,7 @@ Item {
|
|||||||
d.setData(control.model)
|
d.setData(control.model)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
orientation : ListView.Horizontal
|
orientation : control.orientation
|
||||||
delegate: Item{
|
delegate: Item{
|
||||||
id:item_control
|
id:item_control
|
||||||
width: ListView.view.width
|
width: ListView.view.width
|
||||||
@ -88,34 +100,63 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
onMovementEnded:{
|
onMovementEnded:{
|
||||||
d.flagXChanged = false
|
d.isManualMoving = false
|
||||||
list_view.highlightMoveDuration = 0
|
list_view.highlightMoveDuration = 0
|
||||||
currentIndex = list_view.contentX/list_view.width
|
if(control.orientation === Qt.Vertical){
|
||||||
if(currentIndex === 0){
|
currentIndex = (list_view.contentY - list_view.originY) / list_view.height
|
||||||
currentIndex = list_view.count-2
|
if(currentIndex === 0){
|
||||||
}else if(currentIndex === list_view.count-1){
|
currentIndex = list_view.count - 2
|
||||||
currentIndex = 1
|
}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){
|
if(d.isAnimEnable){
|
||||||
timer_run.restart()
|
timer_run.restart()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onMovementStarted: {
|
onMovementStarted: {
|
||||||
d.flagXChanged = true
|
d.isManualMoving = true
|
||||||
timer_run.stop()
|
timer_run.stop()
|
||||||
}
|
}
|
||||||
onContentXChanged: {
|
onContentXChanged: {
|
||||||
if(d.flagXChanged){
|
if(d.isManualMoving && control.orientation === Qt.Horizontal){
|
||||||
var maxX = Math.min(list_view.width*(currentIndex+1),list_view.count*list_view.width)
|
const range = getPosRange(list_view.width, currentIndex)
|
||||||
var minX = Math.max(0,(list_view.width*(currentIndex-1)))
|
if(contentX >= range.max){
|
||||||
if(contentX>=maxX){
|
contentX = range.max
|
||||||
contentX = maxX
|
|
||||||
}
|
}
|
||||||
if(contentX<=minX){
|
if(contentX <= range.min){
|
||||||
contentX = minX
|
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{
|
Component{
|
||||||
id:com_indicator
|
id:com_indicator
|
||||||
@ -140,9 +181,9 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Row{
|
|
||||||
id:layout_indicator
|
Loader{
|
||||||
spacing: control.indicatorSpacing
|
id: indicator_loader
|
||||||
anchors{
|
anchors{
|
||||||
horizontalCenter:(indicatorGravity & Qt.AlignHCenter) ? parent.horizontalCenter : undefined
|
horizontalCenter:(indicatorGravity & Qt.AlignHCenter) ? parent.horizontalCenter : undefined
|
||||||
verticalCenter: (indicatorGravity & Qt.AlignVCenter) ? parent.verticalCenter : undefined
|
verticalCenter: (indicatorGravity & Qt.AlignVCenter) ? parent.verticalCenter : undefined
|
||||||
@ -155,28 +196,66 @@ Item {
|
|||||||
rightMargin: control.indicatorMarginBottom
|
rightMargin: control.indicatorMarginBottom
|
||||||
topMargin: control.indicatorMarginBottom
|
topMargin: control.indicatorMarginBottom
|
||||||
}
|
}
|
||||||
visible: showIndicator
|
active: showIndicator
|
||||||
Repeater{
|
sourceComponent: control.orientation === Qt.Vertical ? column_indicator : row_indicator
|
||||||
id:repeater_indicator
|
}
|
||||||
model: list_view.count
|
|
||||||
FluLoader{
|
Component{
|
||||||
property int displayIndex: {
|
id: row_indicator
|
||||||
if(index === 0)
|
Row{
|
||||||
return list_view.count-3
|
id:layout_indicator
|
||||||
if(index === list_view.count-1)
|
spacing: control.indicatorSpacing
|
||||||
return 0
|
Repeater{
|
||||||
return index-1
|
id:repeater_indicator
|
||||||
}
|
model: list_view.count
|
||||||
property int realIndex: index
|
FluLoader{
|
||||||
property bool checked: list_view.currentIndex === index
|
property int displayIndex: {
|
||||||
sourceComponent: {
|
if(index === 0)
|
||||||
if(index===0 || index===list_view.count-1)
|
return list_view.count-3
|
||||||
return undefined
|
if(index === list_view.count-1)
|
||||||
return control.indicatorDelegate
|
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{
|
Timer{
|
||||||
id:timer_anim
|
id:timer_anim
|
||||||
interval: 250
|
interval: 250
|
||||||
@ -198,10 +277,10 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
function changedIndex(index){
|
function changedIndex(index){
|
||||||
d.flagXChanged = true
|
d.isManualMoving = true
|
||||||
timer_run.stop()
|
timer_run.stop()
|
||||||
list_view.currentIndex = index
|
list_view.currentIndex = index
|
||||||
d.flagXChanged = false
|
d.isManualMoving = false
|
||||||
if(d.isAnimEnable){
|
if(d.isAnimEnable){
|
||||||
timer_run.restart()
|
timer_run.restart()
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user