163 lines
5.9 KiB
Swift
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()
|
|
}
|
|
}
|