DoLayout event

Moho allows users to write new tools and plugins. Discuss scripting ideas and problems here.

Moderators: Víctor Paredes, Belgarath, slowtiger

User avatar
MehdiZangenehBar
Posts: 50
Joined: Wed Feb 07, 2024 7:17 pm
Contact:

DoLayout event

Post by MehdiZangenehBar »

Changing selected layer should fire DoLayout event in the tool script, right? But sometimes this is not happening, anyone knows why?
User avatar
synthsin75
Posts: 10007
Joined: Mon Jan 14, 2008 11:20 pm
Location: Oklahoma
Contact:

Re: DoLayout event

Post by synthsin75 »

On layer changes, DoLayout only reevaluates if you change layer type, like from a vector layer to a group layer, etc..
User avatar
MehdiZangenehBar
Posts: 50
Joined: Wed Feb 07, 2024 7:17 pm
Contact:

Re: DoLayout event

Post by MehdiZangenehBar »

So only event we can use to realize the layer change is WidgetUpdate? any other trigger?
User avatar
synthsin75
Posts: 10007
Joined: Mon Jan 14, 2008 11:20 pm
Location: Oklahoma
Contact:

Re: DoLayout event

Post by synthsin75 »

IsEnabled is triggered by every layer change, so you can also use that function.
User avatar
MehdiZangenehBar
Posts: 50
Joined: Wed Feb 07, 2024 7:17 pm
Contact:

Re: DoLayout event

Post by MehdiZangenehBar »

So we don't have any standard way of calling DoLayout function?
User avatar
KuzKuz
Posts: 502
Joined: Mon Aug 19, 2013 5:12 pm
Location: Ukraine

Re: DoLayout event

Post by KuzKuz »


If I need to completely redraw the script panel from scratch, I use this code:

Code: Select all

local drawingToolsNonZero = MOHO.MohoGlobals.DisableDrawingToolsNonZero
if not drawingToolsNonZero then
	MOHO.MohoGlobals.DisableDrawingToolsNonZero = true
end
local frame = moho.frame
if frame == 0 then
	moho:SetCurFrame(1)
	moho:SetCurFrame(0)
elseif frame ~= 0 then
	moho:SetCurFrame(0)
	moho:SetCurFrame(frame)
end
if not drawingToolsNonZero then
	MOHO.MohoGlobals.DisableDrawingToolsNonZero = drawingToolsNonZero
end
User avatar
MehdiZangenehBar
Posts: 50
Joined: Wed Feb 07, 2024 7:17 pm
Contact:

Re: DoLayout event

Post by MehdiZangenehBar »

Well, your code will not fire DoLayout function for me.
User avatar
MehdiZangenehBar
Posts: 50
Joined: Wed Feb 07, 2024 7:17 pm
Contact:

Re: DoLayout event

Post by MehdiZangenehBar »

This is a test case with your code, you can see which events will be fired:

Code: Select all

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

ScriptName = "TestScript"

TestScript = {}

function TestScript:Name()
	return 'Name'
end

function TestScript:Version()
	return 'Version'
end

function TestScript:UILabel()
	return 'UILabel'
end

function TestScript:Creator()
	return 'Creator'
end

function TestScript:Description()
	return 'Description'
end


-- **************************************************
-- Is Relevant / Is Enabled
-- **************************************************

function TestScript:IsRelevant(moho)
	print('TestScript:IsRelevant')
	return true
end

function TestScript:IsEnabled(moho)
	print('TestScript:IsEnabled')
	return true
end

-- **************************************************
-- Variables
-- **************************************************

local dialog_table = {}

-- **************************************************
-- Events
-- **************************************************

function TestScript:OnMouseDown(moho, mouseEvent)
	print('TestScript:OnMouseDown')
end

function TestScript:DoLayout(moho, layout)
	print('TestScript:DoLayout')

	local dialog = LM.GUI.SimpleDialog('Dialog', dialog_table)
	local dialog_layout = dialog:GetLayout()
	local button = LM.GUI.Button('DoLayout', MOHO.MSG_BASE)
	dialog_layout:AddChild(button, LM.GUI.ALIGN_FILL, 0)
	local popup = LM.GUI.PopupDialog('Popup', true, 0)
	popup:SetDialog(dialog)
	layout:AddChild(popup, LM.GUI.ALIGN_LEFT, 0)
end

function TestScript:UpdateWidgets(moho)
	print('TestScript:UpdateWidgets')
end

