diff --git a/example/qml/page/T_Tour.qml b/example/qml/page/T_Tour.qml index fdba734c..2003016a 100644 --- a/example/qml/page/T_Tour.qml +++ b/example/qml/page/T_Tour.qml @@ -16,7 +16,6 @@ FluScrollablePage{ {title:"Save",description: "Save your changes.",target:()=>btn_save}, {title:"Other Actions",description: "Click to see other actions.",target:()=>btn_more} ] - } FluArea{ @@ -45,14 +44,23 @@ FluScrollablePage{ FluButton{ id:btn_upload text:"Upload" + onClicked: { + showInfo("Upload") + } } FluFilledButton{ id:btn_save text:"Save" + onClicked: { + showInfo("Save") + } } FluIconButton{ id:btn_more iconSource: FluentIcons.More + onClicked: { + showInfo("More") + } } } } diff --git a/example/qml/window/MainWindow.qml b/example/qml/window/MainWindow.qml index 721f255c..80e3c47e 100644 --- a/example/qml/window/MainWindow.qml +++ b/example/qml/window/MainWindow.qml @@ -27,6 +27,7 @@ CustomWindow { Component.onCompleted: { FluTools.setQuitOnLastWindowClosed(false) + tour.open() } SystemTrayIcon { @@ -175,7 +176,8 @@ CustomWindow { title:"FluentUI" onLogoClicked:{ clickCount += 1 - if(clickCount === 1){ + showSuccess("点击%1次".arg(clickCount)) + if(clickCount === 5){ loader.reload() flipable.flipped = true clickCount = 0 @@ -259,4 +261,12 @@ CustomWindow { } } + FluTour{ + id:tour + steps:[ + {title:"夜间模式",description: "这里可以切换夜间模式.",target:()=>app_bar_front.darkButton()}, + {title:"隐藏彩蛋",description: "多点几下试试!!",target:()=>nav_view.logoButton()} + ] + } + } diff --git a/src/imports/FluentUI/Controls/FluNavigationView.qml b/src/imports/FluentUI/Controls/FluNavigationView.qml index 3547e877..5a2d4518 100644 --- a/src/imports/FluentUI/Controls/FluNavigationView.qml +++ b/src/imports/FluentUI/Controls/FluNavigationView.qml @@ -67,7 +67,6 @@ Item { return data } function refreshWindow(){ - console.debug(Window.window.width) Window.window.width = Window.window.width-1 Window.window.width = Window.window.width+1 } @@ -1125,4 +1124,7 @@ Item { function navButton(){ return btn_nav } + function logoButton(){ + return image_logo + } } diff --git a/src/imports/FluentUI/Controls/FluRectangle.qml b/src/imports/FluentUI/Controls/FluRectangle.qml index 9b324204..9882a2e3 100644 --- a/src/imports/FluentUI/Controls/FluRectangle.qml +++ b/src/imports/FluentUI/Controls/FluRectangle.qml @@ -40,27 +40,27 @@ Item{ anchors.fill: parent visible: false onPaint: { - var ctx = getContext("2d"); - var x = 0; - var y = 0; - var w = control.width; - var h = control.height; - ctx.clearRect(0, 0, canvas.width, canvas.height); - ctx.save(); + var ctx = getContext("2d") + var x = 0 + var y = 0 + var w = control.width + var h = control.height + ctx.clearRect(0, 0, canvas.width, canvas.height) + ctx.save() ctx.beginPath(); - ctx.moveTo(x + radius[0], y); - ctx.lineTo(x + w - radius[1], y); - ctx.arcTo(x + w, y, x + w, y + radius[1], radius[1]); - ctx.lineTo(x + w, y + h - radius[2]); - ctx.arcTo(x + w, y + h, x + w - radius[2], y + h, radius[2]); - ctx.lineTo(x + radius[3], y + h); - ctx.arcTo(x, y + h, x, y + h - radius[3], radius[3]); - ctx.lineTo(x, y + radius[0]); - ctx.arcTo(x, y, x + radius[0], y, radius[0]); - ctx.closePath(); - ctx.fillStyle = control.color; - ctx.fill(); - ctx.restore(); + ctx.moveTo(x + radius[0], y) + ctx.lineTo(x + w - radius[1], y) + ctx.arcTo(x + w, y, x + w, y + radius[1], radius[1]) + ctx.lineTo(x + w, y + h - radius[2]) + ctx.arcTo(x + w, y + h, x + w - radius[2], y + h, radius[2]) + ctx.lineTo(x + radius[3], y + h) + ctx.arcTo(x, y + h, x, y + h - radius[3], radius[3]) + ctx.lineTo(x, y + radius[0]) + ctx.arcTo(x, y, x + radius[0], y, radius[0]) + ctx.closePath() + ctx.fillStyle = "#000000" + ctx.fill() + ctx.restore() } } OpacityMask { diff --git a/src/imports/FluentUI/Controls/FluTour.qml b/src/imports/FluentUI/Controls/FluTour.qml index 5e005333..b176d838 100644 --- a/src/imports/FluentUI/Controls/FluTour.qml +++ b/src/imports/FluentUI/Controls/FluTour.qml @@ -1,85 +1,33 @@ import QtQuick import QtQuick.Controls +import QtQuick.Shapes import QtQuick.Window import FluentUI Popup{ - property var steps : [] + property int targetMargins: 5 + property Component nextButton: com_next_button + property Component prevButton: com_prev_button + property int index : 0 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 + control.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 + Component{ + id:com_next_button 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){ @@ -90,12 +38,141 @@ Popup{ } } } - - - function refresh(){ - canvas.requestPaint() + Component{ + id:com_prev_button + FluButton{ + text: "上一步" + onClicked: { + control.index = control.index - 1 + } + } + } + Item{ + id:d + property var window: Window.window + property var pos:Qt.point(0,0) + property var step : steps[index] + property var target : step.target() + } + Connections{ + target: d.window + function onWidthChanged(){ + canvas.requestPaint() + } + function onHeightChanged(){ + canvas.requestPaint() + } + } + Canvas{ + id:canvas + anchors.fill: parent + onPaint: { + d.pos = d.target.mapToItem(control,0,0) + var ctx = canvas.getContext("2d") + ctx.clearRect(0, 0, canvasSize.width, canvasSize.height) + ctx.save() + ctx.fillStyle = "#88000000" + ctx.fillRect(0, 0, canvasSize.width, canvasSize.height) + ctx.globalCompositeOperation = 'destination-out' + ctx.fillStyle = 'black' + drawRoundedRect(Qt.rect(d.pos.x-control.targetMargins,d.pos.y-control.targetMargins, d.target.width+control.targetMargins*2, d.target.height+control.targetMargins*2),2,ctx) + ctx.restore() + } + function drawRoundedRect(rect, r, ctx) { + var ptA = Qt.point(rect.x + r, rect.y) + var ptB = Qt.point(rect.x + rect.width, rect.y) + var ptC = Qt.point(rect.x + rect.width, rect.y + rect.height) + var ptD = Qt.point(rect.x, rect.y + rect.height) + var ptE = Qt.point(rect.x, rect.y) + ctx.beginPath() + ctx.moveTo(ptA.x, ptA.y) + ctx.arcTo(ptB.x, ptB.y, ptC.x, ptC.y, r) + ctx.arcTo(ptC.x, ptC.y, ptD.x, ptD.y, r) + ctx.arcTo(ptD.x, ptD.y, ptE.x, ptE.y, r) + ctx.arcTo(ptE.x, ptE.y, ptA.x, ptA.y, r) + ctx.fill() + ctx.closePath() + } } + FluArea{ + id:layout_panne + radius: 5 + width: 500 + height: 88 + text_desc.height + color: FluTheme.dark ? Qt.rgba(39/255,39/255,39/255,1) : Qt.rgba(251/255,251/255,253/255,1) + x: Math.min(Math.max(0,d.pos.x+d.target.width/2-width/2),d.window?.width-width) + y: d.pos.y+d.target.height+control.targetMargins + 15 + border.width: 0 + FluText{ + text: d.step.title + font: FluTextStyle.BodyStrong + elide: Text.ElideRight + anchors{ + top: parent.top + left: parent.left + topMargin: 15 + leftMargin: 15 + right: parent.right + rightMargin: 32 + } + } + FluText{ + id:text_desc + font: FluTextStyle.Body + wrapMode: Text.WrapAnywhere + maximumLineCount: 4 + elide: Text.ElideRight + text: d.step.description + anchors{ + top: parent.top + left: parent.left + right: parent.right + rightMargin: 15 + topMargin: 42 + leftMargin: 15 + } + } + Loader{ + id:loader_next + property bool isEnd: control.index === steps.length-1 + sourceComponent: com_next_button + anchors{ + top:text_desc.bottom + topMargin: 10 + right: parent.right + rightMargin: 15 + } + } + Loader{ + id:loader_prev + visible: control.index !== 0 + sourceComponent: com_prev_button + anchors{ + right:loader_next.left + top: loader_next.top + rightMargin: 14 + } + } + FluIconButton{ + anchors{ + right: parent.right + top: parent.top + margins: 10 + } + width: 20 + height: 20 + iconSize: 12 + iconSource : FluentIcons.ChromeClose + onClicked: { + control.close() + } + } + } + FluIcon{ + iconSource: FluentIcons.FlickDown + color: layout_panne.color + x: d.pos.x+d.target.width/2-10 + y: d.pos.y+d.target.height + } } - -