A lua greenhorn's question

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

Moderators: Víctor Paredes, Belgarath, slowtiger

stefman
Posts: 75
Joined: Mon Jul 20, 2009 6:46 pm

A lua greenhorn's question

Post by stefman »

Hi, I appologize for that question, but I really don't find the solution by myself.

I would like a function like this to be triggerd by another event than "OnOk".


function LM_Rotate3D_XYZDialog:OnOK()
LM_Rotate3D_XYZ.xangle = self.xangle:FloatValue()
LM_Rotate3D_XYZ.yangle = self.yangle:FloatValue()
LM_Rotate3D_XYZ.zangle = self.zangle:FloatValue()
end

I would like to link it to a button or to a keyboard hint.
Does someone know how to do that?

It's really hard to understand all this by yourself.
The Moho scripting reference is really good, but unfortunately the example pages are missing.

Does anyone know if there are any tutorials which treat directly lua scripting in Anime Studio?

stefman
User avatar
heyvern
Posts: 7035
Joined: Fri Sep 02, 2005 4:49 am

Post by heyvern »

Check into how buttons and widgets work.

A button or check box etc will send a "message". This message is defined in the button or widget. You then use the "message" function to test for the message sent and do something based on it.

It sounds like you want a pop up that stays open and interacts with the document. I haven't personally done anything like this yet and don't know how possible it is to achieve. You need to look at the different options for popups and buttons etc.

-vern
stefman
Posts: 75
Joined: Mon Jul 20, 2009 6:46 pm

Post by stefman »

Thank you Vern.
It sounds like you want a pop up that stays open and interacts with the document.
Indeed, that's exactly what I'm trying to do. Well, I allready am able to keep it open and to do nearly anything I want in AS's interface.

I just change the "(dlog:DoModal()" part do "(dlog:DoModless()" and my window stays open. But, the OK and Cancel buttons disappear as well.

That is why I need to create a new button which will trigger the action which was initially started by "OnOK".
A button or check box etc will send a "message". This message is defined in the button or widget. You then use the "message" function to test for the message sent and do something based on it.
I understand the principle. In the last weeks I've studied a certain number of scripts and I see what happens - an element is equal to something else and then this determines the value of if an action is true or not...

The problem is that scripts are never as simple that you just have one button (that is not the by default Ok button of the SimpleDialog ) which does one isolated action.
Often, the action trigged by button also depends on a parametre which has to be set by a checkbox or something else before.
So, I didn't manage yet to isolate only the needed information and the right syntax to make my button work by myself.

That is why I would like to ask if you or someone else would mind to show me in an example how this works
For this, I think it would be very practical to take AS's LM_LayerTrail script (scripts/Layer Effects/Layer trail...), to integrate a button into it and to trigger this function with it:

function LM_LayerTrailDialog:OnOK()
LM_LayerTrail.startFrame = self.startFrame:IntValue()
LM_LayerTrail.endFrame = self.endFrame:IntValue()
LM_LayerTrail.dashed = self.dashed:Value()
end

This would help me a lot to understand and I would be very grateful. Many, many thanks in advance!

Cheers,

stefman
User avatar
heyvern
Posts: 7035
Joined: Fri Sep 02, 2005 4:49 am

Post by heyvern »

This is a great idea. Plus I have wanted to experiment with this idea of a "floating script" window. I have become quite familar with "message" handling which can be trickier than it looks.

For "training" purposes I will take the "layers trail" script and mod it to work as a floating window with a button. We can both gain from this I think. ;)

-vern
stefman
Posts: 75
Joined: Mon Jul 20, 2009 6:46 pm

Post by stefman »

Great, thank you Vern.

Yes, I think this could open the way to a quiet unused kind of using scripts in AS and of integrating them into the GUI.

Please, let me know when you manage to make the script work with a button. I can't wait to have a look on it.

Many thanks in advance,

stefman
User avatar
heyvern
Posts: 7035
Joined: Fri Sep 02, 2005 4:49 am

Post by heyvern »

I gave it a shot... but not successful yet. I won't give up but I have to move on to other things right now.

Here's the problem I see:

The LM_Star:Run(moho) function initiates when the script is started. It pops up the dialog box and runs the new layer and star building stuff but the new layer and mesh is not inserted yet. Hitting "ok" creates the shape and the layer. The "BuildStar" function is used in two places, for creating the new mesh and also for the preview. This is constantly updated to show the display in the dialog box. So with a "modal" dialog box the document is not effected or changed until the "OK" is pressed.