function dialog_table:HandleMessage(msg)
	print('dialog_table:HandleMessage')

	local helper = MOHO.ScriptInterfaceHelper:new_local()
	local moho = helper:MohoObject()

	local drawingToolsNonZero = MOHO.MohoGlobals.DisableDrawingToolsNonZero
	if not drawingToolsNonZero then
		MOHO.MohoGlobals.DisableDrawingToolsNonZero = true
	end
	local frame = moho.frame
	if frame == 0 then
		moho:SetCurFrame(1)
		moho:SetCurFrame(0)
	elseif frame ~= 0 then
		moho:SetCurFrame(0)
		moho:SetCurFrame(frame)
	end
	if not drawingToolsNonZero then
		MOHO.MohoGlobals.DisableDrawingToolsNonZero = drawingToolsNonZero
	end

	helper:delete()
end
There is no DoLayout.
User avatar
KuzKuz
Posts: 502
Joined: Mon Aug 19, 2013 5:12 pm
Location: Ukraine

Re: DoLayout event

Post by KuzKuz »


Code: Select all

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

ScriptName = "MR_TestScript"

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

MR_TestScript = {}

function MR_TestScript:Name()
	return 'MR Test Script'
end

function MR_TestScript:Version()
	return '1.0'
end

function MR_TestScript:UILabel()
	return 'MR Test Script'
end

function MR_TestScript:Creator()
	return 'Eugene Babich'
end

function MR_TestScript:Description()
	return ''
end


-- **************************************************
-- Is Relevant / Is Enabled
-- **************************************************

function MR_TestScript:IsRelevant(moho)
	return true
end

function MR_TestScript:IsEnabled(moho)
	return true
end

-- **************************************************
-- Keyboard/Mouse Control
-- **************************************************

function MR_TestScript:OnMouseDown(moho, mouseEvent)
	
end

function MR_TestScript:OnMouseMoved(moho, mouseEvent)
	
end

function MR_TestScript:OnMouseUp(moho, mouseEvent)
	
end

function MR_TestScript:OnKeyUp(moho, keyEvent)
	
end

-- **************************************************
-- Tool Panel Layout
-- **************************************************

MR_TestScript.optionalButton = true

MR_TestScript.REDRAW_LAYOUT = MOHO.MSG_BASE
MR_TestScript.OPTIONAL_BUTTON = MOHO.MSG_BASE + 1

function MR_TestScript:DoLayout(moho, layout)
	print('TestScript:DoLayout')
	self.redrawLayoutButton = LM.GUI.Button('Redraw Layout', self.REDRAW_LAYOUT)
	layout:AddChild(self.redrawLayoutButton, LM.GUI.ALIGN_LEFT, 0)
	
	if self.optionalButton then
		self.optionalButtonButton = LM.GUI.Button('Optional Button', self.OPTIONAL_BUTTON)
		layout:AddChild(self.optionalButtonButton, LM.GUI.ALIGN_LEFT, 0)
	end
end

function MR_TestScript:HandleMessage(moho, view, msg)
	if msg == self.REDRAW_LAYOUT then
		self.optionalButton = not self.optionalButton
		local drawingToolsNonZero = MOHO.MohoGlobals.DisableDrawingToolsNonZero
		if not drawingToolsNonZero then
			MOHO.MohoGlobals.DisableDrawingToolsNonZero = true
		end
		local frame = moho.frame
		if frame == 0 then
			moho:SetCurFrame(1)
			moho:SetCurFrame(0)
		elseif frame ~= 0 then
			moho:SetCurFrame(0)
			moho:SetCurFrame(frame)
		end
		if not drawingToolsNonZero then
			MOHO.MohoGlobals.DisableDrawingToolsNonZero = drawingToolsNonZero
		end
	elseif msg == self.OPTIONAL_BUTTON then
	end
end
User avatar
MehdiZangenehBar
Posts: 50
Joined: Wed Feb 07, 2024 7:17 pm
Contact:

Re: DoLayout event

Post by MehdiZangenehBar »

Your code actually works, except for group layer, so I changed the code to support that as well.
Note that I added some flag to prevent fire UpdateWidget and DoLayout couple times.
Please have a look:

Code: Select all

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

ScriptName = "TestScript"

TestScript = {}

function TestScript:Name()
	return 'Name'
end

function TestScript:Version()
	return 'Version'
end

function TestScript:UILabel()
	return 'UILabel'
end

function TestScript:Creator()
	return 'Creator'
