|
|
|
02-16-2017, 05:07 PM
|
#1
|
Human being with feelings
Join Date: Dec 2014
Posts: 600
|
Collapse folder from string find
Hi guys,
So, i'm fighting since hours with a simple lua script for reaper. I'm trying to collapse a folder which name contains a string I manually define.
Here is my folder structure:
-Woodwinds
---Flute
---Oboe
---Clarinet
---Bassoon
-Brass
---Horn
---Trumpet
---Trombone
---Tuba
I'd like to collapse 1st folder (woodwinds, brass,...)
So, i've a kind of script but I can't find a solution for 2 problems :
1- How to make my search case insensitive
2- How to set selection to a track
here is the actual script, any help would really be appreciated
Code:
--reaper.APITest()
----------------------------------------------------------------------------------------
-- DEBUG FUNCTIONS --
---------------------
function msg_s(s)
reaper.ShowConsoleMsg(s..'\n') --for strings
end
function msg_i(s)
str=string.format("%i",s) --for integer
reaper.ShowConsoleMsg(str..'\n')
end
function msg_d(s)
str=string.format("%d",s) --for decimal
reaper.ShowConsoleMsg(str..'\n')
end
function msg_f(s)
str=string.format("%f",s) --for float
reaper.ShowConsoleMsg(str..'\n')
end
function msg_b(s)
str=string.format("%s\n", tostring(true)) --for f***ing boolean
reaper.ShowConsoleMsg(str..'\n')
end
---------------------------------------------------------------------------------------
-- FIND TRACK NAME --
--------------------
-- returns -1 on error
-- returns true if name was in track names
-- returns false if name wasn't in track names
function CollapseFolder(name)
for i=1, reaper.CountTracks(0) do
track = reaper.GetTrack(0, i-1)
-- this is not necessary, but it's a good practice
if track == nil then
reaper.ShowConsoleMsg("Error: Track pointer is nil")
return -1 -- return -1
end
retval, track_name = reaper.GetSetMediaTrackInfo_String(track, "P_NAME", "", false)
if retval then
if track_name == name then
reaper.Main_OnCommand(reaper.NamedCommandLookup("_SWS_COLLAPSE"),0)
return true -- name was already in track names -> return true
end
end
end
return false -- name was not in track names -> return false
end
-- Test:
local name = "Brass" -- this is the search string (track name)
reaper.Undo_BeginBlock()
CollapseFolder(name)
|
|
|
02-16-2017, 06:37 PM
|
#2
|
Human being with feelings
Join Date: Mar 2016
Posts: 117
|
Quote:
Originally Posted by daeavelwyn
1- How to make my search case insensitive
2- How to set selection to a track
|
1- How to make my search case insensitive
I think lua's "string.upper" and "string.lower" is useful. and "tostring" function. (when using tostring with number ,it tostring function seems to truncate a very small decimal point. ?? )
Code:
--================================
function msg( value )
reaper.ShowConsoleMsg( tostring(value) .. "\n" )
end
--================================
local text = "test-TEST";
--================================
msg( 100 ); -- number
msg( false ); -- boolean
msg( true );
msg( string.upper( text ) ); -- to upper case ( "TEST-TEST")
msg( string.lower( text ) ); -- to lower case ( "test-test")
--================================
msg( ( string.upper( "TeST" ) == string.upper( "test") ) ) -- true
2- How to set selection to a track
"reaper.SetTrackSelected" and
"reaper.SetMediaTrackInfo_Value" function will select track
Code:
local proj =0;
--================================
--================================
local function getTrackByTrackName(targetName)
local outTrack = nil;
--==============================
local count =0;
while ( count < reaper.CountTracks(proj) )
do
local _track = reaper.GetTrack(proj,count);
--============================
local _retval
, _trackName = reaper.GetSetMediaTrackInfo_String( _track
, "P_NAME"
, ""
, false);
if ( string.upper(_trackName) == string.upper(targetName))
then
outTrack = _track;
break;
end
--============================
count= count+1;
end
--==============================
return outTrack ;-- nil or track
end
--================================
-- test( to select Track by track Name )
--================================
local track = getTrackByTrackName("brass") ;-- track name brass
if ( track ~= nil) -- check wheter found
then
-- reaper.SetMediaTrackInfo_Value(track, "I_SELECTED", 1); -- 0 (false) or 1(true)
reaper.SetTrackSelected(track,true);
end
--================================
|
|
|
02-17-2017, 05:15 AM
|
#3
|
Human being with feelings
Join Date: Dec 2014
Posts: 600
|
Hey kawa, your method works really better than mine ! thanks a lot
Now I just have to create a vector containing my folders title and loop on it to create a toggle from my tablet
Do you know if there is a way to pass argument to a script ?
I'd like to send data from my OSC tablet (lemur) it could be something like :
/action/Rblablablalba 'woodwinds'
Here is now the fully functional script I got :
Code:
----------------------------------------------------------------------------------------
-- DEBUG FUNCTIONS --
---------------------
function msg_s(s)
reaper.ShowConsoleMsg(s..'\n') --for strings
end
function msg_i(s)
str=string.format("%i",s) --for integer
reaper.ShowConsoleMsg(str..'\n')
end
function msg_d(s)
str=string.format("%d",s) --for decimal
reaper.ShowConsoleMsg(str..'\n')
end
function msg_f(s)
str=string.format("%f",s) --for float
reaper.ShowConsoleMsg(str..'\n')
end
function msg_b(s)
str=string.format("%s\n", tostring(true)) --for f***ing boolean
reaper.ShowConsoleMsg(str..'\n')
end
---------------------------------------------------------------------------------------
local proj =0;
--================================
-- Script By Kawa : http://forum.cockos.com/showpost.php?p=1803420&postcount=2
--================================
local function getTrackByTrackName(targetName)
local outTrack = nil;
--==============================
local count =0;
while ( count < reaper.CountTracks(proj) )
do
local _track = reaper.GetTrack(proj,count);
--============================
local _retval
, _trackName = reaper.GetSetMediaTrackInfo_String( _track
, "P_NAME"
, ""
, false);
if ( string.upper(_trackName) == string.upper(targetName))
then
outTrack = _track;
break;
end
--============================
count= count+1;
end
--==============================
return outTrack ;-- nil or track
end
--================================
-- test( to select Track by track Name )
--================================
local tracks = {"woodwinds","brass","percussions","keyboards - harp","voices","strings","sound design","band","ethnic","scarlett 18i20 audio input"}
for i, CurrentTrack in ipairs(tracks) do
if ( CurrentTrack ~= nil) -- check wheter found
then
local track = getTrackByTrackName(CurrentTrack)
-- reaper.SetMediaTrackInfo_Value(track, "I_SELECTED", 1); -- 0 (false) or 1(true)
reaper.SetTrackSelected(track,true);
reaper.Main_OnCommand(reaper.NamedCommandLookup("_SWS_COLLAPSE"),0)
reaper.SetTrackSelected(track,false);
end
end
--================================
Just change _SWS_COLLAPSE by _SWS_UNCOLLAPSE to to the reverse
Last edited by daeavelwyn; 02-17-2017 at 05:37 AM.
|
|
|
02-17-2017, 06:07 AM
|
#4
|
Human being with feelings
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
|
The only way I've found is to have another, smaller script call the main one - my "Duplicate selected notes diatonically" scripts do this.
Code:
interval = -9
local script_path = debug.getinfo(1,'S').source:match[[^@?(.*[\/])[^\/]-$]]
dofile(script_path .. "../Lokasenna_Duplicate selected notes chromatically.lua")
That's the whole script. It just sets a global variable, gets the script path, and looks in the folder above it for the main script. The main script essentially gets unpacked into the same environment and variable scope, so when it looks for interval it finds it right away.
Also, just out of curiosity - why not use one function for all of your Msg needs?
Code:
function Msg(str)
reaper.ShowConsoleMsg(tostring(str).."\n")
end
tostring works on pretty much anything, including nils and booleans.
|
|
|
02-17-2017, 06:37 AM
|
#5
|
Human being with feelings
Join Date: Dec 2014
Posts: 600
|
Hi lokasenna !
Thanks for your post, but my goal is to have a script instead of using cycle actions (which are quite slower I guess) and avoid having a script for each main folder I'd like to collapse or uncollapse. So, if I can't pass argument from osc, my script is quite unusable :-/
So if I can avoid external stuff, I'd rather, I want to keep the stuff as simple as possible and not use temp file if possible. But your answer suggests it's not possible :-/
Thks for the tip concerning reaper.ShowConsoleMsg, it's my first script, so i'm not really familiar with every aspects
|
|
|
Thread Tools |
|
Display Modes |
Linear Mode
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
All times are GMT -7. The time now is 06:09 PM.
|