From 225c2b095b03e4b0383a99863349fc28b6a3f893 Mon Sep 17 00:00:00 2001 From: Grant Limberg Date: Sat, 14 May 2016 15:42:45 -0700 Subject: [PATCH] Initial start of the menu bar app. Has menu items to join/leave networks which currently displays an empty popover from the icon (icon needs to be made still) --- ZeroTier One.xcodeproj/project.pbxproj | 16 +++++ .../xcdebugger/Breakpoints_v2.xcbkptlist | 5 ++ ZeroTier One/AppDelegate.swift | 64 +++++++++++++++++- ZeroTier One/Assets.xcassets/Contents.json | 6 ++ .../MenuBarIconMac.imageset/Contents.json | 21 ++++++ .../MenuBarIconMac.png | Bin 0 -> 3810 bytes .../MenuBarIconMac@2x.png | Bin 0 -> 5444 bytes ZeroTier One/Base.lproj/MainMenu.xib | 11 +-- ZeroTier One/Info.plist | 2 + ZeroTier One/JoinNetworkViewController.swift | 18 +++++ ZeroTier One/JoinNetworkViewController.xib | 20 ++++++ ZeroTier One/ShowNetworksViewController.swift | 18 +++++ ZeroTier One/ShowNetworksViewController.xib | 20 ++++++ 13 files changed, 195 insertions(+), 6 deletions(-) create mode 100644 ZeroTier One.xcodeproj/xcuserdata/grant.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist create mode 100644 ZeroTier One/Assets.xcassets/Contents.json create mode 100644 ZeroTier One/Assets.xcassets/MenuBarIconMac.imageset/Contents.json create mode 100644 ZeroTier One/Assets.xcassets/MenuBarIconMac.imageset/MenuBarIconMac.png create mode 100644 ZeroTier One/Assets.xcassets/MenuBarIconMac.imageset/MenuBarIconMac@2x.png create mode 100644 ZeroTier One/JoinNetworkViewController.swift create mode 100644 ZeroTier One/JoinNetworkViewController.xib create mode 100644 ZeroTier One/ShowNetworksViewController.swift create mode 100644 ZeroTier One/ShowNetworksViewController.xib diff --git a/ZeroTier One.xcodeproj/project.pbxproj b/ZeroTier One.xcodeproj/project.pbxproj index 107870671..2730b9873 100644 --- a/ZeroTier One.xcodeproj/project.pbxproj +++ b/ZeroTier One.xcodeproj/project.pbxproj @@ -10,6 +10,10 @@ 93326BDC1CE7C816005CA2AC /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93326BDB1CE7C816005CA2AC /* AppDelegate.swift */; }; 93326BDE1CE7C816005CA2AC /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 93326BDD1CE7C816005CA2AC /* Assets.xcassets */; }; 93326BE11CE7C816005CA2AC /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 93326BDF1CE7C816005CA2AC /* MainMenu.xib */; }; + 93326BEA1CE7D9B9005CA2AC /* JoinNetworkViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93326BE81CE7D9B9005CA2AC /* JoinNetworkViewController.swift */; }; + 93326BEB1CE7D9B9005CA2AC /* JoinNetworkViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 93326BE91CE7D9B9005CA2AC /* JoinNetworkViewController.xib */; }; + 93326BEE1CE7DA30005CA2AC /* ShowNetworksViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93326BEC1CE7DA30005CA2AC /* ShowNetworksViewController.swift */; }; + 93326BEF1CE7DA30005CA2AC /* ShowNetworksViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 93326BED1CE7DA30005CA2AC /* ShowNetworksViewController.xib */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -18,6 +22,10 @@ 93326BDD1CE7C816005CA2AC /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 93326BE01CE7C816005CA2AC /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; 93326BE21CE7C816005CA2AC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 93326BE81CE7D9B9005CA2AC /* JoinNetworkViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JoinNetworkViewController.swift; sourceTree = ""; }; + 93326BE91CE7D9B9005CA2AC /* JoinNetworkViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = JoinNetworkViewController.xib; sourceTree = ""; }; + 93326BEC1CE7DA30005CA2AC /* ShowNetworksViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ShowNetworksViewController.swift; sourceTree = ""; }; + 93326BED1CE7DA30005CA2AC /* ShowNetworksViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ShowNetworksViewController.xib; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -51,9 +59,13 @@ isa = PBXGroup; children = ( 93326BDB1CE7C816005CA2AC /* AppDelegate.swift */, + 93326BE81CE7D9B9005CA2AC /* JoinNetworkViewController.swift */, + 93326BEC1CE7DA30005CA2AC /* ShowNetworksViewController.swift */, 93326BDD1CE7C816005CA2AC /* Assets.xcassets */, 93326BDF1CE7C816005CA2AC /* MainMenu.xib */, 93326BE21CE7C816005CA2AC /* Info.plist */, + 93326BE91CE7D9B9005CA2AC /* JoinNetworkViewController.xib */, + 93326BED1CE7DA30005CA2AC /* ShowNetworksViewController.xib */, ); path = "ZeroTier One"; sourceTree = ""; @@ -116,6 +128,8 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 93326BEF1CE7DA30005CA2AC /* ShowNetworksViewController.xib in Resources */, + 93326BEB1CE7D9B9005CA2AC /* JoinNetworkViewController.xib in Resources */, 93326BDE1CE7C816005CA2AC /* Assets.xcassets in Resources */, 93326BE11CE7C816005CA2AC /* MainMenu.xib in Resources */, ); @@ -129,6 +143,8 @@ buildActionMask = 2147483647; files = ( 93326BDC1CE7C816005CA2AC /* AppDelegate.swift in Sources */, + 93326BEA1CE7D9B9005CA2AC /* JoinNetworkViewController.swift in Sources */, + 93326BEE1CE7DA30005CA2AC /* ShowNetworksViewController.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/ZeroTier One.xcodeproj/xcuserdata/grant.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/ZeroTier One.xcodeproj/xcuserdata/grant.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist new file mode 100644 index 000000000..fe2b45415 --- /dev/null +++ b/ZeroTier One.xcodeproj/xcuserdata/grant.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -0,0 +1,5 @@ + + + diff --git a/ZeroTier One/AppDelegate.swift b/ZeroTier One/AppDelegate.swift index 6ac5a5c14..e5932f5f5 100644 --- a/ZeroTier One/AppDelegate.swift +++ b/ZeroTier One/AppDelegate.swift @@ -14,8 +14,34 @@ class AppDelegate: NSObject, NSApplicationDelegate { @IBOutlet weak var window: NSWindow! + let statusItem = NSStatusBar.systemStatusBar().statusItemWithLength(-2.0) + + let networkListPopover = NSPopover() + let joinNetworkPopover = NSPopover() + + var transientMonitor: AnyObject? = nil + func applicationDidFinishLaunching(aNotification: NSNotification) { - // Insert code here to initialize your application + + + statusItem.image = NSImage(named: "MenuBarIconMac") + + let menu = NSMenu() + + menu.addItem(NSMenuItem(title: "Show Networks", action: #selector(AppDelegate.showNetworks), keyEquivalent: "n")) + menu.addItem(NSMenuItem(title: "Join Network", action: #selector(AppDelegate.joinNetwork), keyEquivalent: "j")) + menu.addItem(NSMenuItem.separatorItem()) + menu.addItem(NSMenuItem(title: "Quit ZeroTier One", action: #selector(AppDelegate.quit), keyEquivalent: "q")) + + statusItem.menu = menu + + joinNetworkPopover.contentViewController = JoinNetworkViewController( + nibName: "JoinNetworkViewController", bundle: nil) + joinNetworkPopover.behavior = .Transient + + networkListPopover.contentViewController = ShowNetworksViewController( + nibName: "ShowNetworksViewController", bundle: nil) + networkListPopover.behavior = .Transient } func applicationWillTerminate(aNotification: NSNotification) { @@ -23,5 +49,41 @@ class AppDelegate: NSObject, NSApplicationDelegate { } + func showNetworks() { + if let button = statusItem.button { + networkListPopover.showRelativeToRect(button.bounds, ofView: button, preferredEdge: .MinY) + + if transientMonitor == nil { + transientMonitor = NSEvent.addGlobalMonitorForEventsMatchingMask( + [.LeftMouseDownMask, .RightMouseDownMask, .OtherMouseDownMask]) { (event: NSEvent) -> Void in + + NSEvent.removeMonitor(self.transientMonitor!) + self.transientMonitor = nil + self.networkListPopover.close() + } + } + } + } + + func joinNetwork() { + if let button = statusItem.button { + joinNetworkPopover.showRelativeToRect(button.bounds, ofView: button, preferredEdge: .MinY) + + if transientMonitor == nil { + transientMonitor = NSEvent.addGlobalMonitorForEventsMatchingMask( + [.LeftMouseDownMask, .RightMouseDownMask, .OtherMouseDownMask]) { (event: NSEvent) -> Void in + + NSEvent.removeMonitor(self.transientMonitor!) + self.transientMonitor = nil + self.joinNetworkPopover.close() + + } + } + } + } + + func quit() { + NSApp.performSelector(#selector(NSApp.terminate(_:)), withObject: nil, afterDelay: 0.0) + } } diff --git a/ZeroTier One/Assets.xcassets/Contents.json b/ZeroTier One/Assets.xcassets/Contents.json new file mode 100644 index 000000000..da4a164c9 --- /dev/null +++ b/ZeroTier One/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/ZeroTier One/Assets.xcassets/MenuBarIconMac.imageset/Contents.json b/ZeroTier One/Assets.xcassets/MenuBarIconMac.imageset/Contents.json new file mode 100644 index 000000000..ab75ef9a7 --- /dev/null +++ b/ZeroTier One/Assets.xcassets/MenuBarIconMac.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "mac", + "filename" : "MenuBarIconMac.png", + "scale" : "1x" + }, + { + "idiom" : "mac", + "filename" : "MenuBarIconMac@2x.png", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "template-rendering-intent" : "template" + } +} \ No newline at end of file diff --git a/ZeroTier One/Assets.xcassets/MenuBarIconMac.imageset/MenuBarIconMac.png b/ZeroTier One/Assets.xcassets/MenuBarIconMac.imageset/MenuBarIconMac.png new file mode 100644 index 0000000000000000000000000000000000000000..74e59fe79bd676b378d66de2d12d05dfa26e3746 GIT binary patch literal 3810 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 - + - + + @@ -11,7 +12,7 @@ - + @@ -666,11 +667,11 @@ - + - + diff --git a/ZeroTier One/Info.plist b/ZeroTier One/Info.plist index d5b744c6a..f5d0dc948 100644 --- a/ZeroTier One/Info.plist +++ b/ZeroTier One/Info.plist @@ -2,6 +2,8 @@ + LSUIElement + CFBundleDevelopmentRegion en CFBundleExecutable diff --git a/ZeroTier One/JoinNetworkViewController.swift b/ZeroTier One/JoinNetworkViewController.swift new file mode 100644 index 000000000..d071ce912 --- /dev/null +++ b/ZeroTier One/JoinNetworkViewController.swift @@ -0,0 +1,18 @@ +// +// JoinNetworkViewController.swift +// ZeroTier One +// +// Created by Grant Limberg on 5/14/16. +// Copyright © 2016 ZeroTier, Inc. All rights reserved. +// + +import Cocoa + +class JoinNetworkViewController: NSViewController { + + override func viewDidLoad() { + super.viewDidLoad() + // Do view setup here. + } + +} diff --git a/ZeroTier One/JoinNetworkViewController.xib b/ZeroTier One/JoinNetworkViewController.xib new file mode 100644 index 000000000..7f3f13297 --- /dev/null +++ b/ZeroTier One/JoinNetworkViewController.xib @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/ZeroTier One/ShowNetworksViewController.swift b/ZeroTier One/ShowNetworksViewController.swift new file mode 100644 index 000000000..0ecb38f53 --- /dev/null +++ b/ZeroTier One/ShowNetworksViewController.swift @@ -0,0 +1,18 @@ +// +// ShowNetworksViewController.swift +// ZeroTier One +// +// Created by Grant Limberg on 5/14/16. +// Copyright © 2016 ZeroTier, Inc. All rights reserved. +// + +import Cocoa + +class ShowNetworksViewController: NSViewController { + + override func viewDidLoad() { + super.viewDidLoad() + // Do view setup here. + } + +} diff --git a/ZeroTier One/ShowNetworksViewController.xib b/ZeroTier One/ShowNetworksViewController.xib new file mode 100644 index 000000000..2fe5f22f3 --- /dev/null +++ b/ZeroTier One/ShowNetworksViewController.xib @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + +