Dissecting a menu script : Draw Triangle

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

Moderators: Fahim, Distinct Sun, Víctor Paredes, erey, Belgarath, slowtiger

Dissecting a menu script : Draw Triangle

Postby Rasheed » Fri Jan 20, 2006 5:23 pm

Just for educational purposes, I will be dissecting some Moho scripts, which are located in your Moho directory (subdirectory "/scripts/").

I hope that more Moho users wil try Lua coding, because it isn't really that difficult once you are getting the hang of it. Some useful resources for the Lua language are:
Programming in Lua
Lua Tutorial (for Newbies)

The triangle script I'm dissecting today is located in the "/scripts/menu/Draw/" subdirectory (subfolder) relative to your Moho directory (folder). The explanation is in the comments (start with double dash "--"). I will only discuss the drawing function and stay away from the other stuff that is necessary for a menu script. Therefore, I have rewritten the triangle drawing function of the menu script so, that it will run in a layer script.

The disadvantage of using a layer script is that it is called again and again, so you have to make sure the script doesn't go into an endless loop and keeps redrawing the same triangle. In the layer script version the triangle is only drawn if there are no points in the layer. If you delete the triangle, it will automatically be redrawn.

Writing a layer script is nothing more than this:
Code: Select all
function LayerScript(moho)
... -- your code
end
The function LayerScript(moho) is obligatory, just like the end statement, which closes the function block. The rest is up to you!

You can copy the text in the code below and paste it into a text editor (e.g. Notepad), then save as "Triangle.lua" (tip for Notepad users: put quotes around the filename, otherwise it will be saved as "Triangle.lua.txt"). You can add the script to a vector layer in the Layer Properties window (check "Embedded script file").

You can also download the zipped lua file (1.2 KB):
DrawTriangleLayerScript.lua.zip

I encourage you to modify the script and try some variations. For instance, how do you draw a square, or a circle*, or a figure with a hole in the middle? I think you can learn a lot from this and gain a greater understanding of the inner workings of Moho, even if you don't want to be a script writer and are just curious how this "scripting thing" works.
___

* Note: use MOHO.SMOOTH as a value for the SetCurvature function for smooth edges instead of sharp edges with MOHO.PEAKED.
___
Code: Select all
function LayerScript(moho)

   -- ensure this is a 2D vector layer, otherwise skip the script
   local mesh = moho:Mesh()
   if mesh == nil then
       return
   end
      
   -- prevent this layer script to go in an endless loop
   -- ensure there are no points drawn, otherwise skip this script
   -- (BTW this is not part of the original menu script, see text)
   if mesh:CountPoints() > 0 then
       return
   end

   -- mark a point in editing that the user can "undo" to return to
   moho.document:PrepUndo(moho.layer)

   -- mark the document as "dirty" or modified,
   -- prompting the user to save if he tries to quit.
   moho.document:SetDirty()

   -- count the current amount of points
   local n = mesh:CountPoints()

   -- define a vector by called the new_local() function
   -- of Moho's LM.Vector2 class
   local v = LM.Vector2:new_local()

   -- it will be an equal-side triangle on a circle with a radius
   -- of 0.75 units
   local r = 0.75

   -- deselect all points
   mesh:SelectNone()

   -- set the x and y values of the vector v
   -- to a point on the circle with angle pi/2
   v.x = r * math.cos(math.pi / 2)
   v.y = r * math.sin(math.pi / 2)

   -- normally, you cannot "add" single points;
   -- this function allows you to set a single point
   mesh:AddLonePoint(v, 0)

   -- set the x and y values of the vector v
   -- to a point on the circle with angle 7*pi/6
   v.x = r * math.cos(math.pi + math.pi / 6)
   v.y = r * math.sin(math.pi + math.pi / 6)

   -- append this point to the previous set point
   -- which creates a curve of two points
   mesh:AppendPoint(v, 0)

   -- set the x and y values of the vector v
   -- to a point on the circle with angle 11*pi/6
   v.x = r * math.cos(2 * math.pi - math.pi / 6)
   v.y = r * math.sin(2 * math.pi - math.pi / 6)

   -- append this point to the previous set point
   -- which extends the curve with one point (3 in total)
   mesh:AppendPoint(v, 0)

   -- set the x and y values of the vector v
   -- to the same coordinates as the first point
   v.x = r * math.cos(math.pi / 2)
   v.y = r * math.sin(math.pi / 2)

   -- append this point to the previous set point
   -- which extends the curve with one point (4 in total)
   mesh:AppendPoint(v, 0)

   -- weld the previous points,
   -- therefore closing the curve
   -- now only 3 points remain in this closed curve
   mesh:WeldPoints(n, n + 3, 0)

   -- set the curvature of the first point of the shape
   -- to a peaked value (straight lines),
   -- on frame zero
   mesh:Point(n):SetCurvature(MOHO.PEAKED, 0)

   -- the same for the second point
   mesh:Point(n + 1):SetCurvature(MOHO.PEAKED, 0)

   -- the same for the third point
   mesh:Point(n + 2):SetCurvature(MOHO.PEAKED, 0)

   -- ensure that all the points in the curve (now a triangle)
   --  are selected
   mesh:SelectConnected()

   -- give the default fill and outline to the triangle
   moho:CreateShape(true)

end
User avatar
Rasheed
 
Posts: 2008
Joined: Tue May 17, 2005 8:30 am
Location: The Netherlands

Postby bupaje » Fri Jan 20, 2006 5:51 pm

This is something I've been wanting to learn. Please keep doing this.
[url=http://burtabreu.animationblogspot.com:2gityfdw]My AnimationBlogSpot[/url:2gityfdw]
User avatar
bupaje
 
Posts: 1175
Joined: Fri Nov 12, 2004 5:44 pm
Location: California

Postby ulrik » Fri Jan 20, 2006 6:36 pm

Great Rasheed, keep this tutorials coming and I'll do my best to keep up with them :D
ulrik
 
Posts: 1061
Joined: Thu Aug 11, 2005 10:32 pm
Location: Stockholm Sweden

Postby Ramón López » Fri Jan 20, 2006 8:33 pm

I TOTALLY agree with both!!! This is a GREAT idea and I still LOVE it! :) Definitely it increase me interest and curiosity and that "-- lines" give me the courage to definitely can confront this hard job! I hope this go far away!!! You can be sure I'll do my homeworks :D ...THANKS!!!
User avatar
Ramón López
 
Posts: 1799
Joined: Sun Aug 08, 2004 1:41 pm
Location: Elda! Again...

Postby Rasheed » Sat Jan 21, 2006 12:02 am

Thanks for your kinds words, guys!

Perhaps I should recap some stuff, so it sticks better into your memory. I always like when things are repeated in different words. I tend to remember it better.

A layer script is defined as follows:
Code: Select all
function LayerScript(moho)
...
end
The ... represents your code and that's all the overhead that is needed, unlike menu and tool scripts. The moho stands for the interface between Lua and Moho. Moho calls all active layer scripts and assigns an individual stack of memory to them. The moho variable kind of stands for this interface via a stack in memory.

So
Code: Select all
moho:Mesh()
stands for the object Mesh() inside the running Moho program. The Mesh() object is in effect the 2D vector layer in which the layer script is embedded.
Code: Select all
local mesh = moho:Mesh()
means that the local variable mesh now stands for the 2D vector layer. If the current layer isn't a vector layer, the expression
Code: Select all
mesh == nil
will become true. Nil means "nothing", "emty", "non-existent".

So this:
Code: Select all
function LayerScript(moho)
   local mesh = moho:Mesh()
   if mesh == nil then
      return
   end
   ...
end
means that the code ... will only be executed if a mesh could be found, otherwise the function executes a return to the caller of the function (Moho).

Here is another piece of educational code. It contains a LayerScript function and a CreateSquareCurve function, which is called from within LayerScript. This layer script creates a square shape with a square hole in it. The zipped archive can be downloaded here:
DrawRectWithHole.lua.zip

Install as usual.

Here is the code. I added comments, so you can easily understand what each part is supposed to do.
Code: Select all
function LayerScript(moho)
-- ************************************************************
-- create a large square shape with a square hole
--
-- procedure:
-- * create a large square curve with a smaller one inside
-- * turn the selected curves into a shape
-- ************************************************************

   -- if this is not a 2D vector layer or
   -- if there are points present, then skip the script
   local mesh = moho:Mesh()
   if mesh == nil or mesh:CountPoints() > 0 then
      return
   end

   -- create a large and a smaller square curve
   CreateSquareCurve(moho, 0.75)
   CreateSquareCurve(moho, 0.3)

   -- give the default fill and outline to the selected curve
   moho:CreateShape(true)
