mirror of
https://github.com/nicoverbruggen/phpmon.git
synced 2025-08-07 20:10:08 +02:00
👌 Polish preferences screen
This commit is contained in:
@ -19,6 +19,7 @@
|
|||||||
C41C1B4922B00A9800E7CF16 /* MenuBarImageGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41C1B4822B00A9800E7CF16 /* MenuBarImageGenerator.swift */; };
|
C41C1B4922B00A9800E7CF16 /* MenuBarImageGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41C1B4822B00A9800E7CF16 /* MenuBarImageGenerator.swift */; };
|
||||||
C41C1B4B22B019FF00E7CF16 /* PhpInstallation.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41C1B4A22B019FF00E7CF16 /* PhpInstallation.swift */; };
|
C41C1B4B22B019FF00E7CF16 /* PhpInstallation.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41C1B4A22B019FF00E7CF16 /* PhpInstallation.swift */; };
|
||||||
C41C1B4D22B0215A00E7CF16 /* Actions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41C1B4C22B0215A00E7CF16 /* Actions.swift */; };
|
C41C1B4D22B0215A00E7CF16 /* Actions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41C1B4C22B0215A00E7CF16 /* Actions.swift */; };
|
||||||
|
C41CD0292628D8EE0065BBED /* GlobalKeybindPreference.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41CD0282628D8EE0065BBED /* GlobalKeybindPreference.swift */; };
|
||||||
C42295DD2358D02000E263B2 /* Command.swift in Sources */ = {isa = PBXBuildFile; fileRef = C42295DC2358D02000E263B2 /* Command.swift */; };
|
C42295DD2358D02000E263B2 /* Command.swift in Sources */ = {isa = PBXBuildFile; fileRef = C42295DC2358D02000E263B2 /* Command.swift */; };
|
||||||
C4232EE52612526500158FC6 /* Credits.html in Resources */ = {isa = PBXBuildFile; fileRef = C4232EE42612526500158FC6 /* Credits.html */; };
|
C4232EE52612526500158FC6 /* Credits.html in Resources */ = {isa = PBXBuildFile; fileRef = C4232EE42612526500158FC6 /* Credits.html */; };
|
||||||
C42759672627662800093CAE /* NSMenuExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = C42759662627662800093CAE /* NSMenuExtension.swift */; };
|
C42759672627662800093CAE /* NSMenuExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = C42759662627662800093CAE /* NSMenuExtension.swift */; };
|
||||||
@ -101,6 +102,7 @@
|
|||||||
C41C1B4822B00A9800E7CF16 /* MenuBarImageGenerator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuBarImageGenerator.swift; sourceTree = "<group>"; };
|
C41C1B4822B00A9800E7CF16 /* MenuBarImageGenerator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuBarImageGenerator.swift; sourceTree = "<group>"; };
|
||||||
C41C1B4A22B019FF00E7CF16 /* PhpInstallation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhpInstallation.swift; sourceTree = "<group>"; };
|
C41C1B4A22B019FF00E7CF16 /* PhpInstallation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhpInstallation.swift; sourceTree = "<group>"; };
|
||||||
C41C1B4C22B0215A00E7CF16 /* Actions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Actions.swift; sourceTree = "<group>"; };
|
C41C1B4C22B0215A00E7CF16 /* Actions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Actions.swift; sourceTree = "<group>"; };
|
||||||
|
C41CD0282628D8EE0065BBED /* GlobalKeybindPreference.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GlobalKeybindPreference.swift; sourceTree = "<group>"; };
|
||||||
C42295DC2358D02000E263B2 /* Command.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Command.swift; sourceTree = "<group>"; };
|
C42295DC2358D02000E263B2 /* Command.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Command.swift; sourceTree = "<group>"; };
|
||||||
C4232EE42612526500158FC6 /* Credits.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = Credits.html; sourceTree = "<group>"; };
|
C4232EE42612526500158FC6 /* Credits.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = Credits.html; sourceTree = "<group>"; };
|
||||||
C42759662627662800093CAE /* NSMenuExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSMenuExtension.swift; sourceTree = "<group>"; };
|
C42759662627662800093CAE /* NSMenuExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSMenuExtension.swift; sourceTree = "<group>"; };
|
||||||
@ -162,6 +164,7 @@
|
|||||||
C4998F092617633900B2526E /* PrefsWC.swift */,
|
C4998F092617633900B2526E /* PrefsWC.swift */,
|
||||||
5420395826135DC100FB00FA /* PrefsVC.swift */,
|
5420395826135DC100FB00FA /* PrefsVC.swift */,
|
||||||
5420395E2613607600FB00FA /* Preferences.swift */,
|
5420395E2613607600FB00FA /* Preferences.swift */,
|
||||||
|
C41CD0272628D8E20065BBED /* Keybinds */,
|
||||||
);
|
);
|
||||||
path = Preferences;
|
path = Preferences;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -213,6 +216,14 @@
|
|||||||
path = phpmon;
|
path = phpmon;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
C41CD0272628D8E20065BBED /* Keybinds */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
C41CD0282628D8EE0065BBED /* GlobalKeybindPreference.swift */,
|
||||||
|
);
|
||||||
|
path = Keybinds;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
C41E181722CB61EB0072CF09 /* Domain */ = {
|
C41E181722CB61EB0072CF09 /* Domain */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@ -421,6 +432,7 @@
|
|||||||
C41C1B4722B009A400E7CF16 /* Shell.swift in Sources */,
|
C41C1B4722B009A400E7CF16 /* Shell.swift in Sources */,
|
||||||
C41C1B4D22B0215A00E7CF16 /* Actions.swift in Sources */,
|
C41C1B4D22B0215A00E7CF16 /* Actions.swift in Sources */,
|
||||||
C48D0CA325CC992000CC7490 /* StatsView.swift in Sources */,
|
C48D0CA325CC992000CC7490 /* StatsView.swift in Sources */,
|
||||||
|
C41CD0292628D8EE0065BBED /* GlobalKeybindPreference.swift in Sources */,
|
||||||
C42295DD2358D02000E263B2 /* Command.swift in Sources */,
|
C42295DD2358D02000E263B2 /* Command.swift in Sources */,
|
||||||
C4811D2422D70A4700B5F6B3 /* App.swift in Sources */,
|
C4811D2422D70A4700B5F6B3 /* App.swift in Sources */,
|
||||||
C41C1B4922B00A9800E7CF16 /* MenuBarImageGenerator.swift in Sources */,
|
C41C1B4922B00A9800E7CF16 /* MenuBarImageGenerator.swift in Sources */,
|
||||||
|
@ -85,21 +85,24 @@
|
|||||||
<objects>
|
<objects>
|
||||||
<viewController title="Preferences" storyboardIdentifier="preferences" showSeguePresentationStyle="single" id="AW2-rV-rbS" customClass="PrefsVC" customModule="PHP_Monitor" customModuleProvider="target" sceneMemberID="viewController">
|
<viewController title="Preferences" storyboardIdentifier="preferences" showSeguePresentationStyle="single" id="AW2-rV-rbS" customClass="PrefsVC" customModule="PHP_Monitor" customModuleProvider="target" sceneMemberID="viewController">
|
||||||
<view key="view" wantsLayer="YES" id="Pf1-A5-3Xz">
|
<view key="view" wantsLayer="YES" id="Pf1-A5-3Xz">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="462" height="185"/>
|
<rect key="frame" x="0.0" y="0.0" width="574" height="189"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="GSr-K5-3yw">
|
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="GSr-K5-3yw">
|
||||||
<rect key="frame" x="373" y="13" width="76" height="32"/>
|
<rect key="frame" x="485" y="13" width="76" height="32"/>
|
||||||
<buttonCell key="cell" type="push" title="CLOSE" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="ocw-Rx-gyh">
|
<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"/>
|
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
|
<string key="keyEquivalent" base64-UTF8="YES">
|
||||||
|
Gw
|
||||||
|
</string>
|
||||||
</buttonCell>
|
</buttonCell>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="pressed:" target="AW2-rV-rbS" id="8dA-y4-voq"/>
|
<action selector="pressed:" target="AW2-rV-rbS" id="8dA-y4-voq"/>
|
||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="MEf-MN-oXt">
|
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="MEf-MN-oXt">
|
||||||
<rect key="frame" x="18" y="148" width="424" height="18"/>
|
<rect key="frame" x="148" y="152" width="406" height="18"/>
|
||||||
<buttonCell key="cell" type="check" title="DYN_ICON" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="m5s-qp-Iaj">
|
<buttonCell key="cell" type="check" title="DYN_ICON" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="m5s-qp-Iaj">
|
||||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
@ -109,18 +112,32 @@
|
|||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="JrH-aa-AzL">
|
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="JrH-aa-AzL">
|
||||||
<rect key="frame" x="18" y="127" width="426" height="14"/>
|
<rect key="frame" x="148" y="131" width="408" height="14"/>
|
||||||
<textFieldCell key="cell" title="DYN_ICON_DESC" id="MHA-Xt-xgF">
|
<textFieldCell key="cell" title="DYN_ICON_DESC" id="MHA-Xt-xgF">
|
||||||
<font key="font" metaFont="smallSystem"/>
|
<font key="font" metaFont="smallSystem"/>
|
||||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
|
||||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
</textField>
|
</textField>
|
||||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="V7b-jv-oCB">
|
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="V7b-jv-oCB">
|
||||||
<rect key="frame" x="13" y="72" width="164" height="32"/>
|
<rect key="frame" x="143" y="75" width="184" height="32"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstAttribute="width" constant="150" id="9jD-Bf-T2M"/>
|
<constraint firstAttribute="width" constant="170" id="9jD-Bf-T2M"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
|
<backgroundFilters>
|
||||||
|
<ciFilter name="CIDotScreen">
|
||||||
|
<configuration>
|
||||||
|
<real key="inputAngle" value="0.0"/>
|
||||||
|
<ciVector key="inputCenter">
|
||||||
|
<real value="150"/>
|
||||||
|
<real value="150"/>
|
||||||
|
</ciVector>
|
||||||
|
<null key="inputImage"/>
|
||||||
|
<real key="inputSharpness" value="0.69999999999999996"/>
|
||||||
|
<real key="inputWidth" value="6"/>
|
||||||
|
</configuration>
|
||||||
|
</ciFilter>
|
||||||
|
</backgroundFilters>
|
||||||
<buttonCell key="cell" type="push" title="SET_SHORTCUT" bezelStyle="rounded" alignment="center" borderStyle="border" inset="2" id="R63-tN-KVQ">
|
<buttonCell key="cell" type="push" title="SET_SHORTCUT" bezelStyle="rounded" alignment="center" borderStyle="border" inset="2" id="R63-tN-KVQ">
|
||||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
@ -130,20 +147,39 @@
|
|||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="YsQ-AZ-Aei">
|
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="YsQ-AZ-Aei">
|
||||||
<rect key="frame" x="175" y="72" width="154" height="32"/>
|
<rect key="frame" x="325" y="75" width="138" height="32"/>
|
||||||
<buttonCell key="cell" type="push" title="CLEAR_SHORTCUT" bezelStyle="rounded" alignment="center" enabled="NO" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="nvE-5d-VOS">
|
<buttonCell key="cell" type="push" title="CLEAR_SHORTCUT" bezelStyle="rounded" alignment="center" enabled="NO" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="nvE-5d-VOS">
|
||||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system" size="11"/>
|
||||||
</buttonCell>
|
</buttonCell>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="unregister:" target="AW2-rV-rbS" id="2RI-4w-6Td"/>
|
<action selector="unregister:" target="AW2-rV-rbS" id="2RI-4w-6Td"/>
|
||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
|
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="5ZK-BG-o1t">
|
||||||
|
<rect key="frame" x="42" y="85" width="100" height="16"/>
|
||||||
|
<textFieldCell key="cell" lineBreakMode="clipping" title="PREF_GLOSHO:" id="xiD-8H-p5s">
|
||||||
|
<font key="font" metaFont="system"/>
|
||||||
|
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
</textFieldCell>
|
||||||
|
</textField>
|
||||||
|
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="31d-gd-auR">
|
||||||
|
<rect key="frame" x="18" y="153" width="124" height="16"/>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstAttribute="width" constant="120" id="8dt-Pg-wFI"/>
|
||||||
|
</constraints>
|
||||||
|
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="PREF_DYN_ICON:" id="E10-ss-Cdz">
|
||||||
|
<font key="font" metaFont="system"/>
|
||||||
|
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
</textFieldCell>
|
||||||
|
</textField>
|
||||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="1TO-9H-z2d">
|
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="1TO-9H-z2d">
|
||||||
<rect key="frame" x="18" y="57" width="101" height="14"/>
|
<rect key="frame" x="148" y="60" width="101" height="14"/>
|
||||||
<textFieldCell key="cell" title="SHORTCUT_DESC" id="nYP-yi-DBf">
|
<textFieldCell key="cell" title="SHORTCUT_DESC" id="nYP-yi-DBf">
|
||||||
<font key="font" metaFont="smallSystem"/>
|
<font key="font" metaFont="smallSystem"/>
|
||||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
|
||||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
</textField>
|
</textField>
|
||||||
@ -151,19 +187,24 @@
|
|||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstAttribute="trailing" secondItem="JrH-aa-AzL" secondAttribute="trailing" constant="20" symbolic="YES" id="8iM-Xf-ShU"/>
|
<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 firstAttribute="trailing" secondItem="GSr-K5-3yw" secondAttribute="trailing" constant="20" symbolic="YES" id="AT9-5F-6g1"/>
|
||||||
<constraint firstItem="YsQ-AZ-Aei" firstAttribute="leading" secondItem="V7b-jv-oCB" secondAttribute="trailing" constant="8" symbolic="YES" id="Bk6-4V-GLk"/>
|
<constraint firstItem="YsQ-AZ-Aei" firstAttribute="leading" secondItem="V7b-jv-oCB" secondAttribute="trailing" constant="12" symbolic="YES" id="Bk6-4V-GLk"/>
|
||||||
<constraint firstItem="YsQ-AZ-Aei" firstAttribute="top" secondItem="V7b-jv-oCB" secondAttribute="top" id="CzF-dC-Jm8"/>
|
<constraint firstItem="31d-gd-auR" firstAttribute="top" secondItem="Pf1-A5-3Xz" secondAttribute="top" constant="20" symbolic="YES" id="C3K-NX-BBl"/>
|
||||||
<constraint firstItem="V7b-jv-oCB" firstAttribute="leading" secondItem="MEf-MN-oXt" secondAttribute="leading" id="El4-TW-O0d"/>
|
<constraint firstItem="YsQ-AZ-Aei" firstAttribute="top" secondItem="V7b-jv-oCB" secondAttribute="top" id="DY5-za-saX"/>
|
||||||
<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="31d-gd-auR" secondAttribute="trailing" constant="10" id="G5S-JV-re3"/>
|
||||||
<constraint firstItem="V7b-jv-oCB" firstAttribute="top" secondItem="JrH-aa-AzL" secondAttribute="bottom" constant="28" id="I62-Jw-hfy"/>
|
<constraint firstItem="V7b-jv-oCB" firstAttribute="firstBaseline" secondItem="5ZK-BG-o1t" secondAttribute="firstBaseline" id="H5D-2D-DLH"/>
|
||||||
<constraint firstItem="MEf-MN-oXt" firstAttribute="leading" secondItem="Pf1-A5-3Xz" secondAttribute="leading" constant="20" symbolic="YES" id="Imd-YJ-Ae7"/>
|
<constraint firstItem="1TO-9H-z2d" firstAttribute="leading" secondItem="V7b-jv-oCB" secondAttribute="leading" id="Imk-o0-2fS"/>
|
||||||
|
<constraint firstItem="JrH-aa-AzL" firstAttribute="leading" secondItem="MEf-MN-oXt" secondAttribute="leading" id="K2H-Af-2qK"/>
|
||||||
|
<constraint firstItem="5ZK-BG-o1t" firstAttribute="top" secondItem="JrH-aa-AzL" secondAttribute="bottom" constant="30" id="NMk-yt-fha"/>
|
||||||
<constraint firstItem="JrH-aa-AzL" firstAttribute="top" secondItem="MEf-MN-oXt" secondAttribute="bottom" constant="8" symbolic="YES" id="Vf8-fx-H50"/>
|
<constraint firstItem="JrH-aa-AzL" firstAttribute="top" secondItem="MEf-MN-oXt" secondAttribute="bottom" constant="8" symbolic="YES" id="Vf8-fx-H50"/>
|
||||||
|
<constraint firstItem="MEf-MN-oXt" firstAttribute="firstBaseline" secondItem="31d-gd-auR" secondAttribute="firstBaseline" id="W36-bE-iAT"/>
|
||||||
<constraint firstItem="1TO-9H-z2d" firstAttribute="firstBaseline" secondItem="V7b-jv-oCB" secondAttribute="baseline" constant="25" id="bJG-ed-pch"/>
|
<constraint firstItem="1TO-9H-z2d" firstAttribute="firstBaseline" secondItem="V7b-jv-oCB" secondAttribute="baseline" constant="25" id="bJG-ed-pch"/>
|
||||||
|
<constraint firstItem="V7b-jv-oCB" firstAttribute="leading" secondItem="JrH-aa-AzL" secondAttribute="leading" id="bUY-uH-N7A"/>
|
||||||
|
<constraint firstItem="5ZK-BG-o1t" firstAttribute="trailing" secondItem="31d-gd-auR" secondAttribute="trailing" id="c4g-jO-JUm"/>
|
||||||
<constraint firstAttribute="bottom" secondItem="GSr-K5-3yw" secondAttribute="bottom" constant="20" symbolic="YES" id="dAS-yW-vua"/>
|
<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"/>
|
|
||||||
<constraint firstItem="1TO-9H-z2d" firstAttribute="leading" secondItem="V7b-jv-oCB" secondAttribute="leading" id="lzx-14-MwL"/>
|
|
||||||
<constraint firstItem="GSr-K5-3yw" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="Pf1-A5-3Xz" secondAttribute="leading" constant="20" symbolic="YES" id="mTE-WD-54L"/>
|
<constraint firstItem="GSr-K5-3yw" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="Pf1-A5-3Xz" secondAttribute="leading" constant="20" symbolic="YES" id="mTE-WD-54L"/>
|
||||||
|
<constraint firstItem="31d-gd-auR" firstAttribute="leading" secondItem="Pf1-A5-3Xz" secondAttribute="leading" constant="20" symbolic="YES" id="o0J-yT-TDX"/>
|
||||||
<constraint firstAttribute="trailing" secondItem="MEf-MN-oXt" secondAttribute="trailing" constant="20" symbolic="YES" id="pJg-zj-cBs"/>
|
<constraint firstAttribute="trailing" secondItem="MEf-MN-oXt" secondAttribute="trailing" constant="20" symbolic="YES" id="pJg-zj-cBs"/>
|
||||||
|
<constraint firstItem="GSr-K5-3yw" firstAttribute="top" secondItem="1TO-9H-z2d" secondAttribute="bottom" constant="20" id="pMZ-Gx-Jmm"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
</view>
|
</view>
|
||||||
<connections>
|
<connections>
|
||||||
@ -173,11 +214,13 @@
|
|||||||
<outlet property="buttonSetShortcut" destination="V7b-jv-oCB" id="2aS-S4-cKR"/>
|
<outlet property="buttonSetShortcut" destination="V7b-jv-oCB" id="2aS-S4-cKR"/>
|
||||||
<outlet property="labelDynamicIcon" destination="JrH-aa-AzL" id="CFc-fF-oPq"/>
|
<outlet property="labelDynamicIcon" destination="JrH-aa-AzL" id="CFc-fF-oPq"/>
|
||||||
<outlet property="labelShortcut" destination="1TO-9H-z2d" id="paF-hK-78x"/>
|
<outlet property="labelShortcut" destination="1TO-9H-z2d" id="paF-hK-78x"/>
|
||||||
|
<outlet property="leftLabelDynamicIcon" destination="31d-gd-auR" id="ANZ-Zs-4d7"/>
|
||||||
|
<outlet property="leftLabelGlobalShortcut" destination="5ZK-BG-o1t" id="73E-9i-cg8"/>
|
||||||
</connections>
|
</connections>
|
||||||
</viewController>
|
</viewController>
|
||||||
<customObject id="eQC-8B-FkX" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
|
<customObject id="eQC-8B-FkX" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
|
||||||
</objects>
|
</objects>
|
||||||
<point key="canvasLocation" x="208" y="336"/>
|
<point key="canvasLocation" x="264" y="399.5"/>
|
||||||
</scene>
|
</scene>
|
||||||
</scenes>
|
</scenes>
|
||||||
</document>
|
</document>
|
||||||
|
@ -0,0 +1,75 @@
|
|||||||
|
//
|
||||||
|
// GlobalKeybindPreference.swift
|
||||||
|
// PHP Monitor
|
||||||
|
//
|
||||||
|
// Created by Nico Verbruggen on 15/04/2021.
|
||||||
|
// Copyright © 2021 Nico Verbruggen. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
struct GlobalKeybindPreference: Codable, CustomStringConvertible {
|
||||||
|
|
||||||
|
// MARK: - Internal variables
|
||||||
|
|
||||||
|
let function : Bool
|
||||||
|
let control : Bool
|
||||||
|
let command : Bool
|
||||||
|
let shift : Bool
|
||||||
|
let option : Bool
|
||||||
|
let capsLock : Bool
|
||||||
|
let carbonFlags : UInt32
|
||||||
|
let characters : String?
|
||||||
|
let keyCode : UInt32
|
||||||
|
|
||||||
|
// MARK: - How the keybind is display in Preferences
|
||||||
|
|
||||||
|
var description: String {
|
||||||
|
var stringBuilder = ""
|
||||||
|
if self.function {
|
||||||
|
stringBuilder += "Fn"
|
||||||
|
}
|
||||||
|
if self.control {
|
||||||
|
stringBuilder += "⌃"
|
||||||
|
}
|
||||||
|
if self.option {
|
||||||
|
stringBuilder += "⌥"
|
||||||
|
}
|
||||||
|
if self.command {
|
||||||
|
stringBuilder += "⌘"
|
||||||
|
}
|
||||||
|
if self.shift {
|
||||||
|
stringBuilder += "⇧"
|
||||||
|
}
|
||||||
|
if self.capsLock {
|
||||||
|
stringBuilder += "⇪"
|
||||||
|
}
|
||||||
|
if let characters = self.characters {
|
||||||
|
stringBuilder += characters.uppercased()
|
||||||
|
}
|
||||||
|
return "\(stringBuilder)"
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Persisting data to UserDefaults (as JSON)
|
||||||
|
|
||||||
|
public func toJson() -> String {
|
||||||
|
let jsonData = try! JSONEncoder().encode(self)
|
||||||
|
return String(data: jsonData, encoding: .utf8)!
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func fromJson(_ string: String?) -> GlobalKeybindPreference? {
|
||||||
|
if string == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if let jsonData = string!.data(using: .utf8) {
|
||||||
|
let decoder = JSONDecoder()
|
||||||
|
do {
|
||||||
|
return try decoder.decode(GlobalKeybindPreference.self, from: jsonData)
|
||||||
|
} catch {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
@ -12,6 +12,9 @@ import Carbon
|
|||||||
|
|
||||||
class PrefsVC: NSViewController {
|
class PrefsVC: NSViewController {
|
||||||
|
|
||||||
|
@IBOutlet weak var leftLabelDynamicIcon: NSTextField!
|
||||||
|
@IBOutlet weak var leftLabelGlobalShortcut: NSTextField!
|
||||||
|
|
||||||
@IBOutlet weak var buttonDynamicIcon: NSButton!
|
@IBOutlet weak var buttonDynamicIcon: NSButton!
|
||||||
@IBOutlet weak var labelDynamicIcon: NSTextField!
|
@IBOutlet weak var labelDynamicIcon: NSTextField!
|
||||||
@IBOutlet weak var buttonClose: NSButton!
|
@IBOutlet weak var buttonClose: NSButton!
|
||||||
@ -20,26 +23,6 @@ class PrefsVC: NSViewController {
|
|||||||
@IBOutlet weak var buttonClearShortcut: NSButton!
|
@IBOutlet weak var buttonClearShortcut: NSButton!
|
||||||
@IBOutlet weak var labelShortcut: NSTextField!
|
@IBOutlet weak var labelShortcut: NSTextField!
|
||||||
|
|
||||||
// MARK: - Variables
|
|
||||||
|
|
||||||
var listening = false {
|
|
||||||
didSet {
|
|
||||||
if listening {
|
|
||||||
DispatchQueue.main.async { [weak self] in
|
|
||||||
self?.buttonSetShortcut.highlight(true)
|
|
||||||
self?.buttonSetShortcut.title = "prefs.shortcut_listening".localized
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
DispatchQueue.main.async { [weak self] in
|
|
||||||
self?.buttonSetShortcut.highlight(false)
|
|
||||||
if (App.shared.shortcutHotkey == nil) {
|
|
||||||
self?.buttonSetShortcut.title = "prefs.shortcut_set".localized
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Display
|
// MARK: - Display
|
||||||
|
|
||||||
public static func show(delegate: NSWindowDelegate? = nil) {
|
public static func show(delegate: NSWindowDelegate? = nil) {
|
||||||
@ -62,32 +45,73 @@ class PrefsVC: NSViewController {
|
|||||||
// MARK: - Lifecycle
|
// MARK: - Lifecycle
|
||||||
|
|
||||||
override func viewWillAppear() {
|
override func viewWillAppear() {
|
||||||
// Load localization
|
loadLocalization()
|
||||||
buttonDynamicIcon.title = "prefs.dynamic_icon_title".localized
|
loadDynamicIconFromPreferences()
|
||||||
|
loadGlobalKeybindFromPreferences()
|
||||||
|
}
|
||||||
|
|
||||||
|
override func viewWillDisappear() {
|
||||||
|
if self.listeningForGlobalHotkey {
|
||||||
|
listeningForGlobalHotkey = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func loadLocalization() {
|
||||||
|
// Dynamic icon
|
||||||
|
leftLabelDynamicIcon.stringValue = "prefs.dynamic_icon".localized
|
||||||
labelDynamicIcon.stringValue = "prefs.dynamic_icon_desc".localized
|
labelDynamicIcon.stringValue = "prefs.dynamic_icon_desc".localized
|
||||||
buttonClose.title = "prefs.close".localized
|
buttonDynamicIcon.title = "prefs.dynamic_icon_title".localized
|
||||||
|
|
||||||
|
// Global Shortcut
|
||||||
|
leftLabelGlobalShortcut.stringValue = "prefs.global_shortcut".localized
|
||||||
labelShortcut.stringValue = "prefs.shortcut_desc".localized
|
labelShortcut.stringValue = "prefs.shortcut_desc".localized
|
||||||
buttonSetShortcut.title = "prefs.shortcut_set".localized
|
buttonSetShortcut.title = "prefs.shortcut_set".localized
|
||||||
buttonClearShortcut.title = "prefs.shortcut_clear".localized
|
buttonClearShortcut.title = "prefs.shortcut_clear".localized
|
||||||
|
|
||||||
let prefs = Preferences.preferences
|
// Close button
|
||||||
|
buttonClose.title = "prefs.close".localized
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Dynamic Icon Preference
|
||||||
|
|
||||||
|
func loadDynamicIconFromPreferences() {
|
||||||
|
let shouldDisplay = Preferences.preferences[.shouldDisplayDynamicIcon] as! Bool == true
|
||||||
|
self.buttonDynamicIcon.state = shouldDisplay ? .on : .off
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Shortcut Preference
|
||||||
|
// Adapted from: https://dev.to/mitchartemis/creating-a-global-configurable-shortcut-for-macos-apps-in-swift-25e9
|
||||||
|
|
||||||
|
var listeningForGlobalHotkey = false {
|
||||||
|
didSet {
|
||||||
|
if listeningForGlobalHotkey {
|
||||||
|
DispatchQueue.main.async { [weak self] in
|
||||||
|
self?.buttonSetShortcut.highlight(true)
|
||||||
|
self?.buttonSetShortcut.title = "prefs.shortcut_listening".localized
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
DispatchQueue.main.async { [weak self] in
|
||||||
|
self?.buttonSetShortcut.highlight(false)
|
||||||
|
self?.loadGlobalKeybindFromPreferences()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadGlobalKeybindFromPreferences() {
|
||||||
|
let globalKeybind = GlobalKeybindPreference.fromJson(Preferences.preferences[.globalHotkey] as! String?)
|
||||||
|
|
||||||
// Load dynamic icon
|
|
||||||
self.buttonDynamicIcon.state = (prefs[.shouldDisplayDynamicIcon] as! Bool == true) ? .on : .off
|
|
||||||
|
|
||||||
// Load global keybind initial state
|
|
||||||
let globalKeybind = GlobalKeybindPreference.fromJson(prefs[.globalHotkey] as! String?)
|
|
||||||
if (globalKeybind != nil) {
|
if (globalKeybind != nil) {
|
||||||
updateKeybindButton(globalKeybind!)
|
updateKeybindButton(globalKeybind!)
|
||||||
|
} else {
|
||||||
|
buttonSetShortcut.title = "prefs.shortcut_set".localized
|
||||||
}
|
}
|
||||||
|
|
||||||
buttonClearShortcut.isEnabled = globalKeybind != nil
|
buttonClearShortcut.isEnabled = globalKeybind != nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Shortcut
|
|
||||||
// Adapted from: https://dev.to/mitchartemis/creating-a-global-configurable-shortcut-for-macos-apps-in-swift-25e9
|
|
||||||
|
|
||||||
func updateGlobalShortcut(_ event : NSEvent) {
|
func updateGlobalShortcut(_ event : NSEvent) {
|
||||||
self.listening = false
|
self.listeningForGlobalHotkey = false
|
||||||
|
|
||||||
if let characters = event.charactersIgnoringModifiers {
|
if let characters = event.charactersIgnoringModifiers {
|
||||||
let newGlobalKeybind = GlobalKeybindPreference.init(
|
let newGlobalKeybind = GlobalKeybindPreference.init(
|
||||||
@ -118,12 +142,12 @@ class PrefsVC: NSViewController {
|
|||||||
|
|
||||||
@IBAction func register(_ sender: Any) {
|
@IBAction func register(_ sender: Any) {
|
||||||
unregister(nil)
|
unregister(nil)
|
||||||
listening = true
|
listeningForGlobalHotkey = true
|
||||||
view.window?.makeFirstResponder(nil)
|
view.window?.makeFirstResponder(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
@IBAction func unregister(_ sender: Any?) {
|
@IBAction func unregister(_ sender: Any?) {
|
||||||
listening = false
|
listeningForGlobalHotkey = false
|
||||||
App.shared.shortcutHotkey = nil
|
App.shared.shortcutHotkey = nil
|
||||||
buttonSetShortcut.title = ""
|
buttonSetShortcut.title = ""
|
||||||
|
|
||||||
@ -159,69 +183,3 @@ class PrefsVC: NSViewController {
|
|||||||
print("VC deallocated")
|
print("VC deallocated")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct GlobalKeybindPreference: Codable, CustomStringConvertible {
|
|
||||||
|
|
||||||
// MARK: - Internal variables
|
|
||||||
|
|
||||||
let function : Bool
|
|
||||||
let control : Bool
|
|
||||||
let command : Bool
|
|
||||||
let shift : Bool
|
|
||||||
let option : Bool
|
|
||||||
let capsLock : Bool
|
|
||||||
let carbonFlags : UInt32
|
|
||||||
let characters : String?
|
|
||||||
let keyCode : UInt32
|
|
||||||
|
|
||||||
// MARK: - How the keybind is display in Preferences
|
|
||||||
|
|
||||||
var description: String {
|
|
||||||
var stringBuilder = ""
|
|
||||||
if self.function {
|
|
||||||
stringBuilder += "Fn"
|
|
||||||
}
|
|
||||||
if self.control {
|
|
||||||
stringBuilder += "⌃"
|
|
||||||
}
|
|
||||||
if self.option {
|
|
||||||
stringBuilder += "⌥"
|
|
||||||
}
|
|
||||||
if self.command {
|
|
||||||
stringBuilder += "⌘"
|
|
||||||
}
|
|
||||||
if self.shift {
|
|
||||||
stringBuilder += "⇧"
|
|
||||||
}
|
|
||||||
if self.capsLock {
|
|
||||||
stringBuilder += "⇪"
|
|
||||||
}
|
|
||||||
if let characters = self.characters {
|
|
||||||
stringBuilder += characters.uppercased()
|
|
||||||
}
|
|
||||||
return "\(stringBuilder)"
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Persisting data to UserDefaults (as JSON)
|
|
||||||
|
|
||||||
public func toJson() -> String {
|
|
||||||
let jsonData = try! JSONEncoder().encode(self)
|
|
||||||
return String(data: jsonData, encoding: .utf8)!
|
|
||||||
}
|
|
||||||
|
|
||||||
public static func fromJson(_ string: String?) -> GlobalKeybindPreference? {
|
|
||||||
if string == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if let jsonData = string!.data(using: .utf8) {
|
|
||||||
let decoder = JSONDecoder()
|
|
||||||
do {
|
|
||||||
return try decoder.decode(GlobalKeybindPreference.self, from: jsonData)
|
|
||||||
} catch {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -8,17 +8,27 @@
|
|||||||
|
|
||||||
import Cocoa
|
import Cocoa
|
||||||
|
|
||||||
|
struct Keys {
|
||||||
|
static let Escape = 53
|
||||||
|
static let Space = 49
|
||||||
|
}
|
||||||
|
|
||||||
class PrefsWC: NSWindowController {
|
class PrefsWC: NSWindowController {
|
||||||
|
|
||||||
override func windowDidLoad() {
|
override func windowDidLoad() {
|
||||||
super.windowDidLoad()
|
super.windowDidLoad()
|
||||||
}
|
}
|
||||||
|
|
||||||
override func keyDown(with event: NSEvent) {
|
override func keyDown(with event: NSEvent) {
|
||||||
super.keyDown(with: event)
|
super.keyDown(with: event)
|
||||||
|
|
||||||
if let vc = self.contentViewController as? PrefsVC {
|
if let vc = self.contentViewController as? PrefsVC {
|
||||||
if vc.listening {
|
if vc.listeningForGlobalHotkey {
|
||||||
vc.updateGlobalShortcut(event)
|
if event.keyCode == Keys.Escape || event.keyCode == Keys.Space {
|
||||||
|
print("A blacklisted key was pressed, canceling listen")
|
||||||
|
vc.listeningForGlobalHotkey = false
|
||||||
|
} else {
|
||||||
|
vc.updateGlobalShortcut(event)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,14 +46,19 @@
|
|||||||
|
|
||||||
// PREFERENCES
|
// PREFERENCES
|
||||||
|
|
||||||
"prefs.title" = "PHP Monitor: Preferences";
|
"prefs.title" = "PHP Monitor";
|
||||||
"prefs.close" = "Close";
|
"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.";
|
"prefs.global_shortcut" = "Global shortcut:";
|
||||||
|
"prefs.dynamic_icon" = "Dynamic icon:";
|
||||||
|
|
||||||
|
"prefs.dynamic_icon_title" = "Display dynamic icon in 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\ncurrently linked PHP version.";
|
||||||
|
|
||||||
"prefs.shortcut_set" = "Set global shortcut";
|
"prefs.shortcut_set" = "Set global shortcut";
|
||||||
"prefs.shortcut_listening" = "<press for shortcut>";
|
"prefs.shortcut_listening" = "<listening for keypress>";
|
||||||
"prefs.shortcut_clear" = "Clear";
|
"prefs.shortcut_clear" = "Clear";
|
||||||
"prefs.shortcut_desc" = "If a shortcut combination is set up, you can toggle PHP Monitor\nwherever you are by pressing the key combination you chose.";
|
"prefs.shortcut_desc" = "If a shortcut combination is set up, you can toggle PHP Monitor\nwherever you are by pressing the key combination you chose.\n(Cancel choosing a shortcut by pressing the spacebar.)";
|
||||||
|
|
||||||
// NOTIFICATIONS
|
// NOTIFICATIONS
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user