Goofing around with Box

This commit is contained in:
James Magahern
2021-07-13 18:11:47 -07:00
parent 560b1a4a75
commit 777b079f5e
5 changed files with 133 additions and 48 deletions

View File

@@ -287,6 +287,11 @@ class BrowserViewController: UIViewController
showSettingsWindow() showSettingsWindow()
}, for: .touchUpInside) }, for: .touchUpInside)
// Share
documentControls.sharingView.addAction(UIAction { [unowned self] _ in
showShareSheetForCurrentURL(fromViewController: documentControls)
}, for: .touchUpInside)
present(documentControls, animated: true, completion: nil) present(documentControls, animated: true, completion: nil)
}), for: .touchUpInside) }), for: .touchUpInside)

View File

@@ -14,6 +14,13 @@ class DocumentControlItemView: UIControl
let imageView = UIImageView(frame: .zero) let imageView = UIImageView(frame: .zero)
let label = UILabel(frame: .zero) let label = UILabel(frame: .zero)
enum ViewType: String {
case imageView
case label
case separator
case highlightView
}
var drawsBottomSeparator: Bool = false { var drawsBottomSeparator: Bool = false {
didSet { setNeedsLayout() } didSet { setNeedsLayout() }
} }
@@ -50,38 +57,68 @@ class DocumentControlItemView: UIControl
CGSize(width: size.width, height: Self.controlHeight) CGSize(width: size.width, height: Self.controlHeight)
} }
private func box(_ bounds: CGRect) -> Box<ViewType> {
Box {
let padding: CGFloat = 18.0
let imageSize: CGFloat = 24.0
let ibounds = bounds.inset(by: layoutMargins)
let imageRect = CGRect(
x: ibounds.minX + 6.0, y: 0.0,
width: imageSize, height: imageSize
).centeredY(inRect: bounds)
(ViewType.imageView, imageRect)
(ViewType.highlightView, bounds)
(ViewType.label, CGRect(
x: imageRect.maxX + padding, y: ibounds.minY,
width: ibounds.width - imageRect.maxX - padding, height: ibounds.height
))
let separatorHeight: CGFloat = 1.0
if drawsBottomSeparator {
(ViewType.separator, CGRect(
x: bounds.minX, y: bounds.height - separatorHeight,
width: bounds.width, height: separatorHeight
))
} else {
(ViewType.separator, CGRect.zero)
}
}
}
override func layoutSubviews() { override func layoutSubviews() {
super.layoutSubviews() super.layoutSubviews()
highlightView.frame = bounds box(bounds).fill([
.imageView : imageView,
.separator : separatorView,
.label : label,
.highlightView : highlightView
])
let padding: CGFloat = 18.0 separatorView.isHidden = !drawsBottomSeparator
let imageSize: CGFloat = 24.0
let bounds = self.bounds.inset(by: layoutMargins)
imageView.frame = CGRect(
x: bounds.minX + 6.0, y: 0.0,
width: imageSize, height: imageSize
).centeredY(inRect: self.bounds)
label.frame = CGRect(
x: imageView.frame.maxX + padding, y: bounds.minY,
width: bounds.width - imageView.frame.maxX - padding, height: bounds.height
)
let separatorHeight: CGFloat = 1.0
if drawsBottomSeparator {
separatorView.isHidden = false
separatorView.frame = CGRect(
x: self.bounds.minX, y: self.bounds.height - separatorHeight,
width: self.bounds.width, height: separatorHeight
)
} else {
separatorView.isHidden = true
}
} }
override func setTracking(_ tracking: Bool) { override func setTracking(_ tracking: Bool) {
super.setTracking(tracking) super.setTracking(tracking)
highlightView.isHidden = !tracking highlightView.isHidden = !tracking
} }
public func title(_ title: String) -> Self {
self.label.text = title
return self
}
public func image(_ image: UIImage?) -> Self {
self.imageView.image = image
return self
}
public func symbol(_ name: String) -> Self {
return self.image(UIImage(systemName: name))
}
} }

View File