end

function CreateSquareCurve(moho, d)
-- ************************************************************
-- create a square curve
--
-- procedure:
-- * determine the number of the first point
-- * define a 2D vector
-- * set the 5 points of the rectangle
--   (first and last point overlap)
-- * weld first and last point
-- * set curvature of 4 remaining points to PEAK
-- ************************************************************

   -- count the current amount of points
   local mesh = moho:Mesh()
   local n = mesh:CountPoints()

   -- define a 2D vector
   local v = LM.Vector2:new_local()

   -- set the 1st point
   v.x = d
   v.y = d -- (d , d)
   mesh:AddLonePoint(v, 0)

   -- append the 2nd point
   v.x = -d
   v.y = d -- (-d , d)
   mesh:AppendPoint(v, 0)

   -- append the 3rd point
   v.x = -d
   v.y = -d -- (-d , -d)
   mesh:AppendPoint(v, 0)

   -- append the 4th point
   v.x = d
   v.y = -d -- (d , -d)
   mesh:AppendPoint(v, 0)

   -- append the 5th point
   v.x = d
   v.y = d -- (d , d)
   mesh:AppendPoint(v, 0)

   -- weld the 1st and 5th point
   mesh:WeldPoints(n, n+4, 0)

   -- set the curvature for the 4 remaining points to PEAK
   for i = n, n+3 do
      mesh:Point(i):SetCurvature(MOHO.PEAKED, 0)
   end
end

BTW If you haven't do so already, I strongly recommend to read and do the Lua Tutorial. It is reasonably easy to understand and you need to understand Lua before you can write effective scripts for yourself. C'mon it takes only a few hours of reading.

You might want to download the stand-alone Lua interpreter for writing simple code yourself (following the examples in the tutorial). The different versions for different platforms can be found through this page:
Lua Binaries
(Brief explanation for downloaders: lua is the interpreter, luac is a compiler to create socalled "bytecode", which runs Lua modules faster; Lua source code is just plain text, but it can be converted into something between machinecode and plain text, which is called bytecode; bytecode is machine independent, so it runs on every platform; for running the examples in the Lua Tutorial you only need the lua command, which runs on the command line—aka Terminal in Mac OS X.)
User avatar
Rasheed
 
Posts: 2008
Joined: Tue May 17, 2005 8:30 am
Location: The Netherlands

Postby Rasheed » Sat Jan 21, 2006 11:38 am

I wanted to elaborate on a few things and then I'll go on discussing the rest of the Draw Triangle menu script.

I wrote that
Code: Select all
function LayerScript(moho)
is obligatory for layer scripting. Of course, the moho object can be called anything you like; "moho" is just very descriptive for what it represents.

Another thing is that you have to use local variables instead of global variables to interface with Moho, because if you use global variables and there is another layer script that uses the same variable, an uncertain situation occurs. You will never know what value the global exchange variable has, because either script can give it a value. You define local variables with the keyword local.

This explains for instance
Code: Select all
local mesh = moho:Mesh()
You want the mesh of the layer in which the layer script is embedded. If another layer uses the same script, then mesh in that other layer means the mesh of that layer, and not of the first layer.

Perhaps you were wondering when to use a period "." and when to use a colon ":". These are punctuation used for object oriented (OO) programming. Lua is fully OO, but you can also use procedural and functional programming styles, which makes script languages like Lua so versatile.

Here's something about objects. When you define an object, it is abstract. As long as this definition is not executed ("instantiated") by executing the line of code in the script, the object is abstract. Only after the definition code is executed, the object actually exists in computer memory. After completion of the code and when it is no longer needed, the object will be destroyed and become abstract again. If at the same time as an object is instantiated, the same line of object definition code is run by the Lua interpreter in another script, a physically other object is created. It may seem the same, but it resides in another part of the computer's memory. At least, if these object definitions are local. Global definitions are just that: global. Every script that refers to a global variable (a global object, so to speak), refers to the same object, in the same location in the computer's memory.

So this implies that most object definitions have to be local. If an object is to be used more than once at the same time, it should be defined as a local object. This concept is very important when scripting for layers. If you are sure that only one script is running at the same time, this is not so critical, but the mere existence of layer scripts means that menu scripts and tool scripts have to take into account that layer scripts could be using the same variable names for their objects.

