mirror of
https://github.com/noctalia-dev/noctalia-shell.git
synced 2026-05-11 17:08:27 +08:00
Tooltip: improved positionning logic
This commit is contained in:
+102
-8
@@ -273,19 +273,71 @@ PopupWindow {
|
||||
}
|
||||
|
||||
// Adjust horizontal position to keep tooltip on screen
|
||||
// For top/bottom tooltips, always adjust horizontally (they don't overlap horizontally)
|
||||
// For left/right tooltips, check for overlap before adjusting
|
||||
const globalX = targetGlobal.x + newAnchorX;
|
||||
const isHorizontalTooltip = (direction === "top" || direction === "bottom");
|
||||
|
||||
if (globalX < 0) {
|
||||
newAnchorX = -targetGlobal.x + margin;
|
||||
// Clipping at left - only adjust if tooltip won't overlap target
|
||||
const adjustedX = -targetGlobal.x + margin;
|
||||
if (isHorizontalTooltip) {
|
||||
// Top/bottom tooltips: always allow horizontal adjustment
|
||||
newAnchorX = adjustedX;
|
||||
} else {
|
||||
// Left/right tooltips: check for vertical overlap
|
||||
const wouldOverlap = adjustedX < targetWidth && adjustedX + tipWidth > 0;
|
||||
if (!wouldOverlap) {
|
||||
newAnchorX = adjustedX;
|
||||
}
|
||||
}
|
||||
} else if (globalX + tipWidth > screenWidth) {
|
||||
newAnchorX = screenWidth - targetGlobal.x - tipWidth - margin;
|
||||
// Clipping at right - only adjust if tooltip won't overlap target
|
||||
const adjustedX = screenWidth - targetGlobal.x - tipWidth - margin;
|
||||
if (isHorizontalTooltip) {
|
||||
// Top/bottom tooltips: always allow horizontal adjustment
|
||||
newAnchorX = adjustedX;
|
||||
} else {
|
||||
// Left/right tooltips: check for vertical overlap
|
||||
const wouldOverlap = adjustedX < targetWidth && adjustedX + tipWidth > 0;
|
||||
if (!wouldOverlap) {
|
||||
newAnchorX = adjustedX;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Adjust vertical position to keep tooltip on screen
|
||||
// For left/right tooltips, always adjust vertically (they don't overlap vertically)
|
||||
// For top/bottom tooltips, check for overlap before adjusting
|
||||
const globalY = targetGlobal.y + newAnchorY;
|
||||
const isVerticalTooltip = (direction === "left" || direction === "right");
|
||||
|
||||
if (globalY < 0) {
|
||||
newAnchorY = -targetGlobal.y + margin;
|
||||
// Clipping at top - only adjust if tooltip won't overlap target
|
||||
const adjustedY = -targetGlobal.y + margin;
|
||||
if (isVerticalTooltip) {
|
||||
// Left/right tooltips: always allow vertical adjustment
|
||||
newAnchorY = adjustedY;
|
||||
} else {
|
||||
// Top/bottom tooltips: check for horizontal overlap
|
||||
const wouldOverlap = adjustedY < targetHeight && adjustedY + tipHeight > 0;
|
||||
if (!wouldOverlap) {
|
||||
newAnchorY = adjustedY;
|
||||
}
|
||||
}
|
||||
} else if (globalY + tipHeight > screenHeight) {
|
||||
newAnchorY = screenHeight - targetGlobal.y - tipHeight - margin;
|
||||
// Clipping at bottom - only adjust if tooltip won't overlap target
|
||||
const adjustedY = screenHeight - targetGlobal.y - tipHeight - margin;
|
||||
if (isVerticalTooltip) {
|
||||
// Left/right tooltips: always allow vertical adjustment
|
||||
newAnchorY = adjustedY;
|
||||
} else {
|
||||
// Top/bottom tooltips: check for horizontal overlap
|
||||
const wouldOverlap = adjustedY < targetHeight && adjustedY + tipHeight > 0;
|
||||
if (!wouldOverlap) {
|
||||
newAnchorY = adjustedY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Apply position first (before making visible)
|
||||
@@ -369,34 +421,76 @@ PopupWindow {
|
||||
|
||||
// Determine which direction the tooltip is currently positioned
|
||||
// and recalculate the centering for that direction
|
||||
var isHorizontalTooltip = false;
|
||||
var isVerticalTooltip = false;
|
||||
if (anchorY > targetHeight / 2) {
|
||||
// Tooltip is below target
|
||||
newAnchorX = (targetWidth - tipWidth) / 2;
|
||||
isHorizontalTooltip = true;
|
||||
} else if (anchorY < -tipHeight / 2) {
|
||||
// Tooltip is above target
|
||||
newAnchorX = (targetWidth - tipWidth) / 2;
|
||||
isHorizontalTooltip = true;
|
||||
} else if (anchorX > targetWidth / 2) {
|
||||
// Tooltip is to the right
|
||||
newAnchorY = (targetHeight - tipHeight) / 2;
|
||||
isVerticalTooltip = true;
|
||||
} else if (anchorX < -tipWidth / 2) {
|
||||
// Tooltip is to the left
|
||||
newAnchorY = (targetHeight - tipHeight) / 2;
|
||||
isVerticalTooltip = true;
|
||||
}
|
||||
|
||||
// Adjust horizontal position to keep tooltip on screen if needed
|
||||
// For top/bottom tooltips, always adjust horizontally (they don't overlap horizontally)
|
||||
// For left/right tooltips, check for overlap before adjusting
|
||||
const globalX = targetGlobal.x + newAnchorX;
|
||||
if (globalX < 0) {
|
||||
newAnchorX = -targetGlobal.x + margin;
|
||||
const adjustedX = -targetGlobal.x + margin;
|
||||
if (isHorizontalTooltip) {
|
||||
newAnchorX = adjustedX;
|
||||
} else {
|
||||
const wouldOverlap = adjustedX < targetWidth && adjustedX + tipWidth > 0;
|
||||
if (!wouldOverlap) {
|
||||
newAnchorX = adjustedX;
|
||||
}
|
||||
}
|
||||
} else if (globalX + tipWidth > screenWidth) {
|
||||
newAnchorX = screenWidth - targetGlobal.x - tipWidth - margin;
|
||||
const adjustedX = screenWidth - targetGlobal.x - tipWidth - margin;
|
||||
if (isHorizontalTooltip) {
|
||||
newAnchorX = adjustedX;
|
||||
} else {
|
||||
const wouldOverlap = adjustedX < targetWidth && adjustedX + tipWidth > 0;
|
||||
if (!wouldOverlap) {
|
||||
newAnchorX = adjustedX;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Adjust vertical position to keep tooltip on screen if needed
|
||||
// For left/right tooltips, always adjust vertically (they don't overlap vertically)
|
||||
// For top/bottom tooltips, check for overlap before adjusting
|
||||
const globalY = targetGlobal.y + newAnchorY;
|
||||
if (globalY < 0) {
|
||||
newAnchorY = -targetGlobal.y + margin;
|
||||
const adjustedY = -targetGlobal.y + margin;
|
||||
if (isVerticalTooltip) {
|
||||
newAnchorY = adjustedY;
|
||||
} else {
|
||||
const wouldOverlap = adjustedY < targetHeight && adjustedY + tipHeight > 0;
|
||||
if (!wouldOverlap) {
|
||||
newAnchorY = adjustedY;
|
||||
}
|
||||
}
|
||||
} else if (globalY + tipHeight > screenHeight) {
|
||||
newAnchorY = screenHeight - targetGlobal.y - tipHeight - margin;
|
||||
const adjustedY = screenHeight - targetGlobal.y - tipHeight - margin;
|
||||
if (isVerticalTooltip) {
|
||||
newAnchorY = adjustedY;
|
||||
} else {
|
||||
const wouldOverlap = adjustedY < targetHeight && adjustedY + tipHeight > 0;
|
||||
if (!wouldOverlap) {
|
||||
newAnchorY = adjustedY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Apply the new anchor positions
|
||||
|
||||
Reference in New Issue
Block a user