Go Back   Cockos Incorporated Forums > REAPER Forums > REAPER Q&A, Tips, Tricks and Howto

Reply
 
Thread Tools Display Modes
Old 02-11-2012, 04:43 PM   #1
Viente
Human being with feelings
 
Viente's Avatar
 
Join Date: Feb 2012
Posts: 1,972
Default Copying item preserving offset relative to grid position

for example i put snare and moved it a little bit off the grid, then i try to copy it to the next bar but it snaps to absolute grid value

Is it possible to copy it preserving this offest i made?

Thanks!
Viente is offline   Reply With Quote
Old 02-11-2012, 05:24 PM   #2
buckman
Human being with feelings
 
buckman's Avatar
 
Join Date: Jul 2008
Posts: 1,850
Default

I'd like to know this too
__________________
==
Reaper 6 needs Area Selection!
http://forum.cockos.com/project.php?issueid=122
buckman is offline   Reply With Quote
Old 02-11-2012, 06:22 PM   #3
Viente
Human being with feelings
 
Viente's Avatar
 
Join Date: Feb 2012
Posts: 1,972
Default

This is essential for my production, i hope we can figure it out

So far i've only got solution to select a time range, then select desired items and press ctrl+shift+d

but i hope for some faster one click solution
Viente is offline   Reply With Quote
Old 02-11-2012, 06:42 PM   #4
beingmf
Human being with feelings
 
beingmf's Avatar
 
Join Date: Jul 2007
Location: Jazz City
Posts: 5,065
Default

Search for "relative grid position" in the action list.
beingmf is online now   Reply With Quote
Old 02-11-2012, 06:56 PM   #5
Viente
Human being with feelings
 
Viente's Avatar
 
Join Date: Feb 2012
Posts: 1,972
Default

Quote:
Originally Posted by beingmf View Post
Search for "relative grid position" in the action list.
Yay!! You made my day cheers!
Viente is offline   Reply With Quote
Old 02-11-2012, 07:30 PM   #6
Marah Mag
Human being with feelings
 
Marah Mag's Avatar
 
Join Date: Sep 2008
Location: Here
Posts: 3,000
Default

Quote:
Originally Posted by beingmf View Post
Search for "relative grid position" in the action list.
I'd never seen those actions before. hmm.

Another approach. Every item can have a 'Snap offset' as one of its properties.

Search the action list for 'set snap offset' for 2 actions that let you set this automatically. I have 'snap offset to nearest gridline' mapped to my O key.

What this does is, it gives a selected item an offset point at the nearest gridline to the item's actual start position (I believe this is based on the current grid setting.) An offset line is visible on the item, and can even be grabbed at the bottom & dragged.