I will now explain what the period is all about.

When you define
Code: Select all
Dog.leg = "dog leg"
then that is the same as
Code: Select all
Dog["leg"] = "dog leg"
It is the object called "leg" inside the table called "Dog". The so-called syntactic sugar Dog.leg is just another way of writing that.

Just like real-life objects, objects in OO programming have properties. So, Jango is a blond horse, and has, of course, been given the name "Jango". So you might write this down as:
Code: Select all
Jango.name = "Jango"
Jango.color = "blond"
or, of course:
Code: Select all
Jango["name"] = "Jango"
Jango["color"] = "blond"

When you would write it like this in code, all objects derived (in technical terms: instantiated) from this definition of the horse object would contain the same properties. In scripts that are executed by Moho, the script can gather information about a particular situation that is at hand for that instance of the script. As you have already seen above, a layer script can be executed within several layers at the same time. So, within the layer, the layer script is an instance of that script.

(Wouldn't that mean that a script is an object once it is executed? Yes, indeed, as everything in Lua is an object, which becomes an instance of object when executed.)

For instance, if you read the number of points in a layer, we use something like:
Code: Select all
local n = mesh:CountPoints()
This means that in every layer script that is executed, the variable n could have a different value. The value also depend on what the script does. If it adds points and executes
Code: Select all
n = mesh:CountPoints()
n will have a different value. So, n is what is called dynamic; it can change over time. And because n is an object, you see that in general, objects are dynamic (at least in Lua). (Almost) everything can be changed and nothing is written in stone. That is another reason why Lua is so versatile.

I will be discussing the colon sign in the following post.
Last edited by Rasheed on Sat Jan 21, 2006 2:09 pm, edited 2 times in total.
User avatar
Rasheed
 
Posts: 2008
Joined: Tue May 17, 2005 8:30 am
Location: The Netherlands

Postby rylleman » Sat Jan 21, 2006 1:53 pm

Thank you Rasheed!
Very pedagogical and very useful, much appriciated.
User avatar
rylleman
 
Posts: 746
Joined: Tue Feb 15, 2005 5:22 pm
Location: sweden

Postby Rasheed » Sat Jan 21, 2006 2:04 pm

Thanks. If you re-read the earlier post, you'll see I have changed some things, because they were not as they should have been. I'm a relative newbie at programming, so I might make a mistake here and there. But luckily, it is easy to correct things.
User avatar
Rasheed
 
Posts: 2008
Joined: Tue May 17, 2005 8:30 am
Location: The Netherlands

Postby Rasheed » Mon Jan 23, 2006 4:03 am

Now about that colon, like in
Code: Select all
mesh:CountPoints()

In object oriented programming, classes are an important concept. A class is a container, that has properties and methods. Those properties and methods are called member values and member functions, respectively.

A class has to be instantiated to exist in computer memory, otherwise it is just an abstract piece of code. This is similar to the behavior of objects; objects have to be instantiated as well to exist. In Lua this instantiation takes place by the execution of the code line(s) which defines each object or class. However, because Lua interfaces with Moho, we have to remember that Moho has classes of its own, which we can reach through the interface—the moho variable in
Code: Select all
function LayerScript(moho)

Member values tell us something about the state of an instance of a class (e.g. the number of points in a vector layer); member functions perform a task (e.g. add a point to a vector layer).

To call a member function of a class, we need to give it some data to work on and we need somewhere to store the data the member function returns. Well, we could use the same variable to give data to the function and store the data the function returns. In code we could write that like this:
Code: Select all
 x = { value = 0 }
function x.Calc(v)
   x.value = x.value + v
end
However, this is not a safe way to write code, because if we want another object y with the same functionality, we encounter problems if we delete x, because it is hard coded into the function:
Code: Select all
y = x; x = nil
y.Calc(10) -- error because x doesn't exist anymore
A better way to write the function is:
Code: Select all
function x.Calc(self, v)
   self.value = self.value + v
end
and call it like so:
Code: Select all
y = x; x = nil
y.Calc(y, 10) -- now y.value become 10

A way to abbreviate y.Calc(y,v) is by writing: y:Calc(v) which means:
give y as an argument to function Calc
and process it as the self value within the function

The self value is another important concept in object oriented programming. It simply replaces the class (x or y) in the body of the member function (x.Calc or y.Calc), so the class isn't hard coded.

It is a bit more complex than this, as I will explain later. It isn't really necessary to be bothered with object oriented programming in Lua. You can write just procedural or functional programs, while the object oriented stuff is going on "under the hood". The only reason why some object oriented programming has to take place, is that Moho is written in C++ and has to interface in an object oriented way with Lua.

So, simply stated:
The colon is used for calling functions of classes, either defined by Lua or Moho.

Now, what is that "more complex" stuff? Well, what particular member functions and member variables are available depends on what class is acted upon by Lua. Not every class has the same members. For example, bone layers don't have points, so there is no need for a Point() function. Remember we used the code
Code: Select all
local mesh = moho:Mesh()
if mesh == nil then
    return
end
the Lua variable mesh is referring to the Mesh class in the Moho layer. If this Mesh class does not exist, mesh will receive the value nil (meaning: it does not exist), and the layer script will return to its caller (which is the Moho program).

If the class exists, we can call a member function like AddLonePoint. The AddLonePoint member function is located inside Moho's Mesh class. And, therefore, Moho has to know what layer to process. That is why the Lua script should supply the layer object to Moho and the best way to write this in Lua script code is by using the notation with the colon in the function call.
Code: Select all
mesh:AddLonePoint(v,0)
gives the following parameters to the AddLonePoint member function:
Code: Select all
mesh -- the vector layer object
v -- the vector point
0 -- the frame number
The member function AddLonePoint is processed within Moho. AddLonePoint doesn't return any values. There are, of course, member functions that do return values. E.g. CountPoints, returns the number of points Moho has counted in the vector layer. If we want to catch this value, we have to assign it to a Lua variable (which has to be local, as was explain earlier):
Code: Select all
local n = mesh:CountPoints()

Now something about the period punctuation. Remember the
Code: Select all
local v = LM.Vector2:new_local()
This function calls the member function new_local of the LM.Vector2 class. This Lua class isn't located within the Moho program, but instead it is a class within the Lua scripting engine. The function returns a vector object, which is a table with two entries:
Code: Select all
v["x"]
v["y"]
or
Code: Select all
v.x
v.y
So this is a way to define a vector. And Moho is happy to accept this notation, because in
Code: Select all
mesh:AppendPoint(v, 0)
the vector v (containing v.x and v.y) is given to Moho.

So, as you can see, both Moho and the Lua scripting interface use classes. And although in your own scripts you don't have to use object oriented programming, the fact both Moho and the scripting interface do, means you have to know something about it. I hope this explanation will have helped you to gain enough knowledge to deal with the object oriented part of scripting for Moho.

As always, if you think you have found errors in or have questions about this or earlier posts in this thread, feel free to add a reply and I'll try to answer it.

BTW I hope this is the last of the theory so far, because re/writing this post took me several hours.

The next subject on my list is to describe how the overhead of a menu script works, so you can start writing your own menu scripts.
User avatar
Rasheed
 
Posts: 2008
Joined: Tue May 17, 2005 8:30 am
Location: The Netherlands

Postby Rasheed » Mon Jan 23, 2006 3:08 pm

Let's look at the full Lua script of Draw Triangle
Code: Select all
-- **************************************************
-- Provide Moho with the name of this script object
-- **************************************************

ScriptName = "LM_Triangle"

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

LM_Triangle = {}

function LM_Triangle:Name()
    return "Triangle"
end

function LM_Triangle:Version()
    return "5.0"
end

function LM_Triangle:Description()
    return "Creates a new triangle shape in the current layer."
end

function LM_Triangle:Creator()
    return "Lost Marble"
end

function LM_Triangle:UILabel()
    return("Triangle")
end

-- **************************************************
-- The guts of this script
-- **************************************************

function LM_Triangle:IsEnabled(moho)
    if (moho.layer:LayerType() ~= MOHO.LT_VECTOR) then
        return false
    end
    if (moho.layer:CurrentAction() ~= "") then
        return false -- creating new objects in the middle of an action can lead to unexpected results
    end
    return true
end

function LM_Triangle:Run(moho)
    local mesh = moho:Mesh()
    if (mesh == nil) then
        return
    end

    moho.document:PrepUndo(moho.layer)
    moho.document:SetDirty()

    local n = mesh:CountPoints()
    local v = LM.Vector2:new_local()
    local r = 0.75

    mesh:SelectNone()

    v.x = r * math.cos(math.pi / 2)
    v.y = r * math.sin(math.pi / 2)
    mesh:AddLonePoint(v, 0)

    v.x = r * math.cos(math.pi + math.pi / 6)
    v.y = r * math.sin(math.pi + math.pi / 6)
    mesh:AppendPoint(v, 0)

    v.x = r * math.cos(2 * math.pi - math.pi / 6)
    v.y = r * math.sin(2 * math.pi - math.pi / 6)
    mesh:AppendPoint(v, 0)

    v.x = r * math.cos(math.pi / 2)
    v.y = r * math.sin(math.pi / 2)
    mesh:AppendPoint(v, 0)
    mesh:WeldPoints(n, n + 3, 0)

    mesh:Point(n):SetCurvature(MOHO.PEAKED, 0)
    mesh:Point(n + 1):SetCurvature(MOHO.PEAKED, 0)
    mesh:Point(n + 2):SetCurvature(MOHO.PEAKED, 0)

    mesh:SelectConnected()
    moho:CreateShape(true)
end

Now let's look at this script a piece at the time.

The name of the script
Code: Select all
ScriptName = "LM_Triangle"
This seems to be a "no brainer". The global variable ScriptName is supplied with the name of the script. But look at the other occurrences of "LM_Triangle":
Code: Select all
function LM_Triangle:Name()    -- name of the script
function LM_Triangle:Version()    -- version of the script
function LM_Triangle:Description()    -- description of the script
function LM_Triangle:Creator()    -- creator of the script
function LM_Triangle:UILabel()    -- text in Moho's menu bar
function LM_Triangle:IsEnabled(moho)    -- test whether or not the script should be executed
function LM_Triangle:Run(moho)    -- code to be executed when the script is called
As you can see, all these occurrences are member function definitions, which means (as you may recall from the previous post) that LM_Triangle is in fact a class. So the global variable ScriptName is read by Moho and interpreted as the name of a class.

That LM_Triangle IS a class, follows from this line of code:
Code: Select all
LM_Triangle = {}
Lua doesn't have a separate class statement to declare classes, as some languages have. Instead, Lua uses tables to define classes. So the definition of the global variable LM_Triangle as an empty table, is in fact the definition of an empty class. The function definitions that follow are in fact the member functions to the class LM_Triangle. Any member variables can be defined just as easily, simply by:
Code: Select all
LM_Triangle.key = value
or
Code: Select all
LM_Triangle["key"] = value
Note, that although the self variable (which points to the LM_Triangle class within the member functions) isn't used here, but it can be if you would ever need to.

However, because there is always only one menu script active, you can use the class name to refer to the class (by doing so, hard coding the class name in the member functions). Therefore, for practical purposes, in menu scripts (and tool scripts) there often seems to be no need for using self. Remember, that when using layer scripts there may be more instances of a class. Knowing that, it may be prudent not to use "LM_Triangle" as a class name in a layer script, because conflicts may occur when you call the menu script Draw Triangle.

Image Image
As you can observe from the screenshots above, the submenu file structure has a close resemblence with Moho's Scripts menu structure. The filename "lm_triangle.lua" is different from the script name "LM_Triangle". If you change the file name, the name in the Moho menu bar will not change, because of the member function LM_Triangle:UILabel(). If you change the string value of ScriptName (and the name of the class used in the script) to e.g. "LM_Dreieck", the menu bar will still show "Triangle" once you have (re)launched Moho. Only when you change the UILabel() member function, the actual name that occurs in the Moho menu bar will change accordingly.

The member function Description doesn't seem to do anything in menu scripts, but in tool scripts, the returned string will appear in the status bar. The member functions Name, Version and Creator are apparently only for script readers, because these don't appear to be used by the Moho program at all. However, other functions in the script may refer to the values these member functions return.

Enable and Run the script
The IsEnabled member function uses moho as an argument, which means that Moho supplies a context to this function when it is called. The function should use this moho object to establish if the script should be executed or not. It can only return a true or false value. Only if the value is true, the Run member function is called by Moho. The IsEnabled function is easy to understand (MOHO.LT_VECTOR is equal to a value that coincides with a vector layer type).

And the Run member function has already been discussed in an earlier post in this thread.



So, I guess this is about all what can be written about the Draw Triangle script, unless there are any questions or comments.

I suggest you do some dissecting of menu scripts by yourself, so you might learn a lot from own experience. Don't forget to read the stickies to the Scripting subforum (especially download the Scripting Documentation).
User avatar
Rasheed
 
Posts: 2008
Joined: Tue May 17, 2005 8:30 am
Location: The Netherlands

Postby 7feet » Mon Jan 23, 2006 4:04 pm

Excellent explanations.

One truly monor point - the Name, Creator, and Version info are visible inside Moho with the Help>About Scripts bit. I use it occasionally to check which version of a script I have installed without having to open up the Lua file.
User avatar
7feet
 
Posts: 840
Joined: Wed Aug 04, 2004 5:45 am
Location: L.I., New Yawk.

Postby Ramón López » Thu Feb 02, 2006 9:47 pm

...Ufff! Really I've enjoined it! :D I don't know if I've catched all the things (I suspect not yet... :() but definitely this explanations are incredible USEFUL! You have resolved to me so much doubts that, beliveme, I can't be more GRATEFUL! THANKS for all that work and time that you are dedicating Rasheed, I think you are doing a GREAT and (the most important thing) really NECESSARY work! :) CIAO! And CHEER UP!!!

