updated submodules

This commit is contained in:
Balackburn
2023-06-27 14:19:24 +02:00
parent 767b3b7798
commit 036ad6b006
1412 changed files with 18 additions and 83422 deletions

6
.gitmodules vendored
View File

@@ -31,9 +31,6 @@
[submodule "Tweaks/iSponsorBlock"]
path = Tweaks/iSponsorBlock
url = https://github.com/Galactic-Dev/iSponsorBlock.git
[submodule "Extensions"]
path = Extensions
url = https://github.com/CokePokes/YoutubeExtensions.git
[submodule "Tweaks/YTHoldForSpeed"]
path = Tweaks/YTHoldForSpeed
url = https://github.com/arichorn/YTHoldForSpeed.git
@@ -43,3 +40,6 @@
[submodule "Tweaks/YTLite"]
path = Tweaks/YTLite
url = https://github.com/dayanch96/YTLite.git
[submodule "Extensions"]
path = Extensions
url = https://github.com/CokePokes/YoutubeExtensions.git

1
Extensions Submodule

Submodule Extensions added at a68d70883d

View File

@@ -1,2 +0,0 @@
# Auto detect text files and perform LF normalization
* text=auto

View File

@@ -1 +0,0 @@
.DS_Store

View File

@@ -1,333 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>files</key>
<dict>
<key>Info.plist</key>
<data>
5KaPBsMVTGZfcc05Od8nGW6/EyQ=
</data>
<key>_locales/en/messages.json</key>
<data>
8cPkszxzYFSjhRWsf34A0AiHaPM=
</data>
<key>background.js</key>
<data>
tClFxbnUm0L65Qj+Qu8Fk9asL2o=
</data>
<key>content.js</key>
<data>
a6o4B4PMlrIOBXlniU2NS4D9SJE=
</data>
<key>embedded.mobileprovision</key>
<data>
dVGLS8Qpu/eCI1J5VCu9IfYq3Z4=
</data>
<key>images/cat_1.0.gif</key>
<data>
DtSTnvB7wRt647kM1b38KLfDfXA=
</data>
<key>images/icon-128.png</key>
<data>
rYa1lv1LgkO3fkP9h6gRSjlQgqk=
</data>
<key>images/icon-256.png</key>
<data>
05xbekvTg28KsH9RRIKQRL8tqQs=
</data>
<key>images/icon-48.png</key>
<data>
BWUZe8raKzOzA2cDWIYFoBPxxw8=
</data>
<key>images/icon-512.png</key>
<data>
shzpVHJMsAu4q820Fb+YzByiFhc=
</data>
<key>images/icon-64.png</key>
<data>
HZC4YIb4ZLg4lpjNAKFqSaka6r0=
</data>
<key>images/icon-96.png</key>
<data>
IPAOd1HfCtCI7ybhVhwA5TU/BZ8=
</data>
<key>images/toolbar-icon-16.png</key>
<data>
Bkb2Cy8VYIcWl7wFZ2HcWZcCoyA=
</data>
<key>images/toolbar-icon-19.png</key>
<data>
XLkdODJ73CVbwn/1LCAsfB6scPg=
</data>
<key>images/toolbar-icon-32.png</key>
<data>
0cQgf/z3urGdzsmtmc2Wnim1+lg=
</data>
<key>images/toolbar-icon-38.png</key>
<data>
eas7Tl3/r2JMZf6nK84ZjoBJrZo=
</data>
<key>images/toolbar-icon-48.png</key>
<data>
fxyz1xgkIR877Cf/7uYNUqXrxoM=
</data>
<key>images/toolbar-icon-72.png</key>
<data>
pHL3CJwjPY30T9sFvvcA2qlraBw=
</data>
<key>manifest.json</key>
<data>
b37QyqMYHlvlfOjbvJLOKeAM5Y4=
</data>
<key>popup.css</key>
<data>
mXR2qQxu+ceMOItNpc4aImux5wY=
</data>
<key>popup.html</key>
<data>
zTk6QImmvcZjMYLQY8ek+cqSEWg=
</data>
<key>popup.js</key>
<data>
grmSQBg1aRbGzHHjd3TWHS/HbOY=
</data>
</dict>
<key>files2</key>
<dict>
<key>_locales/en/messages.json</key>
<dict>
<key>hash2</key>
<data>
4pOaVgBrOGGIoI81XdEOZidIyW9peYtz85HIYX7d1QE=
</data>
</dict>
<key>background.js</key>
<dict>
<key>hash2</key>
<data>
2S7ONYvdkGsryEavyrR7nMCTwsjNGqMV2BSWIxWLSYg=
</data>
</dict>
<key>content.js</key>
<dict>
<key>hash2</key>
<data>
9CYz6yZ8bRI2JRzRwnn4DOGuPuy2GSsOudXSZU6s1po=
</data>
</dict>
<key>embedded.mobileprovision</key>
<dict>
<key>hash2</key>
<data>
4TQyzTTz0VYUTM0IXf2PMSufVEkzd4WlPWbwKMyfKfQ=
</data>
</dict>
<key>images/cat_1.0.gif</key>
<dict>
<key>hash2</key>
<data>
65Ql3FhfivRMoMifbuY5KK8I/1rZx/Zmmwsx1La4OyI=
</data>
</dict>
<key>images/icon-128.png</key>
<dict>
<key>hash2</key>
<data>
TV8I8bcVP9rAnVA4AJRAWtkJveIenMpYsd/7+rsMLzo=
</data>
</dict>
<key>images/icon-256.png</key>
<dict>
<key>hash2</key>
<data>
kksdsW0Y1svz0bT0i3UzQGBmBDxJGr2eTCZmaqTS+XM=
</data>
</dict>
<key>images/icon-48.png</key>
<dict>
<key>hash2</key>
<data>
mBNPpZ78p0eH4WsNdF/EXw/sFHq5f8PqERARlLulYbY=
</data>
</dict>
<key>images/icon-512.png</key>
<dict>
<key>hash2</key>
<data>
waQn18oFc3GbhXXm2HEn6xFQk3HKehp9crGljWAMsGQ=
</data>
</dict>
<key>images/icon-64.png</key>
<dict>
<key>hash2</key>
<data>
CJwxajQk49Cd0RfR22yEPO6pjDbg+Aa4Ocxi+812CiM=
</data>
</dict>
<key>images/icon-96.png</key>
<dict>
<key>hash2</key>
<data>
zuzRjCepizxOWXh9ftCPth38GUxy1Ea/4zS3dw19OXo=
</data>
</dict>
<key>images/toolbar-icon-16.png</key>
<dict>
<key>hash2</key>
<data>
xmXH4YHb+Pq/YuC1e8JLIun93LuM3+/8MvB3r8oTKls=
</data>
</dict>
<key>images/toolbar-icon-19.png</key>
<dict>
<key>hash2</key>
<data>
qSX/1Ux4BOUIhixJK5NkvyTomLwp0yISfsQ97uF8/5g=
</data>
</dict>
<key>images/toolbar-icon-32.png</key>
<dict>
<key>hash2</key>
<data>
pGDg4NcSdD5EQaZgaiwxNosbSEXmZnpRc79RfitKc1c=
</data>
</dict>
<key>images/toolbar-icon-38.png</key>
<dict>
<key>hash2</key>
<data>
BUU3dwrCSvNOiFkBQWdPkrwASjUvxSxbizW+Izt3LBA=
</data>
</dict>
<key>images/toolbar-icon-48.png</key>
<dict>
<key>hash2</key>
<data>
JLZV5da+fZkfw0m2KfMqHSixWBCJvZoUNlt3la7gm54=
</data>
</dict>
<key>images/toolbar-icon-72.png</key>
<dict>
<key>hash2</key>
<data>
TwM7A1Bkuv4C3SWorFNwG+w38mWo3TaMtglLdDXxcFw=
</data>
</dict>
<key>manifest.json</key>
<dict>
<key>hash2</key>
<data>
+nWdvS9ap7YzpjqKSWsGUHP5K2irkTGozQX/tI4WrYc=
</data>
</dict>
<key>popup.css</key>
<dict>
<key>hash2</key>
<data>
LIfF3an8mzKIMD8PDhKILnrZBhxxSTzoZQKyRiyWuB0=
</data>
</dict>
<key>popup.html</key>
<dict>
<key>hash2</key>
<data>
9Ro1fCC5Meq0eSNrYab7V3uc4tNvmwRqMsCb1757M6Q=
</data>
</dict>
<key>popup.js</key>
<dict>
<key>hash2</key>
<data>
ruLXAORE+vDoLKPGBSkl7hnXv8V+ZexCoX3KvJyHxBk=
</data>
</dict>
</dict>
<key>rules</key>
<dict>
<key>^.*</key>
<true/>
<key>^.*\.lproj/</key>
<dict>
<key>optional</key>
<true/>
<key>weight</key>
<real>1000</real>
</dict>
<key>^.*\.lproj/locversion.plist$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>1100</real>
</dict>
<key>^Base\.lproj/</key>
<dict>
<key>weight</key>
<real>1010</real>
</dict>
<key>^version.plist$</key>
<true/>
</dict>
<key>rules2</key>
<dict>
<key>.*\.dSYM($|/)</key>
<dict>
<key>weight</key>
<real>11</real>
</dict>
<key>^(.*/)?\.DS_Store$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>2000</real>
</dict>
<key>^.*</key>
<true/>
<key>^.*\.lproj/</key>
<dict>
<key>optional</key>
<true/>
<key>weight</key>
<real>1000</real>
</dict>
<key>^.*\.lproj/locversion.plist$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>1100</real>
</dict>
<key>^Base\.lproj/</key>
<dict>
<key>weight</key>
<real>1010</real>
</dict>
<key>^Info\.plist$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>20</real>
</dict>
<key>^PkgInfo$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>20</real>
</dict>
<key>^embedded\.provisionprofile$</key>
<dict>
<key>weight</key>
<real>20</real>
</dict>
<key>^version\.plist$</key>
<dict>
<key>weight</key>
<real>20</real>
</dict>
</dict>
</dict>
</plist>

View File

@@ -1,10 +0,0 @@
{
"extension_name": {
"message": "OpenYoutube",
"description": "The display name for the extension."
},
"extension_description": {
"message": "Displays an Open in Youtube alert for sideloaded YT",
"description": "Description of what the extension does."
}
}

View File

@@ -1,6 +0,0 @@
browser.runtime.onMessage.addListener((request, sender, sendResponse) => {
console.log("Received request: ", request);
if (request.greeting === "hello")
sendResponse({ farewell: "goodbye" });
});

View File

@@ -1,25 +0,0 @@
browser.runtime.sendMessage({ greeting: "hello" }).then((response) => {
console.log("Received response: ", response);
});
browser.runtime.onMessage.addListener((request, sender, sendResponse) => {
console.log("Received request: ", request);
});
function afterNavigate() {
if ('/watch' === location.pathname) {
window.location.href = `youtube://${window.location.pathname.slice(1)}${
window.location.search
}${window.location.hash}`;
}
}
(document.body || document.documentElement).addEventListener('transitionend',
function(/*TransitionEvent*/ event) {
if (event.propertyName === 'width' && event.target.id === 'progress') {
afterNavigate();
}
}, true);
// After page load
afterNavigate();

Binary file not shown.

Before

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 454 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 569 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 919 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

View File

@@ -1,40 +0,0 @@
{
"manifest_version": 2,
"default_locale": "en",
"name": "__MSG_extension_name__",
"description": "__MSG_extension_description__",
"version": "1.0",
"icons": {
"48": "images/icon-48.png",
"96": "images/icon-96.png",
"128": "images/icon-128.png",
"256": "images/icon-256.png",
"512": "images/icon-512.png"
},
"background": {
"scripts": [ "background.js" ],
"persistent": false
},
"content_scripts": [{
"js": [ "content.js" ],
"matches": [ "*://*.youtube.com/*" ]
}],
"browser_action": {
"default_popup": "popup.html",
"default_icon": {
"16": "images/toolbar-icon-16.png",
"19": "images/toolbar-icon-19.png",
"32": "images/toolbar-icon-32.png",
"38": "images/toolbar-icon-38.png",
"48": "images/toolbar-icon-48.png",
"72": "images/toolbar-icon-72.png"
}
},
"permissions": [ ]
}

View File

@@ -1,15 +0,0 @@
:root {
color-scheme: light dark;
}
body {
width: 100px;
padding: 10px;
font-family: system-ui;
text-align: center;
}
@media (prefers-color-scheme: dark) {
/* Dark Mode styles go here. */
}

View File

@@ -1,21 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="popup.css">
<script type="module" src="popup.js"></script>
</head>
<style>
body {
background-image:url('images/cat_1.0.gif');
background-size:100%;
background-repeat: repeat-y;
background-attachment: fixed;
height:100%;
width:100%;
}
</style>
<body>
<strong>Extension made by @CokePokes</strong>
</body>
</html>

View File

@@ -1 +0,0 @@
console.log("Hello World!", browser);

View File