@@ -10,37 +10,25 @@ import UIKit
class DocumentControlViewController: UIViewController class DocumentControlViewController: UIViewController
{ {
let documentControlsView = DocumentControlsView() let documentControlsView = DocumentControlsView()
let fontSizeAdjustView = FontSizeAdjustView() let fontSizeAdjustView = FontSizeAdjustView()
let findOnPageControlView = DocumentControlItemView()
let navigationControlView = NavigationControlsView() let navigationControlView = NavigationControlsView()
let settingsView = DocumentControlItemView()
let readabilityView = DocumentControlItemView() let findOnPageControlView = DocumentControlItemView().title("Find On Page") .symbol("magnifyingglass")
let darkModeView = DocumentControlItemView() let settingsView = DocumentControlItemView().title("Settings") .symbol("gear")
let archiveView = DocumentControlItemView() let readabilityView = DocumentControlItemView().title("Reader Mode") .symbol("doc.richtext")
let emailView = DocumentControlItemView() let archiveView = DocumentControlItemView().title("Archive.today") .symbol("shippingbox")
let emailView = DocumentControlItemView().title("Email") .symbol("envelope")
let sharingView = DocumentControlItemView().title("Share") .symbol("square.and.arrow.up")
let darkModeView = DocumentControlItemView().title("Dark Mode")
var observations: [NSKeyValueObservation] = [] var observations: [NSKeyValueObservation] = []
static public let preferredWidth = CGFloat(200.0) static public let preferredWidth = CGFloat(230.0)
init(darkModeEnabled: Bool) { init(darkModeEnabled: Bool) {
super.init(nibName: nil, bundle: nil) super.init(nibName: nil, bundle: nil)
findOnPageControlView.label.text = "Find On Page"
findOnPageControlView.imageView.image = UIImage(systemName: "magnifyingglass")
settingsView.label.text = "Settings"
settingsView.imageView.image = UIImage(systemName: "gear")
readabilityView.label.text = "Reader Mode"
readabilityView.imageView.image = UIImage(systemName: "doc.richtext")
archiveView.label.text = "Archive.today"
archiveView.imageView.image = UIImage(systemName: "shippingbox")
emailView.label.text = "Email"
emailView.imageView.image = UIImage(systemName: "envelope")
if darkModeEnabled { if darkModeEnabled {
darkModeView.label.text = "Disable Dark Mode" darkModeView.label.text = "Disable Dark Mode"
} else { } else {
@@ -53,6 +41,7 @@ class DocumentControlViewController: UIViewController
documentControlsView.stackView.addArrangedSubview(fontSizeAdjustView) documentControlsView.stackView.addArrangedSubview(fontSizeAdjustView)
documentControlsView.stackView.addArrangedSubview(emailView) documentControlsView.stackView.addArrangedSubview(emailView)
documentControlsView.stackView.addArrangedSubview(sharingView)
documentControlsView.stackView.addArrangedSubview(findOnPageControlView) documentControlsView.stackView.addArrangedSubview(findOnPageControlView)
documentControlsView.stackView.addArrangedSubview(darkModeView) documentControlsView.stackView.addArrangedSubview(darkModeView)
documentControlsView.stackView.addArrangedSubview(readabilityView) documentControlsView.stackView.addArrangedSubview(readabilityView)

50
App/Utilities/Box.swift Normal file
View File

@@ -0,0 +1,50 @@
//
// Box.swift
// Box
//
// Created by James Magahern on 7/13/21.
//
import UIKit
struct Box<Identifier: Hashable> {
typealias Compartment = (Identifier, CGRect)
typealias Realized = (Identifier, UIView)
@resultBuilder
struct BoxBuilder {
static func buildEither(first component: [Compartment]) -> Compartment {
component[0]
}
static func buildEither(second component: [Compartment]) -> Compartment {
component[0]
}
static func buildBlock(_ compartments: Compartment...) -> [Compartment] {
return compartments
}
}
public var boundingRect: CGRect {
get {
compartmentMap.reduce(into: CGRect.zero) { (result, compartment) in
result = result.union(compartment.value)
}
}
}
private var compartmentMap: [Identifier: CGRect] = [:]
init(@BoxBuilder _ compartments: () -> [Compartment]) {
self.compartmentMap = compartments().reduce(into: [:]) { (result, compartment) in
result[compartment.0] = compartment.1
}
}
public func fill(_ realized: [Identifier: UIView]) {
realized.forEach { (key, value) in
value.frame = compartmentMap[key] ?? .zero
}
}
}

View File

@@ -41,6 +41,7 @@
1ADFF4CD24CBB0C8006DC7AE /* ScriptPolicyViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1ADFF4CC24CBB0C8006DC7AE /* ScriptPolicyViewController.swift */; }; 1ADFF4CD24CBB0C8006DC7AE /* ScriptPolicyViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1ADFF4CC24CBB0C8006DC7AE /* ScriptPolicyViewController.swift */; };
CD01D5A5254A10BB00189CDC /* TabBarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD01D5A4254A10BB00189CDC /* TabBarView.swift */; }; CD01D5A5254A10BB00189CDC /* TabBarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD01D5A4254A10BB00189CDC /* TabBarView.swift */; };
CD01D5AB254A206D00189CDC /* TabBarViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD01D5AA254A206D00189CDC /* TabBarViewController.swift */; }; CD01D5AB254A206D00189CDC /* TabBarViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD01D5AA254A206D00189CDC /* TabBarViewController.swift */; };
CD16844D269E709400B8F8A5 /* Box.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD16844C269E709400B8F8A5 /* Box.swift */; };
CD19576D268BE95900E8089B /* GenericContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD19576C268BE95900E8089B /* GenericContentView.swift */; }; CD19576D268BE95900E8089B /* GenericContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD19576C268BE95900E8089B /* GenericContentView.swift */; };
CD470C4225DE056600AFBE0E /* BrowserViewController+WebKitDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD470C4125DE056600AFBE0E /* BrowserViewController+WebKitDelegate.swift */; }; CD470C4225DE056600AFBE0E /* BrowserViewController+WebKitDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD470C4125DE056600AFBE0E /* BrowserViewController+WebKitDelegate.swift */; };
CD470C4425DE070400AFBE0E /* BrowserViewController+Keyboard.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD470C4325DE070400AFBE0E /* BrowserViewController+Keyboard.swift */; }; CD470C4425DE070400AFBE0E /* BrowserViewController+Keyboard.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD470C4325DE070400AFBE0E /* BrowserViewController+Keyboard.swift */; };
@@ -139,6 +140,7 @@
1ADFF4CC24CBB0C8006DC7AE /* ScriptPolicyViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScriptPolicyViewController.swift; sourceTree = "<group>"; }; 1ADFF4CC24CBB0C8006DC7AE /* ScriptPolicyViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScriptPolicyViewController.swift; sourceTree = "<group>"; };
CD01D5A4254A10BB00189CDC /* TabBarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBarView.swift; sourceTree = "<group>"; }; CD01D5A4254A10BB00189CDC /* TabBarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBarView.swift; sourceTree = "<group>"; };
CD01D5AA254A206D00189CDC /* TabBarViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBarViewController.swift; sourceTree = "<group>"; }; CD01D5AA254A206D00189CDC /* TabBarViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBarViewController.swift; sourceTree = "<group>"; };
CD16844C269E709400B8F8A5 /* Box.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Box.swift; sourceTree = "<group>"; };
CD19576C268BE95900E8089B /* GenericContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GenericContentView.swift; sourceTree = "<group>"; }; CD19576C268BE95900E8089B /* GenericContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GenericContentView.swift; sourceTree = "<group>"; };
CD470C4125DE056600AFBE0E /* BrowserViewController+WebKitDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "BrowserViewController+WebKitDelegate.swift"; sourceTree = "<group>"; }; CD470C4125DE056600AFBE0E /* BrowserViewController+WebKitDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "BrowserViewController+WebKitDelegate.swift"; sourceTree = "<group>"; };
CD470C4325DE070400AFBE0E /* BrowserViewController+Keyboard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "BrowserViewController+Keyboard.swift"; sourceTree = "<group>"; }; CD470C4325DE070400AFBE0E /* BrowserViewController+Keyboard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "BrowserViewController+Keyboard.swift"; sourceTree = "<group>"; };
@@ -355,6 +357,7 @@
1ADFF4C124CA6AE4006DC7AE /* Utilities */ = { 1ADFF4C124CA6AE4006DC7AE /* Utilities */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
CD16844C269E709400B8F8A5 /* Box.swift */,
1ADFF4C224CA6AF6006DC7AE /* Geometry.swift */, 1ADFF4C224CA6AF6006DC7AE /* Geometry.swift */,
CD7A8918251989C90075991E /* UIKeyCommand+ConvInit.swift */, CD7A8918251989C90075991E /* UIKeyCommand+ConvInit.swift */,
1ADFF4C624CA6DEB006DC7AE /* UIEdgeInsets+Layout.swift */, 1ADFF4C624CA6DEB006DC7AE /* UIEdgeInsets+Layout.swift */,
@@ -580,6 +583,7 @@
1AD3103D252541E600A4A952 /* PersonalRedirectRules.swift in Sources */, 1AD3103D252541E600A4A952 /* PersonalRedirectRules.swift in Sources */,
1AB88F0624D4D3A90006F850 /* UIGestureRecognizer+Actions.swift in Sources */, 1AB88F0624D4D3A90006F850 /* UIGestureRecognizer+Actions.swift in Sources */,
1ADFF46224C7DE53006DC7AE /* SceneDelegate.swift in Sources */, 1ADFF46224C7DE53006DC7AE /* SceneDelegate.swift in Sources */,
CD16844D269E709400B8F8A5 /* Box.swift in Sources */,
CD853BCE24E7763900D2BDCC /* BrowserHistory.swift in Sources */, CD853BCE24E7763900D2BDCC /* BrowserHistory.swift in Sources */,
1A03810B24E71C5600826501 /* ToolbarButtonContainerView.swift in Sources */, 1A03810B24E71C5600826501 /* ToolbarButtonContainerView.swift in Sources */,
CD7A7EA12686B2E600E20BA3 /* RedirectRulesSettingsViewController.swift in Sources */, CD7A7EA12686B2E600E20BA3 /* RedirectRulesSettingsViewController.swift in Sources */,