mirror of
https://github.com/FBukovina/Atoll.git
synced 2026-10-27 15:14:33 +00:00
UIFix: Window Shadows and Notch Shadows
This commit is contained in:
parent
80d132a85f
commit
3bba53c583
4 changed files with 68 additions and 17 deletions
|
|
@ -126,6 +126,20 @@ struct ContentView: View {
|
|||
}
|
||||
return cornerRadiusInsets
|
||||
}
|
||||
|
||||
private var currentShadowPadding: CGFloat {
|
||||
notchShadowPaddingValue(isMinimalistic: enableMinimalisticUI)
|
||||
}
|
||||
|
||||
private var currentNotchShape: NotchShape {
|
||||
let topRadius = (vm.notchState == .open && Defaults[.cornerRadiusScaling])
|
||||
? activeCornerRadiusInsets.opened.top
|
||||
: activeCornerRadiusInsets.closed.top
|
||||
let bottomRadius = (vm.notchState == .open && Defaults[.cornerRadiusScaling])
|
||||
? activeCornerRadiusInsets.opened.bottom
|
||||
: activeCornerRadiusInsets.closed.bottom
|
||||
return NotchShape(topCornerRadius: topRadius, bottomCornerRadius: bottomRadius)
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
let interactionsEnabled = !lockScreenManager.isLocked
|
||||
|
|
@ -139,16 +153,20 @@ struct ContentView: View {
|
|||
)
|
||||
.padding([.horizontal, .bottom], vm.notchState == .open ? 12 : 0)
|
||||
.background(.black)
|
||||
.mask {
|
||||
((vm.notchState == .open) && Defaults[.cornerRadiusScaling])
|
||||
? NotchShape(topCornerRadius: activeCornerRadiusInsets.opened.top, bottomCornerRadius: activeCornerRadiusInsets.opened.bottom)
|
||||
.drawingGroup()
|
||||
: NotchShape(topCornerRadius: activeCornerRadiusInsets.closed.top, bottomCornerRadius: activeCornerRadiusInsets.closed.bottom)
|
||||
.drawingGroup()
|
||||
}
|
||||
.padding(.bottom, vm.notchState == .open && Defaults[.extendHoverArea] ? 0 : (vm.effectiveClosedNotchHeight == 0)
|
||||
? zeroHeightHoverPadding
|
||||
: 0
|
||||
.clipShape(currentNotchShape)
|
||||
.compositingGroup()
|
||||
.shadow(
|
||||
color: ((vm.notchState == .open || isHovering) && Defaults[.enableShadow])
|
||||
? .black.opacity(0.6)
|
||||
: .clear,
|
||||
radius: Defaults[.cornerRadiusScaling] ? 10 : 5
|
||||
)
|
||||
.padding(.bottom,
|
||||
currentShadowPadding + (
|
||||
vm.notchState == .open && Defaults[.extendHoverArea]
|
||||
? 0
|
||||
: (vm.effectiveClosedNotchHeight == 0 ? zeroHeightHoverPadding : 0)
|
||||
)
|
||||
)
|
||||
|
||||
mainLayout
|
||||
|
|
@ -280,7 +298,11 @@ struct ContentView: View {
|
|||
// .keyboardShortcut("E", modifiers: .command)
|
||||
}
|
||||
}
|
||||
.frame(maxWidth: dynamicNotchSize.width, maxHeight: dynamicNotchSize.height, alignment: .top)
|
||||
.frame(
|
||||
maxWidth: dynamicNotchSize.width,
|
||||
maxHeight: dynamicNotchSize.height + currentShadowPadding,
|
||||
alignment: .top
|
||||
)
|
||||
.animation(dynamicNotchResizeAnimation, value: dynamicNotchSize)
|
||||
.animation(.easeInOut(duration: 0.4), value: coordinator.currentView)
|
||||
.environmentObject(privacyManager)
|
||||
|
|
@ -291,7 +313,6 @@ struct ContentView: View {
|
|||
vm.shouldRecheckHover.toggle()
|
||||
}
|
||||
}
|
||||
.shadow(color: ((vm.notchState == .open || isHovering) && Defaults[.enableShadow]) ? .black.opacity(0.6) : .clear, radius: Defaults[.cornerRadiusScaling] ? 10 : 5)
|
||||
.background(dragDetector)
|
||||
.environmentObject(vm)
|
||||
.environmentObject(webcamManager)
|
||||
|
|
|
|||
|
|
@ -278,11 +278,15 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
|||
|
||||
// Use minimalistic or normal size based on settings, then adjust for stats layout
|
||||
let baseSize = Defaults[.enableMinimalisticUI] ? minimalisticOpenNotchSize : openNotchSize
|
||||
return statsAdjustedNotchSize(
|
||||
let adjustedContentSize = statsAdjustedNotchSize(
|
||||
from: baseSize,
|
||||
isStatsTabActive: coordinator.currentView == .stats,
|
||||
secondRowProgress: coordinator.statsSecondRowExpansion
|
||||
)
|
||||
return addShadowPadding(
|
||||
to: adjustedContentSize,
|
||||
isMinimalistic: Defaults[.enableMinimalisticUI]
|
||||
)
|
||||
}
|
||||
|
||||
func ensureWindowSize(_ size: CGSize, animated: Bool, force: Bool = false) {
|
||||
|
|
|
|||
|
|
@ -84,7 +84,11 @@ class DynamicIslandViewModel: NSObject, ObservableObject {
|
|||
self.notchSize = updatedTarget
|
||||
}
|
||||
if let delegate = AppDelegate.shared {
|
||||
delegate.ensureWindowSize(updatedTarget, animated: true, force: false)
|
||||
delegate.ensureWindowSize(
|
||||
addShadowPadding(to: updatedTarget, isMinimalistic: Defaults[.enableMinimalisticUI]),
|
||||
animated: true,
|
||||
force: false
|
||||
)
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
|
@ -106,7 +110,11 @@ class DynamicIslandViewModel: NSObject, ObservableObject {
|
|||
self.notchSize = updatedTarget
|
||||
}
|
||||
if let delegate = AppDelegate.shared {
|
||||
delegate.ensureWindowSize(updatedTarget, animated: true, force: false)
|
||||
delegate.ensureWindowSize(
|
||||
addShadowPadding(to: updatedTarget, isMinimalistic: Defaults[.enableMinimalisticUI]),
|
||||
animated: true,
|
||||
force: false
|
||||
)
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
|
@ -123,7 +131,11 @@ class DynamicIslandViewModel: NSObject, ObservableObject {
|
|||
self.notchSize = updatedTarget
|
||||
}
|
||||
if let delegate = AppDelegate.shared {
|
||||
delegate.ensureWindowSize(updatedTarget, animated: false, force: false)
|
||||
delegate.ensureWindowSize(
|
||||
addShadowPadding(to: updatedTarget, isMinimalistic: Defaults[.enableMinimalisticUI]),
|
||||
animated: false,
|
||||
force: false
|
||||
)
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
|
@ -184,7 +196,11 @@ class DynamicIslandViewModel: NSObject, ObservableObject {
|
|||
|
||||
let applyWindowResize: () -> Void = {
|
||||
guard let delegate = AppDelegate.shared else { return }
|
||||
delegate.ensureWindowSize(targetSize, animated: false, force: true)
|
||||
delegate.ensureWindowSize(
|
||||
addShadowPadding(to: targetSize, isMinimalistic: Defaults[.enableMinimalisticUI]),
|
||||
animated: false,
|
||||
force: true
|
||||
)
|
||||
}
|
||||
|
||||
if Thread.isMainThread {
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@ private let minimalisticBaseOpenNotchSize: CGSize = .init(width: 420, height: 18
|
|||
private let minimalisticLyricsExtraHeight: CGFloat = 40
|
||||
let statsSecondRowContentHeight: CGFloat = 120
|
||||
let statsGridSpacingHeight: CGFloat = 12
|
||||
let notchShadowPaddingStandard: CGFloat = 18
|
||||
let notchShadowPaddingMinimalistic: CGFloat = 12
|
||||
|
||||
@MainActor
|
||||
var minimalisticOpenNotchSize: CGSize {
|
||||
|
|
@ -71,6 +73,14 @@ func statsAdjustedNotchSize(
|
|||
return adjustedSize
|
||||
}
|
||||
|
||||
func notchShadowPaddingValue(isMinimalistic: Bool) -> CGFloat {
|
||||
isMinimalistic ? notchShadowPaddingMinimalistic : notchShadowPaddingStandard
|
||||
}
|
||||
|
||||
func addShadowPadding(to size: CGSize, isMinimalistic: Bool) -> CGSize {
|
||||
CGSize(width: size.width, height: size.height + notchShadowPaddingValue(isMinimalistic: isMinimalistic))
|
||||
}
|
||||
|
||||
enum MusicPlayerImageSizes {
|
||||
static let cornerRadiusInset: (opened: CGFloat, closed: CGFloat) = (opened: 13.0, closed: 4.0)
|
||||
static let size = (opened: CGSize(width: 90, height: 90), closed: CGSize(width: 20, height: 20))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue