334 lines
12 KiB
QML
334 lines
12 KiB
QML
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]
|
|
}
|
|
}
|