Compare commits
5 Commits
c0a05c1a99
...
c53aa3b927
Author | SHA1 | Date |
---|---|---|
|
c53aa3b927 | |
|
01e20c3fd3 | |
|
0912dc3937 | |
|
94e6417845 | |
|
1ce411be5e |
|
@ -777,5 +777,29 @@ RibbonTabBar {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
RibbonTabGroup{
|
||||||
|
width: messagebar_layout.width + 30
|
||||||
|
text: qsTr("MessageBar")
|
||||||
|
ColumnLayout{
|
||||||
|
id: messagebar_layout
|
||||||
|
anchors.centerIn: parent
|
||||||
|
height: parent.height
|
||||||
|
spacing: 10
|
||||||
|
RibbonButton{
|
||||||
|
text: qsTr("Generate One Message")
|
||||||
|
iconSource: RibbonIcons.Add
|
||||||
|
onClicked: {
|
||||||
|
messageBar.showMessage(Math.floor(Math.random()*6), "test"+Math.floor(Math.random()*6))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RibbonButton{
|
||||||
|
text: qsTr("Clear All Messages")
|
||||||
|
iconSource: RibbonIcons.DismissCircle
|
||||||
|
onClicked: {
|
||||||
|
messageBar.clearMessages()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,57 @@ RibbonWindow {
|
||||||
title: qsTr("RibbonUI APP")
|
title: qsTr("RibbonUI APP")
|
||||||
comfirmedQuit: true
|
comfirmedQuit: true
|
||||||
property bool modernStyle: RibbonTheme.modernStyle
|
property bool modernStyle: RibbonTheme.modernStyle
|
||||||
|
RibbonMessageBarGroup{
|
||||||
|
id: msg_bar
|
||||||
|
implicitWidth: windowItems.width
|
||||||
|
x: windowItems.x
|
||||||
|
y: titleBar.height + tab_bar.y + tab_bar.height - tab_bar.modernMargin + (RibbonTheme.modernStyle ? 5 : 0)
|
||||||
|
target: windowItems
|
||||||
|
Component.onCompleted: {
|
||||||
|
messageModel.append([{
|
||||||
|
type: RibbonMessageBar.Info,
|
||||||
|
text: "Info (default) MessageBar."
|
||||||
|
},{
|
||||||
|
type: RibbonMessageBar.Warning,
|
||||||
|
text: "Warning defaults to multiline. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi luctus, purus a lobortis tristique, odio augue pharetra metus, ac placerat nunc mi nec dui. Vestibulum aliquam et nunc semper scelerisque. Curabitur vitae orci nec quam condimentum porttitor et sed lacus. Vivamus ac efficitur leo. Cras faucibus mauris libero, ac placerat erat euismod et. Donec pulvinar commodo odio sit amet faucibus. In hac habitasse platea dictumst. Duis eu ante commodo, condimentum nibh pellentesque, laoreet enim. Fusce massa lorem, ultrices eu mi a, fermentum suscipit magna. Integer porta purus pulvinar, hendrerit felis eget, condimentum mauris.Visit our website.",
|
||||||
|
actionALabel: "Yes",
|
||||||
|
actionBLabel: "No",
|
||||||
|
externalURL: "https://github.com/mentalfl0w/RibbonUI",
|
||||||
|
externalURLLabel: "Visit our website."
|
||||||
|
},{
|
||||||
|
type: RibbonMessageBar.Warning,
|
||||||
|
text: "Warning MessageBar content.",
|
||||||
|
actionALabel: "Action",
|
||||||
|
externalURL: "https://github.com/mentalfl0w/RibbonUI",
|
||||||
|
externalURLLabel: "Visit our website.",
|
||||||
|
disableMultiline: true
|
||||||
|
},{
|
||||||
|
type: RibbonMessageBar.SevereWarning,
|
||||||
|
text: "SevereWarning MessageBar with action buttons which defaults to multiline.",
|
||||||
|
actionALabel: "Yes",
|
||||||
|
actionBLabel: "No",
|
||||||
|
externalURL: "https://github.com/mentalfl0w/RibbonUI",
|
||||||
|
externalURLLabel: "Visit our website.",
|
||||||
|
},{
|
||||||
|
type: RibbonMessageBar.Blocked,
|
||||||
|
text: "Blocked MessageBar - single line, with dismiss button and truncated text. Truncation is not available if you use action buttons or multiline and should be used sparingly. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi luctus, purus a lobortis tristique, odio augue pharetra metus, ac placerat nunc mi nec dui. Vestibulum aliquam et nunc semper scelerisque. Curabitur vitae orci nec quam condimentum porttitor et sed lacus. Vivamus ac efficitur leo. Cras faucibus mauris libero, ac placerat erat euismod et. Donec pulvinar commodo odio sit amet faucibus. In hac habitasse platea dictumst. Duis eu ante commodo, condimentum nibh pellentesque, laoreet enim. Fusce massa lorem, ultrices eu mi a, fermentum suscipit magna. Integer porta purus pulvinar, hendrerit felis eget, condimentum mauris.",
|
||||||
|
},{
|
||||||
|
type: RibbonMessageBar.Success,
|
||||||
|
text: "Success MessageBar with single line and action buttons.",
|
||||||
|
actionALabel: "Yes",
|
||||||
|
actionBLabel: "No",
|
||||||
|
externalURL: "https://github.com/mentalfl0w/RibbonUI",
|
||||||
|
externalURLLabel: "Visit our website."
|
||||||
|
},{
|
||||||
|
type: RibbonMessageBar.Error,
|
||||||
|
text: "Error MessageBar with single line, with dismiss button.",
|
||||||
|
externalURL: "https://github.com/mentalfl0w/RibbonUI",
|
||||||
|
externalURLLabel: "Visit our website."
|
||||||
|
}])
|
||||||
|
messageBar.showMessage(RibbonMessageBar.Info, "test")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
RibbonTour{
|
RibbonTour{
|
||||||
id: tour
|
id: tour
|
||||||
RibbonTourItem{
|
RibbonTourItem{
|
||||||
|
@ -106,6 +157,7 @@ RibbonWindow {
|
||||||
pageWidth: (page_slider.value / 100.0) * width
|
pageWidth: (page_slider.value / 100.0) * width
|
||||||
spacing: 0
|
spacing: 0
|
||||||
isMainView: true
|
isMainView: true
|
||||||
|
topBorderFix: msg_bar.folded ? msg_bar.barHeight : 0
|
||||||
ColumnLayout{
|
ColumnLayout{
|
||||||
Layout.alignment: Qt.AlignCenter
|
Layout.alignment: Qt.AlignCenter
|
||||||
Layout.topMargin: 30
|
Layout.topMargin: 30
|
||||||
|
|
|
@ -777,5 +777,29 @@ RibbonTabBar {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
RibbonTabGroup{
|
||||||
|
width: messagebar_layout.width + 30
|
||||||
|
text: qsTr("MessageBar")
|
||||||
|
ColumnLayout{
|
||||||
|
id: messagebar_layout
|
||||||
|
anchors.centerIn: parent
|
||||||
|
height: parent.height
|
||||||
|
spacing: 10
|
||||||
|
RibbonButton{
|
||||||
|
text: qsTr("Generate One Message")
|
||||||
|
iconSource: RibbonIcons.Add
|
||||||
|
onClicked: {
|
||||||
|
messageBar.showMessage(Math.floor(Math.random()*6), "test"+Math.floor(Math.random()*6))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RibbonButton{
|
||||||
|
text: qsTr("Clear All Messages")
|
||||||
|
iconSource: RibbonIcons.DismissCircle
|
||||||
|
onClicked: {
|
||||||
|
messageBar.clearMessages()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,57 @@ RibbonWindow {
|
||||||
title: qsTr("RibbonUI APP")
|
title: qsTr("RibbonUI APP")
|
||||||
comfirmedQuit: true
|
comfirmedQuit: true
|
||||||
property bool modernStyle: RibbonTheme.modernStyle
|
property bool modernStyle: RibbonTheme.modernStyle
|
||||||
|
RibbonMessageBarGroup{
|
||||||
|
id: msg_bar
|
||||||
|
implicitWidth: windowItems.width
|
||||||
|
x: windowItems.x
|
||||||
|
y: titleBar.height + tab_bar.y + tab_bar.height - tab_bar.modernMargin + (RibbonTheme.modernStyle ? 5 : 0)
|
||||||
|
target: windowItems
|
||||||
|
Component.onCompleted: {
|
||||||
|
messageModel.append([{
|
||||||
|
type: RibbonMessageBar.Info,
|
||||||
|
text: "Info (default) MessageBar."
|
||||||
|
},{
|
||||||
|
type: RibbonMessageBar.Warning,
|
||||||
|
text: "Warning defaults to multiline. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi luctus, purus a lobortis tristique, odio augue pharetra metus, ac placerat nunc mi nec dui. Vestibulum aliquam et nunc semper scelerisque. Curabitur vitae orci nec quam condimentum porttitor et sed lacus. Vivamus ac efficitur leo. Cras faucibus mauris libero, ac placerat erat euismod et. Donec pulvinar commodo odio sit amet faucibus. In hac habitasse platea dictumst. Duis eu ante commodo, condimentum nibh pellentesque, laoreet enim. Fusce massa lorem, ultrices eu mi a, fermentum suscipit magna. Integer porta purus pulvinar, hendrerit felis eget, condimentum mauris.Visit our website.",
|
||||||
|
actionALabel: "Yes",
|
||||||
|
actionBLabel: "No",
|
||||||
|
externalURL: "https://github.com/mentalfl0w/RibbonUI",
|
||||||
|
externalURLLabel: "Visit our website."
|
||||||
|
},{
|
||||||
|
type: RibbonMessageBar.Warning,
|
||||||
|
text: "Warning MessageBar content.",
|
||||||
|
actionALabel: "Action",
|
||||||
|
externalURL: "https://github.com/mentalfl0w/RibbonUI",
|
||||||
|
externalURLLabel: "Visit our website.",
|
||||||
|
disableMultiline: true
|
||||||
|
},{
|
||||||
|
type: RibbonMessageBar.SevereWarning,
|
||||||
|
text: "SevereWarning MessageBar with action buttons which defaults to multiline.",
|
||||||
|
actionALabel: "Yes",
|
||||||
|
actionBLabel: "No",
|
||||||
|
externalURL: "https://github.com/mentalfl0w/RibbonUI",
|
||||||
|
externalURLLabel: "Visit our website.",
|
||||||
|
},{
|
||||||
|
type: RibbonMessageBar.Blocked,
|
||||||
|
text: "Blocked MessageBar - single line, with dismiss button and truncated text. Truncation is not available if you use action buttons or multiline and should be used sparingly. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi luctus, purus a lobortis tristique, odio augue pharetra metus, ac placerat nunc mi nec dui. Vestibulum aliquam et nunc semper scelerisque. Curabitur vitae orci nec quam condimentum porttitor et sed lacus. Vivamus ac efficitur leo. Cras faucibus mauris libero, ac placerat erat euismod et. Donec pulvinar commodo odio sit amet faucibus. In hac habitasse platea dictumst. Duis eu ante commodo, condimentum nibh pellentesque, laoreet enim. Fusce massa lorem, ultrices eu mi a, fermentum suscipit magna. Integer porta purus pulvinar, hendrerit felis eget, condimentum mauris.",
|
||||||
|
},{
|
||||||
|
type: RibbonMessageBar.Success,
|
||||||
|
text: "Success MessageBar with single line and action buttons.",
|
||||||
|
actionALabel: "Yes",
|
||||||
|
actionBLabel: "No",
|
||||||
|
externalURL: "https://github.com/mentalfl0w/RibbonUI",
|
||||||
|
externalURLLabel: "Visit our website."
|
||||||
|
},{
|
||||||
|
type: RibbonMessageBar.Error,
|
||||||
|
text: "Error MessageBar with single line, with dismiss button.",
|
||||||
|
externalURL: "https://github.com/mentalfl0w/RibbonUI",
|
||||||
|
externalURLLabel: "Visit our website."
|
||||||
|
}])
|
||||||
|
messageBar.showMessage(RibbonMessageBar.Info, "test")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
RibbonTour{
|
RibbonTour{
|
||||||
id: tour
|
id: tour
|
||||||
RibbonTourItem{
|
RibbonTourItem{
|
||||||
|
@ -106,6 +157,7 @@ RibbonWindow {
|
||||||
pageWidth: (page_slider.value / 100.0) * width
|
pageWidth: (page_slider.value / 100.0) * width
|
||||||
spacing: 0
|
spacing: 0
|
||||||
isMainView: true
|
isMainView: true
|
||||||
|
topBorderFix: msg_bar.folded ? msg_bar.barHeight : 0
|
||||||
ColumnLayout{
|
ColumnLayout{
|
||||||
Layout.alignment: Qt.AlignCenter
|
Layout.alignment: Qt.AlignCenter
|
||||||
Layout.topMargin: 30
|
Layout.topMargin: 30
|
||||||
|
|
|
@ -47,7 +47,8 @@ set(qml_files
|
||||||
RibbonBackStageView.qml RibbonBackStagePage.qml RibbonBackStageGroup.qml
|
RibbonBackStageView.qml RibbonBackStagePage.qml RibbonBackStageGroup.qml
|
||||||
RibbonRadioButton.qml RibbonBackStageMenuItem.qml RibbonTourItem.qml
|
RibbonRadioButton.qml RibbonBackStageMenuItem.qml RibbonTourItem.qml
|
||||||
RibbonObject.qml RibbonProgressBar.qml RibbonProgressRing.qml
|
RibbonObject.qml RibbonProgressBar.qml RibbonProgressRing.qml
|
||||||
RibbonBusyBar.qml RibbonBusyRing.qml RibbonPageIndicator.qml)
|
RibbonBusyBar.qml RibbonBusyRing.qml RibbonPageIndicator.qml
|
||||||
|
RibbonMessageBar.qml RibbonMessageBarGroup.qml)
|
||||||
|
|
||||||
# Set the QML prefix path
|
# Set the QML prefix path
|
||||||
set(qml_prefix "qml/Qt${QT_VERSION_MAJOR}/")
|
set(qml_prefix "qml/Qt${QT_VERSION_MAJOR}/")
|
||||||
|
|
|
@ -4,6 +4,7 @@ import RibbonUI 1.0
|
||||||
|
|
||||||
RibbonRectangle {
|
RibbonRectangle {
|
||||||
id: control
|
id: control
|
||||||
|
property bool enableEffect: true
|
||||||
property int blurRadius: 32
|
property int blurRadius: 32
|
||||||
property alias target: effect.sourceItem
|
property alias target: effect.sourceItem
|
||||||
property rect targetRect : Qt.rect(control.x, control.y, control.width, control.height)
|
property rect targetRect : Qt.rect(control.x, control.y, control.width, control.height)
|
||||||
|
@ -18,7 +19,7 @@ RibbonRectangle {
|
||||||
id: effect
|
id: effect
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
sourceRect: control.targetRect
|
sourceRect: control.targetRect
|
||||||
visible: false
|
visible: !enableEffect
|
||||||
}
|
}
|
||||||
|
|
||||||
GaussianBlur{
|
GaussianBlur{
|
||||||
|
@ -28,6 +29,7 @@ RibbonRectangle {
|
||||||
deviation: 8
|
deviation: 8
|
||||||
samples: (control.blurRadius / 4) * 3
|
samples: (control.blurRadius / 4) * 3
|
||||||
source: effect
|
source: effect
|
||||||
|
visible: enableEffect
|
||||||
}
|
}
|
||||||
|
|
||||||
RibbonRectangle{
|
RibbonRectangle{
|
||||||
|
|
|
@ -0,0 +1,333 @@
|
||||||
|
import QtQuick 2.15
|
||||||
|
import QtQuick.Layouts 1.11
|
||||||
|
import QtQuick.Window 2.15
|
||||||
|
import QtQuick.Controls 2.15
|
||||||
|
import RibbonUI 1.0
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: control
|
||||||
|
implicitWidth: parent ? parent.width : 100
|
||||||
|
implicitHeight: contentHeight
|
||||||
|
enum Type {
|
||||||
|
Info,
|
||||||
|
Success,
|
||||||
|
SevereWarning,
|
||||||
|
Blocked,
|
||||||
|
Error,
|
||||||
|
Warning
|
||||||
|
}
|
||||||
|
property real contentHeight: layout.height + layout.anchors.topMargin * 2
|
||||||
|
property alias text: barText.text
|
||||||
|
property int type: RibbonMessageBar.Info
|
||||||
|
property bool rounded: false
|
||||||
|
property string warningColor: RibbonTheme.isDarkMode ? "#41361D" : "#FDF4D2"
|
||||||
|
property string successColor: RibbonTheme.isDarkMode ? "#3A3D1F" : "#E3F5DF"
|
||||||
|
property string severeWarningColor: RibbonTheme.isDarkMode ? "#4A2C15" : "#F8DACE"
|
||||||
|
property string blockedColor: RibbonTheme.isDarkMode ? "#402827" : "#F9E8E9"
|
||||||
|
property string errorColor: RibbonTheme.isDarkMode ? "#402827" : "#F9E8E9"
|
||||||
|
property string infoColor: RibbonTheme.isDarkMode ? "#323130" : "#F3F2F1"
|
||||||
|
property string externalURL: ""
|
||||||
|
property string externalURLLabel: qsTr("Link")
|
||||||
|
property string dismissLabel: qsTr("Close")
|
||||||
|
property string overflowLabel: qsTr("See More")
|
||||||
|
property string actionALabel: qsTr("ActionA")
|
||||||
|
property string actionBLabel: qsTr("ActionB")
|
||||||
|
property bool isMultiline: type === RibbonMessageBar.SevereWarning || type === RibbonMessageBar.Warning
|
||||||
|
property bool showActionA: false
|
||||||
|
property bool showActionB: false
|
||||||
|
property bool truncated: !(isMultiline || showActionA || showActionB) && type === RibbonMessageBar.Blocked
|
||||||
|
property var actionA: ()=>console.log(qsTr("ActionA Clicked"))
|
||||||
|
property var actionB: ()=>console.log(qsTr("ActionB Clicked"))
|
||||||
|
property var dismissAction
|
||||||
|
|
||||||
|
radius: rounded ? 3 : 0
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
signal dismissClicked()
|
||||||
|
signal actionAClicked()
|
||||||
|
signal actionBClicked()
|
||||||
|
|
||||||
|
Behavior on implicitHeight {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: 200
|
||||||
|
easing.type: Easing.OutSine
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on color {
|
||||||
|
ColorAnimation {
|
||||||
|
duration: 200
|
||||||
|
easing.type: Easing.OutSine
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on opacity{
|
||||||
|
NumberAnimation {
|
||||||
|
duration: 200
|
||||||
|
easing.type: Easing.OutSine
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onOpacityChanged: {
|
||||||
|
if(opacity > 0)
|
||||||
|
visible = true
|
||||||
|
else
|
||||||
|
visible = false
|
||||||
|
}
|
||||||
|
|
||||||
|
onVisibleChanged: {
|
||||||
|
if(visible && opacity === 0)
|
||||||
|
opacity = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle{
|
||||||
|
anchors{
|
||||||
|
top: parent.top
|
||||||
|
horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
width: parent.width
|
||||||
|
height: 1
|
||||||
|
color: Qt.rgba(0,0,0,0.1)
|
||||||
|
visible: RibbonTheme.modernStyle
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle{
|
||||||
|
anchors{
|
||||||
|
bottom: parent.bottom
|
||||||
|
horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
width: parent.width
|
||||||
|
height: 1
|
||||||
|
color: Qt.rgba(0,0,0,0.1)
|
||||||
|
}
|
||||||
|
|
||||||
|
gradient: Gradient {
|
||||||
|
GradientStop { position: 0.0; color: calculateClassicColor(control.color)[0]}
|
||||||
|
GradientStop { position: 1.0; color: calculateClassicColor(control.color)[1]}
|
||||||
|
}
|
||||||
|
|
||||||
|
Column{
|
||||||
|
id: layout
|
||||||
|
anchors{
|
||||||
|
top: parent.top
|
||||||
|
left: parent.left
|
||||||
|
leftMargin: 12
|
||||||
|
right: parent.right
|
||||||
|
rightMargin: anchors.leftMargin
|
||||||
|
topMargin: 8
|
||||||
|
bottomMargin: anchors.topMargin
|
||||||
|
}
|
||||||
|
spacing: 5
|
||||||
|
RowLayout{
|
||||||
|
id: row_1
|
||||||
|
RibbonIcon{
|
||||||
|
id: icon
|
||||||
|
iconSize: height
|
||||||
|
Layout.alignment: Qt.AlignTop
|
||||||
|
Layout.preferredHeight: Math.min(barText.contentHeight, 16)
|
||||||
|
}
|
||||||
|
Text{
|
||||||
|
id: barText
|
||||||
|
elide: truncated.checked ? Text.ElideNone : Text.ElideRight
|
||||||
|
renderType: RibbonTheme.nativeText ? Text.NativeRendering : Text.QtRendering
|
||||||
|
wrapMode: truncated.checked ? Text.Wrap : Text.NoWrap
|
||||||
|
color: RibbonTheme.isDarkMode ? "white" : "black"
|
||||||
|
Layout.alignment: Qt.AlignTop
|
||||||
|
Layout.preferredWidth: {
|
||||||
|
var w = 0
|
||||||
|
if(actiona.visible && !control.isMultiline)
|
||||||
|
w += actiona.width + row_1.spacing
|
||||||
|
if(actionb.visible && !control.isMultiline)
|
||||||
|
w += actionb.width + row_1.spacing
|
||||||
|
if(link.visible)
|
||||||
|
w += link.width + row_1.spacing
|
||||||
|
if(truncated.visible)
|
||||||
|
w += truncated.width + row_1.spacing
|
||||||
|
if(dismiss.visible)
|
||||||
|
w += dismiss.width + row_1.spacing
|
||||||
|
return control.implicitWidth - (w + icon.width + layout.anchors.leftMargin * 2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Text{
|
||||||
|
id: link
|
||||||
|
text: control.externalURLLabel
|
||||||
|
font.underline: true
|
||||||
|
elide: Text.ElideRight
|
||||||
|
renderType: RibbonTheme.nativeText ? Text.NativeRendering : Text.QtRendering
|
||||||
|
color: tm.containsMouse ? RibbonTheme.isDarkMode ? "#91C5FA" : "#1A4474" :
|
||||||
|
RibbonTheme.isDarkMode ? "#7EB6F1" : "#255999"
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
Layout.maximumWidth: 150
|
||||||
|
Layout.preferredHeight: Math.min(barText.contentHeight, 16)
|
||||||
|
visible: control.externalURL
|
||||||
|
MouseArea{
|
||||||
|
id: tm
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
onClicked: Qt.openUrlExternally(control.externalURL)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Item{
|
||||||
|
parent: control.isMultiline ? row_2 : row_1
|
||||||
|
visible: control.isMultiline && (showActionA || showActionB)
|
||||||
|
implicitHeight: 1
|
||||||
|
implicitWidth: {
|
||||||
|
var w = 0
|
||||||
|
if(actiona.visible && control.isMultiline)
|
||||||
|
w += actiona.width + row_2.spacing
|
||||||
|
if(actionb.visible && control.isMultiline)
|
||||||
|
w += actionb.width + row_2.spacing
|
||||||
|
return layout.width - w
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RibbonButton{
|
||||||
|
id: actiona
|
||||||
|
parent: control.isMultiline ? row_2 : row_1
|
||||||
|
text: control.actionALabel
|
||||||
|
Layout.alignment: control.isMultiline ? Qt.AlignVCenter : Qt.AlignTop
|
||||||
|
Layout.topMargin: control.isMultiline ? 0 : - layout.anchors.topMargin * 3 / 4
|
||||||
|
Layout.bottomMargin: Layout.topMargin
|
||||||
|
onClicked: {
|
||||||
|
actionA()
|
||||||
|
actionAClicked()
|
||||||
|
}
|
||||||
|
visible: control.showActionA
|
||||||
|
}
|
||||||
|
RibbonButton{
|
||||||
|
id: actionb
|
||||||
|
parent: control.isMultiline ? row_2 : row_1
|
||||||
|
text: control.actionBLabel
|
||||||
|
Layout.alignment: control.isMultiline ? Qt.AlignVCenter : Qt.AlignTop
|
||||||
|
Layout.topMargin: control.isMultiline ? 0 : - layout.anchors.topMargin * 3 / 4
|
||||||
|
Layout.bottomMargin: Layout.topMargin
|
||||||
|
onClicked: {
|
||||||
|
actionB()
|
||||||
|
actionBClicked()
|
||||||
|
}
|
||||||
|
visible: control.showActionB
|
||||||
|
}
|
||||||
|
RibbonButton{
|
||||||
|
id: truncated
|
||||||
|
textColor: RibbonTheme.isDarkMode ? "#F1F0EF" : "#3E3D3C"
|
||||||
|
showBg: false
|
||||||
|
checkable: true
|
||||||
|
showHoveredBg: false
|
||||||
|
iconSource: RibbonIcons.ChevronDoubleDown
|
||||||
|
rotation: checked ? 180 : 0
|
||||||
|
tipText: control.overflowLabel
|
||||||
|
Layout.alignment: Qt.AlignTop
|
||||||
|
Layout.preferredHeight: Math.min(barText.contentHeight, 16)
|
||||||
|
visible: control.truncated && ((barText.height > link.height) || barText.truncated)
|
||||||
|
checked: control.isMultiline
|
||||||
|
Behavior on rotation {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: 200
|
||||||
|
easing.type: Easing.OutSine
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RibbonButton{
|
||||||
|
id: dismiss
|
||||||
|
textColor: RibbonTheme.isDarkMode ? "#F1F0EF" : "#3E3D3C"
|
||||||
|
showBg: false
|
||||||
|
showHoveredBg: false
|
||||||
|
iconSource: RibbonIcons.Dismiss
|
||||||
|
Layout.alignment: Qt.AlignTop
|
||||||
|
Layout.preferredHeight: Math.min(barText.contentHeight, 16)
|
||||||
|
tipText: control.dismissLabel
|
||||||
|
onClicked: {
|
||||||
|
dismissAction()
|
||||||
|
dismissClicked()
|
||||||
|
control.opacity = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RowLayout{
|
||||||
|
id: row_2
|
||||||
|
visible: control.isMultiline
|
||||||
|
layoutDirection: Qt.RightToLeft
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onInfoColorChanged: refresh()
|
||||||
|
onTypeChanged: refresh()
|
||||||
|
Component.onCompleted: refresh()
|
||||||
|
|
||||||
|
function refresh(){
|
||||||
|
switch(type){
|
||||||
|
case RibbonMessageBar.Info:{
|
||||||
|
icon.color = !RibbonTheme.isDarkMode ? "#605E5C" : "#C8C6C4"
|
||||||
|
icon.iconSource = RibbonIcons.Info
|
||||||
|
control.color = infoColor
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case RibbonMessageBar.Warning:{
|
||||||
|
icon.color = !RibbonTheme.isDarkMode ? "#605E5C" : "#C8C6C4"
|
||||||
|
icon.iconSource = RibbonIcons.Info
|
||||||
|
control.color = warningColor
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case RibbonMessageBar.Success:{
|
||||||
|
icon.color = !RibbonTheme.isDarkMode ? "#387A26" : "#9CC262"
|
||||||
|
icon.iconSource = RibbonIcons.CheckmarkCircle
|
||||||
|
control.color = successColor
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case RibbonMessageBar.SevereWarning:{
|
||||||
|
icon.color = !RibbonTheme.isDarkMode ? "#C74821" : "#F8E24B"
|
||||||
|
icon.iconSource = RibbonIcons.Warning
|
||||||
|
control.color = severeWarningColor
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case RibbonMessageBar.Blocked:{
|
||||||
|
icon.color = !RibbonTheme.isDarkMode ? "#9A1E13" : "#E1777E"
|
||||||
|
icon.iconSource = RibbonIcons.SubtractCircle
|
||||||
|
control.color = blockedColor
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case RibbonMessageBar.Error:{
|
||||||
|
icon.color = !RibbonTheme.isDarkMode ? "#9A1E13" : "#E1777E"
|
||||||
|
icon.iconSource = RibbonIcons.DismissCircle
|
||||||
|
control.color = errorColor
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function calculateClassicColor(modernColor){
|
||||||
|
function limit(num){
|
||||||
|
if(num < 0)
|
||||||
|
return 0
|
||||||
|
else if(num > 255)
|
||||||
|
return 255
|
||||||
|
else
|
||||||
|
return num
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!RibbonTheme.modernStyle){
|
||||||
|
modernColor = String(modernColor)
|
||||||
|
const num = parseInt(modernColor.slice(1), 16)
|
||||||
|
if(modernColor.length === 7)
|
||||||
|
return [Qt.rgba(limit((num >> 16) & 255) / 255,
|
||||||
|
limit(((num >> 8) & 255) + 0x03) / 255,
|
||||||
|
limit((num & 255) + 0x12) / 255,
|
||||||
|
1),
|
||||||
|
Qt.rgba(limit(((num >> 16) & 255) - 0x05) / 255,
|
||||||
|
limit(((num >> 8) & 255) - 0x01) / 255,
|
||||||
|
limit((num & 255) + 0x0C) / 255,
|
||||||
|
1)]
|
||||||
|
else
|
||||||
|
return [Qt.rgba(limit((num >> 24) & 255) / 255,
|
||||||
|
limit(((num >> 16) & 255) + 0x03) / 255,
|
||||||
|
limit(((num >> 8) & 255) + 0x12) / 255,
|
||||||
|
limit(num & 255) / 255),
|
||||||
|
Qt.rgba(limit(((num >> 24) & 255) - 0x05) / 255,
|
||||||
|
limit(((num >> 16) & 255) - 0x01) / 255,
|
||||||
|
limit(((num >> 8) & 255) + 0x0C) / 255,
|
||||||
|
limit(num & 255) / 255)]
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return [modernColor,modernColor]
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,249 @@
|
||||||
|
import QtQuick 2.15
|
||||||
|
import QtQuick.Layouts 1.11
|
||||||
|
import QtQuick.Controls 2.15
|
||||||
|
import RibbonUI 1.0
|
||||||
|
|
||||||
|
RibbonBlur {
|
||||||
|
id: control
|
||||||
|
parent: Overlay.overlay
|
||||||
|
implicitWidth: parent.width
|
||||||
|
useSolidBg: true
|
||||||
|
implicitHeight: 30
|
||||||
|
maskColor: folded ? "transparent" : RibbonTheme.isDarkMode ? Qt.rgba(0,0,0,1) : Qt.rgba(1,1,1,1)
|
||||||
|
bottomLeftRadius: folded ? 0 : 5
|
||||||
|
bottomRightRadius: bottomLeftRadius
|
||||||
|
enableEffect: handler.visible || !folded
|
||||||
|
readonly property alias folded: folded_btn.checked
|
||||||
|
property int animationTime: 400
|
||||||
|
property real barHeight: implicitHeight - handler.height
|
||||||
|
property alias messageModel: messageModel
|
||||||
|
|
||||||
|
Behavior on implicitHeight {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: control.animationTime / 2
|
||||||
|
easing.type: Easing.OutSine
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ListModel{
|
||||||
|
id: messageModel
|
||||||
|
onCountChanged: {
|
||||||
|
message_list.currentIndex = count ? count - 1 : 0
|
||||||
|
if(count === 0)
|
||||||
|
folded_btn.checked = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer{
|
||||||
|
id: auto_scroll_btn_timer
|
||||||
|
interval: control.animationTime
|
||||||
|
repeat: false
|
||||||
|
onTriggered: {
|
||||||
|
message_list.positionViewAtIndex(message_list.currentIndex, ListView.Center)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ListView{
|
||||||
|
id: message_list
|
||||||
|
cacheBuffer: Math.abs(message_list.height * 2)
|
||||||
|
interactive: !folded
|
||||||
|
clip: true
|
||||||
|
anchors{
|
||||||
|
top: parent.top
|
||||||
|
left: parent.left
|
||||||
|
right: parent.right
|
||||||
|
}
|
||||||
|
height: parent.height - (folded ? handler.height : 0)
|
||||||
|
model: messageModel
|
||||||
|
delegate: Item{
|
||||||
|
id: item
|
||||||
|
implicitHeight: bar.contentHeight + (control.folded ? 0 : 10)
|
||||||
|
implicitWidth: control.width
|
||||||
|
RibbonMessageBar{
|
||||||
|
id: bar
|
||||||
|
anchors.centerIn: parent
|
||||||
|
property bool isCurrentItem: item === message_list.currentItem
|
||||||
|
onIsCurrentItemChanged: {
|
||||||
|
if(folded){
|
||||||
|
message_list.height = item.implicitHeight
|
||||||
|
control.implicitHeight = item.implicitHeight + handler.height
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
text: model.text
|
||||||
|
externalURL: model.externalURL
|
||||||
|
dismissAction: ()=>messageModel.remove(index)
|
||||||
|
Component.onCompleted: {
|
||||||
|
if(model.disableMultiline)
|
||||||
|
isMultiline = !model.disableMultiline
|
||||||
|
if(model.type)
|
||||||
|
type = model.type
|
||||||
|
if(model.rounded)
|
||||||
|
rounded = model.rounded
|
||||||
|
if(model.externalURLLabel)
|
||||||
|
externalURLLabel = model.externalURLLabel
|
||||||
|
if(model.dismissLabel)
|
||||||
|
dismissLabel = model.dismissLabel
|
||||||
|
if(model.overflowLabel)
|
||||||
|
overflowLabel = model.overflowLabel
|
||||||
|
if(model.actionALabel){
|
||||||
|
actionALabel = model.actionALabel
|
||||||
|
showActionA = true
|
||||||
|
if(model.actionA){
|
||||||
|
actionA = model.actionA
|
||||||
|
}else{
|
||||||
|
actionA = ()=>console.log(index+qsTr(`'s ${model.actionALabel} Clicked`))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(model.actionBLabel){
|
||||||
|
actionBLabel = model.actionBLabel
|
||||||
|
showActionB = true
|
||||||
|
if(model.actionB){
|
||||||
|
actionB = model.actionB
|
||||||
|
}else{
|
||||||
|
actionB = ()=>console.log(index+qsTr(`'s ${model.actionBLabel} Clicked`))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onImplicitHeightChanged:{
|
||||||
|
if(message_list.currentIndex === index && folded){
|
||||||
|
message_list.height = item.implicitHeight
|
||||||
|
control.implicitHeight = item.implicitHeight + handler.height
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
verticalLayoutDirection: ListView.BottomToTop
|
||||||
|
|
||||||
|
add: Transition {
|
||||||
|
NumberAnimation {
|
||||||
|
properties: "y"
|
||||||
|
from: message_list.height
|
||||||
|
duration: control.animationTime / 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
remove: Transition {
|
||||||
|
NumberAnimation {
|
||||||
|
property: "opacity"
|
||||||
|
from: 1
|
||||||
|
to: 0
|
||||||
|
duration: control.animationTime / 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ScrollBar.vertical: RibbonScrollBar {
|
||||||
|
anchors.right: message_list.right
|
||||||
|
anchors.rightMargin: 2
|
||||||
|
interactive: !folded
|
||||||
|
}
|
||||||
|
onCurrentItemChanged: {
|
||||||
|
auto_scroll_btn_timer.restart()
|
||||||
|
}
|
||||||
|
Behavior on height {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: control.animationTime / 2
|
||||||
|
easing.type: Easing.OutSine
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HoverHandler{
|
||||||
|
id: hover
|
||||||
|
}
|
||||||
|
|
||||||
|
RibbonRectangle{
|
||||||
|
id: handler
|
||||||
|
x: message_list.x + (message_list.width - width) / 2
|
||||||
|
y: message_list.y + message_list.height * (folded ? 1 : 0)
|
||||||
|
implicitHeight: 20
|
||||||
|
implicitWidth: parent.width
|
||||||
|
topLeftRadius: folded ? 0 : 10
|
||||||
|
topRightRadius: topLeftRadius
|
||||||
|
bottomLeftRadius: folded ? 10 : 0
|
||||||
|
bottomRightRadius: bottomLeftRadius
|
||||||
|
visible: hover.hovered && messageModel.count
|
||||||
|
color: RibbonTheme.isDarkMode ? Qt.rgba(0,0,0,0.5) : Qt.rgba(1,1,1,0.5)
|
||||||
|
Behavior on color {
|
||||||
|
ColorAnimation {
|
||||||
|
duration: control.animationTime / 2
|
||||||
|
easing.type: Easing.OutSine
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout{
|
||||||
|
anchors.centerIn: parent
|
||||||
|
RibbonButton{
|
||||||
|
checkable: true
|
||||||
|
showBg: false
|
||||||
|
showHoveredBg: false
|
||||||
|
iconSource: RibbonIcons.DismissCircle
|
||||||
|
tipText: qsTr("Clear All")
|
||||||
|
onClicked: clearMessages()
|
||||||
|
visible: !folded
|
||||||
|
}
|
||||||
|
|
||||||
|
RibbonButton{
|
||||||
|
id: folded_btn
|
||||||
|
checkable: true
|
||||||
|
showBg: false
|
||||||
|
showHoveredBg: false
|
||||||
|
iconSource: RibbonIcons.TriangleDown
|
||||||
|
rotation: checked ? 0 : 180
|
||||||
|
checked: true
|
||||||
|
tipText: checked ? qsTr("Show all messages") : qsTr("Hide all messages")
|
||||||
|
textColor: RibbonTheme.isDarkMode ? "white" : "black"
|
||||||
|
onClicked:{
|
||||||
|
if(!folded){
|
||||||
|
control.implicitHeight = Window.window.viewItems.height - control.x
|
||||||
|
message_list.height = control.implicitHeight
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
message_list.height = message_list.currentItem.implicitHeight
|
||||||
|
control.implicitHeight = message_list.currentItem.implicitHeight + handler.height
|
||||||
|
auto_scroll_btn_timer.restart()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on rotation {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: control.animationTime
|
||||||
|
easing.type: Easing.OutSine
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
message_list.currentIndex = messageModel.count > 0 ? messageModel.count - 1 : 0
|
||||||
|
Window.window.messageBar = control
|
||||||
|
}
|
||||||
|
|
||||||
|
function showMessage(type, text, actionALabel, actionBLabel, externalURL,
|
||||||
|
externalURLLabel, disableMultiline, rounded){
|
||||||
|
let item = {}
|
||||||
|
if(type)
|
||||||
|
item['type'] = type
|
||||||
|
if(text)
|
||||||
|
item['text'] = text
|
||||||
|
if(actionALabel)
|
||||||
|
item['actionALabel'] = actionALabel
|
||||||
|
if(actionBLabel)
|
||||||
|
item['actionBLabel'] = actionBLabel
|
||||||
|
if(externalURL)
|
||||||
|
item['externalURL'] = externalURL
|
||||||
|
if(externalURLLabel)
|
||||||
|
item['externalURLLabel'] = externalURLLabel
|
||||||
|
if(disableMultiline)
|
||||||
|
item['disableMultiline'] = disableMultiline
|
||||||
|
if(rounded)
|
||||||
|
item['rounded'] = rounded
|
||||||
|
messageModel.append(item)
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearMessages(){
|
||||||
|
messageModel.clear()
|
||||||
|
implicitHeight = 0
|
||||||
|
barHeight = 0
|
||||||
|
message_list.height = 0
|
||||||
|
}
|
||||||
|
}
|
|
@ -66,6 +66,7 @@ Item {
|
||||||
implicitHeight: container.height
|
implicitHeight: container.height
|
||||||
implicitWidth: container.width
|
implicitWidth: container.width
|
||||||
maskSource: shape
|
maskSource: shape
|
||||||
|
invert: control.color === "transparent" || control.color === "#00000000"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,8 @@ Item {
|
||||||
property bool isMainView: false
|
property bool isMainView: false
|
||||||
property alias bgColor: bg.color
|
property alias bgColor: bg.color
|
||||||
property alias bgVisible: bg.visible
|
property alias bgVisible: bg.visible
|
||||||
|
property real topBorderFix: 0
|
||||||
|
property real bottomBorderFix: 0
|
||||||
z:-2
|
z:-2
|
||||||
clip: true
|
clip: true
|
||||||
width: parent.width
|
width: parent.width
|
||||||
|
@ -32,7 +34,7 @@ Item {
|
||||||
right: parent.right
|
right: parent.right
|
||||||
top: parent.top
|
top: parent.top
|
||||||
}
|
}
|
||||||
height: isMainView ? Window.window ? Window.window.tabBar ? Math.abs(Window.window.tabBar.height - Window.window.tabBar.modernMargin) : 0 : 0 : 0
|
height: (isMainView ? Window.window ? Window.window.tabBar ? Math.abs(Window.window.tabBar.height - Window.window.tabBar.modernMargin) : 0 : 0 : 0) + topBorderFix
|
||||||
}
|
}
|
||||||
|
|
||||||
Item{
|
Item{
|
||||||
|
@ -60,7 +62,7 @@ Item {
|
||||||
right: parent.right
|
right: parent.right
|
||||||
bottom: parent.bottom
|
bottom: parent.bottom
|
||||||
}
|
}
|
||||||
height: isMainView ? Window.window ? Window.window.tabBar ? Math.abs(Window.window.bottomBar.height) : 0 : 0 : 0
|
height: (isMainView ? Window.window ? Window.window.tabBar ? Math.abs(Window.window.bottomBar.height) : 0 : 0 : 0) + bottomBorderFix
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
|
|
|
@ -22,6 +22,7 @@ Window {
|
||||||
property var viewItems
|
property var viewItems
|
||||||
property var tabBar
|
property var tabBar
|
||||||
property var bottomBar
|
property var bottomBar
|
||||||
|
property var messageBar
|
||||||
readonly property int borderWidth: border_rect.border.width
|
readonly property int borderWidth: border_rect.border.width
|
||||||
readonly property int borderRadius: border_rect.radius
|
readonly property int borderRadius: border_rect.radius
|
||||||
visible: false
|
visible: false
|
||||||
|
|
|
@ -4,6 +4,7 @@ import RibbonUI
|
||||||
|
|
||||||
RibbonRectangle {
|
RibbonRectangle {
|
||||||
id: control
|
id: control
|
||||||
|
property bool enableEffect: true
|
||||||
property int blurRadius: 32
|
property int blurRadius: 32
|
||||||
property alias target: effect.sourceItem
|
property alias target: effect.sourceItem
|
||||||
property rect targetRect : Qt.rect(control.x, control.y, control.width, control.height)
|
property rect targetRect : Qt.rect(control.x, control.y, control.width, control.height)
|
||||||
|
@ -18,7 +19,7 @@ RibbonRectangle {
|
||||||
id: effect
|
id: effect
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
sourceRect: control.targetRect
|
sourceRect: control.targetRect
|
||||||
visible: false
|
visible: !enableEffect
|
||||||
}
|
}
|
||||||
|
|
||||||
GaussianBlur{
|
GaussianBlur{
|
||||||
|
@ -28,6 +29,7 @@ RibbonRectangle {
|
||||||
deviation: 8
|
deviation: 8
|
||||||
samples: (control.blurRadius / 4) * 3
|
samples: (control.blurRadius / 4) * 3
|
||||||
source: effect
|
source: effect
|
||||||
|
visible: enableEffect
|
||||||
}
|
}
|
||||||
|
|
||||||
RibbonRectangle{
|
RibbonRectangle{
|
||||||
|
|
|
@ -0,0 +1,333 @@
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import QtQuick.Window
|
||||||
|
import QtQuick.Controls
|
||||||
|
import RibbonUI
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: control
|
||||||
|
implicitWidth: parent ? parent.width : 100
|
||||||
|
implicitHeight: contentHeight
|
||||||
|
enum Type {
|
||||||
|
Info,
|
||||||
|
Success,
|
||||||
|
SevereWarning,
|
||||||
|
Blocked,
|
||||||
|
Error,
|
||||||
|
Warning
|
||||||
|
}
|
||||||
|
property real contentHeight: layout.height + layout.anchors.topMargin * 2
|
||||||
|
property alias text: barText.text
|
||||||
|
property int type: RibbonMessageBar.Info
|
||||||
|
property bool rounded: false
|
||||||
|
property string warningColor: RibbonTheme.isDarkMode ? "#41361D" : "#FDF4D2"
|
||||||
|
property string successColor: RibbonTheme.isDarkMode ? "#3A3D1F" : "#E3F5DF"
|
||||||
|
property string severeWarningColor: RibbonTheme.isDarkMode ? "#4A2C15" : "#F8DACE"
|
||||||
|
property string blockedColor: RibbonTheme.isDarkMode ? "#402827" : "#F9E8E9"
|
||||||
|
property string errorColor: RibbonTheme.isDarkMode ? "#402827" : "#F9E8E9"
|
||||||
|
property string infoColor: RibbonTheme.isDarkMode ? "#323130" : "#F3F2F1"
|
||||||
|
property string externalURL: ""
|
||||||
|
property string externalURLLabel: qsTr("Link")
|
||||||
|
property string dismissLabel: qsTr("Close")
|
||||||
|
property string overflowLabel: qsTr("See More")
|
||||||
|
property string actionALabel: qsTr("ActionA")
|
||||||
|
property string actionBLabel: qsTr("ActionB")
|
||||||
|
property bool isMultiline: type === RibbonMessageBar.SevereWarning || type === RibbonMessageBar.Warning
|
||||||
|
property bool showActionA: false
|
||||||
|
property bool showActionB: false
|
||||||
|
property bool truncated: !(isMultiline || showActionA || showActionB) && type === RibbonMessageBar.Blocked
|
||||||
|
property var actionA: ()=>console.log(qsTr("ActionA Clicked"))
|
||||||
|
property var actionB: ()=>console.log(qsTr("ActionB Clicked"))
|
||||||
|
property var dismissAction
|
||||||
|
|
||||||
|
radius: rounded ? 3 : 0
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
signal dismissClicked()
|
||||||
|
signal actionAClicked()
|
||||||
|
signal actionBClicked()
|
||||||
|
|
||||||
|
Behavior on implicitHeight {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: 200
|
||||||
|
easing.type: Easing.OutSine
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on color {
|
||||||
|
ColorAnimation {
|
||||||
|
duration: 200
|
||||||
|
easing.type: Easing.OutSine
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on opacity{
|
||||||
|
NumberAnimation {
|
||||||
|
duration: 200
|
||||||
|
easing.type: Easing.OutSine
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onOpacityChanged: {
|
||||||
|
if(opacity > 0)
|
||||||
|
visible = true
|
||||||
|
else
|
||||||
|
visible = false
|
||||||
|
}
|
||||||
|
|
||||||
|
onVisibleChanged: {
|
||||||
|
if(visible && opacity === 0)
|
||||||
|
opacity = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle{
|
||||||
|
anchors{
|
||||||
|
top: parent.top
|
||||||
|
horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
width: parent.width
|
||||||
|
height: 1
|
||||||
|
color: Qt.rgba(0,0,0,0.1)
|
||||||
|
visible: RibbonTheme.modernStyle
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle{
|
||||||
|
anchors{
|
||||||
|
bottom: parent.bottom
|
||||||
|
horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
width: parent.width
|
||||||
|
height: 1
|
||||||
|
color: Qt.rgba(0,0,0,0.1)
|
||||||
|
}
|
||||||
|
|
||||||
|
gradient: Gradient {
|
||||||
|
GradientStop { position: 0.0; color: calculateClassicColor(control.color)[0]}
|
||||||
|
GradientStop { position: 1.0; color: calculateClassicColor(control.color)[1]}
|
||||||
|
}
|
||||||
|
|
||||||
|
Column{
|
||||||
|
id: layout
|
||||||
|
anchors{
|
||||||
|
top: parent.top
|
||||||
|
left: parent.left
|
||||||
|
leftMargin: 12
|
||||||
|
right: parent.right
|
||||||
|
rightMargin: anchors.leftMargin
|
||||||
|
topMargin: 8
|
||||||
|
bottomMargin: anchors.topMargin
|
||||||
|
}
|
||||||
|
spacing: 5
|
||||||
|
RowLayout{
|
||||||
|
id: row_1
|
||||||
|
RibbonIcon{
|
||||||
|
id: icon
|
||||||
|
iconSize: height
|
||||||
|
Layout.alignment: Qt.AlignTop
|
||||||
|
Layout.preferredHeight: Math.min(barText.contentHeight, 16)
|
||||||
|
}
|
||||||
|
Text{
|
||||||
|
id: barText
|
||||||
|
elide: truncated.checked ? Text.ElideNone : Text.ElideRight
|
||||||
|
renderType: RibbonTheme.nativeText ? Text.NativeRendering : Text.QtRendering
|
||||||
|
wrapMode: truncated.checked ? Text.Wrap : Text.NoWrap
|
||||||
|
color: RibbonTheme.isDarkMode ? "white" : "black"
|
||||||
|
Layout.alignment: Qt.AlignTop
|
||||||
|
Layout.preferredWidth: {
|
||||||
|
var w = 0
|
||||||
|
if(actiona.visible && !control.isMultiline)
|
||||||
|
w += actiona.width + row_1.spacing
|
||||||
|
if(actionb.visible && !control.isMultiline)
|
||||||
|
w += actionb.width + row_1.spacing
|
||||||
|
if(link.visible)
|
||||||
|
w += link.width + row_1.spacing
|
||||||
|
if(truncated.visible)
|
||||||
|
w += truncated.width + row_1.spacing
|
||||||
|
if(dismiss.visible)
|
||||||
|
w += dismiss.width + row_1.spacing
|
||||||
|
return control.implicitWidth - (w + icon.width + layout.anchors.leftMargin * 2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Text{
|
||||||
|
id: link
|
||||||
|
text: control.externalURLLabel
|
||||||
|
font.underline: true
|
||||||
|
elide: Text.ElideRight
|
||||||
|
renderType: RibbonTheme.nativeText ? Text.NativeRendering : Text.QtRendering
|
||||||
|
color: tm.containsMouse ? RibbonTheme.isDarkMode ? "#91C5FA" : "#1A4474" :
|
||||||
|
RibbonTheme.isDarkMode ? "#7EB6F1" : "#255999"
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
Layout.maximumWidth: 150
|
||||||
|
Layout.preferredHeight: Math.min(barText.contentHeight, 16)
|
||||||
|
visible: control.externalURL
|
||||||
|
MouseArea{
|
||||||
|
id: tm
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
onClicked: Qt.openUrlExternally(control.externalURL)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Item{
|
||||||
|
parent: control.isMultiline ? row_2 : row_1
|
||||||
|
visible: control.isMultiline && (showActionA || showActionB)
|
||||||
|
implicitHeight: 1
|
||||||
|
implicitWidth: {
|
||||||
|
var w = 0
|
||||||
|
if(actiona.visible && control.isMultiline)
|
||||||
|
w += actiona.width + row_2.spacing
|
||||||
|
if(actionb.visible && control.isMultiline)
|
||||||
|
w += actionb.width + row_2.spacing
|
||||||
|
return layout.width - w
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RibbonButton{
|
||||||
|
id: actiona
|
||||||
|
parent: control.isMultiline ? row_2 : row_1
|
||||||
|
text: control.actionALabel
|
||||||
|
Layout.alignment: control.isMultiline ? Qt.AlignVCenter : Qt.AlignTop
|
||||||
|
Layout.topMargin: control.isMultiline ? 0 : - layout.anchors.topMargin * 3 / 4
|
||||||
|
Layout.bottomMargin: Layout.topMargin
|
||||||
|
onClicked: {
|
||||||
|
actionA()
|
||||||
|
actionAClicked()
|
||||||
|
}
|
||||||
|
visible: control.showActionA
|
||||||
|
}
|
||||||
|
RibbonButton{
|
||||||
|
id: actionb
|
||||||
|
parent: control.isMultiline ? row_2 : row_1
|
||||||
|
text: control.actionBLabel
|
||||||
|
Layout.alignment: control.isMultiline ? Qt.AlignVCenter : Qt.AlignTop
|
||||||
|
Layout.topMargin: control.isMultiline ? 0 : - layout.anchors.topMargin * 3 / 4
|
||||||
|
Layout.bottomMargin: Layout.topMargin
|
||||||
|
onClicked: {
|
||||||
|
actionB()
|
||||||
|
actionBClicked()
|
||||||
|
}
|
||||||
|
visible: control.showActionB
|
||||||
|
}
|
||||||
|
RibbonButton{
|
||||||
|
id: truncated
|
||||||
|
textColor: RibbonTheme.isDarkMode ? "#F1F0EF" : "#3E3D3C"
|
||||||
|
showBg: false
|
||||||
|
checkable: true
|
||||||
|
showHoveredBg: false
|
||||||
|
iconSource: RibbonIcons.ChevronDoubleDown
|
||||||
|
rotation: checked ? 180 : 0
|
||||||
|
tipText: control.overflowLabel
|
||||||
|
Layout.alignment: Qt.AlignTop
|
||||||
|
Layout.preferredHeight: Math.min(barText.contentHeight, 16)
|
||||||
|
visible: control.truncated && ((barText.height > link.height) || barText.truncated)
|
||||||
|
checked: control.isMultiline
|
||||||
|
Behavior on rotation {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: 200
|
||||||
|
easing.type: Easing.OutSine
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RibbonButton{
|
||||||
|
id: dismiss
|
||||||
|
textColor: RibbonTheme.isDarkMode ? "#F1F0EF" : "#3E3D3C"
|
||||||
|
showBg: false
|
||||||
|
showHoveredBg: false
|
||||||
|
iconSource: RibbonIcons.Dismiss
|
||||||
|
Layout.alignment: Qt.AlignTop
|
||||||
|
Layout.preferredHeight: Math.min(barText.contentHeight, 16)
|
||||||
|
tipText: control.dismissLabel
|
||||||
|
onClicked: {
|
||||||
|
dismissAction()
|
||||||
|
dismissClicked()
|
||||||
|
control.opacity = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RowLayout{
|
||||||
|
id: row_2
|
||||||
|
visible: control.isMultiline
|
||||||
|
layoutDirection: Qt.RightToLeft
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onInfoColorChanged: refresh()
|
||||||
|
onTypeChanged: refresh()
|
||||||
|
Component.onCompleted: refresh()
|
||||||
|
|
||||||
|
function refresh(){
|
||||||
|
switch(type){
|
||||||
|
case RibbonMessageBar.Info:{
|
||||||
|
icon.color = !RibbonTheme.isDarkMode ? "#605E5C" : "#C8C6C4"
|
||||||
|
icon.iconSource = RibbonIcons.Info
|
||||||
|
control.color = infoColor
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case RibbonMessageBar.Warning:{
|
||||||
|
icon.color = !RibbonTheme.isDarkMode ? "#605E5C" : "#C8C6C4"
|
||||||
|
icon.iconSource = RibbonIcons.Info
|
||||||
|
control.color = warningColor
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case RibbonMessageBar.Success:{
|
||||||
|
icon.color = !RibbonTheme.isDarkMode ? "#387A26" : "#9CC262"
|
||||||
|
icon.iconSource = RibbonIcons.CheckmarkCircle
|
||||||
|
control.color = successColor
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case RibbonMessageBar.SevereWarning:{
|
||||||
|
icon.color = !RibbonTheme.isDarkMode ? "#C74821" : "#F8E24B"
|
||||||
|
icon.iconSource = RibbonIcons.Warning
|
||||||
|
control.color = severeWarningColor
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case RibbonMessageBar.Blocked:{
|
||||||
|
icon.color = !RibbonTheme.isDarkMode ? "#9A1E13" : "#E1777E"
|
||||||
|
icon.iconSource = RibbonIcons.SubtractCircle
|
||||||
|
control.color = blockedColor
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case RibbonMessageBar.Error:{
|
||||||
|
icon.color = !RibbonTheme.isDarkMode ? "#9A1E13" : "#E1777E"
|
||||||
|
icon.iconSource = RibbonIcons.DismissCircle
|
||||||
|
control.color = errorColor
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function calculateClassicColor(modernColor){
|
||||||
|
function limit(num){
|
||||||
|
if(num < 0)
|
||||||
|
return 0
|
||||||
|
else if(num > 255)
|
||||||
|
return 255
|
||||||
|
else
|
||||||
|
return num
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!RibbonTheme.modernStyle){
|
||||||
|
modernColor = String(modernColor)
|
||||||
|
const num = parseInt(modernColor.slice(1), 16)
|
||||||
|
if(modernColor.length === 7)
|
||||||
|
return [Qt.rgba(limit((num >> 16) & 255) / 255,
|
||||||
|
limit(((num >> 8) & 255) + 0x03) / 255,
|
||||||
|
limit((num & 255) + 0x12) / 255,
|
||||||
|
1),
|
||||||
|
Qt.rgba(limit(((num >> 16) & 255) - 0x05) / 255,
|
||||||
|
limit(((num >> 8) & 255) - 0x01) / 255,
|
||||||
|
limit((num & 255) + 0x0C) / 255,
|
||||||
|
1)]
|
||||||
|
else
|
||||||
|
return [Qt.rgba(limit((num >> 24) & 255) / 255,
|
||||||
|
limit(((num >> 16) & 255) + 0x03) / 255,
|
||||||
|
limit(((num >> 8) & 255) + 0x12) / 255,
|
||||||
|
limit(num & 255) / 255),
|
||||||
|
Qt.rgba(limit(((num >> 24) & 255) - 0x05) / 255,
|
||||||
|
limit(((num >> 16) & 255) - 0x01) / 255,
|
||||||
|
limit(((num >> 8) & 255) + 0x0C) / 255,
|
||||||
|
limit(num & 255) / 255)]
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return [modernColor,modernColor]
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,249 @@
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import QtQuick.Controls
|
||||||
|
import RibbonUI
|
||||||
|
|
||||||
|
RibbonBlur {
|
||||||
|
id: control
|
||||||
|
parent: Overlay.overlay
|
||||||
|
implicitWidth: parent.width
|
||||||
|
useSolidBg: true
|
||||||
|
implicitHeight: 30
|
||||||
|
maskColor: folded ? "transparent" : RibbonTheme.isDarkMode ? Qt.rgba(0,0,0,1) : Qt.rgba(1,1,1,1)
|
||||||
|
bottomLeftRadius: folded ? 0 : 5
|
||||||
|
bottomRightRadius: bottomLeftRadius
|
||||||
|
enableEffect: handler.visible || !folded
|
||||||
|
readonly property alias folded: folded_btn.checked
|
||||||
|
property int animationTime: 400
|
||||||
|
property real barHeight: implicitHeight - handler.height
|
||||||
|
property alias messageModel: messageModel
|
||||||
|
|
||||||
|
Behavior on implicitHeight {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: control.animationTime / 2
|
||||||
|
easing.type: Easing.OutSine
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ListModel{
|
||||||
|
id: messageModel
|
||||||
|
onCountChanged: {
|
||||||
|
message_list.currentIndex = count ? count - 1 : 0
|
||||||
|
if(count === 0)
|
||||||
|
folded_btn.checked = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer{
|
||||||
|
id: auto_scroll_btn_timer
|
||||||
|
interval: control.animationTime
|
||||||
|
repeat: false
|
||||||
|
onTriggered: {
|
||||||
|
message_list.positionViewAtIndex(message_list.currentIndex, ListView.Center)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ListView{
|
||||||
|
id: message_list
|
||||||
|
cacheBuffer: Math.abs(message_list.height * 2)
|
||||||
|
interactive: !folded
|
||||||
|
clip: true
|
||||||
|
anchors{
|
||||||
|
top: parent.top
|
||||||
|
left: parent.left
|
||||||
|
right: parent.right
|
||||||
|
}
|
||||||
|
height: parent.height - (folded ? handler.height : 0)
|
||||||
|
model: messageModel
|
||||||
|
delegate: Item{
|
||||||
|
id: item
|
||||||
|
implicitHeight: bar.contentHeight + (control.folded ? 0 : 10)
|
||||||
|
implicitWidth: control.width
|
||||||
|
RibbonMessageBar{
|
||||||
|
id: bar
|
||||||
|
anchors.centerIn: parent
|
||||||
|
property bool isCurrentItem: item === message_list.currentItem
|
||||||
|
onIsCurrentItemChanged: {
|
||||||
|
if(folded){
|
||||||
|
message_list.height = item.implicitHeight
|
||||||
|
control.implicitHeight = item.implicitHeight + handler.height
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
text: model.text
|
||||||
|
externalURL: model.externalURL
|
||||||
|
dismissAction: ()=>messageModel.remove(index)
|
||||||
|
Component.onCompleted: {
|
||||||
|
if(model.disableMultiline)
|
||||||
|
isMultiline = !model.disableMultiline
|
||||||
|
if(model.type)
|
||||||
|
type = model.type
|
||||||
|
if(model.rounded)
|
||||||
|
rounded = model.rounded
|
||||||
|
if(model.externalURLLabel)
|
||||||
|
externalURLLabel = model.externalURLLabel
|
||||||
|
if(model.dismissLabel)
|
||||||
|
dismissLabel = model.dismissLabel
|
||||||
|
if(model.overflowLabel)
|
||||||
|
overflowLabel = model.overflowLabel
|
||||||
|
if(model.actionALabel){
|
||||||
|
actionALabel = model.actionALabel
|
||||||
|
showActionA = true
|
||||||
|
if(model.actionA){
|
||||||
|
actionA = model.actionA
|
||||||
|
}else{
|
||||||
|
actionA = ()=>console.log(index+qsTr(`'s ${model.actionALabel} Clicked`))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(model.actionBLabel){
|
||||||
|
actionBLabel = model.actionBLabel
|
||||||
|
showActionB = true
|
||||||
|
if(model.actionB){
|
||||||
|
actionB = model.actionB
|
||||||
|
}else{
|
||||||
|
actionB = ()=>console.log(index+qsTr(`'s ${model.actionBLabel} Clicked`))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onImplicitHeightChanged:{
|
||||||
|
if(message_list.currentIndex === index && folded){
|
||||||
|
message_list.height = item.implicitHeight
|
||||||
|
control.implicitHeight = item.implicitHeight + handler.height
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
verticalLayoutDirection: ListView.BottomToTop
|
||||||
|
|
||||||
|
add: Transition {
|
||||||
|
NumberAnimation {
|
||||||
|
properties: "y"
|
||||||
|
from: message_list.height
|
||||||
|
duration: control.animationTime / 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
remove: Transition {
|
||||||
|
NumberAnimation {
|
||||||
|
property: "opacity"
|
||||||
|
from: 1
|
||||||
|
to: 0
|
||||||
|
duration: control.animationTime / 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ScrollBar.vertical: RibbonScrollBar {
|
||||||
|
anchors.right: message_list.right
|
||||||
|
anchors.rightMargin: 2
|
||||||
|
interactive: !folded
|
||||||
|
}
|
||||||
|
onCurrentItemChanged: {
|
||||||
|
auto_scroll_btn_timer.restart()
|
||||||
|
}
|
||||||
|
Behavior on height {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: control.animationTime / 2
|
||||||
|
easing.type: Easing.OutSine
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HoverHandler{
|
||||||
|
id: hover
|
||||||
|
}
|
||||||
|
|
||||||
|
RibbonRectangle{
|
||||||
|
id: handler
|
||||||
|
x: message_list.x + (message_list.width - width) / 2
|
||||||
|
y: message_list.y + message_list.height * (folded ? 1 : 0)
|
||||||
|
implicitHeight: 20
|
||||||
|
implicitWidth: parent.width
|
||||||
|
topLeftRadius: folded ? 0 : 10
|
||||||
|
topRightRadius: topLeftRadius
|
||||||
|
bottomLeftRadius: folded ? 10 : 0
|
||||||
|
bottomRightRadius: bottomLeftRadius
|
||||||
|
visible: hover.hovered && messageModel.count
|
||||||
|
color: RibbonTheme.isDarkMode ? Qt.rgba(0,0,0,0.5) : Qt.rgba(1,1,1,0.5)
|
||||||
|
Behavior on color {
|
||||||
|
ColorAnimation {
|
||||||
|
duration: control.animationTime / 2
|
||||||
|
easing.type: Easing.OutSine
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout{
|
||||||
|
anchors.centerIn: parent
|
||||||
|
RibbonButton{
|
||||||
|
checkable: true
|
||||||
|
showBg: false
|
||||||
|
showHoveredBg: false
|
||||||
|
iconSource: RibbonIcons.DismissCircle
|
||||||
|
tipText: qsTr("Clear All")
|
||||||
|
onClicked: clearMessages()
|
||||||
|
visible: !folded
|
||||||
|
}
|
||||||
|
|
||||||
|
RibbonButton{
|
||||||
|
id: folded_btn
|
||||||
|
checkable: true
|
||||||
|
showBg: false
|
||||||
|
showHoveredBg: false
|
||||||
|
iconSource: RibbonIcons.TriangleDown
|
||||||
|
rotation: checked ? 0 : 180
|
||||||
|
checked: true
|
||||||
|
tipText: checked ? qsTr("Show all messages") : qsTr("Hide all messages")
|
||||||
|
textColor: RibbonTheme.isDarkMode ? "white" : "black"
|
||||||
|
onClicked:{
|
||||||
|
if(!folded){
|
||||||
|
control.implicitHeight = Window.window.viewItems.height - control.x
|
||||||
|
message_list.height = control.implicitHeight
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
message_list.height = message_list.currentItem.implicitHeight
|
||||||
|
control.implicitHeight = message_list.currentItem.implicitHeight + handler.height
|
||||||
|
auto_scroll_btn_timer.restart()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on rotation {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: control.animationTime
|
||||||
|
easing.type: Easing.OutSine
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
message_list.currentIndex = messageModel.count > 0 ? messageModel.count - 1 : 0
|
||||||
|
Window.window.messageBar = control
|
||||||
|
}
|
||||||
|
|
||||||
|
function showMessage(type, text, actionALabel, actionBLabel, externalURL,
|
||||||
|
externalURLLabel, disableMultiline, rounded){
|
||||||
|
let item = {}
|
||||||
|
if(type)
|
||||||
|
item['type'] = type
|
||||||
|
if(text)
|
||||||
|
item['text'] = text
|
||||||
|
if(actionALabel)
|
||||||
|
item['actionALabel'] = actionALabel
|
||||||
|
if(actionBLabel)
|
||||||
|
item['actionBLabel'] = actionBLabel
|
||||||
|
if(externalURL)
|
||||||
|
item['externalURL'] = externalURL
|
||||||
|
if(externalURLLabel)
|
||||||
|
item['externalURLLabel'] = externalURLLabel
|
||||||
|
if(disableMultiline)
|
||||||
|
item['disableMultiline'] = disableMultiline
|
||||||
|
if(rounded)
|
||||||
|
item['rounded'] = rounded
|
||||||
|
messageModel.append(item)
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearMessages(){
|
||||||
|
messageModel.clear()
|
||||||
|
implicitHeight = 0
|
||||||
|
barHeight = 0
|
||||||
|
message_list.height = 0
|
||||||
|
}
|
||||||
|
}
|
|
@ -68,6 +68,7 @@ Item {
|
||||||
implicitHeight: container.height
|
implicitHeight: container.height
|
||||||
implicitWidth: container.width
|
implicitWidth: container.width
|
||||||
maskSource: shape
|
maskSource: shape
|
||||||
|
invert: control.color === "transparent" || control.color === "#00000000"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,8 @@ Item {
|
||||||
property bool isMainView: false
|
property bool isMainView: false
|
||||||
property alias bgColor: bg.color
|
property alias bgColor: bg.color
|
||||||
property alias bgVisible: bg.visible
|
property alias bgVisible: bg.visible
|
||||||
|
property real topBorderFix: 0
|
||||||
|
property real bottomBorderFix: 0
|
||||||
z:-2
|
z:-2
|
||||||
clip: true
|
clip: true
|
||||||
width: parent.width
|
width: parent.width
|
||||||
|
@ -32,7 +34,7 @@ Item {
|
||||||
right: parent.right
|
right: parent.right
|
||||||
top: parent.top
|
top: parent.top
|
||||||
}
|
}
|
||||||
height: isMainView ? Window.window ? Window.window.tabBar ? Math.abs(Window.window.tabBar.height - Window.window.tabBar.modernMargin) : 0 : 0 : 0
|
height: (isMainView ? Window.window ? Window.window.tabBar ? Math.abs(Window.window.tabBar.height - Window.window.tabBar.modernMargin) : 0 : 0 : 0) + topBorderFix
|
||||||
}
|
}
|
||||||
|
|
||||||
Item{
|
Item{
|
||||||
|
@ -60,7 +62,7 @@ Item {
|
||||||
right: parent.right
|
right: parent.right
|
||||||
bottom: parent.bottom
|
bottom: parent.bottom
|
||||||
}
|
}
|
||||||
height: isMainView ? Window.window ? Window.window.tabBar ? Math.abs(Window.window.bottomBar.height) : 0 : 0 : 0
|
height: (isMainView ? Window.window ? Window.window.tabBar ? Math.abs(Window.window.bottomBar.height) : 0 : 0 : 0) + bottomBorderFix
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
|
|
|
@ -22,6 +22,7 @@ Window {
|
||||||
property var viewItems
|
property var viewItems
|
||||||
property var tabBar
|
property var tabBar
|
||||||
property var bottomBar
|
property var bottomBar
|
||||||
|
property var messageBar
|
||||||
readonly property int borderWidth: border_rect.border.width
|
readonly property int borderWidth: border_rect.border.width
|
||||||
readonly property int borderRadius: border_rect.radius
|
readonly property int borderRadius: border_rect.radius
|
||||||
visible: false
|
visible: false
|
||||||
|
|
Loading…
Reference in New Issue