diff --git a/example/qml/Qt5/about.qml b/example/qml/Qt5/about.qml index 0de40d5..1abcd56 100644 --- a/example/qml/Qt5/about.qml +++ b/example/qml/Qt5/about.qml @@ -1,5 +1,6 @@ import QtQuick 2.15 import QtQuick.Layouts 1.11 +import QtQuick.Controls 2.15 import RibbonUI 1.0 RibbonWindow { diff --git a/example/qml/Qt5/example.qml b/example/qml/Qt5/example.qml index 3d2e508..fb7c4cd 100644 --- a/example/qml/Qt5/example.qml +++ b/example/qml/Qt5/example.qml @@ -13,81 +13,79 @@ RibbonWindow { property bool modernStyle: RibbonTheme.modernStyle RibbonTour{ id: tour - targetList: [ - { - title: qsTr("Tab Bar"), - text: qsTr("A tab bar for window, let user choose the controllers."), - target: tab_bar, - enter_func: ()=>{ - tab_bar.folded = false - tour.refresh(300) // Use it if has animation - } - }, - { - title: qsTr("Tab Bar Buttons"), - text: qsTr("Tool buttons at the top of tab bar."), - target: tab_bar_tool - }, - { - title: qsTr("Sliders"), - text: qsTr("Vertical/Horizental sliders with/without buttons."), - target: slider_layout, - enter_func: ()=>{ - tab_bar.setPage(0) - slider_with_btn.value = 70 - slider_without_btn.value = 70 - tour.refresh(500) - }, - exit_func: ()=>{ - slider_with_btn.value = 50 - slider_without_btn.value = 50 - } - }, - { - title: qsTr("Switch Buttons"), - text: qsTr("Switch buttons with/without background color or grabber text."), - target: switch_layout, - enter_func: ()=>btn_with_color_and_grabberText.checked = true, - exit_func: ()=>btn_with_color_and_grabberText.checked = false - }, - { - title: qsTr("CheckBoxs"), - text: qsTr("CheckBoxs with colorful background or with/without label text."), - target: checkbox_layout - }, - { - title: qsTr("Buttons"), - text: qsTr("Buttons with/without background or label text."), - target: button_layout, - enter_func: ()=>btn_without_bg_and_label.checked = true, - exit_func: ()=>btn_without_bg_and_label.checked = false - }, - { - title: qsTr("Push Buttons"), - text: qsTr("Push buttons with/without sub menu."), - target: pushbutton_layout - }, - { - title: qsTr("Line Edits"), - text: qsTr("Line edits with/without icon."), - target: lineedit_layout, - enter_func: ()=>{ - tab_bar.setPage(1) - lineedit_with_icon.text = "Line Edit with icon." - tour.refresh(300) - }, - exit_func: ()=>{ - tab_bar.setPage(0) - lineedit_with_icon.clear() - tour.refresh(400) - } - }, - { - title: qsTr("Bottom Bar"), - text: qsTr("A bottom bar for window."), - target: bottom_bar - }, - ] + RibbonTourItem{ + title: qsTr("Tab Bar") + text: qsTr("A tab bar for window, let user choose the controllers.") + target: tab_bar + enterFunc: ()=>{ + tab_bar.folded = false + tour.refresh(300) // Use it if has animation + } + } + RibbonTourItem{ + title: qsTr("Tab Bar Buttons") + text: qsTr("Tool buttons at the top of tab bar.") + target: tab_bar_tool + } + RibbonTourItem{ + title: qsTr("Sliders") + text: qsTr("Vertical/Horizental sliders with/without buttons.") + target: slider_layout + enterFunc: ()=>{ + tab_bar.setPage(0) + slider_with_btn.value = 70 + slider_without_btn.value = 70 + tour.refresh(500) + } + exitFunc: ()=>{ + slider_with_btn.value = 50 + slider_without_btn.value = 50 + } + } + RibbonTourItem{ + title: qsTr("Switch Buttons") + text: qsTr("Switch buttons with/without background color or grabber text.") + target: switch_layout + enterFunc: ()=>btn_with_color_and_grabberText.checked = true + exitFunc: ()=>btn_with_color_and_grabberText.checked = false + } + RibbonTourItem{ + title: qsTr("CheckBoxs") + text: qsTr("CheckBoxs with colorful background or with/without label text.") + target: checkbox_layout + } + RibbonTourItem{ + title: qsTr("Buttons") + text: qsTr("Buttons with/without background or label text.") + target: button_layout + enterFunc: ()=>btn_without_bg_and_label.checked = true + exitFunc: ()=>btn_without_bg_and_label.checked = false + } + RibbonTourItem{ + title: qsTr("Push Buttons") + text: qsTr("Push buttons with/without sub menu.") + target: pushbutton_layout + } + RibbonTourItem{ + title: qsTr("Line Edits") + text: qsTr("Line edits with/without icon.") + target: lineedit_layout + enterFunc: ()=>{ + tab_bar.setPage(1) + lineedit_with_icon.text = "Line Edit with icon." + tour.refresh(300) + } + exitFunc: ()=>{ + tab_bar.setPage(0) + lineedit_with_icon.clear() + tour.refresh(400) + } + } + RibbonTourItem{ + title: qsTr("Bottom Bar") + text: qsTr("A bottom bar for window.") + target: bottom_bar + } target: windowItems blurEnabled: true targetRect: Qt.rect(windowItems.x + x, windowItems.y + y, width, height) diff --git a/example/qml/Qt5/pages/SettingsMenuPage.qml b/example/qml/Qt5/pages/SettingsMenuPage.qml index 3c04137..26bfb86 100644 --- a/example/qml/Qt5/pages/SettingsMenuPage.qml +++ b/example/qml/Qt5/pages/SettingsMenuPage.qml @@ -1,6 +1,7 @@ import QtQuick 2.15 -import QtQuick.Controls 2.15 import QtQuick.Layouts 1.11 +import QtQuick.Controls 2.15 +import QtQuick.Window 2.15 import RibbonUI 1.0 RibbonBackStagePage{ @@ -87,5 +88,25 @@ RibbonBackStagePage{ } } } + RibbonBackStageGroup{ + Layout.alignment: Qt.AlignTop + Layout.preferredHeight: render_btn.height + 40 + Layout.fillWidth: true + groupName: qsTr("TitleBar") + RowLayout{ + RibbonText{ + text: qsTr("Show TitleBar Icon: ") + } + RibbonSwitchButton{ + text: "Icon" + grabberText: RibbonTheme.nativeText ? "Show" : "Hide" + checked: true + Layout.alignment: Qt.AlignHCenter + onClicked: { + Window.window.titleBar.titleIcon.visible = checked + } + } + } + } } } diff --git a/example/qml/Qt6/example.qml b/example/qml/Qt6/example.qml index d27c9d4..39a3b2c 100644 --- a/example/qml/Qt6/example.qml +++ b/example/qml/Qt6/example.qml @@ -13,81 +13,79 @@ RibbonWindow { property bool modernStyle: RibbonTheme.modernStyle RibbonTour{ id: tour - targetList: [ - { - title: qsTr("Tab Bar"), - text: qsTr("A tab bar for window, let user choose the controllers."), - target: tab_bar, - enter_func: ()=>{ - tab_bar.folded = false - tour.refresh(300) // Use it if has animation - } - }, - { - title: qsTr("Tab Bar Buttons"), - text: qsTr("Tool buttons at the top of tab bar."), - target: tab_bar_tool - }, - { - title: qsTr("Sliders"), - text: qsTr("Vertical/Horizental sliders with/without buttons."), - target: slider_layout, - enter_func: ()=>{ - tab_bar.setPage(0) - slider_with_btn.value = 70 - slider_without_btn.value = 70 - tour.refresh(500) - }, - exit_func: ()=>{ - slider_with_btn.value = 50 - slider_without_btn.value = 50 - } - }, - { - title: qsTr("Switch Buttons"), - text: qsTr("Switch buttons with/without background color or grabber text."), - target: switch_layout, - enter_func: ()=>btn_with_color_and_grabberText.checked = true, - exit_func: ()=>btn_with_color_and_grabberText.checked = false - }, - { - title: qsTr("CheckBoxs"), - text: qsTr("CheckBoxs with colorful background or with/without label text."), - target: checkbox_layout - }, - { - title: qsTr("Buttons"), - text: qsTr("Buttons with/without background or label text."), - target: button_layout, - enter_func: ()=>btn_without_bg_and_label.checked = true, - exit_func: ()=>btn_without_bg_and_label.checked = false - }, - { - title: qsTr("Push Buttons"), - text: qsTr("Push buttons with/without sub menu."), - target: pushbutton_layout - }, - { - title: qsTr("Line Edits"), - text: qsTr("Line edits with/without icon."), - target: lineedit_layout, - enter_func: ()=>{ - tab_bar.setPage(1) - lineedit_with_icon.text = "Line Edit with icon." - tour.refresh(300) - }, - exit_func: ()=>{ - tab_bar.setPage(0) - lineedit_with_icon.clear() - tour.refresh(400) - } - }, - { - title: qsTr("Bottom Bar"), - text: qsTr("A bottom bar for window."), - target: bottom_bar - }, - ] + RibbonTourItem{ + title: qsTr("Tab Bar") + text: qsTr("A tab bar for window, let user choose the controllers.") + target: tab_bar + enterFunc: ()=>{ + tab_bar.folded = false + tour.refresh(300) // Use it if has animation + } + } + RibbonTourItem{ + title: qsTr("Tab Bar Buttons") + text: qsTr("Tool buttons at the top of tab bar.") + target: tab_bar_tool + } + RibbonTourItem{ + title: qsTr("Sliders") + text: qsTr("Vertical/Horizental sliders with/without buttons.") + target: slider_layout + enterFunc: ()=>{ + tab_bar.setPage(0) + slider_with_btn.value = 70 + slider_without_btn.value = 70 + tour.refresh(500) + } + exitFunc: ()=>{ + slider_with_btn.value = 50 + slider_without_btn.value = 50 + } + } + RibbonTourItem{ + title: qsTr("Switch Buttons") + text: qsTr("Switch buttons with/without background color or grabber text.") + target: switch_layout + enterFunc: ()=>btn_with_color_and_grabberText.checked = true + exitFunc: ()=>btn_with_color_and_grabberText.checked = false + } + RibbonTourItem{ + title: qsTr("CheckBoxs") + text: qsTr("CheckBoxs with colorful background or with/without label text.") + target: checkbox_layout + } + RibbonTourItem{ + title: qsTr("Buttons") + text: qsTr("Buttons with/without background or label text.") + target: button_layout + enterFunc: ()=>btn_without_bg_and_label.checked = true + exitFunc: ()=>btn_without_bg_and_label.checked = false + } + RibbonTourItem{ + title: qsTr("Push Buttons") + text: qsTr("Push buttons with/without sub menu.") + target: pushbutton_layout + } + RibbonTourItem{ + title: qsTr("Line Edits") + text: qsTr("Line edits with/without icon.") + target: lineedit_layout + enterFunc: ()=>{ + tab_bar.setPage(1) + lineedit_with_icon.text = "Line Edit with icon." + tour.refresh(300) + } + exitFunc: ()=>{ + tab_bar.setPage(0) + lineedit_with_icon.clear() + tour.refresh(400) + } + } + RibbonTourItem{ + title: qsTr("Bottom Bar") + text: qsTr("A bottom bar for window.") + target: bottom_bar + } target: windowItems blurEnabled: true targetRect: Qt.rect(windowItems.x + x, windowItems.y + y, width, height) diff --git a/example/qml/Qt6/pages/SettingsMenuPage.qml b/example/qml/Qt6/pages/SettingsMenuPage.qml index 8646814..ed330d0 100644 --- a/example/qml/Qt6/pages/SettingsMenuPage.qml +++ b/example/qml/Qt6/pages/SettingsMenuPage.qml @@ -1,6 +1,7 @@ import QtQuick import QtQuick.Layouts import QtQuick.Controls +import QtQuick.Window import RibbonUI RibbonBackStagePage{ @@ -87,5 +88,25 @@ RibbonBackStagePage{ } } } + RibbonBackStageGroup{ + Layout.alignment: Qt.AlignTop + Layout.preferredHeight: render_btn.height + 40 + Layout.fillWidth: true + groupName: qsTr("TitleBar") + RowLayout{ + RibbonText{ + text: qsTr("Show TitleBar Icon: ") + } + RibbonSwitchButton{ + text: "Icon" + grabberText: RibbonTheme.nativeText ? "Show" : "Hide" + checked: true + Layout.alignment: Qt.AlignHCenter + onClicked: { + Window.window.titleBar.titleIcon.visible = checked + } + } + } + } } } diff --git a/lib_source/CMakeLists.txt b/lib_source/CMakeLists.txt index a2c01ad..de42fd3 100644 --- a/lib_source/CMakeLists.txt +++ b/lib_source/CMakeLists.txt @@ -39,7 +39,8 @@ set(qml_files RibbonTabBar.qml RibbonTabButton.qml RibbonView.qml RibbonScrollBar.qml RibbonWindow.qml RibbonMessage.qml RibbonMessageListView.qml RibbonTour.qml RibbonTourContent.qml RibbonBackStageView.qml RibbonBackStagePage.qml RibbonBackStageGroup.qml - RibbonRadioButton.qml RibbonBackStageMenuItem.qml RibbonObject.qml) + RibbonRadioButton.qml RibbonBackStageMenuItem.qml RibbonTourItem.qml + RibbonObject.qml) set(qml_prefix "qml/Qt${QT_VERSION_MAJOR}/") diff --git a/lib_source/qml/Qt5/RibbonTour.qml b/lib_source/qml/Qt5/RibbonTour.qml index 6da1ce2..1b43857 100644 --- a/lib_source/qml/Qt5/RibbonTour.qml +++ b/lib_source/qml/Qt5/RibbonTour.qml @@ -15,13 +15,14 @@ Popup { property string contentSource: "RibbonTourContent.qml" property var contentItems: undefined property bool destroyAfterClose: true - property var currentTarget: targetList ? targetList[0].target : parent + 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 @@ -33,7 +34,7 @@ Popup { y: (Overlay.overlay.height - height) / 2 closePolicy: Popup.NoAutoClose Overlay.modal:Rectangle{ - color: !RibbonTheme.isDarkMode ? Qt.rgba(255,255,255,0.5) : Qt.rgba(0,0,0,0.5) + color: !RibbonTheme.isDarkMode ? Qt.alpha("white", 0.5) : Qt.alpha("black", 0.5) } Overlay.modeless:Rectangle{ color:"transparent" @@ -85,7 +86,7 @@ Popup { Loader{ id: loader sourceComponent: contentSource ? undefined : contentItems - source: contentSource + source: targetList.length ? contentSource : "" onLoaded: { if (!control.args) return @@ -115,8 +116,8 @@ Popup { showTooltip: false enabled: popup.currentIndex onClicked: { - if(popup.targetList[popup.currentIndex].exit_func) - popup.targetList[popup.currentIndex].exit_func() + if(popup.targetList[popup.currentIndex].exitFunc) + popup.targetList[popup.currentIndex].exitFunc() popup.currentIndex-- popup.currentTarget = popup.targetList[popup.currentIndex].target } @@ -132,8 +133,8 @@ Popup { } else { - if(popup.targetList[popup.currentIndex].exit_func) - popup.targetList[popup.currentIndex].exit_func() + if(popup.targetList[popup.currentIndex].exitFunc) + popup.targetList[popup.currentIndex].exitFunc() popup.currentIndex++ popup.currentTarget = popup.targetList[popup.currentIndex].target } @@ -143,6 +144,24 @@ Popup { } } + 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 @@ -168,8 +187,8 @@ Popup { radius: 5 ShaderEffectSource { anchors.centerIn: parent - width: currentTarget.width - height: currentTarget.height + width: currentTarget ? currentTarget.width : 0 + height: currentTarget ? currentTarget.height : 0 sourceRect: Qt.rect(0, 0, currentTarget.width, currentTarget.height) sourceItem: currentTarget visible: popup.useHighlightOrRect @@ -208,9 +227,13 @@ Popup { onCurrentTargetChanged: { Qt.callLater(function() { + if(targetList.length<=0){ + popup.close() + return + } popup.update() - if(popup.targetList[popup.currentIndex].enter_func) - popup.targetList[popup.currentIndex].enter_func() + if(popup.targetList[popup.currentIndex].enterFunc) + popup.targetList[popup.currentIndex].enterFunc() }) } @@ -229,18 +252,24 @@ Popup { } onAboutToHide: { + if(targetList.length<=0){ + return + } rec.close() - if(popup.targetList[popup.currentIndex].exit_func) - popup.targetList[popup.currentIndex].exit_func() + 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[0].target + currentTarget = targetList.length ? targetList[0].target : parent currentIndex = 0 } diff --git a/lib_source/qml/Qt5/RibbonTourItem.qml b/lib_source/qml/Qt5/RibbonTourItem.qml new file mode 100644 index 0000000..17ecbc4 --- /dev/null +++ b/lib_source/qml/Qt5/RibbonTourItem.qml @@ -0,0 +1,12 @@ +import QtQuick 2.15 +import RibbonUI 1.0 + +RibbonObject { + id: control + required property string title + property string text + property var target + property var enterFunc + property var exitFunc + property_names: ['title','text','target','enterFunc','exitFunc'] +} diff --git a/lib_source/qml/Qt6/RibbonTour.qml b/lib_source/qml/Qt6/RibbonTour.qml index 041d1c2..5f74fc0 100644 --- a/lib_source/qml/Qt6/RibbonTour.qml +++ b/lib_source/qml/Qt6/RibbonTour.qml @@ -16,13 +16,14 @@ Popup { property string contentSource: "RibbonTourContent.qml" property var contentItems: undefined property bool destroyAfterClose: true - property var currentTarget: targetList ? targetList[0].target : parent + 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 @@ -86,7 +87,7 @@ Popup { Loader{ id: loader sourceComponent: contentSource ? undefined : contentItems - source: contentSource + source: targetList.length ? contentSource : "" onLoaded: { if (!control.args) return @@ -116,8 +117,8 @@ Popup { showTooltip: false enabled: popup.currentIndex onClicked: { - if(popup.targetList[popup.currentIndex].exit_func) - popup.targetList[popup.currentIndex].exit_func() + if(popup.targetList[popup.currentIndex].exitFunc) + popup.targetList[popup.currentIndex].exitFunc() popup.currentIndex-- popup.currentTarget = popup.targetList[popup.currentIndex].target } @@ -133,8 +134,8 @@ Popup { } else { - if(popup.targetList[popup.currentIndex].exit_func) - popup.targetList[popup.currentIndex].exit_func() + if(popup.targetList[popup.currentIndex].exitFunc) + popup.targetList[popup.currentIndex].exitFunc() popup.currentIndex++ popup.currentTarget = popup.targetList[popup.currentIndex].target } @@ -144,6 +145,24 @@ Popup { } } + 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 @@ -169,8 +188,8 @@ Popup { radius: 5 ShaderEffectSource { anchors.centerIn: parent - width: currentTarget.width - height: currentTarget.height + width: currentTarget ? currentTarget.width : 0 + height: currentTarget ? currentTarget.height : 0 sourceRect: Qt.rect(0, 0, currentTarget.width, currentTarget.height) sourceItem: currentTarget visible: popup.useHighlightOrRect @@ -209,9 +228,13 @@ Popup { onCurrentTargetChanged: { Qt.callLater(function() { + if(targetList.length<=0){ + popup.close() + return + } popup.update() - if(popup.targetList[popup.currentIndex].enter_func) - popup.targetList[popup.currentIndex].enter_func() + if(popup.targetList[popup.currentIndex].enterFunc) + popup.targetList[popup.currentIndex].enterFunc() }) } @@ -230,18 +253,24 @@ Popup { } onAboutToHide: { + if(targetList.length<=0){ + return + } rec.close() - if(popup.targetList[popup.currentIndex].exit_func) - popup.targetList[popup.currentIndex].exit_func() + 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[0].target + currentTarget = targetList.length ? targetList[0].target : parent currentIndex = 0 } diff --git a/lib_source/qml/Qt6/RibbonTourItem.qml b/lib_source/qml/Qt6/RibbonTourItem.qml new file mode 100644 index 0000000..0c92027 --- /dev/null +++ b/lib_source/qml/Qt6/RibbonTourItem.qml @@ -0,0 +1,12 @@ +import QtQuick +import RibbonUI + +RibbonObject { + id: control + required property string title + property string text + property var target + property var enterFunc + property var exitFunc + property_names: ['title','text','target','enterFunc','exitFunc'] +}