Skip to content
This repository has been archived by the owner on Mar 6, 2024. It is now read-only.

Commit

Permalink
Add "Padding" slider to control distance from edge while docked (#63)
Browse files Browse the repository at this point in the history
  • Loading branch information
ThatsJustCheesy committed Feb 21, 2020
1 parent 46d22f8 commit 883adc7
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 151 deletions.
40 changes: 27 additions & 13 deletions Touch Bar Simulator/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -88,19 +88,33 @@ extension AppDelegate: NSMenuDelegate {
}
menu.items.append(contentsOf: statusMenuDockingItems)

menu.addItem(NSMenuItem(title: "Transparency", action: nil, keyEquivalent: ""))
let transparencyItem = NSMenuItem("Transparency")
let transparencyView = NSView(frame: CGRect(origin: .zero, size: CGSize(width: 200, height: 20)))
let slider = MenubarSlider().alwaysRedisplayOnValueChanged().bindDoubleValue(to: .windowTransparency)
slider.frame = CGRect(x: 20, y: 4, width: 180, height: 11)
slider.minValue = 0.5
transparencyView.addSubview(slider)
slider.translatesAutoresizingMaskIntoConstraints = false
slider.leadingAnchor.constraint(equalTo: transparencyView.leadingAnchor, constant: 24).isActive = true
slider.trailingAnchor.constraint(equalTo: transparencyView.trailingAnchor, constant: -9).isActive = true
slider.centerYAnchor.constraint(equalTo: transparencyView.centerYAnchor).isActive = true
transparencyItem.view = transparencyView
menu.addItem(transparencyItem)
func sliderMenuItem(_ title: String, boundTo key: Defaults.Key<Double>, min: Double, max: Double) -> NSMenuItem {
let menuItem = NSMenuItem(title)
let containerView = NSView(frame: CGRect(origin: .zero, size: CGSize(width: 200, height: 20)))

let slider = MenubarSlider().alwaysRedisplayOnValueChanged()
slider.frame = CGRect(x: 20, y: 4, width: 180, height: 11)
slider.minValue = min
slider.maxValue = max
slider.bindDoubleValue(to: key)

containerView.addSubview(slider)
slider.translatesAutoresizingMaskIntoConstraints = false
slider.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: 24).isActive = true
slider.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: -9).isActive = true
slider.centerYAnchor.constraint(equalTo: containerView.centerYAnchor).isActive = true
menuItem.view = containerView

return menuItem
}

if Defaults[.windowDocking] != .floating {
menu.addItem(NSMenuItem("Padding"))
menu.addItem(sliderMenuItem("Padding", boundTo: .windowPadding, min: 0.0, max: 120.0))
}

menu.addItem(NSMenuItem("Transparency"))
menu.addItem(sliderMenuItem("Transparency", boundTo: .windowTransparency, min: 0.5, max: 1.0))

menu.addItem(NSMenuItem.separator())

Expand Down
1 change: 1 addition & 0 deletions Touch Bar Simulator/Constants.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ struct Constants {
extension Defaults.Keys {
static let windowTransparency = Key<Double>("windowTransparency", default: 0.75)
static let windowDocking = Key<TouchBarWindow.Docking>("windowDocking", default: .floating)
static let windowPadding = Key<Double>("windowPadding", default: 0.0)
static let showOnAllDesktops = Key<Bool>("showOnAllDesktops", default: false)
static let lastFloatingPosition = OptionalKey<CGPoint>("lastFloatingPosition")
static let dockBehavior = Key<Bool>("dockBehavior", default: false)
Expand Down
47 changes: 13 additions & 34 deletions Touch Bar Simulator/Glue.swift
Original file line number Diff line number Diff line change
@@ -1,33 +1,9 @@
import Foundation
import AppKit
import Defaults

// TODO: Upstream all these to https://github.com/sindresorhus/Defaults

extension Defaults {
@discardableResult
static func observe<T: Codable, Weak: AnyObject>(
_ key: Key<T>,
tiedToLifetimeOf weaklyHeldObject: Weak,
options: NSKeyValueObservingOptions = [.initial, .new, .old],
handler: @escaping (KeyChange<T>) -> Void
) -> DefaultsObservation {
var observation: DefaultsObservation!
observation = observe(key, options: options) { [weak weaklyHeldObject] change in
guard let temporaryStrongReference = weaklyHeldObject else {
// Will never occur on first call (outer function holds a strong reference),
// so observation will never be nil
observation.invalidate()
return
}

_ = temporaryStrongReference
handler(change)
}

return observation
}
}

extension NSMenuItem {
/**
Adds an action to this menu item that toggles the value of `key` in the
Expand All @@ -38,15 +14,16 @@ extension NSMenuItem {
let menuItem = NSMenuItem(title: "Invert Colors").bindState(to: .invertColors)
```
*/
@discardableResult
func bindState(to key: Defaults.Key<Bool>) -> Self {
addAction { _ in
Defaults[key].toggle()
}

// swiftlint:disable:next unowned_variable_capture
Defaults.observe(key, tiedToLifetimeOf: self) { [unowned self] change in
self.isChecked = change.newValue
Defaults.observe(key) { [weak self] change in
self?.isChecked = change.newValue
}
.tieToLifetime(of: self)

return self
}
Expand All @@ -65,15 +42,16 @@ extension NSMenuItem {
let menuItem = NSMenuItem(title: "Duck").bindChecked(to: .billingType, value: .duck)
```
*/
@discardableResult
func bindChecked<Value: Equatable>(to key: Defaults.Key<Value>, value: Value) -> Self {
addAction { _ in
Defaults[key] = value
}

// swiftlint:disable:next unowned_variable_capture
Defaults.observe(key, tiedToLifetimeOf: self) { [unowned self] change in
self.isChecked = (change.newValue == value)
Defaults.observe(key) { [weak self] change in
self?.isChecked = (change.newValue == value)
}
.tieToLifetime(of: self)

return self
}
Expand All @@ -91,15 +69,16 @@ extension NSSlider {
let slider = NSSlider().bindDoubleValue(to: .transparency)
```
*/
@discardableResult
func bindDoubleValue(to key: Defaults.Key<Double>) -> Self {
addAction { sender in
Defaults[key] = sender.doubleValue
}

// swiftlint:disable:next unowned_variable_capture
Defaults.observe(key, tiedToLifetimeOf: self) { [unowned self] change in
self.doubleValue = change.newValue
Defaults.observe(key) { [weak self] change in
self?.doubleValue = change.newValue
}
.tieToLifetime(of: self)

return self
}
Expand Down
2 changes: 1 addition & 1 deletion Touch Bar Simulator/ToolbarSlider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ private final class ToolbarSliderCell: NSSliderCell {

extension NSSlider {
// Redisplaying the slider prevents shadow artifacts that result
// from moving a knob that draws a shadow
// from moving a knob that draws a shadow.
// However, only do so if its value has changed, because if a
// redisplay is attempted without a change, then the slider draws
// itself brighter for some reason.
Expand Down
Loading

0 comments on commit 883adc7

Please sign in to comment.