-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
cc70b88
commit a693a10
Showing
5 changed files
with
253 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,86 @@ | ||
# TranslucentWindowStyle | ||
|
||
A description of this package. | ||
Translucent Window Background Style is a Swift package with a custom SwiftUI window background style that creates a translucent window with a blur effect. This package allows you to add a translucent background style to your SwiftUI app's windows. | ||
|
||
## Overview | ||
|
||
The Translucent Window Background Style package provides a `TranslucentBackgroundStyle` struct that conforms to the `WindowBackgroundStyle` protocol. This style creates a translucent window with a blur effect. | ||
|
||
## Usage | ||
|
||
To use the Translucent Window Background Style in your SwiftUI app, follow these steps: | ||
|
||
1. Import the package in your SwiftUI view file: | ||
|
||
```swift | ||
import TranslucentWindowBackgroundStyle | ||
``` | ||
|
||
2. Apply the `presentedWindowBackgroundStyle` modifier to your window view, and pass in an instance of `TranslucentBackgroundStyle`: | ||
|
||
```swift | ||
WindowGroup { | ||
ContentView() | ||
.presentedWindowBackgroundStyle(TranslucentBackgroundStyle.hiddenTitleBarTranslucent) | ||
} | ||
``` | ||
|
||
3. The `hiddenTitleBarTranslucent` static property of `TranslucentBackgroundStyle` provides a convenient method to create a translucent window without a title bar. | ||
|
||
```swift | ||
TranslucentBackgroundStyle.hiddenTitleBarTranslucent | ||
``` | ||
|
||
### Example | ||
|
||
 | ||
|
||
## Installation | ||
|
||
The Translucent Window Background Style package can be installed via Swift Package Manager. To install, follow these steps: | ||
|
||
1. Open your project in Xcode. | ||
|
||
2. Click on File > Swift Packages > Add Package Dependency. | ||
|
||
3. Enter the following URL in the search bar: | ||
|
||
```javascript | ||
https://github.com/DominatorVbN/TranslucentWindowBackgroundStyle | ||
``` | ||
|
||
Replace "your-username" with your GitHub username or the URL of your forked repository. | ||
|
||
4. Choose the version or branch of the package that you want to install. | ||
|
||
5. Click on the Add Package button. | ||
|
||
6. Add `TranslucentWindowBackgroundStyle` to the list of dependencies for your target in your project's `Package.swift` file: | ||
|
||
```swift | ||
dependencies: [ | ||
.package(url: "https://github.com/DominatorVbN/TranslucentWindowBackgroundStyle", .upToNextMinor(from: "1.0.0")) | ||
] | ||
``` | ||
|
||
Replace "your-username" with your GitHub username or the URL of your forked repository, and "1.0.0" with the version or branch that you installed. | ||
|
||
7. Import the package in your SwiftUI view file: | ||
|
||
```swift | ||
import TranslucentWindowBackgroundStyle | ||
``` | ||
|
||
8. You're now ready to use the Translucent Window Background Style in your SwiftUI app! | ||
|
||
## Contributing | ||
|
||
Contributions are always welcome, whether it's bug fixes, feature enhancements, or documentation improvements. To contribute, please follow these steps: | ||
|
||
1. Fork the repository | ||
2. Create a new branch for your changes: `git checkout -b feature/your-feature-name` | ||
3. Make your changes and commit them: `git commit -m 'Add some feature'` | ||
4. Push your changes to your forked repository: `git push origin feature/your-feature-name` | ||
5. Create a pull request on the original repository, with a description of your changes | ||
|
||
Thank you for your contributions! |
171 changes: 168 additions & 3 deletions
171
Sources/TranslucentWindowStyle/TranslucentWindowStyle.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,171 @@ | ||
public struct TranslucentWindowStyle { | ||
public private(set) var text = "Hello, World!" | ||
import SwiftUI | ||
|
||
public init() { | ||
|
||
public protocol WindowBackgroundStyle { | ||
associatedtype Body : View | ||
@ViewBuilder @MainActor var backgroud: Self.Body { get } | ||
} | ||
|
||
extension WindowBackgroundStyle where Self == TranslucentBackgroundStyle { | ||
public static var hiddenTitleBar: TranslucentBackgroundStyle { TranslucentBackgroundStyle() } | ||
} | ||
|
||
public struct TranslucentBackgroundStyle: WindowBackgroundStyle { | ||
public var backgroud: some View { | ||
TranslucentWindowBackground() | ||
} | ||
} | ||
|
||
extension View { | ||
|
||
@MainActor public func presentedWindowBackgroundStyle<S>(_ style: S) -> some View where S : WindowBackgroundStyle { | ||
self.background(style.backgroud) | ||
} | ||
|
||
} | ||
|
||
struct TranslucentWindowBackground: NSViewRepresentable { | ||
|
||
enum ContentViewConfiguration { | ||
case embed(NSView?) | ||
case replace(NSView?) | ||
} | ||
|
||
enum StyleMaskConfiguration { | ||
case insert(NSWindow.StyleMask) | ||
case replace(NSWindow.StyleMask) | ||
} | ||
|
||
struct WindowConfiguration { | ||
let isOpaque: Bool | ||
let backgroundColor: NSColor | ||
let contentViewCofiguration: ContentViewConfiguration | ||
let styleMaskConfiguration: StyleMaskConfiguration | ||
let titlebarAppearsTransparent: Bool | ||
let titleVisibility: NSWindow.TitleVisibility | ||
let standardWindowButtonConfig: StandardWindowButtonConfiguration | ||
let isMovableByWindowBackground: Bool | ||
|
||
public struct StandardWindowButtonConfiguration { | ||
let miniaturizeButtonIsHidden: Bool | ||
let closeButtonIsHidden: Bool | ||
let zoomButtonIsHidden: Bool | ||
} | ||
|
||
static func getTranlucentBackground() -> NSView { | ||
let visualEffect = NSVisualEffectView() | ||
visualEffect.blendingMode = .behindWindow | ||
visualEffect.state = .followsWindowActiveState | ||
visualEffect.material = .sidebar | ||
return visualEffect | ||
} | ||
|
||
static let translucent: WindowConfiguration = WindowConfiguration( | ||
isOpaque: false, | ||
backgroundColor: NSColor.clear, | ||
contentViewCofiguration: .embed(getTranlucentBackground()), | ||
styleMaskConfiguration: .insert(.titled), | ||
titlebarAppearsTransparent: true, | ||
titleVisibility: .hidden, | ||
standardWindowButtonConfig: StandardWindowButtonConfiguration( | ||
miniaturizeButtonIsHidden: true, | ||
closeButtonIsHidden: true, | ||
zoomButtonIsHidden: true | ||
), | ||
isMovableByWindowBackground: true | ||
) | ||
|
||
static func configure(window: NSWindow, forConfig config: WindowConfiguration) { | ||
|
||
window.isOpaque = config.isOpaque | ||
window.backgroundColor = config.backgroundColor | ||
|
||
switch config.contentViewCofiguration { | ||
case let .replace(view): | ||
window.contentView = view | ||
case let .embed(view): | ||
let currentContentView = window.contentView | ||
window.contentView = view | ||
if let currentContentView = currentContentView { | ||
view?.addSubview(currentContentView) | ||
} | ||
} | ||
|
||
switch config.styleMaskConfiguration { | ||
case let .replace(mask): | ||
window.styleMask = mask | ||
case let .insert(mask): | ||
window.styleMask.insert(mask) | ||
} | ||
|
||
window.titlebarAppearsTransparent = config.titlebarAppearsTransparent | ||
window.titleVisibility = config.titleVisibility | ||
window.standardWindowButton(.miniaturizeButton)?.isHidden = config.standardWindowButtonConfig.miniaturizeButtonIsHidden | ||
window.standardWindowButton(.closeButton)?.isHidden = config.standardWindowButtonConfig.closeButtonIsHidden | ||
window.standardWindowButton(.zoomButton)?.isHidden = config.standardWindowButtonConfig.zoomButtonIsHidden | ||
window.isMovableByWindowBackground = config.isMovableByWindowBackground | ||
} | ||
} | ||
|
||
|
||
func makeCoordinator() -> Coordinator { | ||
Coordinator() | ||
} | ||
|
||
|
||
class Coordinator: NSObject { | ||
private var _originalWindowConfiguration: WindowConfiguration? | ||
|
||
func createWindowConfigurationForCurrentContext(_ context: NSWindow) -> WindowConfiguration { | ||
WindowConfiguration( | ||
isOpaque: context.isOpaque, | ||
backgroundColor: context.backgroundColor, | ||
contentViewCofiguration: .replace(context.contentView), | ||
styleMaskConfiguration: .replace(context.styleMask), | ||
titlebarAppearsTransparent: context.titlebarAppearsTransparent, | ||
titleVisibility: context.titleVisibility, | ||
standardWindowButtonConfig: WindowConfiguration.StandardWindowButtonConfiguration( | ||
miniaturizeButtonIsHidden: context.standardWindowButton(.miniaturizeButton)?.isHidden ?? false, | ||
closeButtonIsHidden: context.standardWindowButton(.closeButton)?.isHidden ?? false, | ||
zoomButtonIsHidden: context.standardWindowButton(.zoomButton)?.isHidden ?? false | ||
), | ||
isMovableByWindowBackground: context.isMovableByWindowBackground | ||
) | ||
} | ||
|
||
func makeWindowTranslucent(window: NSWindow?) { | ||
guard let window = window else { return } | ||
self._originalWindowConfiguration = createWindowConfigurationForCurrentContext(window) | ||
let translucentWindowConfiguration = WindowConfiguration.translucent | ||
WindowConfiguration.configure(window: window, forConfig: translucentWindowConfiguration) | ||
} | ||
|
||
func resetWindow(window: NSWindow) { | ||
if let originalWindowConfiguration = _originalWindowConfiguration { | ||
WindowConfiguration.configure(window: window, forConfig: originalWindowConfiguration) | ||
} | ||
} | ||
} | ||
|
||
func makeNSView(context: Context) -> NSView { | ||
let view = NSView() | ||
DispatchQueue.main.async { | ||
let window = view.window | ||
context.coordinator.makeWindowTranslucent(window: window) | ||
} | ||
return view | ||
} | ||
|
||
func updateNSView(_ nsView: NSView, context: Context) { | ||
|
||
} | ||
|
||
static func dismantleNSView(_ nsView: NSView, coordinator: Coordinator) { | ||
guard let window = nsView.window else { | ||
return | ||
} | ||
coordinator.resetWindow(window: window) | ||
} | ||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.