If you change the dialog box to modeless then the script behaves totally differently. The "Run" function creates the layer and the star based on the settings in the dialog box immediately. Clicking buttons or whatever has no effect. The "Run" function has already been activated and you can't "Run" again.

So... I need to play with this some more to figure out how to activate the layer creation and mesh creation from the dialog box.

-vern
stefman
Posts: 75
Joined: Mon Jul 20, 2009 6:46 pm

Post by stefman »

Hi Vern,

I see.

But, wow, you directly attacked one of the harder scripts.

Perhaps it would be easier to try to modify the OnOk function of the Layer Trail script. This script doesn't run directly when set in modeless.
Thus, wouldn't the problem be easier to isolate in that script?
Here we wouldn't have to struggle with all the math stuff.

In the meantime I also tried to get that work but I just don't manage to programm a button.

Would you mind to just write down a sample syntax including all the elements I would need to create a button, please?

This would be very helpful.

But, take your time.

I know that your a busy man.

Cheers,

stefman
User avatar
heyvern
Posts: 7035
Joined: Fri Sep 02, 2005 4:49 am

Post by heyvern »

The main problem I have encountered with Menu and Button scripts is that the "moho" variable is not available to these "built in" functions like "OnOk" or the "HandleMessage" variable. The "moho" variable is a global variable that allows you to access parts of the file, like the mesh, the layer, bones etc. The "Run(moho)" function has that variable but it runs once. You can't run it again to pass the "moho" variable. The "HandleMessage" function can't receive the "moho" variable because it only has one argument "HandleMessage(what)" which is the message variable sent by the button or widget. Without having access to the "moho" variable it is hard to make the modeless dialog box do anything. Haven't given up yet though. ;)

-----------------------

Here's some code snippets for creating a button...

At the bottom of the "top" of the star script where all the buttons and widgets are created in the dialog creation function, you can see where the "newLayer" checkbox is placed. Below that I added code for a button. Please note that I used the "OK" and "Cancel" MSG codes for these two buttons. I was hoping that might help but it has no effect. Normally the message of a widget would be "LM.GUI.MSG_BASE+1" with the +1 incremented for each new item, +2, +3 etc. ;).

Basically "d." is the variable defined for the dialog and gets returned later when this function is called by the "Run(moho)" function. You create the name of the widget defining what it is (checkbox, button etc) then you add the "child" to the dialog box layout.

Code: Select all

	d.newLayer = LM.GUI.CheckBox("Create star in new layer")
	l:AddChild(d.newLayer, LM.GUI.ALIGN_LEFT)

	d.theOkButton = LM.GUI.Button("A Star Is Born", LM.GUI.MSG_OK)
	l:AddChild(d.theOkButton)

	d.theNoButton = LM.GUI.Button("Elvis has left the building", LM.GUI.MSG_CANCEL)
	l:AddChild(d.theNoButton)

	return d
In the "HandleMessage()" function I added the code for the new buttons:
(HV_Star_Button is the name of my script. Has to be different from the LM_Star or they conflict)

Code: Select all

function HV_Star_ButtonDialog:HandleMessage(what)
	if (what == self.UPDATE) then
		self:UpdatePreview()
	end

-- new stuff here---

	if (what == LM.GUI.MSG_OK) then
	        HV_Star_Button.numPoints = self.numPoints:IntValue()
		HV_Star_Button.innerRadius = self.innerRadius:FloatValue()
		HV_Star_Button.newLayer = self.newLayer:Value()
		self:UpdatePreview()
	elseif (what == LM.GUI.MSG_CANCEL) then
		return
	end
end
In the original Star script at the top of the "Run(moho)" function you will see the creation of the dialog pop up is "inside" an "if/then" thingamabob. What is actually happening is that the DoModal() popup creation RETURNS A VALUE. It returns the value of the default buttons clicked (ok/cancel). The "if" structure CREATES the dialog at the same time that it checks for the cancel. By saying: "if(dlog:DoModal()..." the dialog is created.

Code: Select all

function LM_Star:Run(moho)
	local dlog = LM_StarDialog:new(moho)
	if (dlog:DoModal() == LM.GUI.MSG_CANCEL) then
		return
	end
I took out that test and put this in:

Code: Select all

