blob: 2fe8556b6967018a72bf27f308aaa369da668053 [file] [log] [blame]
// Copyright 2018-present the Material Components for iOS authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import MDFTextAccessibility
import MaterialComponents.MaterialContainerScheme
import MaterialComponents.MaterialIcons_ic_check
import MaterialComponents.MaterialPalettes
import MaterialComponents.MaterialThemes
import UIKit
private func schemeWithPalette(_ palette: MDCPalette) -> MDCContainerScheming {
let containerScheme = DefaultContainerScheme()
let scheme = MDCSemanticColorScheme(defaults: .material201804)
scheme.primaryColor = palette.tint500
scheme.primaryColorVariant = palette.tint900
scheme.secondaryColor = scheme.primaryColor
if let onPrimaryColor = MDFTextAccessibility.textColor(fromChoices: [MDCPalette.grey.tint100,
MDCPalette.grey.tint900,
UIColor.black,
UIColor.white],
onBackgroundColor: scheme.primaryColor,
options: .preferLighter) {
scheme.onPrimaryColor = onPrimaryColor
}
if let onSecondaryColor = MDFTextAccessibility.textColor(fromChoices: [MDCPalette.grey.tint100,
MDCPalette.grey.tint900,
UIColor.black,
UIColor.white],
onBackgroundColor: scheme.secondaryColor,
options: .preferLighter) {
scheme.onSecondaryColor = onSecondaryColor
}
containerScheme.colorScheme = scheme
return containerScheme
}
private struct MDCColorThemeCellConfiguration {
let name: String
let mainColor: UIColor
let scheme: MDCContainerScheming
init(name: String, mainColor: UIColor, scheme: MDCContainerScheming) {
self.name = name
self.mainColor = mainColor
self.scheme = scheme
}
}
class MDCThemePickerViewController: UIViewController, UICollectionViewDataSource,
UICollectionViewDelegateFlowLayout {
let palettesCollectionView = UICollectionView(frame: .zero,
collectionViewLayout: UICollectionViewFlowLayout())
private var collectionViewLayout: UICollectionViewFlowLayout {
return palettesCollectionView.collectionViewLayout as! UICollectionViewFlowLayout
}
let titleColor = AppTheme.containerScheme.colorScheme.onSurfaceColor.withAlphaComponent(0.5)
let titleFont = AppTheme.containerScheme.typographyScheme.button
private let cellReuseIdentifier = "cell"
private let colorSchemeConfigurations = [
MDCColorThemeCellConfiguration(name: "Default",
mainColor: AppTheme.containerScheme.colorScheme.primaryColor,
scheme: DefaultContainerScheme()),
MDCColorThemeCellConfiguration(name: "Blue",
mainColor: MDCPalette.blue.tint500,
scheme: schemeWithPalette(MDCPalette.blue)),
MDCColorThemeCellConfiguration(name: "Red",
mainColor: MDCPalette.red.tint500,
scheme: schemeWithPalette(MDCPalette.red)),
MDCColorThemeCellConfiguration(name: "Green",
mainColor: MDCPalette.green.tint500,
scheme: schemeWithPalette(MDCPalette.green)),
MDCColorThemeCellConfiguration(name: "Amber",
mainColor: MDCPalette.amber.tint500,
scheme: schemeWithPalette(MDCPalette.amber)),
MDCColorThemeCellConfiguration(name: "Pink",
mainColor: MDCPalette.pink.tint500,
scheme: schemeWithPalette(MDCPalette.pink)),
MDCColorThemeCellConfiguration(name: "Orange",
mainColor: MDCPalette.orange.tint500,
scheme: schemeWithPalette(MDCPalette.orange)),
]
private let cellSize : CGFloat = 48.0 // minimum touch target
private let cellSpacing : CGFloat = 8.0
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
title = "Material Palette-based themes"
view.backgroundColor = .white
setUpCollectionView()
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
positionCollectionView()
}
func setUpCollectionView() {
palettesCollectionView.register(PaletteCell.self,
forCellWithReuseIdentifier: cellReuseIdentifier)
palettesCollectionView.translatesAutoresizingMaskIntoConstraints = false
palettesCollectionView.delegate = self
palettesCollectionView.dataSource = self
palettesCollectionView.backgroundColor = .white
view.addSubview(palettesCollectionView)
}
func positionCollectionView() {
var originX = view.bounds.origin.x
var width = view.bounds.size.width
var height = view.bounds.size.height
if #available(iOS 11.0, *) {
originX += view.safeAreaInsets.left;
width -= (view.safeAreaInsets.left + view.safeAreaInsets.right);
height -= (view.safeAreaInsets.top + view.safeAreaInsets.bottom);
}
let frame = CGRect(x: originX, y: view.bounds.origin.y, width: width, height: height)
palettesCollectionView.frame = frame
palettesCollectionView.collectionViewLayout.invalidateLayout()
}
func collectionView(_ collectionView: UICollectionView,
cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellReuseIdentifier,
for: indexPath) as! PaletteCell
cell.contentView.backgroundColor = colorSchemeConfigurations[indexPath.item].mainColor
cell.contentView.layer.cornerRadius = cellSize / 2
cell.contentView.layer.borderWidth = 1
cell.contentView.layer.borderColor =
AppTheme.containerScheme.colorScheme.onSurfaceColor.withAlphaComponent(0.05).cgColor
if AppTheme.containerScheme.colorScheme.primaryColor
== colorSchemeConfigurations[indexPath.item].mainColor {
cell.imageView.isHidden = false
cell.isSelected = true
} else {
cell.imageView.isHidden = true
cell.isSelected = false
}
cell.isAccessibilityElement = true
cell.accessibilityLabel = colorSchemeConfigurations[indexPath.row].name
cell.accessibilityHint = "Changes the catalog color theme."
return cell
}
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: cellSize, height: cellSize)
}
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
insetForSectionAt section: Int) -> UIEdgeInsets {
return UIEdgeInsets(top: cellSpacing,
left: cellSpacing,
bottom: cellSpacing,
right: cellSpacing)
}
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return cellSpacing
}
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return cellSpacing
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView,
numberOfItemsInSection section: Int) -> Int {
return colorSchemeConfigurations.count
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
navigationController?.popViewController(animated: true)
let scheme = colorSchemeConfigurations[indexPath.item].scheme
AppTheme.containerScheme = scheme
}
}
class PaletteCell : UICollectionViewCell {
let imageView = UIImageView()
override init(frame: CGRect) {
super.init(frame: frame)
imageView.image = MDCIcons.imageFor_ic_check()?.withRenderingMode(.alwaysTemplate)
imageView.tintColor = .white
imageView.contentMode = .center
self.contentView.addSubview(imageView)
}
override func layoutSubviews() {
imageView.frame = self.contentView.frame
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}