Image
-- **************************************************
-- Provide Moho with the name of this script object
-- **************************************************

ScriptName = "LK_Storyboard"

-- **************************************************
-- General information about this script
-- **************************************************

LK_Storyboard = {}

function LK_Storyboard:Name()
	return "Storyboard Slider"
end

function LK_Storyboard:Version()
	return "0.0"
end

function LK_Storyboard:Description()
	return "Show storyboard as tracing image. (A directory containing images named 'STB' must exist in the same location as the Moho file)"
end

function LK_Storyboard:Creator()
	return "Lukas Krepel, Frame Order"
end

function LK_Storyboard:UILabel()
	return "Storyboard Slider"
end

function LK_Storyboard:ColorizeIcon()
	return true
end

function LK_Storyboard:IsRelevant()
	if MohoMode ~= nil then
		return MohoMode.animation
	else
		return true
	end
end

-- **************************************************
-- Include Layer Transform tool mouse functions
-- **************************************************

function LK_Storyboard:OnMouseDown(moho, mouseEvent)
	-- LM_TransformLayer:OnMouseDown(moho, mouseEvent)
end

function LK_Storyboard:OnMouseMoved(moho, mouseEvent)
	-- LM_TransformLayer:OnMouseMoved(moho, mouseEvent)
end

function LK_Storyboard:OnMouseUp(moho, mouseEvent)
	-- LM_TransformLayer:OnMouseUp(moho, mouseEvent)
end

-- **************************************************
-- Recurring values
-- **************************************************

LK_Storyboard.lastImage = 1
LK_Storyboard.loop = false

LK_Storyboard.SLIDER_DRAG =					MOHO.MSG_BASE + 0
LK_Storyboard.PREV =						MOHO.MSG_BASE + 1
LK_Storyboard.NEXT =						MOHO.MSG_BASE + 2
LK_Storyboard.TOGGLE_TRACING_IMAGE =		MOHO.MSG_BASE + 4
LK_Storyboard.TOGGLE_LOOP =					MOHO.MSG_BASE + 5

function LK_Storyboard:LoadPrefs(prefs)
	prefs:GetInt("LK_Storyboard.lastImage", 0)
	prefs:GetBool("LK_Storyboard.loop", false)
end

function LK_Storyboard:SavePrefs(prefs)
	prefs:SetInt("LK_Storyboard.lastImage", self.lastImage)
	prefs:SetBool("LK_Storyboard.loop", self.loop)
end

