Hey folks,
I'm wondering if it's possible to paste a block of text with prompt fields.
I'm hoping to make a quick way to save notes about my hardware chain as text.
Ideally, I'd press a hotkey and get a popup for each of my pieces of hardware where I'd input values. At the end, I'd get a block of text that I could paste into the PT comments field or any text document.
I'm a total novice with scripting so I'm stuck with using actions for now.
Any help is appreciated!
It would look something like this, with the underscores representing the fields that I want to fill in.
PERKONS
pattern row ___
pattern slot ___
kit row ___
kit slot ___
PROPHET
preset # ___
DIGITAKT
bank ___
slot ___
- Ddanielkassulke @danielkassulke
Hi Les,
I liked this idea so much that i stole it for myself! I think the following snippet is what you were after. The results are copied to the clipboard and ready to paste once you've run this script:
// Get PERKONS pattern row const patternRowResult = sf.interaction.displayDialog({ prompt: "Pattern Row", title: "PERKONS Recall", defaultAnswer: "", buttons: ["OK", "Cancel"], defaultButton: "OK", }); const patternRow = patternRowResult.text; // Get PERKONS pattern slot const patternSlotResult = sf.interaction.displayDialog({ prompt: "Pattern Slot", title: "PERKONS Recall", defaultAnswer: "", buttons: ["OK", "Cancel"], defaultButton: "OK", }); const patternSlot = patternSlotResult.text; // Get PERKONS kit row const kitRowResult = sf.interaction.displayDialog({ prompt: "Kit Row", title: "PERKONS Recall", defaultAnswer: "", buttons: ["OK", "Cancel"], defaultButton: "OK", }); const kitRow = kitRowResult.text; // Get PERKONS kit slot const kitSlotResult = sf.interaction.displayDialog({ prompt: "Kit Slot", title: "PERKONS Recall", defaultAnswer: "", buttons: ["OK", "Cancel"], defaultButton: "OK", }); const kitSlot = kitSlotResult.text; // Get PROPHET preset number const presetNumberResult = sf.interaction.displayDialog({ prompt: "Preset Number", title: "PROPHET Recall", defaultAnswer: "", buttons: ["OK", "Cancel"], defaultButton: "OK", }); const presetNumber = presetNumberResult.text; // Get DIGITAKT bank const bankResult = sf.interaction.displayDialog({ prompt: "Bank", title: "DIGITAKT Recall", defaultAnswer: "", buttons: ["OK", "Cancel"], defaultButton: "OK", }); const bank = bankResult.text; // Get DIGITAKT slot const slotResult = sf.interaction.displayDialog({ prompt: "Slot", title: "DIGITAKT Recall", defaultAnswer: "", buttons: ["OK", "Cancel"], defaultButton: "OK", }); const slot = slotResult.text; // Create the final text block const finalText = `PERKONS Pattern Row: ${patternRow} Pattern Slot: ${patternSlot} Kit Row: ${kitRow} Kit Slot: ${kitSlot} PROPHET Preset Number: ${presetNumber} DIGITAKT Bank: ${bank} Slot: ${slot}`; // Set the new text to the clipboard sf.clipboard.setText({text: finalText}); // Wait for the text to be available in the clipboard sf.clipboard.waitForText();
Chris Shaw @Chris_Shaw2023-10-09 22:59:21.312Z2023-10-09 23:29:11.091Z
Here's a slightly more compact version using an object to reduce repetitive dialog calls:
//Define outboard units and parameters let recallSettings = { "PERKONS": { setting1: { prompt: "Pattern Row" }, setting2: { prompt: "Pattern Slot" }, setting3: { prompt: "Kit Row" }, setting4: { prompt: "Kit Slot" }, presesetting5: { prompt: "Preset Number" } }, "PROPHET": { setting1: { prompt: "Preset Number" } }, "DIGITAKT": { setting1: { prompt: "Bank" }, setting2: { prompt: "Slot" } } }; //C blank text variable let settingsText = ""; // Loop through each unit in object for (const unit in recallSettings) { // Add unit name to text file settingsText = settingsText + `${unit}:\n`; // Loop through each setting in the current unit for (const setting in recallSettings[unit]) { let prompt = recallSettings[unit][setting].prompt let value = sf.interaction.displayDialog({ prompt, title: `${unit} Settings`, defaultAnswer: "", buttons: ["OK", "Cancel"], defaultButton: "OK", }).text; // add parameter setting to text file along with a line return settingsText = settingsText + ` ${prompt}: ${value}\n` } //We're done with the unit. Add a line return before moving to next unit settingsText = settingsText + "\n" } // Set the new text to the clipboard sf.clipboard.setText({ text: settingsText }); // Wait for the text to be available in the clipboard sf.clipboard.waitForText(); log(settingsText)
Chris Shaw @Chris_Shaw2023-10-09 23:25:24.775Z
Re edited the above code.
No need to have unique object keys - just call them setting1, setting 2, etc.
This should make it easier to add more settings in the future.
Theres also a space placed between each unit in the resulting text- LLes Cooper @Les_Cooper
Great!
This works perfectly.
Thanks!
- L
- LLes Cooper @Les_Cooper
Curious,
For formatting, how do I add the empty line/space between sub-categories?
(between Kit Slot / Prophet and Preset Number / Digitakt** EDIT - I figured this one out.. Duh.
- In reply toLes_Cooper⬆:Chris Shaw @Chris_Shaw2023-10-10 15:23:48.498Z2023-10-10 17:03:05.155Z
I realized it could be even more concise.
This version makes it easier to add more outboard if needed://Define outboard units and parameters let recallSettings = { "PERKONS": ["Pattern Row", "Pattern Slot", "Kit Row", "Kit Slot", "Preset Number"], "PROPHET": ["Preset Number"], "DIGITAKT": ["Bank", "Slot"] }; //Set blank text variable let settingsText = ""; // Loop through each unit in recallSettings for (const unit in recallSettings) { // Add unit name to text file settingsText = settingsText + `${unit}:\n`; // Loop through each setting in the current unit recallSettings[unit].forEach(setting => { let value = sf.interaction.displayDialog({ title: `${unit}`, prompt: `${unit}: ${setting}`, defaultAnswer: "", buttons: ["OK", "Cancel"], defaultButton: "OK", }).text; // add parameter setting to text file along with a line return settingsText = settingsText + ` ${setting}: ${value}\n` }) //We're done with the unit. Add a line return before moving to next unit settingsText = settingsText + "\n" } // Set the new text to the clipboard5 sf.clipboard.setText({ text: settingsText }); // Wait for the text to be available in the clipboard sf.clipboard.waitForText(); log(settingsText)
Chris Shaw @Chris_Shaw2023-10-10 15:36:39.253Z2023-10-10 17:06:06.403Z
Last version, I promise:
This one will let you select which pieces of outboard you want to recall://Define outboard units and parameters let recallSettings = { "PERKONS": ["Pattern Row", "Pattern Slot", "Kit Row", "Kit Slot", "Preset Number"], "PROPHET": ["Preset Number"], "DIGITAKT": ["Bank", "Slot"], }; //Get names of outboard gear let outboard = Object.keys(recallSettings) // Set units to recall let selectedGear = sf.interaction.selectFromList({ items: outboard, prompt: "Select items to recall\n(Hold cmd to select multiple items)", allowMultipleSelections: true, }).list //Set blank text variable let settingsText = ""; // Loop through each selected unit in recallSettings selectedGear.forEach(unit => { // Add unit name to text file settingsText = settingsText + `${unit}:\n`; // Loop through each setting in the current unit recallSettings[unit].forEach(setting => { let value = sf.interaction.displayDialog({ title: `${unit}`, prompt: `${unit}: ${setting}`, defaultAnswer: "", buttons: ["OK", "Cancel"], defaultButton: "OK", }).text; // add parameter setting to text file along with a line return settingsText = settingsText + ` ${setting}: ${value}\n` }) //We're done with the unit. Add a line return before moving to next unit settingsText = settingsText + "\n" }) // Set the new text to the clipboard sf.clipboard.setText({ text: settingsText }); // Wait for the text to be available in the clipboard sf.clipboard.waitForText(); log(settingsText)
- LLes Cooper @Les_Cooper
Oh man. Don't apologize!
I'm getting this in my clipboard with these 2 new versionsPERKONS:
function delegate() {{[native code]}}: 4
function delegate() {{[native code]}}: 4
function delegate() {{[native code]}}: 5
function delegate() {{[native code]}}: 5
function delegate() {{[native code]}}: 325PROPHET:
function delegate() {{[native code]}}: 326DIGITAKT:
function delegate() {{[native code]}}: D
function delegate() {{[native code]}}: 6Chris Shaw @Chris_Shaw2023-10-10 16:55:28.454Z
I caught that right after I posted. The code above should work now
- LLes Cooper @Les_Cooper
Works a charm now!
Is there a way to disable the select gear option?
Sometimes, it would be helpful, but in others, it would be quicker without it.Chris Shaw @Chris_Shaw2023-10-10 17:19:05.119Z
Just use the script above that one
Chris Shaw @Chris_Shaw2023-10-10 17:21:00.100Z
Or do you want a choice at the start to choose or use all options?
- LLes Cooper @Les_Cooper
Ah, I didn't realize that you had modded both scripts.
In that case, it's handy to have both full scripts for editing fun.Chris Shaw @Chris_Shaw2023-10-10 17:29:12.371Z
This is the best of both worlds - it'll ask what you want to do - the default button is all units:
//Define outboard units and parameters let recallSettings = { "PERKONS": ["Pattern Row", "Pattern Slot", "Kit Row", "Kit Slot", "Preset Number"], "PROPHET": ["Preset Number"], "DIGITAKT": ["Bank", "Slot"], }; //Get names of outboard gear let outboard = Object.keys(recallSettings) let userResponse = sf.interaction.displayDialog({ prompt: "Do you want to store the settings for everything or a selection?", buttons: ["Selection", "All Units"], defaultButton: "All Units", }).button let selectedGear if (userResponse == "Selection") { // Set units to recall selectedGear = sf.interaction.selectFromList({ items: outboard, prompt: "Select items to recall\n(Hold cmd to select multiple items)", allowMultipleSelections: true, }).list } else selectedGear = outboard //Set blank text variable let settingsText = ""; // Loop through each selected unit in recallSettings selectedGear.forEach(unit => { // Add unit name to text file settingsText = settingsText + `${unit}:\n`; // Loop through each setting in the current unit recallSettings[unit].forEach(setting => { let value = sf.interaction.displayDialog({ title: `${unit}`, prompt: `${unit}: ${setting}`, defaultAnswer: "", buttons: ["OK", "Cancel"], defaultButton: "OK", }).text; // add parameter setting to text file along with a line return settingsText = settingsText + ` ${setting}: ${value}\n` }) //We're done with the unit. Add a line return before moving to next unit settingsText = settingsText + "\n" }) // Set the new text to the clipboard sf.clipboard.setText({ text: settingsText }); // Wait for the text to be available in the clipboard sf.clipboard.waitForText(); log(settingsText)
- LLes Cooper @Les_Cooper
Bloody Brilliant!
- In reply toChris_Shaw⬆:LLes Cooper @Les_Cooper
Hey Chris.
First off, thanks again for doing this, it's really cool!
I'm starting to think that others may enjoy this as well. Maybe share it in the store.
I'm totally happy with it as is but if others were using it, especially folks that are intimidated by code, it could be cool to have a way to add gear. Happy to keep adding ideas or I can just let you run with it.
Maybe a separate script with:MY GEAR LIST
Create new list or add to existing?
Gear Name:
Parameters to add:DONE ADD MORE
Chris Shaw @Chris_Shaw2023-10-10 18:44:35.448Z
That would require a lot more work. You'd need to store all of that info on the user's hard drive which would require a considerable amount of code.
However, it's fairly simple to add more gear to the code itself:
Here's our gear object:let recallSettings = { "PERKONS": ["Pattern Row", "Pattern Slot", "Kit Row", "Kit Slot", "Preset Number"], "PROPHET": ["Preset Number"], "DIGITAKT": ["Bank", "Slot"], };
An object consists of keys and values. it's formatted like this:
let object = { key1: value1, key2: value2 }
Each key/value pair is separated by a comma
In the object above"PERKONS"
is the key and its value is an array of the settings we want to enter:["Pattern Row", "Pattern Slot", "Kit Row", "Kit Slot", "Preset Number"]
To add more gear and settings to the script, just add them to the object.
For example, let's add the settings for an 1176 compressor. The key/value pair would look like this:"1176": ["Input", "Output", "Attack", "Release", "Ratio"]
Just add that to the object above like so (don't forget the comma after the value / array):
let recallSettings = { "PERKONS": ["Pattern Row", "Pattern Slot", "Kit Row", "Kit Slot", "Preset Number"], "PROPHET": ["Preset Number"], "DIGITAKT": ["Bank", "Slot"], "1176": ["Input", "Output", "Attack", "Release", "Ratio"], };
That's all you'd have to do - the script will work with however many key/value pairs that you put into the object.
If you want to add more parameters to a piece of gear just add them to the array:
I'll add more parameters to the Prophet:let recallSettings = { "PERKONS": ["Pattern Row", "Pattern Slot", "Kit Row", "Kit Slot", "Preset Number"], "PROPHET": ["Preset Number", "Volume Level", "MIDI Channel", "Output Jack" ], "DIGITAKT": ["Bank", "Slot"], };
This is the main reason why I refactored the original code - to make it more flexible.
Chris Shaw @Chris_Shaw2023-10-10 18:46:32.613Z
If you want to put this into the store just put the above explanation in to the documentation of the package.
- LLes Cooper @Les_Cooper
Sounds good Chris.
Thanks again and have a great day!
Les
- LIn reply toLes_Cooper⬆:Les Cooper @Les_Cooper
I'm also curious... seeing as it's gone this far :)
The cancel function (either via the escape key or the cancel button) only worked on the first version. Something broke on the revisions.
would there be a way to include the header names in the text prompts but exclude them from what goes to the clipboard?
I realize that they are displayed at the top but when I'm quickly inputting settings. it's easy to get lost.So the prompt would look like this
and the output would look like this
Chris Shaw @Chris_Shaw2023-10-10 17:02:16.681Z
Hmm, the cancel button / esc is working on my end - it stops the script completely.
- In reply toLes_Cooper⬆:
Chris Shaw @Chris_Shaw2023-10-10 17:07:26.802Z
No problem - The edited code above should do it