├── .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 | ![KK Example](https://github.com/d1One/NIPatcher/blob/main/Images/Example_01.png) 34 | ![KK Example 2](https://github.com/d1One/NIPatcher/blob/main/Images/Example_02.png) 35 | ![KK Example 3](https://github.com/d1One/NIPatcher/blob/main/Images/KK_Example%20B%201.png) 36 | ![KK Example 3](https://github.com/d1One/NIPatcher/blob/main/Images/KK_Example%20B%202.png) 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 | ![Label and Font 15 compared to original Maschine](https://github.com/d1One/NIPatcher/blob/main/Images/Labels%2015.png) 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 | --------------------------------------------------------------------------------