├── .DS_Store
├── Help
├── KompleteKontrol.md
├── Maschine.md
└── ToDO.md
├── Images
├── Buttons 15.png
├── Example_01.png
├── Example_02.png
├── Full App V1.png
├── HowToDownload.png
├── KK_Example B 1.png
├── KK_Example B 2.png
├── KK_small.png
├── Labels 15.png
├── MAS_small.png
├── NIPatcher_KK.png
├── Window_Size.png
├── move and replace.png
└── test.txt
├── NIPatcher
├── .DS_Store
├── Functions
│ ├── Functions_Global.swift
│ ├── Functions_KK.swift
│ └── Functions_MAS.swift
├── NIPatcher.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ ├── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ │ └── xcuserdata
│ │ │ └── hackintosh.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ └── xcuserdata
│ │ └── hackintosh.xcuserdatad
│ │ ├── xcdebugger
│ │ └── Breakpoints_v2.xcbkptlist
│ │ └── xcschemes
│ │ └── xcschememanagement.plist
├── NIPatcher
│ ├── .DS_Store
│ ├── Assets.xcassets
│ │ ├── .DS_Store
│ │ ├── AccentColor.colorset
│ │ │ └── Contents.json
│ │ ├── AppIcon.appiconset
│ │ │ ├── Contents.json
│ │ │ ├── NIPatcher_Icon.png
│ │ │ ├── NIPatcher_Icon_128.png
│ │ │ ├── NIPatcher_Icon_256 1.png
│ │ │ ├── NIPatcher_Icon_256.png
│ │ │ ├── NIPatcher_Icon_512 1.png
│ │ │ ├── NIPatcher_Icon_512.png
│ │ │ └── NIPatcher_Icon_64.png
│ │ └── Contents.json
│ ├── ContentView.swift
│ ├── NIPatcher.entitlements
│ ├── NIPatcherApp.swift
│ └── Preview Content
│ │ └── Preview Assets.xcassets
│ │ └── Contents.json
├── Views
│ ├── InfoView.swift
│ ├── KompleteKontrolView.swift
│ └── MaschineView.swift
├── images
│ ├── HDR_LOGO_MAS_Main.png
│ ├── HDR_LOGO_MAS_Picto.png
│ └── HDR_Logo_KP.png
└── shellScripts
│ ├── codesign.sh
│ └── codesignkk.sh
└── README.md
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/d1One/NIPatcher/f125ff4cfb609d9f2ef56cc5a4f610c5dbc2ba98/.DS_Store
--------------------------------------------------------------------------------
/Help/KompleteKontrol.md:
--------------------------------------------------------------------------------
1 | # Komple Kontrol
2 |
3 |
4 |
5 | Born out of the discust for the fixed window size and tiny fonts in Komplete Kontrol 😂
6 |
7 | ### Feature list:
8 | - [x] Change GUI height size
9 | - [x] Increase browser width
10 | - [x] Change font sizes
11 |
12 | ## Window Size
13 | Self explanatory, changes the window height size in pixels.
14 |
15 | `With Plugin`: Changes the height of the KK window when there is a Plugin loaded.
16 | `Without Plugin`: Changes the height of the KK window when there no a Plugin loaded, if this value is bigger than `With Plugin` then the window will always use the value set here.
17 |
18 | - Note - I advise keeping the relationship of originals values, meaning that if you increase the pixel value of `With Plugin` by 300 pixels then also add 300 pixels in the `Without Plugin` option.
19 |
20 | ## Fonts
21 | Self explanatory, changes Font sizes.
22 |
23 | `Butttos`: Tags, File Stab, Scale/Arp buttons, MIDI Learn Knobs/Buttons, and probably more stuff
24 | `Labels`: Preset result list, main MIDI learn button, and probably more stuff
25 | I'll any consider suggestions to change other font sizes.
26 |
27 | - Note - Incresing the font too much without also increasing the deault height the GUI window can result in not being able to have both Types and Character expanded at the same time in the Browser
28 |
29 | ## Wide Browser
30 | A collection of several small mods that makes the browser wider enough to allow 4 rows of product thumbnails instead of 3. (Thanks Pete96 for sharing the details of patch)
31 |
32 | #### Some examples of several patches applied:
33 | 
34 | 
35 | 
36 | 
37 |
--------------------------------------------------------------------------------
/Help/Maschine.md:
--------------------------------------------------------------------------------
1 | # NIPatcher Maschine:
2 |
3 | # Features
4 | ### GUI / Interface
5 | - [x] Change the default GUI window sizes.
6 | - [x] Change GUI window minimum size (Plugins)
7 | - [x] Change Font sizes.
8 |
9 | ### Hardware
10 | - [x] MK3, Mikro Mk3 & M+ - Stop button Double tap.
11 | - [x] JAM - Change patterns without changing focus.
12 |
13 | # ℹ️ GUI / Interface
14 |
15 | ## Window Size
16 |
17 |
18 |
19 |
20 | Changes the default view presets under the Maschine Dropdown > View.
21 | These mods are mostly usefull for the Plugins since their window size is fixed, you can for example:
22 | - Change the one of preset sizes to make sure Maschine-Plugin fills your whole screen, usefull for people with 2 monitors for example since MAS-PLug has no Full-Screen option, only the MAS-App does.
23 | - Minimum height can be used if for some reason you want to be able to make the Maschine App window very small and only see your Scene, Sections / Song View.
24 | - In the future I'll add more complicated mods like making the browser wider for example.
25 |
26 | ## Font Size
27 | This modification exists mainly because the browser has a tiny font + the fact that it's blurry/pixelated due to Maschine not having Hi-Res/Retina support.
28 | - `Button size` affects: Tags in the Browser, Pad Names, Pattern names in Ideas view and many other things.
29 | - `Label size` affets: Mainly the Browser Preset list (But probably many other things too)
30 |
31 | As users share results I'll make a more detailed description of font sizes and possibly add more things to costumize.
32 |
33 | Here is an example of both Buttons and Labels with a fontsize of 15 VS the original value of 11:
34 | 
35 |
36 | # ℹ️ Hardware
37 |
38 | ## Stop Button
39 | TL;DR: This mod makes the STOP button return the Playhead to the beguining if the project is not playing, basically this means we can get the same beahvior as most DAW's have: double press STOP to return to the beguining.
40 |
41 | Longer explanation: The Maschine Mk3 introduced a STOP button on the HW, prior models did not have this, this was great but the Software never changed. If you look at Maschine's top menu Transport section there is no Stop. So as far as the softare is concerned STOP and PLAY **behave exactly the same way when the project is playing**, it makes no difference if you press PLAY again or STOP, they both do the same and thus the STOP button is redundant in this scenario... So, my mod makes STOP restart then stop really fast only when the project is playing which results in leaving the playhead in the beginning without affecting the normal STOP behavior. Best of both worlds! 🎉
42 |
43 | This is not available for the MAS-Plugin because it does not have access to the transport, the Host/DAW does.
44 |
45 | ## Jam Focus
46 | (untested)
47 | Changing Patterns with Jam causes Maschine to lose focus on whatever Group you have active if the Pattern yoou changed is in another Group, often this can be undesirable, this mod changes that. This was shared by maschuser1 on the Maschine Forum [here](https://community.native-instruments.com/discussion/5072/tip-changing-patterns-on-the-maschine-jam-without-changing-focus), all credit goes to him/her.
48 | I dont have a Jam to test this so let me know how it works!
49 |
50 | ## Examples:
51 | Adding more examples soon.
52 |
--------------------------------------------------------------------------------
/Help/ToDO.md:
--------------------------------------------------------------------------------
1 | ## Things to work on:
2 |
3 | - [ ] Clean up the code and upload it to Github.
4 | - [ ] Add: Better examples so people know what the Patcher can do.
5 | - [ ] Add: Visual feeback after user pressed the `Patch!` button.
6 | - [ ] Add: A logo replacer for KK so users can tell when app/plugs are Patched.
7 | - [ ] Add: A help system inside the app.
8 | - [ ] Add: Tool-tips on mouse hoover.
9 | - [ ] Add a way to inform the user what controllers the HW patches affect.
10 | - [ ] Add: A way to stop users from re-applying a HW patch.
11 | - [ ] Add: 'Wide Broser' patch for Maschine.
12 | - [ ] Add: Preferences?
13 | - [ ] Fix: Codesign more than once in the same Session?
14 | - [ ] Investigate: the possibility of having both patched and unpatched plugins side-by-side.
15 |
--------------------------------------------------------------------------------
/Images/Buttons 15.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/d1One/NIPatcher/f125ff4cfb609d9f2ef56cc5a4f610c5dbc2ba98/Images/Buttons 15.png
--------------------------------------------------------------------------------
/Images/Example_01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/d1One/NIPatcher/f125ff4cfb609d9f2ef56cc5a4f610c5dbc2ba98/Images/Example_01.png
--------------------------------------------------------------------------------
/Images/Example_02.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/d1One/NIPatcher/f125ff4cfb609d9f2ef56cc5a4f610c5dbc2ba98/Images/Example_02.png
--------------------------------------------------------------------------------
/Images/Full App V1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/d1One/NIPatcher/f125ff4cfb609d9f2ef56cc5a4f610c5dbc2ba98/Images/Full App V1.png
--------------------------------------------------------------------------------
/Images/HowToDownload.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/d1One/NIPatcher/f125ff4cfb609d9f2ef56cc5a4f610c5dbc2ba98/Images/HowToDownload.png
--------------------------------------------------------------------------------
/Images/KK_Example B 1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/d1One/NIPatcher/f125ff4cfb609d9f2ef56cc5a4f610c5dbc2ba98/Images/KK_Example B 1.png
--------------------------------------------------------------------------------
/Images/KK_Example B 2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/d1One/NIPatcher/f125ff4cfb609d9f2ef56cc5a4f610c5dbc2ba98/Images/KK_Example B 2.png
--------------------------------------------------------------------------------
/Images/KK_small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/d1One/NIPatcher/f125ff4cfb609d9f2ef56cc5a4f610c5dbc2ba98/Images/KK_small.png
--------------------------------------------------------------------------------
/Images/Labels 15.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/d1One/NIPatcher/f125ff4cfb609d9f2ef56cc5a4f610c5dbc2ba98/Images/Labels 15.png
--------------------------------------------------------------------------------
/Images/MAS_small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/d1One/NIPatcher/f125ff4cfb609d9f2ef56cc5a4f610c5dbc2ba98/Images/MAS_small.png
--------------------------------------------------------------------------------
/Images/NIPatcher_KK.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/d1One/NIPatcher/f125ff4cfb609d9f2ef56cc5a4f610c5dbc2ba98/Images/NIPatcher_KK.png
--------------------------------------------------------------------------------
/Images/Window_Size.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/d1One/NIPatcher/f125ff4cfb609d9f2ef56cc5a4f610c5dbc2ba98/Images/Window_Size.png
--------------------------------------------------------------------------------
/Images/move and replace.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/d1One/NIPatcher/f125ff4cfb609d9f2ef56cc5a4f610c5dbc2ba98/Images/move and replace.png
--------------------------------------------------------------------------------
/Images/test.txt:
--------------------------------------------------------------------------------
1 | Test
2 |
--------------------------------------------------------------------------------
/NIPatcher/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/d1One/NIPatcher/f125ff4cfb609d9f2ef56cc5a4f610c5dbc2ba98/NIPatcher/.DS_Store
--------------------------------------------------------------------------------
/NIPatcher/Functions/Functions_Global.swift:
--------------------------------------------------------------------------------
1 | // Functions_Global.swift
2 |
3 | import Cocoa
4 | import AppKit
5 | import Foundation
6 |
7 | // -------------------------------------------------------------
8 | // Check if Maschine app and Plugins exist in the expected paths
9 | // Some people might have the plugs in /User/Library instead ??
10 | // -------------------------------------------------------------
11 |
12 | let filePaths = ["/Library/Audio/Plug-Ins/VST/Maschine 2.vst",
13 | "/Library/Audio/Plug-Ins/VST3/Maschine 2.vst3",
14 | "/Library/Audio/Plug-Ins/Components/Maschine 2.component",
15 | "/Library/Application Support/Avid/Audio/Plug-Ins/Maschine 2.aaxplugin",
16 | "/Applications/Native Instruments/Maschine 2/Maschine 2.app"]
17 |
18 | let fileLabels = ["VST", "VST3", "AU", "AAX", "App"]
19 |
20 | func checkFiles() -> [Bool] {
21 | let fileManager = FileManager.default
22 | var fileExists: [Bool] = []
23 |
24 | for filePath in filePaths {
25 | if fileManager.fileExists(atPath: filePath) {
26 | print("\(filePath) exists")
27 | fileExists.append(true)
28 | } else {
29 | print("\(filePath) does not exist")
30 | fileExists.append(false)
31 | }
32 | }
33 |
34 | return fileExists
35 | }
36 |
37 | // -------------------------------------------------------------
38 | // Check if KK app and Plugins exist in the expected paths
39 | // -------------------------------------------------------------
40 |
41 | let filePathsKK = ["/Library/Audio/Plug-Ins/VST/Komplete Kontrol.vst",
42 | "/Library/Audio/Plug-Ins/VST3/Komplete Kontrol.vst3",
43 | "/Library/Audio/Plug-Ins/Components/Komplete Kontrol.component",
44 | "/Library/Application Support/Avid/Audio/Plug-Ins/Komplete Kontrol.aaxplugin",
45 | "/Applications/Native Instruments/Komplete Kontrol/Komplete Kontrol.app"]
46 |
47 | let fileLabelsKK = ["VST", "VST3", "AU", "AAX", "App"]
48 |
49 | func checkFilesKK() -> [Bool] {
50 | let fileManager = FileManager.default
51 | var fileExists: [Bool] = []
52 |
53 | for filePath in filePathsKK {
54 | if fileManager.fileExists(atPath: filePath) {
55 | print("\(filePath) exists")
56 | fileExists.append(true)
57 | } else {
58 | print("\(filePath) does not exist")
59 | fileExists.append(false)
60 | }
61 | }
62 |
63 | return fileExists
64 | }
65 |
--------------------------------------------------------------------------------
/NIPatcher/Functions/Functions_KK.swift:
--------------------------------------------------------------------------------
1 | // Functions_KK.swift
2 |
3 | import Cocoa
4 | import AppKit
5 | import Foundation
6 |
7 | // -------------------------------------------------------------
8 | // Logo replace (single file)
9 | // /Contents/Resources/skin/pictures/Komplete/KK/Header
10 | // -------------------------------------------------------------
11 |
12 |
13 | func logoReplaceKK() {
14 | let fileManager = FileManager.default
15 |
16 | // Get the URLs for the images in the project folder
17 | guard let mainImageURL = Bundle.main.url(forResource: "HDR_Logo_KP", withExtension: "png") else {
18 | return
19 | }
20 |
21 | // Get the URL for the NIPatcher folder on the desktop
22 | guard let desktopURL = fileManager.urls(for: .desktopDirectory, in: .userDomainMask).first else {
23 | return
24 | }
25 | let nipatcherURL = desktopURL.appendingPathComponent("NIPatcher")
26 |
27 | // Define the destination paths for the images
28 | let destinationPaths = [
29 | "Komplete Kontrol.app/Contents/Resources/skin/pictures/Komplete/KK/Header/",
30 | "Komplete Kontrol.vst/Contents/Resources/skin/pictures/Komplete/KK/Header/",
31 | "Komplete Kontrol.vst3/Contents/Resources/skin/pictures/Komplete/KK/Header",
32 | "Komplete Kontrol.aaxplugin/Contents/Resources/skin/pictures/Komplete/KK/Header/",
33 | "Komplete Kontrol.component/Contents/Resources/skin/pictures/Komplete/KK/Header/"
34 | ]
35 |
36 | // Copy the images to their destination
37 | for path in destinationPaths {
38 | let mainDestinationURL = nipatcherURL.appendingPathComponent(path + "HDR_Logo_KP.png")
39 |
40 | do {
41 | if fileManager.fileExists(atPath: mainDestinationURL.path) {
42 | try fileManager.removeItem(at: mainDestinationURL)
43 | }
44 |
45 | try fileManager.copyItem(at: mainImageURL, to: mainDestinationURL)
46 |
47 | } catch {
48 | print("Error: \(error.localizedDescription)")
49 | }
50 | }
51 | }
52 |
53 |
54 |
55 | // -------------------------------------------------------------
56 | // Copy all KK plugins and app to a folder on the desktop
57 | // -------------------------------------------------------------
58 |
59 | func copyFilesToNIPatcherFolder_KK() throws {
60 | let fileManager = FileManager.default
61 | let desktopURL = fileManager.urls(for: .desktopDirectory, in: .userDomainMask).first!
62 | let destinationURL = desktopURL.appendingPathComponent("NIPatcher")
63 |
64 | try fileManager.createDirectory(at: destinationURL, withIntermediateDirectories: true, attributes: nil)
65 |
66 | let fileURLs = [
67 | URL(fileURLWithPath: "/Library/Audio/Plug-Ins/VST/Komplete Kontrol.vst"),
68 | URL(fileURLWithPath: "/Library/Audio/Plug-Ins/VST3/Komplete Kontrol.vst3"),
69 | URL(fileURLWithPath: "/Library/Audio/Plug-Ins/Components/Komplete Kontrol.component"),
70 | URL(fileURLWithPath: "/Library/Application Support/Avid/Audio/Plug-Ins/Komplete Kontrol.aaxplugin"),
71 | URL(fileURLWithPath: "/Applications/Native Instruments/Komplete Kontrol/Komplete Kontrol.app")
72 | ]
73 |
74 | for fileURL in fileURLs {
75 | let destinationFileURL = destinationURL.appendingPathComponent(fileURL.lastPathComponent)
76 | do {
77 | if fileManager.fileExists(atPath: destinationFileURL.path) {
78 | try fileManager.removeItem(at: destinationFileURL)
79 | }
80 | try fileManager.copyItem(at: fileURL, to: destinationFileURL)
81 | } catch {
82 | print("Error copying file at \(fileURL.path): \(error.localizedDescription)")
83 | }
84 | }
85 | }
86 |
87 | // -------------------------------------------------------------
88 | // Create shortcuts in the desktop.
89 | // -------------------------------------------------------------
90 |
91 | func createAliasesForFolders_KK() {
92 | let fileManager = FileManager.default
93 |
94 | let folders = [
95 | "/Library/Audio/Plug-Ins/VST/",
96 | "/Library/Audio/Plug-Ins/VST3/",
97 | "/Library/Audio/Plug-Ins/Components/",
98 | "/Library/Application Support/Avid/Audio/Plug-Ins/",
99 | "/Applications/Native Instruments/Komplete Kontrol/"
100 | ]
101 |
102 | let folderNames = [
103 | "/Library/Audio/Plug-Ins/VST/": "VST",
104 | "/Library/Audio/Plug-Ins/VST3/": "VST3",
105 | "/Library/Audio/Plug-Ins/Components/": "AU",
106 | "/Library/Application Support/Avid/Audio/Plug-Ins/": "AAX",
107 | "/Applications/Native Instruments/Komplete Kontrol/": "KK App"
108 | ]
109 |
110 | let destinationFolder = URL(fileURLWithPath: NSHomeDirectory()).appendingPathComponent("Desktop/NIPatcher")
111 |
112 | do {
113 | try fileManager.createDirectory(at: destinationFolder, withIntermediateDirectories: true, attributes: nil)
114 | } catch {
115 | print("Error creating directory: \(error.localizedDescription)")
116 | }
117 |
118 | for folder in folders {
119 | let sourceFolder = URL(fileURLWithPath: folder)
120 |
121 | if let folderName = folderNames[folder] {
122 | do {
123 | try fileManager.createSymbolicLink(at: destinationFolder.appendingPathComponent(folderName), withDestinationURL: sourceFolder)
124 | } catch {
125 | print("Error creating alias for \(folder): \(error.localizedDescription)")
126 | }
127 | } else {
128 | print("No folder name found for \(folder)")
129 | }
130 | }
131 | }
132 |
133 | // -----------------------------------------------------------------
134 | // WINDOW HEIGHT SIZE - Hack_1_KK
135 | // (When KK Opens without instruments)
136 | // /Contents/Resources/skin/stylesheets/Komplete/KK/KPI.txt
137 | // -----------------------------------------------------------------
138 |
139 | let inputAppFiles1_KK = "/Komplete Kontrol.app/Contents/Resources/skin/stylesheets/Komplete/KK/KPI.txt"
140 | let inputPlugFiles1_KK = [
141 | "/Komplete Kontrol.vst/Contents/Resources/skin/stylesheets/Komplete/KK/KPI.txt",
142 | "/Komplete Kontrol.vst3/Contents/Resources/skin/stylesheets/Komplete/KK/KPI.txt",
143 | "/Komplete Kontrol.aaxplugin/Contents/Resources/skin/stylesheets/Komplete/KK/KPI.txt",
144 | "/Komplete Kontrol.component/Contents/Resources/skin/stylesheets/Komplete/KK/KPI.txt"
145 | ]
146 |
147 | func Hack_1_KK(KK_app1: Bool, KK_plug1: Bool, defaultHeight: String) {
148 |
149 | if KK_app1 {
150 | let inputFile = basePath + inputAppFiles1_KK
151 | let outputFile = inputFile
152 |
153 | do {
154 | let input = try String(contentsOfFile: inputFile)
155 | var lines = input.components(separatedBy: .newlines)
156 |
157 | lines[24] = " default-height: \(defaultHeight);"
158 |
159 | let output = lines.joined(separator: "\n")
160 | try output.write(toFile: outputFile, atomically: true, encoding: .utf8)
161 | }
162 |
163 | catch {
164 | print("Error: \(error.localizedDescription)")
165 | }
166 | }
167 |
168 | if KK_plug1 {
169 | for inputFile in inputPlugFiles1_KK {
170 | let inputFile = basePath + inputFile
171 | let outputFile = inputFile
172 |
173 | do {
174 | let input = try String(contentsOfFile: inputFile)
175 | var lines = input.components(separatedBy: .newlines)
176 |
177 | lines[24] = " font-size: \(defaultHeight);"
178 |
179 | let output = lines.joined(separator: "\n")
180 | try output.write(toFile: outputFile, atomically: true, encoding: .utf8)
181 | }
182 | catch {
183 | print("Error: \(error.localizedDescription)")
184 | }
185 | }
186 | }
187 | }
188 |
189 | // -----------------------------------------------------------------
190 | // WINDOW HEIGHT SIZE - Hack_2_KK
191 | // (when there IS Plugin loaded)
192 | // lines 798 803 - fix the text not fitting
193 | // Contents/Resources/skin/stylesheets/Komplete/KK/BrowserPanel.txt
194 | // -----------------------------------------------------------------
195 |
196 | let inputAppFiles2_KK = "/Komplete Kontrol.app/Contents/Resources/skin/stylesheets/Komplete/KK/BrowserPanel.txt"
197 | let inputPlugFiles2_KK = [
198 | "/Komplete Kontrol.vst/Contents/Resources/skin/stylesheets/Komplete/KK/BrowserPanel.txt",
199 | "/Komplete Kontrol.vst3/Contents/Resources/skin/stylesheets/Komplete/KK/BrowserPanel.txt",
200 | "/Komplete Kontrol.aaxplugin/Contents/Resources/skin/stylesheets/Komplete/KK/BrowserPanel.txt",
201 | "/Komplete Kontrol.component/Contents/Resources/skin/stylesheets/Komplete/KK/BrowserPanel.txt"
202 | ]
203 |
204 | func Hack_2_KK(KK_app1: Bool, KK_plug1: Bool, minHeight: String) {
205 |
206 | if KK_app1 {
207 | let inputFile = basePath + inputAppFiles2_KK
208 | let outputFile = inputFile
209 |
210 | do {
211 | let input = try String(contentsOfFile: inputFile)
212 | var lines = input.components(separatedBy: .newlines)
213 |
214 | lines[8] = " min-height: \(minHeight);"
215 |
216 | let output = lines.joined(separator: "\n")
217 | try output.write(toFile: outputFile, atomically: true, encoding: .utf8)
218 | }
219 |
220 | catch {
221 | print("Error: \(error.localizedDescription)")
222 | }
223 | }
224 |
225 | if KK_plug1 {
226 | for inputFile in inputPlugFiles2_KK {
227 | let inputFile = basePath + inputFile
228 | let outputFile = inputFile
229 |
230 | do {
231 | let input = try String(contentsOfFile: inputFile)
232 | var lines = input.components(separatedBy: .newlines)
233 |
234 | lines[8] = " min-height: \(minHeight);"
235 |
236 | // lines[797] = " width: 79;"
237 | // lines[802] = " width: 120;"
238 |
239 | let output = lines.joined(separator: "\n")
240 | try output.write(toFile: outputFile, atomically: true, encoding: .utf8)
241 | }
242 | catch {
243 | print("Error: \(error.localizedDescription)")
244 | }
245 | }
246 | }
247 | }
248 |
249 | // -----------------------------------------------------------------
250 | // FONT SIZE Buttons - Hack_3_KK
251 | // ()
252 | // Contents/Resources/skin/stylesheets/Komplete/Global/Buttons.txt
253 | // -----------------------------------------------------------------
254 |
255 | let inputAppFiles3_KK = "/Komplete Kontrol.app/Contents/Resources/skin/stylesheets/Komplete/Global/Buttons.txt"
256 | let inputPlugFiles3_KK = [
257 | "/Komplete Kontrol.vst/Contents/Resources/skin/stylesheets/Komplete/Global/Buttons.txt",
258 | "/Komplete Kontrol.vst3/Contents/Resources/skin/stylesheets/Komplete/Global/Buttons.txt",
259 | "/Komplete Kontrol.aaxplugin/Contents/Resources/skin/stylesheets/Komplete/Global/Buttons.txt",
260 | "/Komplete Kontrol.component/Contents/Resources/skin/stylesheets/Komplete/Global/Buttons.txt"
261 | ]
262 |
263 | func Hack_3_KK(KK_app3: Bool, KK_plug3: Bool, fontButtons: String) {
264 |
265 | if KK_app3 {
266 | let inputFile = basePath + inputAppFiles3_KK
267 | let outputFile = inputFile
268 |
269 | do {
270 | let input = try String(contentsOfFile: inputFile)
271 | var lines = input.components(separatedBy: .newlines)
272 |
273 | lines[21] = " font-size: \(fontButtons);"
274 |
275 | let output = lines.joined(separator: "\n")
276 | try output.write(toFile: outputFile, atomically: true, encoding: .utf8)
277 | }
278 |
279 | catch {
280 | print("Error: \(error.localizedDescription)")
281 | }
282 | }
283 |
284 | if KK_plug3 {
285 | for inputFile in inputPlugFiles3_KK {
286 | let inputFile = basePath + inputFile
287 | let outputFile = inputFile
288 |
289 | do {
290 | let input = try String(contentsOfFile: inputFile)
291 | var lines = input.components(separatedBy: .newlines)
292 |
293 | lines[21] = " font-size: \(fontButtons);"
294 |
295 | let output = lines.joined(separator: "\n")
296 | try output.write(toFile: outputFile, atomically: true, encoding: .utf8)
297 | }
298 | catch {
299 | print("Error: \(error.localizedDescription)")
300 | }
301 | }
302 | }
303 | }
304 |
305 | // -----------------------------------------------------------------
306 | // FONT SIZE Buttons - Hack_4_KK
307 | // ()
308 | // /Contents/Resources/skin/stylesheets/Komplete/Development/Dev_Labels.txt
309 | // -----------------------------------------------------------------
310 |
311 | let inputAppFiles4_KK = "/Komplete Kontrol.app/Contents/Resources/skin/stylesheets/Komplete/Development/Dev_Labels.txt"
312 | let inputPlugFiles4_KK = [
313 | "/Komplete Kontrol.vst/Contents/Resources/skin/stylesheets/Komplete/Development/Dev_Labels.txt",
314 | "/Komplete Kontrol.vst3/Contents/Resources/skin/stylesheets/Komplete/Development/Dev_Labels.txt",
315 | "/Komplete Kontrol.aaxplugin/Contents/Resources/skin/stylesheets/Komplete/Development/Dev_Labels.txt",
316 | "/Komplete Kontrol.component/Contents/Resources/skin/stylesheets/Komplete/Development/Dev_Labels.txt"
317 | ]
318 |
319 | func Hack_4_KK(KK_app3: Bool, KK_plug3: Bool, fontDevLabels: String) {
320 |
321 | if KK_app3 {
322 | let inputFile = basePath + inputAppFiles4_KK
323 | let outputFile = inputFile
324 |
325 | do {
326 | let input = try String(contentsOfFile: inputFile)
327 | var lines = input.components(separatedBy: .newlines)
328 |
329 | lines[9] = " font-size: \(fontDevLabels);"
330 |
331 | let output = lines.joined(separator: "\n")
332 | try output.write(toFile: outputFile, atomically: true, encoding: .utf8)
333 | }
334 |
335 | catch {
336 | print("Error: \(error.localizedDescription)")
337 | }
338 | }
339 |
340 | if KK_plug3 {
341 | for inputFile in inputPlugFiles4_KK {
342 | let inputFile = basePath + inputFile
343 | let outputFile = inputFile
344 |
345 | do {
346 | let input = try String(contentsOfFile: inputFile)
347 | var lines = input.components(separatedBy: .newlines)
348 |
349 | lines[9] = " font-size: \(fontDevLabels);"
350 |
351 | let output = lines.joined(separator: "\n")
352 | try output.write(toFile: outputFile, atomically: true, encoding: .utf8)
353 | }
354 | catch {
355 | print("Error: \(error.localizedDescription)")
356 | }
357 | }
358 | }
359 | }
360 |
361 | // -----------------------------------------------------------------
362 | // FIX needed after Hacks 2 and 3
363 | //
364 | // lines 798 803 of the og, paths constants not needed, reusing the ones from Hack2. Fix wrapper of "Types" "Character" tittle tags
365 | //
366 | // Contents/Resources/skin/stylesheets/Komplete/KK/BrowserPanel.txt
367 | // -----------------------------------------------------------------
368 |
369 | func FontFixKK1(KK_app3: Bool, KK_plug3: Bool) {
370 |
371 | if KK_app3 {
372 | let inputFile = basePath + inputAppFiles2_KK
373 | let outputFile = inputFile
374 |
375 | do {
376 | let input = try String(contentsOfFile: inputFile)
377 | var lines = input.components(separatedBy: .newlines)
378 |
379 | lines[797] = " width: 79;"
380 | lines[802] = " width: 120;"
381 |
382 | let output = lines.joined(separator: "\n")
383 | try output.write(toFile: outputFile, atomically: true, encoding: .utf8)
384 | }
385 |
386 | catch {
387 | print("Error: \(error.localizedDescription)")
388 | }
389 | }
390 |
391 | if KK_plug3 {
392 | for inputFile in inputPlugFiles2_KK {
393 | let inputFile = basePath + inputFile
394 | let outputFile = inputFile
395 |
396 | do {
397 | let input = try String(contentsOfFile: inputFile)
398 | var lines = input.components(separatedBy: .newlines)
399 |
400 | lines[797] = " width: 79;"
401 | lines[802] = " width: 120;"
402 |
403 | let output = lines.joined(separator: "\n")
404 | try output.write(toFile: outputFile, atomically: true, encoding: .utf8)
405 | }
406 | catch {
407 | print("Error: \(error.localizedDescription)")
408 | }
409 | }
410 | }
411 | }
412 |
413 |
414 |
415 | // -----------------------------------------------------------------
416 | // FIX needed after Hacks 2 and 3
417 | //
418 | // lines 72 79 170 176 327 - Fixes button sizes for Scale, Arp & MIDI Learn
419 | //
420 | // /Contents/Resources/skin/stylesheets/Komplete/KK/ParameterArea.txt
421 | // -----------------------------------------------------------------
422 |
423 | let inputAppFix2_KK = "/Komplete Kontrol.app/Contents/Resources/skin/stylesheets/Komplete/KK/ParameterArea.txt"
424 | let inputPlugFix2_KK = [
425 | "/Komplete Kontrol.vst/Contents/Resources/skin/stylesheets/Komplete/KK/ParameterArea.txt",
426 | "/Komplete Kontrol.vst3/Contents/Resources/skin/stylesheets/Komplete/KK/ParameterArea.txt",
427 | "/Komplete Kontrol.aaxplugin/Contents/Resources/skin/stylesheets/Komplete/KK/ParameterArea.txt",
428 | "/Komplete Kontrol.component/Contents/Resources/skin/stylesheets/Komplete/KK/ParameterArea.txt"
429 | ]
430 |
431 | func FontFixKK2(KK_app3: Bool, KK_plug3: Bool) {
432 |
433 | if KK_app3 {
434 | let inputFile = basePath + inputAppFix2_KK
435 | let outputFile = inputFile
436 |
437 | do {
438 | let input = try String(contentsOfFile: inputFile)
439 | var lines = input.components(separatedBy: .newlines)
440 |
441 | lines[71] = " width: 89;"
442 | lines[78] = " width: 76;"
443 | lines[169] = " width: 55;"
444 | lines[175] = " width: 42;"
445 | lines[326] = " width: 102;"
446 |
447 | let output = lines.joined(separator: "\n")
448 | try output.write(toFile: outputFile, atomically: true, encoding: .utf8)
449 | }
450 |
451 | catch {
452 | print("Error: \(error.localizedDescription)")
453 | }
454 | }
455 |
456 | if KK_plug3 {
457 | for inputFile in inputPlugFix2_KK {
458 | let inputFile = basePath + inputFile
459 | let outputFile = inputFile
460 |
461 | do {
462 | let input = try String(contentsOfFile: inputFile)
463 | var lines = input.components(separatedBy: .newlines)
464 |
465 | lines[71] = " width: 89;"
466 | lines[78] = " width: 76;"
467 | lines[169] = " width: 55;"
468 | lines[175] = " width: 42;"
469 | lines[326] = " width: 102;"
470 |
471 | let output = lines.joined(separator: "\n")
472 | try output.write(toFile: outputFile, atomically: true, encoding: .utf8)
473 | }
474 | catch {
475 | print("Error: \(error.localizedDescription)")
476 | }
477 | }
478 | }
479 | }
480 |
481 |
482 | // -----------------------------------------------------------------
483 | // WIDER BROWSER - Hack_5_KK
484 | //
485 | // / Resources/skin/stylesheets/Komplete/Definitions/Metrics.txt
486 | //
487 | // -----------------------------------------------------------------
488 |
489 | let inputAppFiles5_KK = "/Komplete Kontrol.app/Contents/Resources/skin/stylesheets/Komplete/Definitions/Metrics.txt"
490 | let inputPlugFiles5_KK = [
491 | "/Komplete Kontrol.vst/Contents/Resources/skin/stylesheets/Komplete/Definitions/Metrics.txt",
492 | "/Komplete Kontrol.vst3/Contents/Resources/skin/stylesheets/Komplete/Definitions/Metrics.txt",
493 | "/Komplete Kontrol.aaxplugin/Contents/Resources/skin/stylesheets/Komplete/Definitions/Metrics.txt",
494 | "/Komplete Kontrol.component/Contents/Resources/skin/stylesheets/Komplete/Definitions/Metrics.txt"
495 | ]
496 |
497 | func Hack_5_KK(KK_app5: Bool, KK_plug5: Bool) {
498 |
499 | if KK_app5 {
500 | let inputFile = basePath + inputAppFiles5_KK
501 | let outputFile = inputFile
502 |
503 | do {
504 | let input = try String(contentsOfFile: inputFile)
505 | var lines = input.components(separatedBy: .newlines)
506 |
507 | lines[5] = "@define $browserMainWidth 430;"
508 |
509 | let output = lines.joined(separator: "\n")
510 | try output.write(toFile: outputFile, atomically: true, encoding: .utf8)
511 | }
512 |
513 | catch {
514 | print("Error: \(error.localizedDescription)")
515 | }
516 | }
517 |
518 | if KK_plug5 {
519 | for inputFile in inputPlugFiles5_KK {
520 | let inputFile = basePath + inputFile
521 | let outputFile = inputFile
522 |
523 | do {
524 | let input = try String(contentsOfFile: inputFile)
525 | var lines = input.components(separatedBy: .newlines)
526 |
527 | lines[5] = "@define $browserMainWidth 430;"
528 |
529 | let output = lines.joined(separator: "\n")
530 | try output.write(toFile: outputFile, atomically: true, encoding: .utf8)
531 | }
532 | catch {
533 | print("Error: \(error.localizedDescription)")
534 | }
535 | }
536 | }
537 | }
538 |
539 | // -----------------------------------------------------------------
540 | // WIDER BROWSER - Hack_5_KK_fix
541 | // -----------------------------------------------------------------
542 | // Multiple fixes needed when changing the browser width
543 | // /Contents/Resources/skin/stylesheets/Komplete/KK/BrowserPanel.txt
544 | // -----------------------------------------------------------------
545 | // Reusing path constants of HACK 2 since it's the same .txt file
546 | // inputAppFiles2_KK and inputPlugFiles2_KK
547 |
548 |
549 | func WideBrowserKK_fix(KK_app5: Bool, KK_plug5: Bool) {
550 |
551 | if KK_app5 {
552 | let inputFile = basePath + inputAppFiles2_KK
553 | let outputFile = inputFile
554 |
555 | do {
556 | let input = try String(contentsOfFile: inputFile)
557 | var lines = input.components(separatedBy: .newlines)
558 |
559 | lines[40] = " width: 430;"
560 | lines[53] = " width: 430;"
561 | lines[185] = " width: 311;"
562 | lines[532] = " width: 430;"
563 | lines[594] = " width: 414;"
564 | lines[605] = " width: 416;"
565 | lines[1124] = " width: 370;"//can crash, add a delay?
566 |
567 | let output = lines.joined(separator: "\n")
568 | try output.write(toFile: outputFile, atomically: true, encoding: .utf8)
569 | }
570 |
571 | catch {
572 | print("Error: \(error.localizedDescription)")
573 | }
574 | }
575 |
576 | if KK_plug5 {
577 | for inputFile in inputPlugFiles2_KK {
578 | let inputFile = basePath + inputFile
579 | let outputFile = inputFile
580 |
581 | do {
582 | let input = try String(contentsOfFile: inputFile)
583 | var lines = input.components(separatedBy: .newlines)
584 |
585 | lines[40] = " width: 430;"
586 | lines[53] = " width: 430;"
587 | lines[185] = " width: 311;"
588 | lines[532] = " width: 430;"
589 | lines[594] = " width: 414;"
590 | lines[605] = " width: 416;"
591 | lines[1124] = " width: 370;"
592 |
593 | let output = lines.joined(separator: "\n")
594 | try output.write(toFile: outputFile, atomically: true, encoding: .utf8)
595 | }
596 | catch {
597 | print("Error: \(error.localizedDescription)")
598 | }
599 | }
600 | }
601 | }
602 |
--------------------------------------------------------------------------------
/NIPatcher/Functions/Functions_MAS.swift:
--------------------------------------------------------------------------------
1 | // Eventually Function names should match filepath somehow?
2 | // in case more hacks relate to the same file in the future,
3 | // only applies to hacks that change the line count of the og file.
4 |
5 | import Foundation
6 |
7 | // -----------------------------------------------------------------------
8 | // Logo replace (2 files)
9 | // extended attributes have to be removed from pngs for it to work xattr -rc .
10 | // -----------------------------------------------------------------------
11 |
12 | func logoReplaceMAS() {
13 | let fileManager = FileManager.default
14 |
15 | // Get the URLs for the images in the project folder
16 | guard let mainImageURL = Bundle.main.url(forResource: "HDR_LOGO_MAS_Main", withExtension: "png"),
17 | let pictoImageURL = Bundle.main.url(forResource: "HDR_LOGO_MAS_Picto", withExtension: "png") else {
18 | print("Error: Failed to get image URLs")
19 | return
20 | }
21 |
22 | // Get the URL for the NIPatcher folder on the desktop
23 | guard let desktopURL = fileManager.urls(for: .desktopDirectory, in: .userDomainMask).first else {
24 | print("Error: Failed to get desktop URL")
25 | return
26 | }
27 | let nipatcherURL = desktopURL.appendingPathComponent("NIPatcher")
28 |
29 | // Define the destination paths for the images
30 | let destinationPaths = [
31 | "/Maschine 2.app/Contents/Resources/skin/pictures/Maschine/Header/",
32 | "/Maschine 2.vst/Contents/Resources/skin/pictures/Maschine/Header/",
33 | "/Maschine 2.vst3/Contents/Resources/skin/pictures/Maschine/Header/",
34 | "/Maschine 2.aaxplugin/Contents/Resources/skin/pictures/Maschine/Header/",
35 | "/Maschine 2.component/Contents/Resources/skin/pictures/Maschine/Header/"
36 | ]
37 |
38 | // Copy the images to their destination
39 | for path in destinationPaths {
40 | let mainDestinationURL = nipatcherURL.appendingPathComponent(path + "HDR_LOGO_MAS_Main.png")
41 | let pictoDestinationURL = nipatcherURL.appendingPathComponent(path + "HDR_LOGO_MAS_Picto.png")
42 |
43 | do {
44 | if fileManager.fileExists(atPath: mainDestinationURL.path) {
45 | try fileManager.removeItem(at: mainDestinationURL)
46 | try fileManager.copyItem(at: mainImageURL, to: mainDestinationURL)
47 | }
48 |
49 | if fileManager.fileExists(atPath: pictoDestinationURL.path) {
50 | try fileManager.removeItem(at: pictoDestinationURL)
51 | try fileManager.copyItem(at: pictoImageURL, to: pictoDestinationURL)
52 | }
53 | } catch {
54 | print("Error: \(error.localizedDescription)")
55 | }
56 | }
57 | }
58 | // /Contents/Resources/skin/pictures/Komplete/KK/Header
59 |
60 | // -------------------------------------------------------------
61 | // Copy all plugins and app to a folder on the desktop
62 | // -------------------------------------------------------------
63 |
64 | func copyFilesToNIPatcherFolder() throws {
65 | let fileManager = FileManager.default
66 | let desktopURL = fileManager.urls(for: .desktopDirectory, in: .userDomainMask).first!
67 | let destinationURL = desktopURL.appendingPathComponent("NIPatcher")
68 |
69 | try fileManager.createDirectory(at: destinationURL, withIntermediateDirectories: true, attributes: nil)
70 |
71 | let fileURLs = [
72 | URL(fileURLWithPath: "/Library/Audio/Plug-Ins/VST/Maschine 2.vst"),
73 | URL(fileURLWithPath: "/Library/Audio/Plug-Ins/VST3/Maschine 2.vst3"),
74 | URL(fileURLWithPath: "/Library/Audio/Plug-Ins/Components/Maschine 2.component"),
75 | URL(fileURLWithPath: "/Library/Application Support/Avid/Audio/Plug-Ins/Maschine 2.aaxplugin"),
76 | URL(fileURLWithPath: "/Applications/Native Instruments/Maschine 2/Maschine 2.app")
77 | ]
78 |
79 | for fileURL in fileURLs {
80 | let destinationFileURL = destinationURL.appendingPathComponent(fileURL.lastPathComponent)
81 | do {
82 | if fileManager.fileExists(atPath: destinationFileURL.path) {
83 | try fileManager.removeItem(at: destinationFileURL)
84 | }
85 | try fileManager.copyItem(at: fileURL, to: destinationFileURL)
86 | } catch {
87 | print("Error copying file at \(fileURL.path): \(error.localizedDescription)")
88 | }
89 | }
90 | }
91 |
92 | // -------------------------------------------------------------
93 | // Create shortcuts in the desktop.
94 | // -------------------------------------------------------------
95 |
96 | func createAliasesForFolders() {
97 | let fileManager = FileManager.default
98 |
99 | let folders = [
100 | "/Library/Audio/Plug-Ins/VST/",
101 | "/Library/Audio/Plug-Ins/VST3/",
102 | "/Library/Audio/Plug-Ins/Components/",
103 | "/Library/Application Support/Avid/Audio/Plug-Ins/",
104 | "/Applications/Native Instruments/Maschine 2/"
105 | ]
106 |
107 | let folderNames = [
108 | "/Library/Audio/Plug-Ins/VST/": "VST",
109 | "/Library/Audio/Plug-Ins/VST3/": "VST3",
110 | "/Library/Audio/Plug-Ins/Components/": "AU",
111 | "/Library/Application Support/Avid/Audio/Plug-Ins/": "AAX",
112 | "/Applications/Native Instruments/Maschine 2/": "MAS App"
113 | ]
114 |
115 | let destinationFolder = URL(fileURLWithPath: NSHomeDirectory()).appendingPathComponent("Desktop/NIPatcher")
116 |
117 | do {
118 | try fileManager.createDirectory(at: destinationFolder, withIntermediateDirectories: true, attributes: nil)
119 | } catch {
120 | print("Error creating directory: \(error.localizedDescription)")
121 | }
122 |
123 | for folder in folders {
124 | let sourceFolder = URL(fileURLWithPath: folder)
125 |
126 | if let folderName = folderNames[folder] {
127 | do {
128 | try fileManager.createSymbolicLink(at: destinationFolder.appendingPathComponent(folderName), withDestinationURL: sourceFolder)
129 | } catch {
130 | print("Error creating alias for \(folder): \(error.localizedDescription)")
131 | }
132 | } else {
133 | print("No folder name found for \(folder)")
134 | }
135 | }
136 | }
137 |
138 | // ---------------------------------------------------------------------
139 | // HACK #1 - Plugin sizes - Panels_TopLevel
140 | //
141 | // /skin/stylesheets/Maschine/Panels/TopLevel.txt
142 | // ---------------------------------------------------------------------
143 | // For now I use the smallWidth for smallWidthBrowser - revist later
144 |
145 | // Grab the desktop path ?? MOVE THIS TO GLOBAL FUNCTIONS FILE?
146 | let fileManager = FileManager.default
147 | let desktopURL = try! fileManager.url(for: .desktopDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
148 | let nipatcherURL = desktopURL.appendingPathComponent("NIPatcher")
149 | let basePath = nipatcherURL.path
150 |
151 |
152 | let inputAppFiles = "/Maschine 2.app/Contents/Resources/skin/stylesheets/Maschine/Panels/TopLevel.txt"
153 | let inputPlugFiles = [
154 | "/Maschine 2.vst/Contents/Resources/skin/stylesheets/Maschine/Panels/TopLevel.txt",
155 | "/Maschine 2.vst3/Contents/Resources/skin/stylesheets/Maschine/Panels/TopLevel.txt",
156 | "/Maschine 2.aaxplugin/Contents/Resources/skin/stylesheets/Maschine/Panels/TopLevel.txt",
157 | "/Maschine 2.component/Contents/Resources/skin/stylesheets/Maschine/Panels/TopLevel.txt"
158 | ]
159 |
160 | func Hack_1(inputAppFiles: String, inputPlugFiles: [String], app1: Bool, plug1: Bool, MminHeight: String, smallWidth: String, smallWidthBrowser: String, smallHeight: String, medWidth: String, medHeight: String, largeWidth: String, largeHeight: String) {
161 |
162 | if app1 {
163 | let inputFile = basePath + inputAppFiles
164 | let outputFile = inputFile
165 |
166 | do {
167 | // Read the input file into an array of lines
168 | let input = try String(contentsOfFile: inputFile)
169 | var lines = input.components(separatedBy: .newlines)
170 |
171 | // Create an array of new lines to insert
172 | let newLines = [
173 | " min-height: \(MminHeight);",
174 | "",
175 | " window-small-width: \(smallWidth);",
176 | "",
177 | " window-small-width-browser: \(smallWidth);",
178 | " window-small-height: \(smallHeight);",
179 | "",
180 | " window-medium-width: \(medWidth);",
181 | " window-medium-height: \(medHeight);",
182 | "",
183 | " window-large-width: \(largeWidth);",
184 | " window-large-height: \(largeHeight);"
185 | ]
186 |
187 | // Replace the lines in the specified range with the new lines
188 | lines.replaceSubrange(20..<32, with: newLines)
189 |
190 | // Write the modified array of lines to the output file
191 | let output = lines.joined(separator: "\n")
192 | try output.write(toFile: outputFile, atomically: true, encoding: .utf8)
193 |
194 | // Print the output file path - Remove later
195 | print("Hack #1 Applied: \(outputFile)")
196 | }
197 | catch {
198 | print("Error in Hack #1: \(error.localizedDescription)")
199 | }
200 | }
201 |
202 | if plug1 {
203 | for inputFile in inputPlugFiles {
204 | let inputFile = basePath + inputFile
205 | let outputFile = inputFile
206 |
207 | do {
208 | // Read the input file into an array of lines
209 | let input = try String(contentsOfFile: inputFile)
210 | var lines = input.components(separatedBy: .newlines)
211 |
212 | // Create an array of new lines to insert
213 | let newLines = [
214 | " min-height: \(MminHeight);",
215 | "",
216 | " window-small-width: \(smallWidth);",
217 | "",
218 | " window-small-width-browser: \(smallWidthBrowser);",
219 | " window-small-height: \(smallHeight);",
220 | "",
221 | " window-medium-width: \(medWidth);",
222 | " window-medium-height: \(medHeight);",
223 | "",
224 | " window-large-width: \(largeWidth);",
225 | " window-large-height: \(largeHeight);"
226 | ]
227 |
228 | // Replace the lines in the specified range with the new lines
229 | lines.replaceSubrange(20..<32, with: newLines)
230 |
231 | // Write the modified array of lines to the output file
232 | let output = lines.joined(separator: "\n")
233 | try output.write(toFile: outputFile, atomically: true, encoding: .utf8)
234 |
235 | // Print the output file path - Remove later
236 | print("Hack 1 Applied: \(outputFile)")
237 | }
238 | catch {
239 | print("Error in Panels_TopLevel: \(error.localizedDescription)")
240 | }
241 | }
242 | }
243 | }
244 |
245 |
246 | // -----------------------------------------------------------------
247 | // HACK 2 - Font size #1 Labels
248 | // /skin/stylesheets/Maschine/Standard/Labels.txt
249 | //
250 | // Hack 2 and 3 are always both applied regardless, for simplicity.
251 | // -----------------------------------------------------------------
252 |
253 | let inputAppFiles2 = "/Maschine 2.app/Contents/Resources/skin/stylesheets/Maschine/Standard/Labels.txt"
254 |
255 | let inputPlugFiles2 = [
256 | "/Maschine 2.vst/Contents/Resources/skin/stylesheets/Maschine/Standard/Labels.txt",
257 | "/Maschine 2.vst3/Contents/Resources/skin/stylesheets/Maschine/Standard/Labels.txt",
258 | "/Maschine 2.aaxplugin/Contents/Resources/skin/stylesheets/Maschine/Standard/Labels.txt",
259 | "/Maschine 2.component/Contents/Resources/skin/stylesheets/Maschine/Standard/Labels.txt"
260 | ]
261 |
262 | func Hack_2(app2: Bool, plug2: Bool, fontLabel: String) {
263 |
264 | if app2 {
265 | let inputFile = basePath + inputAppFiles2
266 | let outputFile = inputFile
267 |
268 | do {
269 | let input = try String(contentsOfFile: inputFile)
270 | var lines = input.components(separatedBy: .newlines)
271 |
272 | lines[11] = " font-size: \(fontLabel);"
273 |
274 | let output = lines.joined(separator: "\n")
275 | try output.write(toFile: outputFile, atomically: true, encoding: .utf8)
276 | }
277 |
278 | catch {
279 | print("Error in Hack #2: \(error.localizedDescription)")
280 | }
281 | }
282 |
283 | if plug2 {
284 | for inputFile in inputPlugFiles2 {
285 | let inputFile = basePath + inputFile
286 | let outputFile = inputFile
287 |
288 | do {
289 | let input = try String(contentsOfFile: inputFile)
290 | var lines = input.components(separatedBy: .newlines)
291 |
292 | lines[11] = " font-size: \(fontLabel);"
293 |
294 | let output = lines.joined(separator: "\n")
295 | try output.write(toFile: outputFile, atomically: true, encoding: .utf8)
296 | }
297 | catch {
298 | print("Error in Hack #2: \(error.localizedDescription)")
299 | }
300 | }
301 | }
302 | }
303 |
304 | // ------------------------------------------------------------
305 | // HACK 3 - Font size #2 Buttons
306 | // /skin/stylesheets/Maschine/Standard/Buttons.txt
307 | // ------------------------------------------------------------
308 |
309 | let inputAppFiles3 = "/Maschine 2.app/Contents/Resources/skin/stylesheets/Maschine/Standard/Buttons.txt"
310 | let inputPlugFiles3 = [
311 | "/Maschine 2.vst/Contents/Resources/skin/stylesheets/Maschine/Standard/Buttons.txt",
312 | "/Maschine 2.vst3/Contents/Resources/skin/stylesheets/Maschine/Standard/Buttons.txt",
313 | "/Maschine 2.aaxplugin/Contents/Resources/skin/stylesheets/Maschine/Standard/Buttons.txt",
314 | "/Maschine 2.component/Contents/Resources/skin/stylesheets/Maschine/Standard/Buttons.txt"
315 | ]
316 |
317 | func Hack_3(app2: Bool, plug2: Bool, fontButton: String) {
318 |
319 | if app2 {
320 |
321 | let inputFile = basePath + inputAppFiles3
322 | let outputFile = inputFile
323 |
324 | do {
325 | let input = try String(contentsOfFile: inputFile)
326 | var lines = input.components(separatedBy: .newlines)
327 | lines.remove(at: 21)
328 | lines.insert(" font-size: \(fontButton);", at: 21)
329 |
330 | let output = lines.joined(separator: "\n")
331 | try output.write(toFile: outputFile, atomically: true, encoding: .utf8)
332 |
333 | print("Hack #3 Applied: \(outputFile)")
334 | }
335 | catch {
336 | print("Error in Hack #3: \(error.localizedDescription)")
337 | }
338 | }
339 | if plug2 {
340 | for inputFile in inputPlugFiles3 {
341 | let inputFile = basePath + inputFile
342 | let outputFile = inputFile
343 |
344 | do {
345 | let input = try String(contentsOfFile: inputFile)
346 | var lines = input.components(separatedBy: .newlines)
347 | lines.remove(at: 21)
348 | lines.insert(" font-size: \(fontButton);", at: 21)
349 |
350 | let output = lines.joined(separator: "\n")
351 | try output.write(toFile: outputFile, atomically: true, encoding: .utf8)
352 |
353 | print("Hack 3 Applied: \(outputFile)")
354 | }
355 | catch {
356 | print("Error in Hack #3: \(error.localizedDescription)")
357 | }
358 | }
359 |
360 | }
361 | }
362 |
363 | // -------------------------------------------------------------------------
364 | // HACK 2 / HACK 3 fix
365 | // Also need to edit BrowserPanel.txt or "character/type" text wont fit
366 | // /skin/stylesheets/Maschine/Panels/BrowserPanel.txt
367 | // -------------------------------------------------------------------------
368 |
369 | let inputAppFiles2_BrowserPanel = "/Maschine 2.app/Contents/Resources/skin/stylesheets/Maschine/Panels/BrowserPanel.txt"
370 |
371 | let inputPlugFiles2_BrowserPanel = [
372 | "/Maschine 2.vst/Contents/Resources/skin/stylesheets/Maschine/Panels/BrowserPanel.txt",
373 | "/Maschine 2.vst3/Contents/Resources/skin/stylesheets/Maschine/Panels/BrowserPanel.txt",
374 | "/Maschine 2.aaxplugin/Contents/Resources/skin/stylesheets/Maschine/Panels/BrowserPanel.txt",
375 | "/Maschine 2.component/Contents/Resources/skin/stylesheets/Maschine/Panels/BrowserPanel.txt"
376 | ]
377 |
378 | func Hack_2_3_fix(app2: Bool, plug2: Bool) {
379 |
380 | if app2 {
381 | let inputFile = basePath + inputAppFiles2_BrowserPanel
382 | let outputFile = inputFile
383 |
384 | do {
385 | let input = try String(contentsOfFile: inputFile)
386 | var lines = input.components(separatedBy: .newlines)
387 |
388 | lines.remove(at: 879)
389 | lines.insert(" width: 80;", at: 879)
390 | lines.remove(at: 884)
391 | lines.insert(" width: 150;", at: 884)
392 |
393 | let output = lines.joined(separator: "\n")
394 | try output.write(toFile: outputFile, atomically: true, encoding: .utf8)
395 | }
396 |
397 | catch {
398 | print("Error in Hack #2: \(error.localizedDescription)")
399 | }
400 | }
401 |
402 | if plug2 {
403 | for inputFile in inputPlugFiles2_BrowserPanel {
404 | let inputFile = basePath + inputFile
405 | let outputFile = inputFile
406 |
407 | do {
408 | let input = try String(contentsOfFile: inputFile)
409 | var lines = input.components(separatedBy: .newlines)
410 |
411 | lines.remove(at: 879)
412 | lines.insert(" width: 80;", at: 879)
413 | lines.remove(at: 884)
414 | lines.insert(" width: 150;", at: 884)
415 |
416 | let output = lines.joined(separator: "\n")
417 | try output.write(toFile: outputFile, atomically: true, encoding: .utf8)
418 | }
419 | catch {
420 | print("Error in Hack #2: \(error.localizedDescription)")
421 | }
422 | }
423 | }
424 | }
425 |
426 |
427 | // ------------------------------------------------------------
428 | // HACK 4 - Stop Button --- APP ONLY!
429 | // TransportSection.lua
430 | // /Scripts/Shared/Components/TransportSection.lua
431 | // ------------------------------------------------------------
432 |
433 | let inputAppFiles4 = "/Maschine 2.app/Contents/Resources/Scripts/Shared/Components/TransportSection.lua"
434 |
435 | func SC_TransportSection() {
436 | let inputFile = basePath + inputAppFiles4
437 | let outputFile = inputFile
438 |
439 | do {
440 | var lines = try String(contentsOfFile: inputFile).components(separatedBy: .newlines)
441 |
442 | lines.replaceSubrange(106..<113, with: [
443 | " function TransportSection:onStop(Pressed)",
444 | "",
445 | " if Pressed and MaschineHelper.isPlaying() then",
446 | " NI.DATA.TransportAccess.togglePlay(App)",
447 | " else",
448 | " if Pressed and not MaschineHelper.isPlaying() then",
449 | " NI.DATA.TransportAccess.restartTransport(App)",
450 | " NI.DATA.TransportAccess.togglePlay(App)",
451 | " end",
452 | "",
453 | " end",
454 | "",
455 | " end",
456 | ])
457 |
458 | try lines.joined(separator: "\n").write(toFile: outputFile, atomically: true, encoding: .utf8)
459 |
460 | print("Hack #4 Applied: \(outputFile)")
461 | } catch {
462 | print("Error in Hack #4: \(error.localizedDescription)")
463 | }
464 | }
465 |
466 | // ------------------------------------------------------------
467 | // HACK 5 - Font size #2 Buttons
468 | // /Scripts/Maschine/Helper/PatternHelper.lua
469 | // ------------------------------------------------------------
470 | // https://community.native-instruments.com/discussion/5072/tip-changing-patterns-on-the-maschine-jam-without-changing-focus
471 |
472 | let inputAppFiles5 = "/Maschine 2.app/Contents/Resources/Scripts/Maschine/Helper/PatternHelper.lua"
473 | let inputPlugFiles5 = [
474 | "/Maschine 2.vst/Contents/Resources/Scripts/Maschine/Helper/PatternHelper.lua",
475 | "/Maschine 2.vst3/Contents/Resources/Scripts/Maschine/Helper/PatternHelper.lua",
476 | "/Maschine 2.aaxplugin/Resources/Scripts/Maschine/Helper/PatternHelper.lua",
477 | "/Maschine 2.component/Resources/Scripts/Maschine/Helper/PatternHelper.lua"
478 | ]
479 |
480 | func MH_PatternHelper(app5: Bool, plug5: Bool) {
481 |
482 | if app5 {
483 | let inputFile = basePath + inputAppFiles5
484 | let outputFile = inputFile
485 |
486 | do {
487 | let input = try String(contentsOfFile: inputFile)
488 | var lines = input.components(separatedBy: .newlines)
489 |
490 | let newLines = [
491 | "function PatternHelper.focusPatternByGroupAndByIndex(GroupIndex, PatternIndex, CreateIfEmpty)",
492 | "",
493 | " if PatternIndex == nil or PatternIndex < 0 or GroupIndex == nil or GroupIndex < 0 then",
494 | " return",
495 | " end",
496 | "",
497 | " local FocusGroup = NI.DATA.StateHelper.getFocusGroupIndex(App)",
498 | " local Group = MaschineHelper.getGroupAtIndex(GroupIndex)",
499 | "",
500 | " if Group then",
501 | " local Pattern = Group:getPatterns():find(PatternIndex)",
502 | "",
503 | " if Pattern then",
504 | " local FocusSection = NI.DATA.StateHelper.getFocusSection(App)",
505 | " local FocusScene = NI.DATA.StateHelper.getFocusScene(App)",
506 | " local FocusScenePattern = FocusScene and NI.DATA.SceneAccess.getPattern(FocusScene, Group)",
507 | " local HasFocus = Pattern == FocusScenePattern",
508 | "",
509 | " if HasFocus then",
510 | " if FocusSection then",
511 | " NI.DATA.SectionAccess.removePattern(App, FocusSection, Group)",
512 | " else -- In Idea Space we work on Scenes directly.",
513 | " NI.DATA.SceneAccess.removePattern(App, FocusScene, Group)",
514 | " end",
515 | " else",
516 | " NI.DATA.GroupAccess.insertPatternAndFocus(App, Group, Pattern)",
517 | " end",
518 | " if FocusGroup ~= GroupIndex then",
519 | " MaschineHelper.setFocusGroup(FocusGroup + 1, false)",
520 | " end",
521 | " elseif CreateIfEmpty == true then",
522 | " -- note: AudioPatterns can't currently be empty, so CreateIfEmpty is n/a",
523 | " PatternHelper.insertNewPattern(PatternIndex, Group)",
524 | " end",
525 | " end",
526 | "end"
527 | ]
528 |
529 | lines.replaceSubrange(181..<218, with: newLines)
530 |
531 | let output = lines.joined(separator: "\n")
532 | try output.write(toFile: outputFile, atomically: true, encoding: .utf8)
533 |
534 | print("Hack #5 Applied: \(outputFile)")
535 | }
536 | catch {
537 | print("Error in Hack #5: \(error.localizedDescription)")
538 | }
539 | }
540 | if plug5 {
541 | for inputFile in inputPlugFiles5 {
542 | let inputFile = basePath + inputFile
543 | let outputFile = inputFile
544 |
545 | do {
546 | let input = try String(contentsOfFile: inputFile)
547 | var lines = input.components(separatedBy: .newlines)
548 |
549 | let newLines = [
550 | "function PatternHelper.focusPatternByGroupAndByIndex(GroupIndex, PatternIndex, CreateIfEmpty)",
551 | "",
552 | " if PatternIndex == nil or PatternIndex < 0 or GroupIndex == nil or GroupIndex < 0 then",
553 | " return",
554 | " end",
555 | "",
556 | " local FocusGroup = NI.DATA.StateHelper.getFocusGroupIndex(App)",
557 | " local Group = MaschineHelper.getGroupAtIndex(GroupIndex)",
558 | "",
559 | " if Group then",
560 | " local Pattern = Group:getPatterns():find(PatternIndex)",
561 | "",
562 | " if Pattern then",
563 | " local FocusSection = NI.DATA.StateHelper.getFocusSection(App)",
564 | " local FocusScene = NI.DATA.StateHelper.getFocusScene(App)",
565 | " local FocusScenePattern = FocusScene and NI.DATA.SceneAccess.getPattern(FocusScene, Group)",
566 | " local HasFocus = Pattern == FocusScenePattern",
567 | "",
568 | " if HasFocus then",
569 | " if FocusSection then",
570 | " NI.DATA.SectionAccess.removePattern(App, FocusSection, Group)",
571 | " else -- In Idea Space we work on Scenes directly.",
572 | " NI.DATA.SceneAccess.removePattern(App, FocusScene, Group)",
573 | " end",
574 | " else",
575 | " NI.DATA.GroupAccess.insertPatternAndFocus(App, Group, Pattern)",
576 | " end",
577 | " if FocusGroup ~= GroupIndex then",
578 | " MaschineHelper.setFocusGroup(FocusGroup + 1, false)",
579 | " end",
580 | " elseif CreateIfEmpty == true then",
581 | " -- note: AudioPatterns can't currently be empty, so CreateIfEmpty is n/a",
582 | " PatternHelper.insertNewPattern(PatternIndex, Group)",
583 | " end",
584 | " end",
585 | "end"
586 | ]
587 |
588 | lines.replaceSubrange(181..<218, with: newLines)
589 |
590 | let output = lines.joined(separator: "\n")
591 | try output.write(toFile: outputFile, atomically: true, encoding: .utf8)
592 |
593 | print("Hack #5 Applied: \(outputFile)")
594 | }
595 | catch {
596 | print("Error in Hack #5: \(error.localizedDescription)")
597 | }
598 | }
599 |
600 | }
601 | }
602 |
--------------------------------------------------------------------------------
/NIPatcher/NIPatcher.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 56;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | D6142F9D29D49931005BF77D /* NIPatcherApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6142F9C29D49931005BF77D /* NIPatcherApp.swift */; };
11 | D6142F9F29D49931005BF77D /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6142F9E29D49931005BF77D /* ContentView.swift */; };
12 | D6142FA129D49932005BF77D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D6142FA029D49932005BF77D /* Assets.xcassets */; };
13 | D6142FA429D49932005BF77D /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D6142FA329D49932005BF77D /* Preview Assets.xcassets */; };
14 | D6142FAC29D49983005BF77D /* Functions_MAS.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6142FAB29D49983005BF77D /* Functions_MAS.swift */; };
15 | D6142FAF29D49B1E005BF77D /* MaschineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6142FAE29D49B1E005BF77D /* MaschineView.swift */; };
16 | D6142FB129D49B48005BF77D /* KompleteKontrolView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6142FB029D49B48005BF77D /* KompleteKontrolView.swift */; };
17 | D6142FB329D49B60005BF77D /* InfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6142FB229D49B60005BF77D /* InfoView.swift */; };
18 | D6142FB929D4A0D9005BF77D /* codesign.sh in Resources */ = {isa = PBXBuildFile; fileRef = D6142FAD29D49A63005BF77D /* codesign.sh */; };
19 | D6142FC129D4B1E2005BF77D /* HDR_LOGO_MAS_Picto.png in Resources */ = {isa = PBXBuildFile; fileRef = D6142FBF29D4B1E2005BF77D /* HDR_LOGO_MAS_Picto.png */; };
20 | D6142FC229D4B1E2005BF77D /* HDR_LOGO_MAS_Main.png in Resources */ = {isa = PBXBuildFile; fileRef = D6142FC029D4B1E2005BF77D /* HDR_LOGO_MAS_Main.png */; };
21 | D6A9E30329DE2269006FFE78 /* HDR_Logo_KP.png in Resources */ = {isa = PBXBuildFile; fileRef = D6A9E30229DE2243006FFE78 /* HDR_Logo_KP.png */; };
22 | D6CD78EC29D5F36B006845E3 /* Functions_KK.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6CD78EB29D5F36A006845E3 /* Functions_KK.swift */; };
23 | D6CD78EE29D5F48F006845E3 /* Functions_Global.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6CD78ED29D5F48F006845E3 /* Functions_Global.swift */; };
24 | D6DBD65D29D77B3400AE30CB /* codesignkk.sh in Resources */ = {isa = PBXBuildFile; fileRef = D6CD78F129D649A3006845E3 /* codesignkk.sh */; };
25 | /* End PBXBuildFile section */
26 |
27 | /* Begin PBXFileReference section */
28 | D6142F9929D49931005BF77D /* NIPatcher.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = NIPatcher.app; sourceTree = BUILT_PRODUCTS_DIR; };
29 | D6142F9C29D49931005BF77D /* NIPatcherApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NIPatcherApp.swift; sourceTree = ""; };
30 | D6142F9E29D49931005BF77D /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; };
31 | D6142FA029D49932005BF77D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
32 | D6142FA329D49932005BF77D /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; };
33 | D6142FA529D49932005BF77D /* NIPatcher.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = NIPatcher.entitlements; sourceTree = ""; };
34 | D6142FAB29D49983005BF77D /* Functions_MAS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Functions_MAS.swift; sourceTree = ""; };
35 | D6142FAD29D49A63005BF77D /* codesign.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = codesign.sh; sourceTree = ""; };
36 | D6142FAE29D49B1E005BF77D /* MaschineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MaschineView.swift; sourceTree = ""; };
37 | D6142FB029D49B48005BF77D /* KompleteKontrolView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KompleteKontrolView.swift; sourceTree = ""; };
38 | D6142FB229D49B60005BF77D /* InfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InfoView.swift; sourceTree = ""; };
39 | D6142FBF29D4B1E2005BF77D /* HDR_LOGO_MAS_Picto.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = HDR_LOGO_MAS_Picto.png; sourceTree = ""; };
40 | D6142FC029D4B1E2005BF77D /* HDR_LOGO_MAS_Main.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = HDR_LOGO_MAS_Main.png; sourceTree = ""; };
41 | D6A9E30229DE2243006FFE78 /* HDR_Logo_KP.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = HDR_Logo_KP.png; path = images/HDR_Logo_KP.png; sourceTree = SOURCE_ROOT; };
42 | D6CD78EB29D5F36A006845E3 /* Functions_KK.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Functions_KK.swift; sourceTree = ""; };
43 | D6CD78ED29D5F48F006845E3 /* Functions_Global.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Functions_Global.swift; sourceTree = ""; };
44 | D6CD78F129D649A3006845E3 /* codesignkk.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = codesignkk.sh; sourceTree = ""; };
45 | /* End PBXFileReference section */
46 |
47 | /* Begin PBXFrameworksBuildPhase section */
48 | D6142F9629D49931005BF77D /* Frameworks */ = {
49 | isa = PBXFrameworksBuildPhase;
50 | buildActionMask = 2147483647;
51 | files = (
52 | );
53 | runOnlyForDeploymentPostprocessing = 0;
54 | };
55 | /* End PBXFrameworksBuildPhase section */
56 |
57 | /* Begin PBXGroup section */
58 | D6142F9029D49930005BF77D = {
59 | isa = PBXGroup;
60 | children = (
61 | D6CD78F029D5F6FA006845E3 /* Views */,
62 | D6CD78EF29D5F6E1006845E3 /* Functions */,
63 | D6142F9B29D49931005BF77D /* NIPatcher */,
64 | D6142FC329D4B1FD005BF77D /* images */,
65 | D6833B9B29DCA6C9001CC047 /* shellScripts */,
66 | D6142F9A29D49931005BF77D /* Products */,
67 | );
68 | sourceTree = "";
69 | };
70 | D6142F9A29D49931005BF77D /* Products */ = {
71 | isa = PBXGroup;
72 | children = (
73 | D6142F9929D49931005BF77D /* NIPatcher.app */,
74 | );
75 | name = Products;
76 | sourceTree = "";
77 | };
78 | D6142F9B29D49931005BF77D /* NIPatcher */ = {
79 | isa = PBXGroup;
80 | children = (
81 | D6142F9C29D49931005BF77D /* NIPatcherApp.swift */,
82 | D6142F9E29D49931005BF77D /* ContentView.swift */,
83 | D6142FA029D49932005BF77D /* Assets.xcassets */,
84 | D6142FA529D49932005BF77D /* NIPatcher.entitlements */,
85 | D6142FA229D49932005BF77D /* Preview Content */,
86 | );
87 | path = NIPatcher;
88 | sourceTree = "";
89 | };
90 | D6142FA229D49932005BF77D /* Preview Content */ = {
91 | isa = PBXGroup;
92 | children = (
93 | D6142FA329D49932005BF77D /* Preview Assets.xcassets */,
94 | );
95 | path = "Preview Content";
96 | sourceTree = "";
97 | };
98 | D6142FC329D4B1FD005BF77D /* images */ = {
99 | isa = PBXGroup;
100 | children = (
101 | D6A9E30229DE2243006FFE78 /* HDR_Logo_KP.png */,
102 | D6142FC029D4B1E2005BF77D /* HDR_LOGO_MAS_Main.png */,
103 | D6142FBF29D4B1E2005BF77D /* HDR_LOGO_MAS_Picto.png */,
104 | );
105 | name = images;
106 | path = /Users/hackintosh/Desktop/XCODE/FINAL/NIPatcher/images;
107 | sourceTree = "";
108 | };
109 | D6833B9B29DCA6C9001CC047 /* shellScripts */ = {
110 | isa = PBXGroup;
111 | children = (
112 | D6142FAD29D49A63005BF77D /* codesign.sh */,
113 | D6CD78F129D649A3006845E3 /* codesignkk.sh */,
114 | );
115 | path = shellScripts;
116 | sourceTree = "";
117 | };
118 | D6CD78EF29D5F6E1006845E3 /* Functions */ = {
119 | isa = PBXGroup;
120 | children = (
121 | D6142FAB29D49983005BF77D /* Functions_MAS.swift */,
122 | D6CD78EB29D5F36A006845E3 /* Functions_KK.swift */,
123 | D6CD78ED29D5F48F006845E3 /* Functions_Global.swift */,
124 | );
125 | path = Functions;
126 | sourceTree = "";
127 | };
128 | D6CD78F029D5F6FA006845E3 /* Views */ = {
129 | isa = PBXGroup;
130 | children = (
131 | D6142FAE29D49B1E005BF77D /* MaschineView.swift */,
132 | D6142FB029D49B48005BF77D /* KompleteKontrolView.swift */,
133 | D6142FB229D49B60005BF77D /* InfoView.swift */,
134 | );
135 | path = Views;
136 | sourceTree = "";
137 | };
138 | /* End PBXGroup section */
139 |
140 | /* Begin PBXNativeTarget section */
141 | D6142F9829D49931005BF77D /* NIPatcher */ = {
142 | isa = PBXNativeTarget;
143 | buildConfigurationList = D6142FA829D49932005BF77D /* Build configuration list for PBXNativeTarget "NIPatcher" */;
144 | buildPhases = (
145 | D6142F9529D49931005BF77D /* Sources */,
146 | D6142F9629D49931005BF77D /* Frameworks */,
147 | D6142F9729D49931005BF77D /* Resources */,
148 | );
149 | buildRules = (
150 | );
151 | dependencies = (
152 | );
153 | name = NIPatcher;
154 | productName = NIPatcher;
155 | productReference = D6142F9929D49931005BF77D /* NIPatcher.app */;
156 | productType = "com.apple.product-type.application";
157 | };
158 | /* End PBXNativeTarget section */
159 |
160 | /* Begin PBXProject section */
161 | D6142F9129D49930005BF77D /* Project object */ = {
162 | isa = PBXProject;
163 | attributes = {
164 | BuildIndependentTargetsInParallel = 1;
165 | LastSwiftUpdateCheck = 1420;
166 | LastUpgradeCheck = 1430;
167 | TargetAttributes = {
168 | D6142F9829D49931005BF77D = {
169 | CreatedOnToolsVersion = 14.2;
170 | };
171 | };
172 | };
173 | buildConfigurationList = D6142F9429D49930005BF77D /* Build configuration list for PBXProject "NIPatcher" */;
174 | compatibilityVersion = "Xcode 14.0";
175 | developmentRegion = en;
176 | hasScannedForEncodings = 0;
177 | knownRegions = (
178 | en,
179 | Base,
180 | );
181 | mainGroup = D6142F9029D49930005BF77D;
182 | productRefGroup = D6142F9A29D49931005BF77D /* Products */;
183 | projectDirPath = "";
184 | projectRoot = "";
185 | targets = (
186 | D6142F9829D49931005BF77D /* NIPatcher */,
187 | );
188 | };
189 | /* End PBXProject section */
190 |
191 | /* Begin PBXResourcesBuildPhase section */
192 | D6142F9729D49931005BF77D /* Resources */ = {
193 | isa = PBXResourcesBuildPhase;
194 | buildActionMask = 2147483647;
195 | files = (
196 | D6A9E30329DE2269006FFE78 /* HDR_Logo_KP.png in Resources */,
197 | D6DBD65D29D77B3400AE30CB /* codesignkk.sh in Resources */,
198 | D6142FA429D49932005BF77D /* Preview Assets.xcassets in Resources */,
199 | D6142FC129D4B1E2005BF77D /* HDR_LOGO_MAS_Picto.png in Resources */,
200 | D6142FC229D4B1E2005BF77D /* HDR_LOGO_MAS_Main.png in Resources */,
201 | D6142FA129D49932005BF77D /* Assets.xcassets in Resources */,
202 | D6142FB929D4A0D9005BF77D /* codesign.sh in Resources */,
203 | );
204 | runOnlyForDeploymentPostprocessing = 0;
205 | };
206 | /* End PBXResourcesBuildPhase section */
207 |
208 | /* Begin PBXSourcesBuildPhase section */
209 | D6142F9529D49931005BF77D /* Sources */ = {
210 | isa = PBXSourcesBuildPhase;
211 | buildActionMask = 2147483647;
212 | files = (
213 | D6142FAF29D49B1E005BF77D /* MaschineView.swift in Sources */,
214 | D6CD78EC29D5F36B006845E3 /* Functions_KK.swift in Sources */,
215 | D6CD78EE29D5F48F006845E3 /* Functions_Global.swift in Sources */,
216 | D6142F9F29D49931005BF77D /* ContentView.swift in Sources */,
217 | D6142F9D29D49931005BF77D /* NIPatcherApp.swift in Sources */,
218 | D6142FB129D49B48005BF77D /* KompleteKontrolView.swift in Sources */,
219 | D6142FB329D49B60005BF77D /* InfoView.swift in Sources */,
220 | D6142FAC29D49983005BF77D /* Functions_MAS.swift in Sources */,
221 | );
222 | runOnlyForDeploymentPostprocessing = 0;
223 | };
224 | /* End PBXSourcesBuildPhase section */
225 |
226 | /* Begin XCBuildConfiguration section */
227 | D6142FA629D49932005BF77D /* Debug */ = {
228 | isa = XCBuildConfiguration;
229 | buildSettings = {
230 | ALWAYS_SEARCH_USER_PATHS = NO;
231 | CLANG_ANALYZER_NONNULL = YES;
232 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
233 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
234 | CLANG_ENABLE_MODULES = YES;
235 | CLANG_ENABLE_OBJC_ARC = YES;
236 | CLANG_ENABLE_OBJC_WEAK = YES;
237 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
238 | CLANG_WARN_BOOL_CONVERSION = YES;
239 | CLANG_WARN_COMMA = YES;
240 | CLANG_WARN_CONSTANT_CONVERSION = YES;
241 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
242 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
243 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
244 | CLANG_WARN_EMPTY_BODY = YES;
245 | CLANG_WARN_ENUM_CONVERSION = YES;
246 | CLANG_WARN_INFINITE_RECURSION = YES;
247 | CLANG_WARN_INT_CONVERSION = YES;
248 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
249 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
250 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
251 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
252 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
253 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
254 | CLANG_WARN_STRICT_PROTOTYPES = YES;
255 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
256 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
257 | CLANG_WARN_UNREACHABLE_CODE = YES;
258 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
259 | COPY_PHASE_STRIP = NO;
260 | DEAD_CODE_STRIPPING = YES;
261 | DEBUG_INFORMATION_FORMAT = dwarf;
262 | ENABLE_STRICT_OBJC_MSGSEND = YES;
263 | ENABLE_TESTABILITY = YES;
264 | GCC_C_LANGUAGE_STANDARD = gnu11;
265 | GCC_DYNAMIC_NO_PIC = NO;
266 | GCC_NO_COMMON_BLOCKS = YES;
267 | GCC_OPTIMIZATION_LEVEL = 0;
268 | GCC_PREPROCESSOR_DEFINITIONS = (
269 | "DEBUG=1",
270 | "$(inherited)",
271 | );
272 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
273 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
274 | GCC_WARN_UNDECLARED_SELECTOR = YES;
275 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
276 | GCC_WARN_UNUSED_FUNCTION = YES;
277 | GCC_WARN_UNUSED_VARIABLE = YES;
278 | MACOSX_DEPLOYMENT_TARGET = 13.1;
279 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
280 | MTL_FAST_MATH = YES;
281 | ONLY_ACTIVE_ARCH = YES;
282 | SDKROOT = macosx;
283 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
284 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
285 | };
286 | name = Debug;
287 | };
288 | D6142FA729D49932005BF77D /* Release */ = {
289 | isa = XCBuildConfiguration;
290 | buildSettings = {
291 | ALWAYS_SEARCH_USER_PATHS = NO;
292 | CLANG_ANALYZER_NONNULL = YES;
293 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
294 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
295 | CLANG_ENABLE_MODULES = YES;
296 | CLANG_ENABLE_OBJC_ARC = YES;
297 | CLANG_ENABLE_OBJC_WEAK = YES;
298 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
299 | CLANG_WARN_BOOL_CONVERSION = YES;
300 | CLANG_WARN_COMMA = YES;
301 | CLANG_WARN_CONSTANT_CONVERSION = YES;
302 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
303 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
304 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
305 | CLANG_WARN_EMPTY_BODY = YES;
306 | CLANG_WARN_ENUM_CONVERSION = YES;
307 | CLANG_WARN_INFINITE_RECURSION = YES;
308 | CLANG_WARN_INT_CONVERSION = YES;
309 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
310 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
311 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
312 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
313 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
314 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
315 | CLANG_WARN_STRICT_PROTOTYPES = YES;
316 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
317 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
318 | CLANG_WARN_UNREACHABLE_CODE = YES;
319 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
320 | COPY_PHASE_STRIP = NO;
321 | DEAD_CODE_STRIPPING = YES;
322 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
323 | ENABLE_NS_ASSERTIONS = NO;
324 | ENABLE_STRICT_OBJC_MSGSEND = YES;
325 | GCC_C_LANGUAGE_STANDARD = gnu11;
326 | GCC_NO_COMMON_BLOCKS = YES;
327 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
328 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
329 | GCC_WARN_UNDECLARED_SELECTOR = YES;
330 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
331 | GCC_WARN_UNUSED_FUNCTION = YES;
332 | GCC_WARN_UNUSED_VARIABLE = YES;
333 | MACOSX_DEPLOYMENT_TARGET = 13.1;
334 | MTL_ENABLE_DEBUG_INFO = NO;
335 | MTL_FAST_MATH = YES;
336 | SDKROOT = macosx;
337 | SWIFT_COMPILATION_MODE = wholemodule;
338 | SWIFT_OPTIMIZATION_LEVEL = "-O";
339 | };
340 | name = Release;
341 | };
342 | D6142FA929D49932005BF77D /* Debug */ = {
343 | isa = XCBuildConfiguration;
344 | buildSettings = {
345 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
346 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
347 | CODE_SIGN_ENTITLEMENTS = NIPatcher/NIPatcher.entitlements;
348 | CODE_SIGN_STYLE = Automatic;
349 | COMBINE_HIDPI_IMAGES = YES;
350 | CURRENT_PROJECT_VERSION = 1;
351 | DEAD_CODE_STRIPPING = YES;
352 | DEVELOPMENT_ASSET_PATHS = "\"NIPatcher/Preview Content\"";
353 | DEVELOPMENT_TEAM = XA7JZSQPN3;
354 | ENABLE_HARDENED_RUNTIME = YES;
355 | ENABLE_PREVIEWS = YES;
356 | GENERATE_INFOPLIST_FILE = YES;
357 | INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
358 | INFOPLIST_KEY_NSHumanReadableCopyright = "";
359 | LD_RUNPATH_SEARCH_PATHS = (
360 | "$(inherited)",
361 | "@executable_path/../Frameworks",
362 | );
363 | MACOSX_DEPLOYMENT_TARGET = 11.0;
364 | MARKETING_VERSION = 1.1.1;
365 | "OTHER_CODE_SIGN_FLAGS[sdk=*]" = "--deep";
366 | PRODUCT_BUNDLE_IDENTIFIER = "D-One.NIPatcher";
367 | PRODUCT_NAME = "$(TARGET_NAME)";
368 | SWIFT_EMIT_LOC_STRINGS = YES;
369 | SWIFT_VERSION = 5.0;
370 | };
371 | name = Debug;
372 | };
373 | D6142FAA29D49932005BF77D /* Release */ = {
374 | isa = XCBuildConfiguration;
375 | buildSettings = {
376 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
377 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
378 | CODE_SIGN_ENTITLEMENTS = NIPatcher/NIPatcher.entitlements;
379 | CODE_SIGN_STYLE = Automatic;
380 | COMBINE_HIDPI_IMAGES = YES;
381 | CURRENT_PROJECT_VERSION = 1;
382 | DEAD_CODE_STRIPPING = YES;
383 | DEVELOPMENT_ASSET_PATHS = "\"NIPatcher/Preview Content\"";
384 | DEVELOPMENT_TEAM = XA7JZSQPN3;
385 | ENABLE_HARDENED_RUNTIME = YES;
386 | ENABLE_PREVIEWS = YES;
387 | GENERATE_INFOPLIST_FILE = YES;
388 | INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
389 | INFOPLIST_KEY_NSHumanReadableCopyright = "";
390 | LD_RUNPATH_SEARCH_PATHS = (
391 | "$(inherited)",
392 | "@executable_path/../Frameworks",
393 | );
394 | MACOSX_DEPLOYMENT_TARGET = 11.0;
395 | MARKETING_VERSION = 1.1.1;
396 | "OTHER_CODE_SIGN_FLAGS[sdk=*]" = "--deep";
397 | PRODUCT_BUNDLE_IDENTIFIER = "D-One.NIPatcher";
398 | PRODUCT_NAME = "$(TARGET_NAME)";
399 | SWIFT_EMIT_LOC_STRINGS = YES;
400 | SWIFT_VERSION = 5.0;
401 | };
402 | name = Release;
403 | };
404 | /* End XCBuildConfiguration section */
405 |
406 | /* Begin XCConfigurationList section */
407 | D6142F9429D49930005BF77D /* Build configuration list for PBXProject "NIPatcher" */ = {
408 | isa = XCConfigurationList;
409 | buildConfigurations = (
410 | D6142FA629D49932005BF77D /* Debug */,
411 | D6142FA729D49932005BF77D /* Release */,
412 | );
413 | defaultConfigurationIsVisible = 0;
414 | defaultConfigurationName = Release;
415 | };
416 | D6142FA829D49932005BF77D /* Build configuration list for PBXNativeTarget "NIPatcher" */ = {
417 | isa = XCConfigurationList;
418 | buildConfigurations = (
419 | D6142FA929D49932005BF77D /* Debug */,
420 | D6142FAA29D49932005BF77D /* Release */,
421 | );
422 | defaultConfigurationIsVisible = 0;
423 | defaultConfigurationName = Release;
424 | };
425 | /* End XCConfigurationList section */
426 | };
427 | rootObject = D6142F9129D49930005BF77D /* Project object */;
428 | }
429 |
--------------------------------------------------------------------------------
/NIPatcher/NIPatcher.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/NIPatcher/NIPatcher.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/NIPatcher/NIPatcher.xcodeproj/project.xcworkspace/xcuserdata/hackintosh.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/d1One/NIPatcher/f125ff4cfb609d9f2ef56cc5a4f610c5dbc2ba98/NIPatcher/NIPatcher.xcodeproj/project.xcworkspace/xcuserdata/hackintosh.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/NIPatcher/NIPatcher.xcodeproj/xcuserdata/hackintosh.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
--------------------------------------------------------------------------------
/NIPatcher/NIPatcher.xcodeproj/xcuserdata/hackintosh.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | NIPatcher.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 0
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/NIPatcher/NIPatcher/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/d1One/NIPatcher/f125ff4cfb609d9f2ef56cc5a4f610c5dbc2ba98/NIPatcher/NIPatcher/.DS_Store
--------------------------------------------------------------------------------
/NIPatcher/NIPatcher/Assets.xcassets/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/d1One/NIPatcher/f125ff4cfb609d9f2ef56cc5a4f610c5dbc2ba98/NIPatcher/NIPatcher/Assets.xcassets/.DS_Store
--------------------------------------------------------------------------------
/NIPatcher/NIPatcher/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/NIPatcher/NIPatcher/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "mac",
5 | "scale" : "1x",
6 | "size" : "16x16"
7 | },
8 | {
9 | "idiom" : "mac",
10 | "scale" : "2x",
11 | "size" : "16x16"
12 | },
13 | {
14 | "idiom" : "mac",
15 | "scale" : "1x",
16 | "size" : "32x32"
17 | },
18 | {
19 | "filename" : "NIPatcher_Icon_64.png",
20 | "idiom" : "mac",
21 | "scale" : "2x",
22 | "size" : "32x32"
23 | },
24 | {
25 | "filename" : "NIPatcher_Icon_128.png",
26 | "idiom" : "mac",
27 | "scale" : "1x",
28 | "size" : "128x128"
29 | },
30 | {
31 | "filename" : "NIPatcher_Icon_256.png",
32 | "idiom" : "mac",
33 | "scale" : "2x",
34 | "size" : "128x128"
35 | },
36 | {
37 | "filename" : "NIPatcher_Icon_256 1.png",
38 | "idiom" : "mac",
39 | "scale" : "1x",
40 | "size" : "256x256"
41 | },
42 | {
43 | "filename" : "NIPatcher_Icon_512.png",
44 | "idiom" : "mac",
45 | "scale" : "2x",
46 | "size" : "256x256"
47 | },
48 | {
49 | "filename" : "NIPatcher_Icon_512 1.png",
50 | "idiom" : "mac",
51 | "scale" : "1x",
52 | "size" : "512x512"
53 | },
54 | {
55 | "filename" : "NIPatcher_Icon.png",
56 | "idiom" : "mac",
57 | "scale" : "2x",
58 | "size" : "512x512"
59 | }
60 | ],
61 | "info" : {
62 | "author" : "xcode",
63 | "version" : 1
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/NIPatcher/NIPatcher/Assets.xcassets/AppIcon.appiconset/NIPatcher_Icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/d1One/NIPatcher/f125ff4cfb609d9f2ef56cc5a4f610c5dbc2ba98/NIPatcher/NIPatcher/Assets.xcassets/AppIcon.appiconset/NIPatcher_Icon.png
--------------------------------------------------------------------------------
/NIPatcher/NIPatcher/Assets.xcassets/AppIcon.appiconset/NIPatcher_Icon_128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/d1One/NIPatcher/f125ff4cfb609d9f2ef56cc5a4f610c5dbc2ba98/NIPatcher/NIPatcher/Assets.xcassets/AppIcon.appiconset/NIPatcher_Icon_128.png
--------------------------------------------------------------------------------
/NIPatcher/NIPatcher/Assets.xcassets/AppIcon.appiconset/NIPatcher_Icon_256 1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/d1One/NIPatcher/f125ff4cfb609d9f2ef56cc5a4f610c5dbc2ba98/NIPatcher/NIPatcher/Assets.xcassets/AppIcon.appiconset/NIPatcher_Icon_256 1.png
--------------------------------------------------------------------------------
/NIPatcher/NIPatcher/Assets.xcassets/AppIcon.appiconset/NIPatcher_Icon_256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/d1One/NIPatcher/f125ff4cfb609d9f2ef56cc5a4f610c5dbc2ba98/NIPatcher/NIPatcher/Assets.xcassets/AppIcon.appiconset/NIPatcher_Icon_256.png
--------------------------------------------------------------------------------
/NIPatcher/NIPatcher/Assets.xcassets/AppIcon.appiconset/NIPatcher_Icon_512 1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/d1One/NIPatcher/f125ff4cfb609d9f2ef56cc5a4f610c5dbc2ba98/NIPatcher/NIPatcher/Assets.xcassets/AppIcon.appiconset/NIPatcher_Icon_512 1.png
--------------------------------------------------------------------------------
/NIPatcher/NIPatcher/Assets.xcassets/AppIcon.appiconset/NIPatcher_Icon_512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/d1One/NIPatcher/f125ff4cfb609d9f2ef56cc5a4f610c5dbc2ba98/NIPatcher/NIPatcher/Assets.xcassets/AppIcon.appiconset/NIPatcher_Icon_512.png
--------------------------------------------------------------------------------
/NIPatcher/NIPatcher/Assets.xcassets/AppIcon.appiconset/NIPatcher_Icon_64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/d1One/NIPatcher/f125ff4cfb609d9f2ef56cc5a4f610c5dbc2ba98/NIPatcher/NIPatcher/Assets.xcassets/AppIcon.appiconset/NIPatcher_Icon_64.png
--------------------------------------------------------------------------------
/NIPatcher/NIPatcher/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | },
6 | "properties" : {
7 | "compression-type" : "lossy"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/NIPatcher/NIPatcher/ContentView.swift:
--------------------------------------------------------------------------------
1 | // ContentView.swift
2 |
3 | import SwiftUI
4 |
5 | struct ContentView: View {
6 | var body: some View {
7 | TabView {
8 | ScrollView {
9 | MaschineView()
10 | .padding(5)
11 | }
12 | .tabItem {
13 | Label("Maschine", systemImage: "tray.and.arrow.down.fill")
14 | }
15 | ScrollView {
16 | KompleteKontrolView()
17 | .padding(5)
18 | }
19 | .tabItem {
20 | Label("Komplete Kontrol", systemImage: "tray.and.arrow.down.fill")
21 | }
22 | ScrollView {
23 | InfoView()
24 | .padding(5)
25 | }
26 | .tabItem {
27 | Label("Info", systemImage: "tray.and.arrow.down.fill")
28 | }
29 | }
30 | //.frame(minWidth: 450, minHeight: 300) // Set default minimum size for all views
31 | //.padding(10)
32 | }
33 | }
34 |
35 | struct ContentView_Previews: PreviewProvider {
36 | static var previews: some View {
37 | ContentView()
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/NIPatcher/NIPatcher/NIPatcher.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.app-sandbox
6 |
7 | com.apple.security.cs.disable-library-validation
8 |
9 | com.apple.security.files.downloads.read-write
10 |
11 | com.apple.security.files.user-selected.read-write
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/NIPatcher/NIPatcher/NIPatcherApp.swift:
--------------------------------------------------------------------------------
1 | // NIPatcherApp.swift
2 |
3 | import SwiftUI
4 |
5 | @main
6 | struct NIPatcherApp: App {
7 | var body: some Scene {
8 | WindowGroup {
9 | ContentView()
10 | .frame(minWidth: 450, maxWidth: 450, minHeight: 300)
11 | .padding(10)
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/NIPatcher/NIPatcher/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/NIPatcher/Views/InfoView.swift:
--------------------------------------------------------------------------------
1 | // PreferencesView.swift
2 |
3 | import SwiftUI
4 |
5 | struct InfoView: View {
6 |
7 | @State private var Mas_Plugs = false
8 | @State private var KK_Plugs = false
9 |
10 | var body: some View {
11 | VStack(alignment: .leading) {
12 | HStack {
13 | Text("Check if App/Plugs exist expected paths")
14 | .padding(5)
15 | Image(systemName: "info.circle")
16 | .frame(width: 50, alignment: .trailing)
17 | .foregroundColor(.blue)
18 | .onTapGesture {
19 | guard let url = URL(string: "https://github.com/d1One/NIPatcher/blob/main/README.md#info-tab") else { return }
20 | NSWorkspace.shared.open(url)
21 | }
22 | }
23 |
24 | GroupBox() {
25 | VStack(alignment: .leading) {
26 | Button(action: {
27 | Mas_Plugs.toggle()
28 | }) {
29 | Text("Maschine")
30 | }
31 | if Mas_Plugs {
32 | ForEach(Array(filePaths.indices), id: \.self) { index in
33 | HStack {
34 | Text(fileLabels[index])
35 | .frame(width: 50)
36 | Image(systemName: checkFiles()[index] ? "checkmark.circle" : "x.circle.fill")
37 | .foregroundColor(checkFiles()[index] ? .green : .red)
38 |
39 | Text(filePaths[index])
40 | .strikethrough(!checkFiles()[index])
41 | .foregroundColor(checkFiles()[index] ? .primary : .secondary)
42 | .lineLimit(1)
43 | }.frame(width: 350, alignment: .leading)
44 | }
45 | }
46 | }.frame(width: 350, alignment: .leading)
47 | }
48 |
49 | GroupBox {
50 | VStack(alignment: .leading) {
51 | Button(action: {
52 | KK_Plugs.toggle()
53 | }) {
54 | Text("Komplete Kontrol")
55 | }
56 | if KK_Plugs {
57 | ForEach(Array(filePaths.indices), id: \.self) { index in
58 | HStack {
59 | Text(fileLabels[index])
60 | .frame(width: 50)
61 |
62 | Image(systemName: checkFilesKK()[index] ? "checkmark.circle" : "x.circle.fill")
63 | .foregroundColor(checkFilesKK()[index] ? .green : .red)
64 |
65 | Text(filePaths[index])
66 | .strikethrough(!checkFilesKK()[index])
67 | .foregroundColor(checkFilesKK()[index] ? .primary : .secondary)
68 | .lineLimit(1)
69 | }
70 | .frame(width: 350, alignment: .leading)
71 | }
72 | }
73 | }.frame(width: 350, alignment: .leading)
74 | }
75 | Spacer()
76 | Divider()
77 | HStack(alignment: .center) {
78 | Text(" Made by D-One")
79 | //let link = "[D-One](https://community.native-instruments.com/profile/D-One)"
80 | //Text(.init(link))
81 | let link2 = "[buymeacoffee](https://www.buymeacoffee.com/done84)"
82 | Text(.init(link2))
83 |
84 | }
85 | .padding(.bottom, 5)
86 | .opacity(0.5)
87 | }
88 | //.frame(width: 350, alignment: .leading)
89 | }
90 | }
91 | struct InfoView_Previews: PreviewProvider {
92 | static var previews: some View {
93 | InfoView()
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/NIPatcher/Views/KompleteKontrolView.swift:
--------------------------------------------------------------------------------
1 | // KompleteKontrolView.swift
2 |
3 | import SwiftUI
4 |
5 | struct KompleteKontrolView: View {
6 |
7 | @State private var toggleKKPlug1 = false
8 | @State private var KK_app1 = false
9 | @State private var KK_plug3 = false
10 | @State private var KK_app3 = false
11 | //where is 4 ?? reorganize all the naming or it gets confusing
12 | @State private var KK_app5 = false
13 | @State private var KK_plug5 = false
14 |
15 | // WINDOW SIZE - BrowserPanel.txt KPI.txt
16 | @State private var minHeight: String = "535"
17 | @State private var defaultHeight: String = "381"
18 |
19 | // FONTS - Buttons.txt Dev_Labels.txt
20 | @State private var fontButtons: String = "11"
21 | @State private var fontDevLabels: String = "11"
22 |
23 | // Variables for the Codesign Button
24 | @State private var output = ""
25 | @State private var showingSheet = false
26 |
27 | var body: some View {
28 | VStack {
29 | Text("Interface GUI")
30 | .font(.title3)
31 | .fontWeight(.semibold)
32 | // ------------ WINDOW SIZE ------------
33 | GroupBox {
34 | HStack {
35 | Text("Window size:")
36 | Spacer()
37 | Toggle("Plug", isOn: $toggleKKPlug1).toggleStyle(.switch).controlSize(.mini)
38 | Toggle("App", isOn: $KK_app1).toggleStyle(.switch).controlSize(.mini)
39 | Image(systemName: "info.circle").frame(width: 40, alignment: .trailing)
40 | .frame(width: 50, alignment: .trailing)
41 | .foregroundColor(.blue)
42 | .onTapGesture {
43 | guard let url = URL(string: "https://github.com/d1One/NIPatcher/blob/main/Help/KompleteKontrol.md#window-size") else { return }
44 | NSWorkspace.shared.open(url)
45 | }
46 | }
47 |
48 | if toggleKKPlug1 || KK_app1 {
49 | VStack {
50 | Divider().frame(maxWidth: 200)
51 | }
52 | HStack {
53 | Text("With Plugin").frame(maxWidth: 110, alignment: .leading)
54 | Image(systemName: "arrow.up.and.down")
55 | TextField("", text: $minHeight).frame(maxWidth: 40)
56 | Spacer()
57 | }
58 | HStack {
59 | Text("Without Plugin").frame(maxWidth: 110, alignment: .leading)
60 | Image(systemName: "arrow.up.and.down")
61 | TextField("", text: $defaultHeight).frame(maxWidth: 40)
62 | Spacer()
63 | }
64 | }
65 | }.frame(width: 400) // Fixed width GroupBox
66 |
67 | // ------------ FONT SIZE ------------
68 | GroupBox {
69 | HStack {
70 | Text("Fonts:")
71 | Spacer()
72 | Toggle("Plug", isOn: $KK_plug3).toggleStyle(.switch).controlSize(.mini)
73 | Toggle("App", isOn: $KK_app3).toggleStyle(.switch).controlSize(.mini)
74 | Image(systemName: "info.circle").frame(width: 40, alignment: .trailing)
75 | .frame(width: 50, alignment: .trailing)
76 | .foregroundColor(.blue)
77 | .onTapGesture {
78 | guard let url = URL(string: "https://github.com/d1One/NIPatcher/blob/main/Help/KompleteKontrol.md#fonts") else { return }
79 | NSWorkspace.shared.open(url)
80 | }
81 | }
82 |
83 | if KK_plug3 || KK_app3 {
84 | VStack {
85 | Divider().frame(maxWidth: 150)
86 | }
87 | HStack {
88 | Text("Buttons").frame(maxWidth: 80, alignment: .leading)
89 | TextField("", text: $fontButtons).frame(maxWidth: 40)
90 | Spacer()
91 | }
92 | HStack {
93 | Text("Labels").frame(maxWidth: 80, alignment: .leading)
94 | TextField("", text: $fontDevLabels).frame(maxWidth: 40)
95 | Spacer()
96 | }
97 | }
98 | }.frame(width: 400) // Fixed width GroupBox
99 | GroupBox {
100 | HStack {
101 | Text("Wide Browser:")
102 | Spacer()
103 | Toggle("Plug", isOn: $KK_plug5).toggleStyle(.switch).controlSize(.mini)
104 | Toggle("App", isOn: $KK_app5).toggleStyle(.switch).controlSize(.mini)
105 | Image(systemName: "info.circle").frame(width: 40, alignment: .trailing)
106 | .frame(width: 50, alignment: .trailing)
107 | .foregroundColor(.blue)
108 | .onTapGesture {
109 | guard let url = URL(string: "https://github.com/d1One/NIPatcher/blob/main/Help/KompleteKontrol.md#wide-browser") else { return }
110 | NSWorkspace.shared.open(url)
111 | }
112 | }
113 | }.frame(width: 400) // Fixed width GroupBox
114 |
115 |
116 | // ------------ BUTTONS ------------
117 | Spacer()
118 | Divider()
119 | HStack {
120 | Button("Copy") {
121 | do {
122 | try copyFilesToNIPatcherFolder_KK()
123 | createAliasesForFolders_KK()
124 | } catch {
125 | print("Error - copyFilesToNIPatcherFolder_KK: \(error)")
126 | }
127 | }
128 | Button("Patch!", action: ApplyPatch)
129 | // ------------ Codesign ------------
130 | // ---- Fix or make this simpler ----
131 | // ------------------------------------
132 | Button("Codesign") {
133 | showingSheet = true
134 | }
135 | .sheet(isPresented: $showingSheet) {
136 | VStack {
137 | ScrollView {
138 | Text(output)
139 | .lineSpacing(2)
140 | }
141 | Button("Close") {
142 | showingSheet = false
143 | }
144 | }.frame(minWidth: 200, minHeight: 250)
145 | .padding(10)
146 | .onAppear() {
147 | let task = Process()
148 | task.launchPath = "/bin/sh"
149 | task.arguments = [Bundle.main.path(forResource: "codesignkk", ofType: "sh")!]
150 |
151 | let pipe = Pipe()
152 | task.standardOutput = pipe
153 |
154 | pipe.fileHandleForReading.readabilityHandler = { fileHandle in
155 | let data = fileHandle.availableData
156 | let string = String(data: data, encoding: .utf8) ?? ""
157 | DispatchQueue.main.async {
158 | output += string
159 | }
160 | }
161 |
162 | task.launch()
163 | }
164 | }
165 | }
166 | .onAppear {
167 | NSApplication.shared.windows.last?.contentView?.subviews.last?.subviews.last?.subviews.last?.layer?.backgroundColor = NSColor.clear.cgColor
168 |
169 | }
170 | }
171 | }
172 |
173 | func ApplyPatch() {
174 | if toggleKKPlug1 || KK_app1 {
175 | Hack_1_KK(KK_app1: self.KK_app1, KK_plug1: self.toggleKKPlug1, defaultHeight: self.defaultHeight)
176 | Hack_2_KK(KK_app1: self.KK_app1, KK_plug1: self.toggleKKPlug1, minHeight: self.minHeight)
177 | }
178 | if KK_plug3 || KK_app3 {
179 | Hack_3_KK(KK_app3: self.KK_app3, KK_plug3: self.KK_plug3, fontButtons: self.fontButtons)
180 | Hack_4_KK(KK_app3: self.KK_app3, KK_plug3: self.KK_plug3, fontDevLabels: self.fontDevLabels)
181 | FontFixKK1(KK_app3: self.KK_app3, KK_plug3: self.KK_plug3)
182 | FontFixKK2(KK_app3: self.KK_app3, KK_plug3: self.KK_plug3)
183 | }
184 | if KK_plug5 || KK_app5 {
185 | WideBrowserKK_fix(KK_app5: self.KK_app5, KK_plug5: self.KK_plug5)
186 | Hack_5_KK(KK_app5: self.KK_app5, KK_plug5: self.KK_plug5)
187 |
188 | }
189 | logoReplaceKK()
190 | }
191 | }
192 |
193 | struct KompleteKontrolView_Previews: PreviewProvider {
194 | static var previews: some View {
195 | KompleteKontrolView()
196 | }
197 | }
198 |
--------------------------------------------------------------------------------
/NIPatcher/Views/MaschineView.swift:
--------------------------------------------------------------------------------
1 | // ContentView.swift
2 |
3 | import SwiftUI
4 |
5 | struct MaschineView: View {
6 |
7 | // Variables for Maschine Plugin Sizes
8 | @State private var MminHeight: String = "631"
9 | @State private var smallWidth: String = "1129"
10 | @State private var smallWidthBrowser: String = "1194"//Not using this, should I add it?
11 | @State private var smallHeight: String = "631"
12 | @State private var medWidth: String = "1210"
13 | @State private var medHeight: String = "758"
14 | @State private var largeWidth: String = "1500"
15 | @State private var largeHeight: String = "930"
16 |
17 | // Bool vars for the toggles
18 | @State private var plug1 = false
19 | @State private var app1 = false
20 | @State private var plug2 = false
21 | @State private var app2 = false
22 | @State private var plug3 = false
23 | @State private var app3 = false
24 | @State private var app4 = false//Stop - Hack #4
25 | @State private var plug5 = false
26 | @State private var app5 = false
27 |
28 | // String vars for Maschine Font Sizes
29 | @State private var fontButton: String = "11"
30 | @State private var fontLabel: String = "11"
31 |
32 | // String var for the Codesign shell output
33 | @State private var output = ""
34 |
35 | // String var for the pop-up codesign window with the shell output.
36 | @State private var showingSheet = false
37 |
38 | var body: some View {
39 | VStack {
40 | // HACK #1 WINDOW SIZES
41 | // ----------------------------------------------
42 | VStack {
43 | //Image("HDR_LOGO_MAS_Picto")
44 | Text("Interface")
45 | .font(.title3)
46 | .fontWeight(.semibold)
47 | }
48 | GroupBox {
49 | HStack {
50 | Text("Window size:").frame(width: 150, alignment: .leading)
51 | Toggle("Plug", isOn: $plug1).toggleStyle(.switch).controlSize(.mini)
52 | Toggle("App", isOn: $app1).toggleStyle(.switch).controlSize(.mini)
53 | Image(systemName: "info.circle")
54 | .frame(width: 50, alignment: .trailing)
55 | .foregroundColor(.blue)
56 | .onTapGesture {
57 | guard let url = URL(string: "https://github.com/d1One/NIPatcher/blob/main/Help/Maschine.md#window-size") else { return }
58 | NSWorkspace.shared.open(url)
59 | }
60 |
61 | }
62 |
63 | if plug1 || app1 {
64 | VStack {
65 | Divider().frame(maxWidth: 250)
66 | }
67 | HStack {
68 | Text("Min").frame(maxWidth: 50)
69 | Image(systemName: "arrow.up.and.down").frame(width: 25)
70 | TextField("", text: $MminHeight).frame(maxWidth: 40)
71 |
72 | }
73 | HStack {
74 | Text("Small").frame(maxWidth: 50)
75 | Image(systemName: "arrow.left.and.right").frame(width: 25)
76 | TextField("", text: $smallWidth).frame(maxWidth: 40)
77 | Text("Small").frame(maxWidth: 50)
78 | Image(systemName: "arrow.up.and.down").frame(width: 25)
79 | TextField("", text: $smallHeight).frame(maxWidth: 40)
80 |
81 | }
82 | HStack {
83 | Text("Med").frame(maxWidth: 50)
84 | Image(systemName: "arrow.left.and.right").frame(width: 25)
85 | TextField("", text: $medWidth).frame(maxWidth: 40)
86 | Text("Med").frame(maxWidth: 50)
87 | Image(systemName: "arrow.up.and.down").frame(width: 25)
88 | TextField("", text: $medHeight).frame(maxWidth: 40)
89 | }
90 | HStack {
91 | Text("Large").frame(maxWidth: 50)
92 | Image(systemName: "arrow.left.and.right").frame(width: 25)
93 | TextField("", text: $largeWidth).frame(maxWidth: 40)
94 | Text("Large").frame(maxWidth: 50)
95 | Image(systemName: "arrow.up.and.down").frame(width: 25)
96 | TextField("", text: $largeHeight).frame(maxWidth: 40)
97 | }
98 | }
99 | }
100 | // HACK #2 FONT SIZES
101 | // ----------------------------------------------
102 | GroupBox {
103 | HStack {
104 | Text("Font size:").frame(width: 150, alignment: .leading)
105 | Toggle("Plug", isOn: $plug2).toggleStyle(.switch).controlSize(.mini)
106 | Toggle("App", isOn: $app2).toggleStyle(.switch).controlSize(.mini)
107 | Image(systemName: "info.circle")
108 | .frame(width: 50, alignment: .trailing)
109 | .foregroundColor(.blue)
110 | .onTapGesture {
111 | guard let url = URL(string: "https://github.com/d1One/NIPatcher/blob/main/Help/Maschine.md#font-size") else { return }
112 | NSWorkspace.shared.open(url)
113 | }
114 | }
115 | if plug2 || app2 {
116 | VStack {
117 | Divider().frame(maxWidth: 150)
118 | }
119 | HStack {
120 | Text("Buttons").frame(width: 60, alignment: .leading)
121 | TextField("", text: $fontButton).frame(maxWidth: 40)
122 | }
123 | HStack {
124 | Text("Labels").frame(width: 60, alignment: .leading)
125 | TextField("", text: $fontLabel).frame(maxWidth: 40)
126 | }
127 | }
128 | }
129 | // HACK #3 STOP BUTTON ON HW (MK3's, M+ & STUDIO)
130 | // -----------------------------------------------------
131 | VStack {
132 | Text("Hardware")
133 | .font(.title3)
134 | .fontWeight(.semibold)
135 | }
136 | GroupBox {
137 | HStack {
138 | Text("Stop Button").frame(width: 150, alignment: .leading)
139 | Text("").frame(width: 60, alignment: .leading)//just to fill empty space
140 | Toggle(" App", isOn: $app4).toggleStyle(.switch).controlSize(.mini)
141 | Image(systemName: "info.circle")
142 | .frame(width: 50, alignment: .trailing)
143 | .foregroundColor(.blue)
144 | .onTapGesture {
145 | guard let url = URL(string: "https://github.com/d1One/NIPatcher/blob/main/Help/Maschine.md#stop-button") else { return }
146 | NSWorkspace.shared.open(url)
147 | }
148 | }
149 | }
150 | GroupBox {
151 | HStack {
152 | Text("Jam Focus").frame(width: 150, alignment: .leading)
153 | Toggle("Plug", isOn: $plug5).toggleStyle(.switch).controlSize(.mini)
154 | Toggle(" App", isOn: $app5).toggleStyle(.switch).controlSize(.mini)
155 | Image(systemName: "info.circle")
156 | .frame(width: 50, alignment: .trailing)
157 | .foregroundColor(.blue)
158 | .onTapGesture {
159 | guard let url = URL(string: "https://github.com/d1One/NIPatcher/blob/main/Help/Maschine.md#jam-focus") else { return }
160 | NSWorkspace.shared.open(url)
161 | }
162 | }
163 | }
164 |
165 | // PATCH Buttons
166 | // -----------------------------------------------------
167 | Spacer()//why is this spacer not working?
168 | Divider().frame(maxWidth: 150)
169 | HStack {
170 | Button("Copy") {
171 | do {
172 | try copyFilesToNIPatcherFolder()
173 | createAliasesForFolders()
174 | } catch {
175 | print("Error - copyFilesToNIPatcherFolder: \(error)")
176 | }
177 | }
178 | Button("Patch!", action: ApplyPatch)
179 | // Complicated ass way of showing when codesign is done. Revisit this!
180 | // ----------------------------------------------------------------------
181 | Button("Codesign") {
182 | showingSheet = true
183 | output = ""
184 | }
185 | .sheet(isPresented: $showingSheet) {
186 |
187 | VStack {
188 | ScrollView {
189 | Text(output)
190 | .lineSpacing(2)
191 | }
192 | Button("Close") {
193 | showingSheet = false
194 | }
195 | }.frame(minWidth: 200, minHeight: 250)
196 | .padding(10)
197 | .onAppear() {
198 | let task = Process()
199 | task.launchPath = "/bin/sh"
200 | task.arguments = [Bundle.main.path(forResource: "codesign", ofType: "sh")!]
201 |
202 | let pipe = Pipe()
203 | task.standardOutput = pipe
204 |
205 | pipe.fileHandleForReading.readabilityHandler = { fileHandle in
206 | let data = fileHandle.availableData
207 | let string = String(data: data, encoding: .utf8) ?? ""
208 | DispatchQueue.main.async {
209 | output += string
210 | }
211 | }
212 |
213 | task.launch()
214 | }
215 | }
216 | }
217 | .onAppear {
218 | NSApplication.shared.windows.last?.contentView?.subviews.last?.subviews.last?.subviews.last?.layer?.backgroundColor = NSColor.clear.cgColor
219 |
220 | }
221 | }
222 | }
223 |
224 | func ApplyPatch() {
225 | if plug1 || app1 {
226 | Hack_1(inputAppFiles: inputAppFiles, inputPlugFiles: inputPlugFiles, app1: self.app1, plug1: self.plug1, MminHeight: self.MminHeight, smallWidth: self.smallWidth, smallWidthBrowser: self.smallWidthBrowser, smallHeight: self.smallHeight, medWidth: self.medWidth, medHeight: self.medHeight, largeWidth: self.largeWidth, largeHeight: self.largeHeight)
227 | }
228 | if plug2 || app2 {
229 | // uses same toggles because all are always applied
230 | Hack_2(app2: self.app2, plug2: self.plug2, fontLabel: self.fontLabel)
231 | Hack_3(app2: self.app2, plug2: self.plug2, fontButton: self.fontButton)
232 | Hack_2_3_fix(app2: self.app2, plug2: self.plug2)
233 | }
234 | if app4 {
235 | SC_TransportSection()
236 | }
237 | if plug5 || app5 {
238 | MH_PatternHelper(app5: self.app5, plug5: self.plug5)
239 | }
240 | logoReplaceMAS()
241 | // else {
242 | // let alert = NSAlert()
243 | // alert.messageText = "Error! 😢"
244 | // alert.runModal()
245 | // print("nothing selected")
246 | // }
247 |
248 | }
249 |
250 | }
251 |
252 |
253 | struct MaschineView_Previews: PreviewProvider {
254 | static var previews: some View {
255 | MaschineView()
256 | }
257 | }
258 |
--------------------------------------------------------------------------------
/NIPatcher/images/HDR_LOGO_MAS_Main.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/d1One/NIPatcher/f125ff4cfb609d9f2ef56cc5a4f610c5dbc2ba98/NIPatcher/images/HDR_LOGO_MAS_Main.png
--------------------------------------------------------------------------------
/NIPatcher/images/HDR_LOGO_MAS_Picto.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/d1One/NIPatcher/f125ff4cfb609d9f2ef56cc5a4f610c5dbc2ba98/NIPatcher/images/HDR_LOGO_MAS_Picto.png
--------------------------------------------------------------------------------
/NIPatcher/images/HDR_Logo_KP.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/d1One/NIPatcher/f125ff4cfb609d9f2ef56cc5a4f610c5dbc2ba98/NIPatcher/images/HDR_Logo_KP.png
--------------------------------------------------------------------------------
/NIPatcher/shellScripts/codesign.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # codesign.sh
4 | # NIPatcher
5 | #
6 | # Created by Diego Sousa on 29/03/2023.
7 | #
8 | echo "Codesigning"
9 | echo "Please wait..."
10 | echo ""
11 |
12 | if [ -d ~/Desktop/NIPatcher/Maschine\ 2.app ]; then
13 | codesign --verbose --force --deep --sign - ~/Desktop/NIPatcher/Maschine\ 2.app
14 | echo "✅ Maschine App"
15 | else
16 | echo "❌ App"
17 | fi
18 |
19 | if [ -d ~/Desktop/NIPatcher/Maschine\ 2.vst ]; then
20 | codesign --verbose --force --deep --sign - ~/Desktop/NIPatcher/VST/Maschine\ 2.vst
21 | echo "✅ Maschine VST"
22 | else
23 | echo "❌ VST"
24 | fi
25 |
26 | if [ -d ~/Desktop/NIPatcher/Maschine\ 2.vst3 ]; then
27 | codesign --verbose --force --deep --sign - ~/Desktop/NIPatcher/Maschine\ 2.vst3
28 | echo "✅ Maschine VST3"
29 | else
30 | echo "❌ VST3"
31 | fi
32 |
33 |
34 | if [ -d ~/Desktop/NIPatcher/Maschine\ 2.component ]; then
35 | codesign --verbose --force --deep --sign - ~/Desktop/NIPatcher/Maschine\ 2.component
36 | echo "✅ Maschine AU"
37 | else
38 | echo " ❌ AU"
39 | fi
40 |
41 |
42 | if [ -d ~/Desktop/NIPatcher/Maschine\ 2.aaxplugin ]; then
43 | codesign --verbose --force --deep --sign - ~/Desktop/NIPatcher/Maschine\ 2.aaxplugin
44 | echo "✅ Maschine AAX"
45 | else
46 | echo "❌ AAX."
47 | fi
48 |
49 | echo ""
50 | echo " Done! 👍"
51 |
--------------------------------------------------------------------------------
/NIPatcher/shellScripts/codesignkk.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # codesignkk.sh
4 | # NIPatcher
5 | #
6 | # Created by Diego Sousa on 29/03/2023.
7 | #
8 | echo "Codesigning"
9 | echo "Please wait..."
10 | echo ""
11 |
12 | if [ -d ~/Desktop/NIPatcher/Komplete\ Kontrol.app ]; then
13 | codesign --verbose --force --deep --sign - ~/Desktop/NIPatcher/Komplete\ Kontrol.app
14 | echo "✅ KK App"
15 | else
16 | echo "❌ App"
17 | fi
18 |
19 | if [ -d ~/Desktop/NIPatcher/Komplete\ Kontrol.vst ]; then
20 | codesign --verbose --force --deep --sign - ~/Desktop/NIPatcher/VST/Maschine\ 2.vst
21 | echo "✅ KK VST"
22 | else
23 | echo "❌ VST"
24 | fi
25 |
26 | if [ -d ~/Desktop/NIPatcher/Komplete\ Kontrol.vst3 ]; then
27 | codesign --verbose --force --deep --sign - ~/Desktop/NIPatcher/Komplete\ Kontrol.vst3
28 | echo "✅ KK VST3"
29 | else
30 | echo "❌ VST3"
31 | fi
32 |
33 |
34 | if [ -d ~/Desktop/NIPatcher/Komplete\ Kontrol.component ]; then
35 | codesign --verbose --force --deep --sign - ~/Desktop/NIPatcher/Komplete\ Kontrol.component
36 | echo "✅ KK AU"
37 | else
38 | echo " ❌ AU"
39 | fi
40 |
41 |
42 | if [ -d ~/Desktop/NIPatcher/Komplete\ Kontrol.aaxplugin ]; then
43 | codesign --verbose --force --deep --sign - ~/Desktop/NIPatcher/Komplete\ Kontrol.aaxplugin
44 | echo "✅ KK AAX"
45 | else
46 | echo "❌ AAX."
47 | fi
48 |
49 | echo ""
50 | echo " Done! 👍"
51 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # NIPatcher
2 | ## Due to low interest this project is now archived, I won't be continuing it, if anyone wants to do so than feel free, reuse any code, etc...
3 |
4 | Patcher to apply modifications to Native Instruments Maschine and Komplete Kontrol software.
5 |
6 | This project is open-source but currently halted, working on a possibly re-write for cross compatibility with Windows. Only MacOS for now!
7 |
8 | MacOS compatibility:
9 | - Native Apple Silicon support.
10 | - macOS 13 Ventura.
11 | - macOS 12 Monterey.
12 | - macOS 11 Big Sur.
13 |
14 | I might add older versions later depending on users engagement.
15 |
16 | ## How to download:
17 | Press "Releases" to the right of this page then press the .zip file.
18 | 
19 |
20 |
21 | # How to use NIPatcher:
22 | The first time runing the app requires a righ-click and selecting `Open`, MacOS will tell you it can't verify the app, thats normal since I really dont want to pay no $100 for the Apple developer certification.
23 |
24 | * 1 - Press `Copy` button, this will copy all your Plugins + the Maschine/KK App to a new folder on your Desktop called NIPatcher, it will also create shortcuts to your App and Plugin locations.
25 | * 2 - Select the modifications you want and whether you want them to be applied your App, Plugins or both.
26 | * 3 - Press `Patch` and the modifications will be applied to all files in the NIPatcher folder on the Desktop.
27 | * 4 - (Optional) Press `Codesign` - this is mostly only required for Ableton Live users. ⚠️ This is also a good time to test the MAS/KK App before actually replacing your files in the next step!
28 | * 5 - Open the NIPatcher folder on your Desktop and simply move each modified file into its respective shortcut and confirm you want to overwrite the unmodified version.
29 |
30 |
31 |
32 |
33 |
34 | NOTES:
35 | - Step 1 is a good oportunity to zip the NIPatcher folder on your desktop as a backup.
36 | - If you don't codesign in Step #4 MacOS will think the app is damaged, if that happens simply right-click it and select `Open`.
37 | - If you break all your Plugins/App just reinstall Maschine / Komplete Kontrol from Native Access or copy back from the zip backup
38 | - Interface/GUI mods can be applied more than once but HW mods cannot.
39 |
40 | #### Why so many steps?
41 |
42 | 1 Copy
43 | Due to Apple's security features writing into `/Library/Audio/Plug-Ins` or `/Library/Application Support/Avid/Audio/Plug-Ins` requires either the user to be prompted for the folders or for me to make an external helper tool (like the one Native Access has). This is way above my current very low skillset so instead of directly modifying the files they are copied to the desktop first, this might not be ideal but gives the user a chance to check if everything is working on the App copy for example.
44 |
45 |
46 |
47 | 4 Codesign
48 | Codesign is also required due to Security stuff, since we modify the Plugins and/or application and some DAW's like Ableton Live check for this we need to codesign them so Ableton Live can sleep well at night and not be scared.
49 |
50 |
51 |
52 | 5 Manually moving patched files
53 | Moving the files thru the shortcuts is the fastest way I was able to make it work without bothering the user too much, this way it's the MacOS Finder who asks you for permissions when moving the modified files to the Plugins/Application locations.
54 |
55 |
56 | ## Help and details about all modifications
57 | ### [Maschine](https://github.com/d1One/NIPatcher/blob/main/Help/Maschine.md)
58 | ### [Komplete Kontrol](https://github.com/d1One/NIPatcher/blob/main/Help/KompleteKontrol.md)
59 |
60 | ## Why make NIPatcher?
61 | To make some improvements to the software since feature requests seem to not achieve anything. Making modifications manually is annoying and hard for the average user, by having an app dedicated to it perhaps more users will be willing to contribute with more modifications and this project can grow.
62 |
63 |
64 | ## If you want to contribute:
65 | As of now I am just a newbie with this stuff, I'm not a real developer so until I'm more familiar with github pull requests wont be a thing, I also need the app tested by some users to know it's good, rewrite lots of the code to make it more readable etc... Then I'll put it fully on github as open-source.
66 |
67 | So for now anyone that wants to contribute can just right click the Maschine / KK applications , select show package contents, mess around and report anything usefull. If I am not a dev and found some stuff, so can you! :)
68 |
--------------------------------------------------------------------------------