Skip to content

Commit

Permalink
Add option to toggle appearance
Browse files Browse the repository at this point in the history
  • Loading branch information
williambj1 committed Aug 3, 2024
1 parent d90d902 commit 595828b
Show file tree
Hide file tree
Showing 6 changed files with 165 additions and 12 deletions.
12 changes: 8 additions & 4 deletions HeliPort.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
objects = {

/* Begin PBXBuildFile section */
1317990B256986E5006957D8 /* String+NonNullTerminated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1317990A256986E5006957D8 /* String+NonNullTerminated.swift */; };
1317990B256986E5006957D8 /* String+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1317990A256986E5006957D8 /* String+Extensions.swift */; };
1380C36124D54BFD00A448CF /* PrefsSavedNetworksView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1380C36024D54BFD00A448CF /* PrefsSavedNetworksView.swift */; };
1380C36524D5580200A448CF /* PrefsWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1380C36424D5580200A448CF /* PrefsWindow.swift */; };
138D3CC824CE635800793AC1 /* Commands.swift in Sources */ = {isa = PBXBuildFile; fileRef = 138D3CC724CE635800793AC1 /* Commands.swift */; };
Expand All @@ -16,6 +16,7 @@
13AF73B624B25E170015867C /* StatusMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = BCA4DFAC243A307B002A862A /* StatusMenu.swift */; };
13C20DFA24D8B6D100B1E713 /* PrefsGeneralView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13C20DF924D8B6D100B1E713 /* PrefsGeneralView.swift */; };
5013B8FB2C5C8C8D002C5006 /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = 5013B8FA2C5C8C8D002C5006 /* Localizable.xcstrings */; };
5013B8FD2C5DF244002C5006 /* NSApp+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5013B8FC2C5DF244002C5006 /* NSApp+Extensions.swift */; };
505EC11D2C5BD89400F4E4EA /* StatusBarIconManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 505EC11C2C5BD89400F4E4EA /* StatusBarIconManager.swift */; };
505EC11F2C5BD8ED00F4E4EA /* StatusBarIconLegacy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 505EC11E2C5BD8ED00F4E4EA /* StatusBarIconLegacy.swift */; };
505EC1212C5BD95700F4E4EA /* StatusBarIconModern.swift in Sources */ = {isa = PBXBuildFile; fileRef = 505EC1202C5BD95700F4E4EA /* StatusBarIconModern.swift */; };
Expand Down Expand Up @@ -60,14 +61,15 @@
/* End PBXCopyFilesBuildPhase section */

