]> git.ipfire.org Git - thirdparty/wireguard-apple.git/commitdiff
on-demand: macOS: Integrate Ethernet and Wi-Fi controls in one row
authorRoopesh Chander <roop@roopc.net>
Sun, 17 Mar 2019 14:40:26 +0000 (20:10 +0530)
committerJason A. Donenfeld <Jason@zx2c4.com>
Mon, 18 Mar 2019 05:46:56 +0000 (06:46 +0100)
Signed-off-by: Roopesh Chander <roop@roopc.net>
WireGuard/WireGuard/UI/macOS/View/OnDemandWiFiControls.swift
WireGuard/WireGuard/UI/macOS/ViewController/TunnelEditViewController.swift

index 194075d430c47621b177e82c16bae7c4ee01110e..2e3de4811d568b13ea90a0d8e78bd9f15d22e4fd 100644 (file)
@@ -4,7 +4,27 @@
 import Cocoa
 import CoreWLAN
 
-class OnDemandWiFiControls: NSStackView {
+class OnDemandControlsRow: NSView {
+    let keyLabel: NSTextField = {
+        let keyLabel = NSTextField()
+        keyLabel.stringValue = tr("macFieldOnDemand")
+        keyLabel.isEditable = false
+        keyLabel.isSelectable = false
+        keyLabel.isBordered = false
+        keyLabel.alignment = .right
+        keyLabel.maximumNumberOfLines = 1
+        keyLabel.lineBreakMode = .byTruncatingTail
+        keyLabel.backgroundColor = .clear
+        return keyLabel
+    }()
+
+    let onDemandEthernetCheckbox: NSButton = {
+        let checkbox = NSButton()
+        checkbox.title = tr("tunnelOnDemandEthernet")
+        checkbox.setButtonType(.switch)
+        checkbox.state = .off
+        return checkbox
+    }()
 
     let onDemandWiFiCheckbox: NSButton = {
         let checkbox = NSButton()
@@ -23,20 +43,23 @@ class OnDemandWiFiControls: NSStackView {
     let onDemandSSIDsField: NSTokenField = {
         let tokenField = NSTokenField()
         tokenField.tokenizingCharacterSet = CharacterSet([])
+        tokenField.tokenStyle = .squared
         NSLayoutConstraint.activate([
-            tokenField.widthAnchor.constraint(greaterThanOrEqualToConstant: 150)
+            tokenField.widthAnchor.constraint(greaterThanOrEqualToConstant: 180)
         ])
         return tokenField
     }()
 
     override var intrinsicContentSize: NSSize {
         let minHeight: CGFloat = 22
-        let height = max(minHeight, onDemandWiFiCheckbox.intrinsicContentSize.height, onDemandSSIDOptionsPopup.intrinsicContentSize.height, onDemandSSIDsField.intrinsicContentSize.height)
+        let height = max(minHeight, keyLabel.intrinsicContentSize.height,
+                         onDemandEthernetCheckbox.intrinsicContentSize.height, onDemandWiFiCheckbox.intrinsicContentSize.height,
+                         onDemandSSIDOptionsPopup.intrinsicContentSize.height, onDemandSSIDsField.intrinsicContentSize.height)
         return NSSize(width: NSView.noIntrinsicMetric, height: height)
     }
 
     var onDemandViewModel: ActivateOnDemandViewModel? {
-        didSet { updateSSIDControls() }
+        didSet { updateControls() }
     }
 
     var currentSSIDs: [String]
@@ -44,16 +67,45 @@ class OnDemandWiFiControls: NSStackView {
     init() {
         currentSSIDs = getCurrentSSIDs()
         super.init(frame: CGRect.zero)
-        onDemandSSIDOptionsPopup.addItems(withTitles: OnDemandWiFiControls.onDemandSSIDOptions.map { $0.localizedUIString })
-        setViews([onDemandWiFiCheckbox, onDemandSSIDOptionsPopup, onDemandSSIDsField], in: .leading)
-        orientation = .horizontal
+
+        onDemandSSIDOptionsPopup.addItems(withTitles: OnDemandControlsRow.onDemandSSIDOptions.map { $0.localizedUIString })
+
+        let stackView = NSStackView()
+        stackView.setViews([onDemandEthernetCheckbox, onDemandWiFiCheckbox, onDemandSSIDOptionsPopup, onDemandSSIDsField], in: .leading)
+        stackView.orientation = .horizontal
+
+        addSubview(keyLabel)
+        addSubview(stackView)
+        keyLabel.translatesAutoresizingMaskIntoConstraints = false
+        stackView.translatesAutoresizingMaskIntoConstraints = false
 
         NSLayoutConstraint.activate([
-            onDemandWiFiCheckbox.centerYAnchor.constraint(equalTo: centerYAnchor),
-            onDemandSSIDOptionsPopup.lastBaselineAnchor.constraint(equalTo: onDemandWiFiCheckbox.lastBaselineAnchor),
-            onDemandSSIDsField.lastBaselineAnchor.constraint(equalTo: onDemandWiFiCheckbox.lastBaselineAnchor)
+            keyLabel.centerYAnchor.constraint(equalTo: self.centerYAnchor),
+            stackView.centerYAnchor.constraint(equalTo: self.centerYAnchor),
+            self.leadingAnchor.constraint(equalTo: keyLabel.leadingAnchor),
+            stackView.leadingAnchor.constraint(equalTo: keyLabel.trailingAnchor, constant: 5),
+            stackView.trailingAnchor.constraint(equalTo: self.trailingAnchor)
         ])
 
+        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
+
+        NSLayoutConstraint.activate([
+            onDemandEthernetCheckbox.centerYAnchor.constraint(equalTo: stackView.centerYAnchor),
+            onDemandWiFiCheckbox.lastBaselineAnchor.constraint(equalTo: onDemandEthernetCheckbox.lastBaselineAnchor),
+            onDemandSSIDOptionsPopup.lastBaselineAnchor.constraint(equalTo: onDemandEthernetCheckbox.lastBaselineAnchor),
+            onDemandSSIDsField.lastBaselineAnchor.constraint(equalTo: onDemandEthernetCheckbox.lastBaselineAnchor)
+        ])
+
+        onDemandSSIDsField.setContentHuggingPriority(.defaultLow, for: .horizontal)
+
+        onDemandEthernetCheckbox.target = self
+        onDemandEthernetCheckbox.action = #selector(ethernetCheckboxToggled)
+
         onDemandWiFiCheckbox.target = self
         onDemandWiFiCheckbox.action = #selector(wiFiCheckboxToggled)
 
@@ -62,7 +114,7 @@ class OnDemandWiFiControls: NSStackView {
 
         onDemandSSIDsField.delegate = self
 
-        updateSSIDControls()
+        updateControls()
     }
 
     required init?(coder decoder: NSCoder) {
@@ -71,38 +123,44 @@ class OnDemandWiFiControls: NSStackView {
 
     func saveToViewModel() {
         guard let onDemandViewModel = onDemandViewModel else { return }
+        onDemandViewModel.isNonWiFiInterfaceEnabled = onDemandEthernetCheckbox.state == .on
         onDemandViewModel.isWiFiInterfaceEnabled = onDemandWiFiCheckbox.state == .on
-        onDemandViewModel.ssidOption = OnDemandWiFiControls.onDemandSSIDOptions[onDemandSSIDOptionsPopup.indexOfSelectedItem]
+        onDemandViewModel.ssidOption = OnDemandControlsRow.onDemandSSIDOptions[onDemandSSIDOptionsPopup.indexOfSelectedItem]
         onDemandViewModel.selectedSSIDs = (onDemandSSIDsField.objectValue as? [String]) ?? []
     }
 
-    func updateSSIDControls() {
+    func updateControls() {
         guard let onDemandViewModel = onDemandViewModel else { return }
+        onDemandEthernetCheckbox.state = onDemandViewModel.isNonWiFiInterfaceEnabled ? .on : .off
         onDemandWiFiCheckbox.state = onDemandViewModel.isWiFiInterfaceEnabled ? .on : .off
-        let optionIndex = OnDemandWiFiControls.onDemandSSIDOptions.firstIndex(of: onDemandViewModel.ssidOption)
+        let optionIndex = OnDemandControlsRow.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 ethernetCheckboxToggled() {
+        onDemandViewModel?.isNonWiFiInterfaceEnabled = onDemandEthernetCheckbox.state == .on
+    }
+
     @objc func wiFiCheckboxToggled() {
         onDemandViewModel?.isWiFiInterfaceEnabled = onDemandWiFiCheckbox.state == .on
-        updateSSIDControls()
+        updateControls()
     }
 
     @objc func ssidOptionsPopupValueChanged() {
         let selectedIndex = onDemandSSIDOptionsPopup.indexOfSelectedItem
-        onDemandViewModel?.ssidOption = OnDemandWiFiControls.onDemandSSIDOptions[selectedIndex]
+        onDemandViewModel?.ssidOption = OnDemandControlsRow.onDemandSSIDOptions[selectedIndex]
         onDemandViewModel?.selectedSSIDs = (onDemandSSIDsField.objectValue as? [String]) ?? []
-        updateSSIDControls()
+        updateControls()
         if !onDemandSSIDsField.isHidden {
             onDemandSSIDsField.becomeFirstResponder()
         }
     }
 }
 
-extension OnDemandWiFiControls: NSTokenFieldDelegate {
+extension OnDemandControlsRow: NSTokenFieldDelegate {
     func tokenField(_ tokenField: NSTokenField, completionsForSubstring substring: String, indexOfToken tokenIndex: Int, indexOfSelectedItem selectedIndex: UnsafeMutablePointer<Int>?) -> [Any]? {
         return currentSSIDs.filter { $0.hasPrefix(substring) }
     }
index 51420c4b1ceaae2da3407bbef5a455d8ee944580..3d959cfbab4a047941aa4a1e16fa97c0236f2cc9 100644 (file)
@@ -42,15 +42,7 @@ class TunnelEditViewController: NSViewController {
         return textView
     }()
 
-    let onDemandEthernetCheckbox: NSButton = {
-        let checkbox = NSButton()
-        checkbox.title = tr("tunnelOnDemandEthernet")
-        checkbox.setButtonType(.switch)
-        checkbox.state = .off
-        return checkbox
-    }()
-
-    let onDemandWiFiControls = OnDemandWiFiControls()
+    let onDemandControlsRow = OnDemandControlsRow()
 
     let scrollView: NSScrollView = {
         let scrollView = NSScrollView()
@@ -147,20 +139,6 @@ class TunnelEditViewController: NSViewController {
     override func loadView() {
         populateFields()
 
-        let onDemandEthernetRow = ControlRow(controlView: onDemandEthernetCheckbox)
-        onDemandEthernetRow.key = tr("macFieldOnDemand")
-        onDemandEthernetCheckbox.state = onDemandViewModel.isNonWiFiInterfaceEnabled ? .on : .off
-
-        let onDemandWiFiRow = ControlRow(controlView: onDemandWiFiControls)
-        onDemandWiFiRow.key = ""
-        onDemandWiFiControls.onDemandViewModel = onDemandViewModel
-
-        NSLayoutConstraint.activate([
-            onDemandEthernetRow.keyLabel.firstBaselineAnchor.constraint(equalTo: onDemandEthernetRow.controlView.firstBaselineAnchor),
-            onDemandWiFiRow.controlView.centerYAnchor.constraint(equalTo: onDemandWiFiRow.centerYAnchor),
-            onDemandWiFiRow.trailingAnchor.constraint(equalTo: onDemandWiFiControls.trailingAnchor)
-        ])
-
         scrollView.documentView = textView
 
         saveButton.target = self
@@ -172,10 +150,12 @@ class TunnelEditViewController: NSViewController {
         excludePrivateIPsCheckbox.target = self
         excludePrivateIPsCheckbox.action = #selector(excludePrivateIPsCheckboxToggled(sender:))
 
+        onDemandControlsRow.onDemandViewModel = onDemandViewModel
+
         let margin: CGFloat = 20
         let internalSpacing: CGFloat = 10
 
-        let editorStackView = NSStackView(views: [nameRow, publicKeyRow, onDemandEthernetRow, onDemandWiFiRow, scrollView])
+        let editorStackView = NSStackView(views: [nameRow, publicKeyRow, onDemandControlsRow, scrollView])
         editorStackView.orientation = .vertical
         editorStackView.setHuggingPriority(.defaultHigh, for: .horizontal)
         editorStackView.spacing = internalSpacing
@@ -205,7 +185,7 @@ class TunnelEditViewController: NSViewController {
         view.window?.ignoresMouseEvents = !enabled
         nameRow.valueLabel.isEditable = enabled
         textView.isEditable = enabled
-        onDemandWiFiControls.onDemandSSIDsField.isEnabled = enabled
+        onDemandControlsRow.onDemandSSIDsField.isEnabled = enabled
     }
 
     @objc func handleSaveAction() {
@@ -215,8 +195,7 @@ class TunnelEditViewController: NSViewController {
             return
         }
 
-        onDemandViewModel.isNonWiFiInterfaceEnabled = onDemandEthernetCheckbox.state == .on
-        onDemandWiFiControls.saveToViewModel()
+        onDemandControlsRow.saveToViewModel()
         let onDemandOption = onDemandViewModel.toOnDemandOption()
 
         let isTunnelModifiedWithoutChangingName = (tunnel != nil && tunnel!.name == name)