ClashX.Meta/ClashX/ViewControllers/ExternalControlViewControll...

148 lines
6.0 KiB
Swift
Raw Normal View History

//
// ExternalControlViewController.swift
// ClashX Pro
//
// Created by on 2020/6/16.
// Copyright © 2020 west2online. All rights reserved.
//
import Cocoa
class ExternalControlViewController: NSViewController {
@IBOutlet var tableView: NSTableView!
@IBOutlet var addButton: NSButton!
@IBOutlet var deleteButton: NSButton!
override func viewDidLoad() {
super.viewDidLoad()
updateButtonStatus()
NSApp.activate(ignoringOtherApps: true)
}
func updateButtonStatus() {
let selectIdx = tableView.selectedRow
if selectIdx == -1 {
deleteButton.isEnabled = false
return
}
}
@IBAction func actionAdd(_ sender: Any) {
let alertView = NSAlert()
alertView.addButton(withTitle: NSLocalizedString("OK", comment: ""))
alertView.addButton(withTitle: NSLocalizedString("Cancel", comment: ""))
alertView.messageText = NSLocalizedString("Add a remote control config", comment: "")
let addView = ExternalControlAddView(frame: .zero)
alertView.accessoryView = addView
let response = alertView.runModal()
guard response == .alertFirstButtonReturn else { return }
guard addView.isVaild() else {
let alert = NSAlert()
alert.messageText = NSLocalizedString("Invalid input", comment: "")
alert.alertStyle = .warning
alert.runModal()
return
}
let model = RemoteControl(name: addView.nameField.stringValue, url: addView.urlTextField.stringValue, secret: addView.secretField.stringValue)
RemoteControlManager.configs.append(model)
tableView.reloadData()
}
@IBAction func actionDelete(_ sender: Any) {
RemoteControlManager.configs.safeRemove(at: tableView.selectedRow)
tableView.reloadData()
}
}
extension ExternalControlViewController: NSTableViewDataSource, NSTableViewDelegate {
func numberOfRows(in tableView: NSTableView) -> Int {
return RemoteControlManager.configs.count
}
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
guard let config = RemoteControlManager.configs[safe: row] else { return nil }
func setupCell(withIdentifier: String, string: String, textFieldtag: Int = 1) -> NSView? {
let cell = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: withIdentifier), owner: nil)
if let textField = cell?.viewWithTag(1) as? NSTextField {
textField.stringValue = string
} else {
assertionFailure()
}
return cell
}
switch tableColumn?.identifier.rawValue ?? "" {
case "url":
return setupCell(withIdentifier: "urlCell", string: config.url)
case "secret":
return setupCell(withIdentifier: "secretCell", string: config.secret)
case "name":
return setupCell(withIdentifier: "nameCell", string: config.name)
default: assertionFailure()
}
return nil
}
}
class ExternalControlAddView: NSView {
let urlTextField = NSTextField()
let secretField = NSTextField()
let nameField = NSTextField()
let urlLabel = NSTextField(labelWithString: "Api URL:")
let nameLabel = NSTextField(labelWithString: "Name:")
let secretLabel = NSTextField(labelWithString: "Secret:")
override init(frame frameRect: NSRect) {
super.init(frame: frameRect)
frame = NSRect(x: 0, y: 0, width: 300, height: 85)
setupView()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func setupView() {
addSubview(urlTextField)
addSubview(secretField)
addSubview(urlLabel)
addSubview(secretLabel)
addSubview(nameField)
addSubview(nameLabel)
urlTextField.translatesAutoresizingMaskIntoConstraints = false
secretField.translatesAutoresizingMaskIntoConstraints = false
urlLabel.translatesAutoresizingMaskIntoConstraints = false
secretLabel.translatesAutoresizingMaskIntoConstraints = false
nameField.translatesAutoresizingMaskIntoConstraints = false
nameLabel.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
secretField.trailingAnchor.constraint(equalTo: trailingAnchor),
urlTextField.trailingAnchor.constraint(equalTo: trailingAnchor),
nameField.trailingAnchor.constraint(equalTo: trailingAnchor),
urlTextField.topAnchor.constraint(equalTo: topAnchor),
urlTextField.leadingAnchor.constraint(equalTo: secretField.leadingAnchor),
urlTextField.bottomAnchor.constraint(equalTo: secretField.topAnchor, constant: -10),
nameField.topAnchor.constraint(equalTo: secretField.bottomAnchor, constant: 10),
urlLabel.centerYAnchor.constraint(equalTo: urlTextField.centerYAnchor),
secretLabel.centerYAnchor.constraint(equalTo: secretField.centerYAnchor),
urlTextField.leadingAnchor.constraint(equalTo: urlLabel.trailingAnchor, constant: 5),
secretField.leadingAnchor.constraint(equalTo: secretLabel.trailingAnchor, constant: 5),
urlLabel.leadingAnchor.constraint(greaterThanOrEqualTo: leadingAnchor, constant: 0),
secretLabel.leadingAnchor.constraint(greaterThanOrEqualTo: leadingAnchor, constant: 0),
urlTextField.widthAnchor.constraint(equalToConstant: 230),
nameField.leadingAnchor.constraint(equalTo: urlTextField.leadingAnchor),
nameLabel.centerYAnchor.constraint(equalTo: nameField.centerYAnchor),
nameLabel.leadingAnchor.constraint(greaterThanOrEqualTo: leadingAnchor),
nameField.leadingAnchor.constraint(equalTo: nameLabel.trailingAnchor, constant: 5),
])
}
func isVaild() -> Bool {
return urlTextField.stringValue.isUrlVaild() && nameLabel.stringValue.count > 0
}
}