end

function TestScript:Description()
	return 'Description'
end


-- **************************************************
-- Is Relevant / Is Enabled
-- **************************************************

function TestScript:IsRelevant(moho)
	return true
end

function TestScript:IsEnabled(moho)
	return true
end

-- **************************************************
-- Variables
-- **************************************************

local dialog_table = {}
local suspend_update_widgets = false
local suspend_do_layout = false

-- **************************************************
-- Events
-- **************************************************

function TestScript:OnMouseDown(moho, mouseEvent)
end

function TestScript:DoLayout(moho, layout)
	if suspend_do_layout == true then return end
	print('TestScript:DoLayout')

	local dialog = LM.GUI.SimpleDialog('Dialog', dialog_table)
	local dialog_layout = dialog:GetLayout()
	local button = LM.GUI.Button('DoLayout', MOHO.MSG_BASE)
	dialog_layout:AddChild(button, LM.GUI.ALIGN_FILL, 0)
	local popup = LM.GUI.PopupDialog('Popup', true, 0)
	popup:SetDialog(dialog)
	layout:AddChild(popup, LM.GUI.ALIGN_LEFT, 0)
end

function TestScript:UpdateWidgets(moho)
	if suspend_update_widgets == true then return end
	print('TestScript:UpdateWidgets')
end

function dialog_table:HandleMessage(msg)

	suspend_update_widgets = true
	suspend_do_layout = true

	local helper = MOHO.ScriptInterfaceHelper:new_local()
	local moho = helper:MohoObject()

	local drawingToolsNonZero = MOHO.MohoGlobals.DisableDrawingToolsNonZero
	if not drawingToolsNonZero then
		MOHO.MohoGlobals.DisableDrawingToolsNonZero = true
	end

	local temp_layer = nil
	if moho.layer:LayerType() == MOHO.LT_GROUP then temp_layer = moho:CreateNewLayer(MOHO.LT_UNKNOWN, false) end
	
	local frame = moho.frame
	if frame == 0 then
		moho:SetCurFrame(1)
		if temp_layer == nil then suspend_do_layout = false end
		moho:SetCurFrame(0)
	elseif frame ~= 0 then
		moho:SetCurFrame(0)
		if temp_layer == nil then suspend_do_layout = false end
		moho:SetCurFrame(frame)
	end

	suspend_do_layout = false

	if temp_layer ~= nil then moho:DeleteLayer(temp_layer) end
	suspend_update_widgets = false

	if not drawingToolsNonZero then
		MOHO.MohoGlobals.DisableDrawingToolsNonZero = drawingToolsNonZero
	end

	helper:delete()
end
User avatar
KuzKuz
Posts: 502
Joined: Mon Aug 19, 2013 5:12 pm
Location: Ukraine

Re: DoLayout event

Post by KuzKuz »

I don't recommend creating and deleting a layer just to redraw the panel. When you create or delete a layer, you store the entire project in memory for Undo and Redo purposes, even if you don't use PrepUndo().
Each panel update like this will cost you approximately 15-20 megabytes of RAM depending on the size of your project.
It would be better to find the first vector or bone layer, switch to it, refresh the panel, and then return to the layer you were on.
User avatar
MehdiZangenehBar
Posts: 50
Joined: Wed Feb 07, 2024 7:17 pm
Contact:

Re: DoLayout event

Post by MehdiZangenehBar »

So we should iterate over document layers and check the layer type? (find the first?) any example?
User avatar
synthsin75
Posts: 10007
Joined: Mon Jan 14, 2008 11:20 pm
Location: Oklahoma
Contact:

Re: DoLayout event

Post by synthsin75 »

User avatar
MehdiZangenehBar
Posts: 50
Joined: Wed Feb 07, 2024 7:17 pm
Contact:

Re: DoLayout event

Post by MehdiZangenehBar »

synthsin75 wrote: Mon May 06, 2024 11:27 pm https://mohoscripting.com/snippets/1
I don't want to iterate over ALL layers, I need a function to find first match and exit the loop.
User avatar
MehdiZangenehBar
Posts: 50
Joined: Wed Feb 07, 2024 7:17 pm
Contact:

Re: DoLayout event

Post by MehdiZangenehBar »

KuzKuz wrote: Mon May 06, 2024 8:57 pm Each panel update like this will cost you approximately 15-20 megabytes of RAM depending on the size of your project.
Are you sure it took that amount of memory? Any function to calculate that?
Post Reply