Skip to content

Commit 27eecdf

Browse files
committed
feat: secondary border
1 parent 9ac80b8 commit 27eecdf

File tree

5 files changed

+230
-144
lines changed

5 files changed

+230
-144
lines changed

package/contents/ui/CustomBorder.qml

+130
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
pragma ComponentBehavior: Bound
2+
import QtQuick
3+
import QtQuick.Effects
4+
import org.kde.kirigami as Kirigami
5+
6+
Rectangle {
7+
id: root
8+
anchors.fill: parent
9+
color: "transparent"
10+
property var cfgBorder
11+
Kirigami.Theme.colorSet: Kirigami.Theme[cfgBorder.color.systemColorSet]
12+
property color borderColor
13+
property var corners: {
14+
"topLeftRadius": 0,
15+
"topRightRadius": 0,
16+
"bottomLeftRadius": 0,
17+
"bottomRightRadius": 0
18+
}
19+
property bool horizontal: false
20+
property int unifyBgType: 0
21+
22+
Rectangle {
23+
id: customBorderTop
24+
width: parent.width
25+
visible: root.cfgBorder.customSides && root.cfgBorder.custom.widths.top
26+
height: root.cfgBorder.custom.widths.top
27+
color: root.borderColor
28+
anchors.top: parent.top
29+
}
30+
Rectangle {
31+
id: customBorderBottom
32+
width: parent.width
33+
visible: root.cfgBorder.customSides && root.cfgBorder.custom.widths.bottom
34+
height: root.cfgBorder.custom.widths.bottom
35+
color: root.borderColor
36+
anchors.bottom: parent.bottom
37+
}
38+
39+
Rectangle {
40+
id: customBorderLeft
41+
height: parent.height
42+
visible: root.cfgBorder.customSides && root.cfgBorder.custom.widths.left
43+
width: root.cfgBorder.custom.widths.left
44+
color: root.borderColor
45+
anchors.left: parent.left
46+
}
47+
Rectangle {
48+
id: customBorderRight
49+
height: parent.height
50+
visible: root.cfgBorder.customSides && root.cfgBorder.custom.widths.right
51+
width: root.cfgBorder.custom.widths.right
52+
color: root.borderColor
53+
anchors.right: parent.right
54+
}
55+
56+
Kirigami.ShadowedRectangle {
57+
id: normalBorder
58+
anchors.fill: parent
59+
color: "transparent"
60+
// the mask source needs to be hidden by default
61+
visible: false
62+
border {
63+
color: root.borderColor
64+
width: !root.cfgBorder.customSides ? root.cfgBorder.width || -1 : 0
65+
}
66+
corners {
67+
topLeftRadius: root.corners.topLeftRadius
68+
topRightRadius: root.corners.topRightRadius
69+
bottomLeftRadius: root.corners.bottomLeftRadius
70+
bottomRightRadius: root.corners.bottomRightRadius
71+
}
72+
}
73+
74+
// Mask to hide one or two borders for unified backgrounds
75+
MultiEffect {
76+
source: normalBorder
77+
anchors.fill: normalBorder
78+
maskEnabled: true
79+
maskSource: rightBorderMask
80+
maskInverted: true
81+
}
82+
Item {
83+
id: rightBorderMask
84+
layer.enabled: true
85+
visible: false
86+
width: root.width
87+
height: root.height
88+
Rectangle {
89+
id: rect1
90+
width: root.horizontal ? root.cfgBorder.width : root.width - (root.cfgBorder.width * 2)
91+
height: root.horizontal ? root.height - (root.cfgBorder.width * 2) : root.cfgBorder.width
92+
color: (root.unifyBgType === 1 || root.unifyBgType === 2) ? "black" : "transparent"
93+
anchors.right: root.horizontal ? parent.right : undefined
94+
anchors.bottom: !root.horizontal ? parent.bottom : undefined
95+
anchors.verticalCenter: root.horizontal ? parent.verticalCenter : undefined
96+
anchors.horizontalCenter: !root.horizontal ? parent.horizontalCenter : undefined
97+
98+
}
99+
Rectangle {
100+
id: rect2
101+
width: root.horizontal ? root.cfgBorder.width : root.width - (root.cfgBorder.width * 2)
102+
height: root.horizontal ? root.height - (root.cfgBorder.width * 2) : root.cfgBorder.width
103+
color: (root.unifyBgType === 2 || root.unifyBgType === 3) ? "black" : "transparent"
104+
anchors.left: root.horizontal ? parent.left : undefined
105+
anchors.top: !root.horizontal ? parent.top : undefined
106+
anchors.verticalCenter: root.horizontal ? parent.verticalCenter : undefined
107+
anchors.horizontalCenter: !root.horizontal ? parent.horizontalCenter : undefined
108+
}
109+
}
110+
111+
layer.enabled: root.cfgBorder.customSides
112+
layer.effect: MultiEffect {
113+
maskEnabled: true
114+
maskSpreadAtMax: 1
115+
maskSpreadAtMin: 1
116+
maskThresholdMin: 0.5
117+
maskSource: ShaderEffectSource {
118+
sourceItem: Kirigami.ShadowedRectangle {
119+
width: root.width
120+
height: root.height
121+
corners {
122+
topLeftRadius: root.corners.topLeftRadius
123+
topRightRadius: root.corners.topRightRadius
124+
bottomLeftRadius: root.corners.bottomLeftRadius
125+
bottomRightRadius: root.corners.bottomRightRadius
126+
}
127+
}
128+
}
129+
}
130+
}

