mirror of https://github.com/oxen-io/session-ios
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
215 lines
6.7 KiB
Swift
215 lines
6.7 KiB
Swift
// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved.
|
|
|
|
import UIKit
|
|
|
|
public final class SessionButton: UIButton {
|
|
public enum Style {
|
|
case bordered
|
|
case borderless
|
|
case destructive
|
|
case destructiveBorderless
|
|
case filled
|
|
}
|
|
|
|
public enum Size {
|
|
case small
|
|
case medium
|
|
case large
|
|
}
|
|
|
|
public struct Info: Equatable {
|
|
public let style: Style
|
|
public let title: String
|
|
public let isEnabled: Bool
|
|
public let accessibility: Accessibility?
|
|
public let minWidth: CGFloat
|
|
public let onTap: () -> ()
|
|
|
|
public init(
|
|
style: Style,
|
|
title: String,
|
|
isEnabled: Bool,
|
|
accessibility: Accessibility? = nil,
|
|
minWidth: CGFloat = 0,
|
|
onTap: @escaping () -> ()
|
|
) {
|
|
self.style = style
|
|
self.title = title
|
|
self.isEnabled = isEnabled
|
|
self.accessibility = accessibility
|
|
self.onTap = onTap
|
|
self.minWidth = minWidth
|
|
}
|
|
|
|
public static func == (lhs: SessionButton.Info, rhs: SessionButton.Info) -> Bool {
|
|
return (
|
|
lhs.style == rhs.style &&
|
|
lhs.title == rhs.title &&
|
|
lhs.isEnabled == rhs.isEnabled &&
|
|
lhs.accessibility == rhs.accessibility &&
|
|
lhs.minWidth == rhs.minWidth
|
|
)
|
|
}
|
|
}
|
|
|
|
private let style: Style
|
|
|
|
public override var isEnabled: Bool {
|
|
didSet {
|
|
guard isEnabled else {
|
|
setThemeTitleColor(
|
|
{
|
|
switch style {
|
|
case .bordered, .borderless, .destructive,
|
|
.destructiveBorderless:
|
|
return .disabled
|
|
|
|
case .filled: return .white
|
|
}
|
|
}(),
|
|
for: .normal
|
|
)
|
|
setThemeBackgroundColor(
|
|
{
|
|
switch style {
|
|
case .bordered, .borderless, .destructive,
|
|
.destructiveBorderless:
|
|
return .clear
|
|
|
|
case .filled: return .disabled
|
|
}
|
|
}(),
|
|
for: .normal
|
|
)
|
|
setThemeBackgroundColor(nil, for: .highlighted)
|
|
|
|
themeBorderColor = {
|
|
switch style {
|
|
case .bordered, .destructive: return .disabled
|
|
case .filled, .borderless, .destructiveBorderless: return nil
|
|
}
|
|
}()
|
|
return
|
|
}
|
|
|
|
// If we enable the button they just re-apply the existing style
|
|
setup(style: style)
|
|
}
|
|
}
|
|
|
|
// MARK: - Initialization
|
|
|
|
public init(style: Style, size: Size) {
|
|
self.style = style
|
|
|
|
super.init(frame: .zero)
|
|
|
|
setup(size: size)
|
|
setup(style: style)
|
|
}
|
|
|
|
override init(frame: CGRect) {
|
|
preconditionFailure("Use init(style:) instead.")
|
|
}
|
|
|
|
required init?(coder: NSCoder) {
|
|
preconditionFailure("Use init(style:) instead.")
|
|
}
|
|
|
|
private func setup(size: Size) {
|
|
clipsToBounds = true
|
|
let spacing: CGFloat = (size == .small ? Values.smallSpacing : Values.largeSpacing)
|
|
contentEdgeInsets = UIEdgeInsets(
|
|
top: 0,
|
|
left: spacing,
|
|
bottom: 0,
|
|
right: spacing
|
|
)
|
|
titleLabel?.font = .boldSystemFont(ofSize: (size == .small ?
|
|
Values.smallFontSize :
|
|
Values.mediumFontSize
|
|
))
|
|
|
|
let height: CGFloat = {
|
|
switch size {
|
|
case .small: return Values.smallButtonHeight
|
|
case .medium: return Values.mediumButtonHeight
|
|
case .large: return Values.largeButtonHeight
|
|
}
|
|
}()
|
|
set(.height, to: height)
|
|
layer.cornerRadius = {
|
|
switch style {
|
|
case .borderless, .destructiveBorderless: return 5
|
|
default: return (height / 2)
|
|
}
|
|
}()
|
|
}
|
|
|
|
private func setup(style: Style) {
|
|
setThemeTitleColor(
|
|
{
|
|
switch style {
|
|
case .bordered, .borderless: return .sessionButton_text
|
|
case .destructive, .destructiveBorderless: return .sessionButton_destructiveText
|
|
case .filled: return .sessionButton_filledText
|
|
}
|
|
}(),
|
|
for: .normal
|
|
)
|
|
setThemeTitleColor(
|
|
{
|
|
switch style {
|
|
case .borderless: return .highlighted(.sessionButton_text)
|
|
case .destructiveBorderless: return .highlighted(.sessionButton_destructiveText)
|
|
case .bordered, .destructive, .filled: return nil
|
|
}
|
|
}(),
|
|
for: .highlighted
|
|
)
|
|
|
|
setThemeBackgroundColor(
|
|
{
|
|
switch style {
|
|
case .bordered: return .sessionButton_background
|
|
case .destructive: return .sessionButton_destructiveBackground
|
|
case .borderless, .destructiveBorderless: return .clear
|
|
case .filled: return .sessionButton_filledBackground
|
|
}
|
|
}(),
|
|
for: .normal
|
|
)
|
|
setThemeBackgroundColor(
|
|
{
|
|
switch style {
|
|
case .bordered: return .sessionButton_highlight
|
|
case .destructive: return .sessionButton_destructiveHighlight
|
|
case .borderless, .destructiveBorderless: return nil
|
|
case .filled: return .sessionButton_filledHighlight
|
|
}
|
|
}(),
|
|
for: .highlighted
|
|
)
|
|
|
|
layer.borderWidth = {
|
|
switch style {
|
|
case .borderless, .destructiveBorderless: return 0
|
|
default: return 1
|
|
}
|
|
}()
|
|
themeBorderColor = {
|
|
switch style {
|
|
case .bordered: return .sessionButton_border
|
|
case .destructive: return .sessionButton_destructiveBorder
|
|
case .filled, .borderless, .destructiveBorderless: return nil
|
|
}
|
|
}()
|
|
}
|
|
|
|
// MARK: - Functions
|
|
|
|
public func setStyle(_ style: Style) {
|
|
setup(style: style)
|
|
}
|
|
}
|