/* * Copyright 2016 Smith AR * Michail Vourlakos * * This file is part of Latte-Dock * * Latte-Dock is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * Latte-Dock is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ import QtQuick 2.0 import QtGraphicalEffects 1.0 import org.kde.plasma.components 2.0 as Components import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.plasmoid 2.0 Item{ // property string color id: glowItem property bool glow3D: true property bool roundCorners: true property bool showBorder: false property bool showAttention: false property bool showGlow: false property int animation: 250 property int location: PlasmaCore.Types.BottomEdge property real glowOpacity: 0.75 property color attentionColor: "red" property color basicColor: "blue" property color contrastColor: "#b0b0b0" property color currentColor: glowItem.showAttention ? animationColorAlpha : basicColorAlpha property color animationColor: "red" // it is used only internally for the animation readonly property color basicColorAlpha: Qt.rgba(basicColor.r, basicColor.g, basicColor.b, glowOpacity) readonly property color animationColorAlpha: Qt.rgba(animationColor.r, animationColor.g, animationColor.b, glowOpacity) readonly property color contrastColorAlpha: Qt.rgba(contrastColor.r, contrastColor.g, contrastColor.b, Math.min(glowOpacity+0.25,1)) readonly property color contrastColorAlpha2: Qt.rgba(contrastColor.r, contrastColor.g, contrastColor.b, 0.3) readonly property bool isVertical: (location === PlasmaCore.Types.LeftEdge) || (location === PlasmaCore.Types.RightEdge) readonly property bool isHorizontal: !isVertical Grid{ id: mainGlow anchors.horizontalCenter: parent.horizontalCenter anchors.verticalCenter: parent.verticalCenter visible: glowItem.showGlow rows: isHorizontal ? 1 : 0 columns: isVertical ? 1 : 0 property int halfCorner: 3*glowFrame.size property int fullCorner: 6*glowFrame.size Item { id: firstGlowCorner width: isHorizontal ? mainGlow.halfCorner : mainGlow.fullCorner height: isHorizontal ? mainGlow.fullCorner : mainGlow.halfCorner clip: true Item { id: firstGlowCornerFull width: mainGlow.fullCorner height: mainGlow.fullCorner RadialGradient { anchors.fill: parent gradient: Gradient { GradientStop { position: 0.0; color: "transparent" } GradientStop { position: 0.07; color: glowItem.contrastColorAlpha } GradientStop { position: 0.125; color: glowItem.currentColor } GradientStop { position: 0.4; color: "transparent" } GradientStop { position: 1; color: "transparent" } } } states: [ State{ name: "*" when: isHorizontal AnchorChanges{ target:firstGlowCornerFull; anchors{ bottom: undefined; left:parent.left;} } }, State{ name: "vertical" when: isVertical AnchorChanges{ target:firstGlowCornerFull; anchors{ top: parent.top; left:undefined;} } } ] } } Item { id:mainGlowPart width: isHorizontal ? glowItem.width - glowFrame.size : mainGlow.fullCorner height: isHorizontal ? mainGlow.fullCorner : glowItem.height - glowFrame.size LinearGradient { anchors.fill: parent start: { if (location === PlasmaCore.Types.BottomEdge || location === PlasmaCore.Types.Floating) return Qt.point(0, 0); else if (location === PlasmaCore.Types.TopEdge) return Qt.point(0, mainGlow.fullCorner); else if (location === PlasmaCore.Types.LeftEdge) return Qt.point(mainGlow.fullCorner, 0); else if (location === PlasmaCore.Types.RightEdge) return Qt.point(0, 0); return Qt.point(mainGlow.fullCorner, 0); } end: { if (location === PlasmaCore.Types.BottomEdge || location === PlasmaCore.Types.Floating) return Qt.point(0, mainGlow.fullCorner); else if (location === PlasmaCore.Types.TopEdge) return Qt.point(0, 0); else if (location === PlasmaCore.Types.LeftEdge) return Qt.point(0,0); else if (location === PlasmaCore.Types.RightEdge) return Qt.point(mainGlow.fullCorner, 0); return Qt.point(0,0); } gradient: Gradient { GradientStop { position: 0.0; color: "transparent" } GradientStop { position: 0.08; color: "transparent" } GradientStop { position: 0.37; color: glowItem.currentColor } GradientStop { position: 0.43; color: glowItem.contrastColorAlpha } GradientStop { position: 0.57; color: glowItem.contrastColorAlpha } GradientStop { position: 0.63; color: glowItem.currentColor } GradientStop { position: 0.92; color: "transparent" } GradientStop { position: 1; color: "transparent" } } } } Item { id:lastGlowCorner width: isHorizontal ? mainGlow.halfCorner : mainGlow.fullCorner height: isHorizontal ? mainGlow.fullCorner : mainGlow.halfCorner clip: true Item { id: lastGlowCornerFull width: mainGlow.fullCorner height: mainGlow.fullCorner RadialGradient { anchors.fill: parent gradient: Gradient { GradientStop { position: 0.0; color: "transparent" } GradientStop { position: 0.07; color: glowItem.contrastColorAlpha } GradientStop { position: 0.125; color: glowItem.currentColor } GradientStop { position: 0.4; color: "transparent"} GradientStop { position: 1; color: "transparent" } } } states: [ State{ name: "*" when: isHorizontal AnchorChanges{ target:lastGlowCornerFull; anchors{ bottom: undefined; right:parent.right;} } }, State{ name: "vertical" when: isVertical AnchorChanges{ target:lastGlowCornerFull; anchors{ bottom: parent.bottom; right:undefined;} } } ] } } } //! add border around indicator without reducing its size Loader{ anchors.centerIn: mainElement active: glowItem.showBorder && !glowItem.showGlow sourceComponent:Rectangle { width: size height: size anchors.centerIn: parent color: contrastColorAlpha2 radius: glowItem.roundCorners ? Math.min(width,height) / 2 : 0 property int size: Math.min(mainElement.width + 2*Math.max(1,mainElement.width/5 ), mainElement.height + 2*Math.max(1,mainElement.height/5 )) } } Item{ id:mainElement anchors.fill: parent Rectangle { id: smallCircle anchors.centerIn: parent anchors.fill: parent color: glowItem.basicColor radius: glowItem.roundCorners ? Math.min(width,height) / 2 : 0 visible: !glowItem.showAttention } Loader{ anchors.centerIn: parent anchors.fill: parent active: glowItem.showAttention sourceComponent:Rectangle { id: smallCircleInAttention color: glowItem.animationColor radius: smallCircle.radius SequentialAnimation{ running: glowItem.showAttention loops: Animation.Infinite alwaysRunToEnd: true PropertyAnimation { target: glowItem property: "animationColor" to: glowItem.animationColor duration: glowItem.animation easing.type: Easing.InOutQuad } PropertyAnimation { target: glowItem property: "animationColor" to: glowItem.basicColor duration: glowItem.animation easing.type: Easing.InOutQuad } } } } Rectangle { visible: glowItem.showGlow && glowItem.glow3D anchors.horizontalCenter: parent.horizontalCenter anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenterOffset: { if (isHorizontal) return 0; else if (location === PlasmaCore.Types.LeftEdge) return -glowItem.width / 7; else if (location === PlasmaCore.Types.RightEdge) return glowItem.width / 7; } anchors.verticalCenterOffset: { if (isVertical) return 0; else if (location === PlasmaCore.Types.BottomEdge) return glowItem.height / 7; else if (location === PlasmaCore.Types.TopEdge) return -glowItem.height / 7; } width: isHorizontal ? Math.max(mainGlowPart.width, shadow) : shadow height: isHorizontal ? shadow : Math.max(mainGlowPart.height, shadow) radius: isHorizontal ? height/2 : width/2 property int shadow: glowFrame.size / 3 color: glowItem.contrastColorAlpha opacity: 0.2 } } }