function LK_Storyboard:DoLayout(moho, layout, view)
	self.storyboardImages = self:StoryboardImages(moho)
	-- **************************
	-- *** Storyboard Slider: ***
	-- **************************
	FO_Utilities:Divider(layout, "Storyboard")
	-- * Slider:
	local sliderSize = 30 * #self.storyboardImages
	if sliderSize > moho.view:Width() - 100 then
		sliderSize = moho.view:Width() - 100
	end
	self.slider = LM.GUI.Slider(sliderSize,false,false, self.SLIDER_DRAG)
	layout:AddChild(self.slider)
	self.slider:SetRange(1, #self.storyboardImages)
	self.slider:SetNumTicks(#self.storyboardImages)
	self.slider:SetShowTicks(true)
	self.slider:SetSnapToTicks(true)
	self.slider:SetFatSlider(true)
	-- **********************
	-- *** Arrow buttons: ***
	-- **********************
	layout:PushH(LM.GUI.ALIGN_CENTER, 0)
	self.prevKeyButton = LM.GUI.ImageButton("ScriptResources/FO_icons/arrow_left", "Previous", false, self.PREV, true)
	layout:AddChild(self.prevKeyButton)
	self.toggleButton = LM.GUI.ImageButton("ScriptResources/FO_icons/channels_visible_layers_only", "Toggle", true, self.TOGGLE_TRACING_IMAGE, true)	
	layout:AddChild(self.toggleButton)
	self.nextKeyButton = LM.GUI.ImageButton("ScriptResources/FO_icons/arrow_right", "Next", false, self.NEXT, true)	
	layout:AddChild(self.nextKeyButton)
	layout:Pop()
	-- *
	self.loopButton = LM.GUI.ImageButton("ScriptResources/FO_icons/refresh", "Loop", true, self.TOGGLE_LOOP, true)
	layout:AddChild(self.loopButton)
	-- *
	self.fileName = LM.GUI.DynamicText("A directory containing images named 'STB' must exist in the same location as the Moho file!")
	layout:AddChild(self.fileName)
end

function LK_Storyboard:UpdateWidgets(moho)
	self.slider:SetValue(self.lastImage)
	local imagePath = self.storyboardImages[self.lastImage]
	if imagePath ~= nil then
		imagePath = FO_Utilities:FileName(imagePath)
		self.fileName:SetValue(imagePath)
		self.toggleButton:Enable(true)
		self.loopButton:Enable(true)
		if not self.loop then
			self.prevKeyButton:Enable(self.lastImage ~= 1)
			self.nextKeyButton:Enable(self.lastImage ~= #self.storyboardImages)
		else
			self.prevKeyButton:Enable(true)
			self.nextKeyButton:Enable(true)
		end
	else
		self.prevKeyButton:Enable(false)
		self.toggleButton:Enable(false)
		self.nextKeyButton:Enable(false)
		self.loopButton:Enable(false)
	end
	self.toggleButton:SetValue(moho.view:IsTracingOn())
	self.loopButton:SetValue(self.loop)
end

function LK_Storyboard:HandleMessage(moho, view, msg)
	if msg == self.SLIDER_DRAG then
		local value = self.slider:Value()
		local image = self.storyboardImages[value]
		moho.view:SetTracingImage(image)
		self.lastImage = value
	elseif msg == self.PREV then
		self:Run(moho, true)
	elseif msg == self.NEXT then
		self:Run(moho, false)
	elseif msg == self.TOGGLE_TRACING_IMAGE then
		if not moho.view:IsTracingOn() then
			moho.view:SetTracingImage(self.storyboardImages[self.lastImage])
			else
				moho.view:TurnTracingOn(false)
			end
	elseif msg == self.TOGGLE_LOOP then
		self.loop = not self.loop
	end
	moho:UpdateUI()
end

function LK_Storyboard:Run(moho, backwards)
	if not backwards then
		if self.loop then
			if (self.lastImage >= #self.storyboardImages) then
				self.lastImage = 0
			end
		end
		for i = 1, #self.storyboardImages do
			local image = self.storyboardImages[i]
			if i > self.lastImage then
				self.lastImage = i
				moho.view:SetTracingImage(image)
				return
			end
		end
	else
		if self.loop then
			if (self.lastImage <= 1) then
				self.lastImage = #self.storyboardImages+1
			end
		end
		for i = #self.storyboardImages, 1, -1 do
			local image = self.storyboardImages[i]
			if i < self.lastImage then
				self.lastImage = i
				moho.view:SetTracingImage(image)
				return
			end
		end
	end
	moho.view:SetTracingImage(self.storyboardImages[self.lastImage])
	moho:Click()
end

function LK_Storyboard:StoryboardImages(moho)
	local imageExtensions = { "jpg", "jpeg", "png", "bmp", "psd", "tga" }
	local storyboardImages = {}
	local path = moho.document:Path()
	if path == "" then
		return storyboardImages
	end
	local shotDirectory = FO_Utilities:FileDirectory(path)
	local stbDirectory = shotDirectory.."/".."STB"
	moho:BeginFileListing(stbDirectory, true)
	local file = moho:GetNextFile()
	local i = 0
	while file ~= nil do
		i = i + 1
		for j = 1, #imageExtensions do
			if string.match(string.lower(file), "."..imageExtensions[j]) then
				local tracingImage = stbDirectory.."/"..file
				table.insert(storyboardImages, tracingImage)
			end
		end
		file = moho:GetNextFile()
	end
	table.sort(storyboardImages, function(a,b) return a < b end)
	return storyboardImages
end

Icon
Storyboard
Listed

Author: Lukas View Script
Script type: Tool

Uploaded: May 25 2023, 06:25

Last modified: Sep 05 2023, 12:54

Flip through Storyboard as Tracing Image
Useful in case you are using an image sequence as Storyboard, and if the Storyboard contains the shot layout as well.

You need a folder named "STB" in the same folder as the Moho file. (I suggest keeping each Shot in a seperate Shot folder, each with their own STB folder)

Inside the STB folder should be an image sequence.

Image

Forumpost
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: 846