Skip to content

Commit 7e952c9

Browse files
committed
feat: fill background with blur when using Keep Proportions positioning
refs: #207
1 parent 419adb2 commit 7e952c9

5 files changed

Lines changed: 150 additions & 46 deletions

File tree

package/contents/config/main.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,5 +132,12 @@
132132
<label>Whether or not to resume last playing video on startup</label>
133133
<default>True</default>
134134
</entry>
135+
<entry name="FillBlur" type="Bool">
136+
<label>Blur background filling</label>
137+
<default>true</default>
138+
</entry>
139+
<entry name="FillBlurRadius" type="Int">
140+
<default>64</default>
141+
</entry>
135142
</group>
136143
</kcfg>

package/contents/ui/FadePlayer.qml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ Item {
2222
property int changeWallpaperTimerHours: 0
2323
property int changeWallpaperTimerMs: ((changeWallpaperTimerHours * 60 * 60) + (changeWallpaperTimerMinutes * 60) + changeWallpaperTimerSeconds) * 1000
2424
property bool resumeLastVideo: true
25+
property int fillBlurRadius: 32
26+
property bool fillBlur: true
2527

2628
// Crossfade must not be longer than the shortest video or the fade becomes glitchy
2729
// we don't know the length until a video gets played, so the crossfade duration
@@ -43,8 +45,8 @@ Item {
4345
property bool primaryPlayer: true
4446
property VideoPlayer player: primaryPlayer ? videoPlayer1 : videoPlayer2
4547
property VideoPlayer otherPlayer: primaryPlayer ? videoPlayer2 : videoPlayer1
46-
property VideoPlayer player1: videoPlayer1
47-
property VideoPlayer player2: videoPlayer2
48+
readonly property alias player1: videoPlayer1
49+
readonly property alias player2: videoPlayer2
4850

4951
function play() {
5052
player.play();
@@ -105,6 +107,8 @@ Item {
105107
z: 2
106108
opacity: 1
107109
fillMode: root.fillMode
110+
fillBlur: root.fillBlur
111+
fillBlurRadius: root.fillBlurRadius
108112
loops: {
109113
if (!root.multipleVideos || (root.currentSource.loop && !root.crossfadeEnabled))
110114
return MediaPlayer.Infinite;
@@ -192,6 +196,8 @@ Item {
192196
muted: root.muted
193197
z: 1
194198
fillMode: root.fillMode
199+
fillBlur: root.fillBlur
200+
fillBlurRadius: root.fillBlurRadius
195201
loops: {
196202
if (!root.multipleVideos || (root.currentSource.loop && !root.crossfadeEnabled))
197203
return MediaPlayer.Infinite;

package/contents/ui/VideoPlayer.qml

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
import QtQuick
22
import QtMultimedia
3+
import Qt5Compat.GraphicalEffects
34

45
Item {
56
id: root
67
property real volume: 1.0
78
property int actualDuration: player.duration / playbackRate
9+
property int fillBlurRadius: 32
10+
property bool fillBlur: true
811
property alias source: player.source
912
property alias muted: audioOutput.muted
1013
property alias playbackRate: player.playbackRate
@@ -15,6 +18,19 @@ Item {
1518
readonly property alias playing: player.playing
1619
readonly property alias seekable: player.seekable
1720
readonly property alias duration: player.duration
21+
readonly property alias videoHeight: videoOutput.contentRect.height
22+
readonly property alias videoWidth: videoOutput.contentRect.width
23+
readonly property bool showFillBlur: root.fillBlur && root.fitScale !== 1
24+
property real fitScale: {
25+
if (height > videoHeight) {
26+
return height / videoHeight;
27+
}
28+
29+
if (width > videoWidth) {
30+
return width / videoWidth;
31+
}
32+
return 1;
33+
}
1834

1935
function play() {
2036
player.play();
@@ -43,4 +59,25 @@ Item {
4359
audioOutput: audioOutput
4460
loops: root.loops
4561
}
62+
63+
ShaderEffectSource {
64+
id: videoBlur
65+
width: parent.width * root.fitScale + (root.fillBlurRadius * 2)
66+
height: parent.height * root.fitScale + (root.fillBlurRadius * 2)
67+
sourceItem: root.showFillBlur ? videoOutput : null
68+
live: true
69+
anchors.centerIn: parent
70+
clip: true
71+
visible: false
72+
}
73+
74+
FastBlur {
75+
id: fillBlur
76+
source: videoBlur
77+
radius: root.fillBlurRadius
78+
visible: root.showFillBlur && videoBlur.sourceItem
79+
anchors.fill: videoBlur
80+
anchors.centerIn: parent
81+
z: -1
82+
}
4683
}

package/contents/ui/config.qml

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ ColumnLayout {
6666
property alias cfg_ChangeWallpaperTimerSeconds: changeWallpaperTimerSecondsSpinBox.value
6767
property alias cfg_ChangeWallpaperTimerMinutes: changeWallpaperTimerMinutesSpinBox.value
6868
property alias cfg_ChangeWallpaperTimerHours: changeWallpaperTimerHoursSpinBox.value
69+
property alias cfg_FillBlur: blurRadioButton.checked
70+
property alias cfg_FillBlurRadius: fillBlurRadius.value
6971
property int currentTab
7072
property bool showVideosList: false
7173
property var isLockScreenSettings: null
@@ -298,12 +300,49 @@ ColumnLayout {
298300
textRole: "text"
299301
valueRole: "value"
300302
}
303+
}
304+
RowLayout {
305+
visible: root.currentTab === 0
306+
Kirigami.FormData.label: i18n("Background:")
307+
ButtonGroup {
308+
id: backgroundGroup
309+
}
310+
RadioButton {
311+
id: blurRadioButton
312+
text: i18n("Blur:")
313+
ButtonGroup.group: backgroundGroup
314+
visible: currentTab === 0
315+
}
301316
Label {
302-
text: i18n("Background:")
317+
text: i18n("radius")
318+
}
319+
SpinBox {
320+
id: fillBlurRadius
321+
from: 0
322+
to: 145
323+
}
324+
Button {
325+
visible: root.cfg_FillBlurRadius > 64
326+
icon.name: "dialog-warning"
327+
ToolTip.text: i18n("Quality of the blur is reduced if value exceeds 64. Higher values may cause the blur to stop working!")
328+
hoverEnabled: true
329+
flat: true
330+
ToolTip.visible: hovered
331+
Kirigami.Theme.inherit: false
332+
Kirigami.Theme.textColor: root.Kirigami.Theme.neutralTextColor
333+
Kirigami.Theme.highlightColor: root.Kirigami.Theme.neutralTextColor
334+
icon.color: Kirigami.Theme.neutralTextColor
335+
}
336+
RadioButton {
337+
id: colorRadioButton
338+
text: i18n("Solid color")
339+
ButtonGroup.group: backgroundGroup
340+
checked: !root.cfg_FillBlur
303341
}
304342
KQuickControls.ColorButton {
305343
id: colorButton
306344
dialogTitle: i18n("Select Background Color")
345+
ButtonGroup.group: backgroundGroup
307346
}
308347
}
309348

@@ -526,7 +565,7 @@ ColumnLayout {
526565
}
527566
Button {
528567
visible: blurRadiusSpinBox.visible && cfg_BlurRadius > 64
529-
icon.name: "dialog-information-symbolic"
568+
icon.name: "dialog-warning"
530569
ToolTip.text: i18n("Quality of the blur is reduced if value exceeds 64. Higher values may cause the blur to stop working!")
531570
hoverEnabled: true
532571
flat: true
@@ -563,7 +602,6 @@ ColumnLayout {
563602
CheckBox {
564603
id: batteryDisablesBlurCheckBox
565604
text: i18n("Disable blur")
566-
visible: blurRadiusSpinBox.visible
567605
}
568606
}
569607

package/contents/ui/main.qml

Lines changed: 57 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import QtQuick
2222
import QtQuick.Layouts
2323
import org.kde.plasma.core as PlasmaCore
24+
import org.kde.ksvg as KSvg
2425
import org.kde.plasma.plasma5support as P5Support
2526
import org.kde.plasma.plasmoid
2627
import Qt5Compat.GraphicalEffects
@@ -253,6 +254,7 @@ WallpaperItem {
253254
anchors.fill: parent
254255
muted: main.muteAudio
255256
lastVideoPosition: main.configuration.LastVideoPosition
257+
visible: main.videosConfig.length !== 0
256258
onSetNextSource: {
257259
main.nextVideo();
258260
}
@@ -265,58 +267,72 @@ WallpaperItem {
265267
changeWallpaperTimerMinutes: main.changeWallpaperTimerMinutes
266268
changeWallpaperTimerHours: main.changeWallpaperTimerHours
267269
fillMode: main.configuration.FillMode
270+
fillBlur: main.configuration.FillBlur && !main.batteryDisablesBlur
271+
fillBlurRadius: main.configuration.FillBlurRadius
268272
volume: main.volume
269273
playbackRate: main.playbackRate
270274
resumeLastVideo: main.configuration.ResumeLastVideo
271275
}
272-
273-
FastBlur {
274-
source: player
275-
radius: main.showBlur ? main.configuration.BlurRadius : 0
276-
visible: radius !== 0
277-
anchors.fill: parent
278-
Behavior on radius {
279-
NumberAnimation {
280-
duration: main.blurAnimationDuration
281-
}
276+
}
277+
FastBlur {
278+
id: mainBlur
279+
source: background
280+
radius: main.showBlur ? main.configuration.BlurRadius : 0
281+
visible: radius !== 0
282+
anchors.fill: background
283+
Behavior on radius {
284+
NumberAnimation {
285+
duration: main.blurAnimationDuration
282286
}
283287
}
288+
}
284289

285-
PlasmaExtras.PlaceholderMessage {
286-
visible: main.videosConfig.length == 0
287-
anchors.centerIn: parent
288-
width: parent.width - Kirigami.Units.gridUnit * 2
289-
iconName: "video-symbolic"
290-
text: i18n("No video source \n" + main.videoUrls)
291-
}
290+
PlasmaExtras.PlaceholderMessage {
291+
visible: main.videosConfig.length == 0
292+
anchors.centerIn: parent
293+
width: parent.width - Kirigami.Units.gridUnit * 2
294+
iconName: "video-symbolic"
295+
text: i18n("No video source \n" + main.videoUrls)
296+
}
292297

298+
Item {
299+
visible: main.debugEnabled
300+
implicitWidth: debugArea.implicitWidth + debugArea.anchors.leftMargin + debugArea.anchors.rightMargin
301+
implicitHeight: debugArea.implicitHeight + debugArea.anchors.topMargin + debugArea.anchors.bottomMargin
302+
x: 40
303+
y: 100
304+
KSvg.FrameSvgItem {
305+
id: frameSvg
306+
imagePath: "widgets/background"
307+
anchors.fill: parent
308+
}
293309
ColumnLayout {
294-
id: root
295-
visible: main.debugEnabled
296-
Item {
297-
Layout.preferredWidth: 1
298-
Layout.preferredHeight: 100
310+
id: debugArea
311+
anchors {
312+
fill: parent
313+
leftMargin: frameSvg.fixedMargins.left
314+
rightMargin: frameSvg.fixedMargins.right
315+
topMargin: frameSvg.fixedMargins.top
316+
bottomMargin: frameSvg.fixedMargins.bottom
299317
}
300-
Kirigami.AbstractCard {
318+
PlasmaComponents.Label {
301319
Layout.margins: Kirigami.Units.largeSpacing
302-
contentItem: PlasmaComponents.Label {
303-
text: {
304-
let text = `filename: ${main.currentSource.filename}\n`;
305-
text += `loops: ${main.currentSource.loop ?? false}\n`;
306-
text += `currentVideoIndex ${main.currentVideoIndex}\n`;
307-
text += `changeWallpaperMode ${main.changeWallpaperMode}\n`;
308-
text += `crossfade ${main.crossfadeEnabled}\n`;
309-
text += `crossfadeDuration ${player.crossfadeDuration} ${player.crossfadeMinDurationLast} ${player.crossfadeMinDurationCurrent}\n`;
310-
text += `multipleVideos ${player.multipleVideos}\n`;
311-
text += `player ${player.player.objectName}\n`;
312-
text += `media status ${player.player.mediaStatus}\n`;
313-
text += `player1 playing ${player.player1.playing}\n`;
314-
text += `player2 playing ${player.player2.playing}\n`;
315-
text += `position ${player.player.position}\n`;
316-
text += `duration ${player.player.duration}\n`;
317-
text += `resumeLastVideo ${player.resumeLastVideo}`;
318-
return text;
319-
}
320+
text: {
321+
let text = `filename: ${main.currentSource.filename}\n`;
322+
text += `loops: ${main.currentSource.loop ?? false}\n`;
323+
text += `currentVideoIndex ${main.currentVideoIndex}\n`;
324+
text += `changeWallpaperMode ${main.changeWallpaperMode}\n`;
325+
text += `crossfade ${main.crossfadeEnabled}\n`;
326+
text += `crossfadeDuration ${player.crossfadeDuration} ${player.crossfadeMinDurationLast} ${player.crossfadeMinDurationCurrent}\n`;
327+
text += `multipleVideos ${player.multipleVideos}\n`;
328+
text += `player ${player.player.objectName}\n`;
329+
text += `media status ${player.player.mediaStatus}\n`;
330+
text += `player1 playing ${player.player1.playing}\n`;
331+
text += `player2 playing ${player.player2.playing}\n`;
332+
text += `position ${player.player.position}\n`;
333+
text += `duration ${player.player.duration}\n`;
334+
text += `resumeLastVideo ${player.resumeLastVideo}`;
335+
return text;
320336
}
321337
}
322338
}

0 commit comments

Comments
 (0)