aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoopesh Chander <roop@roopc.net>2019-01-06 18:51:06 +0530
committerRoopesh Chander <roop@roopc.net>2019-01-14 14:52:33 +0530
commitc2633987c3bc98c94981c599ac63e8a081ab605c (patch)
tree99f222c48ae28d1fdc8929c35e8d731bb897390a
parentmacOS: Rename *Cell to *Row (diff)
downloadwireguard-apple-c2633987c3bc98c94981c599ac63e8a081ab605c.tar.xz
wireguard-apple-c2633987c3bc98c94981c599ac63e8a081ab605c.zip
macOS: Tunnel edit view
Signed-off-by: Roopesh Chander <roop@roopc.net>
-rw-r--r--WireGuard/WireGuard.xcodeproj/project.pbxproj4
-rw-r--r--WireGuard/WireGuard/Base.lproj/Localizable.strings9
-rw-r--r--WireGuard/WireGuard/UI/macOS/View/KeyValueRow.swift23
-rw-r--r--WireGuard/WireGuard/UI/macOS/ViewController/TunnelDetailTableViewController.swift7
-rw-r--r--WireGuard/WireGuard/UI/macOS/ViewController/TunnelEditViewController.swift125
5 files changed, 159 insertions, 9 deletions
diff --git a/WireGuard/WireGuard.xcodeproj/project.pbxproj b/WireGuard/WireGuard.xcodeproj/project.pbxproj
index b132fdd..402fb29 100644
--- a/WireGuard/WireGuard.xcodeproj/project.pbxproj
+++ b/WireGuard/WireGuard.xcodeproj/project.pbxproj
@@ -119,6 +119,7 @@
6FBA104621D7EBFA0051C35F /* TunnelsListTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FBA104521D7EBFA0051C35F /* TunnelsListTableViewController.swift */; };
6FCD99AA21E0E14700BA4C82 /* NoTunnelsDetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FCD99A821E0E0C700BA4C82 /* NoTunnelsDetailViewController.swift */; };
6FCD99AF21E0EA1700BA4C82 /* ImportPanelPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FCD99AE21E0EA1700BA4C82 /* ImportPanelPresenter.swift */; };
+ 6FCD99B121E0EDA900BA4C82 /* TunnelEditViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FCD99B021E0EDA900BA4C82 /* TunnelEditViewController.swift */; };
6FDB3C3B21DCF47400A0C0BF /* TunnelDetailTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FDB3C3A21DCF47400A0C0BF /* TunnelDetailTableViewController.swift */; };
6FDB3C3C21DCF6BB00A0C0BF /* TunnelViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F628C3C217F09E9003482A3 /* TunnelViewModel.swift */; };
6FDEF7E421846C1A00D8FBF6 /* libwg-go.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6FDEF7E321846C1A00D8FBF6 /* libwg-go.a */; };
@@ -274,6 +275,7 @@
6FBA104521D7EBFA0051C35F /* TunnelsListTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelsListTableViewController.swift; sourceTree = "<group>"; };
6FCD99A821E0E0C700BA4C82 /* NoTunnelsDetailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoTunnelsDetailViewController.swift; sourceTree = "<group>"; };
6FCD99AE21E0EA1700BA4C82 /* ImportPanelPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImportPanelPresenter.swift; sourceTree = "<group>"; };
+ 6FCD99B021E0EDA900BA4C82 /* TunnelEditViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelEditViewController.swift; sourceTree = "<group>"; };
6FDB3C3A21DCF47400A0C0BF /* TunnelDetailTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelDetailTableViewController.swift; sourceTree = "<group>"; };
6FDEF7E321846C1A00D8FBF6 /* libwg-go.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = "libwg-go.a"; sourceTree = BUILT_PRODUCTS_DIR; };
6FDEF7E52185EFAF00D8FBF6 /* QRScanViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QRScanViewController.swift; sourceTree = "<group>"; };
@@ -512,6 +514,7 @@
6F4DD16D21DBEA0700690EAE /* ManageTunnelsRootViewController.swift */,
6FDB3C3A21DCF47400A0C0BF /* TunnelDetailTableViewController.swift */,
6FCD99A821E0E0C700BA4C82 /* NoTunnelsDetailViewController.swift */,
+ 6FCD99B021E0EDA900BA4C82 /* TunnelEditViewController.swift */,
);
path = ViewController;
sourceTree = "<group>";
@@ -1078,6 +1081,7 @@
6F4DD16C21DA558F00690EAE /* NSTableView+Reuse.swift in Sources */,
6FB1BDD821D50F5300A991BF /* WireGuardResult.swift in Sources */,
6FB1BDD921D50F5300A991BF /* LocalizationHelper.swift in Sources */,
+ 6FCD99B121E0EDA900BA4C82 /* TunnelEditViewController.swift in Sources */,
6FB1BDCA21D50F1700A991BF /* x25519.c in Sources */,
6FB1BDCB21D50F1700A991BF /* Curve25519.swift in Sources */,
6FB1BDBB21D50F0200A991BF /* Localizable.strings in Sources */,
diff --git a/WireGuard/WireGuard/Base.lproj/Localizable.strings b/WireGuard/WireGuard/Base.lproj/Localizable.strings
index ecbc087..8cae396 100644
--- a/WireGuard/WireGuard/Base.lproj/Localizable.strings
+++ b/WireGuard/WireGuard/Base.lproj/Localizable.strings
@@ -244,10 +244,15 @@
"macButtonImportTunnels" = "Import tunnel(s) from file";
-// Mac detail view fields
+// Mac detail/edit view fields
-"macDetailFieldKey (%@)" = "%@:";
+"macFieldKey (%@)" = "%@:";
// Mac status display
"macStatus (%@)" = "Status: %@";
+
+// Mac editing config
+
+"macEditDiscard" = "Discard";
+"macEditSave" = "Save";
diff --git a/WireGuard/WireGuard/UI/macOS/View/KeyValueRow.swift b/WireGuard/WireGuard/UI/macOS/View/KeyValueRow.swift
index 4e9fa7d..cdf682c 100644
--- a/WireGuard/WireGuard/UI/macOS/View/KeyValueRow.swift
+++ b/WireGuard/WireGuard/UI/macOS/View/KeyValueRow.swift
@@ -3,7 +3,7 @@
import Cocoa
-class KeyValueRow: NSView {
+class EditableKeyValueRow: NSView {
let keyLabel: NSTextField = {
let keyLabel = NSTextField()
keyLabel.isEditable = false
@@ -18,12 +18,9 @@ class KeyValueRow: NSView {
let valueLabel: NSTextField = {
let valueLabel = NSTextField()
- valueLabel.isEditable = false
valueLabel.isSelectable = true
- valueLabel.isBordered = false
valueLabel.maximumNumberOfLines = 1
valueLabel.lineBreakMode = .byTruncatingTail
- valueLabel.backgroundColor = .clear
return valueLabel
}()
@@ -46,6 +43,11 @@ class KeyValueRow: NSView {
}
}
+ override var intrinsicContentSize: NSSize {
+ let height = max(keyLabel.intrinsicContentSize.height, valueLabel.intrinsicContentSize.height)
+ return NSSize(width: NSView.noIntrinsicMetric, height: height)
+ }
+
init() {
super.init(frame: CGRect.zero)
@@ -74,3 +76,16 @@ class KeyValueRow: NSView {
isKeyInBold = false
}
}
+
+class KeyValueRow: EditableKeyValueRow {
+ override init() {
+ super.init()
+ valueLabel.isEditable = false
+ valueLabel.isBordered = false
+ valueLabel.backgroundColor = .clear
+ }
+
+ required init?(coder decoder: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
+}
diff --git a/WireGuard/WireGuard/UI/macOS/ViewController/TunnelDetailTableViewController.swift b/WireGuard/WireGuard/UI/macOS/ViewController/TunnelDetailTableViewController.swift
index 8e7db43..9e84e12 100644
--- a/WireGuard/WireGuard/UI/macOS/ViewController/TunnelDetailTableViewController.swift
+++ b/WireGuard/WireGuard/UI/macOS/ViewController/TunnelDetailTableViewController.swift
@@ -191,7 +191,8 @@ class TunnelDetailTableViewController: NSViewController {
}
@objc func editButtonClicked() {
- print("editButtonClicked")
+ let tunnelEditVC = TunnelEditViewController(tunnelsManager: tunnelsManager, tunnel: tunnel)
+ presentAsSheet(tunnelEditVC)
}
@objc func statusCheckboxToggled(sender: AnyObject?) {
@@ -217,14 +218,14 @@ extension TunnelDetailTableViewController: NSTableViewDelegate {
case .interfaceFieldRow(let field):
let cell: KeyValueRow = tableView.dequeueReusableCell()
let localizedKeyString = modelRow.isTitleRow() ? modelRow.localizedSectionKeyString() : field.localizedUIString
- cell.key = tr(format: "macDetailFieldKey (%@)", localizedKeyString)
+ cell.key = tr(format: "macFieldKey (%@)", localizedKeyString)
cell.value = tunnelViewModel.interfaceData[field]
cell.isKeyInBold = modelRow.isTitleRow()
return cell
case .peerFieldRow(let peerData, let field):
let cell: KeyValueRow = tableView.dequeueReusableCell()
let localizedKeyString = modelRow.isTitleRow() ? modelRow.localizedSectionKeyString() : field.localizedUIString
- cell.key = tr(format: "macDetailFieldKey (%@)", localizedKeyString)
+ cell.key = tr(format: "macFieldKey (%@)", localizedKeyString)
cell.value = peerData[field]
cell.isKeyInBold = modelRow.isTitleRow()
return cell
diff --git a/WireGuard/WireGuard/UI/macOS/ViewController/TunnelEditViewController.swift b/WireGuard/WireGuard/UI/macOS/ViewController/TunnelEditViewController.swift
new file mode 100644
index 0000000..52b80f6
--- /dev/null
+++ b/WireGuard/WireGuard/UI/macOS/ViewController/TunnelEditViewController.swift
@@ -0,0 +1,125 @@
+// SPDX-License-Identifier: MIT
+// Copyright © 2018 WireGuard LLC. All Rights Reserved.
+
+import Cocoa
+
+class TunnelEditViewController: NSViewController {
+
+ let nameRow: EditableKeyValueRow = {
+ let nameRow = EditableKeyValueRow()
+ nameRow.key = tr(format: "macFieldKey (%@)", TunnelViewModel.InterfaceField.name.localizedUIString)
+ return nameRow
+ }()
+
+ let publicKeyRow: KeyValueRow = {
+ let publicKeyRow = KeyValueRow()
+ publicKeyRow.key = tr(format: "macFieldKey (%@)", TunnelViewModel.InterfaceField.publicKey.localizedUIString)
+ return publicKeyRow
+ }()
+
+ let textView: NSTextView = {
+ let textView = NSTextView()
+ let minWidth: CGFloat = 120
+ let minHeight: CGFloat = 60
+ textView.minSize = NSSize(width: 0, height: minHeight)
+ textView.maxSize = NSSize(width: CGFloat.greatestFiniteMagnitude, height: CGFloat.greatestFiniteMagnitude)
+ textView.autoresizingMask = .width
+ textView.isHorizontallyResizable = true
+ if let textContainer = textView.textContainer {
+ textContainer.size = NSSize(width: minWidth, height: CGFloat.greatestFiniteMagnitude)
+ textContainer.widthTracksTextView = true
+ }
+ NSLayoutConstraint.activate([
+ textView.widthAnchor.constraint(greaterThanOrEqualToConstant: minWidth),
+ textView.heightAnchor.constraint(greaterThanOrEqualToConstant: minHeight)
+ ])
+ return textView
+ }()
+
+ let scrollView: NSScrollView = {
+ let scrollView = NSScrollView()
+ scrollView.hasVerticalScroller = true
+ scrollView.borderType = .bezelBorder
+ return scrollView
+ }()
+
+ let discardButton: NSButton = {
+ let button = NSButton()
+ button.title = tr("macEditDiscard")
+ button.setButtonType(.momentaryPushIn)
+ button.bezelStyle = .rounded
+ return button
+ }()
+
+ let saveButton: NSButton = {
+ let button = NSButton()
+ button.title = tr("macEditSave")
+ button.setButtonType(.momentaryPushIn)
+ button.bezelStyle = .rounded
+ return button
+ }()
+
+ let tunnelsManager: TunnelsManager
+ let tunnel: TunnelContainer?
+
+ init(tunnelsManager: TunnelsManager, tunnel: TunnelContainer?) {
+ self.tunnelsManager = tunnelsManager
+ self.tunnel = tunnel
+ super.init(nibName: nil, bundle: nil)
+ }
+
+ required init?(coder: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
+
+ override func loadView() {
+ if let tunnel = tunnel, let tunnelConfiguration = tunnel.tunnelConfiguration {
+ nameRow.value = tunnel.name
+ publicKeyRow.value = tunnelConfiguration.interface.publicKey.base64EncodedString()
+ textView.string = tunnelConfiguration.asWgQuickConfig()
+ }
+
+ scrollView.documentView = textView
+
+ saveButton.target = self
+ saveButton.action = #selector(saveButtonClicked)
+
+ discardButton.target = self
+ discardButton.action = #selector(discardButtonClicked)
+
+ let margin: CGFloat = 20
+ let internalSpacing: CGFloat = 10
+
+ let editorStackView = NSStackView(views: [nameRow, publicKeyRow, scrollView])
+ editorStackView.orientation = .vertical
+ editorStackView.setHuggingPriority(.defaultHigh, for: .horizontal)
+ editorStackView.spacing = internalSpacing
+
+ let buttonRowStackView = NSStackView()
+ buttonRowStackView.setViews([discardButton, saveButton], in: .trailing)
+ buttonRowStackView.orientation = .horizontal
+ buttonRowStackView.spacing = internalSpacing
+
+ let containerView = NSStackView(views: [editorStackView, buttonRowStackView])
+ containerView.orientation = .vertical
+ containerView.edgeInsets = NSEdgeInsets(top: margin, left: margin, bottom: margin, right: margin)
+ containerView.setHuggingPriority(.defaultHigh, for: .horizontal)
+ containerView.spacing = internalSpacing
+
+ NSLayoutConstraint.activate([
+ containerView.widthAnchor.constraint(greaterThanOrEqualToConstant: 180),
+ containerView.heightAnchor.constraint(greaterThanOrEqualToConstant: 240)
+ ])
+ containerView.frame = NSRect(x: 0, y: 0, width: 480, height: 320)
+
+ self.view = containerView
+ }
+
+ @objc func saveButtonClicked() {
+ print("saveButtonClicked")
+ }
+
+ @objc func discardButtonClicked() {
+ dismiss(self)
+ }
+}