diff --git a/Assets/Translations/en.json b/Assets/Translations/en.json index 4993c64447..6547e81b7a 100644 --- a/Assets/Translations/en.json +++ b/Assets/Translations/en.json @@ -849,6 +849,8 @@ "appearance-margins-description": "Adjust the margins around the floating bar.", "appearance-margins-horizontal": "Horizontal Margin ", "appearance-margins-vertical": "Vertical Margin", + "appearance-floating-outer-edge-rounding-description": "When the floating bar touches a screen edge, draw outward rounding on that edge. Requires the opposite margin to be at least {minMargin}px (container radius + screen corners radius).", + "appearance-floating-outer-edge-rounding-label": "Outer rounding on touching edge", "appearance-outer-corners-description": "Display outwardly curved corners on the bar.", "appearance-outer-corners-label": "Outer corners", "appearance-position-description": "Choose where to place the bar on the screen.", diff --git a/Assets/settings-default.json b/Assets/settings-default.json index 5057d99293..4f83764535 100644 --- a/Assets/settings-default.json +++ b/Assets/settings-default.json @@ -17,6 +17,7 @@ "useSeparateOpacity": false, "marginVertical": 4, "marginHorizontal": 4, + "floatingOuterEdgeRounding": false, "frameThickness": 8, "frameRadius": 12, "outerCorners": true, diff --git a/Assets/settings-search-index.json b/Assets/settings-search-index.json index fbff4a4414..4e5793901b 100644 --- a/Assets/settings-search-index.json +++ b/Assets/settings-search-index.json @@ -371,6 +371,18 @@ "Settings.data.bar.barType === \"floating\"" ] }, + { + "labelKey": "panels.bar.appearance-floating-outer-edge-rounding-label", + "descriptionKey": "panels.bar.appearance-floating-outer-edge-rounding-description", + "widget": "NToggle", + "tab": 4, + "tabLabel": "panels.bar.title", + "subTab": 0, + "subTabLabel": "common.appearance", + "visibleWhen": [ + "Settings.data.bar.barType === \"floating\"" + ] + }, { "labelKey": "panels.bar.appearance-auto-hide-delay-label", "descriptionKey": "panels.bar.appearance-auto-hide-delay-description", diff --git a/Commons/Settings.qml b/Commons/Settings.qml index ad6508e947..ae443a1613 100644 --- a/Commons/Settings.qml +++ b/Commons/Settings.qml @@ -194,6 +194,7 @@ Singleton { // Floating bar settings property int marginVertical: 4 property int marginHorizontal: 4 + property bool floatingOuterEdgeRounding: false // Framed bar settings property int frameThickness: 8 diff --git a/Modules/Bar/Bar.qml b/Modules/Bar/Bar.qml index 51eac97ace..51078a45bd 100644 --- a/Modules/Bar/Bar.qml +++ b/Modules/Bar/Bar.qml @@ -68,6 +68,11 @@ Item { readonly property string barPosition: Settings.getBarPositionForScreen(screen?.name) readonly property bool barIsVertical: barPosition === "left" || barPosition === "right" readonly property bool barFloating: Settings.data.bar.barType === "floating" + readonly property bool floatingOuterEdgeRounding: barFloating && (Settings.data.bar.floatingOuterEdgeRounding ?? false) + readonly property real barFloatMarginH: barFloating ? (Settings.data.bar.marginHorizontal ?? 0) : 0 + readonly property real barFloatMarginV: barFloating ? (Settings.data.bar.marginVertical ?? 0) : 0 + readonly property real floatingOuterRoundingThreshold: Style.radiusL + Style.screenRadius + readonly property bool floatingOuterRoundingAllowed: barIsVertical ? (barFloatMarginV >= floatingOuterRoundingThreshold) : (barFloatMarginH >= floatingOuterRoundingThreshold) // Bar density (per-screen) readonly property string barDensity: Settings.getBarDensityForScreen(screen?.name) @@ -224,9 +229,14 @@ Item { // State 1: Horizontal inversion (outer curve on X-axis) // State 2: Vertical inversion (outer curve on Y-axis) readonly property int topLeftCornerState: { - // Floating bar: always simple rounded corners - if (barFloating) + // Floating bar: flatten corners only on side touching screen edge + if (barFloating) { + if (barPosition === "top" && root.barFloatMarginV <= 0) + return (root.floatingOuterEdgeRounding && root.floatingOuterRoundingAllowed) ? 1 : -1; + if (barPosition === "left" && root.barFloatMarginH <= 0) + return (root.floatingOuterEdgeRounding && root.floatingOuterRoundingAllowed) ? 2 : -1; return 0; + } // Top bar: top corners against screen edge = no radius if (barPosition === "top") return -1; @@ -242,9 +252,14 @@ Item { } readonly property int topRightCornerState: { - // Floating bar: always simple rounded corners - if (barFloating) + // Floating bar: flatten corners only on side touching screen edge + if (barFloating) { + if (barPosition === "top" && root.barFloatMarginV <= 0) + return (root.floatingOuterEdgeRounding && root.floatingOuterRoundingAllowed) ? 1 : -1; + if (barPosition === "right" && root.barFloatMarginH <= 0) + return (root.floatingOuterEdgeRounding && root.floatingOuterRoundingAllowed) ? 2 : -1; return 0; + } // Top bar: top corners against screen edge = no radius if (barPosition === "top") return -1; @@ -260,9 +275,14 @@ Item { } readonly property int bottomLeftCornerState: { - // Floating bar: always simple rounded corners - if (barFloating) + // Floating bar: flatten corners only on side touching screen edge + if (barFloating) { + if (barPosition === "bottom" && root.barFloatMarginV <= 0) + return (root.floatingOuterEdgeRounding && root.floatingOuterRoundingAllowed) ? 1 : -1; + if (barPosition === "left" && root.barFloatMarginH <= 0) + return (root.floatingOuterEdgeRounding && root.floatingOuterRoundingAllowed) ? 2 : -1; return 0; + } // Bottom bar: bottom corners against screen edge = no radius if (barPosition === "bottom") return -1; @@ -278,9 +298,14 @@ Item { } readonly property int bottomRightCornerState: { - // Floating bar: always simple rounded corners - if (barFloating) + // Floating bar: flatten corners only on side touching screen edge + if (barFloating) { + if (barPosition === "bottom" && root.barFloatMarginV <= 0) + return (root.floatingOuterEdgeRounding && root.floatingOuterRoundingAllowed) ? 1 : -1; + if (barPosition === "right" && root.barFloatMarginH <= 0) + return (root.floatingOuterEdgeRounding && root.floatingOuterRoundingAllowed) ? 2 : -1; return 0; + } // Bottom bar: bottom corners against screen edge = no radius if (barPosition === "bottom") return -1; diff --git a/Modules/MainScreen/MainScreen.qml b/Modules/MainScreen/MainScreen.qml index 4526a29d3d..82ca962153 100644 --- a/Modules/MainScreen/MainScreen.qml +++ b/Modules/MainScreen/MainScreen.qml @@ -440,8 +440,13 @@ PanelWindow { readonly property bool isFramed: Settings.data.bar.barType === "framed" readonly property real frameThickness: Settings.data.bar.frameThickness ?? 12 readonly property bool barFloating: Settings.data.bar.barType === "floating" + readonly property bool floatingOuterEdgeRounding: barFloating && (Settings.data.bar.floatingOuterEdgeRounding ?? false) readonly property real barMarginH: barFloating ? Math.floor(Settings.data.bar.marginHorizontal) : 0 readonly property real barMarginV: barFloating ? Math.floor(Settings.data.bar.marginVertical) : 0 + readonly property real barFloatMarginH: barFloating ? (Settings.data.bar.marginHorizontal ?? 0) : 0 + readonly property real barFloatMarginV: barFloating ? (Settings.data.bar.marginVertical ?? 0) : 0 + readonly property real floatingOuterRoundingThreshold: Style.radiusL + Style.screenRadius + readonly property bool floatingOuterRoundingAllowed: barIsVertical ? (barFloatMarginV >= floatingOuterRoundingThreshold) : (barFloatMarginH >= floatingOuterRoundingThreshold) readonly property real barHeight: Style.getBarHeightForScreen(screen?.name) // Auto-hide properties (read by AllBackgrounds for background fade) @@ -492,8 +497,13 @@ PanelWindow { // Corner states (same as Bar.qml) readonly property int topLeftCornerState: { - if (barFloating) + if (barFloating) { + if (barPosition === "top" && barFloatMarginV <= 0) + return (floatingOuterEdgeRounding && floatingOuterRoundingAllowed) ? 1 : -1; + if (barPosition === "left" && barFloatMarginH <= 0) + return (floatingOuterEdgeRounding && floatingOuterRoundingAllowed) ? 2 : -1; return 0; + } if (barPosition === "top") return -1; if (barPosition === "left") @@ -505,8 +515,13 @@ PanelWindow { } readonly property int topRightCornerState: { - if (barFloating) + if (barFloating) { + if (barPosition === "top" && barFloatMarginV <= 0) + return (floatingOuterEdgeRounding && floatingOuterRoundingAllowed) ? 1 : -1; + if (barPosition === "right" && barFloatMarginH <= 0) + return (floatingOuterEdgeRounding && floatingOuterRoundingAllowed) ? 2 : -1; return 0; + } if (barPosition === "top") return -1; if (barPosition === "right") @@ -518,8 +533,13 @@ PanelWindow { } readonly property int bottomLeftCornerState: { - if (barFloating) + if (barFloating) { + if (barPosition === "bottom" && barFloatMarginV <= 0) + return (floatingOuterEdgeRounding && floatingOuterRoundingAllowed) ? 1 : -1; + if (barPosition === "left" && barFloatMarginH <= 0) + return (floatingOuterEdgeRounding && floatingOuterRoundingAllowed) ? 2 : -1; return 0; + } if (barPosition === "bottom") return -1; if (barPosition === "left") @@ -531,8 +551,13 @@ PanelWindow { } readonly property int bottomRightCornerState: { - if (barFloating) + if (barFloating) { + if (barPosition === "bottom" && barFloatMarginV <= 0) + return (floatingOuterEdgeRounding && floatingOuterRoundingAllowed) ? 1 : -1; + if (barPosition === "right" && barFloatMarginH <= 0) + return (floatingOuterEdgeRounding && floatingOuterRoundingAllowed) ? 2 : -1; return 0; + } if (barPosition === "bottom") return -1; if (barPosition === "right") diff --git a/Modules/Panels/Settings/Tabs/Bar/AppearanceSubTab.qml b/Modules/Panels/Settings/Tabs/Bar/AppearanceSubTab.qml index 61ae9f69d2..f211790f99 100644 --- a/Modules/Panels/Settings/Tabs/Bar/AppearanceSubTab.qml +++ b/Modules/Panels/Settings/Tabs/Bar/AppearanceSubTab.qml @@ -297,10 +297,16 @@ ColumnLayout { } ColumnLayout { + id: floatingSettings visible: Settings.data.bar.barType === "floating" spacing: Style.marginL Layout.fillWidth: true + readonly property real floatingOuterRoundingThreshold: Style.radiusL + Style.screenRadius + readonly property bool floatingOuterRoundingAllowed: (Settings.data.bar.position === "top" || Settings.data.bar.position === "bottom") + ? Settings.data.bar.marginHorizontal >= floatingOuterRoundingThreshold + : Settings.data.bar.marginVertical >= floatingOuterRoundingThreshold + NDivider { Layout.fillWidth: true } @@ -326,6 +332,18 @@ ColumnLayout { defaultValue: Settings.getDefaultValue("bar.marginHorizontal") onValueChanged: Settings.data.bar.marginHorizontal = value } + + NToggle { + Layout.fillWidth: true + label: I18n.tr("panels.bar.appearance-floating-outer-edge-rounding-label") + description: I18n.tr("panels.bar.appearance-floating-outer-edge-rounding-description", { + minMargin: Math.ceil(floatingSettings.floatingOuterRoundingThreshold) + }) + checked: Settings.data.bar.floatingOuterEdgeRounding + enabled: floatingSettings.floatingOuterRoundingAllowed + defaultValue: Settings.getDefaultValue("bar.floatingOuterEdgeRounding") + onToggled: checked => Settings.data.bar.floatingOuterEdgeRounding = checked + } } NDivider {