mirror of
https://github.com/nicoverbruggen/phpmon.git
synced 2025-11-08 05:30:05 +01:00
✨ Add preferences dialog to enable static icon (#25)
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
22
phpmon/Assets.xcassets/StatusBarIconStatic.imageset/Contents.json
vendored
Normal file
22
phpmon/Assets.xcassets/StatusBarIconStatic.imageset/Contents.json
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "phpmon.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "phpmon@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
BIN
phpmon/Assets.xcassets/StatusBarIconStatic.imageset/phpmon.png
vendored
Normal file
BIN
phpmon/Assets.xcassets/StatusBarIconStatic.imageset/phpmon.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 229 B |
BIN
phpmon/Assets.xcassets/StatusBarIconStatic.imageset/phpmon@2x.png
vendored
Normal file
BIN
phpmon/Assets.xcassets/StatusBarIconStatic.imageset/phpmon@2x.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 358 B |
@@ -18,6 +18,14 @@ class App {
|
||||
return App.shared.busy
|
||||
}
|
||||
|
||||
/** The list of preferences that are currently active. */
|
||||
var preferences: [PreferenceName: Bool]!
|
||||
|
||||
/**
|
||||
The window controller of the currently active window.
|
||||
*/
|
||||
var windowController: NSWindowController? = nil
|
||||
|
||||
/**
|
||||
Whether the application is busy switching versions.
|
||||
*/
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="17506" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="17701" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="17506"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="17701"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--Application-->
|
||||
@@ -54,5 +55,87 @@
|
||||
</objects>
|
||||
<point key="canvasLocation" x="-343" y="-16"/>
|
||||
</scene>
|
||||
<!--Window Controller-->
|
||||
<scene sceneID="PQa-AT-b2a">
|
||||
<objects>
|
||||
<windowController storyboardIdentifier="preferencesWindow" showSeguePresentationStyle="single" id="hLJ-Fd-wRr" sceneMemberID="viewController">
|
||||
<window key="window" title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" frameAutosaveName="" animationBehavior="default" id="h4c-3b-nko">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||
<rect key="contentRect" x="372" y="403" width="480" height="270"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="2304" height="1271"/>
|
||||
<view key="contentView" id="2yL-50-11x">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="270"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</view>
|
||||
<connections>
|
||||
<outlet property="delegate" destination="hLJ-Fd-wRr" id="6HE-8Y-aCO"/>
|
||||
</connections>
|
||||
</window>
|
||||
<connections>
|
||||
<segue destination="AW2-rV-rbS" kind="relationship" relationship="window.shadowedContentViewController" id="3dX-9V-eA0"/>
|
||||
</connections>
|
||||
</windowController>
|
||||
<customObject id="OF0-qs-3Oh" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="-374" y="327"/>
|
||||
</scene>
|
||||
<!--Preferences-->
|
||||
<scene sceneID="iyi-IS-7Ps">
|
||||
<objects>
|
||||
<viewController title="Preferences" storyboardIdentifier="preferences" showSeguePresentationStyle="single" id="AW2-rV-rbS" customClass="PrefsVC" customModule="PHP_Monitor" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<view key="view" id="Pf1-A5-3Xz">
|
||||
<rect key="frame" x="0.0" y="0.0" width="462" height="139"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="GSr-K5-3yw">
|
||||
<rect key="frame" x="380" y="13" width="69" height="32"/>
|
||||
<buttonCell key="cell" type="push" title="Close" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="ocw-Rx-gyh">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="pressed:" target="AW2-rV-rbS" id="8dA-y4-voq"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="MEf-MN-oXt">
|
||||
<rect key="frame" x="18" y="102" width="108" height="18"/>
|
||||
<buttonCell key="cell" type="check" title="Dynamic Icon" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="m5s-qp-Iaj">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="toggledDynamicIcon:" target="AW2-rV-rbS" id="cuJ-mt-agf"/>
|
||||
</connections>
|
||||
</button>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="JrH-aa-AzL">
|
||||
<rect key="frame" x="18" y="67" width="426" height="28"/>
|
||||
<textFieldCell key="cell" title="If you uncheck this box, the truck icon will always be visible
instead of the version number. No more distractions!" id="MHA-Xt-xgF">
|
||||
<font key="font" metaFont="system" size="11"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" secondItem="JrH-aa-AzL" secondAttribute="trailing" constant="20" symbolic="YES" id="8iM-Xf-ShU"/>
|
||||
<constraint firstAttribute="trailing" secondItem="GSr-K5-3yw" secondAttribute="trailing" constant="20" symbolic="YES" id="AT9-5F-6g1"/>
|
||||
<constraint firstItem="MEf-MN-oXt" firstAttribute="top" secondItem="Pf1-A5-3Xz" secondAttribute="top" constant="20" symbolic="YES" id="FJC-Lx-L8a"/>
|
||||
<constraint firstItem="MEf-MN-oXt" firstAttribute="leading" secondItem="Pf1-A5-3Xz" secondAttribute="leading" constant="20" symbolic="YES" id="Imd-YJ-Ae7"/>
|
||||
<constraint firstItem="JrH-aa-AzL" firstAttribute="top" secondItem="MEf-MN-oXt" secondAttribute="bottom" constant="8" symbolic="YES" id="Vf8-fx-H50"/>
|
||||
<constraint firstAttribute="bottom" secondItem="GSr-K5-3yw" secondAttribute="bottom" constant="20" symbolic="YES" id="dAS-yW-vua"/>
|
||||
<constraint firstItem="JrH-aa-AzL" firstAttribute="leading" secondItem="MEf-MN-oXt" secondAttribute="leading" id="dzR-S7-M6U"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<connections>
|
||||
<outlet property="buttonClose" destination="GSr-K5-3yw" id="d4I-Cf-gXD"/>
|
||||
<outlet property="buttonDynamicIcon" destination="MEf-MN-oXt" id="qEN-Vg-EZS"/>
|
||||
<outlet property="labelDynamicIcon" destination="JrH-aa-AzL" id="CFc-fF-oPq"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<customObject id="eQC-8B-FkX" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="216" y="319"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
</document>
|
||||
|
||||
@@ -96,6 +96,7 @@ class MainMenu: NSObject, NSWindowDelegate {
|
||||
menu.addItem(NSMenuItem.separator())
|
||||
|
||||
// Add about & quit menu items
|
||||
menu.addItem(NSMenuItem(title: "mi_preferences".localized, action: #selector(openPrefs), keyEquivalent: ""))
|
||||
menu.addItem(NSMenuItem(title: "mi_about".localized, action: #selector(openAbout), keyEquivalent: ""))
|
||||
menu.addItem(NSMenuItem(title: "mi_quit".localized, action: #selector(terminateApp), keyEquivalent: "q"))
|
||||
|
||||
@@ -159,16 +160,24 @@ class MainMenu: NSObject, NSWindowDelegate {
|
||||
|
||||
@objc func updatePhpVersionInStatusBar() {
|
||||
App.shared.currentInstall = PhpInstallation()
|
||||
|
||||
refreshIcon()
|
||||
update()
|
||||
}
|
||||
|
||||
func refreshIcon() {
|
||||
DispatchQueue.main.async { [self] in
|
||||
if (App.busy) {
|
||||
setStatusBar(image: NSImage(named: NSImage.Name("StatusBarIcon"))!)
|
||||
} else {
|
||||
setStatusBarImage(version: App.phpInstall!.version.short)
|
||||
if Preferences.preferences[.shouldDisplayDynamicIcon] == false {
|
||||
// Static icon has been requested
|
||||
setStatusBar(image: NSImage(named: NSImage.Name("StatusBarIconStatic"))!)
|
||||
} else {
|
||||
// The dynamic icon has been requested
|
||||
setStatusBarImage(version: App.phpInstall!.version.short)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
update()
|
||||
}
|
||||
|
||||
@objc func reloadPhpMonitorMenu() {
|
||||
@@ -301,6 +310,10 @@ class MainMenu: NSObject, NSWindowDelegate {
|
||||
NSApplication.shared.orderFrontStandardAboutPanel()
|
||||
}
|
||||
|
||||
@objc func openPrefs() {
|
||||
PrefsVC.show()
|
||||
}
|
||||
|
||||
@objc func terminateApp() {
|
||||
NSApplication.shared.terminate(nil)
|
||||
}
|
||||
|
||||
48
phpmon/Domain/Preferences/Preferences.swift
Normal file
48
phpmon/Domain/Preferences/Preferences.swift
Normal file
@@ -0,0 +1,48 @@
|
||||
//
|
||||
// Preferences.swift
|
||||
// PHP Monitor
|
||||
//
|
||||
// Created by Nico Verbruggen on 30/03/2021.
|
||||
// Copyright © 2021 Nico Verbruggen. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
enum PreferenceName: String {
|
||||
case shouldDisplayDynamicIcon = "use_dynamic_icon"
|
||||
}
|
||||
|
||||
class Preferences {
|
||||
|
||||
static func handleFirstTimeLaunch() {
|
||||
let launchedBefore = UserDefaults.standard.bool(forKey: "alreadyLaunched")
|
||||
|
||||
if launchedBefore {
|
||||
return
|
||||
}
|
||||
|
||||
UserDefaults.standard.setValue(true, forKey: PreferenceName.shouldDisplayDynamicIcon.rawValue)
|
||||
UserDefaults.standard.setValue(true, forKey: "alreadyLaunched")
|
||||
UserDefaults.standard.synchronize()
|
||||
}
|
||||
|
||||
static func retrieve() -> [PreferenceName: Bool] {
|
||||
Preferences.handleFirstTimeLaunch()
|
||||
|
||||
return [
|
||||
.shouldDisplayDynamicIcon: UserDefaults.standard.bool(
|
||||
forKey: PreferenceName.shouldDisplayDynamicIcon.rawValue
|
||||
)
|
||||
]
|
||||
}
|
||||
|
||||
static var preferences: [PreferenceName: Bool] {
|
||||
return Preferences.retrieve()
|
||||
}
|
||||
|
||||
static func update(_ preference: PreferenceName, value: Bool) {
|
||||
UserDefaults.standard.setValue(value, forKey: preference.rawValue)
|
||||
UserDefaults.standard.synchronize()
|
||||
}
|
||||
|
||||
}
|
||||
51
phpmon/Domain/Preferences/PrefsVC.swift
Normal file
51
phpmon/Domain/Preferences/PrefsVC.swift
Normal file
@@ -0,0 +1,51 @@
|
||||
//
|
||||
// PrefsVC.swift
|
||||
// PHP Monitor
|
||||
//
|
||||
// Created by Nico Verbruggen on 30/03/2021.
|
||||
// Copyright © 2021 Nico Verbruggen. All rights reserved.
|
||||
//
|
||||
|
||||
import Cocoa
|
||||
|
||||
class PrefsVC: NSViewController {
|
||||
|
||||
@IBOutlet weak var buttonDynamicIcon: NSButton!
|
||||
@IBOutlet weak var labelDynamicIcon: NSTextField!
|
||||
@IBOutlet weak var buttonClose: NSButton!
|
||||
|
||||
public static func show(delegate: NSWindowDelegate? = nil) {
|
||||
if (App.shared.windowController == nil) {
|
||||
let vc = NSStoryboard(name: "Main", bundle: nil).instantiateController(withIdentifier: "preferences") as! PrefsVC
|
||||
let window = NSWindow(contentViewController: vc)
|
||||
window.title = "prefs.title".localized
|
||||
window.delegate = delegate
|
||||
window.styleMask = [.titled, .closable]
|
||||
App.shared.windowController = NSWindowController(window: window)
|
||||
}
|
||||
App.shared.windowController!.showWindow(self)
|
||||
NSApp.activate(ignoringOtherApps: true)
|
||||
}
|
||||
|
||||
@IBAction func toggledDynamicIcon(_ sender: Any) {
|
||||
Preferences.update(.shouldDisplayDynamicIcon, value: buttonDynamicIcon.state == .on)
|
||||
MainMenu.shared.refreshIcon()
|
||||
}
|
||||
|
||||
override func viewWillAppear() {
|
||||
buttonDynamicIcon.title = "prefs.dynamic_icon_title".localized
|
||||
labelDynamicIcon.stringValue = "prefs.dynamic_icon_desc".localized
|
||||
buttonClose.title = "prefs.close".localized
|
||||
|
||||
let prefs = Preferences.preferences
|
||||
self.buttonDynamicIcon.state = (prefs[.shouldDisplayDynamicIcon] == true) ? .on : .off
|
||||
}
|
||||
|
||||
@IBAction func pressed(_ sender: Any) {
|
||||
self.view.window?.windowController?.close()
|
||||
}
|
||||
|
||||
deinit {
|
||||
print("VC deallocated")
|
||||
}
|
||||
}
|
||||
@@ -39,9 +39,17 @@
|
||||
"mi_detected_extensions" = "Detected Extensions";
|
||||
"mi_no_extensions_detected" = "No additional extensions detected.";
|
||||
|
||||
"mi_preferences" = "Preferences...";
|
||||
"mi_quit" = "Quit PHP Monitor";
|
||||
"mi_about" = "About PHP Monitor";
|
||||
|
||||
// PREFERENCES
|
||||
|
||||
"prefs.title" = "Preferences";
|
||||
"prefs.close" = "Close";
|
||||
"prefs.dynamic_icon_title" = "Show a dynamic icon in the menu bar";
|
||||
"prefs.dynamic_icon_desc" = "If you uncheck this box, the truck icon will always be visible.\nIf checked, it will display the major version number of the currently linked PHP version.";
|
||||
|
||||
// NOTIFICATIONS
|
||||
|
||||
"notification.version_changed_title" = "PHP %@ now active";
|
||||
|
||||
Reference in New Issue
Block a user