internal: better colourisation
This commit is contained in:
parent
38b2ef0061
commit
04ce9ccbb4
8 changed files with 100 additions and 42 deletions
83
components/effects/ColouredIcon.qml
Normal file
83
components/effects/ColouredIcon.qml
Normal file
|
|
@ -0,0 +1,83 @@
|
||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
|
import Quickshell.Widgets
|
||||||
|
import QtQuick
|
||||||
|
|
||||||
|
IconImage {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
required property color colour
|
||||||
|
property color sourceColour
|
||||||
|
property url lastSource
|
||||||
|
|
||||||
|
asynchronous: true
|
||||||
|
|
||||||
|
layer.enabled: true
|
||||||
|
layer.effect: Colouriser {
|
||||||
|
sourceColor: root.sourceColour
|
||||||
|
colorizationColor: root.colour
|
||||||
|
}
|
||||||
|
|
||||||
|
layer.onEnabledChanged: {
|
||||||
|
if (layer.enabled)
|
||||||
|
canvas.requestPaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
onStatusChanged: {
|
||||||
|
if (layer.enabled && status === Image.Ready)
|
||||||
|
canvas.requestPaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
Canvas {
|
||||||
|
id: canvas
|
||||||
|
|
||||||
|
property int retryCount
|
||||||
|
|
||||||
|
implicitWidth: 32
|
||||||
|
implicitHeight: 32
|
||||||
|
visible: false
|
||||||
|
|
||||||
|
onPaint: {
|
||||||
|
if (!root.layer.enabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const ctx = getContext("2d");
|
||||||
|
ctx.reset();
|
||||||
|
ctx.drawImage(root.backer, 0, 0, width, height);
|
||||||
|
|
||||||
|
const colours = {} as Object;
|
||||||
|
const data = ctx.getImageData(0, 0, width, height).data;
|
||||||
|
|
||||||
|
for (let i = 0; i < data.length; i += 4) {
|
||||||
|
if (data[i + 3] === 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const c = `${data[i]},${data[i + 1]},${data[i + 2]}`;
|
||||||
|
if (colours.hasOwnProperty(c))
|
||||||
|
colours[c]++;
|
||||||
|
else
|
||||||
|
colours[c] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Canvas is empty, try again next frame
|
||||||
|
if (retryCount < 5 && !Object.keys(colours).length) {
|
||||||
|
retryCount++;
|
||||||
|
Qt.callLater(() => requestPaint());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let max = 0;
|
||||||
|
let maxColour = "0,0,0";
|
||||||
|
for (const [colour, occurences] of Object.entries(colours)) {
|
||||||
|
if (occurences > max) {
|
||||||
|
max = occurences;
|
||||||
|
maxColour = colour;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const [r, g, b] = maxColour.split(",");
|
||||||
|
root.sourceColour = Qt.rgba(r / 255, g / 255, b / 255, 1);
|
||||||
|
retryCount = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,8 +3,10 @@ import QtQuick
|
||||||
import QtQuick.Effects
|
import QtQuick.Effects
|
||||||
|
|
||||||
MultiEffect {
|
MultiEffect {
|
||||||
|
property color sourceColor: "black"
|
||||||
|
|
||||||
colorization: 1
|
colorization: 1
|
||||||
brightness: colorizationColor.hslLightness
|
brightness: 1 - sourceColor.hslLightness
|
||||||
|
|
||||||
Behavior on colorizationColor {
|
Behavior on colorizationColor {
|
||||||
ColorAnimation {
|
ColorAnimation {
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,10 @@
|
||||||
import qs.components.effects
|
import qs.components.effects
|
||||||
import qs.services
|
import qs.services
|
||||||
import qs.utils
|
|
||||||
import qs.config
|
import qs.config
|
||||||
import Quickshell.Widgets
|
import qs.utils
|
||||||
|
|
||||||
IconImage {
|
ColouredIcon {
|
||||||
source: SysInfo.osLogo
|
source: SysInfo.osLogo
|
||||||
implicitSize: Appearance.font.size.large * 1.2
|
implicitSize: Appearance.font.size.large * 1.2
|
||||||
|
colour: Colours.palette.m3tertiary
|
||||||
layer.enabled: true
|
|
||||||
layer.effect: Colouriser {
|
|
||||||
colorizationColor: Colours.palette.m3tertiary
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,7 @@ StyledRect {
|
||||||
|
|
||||||
Colouriser {
|
Colouriser {
|
||||||
source: root.mask
|
source: root.mask
|
||||||
|
sourceColor: Colours.palette.m3onSurface
|
||||||
colorizationColor: Colours.palette.m3onPrimary
|
colorizationColor: Colours.palette.m3onPrimary
|
||||||
|
|
||||||
x: 0
|
x: 0
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ import qs.services
|
||||||
import qs.config
|
import qs.config
|
||||||
import qs.utils
|
import qs.utils
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Widgets
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
|
|
@ -119,7 +118,7 @@ Row {
|
||||||
implicitWidth: icon.implicitWidth + text.width + text.anchors.leftMargin
|
implicitWidth: icon.implicitWidth + text.width + text.anchors.leftMargin
|
||||||
implicitHeight: Math.max(icon.implicitHeight, text.implicitHeight)
|
implicitHeight: Math.max(icon.implicitHeight, text.implicitHeight)
|
||||||
|
|
||||||
IconImage {
|
ColouredIcon {
|
||||||
id: icon
|
id: icon
|
||||||
|
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
|
|
@ -127,11 +126,7 @@ Row {
|
||||||
|
|
||||||
source: SysInfo.osLogo
|
source: SysInfo.osLogo
|
||||||
implicitSize: Math.floor(Appearance.font.size.normal * 1.34)
|
implicitSize: Math.floor(Appearance.font.size.normal * 1.34)
|
||||||
|
colour: Colours.palette.m3primary
|
||||||
layer.enabled: true
|
|
||||||
layer.effect: Colouriser {
|
|
||||||
colorizationColor: Colours.palette.m3primary
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,10 @@
|
||||||
pragma ComponentBehavior: Bound
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
import qs.components
|
import qs.components
|
||||||
import qs.components.widgets
|
|
||||||
import qs.components.effects
|
import qs.components.effects
|
||||||
import qs.services
|
import qs.services
|
||||||
import qs.config
|
import qs.config
|
||||||
import qs.utils
|
import qs.utils
|
||||||
import Quickshell.Widgets
|
|
||||||
import Quickshell.Services.UPower
|
import Quickshell.Services.UPower
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
|
|
@ -149,15 +147,11 @@ ColumnLayout {
|
||||||
visible: active
|
visible: active
|
||||||
}
|
}
|
||||||
|
|
||||||
component OsLogo: IconImage {
|
component OsLogo: ColouredIcon {
|
||||||
source: SysInfo.osLogo
|
source: SysInfo.osLogo
|
||||||
implicitSize: height
|
implicitSize: height
|
||||||
asynchronous: true
|
colour: Colours.palette.m3primary
|
||||||
|
|
||||||
layer.enabled: Config.lock.recolourLogo || SysInfo.isDefaultLogo
|
layer.enabled: Config.lock.recolourLogo || SysInfo.isDefaultLogo
|
||||||
layer.effect: Colouriser {
|
|
||||||
colorizationColor: Colours.palette.m3primary
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
component FetchText: MonoText {
|
component FetchText: MonoText {
|
||||||
|
|
|
||||||
|
|
@ -62,15 +62,11 @@ StyledRect {
|
||||||
Component {
|
Component {
|
||||||
id: appIconComp
|
id: appIconComp
|
||||||
|
|
||||||
IconImage {
|
ColouredIcon {
|
||||||
implicitSize: Math.round(Config.notifs.sizes.image * 0.6)
|
implicitSize: Math.round(Config.notifs.sizes.image * 0.6)
|
||||||
source: Quickshell.iconPath(root.appIcon)
|
source: Quickshell.iconPath(root.appIcon)
|
||||||
asynchronous: true
|
colour: root.urgency === "critical" ? Colours.palette.m3onError : root.urgency === "low" ? Colours.palette.m3onSurface : Colours.palette.m3onSecondaryContainer
|
||||||
|
|
||||||
layer.enabled: root.appIcon.endsWith("symbolic")
|
layer.enabled: root.appIcon.endsWith("symbolic")
|
||||||
layer.effect: Colouriser {
|
|
||||||
colorizationColor: root.urgency === "critical" ? Colours.palette.m3onError : root.urgency === "low" ? Colours.palette.m3onSurface : Colours.palette.m3onSecondaryContainer
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -109,16 +105,12 @@ StyledRect {
|
||||||
color: root.urgency === "critical" ? Colours.palette.m3error : root.urgency === "low" ? Colours.palette.m3surfaceContainerHighest : Colours.palette.m3secondaryContainer
|
color: root.urgency === "critical" ? Colours.palette.m3error : root.urgency === "low" ? Colours.palette.m3surfaceContainerHighest : Colours.palette.m3secondaryContainer
|
||||||
radius: Appearance.rounding.full
|
radius: Appearance.rounding.full
|
||||||
|
|
||||||
IconImage {
|
ColouredIcon {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
implicitSize: Math.round(Config.notifs.sizes.badge * 0.6)
|
implicitSize: Math.round(Config.notifs.sizes.badge * 0.6)
|
||||||
source: Quickshell.iconPath(root.appIcon)
|
source: Quickshell.iconPath(root.appIcon)
|
||||||
asynchronous: true
|
colour: root.urgency === "critical" ? Colours.palette.m3onError : root.urgency === "low" ? Colours.palette.m3onSurface : Colours.palette.m3onSecondaryContainer
|
||||||
|
|
||||||
layer.enabled: root.appIcon.endsWith("symbolic")
|
layer.enabled: root.appIcon.endsWith("symbolic")
|
||||||
layer.effect: Colouriser {
|
|
||||||
colorizationColor: root.urgency === "critical" ? Colours.palette.m3onError : root.urgency === "low" ? Colours.palette.m3onSurface : Colours.palette.m3onSecondaryContainer
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -162,15 +162,11 @@ StyledRect {
|
||||||
width: Math.round(parent.width * 0.6)
|
width: Math.round(parent.width * 0.6)
|
||||||
height: Math.round(parent.width * 0.6)
|
height: Math.round(parent.width * 0.6)
|
||||||
|
|
||||||
sourceComponent: IconImage {
|
sourceComponent: ColouredIcon {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
source: Quickshell.iconPath(root.modelData.appIcon)
|
source: Quickshell.iconPath(root.modelData.appIcon)
|
||||||
asynchronous: true
|
colour: root.modelData.urgency === NotificationUrgency.Critical ? Colours.palette.m3onError : root.modelData.urgency === NotificationUrgency.Low ? Colours.palette.m3onSurface : Colours.palette.m3onTertiaryContainer
|
||||||
|
|
||||||
layer.enabled: root.modelData.appIcon.endsWith("symbolic")
|
layer.enabled: root.modelData.appIcon.endsWith("symbolic")
|
||||||
layer.effect: Colouriser {
|
|
||||||
colorizationColor: root.modelData.urgency === NotificationUrgency.Critical ? Colours.palette.m3onError : root.modelData.urgency === NotificationUrgency.Low ? Colours.palette.m3onSurface : Colours.palette.m3onTertiaryContainer
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue