-- Version History: --================== -- Version 2.1 (by Lukas Krepel, Frame Order) -- Updated for future Moho versions -- *** TODO/WIP *** -- Version 2.0 (by Lukas Krepel, Frame Order) -- Revamped most of the script, consolidated a lot in FO_Channels utility. -- Version 1.3.4 (by Lukas Krepel, Frame Order) -- Removed Reset button, because Moho already has a reset function for tools -- Tick! -- Version 1.3.3 (by Lukas Krepel, Frame Order) -- Simplified description -- Tick! -- Version 1.3.2 (by Lukas Krepel, Frame Order) -- Moho 13.5 support -- Tick! -- Vitruvion bones channels -- Tick! -- Added Wind channels -- Tick! -- Added Wind Checkbox -- Tick! -- Modified shortcuts to match other tools -- Tick! -- Fixed some toolbar icons -- Tick! -- Support for userscripts MohoMode.lua and LK_PaintKeys.lua (not required) -- Tick! -- Version 1.3.1 (by Lukas Krepel, Frame Order) -- Support for channels split dimensions (not for individual bones) (thanks to synthsyn75) -- Tick! -- Version 1.3 (by Lukas Krepel, Frame Order) -- Added all channels up to Moho 12 -- Tick! -- New icons that support the new color schemes and higher resolutions -- Tick! -- Reformatted the toolbar layout to be more user friendly -- Tick ! -- Added shortcuts to tool description -- Tick! -- Disable 'selected points/bones/shapes' buttons if 'points/bones/shapes' buttons are off. -- Tick! -- Hopefully I haven't destroyed any functionality... -- Tick! -- Version 1.2 -- Fixed for AS version 7 -- Tick! -- Used built-in layer visibilty check instead of hack -- Tick! -- Used layer:Mesh() instead of having to activate each layer -- Tick! -- Allowed keys to be deleted using shift count without shifting -- Tick! -- Restricted shifting to above frame 1 instead of frame 0 -- Tick! -- Include negative timeline layer keys in consolidated timeline -- Tick! -- Added support for specifying a list of actions to nudge as well as main timeline -- Tick! -- Fixed bug where detected keys in one channel may overrided detected keys in another -- Tick! -- Fixed bug where not all keys of sequencer-shifted layer would be displayed in consolidated timeline -- Tick! -- Version 1.0 -- Moved rt_utilities functions to their own table instead of using MOHO -- Tick! -- Created this script to roll all of the nudge tools into one -- Tick! -- Now preserving key parameters for interpolation modes that have them (applies to ver 6.0 only) -- Tick! -- Now taking into account timing offset from sequencer (applies to ver 6.0 only) -- Tick! -- Added some missing animation channels: -- BoneDynamics channel -- Tick! -- Effect transform channels (ver 6.0 only) -- Tick! -- Shadow and shading noise channels (ver 6.0 only) -- Tick! -- Audio layer channels (ver 6.1 only) -- Tick! -- Shape effect channel (Still not available in ver 6.1) -- Point curvature channel (ver 6.1 only) -- Tick! -- Added options for omitting certain channels -- Tick! -- Added options for only affecting selected objects -- Tick! -- Added option for only affecting selected layers (ver 6.0 only) -- NB Selected layers only updated when rt_consolidated_layers is run -- Added option for only affecting visible layers -- Tick! -- Added option to specify nudge count -- Tick! -- Added option to only nudge keys on current frame -- Tick! -- Added option to enable or disable camera channels -- Tick! -- Added option to not move cursor -- Tick! -- Version 0.1 -- Initial Release -- ************************************************** -- Provide Moho with the name of this script object -- ************************************************** ScriptName = "LK_NudgeKeys" -- ************************************************** -- General information about this script -- ************************************************** LK_NudgeKeys = {} function LK_NudgeKeys:ColorizeIcon() return true end function LK_NudgeKeys:Name() return "Nudge Keys Toolset" end function LK_NudgeKeys:Version() return "2.0" end -- * Map shortcut keys to keyboard keys LK_NudgeKeys.shortcutPrevKey = ',' LK_NudgeKeys.shortcutNextKey = '.' LK_NudgeKeys.shortcutNudgeKeysLeft = '-' LK_NudgeKeys.shortcutNudgeKeysRight = '=' LK_NudgeKeys.shortcutGlobalNudgeKeysLeft = '<' LK_NudgeKeys.shortcutGlobalNudgeKeysRight = '>' LK_NudgeKeys.ShortcutConsolidatedTimeline = 'i' LK_NudgeKeys.onlyNudgeDocumentChannelsOnGlobalNudges = true function LK_NudgeKeys:Description() return "Tool for interactively manipulating keys. (<"..self.shortcutPrevKey.."/"..self.shortcutNextKey.."> Go to previous/next keyframe, <"..self.shortcutNudgeKeysLeft.."/"..self.shortcutNudgeKeysRight.."> Nudge keys left/right, <"..self.shortcutGlobalNudgeKeysLeft.."/"..self.shortcutGlobalNudgeKeysRight.."> Global nudge keys left/right, <"..self.ShortcutConsolidatedTimeline.."> Create consolidated timeline markers)." end function LK_NudgeKeys:Creator() return "Lukas Krepel, Frame Order (Original tool by Rudiger)" end function LK_NudgeKeys:UILabel() return "Nudge Keys Toolset" end function LK_NudgeKeys:IsRelevant() if MohoMode ~= nil then if not (MohoMode.keys or MohoMode.raymond) then return false end end return true end function LK_NudgeKeys:LoadPrefs(prefs) self.onlyNudgeDocumentChannelsOnGlobalNudges = prefs:GetBool("LK_NudgeKeys.onlyNudgeDocumentChannelsOnGlobalNudges", true) -- * Channels: FO_Channels:LoadPrefs(prefs) -- * TODO TODO TODO CLEAN THIS UP self.allow_key_deletion = prefs:GetBool("LK_NudgeKeys.allow_key_deletion", false) self.overwrite_mode = prefs:GetBool("LK_NudgeKeys.overwrite_mode", false) self.nudge_count = prefs:GetInt("LK_NudgeKeys.nudge_count", 1) self.current_frame_only = prefs:GetBool("LK_NudgeKeys.current_frame_only", false) self.global_move_cursor = prefs:GetBool("LK_NudgeKeys.global_move_cursor", true) self.move_cursor = prefs:GetBool("LK_NudgeKeys.move_cursor", true) self.global_move_endFrame = prefs:GetBool("LK_NudgeKeys.global_move_endFrame", true) self.move_endFrame = prefs:GetBool("LK_NudgeKeys.move_endFrame", false) end function LK_NudgeKeys:SavePrefs(prefs) prefs:SetBool("LK_NudgeKeys.onlyNudgeDocumentChannelsOnGlobalNudges", self.onlyNudgeDocumentChannelsOnGlobalNudges) -- * Channels: FO_Channels:SavePrefs(prefs) -- * TODO TODO TODO CLEAN UP prefs:SetBool("LK_NudgeKeys.allow_key_deletion", self.allow_key_deletion) prefs:SetBool("LK_NudgeKeys.overwrite_mode", self.overwrite_mode) prefs:SetInt("LK_NudgeKeys.nudge_count", self.nudge_count) prefs:SetBool("LK_NudgeKeys.current_frame_only", self.current_frame_only) prefs:SetBool("LK_NudgeKeys.global_move_cursor", self.global_move_cursor) prefs:SetBool("LK_NudgeKeys.move_cursor", self.move_cursor) prefs:SetBool("LK_NudgeKeys.global_move_endFrame", self.global_move_endFrame) prefs:SetBool("LK_NudgeKeys.move_endFrame", self.move_endFrame) end function LK_NudgeKeys:ResetPrefs() LK_NudgeKeys.onlyNudgeDocumentChannelsOnGlobalNudges = true -- * Channels: FO_Channels:ResetPrefs() -- * self.allow_key_deletion = false -- * Set to allow existing keys to be deleted with backspace self.overwrite_mode = false -- * Set option for overwriting frames self.nudge_count = 1 self.current_frame_only = false self.global_move_cursor = true self.move_cursor = true self.global_move_endFrame = true self.move_endFrame = false end LK_NudgeKeys.MARK_CONSOLIDATED_TIMELINE_GLOBAL = MOHO.MSG_BASE LK_NudgeKeys.MARK_CONSOLIDATED_TIMELINE = MOHO.MSG_BASE + 21--* LK_NudgeKeys.CLEAR_CONSOLIDATED_TIMELINE_GLOBAL = MOHO.MSG_BASE + 22--* LK_NudgeKeys.CLEAR_CONSOLIDATED_TIMELINE = MOHO.MSG_BASE + 1 LK_NudgeKeys.PREV_KEY_FRAME = MOHO.MSG_BASE + 2 LK_NudgeKeys.NEXT_KEY_FRAME = MOHO.MSG_BASE + 3 LK_NudgeKeys.NUDGE_KEYS_LEFT = MOHO.MSG_BASE + 4 LK_NudgeKeys.NUDGE_KEYS_RIGHT = MOHO.MSG_BASE + 5 LK_NudgeKeys.GLOBAL_NUDGE_KEYS_LEFT = MOHO.MSG_BASE + 6 LK_NudgeKeys.GLOBAL_NUDGE_KEYS_RIGHT = MOHO.MSG_BASE + 7 LK_NudgeKeys.TOGGLE_OVERWRITE_MODE = MOHO.MSG_BASE + 8 LK_NudgeKeys.NUDGE_COUNT = MOHO.MSG_BASE + 9 LK_NudgeKeys.TOGGLE_CURRENT_FRAME_ONLY = MOHO.MSG_BASE + 10 LK_NudgeKeys.UPDATE_FLAGS = MOHO.MSG_BASE + 11 LK_NudgeKeys.ALLOW_KEYDELETION = MOHO.MSG_BASE + 12 LK_NudgeKeys.TOGGLE_MOVE_CURSOR = MOHO.MSG_BASE + 13 LK_NudgeKeys.TOGGLE_GLOBAL_MOVE_CURSOR = MOHO.MSG_BASE + 14 LK_NudgeKeys.TOGGLE_MOVE_ENDFRAME = MOHO.MSG_BASE + 15 LK_NudgeKeys.TOGGLE_GLOBAL_MOVE_ENDFRAME = MOHO.MSG_BASE + 16 LK_NudgeKeys.FILTER_LAYER_EXPRESSION = MOHO.MSG_BASE + 17 LK_NudgeKeys.ACTIONS_LIST = MOHO.MSG_BASE + 18 LK_NudgeKeys.INTERP_MODE = MOHO.MSG_BASE + 19 LK_NudgeKeys.TOGGLE_GLOBAL = MOHO.MSG_BASE + 20 LK_NudgeKeys.TOGGLE_CHANNELS = MOHO.MSG_BASE + 100 -- * 100 t/m 115 -- ************************************************** -- KeyTool Advanced Options Pop-up Dialog -- ************************************************** local LK_NudgeKeysDialog = {} function LK_NudgeKeysDialog:new() local d = LM.GUI.SimpleDialog("KeyTool Advanced Options", LK_NudgeKeysDialog) local l = d:GetLayout() -- ***************** -- *** Channels: *** -- ***************** FO_Utilities:DialogDivider(l, "Channels", true) -- * d.onlyNudgeDocumentChannelsOnGlobalNudgesCheckbox = LM.GUI.CheckBox("Only nudge Document-Channels on Global-Nudges", LK_NudgeKeys.TOGGLE_GLOBAL) l:AddChild(d.onlyNudgeDocumentChannelsOnGlobalNudgesCheckbox, LM.GUI.ALIGN_LEFT) -- ***************** -- *** Keys: *** -- ***************** FO_Utilities:DialogDivider(l, "Keys", false) -- * d.overwriteModeCheckbox = LM.GUI.CheckBox("Allow Key Overwriting", LK_NudgeKeys.TOGGLE_OVERWRITE_MODE) l:AddChild(d.overwriteModeCheckbox, LM.GUI.ALIGN_LEFT) -- * d.allowKeyDeletionCheckbox = LM.GUI.CheckBox("Allow Key Deletion", LK_NudgeKeys.ALLOW_KEYDELETION) l:AddChild(d.allowKeyDeletionCheckbox, LM.GUI.ALIGN_LEFT) -- ***************** -- *** Include: *** -- ***************** FO_Utilities:DialogDivider(l, "Include", false) -- * l:PushH() l:PushV() l:AddChild(LM.GUI.StaticText("Timeline-Cursor:"), LM.GUI.ALIGN_LEFT) l:AddChild(LM.GUI.StaticText("Endframe:"), LM.GUI.ALIGN_LEFT) l:Pop() l:PushV() d.globalMoveCursorCheckbox = LM.GUI.CheckBox("Global", LK_NudgeKeys.TOGGLE_GLOBAL_MOVE_CURSOR) l:AddChild(d.globalMoveCursorCheckbox, LM.GUI.ALIGN_LEFT) d.globalMoveEndframeCheckbox = LM.GUI.CheckBox("Global", LK_NudgeKeys.TOGGLE_GLOBAL_MOVE_ENDFRAME) l:AddChild(d.globalMoveEndframeCheckbox, LM.GUI.ALIGN_LEFT) l:Pop() l:PushV() d.moveCursorCheckbox = LM.GUI.CheckBox("Normal", LK_NudgeKeys.TOGGLE_MOVE_CURSOR) l:AddChild(d.moveCursorCheckbox, LM.GUI.ALIGN_LEFT) d.moveEndframeCheckbox = LM.GUI.CheckBox("Normal", LK_NudgeKeys.TOGGLE_MOVE_ENDFRAME) l:AddChild(d.moveEndframeCheckbox, LM.GUI.ALIGN_LEFT) l:Pop() l:Pop() return d end function LK_NudgeKeysDialog:UpdateWidgets() self.onlyNudgeDocumentChannelsOnGlobalNudgesCheckbox:SetValue(LK_NudgeKeys.onlyNudgeDocumentChannelsOnGlobalNudges) self.overwriteModeCheckbox:SetValue(LK_NudgeKeys.overwrite_mode) self.allowKeyDeletionCheckbox:SetValue(LK_NudgeKeys.allow_key_deletion) self.globalMoveCursorCheckbox:SetValue(LK_NudgeKeys.global_move_cursor) self.moveCursorCheckbox:SetValue(LK_NudgeKeys.move_cursor) self.globalMoveEndframeCheckbox:SetValue(LK_NudgeKeys.global_move_endFrame) self.moveEndframeCheckbox:SetValue(LK_NudgeKeys.move_endFrame) end function LK_NudgeKeysDialog:OnValidate() -- * end function LK_NudgeKeysDialog:OnOK() LK_NudgeKeys.onlyNudgeDocumentChannelsOnGlobalNudges = self.onlyNudgeDocumentChannelsOnGlobalNudgesCheckbox:Value() LK_NudgeKeys.overwrite_mode = self.overwriteModeCheckbox:Value() LK_NudgeKeys.allow_key_deletion = self.allowKeyDeletionCheckbox:Value() LK_NudgeKeys.global_move_cursor = self.globalMoveCursorCheckbox:Value() LK_NudgeKeys.move_cursor = self.moveCursorCheckbox:Value() LK_NudgeKeys.global_move_endFrame = self.globalMoveEndframeCheckbox:Value() LK_NudgeKeys.move_endFrame = self.moveEndframeCheckbox:Value() end function LK_NudgeKeysDialog:HandleMessage(msg) -- * end -- **************************************************************************** function LK_NudgeKeys:OnMouseDown(moho, mouseEvent) mouseEvent.view:DrawMe() end function LK_NudgeKeys:DrawMe(moho, view) -- FO_Utilities:DrawMeTinyUI(moho) end function LK_NudgeKeys:OnKeyDown(moho, keyEvent) -- * Shortcut Key Mapping: if keyEvent.key == self.shortcutPrevKey then LK_NudgeKeys:HandleMessage(moho, view, self.PREV_KEY_FRAME) elseif keyEvent.key == self.shortcutNextKey then LK_NudgeKeys:HandleMessage(moho, view, self.NEXT_KEY_FRAME) elseif keyEvent.key == self.shortcutNudgeKeysLeft then LK_NudgeKeys:HandleMessage(moho, view, self.NUDGE_KEYS_LEFT) elseif keyEvent.key == self.shortcutNudgeKeysRight then LK_NudgeKeys:HandleMessage(moho, view, self.NUDGE_KEYS_RIGHT) elseif keyEvent.key == self.shortcutGlobalNudgeKeysLeft then LK_NudgeKeys:HandleMessage(moho, view, self.GLOBAL_NUDGE_KEYS_LEFT) elseif keyEvent.key == self.shortcutGlobalNudgeKeysRight then LK_NudgeKeys:HandleMessage(moho, view, self.GLOBAL_NUDGE_KEYS_RIGHT) elseif keyEvent.key == self.ShortcutConsolidatedTimeline then LK_NudgeKeys:HandleMessage(moho, view, self.MARK_CONSOLIDATED_TIMELINE_GLOBAL) end end function LK_NudgeKeys:DoLayout(moho, layout) FO_Utilities.tinyUI = false -- * Consolidate Button: layout:PushH(LM.GUI.ALIGN_CENTER, 1) self.createConsolidatedTimelineButton = LM.GUI.Button("Mark Timeline", self.MARK_CONSOLIDATED_TIMELINE_GLOBAL) self.createConsolidatedTimelineButton:SetAlternateMessage(self.MARK_CONSOLIDATED_TIMELINE) self.createConsolidatedTimelineButton:SetToolTip("Create Consolidated Timeline as Document-wide Markers (" .. LK_NudgeKeys.ShortcutConsolidatedTimeline .. ") (Hold <alt> for local layer only)") layout:AddChild(self.createConsolidatedTimelineButton) self.removeConsolidatedTimelineButton = LM.GUI.ImageButton("ScriptResources/FO_icons/trashcan", "Clear Consolidated Timeline (Hold <alt> for local layer only)", false, self.CLEAR_CONSOLIDATED_TIMELINE_GLOBAL, true) self.removeConsolidatedTimelineButton:SetAlternateMessage(self.CLEAR_CONSOLIDATED_TIMELINE) layout:AddChild(self.removeConsolidatedTimelineButton) layout:Pop() -- ***************** -- *** Navigate: *** -- ***************** FO_Utilities:Divider(layout, "Navigate") layout:PushH(LM.GUI.ALIGN_CENTER, 2) -- * Prev key button: self.prevKeyFrameButton = LM.GUI.ImageButton("ScriptResources/FO_icons/go_to_previous_keyframe", "Prev Keyframe ("..self.shortcutPrevKey..")", false, self.PREV_KEY_FRAME, true) layout:AddChild(self.prevKeyFrameButton) -- * Next key button: self.nextKeyFrameButton = LM.GUI.ImageButton("ScriptResources/FO_icons/go_to_next_keyframe", "Next Keyframe ("..self.shortcutNextKey..")", false, self.NEXT_KEY_FRAME, true) layout:AddChild(self.nextKeyFrameButton) layout:Pop() -- ************** -- *** Nudge: *** -- ************** FO_Utilities:Divider(layout, "Nudge") layout:PushH(LM.GUI.ALIGN_CENTER, 2) -- * Nudge Left: self.nudgeKeysLeftButton = LM.GUI.ImageButton("ScriptResources/FO_icons/nudge_keys_left_button", "Nudge Keys Left ("..self.shortcutNudgeKeysLeft..") (Nudges current layer)", false, self.NUDGE_KEYS_LEFT, true) layout:AddChild(self.nudgeKeysLeftButton) -- * Nudge Right: self.nudgeKeysRightButton = LM.GUI.ImageButton("ScriptResources/FO_icons/nudge_keys_right_button", "Nudge Keys Right ("..self.shortcutNudgeKeysRight..") (Nudges current layer)", false, self.NUDGE_KEYS_RIGHT, true) layout:AddChild(self.nudgeKeysRightButton) -- * Global Nudge Left: self.globalNudgeKeysLeftButton = LM.GUI.ImageButton("ScriptResources/FO_icons/nudge_global_keys_left_button", "Global Nudge Keys Left ("..self.shortcutGlobalNudgeKeysLeft..") (Nudges all root layers)", false, self.GLOBAL_NUDGE_KEYS_LEFT, true) layout:AddChild(self.globalNudgeKeysLeftButton) -- * Global Nudge Right: self.globalNudgeKeysRightButton = LM.GUI.ImageButton("ScriptResources/FO_icons/nudge_global_keys_right_button", "Global Nudge Keys Right ("..self.shortcutGlobalNudgeKeysRight..") (Nudges all root layers)", false, self.GLOBAL_NUDGE_KEYS_RIGHT, true) layout:AddChild(self.globalNudgeKeysRightButton) layout:Pop() -- *************** -- *** Amount: *** -- *************** FO_Utilities:Divider(layout, "Amount") self.nudgeCountTextbox = LM.GUI.TextControl(0, "000", self.NUDGE_COUNT, LM.GUI.FIELD_INT) layout:AddChild(self.nudgeCountTextbox) -- * Toggle Current Frame Only Button: self.currentFrameOnlyCheckbox = LM.GUI.ImageButton("ScriptResources/FO_icons/nudge_current_frame_only", "Current Frame Only", true, self.TOGGLE_CURRENT_FRAME_ONLY, true) layout:AddChild(self.currentFrameOnlyCheckbox) -- ***************** -- *** Channels: *** -- ***************** FO_Channels:DoLayout(moho, layout, self.TOGGLE_CHANNELS) -- * Advanced Dropdown: self.dlog = LK_NudgeKeysDialog:new() self.popup = LM.GUI.PopupDialog("Advanced") self.popup:SetDialog(self.dlog) layout:AddChild(self.popup) end function LK_NudgeKeys:UpdateWidgets(moho) -- * Channels: FO_Channels:UpdateWidgets(moho) -- * self.nudgeCountTextbox:SetValue(LK_NudgeKeys.nudge_count) self.currentFrameOnlyCheckbox:SetValue(LK_NudgeKeys.current_frame_only) -- self:FilterByMarker(moho) end function LK_NudgeKeys:HandleMessage(moho, view, msg) -- * Channels: FO_Channels:HandleMessage(moho, view, msg, self.TOGGLE_LAYER_CHANNELS) -- * if (msg == self.PREV_KEY_FRAME) then FO_Channels:GoToPrevNextKeyFrame(moho, true) elseif (msg == self.NEXT_KEY_FRAME) then FO_Channels:GoToPrevNextKeyFrame(moho, false) elseif (msg == self.NUDGE_KEYS_LEFT) then local right = false local global = false LK_NudgeKeys:RunShift(moho, right, global) elseif (msg == self.NUDGE_KEYS_RIGHT) then local right = true local global = false LK_NudgeKeys:RunShift(moho, right, global) elseif (msg == self.GLOBAL_NUDGE_KEYS_LEFT) then local right = false local global = true LK_NudgeKeys:RunShift(moho, right, global) elseif (msg == self.GLOBAL_NUDGE_KEYS_RIGHT) then local right = true local global = true LK_NudgeKeys:RunShift(moho, right, global) elseif (msg == self.NUDGE_COUNT) then LK_NudgeKeys.nudge_count = self.nudgeCountTextbox:IntValue() elseif (msg == self.TOGGLE_CURRENT_FRAME_ONLY) then LK_NudgeKeys.current_frame_only = self.currentFrameOnlyCheckbox:Value() elseif (msg == self.MARK_CONSOLIDATED_TIMELINE) then self:ConsolidateTimelineAsDocMarkers(moho, false) elseif (msg == self.MARK_CONSOLIDATED_TIMELINE_GLOBAL) then self:ConsolidateTimelineAsDocMarkers(moho, true) elseif (msg == self.CLEAR_CONSOLIDATED_TIMELINE) then self:ClearConsolidatedTimelineDocMakers(moho, false) elseif (msg == self.CLEAR_CONSOLIDATED_TIMELINE_GLOBAL) then self:ClearConsolidatedTimelineDocMakers(moho, true) end -- * Color Keys: FO_Utilities:PaintKeys(moho) -- * Update User Interface: moho:UpdateUI() end function LK_NudgeKeys:SetConsolidatedMarkers(moho, layer, global) -- * Merge all timelines related to layer and put them on points layer -- * Consolidated channel is built up 1 layer at a time to save time local consolidatedChannel = moho.document.fTimelineMarkers if not global then consolidatedChannel = moho.layer.fTimelineMarkers end local timing_offset = 0 if layer.TotalTimingOffset ~= nil then timing_offset = layer:TotalTimingOffset() end local channels = {} FO_Channels:AddLayerChannels(moho, layer, channels) for i = 1, #channels do local channel = channels[i] local duration = channel:Duration()-timing_offset -- * Make it start at -timing_offset to speed things up, but means negative layer frames won't show up -- * Would really like a layer:StartFrame() method for frame = -timing_offset, duration do if channel:HasKey(frame+timing_offset) then if consolidatedChannel:HasKey(frame) then local markerInterp = MOHO.InterpSetting:new_local() consolidatedChannel:GetKeyInterp(frame, markerInterp) if markerInterp.tags == 7 then -- * 7 = Tan local markerVal = consolidatedChannel:GetValue(frame) local layerName = layer:Name() -- * if string.match(layerName, " %(") then layerName = string.sub(layerName, 0, string.find(layerName, " %(")-1) end -- * if not string.match(markerVal, layerName) then markerVal = markerVal.." | "..layerName consolidatedChannel:SetValue(frame, markerVal) end end -- elseif not consolidatedChannel:HasKey(frame) then if frame ~= 0 then -- * Add Marker: consolidatedChannel:SetValue(frame, layer:Name()) local markerInterp = MOHO.InterpSetting:new_local() markerInterp.tags = 7 -- * 7 = Tan consolidatedChannel:SetKeyInterp(frame, markerInterp) end end end end end end function LK_NudgeKeys:ConsolidateTimelineAsDocMarkers(moho, global) moho.document:SetDirty() moho.document:PrepUndo("", moho.layer, false) FO_Channels:BruteOffsetFix(moho) self:ClearConsolidatedTimelineDocMakers(moho, global) local layers = FO_Channels:PreferredLayers(moho, global) -- local layers = {} -- -- * -- if global then -- for i = 0, moho.document:CountLayers()-1 do -- local rootLayer = moho.document:Layer(i) -- FO_Channels:AddLayerWithChildren(moho, rootLayer, layers) -- end -- else -- FO_Channels:AddLayerWithChildren(moho, moho.layer, layers) -- end -- * for i = 1, #layers do self:SetConsolidatedMarkers(moho, layers[i], global) end moho:UpdateUI() -- * Update current frame moho.view:DrawMe() end function LK_NudgeKeys:ClearConsolidatedTimelineDocMakers(moho, global) moho.document:SetDirty() moho.document:PrepUndo("", moho.layer, false) -- * todo begrijpen of dit voldoende is of multi moet? weet ik veel -- * local consolidatedChannel = moho.document.fTimelineMarkers if not global then consolidatedChannel = moho.layer.fTimelineMarkers end duration = consolidatedChannel:Duration() for frame = 0, duration do if consolidatedChannel:HasKey(frame) then local markerInterp = MOHO.InterpSetting:new_local() consolidatedChannel:GetKeyInterp(frame, markerInterp) if markerInterp.tags == 7 then -- * 7 = Tan consolidatedChannel:DeleteKey(frame) end end end end function LK_NudgeKeys:ChannelShift(current_frame, channel, count, forceAll) -- * Shift all channel keys after and including current frame by count value: local frame local val1 = 0 local val2 = 0 local duration local startFrame local endFrame local incr local right_shift if count > 0 then right_shift = true else right_shift = false end -- * Delete frames within count range of cursor: if not right_shift or self.current_frame_only or self.overwrite_mode then if right_shift then if self.overwrite_mode then startFrame = current_frame else startFrame = current_frame+1 end endFrame = current_frame+count incr = 1 else if self.overwrite_mode then startFrame = current_frame else startFrame = current_frame-1 end endFrame = current_frame+count incr = -1 end if self.allow_key_deletion then for frame = startFrame+incr, endFrame, incr do if channel:HasKey(frame) then channel:DeleteKey(frame) end end end end -- * if self.current_frame_only and not forceAll then duration = current_frame else duration = channel:Duration() end -- * if right_shift then -- * We need to start at the last keyframe so we don't overwrite keys startFrame = duration endFrame = current_frame incr = -1 else startFrame = current_frame endFrame = duration incr = 1 end -- * Interface doesn't currently allow keys to be moved -- * so have to create new keys and delete the old ones for frame = startFrame, endFrame, incr do if channel:HasKey(frame) then channel:AddKey(frame + count) local interp_mode = MOHO.InterpSetting:new_local() channel:GetKeyInterp(frame, interp_mode) channel:SetValue(frame + count, channel:GetValue(frame)) channel:SetKeyInterp(frame + count, interp_mode) channel:DeleteKey(frame) end end end function LK_NudgeKeys:LayerShift(current_frame, moho, count, layer, forceAll) -- * Shift all keys in layer and its sub layers local layers = {} FO_Channels:AddLayerWithChildren(moho, layer, layers) for i = 1, #layers do local layer = layers[i] -- * Loop through channels for current layer: local channels = {} channels = FO_Channels:AddLayerChannels(moho, layer, channels, forceAll) for i = 1, #channels do self:ChannelShift(current_frame, channels[i], count, forceAll) end end end function LK_NudgeKeys:GlobalLayerShift(current_frame, moho, count) -- * Shift all keys for all root layers in document for i = 0, moho.document:CountLayers()-1 do self:LayerShift(current_frame, moho, count, moho.document:Layer(i)) end end -- ************************************************** -- Nudge! -- ************************************************** function LK_NudgeKeys:RunShift(moho, right, global) -- * Prepundo: moho.document:PrepUndo(moho.layer, true) moho.document:SetDirty() local layer = moho.layer local frame = moho.frame local actual_nudge_count = self.nudge_count local endFrame -- * Don't run on frame 0! if frame == 0 then return end -- * Don't nudge past frame 1! if not right then endFrame = frame - actual_nudge_count if endFrame < 1 then actual_nudge_count = frame - 1 --why? end else endFrame = frame + actual_nudge_count end -- * if not self.overwrite_mode then if not right or self.current_frame_only then actual_nudge_count = self:LimitNudgeCount(moho, frame, endFrame, global) end end -- * if actual_nudge_count < 1 then return end -- * if not right then actual_nudge_count = -1*actual_nudge_count end -- * if global then self:GlobalLayerShift(frame, moho, actual_nudge_count) else self:LayerShift(frame, moho, actual_nudge_count, layer) end -- * Also move cursor with frames if (global and self.global_move_cursor) or (not global and self.move_cursor) then if right or frame > -1*actual_nudge_count-1 then local newFrame = frame + actual_nudge_count moho:SetCurFrame(newFrame) end end -- * Also move end duration local endFrame = moho.document:EndFrame() if (global and self.global_move_endFrame) or (not global and self.move_endFrame) then moho.document:SetEndFrame(math.max(1, endFrame+actual_nudge_count)) end -- * Also shift global channels (Only for Main timeline) if moho.layer:CurrentAction() == "" then if global or not LK_NudgeKeys.onlyNudgeDocumentChannelsOnGlobalNudges then local channels = {} FO_Channels:AddGlobalChannels(moho, channels) for i, channel in ipairs(channels) do self:ChannelShift(frame, channel, actual_nudge_count, 0) end end end -- * Update user interface moho:UpdateUI() MOHO.Redraw() end -- ************************************************** -- Limit Nudge Count, because we don't want to overwrite any existing keys. -- ************************************************** function LK_NudgeKeys:LimitNudgeCount(moho, startFrame, endFrame, global) local nudge_count = math.abs(endFrame - startFrame) local channels = {} local layers = FO_Channels:PreferredLayers(moho) for i = 1, #layers do FO_Channels:AddLayerChannels(moho, layers[i], channels) end if global or not LK_NudgeKeys.onlyNudgeDocumentChannelsOnGlobalNudges then FO_Channels:AddGlobalChannels(moho, channels) end if startFrame < endFrame then startFrame = startFrame + 1 else startFrame = startFrame - 1 end local foundKey = FO_Channels:FindKey(moho, channels, startFrame, endFrame) if foundKey then moho:Click() -- * Make a clicking sound if we're nudging less than the user wants. local actual_nudge_count = math.min(math.abs(startFrame - foundKey), nudge_count) return actual_nudge_count else return nudge_count end end function LK_NudgeKeys:FilterByMarker(moho) local doFilter = false local channel = moho.document.fTimelineMarkers local keyCount = channel:CountKeys() - 1 local keysFound = 0 local endKey = channel:Duration() local frameNum = endKey while keysFound < keyCount do thisKey = channel:GetClosestKeyID(frameNum) local keyFrameNum = channel:GetKeyWhen(thisKey) keysFound = 1 + keysFound local interp = MOHO.InterpSetting:new_local() channel:GetKeyInterp(keyFrameNum, interp) if interp.tags == 7 then -- * 7 = Tan doFilter = true break end frameNum = keyFrameNum - 1 end local keyVal = nil if doFilter then if channel:HasKey(moho.frame) then local interp = MOHO.InterpSetting:new_local() channel:GetKeyInterp(moho.frame, interp) if interp.tags == 7 then -- * 7 = Tan keyVal = channel:GetValue(moho.frame) end end if keyVal ~= nil then moho:LayersWindowSetSearchContext(1) -- 1 = LAYERWND_SEARCHCONTEXT_NAMECONTAINS moho:LayersWindowSetSearchContextValue(keyVal) end end if keyVal == nil then moho:LayersWindowSetSearchContext(0) -- 0 = LAYERWND_SEARCHCONTEXT_ALL moho:LayersWindowSetSearchContextValue("") moho:ShowLayerInLayersPalette(moho.layer) end end
Nudge Keys
Listed
Author: Lukas
View Script
Script type: Tool
Uploaded: May 22 2023, 08:59
Last modified: Sep 05 2023, 12:56
Script Version: 2.0
Nudge Keys Toolset
My version of Rudiger's Nudge Keys Toolset
- It kind of assumes you're not using the sequencer.
- There's an issue with bezier curves?
This script, and all other scripts on this site are distributed as free software under the GNU General Public License 3.0 or later.
Downloads count: 1083
Nudge Keys
Listed
Author: Lukas
View Script
Script type: Tool
Uploaded: May 22 2023, 08:59
Last modified: Sep 05 2023, 12:56
Script Version: 2.0
Nudge Keys Toolset
My version of Rudiger's Nudge Keys Toolset
- It kind of assumes you're not using the sequencer.
- There's an issue with bezier curves?
- It kind of assumes you're not using the sequencer.
- There's an issue with bezier curves?
This script, and all other scripts on this site are distributed as free software under the GNU General Public License 3.0 or later.
Downloads count: 1083