View Single Post
Old 05-19-2016, 08:30 PM   #56
Human being with feelings
Lokasenna's Avatar
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,277

10. LS GUI in detail

Note: This lesson refers to the LS GUI library provided in part 6. If you haven't downloaded those files yet, see this post: 6. Introducing the LS GUI library

Next up, I'd like to take a stroll through the demonstration scripts for LS GUI and hopefully provide a better picture of how all these parts work together. Even moreso than the previous lessons, I'd recommend having the demo scripts open somewhere handy so you can follow along.

Note: Numbers with parentheses and written in bold italics are there to denote what line of code we're looking at. i.e. (26)

The usage demo

(1) When working with a library file, the first thing we need to do is tell Lua to load said library file. In programming-speak, this is known as requiring, or including, the library.

- debug.getinfo() grabs a whole bunch of information about the function that called it - in this case, that's Reaper.
- Next we use another string function, string.match(), to extract a folder path to where the current script is located.
- A call to dofile(), as the name suggests, tells Lua to run the file we give it, treating it exactly as if the contents were written in this script.

All of the functions and classes from our library are stored under the variable GUI; as I explained in the Tables lesson, it's a very tidy way to bring a library into your own script without causing the user any trouble.

(15) Now that we have all of the GUI functions available, we can start with a few initial settings - the name of our window, position, and coordinates.

(20) This is just a basic example of a function that you might call when one of your buttons is clicked, as discussed in the Button lesson.

(35) Good god, another table. WHEN WILL THE MADNESS STOP!?! All of our GUI elements are stored here. Putting them all in a table makes life easier for our library's main functions, as we'll see shortly.

(61) The usage demo doesn't make use of it, but the GUI library's Main() function allows the user to specify a function that they'd like included in the script's defer loop. Optionally, you can specify how often to run it so that you don't pillage all of the end-user's processing power.

After that, all we do is call our Init() and Main() functions, and that's it.

The library

(63) Even more tables. I must get it from my dad - he made a spreadsheet for how to get around Disneyland as efficiently as possible once.

These tables are there so we can specify a global set of fonts and colors for our GUI elements. They can be overridden in a user script by including your own GUI.fonts{} and GUI.colors{}, provided the same format for key numbers, names, and values is followed.

They're also accompanied by a couple of helper functions that simplify the process of setting a font or color.

(133) Setting a few mouse variables to their default values, just so nothing returns nil by accident later on. The library functions could definitely be rewritten to check for errors, in which case you wouldn't need this, but I always forget to do that.

(130) The next section contains a number of functions that will make life easier. They can be called from a user script just like everything else in the library, via GUI.function_name(parameters).

(303) GUI.Init() is responsible for creating our window. It also converts the color presets from 0-255 RGB, which I find easiest to work with, into the 0-1 RGB that Reaper prefers.

(322) Alrighty, on to the big boys. GUI.Main() does the following every time our script loops around:

- Updates the mouse and keyboard variables. You could access them directly, but storing them locally makes the process a little faster. I think.

- Sees if the window has been closed or not, and calls our old buddy defer() to keep the party going.

- Asks each of our GUI elements to check in and see if it's been clicked, dragged, etc. I told you that table would help.

- If the user wanted to run their own function during the loop, do so.

(364) Here's where each element is sent for its checkup. If it was clicked on, or double-clicked, or dragged, or typed in, GUI.Update() calls that element's appropriate method. All of the elements are also told to redraw themselves while they're here.

This function is also a good example of why classes are useful - by providing Update() with the name of an object, it can check the status of all of them easily and change their variables. Because all of their methods have the same names, Update can call them with a minimum of fuss.

After that it's just the various classes and their methods, which have either been covered already or are on the list for an upcoming lesson.

Hmm. This post ended up being a lot shorter than I expected, partly because I already tried to leave as many comments as possible in the scripts themselves. If I think of anything else worth discussing, I'll edit it in.
Lokasenna is offline   Reply With Quote