Once an offset is set, you can copy the item (even via drag) and when Snap is enabled, the offset line will snap to grid intervals (as will the item's left edge continue to do so.)

Try it. You'll like it!

hth
Marah Mag is offline   Reply With Quote
Old 02-12-2012, 08:49 AM   #7
Tod
Human being with feelings
 
Tod's Avatar
 
Join Date: Jan 2010
Location: Kalispell
Posts: 14,745
Default

Quote:
Originally Posted by beingmf View Post
Search for "relative grid position" in the action list.
When I paste relative grid position in the action filter, I get nothing. I'm on Reaper 4.15 and I have version 2.0.0 build#30 for SWS.

What should I be seeing?
Tod is offline   Reply With Quote
Old 02-12-2012, 11:28 AM   #8
beingmf
Human being with feelings
 
beingmf's Avatar
 
Join Date: Jul 2007
Location: Jazz City
Posts: 5,065
Default

Happy that it worked (btw. you can as well define a time selection, select one or more items and hit copy > items will be pasted relative to the time selection offset!).

@ Tod: you should see "Item edit: Disable relative grid snap", "Item edit: Enable relative grid snap" and "Item edit: toggle relative grid snap". It has nothing to do with SWS.

EDIT: sorry, not "...position"...
beingmf is online now   Reply With Quote
Old 02-12-2012, 11:55 AM   #9
Viente
Human being with feelings
 
Viente's Avatar
 
Join Date: Feb 2012
Posts: 1,972
Default

I've also set up another great solution
i've set my left mouse drag to select items and time simultaneously and then redefine ctrl+d to duplicate time, works perfect!
Viente is offline   Reply With Quote
Old 02-12-2012, 01:22 PM   #10
Tod
Human being with feelings
 
Tod's Avatar
 
Join Date: Jan 2010
Location: Kalispell
Posts: 14,745
Default

Quote:
Originally Posted by beingmf View Post
@ Tod: you should see "Item edit: Disable relative grid snap", "Item edit: Enable relative grid snap" and "Item edit: toggle relative grid snap". It has nothing to do with SWS.

EDIT: sorry, not "...position"...
Okay, thanks beingmf, those could come in handy...
Tod is offline   Reply With Quote
Old 01-02-2013, 02:14 PM   #11
foxAsteria
Human being with feelings
 
foxAsteria's Avatar
 
Join Date: Dec 2009
Location: Oblivion
Posts: 10,254
Default

So we don't have a grid-relative paste or duplicate action? I can't find any way to duplicate items and preserve their relative positions (apart from mouse-dragging to duplicate).

Shouldn't duplicating obey the snap settings too?

Furthermore, I can't find any actions to resize the items to fit the grid without moving the contents position. I need this to ensure that slightly odd-length items do not make chaos of my projects when doing a lot of duplicating. Too often they get further and further off time as the project grows.

IMO when snapping is on, EVERTHING should obey it (duplicated items, recorded items etc).
__________________
foxyyymusic
foxAsteria is online now   Reply With Quote
Old 01-03-2013, 01:47 PM   #12
foxAsteria
Human being with feelings
 
foxAsteria's Avatar
 
Join Date: Dec 2009
Location: Oblivion
Posts: 10,254
Default

Bumping this again rather than start a new thread. How do we keep items from getting off time when using duplicate actions?

Can't find a way to either force items to be grid length (without shifting contents) or paste relative to grid.

Mouse dragging the only solution?

I made a related FR: http://forum.cockos.com/project.php?issueid=4560
__________________
foxyyymusic

Last edited by foxAsteria; 01-03-2013 at 02:37 PM.
foxAsteria is online now   Reply With Quote
Old 11-19-2019, 11:36 AM   #13
BirdBird
Human being with feelings
 
BirdBird's Avatar
 
Join Date: Mar 2019
Posts: 425
Default

Quote:
Originally Posted by foxAsteria View Post
Bumping this again rather than start a new thread. How do we keep items from getting off time when using duplicate actions?

Can't find a way to either force items to be grid length (without shifting contents) or paste relative to grid.

Mouse dragging the only solution?

I made a related FR: http://forum.cockos.com/project.php?issueid=4560
Did you ever find a solution for pasting relative to grid? I am currently trying to do the same thing.
__________________
ReaScript Discord Server | Scripts | JSFX
BirdBird is offline   Reply With Quote
Old 11-19-2019, 12:06 PM   #14
foxAsteria
Human being with feelings
 
foxAsteria's Avatar
 
Join Date: Dec 2009
Location: Oblivion
Posts: 10,254
Default

Quote:
Originally Posted by BirdBird View Post
Did you ever find a solution for pasting relative to grid? I am currently trying to do the same thing.
Well for sheer convenience I'm now in the habit of keeping items always aligned to grid and just shift the contents if necessary. But there are some scripts in ReaPack for duplicate that you can try.
__________________
foxyyymusic
foxAsteria is online now   Reply With Quote
Old 11-19-2019, 12:10 PM   #15
BirdBird
Human being with feelings
 
BirdBird's Avatar
 
Join Date: Mar 2019
Posts: 425
Default

Quote:
Originally Posted by foxAsteria View Post
Well for sheer convenience I'm now in the habit of keeping items always aligned to grid and just shift the contents if necessary. But there are some scripts in ReaPack for duplicate that you can try.
Thank you I ended up modifying X-Raym_Copy selected items and paste at mouse position.lua to support pasting relative to grid.
BirdBird is offline   Reply With Quote
Old 04-03-2023, 01:15 PM   #16
Tycho
Human being with feelings
 
Tycho's Avatar
 
Join Date: Jan 2011
Location: San Francisco
Posts: 461
Default

mind sharing the script? can it paste to cursor position or just mouse?
thanks
Tycho is offline   Reply With Quote
Old 04-04-2023, 07:42 PM   #17
BirdBird
Human being with feelings
 
BirdBird's Avatar
 
Join Date: Mar 2019
Posts: 425
Default

Quote:
Originally Posted by Tycho View Post
mind sharing the script? can it paste to cursor position or just mouse?
thanks
I have no clue how the one I modded in 2019 works to support edit cursor position , so quickly wrote a new one. (set uses_mouse_cursor to false on first line to paste to edit cursor instead, requires js_ReaScriptAPI)
Code:
local use_mouse_cursor = true

--collect items
local selected_item_count = reaper.CountSelectedMediaItems(0)
if selected_item_count == 0 then return end
local snap_enabled = reaper.GetToggleCommandState(1157) == 1
function snap(pos)
 return snap_enabled and reaper.SnapToGrid(0, pos) or pos
end
local minimum = math.huge
local items = {}
reaper.PreventUIRefresh(1)
for i = selected_item_count - 1, 0, -1 do
  local item = reaper.GetSelectedMediaItem(0, i)
  local position = reaper.GetMediaItemInfo_Value(item, "D_POSITION")
  minimum = math.min(minimum, position)
  table.insert(items, {
    chunk = ({reaper.GetItemStateChunk(item, "", false)})[2]:gsub("GUID", ""):gsub("POOLEDEVTS", ""),
    track = reaper.GetMediaItemTrack(item),
    position = position
  })
  reaper.SetMediaItemSelected(item, false)
end
local grid_offset = minimum - snap(minimum)

--calculate target position
local target_position
if use_mouse_cursor == true then
  local main_window = reaper.GetMainHwnd()
  local arrange_window = reaper.JS_Window_FindChildByID(main_window, 0x3E8)
  local x, _ = reaper.GetMousePosition()
  local main_window = reaper.GetMainHwnd()
  local arrange_window = reaper.JS_Window_FindChildByID(main_window, 0x3E8)
  local arrange_start, arrange_end = reaper.GetSet_ArrangeView2(0, false, 0, 0, 0, 0)
  local _, left, top, right, bottom = reaper.JS_Window_GetRect(arrange_window)
  local cx, _ = reaper.JS_Window_ScreenToClient(arrange_window, x, 0)
  local t = cx / (right - left)
  target_position = arrange_start + (arrange_end - arrange_start)*t
else
  target_position = reaper.GetCursorPosition()
end

--create new items
local offset = snap(target_position) - minimum
reaper.Undo_BeginBlock()
for i = 1, #items do
  local item = items[i]
  local new_item = reaper.AddMediaItemToTrack(items[i].track)
  reaper.SetItemStateChunk(new_item, item.chunk, true)
  reaper.SetMediaItemInfo_Value(new_item, "D_POSITION", item.position + offset + grid_offset)
end
reaper.Undo_EndBlock("Paste selected items at " .. (use_mouse_cursor and "mouse" or "edit") .. " cursor (preserve grid offset)", -1)
reaper.PreventUIRefresh(-1)
reaper.UpdateArrange()

But here is also the old one I modded into X_Raym's script way back in 2019:
(it doesn't do edit cursor, but it is tested more as I have been using it for years, my apologies to X_Raym if I butchered the old version of his script there, that was one of the first scripts I have ever touched )
Code:
--[[
 * ReaScript Name: Copy selected items and paste at mouse cursor
 * Description: A quick way to duplicate items
 * Instructions: Here is how to use it. (optional)
 * Author: X-Raym
 * Author URI: http://extremraym.com
 * Repository: GitHub > X-Raym > EEL Scripts for Cockos REAPER
 * Repository URI: https://github.com/X-Raym/REAPER-EEL-Scripts
 * File URI: https://github.com/X-Raym/REAPER-EEL-Scripts/scriptName.eel
 * Licence: GPL v3
 * Forum Thread: Script: Script name
 * Forum Thread URI: http://forum.cockos.com/***.html
 * REAPER: 5.0 pre 27
 * Extensions: SWS/S&M 2.7.1 #0
 * Version: 1.1
--]]
 
--[[
 * Changelog:
 * v1.1 (2015-05-08)
	+ Snap
 * v1.0 (2015-05-08)
	+ Initial Release
--]]

--[[ ----- DEBUGGING ====>
local info = debug.getinfo(1,'S');

local full_script_path = info.source

local script_path = full_script_path:sub(2,-5) -- remove "@" and "file extension" from file name

if reaper.GetOS() == "Win64" or reaper.GetOS() == "Win32" then
  package.path = package.path .. ";" .. script_path:match("(.*".."\\"..")") .. "..\\Functions\\?.lua"
else
  package.path = package.path .. ";" .. script_path:match("(.*".."/"..")") .. "../Functions/?.lua"
end

require("X-Raym_Functions - console debug messages")


debug = 1 -- 0 => No console. 1 => Display console messages for debugging.
clean = 1 -- 0 => No console cleaning before every script execution. 1 => Console cleaning before every script execution.

msg_clean()
]]-- <==== DEBUGGING -----

function main() -- local (i, j, item, take, track)

	reaper.Undo_BeginBlock() -- Begining of the undo block. Leave it at the top of your main function.

	-- YOUR CODE BELOW
	reaper.BR_ItemAtMouseCursor()
	
	track, context, position = reaper.BR_TrackAtMouseCursor()
	
	if context == 2 then
		
		reaper.Main_OnCommand(40297, 0) -- Unselect all tracks (so that it can copy items)
		reaper.Main_OnCommand(40698, 0) -- COpy selected items
		
		-- GET SNAP
		if reaper.GetToggleCommandState(1157) == 1 then 
			position = reaper.SnapToGrid(0, position)
		end
		
		--find the leftmost item
		local minimum = 100000000000000000000000000000
		local trackMinimum = 10000000000000
		local itemCount = reaper.CountSelectedMediaItems(0)
		for i=0, itemCount - 1 do
			local itemX = reaper.GetSelectedMediaItem(0, i)
			local pos = reaper.GetMediaItemInfo_Value( itemX, "D_POSITION") - 0.000000000001
			minimum = math.min(pos, minimum)

			local trackX = reaper.GetMediaItem_Track(itemX)
			local trackID = reaper.GetMediaTrackInfo_Value(trackX, 'IP_TRACKNUMBER')
			trackMinimum = math.min(trackID, trackMinimum)
		end

		local gridPos = reaper.BR_GetClosestGridDivision(minimum)
		local offset = gridPos - minimum


		reaper.SetEditCurPos2(0, position - offset, false, false)
		--reaper.SetOnlyTrackSelected(track)
		
		--select topmost track that contains a media item
		local topTrack = reaper.GetTrack(0, trackMinimum-1)

		reaper.SetOnlyTrackSelected(topTrack)
		
		reaper.Main_OnCommand(40914,0) -- Set first sleected track as last touched
		reaper.Main_OnCommand(40058,0) -- Paste
		
	end

	reaper.Undo_EndBlock("Copy selected items and paste at mouse cursor", -1) -- End of the undo block. Leave it at the bottom of your main function.

end


-- The following functions may be passed as global if needed
--[[ ----- INITIAL SAVE AND RESTORE ====> ]]

-- ITEMS
-- SAVE INITIAL SELECTED ITEMS
init_sel_items = {}
local function SaveSelectedItems (table)
	for i = 0, reaper.CountSelectedMediaItems(0)-1 do
		table[i+1] = reaper.GetSelectedMediaItem(0, i)
	end
end

-- RESTORE INITIAL SELECTED ITEMS
local function RestoreSelectedItems (table)
	reaper.Main_OnCommand(40289, 0) -- Unselect all items
	for _, item in ipairs(table) do
		reaper.SetMediaItemSelected(item, true)
	end
end

-- TRACKS
-- SAVE INITIAL TRACKS SELECTION
init_sel_tracks = {}
local function SaveSelectedTracks (table)
	for i = 0, reaper.CountSelectedTracks(0)-1 do
		table[i+1] = reaper.GetSelectedTrack(0, i)
	end
end

-- RESTORE INITIAL TRACKS SELECTION
local function RestoreSelectedTracks (table)
	reaper.Main_OnCommand(40297, 0) -- Unselect all tracks
	for _, track in ipairs(table) do
		reaper.SetTrackSelected(track, true)
	end
end

-- LOOP AND TIME SELECTION
--[[ SAVE INITIAL LOOP AND TIME SELECTION
function SaveLoopTimesel()
	init_start_timesel, init_end_timesel = reaper.GetSet_LoopTimeRange(0, 0, 0, 0, 0)
	init_start_loop, init_end_loop = reaper.GetSet_LoopTimeRange(0, 1, 0, 0, 0)
end

-- RESTORE INITIAL LOOP AND TIME SELECTION
function RestoreLoopTimesel()
	reaper.GetSet_LoopTimeRange(1, 0, init_start_timesel, init_end_timesel, 0)
	reaper.GetSet_LoopTimeRange(1, 1, init_start_loop, init_end_loop, 0)
end]]

-- CURSOR
-- SAVE INITIAL CURSOR POS
function SaveCursorPos()
	init_cursor_pos = reaper.GetCursorPosition()
end

-- RESTORE INITIAL CURSOR POS
function RestoreCursorPos()
	reaper.SetEditCurPos(init_cursor_pos, false, false)
end

-- VIEW
-- SAVE INITIAL VIEW
function SaveView()
	start_time_view, end_time_view = reaper.BR_GetArrangeView(0)
end


-- RESTORE INITIAL VIEW
function RestoreView()
	reaper.BR_SetArrangeView(0, start_time_view, end_time_view)
end

--[[ <==== INITIAL SAVE AND RESTORE ----- ]]




--msg_start() -- Display characters in the console to show you the begining of the script execution.
local itemCount = reaper.CountSelectedMediaItems(0)
if itemCount == 0 then
	return
end


reaper.PreventUIRefresh(1) -- Prevent UI refreshing. Uncomment it only if the script works.
reaper.Undo_BeginBlock() -- Begining of the undo block. Leave it at the top of your main function.

SaveView()
SaveCursorPos()
--SaveLoopTimesel()
SaveSelectedItems(init_sel_items)
SaveSelectedTracks(init_sel_tracks)

main() -- Execute your main function
	
	RestoreCursorPos()
	--RestoreLoopTimesel()
	RestoreSelectedItems(init_sel_items)
	RestoreSelectedTracks(init_sel_tracks)
	RestoreView()
	
reaper.Undo_EndBlock("Copy selected items and paste at mouse cursor", -1) -- End of the undo block. Leave it at the bottom of your main function.
reaper.PreventUIRefresh(-1) -- Restore UI Refresh. Uncomment it only if the script works.

reaper.UpdateArrange() -- Update the arrangement (often needed)

--msg_end() -- Display characters in the console to show you the end of the script execution.

Last edited by BirdBird; 04-04-2023 at 08:26 PM.
BirdBird is offline   Reply With Quote
Old 04-04-2023, 11:11 PM   #18
dangguidan
Human being with feelings
 
Join Date: Jan 2019
Location: China
Posts: 654
Default

Edit: Paste preserving position in measure
or
Cursor: Advance 1/4
dangguidan is offline   Reply With Quote
Old 04-05-2023, 11:35 AM   #19
skylar_battles
Human being with feelings
 
Join Date: Mar 2022
Posts: 1,522
Default

Would be great if this was integrated with a “smart paste” action
skylar_battles is offline   Reply With Quote
Old 04-05-2023, 12:21 PM   #20
Tycho
Human being with feelings
 
Tycho's Avatar
 
Join Date: Jan 2011
Location: San Francisco
Posts: 461
Default

this is awesome thank you birdbird! and thanks for all of your other amazing scripts.

Edit: working great with mouse, is there a way to make it paste grid relative to the edit cursor and not mouse?

Last edited by Tycho; 04-05-2023 at 12:27 PM.
Tycho is offline   Reply With Quote
Old 04-06-2023, 06:18 PM   #21
BirdBird
Human being with feelings
 
BirdBird's Avatar
 
Join Date: Mar 2019
Posts: 425
Default

Quote:
Originally Posted by Tycho View Post
this is awesome thank you birdbird! and thanks for all of your other amazing scripts.

Edit: working great with mouse, is there a way to make it paste grid relative to the edit cursor and not mouse?
Thanks! You can set the use_mouse_cursor line at the top to false instead of true in the first script, which makes the script paste the selection relative to the edit cursor instead.
BirdBird is offline   Reply With Quote
Old 04-07-2023, 04:02 PM   #22
Tycho
Human being with feelings
 
Tycho's Avatar
 
Join Date: Jan 2011
Location: San Francisco
Posts: 461
Default

amazing, thank you very much!
Tycho 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:56 AM.


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