@@ -1,20 +0,0 @@
# YoutubeExtensions
appex extensions for sideloaded YT
What is this?
These plugins enable "Open In" for sideloaded Youtube without any need to download other Opener apps /Shortcuts.
How to install:
1. Download the .appex files here
2. Unzip Youtube.ipa & copy them to /Payload/Youtube.app/Plugins
3. Compress Payload folder & rename .zip to .ipa
4. Sign & Install onto device
5. Open YouTube once & then open Safari to enable the iOS 15 safari plugin [prompted always allow - do it]
6. Press the Share icon in Safari scroll app list > More > Enable Youtube
Done!

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -1,157 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>files</key>
<dict>
<key>Base.lproj/MainInterface.storyboardc/Info.plist</key>
<data>
Bgt43YuQd48Y7NBkKAH/I1Nd+7Q=
</data>
<key>Base.lproj/MainInterface.storyboardc/UIViewController-j1y-V4-xli.nib</key>
<data>
t/rVTMy59WLCl0e0ydlT2JlJKIs=
</data>
<key>Base.lproj/MainInterface.storyboardc/j1y-V4-xli-view-wbc-yd-nQP.nib</key>
<data>
56s4vIzFNrq5HEvB3Mr6qnqVRFg=
</data>
<key>Info.plist</key>
<data>
7+n2S5sS/Ngeoe21gJMc6iC6+ac=
</data>
<key>embedded.mobileprovision</key>
<data>
dVGLS8Qpu/eCI1J5VCu9IfYq3Z4=
</data>
<key>icon.png</key>
<data>
/pip+c1EETgjhxNcOhgiyQxxzyU=
</data>
</dict>
<key>files2</key>
<dict>
<key>Base.lproj/MainInterface.storyboardc/Info.plist</key>
<dict>
<key>hash2</key>
<data>
Qnp5pVqL/lRCSEISDYZs1VBLxfcEnfpOzHg6WgcgLgk=
</data>
</dict>
<key>Base.lproj/MainInterface.storyboardc/UIViewController-j1y-V4-xli.nib</key>
<dict>
<key>hash2</key>
<data>
VpQww1vK2BoM0RIaiw/B/8JZ3kp5Pks5bM8Sjtjju9w=
</data>
</dict>
<key>Base.lproj/MainInterface.storyboardc/j1y-V4-xli-view-wbc-yd-nQP.nib</key>
<dict>
<key>hash2</key>
<data>
C87FO0vFlvhG8vp7+3v+EcR9kbOeu9v+mDLy/iU+6e8=
</data>
</dict>
<key>embedded.mobileprovision</key>
<dict>
<key>hash2</key>
<data>
4TQyzTTz0VYUTM0IXf2PMSufVEkzd4WlPWbwKMyfKfQ=
</data>
</dict>
<key>icon.png</key>
<dict>
<key>hash2</key>
<data>
mfufJ0CJyFLUpRnLC8q8awHkGqmWeQtRDgF5EBXKUQs=
</data>
</dict>
</dict>
<key>rules</key>
<dict>
<key>^.*</key>
<true/>
<key>^.*\.lproj/</key>
<dict>
<key>optional</key>
<true/>
<key>weight</key>
<real>1000</real>
</dict>
<key>^.*\.lproj/locversion.plist$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>1100</real>
</dict>
<key>^Base\.lproj/</key>
<dict>
<key>weight</key>
<real>1010</real>
</dict>
<key>^version.plist$</key>
<true/>
</dict>
<key>rules2</key>
<dict>
<key>.*\.dSYM($|/)</key>
<dict>
<key>weight</key>
<real>11</real>
</dict>
<key>^(.*/)?\.DS_Store$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>2000</real>
</dict>
<key>^.*</key>
<true/>
<key>^.*\.lproj/</key>
<dict>
<key>optional</key>
<true/>
<key>weight</key>
<real>1000</real>
</dict>
<key>^.*\.lproj/locversion.plist$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>1100</real>
</dict>
<key>^Base\.lproj/</key>
<dict>
<key>weight</key>
<real>1010</real>
</dict>
<key>^Info\.plist$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>20</real>
</dict>
<key>^PkgInfo$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>20</real>
</dict>
<key>^embedded\.provisionprofile$</key>
<dict>
<key>weight</key>
<real>20</real>
</dict>
<key>^version\.plist$</key>
<dict>
<key>weight</key>
<real>20</real>
</dict>
</dict>
</dict>
</plist>

View File

@@ -1,7 +0,0 @@
var GetURL = function() {};
GetURL.prototype = {
run: function(arguments) {
arguments.completionFunction({"URL": document.URL});
}
};
var ExtensionPreprocessingJS = new GetURL;

1
Tweaks/Alderis Submodule

Submodule Tweaks/Alderis added at 7992b3b57e

View File

@@ -1,16 +0,0 @@
# Crap
.DS_Store
# Xcode
*.pbxuser
!default.pbxuser
xcuserdata
*.xccheckout
*.xcuserstate
# Carthage
Carthage/
# Theos
.theos
packages/

View File

