-- ************************************************** -- Provide Moho with the name of this script object -- ************************************************** ScriptName = "LK_TimelineNavigator" -- ************************************************** -- General information about this script -- ************************************************** LK_TimelineNavigator = {} function LK_TimelineNavigator:Name() return "Timeline Navigator" end function LK_TimelineNavigator:Version() return "2.3" end function LK_TimelineNavigator:UILabel() return "Timeline Navigator" end function LK_TimelineNavigator:Creator() return "Lukas Krepel, Frame Order - Original by Stan" end function LK_TimelineNavigator:Description() return "Move the timeline cursor by specified amount of frames or time intervals and jump to document markers. Press <"..self.previousMarkerShortcut.."/"..self.nextMarkerShortcut.."> to jump to previous/next marker." end function LK_TimelineNavigator:ColorizeIcon() return true end -- ************************************************** -- Is Relevant / Is Enabled -- ************************************************** function LK_TimelineNavigator:IsRelevant(moho) if MohoMode ~= nil then if not MohoMode.keys then return false end end return true end function LK_TimelineNavigator:IsEnabled(moho) return true end -- ************************************************** -- Keyboard/Mouse Control -- ************************************************** function LK_TimelineNavigator:OnMouseDown(moho, mouseEvent) if Syn_ScrubWorkspace ~= nil then Syn_ScrubWorkspace:OnMouseDown(moho, mouseEvent) end end function LK_TimelineNavigator:OnMouseMoved(moho, mouseEvent) if Syn_ScrubWorkspace ~= nil then Syn_ScrubWorkspace:OnMouseMoved(moho, mouseEvent) end end function LK_TimelineNavigator:OnMouseUp(moho, mouseEvent) if Syn_ScrubWorkspace ~= nil then Syn_ScrubWorkspace:OnMouseUp(moho, mouseEvent) end end function LK_TimelineNavigator:OnKeyDown(moho, keyEvent) if keyEvent.key == self.nextMarkerShortcut then self:GoToNextmarker(moho, false) end if keyEvent.key == self.previousMarkerShortcut then self:GoToNextmarker(moho, true) end end -- ************************************************** -- Recurring Values -- ************************************************** LK_TimelineNavigator.frames = 1 LK_TimelineNavigator.seconds = 1 LK_TimelineNavigator.timeMinutes = 0 LK_TimelineNavigator.timeSeconds = 0 LK_TimelineNavigator.timeFrames = 0 LK_TimelineNavigator.previousMarkerShortcut = "," LK_TimelineNavigator.nextMarkerShortcut = "." LK_TimelineNavigator.markerLevelOptions = { "Document", "Layer" } -- * TODO: Both / Parent / Any layer ? -- ************************************************** -- Tool options - create and respond to tool's UI -- ************************************************** LK_TimelineNavigator.FRAMES_BACK = MOHO.MSG_BASE LK_TimelineNavigator.FRAMES_INPUT = MOHO.MSG_BASE + 1 LK_TimelineNavigator.FRAMES_FORWARD = MOHO.MSG_BASE + 2 LK_TimelineNavigator.SECONDS_BACK = MOHO.MSG_BASE + 3 LK_TimelineNavigator.SECONDS_INPUT = MOHO.MSG_BASE + 4 LK_TimelineNavigator.SECONDS_FORWARD = MOHO.MSG_BASE + 5 LK_TimelineNavigator.TIME_MINUTES_INPUT = MOHO.MSG_BASE + 6 LK_TimelineNavigator.TIME_SECONDS_INPUT = MOHO.MSG_BASE + 7 LK_TimelineNavigator.TIME_FRAMES_INPUT = MOHO.MSG_BASE + 8 LK_TimelineNavigator.TIME_GO = MOHO.MSG_BASE + 9 LK_TimelineNavigator.GO_TO_FRAME_ZERO = MOHO.MSG_BASE + 10 LK_TimelineNavigator.PREV_MARKER = MOHO.MSG_BASE + 13 LK_TimelineNavigator.NEXT_MARKER = MOHO.MSG_BASE + 14 LK_TimelineNavigator.GO_TO_DOCUMENT_START = MOHO.MSG_BASE + 15 LK_TimelineNavigator.GO_TO_DOCUMENT_END = MOHO.MSG_BASE + 16 LK_TimelineNavigator.SET_MARKER_LEVEL = MOHO.MSG_BASE + 17 -- * 17 to 30 LK_TimelineNavigator.GO_TO_MARKER = MOHO.MSG_BASE + 30 -- * 30 to x function LK_TimelineNavigator:LoadPrefs(prefs) self.markerLevel = prefs:GetString("LK_TimelineNavigator.markerLevel", self.markerLevelOptions[1]) self.frames = prefs:GetInt("LK_TimelineNavigator.frames", 1) self.seconds = prefs:GetInt("LK_TimelineNavigator.seconds", 1) self.timeMinutes = prefs:GetInt("LK_TimelineNavigator.timeMinutes", 0) self.timeSeconds = prefs:GetInt("LK_TimelineNavigator.timeSeconds", 0) self.timeFrames = prefs:GetInt("LK_TimelineNavigator.timeFrames", 0) end function LK_TimelineNavigator:SavePrefs(prefs) prefs:SetString("LK_TimelineNavigator.markerLevel", self.markerLevel) prefs:SetInt("LK_TimelineNavigator.frames", self.frames) prefs:SetInt("LK_TimelineNavigator.seconds", self.seconds) prefs:SetInt("LK_TimelineNavigator.timeMinutes", self.timeMinutes) prefs:SetInt("LK_TimelineNavigator.timeSeconds", self.timeSeconds) prefs:SetInt("LK_TimelineNavigator.timeFrames", self.timeFrames) end function LK_TimelineNavigator:ResetPrefs(prefs) self.markerLevel = self.markerLevelOptions[1] self.frames = 1 self.seconds = 1 self.timeMinutes = 0 self.timeSeconds = 0 self.timeFrames = 0 end -- ************************************************** -- Tool Panel Layout -- ************************************************** function LK_TimelineNavigator:DoLayout(moho, layout) self.markerChannel = moho.layer.fTimelineMarkers -- *** Move x amount of frames left/right: FO_Utilities:Divider(layout, "Move frame(s)", true) layout:AddPadding(-15) self.framesInput = LM.GUI.TextControl(48, '1', self.FRAMES_INPUT, LM.GUI.FIELD_UINT) layout:AddChild(self.framesInput) layout:AddPadding(-15) self.framesBackButton = LM.GUI.ImageButton("ScriptResources/FO_icons/arrow_left", "Back", false, self.FRAMES_BACK, true) layout:AddChild(self.framesBackButton) self.framesForwardButton = LM.GUI.ImageButton("ScriptResources/FO_icons/arrow_right", "Forward", false, self.FRAMES_FORWARD, true) layout:AddChild(self.framesForwardButton) -- *** Move x amount of seconds left/right: FO_Utilities:Divider(layout, "Move second(s)") layout:AddPadding(-15) self.secondsInput = LM.GUI.TextControl(48, '1', self.SECONDS_INPUT, LM.GUI.FIELD_UFLOAT) layout:AddChild(self.secondsInput) layout:AddPadding(-15) self.secondsBackButton = LM.GUI.ImageButton("ScriptResources/FO_icons/arrow_left", "Back", false, self.SECONDS_BACK, true) layout:AddChild(self.secondsBackButton) self.secondsForwardButton = LM.GUI.ImageButton("ScriptResources/FO_icons/arrow_right", "Forward", false, self.SECONDS_FORWARD, true) layout:AddChild(self.secondsForwardButton) -- *** Go to specified timecode or frame: FO_Utilities:Divider(layout, "Go to (MM:SS:FF)") self.timeMinutesInput = LM.GUI.TextControl(28, '0', self.TIME_MINUTES_INPUT, LM.GUI.FIELD_UINT) layout:AddChild(self.timeMinutesInput) layout:AddPadding(-15) layout:AddChild(LM.GUI.StaticText(':')) layout:AddPadding(-19) self.timeSecondsInput = LM.GUI.TextControl(28, '0', self.TIME_SECONDS_INPUT, LM.GUI.FIELD_UINT) layout:AddChild(self.timeSecondsInput) layout:AddPadding(-15) layout:AddChild(LM.GUI.StaticText(':')) layout:AddPadding(-19) self.timeFramesInput = LM.GUI.TextControl(28, '0', self.TIME_FRAMES_INPUT, LM.GUI.FIELD_UINT) layout:AddChild(self.timeFramesInput) layout:AddPadding(-15) self.goButton = LM.GUI.ImageButton("ScriptResources/FO_icons/Set", "Go", false, self.TIME_GO, true) layout:AddChild(self.goButton) -- ******************************* -- *** Go to Markers: *** -- ******************************* FO_Utilities:Divider(layout, "Go to Markers") -- *** Level Dropdown: -- * Level Dropdown: if self.markerLevel == "" then -- * Prefs bugfix self.markerLevel = self.markerLevelOptions[1] end self.levelPopup = LM.GUI.PopupMenu(75, false) layout:AddChild(self.levelPopup) layout:AddPadding(-14) -- * Marker Dropdown: self.markerPopup = LM.GUI.PopupMenu(200, false) layout:AddChild(self.markerPopup) -- * Previous/Next Marker: self.prevMarkerButton = LM.GUI.ImageButton("ScriptResources/FO_icons/timeline_marker_prev", "Back", false, self.PREV_MARKER, true) layout:AddChild(self.prevMarkerButton) layout:AddPadding(-14) self.nextMarkerButton = LM.GUI.ImageButton("ScriptResources/FO_icons/timeline_marker_next", "Forward", false, self.NEXT_MARKER, true) layout:AddChild(self.nextMarkerButton) end function LK_TimelineNavigator:UpdateWidgets(moho) if moho:IsPlaying() then return end FO_Utilities.tinyUI = false self.framesInput:SetValue(self.frames) self.secondsInput:SetValue(self.seconds) self.timeMinutesInput:SetValue(self.timeMinutes) self.timeSecondsInput:SetValue(self.timeSeconds) self.timeFramesInput:SetValue(self.timeFrames) if self.markerLevel == "Document" then self.markerChannel = moho.document.fTimelineMarkers else self.markerChannel = moho.layer.fTimelineMarkers end -- *** Marker Dropdown: local markerChannel = self.markerChannel local markerLabel = "" if moho.frame == 0 then markerLabel = " - Zero" elseif moho.frame == moho.document:StartFrame() then markerLabel = " - Start" elseif moho.frame == moho.document:EndFrame() then markerLabel = " - End" elseif markerChannel:HasKey(moho.frame) then markerLabel = markerChannel:GetValue(moho.frame) markerLabel = string.gsub(markerLabel, "\n", " ") markerLabel = " - "..markerLabel if markerChannel:GetValue(moho.frame) == "" then local markerInterp = MOHO.InterpSetting:new_local() markerChannel:GetKeyInterp(moho.frame, markerInterp) markerLabel = " - "..FO_Utilities.colorNames[markerInterp.tags] end end local menuLabel = string.format("%d", moho.frame)..markerLabel self.markerMenu = LM.GUI.Menu(menuLabel) -- *** Dropdown items: -- * Zero: self.markerMenu:AddItem("0 - Zero", 0, self.GO_TO_FRAME_ZERO) -- * Start: local startFrame = moho.document:StartFrame().." - Start" self.markerMenu:AddItem(startFrame, 0, self.GO_TO_DOCUMENT_START) self.markerMenu:AddItem("---", 0, 0) -- * Markers: local markers = {} for i = 1, markerChannel:CountKeys()-1 do local markerFrame = markerChannel:GetKeyWhen(i) markerFrame = string.format("%d", markerFrame) -- Remove .0 from 1.0 local markerLabel = markerChannel:GetValueByID(i) markerLabel = string.gsub(markerLabel, "\n", " ") if markerLabel == "" then local markerInterp = MOHO.InterpSetting:new_local() markerChannel:GetKeyInterp(markerChannel:GetKeyWhen(i), markerInterp) markerLabel = FO_Utilities.colorNames[markerInterp.tags] end local marker = markerFrame.." - "..markerLabel table.insert(markers, marker) end local i for i = 1, #markers do local file = markers[i] self.markerMenu:AddItem((tostring(markers[i])), 0, (self.GO_TO_MARKER + i)) end if #markers ~= 0 then self.markerMenu:AddItem("---", 0, 0) end -- * End: local endFrame = moho.document:EndFrame().." - End" self.markerMenu:AddItem(endFrame, 0, self.GO_TO_DOCUMENT_END) -- *** Checks: self.markerMenu:SetChecked(self.GO_TO_DOCUMENT_START, moho.document:StartFrame() == moho.frame) for i = 1, markerChannel:CountKeys()-1 do local markerFrame = markerChannel:GetKeyWhen(i) self.markerMenu:SetChecked(self.GO_TO_MARKER + i, moho.frame == markerFrame) end self.markerMenu:SetChecked(self.GO_TO_DOCUMENT_END, moho.document:EndFrame() == moho.frame) -- * Set menu to dropdown: self.markerPopup:SetMenu(self.markerMenu) self.markerPopup:Redraw() -- * Level Menu: self.levelMenu = LM.GUI.Menu(self.markerLevel) for i = 1, #self.markerLevelOptions do local option = self.markerLevelOptions[i] self.levelMenu:AddItem(option, 0, self.SET_MARKER_LEVEL+i) self.levelMenu:SetChecked(self.SET_MARKER_LEVEL+i, self.markerLevel == option) end self.levelPopup:SetMenu(self.levelMenu) self.levelPopup:Redraw() end function LK_TimelineNavigator:HandleMessage(moho, view, msg) local curFrame = moho.frame local fps = moho.document:Fps() self.frames = self.framesInput:IntValue() self.seconds = self.secondsInput:FloatValue() self.timeMinutes = self.timeMinutesInput:IntValue() self.timeSeconds = LM.Clamp(self.timeSecondsInput:IntValue(), 0, 59) self.timeFrames = self.timeFramesInput:IntValue() if msg == self.GO_TO_FRAME_ZERO then moho:SetCurFrame(0) elseif msg == self.GO_TO_DOCUMENT_START then moho:SetCurFrame(moho.document:StartFrame()) elseif msg == self.GO_TO_DOCUMENT_END then moho:SetCurFrame(moho.document:EndFrame()) elseif msg >= self.GO_TO_MARKER then local option = msg - self.GO_TO_MARKER moho:SetCurFrame(self.markerChannel:GetKeyWhen(option)) elseif msg == self.PREV_LAYER_MARKER then self:GoToNextLayerMarker(moho, true) elseif msg == self.NEXT_LAYER_MARKER then self:GoToNextLayerMarker(moho, false) elseif msg == self.PREV_MARKER then self:GoToNextmarker(moho, true) elseif msg == self.NEXT_MARKER then self:GoToNextmarker(moho, false) elseif msg == self.FRAMES_BACK then local newFrame = curFrame - self.frames if newFrame < 0 then newFrame = 0 end moho:SetCurFrame(newFrame) elseif msg == self.FRAMES_FORWARD then moho:SetCurFrame(curFrame + self.frames) elseif msg == self.SECONDS_BACK then local frames = self.seconds * fps local newFrame = curFrame - math.floor(frames) if newFrame < 0 then newFrame = 0 end moho:SetCurFrame(newFrame) elseif msg == self.SECONDS_FORWARD then local frames = self.seconds * fps moho:SetCurFrame(curFrame + math.floor(frames)) elseif msg == self.TIME_GO then local newFrame = (self.timeMinutes * 60 * fps) + (self.timeSeconds * fps) + self.timeFrames moho:SetCurFrame(newFrame) elseif msg == self.TIME_SECONDS_INPUT then self.timeSecondsInput:SetValue(LM.Clamp(self.timeSecondsInput:IntValue(), 0, 59)) elseif msg >= self.SET_MARKER_LEVEL and msg < self.GO_TO_MARKER then local option = msg - self.SET_MARKER_LEVEL self.markerLevel = self.markerLevelOptions[option] self:UpdateWidgets(moho) end end function LK_TimelineNavigator:GoToNextmarker(moho, backwards) backwards = backwards or false local markerFrames = {} local markerChannel = self.markerChannel -- * TODO table.insert(markerFrames, moho.document:StartFrame()) table.insert(markerFrames, moho.document:EndFrame()) for markerID = 1, markerChannel:CountKeys()-1 do local markerFrame = markerChannel:GetKeyWhen(markerID) table.insert(markerFrames, markerFrame) local interp = MOHO.InterpSetting:new_local() markerChannel:GetKeyInterp(markerFrame, interp) if interp.hold > 0 then local holdEndFrame = markerFrame + interp.hold table.insert(markerFrames, holdEndFrame) end end local gotoFrame if backwards then gotoFrame = -1000000000 else gotoFrame = 1000000000 end for i = 1, #markerFrames do local markerFrame = markerFrames[i] if backwards then if markerFrame < moho.frame and gotoFrame < markerFrame then gotoFrame = markerFrame end else if markerFrame > moho.frame and gotoFrame > markerFrame then gotoFrame = markerFrame end end end if gotoFrame == -1000000000 or gotoFrame == 1000000000 then return end moho:SetCurFrame(gotoFrame) end
TimelineNavigator
Listed
Author: Lukas
View Script
Script type: Tool
Uploaded: Jun 25 2022, 03:42
Last modified: Sep 20 2024, 01:45
Script Version: 2.3
Jump through the timeline by amount of frames/times or to document/layer markers
Use keyboard shortcuts , and . to jump from marker to marker. It also jumps to marker ends if you're using hold interpolation on the marker keys and document start/end frames.
Based on Stan's Timeline Navigator tool.
Changelog:
- v2.0 Initial release
- v2.1 Fixed LK_Powertool error
- v2.2 Fixed MohoMode error
- v2.3 Fixed bug where framenumbers would display as floats (1.0 instead of 1)
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: 1144
TimelineNavigator
Listed
Author: Lukas
View Script
Script type: Tool
Uploaded: Jun 25 2022, 03:42
Last modified: Sep 20 2024, 01:45
Script Version: 2.3
Jump through the timeline by amount of frames/times or to document/layer markers
Use keyboard shortcuts , and . to jump from marker to marker. It also jumps to marker ends if you're using hold interpolation on the marker keys and document start/end frames.
Based on Stan's Timeline Navigator tool.
Changelog:
- v2.0 Initial release
- v2.1 Fixed LK_Powertool error
- v2.2 Fixed MohoMode error
- v2.3 Fixed bug where framenumbers would display as floats (1.0 instead of 1)
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: 1144