mirror of
https://github.com/noctalia-dev/noctalia-shell.git
synced 2026-05-11 17:08:27 +08:00
feat(layout): implement framed bar visuals and layout logic
This commit is contained in:
@@ -13,6 +13,7 @@ import qs.Services.UI
|
||||
Variants {
|
||||
model: Quickshell.screens
|
||||
delegate: Item {
|
||||
id: windowItem
|
||||
required property ShellScreen modelData
|
||||
|
||||
property bool shouldBeActive: {
|
||||
@@ -76,23 +77,27 @@ Variants {
|
||||
|
||||
// BarExclusionZone - created after MainScreen has fully loaded
|
||||
// Disabled when bar is hidden or not configured for this screen
|
||||
Loader {
|
||||
active: {
|
||||
if (!parent.windowLoaded || !parent.shouldBeActive || !BarService.isVisible)
|
||||
return false;
|
||||
Repeater {
|
||||
model: Settings.data.bar.barType === "framed" ? ["top", "bottom", "left", "right"] : [Settings.getBarPositionForScreen(windowItem.modelData?.name)]
|
||||
delegate: Loader {
|
||||
active: {
|
||||
if (!windowItem.windowLoaded || !windowItem.shouldBeActive || !BarService.effectivelyVisible)
|
||||
return false;
|
||||
|
||||
// Check if bar is configured for this screen
|
||||
var monitors = Settings.data.bar.monitors || [];
|
||||
return monitors.length === 0 || monitors.includes(modelData?.name);
|
||||
}
|
||||
asynchronous: false
|
||||
// Check if bar is configured for this screen
|
||||
var monitors = Settings.data.bar.monitors || [];
|
||||
return monitors.length === 0 || monitors.includes(windowItem.modelData?.name);
|
||||
}
|
||||
asynchronous: false
|
||||
|
||||
sourceComponent: BarExclusionZone {
|
||||
screen: modelData
|
||||
}
|
||||
sourceComponent: BarExclusionZone {
|
||||
screen: windowItem.modelData
|
||||
edge: modelData
|
||||
}
|
||||
|
||||
onLoaded: {
|
||||
Logger.d("AllScreens", "BarExclusionZone created for", modelData?.name);
|
||||
onLoaded: {
|
||||
Logger.d("AllScreens", "BarExclusionZone (" + modelData + ") created for", windowItem.modelData?.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -48,6 +48,11 @@ ShapePath {
|
||||
// Corner radius (from Style)
|
||||
readonly property real radius: Style.radiusL
|
||||
|
||||
// Framed bar properties
|
||||
readonly property bool isFramed: Settings.data.bar.barType === "framed"
|
||||
readonly property real frameThickness: Settings.data.bar.frameThickness ?? 12
|
||||
readonly property real frameRadius: Settings.data.bar.frameRadius ?? 20
|
||||
|
||||
// Bar position - since bar's parent fills the screen and Shape also fills the screen,
|
||||
// we can use bar.x and bar.y directly (they're already in screen coordinates)
|
||||
readonly property point barMappedPos: bar ? Qt.point(bar.x, bar.y) : Qt.point(0, 0)
|
||||
@@ -56,6 +61,18 @@ ShapePath {
|
||||
readonly property real barWidth: (bar && shouldShow) ? bar.width : 0
|
||||
readonly property real barHeight: (bar && shouldShow) ? bar.height : 0
|
||||
|
||||
// Screen dimensions for frame
|
||||
readonly property real screenWidth: windowRoot?.screen?.width || 0
|
||||
readonly property real screenHeight: windowRoot?.screen?.height || 0
|
||||
|
||||
// Inner hole dimensions for framed mode - always relative to screen
|
||||
readonly property string barPosition: Settings.getBarPositionForScreen(windowRoot?.screen?.name)
|
||||
readonly property bool barIsVertical: barPosition === "left" || barPosition === "right"
|
||||
readonly property real holeX: (barPosition === "left") ? barWidth : frameThickness
|
||||
readonly property real holeY: (barPosition === "top") ? barHeight : frameThickness
|
||||
readonly property real holeWidth: screenWidth - (barPosition === "left" || barPosition === "right" ? (barWidth + frameThickness) : (frameThickness * 2))
|
||||
readonly property real holeHeight: screenHeight - (barPosition === "top" || barPosition === "bottom" ? (barHeight + frameThickness) : (frameThickness * 2))
|
||||
|
||||
// Flatten corners if bar is too small (handle null bar)
|
||||
readonly property bool shouldFlatten: bar ? ShapeCornerHelper.shouldFlatten(barWidth, barHeight, radius) : false
|
||||
readonly property real effectiveRadius: shouldFlatten ? (bar ? ShapeCornerHelper.getFlattenedRadius(Math.min(barWidth, barHeight), radius) : 0) : radius
|
||||
@@ -89,73 +106,159 @@ ShapePath {
|
||||
// ShapePath configuration
|
||||
strokeWidth: -1 // No stroke, fill only
|
||||
fillColor: backgroundColor
|
||||
fillRule: isFramed ? ShapePath.OddEvenFill : ShapePath.WindingFill
|
||||
|
||||
// Starting position (top-left corner, after the arc)
|
||||
// Use mapped coordinates relative to the Shape container
|
||||
startX: barMappedPos.x + tlRadius * tlMultX
|
||||
startY: barMappedPos.y
|
||||
// Starting position
|
||||
// In framed mode, we start at (0,0) to draw the screen rectangle first
|
||||
startX: isFramed ? 0 : (barMappedPos.x + tlRadius * tlMultX)
|
||||
startY: isFramed ? 0 : barMappedPos.y
|
||||
|
||||
// ========== PATH DEFINITION ==========
|
||||
// Draws a rectangle with potentially inverted corners
|
||||
// All coordinates are relative to startX/startY
|
||||
|
||||
// Top edge (moving right)
|
||||
// 1. Main Bar / Outer Screen Rectangle
|
||||
PathLine {
|
||||
relativeX: root.barWidth - root.tlRadius * root.tlMultX - root.trRadius * root.trMultX
|
||||
relativeY: 0
|
||||
x: {
|
||||
if (!root.shouldShow)
|
||||
return 0;
|
||||
if (root.isFramed)
|
||||
return root.screenWidth;
|
||||
return root.barMappedPos.x + root.barWidth - root.trRadius * root.trMultX;
|
||||
}
|
||||
y: root.isFramed ? 0 : root.barMappedPos.y
|
||||
}
|
||||
|
||||
// Top-right corner arc
|
||||
// Bar top-right corner (only if not framed)
|
||||
PathArc {
|
||||
relativeX: root.trRadius * root.trMultX
|
||||
relativeY: root.trRadius * root.trMultY
|
||||
radiusX: root.trRadius
|
||||
radiusY: root.trRadius
|
||||
x: root.isFramed ? (root.shouldShow ? root.screenWidth : 0) : (root.barMappedPos.x + root.barWidth)
|
||||
y: root.isFramed ? 0 : (root.barMappedPos.y + root.trRadius * root.trMultY)
|
||||
radiusX: root.isFramed ? 0 : root.trRadius
|
||||
radiusY: root.isFramed ? 0 : root.trRadius
|
||||
direction: ShapeCornerHelper.getArcDirection(root.trMultX, root.trMultY)
|
||||
}
|
||||
|
||||
// Right edge (moving down)
|
||||
PathLine {
|
||||
relativeX: 0
|
||||
relativeY: root.barHeight - root.trRadius * root.trMultY - root.brRadius * root.brMultY
|
||||
x: root.isFramed ? (root.shouldShow ? root.screenWidth : 0) : (root.barMappedPos.x + root.barWidth)
|
||||
y: {
|
||||
if (!root.shouldShow)
|
||||
return 0;
|
||||
if (root.isFramed)
|
||||
return root.screenHeight;
|
||||
return root.barMappedPos.y + root.barHeight - root.brRadius * root.brMultY;
|
||||
}
|
||||
}
|
||||
|
||||
// Bottom-right corner arc
|
||||
// Bar bottom-right corner (only if not framed)
|
||||
PathArc {
|
||||
relativeX: -root.brRadius * root.brMultX
|
||||
relativeY: root.brRadius * root.brMultY
|
||||
radiusX: root.brRadius
|
||||
radiusY: root.brRadius
|
||||
x: root.isFramed ? (root.shouldShow ? root.screenWidth : 0) : (root.barMappedPos.x + root.barWidth - root.brRadius * root.brMultX)
|
||||
y: root.isFramed ? (root.shouldShow ? root.screenHeight : 0) : (root.barMappedPos.y + root.barHeight)
|
||||
radiusX: root.isFramed ? 0 : root.brRadius
|
||||
radiusY: root.isFramed ? 0 : root.brRadius
|
||||
direction: ShapeCornerHelper.getArcDirection(root.brMultX, root.brMultY)
|
||||
}
|
||||
|
||||
// Bottom edge (moving left)
|
||||
PathLine {
|
||||
relativeX: -(root.barWidth - root.brRadius * root.brMultX - root.blRadius * root.blMultX)
|
||||
relativeY: 0
|
||||
x: {
|
||||
if (!root.shouldShow)
|
||||
return 0;
|
||||
if (root.isFramed)
|
||||
return 0;
|
||||
return root.barMappedPos.x + root.blRadius * root.blMultX;
|
||||
}
|
||||
y: root.isFramed ? (root.shouldShow ? root.screenHeight : 0) : (root.barMappedPos.y + root.barHeight)
|
||||
}
|
||||
|
||||
// Bottom-left corner arc
|
||||
// Bar bottom-left corner (only if not framed)
|
||||
PathArc {
|
||||
relativeX: -root.blRadius * root.blMultX
|
||||
relativeY: -root.blRadius * root.blMultY
|
||||
radiusX: root.blRadius
|
||||
radiusY: root.blRadius
|
||||
x: root.isFramed ? 0 : root.barMappedPos.x
|
||||
y: root.isFramed ? (root.shouldShow ? root.screenHeight : 0) : (root.barMappedPos.y + root.barHeight - root.blRadius * root.blMultY)
|
||||
radiusX: root.isFramed ? 0 : root.blRadius
|
||||
radiusY: root.isFramed ? 0 : root.blRadius
|
||||
direction: ShapeCornerHelper.getArcDirection(root.blMultX, root.blMultY)
|
||||
}
|
||||
|
||||
// Left edge (moving up) - closes the path back to start
|
||||
PathLine {
|
||||
relativeX: 0
|
||||
relativeY: -(root.barHeight - root.blRadius * root.blMultY - root.tlRadius * root.tlMultY)
|
||||
x: root.isFramed ? 0 : root.barMappedPos.x
|
||||
y: {
|
||||
if (!root.shouldShow)
|
||||
return 0;
|
||||
if (root.isFramed)
|
||||
return 0;
|
||||
return root.barMappedPos.y + root.tlRadius * root.tlMultY;
|
||||
}
|
||||
}
|
||||
|
||||
// Top-left corner arc (back to start)
|
||||
// Bar top-left corner (only if not framed, back to start)
|
||||
PathArc {
|
||||
relativeX: root.tlRadius * root.tlMultX
|
||||
relativeY: -root.tlRadius * root.tlMultY
|
||||
radiusX: root.tlRadius
|
||||
radiusY: root.tlRadius
|
||||
x: root.isFramed ? 0 : (root.barMappedPos.x + root.tlRadius * root.tlMultX)
|
||||
y: root.isFramed ? 0 : root.barMappedPos.y
|
||||
radiusX: root.isFramed ? 0 : root.tlRadius
|
||||
radiusY: root.isFramed ? 0 : root.tlRadius
|
||||
direction: ShapeCornerHelper.getArcDirection(root.tlMultX, root.tlMultY)
|
||||
}
|
||||
|
||||
// 2. Inner Hole for Framed Mode (Clockwise)
|
||||
PathMove {
|
||||
x: (root.isFramed && root.shouldShow) ? (root.holeX + root.frameRadius) : root.startX
|
||||
y: (root.isFramed && root.shouldShow) ? root.holeY : root.startY
|
||||
}
|
||||
|
||||
// Top edge
|
||||
PathLine {
|
||||
x: (root.isFramed && root.shouldShow) ? (root.holeX + root.holeWidth - root.frameRadius) : ((root.isFramed && root.shouldShow) ? (root.holeX + root.frameRadius) : root.startX)
|
||||
y: (root.isFramed && root.shouldShow) ? root.holeY : ((root.isFramed && root.shouldShow) ? root.holeY : root.startY)
|
||||
}
|
||||
|
||||
// Top-right corner
|
||||
PathArc {
|
||||
x: (root.isFramed && root.shouldShow) ? (root.holeX + root.holeWidth) : ((root.isFramed && root.shouldShow) ? (root.holeX + root.holeWidth - root.frameRadius) : root.startX)
|
||||
y: (root.isFramed && root.shouldShow) ? (root.holeY + root.frameRadius) : ((root.isFramed && root.shouldShow) ? root.holeY : root.startY)
|
||||
radiusX: (root.isFramed && root.shouldShow) ? root.frameRadius : 0
|
||||
radiusY: (root.isFramed && root.shouldShow) ? root.frameRadius : 0
|
||||
direction: PathArc.Clockwise
|
||||
}
|
||||
|
||||
// Right edge
|
||||
PathLine {
|
||||
x: (root.isFramed && root.shouldShow) ? (root.holeX + root.holeWidth) : root.startX
|
||||
y: (root.isFramed && root.shouldShow) ? (root.holeY + root.holeHeight - root.frameRadius) : root.startY
|
||||
}
|
||||
|
||||
// Bottom-right corner
|
||||
PathArc {
|
||||
x: (root.isFramed && root.shouldShow) ? (root.holeX + root.holeWidth - root.frameRadius) : root.startX
|
||||
y: (root.isFramed && root.shouldShow) ? (root.holeY + root.holeHeight) : root.startY
|
||||
radiusX: (root.isFramed && root.shouldShow) ? root.frameRadius : 0
|
||||
radiusY: (root.isFramed && root.shouldShow) ? root.frameRadius : 0
|
||||
direction: PathArc.Clockwise
|
||||
}
|
||||
|
||||
// Bottom edge
|
||||
PathLine {
|
||||
x: (root.isFramed && root.shouldShow) ? (root.holeX + root.frameRadius) : root.startX
|
||||
y: (root.isFramed && root.shouldShow) ? (root.holeY + root.holeHeight) : root.startY
|
||||
}
|
||||
|
||||
// Bottom-left corner
|
||||
PathArc {
|
||||
x: (root.isFramed && root.shouldShow) ? root.holeX : root.startX
|
||||
y: (root.isFramed && root.shouldShow) ? (root.holeY + root.holeHeight - root.frameRadius) : root.startY
|
||||
radiusX: (root.isFramed && root.shouldShow) ? root.frameRadius : 0
|
||||
radiusY: (root.isFramed && root.shouldShow) ? root.frameRadius : 0
|
||||
direction: PathArc.Clockwise
|
||||
}
|
||||
|
||||
// Left edge
|
||||
PathLine {
|
||||
x: (root.isFramed && root.shouldShow) ? root.holeX : root.startX
|
||||
y: (root.isFramed && root.shouldShow) ? (root.holeY + root.frameRadius) : root.startY
|
||||
}
|
||||
|
||||
// Top-left corner (back to start)
|
||||
PathArc {
|
||||
x: (root.isFramed && root.shouldShow) ? (root.holeX + root.frameRadius) : root.startX
|
||||
y: (root.isFramed && root.shouldShow) ? root.holeY : root.startY
|
||||
radiusX: (root.isFramed && root.shouldShow) ? root.frameRadius : 0
|
||||
radiusY: (root.isFramed && root.shouldShow) ? root.frameRadius : 0
|
||||
direction: PathArc.Clockwise
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,8 @@ PanelWindow {
|
||||
// Position and size to match bar location (per-screen)
|
||||
readonly property string barPosition: Settings.getBarPositionForScreen(barWindow.screen?.name)
|
||||
readonly property bool barIsVertical: barPosition === "left" || barPosition === "right"
|
||||
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.floating || false
|
||||
readonly property real barMarginH: Math.ceil(barFloating ? Settings.data.bar.marginHorizontal : 0)
|
||||
readonly property real barMarginV: Math.ceil(barFloating ? Settings.data.bar.marginVertical : 0)
|
||||
@@ -45,12 +47,12 @@ PanelWindow {
|
||||
right: barPosition === "right" || !barIsVertical
|
||||
}
|
||||
|
||||
// Handle floating margins
|
||||
// Handle floating margins and framed mode offsets
|
||||
margins {
|
||||
top: barPosition === "top" || barIsVertical ? barMarginV : 0
|
||||
bottom: barPosition === "bottom" || barIsVertical ? barMarginV : 0
|
||||
left: barPosition === "left" || !barIsVertical ? barMarginH : 0
|
||||
right: barPosition === "right" || !barIsVertical ? barMarginH : 0
|
||||
top: (barPosition === "top") ? barMarginV : (isFramed ? frameThickness : barMarginV)
|
||||
bottom: (barPosition === "bottom") ? barMarginV : (isFramed ? frameThickness : barMarginV)
|
||||
left: (barPosition === "left") ? barMarginH : (isFramed ? frameThickness : barMarginH)
|
||||
right: (barPosition === "right") ? barMarginH : (isFramed ? frameThickness : barMarginH)
|
||||
}
|
||||
|
||||
// Set a tight window size
|
||||
|
||||
@@ -13,13 +13,14 @@ import qs.Services.Compositor
|
||||
PanelWindow {
|
||||
id: root
|
||||
|
||||
// Edge to anchor to and thickness to reserve
|
||||
property string edge: Settings.getBarPositionForScreen(screen?.name)
|
||||
property real thickness: (edge === Settings.getBarPositionForScreen(screen?.name)) ? Style.getBarHeightForScreen(screen?.name) : (Settings.data.bar.frameThickness ?? 12)
|
||||
|
||||
readonly property bool exclusive: Settings.data.bar.exclusive
|
||||
readonly property string barPosition: Settings.getBarPositionForScreen(screen?.name)
|
||||
readonly property bool barIsVertical: barPosition === "left" || barPosition === "right"
|
||||
readonly property real barHeight: Style.getBarHeightForScreen(screen?.name)
|
||||
readonly property bool barFloating: Settings.data.bar.floating || false
|
||||
readonly property real barMarginH: barFloating ? Math.ceil(Settings.data.bar.marginHorizontal) : 0
|
||||
readonly property real barMarginV: barFloating ? Math.ceil(Settings.data.bar.marginVertical) : 0
|
||||
readonly property real barMarginH: (barFloating && edge === Settings.getBarPositionForScreen(screen?.name)) ? Math.ceil(Settings.data.bar.marginHorizontal) : 0
|
||||
readonly property real barMarginV: (barFloating && edge === Settings.getBarPositionForScreen(screen?.name)) ? Math.ceil(Settings.data.bar.marginVertical) : 0
|
||||
readonly property real fractOffset: CompositorService.getDisplayScale(screen?.name) % 1.0
|
||||
|
||||
// Invisible - just reserves space
|
||||
@@ -29,30 +30,28 @@ PanelWindow {
|
||||
|
||||
// Wayland layer shell configuration
|
||||
WlrLayershell.layer: WlrLayer.Top
|
||||
WlrLayershell.namespace: "noctalia-bar-exclusion-" + (screen?.name || "unknown")
|
||||
WlrLayershell.namespace: "noctalia-bar-exclusion-" + edge + "-" + (screen?.name || "unknown")
|
||||
WlrLayershell.exclusionMode: exclusive ? ExclusionMode.Auto : ExclusionMode.Ignore
|
||||
|
||||
// Anchor based on bar position
|
||||
// Anchor based on specified edge
|
||||
anchors {
|
||||
top: barPosition === "top"
|
||||
bottom: barPosition === "bottom"
|
||||
left: barPosition === "left" || barPosition === "top" || barPosition === "bottom"
|
||||
right: barPosition === "right" || barPosition === "top" || barPosition === "bottom"
|
||||
top: edge === "top"
|
||||
bottom: edge === "bottom"
|
||||
left: edge === "left" || edge === "top" || edge === "bottom"
|
||||
right: edge === "right" || edge === "top" || edge === "bottom"
|
||||
}
|
||||
|
||||
// Size based on bar orientation
|
||||
// Size based on orientation
|
||||
implicitWidth: {
|
||||
if (barIsVertical) {
|
||||
// Vertical bar: reserve bar height + margin on the anchored edge only
|
||||
return barHeight + barMarginH - fractOffset;
|
||||
if (edge === "left" || edge === "right") {
|
||||
return thickness + barMarginH - fractOffset;
|
||||
}
|
||||
return 0; // Auto-width when left/right anchors are true
|
||||
}
|
||||
|
||||
implicitHeight: {
|
||||
if (!barIsVertical) {
|
||||
// Horizontal bar: reserve bar height + margin on the anchored edge only
|
||||
return barHeight + barMarginV - fractOffset;
|
||||
if (edge === "top" || edge === "bottom") {
|
||||
return thickness + barMarginV - fractOffset;
|
||||
}
|
||||
return 0; // Auto-height when top/bottom anchors are true
|
||||
}
|
||||
|
||||
@@ -134,13 +134,58 @@ PanelWindow {
|
||||
Region {
|
||||
id: barMaskRegion
|
||||
|
||||
x: barPlaceholder.x
|
||||
y: barPlaceholder.y
|
||||
readonly property bool isFramed: Settings.data.bar.barType === "framed"
|
||||
readonly property real barThickness: Style.barHeight
|
||||
readonly property real frameThickness: Settings.data.bar.frameThickness ?? 12
|
||||
readonly property string barPos: Settings.data.bar.position || "top"
|
||||
|
||||
// Set width/height to 0 if bar shouldn't show on this screen (makes region empty)
|
||||
width: root.barShouldShow ? barPlaceholder.width : 0
|
||||
height: root.barShouldShow ? barPlaceholder.height : 0
|
||||
intersection: Intersection.Subtract
|
||||
// Bar / Frame Mask
|
||||
Region {
|
||||
// Mode: Simple or Floating
|
||||
x: barPlaceholder.x
|
||||
y: barPlaceholder.y
|
||||
width: (!barMaskRegion.isFramed && root.barShouldShow) ? barPlaceholder.width : 0
|
||||
height: (!barMaskRegion.isFramed && root.barShouldShow) ? barPlaceholder.height : 0
|
||||
intersection: Intersection.Subtract
|
||||
}
|
||||
|
||||
// Mode: Framed - 4 sides
|
||||
Region {
|
||||
// Top side
|
||||
Region {
|
||||
x: 0
|
||||
y: 0
|
||||
width: (barMaskRegion.isFramed && root.barShouldShow) ? root.width : 0
|
||||
height: (barMaskRegion.isFramed && root.barShouldShow) ? (barMaskRegion.barPos === "top" ? barMaskRegion.barThickness : barMaskRegion.frameThickness) : 0
|
||||
intersection: Intersection.Subtract
|
||||
}
|
||||
|
||||
// Bottom side
|
||||
Region {
|
||||
x: 0
|
||||
y: (barMaskRegion.isFramed && root.barShouldShow) ? (root.height - (barMaskRegion.barPos === "bottom" ? barMaskRegion.barThickness : barMaskRegion.frameThickness)) : 0
|
||||
width: (barMaskRegion.isFramed && root.barShouldShow) ? root.width : 0
|
||||
height: (barMaskRegion.isFramed && root.barShouldShow) ? (barMaskRegion.barPos === "bottom" ? barMaskRegion.barThickness : barMaskRegion.frameThickness) : 0
|
||||
intersection: Intersection.Subtract
|
||||
}
|
||||
|
||||
// Left side
|
||||
Region {
|
||||
x: 0
|
||||
y: 0
|
||||
width: (barMaskRegion.isFramed && root.barShouldShow) ? (barMaskRegion.barPos === "left" ? barMaskRegion.barThickness : barMaskRegion.frameThickness) : 0
|
||||
height: (barMaskRegion.isFramed && root.barShouldShow) ? root.height : 0
|
||||
intersection: Intersection.Subtract
|
||||
}
|
||||
|
||||
// Right side
|
||||
Region {
|
||||
x: (barMaskRegion.isFramed && root.barShouldShow) ? (root.width - (barMaskRegion.barPos === "right" ? barMaskRegion.barThickness : barMaskRegion.frameThickness)) : 0
|
||||
width: (barMaskRegion.isFramed && root.barShouldShow) ? (barMaskRegion.barPos === "right" ? barMaskRegion.barThickness : barMaskRegion.frameThickness) : 0
|
||||
height: (barMaskRegion.isFramed && root.barShouldShow) ? root.height : 0
|
||||
intersection: Intersection.Subtract
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Background region for click-to-close - reactive sizing
|
||||
@@ -323,6 +368,8 @@ PanelWindow {
|
||||
// Bar background positioning properties (per-screen)
|
||||
readonly property string barPosition: Settings.getBarPositionForScreen(screen?.name)
|
||||
readonly property bool barIsVertical: barPosition === "left" || barPosition === "right"
|
||||
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.floating || 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
|
||||
@@ -333,24 +380,32 @@ PanelWindow {
|
||||
x: {
|
||||
if (barPosition === "right")
|
||||
return screen.width - barHeight - barMarginH;
|
||||
if (isFramed && !barIsVertical)
|
||||
return frameThickness;
|
||||
return barMarginH;
|
||||
}
|
||||
y: {
|
||||
if (barPosition === "bottom")
|
||||
return screen.height - barHeight - barMarginV;
|
||||
if (isFramed && barIsVertical)
|
||||
return frameThickness;
|
||||
return barMarginV;
|
||||
}
|
||||
width: {
|
||||
if (barIsVertical) {
|
||||
return barHeight;
|
||||
}
|
||||
if (isFramed)
|
||||
return screen.width - frameThickness * 2;
|
||||
return screen.width - barMarginH * 2;
|
||||
}
|
||||
height: {
|
||||
if (barIsVertical) {
|
||||
return screen.height - barMarginV * 2;
|
||||
if (!barIsVertical) {
|
||||
return barHeight;
|
||||
}
|
||||
return barHeight;
|
||||
if (isFramed)
|
||||
return screen.height - frameThickness * 2;
|
||||
return screen.height - barMarginV * 2;
|
||||
}
|
||||
|
||||
// Corner states (same as Bar.qml)
|
||||
|
||||
@@ -91,6 +91,8 @@ Item {
|
||||
readonly property string barPosition: Settings.getBarPositionForScreen(screen?.name)
|
||||
readonly property bool barIsVertical: barPosition === "left" || barPosition === "right"
|
||||
readonly property real barHeight: Style.getBarHeightForScreen(screen?.name)
|
||||
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.floating
|
||||
readonly property real barMarginH: barFloating ? Math.ceil(Settings.data.bar.marginHorizontal) : 0
|
||||
readonly property real barMarginV: barFloating ? Math.ceil(Settings.data.bar.marginVertical) : 0
|
||||
@@ -172,15 +174,19 @@ Item {
|
||||
barWindowX = screenWidth - root.barMarginH - root.barHeight;
|
||||
} else if (root.barPosition === "left") {
|
||||
barWindowX = root.barMarginH;
|
||||
} else if (root.isFramed) {
|
||||
barWindowX = root.frameThickness;
|
||||
}
|
||||
// For top/bottom bars, barWindowX stays 0 (full width window)
|
||||
// For top/bottom bars, barWindowX stays 0 (full width window) unless framed
|
||||
|
||||
if (root.barPosition === "bottom") {
|
||||
barWindowY = screenHeight - root.barMarginV - root.barHeight;
|
||||
} else if (root.barPosition === "top") {
|
||||
barWindowY = root.barMarginV;
|
||||
} else if (root.isFramed) {
|
||||
barWindowY = root.frameThickness;
|
||||
}
|
||||
// For left/right bars, barWindowY stays 0 (full height window)
|
||||
// For left/right bars, barWindowY stays 0 (full height window) unless framed
|
||||
|
||||
root.buttonPosition = Qt.point(barWindowX + buttonLocal.x, barWindowY + buttonLocal.y);
|
||||
root.buttonWidth = buttonItem.width;
|
||||
@@ -298,6 +304,12 @@ Item {
|
||||
return;
|
||||
}
|
||||
|
||||
// Effective screen margins (account for frame thickness)
|
||||
var effMarginL = Style.marginL + (root.isFramed ? root.frameThickness : 0);
|
||||
var effMarginR = Style.marginL + (root.isFramed ? root.frameThickness : 0);
|
||||
var effMarginT = Style.marginL + (root.isFramed ? root.frameThickness : 0);
|
||||
var effMarginB = Style.marginL + (root.isFramed ? root.frameThickness : 0);
|
||||
|
||||
// Calculate panel dimensions first (needed for positioning)
|
||||
var w;
|
||||
// Priority 1: Content-driven size (dynamic)
|
||||
@@ -310,7 +322,7 @@ Item {
|
||||
else {
|
||||
w = root.preferredWidth;
|
||||
}
|
||||
var panelWidth = Math.min(w, root.width - Style.marginL * 2);
|
||||
var panelWidth = Math.min(w, root.width - effMarginL - effMarginR);
|
||||
|
||||
var h;
|
||||
// Priority 1: Content-driven size (dynamic)
|
||||
@@ -323,7 +335,7 @@ Item {
|
||||
else {
|
||||
h = root.preferredHeight;
|
||||
}
|
||||
var panelHeight = Math.min(h, root.height - root.barHeight - Style.marginL * 2);
|
||||
var panelHeight = Math.min(h, root.height - root.barHeight - effMarginT - effMarginB);
|
||||
|
||||
// Update panelBackground target size (will be animated)
|
||||
panelBackground.targetWidth = panelWidth;
|
||||
@@ -337,6 +349,17 @@ Item {
|
||||
var topBarEdgeWithOverlap = root.barMarginV + root.barHeight - overlap;
|
||||
var bottomBarEdgeWithOverlap = root.height - root.barMarginV - root.barHeight + overlap;
|
||||
|
||||
if (root.isFramed) {
|
||||
if (root.barPosition === "left")
|
||||
leftBarEdgeWithOverlap = root.barHeight - overlap;
|
||||
if (root.barPosition === "right")
|
||||
rightBarEdgeWithOverlap = root.width - root.barHeight + overlap;
|
||||
if (root.barPosition === "top")
|
||||
topBarEdgeWithOverlap = root.barHeight - overlap;
|
||||
if (root.barPosition === "bottom")
|
||||
bottomBarEdgeWithOverlap = root.height - root.barHeight + overlap;
|
||||
}
|
||||
|
||||
// Calculate position
|
||||
var calculatedX;
|
||||
var calculatedY;
|
||||
@@ -355,14 +378,14 @@ Item {
|
||||
} else {
|
||||
// Detached panels: center on button X position
|
||||
var panelX = root.buttonPosition.x + root.buttonWidth / 2 - panelWidth / 2;
|
||||
var minX = Style.marginL;
|
||||
var maxX = root.width - panelWidth - Style.marginL;
|
||||
var minX = effMarginL;
|
||||
var maxX = root.width - panelWidth - effMarginR;
|
||||
|
||||
// Account for vertical bar taking up space
|
||||
if (root.barPosition === "left") {
|
||||
minX = root.barMarginH + root.barHeight + Style.marginL;
|
||||
minX = (root.isFramed ? 0 : root.barMarginH) + root.barHeight + Style.marginL;
|
||||
} else if (root.barPosition === "right") {
|
||||
maxX = root.width - root.barMarginH - root.barHeight - panelWidth - Style.marginL;
|
||||
maxX = root.width - (root.isFramed ? 0 : root.barMarginH) - root.barHeight - panelWidth - Style.marginL;
|
||||
}
|
||||
|
||||
panelX = Math.max(minX, Math.min(panelX, maxX));
|
||||
@@ -373,11 +396,11 @@ Item {
|
||||
var panelX = root.buttonPosition.x + root.buttonWidth / 2 - panelWidth / 2;
|
||||
if (panelContent.allowAttach) {
|
||||
var cornerInset = root.barFloating ? Style.radiusL * 2 : 0;
|
||||
var barLeftEdge = root.barMarginH + cornerInset;
|
||||
var barRightEdge = root.width - root.barMarginH - cornerInset;
|
||||
var barLeftEdge = (root.isFramed ? root.frameThickness : root.barMarginH) + cornerInset;
|
||||
var barRightEdge = root.width - (root.isFramed ? root.frameThickness : root.barMarginH) - cornerInset;
|
||||
panelX = Math.max(barLeftEdge, Math.min(panelX, barRightEdge - panelWidth));
|
||||
} else {
|
||||
panelX = Math.max(Style.marginL, Math.min(panelX, root.width - panelWidth - Style.marginL));
|
||||
panelX = Math.max(effMarginL, Math.min(panelX, root.width - panelWidth - effMarginR));
|
||||
}
|
||||
calculatedX = panelX;
|
||||
}
|
||||
@@ -386,12 +409,12 @@ Item {
|
||||
if (root.panelAnchorHorizontalCenter) {
|
||||
if (root.barIsVertical) {
|
||||
if (root.barPosition === "left") {
|
||||
var availableStart = root.barMarginH + root.barHeight;
|
||||
var availableWidth = root.width - availableStart;
|
||||
var availableStart = (root.isFramed ? 0 : root.barMarginH) + root.barHeight;
|
||||
var availableWidth = root.width - availableStart - (root.isFramed ? root.frameThickness : 0);
|
||||
calculatedX = availableStart + (availableWidth - panelWidth) / 2;
|
||||
} else if (root.barPosition === "right") {
|
||||
var availableWidth = root.width - root.barMarginH - root.barHeight;
|
||||
calculatedX = (availableWidth - panelWidth) / 2;
|
||||
var availableWidth = root.width - (root.isFramed ? 0 : root.barMarginH) - root.barHeight - (root.isFramed ? root.frameThickness : 0);
|
||||
calculatedX = (root.isFramed ? root.frameThickness : 0) + (availableWidth - panelWidth) / 2;
|
||||
} else {
|
||||
calculatedX = (root.width - panelWidth) / 2;
|
||||
}
|
||||
@@ -410,12 +433,12 @@ Item {
|
||||
var rightCornerInset = Style.radiusL * 2;
|
||||
calculatedX = root.width - root.barMarginH - rightCornerInset - panelWidth;
|
||||
} else {
|
||||
calculatedX = root.width - panelWidth;
|
||||
calculatedX = root.width - panelWidth - (root.isFramed ? root.frameThickness : 0);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Not attached: position at right with margin
|
||||
calculatedX = root.width - panelWidth - Style.marginL;
|
||||
calculatedX = root.width - panelWidth - effMarginR;
|
||||
}
|
||||
} else if (root.panelAnchorLeft) {
|
||||
// Use raw panelAnchorLeft for positioning decision
|
||||
@@ -429,12 +452,12 @@ Item {
|
||||
var leftCornerInset = Style.radiusL * 2;
|
||||
calculatedX = root.barMarginH + leftCornerInset;
|
||||
} else {
|
||||
calculatedX = 0;
|
||||
calculatedX = (root.isFramed ? root.frameThickness : 0);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Not attached: position at left with margin
|
||||
calculatedX = Style.marginL;
|
||||
calculatedX = effMarginL;
|
||||
}
|
||||
} else {
|
||||
// No explicit anchor: attach to bar if allowAttach, otherwise center
|
||||
@@ -449,19 +472,19 @@ Item {
|
||||
} else {
|
||||
// Not attached: center in available space
|
||||
if (root.barPosition === "left") {
|
||||
var availableStart = root.barMarginH + root.barHeight;
|
||||
var availableWidth = root.width - availableStart - Style.marginL;
|
||||
var availableStart = (root.isFramed ? 0 : root.barMarginH) + root.barHeight;
|
||||
var availableWidth = root.width - availableStart - effMarginR;
|
||||
calculatedX = availableStart + (availableWidth - panelWidth) / 2;
|
||||
} else {
|
||||
var availableWidth = root.width - root.barMarginH - root.barHeight - Style.marginL;
|
||||
calculatedX = Style.marginL + (availableWidth - panelWidth) / 2;
|
||||
var availableWidth = root.width - (root.isFramed ? 0 : root.barMarginH) - root.barHeight - effMarginL;
|
||||
calculatedX = effMarginL + (availableWidth - panelWidth) / 2;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (panelContent.allowAttach) {
|
||||
var cornerInset = Style.radiusL + (root.barFloating ? Style.radiusL : 0);
|
||||
var barLeftEdge = root.barMarginH + cornerInset;
|
||||
var barRightEdge = root.width - root.barMarginH - cornerInset;
|
||||
var barLeftEdge = (root.isFramed ? root.frameThickness : root.barMarginH) + cornerInset;
|
||||
var barRightEdge = root.width - (root.isFramed ? root.frameThickness : root.barMarginH) - cornerInset;
|
||||
var centeredX = (root.width - panelWidth) / 2;
|
||||
calculatedX = Math.max(barLeftEdge, Math.min(centeredX, barRightEdge - panelWidth));
|
||||
} else {
|
||||
@@ -473,8 +496,8 @@ Item {
|
||||
|
||||
// Edge snapping for X
|
||||
if (panelContent.allowAttach && !root.barFloating && root.width > 0 && panelWidth > 0) {
|
||||
var leftEdgePos = root.barPosition === "left" ? leftBarEdgeWithOverlap : root.barMarginH;
|
||||
var rightEdgePos = root.barPosition === "right" ? rightBarEdgeWithOverlap - panelWidth : root.width - root.barMarginH - panelWidth;
|
||||
var leftEdgePos = root.barPosition === "left" ? leftBarEdgeWithOverlap : (root.isFramed ? root.frameThickness : root.barMarginH);
|
||||
var rightEdgePos = root.barPosition === "right" ? rightBarEdgeWithOverlap - panelWidth : root.width - (root.isFramed ? root.frameThickness : root.barMarginH) - panelWidth;
|
||||
|
||||
// Only snap to left edge if panel is actually meant to be at left (or no explicit anchor)
|
||||
var shouldSnapToLeft = root.effectivePanelAnchorLeft || (!root.hasExplicitHorizontalAnchor && root.barPosition === "left");
|
||||
@@ -494,30 +517,30 @@ Item {
|
||||
if (panelContent.allowAttach) {
|
||||
calculatedY = topBarEdgeWithOverlap;
|
||||
} else {
|
||||
calculatedY = root.barMarginV + root.barHeight + Style.marginM;
|
||||
calculatedY = (root.isFramed ? 0 : root.barMarginV) + root.barHeight + Style.marginM;
|
||||
}
|
||||
} else if (root.barPosition === "bottom") {
|
||||
if (panelContent.allowAttach) {
|
||||
calculatedY = bottomBarEdgeWithOverlap - panelHeight;
|
||||
} else {
|
||||
calculatedY = root.height - root.barMarginV - root.barHeight - panelHeight - Style.marginM;
|
||||
calculatedY = root.height - (root.isFramed ? 0 : root.barMarginV) - root.barHeight - panelHeight - Style.marginM;
|
||||
}
|
||||
} else if (root.barIsVertical) {
|
||||
var panelY = root.buttonPosition.y + root.buttonHeight / 2 - panelHeight / 2;
|
||||
var extraPadding = (panelContent.allowAttach && root.barFloating) ? Style.radiusL : 0;
|
||||
if (panelContent.allowAttach) {
|
||||
var cornerInset = extraPadding + (root.barFloating ? Style.radiusL : 0);
|
||||
var barTopEdge = root.barMarginV + cornerInset;
|
||||
var barBottomEdge = root.height - root.barMarginV - cornerInset;
|
||||
var barTopEdge = (root.isFramed ? root.frameThickness : root.barMarginV) + cornerInset;
|
||||
var barBottomEdge = root.height - (root.isFramed ? root.frameThickness : root.barMarginV) - cornerInset;
|
||||
panelY = Math.max(barTopEdge, Math.min(panelY, barBottomEdge - panelHeight));
|
||||
} else {
|
||||
panelY = Math.max(Style.marginL + extraPadding, Math.min(panelY, root.height - panelHeight - Style.marginL - extraPadding));
|
||||
panelY = Math.max(effMarginT + extraPadding, Math.min(panelY, root.height - panelHeight - effMarginB - extraPadding));
|
||||
}
|
||||
calculatedY = panelY;
|
||||
}
|
||||
} else {
|
||||
// Standard anchor positioning
|
||||
var barOffset = !panelContent.allowAttach && (root.barPosition === "top" || root.barPosition === "bottom") ? root.barMarginV + root.barHeight + Style.marginM : 0;
|
||||
var barOffset = !panelContent.allowAttach && (root.barPosition === "top" || root.barPosition === "bottom") ? (root.isFramed ? 0 : root.barMarginV) + root.barHeight + Style.marginM : 0;
|
||||
|
||||
if (panelContent.allowAttach && !root.barIsVertical) {
|
||||
// Attached to horizontal bar: position with overlap
|
||||
@@ -532,12 +555,12 @@ Item {
|
||||
if (root.panelAnchorVerticalCenter) {
|
||||
if (!root.barIsVertical) {
|
||||
if (root.barPosition === "top") {
|
||||
var availableStart = root.barMarginV + root.barHeight;
|
||||
var availableHeight = root.height - availableStart;
|
||||
var availableStart = (root.isFramed ? 0 : root.barMarginV) + root.barHeight;
|
||||
var availableHeight = root.height - availableStart - (root.isFramed ? root.frameThickness : 0);
|
||||
calculatedY = availableStart + (availableHeight - panelHeight) / 2;
|
||||
} else if (root.barPosition === "bottom") {
|
||||
var availableHeight = root.height - root.barMarginV - root.barHeight;
|
||||
calculatedY = (availableHeight - panelHeight) / 2;
|
||||
var availableHeight = root.height - (root.isFramed ? 0 : root.barMarginV) - root.barHeight - (root.isFramed ? root.frameThickness : 0);
|
||||
calculatedY = (root.isFramed ? root.frameThickness : 0) + (availableHeight - panelHeight) / 2;
|
||||
} else {
|
||||
calculatedY = (root.height - panelHeight) / 2;
|
||||
}
|
||||
@@ -546,25 +569,25 @@ Item {
|
||||
}
|
||||
} else if (root.panelAnchorTop) {
|
||||
if (root.effectivePanelAnchorTop) {
|
||||
calculatedY = root.barPosition === "top" ? topBarEdgeWithOverlap : 0;
|
||||
calculatedY = root.barPosition === "top" ? topBarEdgeWithOverlap : (root.isFramed ? root.frameThickness : 0);
|
||||
} else {
|
||||
var topBarOffset = (root.barPosition === "top") ? barOffset : 0;
|
||||
calculatedY = topBarOffset + Style.marginL;
|
||||
calculatedY = topBarOffset + effMarginT;
|
||||
}
|
||||
} else if (root.panelAnchorBottom) {
|
||||
if (root.effectivePanelAnchorBottom) {
|
||||
calculatedY = root.barPosition === "bottom" ? bottomBarEdgeWithOverlap - panelHeight : root.height - panelHeight;
|
||||
calculatedY = root.barPosition === "bottom" ? bottomBarEdgeWithOverlap - panelHeight : root.height - panelHeight - (root.isFramed ? root.frameThickness : 0);
|
||||
} else {
|
||||
var bottomBarOffset = (root.barPosition === "bottom") ? barOffset : 0;
|
||||
calculatedY = root.height - panelHeight - bottomBarOffset - Style.marginL;
|
||||
calculatedY = root.height - panelHeight - bottomBarOffset - effMarginB;
|
||||
}
|
||||
} else {
|
||||
// No explicit vertical anchor
|
||||
if (root.barIsVertical) {
|
||||
if (panelContent.allowAttach) {
|
||||
var cornerInset = root.barFloating ? Style.radiusL * 2 : 0;
|
||||
var barTopEdge = root.barMarginV + cornerInset;
|
||||
var barBottomEdge = root.height - root.barMarginV - cornerInset;
|
||||
var barTopEdge = (root.isFramed ? root.frameThickness : root.barMarginV) + cornerInset;
|
||||
var barBottomEdge = root.height - (root.isFramed ? root.frameThickness : root.barMarginV) - cornerInset;
|
||||
var centeredY = (root.height - panelHeight) / 2;
|
||||
calculatedY = Math.max(barTopEdge, Math.min(centeredY, barBottomEdge - panelHeight));
|
||||
} else {
|
||||
@@ -573,11 +596,11 @@ Item {
|
||||
} else {
|
||||
// Horizontal bar, not attached
|
||||
if (root.barPosition === "top") {
|
||||
calculatedY = barOffset + Style.marginL;
|
||||
calculatedY = barOffset + effMarginT;
|
||||
} else if (root.barPosition === "bottom") {
|
||||
calculatedY = Style.marginL;
|
||||
calculatedY = effMarginT;
|
||||
} else {
|
||||
calculatedY = Style.marginL;
|
||||
calculatedY = effMarginT;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -586,8 +609,8 @@ Item {
|
||||
|
||||
// Edge snapping for Y
|
||||
if (panelContent.allowAttach && !root.barFloating && root.height > 0 && panelHeight > 0) {
|
||||
var topEdgePos = root.barPosition === "top" ? topBarEdgeWithOverlap : root.barMarginV;
|
||||
var bottomEdgePos = root.barPosition === "bottom" ? bottomBarEdgeWithOverlap - panelHeight : root.height - root.barMarginV - panelHeight;
|
||||
var topEdgePos = root.barPosition === "top" ? topBarEdgeWithOverlap : (root.isFramed ? root.frameThickness : root.barMarginV);
|
||||
var bottomEdgePos = root.barPosition === "bottom" ? bottomBarEdgeWithOverlap - panelHeight : root.height - (root.isFramed ? root.frameThickness : root.barMarginV) - panelHeight;
|
||||
|
||||
// Only snap to top edge if panel is actually meant to be at top (or no explicit anchor)
|
||||
var shouldSnapToTop = root.effectivePanelAnchorTop || (!root.hasExplicitVerticalAnchor && root.barPosition === "top");
|
||||
@@ -755,16 +778,16 @@ Item {
|
||||
}
|
||||
|
||||
// Edge detection - detect if panel is touching screen edges
|
||||
readonly property bool touchingLeftEdge: allowAttach && panelBackground.x <= 1
|
||||
readonly property bool touchingRightEdge: allowAttach && (panelBackground.x + panelBackground.width) >= (root.width - 1)
|
||||
readonly property bool touchingTopEdge: allowAttach && panelBackground.y <= 1
|
||||
readonly property bool touchingBottomEdge: allowAttach && (panelBackground.y + panelBackground.height) >= (root.height - 1)
|
||||
readonly property bool touchingLeftEdge: allowAttach && panelBackground.x <= (isFramed ? frameThickness + 1 : 1)
|
||||
readonly property bool touchingRightEdge: allowAttach && (panelBackground.x + panelBackground.width) >= (root.width - (isFramed ? frameThickness + 1 : 1))
|
||||
readonly property bool touchingTopEdge: allowAttach && panelBackground.y <= (isFramed ? frameThickness + 1 : 1)
|
||||
readonly property bool touchingBottomEdge: allowAttach && (panelBackground.y + panelBackground.height) >= (root.height - (isFramed ? frameThickness + 1 : 1))
|
||||
|
||||
// Bar edge detection - detect if panel is touching bar edges (for cases where centered panels snap to bar due to height constraints)
|
||||
readonly property bool touchingTopBar: allowAttachToBar && root.barPosition === "top" && !root.barIsVertical && Math.abs(panelBackground.y - (root.barMarginV + root.barHeight)) <= 1
|
||||
readonly property bool touchingBottomBar: allowAttachToBar && root.barPosition === "bottom" && !root.barIsVertical && Math.abs((panelBackground.y + panelBackground.height) - (root.height - root.barMarginV - root.barHeight)) <= 1
|
||||
readonly property bool touchingLeftBar: allowAttachToBar && root.barPosition === "left" && root.barIsVertical && Math.abs(panelBackground.x - (root.barMarginH + root.barHeight)) <= 1
|
||||
readonly property bool touchingRightBar: allowAttachToBar && root.barPosition === "right" && root.barIsVertical && Math.abs((panelBackground.x + panelBackground.width) - (root.width - root.barMarginH - root.barHeight)) <= 1
|
||||
readonly property bool touchingTopBar: allowAttachToBar && root.barPosition === "top" && !root.barIsVertical && Math.abs(panelBackground.y - ((isFramed ? 0 : root.barMarginV) + root.barHeight)) <= 1
|
||||
readonly property bool touchingBottomBar: allowAttachToBar && root.barPosition === "bottom" && !root.barIsVertical && Math.abs((panelBackground.y + panelBackground.height) - (root.height - (isFramed ? 0 : root.barMarginV) - root.barHeight)) <= 1
|
||||
readonly property bool touchingLeftBar: allowAttachToBar && root.barPosition === "left" && root.barIsVertical && Math.abs(panelBackground.x - ((isFramed ? 0 : root.barMarginH) + root.barHeight)) <= 1
|
||||
readonly property bool touchingRightBar: allowAttachToBar && root.barPosition === "right" && root.barIsVertical && Math.abs((panelBackground.x + panelBackground.width) - (root.width - (isFramed ? 0 : root.barMarginH) - root.barHeight)) <= 1
|
||||
|
||||
// Expose panelBackground for geometry placeholder
|
||||
property alias geometryPlaceholder: panelBackground
|
||||
@@ -792,31 +815,31 @@ Item {
|
||||
readonly property bool willTouchTopBar: {
|
||||
if (!panelContent.allowAttachToBar || root.barPosition !== "top" || root.barIsVertical)
|
||||
return false;
|
||||
var targetTopBarY = root.barMarginV + root.barHeight;
|
||||
var targetTopBarY = (isFramed ? 0 : root.barMarginV) + root.barHeight;
|
||||
return Math.abs(panelBackground.targetY - targetTopBarY) <= 1;
|
||||
}
|
||||
readonly property bool willTouchBottomBar: {
|
||||
if (!panelContent.allowAttachToBar || root.barPosition !== "bottom" || root.barIsVertical)
|
||||
return false;
|
||||
var targetBottomBarY = root.height - root.barMarginV - root.barHeight - panelBackground.targetHeight;
|
||||
var targetBottomBarY = root.height - (isFramed ? 0 : root.barMarginV) - root.barHeight - panelBackground.targetHeight;
|
||||
return Math.abs(panelBackground.targetY - targetBottomBarY) <= 1;
|
||||
}
|
||||
readonly property bool willTouchLeftBar: {
|
||||
if (!panelContent.allowAttachToBar || root.barPosition !== "left" || !root.barIsVertical)
|
||||
return false;
|
||||
var targetLeftBarX = root.barMarginH + root.barHeight;
|
||||
var targetLeftBarX = (isFramed ? 0 : root.barMarginH) + root.barHeight;
|
||||
return Math.abs(panelBackground.targetX - targetLeftBarX) <= 1;
|
||||
}
|
||||
readonly property bool willTouchRightBar: {
|
||||
if (!panelContent.allowAttachToBar || root.barPosition !== "right" || !root.barIsVertical)
|
||||
return false;
|
||||
var targetRightBarX = root.width - root.barMarginH - root.barHeight - panelBackground.targetWidth;
|
||||
var targetRightBarX = root.width - (isFramed ? 0 : root.barMarginH) - root.barHeight - panelBackground.targetWidth;
|
||||
return Math.abs(panelBackground.targetX - targetRightBarX) <= 1;
|
||||
}
|
||||
readonly property bool willTouchTopEdge: panelContent.allowAttach && panelBackground.targetY <= 1
|
||||
readonly property bool willTouchBottomEdge: panelContent.allowAttach && (panelBackground.targetY + panelBackground.targetHeight) >= (root.height - 1)
|
||||
readonly property bool willTouchLeftEdge: panelContent.allowAttach && panelBackground.targetX <= 1
|
||||
readonly property bool willTouchRightEdge: panelContent.allowAttach && (panelBackground.targetX + panelBackground.targetWidth) >= (root.width - 1)
|
||||
readonly property bool willTouchTopEdge: panelContent.allowAttach && panelBackground.targetY <= (isFramed ? frameThickness + 1 : 1)
|
||||
readonly property bool willTouchBottomEdge: panelContent.allowAttach && (panelBackground.targetY + panelBackground.targetHeight) >= (root.height - (isFramed ? frameThickness + 1 : 1))
|
||||
readonly property bool willTouchLeftEdge: panelContent.allowAttach && panelBackground.targetX <= (isFramed ? frameThickness + 1 : 1)
|
||||
readonly property bool willTouchRightEdge: panelContent.allowAttach && (panelBackground.targetX + panelBackground.targetWidth) >= (root.width - (isFramed ? frameThickness + 1 : 1))
|
||||
|
||||
readonly property bool isActuallyAttachedToAnyEdge: {
|
||||
return willTouchTopBar || willTouchBottomBar || willTouchLeftBar || willTouchRightBar || willTouchTopEdge || willTouchBottomEdge || willTouchLeftEdge || willTouchRightEdge;
|
||||
|
||||
Reference in New Issue
Block a user