Skip to content

Commit 376db25

Browse files
Add contrast level indicator to picker
When enabled, a new label will show up in the picker detail view. The label will show the WCAG contrast level between the currently color and the previously picked one. The background color of the label is also the previously picked color to provide a visualization of the contrast.
1 parent 5daf000 commit 376db25

2 files changed

Lines changed: 81 additions & 31 deletions

File tree

Pixel Picker/OverlayPanel/PPOverlayController.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ class PPOverlayController: NSWindowController {
1818
@IBOutlet weak var infoWrapper: NSView!
1919
@IBOutlet weak var infoFormatField: NSTextField!
2020
@IBOutlet weak var infoDetailField: NSTextField!
21+
@IBOutlet weak var infoContrastView: NSView!
22+
@IBOutlet weak var infoContrastField: NSTextField!
2123

2224
// This mode increases the picker's size, increases the magnification and also slows down move
2325
// events to make it easier to pick the right pixel. We dissociate the mouse (input) from the
@@ -66,6 +68,8 @@ class PPOverlayController: NSWindowController {
6668
infoWrapper.wantsLayer = true
6769
infoWrapper.layer?.cornerRadius = 8
6870
infoWrapper.layer?.backgroundColor = NSColor.black.cgColor
71+
infoContrastView.wantsLayer = true
72+
infoContrastView.layer?.cornerRadius = 3
6973

7074
// For some reason if we don't listen for events this way we miss the escape key.
7175
NSEvent.addLocalMonitorForEvents(matching: [.keyDown]) {
@@ -274,6 +278,19 @@ class PPOverlayController: NSWindowController {
274278
infoDetailField.textColor = contrastingColor
275279
infoFormatField.stringValue = PPState.shared.chosenFormat.rawValue
276280
infoDetailField.stringValue = PPState.shared.chosenFormat.asComponentString(withColor: color)
281+
282+
if let previousPick = PPState.shared.recentPicks.last, PPState.shared.showWCAGLevel {
283+
infoContrastView.isHidden = false
284+
285+
let wcagLevel = WCAGLevel(contrastRatio: color.contrastRatio(to: previousPick.color))
286+
infoContrastField.stringValue = wcagLevel.rawValue
287+
288+
infoContrastView.layer?.backgroundColor = previousPick.color.cgColor
289+
infoContrastField.textColor = previousPick.color.bestContrastingColor()
290+
} else {
291+
infoContrastView.isHidden = true
292+
}
293+
277294
resizeInfoPanel()
278295
}
279296

Pixel Picker/OverlayPanel/PPOverlayController.xib

Lines changed: 64 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14109" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
2+
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="16096" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
33
<dependencies>
4-
<deployment identifier="macosx"/>
5-
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14109"/>
4+
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="16096"/>
65
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
76
</dependencies>
87
<objects>
@@ -20,6 +19,8 @@
2019
</customObject>
2120
<customObject id="ECQ-9M-Pkg" customClass="PPOverlayController" customModule="PixelPicker" customModuleProvider="target">
2221
<connections>
22+
<outlet property="infoContrastField" destination="iRx-oZ-llC" id="gxr-6f-BkE"/>
23+
<outlet property="infoContrastView" destination="dIL-Oc-RkF" id="8ya-Ai-pt6"/>
2324
<outlet property="infoDetailField" destination="Re2-GH-fyd" id="K03-75-cf9"/>
2425
<outlet property="infoFormatField" destination="1fa-UE-yMM" id="Nan-fO-kbu"/>
2526
<outlet property="infoPanel" destination="OMO-LB-w57" id="GGj-Y6-LfU"/>
@@ -30,11 +31,11 @@
3031
<outlet property="wrapper" destination="acW-WA-gq2" id="Mpu-0H-rtC"/>
3132
</connections>
3233
</customObject>
33-
<window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" restorable="NO" oneShot="NO" showsToolbarButton="NO" visibleAtLaunch="NO" frameAutosaveName="" animationBehavior="default" id="gZA-A3-IZ5" customClass="PPOverlayPanel" customModule="PixelPicker" customModuleProvider="target">
34+
<window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" restorable="NO" visibleAtLaunch="NO" frameAutosaveName="" animationBehavior="default" id="gZA-A3-IZ5" customClass="PPOverlayPanel" customModule="PixelPicker" customModuleProvider="target">
3435
<windowStyleMask key="styleMask" utility="YES" nonactivatingPanel="YES"/>
3536
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
3637
<rect key="contentRect" x="196" y="132" width="101" height="101"/>
37-
<rect key="screenRect" x="0.0" y="0.0" width="1680" height="1028"/>
38+
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="877"/>
3839
<view key="contentView" id="acW-WA-gq2" customClass="PPOverlayWrapper" customModule="PixelPicker" customModuleProvider="target">
3940
<rect key="frame" x="0.0" y="0.0" width="101" height="101"/>
4041
<autoresizingMask key="autoresizingMask"/>
@@ -52,38 +53,70 @@
5253
</view>
5354
<point key="canvasLocation" x="236" y="82"/>
5455
</window>
55-
<window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" restorable="NO" oneShot="NO" showsToolbarButton="NO" visibleAtLaunch="NO" frameAutosaveName="" animationBehavior="default" id="OMO-LB-w57" customClass="PPOverlayPanel" customModule="PixelPicker" customModuleProvider="target">
56+
<window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" restorable="NO" visibleAtLaunch="NO" frameAutosaveName="" animationBehavior="default" id="OMO-LB-w57" customClass="PPOverlayPanel" customModule="PixelPicker" customModuleProvider="target">
5657
<windowStyleMask key="styleMask" utility="YES" nonactivatingPanel="YES"/>
5758
<rect key="contentRect" x="926" y="538" width="100" height="50"/>
58-
<rect key="screenRect" x="0.0" y="0.0" width="1680" height="1028"/>
59-
<view key="contentView" id="HED-rR-FDP">
59+
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="877"/>
60+
<view key="contentView" misplaced="YES" id="HED-rR-FDP">
6061
<rect key="frame" x="0.0" y="0.0" width="100" height="50"/>
61-
<autoresizingMask key="autoresizingMask"/>
62+
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
6263
<subviews>
63-
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="1fa-UE-yMM">
64-
<rect key="frame" x="-2" y="25" width="104" height="17"/>
65-
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="Label" id="RkG-Wy-Shq">
66-
<font key="font" metaFont="system"/>
67-
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
68-
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
69-
</textFieldCell>
70-
</textField>
71-
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Re2-GH-fyd">
72-
<rect key="frame" x="-2" y="8" width="104" height="14"/>
73-
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="Label" id="IYd-1Y-7cd">
74-
<font key="font" metaFont="smallSystem"/>
75-
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
76-
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
77-
</textFieldCell>
78-
</textField>
64+
<stackView distribution="fill" orientation="vertical" alignment="centerX" spacing="4" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="GvI-6B-Cz3">
65+
<rect key="frame" x="0.0" y="8" width="163" height="56"/>
66+
<subviews>
67+
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="1fa-UE-yMM">
68+
<rect key="frame" x="61" y="40" width="41" height="16"/>
69+
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="Label" id="RkG-Wy-Shq">
70+
<font key="font" metaFont="system"/>
71+
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
72+
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
73+
</textFieldCell>
74+
</textField>
75+
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Re2-GH-fyd">
76+
<rect key="frame" x="63" y="22" width="37" height="14"/>
77+
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="Label" id="IYd-1Y-7cd">
78+
<font key="font" metaFont="label" size="11"/>
79+
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
80+
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
81+
</textFieldCell>
82+
</textField>
83+
<customView translatesAutoresizingMaskIntoConstraints="NO" id="dIL-Oc-RkF">
84+
<rect key="frame" x="0.0" y="0.0" width="163" height="18"/>
85+
<subviews>
86+
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="iRx-oZ-llC">
87+
<rect key="frame" x="2" y="2" width="159" height="14"/>
88+
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="Label" id="WGV-Vi-VsP">
89+
<font key="font" metaFont="label" size="11"/>
90+
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
91+
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
92+
</textFieldCell>
93+
</textField>
94+
</subviews>
95+
<constraints>
96+
<constraint firstAttribute="trailing" secondItem="iRx-oZ-llC" secondAttribute="trailing" constant="4" id="N7S-Bx-3p1"/>
97+
<constraint firstAttribute="bottom" secondItem="iRx-oZ-llC" secondAttribute="bottom" constant="2" id="cN6-Qx-Meg"/>
98+
<constraint firstItem="iRx-oZ-llC" firstAttribute="leading" secondItem="dIL-Oc-RkF" secondAttribute="leading" constant="4" id="pS4-Xb-76o"/>
99+
<constraint firstItem="iRx-oZ-llC" firstAttribute="top" secondItem="dIL-Oc-RkF" secondAttribute="top" constant="2" id="xNR-KQ-YT8"/>
100+
</constraints>
101+
</customView>
102+
</subviews>
103+
<visibilityPriorities>
104+
<integer value="1000"/>
105+
<integer value="1000"/>
106+
<integer value="1000"/>
107+
</visibilityPriorities>
108+
<customSpacing>
109+
<real value="3.4028234663852886e+38"/>
110+
<real value="3.4028234663852886e+38"/>
111+
<real value="3.4028234663852886e+38"/>
112+
</customSpacing>
113+
</stackView>
79114
</subviews>
80115
<constraints>
81-
<constraint firstItem="1fa-UE-yMM" firstAttribute="leading" secondItem="HED-rR-FDP" secondAttribute="leading" id="23z-pW-nAx"/>
82-
<constraint firstItem="1fa-UE-yMM" firstAttribute="top" secondItem="HED-rR-FDP" secondAttribute="top" constant="8" id="G1j-j5-iWY"/>
83-
<constraint firstItem="Re2-GH-fyd" firstAttribute="leading" secondItem="HED-rR-FDP" secondAttribute="leading" id="aZf-QY-Lpd"/>
84-
<constraint firstAttribute="bottom" secondItem="Re2-GH-fyd" secondAttribute="bottom" constant="8" id="amm-jV-oWa"/>
85-
<constraint firstAttribute="trailing" secondItem="1fa-UE-yMM" secondAttribute="trailing" id="flM-Te-2qj"/>
86-
<constraint firstAttribute="trailing" secondItem="Re2-GH-fyd" secondAttribute="trailing" id="jWO-5f-uxW"/>
116+
<constraint firstItem="GvI-6B-Cz3" firstAttribute="leading" secondItem="HED-rR-FDP" secondAttribute="leading" id="3zK-14-Xf5"/>
117+
<constraint firstAttribute="bottom" secondItem="GvI-6B-Cz3" secondAttribute="bottom" constant="8" id="apf-V6-NGV"/>
118+
<constraint firstItem="GvI-6B-Cz3" firstAttribute="top" secondItem="HED-rR-FDP" secondAttribute="top" constant="8" id="dK9-Wq-zGV"/>
119+
<constraint firstAttribute="trailing" secondItem="GvI-6B-Cz3" secondAttribute="trailing" id="mj1-AT-sJL"/>
87120
</constraints>
88121
</view>
89122
<point key="canvasLocation" x="236" y="230"/>

0 commit comments

Comments
 (0)