Skip to content

Commit

Permalink
♻️ Refactor environment values, implement LuminareManagerProtocol
Browse files Browse the repository at this point in the history
  • Loading branch information
KrLite committed Dec 19, 2024
1 parent cfcc584 commit 9b2f592
Show file tree
Hide file tree
Showing 10 changed files with 381 additions and 183 deletions.
22 changes: 9 additions & 13 deletions Sources/Luminare/Components/Auxiliary/LuminareButtonStyles.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,22 @@ import SwiftUI
struct AspectRatioModifier: ViewModifier {
@Environment(\.luminareMinHeight) private var minHeight
@Environment(\.luminareAspectRatio) private var aspectRatio
@Environment(\.luminareAspectRatioContentMode) private var contentMode
@Environment(\.luminareAspectRatioHasFixedHeight) private var hasFixedHeight

@ViewBuilder func body(content: Content) -> some View {
if let aspectRatio {
Group {
if isConstrained {
if isConstrained, let contentMode {
content
.frame(
minWidth: minWidth, maxWidth: .infinity,
minHeight: minHeight,
maxHeight: hasFixedHeight ? nil : .infinity
)
.aspectRatio(
aspectRatio.aspectRatio,
contentMode: aspectRatio.contentMode
aspectRatio,
contentMode: contentMode
)
} else {
content
Expand All @@ -34,27 +36,21 @@ struct AspectRatioModifier: ViewModifier {
}
}
.fixedSize(
horizontal: aspectRatio.contentMode == .fit,
horizontal: contentMode == .fit,
vertical: hasFixedHeight
)
} else {
content
}
}

private var hasFixedHeight: Bool {
guard let aspectRatio else { return false }
return aspectRatio.hasFixedHeight
}

private var isConstrained: Bool {
guard let aspectRatio else { return false }
return aspectRatio.contentMode == .fit || hasFixedHeight
guard let contentMode else { return false }
return contentMode == .fit || hasFixedHeight
}

private var minWidth: CGFloat? {
if hasFixedHeight,
let aspectRatio = aspectRatio?.aspectRatio {
if hasFixedHeight, let aspectRatio {
minHeight * aspectRatio
} else {
nil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ import SwiftUI

/// A simple scroll view that enables scrolling only if the content is large enough to scroll.
public struct AutoScrollView<Content>: View where Content: View {
@Environment(\.luminareContentMarginsTop) private var contentMarginsTop
@Environment(\.luminareContentMarginsLeading) private var contentMarginsLeading
@Environment(\.luminareContentMarginsBottom) private var contentMarginsBottom
@Environment(\.luminareContentMarginsTrailing) private var contentMarginsTrailing

private let axes: Axis.Set
private let showsIndicators: Bool
@ViewBuilder private var content: () -> Content
Expand All @@ -33,29 +38,68 @@ public struct AutoScrollView<Content>: View where Content: View {
}

public var body: some View {
ScrollView(axes, showsIndicators: showsIndicators) {
content()
.onGeometryChange(for: CGSize.self) { proxy in
proxy.size
} action: { size in
contentSize = size
ScrollView(allowedAxes, showsIndicators: showsIndicators) {
VStack(spacing: 0) {
if contentMarginsTop > 0 {
Spacer()
.frame(height: contentMarginsTop)
}

content()
.padding(.leading, contentMarginsLeading)
.padding(.trailing, contentMarginsTrailing)

if contentMarginsBottom > 0 {
Spacer()
.frame(height: contentMarginsBottom)
}
}
.onGeometryChange(for: CGSize.self) { proxy in
proxy.size
} action: { size in
contentSize = size
}
}
.onGeometryChange(for: CGSize.self) { proxy in
proxy.size
} action: { size in
containerSize = size
}
.scrollDisabled(isHorizontalScrollDisabled && isVerticalScrollDisabled)
.scrollDisabled(isHorizontalScrollingDisabled && isVerticalScrollingDisabled)
}

private var allowedAxes: Axis.Set {
if isHorizontalScrollingDisabled && isVerticalScrollingDisabled {
axes
} else if isHorizontalScrollingDisabled {
axes.intersection(.vertical)
} else if isVerticalScrollingDisabled {
axes.intersection(.horizontal)
} else {
axes
}
}

private var isHorizontalScrollDisabled: Bool {
private var isHorizontalScrollingDisabled: Bool {
guard axes.contains(.horizontal) else { return true }
return contentSize.width <= containerSize.width
}

private var isVerticalScrollDisabled: Bool {
private var isVerticalScrollingDisabled: Bool {
guard axes.contains(.vertical) else { return true }
return contentSize.height <= containerSize.height
}
}

@available(macOS 15.0, *)
#Preview(
"AutoScrollView",
traits: .sizeThatFitsLayout
) {
AutoScrollView {
Color.red
.frame(height: 300)
}
.luminareContentMargins(.vertical, 50)
.frame(width: 100, height: 300)
}
22 changes: 13 additions & 9 deletions Sources/Luminare/Components/LuminareList.swift
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,14 @@ public struct LuminareList<ContentA, ContentB, V, ID>: View
@Environment(\.luminareClickedOutside) private var luminareClickedOutside
@Environment(\.luminareTint) private var tint
@Environment(\.luminareAnimation) private var animation
@Environment(\.luminareListContentMarginsTop) private var marginsTop
@Environment(\.luminareListContentMarginsBottom) private var marginsBottom
@Environment(\.luminareContentMarginsTop) private var contentMarginsTop
@Environment(\.luminareContentMarginsLeading) private var contentMarginsLeading
@Environment(\.luminareContentMarginsBottom) private var contentMarginsBottom
@Environment(\.luminareContentMarginsTrailing) private var contentMarginsTrailing
@Environment(\.luminareListItemHeight) private var itemHeight
@Environment(\.luminareListFixedHeightUntil) private var fixedHeight
@Environment(\.luminareListRoundedTopCornerBehavior) private var topCorner
@Environment(\.luminareListRoundedBottomCornerBehavior) private
var bottomCorner
@Environment(\.luminareListRoundedBottomCornerBehavior) private var bottomCorner

// MARK: Fields

Expand Down Expand Up @@ -128,9 +129,9 @@ public struct LuminareList<ContentA, ContentB, V, ID>: View
emptyView()
} else {
List(selection: $selection) {
if marginsTop > 0 {
if contentMarginsTop > 0 {
Spacer()
.frame(height: marginsTop)
.frame(height: contentMarginsTop)
}

ForEach($items, id: keyPath) { item in
Expand Down Expand Up @@ -184,11 +185,13 @@ public struct LuminareList<ContentA, ContentB, V, ID>: View
.listRowSeparator(.hidden)
.listRowInsets(.init())
.padding(.horizontal, -10)
.padding(.leading, contentMarginsLeading)
.padding(.trailing, contentMarginsTrailing)
.transition(.slide)

if marginsBottom > 0 {
if contentMarginsBottom > 0 {
Spacer()
.frame(height: marginsBottom)
.frame(height: contentMarginsBottom)
}
}
.listStyle(.plain)
Expand Down Expand Up @@ -237,7 +240,8 @@ public struct LuminareList<ContentA, ContentB, V, ID>: View
}

private var totalHeight: CGFloat {
CGFloat(max(1, items.count)) * itemHeight + marginsTop + marginsBottom
let margins = contentMarginsTop + contentMarginsBottom
return CGFloat(max(1, items.count)) * itemHeight + margins
}

private var hasFixedHeight: Bool {
Expand Down
10 changes: 6 additions & 4 deletions Sources/Luminare/Main Window/LuminareView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ public struct LuminareView<Content>: View where Content: View {

@Environment(\.luminareTint) private var tint
@Environment(\.luminareWindow) private var window
@Environment(\.luminareWindowMinFrame) private var minFrame
@Environment(\.luminareWindowMaxFrame) private var maxFrame
@Environment(\.luminareWindowMinWidth) private var minWidth
@Environment(\.luminareWindowMaxWidth) private var maxWidth
@Environment(\.luminareWindowMinHeight) private var minHeight
@Environment(\.luminareWindowMaxHeight) private var maxHeight

// MARK: Fields

Expand All @@ -42,8 +44,8 @@ public struct LuminareView<Content>: View where Content: View {
}
}
.frame(
minWidth: minFrame.width, maxWidth: maxFrame.width,
minHeight: minFrame.height, maxHeight: maxFrame.height,
minWidth: minWidth, maxWidth: maxWidth,
minHeight: minHeight, maxHeight: maxHeight,
alignment: .leading
)
.focusable(false)
Expand Down
3 changes: 1 addition & 2 deletions Sources/Luminare/Main Window/LuminareWindow.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,7 @@ public class LuminareWindow: NSWindow {
let view = NSHostingView(
rootView: LuminareView(content: content)
.environment(\.luminareWindow, self)
.environment(\.luminareWindowMinFrame, minFrame)
.environment(\.luminareWindowMaxFrame, maxFrame)
.luminareWindowFrame(min: minFrame, max: maxFrame)
)

contentView = view
Expand Down
74 changes: 35 additions & 39 deletions Sources/Luminare/Main Window/Sidebar/LuminareSidebar.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ import SwiftUI

/// A stylized sidebar for ``LuminareWindow``.
public struct LuminareSidebar<Content>: View where Content: View {
@Environment(\.luminareContentMarginsTop) private var contentMarginsTop
@Environment(\.luminareContentMarginsBottom) private var contentMarginsBottom
@Environment(\.luminareSidebarOverflow) private var overflow

@ViewBuilder private var content: () -> Content

/// Initializes a ``LuminareSidebar``.
Expand All @@ -21,48 +25,40 @@ public struct LuminareSidebar<Content>: View where Content: View {
}

public var body: some View {
if #available(macOS 14.0, *) {
let overflow: CGFloat = 50

AutoScrollView(.vertical) {
VStack(spacing: 24) {
content()
}
.padding(.bottom, 12)
}
.scrollIndicators(.never)
.scrollContentBackground(.hidden)
.padding(.horizontal, 12)
.frame(maxHeight: .infinity, alignment: .top)
.padding(.top, -overflow)
.contentMargins(.top, overflow)
.mask {
VStack(spacing: 0) {
LinearGradient(
colors: [.clear, .white],
startPoint: .top,
endPoint: .bottom
)
.frame(height: overflow)

Color.white
}
.padding(.top, -overflow)
AutoScrollView(.vertical) {
VStack(spacing: 24) {
content()
}

.luminareBackground()
} else {
AutoScrollView(.vertical) {
VStack(spacing: 24) {
content()
}
.padding(.bottom, 12)
}
.luminareContentMargins(.top, overflow + contentMarginsTop)
.luminareContentMargins(.bottom, overflow + contentMarginsBottom)
.scrollIndicators(.never)
.scrollContentBackground(.hidden)
.padding(.horizontal, 12)
.frame(maxHeight: .infinity, alignment: .top)
.padding(.top, -overflow)
.mask {
VStack(spacing: 0) {
LinearGradient(
colors: [.clear, .white],
startPoint: .top,
endPoint: .bottom
)
.frame(height: overflow)

Color.white

LinearGradient(
colors: [.clear, .white],
startPoint: .top,
endPoint: .bottom
)
.frame(height: overflow)
}
.scrollIndicators(.never)
.scrollContentBackground(.hidden)
.padding(.horizontal, 12)
.frame(maxHeight: .infinity, alignment: .top)
.luminareBackground()
.padding(.vertical, -overflow)
}
.luminareBackground()
}
}

Expand Down
Loading

0 comments on commit 9b2f592

Please sign in to comment.