Nicer toolbar buttons
This commit is contained in:
72
App/Common UI/GradientView.swift
Normal file
72
App/Common UI/GradientView.swift
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
//
|
||||||
|
// GradientView.swift
|
||||||
|
// App
|
||||||
|
//
|
||||||
|
// Created by James Magahern on 8/14/20.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
class GradientView: UIImageView
|
||||||
|
{
|
||||||
|
enum Direction {
|
||||||
|
case horizontal
|
||||||
|
case vertical
|
||||||
|
}
|
||||||
|
|
||||||
|
var direction: Direction = .horizontal {
|
||||||
|
didSet { image = nil; setNeedsLayout() }
|
||||||
|
}
|
||||||
|
|
||||||
|
var colors: [UIColor] = [] {
|
||||||
|
didSet { image = nil; setNeedsLayout() }
|
||||||
|
}
|
||||||
|
|
||||||
|
private var generatedImageSize: CGSize?
|
||||||
|
|
||||||
|
convenience init(direction: Direction, colors: [UIColor]) {
|
||||||
|
self.init(image: nil)
|
||||||
|
self.direction = direction
|
||||||
|
self.colors = colors
|
||||||
|
}
|
||||||
|
|
||||||
|
private func gradientImage(forSize size: CGSize) -> UIImage? {
|
||||||
|
var image: UIImage? = nil
|
||||||
|
|
||||||
|
UIGraphicsBeginImageContext(size)
|
||||||
|
if let context = UIGraphicsGetCurrentContext() {
|
||||||
|
let gradientColorsArray = self.colors.map { $0.cgColor }
|
||||||
|
|
||||||
|
if let gradient = CGGradient(colorsSpace: nil, colors: gradientColorsArray as CFArray, locations: nil) {
|
||||||
|
if direction == .horizontal {
|
||||||
|
context.drawLinearGradient(gradient, start: .zero, end: CGPoint(x: size.width, y: 0.0), options: CGGradientDrawingOptions())
|
||||||
|
} else if direction == .vertical {
|
||||||
|
context.drawLinearGradient(gradient, start: CGPoint(x: size.width / 2, y: 0), end: CGPoint(x: size.width / 2, y: size.height), options: CGGradientDrawingOptions())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
image = UIGraphicsGetImageFromCurrentImageContext()
|
||||||
|
UIGraphicsEndImageContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
return image
|
||||||
|
}
|
||||||
|
|
||||||
|
override func layoutSubviews() {
|
||||||
|
super.layoutSubviews()
|
||||||
|
|
||||||
|
var needsNewImage: Bool = image == nil
|
||||||
|
if let generatedImageSize = generatedImageSize {
|
||||||
|
if generatedImageSize != bounds.size {
|
||||||
|
needsNewImage = true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
needsNewImage = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if needsNewImage {
|
||||||
|
image = gradientImage(forSize: bounds.size)
|
||||||
|
generatedImageSize = bounds.size
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
130
App/Common UI/ReliefButton.swift
Normal file
130
App/Common UI/ReliefButton.swift
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
//
|
||||||
|
// ReliefButton.swift
|
||||||
|
// App
|
||||||
|
//
|
||||||
|
// Created by James Magahern on 8/14/20.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
class ReliefButton: UIButton
|
||||||
|
{
|
||||||
|
internal let shadowView = UIView(frame: .zero)
|
||||||
|
internal let backgroundView = GradientView(direction: .vertical, colors: ReliefButton.gradientColors(inverted: false, darkMode: false))
|
||||||
|
|
||||||
|
static let padding = CGFloat(24.0)
|
||||||
|
|
||||||
|
override var isHighlighted: Bool {
|
||||||
|
didSet {
|
||||||
|
setBackgroundInverted(isHighlighted)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
init() {
|
||||||
|
super.init(frame: .zero)
|
||||||
|
|
||||||
|
let cornerRadius = CGFloat(4.0)
|
||||||
|
|
||||||
|
self.tintColor = .init(dynamicProvider: { traitCollection -> UIColor in
|
||||||
|
if traitCollection.userInterfaceStyle == .light {
|
||||||
|
return .init(white: 0.15, alpha: 1.0)
|
||||||
|
} else {
|
||||||
|
return .white
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
shadowView.alpha = 0.28
|
||||||
|
shadowView.backgroundColor = UIColor(white: 0.0, alpha: 1.0)
|
||||||
|
shadowView.isUserInteractionEnabled = false
|
||||||
|
shadowView.layer.shadowColor = UIColor.black.cgColor
|
||||||
|
shadowView.layer.shadowOffset = CGSize(width: 0.0, height: 1.0)
|
||||||
|
shadowView.layer.shadowRadius = 1.0
|
||||||
|
shadowView.layer.shadowOpacity = 1.0
|
||||||
|
shadowView.layer.cornerRadius = cornerRadius
|
||||||
|
shadowView.layer.masksToBounds = false
|
||||||
|
shadowView.layer.shouldRasterize = true
|
||||||
|
shadowView.layer.rasterizationScale = UIScreen.main.scale
|
||||||
|
addSubview(shadowView)
|
||||||
|
|
||||||
|
backgroundView.layer.cornerRadius = cornerRadius
|
||||||
|
backgroundView.isUserInteractionEnabled = false
|
||||||
|
backgroundView.layer.masksToBounds = true
|
||||||
|
backgroundView.layer.borderWidth = 1.0
|
||||||
|
addSubview(backgroundView)
|
||||||
|
|
||||||
|
traitCollectionDidChange(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
required init?(coder: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
static func gradientColors(inverted: Bool, darkMode: Bool) -> [UIColor] {
|
||||||
|
if darkMode {
|
||||||
|
if !inverted {
|
||||||
|
return [
|
||||||
|
UIColor(white: 0.30, alpha: 1.0),
|
||||||
|
UIColor(white: 0.10, alpha: 1.0)
|
||||||
|
]
|
||||||
|
} else {
|
||||||
|
return [
|
||||||
|
UIColor(white: 0.10, alpha: 1.0),
|
||||||
|
UIColor(white: 0.30, alpha: 1.0)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if !inverted {
|
||||||
|
return [
|
||||||
|
UIColor(white: 0.98, alpha: 1.0),
|
||||||
|
UIColor(white: 0.93, alpha: 1.0)
|
||||||
|
]
|
||||||
|
} else {
|
||||||
|
return [
|
||||||
|
UIColor(white: 0.88, alpha: 1.0),
|
||||||
|
UIColor(white: 0.93, alpha: 1.0)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
|
||||||
|
setBackgroundInverted(isHighlighted)
|
||||||
|
backgroundView.layer.borderColor = { traitCollection -> UIColor in
|
||||||
|
if traitCollection.userInterfaceStyle == .dark {
|
||||||
|
return .init(white: 0.3, alpha: 1.0)
|
||||||
|
} else {
|
||||||
|
return .white
|
||||||
|
}
|
||||||
|
}(traitCollection).cgColor
|
||||||
|
}
|
||||||
|
|
||||||
|
internal func setBackgroundInverted(_ inverted: Bool) {
|
||||||
|
let darkMode: Bool = (traitCollection.userInterfaceStyle == .dark)
|
||||||
|
backgroundView.colors = Self.gradientColors(inverted: inverted, darkMode: darkMode)
|
||||||
|
}
|
||||||
|
|
||||||
|
override func imageRect(forContentRect contentRect: CGRect) -> CGRect {
|
||||||
|
let inset = CGFloat(7.0)
|
||||||
|
return contentRect.insetBy(dx: inset, dy: inset)
|
||||||
|
}
|
||||||
|
|
||||||
|
override func sizeThatFits(_ size: CGSize) -> CGSize {
|
||||||
|
let ourSize = super.sizeThatFits(size)
|
||||||
|
return CGSize(width: ourSize.width + Self.padding, height: ourSize.height)
|
||||||
|
}
|
||||||
|
|
||||||
|
override func layoutSubviews() {
|
||||||
|
self.imageView?.contentMode = .scaleAspectFit
|
||||||
|
|
||||||
|
super.layoutSubviews()
|
||||||
|
|
||||||
|
sendSubviewToBack(backgroundView)
|
||||||
|
sendSubviewToBack(shadowView)
|
||||||
|
|
||||||
|
let backgroundDimension = bounds.height - 1.0
|
||||||
|
backgroundView.frame = CGRect(origin: .zero, size: CGSize(width: backgroundDimension, height: backgroundDimension))
|
||||||
|
backgroundView.frame = backgroundView.frame.centeredX(inRect: bounds)
|
||||||
|
shadowView.frame = backgroundView.frame
|
||||||
|
}
|
||||||
|
}
|
||||||
57
App/Common UI/SegmentedReliefButton.swift
Normal file
57
App/Common UI/SegmentedReliefButton.swift
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
//
|
||||||
|
// SegmentedReliefButton.swift
|
||||||
|
// App
|
||||||
|
//
|
||||||
|
// Created by James Magahern on 8/14/20.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
class SegmentedReliefButton: ReliefButton
|
||||||
|
{
|
||||||
|
var children: [ReliefButton] = [] {
|
||||||
|
willSet { children.forEach { $0.removeFromSuperview() } }
|
||||||
|
didSet { children.forEach { addSubview($0) }; setNeedsLayout() }
|
||||||
|
}
|
||||||
|
|
||||||
|
init(children: [ReliefButton]) {
|
||||||
|
super.init()
|
||||||
|
self.children = children
|
||||||
|
}
|
||||||
|
|
||||||
|
override var isHighlighted: Bool {
|
||||||
|
didSet {}
|
||||||
|
}
|
||||||
|
|
||||||
|
required init?(coder: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
override func sizeThatFits(_ size: CGSize) -> CGSize {
|
||||||
|
let width: CGFloat = children.reduce(0.0) { (result, button) -> CGFloat in
|
||||||
|
return result + button.sizeThatFits(size).width
|
||||||
|
}
|
||||||
|
|
||||||
|
return CGSize(width: width, height: size.height)
|
||||||
|
}
|
||||||
|
|
||||||
|
override func layoutSubviews() {
|
||||||
|
super.layoutSubviews()
|
||||||
|
|
||||||
|
backgroundView.frame = bounds
|
||||||
|
shadowView.frame = bounds
|
||||||
|
|
||||||
|
var buttonRect = CGRect(origin: .zero, size: CGSize(width: 0, height: bounds.height))
|
||||||
|
for child in children {
|
||||||
|
child.shadowView.isHidden = true
|
||||||
|
child.backgroundView.layer.borderWidth = 0
|
||||||
|
bringSubviewToFront(child)
|
||||||
|
|
||||||
|
let childSize = child.sizeThatFits(bounds.size)
|
||||||
|
buttonRect.size = CGSize(width: childSize.width, height: bounds.height)
|
||||||
|
child.frame = buttonRect
|
||||||
|
|
||||||
|
buttonRect.origin.x += buttonRect.width
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -24,8 +24,10 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
|||||||
window.makeKeyAndVisible()
|
window.makeKeyAndVisible()
|
||||||
self.window = window
|
self.window = window
|
||||||
|
|
||||||
windowScene.titlebar?.titleVisibility = .hidden
|
#if targetEnvironment(macCatalyst)
|
||||||
windowScene.titlebar?.separatorStyle = .none
|
windowScene.titlebar?.titleVisibility = .hidden
|
||||||
|
windowScene.titlebar?.separatorStyle = .none
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
class ScriptControllerIconView: UIButton
|
class ScriptControllerIconView: ReliefButton
|
||||||
{
|
{
|
||||||
public var shieldsDown: Bool = false {
|
public var shieldsDown: Bool = false {
|
||||||
didSet { setNeedsLayout() }
|
didSet { setNeedsLayout() }
|
||||||
@@ -23,8 +23,9 @@ class ScriptControllerIconView: UIButton
|
|||||||
private let shieldsUpImage = UIImage(systemName: "shield")
|
private let shieldsUpImage = UIImage(systemName: "shield")
|
||||||
private let shieldsPartiallyUpImage = UIImage(systemName: "shield.lefthalf.fill")
|
private let shieldsPartiallyUpImage = UIImage(systemName: "shield.lefthalf.fill")
|
||||||
|
|
||||||
convenience init() {
|
|
||||||
self.init(frame: .zero)
|
override init() {
|
||||||
|
super.init()
|
||||||
|
|
||||||
addSubview(labelView)
|
addSubview(labelView)
|
||||||
|
|
||||||
@@ -39,6 +40,10 @@ class ScriptControllerIconView: UIButton
|
|||||||
setBlockedScriptsNumber(0)
|
setBlockedScriptsNumber(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
required init?(coder: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
|
||||||
public func setBlockedScriptsNumber(_ num: Int) {
|
public func setBlockedScriptsNumber(_ num: Int) {
|
||||||
if num > 0 {
|
if num > 0 {
|
||||||
labelView.isHidden = false
|
labelView.isHidden = false
|
||||||
|
|||||||
@@ -10,11 +10,14 @@ import UIKit
|
|||||||
class TitlebarView: UIView
|
class TitlebarView: UIView
|
||||||
{
|
{
|
||||||
private let titleLabelView = UILabel(frame: .zero)
|
private let titleLabelView = UILabel(frame: .zero)
|
||||||
private let backgroundImageView = UIImageView(frame: .zero)
|
private let backgroundView = GradientView(direction: .horizontal, colors: [
|
||||||
|
UIColor(red: 0.101, green: 0.176, blue: 0.415, alpha: 1.0),
|
||||||
|
UIColor(red: 0.153, green: 0.000, blue: 0.153, alpha: 1.0)
|
||||||
|
])
|
||||||
|
|
||||||
convenience init() {
|
convenience init() {
|
||||||
self.init(frame: .zero)
|
self.init(frame: .zero)
|
||||||
addSubview(backgroundImageView)
|
addSubview(backgroundView)
|
||||||
addSubview(titleLabelView)
|
addSubview(titleLabelView)
|
||||||
|
|
||||||
titleLabelView.textColor = .white
|
titleLabelView.textColor = .white
|
||||||
@@ -23,7 +26,7 @@ class TitlebarView: UIView
|
|||||||
titleLabelView.layer.shadowOffset = CGSize(width: 0.0, height: 2.0)
|
titleLabelView.layer.shadowOffset = CGSize(width: 0.0, height: 2.0)
|
||||||
titleLabelView.font = UIFont.boldSystemFont(ofSize: 12.0)
|
titleLabelView.font = UIFont.boldSystemFont(ofSize: 12.0)
|
||||||
|
|
||||||
backgroundImageView.alpha = 0.98
|
backgroundView.alpha = 0.98
|
||||||
}
|
}
|
||||||
|
|
||||||
func setTitle(_ title: String) {
|
func setTitle(_ title: String) {
|
||||||
@@ -49,37 +52,10 @@ class TitlebarView: UIView
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func backgroundImageForSize(_ size: CGSize) -> UIImage? {
|
|
||||||
var image: UIImage? = nil
|
|
||||||
|
|
||||||
UIGraphicsBeginImageContext(CGSize(width: size.width, height: 1.0))
|
|
||||||
if let context = UIGraphicsGetCurrentContext() {
|
|
||||||
let gradientColorsArray = [
|
|
||||||
UIColor(red: 0.101, green: 0.176, blue: 0.415, alpha: 1.0).cgColor,
|
|
||||||
UIColor(red: 0.153, green: 0.000, blue: 0.153, alpha: 1.0).cgColor
|
|
||||||
]
|
|
||||||
|
|
||||||
if let gradient = CGGradient(colorsSpace: nil, colors: gradientColorsArray as CFArray, locations: nil) {
|
|
||||||
context.drawLinearGradient(gradient, start: .zero, end: CGPoint(x: size.width, y: 0.0), options: CGGradientDrawingOptions())
|
|
||||||
}
|
|
||||||
|
|
||||||
image = UIGraphicsGetImageFromCurrentImageContext()
|
|
||||||
UIGraphicsEndImageContext();
|
|
||||||
}
|
|
||||||
|
|
||||||
return image
|
|
||||||
}
|
|
||||||
|
|
||||||
override func layoutSubviews() {
|
override func layoutSubviews() {
|
||||||
super.layoutSubviews()
|
super.layoutSubviews()
|
||||||
|
|
||||||
backgroundImageView.frame = bounds
|
backgroundView.frame = bounds
|
||||||
titleLabelView.frame = bounds.avoiding(verticalInsets: safeAreaInsets).insetBy(dx: 8.0 + layoutMargins.left, dy: 0.0)
|
titleLabelView.frame = bounds.avoiding(verticalInsets: safeAreaInsets).insetBy(dx: 8.0 + layoutMargins.left, dy: 0.0)
|
||||||
|
|
||||||
if let image = backgroundImageView.image, image.size == bounds.size {
|
|
||||||
// No op
|
|
||||||
} else {
|
|
||||||
backgroundImageView.image = backgroundImageForSize(bounds.size)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
47
App/Titlebar and URL Bar/ToolbarButtonContainerView.swift
Normal file
47
App/Titlebar and URL Bar/ToolbarButtonContainerView.swift
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
//
|
||||||
|
// ToolbarButtonContainerView.swift
|
||||||
|
// App
|
||||||
|
//
|
||||||
|
// Created by James Magahern on 8/14/20.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
class ToolbarButtonContainerView: UIView
|
||||||
|
{
|
||||||
|
private var buttonViews: [UIView] = []
|
||||||
|
|
||||||
|
public var numberOfButtonViews: Int { buttonViews.count }
|
||||||
|
|
||||||
|
func addButtonView(_ button: UIView) {
|
||||||
|
buttonViews.append(button)
|
||||||
|
addSubview(button)
|
||||||
|
setNeedsLayout()
|
||||||
|
}
|
||||||
|
|
||||||
|
func removeAllButtonViews() {
|
||||||
|
buttonViews.forEach { $0.removeFromSuperview() }
|
||||||
|
buttonViews.removeAll()
|
||||||
|
setNeedsLayout()
|
||||||
|
}
|
||||||
|
|
||||||
|
override func sizeThatFits(_ size: CGSize) -> CGSize {
|
||||||
|
let width: CGFloat = buttonViews.reduce(0.0) { (result, button) -> CGFloat in
|
||||||
|
return result + button.sizeThatFits(size).width
|
||||||
|
}
|
||||||
|
|
||||||
|
return CGSize(width: width, height: size.height)
|
||||||
|
}
|
||||||
|
|
||||||
|
override func layoutSubviews() {
|
||||||
|
var buttonRect = CGRect(origin: .zero, size: CGSize(width: 0, height: bounds.height))
|
||||||
|
|
||||||
|
for button in buttonViews {
|
||||||
|
let buttonSize = button.sizeThatFits(bounds.size)
|
||||||
|
buttonRect.size = CGSize(width: buttonSize.width, height: bounds.height)
|
||||||
|
button.frame = buttonRect
|
||||||
|
|
||||||
|
buttonRect.origin.x += buttonRect.width
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
115
App/Titlebar and URL Bar/ToolbarView.swift
Normal file
115
App/Titlebar and URL Bar/ToolbarView.swift
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
//
|
||||||
|
// ToolbarView.swift
|
||||||
|
// App
|
||||||
|
//
|
||||||
|
// Created by James Magahern on 8/14/20.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
class ToolbarView: UIView
|
||||||
|
{
|
||||||
|
var urlBar: URLBar? { didSet { containerView.addSubview(urlBar!) } }
|
||||||
|
|
||||||
|
var cancelButtonVisible: Bool = false { didSet { layoutSubviews() } }
|
||||||
|
|
||||||
|
let containerView = UIView(frame: .zero)
|
||||||
|
let backgroundView = UIVisualEffectView(effect: UIBlurEffect(style: .systemThickMaterial))
|
||||||
|
let cancelButton = UIButton(type: .system)
|
||||||
|
|
||||||
|
let leadingButtonsView = ToolbarButtonContainerView(frame: .zero)
|
||||||
|
let trailingButtonsView = ToolbarButtonContainerView(frame: .zero)
|
||||||
|
|
||||||
|
convenience init()
|
||||||
|
{
|
||||||
|
self.init(frame: .zero)
|
||||||
|
addSubview(backgroundView)
|
||||||
|
addSubview(containerView)
|
||||||
|
|
||||||
|
containerView.addSubview(leadingButtonsView)
|
||||||
|
containerView.addSubview(trailingButtonsView)
|
||||||
|
|
||||||
|
cancelButton.setTitle("Cancel", for: .normal)
|
||||||
|
containerView.addSubview(cancelButton)
|
||||||
|
|
||||||
|
layer.masksToBounds = false
|
||||||
|
layer.shadowColor = UIColor.black.cgColor
|
||||||
|
layer.shadowOpacity = 0.2
|
||||||
|
layer.shadowOffset = CGSize(width: 0.0, height: 1.0)
|
||||||
|
layer.shadowRadius = 1.5
|
||||||
|
}
|
||||||
|
|
||||||
|
override func sizeThatFits(_ size: CGSize) -> CGSize
|
||||||
|
{
|
||||||
|
return CGSize(width: size.width, height: 44.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
override func layoutSubviews()
|
||||||
|
{
|
||||||
|
super.layoutSubviews()
|
||||||
|
|
||||||
|
backgroundView.frame = bounds
|
||||||
|
|
||||||
|
var containerBounds = bounds
|
||||||
|
containerBounds.size.height -= safeAreaInsets.bottom
|
||||||
|
containerView.frame = containerBounds
|
||||||
|
containerView.frame = containerView.frame.insetBy(dx: 8.0, dy: 4.0)
|
||||||
|
|
||||||
|
let buttonContainerInset = UIEdgeInsets(top: 1.0, left: 0.0, bottom: 1.0, right: 0.0)
|
||||||
|
|
||||||
|
var urlBarPadding = CGFloat(8.0)
|
||||||
|
var urlBarInsets = UIEdgeInsets(top: 0.0, left: 0.0, bottom: 0.0, right: 0.0)
|
||||||
|
|
||||||
|
// Cancel button
|
||||||
|
var cancelButtonSize = cancelButton.sizeThatFits(containerView.bounds.size)
|
||||||
|
cancelButtonSize.width += (urlBarPadding * 2)
|
||||||
|
cancelButton.frame = CGRect(origin: CGPoint(x: (containerView.bounds.maxX - cancelButtonSize.width), y: 0),
|
||||||
|
size: CGSize(width: cancelButtonSize.width + urlBarPadding, height: containerView.bounds.height))
|
||||||
|
|
||||||
|
// Leading toolbar buttons
|
||||||
|
if leadingButtonsView.numberOfButtonViews > 0 {
|
||||||
|
let leadingContainerSize = leadingButtonsView.sizeThatFits(containerView.bounds.size)
|
||||||
|
leadingButtonsView.frame = CGRect(origin: .zero, size: leadingContainerSize).inset(by: buttonContainerInset)
|
||||||
|
urlBarInsets.left = urlBarPadding
|
||||||
|
} else {
|
||||||
|
leadingButtonsView.frame = .zero
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trailing toolbar buttons
|
||||||
|
let trailingContainerSize = trailingButtonsView.sizeThatFits(containerView.bounds.size)
|
||||||
|
trailingButtonsView.frame = CGRect(origin: CGPoint(x: (containerView.bounds.maxX - trailingContainerSize.width), y: 0), size: trailingContainerSize)
|
||||||
|
trailingButtonsView.frame = trailingButtonsView.frame.inset(by: buttonContainerInset)
|
||||||
|
urlBarInsets.right = urlBarPadding
|
||||||
|
|
||||||
|
var avoidingSize: CGSize = .zero
|
||||||
|
if cancelButtonVisible {
|
||||||
|
cancelButton.alpha = 1.0
|
||||||
|
trailingButtonsView.alpha = 0.0
|
||||||
|
|
||||||
|
avoidingSize = cancelButtonSize
|
||||||
|
} else {
|
||||||
|
cancelButton.alpha = 0.0
|
||||||
|
trailingButtonsView.alpha = 1.0
|
||||||
|
|
||||||
|
avoidingSize = trailingContainerSize
|
||||||
|
}
|
||||||
|
|
||||||
|
if let urlBar = urlBar {
|
||||||
|
let origin = CGPoint(
|
||||||
|
x: leadingButtonsView.frame.maxX,
|
||||||
|
y: 0.0
|
||||||
|
)
|
||||||
|
|
||||||
|
urlBar.frame = CGRect(
|
||||||
|
origin: origin,
|
||||||
|
size: CGSize(
|
||||||
|
width: containerView.bounds.width - avoidingSize.width - origin.x,
|
||||||
|
height: trailingContainerSize.height
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
urlBar.frame = urlBar.frame.inset(by: urlBarInsets)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -7,154 +7,20 @@
|
|||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
class ToolbarButtonView: UIView
|
|
||||||
{
|
|
||||||
private var buttonPadding = CGFloat(24.0)
|
|
||||||
private var buttonViews: [UIView] = []
|
|
||||||
|
|
||||||
public var numberOfButtonViews: Int { buttonViews.count }
|
|
||||||
|
|
||||||
func addButtonView(_ button: UIView) {
|
|
||||||
buttonViews.append(button)
|
|
||||||
addSubview(button)
|
|
||||||
setNeedsLayout()
|
|
||||||
}
|
|
||||||
|
|
||||||
func removeAllButtonViews() {
|
|
||||||
buttonViews.forEach { $0.removeFromSuperview() }
|
|
||||||
buttonViews.removeAll()
|
|
||||||
setNeedsLayout()
|
|
||||||
}
|
|
||||||
|
|
||||||
override func sizeThatFits(_ size: CGSize) -> CGSize {
|
|
||||||
let width: CGFloat = buttonViews.reduce(buttonPadding / 2.0) { (result, button) -> CGFloat in
|
|
||||||
return result + button.sizeThatFits(size).width + buttonPadding
|
|
||||||
}
|
|
||||||
|
|
||||||
return CGSize(width: width, height: size.height)
|
|
||||||
}
|
|
||||||
|
|
||||||
override func layoutSubviews() {
|
|
||||||
var buttonRect = CGRect(origin: .zero, size: CGSize(width: 0, height: bounds.height))
|
|
||||||
|
|
||||||
for button in buttonViews {
|
|
||||||
let buttonSize = button.sizeThatFits(bounds.size)
|
|
||||||
buttonRect.size = CGSize(width: buttonSize.width + buttonPadding, height: bounds.height)
|
|
||||||
button.frame = buttonRect
|
|
||||||
|
|
||||||
buttonRect.origin.x += buttonRect.width
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ToolbarView: UIView
|
|
||||||
{
|
|
||||||
var urlBar: URLBar? { didSet { containerView.addSubview(urlBar!) } }
|
|
||||||
|
|
||||||
var cancelButtonVisible: Bool = false { didSet { layoutSubviews() } }
|
|
||||||
|
|
||||||
let containerView = UIView(frame: .zero)
|
|
||||||
let backgroundView = UIVisualEffectView(effect: UIBlurEffect(style: .systemThickMaterial))
|
|
||||||
let cancelButton = UIButton(type: .system)
|
|
||||||
|
|
||||||
let leadingButtonsView = ToolbarButtonView(frame: .zero)
|
|
||||||
let trailingButtonsView = ToolbarButtonView(frame: .zero)
|
|
||||||
|
|
||||||
convenience init()
|
|
||||||
{
|
|
||||||
self.init(frame: .zero)
|
|
||||||
addSubview(backgroundView)
|
|
||||||
addSubview(containerView)
|
|
||||||
|
|
||||||
containerView.addSubview(leadingButtonsView)
|
|
||||||
containerView.addSubview(trailingButtonsView)
|
|
||||||
|
|
||||||
cancelButton.setTitle("Cancel", for: .normal)
|
|
||||||
containerView.addSubview(cancelButton)
|
|
||||||
|
|
||||||
layer.masksToBounds = false
|
|
||||||
layer.shadowColor = UIColor.black.cgColor
|
|
||||||
layer.shadowOpacity = 0.2
|
|
||||||
layer.shadowOffset = CGSize(width: 0.0, height: 1.0)
|
|
||||||
layer.shadowRadius = 1.5
|
|
||||||
}
|
|
||||||
|
|
||||||
override func sizeThatFits(_ size: CGSize) -> CGSize
|
|
||||||
{
|
|
||||||
return CGSize(width: size.width, height: 44.0)
|
|
||||||
}
|
|
||||||
|
|
||||||
override func layoutSubviews()
|
|
||||||
{
|
|
||||||
super.layoutSubviews()
|
|
||||||
|
|
||||||
backgroundView.frame = bounds
|
|
||||||
|
|
||||||
var containerBounds = bounds
|
|
||||||
containerBounds.size.height -= safeAreaInsets.bottom
|
|
||||||
containerView.frame = containerBounds
|
|
||||||
containerView.frame = containerView.frame.insetBy(dx: 8.0, dy: 4.0)
|
|
||||||
|
|
||||||
// Cancel button
|
|
||||||
let urlBarPadding: CGFloat = 8.0
|
|
||||||
var cancelButtonSize = cancelButton.sizeThatFits(containerView.bounds.size)
|
|
||||||
cancelButtonSize.width += (urlBarPadding * 2)
|
|
||||||
cancelButton.frame = CGRect(origin: CGPoint(x: (containerView.bounds.maxX - cancelButtonSize.width), y: 0),
|
|
||||||
size: CGSize(width: cancelButtonSize.width + urlBarPadding, height: containerView.bounds.height))
|
|
||||||
|
|
||||||
// Leading toolbar buttons
|
|
||||||
if leadingButtonsView.numberOfButtonViews > 0 {
|
|
||||||
let leadingContainerSize = leadingButtonsView.sizeThatFits(containerView.bounds.size)
|
|
||||||
leadingButtonsView.frame = CGRect(origin: .zero, size: leadingContainerSize)
|
|
||||||
} else {
|
|
||||||
leadingButtonsView.frame = .zero
|
|
||||||
}
|
|
||||||
|
|
||||||
// Trailing toolbar buttons
|
|
||||||
let trailingContainerSize = trailingButtonsView.sizeThatFits(containerView.bounds.size)
|
|
||||||
trailingButtonsView.frame = CGRect(origin: CGPoint(x: (containerView.bounds.maxX - trailingContainerSize.width) + urlBarPadding, y: 0), size: trailingContainerSize)
|
|
||||||
|
|
||||||
var avoidingSize: CGSize = .zero
|
|
||||||
if cancelButtonVisible {
|
|
||||||
cancelButton.alpha = 1.0
|
|
||||||
trailingButtonsView.alpha = 0.0
|
|
||||||
|
|
||||||
avoidingSize = cancelButtonSize
|
|
||||||
} else {
|
|
||||||
cancelButton.alpha = 0.0
|
|
||||||
trailingButtonsView.alpha = 1.0
|
|
||||||
|
|
||||||
avoidingSize = trailingContainerSize
|
|
||||||
}
|
|
||||||
|
|
||||||
if let urlBar = urlBar {
|
|
||||||
let origin = CGPoint(
|
|
||||||
x: leadingButtonsView.frame.maxX,
|
|
||||||
y: 0.0
|
|
||||||
)
|
|
||||||
|
|
||||||
urlBar.frame = CGRect(
|
|
||||||
origin: origin,
|
|
||||||
size: CGSize(
|
|
||||||
width: containerView.bounds.width - avoidingSize.width - origin.x,
|
|
||||||
height: containerView.bounds.height
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ToolbarViewController: UIViewController
|
class ToolbarViewController: UIViewController
|
||||||
{
|
{
|
||||||
let urlBar = URLBar()
|
let urlBar = URLBar()
|
||||||
let toolbarView = ToolbarView()
|
let toolbarView = ToolbarView()
|
||||||
let scriptControllerIconView = ScriptControllerIconView()
|
let scriptControllerIconView = ScriptControllerIconView()
|
||||||
let shareButton = UIButton(frame: .zero)
|
|
||||||
let darkModeButton = UIButton(frame: .zero)
|
let shareButton = ReliefButton()
|
||||||
let windowButton = UIButton(frame: .zero)
|
let darkModeButton = ReliefButton()
|
||||||
let backButton = UIButton(frame: .zero)
|
let windowButton = ReliefButton()
|
||||||
let forwardButton = UIButton(frame: .zero)
|
let newTabButton = ReliefButton()
|
||||||
let newTabButton = UIButton(frame: .zero)
|
|
||||||
|
let backButton = ReliefButton()
|
||||||
|
let forwardButton = ReliefButton()
|
||||||
|
let navigationSegmentedButton = SegmentedReliefButton(children: [])
|
||||||
|
|
||||||
var darkModeEnabled: Bool = false {
|
var darkModeEnabled: Bool = false {
|
||||||
didSet {
|
didSet {
|
||||||
@@ -189,6 +55,9 @@ class ToolbarViewController: UIViewController
|
|||||||
// Forward button
|
// Forward button
|
||||||
forwardButton.setImage(UIImage(systemName: "chevron.right"), for: .normal)
|
forwardButton.setImage(UIImage(systemName: "chevron.right"), for: .normal)
|
||||||
|
|
||||||
|
// Navigation control
|
||||||
|
navigationSegmentedButton.children = [ backButton, forwardButton ]
|
||||||
|
|
||||||
// New tab button
|
// New tab button
|
||||||
newTabButton.setImage(UIImage(systemName: "plus"), for: .normal)
|
newTabButton.setImage(UIImage(systemName: "plus"), for: .normal)
|
||||||
|
|
||||||
@@ -214,18 +83,27 @@ class ToolbarViewController: UIViewController
|
|||||||
toolbarView.leadingButtonsView.removeAllButtonViews()
|
toolbarView.leadingButtonsView.removeAllButtonViews()
|
||||||
toolbarView.trailingButtonsView.removeAllButtonViews()
|
toolbarView.trailingButtonsView.removeAllButtonViews()
|
||||||
|
|
||||||
|
let spacerView = { () -> SpacerView in
|
||||||
|
SpacerView(space: 24.0)
|
||||||
|
}
|
||||||
|
|
||||||
// Setup toolbar based on trait collection
|
// Setup toolbar based on trait collection
|
||||||
if traitCollection.horizontalSizeClass == .compact {
|
if traitCollection.horizontalSizeClass == .compact {
|
||||||
toolbarView.trailingButtonsView.addButtonView(darkModeButton)
|
toolbarView.trailingButtonsView.addButtonView(darkModeButton)
|
||||||
toolbarView.trailingButtonsView.addButtonView(scriptControllerIconView)
|
toolbarView.trailingButtonsView.addButtonView(scriptControllerIconView)
|
||||||
toolbarView.trailingButtonsView.addButtonView(windowButton)
|
toolbarView.trailingButtonsView.addButtonView(windowButton)
|
||||||
} else {
|
} else {
|
||||||
toolbarView.leadingButtonsView.addButtonView(backButton)
|
toolbarView.leadingButtonsView.addButtonView(navigationSegmentedButton)
|
||||||
toolbarView.leadingButtonsView.addButtonView(forwardButton)
|
toolbarView.leadingButtonsView.addButtonView(spacerView())
|
||||||
|
|
||||||
|
toolbarView.trailingButtonsView.addButtonView(shareButton)
|
||||||
|
toolbarView.trailingButtonsView.addButtonView(spacerView())
|
||||||
|
|
||||||
toolbarView.trailingButtonsView.addButtonView(darkModeButton)
|
toolbarView.trailingButtonsView.addButtonView(darkModeButton)
|
||||||
toolbarView.trailingButtonsView.addButtonView(shareButton)
|
|
||||||
toolbarView.trailingButtonsView.addButtonView(scriptControllerIconView)
|
toolbarView.trailingButtonsView.addButtonView(scriptControllerIconView)
|
||||||
|
|
||||||
|
toolbarView.trailingButtonsView.addButtonView(spacerView())
|
||||||
|
|
||||||
toolbarView.trailingButtonsView.addButtonView(newTabButton)
|
toolbarView.trailingButtonsView.addButtonView(newTabButton)
|
||||||
toolbarView.trailingButtonsView.addButtonView(windowButton)
|
toolbarView.trailingButtonsView.addButtonView(windowButton)
|
||||||
}
|
}
|
||||||
@@ -239,3 +117,16 @@ class ToolbarViewController: UIViewController
|
|||||||
fatalError("init(coder:) has not been implemented")
|
fatalError("init(coder:) has not been implemented")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class SpacerView: UIView {
|
||||||
|
internal var space: CGFloat = 0
|
||||||
|
|
||||||
|
convenience init(space: CGFloat) {
|
||||||
|
self.init(frame: .zero)
|
||||||
|
self.space = space
|
||||||
|
}
|
||||||
|
|
||||||
|
override func sizeThatFits(_ size: CGSize) -> CGSize {
|
||||||
|
CGSize(width: space, height: size.height)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ class URLBar: UIView
|
|||||||
}
|
}
|
||||||
|
|
||||||
private let backgroundView = UIVisualEffectView(effect: UIBlurEffect(style: .systemThickMaterial))
|
private let backgroundView = UIVisualEffectView(effect: UIBlurEffect(style: .systemThickMaterial))
|
||||||
|
private let shadowView = UIView(frame: .zero)
|
||||||
private let progressIndicatorView = ProgressIndicatorView()
|
private let progressIndicatorView = ProgressIndicatorView()
|
||||||
private let fadeMaskView = UIImageView(frame: .zero)
|
private let fadeMaskView = UIImageView(frame: .zero)
|
||||||
|
|
||||||
@@ -40,7 +41,7 @@ class URLBar: UIView
|
|||||||
backgroundView.layer.masksToBounds = true
|
backgroundView.layer.masksToBounds = true
|
||||||
backgroundView.layer.cornerRadius = backgroundCornerRadius
|
backgroundView.layer.cornerRadius = backgroundCornerRadius
|
||||||
backgroundView.layer.borderWidth = 1
|
backgroundView.layer.borderWidth = 1
|
||||||
backgroundView.layer.borderColor = UIColor.systemFill.cgColor
|
backgroundView.layer.borderColor = UIColor.secondarySystemFill.cgColor
|
||||||
backgroundView.isUserInteractionEnabled = false
|
backgroundView.isUserInteractionEnabled = false
|
||||||
addSubview(backgroundView)
|
addSubview(backgroundView)
|
||||||
|
|
||||||
@@ -166,6 +167,7 @@ class URLBar: UIView
|
|||||||
override func layoutSubviews() {
|
override func layoutSubviews() {
|
||||||
super.layoutSubviews()
|
super.layoutSubviews()
|
||||||
backgroundView.frame = bounds
|
backgroundView.frame = bounds
|
||||||
|
shadowView.frame = bounds
|
||||||
progressIndicatorView.frame = backgroundView.contentView.bounds
|
progressIndicatorView.frame = backgroundView.contentView.bounds
|
||||||
textField.frame = bounds.insetBy(dx: 6.0, dy: 0)
|
textField.frame = bounds.insetBy(dx: 6.0, dy: 0)
|
||||||
|
|
||||||
|
|||||||
@@ -29,4 +29,26 @@ extension CGRect
|
|||||||
|
|
||||||
return rect
|
return rect
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func centeredX(inRect: CGRect) -> CGRect {
|
||||||
|
var rect = self
|
||||||
|
rect.origin.x = CGRound((inRect.width - rect.width) / 2.0)
|
||||||
|
|
||||||
|
return rect
|
||||||
|
}
|
||||||
|
|
||||||
|
public func centered(inRect: CGRect) -> CGRect {
|
||||||
|
self.centeredX(inRect: inRect).centeredY(inRect: inRect)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension CGSize
|
||||||
|
{
|
||||||
|
public func extendingBy(dw: CGFloat, dh: CGFloat) -> CGSize {
|
||||||
|
var ourSize = self
|
||||||
|
ourSize.width += dw
|
||||||
|
ourSize.height += dh
|
||||||
|
|
||||||
|
return ourSize
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -7,6 +7,11 @@
|
|||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
|
1A03810B24E71C5600826501 /* ToolbarButtonContainerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A03810A24E71C5600826501 /* ToolbarButtonContainerView.swift */; };
|
||||||
|
1A03810D24E71CA700826501 /* ToolbarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A03810C24E71CA700826501 /* ToolbarView.swift */; };
|
||||||
|
1A03811024E71CF000826501 /* ReliefButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A03810F24E71CF000826501 /* ReliefButton.swift */; };
|
||||||
|
1A03811224E71EAA00826501 /* GradientView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A03811124E71EAA00826501 /* GradientView.swift */; };
|
||||||
|
1A03811424E73EB300826501 /* SegmentedReliefButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A03811324E73EB300826501 /* SegmentedReliefButton.swift */; };
|
||||||
1A14FC2324D203D9009B3F83 /* TitlebarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A14FC2224D203D9009B3F83 /* TitlebarView.swift */; };
|
1A14FC2324D203D9009B3F83 /* TitlebarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A14FC2224D203D9009B3F83 /* TitlebarView.swift */; };
|
||||||
1A14FC2624D251BD009B3F83 /* darkmode.css in Resources */ = {isa = PBXBuildFile; fileRef = 1A14FC2524D251BD009B3F83 /* darkmode.css */; };
|
1A14FC2624D251BD009B3F83 /* darkmode.css in Resources */ = {isa = PBXBuildFile; fileRef = 1A14FC2524D251BD009B3F83 /* darkmode.css */; };
|
||||||
1A14FC2824D26749009B3F83 /* Tab.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A14FC2724D26749009B3F83 /* Tab.swift */; };
|
1A14FC2824D26749009B3F83 /* Tab.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A14FC2724D26749009B3F83 /* Tab.swift */; };
|
||||||
@@ -25,7 +30,7 @@
|
|||||||
1ADFF4AA24C8D477006DC7AE /* SBRProcessPlugin.m in Sources */ = {isa = PBXBuildFile; fileRef = 1ADFF4A924C8D477006DC7AE /* SBRProcessPlugin.m */; };
|
1ADFF4AA24C8D477006DC7AE /* SBRProcessPlugin.m in Sources */ = {isa = PBXBuildFile; fileRef = 1ADFF4A924C8D477006DC7AE /* SBRProcessPlugin.m */; };
|
||||||
1ADFF4AE24C8ED32006DC7AE /* ResourcePolicyManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1ADFF4AD24C8ED32006DC7AE /* ResourcePolicyManager.swift */; };
|
1ADFF4AE24C8ED32006DC7AE /* ResourcePolicyManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1ADFF4AD24C8ED32006DC7AE /* ResourcePolicyManager.swift */; };
|
||||||
1ADFF4C024CA6964006DC7AE /* URLBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1ADFF4BF24CA6964006DC7AE /* URLBar.swift */; };
|
1ADFF4C024CA6964006DC7AE /* URLBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1ADFF4BF24CA6964006DC7AE /* URLBar.swift */; };
|
||||||
1ADFF4C324CA6AF6006DC7AE /* CGPoint+Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1ADFF4C224CA6AF6006DC7AE /* CGPoint+Utils.swift */; };
|
1ADFF4C324CA6AF6006DC7AE /* Geometry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1ADFF4C224CA6AF6006DC7AE /* Geometry.swift */; };
|
||||||
1ADFF4C724CA6DEB006DC7AE /* UIEdgeInsets+Layout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1ADFF4C624CA6DEB006DC7AE /* UIEdgeInsets+Layout.swift */; };
|
1ADFF4C724CA6DEB006DC7AE /* UIEdgeInsets+Layout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1ADFF4C624CA6DEB006DC7AE /* UIEdgeInsets+Layout.swift */; };
|
||||||
1ADFF4C924CA793E006DC7AE /* ToolbarViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1ADFF4C824CA793E006DC7AE /* ToolbarViewController.swift */; };
|
1ADFF4C924CA793E006DC7AE /* ToolbarViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1ADFF4C824CA793E006DC7AE /* ToolbarViewController.swift */; };
|
||||||
1ADFF4CB24CB8278006DC7AE /* ScriptControllerIconView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1ADFF4CA24CB8278006DC7AE /* ScriptControllerIconView.swift */; };
|
1ADFF4CB24CB8278006DC7AE /* ScriptControllerIconView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1ADFF4CA24CB8278006DC7AE /* ScriptControllerIconView.swift */; };
|
||||||
@@ -58,6 +63,11 @@
|
|||||||
/* End PBXCopyFilesBuildPhase section */
|
/* End PBXCopyFilesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
|
1A03810A24E71C5600826501 /* ToolbarButtonContainerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToolbarButtonContainerView.swift; sourceTree = "<group>"; };
|
||||||
|
1A03810C24E71CA700826501 /* ToolbarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToolbarView.swift; sourceTree = "<group>"; };
|
||||||
|
1A03810F24E71CF000826501 /* ReliefButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReliefButton.swift; sourceTree = "<group>"; };
|
||||||
|
1A03811124E71EAA00826501 /* GradientView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GradientView.swift; sourceTree = "<group>"; };
|
||||||
|
1A03811324E73EB300826501 /* SegmentedReliefButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SegmentedReliefButton.swift; sourceTree = "<group>"; };
|
||||||
1A14FC2224D203D9009B3F83 /* TitlebarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TitlebarView.swift; sourceTree = "<group>"; };
|
1A14FC2224D203D9009B3F83 /* TitlebarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TitlebarView.swift; sourceTree = "<group>"; };
|
||||||
1A14FC2524D251BD009B3F83 /* darkmode.css */ = {isa = PBXFileReference; lastKnownFileType = text.css; path = darkmode.css; sourceTree = "<group>"; };
|
1A14FC2524D251BD009B3F83 /* darkmode.css */ = {isa = PBXFileReference; lastKnownFileType = text.css; path = darkmode.css; sourceTree = "<group>"; };
|
||||||
1A14FC2724D26749009B3F83 /* Tab.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tab.swift; sourceTree = "<group>"; };
|
1A14FC2724D26749009B3F83 /* Tab.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tab.swift; sourceTree = "<group>"; };
|
||||||
@@ -85,7 +95,7 @@
|
|||||||
1ADFF4AC24C8DFEE006DC7AE /* SBRWebProcessProxy.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SBRWebProcessProxy.h; sourceTree = "<group>"; };
|
1ADFF4AC24C8DFEE006DC7AE /* SBRWebProcessProxy.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SBRWebProcessProxy.h; sourceTree = "<group>"; };
|
||||||
1ADFF4AD24C8ED32006DC7AE /* ResourcePolicyManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResourcePolicyManager.swift; sourceTree = "<group>"; };
|
1ADFF4AD24C8ED32006DC7AE /* ResourcePolicyManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResourcePolicyManager.swift; sourceTree = "<group>"; };
|
||||||
1ADFF4BF24CA6964006DC7AE /* URLBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLBar.swift; sourceTree = "<group>"; };
|
1ADFF4BF24CA6964006DC7AE /* URLBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLBar.swift; sourceTree = "<group>"; };
|
||||||
1ADFF4C224CA6AF6006DC7AE /* CGPoint+Utils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CGPoint+Utils.swift"; sourceTree = "<group>"; };
|
1ADFF4C224CA6AF6006DC7AE /* Geometry.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Geometry.swift; sourceTree = "<group>"; };
|
||||||
1ADFF4C624CA6DEB006DC7AE /* UIEdgeInsets+Layout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIEdgeInsets+Layout.swift"; sourceTree = "<group>"; };
|
1ADFF4C624CA6DEB006DC7AE /* UIEdgeInsets+Layout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIEdgeInsets+Layout.swift"; sourceTree = "<group>"; };
|
||||||
1ADFF4C824CA793E006DC7AE /* ToolbarViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToolbarViewController.swift; sourceTree = "<group>"; };
|
1ADFF4C824CA793E006DC7AE /* ToolbarViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToolbarViewController.swift; sourceTree = "<group>"; };
|
||||||
1ADFF4CA24CB8278006DC7AE /* ScriptControllerIconView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScriptControllerIconView.swift; sourceTree = "<group>"; };
|
1ADFF4CA24CB8278006DC7AE /* ScriptControllerIconView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScriptControllerIconView.swift; sourceTree = "<group>"; };
|
||||||
@@ -112,6 +122,16 @@
|
|||||||
/* End PBXFrameworksBuildPhase section */
|
/* End PBXFrameworksBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXGroup section */
|
/* Begin PBXGroup section */
|
||||||
|
1A03810E24E71CCA00826501 /* Common UI */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
1A03811124E71EAA00826501 /* GradientView.swift */,
|
||||||
|
1A03810F24E71CF000826501 /* ReliefButton.swift */,
|
||||||
|
1A03811324E73EB300826501 /* SegmentedReliefButton.swift */,
|
||||||
|
);
|
||||||
|
path = "Common UI";
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
1A14FC2424D2517A009B3F83 /* Resources */ = {
|
1A14FC2424D2517A009B3F83 /* Resources */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@@ -134,7 +154,9 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
1A14FC2224D203D9009B3F83 /* TitlebarView.swift */,
|
1A14FC2224D203D9009B3F83 /* TitlebarView.swift */,
|
||||||
|
1A03810C24E71CA700826501 /* ToolbarView.swift */,
|
||||||
1ADFF4C824CA793E006DC7AE /* ToolbarViewController.swift */,
|
1ADFF4C824CA793E006DC7AE /* ToolbarViewController.swift */,
|
||||||
|
1A03810A24E71C5600826501 /* ToolbarButtonContainerView.swift */,
|
||||||
1ADFF4BF24CA6964006DC7AE /* URLBar.swift */,
|
1ADFF4BF24CA6964006DC7AE /* URLBar.swift */,
|
||||||
);
|
);
|
||||||
path = "Titlebar and URL Bar";
|
path = "Titlebar and URL Bar";
|
||||||
@@ -166,6 +188,7 @@
|
|||||||
1ADFF46124C7DE53006DC7AE /* SceneDelegate.swift */,
|
1ADFF46124C7DE53006DC7AE /* SceneDelegate.swift */,
|
||||||
1ADFF47A24C7E176006DC7AE /* Backend */,
|
1ADFF47A24C7E176006DC7AE /* Backend */,
|
||||||
1ADFF47724C7DFE8006DC7AE /* Browser View */,
|
1ADFF47724C7DFE8006DC7AE /* Browser View */,
|
||||||
|
1A03810E24E71CCA00826501 /* Common UI */,
|
||||||
1ADFF4CE24CBBCBD006DC7AE /* Script Policy UI */,
|
1ADFF4CE24CBBCBD006DC7AE /* Script Policy UI */,
|
||||||
1AB88F0324D3E1EC0006F850 /* Tabs */,
|
1AB88F0324D3E1EC0006F850 /* Tabs */,
|
||||||
1AB88F0424D3E1F90006F850 /* Titlebar and URL Bar */,
|
1AB88F0424D3E1F90006F850 /* Titlebar and URL Bar */,
|
||||||
@@ -238,7 +261,7 @@
|
|||||||
1ADFF4C124CA6AE4006DC7AE /* Utilities */ = {
|
1ADFF4C124CA6AE4006DC7AE /* Utilities */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
1ADFF4C224CA6AF6006DC7AE /* CGPoint+Utils.swift */,
|
1ADFF4C224CA6AF6006DC7AE /* Geometry.swift */,
|
||||||
1ADFF4C624CA6DEB006DC7AE /* UIEdgeInsets+Layout.swift */,
|
1ADFF4C624CA6DEB006DC7AE /* UIEdgeInsets+Layout.swift */,
|
||||||
1AB88F0524D4D3A90006F850 /* UIGestureRecognizer+Actions.swift */,
|
1AB88F0524D4D3A90006F850 /* UIGestureRecognizer+Actions.swift */,
|
||||||
);
|
);
|
||||||
@@ -357,17 +380,22 @@
|
|||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
1ADFF46024C7DE53006DC7AE /* AppDelegate.swift in Sources */,
|
1ADFF46024C7DE53006DC7AE /* AppDelegate.swift in Sources */,
|
||||||
|
1A03811424E73EB300826501 /* SegmentedReliefButton.swift in Sources */,
|
||||||
|
1A03811024E71CF000826501 /* ReliefButton.swift in Sources */,
|
||||||
|
1A03811224E71EAA00826501 /* GradientView.swift in Sources */,
|
||||||
1ADFF4C024CA6964006DC7AE /* URLBar.swift in Sources */,
|
1ADFF4C024CA6964006DC7AE /* URLBar.swift in Sources */,
|
||||||
1ADFF4C724CA6DEB006DC7AE /* UIEdgeInsets+Layout.swift in Sources */,
|
1ADFF4C724CA6DEB006DC7AE /* UIEdgeInsets+Layout.swift in Sources */,
|
||||||
1ADFF4AE24C8ED32006DC7AE /* ResourcePolicyManager.swift in Sources */,
|
1ADFF4AE24C8ED32006DC7AE /* ResourcePolicyManager.swift in Sources */,
|
||||||
1ADFF47424C7DE9C006DC7AE /* BrowserViewController.swift in Sources */,
|
1ADFF47424C7DE9C006DC7AE /* BrowserViewController.swift in Sources */,
|
||||||
1ADFF4D024CBBCD1006DC7AE /* ScriptPolicyControl.swift in Sources */,
|
1ADFF4D024CBBCD1006DC7AE /* ScriptPolicyControl.swift in Sources */,
|
||||||
|
1A03810D24E71CA700826501 /* ToolbarView.swift in Sources */,
|
||||||
1ADFF48D24C8C176006DC7AE /* SBRProcessBundleBridge.m in Sources */,
|
1ADFF48D24C8C176006DC7AE /* SBRProcessBundleBridge.m in Sources */,
|
||||||
1AB88F0624D4D3A90006F850 /* UIGestureRecognizer+Actions.swift in Sources */,
|
1AB88F0624D4D3A90006F850 /* UIGestureRecognizer+Actions.swift in Sources */,
|
||||||
1ADFF46224C7DE53006DC7AE /* SceneDelegate.swift in Sources */,
|
1ADFF46224C7DE53006DC7AE /* SceneDelegate.swift in Sources */,
|
||||||
|
1A03810B24E71C5600826501 /* ToolbarButtonContainerView.swift in Sources */,
|
||||||
1ADFF4CB24CB8278006DC7AE /* ScriptControllerIconView.swift in Sources */,
|
1ADFF4CB24CB8278006DC7AE /* ScriptControllerIconView.swift in Sources */,
|
||||||
1AB88EFD24D3BA560006F850 /* TabController.swift in Sources */,
|
1AB88EFD24D3BA560006F850 /* TabController.swift in Sources */,
|
||||||
1ADFF4C324CA6AF6006DC7AE /* CGPoint+Utils.swift in Sources */,
|
1ADFF4C324CA6AF6006DC7AE /* Geometry.swift in Sources */,
|
||||||
1ADFF4C924CA793E006DC7AE /* ToolbarViewController.swift in Sources */,
|
1ADFF4C924CA793E006DC7AE /* ToolbarViewController.swift in Sources */,
|
||||||
1ADFF4CD24CBB0C8006DC7AE /* ScriptPolicyViewController.swift in Sources */,
|
1ADFF4CD24CBB0C8006DC7AE /* ScriptPolicyViewController.swift in Sources */,
|
||||||
1A14FC2824D26749009B3F83 /* Tab.swift in Sources */,
|
1A14FC2824D26749009B3F83 /* Tab.swift in Sources */,
|
||||||
|
|||||||
Reference in New Issue
Block a user