function HV_Star_Button:Run(moho)
	local dlog = HV_Star_ButtonDialog:new(moho)
	dlog:DoModeless()
It doesn't work. The two buttons do absolutely nothing. The update display in the script works fine but the star layer is created as soon as the script is loaded and the pop up appears. This happens with the Run(moho) function and can't be "rerun" again.

-vern
Rudiger
Posts: 786
Joined: Sun Dec 18, 2005 2:25 am

Post by Rudiger »

Couldn't you do something dodgy like store the moho object inside the dialog when it is first created, then all of the buttons would have access to it even though it hasn't been passed to them. Might run into problems with garbage collection though.
User avatar
heyvern
Posts: 7035
Joined: Fri Sep 02, 2005 4:49 am

Post by heyvern »

I tried passing "moho" using a global variable and it worked... sort of... but it would cause AS to crash when I tried using it in other functions.

-vern
Rudiger
Posts: 786
Joined: Sun Dec 18, 2005 2:25 am

Post by Rudiger »

But does storing moho in a table make other functions crash too?

Something else dodgy you could try is have a tool that works in parallel with the dialog. Not sure, though, whether the OnMouseUp event would be triggered in the tool if clicking on a non-modal dialog box button instead of the workspace.
User avatar
heyvern
Posts: 7035
Joined: Fri Sep 02, 2005 4:49 am

Post by heyvern »

I'm starting to think that maybe this is a "bug" in the script interface. I think that a "modeless" dialog box should have the same behavior as a modal dialog box.

When you close the modeless dialog box it sends an "OnOk" message function. The same as hitting "OK" in a modal dialog box. However this is not the same behavior as the modal box. It doesn't do the "Run" function. A modal box seems to "hold" the action until OK is pressed. I have to figure out how to activate the function to edit a mesh from a button click in the dialog box but with no way to pass that "moho" variable I can't do anything when the message is received. I can run another function from the message handler but I can't pass anything useful to it.

For example the "display" or "preview" in the star script is using the same mesh building code that draws the star when you hit OK. In a modal box pressing OK creates the new layer if needed and draws the star mesh. The "Run" function happens TWICE. Once when the script is activated and once when you press OK.

I think the modeless box should do that as well. If you have a button that sends an "OK" message then it should behave exactly like a modal dialog box. My feeling is a modeless box should just be a "modal" box that "repeats" and stays open.

I will be the first to admit I am not an expert with this stuff and I am probably doing something totally wrong. :oops:

-vern
Rudiger
Posts: 786
Joined: Sun Dec 18, 2005 2:25 am

Post by Rudiger »

OK, I had a look at the lm_star.lua script and it looks like the moho object is already embedded in the dialog! IE on line 55 is says "d.moho = moho". This means any dialog method can access the scripting interface simply by using self.moho.

By the way, I don't think the script object's Run method is called twice. It is called, creates the modal dialog hands over control to it and waits. When you press OK or CANCEL the dialog is closed and the Run method continues on using the parameters injected into the script object by the dialog.

For a modeless dialog I think the script object's Run method would just create the dialog and that's it. It would then be up to the button methods of the dialog to do all of the work using self.moho. Of course, these button methods could just pass self.moho to script object methods to be a bit cleaner.
Rudiger
Posts: 786
Joined: Sun Dec 18, 2005 2:25 am

Post by Rudiger »

Hmmm, got some mixed results. I found that while you can store the moho pointer in the dialog, the scripting interface it points to changes when the main script object's Run procedure ends, meaning that the current Layer, Mesh, and Skeleton methods subsequently return nil.

What you can do though, is store the document pointer and do document level operations from there. This means that you could have a floating custom timeline window that automatically keeps synchronised with the actual timeline and sequencer windows.

EDIT:
Here's the non-modal dialog example I was trying out.
http://www.users.on.net/~alexical/Anime ... window.zip
stefman
Posts: 75
Joined: Mon Jul 20, 2009 6:46 pm

Post by stefman »

Clever-clever. Thank you Vern and Rudiger for these great researching works. This is very precious.

Especially,

Thank you Vern for your complete button lesson!
Thank you Rudiger for the button in action!
What you can do though, is store the document pointer and do document level operations from there. This means that you could have a floating custom timeline window that automatically keeps synchronised with the actual timeline and sequencer windows.
Oh, this is very good news!!!

I'll delve again into this question this week-end. Work is eating all my time and energy at the moment.


Cheers,

stefman
Post Reply