From fff75adfe1ada43a3b5ec9212f6220f192b25790 Mon Sep 17 00:00:00 2001 From: Roopesh Chander Date: Wed, 6 Mar 2019 15:30:42 +0530 Subject: on-demand: macOS: Support SSIDs in on demand activation Signed-off-by: Roopesh Chander --- WireGuard/WireGuard/UI/macOS/View/ControlRow.swift | 61 ++++++++++++++ .../UI/macOS/View/OnDemandWiFiControls.swift | 97 ++++++++++++++++++++++ 2 files changed, 158 insertions(+) create mode 100644 WireGuard/WireGuard/UI/macOS/View/ControlRow.swift create mode 100644 WireGuard/WireGuard/UI/macOS/View/OnDemandWiFiControls.swift (limited to 'WireGuard/WireGuard/UI/macOS/View') diff --git a/WireGuard/WireGuard/UI/macOS/View/ControlRow.swift b/WireGuard/WireGuard/UI/macOS/View/ControlRow.swift new file mode 100644 index 0000000..7759073 --- /dev/null +++ b/WireGuard/WireGuard/UI/macOS/View/ControlRow.swift @@ -0,0 +1,61 @@ +// SPDX-License-Identifier: MIT +// Copyright © 2018-2019 WireGuard LLC. All Rights Reserved. + +import Cocoa + +class ControlRow: NSView { + let keyLabel: NSTextField = { + let keyLabel = NSTextField() + keyLabel.isEditable = false + keyLabel.isSelectable = false + keyLabel.isBordered = false + keyLabel.alignment = .right + keyLabel.maximumNumberOfLines = 1 + keyLabel.lineBreakMode = .byTruncatingTail + keyLabel.backgroundColor = .clear + return keyLabel + }() + + var key: String { + get { return keyLabel.stringValue } + set(value) { keyLabel.stringValue = value } + } + + override var intrinsicContentSize: NSSize { + let height = max(keyLabel.intrinsicContentSize.height, controlView.intrinsicContentSize.height) + return NSSize(width: NSView.noIntrinsicMetric, height: height) + } + + let controlView: NSView + + init(controlView: NSView) { + self.controlView = controlView + super.init(frame: CGRect.zero) + + addSubview(keyLabel) + addSubview(controlView) + keyLabel.translatesAutoresizingMaskIntoConstraints = false + controlView.translatesAutoresizingMaskIntoConstraints = false + + NSLayoutConstraint.activate([ + keyLabel.centerYAnchor.constraint(equalTo: self.centerYAnchor), + self.leadingAnchor.constraint(equalTo: keyLabel.leadingAnchor), + keyLabel.trailingAnchor.constraint(equalTo: controlView.leadingAnchor, constant: -5) + ]) + + keyLabel.setContentCompressionResistancePriority(.defaultHigh + 2, for: .horizontal) + keyLabel.setContentHuggingPriority(.defaultHigh, for: .horizontal) + + let widthConstraint = keyLabel.widthAnchor.constraint(equalToConstant: 150) + widthConstraint.priority = .defaultHigh + 1 + widthConstraint.isActive = true + } + + required init?(coder decoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func prepareForReuse() { + key = "" + } +} diff --git a/WireGuard/WireGuard/UI/macOS/View/OnDemandWiFiControls.swift b/WireGuard/WireGuard/UI/macOS/View/OnDemandWiFiControls.swift new file mode 100644 index 0000000..bf0e52b --- /dev/null +++ b/WireGuard/WireGuard/UI/macOS/View/OnDemandWiFiControls.swift @@ -0,0 +1,97 @@ +// SPDX-License-Identifier: MIT +// Copyright © 2018-2019 WireGuard LLC. All Rights Reserved. + +import Cocoa + +class OnDemandWiFiControls: NSStackView { + + let onDemandWiFiCheckbox: NSButton = { + let checkbox = NSButton() + checkbox.title = tr("tunnelOnDemandWiFi") + checkbox.setButtonType(.switch) + checkbox.state = .off + return checkbox + }() + + static let onDemandSSIDOptions: [ActivateOnDemandViewModel.OnDemandSSIDOption] = [ + .anySSID, .onlySpecificSSIDs, .exceptSpecificSSIDs + ] + + let onDemandSSIDOptionsPopup = NSPopUpButton() + + let onDemandSSIDsField: NSTokenField = { + let tokenField = NSTokenField() + tokenField.tokenizingCharacterSet = CharacterSet([]) + NSLayoutConstraint.activate([ + tokenField.widthAnchor.constraint(greaterThanOrEqualToConstant: 150) + ]) + return tokenField + }() + + override var intrinsicContentSize: NSSize { + let minHeight: CGFloat = 22 + let height = max(minHeight, onDemandWiFiCheckbox.intrinsicContentSize.height, onDemandSSIDOptionsPopup.intrinsicContentSize.height, onDemandSSIDsField.intrinsicContentSize.height) + return NSSize(width: NSView.noIntrinsicMetric, height: height) + } + + var onDemandViewModel: ActivateOnDemandViewModel? { + didSet { updateSSIDControls() } + } + + init() { + super.init(frame: CGRect.zero) + onDemandSSIDOptionsPopup.addItems(withTitles: OnDemandWiFiControls.onDemandSSIDOptions.map { $0.localizedUIString }) + setViews([onDemandWiFiCheckbox, onDemandSSIDOptionsPopup, onDemandSSIDsField], in: .leading) + orientation = .horizontal + + NSLayoutConstraint.activate([ + onDemandWiFiCheckbox.centerYAnchor.constraint(equalTo: centerYAnchor), + onDemandSSIDOptionsPopup.lastBaselineAnchor.constraint(equalTo: onDemandWiFiCheckbox.lastBaselineAnchor), + onDemandSSIDsField.lastBaselineAnchor.constraint(equalTo: onDemandWiFiCheckbox.lastBaselineAnchor) + ]) + + onDemandWiFiCheckbox.target = self + onDemandWiFiCheckbox.action = #selector(wiFiCheckboxToggled) + + onDemandSSIDOptionsPopup.target = self + onDemandSSIDOptionsPopup.action = #selector(ssidOptionsPopupValueChanged) + + updateSSIDControls() + } + + required init?(coder decoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + func saveToViewModel() { + guard let onDemandViewModel = onDemandViewModel else { return } + onDemandViewModel.isWiFiInterfaceEnabled = onDemandWiFiCheckbox.state == .on + onDemandViewModel.ssidOption = OnDemandWiFiControls.onDemandSSIDOptions[onDemandSSIDOptionsPopup.indexOfSelectedItem] + onDemandViewModel.selectedSSIDs = (onDemandSSIDsField.objectValue as? [String]) ?? [] + } + + func updateSSIDControls() { + guard let onDemandViewModel = onDemandViewModel else { return } + onDemandWiFiCheckbox.state = onDemandViewModel.isWiFiInterfaceEnabled ? .on : .off + let optionIndex = OnDemandWiFiControls.onDemandSSIDOptions.firstIndex(of: onDemandViewModel.ssidOption) + onDemandSSIDOptionsPopup.selectItem(at: optionIndex ?? 0) + onDemandSSIDsField.objectValue = onDemandViewModel.selectedSSIDs + onDemandSSIDOptionsPopup.isHidden = !onDemandViewModel.isWiFiInterfaceEnabled + onDemandSSIDsField.isHidden = !onDemandViewModel.isWiFiInterfaceEnabled || onDemandViewModel.ssidOption == .anySSID + } + + @objc func wiFiCheckboxToggled() { + onDemandViewModel?.isWiFiInterfaceEnabled = onDemandWiFiCheckbox.state == .on + updateSSIDControls() + } + + @objc func ssidOptionsPopupValueChanged() { + let selectedIndex = onDemandSSIDOptionsPopup.indexOfSelectedItem + onDemandViewModel?.ssidOption = OnDemandWiFiControls.onDemandSSIDOptions[selectedIndex] + onDemandViewModel?.selectedSSIDs = (onDemandSSIDsField.objectValue as? [String]) ?? [] + updateSSIDControls() + if !onDemandSSIDsField.isHidden { + onDemandSSIDsField.becomeFirstResponder() + } + } +} -- cgit v1.2.3-59-g8ed1b