mirror of
https://github.com/zoriya/noctalia-shell.git
synced 2026-08-15 18:43:59 +00:00
Panels: beautifull NRectangleCurved shape - conditionnal with a new settings, default is true.
This commit is contained in:
@@ -872,6 +872,10 @@
|
||||
"tooltips": {
|
||||
"description": "Tooltips in der gesamten Benutzeroberfläche aktivieren oder deaktivieren.",
|
||||
"label": "Tooltips anzeigen"
|
||||
},
|
||||
"panels-attached-to-bar": {
|
||||
"description": "Wenn aktiviert, werden die Panels mit einem schönen, umgekehrten Eckdesign an der Leiste befestigt.",
|
||||
"label": "Paneele an Stange befestigen"
|
||||
}
|
||||
},
|
||||
"lock-screen": {
|
||||
|
||||
@@ -869,6 +869,10 @@
|
||||
"label": "Disable UI Animations",
|
||||
"description": "Disable all animations for a faster, more responsive experience."
|
||||
},
|
||||
"panels-attached-to-bar": {
|
||||
"label": "Attach panels to bar",
|
||||
"description": "When enabled, panels will be attached to the bar with beautiful inverted corner design"
|
||||
},
|
||||
"panels-overlay": {
|
||||
"label": "Open panels in overlay layer",
|
||||
"description": "Panels will appear above fullscreen windows"
|
||||
|
||||
@@ -872,6 +872,10 @@
|
||||
"tooltips": {
|
||||
"description": "Activar o desactivar los avisos emergentes en toda la interfaz.",
|
||||
"label": "Mostrar sugerencias"
|
||||
},
|
||||
"panels-attached-to-bar": {
|
||||
"description": "Cuando está habilitado, los paneles se adjuntarán a la barra con un hermoso diseño de esquina invertida.",
|
||||
"label": "Adjuntar paneles a la barra"
|
||||
}
|
||||
},
|
||||
"lock-screen": {
|
||||
|
||||
@@ -872,6 +872,10 @@
|
||||
"tooltips": {
|
||||
"description": "Activer ou désactiver les info-bulles dans toute l'interface.",
|
||||
"label": "Afficher les infobulles"
|
||||
},
|
||||
"panels-attached-to-bar": {
|
||||
"description": "Lorsque cette option est activée, les panneaux seront attachés à la barre avec un design élégant de coin inversé.",
|
||||
"label": "Fixer les panneaux à la barre."
|
||||
}
|
||||
},
|
||||
"lock-screen": {
|
||||
|
||||
@@ -872,6 +872,10 @@
|
||||
"tooltips": {
|
||||
"description": "Ativar ou desativar dicas de ferramentas em toda a interface.",
|
||||
"label": "Mostrar dicas de ferramenta"
|
||||
},
|
||||
"panels-attached-to-bar": {
|
||||
"description": "Quando ativado, os painéis serão anexados à barra com um belo design de canto invertido.",
|
||||
"label": "Anexar painéis à barra"
|
||||
}
|
||||
},
|
||||
"lock-screen": {
|
||||
|
||||
@@ -872,6 +872,10 @@
|
||||
"tooltips": {
|
||||
"description": "启用或禁用整个界面的工具提示。",
|
||||
"label": "显示工具提示"
|
||||
},
|
||||
"panels-attached-to-bar": {
|
||||
"description": "启用后,面板将以美观的倒角设计附加到栏上。",
|
||||
"label": "将面板连接到杆上"
|
||||
}
|
||||
},
|
||||
"lock-screen": {
|
||||
|
||||
@@ -217,6 +217,7 @@
|
||||
"fontDefaultScale": 1,
|
||||
"fontFixedScale": 1,
|
||||
"tooltipsEnabled": true,
|
||||
"panelsAttachedToBar": true,
|
||||
"panelsOverlayLayer": true
|
||||
},
|
||||
"brightness": {
|
||||
|
||||
@@ -354,6 +354,7 @@ Singleton {
|
||||
property real fontDefaultScale: 1.0
|
||||
property real fontFixedScale: 1.0
|
||||
property bool tooltipsEnabled: true
|
||||
property bool panelsAttachedToBar: true
|
||||
property bool panelsOverlayLayer: true
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,13 @@ ColumnLayout {
|
||||
onToggled: checked => Settings.data.ui.tooltipsEnabled = checked
|
||||
}
|
||||
|
||||
NToggle {
|
||||
label: I18n.tr("settings.user-interface.panels-attached-to-bar.label")
|
||||
description: I18n.tr("settings.user-interface.panels-attached-to-bar.description")
|
||||
checked: Settings.data.ui.panelsAttachedToBar
|
||||
onToggled: checked => Settings.data.ui.panelsAttachedToBar = checked
|
||||
}
|
||||
|
||||
NToggle {
|
||||
label: I18n.tr("settings.user-interface.panels-overlay.label")
|
||||
description: I18n.tr("settings.user-interface.panels-overlay.description")
|
||||
|
||||
+126
-35
@@ -9,6 +9,7 @@ Loader {
|
||||
|
||||
property ShellScreen screen
|
||||
|
||||
property bool attachedToBar: Settings.data.ui.panelsAttachedToBar
|
||||
property bool useOverlay: Settings.data.ui.panelsOverlayLayer
|
||||
|
||||
property Component panelContent: null
|
||||
@@ -39,10 +40,20 @@ Loader {
|
||||
property bool backgroundClickEnabled: true
|
||||
|
||||
// Animation properties
|
||||
readonly property real originalScale: 0.0
|
||||
property real scaleValue: originalScale
|
||||
property real panelBackgroundOpacity: 0
|
||||
property real panelContentOpacity: 0
|
||||
property real dimmingOpacity: 0
|
||||
|
||||
readonly property string barPosition: Settings.data.bar.position
|
||||
readonly property bool barIsVertical: barPosition === "left" || barPosition === "right"
|
||||
readonly property real verticalBarWidth: Style.barHeight
|
||||
|
||||
// Effective anchor properties - combines explicit anchors with implicit anchoring from useButtonPosition
|
||||
readonly property bool effectivePanelAnchorTop: panelAnchorTop || (useButtonPosition && barPosition === "top")
|
||||
readonly property bool effectivePanelAnchorBottom: panelAnchorBottom || (useButtonPosition && barPosition === "bottom")
|
||||
readonly property bool effectivePanelAnchorLeft: panelAnchorLeft || (useButtonPosition && barPosition === "left")
|
||||
readonly property bool effectivePanelAnchorRight: panelAnchorRight || (useButtonPosition && barPosition === "right")
|
||||
|
||||
signal opened
|
||||
signal closed
|
||||
|
||||
@@ -97,7 +108,8 @@ Loader {
|
||||
// -----------------------------------------
|
||||
function close() {
|
||||
dimmingOpacity = 0
|
||||
scaleValue = originalScale
|
||||
panelBackgroundOpacity = 0
|
||||
panelContentOpacity = 0
|
||||
root.closed()
|
||||
active = false
|
||||
useButtonPosition = false
|
||||
@@ -132,10 +144,7 @@ Loader {
|
||||
PanelWindow {
|
||||
id: panelWindow
|
||||
|
||||
readonly property string barPosition: Settings.data.bar.position
|
||||
readonly property bool isVertical: barPosition === "left" || barPosition === "right"
|
||||
readonly property bool barIsVisible: (screen !== null) && (Settings.data.bar.monitors.includes(screen.name) || (Settings.data.bar.monitors.length === 0))
|
||||
readonly property real verticalBarWidth: Style.barHeight
|
||||
|
||||
Component.onCompleted: {
|
||||
Logger.d("NPanel", "Opened", root.objectName, "on", screen.name)
|
||||
@@ -195,12 +204,73 @@ Loader {
|
||||
}
|
||||
|
||||
// The actual panel's content
|
||||
Rectangle {
|
||||
NRectangleCurved {
|
||||
id: panelBackground
|
||||
color: panelBackgroundColor
|
||||
radius: Style.radiusL
|
||||
border.color: panelBorderColor
|
||||
border.width: Style.borderS
|
||||
|
||||
backgroundColor: panelBackgroundColor
|
||||
|
||||
topLeftRadius: Style.radiusL
|
||||
topRightRadius: Style.radiusL
|
||||
bottomLeftRadius: Style.radiusL
|
||||
bottomRightRadius: Style.radiusL
|
||||
|
||||
// Set inverted corners based on panel anchors and bar position
|
||||
|
||||
// Top-left corner
|
||||
topLeftInverted: {
|
||||
if (!attachedToBar) return false
|
||||
|
||||
// Inverted if panel is anchored to top edge (bar is at top)
|
||||
if (effectivePanelAnchorTop)
|
||||
return true
|
||||
// Or if panel is anchored to left edge (bar is at left)
|
||||
if (effectivePanelAnchorLeft)
|
||||
return true
|
||||
return false
|
||||
}
|
||||
topLeftInvertedDirection: effectivePanelAnchorTop ? "horizontal" : "vertical"
|
||||
|
||||
// Top-right corner
|
||||
topRightInverted: {
|
||||
if (!attachedToBar) return false
|
||||
|
||||
// Inverted if panel is anchored to top edge (bar is at top)
|
||||
if (effectivePanelAnchorTop)
|
||||
return true
|
||||
// Or if panel is anchored to right edge (bar is at right)
|
||||
if (effectivePanelAnchorRight)
|
||||
return true
|
||||
return false
|
||||
}
|
||||
topRightInvertedDirection: effectivePanelAnchorTop ? "horizontal" : "vertical"
|
||||
|
||||
// Bottom-left corner
|
||||
bottomLeftInverted: {
|
||||
if (!attachedToBar) return false
|
||||
|
||||
// Inverted if panel is anchored to bottom edge (bar is at bottom)
|
||||
if (effectivePanelAnchorBottom)
|
||||
return true
|
||||
// Or if panel is anchored to left edge (bar is at left)
|
||||
if (effectivePanelAnchorLeft)
|
||||
return true
|
||||
return false
|
||||
}
|
||||
bottomLeftInvertedDirection: effectivePanelAnchorBottom ? "horizontal" : "vertical"
|
||||
|
||||
// Bottom-right corner
|
||||
bottomRightInverted: {
|
||||
if (!attachedToBar) return false
|
||||
|
||||
// Inverted if panel is anchored to bottom edge (bar is at bottom)
|
||||
if (effectivePanelAnchorBottom)
|
||||
return true
|
||||
// Or if panel is anchored to right edge (bar is at right)
|
||||
if (effectivePanelAnchorRight)
|
||||
return true
|
||||
return false
|
||||
}
|
||||
bottomRightInvertedDirection: effectivePanelAnchorBottom ? "horizontal" : "vertical"
|
||||
|
||||
// Dragging support
|
||||
property bool draggable: root.draggable
|
||||
@@ -229,7 +299,7 @@ Loader {
|
||||
return Math.min(h, screen?.height - Style.barHeight - Style.marginL * 2)
|
||||
}
|
||||
|
||||
scale: root.scaleValue
|
||||
opacity: root.panelBackgroundOpacity
|
||||
x: isDragged ? manualX : calculatedX
|
||||
y: isDragged ? manualY : calculatedY
|
||||
|
||||
@@ -240,11 +310,12 @@ Loader {
|
||||
if (!barIsVisible) {
|
||||
return 0
|
||||
}
|
||||
|
||||
switch (barPosition) {
|
||||
case "top":
|
||||
return (Style.barHeight + Style.marginS) + (Settings.data.bar.floating ? Settings.data.bar.marginVertical * Style.marginXL : 0)
|
||||
return (Style.barHeight + (attachedToBar ? 0 : Style.marginS)) + (Settings.data.bar.floating ? Settings.data.bar.marginVertical * Style.marginXL : 0)
|
||||
default:
|
||||
return Style.marginS
|
||||
return attachedToBar ? 0 : Style.marginS
|
||||
}
|
||||
}
|
||||
|
||||
@@ -254,9 +325,9 @@ Loader {
|
||||
}
|
||||
switch (barPosition) {
|
||||
case "bottom":
|
||||
return (Style.barHeight + Style.marginS) + (Settings.data.bar.floating ? Settings.data.bar.marginVertical * Style.marginXL : 0)
|
||||
return (Style.barHeight + (attachedToBar ? 0 : Style.marginS)) + (Settings.data.bar.floating ? Settings.data.bar.marginVertical * Style.marginXL : 0)
|
||||
default:
|
||||
return Style.marginS
|
||||
return attachedToBar ? 0 : Style.marginS
|
||||
}
|
||||
}
|
||||
|
||||
@@ -266,9 +337,9 @@ Loader {
|
||||
}
|
||||
switch (barPosition) {
|
||||
case "left":
|
||||
return (Style.barHeight + Style.marginS) + (Settings.data.bar.floating ? Settings.data.bar.marginHorizontal * Style.marginXL : 0)
|
||||
return (Style.barHeight + (attachedToBar ? 0 : Style.marginS)) + (Settings.data.bar.floating ? Settings.data.bar.marginHorizontal * Style.marginXL : 0)
|
||||
default:
|
||||
return Style.marginS
|
||||
return attachedToBar ? 0 : Style.marginS
|
||||
}
|
||||
}
|
||||
|
||||
@@ -278,9 +349,9 @@ Loader {
|
||||
}
|
||||
switch (barPosition) {
|
||||
case "right":
|
||||
return (Style.barHeight + Style.marginS) + (Settings.data.bar.floating ? Settings.data.bar.marginHorizontal * Style.marginXL : 0)
|
||||
return (Style.barHeight + (attachedToBar ? 0 : Style.marginS)) + (Settings.data.bar.floating ? Settings.data.bar.marginHorizontal * Style.marginXL : 0)
|
||||
default:
|
||||
return Style.marginS
|
||||
return attachedToBar ? 0 : Style.marginS
|
||||
}
|
||||
}
|
||||
|
||||
@@ -300,7 +371,7 @@ Loader {
|
||||
}
|
||||
|
||||
// No fixed anchoring
|
||||
if (isVertical) {
|
||||
if (barIsVertical) {
|
||||
// Vertical bar
|
||||
if (barPosition === "right") {
|
||||
// To the left of the right bar
|
||||
@@ -341,7 +412,7 @@ Loader {
|
||||
}
|
||||
|
||||
// No fixed anchoring
|
||||
if (isVertical) {
|
||||
if (barIsVertical) {
|
||||
// Vertical bar
|
||||
if (useButtonPosition) {
|
||||
// Position panel relative to button
|
||||
@@ -368,7 +439,28 @@ Loader {
|
||||
|
||||
// Animate in when component is completed
|
||||
Component.onCompleted: {
|
||||
root.scaleValue = 1.0
|
||||
// Start invisible
|
||||
// Use a timer to delay the animation start, allowing QML to properly set up initial state
|
||||
fadeInTimer.start()
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: fadeInTimer
|
||||
interval: 1
|
||||
repeat: false
|
||||
onTriggered: {
|
||||
// Fade in background
|
||||
root.panelBackgroundOpacity = 1.0
|
||||
}
|
||||
}
|
||||
|
||||
// Timer to fade in content after slide animation completes
|
||||
Timer {
|
||||
id: contentFadeInTimer
|
||||
interval: Style.animationFast
|
||||
repeat: false
|
||||
running: true
|
||||
onTriggered: root.panelContentOpacity = 1.0
|
||||
}
|
||||
|
||||
// Reset drag position when panel closes
|
||||
@@ -384,17 +476,10 @@ Loader {
|
||||
anchors.fill: parent
|
||||
}
|
||||
|
||||
// Animation behaviors
|
||||
Behavior on scale {
|
||||
NumberAnimation {
|
||||
duration: Style.animationNormal
|
||||
easing.type: Easing.OutExpo
|
||||
}
|
||||
}
|
||||
|
||||
// Animation behavior
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
duration: Style.animationNormal
|
||||
duration: Style.animationFast
|
||||
easing.type: Easing.OutQuad
|
||||
}
|
||||
}
|
||||
@@ -403,6 +488,14 @@ Loader {
|
||||
id: panelContentLoader
|
||||
anchors.fill: parent
|
||||
sourceComponent: root.panelContent
|
||||
opacity: root.panelContentOpacity
|
||||
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
duration: Style.animationFast
|
||||
easing.type: Easing.OutQuad
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Handle drag move on the whole panel area
|
||||
@@ -460,8 +553,7 @@ Loader {
|
||||
anchors.margins: 0
|
||||
color: Color.transparent
|
||||
border.color: Color.mPrimary
|
||||
border.width: Style.borderL
|
||||
radius: parent.radius
|
||||
border.width: Style.borderM
|
||||
visible: panelBackground.isDragged && dragHandler.active
|
||||
opacity: 0.8
|
||||
z: 3000
|
||||
@@ -473,7 +565,6 @@ Loader {
|
||||
color: Color.transparent
|
||||
border.color: Color.mPrimary
|
||||
border.width: Style.borderS
|
||||
radius: parent.radius
|
||||
opacity: 0.3
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,187 @@
|
||||
import QtQuick
|
||||
import qs.Commons
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
// Corner radius properties
|
||||
property real topLeftRadius: 0
|
||||
property real topRightRadius: 0
|
||||
property real bottomLeftRadius: 0
|
||||
property real bottomRightRadius: 0
|
||||
|
||||
// Inverted corner properties (concave instead of convex)
|
||||
property bool topLeftInverted: false
|
||||
property bool topRightInverted: false
|
||||
property bool bottomLeftInverted: false
|
||||
property bool bottomRightInverted: false
|
||||
|
||||
// Direction for inverted corners: "horizontal" or "vertical"
|
||||
// horizontal: curves left/right (extends beyond left/right edges)
|
||||
// vertical: curves up/down (extends beyond top/bottom edges)
|
||||
property string topLeftInvertedDirection: "horizontal" // default: curves left
|
||||
property string topRightInvertedDirection: "horizontal" // default: curves right
|
||||
property string bottomLeftInvertedDirection: "horizontal" // default: curves left
|
||||
property string bottomRightInvertedDirection: "horizontal" // default: curves right
|
||||
|
||||
// Background color
|
||||
property color backgroundColor: "white"
|
||||
|
||||
// Check if any corner is inverted
|
||||
readonly property bool hasInvertedCorners: topLeftInverted || topRightInverted || bottomLeftInverted || bottomRightInverted
|
||||
|
||||
// Calculate padding needed for inverted corners based on their direction
|
||||
readonly property real topPadding: Math.max((topLeftInverted && topLeftInvertedDirection === "vertical") ? topLeftRadius : 0, (topRightInverted && topRightInvertedDirection === "vertical") ? topRightRadius : 0)
|
||||
readonly property real bottomPadding: Math.max((bottomLeftInverted && bottomLeftInvertedDirection === "vertical") ? bottomLeftRadius : 0, (bottomRightInverted && bottomRightInvertedDirection === "vertical") ? bottomRightRadius : 0)
|
||||
readonly property real leftPadding: Math.max((topLeftInverted && topLeftInvertedDirection === "horizontal") ? topLeftRadius : 0, (bottomLeftInverted && bottomLeftInvertedDirection === "horizontal") ? bottomLeftRadius : 0)
|
||||
readonly property real rightPadding: Math.max((topRightInverted && topRightInvertedDirection === "horizontal") ? topRightRadius : 0, (bottomRightInverted && bottomRightInvertedDirection === "horizontal") ? bottomRightRadius : 0)
|
||||
|
||||
// Simple rectangle for non-inverted corners (better performance)
|
||||
Rectangle {
|
||||
id: simpleBackground
|
||||
anchors.fill: parent
|
||||
color: root.backgroundColor
|
||||
radius: topLeftRadius // Use topLeftRadius as default
|
||||
visible: !root.hasInvertedCorners
|
||||
|
||||
topLeftRadius: root.topLeftRadius
|
||||
topRightRadius: root.topRightRadius
|
||||
bottomLeftRadius: root.bottomLeftRadius
|
||||
bottomRightRadius: root.bottomRightRadius
|
||||
}
|
||||
|
||||
// Background with custom corners (for inverted corners)
|
||||
Canvas {
|
||||
id: background
|
||||
anchors.fill: parent
|
||||
anchors.topMargin: -root.topPadding
|
||||
anchors.bottomMargin: -root.bottomPadding
|
||||
anchors.leftMargin: -root.leftPadding
|
||||
anchors.rightMargin: -root.rightPadding
|
||||
visible: root.hasInvertedCorners
|
||||
|
||||
onPaint: {
|
||||
var ctx = getContext("2d")
|
||||
ctx.reset()
|
||||
|
||||
// Adjust coordinates to account for inverted corner padding
|
||||
var x = root.leftPadding
|
||||
var y = root.topPadding
|
||||
var w = width - root.leftPadding - root.rightPadding
|
||||
var h = height - root.topPadding - root.bottomPadding
|
||||
|
||||
ctx.fillStyle = root.backgroundColor
|
||||
ctx.beginPath()
|
||||
|
||||
// Start from top left
|
||||
if (topLeftInverted) {
|
||||
if (topLeftInvertedDirection === "vertical") {
|
||||
ctx.moveTo(x, y)
|
||||
} else {
|
||||
ctx.moveTo(x + topLeftRadius, y)
|
||||
}
|
||||
} else {
|
||||
ctx.moveTo(x + topLeftRadius, y)
|
||||
}
|
||||
|
||||
// Top edge and top right corner
|
||||
if (topRightInverted) {
|
||||
if (topRightInvertedDirection === "horizontal") {
|
||||
// Curves to the right
|
||||
ctx.lineTo(x + w, y)
|
||||
ctx.lineTo(x + w + topRightRadius, y)
|
||||
ctx.quadraticCurveTo(x + w, y, x + w, y + topRightRadius)
|
||||
} else {
|
||||
// Curves upward
|
||||
ctx.lineTo(x + w, y)
|
||||
ctx.lineTo(x + w, y - topRightRadius)
|
||||
ctx.quadraticCurveTo(x + w, y, x + w - topRightRadius, y)
|
||||
ctx.lineTo(x + w, y)
|
||||
ctx.lineTo(x + w, y + topRightRadius)
|
||||
}
|
||||
} else {
|
||||
ctx.lineTo(x + w - topRightRadius, y)
|
||||
ctx.arcTo(x + w, y, x + w, y + topRightRadius, topRightRadius)
|
||||
}
|
||||
|
||||
// Right edge and bottom right corner
|
||||
if (bottomRightInverted) {
|
||||
if (bottomRightInvertedDirection === "horizontal") {
|
||||
// Curves to the right
|
||||
ctx.lineTo(x + w, y + h - bottomRightRadius)
|
||||
ctx.quadraticCurveTo(x + w, y + h, x + w + bottomRightRadius, y + h)
|
||||
ctx.lineTo(x + w, y + h)
|
||||
ctx.lineTo(x + w - bottomRightRadius, y + h)
|
||||
} else {
|
||||
// Curves downward
|
||||
ctx.lineTo(x + w, y + h)
|
||||
ctx.lineTo(x + w, y + h + bottomRightRadius)
|
||||
ctx.quadraticCurveTo(x + w, y + h, x + w - bottomRightRadius, y + h)
|
||||
}
|
||||
} else {
|
||||
ctx.lineTo(x + w, y + h - bottomRightRadius)
|
||||
ctx.arcTo(x + w, y + h, x + w - bottomRightRadius, y + h, bottomRightRadius)
|
||||
}
|
||||
|
||||
// Bottom edge and bottom left corner
|
||||
if (bottomLeftInverted) {
|
||||
if (bottomLeftInvertedDirection === "horizontal") {
|
||||
// Curves to the left
|
||||
ctx.lineTo(x + bottomLeftRadius, y + h)
|
||||
ctx.lineTo(x - bottomLeftRadius, y + h)
|
||||
ctx.quadraticCurveTo(x, y + h, x, y + h - bottomLeftRadius)
|
||||
} else {
|
||||
// Curves downward
|
||||
ctx.lineTo(x, y + h)
|
||||
ctx.lineTo(x, y + h + bottomLeftRadius)
|
||||
ctx.quadraticCurveTo(x, y + h, x + bottomLeftRadius, y + h)
|
||||
ctx.lineTo(x, y + h)
|
||||
ctx.lineTo(x, y + h - bottomLeftRadius)
|
||||
}
|
||||
} else {
|
||||
ctx.lineTo(x + bottomLeftRadius, y + h)
|
||||
ctx.arcTo(x, y + h, x, y + h - bottomLeftRadius, bottomLeftRadius)
|
||||
}
|
||||
|
||||
// Left edge and back to top left corner
|
||||
if (topLeftInverted) {
|
||||
if (topLeftInvertedDirection === "horizontal") {
|
||||
// Curves to the left
|
||||
ctx.lineTo(x, y + topLeftRadius)
|
||||
ctx.quadraticCurveTo(x, y, x - topLeftRadius, y)
|
||||
ctx.lineTo(x, y)
|
||||
ctx.lineTo(x + topLeftRadius, y)
|
||||
} else {
|
||||
// Curves upward
|
||||
ctx.lineTo(x, y + topLeftRadius)
|
||||
ctx.lineTo(x, y)
|
||||
ctx.lineTo(x, y - topLeftRadius)
|
||||
ctx.quadraticCurveTo(x, y, x + topLeftRadius, y)
|
||||
}
|
||||
} else {
|
||||
ctx.lineTo(x, y + topLeftRadius)
|
||||
ctx.arcTo(x, y, x + topLeftRadius, y, topLeftRadius)
|
||||
}
|
||||
|
||||
ctx.closePath()
|
||||
ctx.fill()
|
||||
}
|
||||
}
|
||||
|
||||
// Trigger repaint when properties change
|
||||
onTopLeftRadiusChanged: background.requestPaint()
|
||||
onTopRightRadiusChanged: background.requestPaint()
|
||||
onBottomLeftRadiusChanged: background.requestPaint()
|
||||
onBottomRightRadiusChanged: background.requestPaint()
|
||||
onTopLeftInvertedChanged: background.requestPaint()
|
||||
onTopRightInvertedChanged: background.requestPaint()
|
||||
onBottomLeftInvertedChanged: background.requestPaint()
|
||||
onBottomRightInvertedChanged: background.requestPaint()
|
||||
onTopLeftInvertedDirectionChanged: background.requestPaint()
|
||||
onTopRightInvertedDirectionChanged: background.requestPaint()
|
||||
onBottomLeftInvertedDirectionChanged: background.requestPaint()
|
||||
onBottomRightInvertedDirectionChanged: background.requestPaint()
|
||||
onBackgroundColorChanged: background.requestPaint()
|
||||
onWidthChanged: background.requestPaint()
|
||||
onHeightChanged: background.requestPaint()
|
||||
}
|
||||
Reference in New Issue
Block a user