package/contents/ui/code/globals.js

+4
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ const basePanelConfig = {
163163
"margin": baseMargin,
164164
"padding": basePadding,
165165
"border": baseBorder,
166+
"borderSecondary": baseBorder,
166167
"shadow": baseShadowConfig,
167168
"floatingDialogs": false
168169
}
@@ -176,6 +177,7 @@ const baseWidgetConfig = {
176177
"margin": baseMargin,
177178
"spacing": 4,
178179
"border": baseBorder,
180+
"borderSecondary": baseBorder,
179181
"shadow": baseShadowConfig,
180182
}
181183

@@ -187,6 +189,7 @@ const baseTrayConfig = {
187189
"radius": baseRadius,
188190
"margin": baseMargin,
189191
"border": baseBorder,
192+
"borderSecondary": baseBorder,
190193
"shadow": baseShadowConfig,
191194
}
192195

@@ -198,6 +201,7 @@ const baseOverrideConfig = {
198201
"margin": baseMargin,
199202
"spacing": 4,
200203
"border": baseBorder,
204+
"borderSecondary": baseBorder,
201205
"shadow": baseShadowConfig,
202206
"enabled": true,
203207
"disabledFallback": true

package/contents/ui/components/FormBorder.qml

+31-29
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ Kirigami.FormLayout {
1010
twinFormLayouts: parentLayout
1111
Layout.fillWidth: true
1212
property bool isSection: true
13+
property string sectionName
1314
// wether read from the string or existing config object
1415
property bool handleString
1516
// internal config objects to be sent, both string and json
@@ -21,17 +22,17 @@ Kirigami.FormLayout {
2122
configString = JSON.stringify(config, null, null)
2223
updateConfigString(configString, config)
2324
}
24-
// Kirigami.Separator {
25-
// Kirigami.FormData.isSection: isSection
26-
// Kirigami.FormData.label: i18n("Border")
27-
// }
25+
Kirigami.Separator {
26+
Kirigami.FormData.isSection: isSection
27+
Kirigami.FormData.label: sectionName || i18n("Border")
28+
}
2829

2930
CheckBox {
3031
Kirigami.FormData.label: i18n("Enabled:")
3132
id: enabledCheckbox
32-
checked: config.border.enabled
33+
checked: config.enabled
3334
onCheckedChanged: {
34-
config.border.enabled = checked
35+
config.enabled = checked
3536
updateConfig()
3637
}
3738
Binding {
@@ -43,29 +44,30 @@ Kirigami.FormLayout {
4344
Kirigami.Theme.inherit: false
4445
text: checked ? "" : i18n("Disabled")
4546
}
46-
47-
SpinBox {
48-
Kirigami.FormData.label: i18n("Width:")
49-
id: borderWidth
50-
value: config.border.width
51-
from: 0
52-
to: 99
53-
Layout.row: 1
54-
Layout.column: 2
55-
onValueModified: {
56-
config.border.width = value
57-
updateConfig()
47+
RowLayout {
48+
SpinBoxDecimal {
49+
Kirigami.FormData.label: i18n("Width:")
50+
id: borderWidth
51+
value: config.width
52+
from: 0
53+
to: 99
54+
Layout.preferredWidth: Kirigami.Units.gridUnit * 5
55+
Layout.fillWidth: false
56+
onValueChanged: {
57+
config.width = value
58+
updateConfig()
59+
}
60+
enabled: !borderCustomSidesCheckbox.checked && enabledCheckbox.checked
5861
}
59-
enabled: !borderCustomSidesCheckbox.checked && enabledCheckbox.checked
6062
}
6163

6264
RowLayout {
6365
Kirigami.FormData.label: i18n("Custom widths:")
6466
CheckBox {
6567
id: borderCustomSidesCheckbox
66-
checked: config.border.customSides
68+
checked: config.customSides
6769
onCheckedChanged: {
68-
config.border.customSides = checked
70+
config.customSides = checked
6971
updateConfig()
7072
}
7173
}
@@ -76,50 +78,50 @@ Kirigami.FormLayout {
7678
enabled: borderCustomSidesCheckbox.checked && enabledCheckbox.checked
7779
SpinBox {
7880
id: topBorderWidth
79-
value: config.border.custom.widths.top
81+
value: config.custom.widths.top
8082
from: 0
8183
to: 99
8284
Layout.row: 0
8385
Layout.column: 1
8486
onValueModified: {
85-
config.border.custom.widths.top = value
87+
config.custom.widths.top = value
8688
updateConfig()
8789
}
8890
}
8991
SpinBox {
9092
id: bottomBorderWidth
91-
value: config.border.custom.widths.bottom
93+
value: config.custom.widths.bottom
9294
from: 0
9395
to: 99
9496
Layout.row: 2
9597
Layout.column: 1
9698
onValueModified: {
97-
config.border.custom.widths.bottom = value
99+
config.custom.widths.bottom = value
98100
updateConfig()
99101
}
100102
}
101103
SpinBox {
102104
id: leftBorderWidth
103-
value: config.border.custom.widths.left
105+
value: config.custom.widths.left
104106
from: 0
105107
to: 99
106108
Layout.row: 1
107109
Layout.column: 0
108110
onValueModified: {
109-
config.border.custom.widths.left = value
111+
config.custom.widths.left = value
110112
updateConfig()
111113
}
112114
}
113115

114116
SpinBox {
115117
id: rightBorderWidth
116-
value: config.border.custom.widths.right
118+
value: config.custom.widths.right
117119
from: 0
118120
to: 99
119121
Layout.row: 1
120122
Layout.column: 2
121123
onValueModified: {
122-
config.border.custom.widths.right = value
124+
config.custom.widths.right = value
123125
updateConfig()
124126
}
125127
}

package/contents/ui/components/FormWidgetSettings.qml

+29-2
Original file line numberDiff line numberDiff line change
@@ -297,16 +297,19 @@ ColumnLayout {
297297
}
298298

299299
FormBorder {
300+
isSection: true
301+
sectionName: i18n("Primary Border")
300302
enabled: backgroundRoot.isEnabled
301303
visible: currentTab === 2
302-
config: backgroundRoot.configLocal
304+
config: backgroundRoot.configLocal.border
303305
onUpdateConfigString: (newString, newConfig) => {
304-
backgroundRoot.configLocal = newConfig
306+
backgroundRoot.configLocal.border = newConfig
305307
backgroundRoot.updateConfig()
306308
}
307309
}
308310

309311
FormColors {
312+
isSection: false
310313
enabled: backgroundRoot.isEnabled
311314
visible: currentTab === 2
312315
config: backgroundRoot.configLocal.border.color
@@ -317,6 +320,30 @@ ColumnLayout {
317320
followOptions: followVisbility.foreground
318321
}
319322

323+
FormBorder {
324+
isSection: true
325+
sectionName: i18n("Secondary Border")
326+
enabled: backgroundRoot.isEnabled
327+
visible: currentTab === 2
328+
config: backgroundRoot.configLocal.borderSecondary
329+
onUpdateConfigString: (newString, newConfig) => {
330+
backgroundRoot.configLocal.borderSecondary = newConfig
331+
backgroundRoot.updateConfig()
332+
}
333+
}
334+
335+
FormColors {
336+
isSection: false
337+
enabled: backgroundRoot.isEnabled
338+
visible: currentTab === 2
339+
config: backgroundRoot.configLocal.borderSecondary.color
340+
onUpdateConfigString: (newString, newConfig) => {
341+
backgroundRoot.configLocal.borderSecondary.color = newConfig
342+
backgroundRoot.updateConfig()
343+
}
344+
followOptions: followVisbility.foreground
345+
}
346+
320347
FormShadow {
321348
enabled: backgroundRoot.isEnabled
322349
visible: currentTab === 3

0 commit comments

Comments
 (0)