375 lines
12 KiB
QML
375 lines
12 KiB
QML
import QtQuick
|
|
import QtQuick.Layouts
|
|
import QtQuick.Controls
|
|
import QtQuick.Window
|
|
import RibbonUI
|
|
import Qt5Compat.GraphicalEffects
|
|
|
|
Popup {
|
|
id: popup
|
|
parent: Overlay.overlay
|
|
property var targetList: []
|
|
property bool blurEnabled: false
|
|
property alias target: blur.target
|
|
property alias targetRect: blur.targetRect
|
|
property alias radius: blur.radius
|
|
property string contentSource: "RibbonTourContent.qml"
|
|
property var contentItems: undefined
|
|
property bool destroyAfterClose: true
|
|
property var currentTarget: targetList.length ? targetList[0].target : parent
|
|
property int currentIndex: 0
|
|
property bool preferShowAbove: true
|
|
property bool useHighlightOrRect: true
|
|
property real contentEdgeMargin: 10
|
|
property alias contentArgs: control.args
|
|
property alias alwaysNotAutoPopup: always_hide_ckbox.checked
|
|
default property alias data: data_container.data
|
|
modal: true
|
|
margins: 0
|
|
padding: 0
|
|
topInset: 0
|
|
leftInset: 0
|
|
rightInset: 0
|
|
bottomInset: 0
|
|
x: (Overlay.overlay.width - width) / 2
|
|
y: (Overlay.overlay.height - height) / 2
|
|
closePolicy: Popup.NoAutoClose
|
|
Overlay.modal:Rectangle{
|
|
color: !RibbonTheme.isDarkMode ? Qt.alpha("white", 0.5) : Qt.alpha("black", 0.5)
|
|
}
|
|
Overlay.modeless:Rectangle{
|
|
color:"transparent"
|
|
}
|
|
background: Item{
|
|
RectangularGlow {
|
|
id: effect
|
|
anchors.fill: blur
|
|
anchors.margins: blur.maskBorderWidth
|
|
glowRadius: 10
|
|
spread: 0
|
|
color: RibbonTheme.isDarkMode ? Qt.rgba(0,0,0,0.7) : Qt.rgba(0,0,0,0.45)
|
|
cornerRadius: blur.radius + glowRadius + 10
|
|
}
|
|
RibbonBlur{
|
|
implicitHeight: parent.height
|
|
implicitWidth: parent.width
|
|
id: blur
|
|
radius: 7
|
|
maskOpacity: blurEnabled ? 0.9 : 1
|
|
maskBorderColor: RibbonTheme.modernStyle ?
|
|
RibbonTheme.isDarkMode ? "#7A7A7A" : "#2C59B7" :
|
|
RibbonTheme.isDarkMode ? "#5C5D5D" : "#B5B4B5"
|
|
maskBorderWidth: 1
|
|
}
|
|
}
|
|
contentItem: Item{
|
|
id: control
|
|
x:0
|
|
y:0
|
|
implicitHeight: container.height
|
|
implicitWidth: container.width
|
|
property var args
|
|
RibbonButton{
|
|
anchors{
|
|
top:parent.top
|
|
topMargin: 8
|
|
right:parent.right
|
|
rightMargin: anchors.topMargin
|
|
}
|
|
showBg: false
|
|
showHoveredBg: false
|
|
iconSource: RibbonIcons.Dismiss
|
|
onClicked: popup.close()
|
|
}
|
|
ColumnLayout{
|
|
id: container
|
|
spacing: 10
|
|
Loader{
|
|
id: loader
|
|
sourceComponent: contentSource ? undefined : contentItems
|
|
source: targetList.length ? contentSource : ""
|
|
onLoaded: {
|
|
if (!control.args)
|
|
return
|
|
else if(Object.keys(control.args).length){
|
|
for (let arg in control.args){
|
|
item[arg] = control.args[arg]
|
|
}
|
|
}
|
|
else{
|
|
console.error("RibbonTour: Arguments error, please check.")
|
|
}
|
|
}
|
|
}
|
|
RowLayout{
|
|
Layout.leftMargin: 10
|
|
Layout.rightMargin: Layout.leftMargin
|
|
Layout.bottomMargin: Layout.leftMargin
|
|
spacing: 20
|
|
RibbonCheckBox{
|
|
id: always_hide_ckbox
|
|
showTooltip: false
|
|
text: qsTr("Don't auto pop up")
|
|
}
|
|
RibbonButton{
|
|
id: previous_btn
|
|
text: qsTr("Previous")
|
|
showTooltip: false
|
|
enabled: popup.currentIndex
|
|
onClicked: {
|
|
if(popup.targetList[popup.currentIndex].exitFunc)
|
|
popup.targetList[popup.currentIndex].exitFunc()
|
|
popup.currentIndex--
|
|
popup.currentTarget = popup.targetList[popup.currentIndex].target
|
|
}
|
|
}
|
|
RibbonButton{
|
|
id: next_btn
|
|
text: (popup.currentIndex + 1) === popup.targetList.length ? qsTr("Finish") : qsTr("Next")
|
|
showTooltip: false
|
|
onClicked: {
|
|
if ((popup.currentIndex + 1) === popup.targetList.length)
|
|
{
|
|
popup.close()
|
|
}
|
|
else
|
|
{
|
|
if(popup.targetList[popup.currentIndex].exitFunc)
|
|
popup.targetList[popup.currentIndex].exitFunc()
|
|
popup.currentIndex++
|
|
popup.currentTarget = popup.targetList[popup.currentIndex].target
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Item{
|
|
id: data_container
|
|
}
|
|
|
|
Component.onCompleted: {
|
|
for(let index = targetList.length; index < data_container.resources.length; index++)
|
|
{
|
|
if(data_container.resources[index] instanceof RibbonTourItem)
|
|
{
|
|
let item = data_container.resources[index]
|
|
item.getPropertiesReady()
|
|
targetList.push(item.properties)
|
|
}
|
|
}
|
|
if(targetList.length)
|
|
targetListChanged()
|
|
}
|
|
|
|
Popup{
|
|
id: rec
|
|
parent: Overlay.overlay
|
|
margins: 0
|
|
padding: 0
|
|
topInset: 0
|
|
leftInset: 0
|
|
rightInset: 0
|
|
bottomInset: 0
|
|
closePolicy: Popup.NoAutoClose
|
|
property int borderWidth: popup.useHighlightOrRect ? 0 : 3
|
|
Overlay.modal:Rectangle{
|
|
color:"transparent"
|
|
}
|
|
Overlay.modeless:Rectangle{
|
|
color:"transparent"
|
|
}
|
|
background: Item{}
|
|
contentItem:Rectangle{
|
|
color: 'transparent'
|
|
border.width: rec.borderWidth
|
|
border.color: RibbonTheme.isDarkMode ? "#3B69DA" : "#2C59B7"
|
|
radius: 5
|
|
ShaderEffectSource {
|
|
anchors.centerIn: parent
|
|
width: currentTarget ? currentTarget.width : 0
|
|
height: currentTarget ? currentTarget.height : 0
|
|
sourceRect: Qt.rect(0, 0, currentTarget.width, currentTarget.height)
|
|
sourceItem: currentTarget
|
|
visible: popup.useHighlightOrRect
|
|
}
|
|
}
|
|
Behavior on x {
|
|
enabled: !popup.useHighlightOrRect
|
|
NumberAnimation {
|
|
id: ani
|
|
duration: 300
|
|
easing.type: Easing.OutSine
|
|
}
|
|
}
|
|
Behavior on y {
|
|
enabled: !popup.useHighlightOrRect
|
|
NumberAnimation {
|
|
duration: 300
|
|
easing.type: Easing.OutSine
|
|
}
|
|
}
|
|
Behavior on contentWidth {
|
|
enabled: !popup.useHighlightOrRect
|
|
NumberAnimation {
|
|
duration: 300
|
|
easing.type: Easing.OutSine
|
|
}
|
|
}
|
|
Behavior on contentHeight {
|
|
enabled: !popup.useHighlightOrRect
|
|
NumberAnimation {
|
|
duration: 300
|
|
easing.type: Easing.OutSine
|
|
}
|
|
}
|
|
}
|
|
|
|
onCurrentTargetChanged: {
|
|
Qt.callLater(function() {
|
|
if(targetList.length<=0){
|
|
popup.close()
|
|
return
|
|
}
|
|
popup.update()
|
|
if(popup.targetList[popup.currentIndex].enterFunc)
|
|
popup.targetList[popup.currentIndex].enterFunc()
|
|
})
|
|
}
|
|
|
|
Behavior on x {
|
|
NumberAnimation {
|
|
duration: 300
|
|
easing.type: Easing.OutSine
|
|
}
|
|
}
|
|
|
|
Behavior on y {
|
|
NumberAnimation {
|
|
duration: 300
|
|
easing.type: Easing.OutSine
|
|
}
|
|
}
|
|
|
|
onAboutToHide: {
|
|
if(targetList.length<=0){
|
|
return
|
|
}
|
|
rec.close()
|
|
if(popup.targetList[popup.currentIndex].exitFunc)
|
|
popup.targetList[popup.currentIndex].exitFunc()
|
|
loader.sourceComponent = undefined
|
|
loader.source = ""
|
|
}
|
|
|
|
onAboutToShow: {
|
|
if(targetList.length<=0){
|
|
return
|
|
}
|
|
loader.sourceComponent = contentSource ? undefined : contentItems
|
|
loader.source = contentSource
|
|
rec.open()
|
|
currentTarget = targetList.length ? targetList[0].target : parent
|
|
currentIndex = 0
|
|
}
|
|
|
|
enter: Transition {
|
|
NumberAnimation {
|
|
properties: "scale"
|
|
from:0.5
|
|
to:1
|
|
duration: 100
|
|
easing.type: Easing.OutSine
|
|
}
|
|
NumberAnimation {
|
|
property: "opacity"
|
|
duration: 100
|
|
from:0
|
|
to:1
|
|
easing.type: Easing.OutSine
|
|
}
|
|
}
|
|
exit:Transition {
|
|
NumberAnimation {
|
|
properties: "scale"
|
|
from:1
|
|
to:0.5
|
|
duration: 100
|
|
easing.type: Easing.OutSine
|
|
}
|
|
NumberAnimation {
|
|
property: "opacity"
|
|
duration: 100
|
|
from:1
|
|
to:0
|
|
easing.type: Easing.OutSine
|
|
}
|
|
}
|
|
|
|
Timer{
|
|
id: refresh_timer
|
|
interval: 200
|
|
repeat: false
|
|
triggeredOnStart: false
|
|
onTriggered: Qt.callLater(()=>{
|
|
popup.update()
|
|
rec.visible = true
|
|
})
|
|
}
|
|
|
|
function getX()
|
|
{
|
|
let targetX = currentTarget.mapToGlobal(0,0).x
|
|
let showX = (targetX + currentTarget.width/2) - (width/2)
|
|
showX = Overlay.overlay.mapFromGlobal(showX,0).x
|
|
if(showX < contentEdgeMargin)
|
|
return contentEdgeMargin
|
|
if((showX + width + contentEdgeMargin) >Overlay.overlay.width)
|
|
return Overlay.overlay.width - width - contentEdgeMargin
|
|
return showX
|
|
}
|
|
|
|
function getY()
|
|
{
|
|
let targetY = currentTarget.mapToGlobal(0,0).y
|
|
let showY = targetY + (preferShowAbove ? - height - contentEdgeMargin : currentTarget.height + contentEdgeMargin)
|
|
let sub_showY = targetY + (preferShowAbove ? currentTarget.height + contentEdgeMargin : - height - contentEdgeMargin)
|
|
showY = Overlay.overlay.mapFromGlobal(0,showY).y
|
|
sub_showY = Overlay.overlay.mapFromGlobal(0,sub_showY).y
|
|
if(showY < 30)
|
|
{
|
|
if (sub_showY < 30)
|
|
return 30
|
|
else
|
|
return sub_showY
|
|
}
|
|
if((showY + height + contentEdgeMargin) > Overlay.overlay.height)
|
|
{
|
|
if ((sub_showY + height + contentEdgeMargin) > Overlay.overlay.height)
|
|
return Overlay.overlay.height - height - contentEdgeMargin
|
|
else
|
|
return sub_showY
|
|
}
|
|
return showY
|
|
}
|
|
|
|
function refresh(delay)
|
|
{
|
|
rec.visible = false
|
|
if(typeof(delay) != 'undefined')
|
|
refresh_timer.interval = delay
|
|
refresh_timer.start()
|
|
}
|
|
|
|
function update()
|
|
{
|
|
popup.x = getX()
|
|
popup.y = getY()
|
|
rec.x = Overlay.overlay.mapFromGlobal(currentTarget.mapToGlobal(0,0).x,0).x - rec.borderWidth*2
|
|
rec.y = Overlay.overlay.mapFromGlobal(0, currentTarget.mapToGlobal(0,0).y).y - rec.borderWidth*2
|
|
rec.contentWidth = currentTarget.width + rec.borderWidth*4
|
|
rec.contentHeight = currentTarget.height + rec.borderWidth*4
|
|
}
|
|
}
|