@@ -1,36 +0,0 @@
clean: true
author: HASHBANG Productions
author_url: https://hbang.github.io/
github_url: https://github.com/hbang/Alderis
root_url: https://hbang.github.io/Alderis/
dash_url: https://hbang.github.io/Alderis/docsets/Alderis.xml
documentation: info/*.md
hide_documentation_coverage: true
custom_categories:
- name: "Guides"
children:
- "Preference Bundles"
- "Migrating to 1.1"
- name: "Color Picker"
children:
- ColorPickerViewController
- ColorPickerConfiguration
- ColorPickerDelegate
- ColorPickerTab
- name: "UI Components"
children:
- ColorWell
- name: "Extensions"
children:
- UIColor
- ColorPropertyListValue
- String
- Array
- name: "Deprecated"
children:
- ColorPickerCircleView

View File

@@ -1,61 +0,0 @@
disabled_rules:
- trailing_comma
- nesting
- fallthrough
- shorthand_operator
- todo
- large_tuple
- identifier_name
- type_name
- type_body_length
# TODO: Why is vertical_parameter_alignment giving false positives?
- vertical_parameter_alignment
- vertical_parameter_alignment_on_call
# TODO: Enable when removing support for older Swift versions (<5.6)
- unavailable_condition
opt_in_rules:
- closure_end_indentation
- closure_spacing
- contains_over_first_not_nil
- empty_count
- explicit_init
- fatal_error_message
- first_where
- joined_default_parameter
- literal_expression_end_indentation
- overridden_super_call
- prohibited_super_call
- sorted_first_last
- unneeded_parentheses_in_closure_argument
- vertical_parameter_alignment_on_call
- yoda_condition
- nslocalizedstring_key
- unused_setter_value
custom_rules:
comment_whitespace:
name: "Comment Whitespace"
regex: //\S
match_kinds: comment
message: "Comments must begin with a whitespace character"
spaces_not_tabs:
name: "Tabs not Spaces"
regex: ^( )
message: "Use tabs instead of spaces"
point_zero:
name: "Point Zero"
regex: '(?<!iOS\s)(?<!macOS\s)(?<!\.)\b[\d_]+\.0\b'
match_kinds:
- number
- attribute.builtin
message: "Don't add a .0 to the end of floating point literals"
color_init:
name: "Color Initializer"
regex: 'UIColor\(red: (.+), green: \1, blue: \1, alpha: .+\)'
message: "Use UIColor(white:alpha:)"
force_try: warning
force_cast: warning
function_body_length: 200
line_length: 200
file_length: 450
cyclomatic_complexity: 12
function_parameter_count: 7

View File

@@ -1,30 +0,0 @@
Pod::Spec.new do |spec|
spec.name = "Alderis"
spec.version = "1.2.0"
spec.summary = "A fresh new color picker, with a gentle, fun, and dead simple user interface."
spec.description = <<-DESC
Alderis is a fresh new color picker, with a gentle, fun, and dead simple user
interface. It aims to incorporate the usual elements of a color picker, in a way
that users will find easy and fun to use.
The user can start by selecting a color they like on the initial color palette
tab, and either accept it, or refine it using the color wheel and adjustment
sliders found on the two other tabs.
DESC
spec.homepage = "https://github.com/hbang/Alderis"
spec.screenshots = "https://github.com/hbang/Alderis/raw/main/screenshots/alderis-1.jpg",
"https://github.com/hbang/Alderis/raw/main/screenshots/alderis-2.jpg",
"https://github.com/hbang/Alderis/raw/main/screenshots/alderis-3.jpg",
"https://github.com/hbang/Alderis/raw/main/screenshots/alderis-4.jpg"
spec.license = "Apache License, Version 2.0"
spec.author = "HASHBANG Productions"
spec.social_media_url = "https://twitter.com/hashbang"
spec.swift_versions = "5.0"
spec.platform = :ios, "12.0"
spec.source = { :git => "https://github.com/hbang/Alderis.git", :tag => "#{spec.version}" }
spec.requires_arc = true
spec.source_files = [ "Alderis/*.swift", "Alderis/*.h" ]
spec.resource_bundles = { "Alderis" => "Alderis/Assets-ios12.xcassets" }
end

View File

@@ -1,482 +0,0 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 52;
objects = {
/* Begin PBXBuildFile section */
4E1C741328266C5900227EC3 /* UIFontDescriptorAdditions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E1C741228266C5900227EC3 /* UIFontDescriptorAdditions.swift */; };
4E1C74172826C1F100227EC3 /* ColorPickerAccessibilityViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E1C74162826C1F100227EC3 /* ColorPickerAccessibilityViewController.swift */; };
4E1C741928276D5600227EC3 /* TextViewLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E1C741828276D5600227EC3 /* TextViewLabel.swift */; };
4E1C741B2827829E00227EC3 /* AccessibilityComplianceLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E1C741A2827829E00227EC3 /* AccessibilityComplianceLabel.swift */; };
4E1C741D2827882600227EC3 /* AccessibilityContrastSelector.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E1C741C2827882600227EC3 /* AccessibilityContrastSelector.swift */; };
4E1C741F2827B3C800227EC3 /* UIFloat.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E1C741E2827B3C800227EC3 /* UIFloat.swift */; };
4E1C74212827B8F800227EC3 /* NSBeep.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E1C74202827B8F800227EC3 /* NSBeep.swift */; };
4E2E6C06282BD5990089E4FB /* GradientView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E2E6C05282BD5990089E4FB /* GradientView.swift */; };
569C25522427F57000022C60 /* ColorPickerTabViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 569C25512427F57000022C60 /* ColorPickerTabViewController.swift */; };
569C25582428346900022C60 /* ColorPickerMapSlider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 569C25572428346900022C60 /* ColorPickerMapSlider.swift */; };
56C74667242F722A003ED00A /* ColorPickerSlider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56C74666242F722A003ED00A /* ColorPickerSlider.swift */; };
56C74669242F75E3003ED00A /* ColorPickerNumericSlider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56C74668242F75E3003ED00A /* ColorPickerNumericSlider.swift */; };
94A2368C252B5951002B5D0B /* UIColorAdditions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94A2368B252B5951002B5D0B /* UIColorAdditions.swift */; };
CF73D33A241F9C23000B1B10 /* Alderis.h in Headers */ = {isa = PBXBuildFile; fileRef = CF73D338241F9C23000B1B10 /* Alderis.h */; settings = {ATTRIBUTES = (Public, ); }; };
CF73D344241F9C31000B1B10 /* ColorWell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CF73D32D241E49EE000B1B10 /* ColorWell.swift */; };
CF73D345241F9C31000B1B10 /* ColorPickerMapViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CFE70280241CBDE700083903 /* ColorPickerMapViewController.swift */; };
CF73D346241F9C31000B1B10 /* ColorPickerSlidersViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CFE70282241CC88D00083903 /* ColorPickerSlidersViewController.swift */; };
CF73D347241F9C31000B1B10 /* ColorPickerWheelView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CFE70288241D0E7300083903 /* ColorPickerWheelView.swift */; };
CF73D348241F9C31000B1B10 /* ColorPickerInnerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CFE7027B241A62ED00083903 /* ColorPickerInnerViewController.swift */; };
CF73D34A241F9C31000B1B10 /* ColorPickerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CFE70273241A4C5500083903 /* ColorPickerViewController.swift */; };
CF73D34B241F9C31000B1B10 /* ColorPickerSwatchViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CFE7027E241B984600083903 /* ColorPickerSwatchViewController.swift */; };
CF73D34C241F9C4D000B1B10 /* Color.swift in Sources */ = {isa = PBXBuildFile; fileRef = CF73D32B241E4720000B1B10 /* Color.swift */; };
CF73D351241F9FB3000B1B10 /* ColorPickerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CF73D350241F9FB3000B1B10 /* ColorPickerDelegate.swift */; };
CF7750B72520D3B50069CC57 /* Assets.swift in Sources */ = {isa = PBXBuildFile; fileRef = CF7750B62520D3B50069CC57 /* Assets.swift */; };
CF7750BE252203630069CC57 /* DialogButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = CF7750BD252203630069CC57 /* DialogButton.swift */; };
CF7750CF252433680069CC57 /* ColorPickerConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = CF7750CE252433680069CC57 /* ColorPickerConfiguration.swift */; };
CF7750D62524615D0069CC57 /* SeparatorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CF7750D52524615D0069CC57 /* SeparatorView.swift */; };
CF775122252852460069CC57 /* AlderisSDKCompatibility.h in Headers */ = {isa = PBXBuildFile; fileRef = CF775121252852110069CC57 /* AlderisSDKCompatibility.h */; settings = {ATTRIBUTES = (Public, ); }; };
CF79DA31251723C500F17BCB /* BottomSheetTransition.swift in Sources */ = {isa = PBXBuildFile; fileRef = CF79DA30251723C500F17BCB /* BottomSheetTransition.swift */; };
CFAFFC9124277CEE005AD4C1 /* Assets-ios12.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CFAFFC9024277CEE005AD4C1 /* Assets-ios12.xcassets */; platformFilter = ios; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
4E1C741228266C5900227EC3 /* UIFontDescriptorAdditions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIFontDescriptorAdditions.swift; sourceTree = "<group>"; };
4E1C74162826C1F100227EC3 /* ColorPickerAccessibilityViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorPickerAccessibilityViewController.swift; sourceTree = "<group>"; };
4E1C741828276D5600227EC3 /* TextViewLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextViewLabel.swift; sourceTree = "<group>"; };
4E1C741A2827829E00227EC3 /* AccessibilityComplianceLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccessibilityComplianceLabel.swift; sourceTree = "<group>"; };
4E1C741C2827882600227EC3 /* AccessibilityContrastSelector.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccessibilityContrastSelector.swift; sourceTree = "<group>"; };
4E1C741E2827B3C800227EC3 /* UIFloat.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIFloat.swift; sourceTree = "<group>"; };
4E1C74202827B8F800227EC3 /* NSBeep.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSBeep.swift; sourceTree = "<group>"; };
4E2E6C05282BD5990089E4FB /* GradientView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GradientView.swift; sourceTree = "<group>"; };
569C25512427F57000022C60 /* ColorPickerTabViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorPickerTabViewController.swift; sourceTree = "<group>"; };
569C25572428346900022C60 /* ColorPickerMapSlider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorPickerMapSlider.swift; sourceTree = "<group>"; };
56C74666242F722A003ED00A /* ColorPickerSlider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorPickerSlider.swift; sourceTree = "<group>"; };
56C74668242F75E3003ED00A /* ColorPickerNumericSlider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorPickerNumericSlider.swift; sourceTree = "<group>"; };
94A2368B252B5951002B5D0B /* UIColorAdditions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIColorAdditions.swift; sourceTree = "<group>"; };
CF73D32B241E4720000B1B10 /* Color.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Color.swift; sourceTree = "<group>"; };
CF73D32D241E49EE000B1B10 /* ColorWell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorWell.swift; sourceTree = "<group>"; };
CF73D336241F9C23000B1B10 /* Alderis.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Alderis.framework; sourceTree = BUILT_PRODUCTS_DIR; };
CF73D338241F9C23000B1B10 /* Alderis.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Alderis.h; sourceTree = "<group>"; };
CF73D339241F9C23000B1B10 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
CF73D350241F9FB3000B1B10 /* ColorPickerDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorPickerDelegate.swift; sourceTree = "<group>"; };
CF7750B62520D3B50069CC57 /* Assets.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Assets.swift; sourceTree = "<group>"; };
CF7750BD252203630069CC57 /* DialogButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DialogButton.swift; sourceTree = "<group>"; };
CF7750CE252433680069CC57 /* ColorPickerConfiguration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ColorPickerConfiguration.swift; sourceTree = "<group>"; };
CF7750D52524615D0069CC57 /* SeparatorView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SeparatorView.swift; sourceTree = "<group>"; };
CF775121252852110069CC57 /* AlderisSDKCompatibility.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AlderisSDKCompatibility.h; sourceTree = "<group>"; };
CF79DA30251723C500F17BCB /* BottomSheetTransition.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BottomSheetTransition.swift; sourceTree = "<group>"; };
CFAFFC9024277CEE005AD4C1 /* Assets-ios12.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Assets-ios12.xcassets"; sourceTree = "<group>"; };
CFE70273241A4C5500083903 /* ColorPickerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorPickerViewController.swift; sourceTree = "<group>"; };
CFE7027B241A62ED00083903 /* ColorPickerInnerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorPickerInnerViewController.swift; sourceTree = "<group>"; };
CFE7027E241B984600083903 /* ColorPickerSwatchViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorPickerSwatchViewController.swift; sourceTree = "<group>"; };
CFE70280241CBDE700083903 /* ColorPickerMapViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorPickerMapViewController.swift; sourceTree = "<group>"; };
CFE70282241CC88D00083903 /* ColorPickerSlidersViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorPickerSlidersViewController.swift; sourceTree = "<group>"; };
CFE70288241D0E7300083903 /* ColorPickerWheelView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorPickerWheelView.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
CF73D333241F9C23000B1B10 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
CF39D435222BC07C001EF57F = {
isa = PBXGroup;
children = (
CF73D337241F9C23000B1B10 /* Alderis */,
CF39D43F222BC07C001EF57F /* Products */,
);
indentWidth = 2;
sourceTree = "<group>";
tabWidth = 2;
usesTabs = 1;
};
CF39D43F222BC07C001EF57F /* Products */ = {
isa = PBXGroup;
children = (
CF73D336241F9C23000B1B10 /* Alderis.framework */,
);
name = Products;
sourceTree = "<group>";
};
CF73D337241F9C23000B1B10 /* Alderis */ = {
isa = PBXGroup;
children = (
CF73D338241F9C23000B1B10 /* Alderis.h */,
CF775121252852110069CC57 /* AlderisSDKCompatibility.h */,
CF7750B62520D3B50069CC57 /* Assets.swift */,
CF79DA30251723C500F17BCB /* BottomSheetTransition.swift */,
CF73D32B241E4720000B1B10 /* Color.swift */,
CFE70273241A4C5500083903 /* ColorPickerViewController.swift */,
CF7750CE252433680069CC57 /* ColorPickerConfiguration.swift */,
CF73D350241F9FB3000B1B10 /* ColorPickerDelegate.swift */,
CFE7027B241A62ED00083903 /* ColorPickerInnerViewController.swift */,
569C25512427F57000022C60 /* ColorPickerTabViewController.swift */,
56C74666242F722A003ED00A /* ColorPickerSlider.swift */,
CFE7027E241B984600083903 /* ColorPickerSwatchViewController.swift */,
569C25572428346900022C60 /* ColorPickerMapSlider.swift */,
CFE70280241CBDE700083903 /* ColorPickerMapViewController.swift */,
CFE70288241D0E7300083903 /* ColorPickerWheelView.swift */,
CFE70282241CC88D00083903 /* ColorPickerSlidersViewController.swift */,
56C74668242F75E3003ED00A /* ColorPickerNumericSlider.swift */,
4E1C74162826C1F100227EC3 /* ColorPickerAccessibilityViewController.swift */,
4E1C741A2827829E00227EC3 /* AccessibilityComplianceLabel.swift */,
4E1C741C2827882600227EC3 /* AccessibilityContrastSelector.swift */,
CF73D32D241E49EE000B1B10 /* ColorWell.swift */,
CF7750BD252203630069CC57 /* DialogButton.swift */,
CF7750D52524615D0069CC57 /* SeparatorView.swift */,
4E2E6C05282BD5990089E4FB /* GradientView.swift */,
94A2368B252B5951002B5D0B /* UIColorAdditions.swift */,
4E1C741228266C5900227EC3 /* UIFontDescriptorAdditions.swift */,
4E1C741E2827B3C800227EC3 /* UIFloat.swift */,
4E1C741828276D5600227EC3 /* TextViewLabel.swift */,
4E1C74202827B8F800227EC3 /* NSBeep.swift */,
CF73D339241F9C23000B1B10 /* Info.plist */,
CFAFFC9024277CEE005AD4C1 /* Assets-ios12.xcassets */,
);
path = Alderis;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
CF73D331241F9C23000B1B10 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
CF73D33A241F9C23000B1B10 /* Alderis.h in Headers */,
CF775122252852460069CC57 /* AlderisSDKCompatibility.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
CF73D335241F9C23000B1B10 /* Alderis */ = {
isa = PBXNativeTarget;
buildConfigurationList = CF73D340241F9C23000B1B10 /* Build configuration list for PBXNativeTarget "Alderis" */;
buildPhases = (
CF73D331241F9C23000B1B10 /* Headers */,
CF73D332241F9C23000B1B10 /* Sources */,
CF73D333241F9C23000B1B10 /* Frameworks */,
CF73D334241F9C23000B1B10 /* Resources */,
CF77511225281F7E0069CC57 /* SwiftLint */,
);
buildRules = (
);
dependencies = (
);
name = Alderis;
productName = Alderis;
productReference = CF73D336241F9C23000B1B10 /* Alderis.framework */;
productType = "com.apple.product-type.framework";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
CF39D436222BC07C001EF57F /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1330;
ORGANIZATIONNAME = "HASHBANG Productions";
TargetAttributes = {
CF73D335241F9C23000B1B10 = {
CreatedOnToolsVersion = 11.3.1;
};
};
};
buildConfigurationList = CF39D439222BC07C001EF57F /* Build configuration list for PBXProject "Alderis" */;
compatibilityVersion = "Xcode 9.3";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = CF39D435222BC07C001EF57F;
productRefGroup = CF39D43F222BC07C001EF57F /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
CF73D335241F9C23000B1B10 /* Alderis */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
CF73D334241F9C23000B1B10 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
CFAFFC9124277CEE005AD4C1 /* Assets-ios12.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
CF77511225281F7E0069CC57 /* SwiftLint */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
);
name = SwiftLint;
outputFileListPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "export PATH=$PATH:/opt/homebrew/bin\nif which swiftlint >/dev/null; then\n\tswiftlint\nelse\n\techo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi\n";
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
CF73D332241F9C23000B1B10 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
CF73D34B241F9C31000B1B10 /* ColorPickerSwatchViewController.swift in Sources */,
CF7750BE252203630069CC57 /* DialogButton.swift in Sources */,
4E1C741928276D5600227EC3 /* TextViewLabel.swift in Sources */,
CF73D347241F9C31000B1B10 /* ColorPickerWheelView.swift in Sources */,
CF7750D62524615D0069CC57 /* SeparatorView.swift in Sources */,
CF73D34C241F9C4D000B1B10 /* Color.swift in Sources */,
94A2368C252B5951002B5D0B /* UIColorAdditions.swift in Sources */,
569C25582428346900022C60 /* ColorPickerMapSlider.swift in Sources */,
4E2E6C06282BD5990089E4FB /* GradientView.swift in Sources */,
CF73D344241F9C31000B1B10 /* ColorWell.swift in Sources */,
CF7750B72520D3B50069CC57 /* Assets.swift in Sources */,
CF73D348241F9C31000B1B10 /* ColorPickerInnerViewController.swift in Sources */,
56C74667242F722A003ED00A /* ColorPickerSlider.swift in Sources */,
4E1C74212827B8F800227EC3 /* NSBeep.swift in Sources */,
4E1C74172826C1F100227EC3 /* ColorPickerAccessibilityViewController.swift in Sources */,
4E1C741D2827882600227EC3 /* AccessibilityContrastSelector.swift in Sources */,
CF73D345241F9C31000B1B10 /* ColorPickerMapViewController.swift in Sources */,
CF79DA31251723C500F17BCB /* BottomSheetTransition.swift in Sources */,
4E1C741328266C5900227EC3 /* UIFontDescriptorAdditions.swift in Sources */,
CF73D34A241F9C31000B1B10 /* ColorPickerViewController.swift in Sources */,
CF7750CF252433680069CC57 /* ColorPickerConfiguration.swift in Sources */,
56C74669242F75E3003ED00A /* ColorPickerNumericSlider.swift in Sources */,
569C25522427F57000022C60 /* ColorPickerTabViewController.swift in Sources */,
4E1C741F2827B3C800227EC3 /* UIFloat.swift in Sources */,
CF73D351241F9FB3000B1B10 /* ColorPickerDelegate.swift in Sources */,
CF73D346241F9C31000B1B10 /* ColorPickerSlidersViewController.swift in Sources */,
4E1C741B2827829E00227EC3 /* AccessibilityComplianceLabel.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
CF39D452222BC07E001EF57F /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
};
name = Debug;
};
CF39D453222BC07E001EF57F /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
SDKROOT = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
VALIDATE_PRODUCT = YES;
};
name = Release;
};
CF73D341241F9C23000B1B10 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
APPLICATION_EXTENSION_API_ONLY = YES;
BUILD_LIBRARY_FOR_DISTRIBUTION = YES;
CURRENT_PROJECT_VERSION = 3;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = Alderis/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
MARKETING_VERSION = 1.2;
PRODUCT_BUNDLE_IDENTIFIER = ws.hbang.Alderis;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SKIP_INSTALL = NO;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Debug;
};
CF73D342241F9C23000B1B10 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
APPLICATION_EXTENSION_API_ONLY = YES;
BUILD_LIBRARY_FOR_DISTRIBUTION = YES;
CURRENT_PROJECT_VERSION = 3;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = Alderis/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
MARKETING_VERSION = 1.2;
PRODUCT_BUNDLE_IDENTIFIER = ws.hbang.Alderis;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SKIP_INSTALL = NO;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
CF39D439222BC07C001EF57F /* Build configuration list for PBXProject "Alderis" */ = {
isa = XCConfigurationList;
buildConfigurations = (
CF39D452222BC07E001EF57F /* Debug */,
CF39D453222BC07E001EF57F /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
CF73D340241F9C23000B1B10 /* Build configuration list for PBXNativeTarget "Alderis" */ = {
isa = XCConfigurationList;
buildConfigurations = (
CF73D341241F9C23000B1B10 /* Debug */,
CF73D342241F9C23000B1B10 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = CF39D436222BC07C001EF57F /* Project object */;
}

View File

@@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:Alderis Demo.xcodeproj">
</FileRef>
</Workspace>

View File

@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

View File

@@ -1,67 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1330"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "CF73D335241F9C23000B1B10"
BuildableName = "Alderis.framework"
BlueprintName = "Alderis"
ReferencedContainer = "container:Alderis.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "CF73D335241F9C23000B1B10"
BuildableName = "Alderis.framework"
BlueprintName = "Alderis"
ReferencedContainer = "container:Alderis.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@@ -1,77 +0,0 @@
//
// AccessibilityComplianceLabel.swift
// Alderis
//
// Created by Adam Demasi on 8/5/2022.
// Copyright © 2022 HASHBANG Productions. All rights reserved.
//
import UIKit
internal class AccessibilityComplianceLabel: UIView {
var text: String {
get { label.text! }
set { label.text = newValue }
}
var isCompliant = false {
didSet { updateState() }
}
private let tickImage = Assets.systemImage(named: "checkmark.circle.fill")
private let crossImage = Assets.systemImage(named: "xmark.circle.fill")
private var imageView: UIImageView!
private var label: UILabel!
override init(frame: CGRect) {
super.init(frame: frame)
let font = UIFont.systemFont(ofSize: UIFloat(16), weight: .medium)
imageView = UIImageView()
if #available(iOS 13, *) {
imageView.preferredSymbolConfiguration = UIImage.SymbolConfiguration(font: font, scale: .small)
}
label = UILabel()
label.font = font
let stackView = UIStackView(arrangedSubviews: [imageView, label])
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.alignment = .center
stackView.spacing = UIFloat(6)
addSubview(stackView)
NSLayoutConstraint.activate([
stackView.topAnchor.constraint(equalTo: self.topAnchor),
stackView.bottomAnchor.constraint(equalTo: self.bottomAnchor),
stackView.leadingAnchor.constraint(equalTo: self.leadingAnchor),
stackView.trailingAnchor.constraint(equalTo: self.trailingAnchor)
])
}
convenience init(text: String) {
self.init(frame: .zero)
self.text = text
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func updateState() {
let color = isCompliant ? Assets.green : Assets.red
tintColor = color
accessibilityLabel = "\(text): \(isCompliant ? "Compliant" : "Not compliant")"
imageView.image = isCompliant ? tickImage : crossImage
}
override func tintColorDidChange() {
super.tintColorDidChange()
label.textColor = tintColor
}
}

View File

@@ -1,91 +0,0 @@
//
// AccessibilityContrastSelector.swift
// Alderis
//
// Created by Adam Demasi on 8/5/2022.
// Copyright © 2022 HASHBANG Productions. All rights reserved.
//
import UIKit
internal class AccessibilityContrastSelector: UIView {
enum Mode: Int, CaseIterable {
case color, black, white
var label: String {
switch self {
case .color: return "Color"
case .black: return "Black"
case .white: return "White"
}
}
func color(withColor color: Color) -> Color {
switch self {
case .color: return color
case .black: return .black
case .white: return .white
}
}
}
var text: String {
get { label.text! }
set { label.text = newValue }
}
var value: Mode = .white {
didSet {
if segmentedControl.selectedSegmentIndex != value.rawValue {
segmentedControl.selectedSegmentIndex = value.rawValue
handleChange?(value)
}
}
}
var handleChange: ((Mode) -> Void)?
private var label: UILabel!
private var segmentedControl: UISegmentedControl!
override init(frame: CGRect) {
super.init(frame: frame)
label = UILabel()
label.font = UIFont.systemFont(ofSize: UIFloat(16), weight: .medium)
segmentedControl = UISegmentedControl(items: Mode.allCases.map(\.label))
segmentedControl.addTarget(self, action: #selector(handleValueChanged), for: .valueChanged)
let stackView = UIStackView(arrangedSubviews: [label, UIView(), segmentedControl])
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.alignment = .center
stackView.distribution = .fill
stackView.spacing = UIFloat(5)
addSubview(stackView)
NSLayoutConstraint.activate([
stackView.topAnchor.constraint(equalTo: self.topAnchor),
stackView.bottomAnchor.constraint(equalTo: self.bottomAnchor),
stackView.leadingAnchor.constraint(equalTo: self.leadingAnchor),
stackView.trailingAnchor.constraint(equalTo: self.trailingAnchor)
])
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
convenience init(text: String, value: Mode) {
self.init(frame: .zero)
self.text = text
self.value = value
}
@objc private func handleValueChanged() {
value = Mode(rawValue: segmentedControl.selectedSegmentIndex)!
handleChange?(value)
}
}

View File

@@ -1,11 +0,0 @@
//
// Alderis.h
// Alderis
//
// Created by Adam Demasi on 16/3/20.
// Copyright © 2020 HASHBANG Productions. All rights reserved.
//
@import UIKit;
#import "AlderisSDKCompatibility.h"

View File

@@ -1,21 +0,0 @@
//
// AlderisSDKCompatibility.h
// Alderis
//
// Created by Adam Demasi on 3/10/20.
// Copyright © 2020 HASHBANG Productions. All rights reserved.
//
@import UIKit;
#ifndef __IPHONE_14_0
// Allows building with the iOS 13 SDK while retaining iOS 14 compatibility.
@interface UIControl ()
- (void)addAction:(UIAction *)action forControlEvents:(UIControlEvents)controlEvents NS_SWIFT_NAME(addAction(_:for:)) API_AVAILABLE(ios(14.0));
- (void)removeAction:(UIAction *)action forControlEvents:(UIControlEvents)controlEvents NS_SWIFT_NAME(removeAction(_:for:)) API_AVAILABLE(ios(14.0));
- (void)removeActionForIdentifier:(UIActionIdentifier)actionIdentifier forControlEvents:(UIControlEvents)controlEvents NS_SWIFT_NAME(removeAction(identifiedBy:for:)) API_AVAILABLE(ios(14.0));
@end
#endif

View File

@@ -1,6 +0,0 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@@ -1,26 +0,0 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "sun.max.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "sun.max@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "sun.max@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
},
"properties" : {
"template-rendering-intent" : "template"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 310 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 661 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 942 B

View File

@@ -1,26 +0,0 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "sun.min.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "sun.min@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "sun.min@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
},
"properties" : {
"template-rendering-intent" : "template"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 307 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 606 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 909 B

View File

@@ -1,6 +0,0 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -1,6 +0,0 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -1,26 +0,0 @@
{
"images" : [
{
"filename" : "checkmark.circle.fill.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "checkmark.circle.fill@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "checkmark.circle.fill@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"template-rendering-intent" : "template"
}
}

View File

@@ -1,26 +0,0 @@
{
"images" : [
{
"filename" : "sparkles.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "sparkles@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "sparkles@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"template-rendering-intent" : "template"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 184 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 324 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 427 B

View File

@@ -1,26 +0,0 @@
{
"images" : [
{
"filename" : "xmark.circle.fill.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "xmark.circle.fill@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "xmark.circle.fill@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"template-rendering-intent" : "template"
}
}

View File

@@ -1,6 +0,0 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -1,26 +0,0 @@
{
"images" : [
{
"filename" : "circle.righthalf.fill.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "circle.righthalf.fill@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "circle.righthalf.fill@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"template-rendering-intent" : "template"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 229 B

View File

@@ -1,26 +0,0 @@
{
"images" : [
{
"filename" : "slider.horizontal.3.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "slider.horizontal.3@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "slider.horizontal.3@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"template-rendering-intent" : "template"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 208 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 361 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 507 B

View File

@@ -1,26 +0,0 @@
{
"images" : [
{
"filename" : "slider.horizontal.below.rectangle.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "slider.horizontal.below.rectangle@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "slider.horizontal.below.rectangle@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"template-rendering-intent" : "template"
}
}

View File

@@ -1,26 +0,0 @@
{
"images" : [
{
"filename" : "square.grid.4x3.fill.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "square.grid.4x3.fill@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "square.grid.4x3.fill@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"template-rendering-intent" : "template"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 211 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 289 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 419 B

View File

@@ -1,135 +0,0 @@
//
// Assets.swift
// Alderis
//
// Created by Adam Demasi on 27/9/20.
// Copyright © 2020 HASHBANG Productions. All rights reserved.
//
import UIKit
internal struct Assets {
internal enum SymbolScale: Int {
case `default` = -1
case unspecified, small, medium, large
@available(iOS 13, *)
var uiImageSymbolScale: UIImage.SymbolScale { UIImage.SymbolScale(rawValue: rawValue)! }
}
private static let bundle: Bundle = {
let myBundle = Bundle(for: ColorPickerViewController.self)
if let resourcesURL = myBundle.url(forResource: "Alderis", withExtension: "bundle"),
let resourcesBundle = Bundle(url: resourcesURL) {
return resourcesBundle
}
return myBundle
}()
private static let uikitBundle = Bundle(for: UIView.self)
// MARK: - Localization
static func uikitLocalize(_ key: String) -> String {
uikitBundle.localizedString(forKey: key, value: nil, table: nil)
}
// MARK: - Images
static func systemImage(named name: String, font: UIFont? = nil, scale: SymbolScale = .default) -> UIImage? {
if #available(iOS 13, *) {
var configuration: UIImage.SymbolConfiguration?
if let font = font {
configuration = UIImage.SymbolConfiguration(font: font, scale: scale.uiImageSymbolScale)
}
return UIImage(systemName: name, withConfiguration: configuration)
}
return UIImage(named: name, in: bundle, compatibleWith: nil)
}
// MARK: - Fonts
static func niceMonospaceDigitFont(ofSize size: CGFloat) -> UIFont {
// Take the monospace digit font and enable stylistic alternative 6, which provides a
// high-legibility, monospace-looking style of the system font.
let font = UIFont.monospacedDigitSystemFont(ofSize: size, weight: .regular)
let fontDescriptor = font.fontDescriptor.addingAttributes([
.featureSettings: [
[
.alderisFeature: kStylisticAlternativesType,
.alderisSelector: kStylisticAltSixOnSelector
]
] as [[UIFontDescriptor.FeatureKey: Int]]
])
return UIFont(descriptor: fontDescriptor, size: 0)
}
// MARK: - Colors
private static func color(userInterfaceStyles colors: [UIUserInterfaceStyle: UIColor], fallback: UIUserInterfaceStyle = .light) -> UIColor {
if #available(iOS 13, *) {
return UIColor { colors[$0.userInterfaceStyle] ?? colors[fallback] ?? colors.values.first! }
}
return colors[fallback] ?? colors.values.first!
}
static let backdropColor = UIColor(white: 0, alpha: 0.2)
static let separatorColor = UIColor(white: 1, alpha: 0.15)
static let labelColor: UIColor = {
if #available(iOS 13, *) {
return .label
}
return .black
}()
static let secondaryLabelColor: UIColor = {
if #available(iOS 13, *) {
return .secondaryLabel
}
return UIColor(white: 60 / 255, alpha: 0.6)
}()
static let borderColor: UIColor = {
if #available(iOS 13, *) {
return .separator
}
return UIColor(white: 1, alpha: 0.35)
}()
@available(iOS 13, *)
static let macTabBarSelectionColor = color(userInterfaceStyles: [
.light: .black,
.dark: .label
])
static let red = UIColor.systemRed
// .systemGreen adjusted to be more consistent / easier to read
static let green = color(userInterfaceStyles: [
.light: UIColor(red: 15 / 255, green: 189 / 255, blue: 59 / 255, alpha: 1),
// swiftlint:disable:next colon
.dark: UIColor(red: 41 / 255, green: 179 / 255, blue: 76 / 255, alpha: 1)
])
static let checkerboardPatternColor = color(userInterfaceStyles: [
.light: renderCheckerboardPattern(colors: (UIColor(white: 200 / 255, alpha: 1),
UIColor(white: 255 / 255, alpha: 1))),
// swiftlint:disable:next colon
.dark: renderCheckerboardPattern(colors: (UIColor(white: 140 / 255, alpha: 1),
UIColor(white: 186 / 255, alpha: 1)))
])
private static func renderCheckerboardPattern(colors: (dark: UIColor, light: UIColor)) -> UIColor {
let size = 11
let image = UIGraphicsImageRenderer(size: CGSize(width: size * 2, height: size * 2)).image { context in
colors.dark.setFill()
context.fill(CGRect(x: 0, y: 0, width: size * 2, height: size * 2))
colors.light.setFill()
context.fill(CGRect(x: size, y: 0, width: size, height: size))
context.fill(CGRect(x: 0, y: size, width: size, height: size))
}
return UIColor(patternImage: image)
}
}

View File

@@ -1,48 +0,0 @@
//
// BottomSheetTransition.swift
// Alderis
//
// Created by Adam Demasi on 20/9/20.
// Copyright © 2020 HASHBANG Productions. All rights reserved.
//
import UIKit
internal class BottomSheetTransitioningDelegate: NSObject, UIViewControllerTransitioningDelegate {
func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return BottomSheetTransition(direction: true)
}
func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return BottomSheetTransition(direction: false)
}
}
internal class BottomSheetTransition: NSObject, UIViewControllerAnimatedTransitioning {
// Opening: true
// Closing: false
let direction: Bool
init(direction: Bool) {
self.direction = direction
}
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
0.4
}
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
if direction {
let to = transitionContext.viewController(forKey: .to)!
transitionContext.containerView.addSubview(to.view)
}
Timer.scheduledTimer(withTimeInterval: transitionDuration(using: transitionContext), repeats: false) { _ in
transitionContext.completeTransition(true)
}
}
}

View File

@@ -1,342 +0,0 @@
//
// Color.swift
// Alderis
//
// Created by Adam Demasi on 15/3/20.
// Copyright © 2020 HASHBANG Productions. All rights reserved.
//
import UIKit
internal struct Color: Equatable, Hashable {
static let black = Color(white: 0, alpha: 1)
static let white = Color(white: 1, alpha: 1)
var red: CGFloat = 0 {
didSet {
self = Color(red: red, green: green, blue: blue, alpha: alpha)
}
}
var green: CGFloat = 0 {
didSet {
self = Color(red: red, green: green, blue: blue, alpha: alpha)
}
}
var blue: CGFloat = 0 {
didSet {
self = Color(red: red, green: green, blue: blue, alpha: alpha)
}
}
var hue: CGFloat = 0 {
didSet {
self = Color(hue: hue, saturation: saturation, brightness: brightness, alpha: alpha)
}
}
var saturation: CGFloat = 0 {
didSet {
self = Color(hue: hue, saturation: saturation, brightness: brightness, alpha: alpha)
}
}
var brightness: CGFloat = 0 {
didSet {
self = Color(hue: hue, saturation: saturation, brightness: brightness, alpha: alpha)
}
}
var hslSaturation: CGFloat = 0 {
didSet {
self = Color(hue: hue, saturation: hslSaturation, lightness: lightness, alpha: alpha)
}
}
var lightness: CGFloat = 0 {
didSet {
self = Color(hue: hue, saturation: hslSaturation, lightness: lightness, alpha: alpha)
}
}
var white: CGFloat = 0 {
didSet {
self = Color(white: white, alpha: alpha)
}
}
var alpha: CGFloat = 0
static func == (lhs: Color, rhs: Color) -> Bool {
lhs.red == rhs.red &&
lhs.green == rhs.green &&
lhs.blue == rhs.blue &&
lhs.alpha == rhs.alpha
}
func hash(into hasher: inout Hasher) {
hasher.combine(red)
hasher.combine(green)
hasher.combine(blue)
hasher.combine(alpha)
}
var uiColor: UIColor { .init(red: red, green: green, blue: blue, alpha: alpha) }
init(uiColor: UIColor) {
uiColor.getRed(&red, green: &green, blue: &blue, alpha: &alpha)
uiColor.getHue(&hue, saturation: &saturation, brightness: &brightness, alpha: nil)
self.white = brightness
(self.hslSaturation, self.lightness) = hslValue
}
init(red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) {
self.red = red
self.green = green
self.blue = blue
self.alpha = alpha
let uiColor = UIColor(red: red, green: green, blue: blue, alpha: alpha)
uiColor.getHue(&hue, saturation: &saturation, brightness: &brightness, alpha: nil)
self.white = brightness
(self.hslSaturation, self.lightness) = hslValue
}
init(white: CGFloat, alpha: CGFloat) {
self.init(red: white, green: white, blue: white, alpha: alpha)
}
init(hue: CGFloat, saturation: CGFloat, brightness: CGFloat, alpha: CGFloat) {
self.hue = hue
self.saturation = saturation
self.brightness = brightness
self.white = brightness
self.alpha = alpha
let uiColor = UIColor(hue: hue, saturation: saturation, brightness: brightness, alpha: alpha)
uiColor.getRed(&red, green: &green, blue: &blue, alpha: nil)
(self.hslSaturation, self.lightness) = hslValue
}
init(hue: CGFloat, saturation: CGFloat, lightness: CGFloat, alpha: CGFloat) {
self.hue = hue
self.hslSaturation = saturation
self.lightness = lightness
self.alpha = alpha
(self.saturation, self.brightness) = hsbValue
let uiColor = UIColor(hue: hue, saturation: self.saturation, brightness: self.brightness, alpha: alpha)
uiColor.getRed(&red, green: &green, blue: &blue, alpha: nil)
self.white = brightness
}
}
extension Color {
static var brightnessThreshold: CGFloat {
// Accessibility enabled: conforms to WCAG 2.1 AAA
// Accessibility disabled: conforms to WCAG 2.1 AA
UIAccessibility.isDarkerSystemColorsEnabled ? 7 : 4.5
}
var relativeLuminanceValues: (red: CGFloat, green: CGFloat, blue: CGFloat) {
// https://www.w3.org/TR/WCAG21/#dfn-relative-luminance
let values = [red, green, blue]
.map { $0 <= 0.03928 ? $0 / 12.92 : pow((($0 + 0.055) / 1.055), 2.4) }
return (values[0], values[1], values[2])
}
var relativeLuminance: CGFloat {
// https://www.w3.org/TR/WCAG21/#dfn-relative-luminance
let (r, g, b) = relativeLuminanceValues
return (r * 0.2126) + (g * 0.7152) + (b * 0.0722)
}
func perceivedBrightness(onBackgroundColor background: Color) -> CGFloat {
// https://www.w3.org/TR/WCAG21/#dfn-contrast-ratio - between 0-21
let a = relativeLuminance + 0.05
let b = background.relativeLuminance + 0.05
return a > b ? a / b : b / a
}
var isDark: Bool { perceivedBrightness(onBackgroundColor: .white) > Self.brightnessThreshold && alpha > 0.5 }
}
extension Color {
struct HexOptions: OptionSet {
let rawValue: Int
static let allowShorthand = Self(rawValue: 1 << 0)
static let forceAlpha = Self(rawValue: 1 << 1)
}
// if the character in `value` is repeated, `repeatedValue` is a single copy of that character. If
// `value` consists of two unique characters, `repeatedValue` is nil
// e.g. valid return values are `("AA", "A")` and `("AB", nil)`
private func hex(_ val: CGFloat) -> (value: String, repeatedValue: Character?) {
let byte = Int(val * 255) & 0xFF
let isRepeated = (byte & 0xF) == (byte >> 4)
let value = String(format: "%02X", byte)
return (value, isRepeated ? value.first : nil)
}
func hexString(with options: HexOptions = []) -> String {
let (r, rRep) = hex(red)
let (g, gRep) = hex(green)
let (b, bRep) = hex(blue)
let (a, aRep) = hex(alpha)
let showAlpha = options.contains(.forceAlpha) || alpha != 1
if options.contains(.allowShorthand),
let rRep = rRep, let gRep = gRep, let bRep = bRep, let aRep = aRep {
return "#\(rRep)\(gRep)\(bRep)\(showAlpha ? "\(aRep)" : "")"
} else {
return "#\(r)\(g)\(b)\(showAlpha ? a : "")"
}
}
var hexString: String { hexString() }
var hslValue: (saturation: CGFloat, lightness: CGFloat) {
let lightness = brightness - (brightness * (saturation / 2))
var saturation = min(lightness, 1 - lightness)
saturation = saturation == 0 ? 0 : (brightness - lightness) / saturation
return (saturation, lightness)
}
var hsbValue: (saturation: CGFloat, brightness: CGFloat) {
let brightness = hslSaturation * min(lightness, 1 - lightness) + lightness
let saturation = brightness == 0 ? 0 : 2 - 2 * lightness / brightness
return (saturation, brightness)
}
private func cssString(function: String, params: [String?]) -> String {
let filteredParams = params.compactMap { $0 }
return "\(function)\(filteredParams.count == 4 ? "a" : "")(\(filteredParams.joined(separator: ", ")))"
}
var rgbString: String {
cssString(function: "rgb", params: [
"\(Int(red * 255))",
"\(Int(green * 255))",
"\(Int(blue * 255))",
alpha == 1 ? nil : String(format: "%.2f", alpha)
])
}
var hslString: String {
cssString(function: "hsl", params: [
"\(Int(hue * 360))",
"\(Int(hslSaturation * 100))%",
"\(Int(lightness * 100))%",
alpha == 1 ? nil : String(format: "%.2f", alpha)
])
}
var objcString: String {
red == green && green == blue
? String(format: "[UIColor colorWithWhite:%.3f alpha:%.2f]", white, alpha)
: String(format: "[UIColor colorWithRed:%.3f green:%.3f blue:%.3f alpha:%.2f]", red, green, blue, alpha)
}
var swiftString: String {
red == green && green == blue
? String(format: "UIColor(white: %.3f, alpha: %.3f", white, alpha)
// swiftlint:disable:next color_init
: String(format: "UIColor(red: %.3f, green: %.3f, blue: %.3f, alpha: %.2f)", red, green, blue, alpha)
}
}
extension Color {
struct Component {
let keyPath: WritableKeyPath<Color, CGFloat>
let limit: CGFloat
let title: String
private let sliderTintColorForColor: (Color) -> [Color]
init(
keyPath: WritableKeyPath<Color, CGFloat>,
limit: CGFloat,
title: String,
sliderTintColorForColor: @escaping (Color) -> [Color]
) {
self.keyPath = keyPath
self.limit = limit
self.title = title
self.sliderTintColorForColor = sliderTintColorForColor
}
init(
keyPath: WritableKeyPath<Color, CGFloat>,
limit: CGFloat,
title: String,
sliderTint: [Color]
) {
self.keyPath = keyPath
self.limit = limit
self.title = title
self.sliderTintColorForColor = { _ in sliderTint }
}
func sliderTintColor(for color: Color) -> [Color] {
sliderTintColorForColor(color)
}
static let red: Component = .init(keyPath: \.red, limit: 255, title: "Red") { color in
[
Color(red: 0, green: color.green, blue: color.blue, alpha: 1),
Color(red: 1, green: color.green, blue: color.blue, alpha: 1)
]
}
static let green: Component = .init(keyPath: \.green, limit: 255, title: "Green") { color in
[
Color(red: color.red, green: 0, blue: color.blue, alpha: 1),
Color(red: color.red, green: 1, blue: color.blue, alpha: 1)
]
}
static let blue: Component = .init(keyPath: \.blue, limit: 255, title: "Blue") { color in
[
Color(red: color.red, green: color.green, blue: 0, alpha: 1),
Color(red: color.red, green: color.green, blue: 1, alpha: 1)
]
}
static let hue: Component = .init(keyPath: \.hue, limit: 360, title: "Hue") { color in
Array(0...8).map { Color(hue: CGFloat($0) * 45 / 360, saturation: color.saturation, brightness: color.brightness, alpha: 1) }
}
static let saturation: Component = .init(keyPath: \.saturation, limit: 100, title: "Satur.") { color in
[
.white,
Color(hue: color.hue, saturation: 1, brightness: color.brightness, alpha: 1)
]
}
static let brightness: Component = .init(keyPath: \.brightness, limit: 100, title: "Bright") { color in
[
.black,
Color(hue: color.hue, saturation: color.saturation, brightness: 1, alpha: 1)
]
}
static let hslSaturation: Component = .init(keyPath: \.hslSaturation, limit: 100, title: "Satur.") { color in
[
Color(hue: color.hue, saturation: 0, lightness: color.lightness, alpha: 1),
Color(hue: color.hue, saturation: 1, lightness: color.lightness, alpha: 1)
]
}
static let lightness: Component = .init(keyPath: \.lightness, limit: 100, title: "Light") { color in
[
.black,
Color(hue: color.hue, saturation: color.hslSaturation, lightness: 0.5, alpha: 1),
.white
]
}
static let white: Component = .init(keyPath: \.white, limit: 255, title: "White") { _ in
[
.black,
.white
]
}
static let alpha: Component = .init(keyPath: \.alpha, limit: 100, title: "Alpha") { color in
[
Color(red: color.red, green: color.green, blue: color.blue, alpha: 0),
Color(red: color.red, green: color.green, blue: color.blue, alpha: 1)
]
}
}
}

View File

@@ -1,218 +0,0 @@
//
// ColorPickerAccessibilityViewController.swift
// Alderis
//
// Created by Adam Demasi on 8/5/2022.
// Copyright © 2022 HASHBANG Productions. All rights reserved.
//
import UIKit
internal class ColorPickerAccessibilityViewController: ColorPickerTabViewController {
static let title = "Contrast Checker"
static let imageName = "circle.righthalf.fill"
private static let percentFormatter: NumberFormatter = {
let formatter = NumberFormatter()
formatter.numberStyle = .percent
return formatter
}()
private var backgroundMode: AccessibilityContrastSelector.Mode = .white {
didSet { colorDidChange() }
}
private var foregroundMode: AccessibilityContrastSelector.Mode = .color {
didSet { colorDidChange() }
}
private var scrollView: UIScrollView!
private var demoContainerView: UIView!
private var demoLabels: [UIView]!
private var contrastStackView: UIStackView!
private var contrastRatioLabel: UILabel!
private var aaComplianceLabel: AccessibilityComplianceLabel!
private var aaaComplianceLabel: AccessibilityComplianceLabel!
private var backgroundSelector: AccessibilityContrastSelector!
private var foregroundSelector: AccessibilityContrastSelector!
override func viewDidLoad() {
super.viewDidLoad()
// Catalyst in iPad UI mode scales all UI down to 77%, so we cancel out the scaling (as well as
// we possibly can, given scaling down is throwing away quality) for the demo labels.
let scaleFactor: CGFloat = isCatalystPad ? 1 / 0.77 : 1
let demoTitleLabel = UILabel()
demoTitleLabel.translatesAutoresizingMaskIntoConstraints = false
demoTitleLabel.font = .systemFont(ofSize: 18 * scaleFactor, weight: .semibold)
demoTitleLabel.text = "Size 18 • Contrast Checker"
let demoImageView = UIImageView(image: Assets.systemImage(named: "sparkles", font: demoTitleLabel.font, scale: .small))
demoImageView.translatesAutoresizingMaskIntoConstraints = false
let titleStackView = UIStackView(arrangedSubviews: [demoImageView, demoTitleLabel])
titleStackView.translatesAutoresizingMaskIntoConstraints = false
titleStackView.spacing = UIFloat(6)
titleStackView.alignment = .center
let demoSubtitleLabel = UILabel()
demoSubtitleLabel.translatesAutoresizingMaskIntoConstraints = false
demoSubtitleLabel.font = .systemFont(ofSize: 14 * scaleFactor, weight: .medium)
demoSubtitleLabel.text = "Size 14 • Contrast ratios are a measure of how easily text and images can be read, especially by people with lower vision."
demoSubtitleLabel.numberOfLines = 0
let demoTextLabel = TextViewLabel()
demoTextLabel.translatesAutoresizingMaskIntoConstraints = false
demoTextLabel.linkTextAttributes = [
.underlineStyle: NSUnderlineStyle.single.rawValue
]
let explainerText = "Size 12 • Learn more about minimum (AA) and enhanced (AAA) contrast."
let attributedString = NSMutableAttributedString(string: explainerText,
attributes: [
.font: UIFont.systemFont(ofSize: 12 * scaleFactor, weight: .regular)
])
attributedString.addAttribute(.link,
value: URL(string: "https://www.w3.org/WAI/WCAG21/Understanding/contrast-minimum")!,
range: (attributedString.string as NSString).range(of: "minimum (AA)"))
attributedString.addAttribute(.link,
value: URL(string: "https://www.w3.org/WAI/WCAG21/Understanding/contrast-enhanced")!,
range: (attributedString.string as NSString).range(of: "enhanced (AAA)"))
demoTextLabel.attributedText = attributedString
demoLabels = [demoTitleLabel, demoSubtitleLabel, demoTextLabel]
let demoStackView = UIStackView(arrangedSubviews: [titleStackView, demoSubtitleLabel, demoTextLabel])
demoStackView.translatesAutoresizingMaskIntoConstraints = false
demoStackView.axis = .vertical
demoStackView.alignment = .leading
demoStackView.spacing = UIFloat(8)
demoContainerView = UIView()
demoContainerView.translatesAutoresizingMaskIntoConstraints = false
demoContainerView.layer.cornerRadius = 12
if #available(iOS 13, *) {
demoContainerView.layer.cornerCurve = .continuous
}
demoContainerView.addSubview(demoStackView)
contrastRatioLabel = UILabel()
contrastRatioLabel.translatesAutoresizingMaskIntoConstraints = false
contrastRatioLabel.font = .systemFont(ofSize: UIFloat(16), weight: .medium)
aaComplianceLabel = AccessibilityComplianceLabel(text: "AA")
aaaComplianceLabel = AccessibilityComplianceLabel(text: "AAA")
let complianceStackView = UIStackView(arrangedSubviews: [UIView(), aaComplianceLabel, aaaComplianceLabel])
complianceStackView.translatesAutoresizingMaskIntoConstraints = false
complianceStackView.spacing = UIFloat(12)
contrastStackView = UIStackView(arrangedSubviews: [contrastRatioLabel, complianceStackView])
contrastStackView.translatesAutoresizingMaskIntoConstraints = false
contrastStackView.spacing = UIFloat(8)
backgroundSelector = AccessibilityContrastSelector(text: "Background", value: backgroundMode)
backgroundSelector.handleChange = { self.backgroundMode = $0 }
foregroundSelector = AccessibilityContrastSelector(text: "Foreground", value: foregroundMode)
foregroundSelector.handleChange = { self.foregroundMode = $0 }
scrollView = UIScrollView()
scrollView.translatesAutoresizingMaskIntoConstraints = false
scrollView.alwaysBounceVertical = false
view.addSubview(scrollView)
let rootStackView = UIStackView(arrangedSubviews: [demoContainerView, UIView(), contrastStackView, backgroundSelector, foregroundSelector, UIView()])
rootStackView.translatesAutoresizingMaskIntoConstraints = false
rootStackView.axis = .vertical
rootStackView.alignment = .fill
rootStackView.distribution = .fill
rootStackView.spacing = UIFloat(10)
scrollView.addSubview(rootStackView)
NSLayoutConstraint.activate([
scrollView.topAnchor.constraint(equalTo: view.topAnchor),
scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
rootStackView.topAnchor.constraint(equalTo: scrollView.contentLayoutGuide.topAnchor, constant: UIFloat(15)),
rootStackView.bottomAnchor.constraint(equalTo: scrollView.contentLayoutGuide.bottomAnchor, constant: UIFloat(-15)),
rootStackView.leadingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.leadingAnchor, constant: UIFloat(15)),
rootStackView.trailingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.trailingAnchor, constant: UIFloat(-15)),
rootStackView.heightAnchor.constraint(equalTo: scrollView.contentLayoutGuide.heightAnchor, constant: UIFloat(-30)),
scrollView.contentLayoutGuide.widthAnchor.constraint(equalTo: scrollView.widthAnchor),
scrollView.contentLayoutGuide.heightAnchor.constraint(greaterThanOrEqualTo: scrollView.heightAnchor),
demoStackView.topAnchor.constraint(equalTo: demoContainerView.topAnchor, constant: UIFloat(16)),
demoStackView.bottomAnchor.constraint(equalTo: demoContainerView.bottomAnchor, constant: UIFloat(-17)),
demoStackView.leadingAnchor.constraint(equalTo: demoContainerView.leadingAnchor, constant: UIFloat(20)),
demoStackView.trailingAnchor.constraint(equalTo: demoContainerView.trailingAnchor, constant: UIFloat(-20)),
contrastStackView.heightAnchor.constraint(greaterThanOrEqualTo: backgroundSelector.heightAnchor),
contrastStackView.heightAnchor.constraint(greaterThanOrEqualTo: foregroundSelector.heightAnchor)
])
colorDidChange()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
scrollView.flashScrollIndicators()
}
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
contrastStackView.axis = view.frame.size.width > UIFloat(300) ? .horizontal : .vertical
}
override func colorDidChange() {
let backgroundColor = backgroundMode.color(withColor: color)
let foregroundColor = foregroundMode.color(withColor: color)
if backgroundColor == foregroundColor {
// Change one or the other to not be identical
if backgroundMode == foregroundMode {
switch backgroundMode {
case .black, .white: foregroundMode = .color
default: foregroundMode = .white
}
} else {
if foregroundMode == .color {
backgroundMode = backgroundColor == .white ? .black : .white
} else if backgroundMode == .color {
foregroundMode = foregroundColor == .white ? .black : .white
}
}
return
}
backgroundSelector.value = backgroundMode
foregroundSelector.value = foregroundMode
demoContainerView.backgroundColor = backgroundColor.uiColor
demoContainerView.tintColor = foregroundColor.uiColor
for label in demoLabels {
if let label = label as? UILabel {
label.textColor = foregroundColor.uiColor
} else if let label = label as? UITextView,
let attributedString = label.attributedText.mutableCopy() as? NSMutableAttributedString {
attributedString.addAttribute(.foregroundColor,
value: foregroundColor.uiColor,
range: NSRange(location: 0, length: attributedString.string.count))
label.attributedText = attributedString
}
}
let contrastRatio = foregroundColor.perceivedBrightness(onBackgroundColor: backgroundColor)
contrastRatioLabel.text = "Contrast: \(String(format: "%.2f", contrastRatio)) (\(Self.percentFormatter.string(for: contrastRatio / 21)!))"
aaComplianceLabel.isCompliant = contrastRatio > 4.5
aaaComplianceLabel.isCompliant = contrastRatio > 7
}
}

View File

@@ -1,91 +0,0 @@
//
// ColorPickerConfiguration.swift
// Alderis
//
// Created by Adam Demasi on 10/5/20.
// Copyright © 2020 HASHBANG Productions. All rights reserved.
//
import UIKit
/// An enumeration of the tabs `ColorPickerViewController` features. Use these enumeration values to
/// set tab-related settings on `ColorPickerConfiguration`.
@objc(HBColorPickerTab)
public enum ColorPickerTab: Int, CaseIterable {
/// Tab 1: A grid of 9 variations of 11 colours, and a grayscale ramp. The first and default tab.
case swatch = 0
/// Tab 2: A color wheel displaying every possible hue and saturation combination. The user can
/// additionally adjust the brightness of the colour using a slider.
case map = 1
/// Tab 3: A set of sliders for red, green, and blue color values, which can be switched to hue,
/// saturation, and brightness. The user can additionally copy or enter a color value expressed
/// using a CSS-style hexadecimal string, and adjust alpha transparency.
case sliders = 2
/// Tab 4: A tab that allows the user to test various configurations of the color, and its
/// conformance to WCAG color contrast.
case accessibility = 3
}
/// ColorPickerConfiguration is used to configure an instance of `ColorPickerViewController`.
@objc(HBColorPickerConfiguration)
open class ColorPickerConfiguration: NSObject {
/// Initialise a configuration object with the required color property configured.
@objc public init(color: UIColor) {
self.color = color
super.init()
}
/// The initial color to use when launching the color picker. Required. If you dont have a value
/// set yet, provide a sensible default.
@objc open var color: UIColor
/// Whether to allow the user to set an alpha transparency value on the color. This controls the
/// visibility of an Alpha slider on the Sliders tab. When set to `false`, alpha values provided
/// via the `color` property, or by the user when entering a hexadecimal value on the Sliders tab,
/// will be discarded.
@objc open var supportsAlpha = true
/// The title to display at the top of the popup. If set to `nil`, no title will be displayed. The
/// default is `nil`.
@objc open var title: String?
/// The initial tab to select when the color picker is presented. The default is
/// `ColorPickerTab.swatch`.
///
/// This value must be found in `visibleTabs`.
///
/// - see: `visibleTabs`
@objc open var initialTab = ColorPickerTab.swatch
/// The tabs the user can select and switch between at the top of the window, if tabs are enabled
/// by `showTabs`.
///
/// - see: `initialTab`
@nonobjc open var visibleTabs: [ColorPickerTab] = [.swatch, .map, .sliders, .accessibility]
/// Maps `visibleTabs` to Objective-C due to Swift limitations. This is an implementation detail.
/// Ignore this and use `visibleTabs` per usual.
@objc(visibleTabs)
open var _visibleTabsObjC: [ColorPickerTab.RawValue] {
get { visibleTabs.map(\.rawValue) }
set { visibleTabs = newValue.map { ColorPickerTab(rawValue: $0)! } }
}
/// Whether to display the tab selection at the top of the popup. The default is `true`. When set
/// to `false`, the user will only be able to access the tab specified in initialTab.
@objc open var showTabs = true
/// When the Smart Invert accessibility feature is enabled, Alderis instructs the system to not
/// invert most of its user interface. This ensures the user can make a more accurate color
/// selection. If this behavior is not desired, you can disable it here.
@objc open var overrideSmartInvert = true
/// Whether the user can end a drag interaction by dropping on the color picker window, allowing
/// them to drag a color from a supporting app. The default is `true`.
@objc open var isDropInteractionEnabled = true
}

View File

@@ -1,51 +0,0 @@
//
// ColorPickerDelegate.swift
// Alderis
//
// Created by Adam Demasi on 16/3/20.
// Copyright © 2020 HASHBANG Productions. All rights reserved.
//
import UIKit
/// Use `ColorPickerDelegate` to handle the users response to `ColorPickerViewController`.
@objc(HBColorPickerDelegate)
public protocol ColorPickerDelegate: NSObjectProtocol {
/// Informs the delegate that the user has selected a color in the color picker. Optional.
///
/// Use this to update your user interface with the new color value, if suitable to your use case.
///
/// You should, at minimum, implement either this method or `colorPicker(_:didAccept:)`. If you
/// dont intend to implement this method, it is expected that you implement
/// `colorPicker(_:didAccept:)`. If you implement this method and the user selects Cancel, this
/// method will be called with the initial color passed in via `ColorPickerConfiguration.color` to
/// undo the selection.
///
/// - parameter colorPicker: The `ColorPickerViewController` instance that triggered the action.
/// - parameter color: The `UIColor` selection the user made.
/// - see: `colorPicker(_:didAccept:)`
@objc(colorPicker:didSelectColor:)
optional func colorPicker(_ colorPicker: ColorPickerViewController, didSelect color: UIColor)
/// Informs the delegate that the user has dismissed the color picker with a positive response,
/// having selected the selected color. Optional.
///
/// You should, at minimum, implement either this method or `colorPicker(_:didSelect:)`.
///
/// - parameter colorPicker: The `ColorPickerViewController` instance that triggered the action.
/// - parameter color: The `UIColor` selection the user made.
/// - see: `colorPicker(_:didSelect:)`
@objc(colorPicker:didAcceptColor:)
optional func colorPicker(_ colorPicker: ColorPickerViewController, didAccept color: UIColor)
/// Informs the delegate that the user has dismissed the color picker with a negative response.
/// Optional.
///
/// You usually do not need to handle this condition.
///
/// - parameter colorPicker: The `ColorPickerViewController` instance that triggered the action.
@objc(colorPickerDidCancel:)
optional func colorPickerDidCancel(_ colorPicker: ColorPickerViewController)
}

View File

@@ -1,445 +0,0 @@
//
// ColorPickerInnerViewController.swift
// Alderis
//
// Created by Adam Demasi on 12/3/20.
// Copyright © 2020 HASHBANG Productions. All rights reserved.
//
import UIKit
internal extension ColorPickerTab {
var tabClass: ColorPickerTabViewController.Type {
switch self {
case .swatch: return ColorPickerSwatchViewController.self
case .map: return ColorPickerMapViewController.self
case .sliders: return ColorPickerSlidersViewController.self
case .accessibility: return ColorPickerAccessibilityViewController.self
}
}
var index: Int { Self.allCases.firstIndex(of: self)! }
}
internal class ColorPickerInnerViewController: UIViewController {
weak var delegate: ColorPickerDelegate?
let configuration: ColorPickerConfiguration
var color: Color
var tab: ColorPickerTab {
get { configuration.visibleTabs[currentTab] }
set { currentTab = configuration.visibleTabs.firstIndex(of: newValue) ?? 0 }
}
var compatibilityMode = false
private var colorPicker: ColorPickerViewController {
// swiftlint:disable:next force_cast
parent as! ColorPickerViewController
}
init(delegate: ColorPickerDelegate?, configuration: ColorPickerConfiguration) {
self.delegate = delegate
self.configuration = configuration
color = Color(uiColor: configuration.color)
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private var currentTab = 0 {
didSet { tabDidChange(oldValue: oldValue) }
}
func setColor(_ color: Color, withSource source: ColorPickerTabViewControllerBase? = nil) {
self.color = color
colorDidChange(withSource: source)
}
private var pageViewController: UIPageViewController!
private var tabs = [ColorPickerTabViewController]()
private var tabsView: UISegmentedControl!
private var titleLabel: UILabel!
private var cancelButton: DialogButton?
private var saveButton: DialogButton?
private var tabsBackgroundView: UIView!
private var buttonsBackgroundView: UIView?
private var heightConstraint: NSLayoutConstraint!
private var backgroundView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
for tabType in configuration.visibleTabs {
let tab = tabType.tabClass.init(tabDelegate: self, configuration: configuration, color: color)
// Force the view to be initialised
tab.loadViewIfNeeded()
tabs.append(tab)
}
if configuration.isDropInteractionEnabled {
view.addInteraction(UIDropInteraction(delegate: self))
}
backgroundView = UIView()
backgroundView.translatesAutoresizingMaskIntoConstraints = false
backgroundView.accessibilityIgnoresInvertColors = configuration.overrideSmartInvert
view.addSubview(backgroundView)
let tabsCheckerboardView = UIView()
tabsCheckerboardView.translatesAutoresizingMaskIntoConstraints = false
tabsCheckerboardView.accessibilityIgnoresInvertColors = configuration.overrideSmartInvert
tabsCheckerboardView.backgroundColor = Assets.checkerboardPatternColor
view.addSubview(tabsCheckerboardView)
tabsBackgroundView = UIView()
tabsBackgroundView.translatesAutoresizingMaskIntoConstraints = false
tabsBackgroundView.accessibilityIgnoresInvertColors = configuration.overrideSmartInvert
view.addSubview(tabsBackgroundView)
let topSeparatorView = SeparatorView(direction: .horizontal)
topSeparatorView.translatesAutoresizingMaskIntoConstraints = false
tabsBackgroundView.addSubview(topSeparatorView)
let titleView = UIView()
titleView.translatesAutoresizingMaskIntoConstraints = false
titleView.isHidden = configuration.title == nil || configuration.title!.isEmpty
titleLabel = UILabel()
titleLabel.translatesAutoresizingMaskIntoConstraints = false
titleLabel.textAlignment = .center
titleLabel.font = .systemFont(ofSize: UIFloat(17), weight: .semibold)
titleLabel.text = configuration.title
titleView.addSubview(titleLabel)
let tabsContainerView = UIView()
tabsContainerView.translatesAutoresizingMaskIntoConstraints = false
tabsContainerView.isHidden = !configuration.showTabs
tabsView = UISegmentedControl()
tabsView.translatesAutoresizingMaskIntoConstraints = false
tabsView.accessibilityIgnoresInvertColors = configuration.overrideSmartInvert
tabsView.addTarget(self, action: #selector(segmentControlChanged(_:)), for: .valueChanged)
tabsContainerView.addSubview(tabsView)
if #available(iOS 13, *) {
tabsView.selectedSegmentTintColor = UIColor.white.withAlphaComponent(0.35)
if isCatalystMac {
tabsView.setTitleTextAttributes([ .foregroundColor: Assets.macTabBarSelectionColor ], for: .highlighted)
tabsView.setTitleTextAttributes([ .foregroundColor: Assets.macTabBarSelectionColor ], for: .selected)
}
}
for (i, tab) in tabs.enumerated() {
let tabClass = type(of: tab)
#if swift(>=5.3)
if #available(iOS 14, *) {
tabsView.insertSegment(action: UIAction(title: tabClass.title,
image: tabClass.image,
handler: { _ in }),
at: i,
animated: false)
} else {
tabsView.insertSegment(with: tabClass.image, at: i, animated: false)
}
#else
tabsView.insertSegment(with: tabClass.image, at: i, animated: false)
#endif
}
NSLayoutConstraint.activate([
tabsView.centerXAnchor.constraint(equalTo: tabsContainerView.centerXAnchor),
tabsView.centerYAnchor.constraint(equalTo: tabsContainerView.centerYAnchor),
tabsView.leadingAnchor.constraint(greaterThanOrEqualTo: tabsContainerView.leadingAnchor, constant: 4),
tabsView.trailingAnchor.constraint(lessThanOrEqualTo: tabsContainerView.trailingAnchor, constant: -4)
])
if #available(iOS 13, *) {
} else {
NSLayoutConstraint.activate([
tabsView.heightAnchor.constraint(equalToConstant: 32)
])
for i in 0..<tabsView.numberOfSegments {
tabsView.setWidth(40, forSegmentAt: i)
}
}
let pageViewContainer = UIView()
pageViewContainer.translatesAutoresizingMaskIntoConstraints = false
pageViewController = UIPageViewController(transitionStyle: .scroll, navigationOrientation: .horizontal, options: [:])
pageViewController.view.translatesAutoresizingMaskIntoConstraints = false
pageViewController.willMove(toParent: self)
addChild(pageViewController)
pageViewContainer.addSubview(pageViewController.view)
let mainStackView = UIStackView(arrangedSubviews: [titleView, tabsContainerView, pageViewContainer])
mainStackView.translatesAutoresizingMaskIntoConstraints = false
mainStackView.axis = .vertical
mainStackView.alignment = .fill
mainStackView.distribution = .fill
view.addSubview(mainStackView)
heightConstraint = pageViewContainer.heightAnchor.constraint(equalToConstant: 0)
let barHeight: CGFloat = UIFloat(48)
let topHeight = (titleView.isHidden ? 0 : barHeight) + (tabsContainerView.isHidden ? 0 : barHeight)
let titleLabelTopOffset: CGFloat = tabsContainerView.isHidden ? 0 : 3
NSLayoutConstraint.activate([
backgroundView.topAnchor.constraint(equalTo: view.topAnchor),
backgroundView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
backgroundView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
backgroundView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
mainStackView.topAnchor.constraint(equalTo: view.topAnchor),
mainStackView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
mainStackView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
mainStackView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
titleView.heightAnchor.constraint(equalToConstant: barHeight),
tabsContainerView.heightAnchor.constraint(equalToConstant: barHeight),
titleLabel.topAnchor.constraint(equalTo: titleView.topAnchor, constant: titleLabelTopOffset),
titleLabel.bottomAnchor.constraint(equalTo: titleView.bottomAnchor),
titleLabel.leadingAnchor.constraint(equalTo: titleView.leadingAnchor, constant: 4),
titleLabel.trailingAnchor.constraint(equalTo: titleView.trailingAnchor, constant: -4),
tabsBackgroundView.topAnchor.constraint(equalTo: view.topAnchor),
tabsBackgroundView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
tabsBackgroundView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
tabsBackgroundView.heightAnchor.constraint(equalToConstant: topHeight),
tabsCheckerboardView.topAnchor.constraint(equalTo: tabsBackgroundView.topAnchor),
tabsCheckerboardView.bottomAnchor.constraint(equalTo: tabsBackgroundView.bottomAnchor),
tabsCheckerboardView.leadingAnchor.constraint(equalTo: tabsBackgroundView.leadingAnchor),
tabsCheckerboardView.trailingAnchor.constraint(equalTo: tabsBackgroundView.trailingAnchor),
topSeparatorView.leadingAnchor.constraint(equalTo: tabsBackgroundView.leadingAnchor),
topSeparatorView.trailingAnchor.constraint(equalTo: tabsBackgroundView.trailingAnchor),
topSeparatorView.bottomAnchor.constraint(equalTo: tabsBackgroundView.bottomAnchor),
pageViewController.view.topAnchor.constraint(equalTo: pageViewContainer.topAnchor),
pageViewController.view.bottomAnchor.constraint(equalTo: pageViewContainer.bottomAnchor),
pageViewController.view.leadingAnchor.constraint(equalTo: pageViewContainer.leadingAnchor),
pageViewController.view.trailingAnchor.constraint(equalTo: pageViewContainer.trailingAnchor),
heightConstraint
])
if !isCatalystMac {
let buttonsCheckerboardView = UIView()
buttonsCheckerboardView.translatesAutoresizingMaskIntoConstraints = false
buttonsCheckerboardView.accessibilityIgnoresInvertColors = configuration.overrideSmartInvert
buttonsCheckerboardView.backgroundColor = Assets.checkerboardPatternColor
view.insertSubview(buttonsCheckerboardView, aboveSubview: tabsBackgroundView)
let buttonsBackgroundView = UIView()
buttonsBackgroundView.translatesAutoresizingMaskIntoConstraints = false
buttonsBackgroundView.accessibilityIgnoresInvertColors = configuration.overrideSmartInvert
view.insertSubview(buttonsBackgroundView, aboveSubview: buttonsCheckerboardView)
self.buttonsBackgroundView = buttonsBackgroundView
let bottomSeparatorView = SeparatorView(direction: .horizontal)
bottomSeparatorView.translatesAutoresizingMaskIntoConstraints = false
buttonsBackgroundView.addSubview(bottomSeparatorView)
let cancelButton = DialogButton()
cancelButton.translatesAutoresizingMaskIntoConstraints = false
cancelButton.accessibilityIgnoresInvertColors = configuration.overrideSmartInvert
cancelButton.titleLabel!.font = .systemFont(ofSize: 17, weight: .regular)
cancelButton.setTitle(Assets.uikitLocalize("Cancel"), for: .normal)
cancelButton.addTarget(self, action: #selector(cancelTapped), for: .touchUpInside)
self.cancelButton = cancelButton
let saveButton = DialogButton()
saveButton.translatesAutoresizingMaskIntoConstraints = false
saveButton.accessibilityIgnoresInvertColors = configuration.overrideSmartInvert
saveButton.titleLabel!.font = .systemFont(ofSize: 17, weight: .semibold)
saveButton.setTitle(Assets.uikitLocalize("Done"), for: .normal)
saveButton.addTarget(self, action: #selector(saveTapped), for: .touchUpInside)
self.saveButton = saveButton
let buttonSeparatorView = SeparatorView(direction: .vertical)
buttonSeparatorView.translatesAutoresizingMaskIntoConstraints = false
buttonsBackgroundView.addSubview(buttonSeparatorView)
let buttonsView = UIStackView(arrangedSubviews: [cancelButton, saveButton])
buttonsView.translatesAutoresizingMaskIntoConstraints = false
buttonsView.axis = .horizontal
buttonsView.alignment = .fill
mainStackView.addSubview(buttonsView)
mainStackView.addArrangedSubview(buttonsView)
NSLayoutConstraint.activate([
buttonsView.heightAnchor.constraint(equalToConstant: barHeight),
buttonsBackgroundView.topAnchor.constraint(equalTo: buttonsView.topAnchor),
buttonsBackgroundView.bottomAnchor.constraint(equalTo: buttonsView.bottomAnchor),
buttonsBackgroundView.leadingAnchor.constraint(equalTo: buttonsView.leadingAnchor),
buttonsBackgroundView.trailingAnchor.constraint(equalTo: buttonsView.trailingAnchor),
buttonSeparatorView.heightAnchor.constraint(equalToConstant: barHeight / 2),
buttonSeparatorView.centerXAnchor.constraint(equalTo: buttonsBackgroundView.centerXAnchor),
buttonSeparatorView.centerYAnchor.constraint(equalTo: buttonsBackgroundView.centerYAnchor),
buttonsCheckerboardView.topAnchor.constraint(equalTo: buttonsBackgroundView.topAnchor),
buttonsCheckerboardView.bottomAnchor.constraint(equalTo: buttonsBackgroundView.bottomAnchor),
buttonsCheckerboardView.leadingAnchor.constraint(equalTo: buttonsBackgroundView.leadingAnchor),
buttonsCheckerboardView.trailingAnchor.constraint(equalTo: buttonsBackgroundView.trailingAnchor),
bottomSeparatorView.leadingAnchor.constraint(equalTo: buttonsBackgroundView.leadingAnchor),
bottomSeparatorView.trailingAnchor.constraint(equalTo: buttonsBackgroundView.trailingAnchor),
bottomSeparatorView.topAnchor.constraint(equalTo: buttonsBackgroundView.topAnchor),
cancelButton.widthAnchor.constraint(equalTo: saveButton.widthAnchor)
])
}
colorDidChange()
tab = configuration.initialTab
tabsView?.selectedSegmentIndex = currentTab
}
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
updateHeightConstraint()
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
updateHeightConstraint()
}
override func preferredContentSizeDidChange(forChildContentContainer container: UIContentContainer) {
super.preferredContentSizeDidChange(forChildContentContainer: container)
updateHeightConstraint()
}
private func updateHeightConstraint() {
heightConstraint.constant = (view.frame.size.width / 12) * 10
preferredContentSize = view.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize)
}
@objc private func segmentControlChanged(_ sender: UISegmentedControl) {
UIView.animate(withDuration: 0.2) {
self.currentTab = self.tabsView.selectedSegmentIndex
}
}
@objc private func oldTabButtonTapped(_ sender: UIButton) {
UIView.animate(withDuration: 0.2) {
self.currentTab = sender.tag
}
}
@objc private func cancelTapped() {
if !compatibilityMode {
delegate?.colorPicker?(colorPicker, didSelect: configuration.color)
}
delegate?.colorPickerDidCancel?(colorPicker)
dismiss(animated: true)
}
@objc func saveTapped() {
if compatibilityMode {
delegate?.colorPicker?(colorPicker, didSelect: color.uiColor)
} else {
delegate?.colorPicker?(colorPicker, didAccept: color.uiColor)
}
dismiss(animated: true)
}
private func colorDidChange(withSource source: ColorPickerTabViewControllerBase? = nil) {
let uiColor = color.uiColor
if !compatibilityMode {
delegate?.colorPicker?(colorPicker, didSelect: uiColor)
}
let foregroundColor: UIColor = color.isDark ? .white : .black
view.tintColor = uiColor
tabsBackgroundView.backgroundColor = uiColor
buttonsBackgroundView?.backgroundColor = uiColor
titleLabel.textColor = foregroundColor
cancelButton?.setTitleColor(foregroundColor, for: .normal)
saveButton?.setTitleColor(foregroundColor, for: .normal)
cancelButton?.highlightBackgroundColor = foregroundColor.withAlphaComponent(0.25)
saveButton?.highlightBackgroundColor = foregroundColor.withAlphaComponent(0.25)
tabsView.setTitleTextAttributes([ .foregroundColor: foregroundColor ], for: .normal)
if #available(iOS 13, *) {
} else {
tabsView.tintColor = foregroundColor
}
// Even though `shouldBroadcast: false` avoids recursion if we call setColor on the callee tab,
// doing so on ColorPickerSlidersViewController would reset `hexOptions`, leading to a buggy
// typing experience in `hexTextField`
for tab in tabs where tab != source {
tab.setColor(color, shouldBroadcast: false)
}
backgroundView.backgroundColor = uiColor.withAlphaComponent(color.alpha * 0.2)
}
private func tabDidChange(oldValue: Int) {
let stuff = {
let direction: UIPageViewController.NavigationDirection = self.currentTab < oldValue ? .reverse : .forward
self.pageViewController.setViewControllers([self.tabs[self.currentTab]], direction: direction, animated: !isCatalystMac)
self.colorDidChange()
UIView.animate(withDuration: 0.2) {
self.view.layoutIfNeeded()
}
}
if isCatalystMac {
UIView.performWithoutAnimation(stuff)
} else {
stuff()
}
}
}
extension ColorPickerInnerViewController: ColorPickerTabDelegate {
func colorPickerTab(_ tab: ColorPickerTabViewControllerBase, didSelect color: Color) {
setColor(color, withSource: tab)
}
}
extension ColorPickerInnerViewController: UIDropInteractionDelegate {
/// :nodoc:
public func dropInteraction(_ interaction: UIDropInteraction, canHandle session: UIDropSession) -> Bool {
return session.items.count == 1 && session.canLoadObjects(ofClass: UIColor.self)
}
/// :nodoc:
public func dropInteraction(_ interaction: UIDropInteraction, sessionDidUpdate session: UIDropSession) -> UIDropProposal {
return UIDropProposal(operation: .copy)
}
/// :nodoc:
public func dropInteraction(_ interaction: UIDropInteraction, performDrop session: UIDropSession) {
session.loadObjects(ofClass: UIColor.self) { items in
if let color = items.first as? UIColor {
self.setColor(Color(uiColor: color), withSource: nil)
}
}
}
}
extension ColorPickerInnerViewController: UIPopoverPresentationControllerDelegate {
/// :nodoc:
public func presentationControllerWillDismiss(_ presentationController: UIPresentationController) {
saveTapped()
}
}

View File

@@ -1,49 +0,0 @@
//
// ColorPickerMapSlider.swift
// Alderis
//
// Created by Kabir Oberai on 23/03/20.
// Copyright © 2020 HASHBANG Productions. All rights reserved.
//
import UIKit
internal class ColorPickerMapSlider: ColorPickerComponentSlider {
init(minImageName: String, maxImageName: String, component: Color.Component, overrideSmartInvert: Bool) {
super.init(component: component, overrideSmartInvert: overrideSmartInvert)
stackView.alignment = .center
stackView.spacing = UIFloat(13)
let leftImageView = UIImageView(image: Assets.systemImage(named: minImageName))
leftImageView.translatesAutoresizingMaskIntoConstraints = false
leftImageView.contentMode = .center
leftImageView.tintColor = Assets.secondaryLabelColor
stackView.insertArrangedSubview(leftImageView, at: 0)
let rightImageView = UIImageView(image: Assets.systemImage(named: maxImageName))
rightImageView.translatesAutoresizingMaskIntoConstraints = false
rightImageView.contentMode = .center
rightImageView.tintColor = Assets.secondaryLabelColor
stackView.addArrangedSubview(rightImageView)
if #available(iOS 13, *) {
let symbolConfig = UIImage.SymbolConfiguration(font: .systemFont(ofSize: UIFloat(18), weight: .medium), scale: .medium)
leftImageView.preferredSymbolConfiguration = symbolConfig
rightImageView.preferredSymbolConfiguration = symbolConfig
}
NSLayoutConstraint.activate([
leftImageView.widthAnchor.constraint(equalToConstant: UIFloat(22)),
leftImageView.widthAnchor.constraint(equalTo: rightImageView.widthAnchor),
leftImageView.heightAnchor.constraint(equalTo: leftImageView.widthAnchor),
rightImageView.heightAnchor.constraint(equalTo: rightImageView.widthAnchor)
])
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}

View File

@@ -1,79 +0,0 @@
//
// ColorPickerMapViewController.swift
// Alderis
//
// Created by Adam Demasi on 14/3/20.
// Copyright © 2020 HASHBANG Productions. All rights reserved.
//
import UIKit
internal class ColorPickerMapViewController: ColorPickerTabViewController {
static let title = "Color Wheel"
static let imageName = "slider.horizontal.below.rectangle"
private var wheelView: ColorPickerWheelView!
private var sliders = [ColorPickerMapSlider]()
override func viewDidLoad() {
super.viewDidLoad()
wheelView = ColorPickerWheelView(color: color)
wheelView.translatesAutoresizingMaskIntoConstraints = false
wheelView.accessibilityIgnoresInvertColors = configuration.overrideSmartInvert
wheelView.delegate = self
view.addSubview(wheelView)
sliders = [
ColorPickerMapSlider(
minImageName: "sun.min", maxImageName: "sun.max", component: .brightness,
overrideSmartInvert: configuration.overrideSmartInvert
)
]
sliders.forEach {
$0.translatesAutoresizingMaskIntoConstraints = false
$0.addTarget(self, action: #selector(sliderChanged(_:)), for: .valueChanged)
}
let mainStackView = UIStackView(arrangedSubviews: [wheelView] + sliders)
mainStackView.translatesAutoresizingMaskIntoConstraints = false
mainStackView.axis = .vertical
mainStackView.alignment = .fill
mainStackView.distribution = .fill
view.addSubview(mainStackView)
NSLayoutConstraint.activate([
mainStackView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: UIFloat(15)),
mainStackView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: UIFloat(-15)),
mainStackView.topAnchor.constraint(equalTo: view.topAnchor, constant: 0),
mainStackView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: UIFloat(-10))
])
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
colorDidChange()
}
@objc private func sliderChanged(_ slider: ColorPickerMapSlider) {
var color = self.color
slider.apply(to: &color)
self.setColor(color)
}
override func colorDidChange() {
wheelView.color = color
sliders.forEach { $0.setColor(color) }
}
}
extension ColorPickerMapViewController: ColorPickerWheelViewDelegate {
func colorPickerWheelView(didSelectColor color: Color) {
self.setColor(color)
}
}

View File

@@ -1,83 +0,0 @@
//
// ColorPickerNumericSlider.swift
// Alderis
//
// Created by Kabir Oberai on 28/03/20.
// Copyright © 2020 HASHBANG Productions. All rights reserved.
//
import UIKit
internal class ColorPickerNumericSlider: ColorPickerComponentSlider {
private var textField: UITextField!
override init(component: Color.Component, overrideSmartInvert: Bool) {
super.init(component: component, overrideSmartInvert: overrideSmartInvert)
stackView.alignment = .fill
stackView.spacing = UIFloat(8)
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.font = UIFont.systemFont(ofSize: UIFloat(16), weight: .medium)
label.text = component.title
stackView.insertArrangedSubview(label, at: 0)
textField = UITextField()
textField.translatesAutoresizingMaskIntoConstraints = false
textField.delegate = self
textField.returnKeyType = .next
textField.keyboardType = .numberPad
textField.autocapitalizationType = .none
textField.autocorrectionType = .no
textField.spellCheckingType = .no
textField.textAlignment = .right
textField.font = Assets.niceMonospaceDigitFont(ofSize: UIFloat(16))
stackView.addArrangedSubview(textField)
NSLayoutConstraint.activate([
label.widthAnchor.constraint(equalToConstant: UIFloat(50)),
textField.widthAnchor.constraint(equalToConstant: UIFloat(35))
])
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func setColor(_ color: Color) {
super.setColor(color)
textField.text = "\(Int((color[keyPath: component.keyPath] * component.limit).rounded()))"
}
}
extension ColorPickerNumericSlider: UITextFieldDelegate {
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let newString = textField.text!.replacingCharacters(in: Range(range, in: textField.text!)!, with: string)
guard !newString.isEmpty else { return true }
// Numeric only, 0-limit
let badCharacterSet = CharacterSet(charactersIn: "0123456789").inverted
guard newString.rangeOfCharacter(from: badCharacterSet) == nil else {
beep()
return false
}
let limit = component.limit
guard let value = Int(newString), 0...limit ~= CGFloat(value) else {
beep()
return false
}
// Run this after the input is fully processed by enqueuing it onto the run loop
OperationQueue.main.addOperation {
self.value = CGFloat(value) / limit
self.sliderChanged()
}
return true
}
}

View File

@@ -1,206 +0,0 @@
//
// ColorPickerSlider.swift
// Alderis
//
// Created by Kabir Oberai on 28/03/20.
// Copyright © 2020 HASHBANG Productions. All rights reserved.
//
import UIKit
internal class ColorPickerSliderBase: UIControl {
var overrideSmartInvert: Bool {
didSet {
slider.accessibilityIgnoresInvertColors = overrideSmartInvert
}
}
let stackView: UIStackView
let slider: ColorSlider
var value: CGFloat {
get { CGFloat(slider.value) }
set { slider.value = Float(newValue) }
}
init(overrideSmartInvert: Bool) {
self.overrideSmartInvert = overrideSmartInvert
slider = ColorSlider()
slider.translatesAutoresizingMaskIntoConstraints = false
slider.accessibilityIgnoresInvertColors = overrideSmartInvert
stackView = UIStackView(arrangedSubviews: [slider])
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .horizontal
stackView.distribution = .fill
super.init(frame: .zero)
slider.addTarget(self, action: #selector(sliderChanged), for: .valueChanged)
addSubview(stackView)
NSLayoutConstraint.activate([
stackView.leadingAnchor.constraint(equalTo: self.leadingAnchor),
stackView.trailingAnchor.constraint(equalTo: self.trailingAnchor),
stackView.topAnchor.constraint(equalTo: self.topAnchor),
stackView.bottomAnchor.constraint(equalTo: self.bottomAnchor)
])
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
@objc internal func sliderChanged() {
sendActions(for: .valueChanged)
}
}
internal protocol ColorPickerSliderProtocol: ColorPickerSliderBase {
func setColor(_ color: Color)
func apply(to color: inout Color)
}
internal typealias ColorPickerSlider = ColorPickerSliderBase & ColorPickerSliderProtocol
internal class ColorPickerComponentSlider: ColorPickerSlider {
let component: Color.Component
init(component: Color.Component, overrideSmartInvert: Bool) {
self.component = component
super.init(overrideSmartInvert: overrideSmartInvert)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func setColor(_ color: Color) {
value = color[keyPath: component.keyPath]
slider.color = color.uiColor
slider.gradientColors = component.sliderTintColor(for: color).map(\.uiColor)
}
func apply(to color: inout Color) {
color[keyPath: component.keyPath] = value
}
}
internal class ColorSlider: UISlider {
private let thumbImage = UIGraphicsImageRenderer(size: CGSize(width: 26, height: 26)).image { _ in }
var gradientColors = [UIColor]() {
didSet { gradientView.gradientLayer.colors = gradientColors.map(\.cgColor) }
}
var color: UIColor? {
get { selectionView?.color }
set { selectionView?.color = newValue }
}
private var checkerboardView: UIView!
private var gradientView: GradientView!
private var selectionView: ColorWell?
private var selectionViewXConstraint: NSLayoutConstraint?
private var valueObserver: NSKeyValueObservation?
override init(frame: CGRect) {
super.init(frame: frame)
#if swift(>=5.5)
var useSliderTrack = !isCatalystMac
if #available(iOS 15, *) {
preferredBehavioralStyle = .pad
useSliderTrack = true
}
#else
let useSliderTrack = true
#endif
if useSliderTrack {
setMinimumTrackImage(UIImage(), for: .normal)
setMaximumTrackImage(UIImage(), for: .normal)
setThumbImage(thumbImage, for: .normal)
}
checkerboardView = UIView()
checkerboardView.translatesAutoresizingMaskIntoConstraints = false
checkerboardView.backgroundColor = Assets.checkerboardPatternColor
checkerboardView.clipsToBounds = true
if #available(iOS 13, *) {
checkerboardView.layer.cornerCurve = .continuous
}
insertSubview(checkerboardView, at: 0)
gradientView = GradientView()
gradientView.translatesAutoresizingMaskIntoConstraints = false
gradientView.gradientLayer.startPoint = CGPoint(x: 0, y: 0)
gradientView.gradientLayer.endPoint = CGPoint(x: 1, y: 0)
gradientView.gradientLayer.allowsGroupOpacity = false
checkerboardView.addSubview(gradientView)
NSLayoutConstraint.activate([
checkerboardView.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: UIFloat(-3)),
checkerboardView.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: UIFloat(3)),
checkerboardView.topAnchor.constraint(equalTo: self.topAnchor, constant: -1),
checkerboardView.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: 1),
gradientView.leadingAnchor.constraint(equalTo: checkerboardView.leadingAnchor),
gradientView.trailingAnchor.constraint(equalTo: checkerboardView.trailingAnchor),
gradientView.topAnchor.constraint(equalTo: checkerboardView.topAnchor),
gradientView.bottomAnchor.constraint(equalTo: checkerboardView.bottomAnchor),
])
if useSliderTrack {
let selectionView = ColorWell()
selectionView.translatesAutoresizingMaskIntoConstraints = false
selectionView.isDragInteractionEnabled = false
selectionView.isDropInteractionEnabled = false
#if swift(>=5.3)
if #available(iOS 14, *) {
selectionView.isContextMenuInteractionEnabled = false
}
#endif
insertSubview(selectionView, aboveSubview: checkerboardView)
self.selectionView = selectionView
selectionViewXConstraint = selectionView.leadingAnchor.constraint(equalTo: checkerboardView.leadingAnchor)
// Remove minimum width constraint configured by ColorWell internally
let selectionWidthConstraint = selectionView.constraints.first { $0.firstAnchor == selectionView.widthAnchor }
selectionWidthConstraint?.isActive = false
NSLayoutConstraint.activate([
selectionViewXConstraint!,
selectionView.centerYAnchor.constraint(equalTo: self.centerYAnchor),
selectionView.widthAnchor.constraint(equalToConstant: UIFloat(24))
])
valueObserver = observe(\.value) { _, _ in self.valueChanged() }
}
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
super.layoutSubviews()
checkerboardView.layer.cornerRadius = checkerboardView.frame.size.height / 2
valueChanged()
}
private func valueChanged() {
guard let selectionView = selectionView,
let selectionViewXConstraint = selectionViewXConstraint else {
return
}
let spacing = frame.size.height - selectionView.frame.size.height
selectionViewXConstraint.constant = (spacing / 2) + ((frame.size.width - selectionView.frame.size.width - spacing) * CGFloat(value))
}
}

Some files were not shown because too many files have changed in this diff Show More