PS: I'll be waiting for more knowledges! If you don't mind... :)
User avatar
Ramón López
 
Posts: 1799
Joined: Sun Aug 08, 2004 1:41 pm
Location: Elda! Again...

Postby Rasheed » Fri Feb 03, 2006 10:27 am

Ramón López wrote:I'll be waiting for more knowledges! If you don't mind... :)

The next subject proved to be a tad more difficult. It seems I have to do some serious studying, because the concepts of GUI programming are so much harder to understand than for procedural and functional programming. GUI programming is no so much a theory you can learn by reading than a craft you should learn by doing.

IOW I need to do some GUI programming of myself, to gain enough knowledge and experience to be able to explain it to you. It is hard work to explain something in simple words and still not oversimplify. I really want you to make that first step in GUI programming, but before that I'll have to make that first step to be able to guide you.

So I ask you to be patient, please. This may take considerable time. But hey, perhaps by that time I'll be able to start writing a complete tutorial on Moho scripting. GUI programming has a steep learning curve, but I expect once you have conquered that mountain of knowledge, things will get more relaxed (I hope).
User avatar
Rasheed
 
Posts: 2008
Joined: Tue May 17, 2005 8:30 am
Location: The Netherlands

Postby Ramón López » Tue Feb 07, 2006 11:14 am

YEAH! And I understand you, study and write all that things must take a lot of time! And although I'm very happy/excited and thirsty for new knowledges, of course I'll be patient and will be waiting in silence :) ...THANKS!!!
User avatar
Ramón López
 
Posts: 1799
Joined: Sun Aug 08, 2004 1:41 pm
Location: Elda! Again...

Postby Ramón López » Fri Feb 10, 2006 10:08 am

Ey, Rasheed! HI!!! :D You don'k know how much useful your explanations are to me! Even I've printed it and DEFINITELY it has become in my bedside topic! :D Belive me if I say you that I couldn't be more GRATEFUL :)

Well, as you can see I've been doing my homeworks (as I still said) and now I'm treating to understand how that curious "DrawRectWithHole.lua" works, cause is difficult to my understand that "different" structure... you know, it's like "divided" in two parts and seems little different to the other Embedded Scripts, well, I don't know why and it make my curious...

Emmm... Obviously I've tons of doubts apart of this one, yes... and I wouldn't know where to begin asking, but... you quiet! :) I'll treat to go on learn by myself too (as much as I can :wink:) And I will broke my silence as less as I can :roll: ...Well, THANK YOU again (very much) and BYE!


EDIT1: Hmmm... interesting... I am/go understanding something (soomething...) about that misterious script...

EDIT2: ...And yes! I'm trying to confront that Lua Tutorials too right now! :D (I had never dare to do it before) Uf! we'll see...
User avatar
Ramón López
 
Posts: 1799
Joined: Sun Aug 08, 2004 1:41 pm
Location: Elda! Again...


Return to Scripting

Who is online

Users browsing this forum: No registered users and 1 guest