Old 02-16-2017, 05:07 PM   #1
daeavelwyn
Human being with feelings
 
daeavelwyn's Avatar
 
Join Date: Dec 2014
Posts: 600
Default 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)
daeavelwyn is offline   Reply With Quote
Old 02-16-2017, 06:37 PM   #2
kawa_
Human being with feelings
 
kawa_'s Avatar
 
Join Date: Mar 2016
Posts: 117
Default


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
--================================
__________________
web | kawaScripts | donate | twitter |
kawa_ is offline   Reply With Quote
Old 02-17-2017, 05:15 AM   #3
daeavelwyn
Human being with feelings
 
daeavelwyn's Avatar
 
Join Date: Dec 2014
Posts: 600
Default

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.
daeavelwyn is offline   Reply With Quote
Old 02-17-2017, 06:07 AM   #4
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
Default

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.
__________________
I'm no longer using Reaper or working on scripts for it. Sorry. :(
Default 5.0 Nitpicky Edition / GUI library for Lua scripts / Theory Helper / Radial Menu / Donate
Lokasenna is offline   Reply With Quote
Old 02-17-2017, 06:37 AM   #5
daeavelwyn
Human being with feelings
 
daeavelwyn's Avatar
 
Join Date: Dec 2014
Posts: 600
Default

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
daeavelwyn is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -7. The time now is 06:09 PM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.