/* Begin PBXFileReference section */
1317990A256986E5006957D8 /* String+NonNullTerminated.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+NonNullTerminated.swift"; sourceTree = "<group>"; };
1317990A256986E5006957D8 /* String+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+Extensions.swift"; sourceTree = "<group>"; };
1380C36024D54BFD00A448CF /* PrefsSavedNetworksView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrefsSavedNetworksView.swift; sourceTree = "<group>"; };
1380C36424D5580200A448CF /* PrefsWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrefsWindow.swift; sourceTree = "<group>"; };
138D3CC724CE635800793AC1 /* Commands.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Commands.swift; sourceTree = "<group>"; };
138D3CC924CE663B00793AC1 /* BugReporter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BugReporter.swift; sourceTree = "<group>"; };
13AB3CA724DE47D10093D283 /* WiFiConfigWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WiFiConfigWindow.swift; sourceTree = "<group>"; };
13C20DF924D8B6D100B1E713 /* PrefsGeneralView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrefsGeneralView.swift; sourceTree = "<group>"; };
5013B8FA2C5C8C8D002C5006 /* Localizable.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; path = Localizable.xcstrings; sourceTree = "<group>"; };
5013B8FC2C5DF244002C5006 /* NSApp+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSApp+Extensions.swift"; sourceTree = "<group>"; };
505EC11C2C5BD89400F4E4EA /* StatusBarIconManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusBarIconManager.swift; sourceTree = "<group>"; };
505EC11E2C5BD8ED00F4E4EA /* StatusBarIconLegacy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusBarIconLegacy.swift; sourceTree = "<group>"; };
505EC1202C5BD95700F4E4EA /* StatusBarIconModern.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusBarIconModern.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -218,9 +220,10 @@
F336D63D24B4986C004C98C4 /* itl_phy_mode+Description.swift */,
F336D63F24B7B7D8004C98C4 /* itl80211_security+Description.swift */,
F336D63B24B497B6004C98C4 /* NetworkManager+Data.swift */,
5013B8FC2C5DF244002C5006 /* NSApp+Extensions.swift */,
F33A1F3E24C8347F008ED2BD /* NSLocalizedString+Extensions.swift */,
F34B2B8C24AA4C1E009AB1BB /* NSMenuItem+Extensions.swift */,
1317990A256986E5006957D8 /* String+NonNullTerminated.swift */,
1317990A256986E5006957D8 /* String+Extensions.swift */,
);
path = "Supporting files";
sourceTree = "<group>";
Expand Down Expand Up @@ -422,7 +425,8 @@
50F4959824BDD26D00AE4C08 /* LoginItemManager.swift in Sources */,
F34B2B8D24AA4C1E009AB1BB /* NSMenuItem+Extensions.swift in Sources */,
50E7700F2C5A7CE100DB1160 /* UpdateManager.swift in Sources */,
1317990B256986E5006957D8 /* String+NonNullTerminated.swift in Sources */,
5013B8FD2C5DF244002C5006 /* NSApp+Extensions.swift in Sources */,
1317990B256986E5006957D8 /* String+Extensions.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
11 changes: 10 additions & 1 deletion HeliPort/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,17 @@ class AppDelegate: NSObject, NSApplicationDelegate {

let statusBar = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)

let legacyUIEnabled = {
if #unavailable(macOS 11) {
return true
}
return UserDefaults.standard.bool(forKey: .DefaultsKey.legacyUI)
}()

Log.debug("UI appearance: \(legacyUIEnabled ? "legacy" : "modern")")

let iconProvider: StatusBarIconProvider = {
if #available(macOS 11, *) {
if #available(macOS 11, *), !legacyUIEnabled {
return StatusBarIconModern()
}
return StatusBarIconLegacy()
Expand Down
66 changes: 66 additions & 0 deletions HeliPort/Appearance/Localizable.xcstrings
Original file line number Diff line number Diff line change
Expand Up @@ -1987,6 +1987,17 @@
}
}
},
"Appearance:" : {
"extractionState" : "manual",
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "外观:"
}
}
}
},
"Auto Join" : {
"extractionState" : "manual",
"localizations" : {
Expand Down Expand Up @@ -3965,6 +3976,17 @@
}
}
},
"HeliPort Restart Required" : {
"extractionState" : "manual",
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "HeliPort 需要重启"
}
}
}
},
"HeliPort running at an unexpected path" : {
"extractionState" : "manual",
"localizations" : {
Expand Down Expand Up @@ -4666,6 +4688,17 @@
}
}
},
"Later" : {
"extractionState" : "manual",
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "稍后"
}
}
}
},
"Launch At Login" : {
"extractionState" : "manual",
"localizations" : {
Expand Down Expand Up @@ -6530,6 +6563,17 @@
}
}
},
"Restart" : {
"extractionState" : "manual",
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "重启"
}
}
}
},
"Saved Networks:" : {
"extractionState" : "manual",
"localizations" : {
Expand Down Expand Up @@ -6946,6 +6990,17 @@
}
}
},
"Switching appearance requires a restart of the application to take effect." : {
"extractionState" : "manual",
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "切换外观需要重新启动应用程序才能生效。"
}
}
}
},
"The bug report will be generated in the seleted folder" : {
"extractionState" : "manual",
"localizations" : {
Expand Down Expand Up @@ -7611,6 +7666,17 @@
}
}
},
"Use Legacy UI" : {
"extractionState" : "manual",
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "使用传统界面"
}
}
}
},
"Username:" : {
"extractionState" : "manual",
"localizations" : {
Expand Down
53 changes: 48 additions & 5 deletions HeliPort/Appearance/Preferences/PrefsGeneralView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class PrefsGeneralView: NSView {
target: self,
action: #selector(checkboxChanged(_:)))
checkbox.identifier = .autoUpdateId
checkbox.state = UpdateManager.sharedUpdater.automaticallyChecksForUpdates ? .on : .off
return checkbox
}()

Expand All @@ -37,6 +38,29 @@ class PrefsGeneralView: NSView {
target: self,
action: #selector(checkboxChanged(_:)))
checkbox.identifier = .autoDownloadId
checkbox.state = UpdateManager.sharedUpdater.automaticallyDownloadsUpdates ? .on : .off
return checkbox
}()

let appearanceLabel: NSTextField = {
let view = NSTextField(labelWithString: .appearance)
view.alignment = .right
return view
}()

lazy var legacyUICheckbox: NSButton = {
let checkbox = NSButton(checkboxWithTitle: .useLegacyUI,
target: self,
action: #selector(self.checkboxChanged(_:)))
checkbox.identifier = .legacyUIId

if #available(macOS 11, *) {
checkbox.state = UserDefaults.standard.bool(forKey: .DefaultsKey.legacyUI) ? .on : .off
} else {
checkbox.state = .on
checkbox.isEnabled = false
}

return checkbox
}()

Expand All @@ -53,13 +77,10 @@ class PrefsGeneralView: NSView {
override init(frame frameRect: NSRect) {
super.init(frame: frameRect)

autoUpdateCheckbox.target = self
autoDownloadCheckbox.target = self
gridView.addRow(with: [updatesLabel])
gridView.addColumn(with: [autoUpdateCheckbox, autoDownloadCheckbox])

autoUpdateCheckbox.state = UpdateManager.sharedUpdater.automaticallyChecksForUpdates ? .on : .off
autoDownloadCheckbox.state = UpdateManager.sharedUpdater.automaticallyDownloadsUpdates ? .on : .off
let appearanceRow = gridView.addRow(with: [appearanceLabel, legacyUICheckbox])
appearanceRow.topPadding = 5

addSubview(gridView)
setupConstraints()
Expand Down Expand Up @@ -90,6 +111,17 @@ extension PrefsGeneralView {
UpdateManager.sharedUpdater.automaticallyChecksForUpdates = sender.state == .on
case .autoDownloadId:
UpdateManager.sharedUpdater.automaticallyDownloadsUpdates = sender.state == .on
case .legacyUIId:
if #available(macOS 11, *) {
UserDefaults.standard.set(sender.state == .on, forKey: .DefaultsKey.legacyUI)
let alert = CriticalAlert(message: .heliportRestart,
informativeText: .restartInfoText,
options: [.restart, .later])

if alert.show() == .alertFirstButtonReturn {
NSApp.restartApp()
}
}
default:
break
}
Expand All @@ -99,10 +131,21 @@ extension PrefsGeneralView {
private extension NSUserInterfaceItemIdentifier {
static let autoUpdateId = NSUserInterfaceItemIdentifier(rawValue: "AutoUpdateCheckbox")
static let autoDownloadId = NSUserInterfaceItemIdentifier(rawValue: "AutoDownloadCheckbox")

static let legacyUIId = NSUserInterfaceItemIdentifier(rawValue: "legacyUICheckbox")
}

private extension String {
static let startup = NSLocalizedString("Updates:")
static let autoCheckUpdate = NSLocalizedString("Automatically check for updates.")
static let autoDownload = NSLocalizedString("Automatically download new updates.")

static let appearance = NSLocalizedString("Appearance:")
static let useLegacyUI = NSLocalizedString("Use Legacy UI")

static let heliportRestart = NSLocalizedString("HeliPort Restart Required")
static let restartInfoText =
NSLocalizedString("Switching appearance requires a restart of the application to take effect.")
static let restart = NSLocalizedString("Restart")
static let later = NSLocalizedString("Later")
}
29 changes: 29 additions & 0 deletions HeliPort/Supporting files/NSApp+Extensions.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//
// NSApp+Extensions.swift
// HeliPort
//
// Created by Bat.bat on 29/7/2024.
// Copyright © 2024 OpenIntelWireless. All rights reserved.
//

import Cocoa

extension NSApplication {
@available(macOS 10.15, *)
func restartApp() {
let config = NSWorkspace.OpenConfiguration()
config.createsNewApplicationInstance = true

NSWorkspace.shared.openApplication(at: Bundle.main.bundleURL,
configuration: config,
completionHandler: { _, error in
if let error {
Log.error("Failed to restart the app: \(error)")
} else {
DispatchQueue.main.async {
NSApp.terminate(nil)
}
}
})
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@
import Foundation

public extension String {
enum DefaultsKey {
static let legacyUI = "legacyUIEnabled"
}

static func getSSIDFromCString(cString: UnsafePointer<CUnsignedChar>) -> String {
var string = String(cString: cString)
// Fixes memory leak, see https://stackoverflow.com/a/37584615
Expand All @@ -36,9 +40,7 @@ public extension String {
}
return string
}
}

public extension String {
init<T>(cCharArray: T) {
self = withUnsafeBytes(of: cCharArray) {
$0.withMemoryRebound(to: CChar.self) { String(cString: $0.baseAddress!)}
Expand Down

0 comments on commit 595828b

Please sign in to comment.