From b35b7542d1b0cdd0f6d3f4e86d70c095f3ed2498 Mon Sep 17 00:00:00 2001 From: AZpercussion <70285853+AZpercussion@users.noreply.github.com> Date: Tue, 10 Feb 2026 20:10:43 +0300 Subject: [PATCH] Release Simple project reconform v1.0 - Improve advanced time options for EDL - Update EDL start time according to advanced time options change - New feature: Comparison assistant - Indicate that reconform process is going - Fix UI inconsistences and font size --- Various/az_Simple project reconform.lua | 579 +++++++++--------- .../az_Common reconform functions.lua | 235 +++++++ ...istant for az_Simple project reconform.lua | 435 +++++++++++++ 3 files changed, 946 insertions(+), 303 deletions(-) create mode 100644 Various/az_Simple project reconform/az_Common reconform functions.lua create mode 100644 Various/az_Simple project reconform/az_Comparison assistant for az_Simple project reconform.lua diff --git a/Various/az_Simple project reconform.lua b/Various/az_Simple project reconform.lua index f623edae7..f7feec7b2 100644 --- a/Various/az_Simple project reconform.lua +++ b/Various/az_Simple project reconform.lua @@ -1,10 +1,15 @@ -- @description Simple project reconform -- @author AZ --- @version 0.9 +-- @version 1.0 -- @changelog --- - Redesign logic and UI of time adjustments in cases when EDLs don't start from zero. --- - New option to analyze time selection (in project tabs) and align reference item to it. --- - Fix Report markers track settings related to fixed lanes visibility. +-- - Improve advanced time options for EDL +-- - Update EDL start time according to advanced time options change +-- - New feature: Comparison assistant +-- - Indicate that reconform process is going +-- - Fix UI inconsistences and font size +-- @provides +-- az_Simple project reconform/az_Common reconform functions.lua +-- [main] az_Simple project reconform/az_Comparison assistant for az_Simple project reconform.lua -- @link Forum thread https://forum.cockos.com/showthread.php?t=293746 -- @donation Donate via PayPal https://www.paypal.me/AZsound -- @about @@ -24,36 +29,8 @@ end ----------------------------- BugTIME = -1 --reaper.parse_timestr_pos('10:16:17:04', 5) --------------------------- -function rgbToHex(rgba) -- passing a table with percentage like {100, 50, 20, 90} - local hexadecimal = '0X' - - for key, value in pairs(rgba) do - local hex = '' - if value > 100 or value < 0 then return error('Color must be a percantage value\n between 0 and 100') end - value = (255/100)*value - while (value > 0) do - local index = math.floor(math.fmod(value, 16) + 1) - value = math.floor(value / 16) - hex = string.sub('0123456789ABCDEF', index, index) .. hex - end - - if (string.len(hex) == 0) then - hex = '00' - - elseif (string.len(hex) == 1) then - hex = '0' .. hex - end - - hexadecimal = hexadecimal .. hex - end - - return hexadecimal -end ----------------------- -ExtStateName = "SimpleReconform_AZ" - function GetExtStates() for i, option in ipairs(OptDefaults) do if option[3] ~= nil then @@ -86,6 +63,22 @@ end --------------------- +function get_script_path() + local info = debug.getinfo(1,'S'); + local script_path = info.source:match[[^@?(.*[\/])[^\/]-$]] + --script_path = script_path:gsub('[^/\\]*[/\\]*$','') --one level up + return script_path +end + +--------------------------- + +local script_path = get_script_path() +local commonFile = script_path .. 'az_Simple project reconform/' +..'az_Common reconform functions.lua' +dofile(commonFile) + +------------------------ + function OptionsDefaults() OptDefaults = {} local text @@ -169,16 +162,17 @@ function OptionsWindow() reaper.ShowMessageBox('Please, install ReaImGui from Reapack!', 'No Imgui library', 0) return end - dofile(imgui_path) '0.9.3' + dofile(imgui_path) '0.10' OptionsDefaults() GetExtStates() - local fontSize = 17 + local fontSize = 16 local ctx, ctxPr, font, fontSep, fontBig local H = fontSize local W = fontSize local loopcnt = 0 local esc - local runReconf + local refItems + local runReconf, processingReconf local reconfOpt = true local OldEDL @@ -248,7 +242,7 @@ function OptionsWindow() else AnalyseTS = true end - OldPrjStart = 0 + OldPrjStart = nil NewPrjStart = nil local oldprjOffsetTime = '' local newprjOffsetTime = '' @@ -260,41 +254,8 @@ function OptionsWindow() if type(savedFontSize) == 'number' then fontSize = savedFontSize end if not savedFontSize then savedFontSize = fontSize end - local gui_colors = { - White = rgbToHex({90,90,90,100}), - Green = rgbToHex({52,85,52,100}), - Red = rgbToHex({90,10,10,100}), - Blue = rgbToHex({30,60,80,100}), - TitleBg = rgbToHex({30,20,30,100}), - Background = rgbToHex({11,14,14,95}), - Text = rgbToHex({92,92,81.5,100}), - activeText = rgbToHex({50,95,80,100}), - ComboBox = { - Default = rgbToHex({20,25,30,100}), - Hovered = rgbToHex({35,40,45,80}), - Active = rgbToHex({42,42,37,100}), - }, - Button = { - Default = rgbToHex({25,30,30,100}), - Hovered = rgbToHex({35,40,45,100}), - Active = rgbToHex({42,42,37,100}), - }, - MainButton = { - Default = rgbToHex({25,50,40,80}), - Hovered = rgbToHex({35,60,55,80}), - Active = rgbToHex({56,56,42,90}), - } - } - --------- - ---Flags--- - local Flags = {} - Flags.childRounding = reaper.ImGui_StyleVar_ChildRounding() - Flags.frameRounding = reaper.ImGui_StyleVar_FrameRounding() - Flags.childBorder = reaper.ImGui_ChildFlags_Border() - Flags.menubar = reaper.ImGui_WindowFlags_MenuBar() - Flags.tableResizeflag = reaper.ImGui_TableFlags_Resizable() - Flags.childAutoResizeX = reaper.ImGui_ChildFlags_AutoResizeX() - Flags.childAutoResizeY = reaper.ImGui_ChildFlags_AutoResizeY() + local gui_colors = SetGUIcolors() + local Flags = SetGUIflags() -------------- function SplitFilename(strFilename) -- Path, Filename, Extension @@ -375,15 +336,23 @@ function OptionsWindow() end -------------- + local fontName, OScoeff + ctx = reaper.ImGui_CreateContext('SimpleProjectReconform_AZ') + if reaper.GetOS():match("^Win") == nil then + reaper.ImGui_SetConfigVar(ctx, reaper.ImGui_ConfigVar_ViewportsNoDecoration(), 0) + fontName, OScoeff = 'sans-serif', 1.08 + else fontName, OScoeff = 'Calibri', 1 + end + ----------- - function frame() + local function frame() local childALLflags = Flags.childAutoResizeY | Flags.childAutoResizeX local ChildALL = reaper.ImGui_BeginChild(ctx, 'ChildALL', 0, 0, childALLflags) if ChildALL then - reaper.ImGui_PushFont(ctx, font) + reaper.ImGui_PushFont(ctx, font, fontSize) --About button reaper.ImGui_SameLine(ctx, fontSize*25, nil) @@ -480,15 +449,16 @@ function OptionsWindow() end local timeOldRegionStart, timeOldRegionEnd = 0, 0 + local timeNewRegionStart, timeNewRegionEnd = 0, 0 if old_TakeRegion == true then - timeOldRegionStart = reaper.parse_timestr_pos( TrimOldTimeStart, 5 ) - PrjTimeOffset - timeOldRegionEnd = reaper.parse_timestr_pos( TrimOldTimeEnd, 5 ) - PrjTimeOffset + timeOldRegionStart = reaper.parse_timestr_pos( TrimOldTimeStart, 5 ) -- - PrjTimeOffset + timeOldRegionEnd = reaper.parse_timestr_pos( TrimOldTimeEnd, 5 ) -- - PrjTimeOffset end if new_TakeRegion == true then - timeNewRegionStart = reaper.parse_timestr_pos( TrimNewTimeStart, 5 ) - PrjTimeOffset - timeNewRegionEnd = reaper.parse_timestr_pos( TrimNewTimeEnd, 5 ) - PrjTimeOffset + timeNewRegionStart = reaper.parse_timestr_pos( TrimNewTimeStart, 5 ) -- - PrjTimeOffset + timeNewRegionEnd = reaper.parse_timestr_pos( TrimNewTimeEnd, 5 ) -- - PrjTimeOffset end if reaper.ImGui_Button(ctx, ' old EDLs ') then --msg(iniFolder) @@ -505,18 +475,13 @@ function OptionsWindow() if fileNames ~= '' then OldEDL = {} - addFileNamesToList(OldEDL, fileNames) + addFileNamesToList(OldEDL, fileNames) OldEdlTable = AnalyseEDLs(OldEDL, timeOldRegionStart, timeOldRegionEnd) - - if OldEdlTable and OldEdlTable.firstItemTime then - AlignOldTime = OldEdlTable.firstItemTime - else AlignOldTime = nil - end end end reaper.ImGui_SameLine(ctx) - reaper.ImGui_PushFont(ctx, fontSep) + reaper.ImGui_PushFont(ctx, fontSep, fontSize-2) reaper.ImGui_Text(ctx, 'Note: EDL must be CMX 3600') reaper.ImGui_PopFont(ctx) @@ -538,11 +503,6 @@ function OptionsWindow() NewEDL ={} addFileNamesToList(NewEDL, fileNames) NewEdlTable = AnalyseEDLs(NewEDL, timeNewRegionStart, timeNewRegionEnd) - - if NewEdlTable and NewEdlTable.firstItemTime then - AlignNewTime = NewEdlTable.firstItemTime - else AlignNewTime = nil - end end end @@ -558,7 +518,7 @@ function OptionsWindow() local extensionList = "Media file\0*.wav;*.mp3;*.flac;*.aif;*.mpa;*.wma;*.mp4;*.mov;*.m4v;*.webm\0\0" local allowMultiple = false local ret, fileNames = reaper.JS_Dialog_BrowseForOpenFiles - ( 'Choose media file', iniFolder, iniFile, extensionList, allowMultiple ) + ( 'Choose media file', iniFolder, iniFile, extensionList, allowMultiple ) if fileNames ~= '' then ReferenceFile = {} @@ -591,8 +551,18 @@ function OptionsWindow() showEDLsNames(ReferenceFile) local ret - - reaper.ImGui_PushItemWidth(ctx, fontSize*6 ) + + if OldEdlTable and OldEdlTable.firstItemTime then + AlignOldTime = OldEdlTable.firstItemTime + else AlignOldTime = nil + end + + if NewEdlTable and NewEdlTable.firstItemTime then + AlignNewTime = NewEdlTable.firstItemTime + else AlignNewTime = nil + end + + reaper.ImGui_PushItemWidth(ctx, fontSize*6*OScoeff ) if type(AlignOldTime) == 'number' then AlignOldTime = reaper.format_timestr_pos(AlignOldTime,'',5) end @@ -603,7 +573,7 @@ function OptionsWindow() ret, old_UseAlignPoint = reaper.ImGui_Checkbox(ctx,'Set align point for reference item',old_UseAlignPoint) if ret then reaper.SetProjExtState(0,ExtStateName,'old_UseAlignPoint', tostring(old_UseAlignPoint), true) end - reaper.ImGui_PushItemWidth(ctx, fontSize*6 ) + reaper.ImGui_PushItemWidth(ctx, fontSize*6*OScoeff ) if type(AlignNewTime) == 'number' then AlignNewTime = reaper.format_timestr_pos(AlignNewTime,'',5) end @@ -653,7 +623,21 @@ function OptionsWindow() end end - if abort ~= true then CreateRefTrack(CompResult, ReferenceFile, true) end + if abort ~= true then + if AlignOldTime < timeOldRegionStart + and old_UseAlignPoint then + AlignOldTime = timeOldRegionStart + PrjTimeOffset + end + if AlignNewTime < timeNewRegionStart + and new_TrimTime then + AlignNewTime = timeNewRegionStart + PrjTimeOffset + end + CreateRefTrack(CompResult, ReferenceFile, true) + end + + AlignOldTime = OldEdlTable.firstItemTime + AlignNewTime = NewEdlTable.firstItemTime + else reaper.ShowMessageBox('Choose both EDLs and a reference file first.', 'Simple Rroject Reconform', 0) end @@ -662,58 +646,79 @@ function OptionsWindow() --------Adv timing options reaper.ImGui_SameLine(ctx, fontSize*20, nil) - reaper.ImGui_PushFont(ctx, fontSep) + reaper.ImGui_PushFont(ctx, fontSep, fontSize-2) if reaper.ImGui_CollapsingHeader(ctx, 'Advanced timing options') then reaper.ImGui_NewLine(ctx) reaper.ImGui_SameLine(ctx, fontSize*7, nil) local childAdvflags = Flags.childBorder | Flags.childAutoResizeY --| Flags.childAutoResizeX local advOpt = reaper.ImGui_BeginChild(ctx, 'advOpt', 0, 0, childAdvflags, nil) if advOpt then - local ret - ret, old_TakeRegion = reaper.ImGui_Checkbox(ctx,'Take region from OLD EDLs',old_TakeRegion) - if ret == true then reaper.SetProjExtState(0,ExtStateName,'old_TakeRegion', tostring(old_TakeRegion), true) end + local retChk, retOst, retOend, retNst, retNend + retChk, old_TakeRegion = reaper.ImGui_Checkbox(ctx,'Take region from OLD EDLs',old_TakeRegion) + if retChk == true then reaper.SetProjExtState(0,ExtStateName,'old_TakeRegion', tostring(old_TakeRegion), true) end reaper.ImGui_SameLine(ctx, fontSize*14) - reaper.ImGui_PushItemWidth(ctx, fontSize*5.3 ) - ret, TrimOldTimeStart = reaper.ImGui_InputText(ctx, '##1', TrimOldTimeStart, nil, nil) - if ret == true then + reaper.ImGui_PushItemWidth(ctx, fontSize * 5.3 * OScoeff ) + retOst, TrimOldTimeStart = reaper.ImGui_InputText(ctx, '##1', TrimOldTimeStart, nil, nil) + if retOst == true then TrimOldTimeStart = reaper.parse_timestr_pos( TrimOldTimeStart, 5 ) TrimOldTimeStart = reaper.format_timestr_pos(TrimOldTimeStart,'',5) reaper.SetProjExtState(0, ExtStateName,'TrimOldTimeStart', TrimOldTimeStart, true) end reaper.ImGui_SameLine(ctx) - reaper.ImGui_PushItemWidth(ctx, fontSize*5.3 ) - ret, TrimOldTimeEnd = reaper.ImGui_InputText(ctx, '##2', TrimOldTimeEnd, nil, nil) - if ret == true then + reaper.ImGui_PushItemWidth(ctx, fontSize * 5.3 * OScoeff ) + retOend, TrimOldTimeEnd = reaper.ImGui_InputText(ctx, '##2', TrimOldTimeEnd, nil, nil) + if retOend == true then TrimOldTimeEnd = reaper.parse_timestr_pos( TrimOldTimeEnd, 5 ) TrimOldTimeEnd = reaper.format_timestr_pos(TrimOldTimeEnd,'',5) reaper.SetProjExtState(0, ExtStateName,'TrimOldTimeEnd', TrimOldTimeEnd, true) end - --- + if retChk or retOst or retOend then + if old_TakeRegion then + timeOldRegionStart = reaper.parse_timestr_pos( TrimOldTimeStart, 5 ) -- PrjTimeOffset + timeOldRegionEnd = reaper.parse_timestr_pos( TrimOldTimeEnd, 5 ) -- PrjTimeOffset + else + timeOldRegionStart, timeOldRegionEnd = 0, 0 + end + --msg(timeOldRegionStart) msg(timeOldRegionEnd) + OldEdlTable = AnalyseEDLs(OldEDL, timeOldRegionStart, timeOldRegionEnd) + end - ret, new_TakeRegion = reaper.ImGui_Checkbox(ctx,'Take region from NEW EDLs',new_TakeRegion) - if ret == true then reaper.SetProjExtState(0,ExtStateName,'new_TakeRegion', tostring(new_TakeRegion), true) end + --- + + retChk, new_TakeRegion = reaper.ImGui_Checkbox(ctx,'Take region from NEW EDLs',new_TakeRegion) + if retChk == true then reaper.SetProjExtState(0,ExtStateName,'new_TakeRegion', tostring(new_TakeRegion), true) end reaper.ImGui_SameLine(ctx, fontSize*14) - reaper.ImGui_PushItemWidth(ctx, fontSize*5.3 ) - ret, TrimNewTimeStart = reaper.ImGui_InputText(ctx, '##3', TrimNewTimeStart, nil, nil) - if ret == true then + reaper.ImGui_PushItemWidth(ctx, fontSize * 5.3 * OScoeff ) + retNst, TrimNewTimeStart = reaper.ImGui_InputText(ctx, '##3', TrimNewTimeStart, nil, nil) + if retNst == true then TrimNewTimeStart = reaper.parse_timestr_pos( TrimNewTimeStart, 5 ) TrimNewTimeStart = reaper.format_timestr_pos(TrimNewTimeStart,'',5) reaper.SetProjExtState(0, ExtStateName,'TrimNewTimeStart', TrimNewTimeStart, true) end reaper.ImGui_SameLine(ctx) - reaper.ImGui_PushItemWidth(ctx, fontSize*5.3 ) - ret, TrimNewTimeEnd = reaper.ImGui_InputText(ctx, '##4', TrimNewTimeEnd, nil, nil) - if ret == true then + reaper.ImGui_PushItemWidth(ctx, fontSize * 5.3 * OScoeff ) + retNend, TrimNewTimeEnd = reaper.ImGui_InputText(ctx, '##4', TrimNewTimeEnd, nil, nil) + if retNend == true then TrimNewTimeEnd = reaper.parse_timestr_pos( TrimNewTimeEnd, 5 ) TrimNewTimeEnd = reaper.format_timestr_pos(TrimNewTimeEnd,'',5) reaper.SetProjExtState(0, ExtStateName,'TrimNewTimeEnd', TrimNewTimeEnd, true) end + if retChk or retNst or retNend then + if new_TakeRegion then + timeNewRegionStart = reaper.parse_timestr_pos( TrimNewTimeStart, 5 ) + timeNewRegionEnd = reaper.parse_timestr_pos( TrimNewTimeEnd, 5 ) + else + timeNewRegionStart, timeNewRegionEnd = 0, 0 + end + NewEdlTable = AnalyseEDLs(NewEDL, timeNewRegionStart, timeNewRegionEnd) + end + reaper.ImGui_EndChild(ctx) end end @@ -828,7 +833,7 @@ function OptionsWindow() reaper.ImGui_SetWindowSize(ctx, 0, 0, nil ) end - --------end of Prj analysys section + --------end of Prj analysis section reaper.ImGui_NewLine(ctx) @@ -853,39 +858,63 @@ function OptionsWindow() end if NewPrjStart then reaper.ImGui_PopStyleColor(ctx, 3) end - reaper.ImGui_NewLine(ctx) - reaper.ImGui_Text(ctx, 'To get much faster results') + reaper.ImGui_SameLine(ctx, fontSize*25) + if reaper.ImGui_Button(ctx, 'Comparison\n assistant', fontSize*8) then + local file = script_path .. 'az_Simple project reconform/' + ..'az_Comparison assistant for az_Simple project reconform.lua' + dofile(file) + end + + --reaper.ImGui_NewLine(ctx) + reaper.ImGui_Text(ctx, 'To get much faster results:') if reaper.ImGui_Button(ctx, 'Set FX on selected items OFFLINE') then reaper.Main_OnCommandEx(42353,0,0) --Items: Set all take FX offline for selected media items end - reaper.ImGui_SameLine(ctx, fontSize*15.5) + reaper.ImGui_SameLine(ctx, nil, fontSize * 1.8) if reaper.ImGui_Button(ctx, 'Revert FX on selected items ONLINE') then reaper.Main_OnCommandEx(42354,0,0) --Items: Set all take FX online for selected media items end reaper.ImGui_NewLine(ctx) --Input box + button - reaper.ImGui_PushItemWidth(ctx, fontSize*6 ) + reaper.ImGui_PushItemWidth(ctx, fontSize * 6 * OScoeff ) local fieldState, retOldPrjOffsetTime = reaper.ImGui_InputText(ctx, 'Old project position', reaper.format_timestr_pos( OldPrjStart, '', 5 ), nil, nil) if fieldState == true then OldPrjStart = reaper.parse_timestr_pos( retOldPrjOffsetTime, 5 ) end - reaper.ImGui_SameLine(ctx, fontSize*15.5, nil) + reaper.ImGui_SameLine(ctx, fontSize*16, nil) reaper.ImGui_PushID(ctx, 1) - if reaper.ImGui_Button(ctx, 'Get edit cursor', nil, nil ) then - OldPrjStart = reaper.GetCursorPosition() + local btnState = reaper.ImGui_Button(ctx, 'Get edit cursor', nil, nil ) + + if btnState then OldPrjStart = reaper.GetCursorPosition() end + + if fieldState or btnState then + reaper.SetProjExtState(0,ExtStateName, 'OldPrjStart', OldPrjStart ) end reaper.ImGui_PopID(ctx) --Renonform button - reaper.ImGui_SameLine(ctx, nil, fontSize*2.2) + reaper.ImGui_SameLine(ctx, nil, fontSize*1.8) reaper.ImGui_PushStyleColor(ctx, reaper.ImGui_Col_Button(), gui_colors.MainButton.Default) reaper.ImGui_PushStyleColor(ctx, reaper.ImGui_Col_ButtonHovered(), gui_colors.MainButton.Hovered) reaper.ImGui_PushStyleColor(ctx, reaper.ImGui_Col_ButtonActive(), gui_colors.MainButton.Active) - runReconf = reaper.ImGui_Button(ctx, 'Reconform', fontSize*8, nil) + local actionBtnName = 'Reconform' + + if processingReconf then + reaper.ImGui_PopStyleColor(ctx, 3) + actionBtnName = 'Need some time...' + reaper.ImGui_PushStyleColor(ctx, reaper.ImGui_Col_Button(), gui_colors.MainButton.Active) + reaper.ImGui_PushStyleColor(ctx, reaper.ImGui_Col_ButtonHovered(), gui_colors.MainButton.Active) + reaper.ImGui_PushStyleColor(ctx, reaper.ImGui_Col_ButtonActive(), gui_colors.MainButton.Active) + end + + if reaper.ImGui_Button(ctx, actionBtnName, fontSize*8, nil) then + runReconf = true + else runReconf = false + end reaper.ImGui_PopStyleColor(ctx, 3) @@ -905,20 +934,25 @@ function OptionsWindow() end end - reaper.ImGui_SameLine(ctx, fontSize*15.5, nil) + reaper.ImGui_SameLine(ctx, fontSize*16, nil) reaper.ImGui_PushID(ctx, 2) - if reaper.ImGui_Button(ctx, 'Get edit cursor', nil, nil ) then - NewPrjStart = reaper.GetCursorPosition() - end + local btnState = reaper.ImGui_Button(ctx, 'Get edit cursor', nil, nil ) + reaper.ImGui_PopID(ctx) + + if btnState then NewPrjStart = reaper.GetCursorPosition() end if NewPrjStart and NewPrjStart <= OldPrjStart then - reaper.ShowMessageBox('Reconformed project must be placed next to the old version.\nLet it be +1 hour after the Old verion.','Warning!', 0) + reaper.ShowMessageBox('Reconformed project must be placed next to the old version.\nLet it be +1 hour after the old verion.','Warning!', 0) NewPrjStart = OldPrjStart + 3600 end + if NewPrjStart and (fieldState or btnState) then + reaper.SetProjExtState(0,ExtStateName, 'NewPrjStart', NewPrjStart ) + end + --Options button - reaper.ImGui_SameLine(ctx, nil, fontSize*2.2) + reaper.ImGui_SameLine(ctx, nil, fontSize*1.8) tglReconfOpt = reaper.ImGui_Button(ctx, 'Options >', fontSize*8, nil) if tglReconfOpt then reconfOpt = not reconfOpt end @@ -965,7 +999,7 @@ function OptionsWindow() PasteItemsFromPrj(cur_retprj, SourcePrj) - reaper.Undo_EndBlock2( 0, 'Paste new items - Simple reconform', -1 ) + reaper.Undo_EndBlock2( 0, 'Paste new items - Simple reconform', -1 ) reaper.UpdateArrange() end if NewPrjStart then reaper.ImGui_PopStyleColor(ctx, 3) end @@ -974,9 +1008,9 @@ function OptionsWindow() end -- end of collapsing header reaper.ImGui_NewLine(ctx) - reaper.ImGui_PushItemWidth(ctx, savedFontSize*5.5) + reaper.ImGui_PushItemWidth(ctx, savedFontSize * 5.5 * OScoeff ) _, savedFontSize = reaper.ImGui_InputInt - (ctx, 'Font size for the window (default is 17)', savedFontSize) + (ctx, 'Font size for the window (default is 16)', savedFontSize) reaper.ImGui_PopFont(ctx) @@ -1043,7 +1077,7 @@ function OptionsWindow() end if type(option[3]) == 'nil' then - reaper.ImGui_PushFont(ctx, fontSep) + reaper.ImGui_PushFont(ctx, fontSep, fontSize-2) reaper.ImGui_PushStyleColor(ctx, reaper.ImGui_Col_Text(), gui_colors.White) if i ~= 1 then reaper.ImGui_NewLine(ctx) end @@ -1064,10 +1098,11 @@ function OptionsWindow() end -------------- - function loop() + local function loop() + local curProj, projfn = reaper.EnumProjects( -1 ) PrjTimeOffset = -reaper.GetProjectTimeOffset( 0, false ) - MIN_luft_ZERO = ( reaper.parse_timestr_pos('00:00:00:01', 5) - PrjTimeOffset ) / 4 + MIN_luft_ZERO = GetMinLuftZero(PrjTimeOffset) PrFrRate = reaper.SNM_GetIntConfigVar( 'projfrbase', -1 ) PrDropFrame = reaper.SNM_GetIntConfigVar( 'projfrdrop', -1 ) @@ -1077,6 +1112,23 @@ function OptionsWindow() elseif PrFrRate == 24 and PrDropFrame == 2 then PrFrRate = '23.976' end + if not OldPrjStart or curProj ~= prevProj then + _, OldPrjStart = reaper.GetProjExtState(0, ExtStateName, 'OldPrjStart') + if OldPrjStart == '' then OldPrjStart = 0 + else OldPrjStart = tonumber(OldPrjStart) + end + if not OldPrjStart then OldPrjStart = 0 end + end + + if not NewPrjStart or curProj ~= prevProj then + local _, savedNewPrjStart = reaper.GetProjExtState(0, ExtStateName, 'NewPrjStart') + + if tonumber(savedNewPrjStart) then NewPrjStart = tonumber(savedNewPrjStart) end + --if not NewPrjStart then NewPrjStart = 3600 end + end + + prevProj = curProj + if reaper.CountSelectedTracks(0) ~= 0 then RefTrIdx = reaper.GetMediaTrackInfo_Value( reaper.GetSelectedTrack(0,0), 'IP_TRACKNUMBER' ) end @@ -1088,13 +1140,12 @@ function OptionsWindow() reaper.SetExtState(ExtStateName, 'FontSize', savedFontSize, true) fontSize = savedFontSize if font then reaper.ImGui_Detach(ctx, font) end - if fontSep then reaper.ImGui_Detach(ctx, fontSep) end - font = reaper.ImGui_CreateFont(fontName, fontSize, reaper.ImGui_FontFlags_None()) -- Create the fonts you need - fontSep = reaper.ImGui_CreateFont(fontName, fontSize-2, reaper.ImGui_FontFlags_Italic()) - fontBig = reaper.ImGui_CreateFont(fontName, fontSize+4, reaper.ImGui_FontFlags_None()) + if fontSep then reaper.ImGui_Detach(ctx, fontSep) end + font = reaper.ImGui_CreateFont(fontName, reaper.ImGui_FontFlags_None()) -- Create the fonts you need + fontSep = reaper.ImGui_CreateFont(fontName, reaper.ImGui_FontFlags_Italic()) + --fontBig = reaper.ImGui_CreateFont(fontName, reaper.ImGui_FontFlags_None()) reaper.ImGui_Attach(ctx, font) reaper.ImGui_Attach(ctx, fontSep) - reaper.ImGui_Attach(ctx, fontBig) end esc = reaper.ImGui_IsKeyPressed(ctx, reaper.ImGui_Key_Escape()) @@ -1102,71 +1153,54 @@ function OptionsWindow() undo = reaper.ImGui_Shortcut(ctx, reaper.ImGui_Mod_Ctrl() | reaper.ImGui_Key_Z(), reaper.ImGui_InputFlags_RouteGlobal()) redo = reaper.ImGui_Shortcut(ctx, reaper.ImGui_Mod_Ctrl() | reaper.ImGui_Mod_Shift() | reaper.ImGui_Key_Z(), reaper.ImGui_InputFlags_RouteGlobal()) - - reaper.ImGui_PushFont(ctx, font) - - reaper.ImGui_PushStyleColor(ctx, reaper.ImGui_Col_WindowBg(), gui_colors.Background) - reaper.ImGui_PushStyleColor(ctx, reaper.ImGui_Col_TitleBgActive(), gui_colors.TitleBg) - reaper.ImGui_PushStyleColor(ctx, reaper.ImGui_Col_Text(), gui_colors.Text) - - reaper.ImGui_PushStyleColor(ctx, reaper.ImGui_Col_Button(), gui_colors.Button.Default) - reaper.ImGui_PushStyleColor(ctx, reaper.ImGui_Col_ButtonHovered(), gui_colors.Button.Hovered) - reaper.ImGui_PushStyleColor(ctx, reaper.ImGui_Col_ButtonActive(), gui_colors.Button.Active) - reaper.ImGui_PushStyleColor(ctx, reaper.ImGui_Col_CheckMark(), gui_colors.Green) - - --Combo box and check box background - reaper.ImGui_PushStyleColor(ctx, reaper.ImGui_Col_FrameBg(), gui_colors.ComboBox.Default) - reaper.ImGui_PushStyleColor(ctx, reaper.ImGui_Col_FrameBgHovered(), gui_colors.ComboBox.Hovered) - reaper.ImGui_PushStyleColor(ctx, reaper.ImGui_Col_FrameBgActive(), gui_colors.ComboBox.Active) - --Combo box drop down list - reaper.ImGui_PushStyleColor(ctx, reaper.ImGui_Col_Header(), gui_colors.ComboBox.Default) - reaper.ImGui_PushStyleColor(ctx, reaper.ImGui_Col_HeaderHovered(), gui_colors.ComboBox.Hovered) - reaper.ImGui_PushStyleColor(ctx, reaper.ImGui_Col_HeaderActive(), gui_colors.ComboBox.Active) - - reaper.ImGui_PushStyleColor(ctx, reaper.ImGui_Col_Text(), gui_colors.White) - -- - reaper.ImGui_PushStyleVar(ctx, reaper.ImGui_StyleVar_WindowRounding(), fontSize/4) - reaper.ImGui_PushStyleVar(ctx, Flags.frameRounding, fontSize/4) - reaper.ImGui_PushStyleVar(ctx, Flags.childRounding, fontSize/4) - reaper.ImGui_PushStyleVar(ctx, reaper.ImGui_StyleVar_FramePadding(), fontSize/2, fontSize/4) - - local window_flags = reaper.ImGui_WindowFlags_None()--reaper.ImGui_WindowFlags_MenuBar() - reaper.ImGui_SetNextWindowSize(ctx, W, H, reaper.ImGui_Cond_Once()) -- Set the size of the windows. Use in the 4th argument reaper.ImGui_Cond_FirstUseEver() to just apply at the first user run, so ImGUI remembers user resize s2 - - local visible, open = reaper.ImGui_Begin(ctx, 'Simple Project Reconform', true, window_flags) - reaper.ImGui_PopStyleColor(ctx, 1) - - if visible then - frame() - reaper.ImGui_SetWindowSize(ctx, 0, 0, nil ) - reaper.ImGui_End(ctx) - end - - reaper.ImGui_PopStyleColor(ctx, 13) - reaper.ImGui_PopStyleVar(ctx, 4) - reaper.ImGui_PopFont(ctx) - - esc = reaper.ImGui_IsKeyReleased(ctx, reaper.ImGui_Key_Escape()) - - if undo then reaper.Main_OnCommandEx(40029,0,0) end - if redo then reaper.Main_OnCommandEx(40030,0,0) end - - if open and not esc then - if IsOptTgl == true then SetExtStates() end - if runReconf == true then main() end - reaper.defer(loop) + + reaper.ImGui_PushFont(ctx, font, fontSize) + + local colorCnt, styleCnt = PUSHstyle(ctx, gui_colors, Flags, fontSize) + + local window_flags = reaper.ImGui_WindowFlags_None()--reaper.ImGui_WindowFlags_MenuBar() + reaper.ImGui_SetNextWindowSize(ctx, W, H, reaper.ImGui_Cond_Once()) -- Set the size of the windows. Use in the 4th argument reaper.ImGui_Cond_FirstUseEver() to just apply at the first user run, so ImGUI remembers user resize s2 + + local visible, open = reaper.ImGui_Begin(ctx, 'Simple Project Reconform', true, window_flags) + reaper.ImGui_PopStyleColor(ctx, 1) + + if processingReconf then + processingReconf = false + main(refItems) + end + + if runReconf then + refItems = CollectSelectedItems() + if #refItems == 0 then + reaper.ShowMessageBox('Please select reference items on a track','Simple Project Reconform', 0) + else + processingReconf = true end + end + + if visible then + frame() + reaper.ImGui_SetWindowSize(ctx, 0, 0, nil ) + reaper.ImGui_End(ctx) + end + + reaper.ImGui_PopStyleColor(ctx, colorCnt) + reaper.ImGui_PopStyleVar(ctx, styleCnt) + reaper.ImGui_PopFont(ctx) + + esc = reaper.ImGui_IsKeyReleased(ctx, reaper.ImGui_Key_Escape()) + + if undo then reaper.Main_OnCommandEx(40029,0,0) end + if redo then reaper.Main_OnCommandEx(40030,0,0) end + + if open and not esc then + if IsOptTgl == true then SetExtStates() end + reaper.defer(loop) + end loopcnt = loopcnt+1 end ----------------- - local fontName - ctx = reaper.ImGui_CreateContext('SimpleProjectReconform_AZ') - if reaper.GetOS():match("^Win") == nil then - reaper.ImGui_SetConfigVar(ctx, reaper.ImGui_ConfigVar_ViewportsNoDecoration(), 0) - fontName = 'sans-serif' - else fontName = 'Calibri' - end loop() --reaper.defer(ShowProgress) @@ -1185,26 +1219,6 @@ function copy(tbl) return result end -------------------------- -------------------------- - -function FieldMatch(Table,value, AddRemoveFlag) -- can remove only first finded value - for i=1, #Table do - if value == Table[i] then - if AddRemoveFlag == false then table.remove(Table,i) end - if AddRemoveFlag ~= nil then - return true, Table - else return true - end - end - end - if AddRemoveFlag == true then table.insert(Table, value) end - if AddRemoveFlag ~= nil then - return false, Table - else return false - end -end - ------------------------- function GetItemsPerTrack(project, timeStart, timeEnd, selTrOnly, selItemsOnly, addMeta) @@ -1375,7 +1389,7 @@ function CreateRefTrack(Items, file, isEDL) --each item = {oldstart, oldend, tar if old_UseAlignPoint == true and AlignOldTime then aOldT = AlignOldTime - PrjTimeOffset end if new_TrimTime == true and AlignNewTime then aNewT = AlignNewTime - PrjTimeOffset end end - + --msg(reaper.format_timestr_pos(AlignOldTime,'',5)..' '..reaper.format_timestr_pos(AlignNewTime,'',5)) file = file[1] local startPoint = OldPrjStart - aNewT if NewPrjStart then startPoint = NewPrjStart - aNewT end @@ -1560,13 +1574,6 @@ function AnalyseEDLs(EDLs, timeRegionStart, timeRegionEnd, userStartPoint) --tab item.DestIn = block.main[1]['Time'][3] item.DestOut = block.main[1]['Time'][4] - if not userStartPoint then - if not CommonEDL.firstItemTime then - CommonEDL.firstItemTime = reaper.parse_timestr_pos( item.DestIn, 5 ) - end - CommonEDL.firstItemTime = math.min(CommonEDL.firstItemTime, reaper.parse_timestr_pos( item.DestIn, 5 ) ) - end - clip.SrcIn = reaper.parse_timestr_pos( clip.SrcIn, 5 ) - PrjTimeOffset clip.SrcOut = reaper.parse_timestr_pos( clip.SrcOut, 5 ) - PrjTimeOffset item.DestIn = reaper.parse_timestr_pos( item.DestIn, 5 ) - PrjTimeOffset @@ -1578,8 +1585,20 @@ function AnalyseEDLs(EDLs, timeRegionStart, timeRegionEnd, userStartPoint) --tab if timeRegionStart ~= timeRegionEnd then if item.DestIn >= timeRegionStart - PrjTimeOffset and item.DestOut <= timeRegionEnd - PrjTimeOffset then table.insert(itemsList, copy(item) ) + + if not CommonEDL.firstItemTime then + CommonEDL.firstItemTime = item.DestIn + end + CommonEDL.firstItemTime = math.min(CommonEDL.firstItemTime, item.DestIn ) + + end + else + table.insert(itemsList, copy(item) ) + + if not CommonEDL.firstItemTime then + CommonEDL.firstItemTime = item.DestIn end - else table.insert(itemsList, copy(item) ) + CommonEDL.firstItemTime = math.min(CommonEDL.firstItemTime, item.DestIn ) end item.Clips = {} @@ -1641,13 +1660,6 @@ function AnalyseEDLs(EDLs, timeRegionStart, timeRegionEnd, userStartPoint) --tab item.DestIn = block.main[i]['Time'][3] item.DestOut = block.main[i]['Time'][4] - if not userStartPoint then - if not CommonEDL.firstItemTime then - CommonEDL.firstItemTime = reaper.parse_timestr_pos( item.DestIn, 5 ) - end - CommonEDL.firstItemTime = math.min(CommonEDL.firstItemTime, reaper.parse_timestr_pos( item.DestIn, 5 ) ) - end - clip.SrcIn = reaper.parse_timestr_pos( clip.SrcIn, 5 ) - PrjTimeOffset clip.SrcOut = reaper.parse_timestr_pos( clip.SrcOut, 5 ) - PrjTimeOffset item.DestIn = reaper.parse_timestr_pos( item.DestIn, 5 ) - PrjTimeOffset @@ -1683,8 +1695,19 @@ function AnalyseEDLs(EDLs, timeRegionStart, timeRegionEnd, userStartPoint) --tab if timeRegionStart ~= timeRegionEnd then if item.DestIn >= timeRegionStart - PrjTimeOffset and item.DestOut <= timeRegionEnd - PrjTimeOffset then table.insert(itemsList, copy(item) ) + + if not CommonEDL.firstItemTime then + CommonEDL.firstItemTime = item.DestIn + end + CommonEDL.firstItemTime = math.min(CommonEDL.firstItemTime, item.DestIn ) end - else table.insert(itemsList, copy(item) ) + else + table.insert(itemsList, copy(item) ) + + if not CommonEDL.firstItemTime then + CommonEDL.firstItemTime = item.DestIn + end + CommonEDL.firstItemTime = math.min(CommonEDL.firstItemTime, item.DestIn ) end item.Clips = {} @@ -1826,7 +1849,17 @@ function AnalyseEDLs(EDLs, timeRegionStart, timeRegionEnd, userStartPoint) --tab end --end of edl files cycle - if userStartPoint then CommonEDL.firstItemTime = userStartPoint end + if CommonEDL.firstItemTime then --compencate offset to return to EDL time scale + CommonEDL.firstItemTime = CommonEDL.firstItemTime + PrjTimeOffset + end + + if userStartPoint then + if timeRegionStart ~= timeRegionEnd + and userStartPoint < timeRegionStart then + --CommonEDL.firstItemTime stays as is + else CommonEDL.firstItemTime = userStartPoint + end + end CleanUpEDL(CommonEDL, Splits) @@ -2508,7 +2541,7 @@ function CreateReportMarkers() reaper.SetMediaItemInfo_Value(splitsItem, 'I_FIXEDLANE', splits) end - local timetxt = reaper.format_timestr_pos(item[1],'', 5) ..' - '.. reaper.format_timestr_pos(item[2],'', 5) + local timetxt = reaper.format_timestr_pos(item[1]+OldPrjStart,'', 5) ..' - '.. reaper.format_timestr_pos(item[2]+OldPrjStart,'', 5) reaper.SetTakeMarker(splitsTake, -1, splcnt..' src '..timetxt..tag, itemPos - NewPrjStart) splcnt = splcnt +1 end @@ -2633,63 +2666,8 @@ function PasteItemsFromPrj(CurPrj, SrcPrj) end ---------------------------- -------------------------- - -function CollectSelectedItems(TableToAdd,areaStart,areaEnd) - local ItemsTable = {} - Gaps = {} - LastRefTrID = 0 - - if type(TableToAdd) == 'table' then - ItemsTable = TableToAdd - end - - if not OldPrjStart then OldPrjStart = 0 end - - local prevEnd = NewPrjStart - local selItNumb = reaper.CountSelectedMediaItems(0) - for i = 0, selItNumb - 1 do - local item = reaper.GetSelectedMediaItem(0,i) - local take = reaper.GetActiveTake(item) - local refPos = reaper.GetMediaItemInfo_Value(item, 'D_POSITION') - local refLength = reaper.GetMediaItemInfo_Value(item, 'D_LENGTH') - - if areaStart and areaEnd then - if refPos > areaEnd or refPos + refLength < areaStart then take = nil end - end - - if take then - local src = reaper.GetMediaItemTake_Source( take ) - local srctype = reaper.GetMediaSourceType( src ) - if srctype ~= 'EMPTY' and srctype ~= 'MIDI' then - local offset = reaper.GetMediaItemTakeInfo_Value(take, 'D_STARTOFFS') + OldPrjStart - table.insert(ItemsTable, {offset, offset + refLength, refPos}) - - local tr = reaper.GetMediaItem_Track(item) - local trID = reaper.GetMediaTrackInfo_Value( tr, 'IP_TRACKNUMBER' ) -1 - - if LastRefTrID < trID then LastRefTrID = trID end - - if prevEnd then - if refPos - prevEnd > MIN_luft_ZERO then - table.insert(Gaps, {prevEnd, refPos}) - end - end - - prevEnd = refPos + refLength - end - end - - end - return ItemsTable -end - ----------------------------- -function round(value, digitsAfterDot) - return tonumber(string.format("%."..digitsAfterDot.."f", tostring(value))) -end ------------------------------ function CleanUpRefItems(Items) local i = #Items @@ -3305,12 +3283,12 @@ end ----------------------------- -function main() +function main(refItems) SetOptGlobals() local editCurPos = reaper.GetCursorPosition() Regions = {} - local refItems = CollectSelectedItems() + if Opt.HealGaps == true or Opt.HealSplits == true then CleanUpRefItems(refItems) end @@ -3319,11 +3297,6 @@ function main() AdjustRefItems(refItems) end - if #refItems == 0 then - reaper.ShowMessageBox('Please select reference items on a track','Simple Project Reconform', 0) - return - end - if Opt.ReconfOnlySel then for t = 0, reaper.CountSelectedTracks(0) - 1 do local tr = reaper.GetSelectedTrack(0,t) @@ -3399,8 +3372,8 @@ function main() for i, item in ipairs(refItems) do --Start reconform cycle - local areaStart = item[1] - local areaEnd = item[2] + local areaStart = item[1] + OldPrjStart + local areaEnd = item[2] + OldPrjStart local refPos = item[3] if TimeSigCount > 1 then diff --git a/Various/az_Simple project reconform/az_Common reconform functions.lua b/Various/az_Simple project reconform/az_Common reconform functions.lua new file mode 100644 index 000000000..8f4920b59 --- /dev/null +++ b/Various/az_Simple project reconform/az_Common reconform functions.lua @@ -0,0 +1,235 @@ +-- @noindex + + +ExtStateName = "SimpleReconform_AZ" + +-------------------------- +function rgbToHex(rgba) -- passing a table with percentage like {100, 50, 20, 90} + local hexadecimal = '0X' + + for key, value in pairs(rgba) do + local hex = '' + if value > 100 or value < 0 then return error('Color must be a percantage value\n between 0 and 100') end + value = (255/100)*value + while (value > 0) do + local index = math.floor(math.fmod(value, 16) + 1) + value = math.floor(value / 16) + hex = string.sub('0123456789ABCDEF', index, index) .. hex + end + + if (string.len(hex) == 0) then + hex = '00' + + elseif (string.len(hex) == 1) then + hex = '0' .. hex + end + + hexadecimal = hexadecimal .. hex + end + + return hexadecimal +end + +---------------------------------- + +function SetGUIcolors() + local gui_colors = { + White = rgbToHex({90,90,90,100}), + Green = rgbToHex({52,85,52,100}), + Red = rgbToHex({80,30,30,100}), + Blue = rgbToHex({30,60,80,100}), + TitleBg = rgbToHex({30,20,30,100}), + Background = rgbToHex({11,14,14,95}), + Text = rgbToHex({92,92,81.5,100}), + activeText = rgbToHex({50,95,80,100}), + ComboBox = { + Default = rgbToHex({20,25,30,100}), + Hovered = rgbToHex({35,40,45,80}), + Active = rgbToHex({42,42,37,100}), + }, + Button = { + Default = rgbToHex({25,30,30,100}), + Hovered = rgbToHex({35,40,45,100}), + Active = rgbToHex({42,42,37,100}), + }, + MainButton = { + Default = rgbToHex({25,50,40,80}), + Hovered = rgbToHex({35,60,55,80}), + Active = rgbToHex({56,56,42,90}), + } + } + + return gui_colors +end + +--------------------- + +function SetGUIflags() + local Flags = {} + Flags.childRounding = reaper.ImGui_StyleVar_ChildRounding() + Flags.frameRounding = reaper.ImGui_StyleVar_FrameRounding() + Flags.childBorder = reaper.ImGui_ChildFlags_Borders() + Flags.menubar = reaper.ImGui_WindowFlags_MenuBar() + Flags.tableResizeflag = reaper.ImGui_TableFlags_Resizable() + Flags.childAutoResizeX = reaper.ImGui_ChildFlags_AutoResizeX() + Flags.childAutoResizeY = reaper.ImGui_ChildFlags_AutoResizeY() + return Flags +end + +-------------------- + +function PUSHstyle(ctx, gui_colors, Flags, fontSize) + local colorCnt, styleCnt + reaper.ImGui_PushStyleColor(ctx, reaper.ImGui_Col_WindowBg(), gui_colors.Background) + reaper.ImGui_PushStyleColor(ctx, reaper.ImGui_Col_TitleBgActive(), gui_colors.TitleBg) + reaper.ImGui_PushStyleColor(ctx, reaper.ImGui_Col_Text(), gui_colors.Text) + + reaper.ImGui_PushStyleColor(ctx, reaper.ImGui_Col_Button(), gui_colors.Button.Default) + reaper.ImGui_PushStyleColor(ctx, reaper.ImGui_Col_ButtonHovered(), gui_colors.Button.Hovered) + reaper.ImGui_PushStyleColor(ctx, reaper.ImGui_Col_ButtonActive(), gui_colors.Button.Active) + reaper.ImGui_PushStyleColor(ctx, reaper.ImGui_Col_CheckMark(), gui_colors.Green) + + --Combo box and check box background + reaper.ImGui_PushStyleColor(ctx, reaper.ImGui_Col_FrameBg(), gui_colors.ComboBox.Default) + reaper.ImGui_PushStyleColor(ctx, reaper.ImGui_Col_FrameBgHovered(), gui_colors.ComboBox.Hovered) + reaper.ImGui_PushStyleColor(ctx, reaper.ImGui_Col_FrameBgActive(), gui_colors.ComboBox.Active) + --Combo box drop down list + reaper.ImGui_PushStyleColor(ctx, reaper.ImGui_Col_Header(), gui_colors.ComboBox.Default) + reaper.ImGui_PushStyleColor(ctx, reaper.ImGui_Col_HeaderHovered(), gui_colors.ComboBox.Hovered) + reaper.ImGui_PushStyleColor(ctx, reaper.ImGui_Col_HeaderActive(), gui_colors.ComboBox.Active) + + reaper.ImGui_PushStyleColor(ctx, reaper.ImGui_Col_Text(), gui_colors.White) + + colorCnt = 13 + -- + reaper.ImGui_PushStyleVar(ctx, reaper.ImGui_StyleVar_WindowRounding(), fontSize/4) + reaper.ImGui_PushStyleVar(ctx, Flags.frameRounding, fontSize/4) + reaper.ImGui_PushStyleVar(ctx, Flags.childRounding, fontSize/4) + reaper.ImGui_PushStyleVar(ctx, reaper.ImGui_StyleVar_FramePadding(), fontSize/2, fontSize/4) + styleCnt = 4 + + return colorCnt, styleCnt +end + +------------------ + +function serializeTable(tbl) + return "return " .. tableToString(tbl) +end + +-------- + +function tableToString(tbl, indent) + indent = indent or 0 + local result = "{\n" + local prefix = string.rep(" ", indent + 1) + + for k, v in pairs(tbl) do + local key + if type(k) == "string" then + key = string.format("[%q]", k) + else + key = string.format("[%s]", tostring(k)) + end + + if type(v) == "table" then + result = result .. prefix .. key .. " = " .. tableToString(v, indent + 1) .. ",\n" + elseif type(v) == "string" then + result = result .. prefix .. key .. " = " .. string.format("%q", v) .. ",\n" + else + result = result .. prefix .. key .. " = " .. tostring(v) .. ",\n" + end + end + + result = result .. string.rep(" ", indent) .. "}" + return result +end + +----------------------------- + +function round(value, digitsAfterDot) + return tonumber(string.format("%."..digitsAfterDot.."f", tostring(value))) +end + +------------------------- + +function CollectSelectedItems(TableToAdd,areaStart,areaEnd) + local ItemsTable = {} + Gaps = {} + LastRefTrID = 0 + + if type(TableToAdd) == 'table' then + ItemsTable = TableToAdd + end + + if not OldPrjStart then OldPrjStart = 0 end + + local prevEnd = NewPrjStart + local selItNumb = reaper.CountSelectedMediaItems(0) + for i = 0, selItNumb - 1 do + local item = reaper.GetSelectedMediaItem(0,i) + local take = reaper.GetActiveTake(item) + local refPos = reaper.GetMediaItemInfo_Value(item, 'D_POSITION') + local refLength = reaper.GetMediaItemInfo_Value(item, 'D_LENGTH') + + if areaStart and areaEnd then + if refPos > areaEnd or refPos + refLength < areaStart then take = nil end + end + + if take then + local src = reaper.GetMediaItemTake_Source( take ) + local srctype = reaper.GetMediaSourceType( src ) + if srctype ~= 'EMPTY' and srctype ~= 'MIDI' then + local offset = reaper.GetMediaItemTakeInfo_Value(take, 'D_STARTOFFS') + table.insert(ItemsTable, {round(offset,4), round(offset + refLength, 4), round(refPos,4)}) + + local tr = reaper.GetMediaItem_Track(item) + local trID = reaper.GetMediaTrackInfo_Value( tr, 'IP_TRACKNUMBER' ) -1 + + if LastRefTrID < trID then LastRefTrID = trID end + + if prevEnd then + if refPos - prevEnd > MIN_luft_ZERO then + table.insert(Gaps, {round(prevEnd,4), round(refPos,4)}) + end + end + + prevEnd = refPos + refLength + end + end + + end + + reaper.SetProjExtState(0,ExtStateName, 'OldPrjStart', OldPrjStart ) + if #ItemsTable ~= 0 then + reaper.SetProjExtState(0,ExtStateName, 'RefTrack', serializeTable(ItemsTable) ) + end + + return ItemsTable +end + +------------------------- + +function FieldMatch(Table,value, AddRemoveFlag) -- can remove only first finded value + for i=1, #Table do + if value == Table[i] then + if AddRemoveFlag == false then table.remove(Table,i) end + if AddRemoveFlag ~= nil then + return true, Table + else return true + end + end + end + if AddRemoveFlag == true then table.insert(Table, value) end + if AddRemoveFlag ~= nil then + return false, Table + else return false + end +end + +------------------------- + +function GetMinLuftZero(PrjTimeOffset) + return ( reaper.parse_timestr_pos('00:00:00:01', 5) - PrjTimeOffset ) / 4 +end +---------------------- diff --git a/Various/az_Simple project reconform/az_Comparison assistant for az_Simple project reconform.lua b/Various/az_Simple project reconform/az_Comparison assistant for az_Simple project reconform.lua new file mode 100644 index 000000000..d41bc79c0 --- /dev/null +++ b/Various/az_Simple project reconform/az_Comparison assistant for az_Simple project reconform.lua @@ -0,0 +1,435 @@ +-- @noindex + +----------------------------- +function msg(value) + reaper.ShowConsoleMsg(tostring(value)..'\n') +end + +-------------------------- + +function get_script_path() + local info = debug.getinfo(1,'S'); + local script_path = info.source:match[[^@?(.*[\/])[^\/]-$]] + --script_path = script_path:gsub('[^/\\]*[/\\]*$','') --one level up + return script_path +end + +------------------------ + +local script_path = get_script_path() +local commonFile = script_path..'az_Common reconform functions.lua' +dofile(commonFile) + +------------------------ + +function GetOldRefTime(prjTime, refTable) + if not refTable or #refTable == 0 then return 'No ref track' end + + local retval + local matches = {} + + for i, v in ipairs(refTable) do + local origIn = v[1] + local origOut = v[2] + local target = v[3] + + if prjTime >= target and prjTime-0.001 <= target + (origOut - origIn) then + retval = origIn + (prjTime - target) + OldPrjStart + table.insert(matches, retval) + end + + end + + if #matches == 0 then retval = 'GAP' end + if #matches > 1 then retval = matches[2] end + + return retval +end + +------------------------ + +function GetPrevNextRefTime(prjTime, refTable) -- return min, max + if not refTable or #refTable == 0 then return end + prjTime = round(prjTime, 4) + local min, max + local prevMax + local flatList={} + if NewPrjStart then table.insert(flatList, NewPrjStart) end + + for i, v in ipairs(refTable) do + local posIn = v[3] + local posOut = posIn + (v[2] - v[1]) + FieldMatch(flatList, posIn, true) + FieldMatch(flatList, round(posOut, 4), true) + end + + table.sort(flatList) + for i, v in ipairs(flatList) do + if prjTime == v then + min = flatList[i - 1] + max = flatList[i + 1] + return min, max + elseif prjTime < v and (not flatList[i - 1] or round(prjTime - flatList[i - 1], 4) > 0)then + min = flatList[i - 1] + max = v + return min, max + elseif prjTime > v and ( not flatList[i + 1] or round(prjTime - flatList[i + 1], 4) < 0 ) then + min = v + max = flatList[i + 1] + return min, max + end + end + +end + +----------------------- + +local function ScriptWindow() + if not reaper.APIExists('SNM_SetIntConfigVar') then + reaper.ShowMessageBox('Please, install SWS extension!', 'No SWS extention', 0) + return + end + + local imgui_path = reaper.GetResourcePath() .. '/Scripts/ReaTeam Extensions/API/imgui.lua' + if not reaper.file_exists(imgui_path) then + reaper.ShowMessageBox('Please, install ReaImGui from Reapack!', 'No Imgui library', 0) + return + end + dofile(imgui_path) '0.10' + local fontSize = 16 + local ctx, fontName, OScoeff, font, fontSep, fontBig + local H = fontSize + local W = fontSize + local loopcnt = 0 + local esc + local settingsOpen = false + local btnGetRefText + local refTrack, prevProj + + local newEditTimeShow, oldEditTimeShow + local newEditTime, oldEditTime, oldFixedTime + + local refTrackString = '' + + local savedFontSize = tonumber(reaper.GetExtState(ExtStateName, 'AssistantFontSize')) + if type(savedFontSize) == 'number' then fontSize = savedFontSize end + if not savedFontSize then savedFontSize = fontSize end + + local gui_colors = SetGUIcolors() + local Flags = SetGUIflags() + + ctx = reaper.ImGui_CreateContext('ComparisonAssistantForSPR_AZ') + if reaper.GetOS():match("^Win") == nil then + reaper.ImGui_SetConfigVar(ctx, reaper.ImGui_ConfigVar_ViewportsNoDecoration(), 0) + fontName, OScoeff = 'sans-serif', 1.08 + else fontName, OScoeff = 'Calibri', 1 + end + + -------------- + + function frame() + + local childALLflags = Flags.childAutoResizeY | Flags.childAutoResizeX + local ChildALL = reaper.ImGui_BeginChild(ctx, 'ChildALL', 0, 0, childALLflags) + + if ChildALL then + + reaper.ImGui_PushFont(ctx, font, fontSize) + + if type(refTrack) ~= 'table' then + reaper.ImGui_Text(ctx, 'There is no saved reference track in project!') + btnGetRefText = 'Get selected items as reference' + else btnGetRefText = 'Update reference track' --msg(#refTrack) + end + + ---Settings section--- + reaper.ImGui_PushFont(ctx, fontSep, fontSize-2) + if reaper.ImGui_Button(ctx, 'Settings' ) then + settingsOpen = not settingsOpen + end + reaper.ImGui_PopFont(ctx) + + if settingsOpen then + reaper.ImGui_SameLine(ctx, nil, fontSize*4) + if reaper.ImGui_Button(ctx, btnGetRefText ) then + refTrack = CollectSelectedItems() + if #refTrack == 0 then refTrack = nil end + end + + local childflags = Flags.childAutoResizeY | Flags.childAutoResizeX | Flags.childBorder + local ChildSettings = reaper.ImGui_BeginChild(ctx, 'Settings', 0, 0, childflags) + + if ChildSettings then + --Input box + button + reaper.ImGui_PushItemWidth(ctx, fontSize * 6 * OScoeff ) + + local fieldState, retOldPrjOffsetTime = + reaper.ImGui_InputText(ctx, 'Old project position', reaper.format_timestr_pos( OldPrjStart, '', 5 ), nil, nil) + if fieldState == true then + OldPrjStart = reaper.parse_timestr_pos( retOldPrjOffsetTime, 5 ) + reaper.SetProjExtState(0,ExtStateName, 'OldPrjStart', OldPrjStart ) + end + reaper.ImGui_SameLine(ctx, fontSize*17, nil) + reaper.ImGui_PushID(ctx, 1) + if reaper.ImGui_Button(ctx, 'Get edit cursor', nil, nil ) then + OldPrjStart = reaper.GetCursorPosition() + reaper.SetProjExtState(0,ExtStateName, 'OldPrjStart', OldPrjStart ) + end + reaper.ImGui_PopID(ctx) + --------------- + + --Input box + button + local fieldState, retNewPrjOffsetTime = + reaper.ImGui_InputText(ctx, 'New project position', reaper.format_timestr_pos( NewPrjStart, '', 5 ), nil, nil) + + if fieldState == true then + NewPrjStart = reaper.parse_timestr_pos( retNewPrjOffsetTime, 5 ) + end + + reaper.ImGui_SameLine(ctx, fontSize*17, nil) + reaper.ImGui_PushID(ctx, 2) + local btnState = reaper.ImGui_Button(ctx, 'Get edit cursor', nil, nil ) + if btnState then + NewPrjStart = reaper.GetCursorPosition() + end + reaper.ImGui_PopID(ctx) + + if btnState or fieldState then + if NewPrjStart and NewPrjStart <= OldPrjStart then + reaper.ShowMessageBox('Reconformed project must be placed next to the old version.\nLet it be +1 hour after the old verion.','Warning!', 0) + NewPrjStart = OldPrjStart + 3600 + end + reaper.SetProjExtState(0, ExtStateName, 'NewPrjStart', NewPrjStart ) + end + ------------- + + reaper.ImGui_NewLine(ctx) + reaper.ImGui_PushItemWidth(ctx, savedFontSize * 5.5 * OScoeff) + _, savedFontSize = reaper.ImGui_InputInt + (ctx, 'Font size for the window (default is 16)', savedFontSize) + + reaper.ImGui_EndChild(ctx) + end + end + -----End of Settings section---- + + if not settingsOpen then reaper.ImGui_SameLine(ctx, fontSize*6 ) end + reaper.ImGui_Text(ctx, 'Ref navigation') + + reaper.ImGui_SameLine(ctx, fontSize*13.5 ) + if reaper.ImGui_Button(ctx, '<', fontSize*2.5) and not Teleported then + reaper.JS_Window_SetFocus(reaper.GetMainHwnd()) + local min, max = GetPrevNextRefTime(newEditTime + NewPrjStart - PrjTimeOffset, refTrack) + if min then --msg(min..' '..NewPrjStart..' '..PrjTimeOffset) + reaper.SetEditCurPos2(0, min, true, false) + end + end + + reaper.ImGui_SameLine(ctx, nil, fontSize) + if reaper.ImGui_Button(ctx, '> ', fontSize*2.5) and not Teleported then + reaper.JS_Window_SetFocus(reaper.GetMainHwnd()) + local min, max = GetPrevNextRefTime(newEditTime + NewPrjStart - PrjTimeOffset, refTrack) + if max then --msg(max..' '..NewPrjStart..' '..PrjTimeOffset) + reaper.SetEditCurPos2(0, max, true, false) + end + end + + local childTimeflags = Flags.childAutoResizeY | Flags.childAutoResizeX + local ChildTime = reaper.ImGui_BeginChild(ctx, 'ChildTime', 0, 0, childTimeflags) + + if ChildTime then + local gotoOldText = 'Go to Old edit position:' + local gotoNewText = 'New edit position:' + + if not Teleported then + newEditTime = reaper.GetCursorPosition() - NewPrjStart + PrjTimeOffset + newEditTimeShow = reaper.format_timestr_pos(newEditTime, '', 5) + + oldEditTime = GetOldRefTime(newEditTime, refTrack) + if type(oldEditTime) ~= 'number' then + oldEditTimeShow = oldEditTime + else oldEditTimeShow = reaper.format_timestr_pos(oldEditTime, '', 5) + end + else + gotoOldText = 'Old edit position:' + gotoNewText = 'Back to New edit position:' + oldEditTime = reaper.GetCursorPosition() - OldPrjStart + PrjTimeOffset + oldEditTimeShow = reaper.format_timestr_pos(oldEditTime, '', 5) + end + + reaper.ImGui_Text(ctx, gotoNewText) + + reaper.ImGui_SameLine(ctx, fontSize*11.5 ) + reaper.ImGui_PushFont(ctx, fontBig, fontSize+4) + if Teleported then + reaper.ImGui_PushStyleColor(ctx, reaper.ImGui_Col_Text(), gui_colors.Red) + else + reaper.ImGui_PushStyleColor(ctx, reaper.ImGui_Col_Text(), gui_colors.Green) + end + reaper.ImGui_PushID(ctx, 3) + if reaper.ImGui_Button(ctx, newEditTimeShow, fontSize*8 ) then + reaper.JS_Window_SetFocus(reaper.GetMainHwnd()) + if Teleported then + local _, pos = reaper.GetProjExtState(0,ExtStateName, 'SavedPosition') + if pos ~='' then + reaper.SetEditCurPos2(0, tonumber(pos), true, false) + Teleported = false + end + end + end + reaper.ImGui_PopID(ctx) + reaper.ImGui_PopStyleColor(ctx, 1) + reaper.ImGui_PopFont(ctx) + --------- + + reaper.ImGui_Text(ctx, gotoOldText) + + reaper.ImGui_SameLine(ctx, fontSize*11.5 ) + reaper.ImGui_PushFont(ctx, fontBig, fontSize+4) + reaper.ImGui_PushStyleColor(ctx, reaper.ImGui_Col_Text(), gui_colors.White) + reaper.ImGui_PushID(ctx, 4) + if reaper.ImGui_Button(ctx, oldEditTimeShow, fontSize*8 ) then + reaper.JS_Window_SetFocus(reaper.GetMainHwnd()) + if not Teleported and type(oldEditTime) == 'number' then + oldFixedTime = oldEditTime - OldPrjStart + PrjTimeOffset + reaper.SetEditCurPos2(0, oldEditTime, true, false) + reaper.SetProjExtState(0,ExtStateName, 'SavedPosition', newEditTime) + Teleported = true + end + end + reaper.ImGui_PopID(ctx) + reaper.ImGui_PopStyleColor(ctx, 1) + reaper.ImGui_PopFont(ctx) + + reaper.ImGui_EndChild(ctx) + end + + ---------------- + reaper.ImGui_SameLine(ctx) + local childDOPflags = Flags.childAutoResizeY | Flags.childAutoResizeX + local ChildDOP = reaper.ImGui_BeginChild(ctx, 'ChildDOP', 0, 0, childALLflags) + + + if ChildDOP then + reaper.ImGui_PushFont(ctx, font, fontSize) + + if reaper.ImGui_Button(ctx, ' Back\nwith drift' ) then + reaper.JS_Window_SetFocus(reaper.GetMainHwnd()) + if Teleported then + local _, pos = reaper.GetProjExtState(0,ExtStateName, 'SavedPosition') + if pos ~='' then + reaper.SetEditCurPos2(0, tonumber(pos) + (oldEditTime-oldFixedTime), true, false) + Teleported = false + end + end + end + + reaper.ImGui_PopFont(ctx) + reaper.ImGui_EndChild(ctx) + end + + reaper.ImGui_PopFont(ctx) + + reaper.ImGui_EndChild(ctx) + end + + end + + -------------- + function loop() + local curProj, projfn = reaper.EnumProjects( -1 ) + + if not refTrack or curProj ~= prevProj then + _, refTrackString = reaper.GetProjExtState(curProj, ExtStateName, 'RefTrack') + local f = load(refTrackString) + refTrack = f() + end + + if loopcnt == 0 and type(refTrack) ~= 'table' then + settingsOpen = true + end + + --if loopcnt == 0 then msg(refTrackString)end + if not OldPrjStart or curProj ~= prevProj then + _, OldPrjStart = reaper.GetProjExtState(0, ExtStateName, 'OldPrjStart') + end + if OldPrjStart == '' then OldPrjStart = 0 + else OldPrjStart = tonumber(OldPrjStart) + end + + if not NewPrjStart or curProj ~= prevProj then + _, NewPrjStart = reaper.GetProjExtState(0, ExtStateName, 'NewPrjStart') + end + + if NewPrjStart == '' then NewPrjStart = 3600 + else NewPrjStart = tonumber(NewPrjStart) + end + if not NewPrjStart then NewPrjStart = 3600 end + + prevProj = curProj + + PrjTimeOffset = -reaper.GetProjectTimeOffset( 0, false ) + + MIN_luft_ZERO = GetMinLuftZero(PrjTimeOffset) + + if not font or savedFontSize ~= fontSize then + if savedFontSize < 7 then savedFontSize = 7 end + if savedFontSize > 60 then savedFontSize = 60 end + reaper.SetExtState(ExtStateName, 'AssistantFontSize', savedFontSize, true) + fontSize = savedFontSize + if font then reaper.ImGui_Detach(ctx, font) end + if fontSep then reaper.ImGui_Detach(ctx, fontSep) end + font = reaper.ImGui_CreateFont(fontName, reaper.ImGui_FontFlags_None()) -- Create the fonts you need + fontSep = reaper.ImGui_CreateFont(fontName, reaper.ImGui_FontFlags_Italic()) + fontBig = reaper.ImGui_CreateFont(fontName, reaper.ImGui_FontFlags_None()) + reaper.ImGui_Attach(ctx, font) + reaper.ImGui_Attach(ctx, fontSep) + reaper.ImGui_Attach(ctx, fontBig) + end + + esc = reaper.ImGui_IsKeyPressed(ctx, reaper.ImGui_Key_Escape()) + + undo = reaper.ImGui_Shortcut(ctx, reaper.ImGui_Mod_Ctrl() | reaper.ImGui_Key_Z(), reaper.ImGui_InputFlags_RouteGlobal()) + + redo = reaper.ImGui_Shortcut(ctx, reaper.ImGui_Mod_Ctrl() | reaper.ImGui_Mod_Shift() | reaper.ImGui_Key_Z(), reaper.ImGui_InputFlags_RouteGlobal()) + + reaper.ImGui_PushFont(ctx, font, fontSize) + + local colorCnt, styleCnt = PUSHstyle(ctx, gui_colors, Flags, fontSize) + + local window_flags = reaper.ImGui_WindowFlags_None()--reaper.ImGui_WindowFlags_MenuBar() + reaper.ImGui_SetNextWindowSize(ctx, W, H, reaper.ImGui_Cond_Once()) -- Set the size of the windows. Use in the 4th argument reaper.ImGui_Cond_FirstUseEver() to just apply at the first user run, so ImGUI remembers user resize s2 + + local visible, open = reaper.ImGui_Begin(ctx, 'Comparison assistant for reconform', true, window_flags) + reaper.ImGui_PopStyleColor(ctx, 1) + + if visible then + frame() + reaper.ImGui_SetWindowSize(ctx, 0, 0, nil ) + reaper.ImGui_End(ctx) + end + + reaper.ImGui_PopStyleColor(ctx, colorCnt) + reaper.ImGui_PopStyleVar(ctx, styleCnt) + reaper.ImGui_PopFont(ctx) + + esc = reaper.ImGui_IsKeyReleased(ctx, reaper.ImGui_Key_Escape()) + + if undo then reaper.Main_OnCommandEx(40029,0,0) end + if redo then reaper.Main_OnCommandEx(40030,0,0) end + + if open and not esc then + if IsOptTgl == true then SetExtStates() end + if runReconf == true then main() end + reaper.defer(loop) + end + + loopcnt = loopcnt+1 + end + ----------------- + + loop() +end +--------------------------- + +ScriptWindow()