Help: reduce complex function: "swap tracks & groups"

Hi

This is a bit more advanced than usual and it is necessary to think a little.This is the second time I have built a couple of functions to “swap tracks and groups” or rather, exchange positions within the index, using two buttons. The first time I did not like the result. This second time, the two functions are more advanced, but very complex. Then I wonder, if there is any way to make this much simpler. I copy both functions separately:

SWAP TO LEFT:

function navt_swap_left( song, type, sti, m, n, parent_index )
  song = renoise.song()
  type = song.selected_track.type
  sti = song.selected_track_index

  --For track
  if type == renoise.Track.TRACK_TYPE_SEQUENCER then
    --left out of the group
    if song.tracks[sti].group_parent then
      m = #song.tracks[sti].group_parent.members
      print('m: ', m)

      --Parent Index
      for i, track in ripairs ( song.tracks ) do
        if track.type == renoise.Track.TRACK_TYPE_GROUP then
          if i - #track.members <= sti and sti < i then
            parent_index = i
          end
        end
      end
      --For first member and rest
      if sti == parent_index - m then
        song:insert_track_at( sti )
        song:swap_tracks_at( sti + 1, sti )
        song:delete_track_at( sti + 1 )
        song:select_previous_track()
        --if previeus is track
        else
        if sti > 1 then
          if song.tracks[sti - 1].type ~= renoise.Track.TRACK_TYPE_GROUP then
            song:swap_tracks_at( sti, sti - 1 )
            song:select_previous_track()
          end
        --if previeus is group
          if song.tracks[sti - 1].type == renoise.Track.TRACK_TYPE_GROUP then
            song:add_track_to_group( sti, sti - 1 )
            song:select_previous_track()
          end
        end
      end

      else
      --left track swap track out of group
      if sti > 1 then
        if song.tracks[sti - 1].type == renoise.Track.TRACK_TYPE_GROUP then
          song:add_track_to_group( sti, sti - 1 )
          song:select_previous_track()
          else
          song:swap_tracks_at( sti, sti - 1 )
          song:select_previous_track()
        end
      end
    end
  end
  --- --- ---
  --For Group
  if type == renoise.Track.TRACK_TYPE_GROUP then
    n = #song.tracks[sti].members
    print('n: ', n)
    if song.tracks[sti].group_parent then
      m = #song.tracks[sti].group_parent.members
      print('m: ', m)

      --Parent Index
      for i, track in ripairs ( song.tracks ) do
        if track.type == renoise.Track.TRACK_TYPE_GROUP then
          if i - #track.members <= sti and sti < i then
            parent_index = i
          end
        end
      end
      --For first member and rest
      if sti == parent_index - m + n then
        song:insert_track_at( sti - n )
        song:swap_tracks_at( sti + 1, sti - n )
        song:delete_track_at( sti + 1 )
        song:select_previous_track()
        --if previeus is track
        elseif song.tracks[sti - n - 1].type ~= renoise.Track.TRACK_TYPE_GROUP then
        song:swap_tracks_at( sti, sti - n - 1 )
        song:select_previous_track()
        --if previeus is group
        elseif song.tracks[sti - n - 1].type == renoise.Track.TRACK_TYPE_GROUP then
        song:add_track_to_group( sti, sti -n - 1 )
        song:select_previous_track()
      end
      
      else
      --left track swap track out of group
      if sti > n + 1 then
        if song.tracks[sti - n - 1].type == renoise.Track.TRACK_TYPE_GROUP then --
          song:add_track_to_group( sti, sti - n - 1 )
          song:select_previous_track()
          else
          song:swap_tracks_at( sti, sti - n - 1 )
          song:select_previous_track()
        end
      end
    end
  end
end

SWAP TO RIGHT:

function navt_swap_right( song, type, sti, sti2, m, n, parent_index )
  song = renoise.song()
  type = song.selected_track.type
  sti = song.selected_track_index
  --For Track
  if type == renoise.Track.TRACK_TYPE_SEQUENCER and sti < song.sequencer_track_count then
    if song.tracks[sti + 1].group_parent then
      m = #song.tracks[sti + 1].group_parent.members

      --Parent Index
      for i, track in ripairs ( song.tracks ) do
        if track.type == renoise.Track.TRACK_TYPE_GROUP then
          if i - #track.members <= sti + 1 and sti + 1 < i then
            parent_index = i
          end
        end
      end

      print( 'sti: ', sti )
      print( 'parent_index: ', parent_index )
      print( 'm: ', m )

      if sti > parent_index - m - 1 and song.tracks[sti + 1].type == renoise.Track.TRACK_TYPE_SEQUENCER then
        song:swap_tracks_at( sti + 1, sti )
        song:select_next_track()
      end
      if sti == parent_index - m - 1 then
        if song.tracks[sti + 1].type == renoise.Track.TRACK_TYPE_GROUP and song.tracks[sti + 2].type == renoise.Track.TRACK_TYPE_GROUP then
          song:add_track_to_group( sti, sti + 1 )
          elseif song.tracks[sti + 1].type == renoise.Track.TRACK_TYPE_GROUP and song.tracks[sti + 2].type == renoise.Track.TRACK_TYPE_SEQUENCER then
            song:add_track_to_group( sti, parent_index - m )
            song.selected_track_index = sti
          else
          song:add_track_to_group( sti, parent_index - m )
          song:delete_track_at( sti + 2 )
          song.selected_track_index = sti
        end
        elseif song.tracks[sti + 1].type == renoise.Track.TRACK_TYPE_GROUP then
        song:insert_track_at( sti + 2 )
        song:swap_tracks_at( sti, sti + 2 )
        song:delete_track_at( sti )
        song.selected_track_index = sti + 1
      end
      else
      if song.tracks[sti + 1].type == renoise.Track.TRACK_TYPE_SEQUENCER then
        song:swap_tracks_at( sti, sti + 1 )
        song:select_next_track()
        else
        song:insert_track_at( sti + 2 )
        song:swap_tracks_at( sti, sti + 2 )
        song:delete_track_at( sti )
        song.selected_track_index = sti + 1
      end
    end
  end

  --For Group
  if type == renoise.Track.TRACK_TYPE_GROUP and sti < song.sequencer_track_count then
    n = #song.tracks[sti].members
    print('n: ', n)
    if song.tracks[sti + 1].group_parent then
      m = #song.tracks[sti + 1].group_parent.members

      --Parent Index
      for i, track in ripairs ( song.tracks ) do
        if track.type == renoise.Track.TRACK_TYPE_GROUP then
          if i - #track.members <= sti + 1 and sti + 1 < i then
            parent_index = i
          end
        end
      end

      print( 'sti: ', sti )
      print( 'parent_index: ', parent_index )
      print( 'm: ', m )

      if sti > parent_index - m - 1 and song.tracks[sti + 1].type == renoise.Track.TRACK_TYPE_SEQUENCER then
        song:swap_tracks_at( sti + 1, sti )
        song:select_next_track()
      elseif song.tracks[sti + 1].type == renoise.Track.TRACK_TYPE_GROUP then
        song:insert_track_at( sti + 2 )
        song:swap_tracks_at( sti, sti + 2 )
        song:delete_track_at( sti - n )
        song.selected_track_index = sti + 1      
      end
      --- ---
      if sti == parent_index - m - 1 then
        if song.tracks[sti + 1].type == renoise.Track.TRACK_TYPE_GROUP and song.tracks[sti + 2].type == renoise.Track.TRACK_TYPE_GROUP then
            --song:add_track_to_group( sti, sti + 1 )
          elseif song.tracks[sti + 1].type == renoise.Track.TRACK_TYPE_GROUP and song.tracks[sti + 2].type == renoise.Track.TRACK_TYPE_SEQUENCER then
            song:add_track_to_group( sti, parent_index - m )
            song.selected_track_index = sti
          else
          song:add_track_to_group( sti, parent_index - m ) --ok
          song:delete_track_at( sti + 2 )
          song.selected_track_index = sti
        end
      end
      --- ---
      else
      if song.tracks[sti + 1].type == renoise.Track.TRACK_TYPE_SEQUENCER then
        song:swap_tracks_at( sti, sti + 1 )
        song:select_next_track()
        else
        song:insert_track_at( sti + 2 )
        song:swap_tracks_at( sti, sti + 2 )
        song:delete_track_at( sti - n )
        song.selected_track_index = sti + 1
      end

    end
  end
end
  • The function of “swap to left” work perfect in all possible cases.
  • The function of “swap to right”. Only has a small defect, when the selected group has to their right two groups that are not their parents. I can not get him into the first group.

But my question is another. Is there a much simpler way of doing the same without these complex functions?

Doing all this I have encountered somewhat strange situations. For example, sometimes, when you insert a track within a group, another group is automatically created. On the other hand, a complex case is when you have a track A and to the right a group C that is not a parent, and inside another track B, and you want to add track A within group C but to the left of track B It turns out that track A will have the same position after moving it.It is also a bit of a mess to pull a clue or group within another parent group with the native swap function.In the end, all this is a very complicated thing to build a function.

Finally, I have tried to move groups with many tracks inside, and the performance is worse. In this case the functions are heavy. That’s why I wonder if there is a much simpler way of doing the same thing.

Danoise , any suggestions?

Joule , you may remember something with these functions: parent_index?Maybe the API would need some more details. Sometimes managing groups and clues is a bit complicated.

4Tey , you usually improve things by magic.Would this be a challenge?I am a newbie.Perhaps there is some simpler way that I do not know yet.

Thank you all!!!

No one wants to keep an eye on this? :slight_smile: