Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tiny new features, more robust localization #35

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 48 additions & 76 deletions Apple Juice.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions AppleJuice/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ import Cocoa

@NSApplicationMain
final class AppDelegate: NSObject, NSApplicationDelegate {



func applicationDidFinishLaunching(_: Notification) {
UserPreferences.registerDefaults()
}
Expand Down
20 changes: 18 additions & 2 deletions AppleJuice/ApplicationController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ final class ApplicationController: NSObject {

private var statusItem: StatusBarItem?
private var battery: BatteryService!

private let notificationSubmenu = NotificationSubmenu()

@IBOutlet weak var applicationMenu: NSMenu!

@objc dynamic var launchAtLogin = LaunchAtLogin.kvo
Expand All @@ -25,11 +26,24 @@ final class ApplicationController: NSObject {
withAction: #selector(ApplicationController.displayAppMenu(_:)),
forTarget: self)
statusItem?.update(batteryInfo: battery)


// Register the ApplicationController as observer for power source and user preference changes
UserDefaults
.standard
.addObserver(self, forKeyPath: PreferenceKey.showTime.rawValue, options: .new, context: nil)
.addObserver(self, forKeyPath: PreferenceKey.showTimeBat.rawValue, options: .new, context: nil)

UserDefaults
.standard
.addObserver(self, forKeyPath: PreferenceKey.showTimeCharge.rawValue, options: .new, context: nil)

UserDefaults
.standard
.addObserver(self, forKeyPath: PreferenceKey.showPercentageETA.rawValue, options: .new, context: nil)

UserDefaults
.standard
.addObserver(self, forKeyPath: PreferenceKey.percentagesNotifications.rawValue, options: .new, context: nil)

UserDefaults
.standard
Expand Down Expand Up @@ -73,6 +87,7 @@ final class ApplicationController: NSObject {
statusItem?.popUpMenu(applicationMenu)
}


// MARK: Internal

/// This message is sent to the receiver when the value at the specified key path relative to the given object
Expand All @@ -91,5 +106,6 @@ final class ApplicationController: NSObject {
context _: UnsafeMutableRawPointer?)
{
statusItem?.update(batteryInfo: battery)
notificationSubmenu.update(mainMenu: applicationMenu)
}
}
5 changes: 3 additions & 2 deletions AppleJuice/ApplicationMenuDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -51,15 +51,16 @@ class ApplicationMenuDelegate: NSObject, NSMenuDelegate {
let amperage = batteryService?.amperage,
let percentage = batteryService?.percentage,
let timeRemaining = batteryService?.timeRemaining,
let powerSource = batteryService?.powerSource
let powerSource = batteryService?.powerSource,
let isCharging = batteryService?.isCharging
else {
return NSAttributedString(string: NSLocalizedString("Unknown", comment: "Information missing"))
}

let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.paragraphSpacing = 3.0

let remaining = UserPreferences.showTime ? percentage.formatted : timeRemaining.formatted
let remaining = ((UserPreferences.showTimeBat && !isCharging) || (UserPreferences.showTimeCharge && isCharging)) ? percentage.formatted : timeRemaining.formatted

let powerSourceLabel = NSMutableAttributedString(
string: powerSource.localizedDescription,
Expand Down
18 changes: 18 additions & 0 deletions AppleJuice/Base.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,24 @@
"Power Adapter" = "Power Adapter";
"Calculating" = "Calculating…";

// Static menu item strings
"menu_bat_status" = "Unknown…";
"menu_prefs" = "Preferences";
"menu_notifications" = "Notifications";
"menu_add_notif" = "Add notification";
"menu_on_bat" = "On battery";
"menu_charging" = "Power Adapter";
"menu_show_time_remaining" = "Show Remaining Time";
"menu_show_per_while_eta" = "Show Percentage during ETA Calculation";
"menu_hide_info" = "Hide Menu Bar Info";
"menu_hide_bat" = "Hide Battery Icon";
"menu_launch_at_login" = "Launch at Login";
"menu_check_updates" = "Check for Updates…";
"menu_about" = "About Apple Juice…";
"menu_quit" = "Quit";

// UI buttons
"ui_cancel" = "Cancel";

// Notifications

Expand Down
102 changes: 72 additions & 30 deletions AppleJuice/Base.lproj/MainMenu.xib
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="17506" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="20037" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="17506"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="20037"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
Expand All @@ -26,58 +26,82 @@
<items>
<menuItem title="Unknown..." enabled="NO" id="Jwd-Td-BfA">
<modifierMask key="keyEquivalentModifierMask"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="xibLocKey" value="menu_bat_status_unknown"/>
</userDefinedRuntimeAttributes>
</menuItem>
<menuItem isSeparatorItem="YES" id="OYt-Th-ZmC"/>
<menuItem title="Notifications" id="uGl-yK-qDZ">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Notifications" id="s9C-tt-TOv">
<items>
<menuItem title="5 %" id="BqN-sm-Uru">
<menuItem title="15 %" id="BqN-sm-Uru">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<binding destination="OgL-rZ-xAG" name="value" keyPath="values.FivePercentNotificationPref" id="dFS-9B-FLf"/>
</connections>
</menuItem>
<menuItem title="10 %" id="yXd-MQ-b9b">
<menuItem isSeparatorItem="YES" identifier="separator" id="HoG-Jh-UIk"/>
<menuItem title="Add notification" id="Dvk-tQ-PLN">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<binding destination="OgL-rZ-xAG" name="value" keyPath="values.TenPercentNotificationPref" id="pk3-fW-qx5"/>
</connections>
<menu key="submenu" id="qJ3-LZ-OT7"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="xibLocKey" value="menu_add_notif"/>
</userDefinedRuntimeAttributes>
</menuItem>
</items>
</menu>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="xibLocKey" value="menu_notifications"/>
</userDefinedRuntimeAttributes>
</menuItem>
<menuItem title="Preferences" id="tiY-Hf-wFt">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Preferences" id="kuh-P6-ZjK">
<items>
<menuItem title="On battery" id="lVh-Os-Ltq">
<modifierMask key="keyEquivalentModifierMask"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="xibLocKey" value="menu_on_bat"/>
</userDefinedRuntimeAttributes>
</menuItem>
<menuItem title="15 %" id="IiQ-lQ-6Kw">
<menuItem title="Show Time Remaining" indentationLevel="1" id="Kin-Z7-Y0F">
<modifierMask key="keyEquivalentModifierMask"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="xibLocKey" value="menu_show_time_remaining"/>
</userDefinedRuntimeAttributes>
<connections>
<binding destination="OgL-rZ-xAG" name="value" keyPath="values.FifeteenPercentNotificationPref" id="qgh-4q-kHe"/>
<binding destination="OgL-rZ-xAG" name="value" keyPath="values.ShowTimeBatPref" id="nRp-gx-SfQ"/>
</connections>
</menuItem>
<menuItem title="20 %" id="Pag-Zv-yRx">
<menuItem isSeparatorItem="YES" id="Olo-ub-6Cx"/>
<menuItem title="Charging" id="HJw-pV-bbx">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<binding destination="OgL-rZ-xAG" name="value" keyPath="values.TwentyPercentNotificationPref" id="GGC-Ot-acB"/>
</connections>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="xibLocKey" value="menu_charging"/>
</userDefinedRuntimeAttributes>
</menuItem>
<menuItem isSeparatorItem="YES" id="fZI-EN-bOn"/>
<menuItem title="100 %" id="bgK-RS-y5X">
<menuItem title="Show Time Remaining" indentationLevel="1" id="tza-sa-3fF">
<modifierMask key="keyEquivalentModifierMask"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="xibLocKey" value="menu_show_time_remaining"/>
</userDefinedRuntimeAttributes>
<connections>
<binding destination="OgL-rZ-xAG" name="value" keyPath="values.HundredPercentNotificationPref" id="Vuz-F7-ftw"/>
<binding destination="OgL-rZ-xAG" name="value" keyPath="values.ShowTimeChargePref" id="LSh-EL-s4G"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Preferences" id="tiY-Hf-wFt">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Preferences" id="kuh-P6-ZjK">
<items>
<menuItem title="Show Time Remaining" id="Kin-Z7-Y0F">
<menuItem isSeparatorItem="YES" id="ylj-gG-Uds"/>
<menuItem title="Show Percentage during ETA Calculation" id="D2D-m9-6t9">
<modifierMask key="keyEquivalentModifierMask"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="xibLocKey" value="menu_show_per_while_eta"/>
</userDefinedRuntimeAttributes>
<connections>
<binding destination="OgL-rZ-xAG" name="value" keyPath="values.ShowTimePref" id="5Mm-fA-cBY"/>
<binding destination="OgL-rZ-xAG" name="value" keyPath="values.ShowPercentageETAPref" id="X6y-J6-GGq"/>
</connections>
</menuItem>
<menuItem title="Hide Menu Bar Info" id="Wmn-z6-g7g">
<modifierMask key="keyEquivalentModifierMask"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="xibLocKey" value="menu_hide_info"/>
</userDefinedRuntimeAttributes>
<connections>
<binding destination="OgL-rZ-xAG" name="enabled" keyPath="values.HideBatteryIconPref" id="8HY-3f-0ET">
<dictionary key="options">
Expand All @@ -89,6 +113,9 @@
</menuItem>
<menuItem title="Hide Battery Icon" id="sbN-Mr-efU">
<modifierMask key="keyEquivalentModifierMask"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="xibLocKey" value="menu_hide_bat"/>
</userDefinedRuntimeAttributes>
<connections>
<binding destination="OgL-rZ-xAG" name="value" keyPath="values.HideBatteryIconPref" id="6p3-vG-TYg"/>
<binding destination="OgL-rZ-xAG" name="enabled" keyPath="values.HideMenubarInfoPref" id="avg-d2-Fsg">
Expand All @@ -100,29 +127,44 @@
</menuItem>
<menuItem title="Launch at Login" id="gXB-33-x5J">
<modifierMask key="keyEquivalentModifierMask"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="xibLocKey" value="menu_launch_at_login"/>
</userDefinedRuntimeAttributes>
<connections>
<binding destination="FRD-GK-LcV" name="value" keyPath="launchAtLogin.isEnabled" id="Zx9-Yu-AB5"/>
</connections>
</menuItem>
</items>
</menu>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="xibLocKey" value="menu_prefs"/>
</userDefinedRuntimeAttributes>
</menuItem>
<menuItem isSeparatorItem="YES" id="HoG-Jh-UIk"/>
<menuItem isSeparatorItem="YES" id="CQH-z6-Moz"/>
<menuItem title="Check for Updates…" id="OFJ-1T-Wc5">
<modifierMask key="keyEquivalentModifierMask"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="xibLocKey" value="menu_check_updates"/>
</userDefinedRuntimeAttributes>
<connections>
<action selector="checkForUpdates:" target="Avc-Ie-Abt" id="Aqj-nm-y4m"/>
</connections>
</menuItem>
<menuItem title="About Apple Juice…" id="PUB-MR-Ddo">
<modifierMask key="keyEquivalentModifierMask"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="xibLocKey" value="menu_about"/>
</userDefinedRuntimeAttributes>
<connections>
<action selector="orderFrontStandardAboutPanel:" target="-1" id="vXr-y6-aUC"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="bcW-nq-A9L"/>
<menuItem title="Quit" id="fXh-MN-Omu">
<modifierMask key="keyEquivalentModifierMask"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="xibLocKey" value="menu_quit"/>
</userDefinedRuntimeAttributes>
<connections>
<action selector="terminate:" target="-1" id="f0e-26-aRM"/>
</connections>
Expand All @@ -131,7 +173,7 @@
<connections>
<outlet property="delegate" destination="hOe-ib-loY" id="FJU-36-bfo"/>
</connections>
<point key="canvasLocation" x="-148" y="142"/>
<point key="canvasLocation" x="-1869" y="-193"/>
</menu>
</objects>
</document>
15 changes: 8 additions & 7 deletions AppleJuice/MenuInfoViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@ class MenuInfoViewModel: ObservableObject {

update()

NotificationCenter.default
.addObserver(self,
selector: #selector(MenuInfoViewModel.powerSourceChanged(_:)),
name: NSNotification.Name(rawValue: powerSourceChangedNotification),
object: nil)
NotificationCenter.default
.addObserver(self,
selector: #selector(MenuInfoViewModel.powerSourceChanged(_:)),
name: NSNotification.Name(rawValue: powerSourceChangedNotification),
object: nil)
}

@objc public func powerSourceChanged(_: AnyObject) {
Expand All @@ -40,14 +40,15 @@ class MenuInfoViewModel: ObservableObject {
let currentCharge = batteryService?.charge,
let maxCapacity = batteryService?.capacity,
let amperage = batteryService?.amperage,
let powerSource = batteryService?.powerSource
let powerSource = batteryService?.powerSource,
let isCharging = batteryService?.isCharging
else {
return
}

self.powerSource = powerSource.localizedDescription
self.currentCharge = String(format: "%i / %i mAh (%i mA)", currentCharge, maxCapacity, amperage)
if UserPreferences.showTime {
if (UserPreferences.showTimeBat && !isCharging) || (UserPreferences.showTimeCharge && isCharging){
self.remaining = percentage.formatted
} else {
self.remaining = timeRemaining.formatted
Expand Down
32 changes: 32 additions & 0 deletions AppleJuice/MenuLocalization.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//
// MenuLocalization.swift
// Apple Juice
// https://github.com/raphaelhanneken/apple-juice
//

import Foundation
import AppKit

protocol Localizable {
var localized: String { get }
}

extension String: Localizable {
var localized: String {
return NSLocalizedString(self, comment: "")
}
}

protocol XIBLocalizable {
var xibLocKey: String? { get set }
}

// Allow menu items to use localizable strings as titles
extension NSMenuItem: XIBLocalizable {
@IBInspectable var xibLocKey: String? {
get { return nil }
set(key) {
attributedTitle = NSAttributedString(string: key?.localized ?? "Could not translate");
}
}
}
22 changes: 0 additions & 22 deletions AppleJuice/NotificationKey.swift

This file was deleted.

Loading