mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-22 08:27:31 +09:00
Dactyloidae iOS initial commit
This commit is contained in:
parent
daa6179d22
commit
7154a0497e
2123 changed files with 197052 additions and 0 deletions
258
mobile/ios/Client/Frontend/Browser/TopTabsViews.swift
Normal file
258
mobile/ios/Client/Frontend/Browser/TopTabsViews.swift
Normal file
|
|
@ -0,0 +1,258 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
import Foundation
|
||||
|
||||
struct TopTabsSeparatorUX {
|
||||
static let Identifier = "Separator"
|
||||
static let Color = UIColor(rgb: 0x3c3c3d)
|
||||
static let Width: CGFloat = 1
|
||||
}
|
||||
|
||||
class TopTabsSeparator: UICollectionReusableView {
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
self.backgroundColor = TopTabsSeparatorUX.Color
|
||||
}
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
}
|
||||
|
||||
class TopTabsHeaderFooter: UICollectionReusableView {
|
||||
let line = UIView()
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
addSubview(line)
|
||||
line.backgroundColor = TopTabsSeparatorUX.Color
|
||||
}
|
||||
|
||||
func arrangeLine(_ kind: String) {
|
||||
line.snp.removeConstraints()
|
||||
switch kind {
|
||||
case UICollectionElementKindSectionHeader:
|
||||
line.snp.makeConstraints { make in
|
||||
make.trailing.equalTo(self)
|
||||
}
|
||||
case UICollectionElementKindSectionFooter:
|
||||
line.snp.makeConstraints { make in
|
||||
make.leading.equalTo(self)
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
line.snp.makeConstraints { make in
|
||||
make.height.equalTo(TopTabsUX.SeparatorHeight)
|
||||
make.width.equalTo(TopTabsUX.SeparatorWidth)
|
||||
make.top.equalTo(self).offset(TopTabsUX.SeparatorYOffset)
|
||||
}
|
||||
}
|
||||
|
||||
override func apply(_ layoutAttributes: UICollectionViewLayoutAttributes) {
|
||||
layer.zPosition = CGFloat(layoutAttributes.zIndex)
|
||||
}
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
}
|
||||
|
||||
class TopTabCell: UICollectionViewCell {
|
||||
enum Style {
|
||||
case light
|
||||
case dark
|
||||
}
|
||||
|
||||
static let Identifier = "TopTabCellIdentifier"
|
||||
static let ShadowOffsetSize: CGFloat = 2 //The shadow is used to hide the tab separator
|
||||
|
||||
var style: Style = .light {
|
||||
didSet {
|
||||
if style != oldValue {
|
||||
applyStyle(style)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var selectedTab = false {
|
||||
didSet {
|
||||
backgroundColor = selectedTab ? UIColor(rgb: 0xf9f9fa) : UIColor(rgb: 0x272727)
|
||||
titleText.textColor = selectedTab ? UIColor(rgb: 0x0c0c0d) : UIColor(rgb: 0xb1b1b3)
|
||||
highlightLine.isHidden = !selectedTab
|
||||
closeButton.tintColor = selectedTab ? UIColor(rgb: 0x272727) : UIColor(rgb: 0xb1b1b3)
|
||||
// restyle if we are in PBM
|
||||
if style == .dark && selectedTab {
|
||||
backgroundColor = UIColor(rgb: 0x38383D)
|
||||
titleText.textColor = UIColor(rgb: 0xf9f9fa)
|
||||
closeButton.tintColor = UIColor(rgb: 0xf9f9fa)
|
||||
}
|
||||
closeButton.backgroundColor = backgroundColor
|
||||
closeButton.layer.shadowColor = backgroundColor?.cgColor
|
||||
if selectedTab {
|
||||
drawShadow()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let titleText: UILabel = {
|
||||
let titleText = UILabel()
|
||||
titleText.textAlignment = NSTextAlignment.left
|
||||
titleText.isUserInteractionEnabled = false
|
||||
titleText.numberOfLines = 1
|
||||
titleText.lineBreakMode = .byCharWrapping
|
||||
titleText.font = DynamicFontHelper.defaultHelper.DefaultSmallFont
|
||||
return titleText
|
||||
}()
|
||||
|
||||
let favicon: UIImageView = {
|
||||
let favicon = UIImageView()
|
||||
favicon.layer.cornerRadius = 2.0
|
||||
favicon.layer.masksToBounds = true
|
||||
return favicon
|
||||
}()
|
||||
|
||||
let closeButton: UIButton = {
|
||||
let closeButton = UIButton()
|
||||
closeButton.setImage(UIImage.templateImageNamed("menu-CloseTabs"), for: UIControlState())
|
||||
closeButton.tintColor = UIColor(rgb: 0xb1b1b3)
|
||||
closeButton.imageEdgeInsets = UIEdgeInsets(top: 15, left: TopTabsUX.TabTitlePadding, bottom: 15, right: TopTabsUX.TabTitlePadding)
|
||||
closeButton.layer.shadowOpacity = 0.8
|
||||
closeButton.layer.masksToBounds = false
|
||||
closeButton.layer.shadowOffset = CGSize(width: -TopTabsUX.TabTitlePadding, height: 0)
|
||||
return closeButton
|
||||
}()
|
||||
|
||||
let highlightLine: UIView = {
|
||||
let line = UIView()
|
||||
line.backgroundColor = UIColor(rgb: 0x0066DC)
|
||||
line.isHidden = true
|
||||
return line
|
||||
}()
|
||||
|
||||
weak var delegate: TopTabCellDelegate?
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
|
||||
closeButton.addTarget(self, action: #selector(TopTabCell.closeTab), for: UIControlEvents.touchUpInside)
|
||||
|
||||
contentView.addSubview(titleText)
|
||||
contentView.addSubview(closeButton)
|
||||
contentView.addSubview(favicon)
|
||||
contentView.addSubview(highlightLine)
|
||||
|
||||
favicon.snp.makeConstraints { make in
|
||||
make.centerY.equalTo(self).offset(TopTabsUX.TabNudge)
|
||||
make.size.equalTo(TabTrayControllerUX.FaviconSize)
|
||||
make.leading.equalTo(self).offset(TopTabsUX.TabTitlePadding)
|
||||
}
|
||||
titleText.snp.makeConstraints { make in
|
||||
make.centerY.equalTo(self)
|
||||
make.height.equalTo(self)
|
||||
make.trailing.equalTo(closeButton.snp.leading).offset(TopTabsUX.TabTitlePadding)
|
||||
make.leading.equalTo(favicon.snp.trailing).offset(TopTabsUX.TabTitlePadding)
|
||||
}
|
||||
closeButton.snp.makeConstraints { make in
|
||||
make.centerY.equalTo(self).offset(TopTabsUX.TabNudge)
|
||||
make.height.equalTo(self)
|
||||
make.width.equalTo(self.snp.height).offset(-TopTabsUX.TabTitlePadding)
|
||||
make.trailing.equalTo(self.snp.trailing)
|
||||
}
|
||||
highlightLine.snp.makeConstraints { make in
|
||||
make.top.equalTo(self)
|
||||
make.leading.equalTo(self).offset(-TopTabCell.ShadowOffsetSize)
|
||||
make.trailing.equalTo(self).offset(TopTabCell.ShadowOffsetSize)
|
||||
make.height.equalTo(TopTabsUX.HighlightLineWidth)
|
||||
}
|
||||
|
||||
self.clipsToBounds = false
|
||||
|
||||
applyStyle(style)
|
||||
}
|
||||
|
||||
fileprivate func applyStyle(_ style: Style) {
|
||||
switch style {
|
||||
case Style.light:
|
||||
titleText.textColor = UIColor.darkText
|
||||
backgroundColor = UIConstants.AppBackgroundColor
|
||||
highlightLine.backgroundColor = UIColor(rgb: 0x0066DC)
|
||||
case Style.dark:
|
||||
titleText.textColor = UIColor.lightText
|
||||
backgroundColor = UIColor(rgb: 0x38383D)
|
||||
highlightLine.backgroundColor = UIColor(rgb: 0x9400ff)
|
||||
}
|
||||
}
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
override func prepareForReuse() {
|
||||
super.prepareForReuse()
|
||||
self.layer.shadowOpacity = 0
|
||||
}
|
||||
|
||||
func closeTab() {
|
||||
delegate?.tabCellDidClose(self)
|
||||
}
|
||||
|
||||
// When a tab is selected the shadow prevents the tab separators from showing.
|
||||
func drawShadow() {
|
||||
self.layer.masksToBounds = false
|
||||
self.layer.shadowColor = backgroundColor?.cgColor
|
||||
self.layer.shadowOpacity = 1
|
||||
self.layer.shadowRadius = 0
|
||||
|
||||
self.layer.shadowPath = UIBezierPath(roundedRect: CGRect(x: 0, y: 0, width: self.frame.size.width + (TopTabCell.ShadowOffsetSize * 2), height: self.frame.size.height), cornerRadius: 0).cgPath
|
||||
self.layer.shadowOffset = CGSize(width: -TopTabCell.ShadowOffsetSize, height: 0)
|
||||
}
|
||||
|
||||
override func apply(_ layoutAttributes: UICollectionViewLayoutAttributes) {
|
||||
layer.zPosition = CGFloat(layoutAttributes.zIndex)
|
||||
}
|
||||
}
|
||||
|
||||
class TopTabFader: UIView {
|
||||
lazy var hMaskLayer: CAGradientLayer = {
|
||||
let innerColor: CGColor = UIColor(white: 1, alpha: 1.0).cgColor
|
||||
let outerColor: CGColor = UIColor(white: 1, alpha: 0.0).cgColor
|
||||
let hMaskLayer = CAGradientLayer()
|
||||
hMaskLayer.colors = [outerColor, innerColor, innerColor, outerColor]
|
||||
hMaskLayer.locations = [0.00, 0.005, 0.995, 1.0]
|
||||
hMaskLayer.startPoint = CGPoint(x: 0, y: 0.5)
|
||||
hMaskLayer.endPoint = CGPoint(x: 1.0, y: 0.5)
|
||||
hMaskLayer.anchorPoint = CGPoint.zero
|
||||
return hMaskLayer
|
||||
}()
|
||||
|
||||
init() {
|
||||
super.init(frame: CGRect.zero)
|
||||
layer.mask = hMaskLayer
|
||||
}
|
||||
|
||||
internal override func layoutSubviews() {
|
||||
super.layoutSubviews()
|
||||
|
||||
let widthA = NSNumber(value: Float(CGFloat(8) / frame.width))
|
||||
let widthB = NSNumber(value: Float(1 - CGFloat(8) / frame.width))
|
||||
|
||||
hMaskLayer.locations = [0.00, widthA, widthB, 1.0]
|
||||
hMaskLayer.frame = CGRect(x: 0, y: 0, width: frame.width, height: frame.height)
|
||||
}
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
}
|
||||
|
||||
class TopTabsViewLayoutAttributes: UICollectionViewLayoutAttributes {
|
||||
|
||||
override func isEqual(_ object: Any?) -> Bool {
|
||||
guard let object = object as? TopTabsViewLayoutAttributes else {
|
||||
return false
|
||||
}
|
||||
return super.isEqual(object)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue