mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-22 00:17:32 +09:00
Dactyloidae iOS initial commit
This commit is contained in:
parent
daa6179d22
commit
7154a0497e
2123 changed files with 197052 additions and 0 deletions
315
mobile/ios/Client/Frontend/Browser/TabToolbar.swift
Normal file
315
mobile/ios/Client/Frontend/Browser/TabToolbar.swift
Normal file
|
|
@ -0,0 +1,315 @@
|
|||
/* 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
|
||||
import UIKit
|
||||
import SnapKit
|
||||
import Shared
|
||||
import XCGLogger
|
||||
|
||||
private let log = Logger.browserLogger
|
||||
|
||||
protocol TabToolbarProtocol: class {
|
||||
weak var tabToolbarDelegate: TabToolbarDelegate? { get set }
|
||||
var tabsButton: TabsButton { get }
|
||||
var menuButton: ToolbarButton { get }
|
||||
var forwardButton: ToolbarButton { get }
|
||||
var backButton: ToolbarButton { get }
|
||||
var stopReloadButton: ToolbarButton { get }
|
||||
var actionButtons: [Themeable & UIButton] { get }
|
||||
|
||||
func updateBackStatus(_ canGoBack: Bool)
|
||||
func updateForwardStatus(_ canGoForward: Bool)
|
||||
func updateReloadStatus(_ isLoading: Bool)
|
||||
func updatePageStatus(_ isWebPage: Bool)
|
||||
func updateTabCount(_ count: Int, animated: Bool)
|
||||
}
|
||||
|
||||
protocol TabToolbarDelegate: class {
|
||||
func tabToolbarDidPressBack(_ tabToolbar: TabToolbarProtocol, button: UIButton)
|
||||
func tabToolbarDidPressForward(_ tabToolbar: TabToolbarProtocol, button: UIButton)
|
||||
func tabToolbarDidLongPressBack(_ tabToolbar: TabToolbarProtocol, button: UIButton)
|
||||
func tabToolbarDidLongPressForward(_ tabToolbar: TabToolbarProtocol, button: UIButton)
|
||||
func tabToolbarDidPressReload(_ tabToolbar: TabToolbarProtocol, button: UIButton)
|
||||
func tabToolbarDidLongPressReload(_ tabToolbar: TabToolbarProtocol, button: UIButton)
|
||||
func tabToolbarDidPressStop(_ tabToolbar: TabToolbarProtocol, button: UIButton)
|
||||
func tabToolbarDidPressMenu(_ tabToolbar: TabToolbarProtocol, button: UIButton)
|
||||
func tabToolbarDidPressTabs(_ tabToolbar: TabToolbarProtocol, button: UIButton)
|
||||
func tabToolbarDidLongPressTabs(_ tabToolbar: TabToolbarProtocol, button: UIButton)
|
||||
}
|
||||
|
||||
@objc
|
||||
open class TabToolbarHelper: NSObject {
|
||||
let toolbar: TabToolbarProtocol
|
||||
|
||||
let ImageReload = UIImage.templateImageNamed("nav-refresh")
|
||||
let ImageStop = UIImage.templateImageNamed("nav-stop")
|
||||
|
||||
var loading: Bool = false {
|
||||
didSet {
|
||||
if loading {
|
||||
toolbar.stopReloadButton.setImage(ImageStop, for: .normal)
|
||||
toolbar.stopReloadButton.accessibilityLabel = NSLocalizedString("Stop", comment: "Accessibility Label for the tab toolbar Stop button")
|
||||
} else {
|
||||
toolbar.stopReloadButton.setImage(ImageReload, for: .normal)
|
||||
toolbar.stopReloadButton.accessibilityLabel = NSLocalizedString("Reload", comment: "Accessibility Label for the tab toolbar Reload button")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate func setTheme(theme: String, forButtons buttons: [Themeable]) {
|
||||
buttons.forEach { $0.applyTheme(theme) }
|
||||
}
|
||||
|
||||
init(toolbar: TabToolbarProtocol) {
|
||||
self.toolbar = toolbar
|
||||
super.init()
|
||||
|
||||
toolbar.backButton.setImage(UIImage.templateImageNamed("nav-back"), for: .normal)
|
||||
toolbar.backButton.accessibilityLabel = NSLocalizedString("Back", comment: "Accessibility label for the Back button in the tab toolbar.")
|
||||
let longPressGestureBackButton = UILongPressGestureRecognizer(target: self, action: #selector(TabToolbarHelper.SELdidLongPressBack(_:)))
|
||||
toolbar.backButton.addGestureRecognizer(longPressGestureBackButton)
|
||||
toolbar.backButton.addTarget(self, action: #selector(TabToolbarHelper.SELdidClickBack), for: UIControlEvents.touchUpInside)
|
||||
|
||||
toolbar.forwardButton.setImage(UIImage.templateImageNamed("nav-forward"), for: .normal)
|
||||
toolbar.forwardButton.accessibilityLabel = NSLocalizedString("Forward", comment: "Accessibility Label for the tab toolbar Forward button")
|
||||
let longPressGestureForwardButton = UILongPressGestureRecognizer(target: self, action: #selector(TabToolbarHelper.SELdidLongPressForward(_:)))
|
||||
toolbar.forwardButton.addGestureRecognizer(longPressGestureForwardButton)
|
||||
toolbar.forwardButton.addTarget(self, action: #selector(TabToolbarHelper.SELdidClickForward), for: UIControlEvents.touchUpInside)
|
||||
|
||||
toolbar.stopReloadButton.setImage(UIImage.templateImageNamed("nav-refresh"), for: .normal)
|
||||
toolbar.stopReloadButton.accessibilityLabel = NSLocalizedString("Reload", comment: "Accessibility Label for the tab toolbar Reload button")
|
||||
let longPressGestureStopReloadButton = UILongPressGestureRecognizer(target: self, action: #selector(TabToolbarHelper.SELdidLongPressStopReload(_:)))
|
||||
toolbar.stopReloadButton.addGestureRecognizer(longPressGestureStopReloadButton)
|
||||
toolbar.stopReloadButton.addTarget(self, action: #selector(TabToolbarHelper.SELdidClickStopReload), for: UIControlEvents.touchUpInside)
|
||||
|
||||
toolbar.tabsButton.addTarget(self, action: #selector(TabToolbarHelper.SELdidClickTabs), for: .touchUpInside)
|
||||
let longPressGestureTabsButton = UILongPressGestureRecognizer(target: self, action: #selector(TabToolbarHelper.SELdidLongPressTabs(_:)))
|
||||
toolbar.tabsButton.addGestureRecognizer(longPressGestureTabsButton)
|
||||
|
||||
toolbar.menuButton.contentMode = UIViewContentMode.center
|
||||
toolbar.menuButton.setImage(UIImage.templateImageNamed("nav-menu"), for: .normal)
|
||||
toolbar.menuButton.accessibilityLabel = Strings.AppMenuButtonAccessibilityLabel
|
||||
toolbar.menuButton.addTarget(self, action: #selector(TabToolbarHelper.SELdidClickMenu), for: UIControlEvents.touchUpInside)
|
||||
toolbar.menuButton.accessibilityIdentifier = "TabToolbar.menuButton"
|
||||
setTheme(theme: Theme.NormalMode, forButtons: toolbar.actionButtons)
|
||||
}
|
||||
|
||||
func SELdidClickBack() {
|
||||
toolbar.tabToolbarDelegate?.tabToolbarDidPressBack(toolbar, button: toolbar.backButton)
|
||||
}
|
||||
|
||||
func SELdidLongPressBack(_ recognizer: UILongPressGestureRecognizer) {
|
||||
if recognizer.state == UIGestureRecognizerState.began {
|
||||
toolbar.tabToolbarDelegate?.tabToolbarDidLongPressBack(toolbar, button: toolbar.backButton)
|
||||
}
|
||||
}
|
||||
|
||||
func SELdidClickTabs() {
|
||||
toolbar.tabToolbarDelegate?.tabToolbarDidPressTabs(toolbar, button: toolbar.tabsButton)
|
||||
}
|
||||
|
||||
func SELdidLongPressTabs(_ recognizer: UILongPressGestureRecognizer) {
|
||||
toolbar.tabToolbarDelegate?.tabToolbarDidLongPressTabs(toolbar, button: toolbar.tabsButton)
|
||||
}
|
||||
|
||||
func SELdidClickForward() {
|
||||
toolbar.tabToolbarDelegate?.tabToolbarDidPressForward(toolbar, button: toolbar.forwardButton)
|
||||
}
|
||||
|
||||
func SELdidLongPressForward(_ recognizer: UILongPressGestureRecognizer) {
|
||||
if recognizer.state == UIGestureRecognizerState.began {
|
||||
toolbar.tabToolbarDelegate?.tabToolbarDidLongPressForward(toolbar, button: toolbar.forwardButton)
|
||||
}
|
||||
}
|
||||
|
||||
func SELdidClickMenu() {
|
||||
toolbar.tabToolbarDelegate?.tabToolbarDidPressMenu(toolbar, button: toolbar.menuButton)
|
||||
}
|
||||
|
||||
func SELdidClickStopReload() {
|
||||
if loading {
|
||||
toolbar.tabToolbarDelegate?.tabToolbarDidPressStop(toolbar, button: toolbar.stopReloadButton)
|
||||
} else {
|
||||
toolbar.tabToolbarDelegate?.tabToolbarDidPressReload(toolbar, button: toolbar.stopReloadButton)
|
||||
}
|
||||
}
|
||||
|
||||
func SELdidLongPressStopReload(_ recognizer: UILongPressGestureRecognizer) {
|
||||
if recognizer.state == UIGestureRecognizerState.began && !loading {
|
||||
toolbar.tabToolbarDelegate?.tabToolbarDidLongPressReload(toolbar, button: toolbar.stopReloadButton)
|
||||
}
|
||||
}
|
||||
|
||||
func updateReloadStatus(_ isLoading: Bool) {
|
||||
loading = isLoading
|
||||
}
|
||||
}
|
||||
|
||||
class ToolbarButton: UIButton {
|
||||
static let Themes: [String: Theme] = {
|
||||
var themes = [String: Theme]()
|
||||
var theme = Theme()
|
||||
theme.buttonTintColor = UIColor(rgb: 0xd2d2d4)
|
||||
theme.highlightButtonColor = UIColor(rgb: 0xAC39FF)
|
||||
theme.disabledButtonColor = UIColor.gray
|
||||
themes[Theme.PrivateMode] = theme
|
||||
|
||||
theme = Theme()
|
||||
theme.buttonTintColor = UIColor(rgb: 0x272727)
|
||||
theme.highlightButtonColor = UIColor(rgb: 0x00A2FE)
|
||||
theme.disabledButtonColor = UIColor.lightGray
|
||||
themes[Theme.NormalMode] = theme
|
||||
|
||||
return themes
|
||||
}()
|
||||
|
||||
var selectedTintColor: UIColor!
|
||||
var unselectedTintColor: UIColor!
|
||||
var disabledTintColor: UIColor!
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
adjustsImageWhenHighlighted = false
|
||||
selectedTintColor = tintColor
|
||||
unselectedTintColor = tintColor
|
||||
disabledTintColor = UIColor.gray
|
||||
}
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
override open var isHighlighted: Bool {
|
||||
didSet {
|
||||
self.tintColor = isHighlighted ? selectedTintColor : unselectedTintColor
|
||||
}
|
||||
}
|
||||
|
||||
override open var isEnabled: Bool {
|
||||
didSet {
|
||||
self.tintColor = isEnabled ? unselectedTintColor : disabledTintColor
|
||||
}
|
||||
}
|
||||
|
||||
override var tintColor: UIColor! {
|
||||
didSet {
|
||||
self.imageView?.tintColor = self.tintColor
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension ToolbarButton: Themeable {
|
||||
func applyTheme(_ themeName: String) {
|
||||
guard let theme = ToolbarButton.Themes[themeName] else {
|
||||
log.error("Unable to apply unknown theme \(themeName)")
|
||||
return
|
||||
}
|
||||
selectedTintColor = theme.highlightButtonColor
|
||||
disabledTintColor = theme.disabledButtonColor
|
||||
unselectedTintColor = theme.buttonTintColor
|
||||
tintColor = isEnabled ? unselectedTintColor : disabledTintColor
|
||||
imageView?.tintColor = tintColor
|
||||
}
|
||||
}
|
||||
|
||||
class TabToolbar: Toolbar, TabToolbarProtocol {
|
||||
weak var tabToolbarDelegate: TabToolbarDelegate?
|
||||
|
||||
let tabsButton: TabsButton
|
||||
let menuButton: ToolbarButton
|
||||
let forwardButton: ToolbarButton
|
||||
let backButton: ToolbarButton
|
||||
let stopReloadButton: ToolbarButton
|
||||
let actionButtons: [Themeable & UIButton]
|
||||
|
||||
var helper: TabToolbarHelper?
|
||||
|
||||
static let Themes: [String: Theme] = {
|
||||
var themes = [String: Theme]()
|
||||
var theme = Theme()
|
||||
theme.backgroundColor = UIColor(rgb: 0x38383D)
|
||||
themes[Theme.PrivateMode] = theme
|
||||
|
||||
theme = Theme()
|
||||
theme.backgroundColor = UIConstants.AppBackgroundColor
|
||||
themes[Theme.NormalMode] = theme
|
||||
|
||||
return themes
|
||||
}()
|
||||
|
||||
// This has to be here since init() calls it
|
||||
fileprivate override init(frame: CGRect) {
|
||||
// And these have to be initialized in here or the compiler will get angry
|
||||
backButton = ToolbarButton()
|
||||
backButton.accessibilityIdentifier = "TabToolbar.backButton"
|
||||
forwardButton = ToolbarButton()
|
||||
forwardButton.accessibilityIdentifier = "TabToolbar.forwardButton"
|
||||
stopReloadButton = ToolbarButton()
|
||||
stopReloadButton.accessibilityIdentifier = "TabToolbar.stopReloadButton"
|
||||
tabsButton = TabsButton()
|
||||
tabsButton.accessibilityIdentifier = "TabToolbar.tabsButton"
|
||||
menuButton = ToolbarButton()
|
||||
menuButton.accessibilityIdentifier = "TabToolbar.menuButton"
|
||||
actionButtons = [backButton, forwardButton, stopReloadButton, tabsButton, menuButton]
|
||||
|
||||
super.init(frame: frame)
|
||||
|
||||
helper = TabToolbarHelper(toolbar: self)
|
||||
addButtons(actionButtons)
|
||||
|
||||
accessibilityNavigationStyle = .combined
|
||||
accessibilityLabel = NSLocalizedString("Navigation Toolbar", comment: "Accessibility label for the navigation toolbar displayed at the bottom of the screen.")
|
||||
}
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
func updateBackStatus(_ canGoBack: Bool) {
|
||||
backButton.isEnabled = canGoBack
|
||||
}
|
||||
|
||||
func updateForwardStatus(_ canGoForward: Bool) {
|
||||
forwardButton.isEnabled = canGoForward
|
||||
}
|
||||
|
||||
func updateReloadStatus(_ isLoading: Bool) {
|
||||
helper?.updateReloadStatus(isLoading)
|
||||
}
|
||||
|
||||
func updatePageStatus(_ isWebPage: Bool) {
|
||||
stopReloadButton.isEnabled = isWebPage
|
||||
}
|
||||
|
||||
func updateTabCount(_ count: Int, animated: Bool) {
|
||||
tabsButton.updateTabCount(count, animated: animated)
|
||||
}
|
||||
|
||||
override func draw(_ rect: CGRect) {
|
||||
if let context = UIGraphicsGetCurrentContext() {
|
||||
drawLine(context, start: CGPoint(x: 0, y: 0), end: CGPoint(x: frame.width, y: 0))
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate func drawLine(_ context: CGContext, start: CGPoint, end: CGPoint) {
|
||||
context.setStrokeColor(UIColor.black.withAlphaComponent(0.05).cgColor)
|
||||
context.setLineWidth(2)
|
||||
context.move(to: CGPoint(x: start.x, y: start.y))
|
||||
context.addLine(to: CGPoint(x: end.x, y: end.y))
|
||||
context.strokePath()
|
||||
}
|
||||
}
|
||||
|
||||
extension TabToolbar: Themeable {
|
||||
func applyTheme(_ themeName: String) {
|
||||
guard let theme = TabToolbar.Themes[themeName] else {
|
||||
log.error("Unable to apply unknown theme \(themeName)")
|
||||
return
|
||||
}
|
||||
backgroundColor = theme.backgroundColor!
|
||||
helper?.setTheme(theme: themeName, forButtons: actionButtons)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue