Files

163 lines
5.9 KiB
Swift

//
// SideMenuController.swift
// PrivadoVPN
//
// Created by Murad Shabanov on 14.03.2022.
// Copyright © 2022 Privado LLC. All rights reserved.
//
import Foundation
protocol SideMenuControllerOutput: AnyObject {
func sideMenuBottomItem(at index: Int) -> SideMenuItem
func bottomItemscount() -> Int
func itemSelectedAt(index: Int)
}
protocol SideMenuControllerInput: AnyObject {
func reloadBottomItems()
}
final class SideMenuController: NSViewController, SideMenuControllerInput {
enum Constants {
static let columnIdentifier = NSUserInterfaceItemIdentifier("SideMenuItemList")
static let cellIdentifier = NSUserInterfaceItemIdentifier("SideMenuItemCell")
enum Image {
static let privado: String = "sidemenu-privado"
}
}
private var privadoLogoView: ImageView
private let privadoLogoSeparator: View
private let bottomItemsView: NSTableView
private let ouput: SideMenuControllerOutput
init(output: SideMenuControllerOutput) {
self.ouput = output
self.bottomItemsView = NSTableView()
self.privadoLogoView = ImageView(frame: .zero)
self.privadoLogoSeparator = View(frame: .zero)
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func loadView() {
let view = NSView(frame: .zero)
view.wantsLayer = true
view.translatesAutoresizingMaskIntoConstraints = false
view.layer?.backgroundColor = NSColor(red: 29, green: 33, blue: 91).cgColor
self.view = view
}
override func viewDidLoad() {
super.viewDidLoad()
self.configureUI()
self.layoutView()
}
override func viewDidAppear() {
if let superview = self.view.superview {
NSLayoutConstraint.activate([
self.view.leadingAnchor.constraint(equalTo: superview.leadingAnchor),
self.view.bottomAnchor.constraint(equalTo: superview.bottomAnchor),
self.view.heightAnchor.constraint(equalToConstant: 550),
self.view.widthAnchor.constraint(equalToConstant: 60)
])
}
}
private func configureUI() {
if let logoImage = NSImage(named: Constants.Image.privado) {
let logoView = ImageView(image: logoImage)
logoView.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(logoView)
self.privadoLogoView = logoView
}
self.privadoLogoSeparator.translatesAutoresizingMaskIntoConstraints = false
self.privadoLogoSeparator.viewBackgroundColor = NSColor(red: 130, green: 136, blue: 216)
self.view.addSubview(self.privadoLogoSeparator)
let column = NSTableColumn(identifier: Constants.columnIdentifier)
column.isEditable = false
self.bottomItemsView.addTableColumn(column)
self.bottomItemsView.translatesAutoresizingMaskIntoConstraints = false
self.bottomItemsView.selectionHighlightStyle = .none
self.bottomItemsView.backgroundColor = .clear
self.bottomItemsView.focusRingType = .none
self.bottomItemsView.rowSizeStyle = .custom
self.bottomItemsView.cornerView = NSView()
self.bottomItemsView.allowsMultipleSelection = false
self.bottomItemsView.delegate = self
self.bottomItemsView.dataSource = self
self.view.addSubview(self.bottomItemsView)
}
private func layoutView() {
NSLayoutConstraint.activate([
self.bottomItemsView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: -15),
self.bottomItemsView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor),
self.bottomItemsView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor),
self.privadoLogoView.widthAnchor.constraint(equalToConstant: 30),
self.privadoLogoView.heightAnchor.constraint(equalToConstant: 30),
self.privadoLogoView.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 20),
self.privadoLogoView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 15),
self.privadoLogoSeparator.topAnchor.constraint(equalTo: self.privadoLogoView.bottomAnchor, constant: 20),
self.privadoLogoSeparator.heightAnchor.constraint(equalToConstant: 1),
self.privadoLogoSeparator.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 10),
self.privadoLogoSeparator.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: -10)
])
}
func reloadBottomItems() {
self.bottomItemsView.reloadData()
}
}
extension SideMenuController: NSTableViewDelegate {
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
guard tableView.tableColumns[safe: 0] == tableColumn
, tableColumn.isExist else {
return nil
}
tableView.makeView(withIdentifier: Constants.cellIdentifier, owner: nil)
let item = self.ouput.sideMenuBottomItem(at: row)
let cell = BottomItemCell(frame: .zero)
cell.isHoverEnabled = true
cell.update(with: item.image, lineIsVisible: row != 0, type: item.type)
return cell
}
func tableViewSelectionDidChange(_ notification: Notification) {
let selectedRow = self.bottomItemsView.selectedRow
self.ouput.itemSelectedAt(index: selectedRow)
self.bottomItemsView.deselectRow(selectedRow)
}
func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat {
return 60
}
}
extension SideMenuController: NSTableViewDataSource {
func numberOfRows(in tableView: NSTableView) -> Int {
return self.ouput.bottomItemscount()
}
}