Skip to content

Commit

Permalink
Feat: initial implementation 🚀
Browse files Browse the repository at this point in the history
  • Loading branch information
DominatorVbN committed Mar 5, 2023
1 parent cc70b88 commit a693a10
Show file tree
Hide file tree
Showing 5 changed files with 253 additions and 10 deletions.
1 change: 1 addition & 0 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import PackageDescription

let package = Package(
name: "TranslucentWindowStyle",
platforms: [.macOS(.v13)],
products: [
// Products define the executables and libraries a package produces, and make them visible to other packages.
.library(
Expand Down
85 changes: 84 additions & 1 deletion README.md
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

![screenshot](screenshot.png)

## 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 Sources/TranslucentWindowStyle/TranslucentWindowStyle.swift
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)
}
}


Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,4 @@ import XCTest
@testable import TranslucentWindowStyle

final class TranslucentWindowStyleTests: XCTestCase {
func testExample() throws {
// This is an example of a functional test case.
// Use XCTAssert and related functions to verify your tests produce the correct
// results.
XCTAssertEqual(TranslucentWindowStyle().text, "Hello, World!")
}
}
Binary file added screenshot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit a693a10

Please sign in to comment.