mirror of
https://github.com/zhuzichu520/FluentUI.git
synced 2025-07-05 01:25:25 +08:00
update
This commit is contained in:
@ -2,102 +2,170 @@ import QtQuick
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
|
||||
Item {
|
||||
property bool flagXChanged: true
|
||||
property int radius : 5
|
||||
FluItem {
|
||||
property int loopTime: 2000
|
||||
property var model
|
||||
property Component delegate
|
||||
property bool showIndicator: true
|
||||
property int indicatorGravity : Qt.AlignBottom | Qt.AlignHCenter
|
||||
property int indicatorMarginLeft: 0
|
||||
property int indicatorMarginRight: 0
|
||||
property int indicatorMarginTop: 0
|
||||
property int indicatorMarginBottom: 20
|
||||
property int indicatorSpacing: 10
|
||||
property alias indicatorAnchors: layout_indicator.anchors
|
||||
property Component indicatorDelegate : com_indicator
|
||||
id:control
|
||||
width: 400
|
||||
height: 300
|
||||
ListModel{
|
||||
id:content_model
|
||||
}
|
||||
FluRectangle{
|
||||
anchors.fill: parent
|
||||
radius: [control.radius,control.radius,control.radius,control.radius]
|
||||
FluShadow{
|
||||
radius:control.radius
|
||||
QtObject{
|
||||
id:d
|
||||
property bool flagXChanged: true
|
||||
function setData(data){
|
||||
if(!data){
|
||||
return
|
||||
}
|
||||
content_model.clear()
|
||||
content_model.append(data[data.length-1])
|
||||
content_model.append(data)
|
||||
content_model.append(data[0])
|
||||
list_view.highlightMoveDuration = 0
|
||||
list_view.currentIndex = 1
|
||||
list_view.highlightMoveDuration = 250
|
||||
timer_run.restart()
|
||||
}
|
||||
ListView{
|
||||
id:list_view
|
||||
anchors.fill: parent
|
||||
snapMode: ListView.SnapOneItem
|
||||
clip: true
|
||||
boundsBehavior: ListView.StopAtBounds
|
||||
model:content_model
|
||||
maximumFlickVelocity: 4 * (list_view.orientation === Qt.Horizontal ? width : height)
|
||||
preferredHighlightBegin: 0
|
||||
preferredHighlightEnd: 0
|
||||
highlightMoveDuration: 0
|
||||
orientation : ListView.Horizontal
|
||||
delegate: Item{
|
||||
width: ListView.view.width
|
||||
height: ListView.view.height
|
||||
property int displayIndex: {
|
||||
if(index === 0)
|
||||
return content_model.count-3
|
||||
if(index === content_model.count-1)
|
||||
return 0
|
||||
return index-1
|
||||
}
|
||||
Image {
|
||||
anchors.fill: parent
|
||||
source: model.url
|
||||
asynchronous: true
|
||||
fillMode:Image.PreserveAspectCrop
|
||||
}
|
||||
}
|
||||
ListView{
|
||||
id:list_view
|
||||
anchors.fill: parent
|
||||
snapMode: ListView.SnapOneItem
|
||||
clip: true
|
||||
boundsBehavior: ListView.StopAtBounds
|
||||
model:content_model
|
||||
maximumFlickVelocity: 4 * (list_view.orientation === Qt.Horizontal ? width : height)
|
||||
preferredHighlightBegin: 0
|
||||
preferredHighlightEnd: 0
|
||||
highlightMoveDuration: 0
|
||||
Component.onCompleted: {
|
||||
d.setData(control.model)
|
||||
}
|
||||
Connections{
|
||||
target: control
|
||||
function onModelChanged(){
|
||||
d.setData(control.model)
|
||||
}
|
||||
onMovementEnded:{
|
||||
currentIndex = list_view.contentX/list_view.width
|
||||
if(currentIndex === 0){
|
||||
currentIndex = list_view.count-2
|
||||
}else if(currentIndex === list_view.count-1){
|
||||
currentIndex = 1
|
||||
}
|
||||
flagXChanged = false
|
||||
timer_run.start()
|
||||
}
|
||||
orientation : ListView.Horizontal
|
||||
delegate: Item{
|
||||
id:item_control
|
||||
width: ListView.view.width
|
||||
height: ListView.view.height
|
||||
property int displayIndex: {
|
||||
if(index === 0)
|
||||
return content_model.count-3
|
||||
if(index === content_model.count-1)
|
||||
return 0
|
||||
return index-1
|
||||
}
|
||||
onMovementStarted: {
|
||||
flagXChanged = true
|
||||
timer_run.stop()
|
||||
}
|
||||
onContentXChanged: {
|
||||
if(flagXChanged){
|
||||
var maxX = Math.min(list_view.width*(currentIndex+1),list_view.count*list_view.width)
|
||||
var minY = Math.max(0,(list_view.width*(currentIndex-1)))
|
||||
if(contentX>=maxX){
|
||||
contentX = maxX
|
||||
}
|
||||
if(contentX<=minY){
|
||||
contentX = minY
|
||||
Loader{
|
||||
property int displayIndex : item_control.displayIndex
|
||||
property var model: list_view.model.get(index)
|
||||
anchors.fill: parent
|
||||
sourceComponent: {
|
||||
if(model){
|
||||
return control.delegate
|
||||
}
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
}
|
||||
onMovementEnded:{
|
||||
currentIndex = list_view.contentX/list_view.width
|
||||
if(currentIndex === 0){
|
||||
currentIndex = list_view.count-2
|
||||
}else if(currentIndex === list_view.count-1){
|
||||
currentIndex = 1
|
||||
}
|
||||
d.flagXChanged = false
|
||||
timer_run.restart()
|
||||
}
|
||||
onMovementStarted: {
|
||||
d.flagXChanged = true
|
||||
timer_run.stop()
|
||||
}
|
||||
onContentXChanged: {
|
||||
if(d.flagXChanged){
|
||||
var maxX = Math.min(list_view.width*(currentIndex+1),list_view.count*list_view.width)
|
||||
var minY = Math.max(0,(list_view.width*(currentIndex-1)))
|
||||
if(contentX>=maxX){
|
||||
contentX = maxX
|
||||
}
|
||||
if(contentX<=minY){
|
||||
contentX = minY
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Component{
|
||||
id:com_indicator
|
||||
Rectangle{
|
||||
width: 8
|
||||
height: 8
|
||||
radius: 4
|
||||
FluShadow{
|
||||
radius: 4
|
||||
}
|
||||
scale: checked ? 1.2 : 1
|
||||
color: checked ? FluTheme.primaryColor.dark : Qt.rgba(1,1,1,0.7)
|
||||
border.width: mouse_item.containsMouse ? 1 : 0
|
||||
border.color: FluTheme.primaryColor.dark
|
||||
MouseArea{
|
||||
id:mouse_item
|
||||
hoverEnabled: true
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
changedIndex(realIndex)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Row{
|
||||
spacing: 10
|
||||
id:layout_indicator
|
||||
spacing: control.indicatorSpacing
|
||||
anchors{
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
bottom: parent.bottom
|
||||
bottomMargin: 20
|
||||
horizontalCenter:(indicatorGravity & Qt.AlignHCenter) ? parent.horizontalCenter : undefined
|
||||
verticalCenter: (indicatorGravity & Qt.AlignVCenter) ? parent.verticalCenter : undefined
|
||||
bottom: (indicatorGravity & Qt.AlignBottom) ? parent.bottom : undefined
|
||||
top: (indicatorGravity & Qt.AlignTop) ? parent.top : undefined
|
||||
left: (indicatorGravity & Qt.AlignLeft) ? parent.left : undefined
|
||||
right: (indicatorGravity & Qt.AlignRight) ? parent.right : undefined
|
||||
bottomMargin: control.indicatorMarginBottom
|
||||
leftMargin: control.indicatorMarginBottom
|
||||
rightMargin: control.indicatorMarginBottom
|
||||
topMargin: control.indicatorMarginBottom
|
||||
}
|
||||
visible: showIndicator
|
||||
Repeater{
|
||||
id:repeater_indicator
|
||||
model: list_view.count
|
||||
Rectangle{
|
||||
width: 8
|
||||
height: 8
|
||||
radius: 4
|
||||
visible: {
|
||||
if(index===0 || index===list_view.count-1)
|
||||
return false
|
||||
return true
|
||||
Loader{
|
||||
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
|
||||
}
|
||||
border.width: 1
|
||||
border.color: FluColors.Grey100
|
||||
color: list_view.currentIndex === index ? FluTheme.primaryColor.dark : Qt.rgba(1,1,1,0.5)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -121,12 +189,13 @@ Item {
|
||||
timer_anim.start()
|
||||
}
|
||||
}
|
||||
function setData(data){
|
||||
content_model.clear()
|
||||
content_model.append(data[data.length-1])
|
||||
content_model.append(data)
|
||||
content_model.append(data[0])
|
||||
list_view.currentIndex = 1
|
||||
|
||||
function changedIndex(index){
|
||||
d.flagXChanged = true
|
||||
timer_run.stop()
|
||||
list_view.currentIndex = index
|
||||
d.flagXChanged = false
|
||||
timer_run.restart()
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ Item {
|
||||
property int pageMode: FluNavigationViewType.Stack
|
||||
signal logoClicked
|
||||
id:control
|
||||
QtObject{
|
||||
Item{
|
||||
id:d
|
||||
property bool animDisabled:false
|
||||
property var stackItems: []
|
||||
@ -66,6 +66,11 @@ Item {
|
||||
}
|
||||
return data
|
||||
}
|
||||
function refreshWindow(){
|
||||
console.debug(Window.window.width)
|
||||
Window.window.width = Window.window.width-1
|
||||
Window.window.width = Window.window.width+1
|
||||
}
|
||||
}
|
||||
Component.onCompleted: {
|
||||
d.displayMode = Qt.binding(function(){
|
||||
@ -709,6 +714,11 @@ Item {
|
||||
NumberAnimation{
|
||||
duration: 167
|
||||
easing.type: Easing.OutCubic
|
||||
onRunningChanged: {
|
||||
if(!running){
|
||||
d.refreshWindow()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Behavior on x {
|
||||
@ -716,6 +726,11 @@ Item {
|
||||
NumberAnimation{
|
||||
duration: 167
|
||||
easing.type: Easing.OutCubic
|
||||
onRunningChanged: {
|
||||
if(!running){
|
||||
d.refreshWindow()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
visible: {
|
||||
|
101
src/imports/FluentUI/Controls/FluTour.qml
Normal file
101
src/imports/FluentUI/Controls/FluTour.qml
Normal file
@ -0,0 +1,101 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Window
|
||||
import FluentUI
|
||||
|
||||
Popup{
|
||||
|
||||
property var steps : []
|
||||
id:control
|
||||
padding: 0
|
||||
anchors.centerIn: Overlay.overlay
|
||||
width: d.window?.width
|
||||
height: d.window?.height
|
||||
|
||||
background: Item{}
|
||||
|
||||
contentItem: Item{}
|
||||
|
||||
|
||||
property int index: 0
|
||||
property var step : steps[index]
|
||||
property var target : step.target()
|
||||
|
||||
onVisibleChanged: {
|
||||
if(visible){
|
||||
index = 0
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Connections{
|
||||
target: d.window
|
||||
function onWidthChanged(){
|
||||
canvas.requestPaint()
|
||||
}
|
||||
function onHeightChanged(){
|
||||
canvas.requestPaint()
|
||||
}
|
||||
}
|
||||
|
||||
onIndexChanged: {
|
||||
canvas.requestPaint()
|
||||
}
|
||||
|
||||
Item{
|
||||
id:d
|
||||
property var window: Window.window
|
||||
property var pos:Qt.point(0,0)
|
||||
}
|
||||
|
||||
Canvas{
|
||||
id:canvas
|
||||
anchors.fill: parent
|
||||
onPaint: {
|
||||
d.pos = target.mapToItem(control,0,0)
|
||||
var ctx = canvas.getContext("2d");
|
||||
ctx.clearRect(0, 0, canvasSize.width, canvasSize.height);
|
||||
ctx.save()
|
||||
ctx.fillStyle = "#66000000"
|
||||
ctx.fillRect(0, 0, canvasSize.width, canvasSize.height)
|
||||
ctx.globalCompositeOperation = 'destination-out'
|
||||
ctx.fillStyle = 'black'
|
||||
console.debug(d.pos.x)
|
||||
ctx.fillRect(d.pos.x, d.pos.y, target.width, target.height)
|
||||
ctx.restore()
|
||||
}
|
||||
}
|
||||
|
||||
FluRectangle{
|
||||
radius: [5,5,5,5]
|
||||
width: 500
|
||||
height: 120
|
||||
x: Math.min(Math.max(0,d.pos.x+target.width/2-width/2),d.window?.width-width)
|
||||
y:d.pos.y+target.height+1
|
||||
FluFilledButton{
|
||||
property bool isEnd: control.index === steps.length-1
|
||||
anchors{
|
||||
right: parent.right
|
||||
bottom: parent.bottom
|
||||
rightMargin: 10
|
||||
bottomMargin: 10
|
||||
}
|
||||
text: isEnd ? "结束导览" :"下一步"
|
||||
onClicked: {
|
||||
if(isEnd){
|
||||
control.close()
|
||||
}else{
|
||||
control.index = control.index + 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function refresh(){
|
||||
canvas.requestPaint()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user